aboutsummaryrefslogtreecommitdiff
path: root/examples/rp/src/bin/zerocopy.rs
diff options
context:
space:
mode:
authorkalkyl <[email protected]>2024-06-04 00:38:51 +0200
committerkalkyl <[email protected]>2024-06-04 00:38:51 +0200
commit03d8f99aa57d71c27745972f2bcd9ba3450bd8c3 (patch)
tree23c58259b87bd7958af682321b98035f22518335 /examples/rp/src/bin/zerocopy.rs
parent9856d216939d9433e840289966e313c9aa377fca (diff)
rp: Add zerocopy channel example
Diffstat (limited to 'examples/rp/src/bin/zerocopy.rs')
-rw-r--r--examples/rp/src/bin/zerocopy.rs90
1 files changed, 90 insertions, 0 deletions
diff --git a/examples/rp/src/bin/zerocopy.rs b/examples/rp/src/bin/zerocopy.rs
new file mode 100644
index 000000000..b5bd11512
--- /dev/null
+++ b/examples/rp/src/bin/zerocopy.rs
@@ -0,0 +1,90 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_rp::adc::{self, Adc, Async, Config, InterruptHandler};
7use embassy_rp::bind_interrupts;
8use embassy_rp::gpio::Pull;
9use embassy_rp::peripherals::DMA_CH0;
10use embassy_sync::blocking_mutex::raw::NoopRawMutex;
11use embassy_sync::zerocopy_channel::{Channel, Receiver, Sender};
12use embassy_time::{Duration, Ticker, Timer};
13use portable_atomic::{AtomicU16, Ordering};
14use static_cell::StaticCell;
15use {defmt_rtt as _, panic_probe as _};
16
17type SampleBuffer = [u16; 512];
18
19bind_interrupts!(struct Irqs {
20 ADC_IRQ_FIFO => InterruptHandler;
21});
22
23const BLOCK_SIZE: usize = 512;
24const NUM_BLOCKS: usize = 2;
25static MAX: AtomicU16 = AtomicU16::new(0);
26
27struct AdcParts {
28 adc: Adc<'static, Async>,
29 pin: adc::Channel<'static>,
30 dma: DMA_CH0,
31}
32
33#[embassy_executor::main]
34async fn main(spawner: Spawner) {
35 let p = embassy_rp::init(Default::default());
36 info!("Here we go!");
37
38 let adc_parts = AdcParts {
39 adc: Adc::new(p.ADC, Irqs, Config::default()),
40 pin: adc::Channel::new_pin(p.PIN_29, Pull::None),
41 dma: p.DMA_CH0,
42 };
43
44 static BUF: StaticCell<[SampleBuffer; NUM_BLOCKS]> = StaticCell::new();
45 let buf = BUF.init([[0; BLOCK_SIZE]; NUM_BLOCKS]);
46
47 static CHANNEL: StaticCell<Channel<'_, NoopRawMutex, SampleBuffer>> = StaticCell::new();
48 let channel = CHANNEL.init(Channel::new(buf));
49 let (sender, receiver) = channel.split();
50
51 spawner.must_spawn(consumer(receiver));
52 spawner.must_spawn(producer(sender, adc_parts));
53
54 let mut ticker = Ticker::every(Duration::from_secs(1));
55 loop {
56 ticker.next().await;
57 let max = MAX.load(Ordering::Relaxed);
58 info!("latest block's max value: {:?}", max);
59 }
60}
61
62#[embassy_executor::task]
63async fn producer(mut sender: Sender<'static, NoopRawMutex, SampleBuffer>, mut adc: AdcParts) {
64 loop {
65 // Obtain a free buffer from the channel
66 let buf = sender.send().await;
67
68 // Fill it with data
69 adc.adc.read_many(&mut adc.pin, buf, 1, &mut adc.dma).await.unwrap();
70
71 // Notify the channel that the buffer is now ready to be received
72 sender.send_done();
73 }
74}
75
76#[embassy_executor::task]
77async fn consumer(mut receiver: Receiver<'static, NoopRawMutex, SampleBuffer>) {
78 loop {
79 // Receive a buffer from the channel
80 let buf = receiver.receive().await;
81
82 // Simulate using the data, while the producer is filling up the next buffer
83 Timer::after_micros(1000).await;
84 let max = buf.iter().max().unwrap();
85 MAX.store(*max, Ordering::Relaxed);
86
87 // Notify the channel that the buffer is now ready to be reused
88 receiver.receive_done();
89 }
90}