aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/nrf/src/bin/channel.rs45
-rw-r--r--examples/nrf/src/bin/channel_sender_receiver.rs52
-rw-r--r--examples/nrf/src/bin/mpsc.rs60
-rw-r--r--examples/nrf/src/bin/uart_split.rs23
-rw-r--r--examples/stm32f3/src/bin/button_events.rs59
-rw-r--r--examples/stm32h7/src/bin/usart_split.rs26
6 files changed, 139 insertions, 126 deletions
diff --git a/examples/nrf/src/bin/channel.rs b/examples/nrf/src/bin/channel.rs
new file mode 100644
index 000000000..476ec09a1
--- /dev/null
+++ b/examples/nrf/src/bin/channel.rs
@@ -0,0 +1,45 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5use defmt::unwrap;
6use embassy::blocking_mutex::raw::ThreadModeRawMutex;
7use embassy::channel::channel::Channel;
8use embassy::executor::Spawner;
9use embassy::time::{Duration, Timer};
10use embassy_nrf::gpio::{Level, Output, OutputDrive};
11use embassy_nrf::Peripherals;
12
13use defmt_rtt as _; // global logger
14use panic_probe as _;
15
16enum LedState {
17 On,
18 Off,
19}
20
21static CHANNEL: Channel<ThreadModeRawMutex, LedState, 1> = Channel::new();
22
23#[embassy::task]
24async fn my_task() {
25 loop {
26 CHANNEL.send(LedState::On).await;
27 Timer::after(Duration::from_secs(1)).await;
28 CHANNEL.send(LedState::Off).await;
29 Timer::after(Duration::from_secs(1)).await;
30 }
31}
32
33#[embassy::main]
34async fn main(spawner: Spawner, p: Peripherals) {
35 let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard);
36
37 unwrap!(spawner.spawn(my_task()));
38
39 loop {
40 match CHANNEL.recv().await {
41 LedState::On => led.set_high(),
42 LedState::Off => led.set_low(),
43 }
44 }
45}
diff --git a/examples/nrf/src/bin/channel_sender_receiver.rs b/examples/nrf/src/bin/channel_sender_receiver.rs
new file mode 100644
index 000000000..c79f2fd6b
--- /dev/null
+++ b/examples/nrf/src/bin/channel_sender_receiver.rs
@@ -0,0 +1,52 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5use defmt::unwrap;
6use embassy::blocking_mutex::raw::NoopRawMutex;
7use embassy::channel::channel::{Channel, Receiver, Sender};
8use embassy::executor::Spawner;
9use embassy::time::{Duration, Timer};
10use embassy::util::Forever;
11use embassy_nrf::gpio::{AnyPin, Level, Output, OutputDrive, Pin};
12use embassy_nrf::Peripherals;
13
14use defmt_rtt as _; // global logger
15use panic_probe as _;
16
17enum LedState {
18 On,
19 Off,
20}
21
22static CHANNEL: Forever<Channel<NoopRawMutex, LedState, 1>> = Forever::new();
23
24#[embassy::task]
25async fn send_task(sender: Sender<'static, NoopRawMutex, LedState, 1>) {
26 loop {
27 sender.send(LedState::On).await;
28 Timer::after(Duration::from_secs(1)).await;
29 sender.send(LedState::Off).await;
30 Timer::after(Duration::from_secs(1)).await;
31 }
32}
33
34#[embassy::task]
35async fn recv_task(led: AnyPin, receiver: Receiver<'static, NoopRawMutex, LedState, 1>) {
36 let mut led = Output::new(led, Level::Low, OutputDrive::Standard);
37
38 loop {
39 match receiver.recv().await {
40 LedState::On => led.set_high(),
41 LedState::Off => led.set_low(),
42 }
43 }
44}
45
46#[embassy::main]
47async fn main(spawner: Spawner, p: Peripherals) {
48 let channel = CHANNEL.put(Channel::new());
49
50 unwrap!(spawner.spawn(send_task(channel.sender())));
51 unwrap!(spawner.spawn(recv_task(p.P0_13.degrade(), channel.receiver())));
52}
diff --git a/examples/nrf/src/bin/mpsc.rs b/examples/nrf/src/bin/mpsc.rs
deleted file mode 100644
index 0cb182755..000000000
--- a/examples/nrf/src/bin/mpsc.rs
+++ /dev/null
@@ -1,60 +0,0 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5use defmt::unwrap;
6use embassy::blocking_mutex::raw::NoopRawMutex;
7use embassy::channel::mpsc::{self, Channel, Sender, TryRecvError};
8use embassy::executor::Spawner;
9use embassy::time::{Duration, Timer};
10use embassy::util::Forever;
11use embassy_nrf::gpio::{Level, Output, OutputDrive};
12use embassy_nrf::Peripherals;
13
14use defmt_rtt as _; // global logger
15use panic_probe as _;
16
17enum LedState {
18 On,
19 Off,
20}
21
22static CHANNEL: Forever<Channel<NoopRawMutex, LedState, 1>> = Forever::new();
23
24#[embassy::task(pool_size = 1)]
25async fn my_task(sender: Sender<'static, NoopRawMutex, LedState, 1>) {
26 loop {
27 let _ = sender.send(LedState::On).await;
28 Timer::after(Duration::from_secs(1)).await;
29 let _ = sender.send(LedState::Off).await;
30 Timer::after(Duration::from_secs(1)).await;
31 }
32}
33
34#[embassy::main]
35async fn main(spawner: Spawner, p: Peripherals) {
36 let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard);
37
38 let channel = CHANNEL.put(Channel::new());
39 let (sender, mut receiver) = mpsc::split(channel);
40
41 unwrap!(spawner.spawn(my_task(sender)));
42
43 // We could just loop on `receiver.recv()` for simplicity. The code below
44 // is optimized to drain the queue as fast as possible in the spirit of
45 // handling events as fast as possible. This optimization is benign when in
46 // thread mode, but can be useful when interrupts are sending messages
47 // with the channel having been created via with_critical_sections.
48 loop {
49 let maybe_message = match receiver.try_recv() {
50 m @ Ok(..) => m.ok(),
51 Err(TryRecvError::Empty) => receiver.recv().await,
52 Err(TryRecvError::Closed) => break,
53 };
54 match maybe_message {
55 Some(LedState::On) => led.set_high(),
56 Some(LedState::Off) => led.set_low(),
57 _ => (),
58 }
59 }
60}
diff --git a/examples/nrf/src/bin/uart_split.rs b/examples/nrf/src/bin/uart_split.rs
index 909429b1a..3fde2f0d8 100644
--- a/examples/nrf/src/bin/uart_split.rs
+++ b/examples/nrf/src/bin/uart_split.rs
@@ -3,10 +3,9 @@
3#![feature(type_alias_impl_trait)] 3#![feature(type_alias_impl_trait)]
4 4
5use defmt::*; 5use defmt::*;
6use embassy::blocking_mutex::raw::NoopRawMutex; 6use embassy::blocking_mutex::raw::ThreadModeRawMutex;
7use embassy::channel::mpsc::{self, Channel, Sender}; 7use embassy::channel::channel::Channel;
8use embassy::executor::Spawner; 8use embassy::executor::Spawner;
9use embassy::util::Forever;
10use embassy_nrf::peripherals::UARTE0; 9use embassy_nrf::peripherals::UARTE0;
11use embassy_nrf::uarte::UarteRx; 10use embassy_nrf::uarte::UarteRx;
12use embassy_nrf::{interrupt, uarte, Peripherals}; 11use embassy_nrf::{interrupt, uarte, Peripherals};
@@ -14,7 +13,7 @@ use embassy_nrf::{interrupt, uarte, Peripherals};
14use defmt_rtt as _; // global logger 13use defmt_rtt as _; // global logger
15use panic_probe as _; 14use panic_probe as _;
16 15
17static CHANNEL: Forever<Channel<NoopRawMutex, [u8; 8], 1>> = Forever::new(); 16static CHANNEL: Channel<ThreadModeRawMutex, [u8; 8], 1> = Channel::new();
18 17
19#[embassy::main] 18#[embassy::main]
20async fn main(spawner: Spawner, p: Peripherals) { 19async fn main(spawner: Spawner, p: Peripherals) {
@@ -26,14 +25,11 @@ async fn main(spawner: Spawner, p: Peripherals) {
26 let uart = uarte::Uarte::new(p.UARTE0, irq, p.P0_08, p.P0_06, config); 25 let uart = uarte::Uarte::new(p.UARTE0, irq, p.P0_08, p.P0_06, config);
27 let (mut tx, rx) = uart.split(); 26 let (mut tx, rx) = uart.split();
28 27
29 let c = CHANNEL.put(Channel::new());
30 let (s, mut r) = mpsc::split(c);
31
32 info!("uarte initialized!"); 28 info!("uarte initialized!");
33 29
34 // Spawn a task responsible purely for reading 30 // Spawn a task responsible purely for reading
35 31
36 unwrap!(spawner.spawn(reader(rx, s))); 32 unwrap!(spawner.spawn(reader(rx)));
37 33
38 // Message must be in SRAM 34 // Message must be in SRAM
39 { 35 {
@@ -48,19 +44,18 @@ async fn main(spawner: Spawner, p: Peripherals) {
48 // back out the buffer we receive from the read 44 // back out the buffer we receive from the read
49 // task. 45 // task.
50 loop { 46 loop {
51 if let Some(buf) = r.recv().await { 47 let buf = CHANNEL.recv().await;
52 info!("writing..."); 48 info!("writing...");
53 unwrap!(tx.write(&buf).await); 49 unwrap!(tx.write(&buf).await);
54 }
55 } 50 }
56} 51}
57 52
58#[embassy::task] 53#[embassy::task]
59async fn reader(mut rx: UarteRx<'static, UARTE0>, s: Sender<'static, NoopRawMutex, [u8; 8], 1>) { 54async fn reader(mut rx: UarteRx<'static, UARTE0>) {
60 let mut buf = [0; 8]; 55 let mut buf = [0; 8];
61 loop { 56 loop {
62 info!("reading..."); 57 info!("reading...");
63 unwrap!(rx.read(&mut buf).await); 58 unwrap!(rx.read(&mut buf).await);
64 unwrap!(s.send(buf).await); 59 CHANNEL.send(buf).await;
65 } 60 }
66} 61}
diff --git a/examples/stm32f3/src/bin/button_events.rs b/examples/stm32f3/src/bin/button_events.rs
index 99aab3027..06e8eec1f 100644
--- a/examples/stm32f3/src/bin/button_events.rs
+++ b/examples/stm32f3/src/bin/button_events.rs
@@ -11,11 +11,10 @@
11#![feature(type_alias_impl_trait)] 11#![feature(type_alias_impl_trait)]
12 12
13use defmt::*; 13use defmt::*;
14use embassy::blocking_mutex::raw::NoopRawMutex; 14use embassy::blocking_mutex::raw::ThreadModeRawMutex;
15use embassy::channel::mpsc::{self, Channel, Receiver, Sender}; 15use embassy::channel::channel::Channel;
16use embassy::executor::Spawner; 16use embassy::executor::Spawner;
17use embassy::time::{with_timeout, Duration, Timer}; 17use embassy::time::{with_timeout, Duration, Timer};
18use embassy::util::Forever;
19use embassy_stm32::exti::ExtiInput; 18use embassy_stm32::exti::ExtiInput;
20use embassy_stm32::gpio::{AnyPin, Input, Level, Output, Pin, Pull, Speed}; 19use embassy_stm32::gpio::{AnyPin, Input, Level, Output, Pin, Pull, Speed};
21use embassy_stm32::peripherals::PA0; 20use embassy_stm32::peripherals::PA0;
@@ -51,14 +50,15 @@ impl<'a> Leds<'a> {
51 } 50 }
52 } 51 }
53 52
54 async fn show(&mut self, queue: &mut Receiver<'static, NoopRawMutex, ButtonEvent, 4>) { 53 async fn show(&mut self) {
55 self.leds[self.current_led].set_high(); 54 self.leds[self.current_led].set_high();
56 if let Ok(new_message) = with_timeout(Duration::from_millis(500), queue.recv()).await { 55 if let Ok(new_message) = with_timeout(Duration::from_millis(500), CHANNEL.recv()).await {
57 self.leds[self.current_led].set_low(); 56 self.leds[self.current_led].set_low();
58 self.process_event(new_message).await; 57 self.process_event(new_message).await;
59 } else { 58 } else {
60 self.leds[self.current_led].set_low(); 59 self.leds[self.current_led].set_low();
61 if let Ok(new_message) = with_timeout(Duration::from_millis(200), queue.recv()).await { 60 if let Ok(new_message) = with_timeout(Duration::from_millis(200), CHANNEL.recv()).await
61 {
62 self.process_event(new_message).await; 62 self.process_event(new_message).await;
63 } 63 }
64 } 64 }
@@ -77,15 +77,18 @@ impl<'a> Leds<'a> {
77 } 77 }
78 } 78 }
79 79
80 async fn process_event(&mut self, event: Option<ButtonEvent>) { 80 async fn process_event(&mut self, event: ButtonEvent) {
81 match event { 81 match event {
82 Some(ButtonEvent::SingleClick) => self.move_next(), 82 ButtonEvent::SingleClick => {
83 Some(ButtonEvent::DoubleClick) => { 83 self.move_next();
84 }
85 ButtonEvent::DoubleClick => {
84 self.change_direction(); 86 self.change_direction();
85 self.move_next() 87 self.move_next();
88 }
89 ButtonEvent::Hold => {
90 self.flash().await;
86 } 91 }
87 Some(ButtonEvent::Hold) => self.flash().await,
88 _ => {}
89 } 92 }
90 } 93 }
91} 94}
@@ -97,7 +100,7 @@ enum ButtonEvent {
97 Hold, 100 Hold,
98} 101}
99 102
100static BUTTON_EVENTS_QUEUE: Forever<Channel<NoopRawMutex, ButtonEvent, 4>> = Forever::new(); 103static CHANNEL: Channel<ThreadModeRawMutex, ButtonEvent, 4> = Channel::new();
101 104
102#[embassy::main] 105#[embassy::main]
103async fn main(spawner: Spawner, p: Peripherals) { 106async fn main(spawner: Spawner, p: Peripherals) {
@@ -116,27 +119,19 @@ async fn main(spawner: Spawner, p: Peripherals) {
116 ]; 119 ];
117 let leds = Leds::new(leds); 120 let leds = Leds::new(leds);
118 121
119 let buttons_queue = BUTTON_EVENTS_QUEUE.put(Channel::new()); 122 spawner.spawn(button_waiter(button)).unwrap();
120 let (sender, receiver) = mpsc::split(buttons_queue); 123 spawner.spawn(led_blinker(leds)).unwrap();
121 spawner.spawn(button_waiter(button, sender)).unwrap();
122 spawner.spawn(led_blinker(leds, receiver)).unwrap();
123} 124}
124 125
125#[embassy::task] 126#[embassy::task]
126async fn led_blinker( 127async fn led_blinker(mut leds: Leds<'static>) {
127 mut leds: Leds<'static>,
128 mut queue: Receiver<'static, NoopRawMutex, ButtonEvent, 4>,
129) {
130 loop { 128 loop {
131 leds.show(&mut queue).await; 129 leds.show().await;
132 } 130 }
133} 131}
134 132
135#[embassy::task] 133#[embassy::task]
136async fn button_waiter( 134async fn button_waiter(mut button: ExtiInput<'static, PA0>) {
137 mut button: ExtiInput<'static, PA0>,
138 queue: Sender<'static, NoopRawMutex, ButtonEvent, 4>,
139) {
140 const DOUBLE_CLICK_DELAY: u64 = 250; 135 const DOUBLE_CLICK_DELAY: u64 = 250;
141 const HOLD_DELAY: u64 = 1000; 136 const HOLD_DELAY: u64 = 1000;
142 137
@@ -150,9 +145,7 @@ async fn button_waiter(
150 .is_err() 145 .is_err()
151 { 146 {
152 info!("Hold"); 147 info!("Hold");
153 if queue.send(ButtonEvent::Hold).await.is_err() { 148 CHANNEL.send(ButtonEvent::Hold).await;
154 break;
155 }
156 button.wait_for_falling_edge().await; 149 button.wait_for_falling_edge().await;
157 } else if with_timeout( 150 } else if with_timeout(
158 Duration::from_millis(DOUBLE_CLICK_DELAY), 151 Duration::from_millis(DOUBLE_CLICK_DELAY),
@@ -161,15 +154,11 @@ async fn button_waiter(
161 .await 154 .await
162 .is_err() 155 .is_err()
163 { 156 {
164 if queue.send(ButtonEvent::SingleClick).await.is_err() {
165 break;
166 }
167 info!("Single click"); 157 info!("Single click");
158 CHANNEL.send(ButtonEvent::SingleClick).await;
168 } else { 159 } else {
169 info!("Double click"); 160 info!("Double click");
170 if queue.send(ButtonEvent::DoubleClick).await.is_err() { 161 CHANNEL.send(ButtonEvent::DoubleClick).await;
171 break;
172 }
173 button.wait_for_falling_edge().await; 162 button.wait_for_falling_edge().await;
174 } 163 }
175 button.wait_for_rising_edge().await; 164 button.wait_for_rising_edge().await;
diff --git a/examples/stm32h7/src/bin/usart_split.rs b/examples/stm32h7/src/bin/usart_split.rs
index ee1763aa4..40a7c3e44 100644
--- a/examples/stm32h7/src/bin/usart_split.rs
+++ b/examples/stm32h7/src/bin/usart_split.rs
@@ -4,10 +4,9 @@
4 4
5use defmt::*; 5use defmt::*;
6use defmt_rtt as _; // global logger 6use defmt_rtt as _; // global logger
7use embassy::blocking_mutex::raw::NoopRawMutex; 7use embassy::blocking_mutex::raw::ThreadModeRawMutex;
8use embassy::channel::mpsc::{self, Channel, Sender}; 8use embassy::channel::channel::Channel;
9use embassy::executor::Spawner; 9use embassy::executor::Spawner;
10use embassy::util::Forever;
11use embassy_stm32::dma::NoDma; 10use embassy_stm32::dma::NoDma;
12use embassy_stm32::{ 11use embassy_stm32::{
13 peripherals::{DMA1_CH1, UART7}, 12 peripherals::{DMA1_CH1, UART7},
@@ -28,7 +27,7 @@ async fn writer(mut usart: Uart<'static, UART7, NoDma, NoDma>) {
28 } 27 }
29} 28}
30 29
31static CHANNEL: Forever<Channel<NoopRawMutex, [u8; 8], 1>> = Forever::new(); 30static CHANNEL: Channel<ThreadModeRawMutex, [u8; 8], 1> = Channel::new();
32 31
33#[embassy::main] 32#[embassy::main]
34async fn main(spawner: Spawner, p: Peripherals) -> ! { 33async fn main(spawner: Spawner, p: Peripherals) -> ! {
@@ -40,28 +39,21 @@ async fn main(spawner: Spawner, p: Peripherals) -> ! {
40 39
41 let (mut tx, rx) = usart.split(); 40 let (mut tx, rx) = usart.split();
42 41
43 let c = CHANNEL.put(Channel::new()); 42 unwrap!(spawner.spawn(reader(rx)));
44 let (s, mut r) = mpsc::split(c);
45
46 unwrap!(spawner.spawn(reader(rx, s)));
47 43
48 loop { 44 loop {
49 if let Some(buf) = r.recv().await { 45 let buf = CHANNEL.recv().await;
50 info!("writing..."); 46 info!("writing...");
51 unwrap!(tx.write(&buf).await); 47 unwrap!(tx.write(&buf).await);
52 }
53 } 48 }
54} 49}
55 50
56#[embassy::task] 51#[embassy::task]
57async fn reader( 52async fn reader(mut rx: UartRx<'static, UART7, DMA1_CH1>) {
58 mut rx: UartRx<'static, UART7, DMA1_CH1>,
59 s: Sender<'static, NoopRawMutex, [u8; 8], 1>,
60) {
61 let mut buf = [0; 8]; 53 let mut buf = [0; 8];
62 loop { 54 loop {
63 info!("reading..."); 55 info!("reading...");
64 unwrap!(rx.read(&mut buf).await); 56 unwrap!(rx.read(&mut buf).await);
65 unwrap!(s.send(buf).await); 57 CHANNEL.send(buf).await;
66 } 58 }
67} 59}