aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/rp/src/bin/blinky_two_tasks.rs61
1 files changed, 61 insertions, 0 deletions
diff --git a/examples/rp/src/bin/blinky_two_tasks.rs b/examples/rp/src/bin/blinky_two_tasks.rs
new file mode 100644
index 000000000..d6c23b546
--- /dev/null
+++ b/examples/rp/src/bin/blinky_two_tasks.rs
@@ -0,0 +1,61 @@
1#![no_std]
2#![no_main]
3/// This example demonstrates how to access a given pin from more than one embassy task
4/// The on-board LED is toggled by two tasks with slightly different periods, leading to the
5/// apparent duty cycle of the LED increasing, then decreasing, linearly. The phenomenon is similar
6/// to interference and the 'beats' you can hear if you play two frequencies close to one another
7/// [Link explaining it](https://www.physicsclassroom.com/class/sound/Lesson-3/Interference-and-Beats)
8use defmt::*;
9use embassy_executor::Spawner;
10use embassy_rp::{gpio, PeripheralRef};
11use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
12use embassy_sync::mutex::Mutex;
13use embassy_time::Duration;
14use embassy_time::{Ticker, Timer};
15use gpio::{AnyPin, Level, Output};
16use {defmt_rtt as _, panic_probe as _};
17
18type LedType = Mutex<ThreadModeRawMutex, Option<PeripheralRef<'static, Output<'static, AnyPin>>>>;
19static LED: LedType = Mutex::new(None);
20
21#[embassy_executor::main]
22async fn main(spawner: Spawner) {
23 let p = embassy_rp::init(Default::default());
24 // set the content of the global LED reference to the real LED pin
25 let led = Output::new(AnyPin::from(p.PIN_25), Level::High);
26 // inner scope is so that once the mutex is written to, the MutexGuard is dropped, thus the
27 // Mutex is released
28 {
29 *(LED.lock().await) = Some(PeripheralRef::new(led));
30 }
31 let dt = 100 * 1_000_000;
32 let k = 1.003;
33
34 unwrap!(spawner.spawn(toggle(&LED, Duration::from_nanos(dt))));
35 unwrap!(spawner.spawn(toggle_slightly_slower(
36 &LED,
37 Duration::from_nanos((dt as f64 * k) as u64)
38 )));
39}
40
41async fn toggle_led(led: &'static LedType, delay: Duration) {
42 let mut ticker = Ticker::every(delay);
43 loop {
44 {
45 let mut led_unlocked = led.lock().await;
46 if let Some(pin_ref) = led_unlocked.as_mut() {
47 pin_ref.toggle();
48 }
49 }
50 ticker.next().await;
51 }
52}
53#[embassy_executor::task]
54async fn toggle(led: &'static LedType, delay: Duration) {
55 toggle_led(led, delay).await
56}
57
58#[embassy_executor::task]
59async fn toggle_slightly_slower(led: &'static LedType, delay: Duration) {
60 toggle_led(led, delay).await
61}