Removed the Mode enum and factored out into two functions so that we can assert channel limits

This commit is contained in:
huntc 2021-10-17 06:56:56 +11:00
parent a020b1a404
commit cb56f52b99
2 changed files with 55 additions and 22 deletions

View file

@ -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 progress of a sampler, it also signals what should be done
/// 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
/// 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
/// 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_sampler<S, const N0: usize>(
pub async fn run_timer_sampler<S, const N0: usize>(
&mut self,
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,
) where
S: FnMut(&[i16]) -> SamplerState,
@ -269,16 +302,16 @@ impl<'d, const N: usize> Saadc<'d, N> {
let r = Self::regs();
// Establish mode and sample rate
match mode {
Mode::Timers(sample_rate) => {
match sample_rate {
Some(sr) => {
r.samplerate.write(|w| unsafe {
w.cc().bits(sample_rate);
w.cc().bits(sr);
w.mode().timers();
w
});
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.mode().task();
w

View file

@ -7,7 +7,7 @@ mod example_common;
use defmt::panic;
use embassy::executor::Spawner;
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::{interrupt, Peripherals};
use example_common::*;
@ -45,7 +45,7 @@ async fn main(_spawner: Spawner, mut p: Peripherals) {
let mut a: i32 = 0;
saadc
.run_sampler(&mut bufs, Mode::Task, move |buf| {
.run_task_sampler(&mut bufs, move |buf| {
for (i, b) in buf.iter().enumerate() {
if i % 3 == 0 {
a += *b as i32;