From 103a3305e2a7bb9ef87d72a1237cbc5237aa8156 Mon Sep 17 00:00:00 2001 From: huntc Date: Tue, 12 Oct 2021 11:24:26 +1100 Subject: Implements continuous sampling for the nRF SAADC Implements continuous sampling for the nRF SAADC and also renames `OneShot` to `Saadc`. The one-shot behaviour is retained with the `sample` method and a new `run_sampler` method is provided for efficiently (i.e. zero copying) sampler processing. A double buffer is used for continuously sampling, which wlll be swapped once sampling has taken place. A sample frequency is provided and will set the internal timer of the SAADC when there is just the one channel being sampled. Otherwise, PPI will be used to hook up the TIMER peripheral to drive the sampling task. --- examples/nrf/src/bin/saadc.rs | 4 +-- examples/nrf/src/bin/saadc_continuous.rs | 49 ++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 examples/nrf/src/bin/saadc_continuous.rs (limited to 'examples') diff --git a/examples/nrf/src/bin/saadc.rs b/examples/nrf/src/bin/saadc.rs index d12717c04..c6eac555b 100644 --- a/examples/nrf/src/bin/saadc.rs +++ b/examples/nrf/src/bin/saadc.rs @@ -7,7 +7,7 @@ mod example_common; use defmt::panic; use embassy::executor::Spawner; use embassy::time::{Duration, Timer}; -use embassy_nrf::saadc::{ChannelConfig, Config, OneShot}; +use embassy_nrf::saadc::{ChannelConfig, Config, Saadc}; use embassy_nrf::{interrupt, Peripherals}; use example_common::*; @@ -15,7 +15,7 @@ use example_common::*; async fn main(_spawner: Spawner, mut p: Peripherals) { let config = Config::default(); let channel_config = ChannelConfig::single_ended(&mut p.P0_02); - let mut saadc = OneShot::new(p.SAADC, interrupt::take!(SAADC), config, [channel_config]); + let mut saadc = Saadc::new(p.SAADC, interrupt::take!(SAADC), config, [channel_config]); loop { let mut buf = [0; 1]; diff --git a/examples/nrf/src/bin/saadc_continuous.rs b/examples/nrf/src/bin/saadc_continuous.rs new file mode 100644 index 000000000..fba00ebdf --- /dev/null +++ b/examples/nrf/src/bin/saadc_continuous.rs @@ -0,0 +1,49 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +#[path = "../example_common.rs"] +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::timer::{Frequency, Timer}; +use embassy_nrf::{interrupt, Peripherals}; +use example_common::*; + +// Demonstrates both continuous sampling and scanning multiple channels driven by a PPI linked timer + +#[embassy::main] +async fn main(_spawner: Spawner, mut p: Peripherals) { + let config = Config::default(); + let channel_1_config = ChannelConfig::single_ended(&mut p.P0_02); + let channel_2_config = ChannelConfig::single_ended(&mut p.P0_03); + let channel_3_config = ChannelConfig::single_ended(&mut p.P0_04); + let mut saadc = Saadc::new( + p.SAADC, + interrupt::take!(SAADC), + config, + [channel_1_config, channel_2_config, channel_3_config], + ); + + let mut timer = Timer::new(p.TIMER0); + timer.set_frequency(Frequency::F1MHz); + timer.cc(0).write(100); // We want to sample at 10KHz + timer.cc(0).short_compare_clear(); + + let mut ppi = Ppi::new(p.PPI_CH0); + ppi.set_event(timer.cc(0).event_compare()); + ppi.set_task(saadc.task_sample()); + ppi.enable(); + + timer.start(); + + let mut bufs = [[0; 3 * 500]; 2]; // Each buffer of the double buffer has to be large enough for all channels. + saadc + .run_sampler(&mut bufs, Mode::Task, |buf| { + info!("sample len={}", buf.len()); + SamplerState::Sampled + }) + .await; +} -- cgit