aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-10-18 00:51:19 +0000
committerGitHub <[email protected]>2021-10-18 00:51:19 +0000
commita5c11b1a80bd8a20b88a4f8c083c80111ec49b84 (patch)
tree37b120fc9b1e2d512d78b033d09f6a0261a8f7ad /examples
parentfdef0477410c84bca3452fca9b8719ad1f758528 (diff)
parenta94d44a689f5832a9eefbaab8f126a388308a08c (diff)
Merge #425
425: Implements continuous sampling for the nRF SAADC r=huntc a=huntc 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 is swapped appropriately. A sample frequency is provided and will set the internal timer of the SAADC when there is just one channel being sampled. Otherwise, PPI will be used to hook up the TIMER peripheral to drive the sampling task. Two methods are provided for this: `run_task_sampler` and `run_task_sampler` with the latter available where the compiler sees that just one channel is configured. Note that we set up the PPI and timer behaviour outside of the `Saadc` for maximum flexibility. A callback is provided to the `run_sampler` method. This is a synchronous callback that should return in a reasonably short space of time. The SAADC could stall if it does not. A reasonable practice is to perform a small amount of processing within the callback to yield a signal, perhaps via `mpsc`. In the case of `mpsc`, the `try_send` method becomes useful. A new example has been provided to illustrate continuous sampling, along with multiple channels and external timing: ```rust #[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]; 50]; 2]; let mut c = 0; let mut a: i32 = 0; saadc .run_task_sampler(&mut bufs, move |buf| { for b in buf { a += b[0] as i32; } c += buf.len(); if c > 10000 { a = a / c as i32; info!("channel 1: {=i32}", a); c = 0; a = 0; } SamplerState::Sampled }) .await; } ``` Co-authored-by: huntc <[email protected]>
Diffstat (limited to 'examples')
-rw-r--r--examples/nrf/src/bin/saadc.rs4
-rw-r--r--examples/nrf/src/bin/saadc_continuous.rs62
2 files changed, 64 insertions, 2 deletions
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;
7use defmt::panic; 7use defmt::panic;
8use embassy::executor::Spawner; 8use embassy::executor::Spawner;
9use embassy::time::{Duration, Timer}; 9use embassy::time::{Duration, Timer};
10use embassy_nrf::saadc::{ChannelConfig, Config, OneShot}; 10use embassy_nrf::saadc::{ChannelConfig, Config, Saadc};
11use embassy_nrf::{interrupt, Peripherals}; 11use embassy_nrf::{interrupt, Peripherals};
12use example_common::*; 12use example_common::*;
13 13
@@ -15,7 +15,7 @@ use example_common::*;
15async fn main(_spawner: Spawner, mut p: Peripherals) { 15async fn main(_spawner: Spawner, mut p: Peripherals) {
16 let config = Config::default(); 16 let config = Config::default();
17 let channel_config = ChannelConfig::single_ended(&mut p.P0_02); 17 let channel_config = ChannelConfig::single_ended(&mut p.P0_02);
18 let mut saadc = OneShot::new(p.SAADC, interrupt::take!(SAADC), config, [channel_config]); 18 let mut saadc = Saadc::new(p.SAADC, interrupt::take!(SAADC), config, [channel_config]);
19 19
20 loop { 20 loop {
21 let mut buf = [0; 1]; 21 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..149b9c60c
--- /dev/null
+++ b/examples/nrf/src/bin/saadc_continuous.rs
@@ -0,0 +1,62 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5#[path = "../example_common.rs"]
6mod example_common;
7use defmt::panic;
8use embassy::executor::Spawner;
9use embassy_nrf::ppi::Ppi;
10use embassy_nrf::saadc::{ChannelConfig, Config, Saadc, SamplerState};
11use embassy_nrf::timer::{Frequency, Timer};
12use embassy_nrf::{interrupt, Peripherals};
13use example_common::*;
14
15// Demonstrates both continuous sampling and scanning multiple channels driven by a PPI linked timer
16
17#[embassy::main]
18async fn main(_spawner: Spawner, mut p: Peripherals) {
19 let config = Config::default();
20 let channel_1_config = ChannelConfig::single_ended(&mut p.P0_02);
21 let channel_2_config = ChannelConfig::single_ended(&mut p.P0_03);
22 let channel_3_config = ChannelConfig::single_ended(&mut p.P0_04);
23 let mut saadc = Saadc::new(
24 p.SAADC,
25 interrupt::take!(SAADC),
26 config,
27 [channel_1_config, channel_2_config, channel_3_config],
28 );
29
30 let mut timer = Timer::new(p.TIMER0);
31 timer.set_frequency(Frequency::F1MHz);
32 timer.cc(0).write(100); // We want to sample at 10KHz
33 timer.cc(0).short_compare_clear();
34
35 let mut ppi = Ppi::new(p.PPI_CH0);
36 ppi.set_event(timer.cc(0).event_compare());
37 ppi.set_task(saadc.task_sample());
38 ppi.enable();
39
40 timer.start();
41
42 let mut bufs = [[[0; 3]; 50]; 2];
43
44 let mut c = 0;
45 let mut a: i32 = 0;
46
47 saadc
48 .run_task_sampler(&mut bufs, move |buf| {
49 for b in buf {
50 a += b[0] as i32;
51 }
52 c += buf.len();
53 if c > 10000 {
54 a = a / c as i32;
55 info!("channel 1: {=i32}", a);
56 c = 0;
57 a = 0;
58 }
59 SamplerState::Sampled
60 })
61 .await;
62}