embassy/examples
bors[bot] a5c11b1a80
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 <huntchr@gmail.com>
2021-10-18 00:51:19 +00:00
..
nrf Use types to strengthen the buffer dimensioning 2021-10-18 10:26:11 +11:00
rp Update lots of deps 2021-09-11 01:35:23 +02:00
std examples/std: fix warning 2021-10-18 01:37:35 +02:00
stm32f0 Update lots of deps 2021-09-11 01:35:23 +02:00
stm32f1 Initial STM32F1 family support with two examples for STM32F103C8 (Blue Pill) 2021-09-28 18:31:04 +02:00
stm32f4 Update lots of deps 2021-09-11 01:35:23 +02:00
stm32g0 Update lots of deps 2021-09-11 01:35:23 +02:00
stm32h7 Update version of critical-section 2021-09-13 17:05:17 +02:00
stm32l0 Update to newer revision of async lorawan stack 2021-10-11 13:51:00 +02:00
stm32l1 Support for STM32L1 2021-09-21 14:50:23 +02:00
stm32l4 Support for STM32L1 2021-09-21 14:50:23 +02:00
stm32wb55 Update lots of deps 2021-09-11 01:35:23 +02:00
stm32wl55 Update to newer revision of async lorawan stack 2021-10-11 13:51:00 +02:00
wasm Update version of critical-section 2021-09-13 17:05:17 +02:00