Removed the Mode enum and factored out into two functions so that we can assert channel limits
This commit is contained in:
		| @@ -110,20 +110,6 @@ impl<'d> ChannelConfig<'d> { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| /// A sample rate can be provided for the internal clock of the SAADC when |  | ||||||
| /// one channel is to be continuously sampled. When there are multiple channels |  | ||||||
| /// to be continuously sampled then an external source is used to generate |  | ||||||
| /// TASK_SAMPLE tasks. |  | ||||||
| pub enum Mode { |  | ||||||
|     /// The internal clock is to be used with a sample rate expressed as a divisor of |  | ||||||
|     /// 16MHz, ranging from 80..2047. For example, 1600 represnts a sample rate of 10KHz |  | ||||||
|     /// given 16_000_000 / 10_000_000 = 1600. |  | ||||||
|     Timers(u16), |  | ||||||
|     /// TASK_SAMPLE tasks are generated outside of the SAADC e.g. via PPI on a |  | ||||||
|     /// timer. |  | ||||||
|     Task, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /// The state of a continuously running sampler. While it reflects | /// The state of a continuously running sampler. While it reflects | ||||||
| /// the progress of a sampler, it also signals what should be done | /// the progress of a sampler, it also signals what should be done | ||||||
| /// next. For example, if the sampler has stopped then the Saadc implementation | /// next. For example, if the sampler has stopped then the Saadc implementation | ||||||
| @@ -254,14 +240,61 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||||||
|     /// Continuous sampling with double buffers. The sample buffers generally |     /// Continuous sampling with double buffers. The sample buffers generally | ||||||
|     /// should be a multiple of the number of channels configured. |     /// should be a multiple of the number of channels configured. | ||||||
|     /// |     /// | ||||||
|  |     /// The internal clock is to be used with a sample rate expressed as a divisor of | ||||||
|  |     /// 16MHz, ranging from 80..2047. For example, 1600 represnts a sample rate of 10KHz | ||||||
|  |     /// given 16_000_000 / 10_000_000 = 1600. | ||||||
|  |     /// | ||||||
|     /// A sampler closure is provided that receives the buffer of samples, noting |     /// A sampler closure is provided that receives the buffer of samples, noting | ||||||
|     /// that the size of this buffer can be less than the original buffer's size. |     /// that the size of this buffer can be less than the original buffer's size. | ||||||
|     /// A command is return from the closure that indicates whether the sampling |     /// A command is return from the closure that indicates whether the sampling | ||||||
|     /// should continue or stop. |     /// should continue or stop. | ||||||
|     pub async fn run_sampler<S, const N0: usize>( |     pub async fn run_timer_sampler<S, const N0: usize>( | ||||||
|         &mut self, |         &mut self, | ||||||
|         bufs: &mut [[i16; N0]; 2], |         bufs: &mut [[i16; N0]; 2], | ||||||
|         mode: Mode, |         sample_rate: u16, | ||||||
|  |         sampler: S, | ||||||
|  |     ) where | ||||||
|  |         S: FnMut(&[i16]) -> SamplerState, | ||||||
|  |     { | ||||||
|  |         assert!( | ||||||
|  |             N == 1, | ||||||
|  |             "The internal timer can only be used with one channel" | ||||||
|  |         ); | ||||||
|  |         assert!( | ||||||
|  |             N0 % N == 0, | ||||||
|  |             "The buffer size must be a multiple of the number of channels" | ||||||
|  |         ); | ||||||
|  |         self.run_sampler(bufs, Some(sample_rate), sampler).await; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// Continuous sampling with double buffers. The sample buffers generally | ||||||
|  |     /// should be a multiple of the number of channels configured. | ||||||
|  |     /// | ||||||
|  |     /// A task-driven approach to driving TASK_SAMPLE is expected. With a task | ||||||
|  |     /// driven approach, multiple channels can be used. | ||||||
|  |     /// | ||||||
|  |     /// A sampler closure is provided that receives the buffer of samples, noting | ||||||
|  |     /// that the size of this buffer can be less than the original buffer's size. | ||||||
|  |     /// A command is return from the closure that indicates whether the sampling | ||||||
|  |     /// should continue or stop. | ||||||
|  |     pub async fn run_task_sampler<S, const N0: usize>( | ||||||
|  |         &mut self, | ||||||
|  |         bufs: &mut [[i16; N0]; 2], | ||||||
|  |         sampler: S, | ||||||
|  |     ) where | ||||||
|  |         S: FnMut(&[i16]) -> SamplerState, | ||||||
|  |     { | ||||||
|  |         assert!( | ||||||
|  |             N0 % N == 0, | ||||||
|  |             "The buffer size must be a multiple of the number of channels" | ||||||
|  |         ); | ||||||
|  |         self.run_sampler(bufs, None, sampler).await; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     async fn run_sampler<S, const N0: usize>( | ||||||
|  |         &mut self, | ||||||
|  |         bufs: &mut [[i16; N0]; 2], | ||||||
|  |         sample_rate: Option<u16>, | ||||||
|         mut sampler: S, |         mut sampler: S, | ||||||
|     ) where |     ) where | ||||||
|         S: FnMut(&[i16]) -> SamplerState, |         S: FnMut(&[i16]) -> SamplerState, | ||||||
| @@ -269,16 +302,16 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||||||
|         let r = Self::regs(); |         let r = Self::regs(); | ||||||
|  |  | ||||||
|         // Establish mode and sample rate |         // Establish mode and sample rate | ||||||
|         match mode { |         match sample_rate { | ||||||
|             Mode::Timers(sample_rate) => { |             Some(sr) => { | ||||||
|                 r.samplerate.write(|w| unsafe { |                 r.samplerate.write(|w| unsafe { | ||||||
|                     w.cc().bits(sample_rate); |                     w.cc().bits(sr); | ||||||
|                     w.mode().timers(); |                     w.mode().timers(); | ||||||
|                     w |                     w | ||||||
|                 }); |                 }); | ||||||
|                 r.tasks_sample.write(|w| unsafe { w.bits(1) }); // Need to kick-start the internal timer |                 r.tasks_sample.write(|w| unsafe { w.bits(1) }); // Need to kick-start the internal timer | ||||||
|             } |             } | ||||||
|             Mode::Task => r.samplerate.write(|w| unsafe { |             None => r.samplerate.write(|w| unsafe { | ||||||
|                 w.cc().bits(0); |                 w.cc().bits(0); | ||||||
|                 w.mode().task(); |                 w.mode().task(); | ||||||
|                 w |                 w | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ mod example_common; | |||||||
| use defmt::panic; | use defmt::panic; | ||||||
| use embassy::executor::Spawner; | use embassy::executor::Spawner; | ||||||
| use embassy_nrf::ppi::Ppi; | use embassy_nrf::ppi::Ppi; | ||||||
| use embassy_nrf::saadc::{ChannelConfig, Config, Mode, Saadc, SamplerState}; | use embassy_nrf::saadc::{ChannelConfig, Config, Saadc, SamplerState}; | ||||||
| use embassy_nrf::timer::{Frequency, Timer}; | use embassy_nrf::timer::{Frequency, Timer}; | ||||||
| use embassy_nrf::{interrupt, Peripherals}; | use embassy_nrf::{interrupt, Peripherals}; | ||||||
| use example_common::*; | use example_common::*; | ||||||
| @@ -45,7 +45,7 @@ async fn main(_spawner: Spawner, mut p: Peripherals) { | |||||||
|     let mut a: i32 = 0; |     let mut a: i32 = 0; | ||||||
|  |  | ||||||
|     saadc |     saadc | ||||||
|         .run_sampler(&mut bufs, Mode::Task, move |buf| { |         .run_task_sampler(&mut bufs, move |buf| { | ||||||
|             for (i, b) in buf.iter().enumerate() { |             for (i, b) in buf.iter().enumerate() { | ||||||
|                 if i % 3 == 0 { |                 if i % 3 == 0 { | ||||||
|                     a += *b as i32; |                     a += *b as i32; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user