diff options
| author | Frostie314159 <[email protected]> | 2024-03-21 14:17:03 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-03-21 14:17:03 +0100 |
| commit | 7efe8e0005ca75c3753081848e8b176f8ac3a9ba (patch) | |
| tree | 3690b3b873b4643a07e29b60bf92596a819d30f0 /examples/rp/src/bin | |
| parent | 8707462ec23807782796fbac4295bc5bce9ff136 (diff) | |
| parent | 29d388042cdbd76d46f66ebe58cc580edb4515f8 (diff) | |
Merge branch 'embassy-rs:main' into reset-at-after
Diffstat (limited to 'examples/rp/src/bin')
50 files changed, 723 insertions, 136 deletions
diff --git a/examples/rp/src/bin/adc.rs b/examples/rp/src/bin/adc.rs index a579be139..1bb7c2249 100644 --- a/examples/rp/src/bin/adc.rs +++ b/examples/rp/src/bin/adc.rs | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | #![no_std] | 4 | #![no_std] |
| 5 | #![no_main] | 5 | #![no_main] |
| 6 | #![feature(type_alias_impl_trait)] | ||
| 7 | 6 | ||
| 8 | use defmt::*; | 7 | use defmt::*; |
| 9 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
diff --git a/examples/rp/src/bin/blinky.rs b/examples/rp/src/bin/blinky.rs index 66c8773fa..60fc45a70 100644 --- a/examples/rp/src/bin/blinky.rs +++ b/examples/rp/src/bin/blinky.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #![no_std] | 5 | #![no_std] |
| 6 | #![no_main] | 6 | #![no_main] |
| 7 | #![feature(type_alias_impl_trait)] | ||
| 8 | 7 | ||
| 9 | use defmt::*; | 8 | use defmt::*; |
| 10 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
diff --git a/examples/rp/src/bin/blinky_two_channels.rs b/examples/rp/src/bin/blinky_two_channels.rs new file mode 100644 index 000000000..b2eec2a21 --- /dev/null +++ b/examples/rp/src/bin/blinky_two_channels.rs | |||
| @@ -0,0 +1,50 @@ | |||
| 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) | ||
| 8 | use defmt::*; | ||
| 9 | use embassy_executor::Spawner; | ||
| 10 | use embassy_rp::gpio; | ||
| 11 | use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; | ||
| 12 | use embassy_sync::channel::{Channel, Sender}; | ||
| 13 | use embassy_time::{Duration, Ticker}; | ||
| 14 | use gpio::{AnyPin, Level, Output}; | ||
| 15 | use {defmt_rtt as _, panic_probe as _}; | ||
| 16 | |||
| 17 | enum LedState { | ||
| 18 | Toggle, | ||
| 19 | } | ||
| 20 | static CHANNEL: Channel<ThreadModeRawMutex, LedState, 64> = Channel::new(); | ||
| 21 | |||
| 22 | #[embassy_executor::main] | ||
| 23 | async fn main(spawner: Spawner) { | ||
| 24 | let p = embassy_rp::init(Default::default()); | ||
| 25 | let mut led = Output::new(AnyPin::from(p.PIN_25), Level::High); | ||
| 26 | |||
| 27 | let dt = 100 * 1_000_000; | ||
| 28 | let k = 1.003; | ||
| 29 | |||
| 30 | unwrap!(spawner.spawn(toggle_led(CHANNEL.sender(), Duration::from_nanos(dt)))); | ||
| 31 | unwrap!(spawner.spawn(toggle_led( | ||
| 32 | CHANNEL.sender(), | ||
| 33 | Duration::from_nanos((dt as f64 * k) as u64) | ||
| 34 | ))); | ||
| 35 | |||
| 36 | loop { | ||
| 37 | match CHANNEL.receive().await { | ||
| 38 | LedState::Toggle => led.toggle(), | ||
| 39 | } | ||
| 40 | } | ||
| 41 | } | ||
| 42 | |||
| 43 | #[embassy_executor::task(pool_size = 2)] | ||
| 44 | async fn toggle_led(control: Sender<'static, ThreadModeRawMutex, LedState, 64>, delay: Duration) { | ||
| 45 | let mut ticker = Ticker::every(delay); | ||
| 46 | loop { | ||
| 47 | control.send(LedState::Toggle).await; | ||
| 48 | ticker.next().await; | ||
| 49 | } | ||
| 50 | } | ||
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..a57b513d6 --- /dev/null +++ b/examples/rp/src/bin/blinky_two_tasks.rs | |||
| @@ -0,0 +1,49 @@ | |||
| 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) | ||
| 8 | use defmt::*; | ||
| 9 | use embassy_executor::Spawner; | ||
| 10 | use embassy_rp::gpio; | ||
| 11 | use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; | ||
| 12 | use embassy_sync::mutex::Mutex; | ||
| 13 | use embassy_time::{Duration, Ticker}; | ||
| 14 | use gpio::{AnyPin, Level, Output}; | ||
| 15 | use {defmt_rtt as _, panic_probe as _}; | ||
| 16 | |||
| 17 | type LedType = Mutex<ThreadModeRawMutex, Option<Output<'static>>>; | ||
| 18 | static LED: LedType = Mutex::new(None); | ||
| 19 | |||
| 20 | #[embassy_executor::main] | ||
| 21 | async fn main(spawner: Spawner) { | ||
| 22 | let p = embassy_rp::init(Default::default()); | ||
| 23 | // set the content of the global LED reference to the real LED pin | ||
| 24 | let led = Output::new(AnyPin::from(p.PIN_25), Level::High); | ||
| 25 | // inner scope is so that once the mutex is written to, the MutexGuard is dropped, thus the | ||
| 26 | // Mutex is released | ||
| 27 | { | ||
| 28 | *(LED.lock().await) = Some(led); | ||
| 29 | } | ||
| 30 | let dt = 100 * 1_000_000; | ||
| 31 | let k = 1.003; | ||
| 32 | |||
| 33 | unwrap!(spawner.spawn(toggle_led(&LED, Duration::from_nanos(dt)))); | ||
| 34 | unwrap!(spawner.spawn(toggle_led(&LED, Duration::from_nanos((dt as f64 * k) as u64)))); | ||
| 35 | } | ||
| 36 | |||
| 37 | #[embassy_executor::task(pool_size = 2)] | ||
| 38 | async fn toggle_led(led: &'static LedType, delay: Duration) { | ||
| 39 | let mut ticker = Ticker::every(delay); | ||
| 40 | loop { | ||
| 41 | { | ||
| 42 | let mut led_unlocked = led.lock().await; | ||
| 43 | if let Some(pin_ref) = led_unlocked.as_mut() { | ||
| 44 | pin_ref.toggle(); | ||
| 45 | } | ||
| 46 | } | ||
| 47 | ticker.next().await; | ||
| 48 | } | ||
| 49 | } | ||
diff --git a/examples/rp/src/bin/button.rs b/examples/rp/src/bin/button.rs index d7aa89410..4ad2ca3b7 100644 --- a/examples/rp/src/bin/button.rs +++ b/examples/rp/src/bin/button.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #![no_std] | 5 | #![no_std] |
| 6 | #![no_main] | 6 | #![no_main] |
| 7 | #![feature(type_alias_impl_trait)] | ||
| 8 | 7 | ||
| 9 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 10 | use embassy_rp::gpio::{Input, Level, Output, Pull}; | 9 | use embassy_rp::gpio::{Input, Level, Output, Pull}; |
diff --git a/examples/rp/src/bin/debounce.rs b/examples/rp/src/bin/debounce.rs new file mode 100644 index 000000000..0077f19fc --- /dev/null +++ b/examples/rp/src/bin/debounce.rs | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | //! This example shows the ease of debouncing a button with async rust. | ||
| 2 | //! Hook up a button or switch between pin 9 and ground. | ||
| 3 | |||
| 4 | #![no_std] | ||
| 5 | #![no_main] | ||
| 6 | |||
| 7 | use defmt::info; | ||
| 8 | use embassy_executor::Spawner; | ||
| 9 | use embassy_rp::gpio::{Input, Level, Pull}; | ||
| 10 | use embassy_time::{with_deadline, Duration, Instant, Timer}; | ||
| 11 | use {defmt_rtt as _, panic_probe as _}; | ||
| 12 | |||
| 13 | pub struct Debouncer<'a> { | ||
| 14 | input: Input<'a>, | ||
| 15 | debounce: Duration, | ||
| 16 | } | ||
| 17 | |||
| 18 | impl<'a> Debouncer<'a> { | ||
| 19 | pub fn new(input: Input<'a>, debounce: Duration) -> Self { | ||
| 20 | Self { input, debounce } | ||
| 21 | } | ||
| 22 | |||
| 23 | pub async fn debounce(&mut self) -> Level { | ||
| 24 | loop { | ||
| 25 | let l1 = self.input.get_level(); | ||
| 26 | |||
| 27 | self.input.wait_for_any_edge().await; | ||
| 28 | |||
| 29 | Timer::after(self.debounce).await; | ||
| 30 | |||
| 31 | let l2 = self.input.get_level(); | ||
| 32 | if l1 != l2 { | ||
| 33 | break l2; | ||
| 34 | } | ||
| 35 | } | ||
| 36 | } | ||
| 37 | } | ||
| 38 | |||
| 39 | #[embassy_executor::main] | ||
| 40 | async fn main(_spawner: Spawner) { | ||
| 41 | let p = embassy_rp::init(Default::default()); | ||
| 42 | let mut btn = Debouncer::new(Input::new(p.PIN_9, Pull::Up), Duration::from_millis(20)); | ||
| 43 | |||
| 44 | info!("Debounce Demo"); | ||
| 45 | |||
| 46 | loop { | ||
| 47 | // button pressed | ||
| 48 | btn.debounce().await; | ||
| 49 | let start = Instant::now(); | ||
| 50 | info!("Button Press"); | ||
| 51 | |||
| 52 | match with_deadline(start + Duration::from_secs(1), btn.debounce()).await { | ||
| 53 | // Button Released < 1s | ||
| 54 | Ok(_) => { | ||
| 55 | info!("Button pressed for: {}ms", start.elapsed().as_millis()); | ||
| 56 | continue; | ||
| 57 | } | ||
| 58 | // button held for > 1s | ||
| 59 | Err(_) => { | ||
| 60 | info!("Button Held"); | ||
| 61 | } | ||
| 62 | } | ||
| 63 | |||
| 64 | match with_deadline(start + Duration::from_secs(5), btn.debounce()).await { | ||
| 65 | // Button released <5s | ||
| 66 | Ok(_) => { | ||
| 67 | info!("Button pressed for: {}ms", start.elapsed().as_millis()); | ||
| 68 | continue; | ||
| 69 | } | ||
| 70 | // button held for > >5s | ||
| 71 | Err(_) => { | ||
| 72 | info!("Button Long Held"); | ||
| 73 | } | ||
| 74 | } | ||
| 75 | |||
| 76 | // wait for button release before handling another press | ||
| 77 | btn.debounce().await; | ||
| 78 | info!("Button pressed for: {}ms", start.elapsed().as_millis()); | ||
| 79 | } | ||
| 80 | } | ||
diff --git a/examples/rp/src/bin/ethernet_w5500_multisocket.rs b/examples/rp/src/bin/ethernet_w5500_multisocket.rs index c0fde62ab..bd52cadca 100644 --- a/examples/rp/src/bin/ethernet_w5500_multisocket.rs +++ b/examples/rp/src/bin/ethernet_w5500_multisocket.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #![no_std] | 5 | #![no_std] |
| 6 | #![no_main] | 6 | #![no_main] |
| 7 | #![feature(type_alias_impl_trait)] | ||
| 8 | 7 | ||
| 9 | use defmt::*; | 8 | use defmt::*; |
| 10 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| @@ -14,13 +13,13 @@ use embassy_net_wiznet::chip::W5500; | |||
| 14 | use embassy_net_wiznet::*; | 13 | use embassy_net_wiznet::*; |
| 15 | use embassy_rp::clocks::RoscRng; | 14 | use embassy_rp::clocks::RoscRng; |
| 16 | use embassy_rp::gpio::{Input, Level, Output, Pull}; | 15 | use embassy_rp::gpio::{Input, Level, Output, Pull}; |
| 17 | use embassy_rp::peripherals::{PIN_17, PIN_20, PIN_21, SPI0}; | 16 | use embassy_rp::peripherals::SPI0; |
| 18 | use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; | 17 | use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; |
| 19 | use embassy_time::{Delay, Duration}; | 18 | use embassy_time::{Delay, Duration}; |
| 20 | use embedded_hal_bus::spi::ExclusiveDevice; | 19 | use embedded_hal_bus::spi::ExclusiveDevice; |
| 21 | use embedded_io_async::Write; | 20 | use embedded_io_async::Write; |
| 22 | use rand::RngCore; | 21 | use rand::RngCore; |
| 23 | use static_cell::make_static; | 22 | use static_cell::StaticCell; |
| 24 | use {defmt_rtt as _, panic_probe as _}; | 23 | use {defmt_rtt as _, panic_probe as _}; |
| 25 | 24 | ||
| 26 | #[embassy_executor::task] | 25 | #[embassy_executor::task] |
| @@ -28,9 +27,9 @@ async fn ethernet_task( | |||
| 28 | runner: Runner< | 27 | runner: Runner< |
| 29 | 'static, | 28 | 'static, |
| 30 | W5500, | 29 | W5500, |
| 31 | ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static, PIN_17>, Delay>, | 30 | ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static>, Delay>, |
| 32 | Input<'static, PIN_21>, | 31 | Input<'static>, |
| 33 | Output<'static, PIN_20>, | 32 | Output<'static>, |
| 34 | >, | 33 | >, |
| 35 | ) -> ! { | 34 | ) -> ! { |
| 36 | runner.run().await | 35 | runner.run().await |
| @@ -55,7 +54,8 @@ async fn main(spawner: Spawner) { | |||
| 55 | let w5500_reset = Output::new(p.PIN_20, Level::High); | 54 | let w5500_reset = Output::new(p.PIN_20, Level::High); |
| 56 | 55 | ||
| 57 | let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; | 56 | let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; |
| 58 | let state = make_static!(State::<8, 8>::new()); | 57 | static STATE: StaticCell<State<8, 8>> = StaticCell::new(); |
| 58 | let state = STATE.init(State::<8, 8>::new()); | ||
| 59 | let (device, runner) = embassy_net_wiznet::new( | 59 | let (device, runner) = embassy_net_wiznet::new( |
| 60 | mac_addr, | 60 | mac_addr, |
| 61 | state, | 61 | state, |
| @@ -70,11 +70,13 @@ async fn main(spawner: Spawner) { | |||
| 70 | let seed = rng.next_u64(); | 70 | let seed = rng.next_u64(); |
| 71 | 71 | ||
| 72 | // Init network stack | 72 | // Init network stack |
| 73 | let stack = &*make_static!(Stack::new( | 73 | static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new(); |
| 74 | static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new(); | ||
| 75 | let stack = &*STACK.init(Stack::new( | ||
| 74 | device, | 76 | device, |
| 75 | embassy_net::Config::dhcpv4(Default::default()), | 77 | embassy_net::Config::dhcpv4(Default::default()), |
| 76 | make_static!(StackResources::<3>::new()), | 78 | RESOURCES.init(StackResources::<3>::new()), |
| 77 | seed | 79 | seed, |
| 78 | )); | 80 | )); |
| 79 | 81 | ||
| 80 | // Launch network task | 82 | // Launch network task |
diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs index b19362fc1..3e4fbd2e6 100644 --- a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs +++ b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #![no_std] | 5 | #![no_std] |
| 6 | #![no_main] | 6 | #![no_main] |
| 7 | #![feature(type_alias_impl_trait)] | ||
| 8 | 7 | ||
| 9 | use core::str::FromStr; | 8 | use core::str::FromStr; |
| 10 | 9 | ||
| @@ -16,13 +15,13 @@ use embassy_net_wiznet::chip::W5500; | |||
| 16 | use embassy_net_wiznet::*; | 15 | use embassy_net_wiznet::*; |
| 17 | use embassy_rp::clocks::RoscRng; | 16 | use embassy_rp::clocks::RoscRng; |
| 18 | use embassy_rp::gpio::{Input, Level, Output, Pull}; | 17 | use embassy_rp::gpio::{Input, Level, Output, Pull}; |
| 19 | use embassy_rp::peripherals::{PIN_17, PIN_20, PIN_21, SPI0}; | 18 | use embassy_rp::peripherals::SPI0; |
| 20 | use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; | 19 | use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; |
| 21 | use embassy_time::{Delay, Duration, Timer}; | 20 | use embassy_time::{Delay, Duration, Timer}; |
| 22 | use embedded_hal_bus::spi::ExclusiveDevice; | 21 | use embedded_hal_bus::spi::ExclusiveDevice; |
| 23 | use embedded_io_async::Write; | 22 | use embedded_io_async::Write; |
| 24 | use rand::RngCore; | 23 | use rand::RngCore; |
| 25 | use static_cell::make_static; | 24 | use static_cell::StaticCell; |
| 26 | use {defmt_rtt as _, panic_probe as _}; | 25 | use {defmt_rtt as _, panic_probe as _}; |
| 27 | 26 | ||
| 28 | #[embassy_executor::task] | 27 | #[embassy_executor::task] |
| @@ -30,9 +29,9 @@ async fn ethernet_task( | |||
| 30 | runner: Runner< | 29 | runner: Runner< |
| 31 | 'static, | 30 | 'static, |
| 32 | W5500, | 31 | W5500, |
| 33 | ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static, PIN_17>, Delay>, | 32 | ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static>, Delay>, |
| 34 | Input<'static, PIN_21>, | 33 | Input<'static>, |
| 35 | Output<'static, PIN_20>, | 34 | Output<'static>, |
| 36 | >, | 35 | >, |
| 37 | ) -> ! { | 36 | ) -> ! { |
| 38 | runner.run().await | 37 | runner.run().await |
| @@ -58,7 +57,8 @@ async fn main(spawner: Spawner) { | |||
| 58 | let w5500_reset = Output::new(p.PIN_20, Level::High); | 57 | let w5500_reset = Output::new(p.PIN_20, Level::High); |
| 59 | 58 | ||
| 60 | let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; | 59 | let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; |
| 61 | let state = make_static!(State::<8, 8>::new()); | 60 | static STATE: StaticCell<State<8, 8>> = StaticCell::new(); |
| 61 | let state = STATE.init(State::<8, 8>::new()); | ||
| 62 | let (device, runner) = embassy_net_wiznet::new( | 62 | let (device, runner) = embassy_net_wiznet::new( |
| 63 | mac_addr, | 63 | mac_addr, |
| 64 | state, | 64 | state, |
| @@ -73,11 +73,13 @@ async fn main(spawner: Spawner) { | |||
| 73 | let seed = rng.next_u64(); | 73 | let seed = rng.next_u64(); |
| 74 | 74 | ||
| 75 | // Init network stack | 75 | // Init network stack |
| 76 | let stack = &*make_static!(Stack::new( | 76 | static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new(); |
| 77 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||
| 78 | let stack = &*STACK.init(Stack::new( | ||
| 77 | device, | 79 | device, |
| 78 | embassy_net::Config::dhcpv4(Default::default()), | 80 | embassy_net::Config::dhcpv4(Default::default()), |
| 79 | make_static!(StackResources::<2>::new()), | 81 | RESOURCES.init(StackResources::<2>::new()), |
| 80 | seed | 82 | seed, |
| 81 | )); | 83 | )); |
| 82 | 84 | ||
| 83 | // Launch network task | 85 | // Launch network task |
diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_server.rs b/examples/rp/src/bin/ethernet_w5500_tcp_server.rs index c62caed7a..5532851f3 100644 --- a/examples/rp/src/bin/ethernet_w5500_tcp_server.rs +++ b/examples/rp/src/bin/ethernet_w5500_tcp_server.rs | |||
| @@ -5,7 +5,6 @@ | |||
| 5 | 5 | ||
| 6 | #![no_std] | 6 | #![no_std] |
| 7 | #![no_main] | 7 | #![no_main] |
| 8 | #![feature(type_alias_impl_trait)] | ||
| 9 | 8 | ||
| 10 | use defmt::*; | 9 | use defmt::*; |
| 11 | use embassy_executor::Spawner; | 10 | use embassy_executor::Spawner; |
| @@ -15,13 +14,13 @@ use embassy_net_wiznet::chip::W5500; | |||
| 15 | use embassy_net_wiznet::*; | 14 | use embassy_net_wiznet::*; |
| 16 | use embassy_rp::clocks::RoscRng; | 15 | use embassy_rp::clocks::RoscRng; |
| 17 | use embassy_rp::gpio::{Input, Level, Output, Pull}; | 16 | use embassy_rp::gpio::{Input, Level, Output, Pull}; |
| 18 | use embassy_rp::peripherals::{PIN_17, PIN_20, PIN_21, SPI0}; | 17 | use embassy_rp::peripherals::SPI0; |
| 19 | use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; | 18 | use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; |
| 20 | use embassy_time::{Delay, Duration}; | 19 | use embassy_time::{Delay, Duration}; |
| 21 | use embedded_hal_bus::spi::ExclusiveDevice; | 20 | use embedded_hal_bus::spi::ExclusiveDevice; |
| 22 | use embedded_io_async::Write; | 21 | use embedded_io_async::Write; |
| 23 | use rand::RngCore; | 22 | use rand::RngCore; |
| 24 | use static_cell::make_static; | 23 | use static_cell::StaticCell; |
| 25 | use {defmt_rtt as _, panic_probe as _}; | 24 | use {defmt_rtt as _, panic_probe as _}; |
| 26 | 25 | ||
| 27 | #[embassy_executor::task] | 26 | #[embassy_executor::task] |
| @@ -29,9 +28,9 @@ async fn ethernet_task( | |||
| 29 | runner: Runner< | 28 | runner: Runner< |
| 30 | 'static, | 29 | 'static, |
| 31 | W5500, | 30 | W5500, |
| 32 | ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static, PIN_17>, Delay>, | 31 | ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static>, Delay>, |
| 33 | Input<'static, PIN_21>, | 32 | Input<'static>, |
| 34 | Output<'static, PIN_20>, | 33 | Output<'static>, |
| 35 | >, | 34 | >, |
| 36 | ) -> ! { | 35 | ) -> ! { |
| 37 | runner.run().await | 36 | runner.run().await |
| @@ -57,7 +56,8 @@ async fn main(spawner: Spawner) { | |||
| 57 | let w5500_reset = Output::new(p.PIN_20, Level::High); | 56 | let w5500_reset = Output::new(p.PIN_20, Level::High); |
| 58 | 57 | ||
| 59 | let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; | 58 | let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; |
| 60 | let state = make_static!(State::<8, 8>::new()); | 59 | static STATE: StaticCell<State<8, 8>> = StaticCell::new(); |
| 60 | let state = STATE.init(State::<8, 8>::new()); | ||
| 61 | let (device, runner) = embassy_net_wiznet::new( | 61 | let (device, runner) = embassy_net_wiznet::new( |
| 62 | mac_addr, | 62 | mac_addr, |
| 63 | state, | 63 | state, |
| @@ -72,11 +72,13 @@ async fn main(spawner: Spawner) { | |||
| 72 | let seed = rng.next_u64(); | 72 | let seed = rng.next_u64(); |
| 73 | 73 | ||
| 74 | // Init network stack | 74 | // Init network stack |
| 75 | let stack = &*make_static!(Stack::new( | 75 | static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new(); |
| 76 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||
| 77 | let stack = &*STACK.init(Stack::new( | ||
| 76 | device, | 78 | device, |
| 77 | embassy_net::Config::dhcpv4(Default::default()), | 79 | embassy_net::Config::dhcpv4(Default::default()), |
| 78 | make_static!(StackResources::<2>::new()), | 80 | RESOURCES.init(StackResources::<2>::new()), |
| 79 | seed | 81 | seed, |
| 80 | )); | 82 | )); |
| 81 | 83 | ||
| 82 | // Launch network task | 84 | // Launch network task |
diff --git a/examples/rp/src/bin/ethernet_w5500_udp.rs b/examples/rp/src/bin/ethernet_w5500_udp.rs index 76dabce1c..adb1d8941 100644 --- a/examples/rp/src/bin/ethernet_w5500_udp.rs +++ b/examples/rp/src/bin/ethernet_w5500_udp.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #![no_std] | 5 | #![no_std] |
| 6 | #![no_main] | 6 | #![no_main] |
| 7 | #![feature(type_alias_impl_trait)] | ||
| 8 | 7 | ||
| 9 | use defmt::*; | 8 | use defmt::*; |
| 10 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| @@ -15,12 +14,12 @@ use embassy_net_wiznet::chip::W5500; | |||
| 15 | use embassy_net_wiznet::*; | 14 | use embassy_net_wiznet::*; |
| 16 | use embassy_rp::clocks::RoscRng; | 15 | use embassy_rp::clocks::RoscRng; |
| 17 | use embassy_rp::gpio::{Input, Level, Output, Pull}; | 16 | use embassy_rp::gpio::{Input, Level, Output, Pull}; |
| 18 | use embassy_rp::peripherals::{PIN_17, PIN_20, PIN_21, SPI0}; | 17 | use embassy_rp::peripherals::SPI0; |
| 19 | use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; | 18 | use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; |
| 20 | use embassy_time::Delay; | 19 | use embassy_time::Delay; |
| 21 | use embedded_hal_bus::spi::ExclusiveDevice; | 20 | use embedded_hal_bus::spi::ExclusiveDevice; |
| 22 | use rand::RngCore; | 21 | use rand::RngCore; |
| 23 | use static_cell::make_static; | 22 | use static_cell::StaticCell; |
| 24 | use {defmt_rtt as _, panic_probe as _}; | 23 | use {defmt_rtt as _, panic_probe as _}; |
| 25 | 24 | ||
| 26 | #[embassy_executor::task] | 25 | #[embassy_executor::task] |
| @@ -28,9 +27,9 @@ async fn ethernet_task( | |||
| 28 | runner: Runner< | 27 | runner: Runner< |
| 29 | 'static, | 28 | 'static, |
| 30 | W5500, | 29 | W5500, |
| 31 | ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static, PIN_17>, Delay>, | 30 | ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static>, Delay>, |
| 32 | Input<'static, PIN_21>, | 31 | Input<'static>, |
| 33 | Output<'static, PIN_20>, | 32 | Output<'static>, |
| 34 | >, | 33 | >, |
| 35 | ) -> ! { | 34 | ) -> ! { |
| 36 | runner.run().await | 35 | runner.run().await |
| @@ -55,7 +54,8 @@ async fn main(spawner: Spawner) { | |||
| 55 | let w5500_reset = Output::new(p.PIN_20, Level::High); | 54 | let w5500_reset = Output::new(p.PIN_20, Level::High); |
| 56 | 55 | ||
| 57 | let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; | 56 | let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; |
| 58 | let state = make_static!(State::<8, 8>::new()); | 57 | static STATE: StaticCell<State<8, 8>> = StaticCell::new(); |
| 58 | let state = STATE.init(State::<8, 8>::new()); | ||
| 59 | let (device, runner) = embassy_net_wiznet::new( | 59 | let (device, runner) = embassy_net_wiznet::new( |
| 60 | mac_addr, | 60 | mac_addr, |
| 61 | state, | 61 | state, |
| @@ -70,11 +70,13 @@ async fn main(spawner: Spawner) { | |||
| 70 | let seed = rng.next_u64(); | 70 | let seed = rng.next_u64(); |
| 71 | 71 | ||
| 72 | // Init network stack | 72 | // Init network stack |
| 73 | let stack = &*make_static!(Stack::new( | 73 | static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new(); |
| 74 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||
| 75 | let stack = &*STACK.init(Stack::new( | ||
| 74 | device, | 76 | device, |
| 75 | embassy_net::Config::dhcpv4(Default::default()), | 77 | embassy_net::Config::dhcpv4(Default::default()), |
| 76 | make_static!(StackResources::<2>::new()), | 78 | RESOURCES.init(StackResources::<2>::new()), |
| 77 | seed | 79 | seed, |
| 78 | )); | 80 | )); |
| 79 | 81 | ||
| 80 | // Launch network task | 82 | // Launch network task |
diff --git a/examples/rp/src/bin/flash.rs b/examples/rp/src/bin/flash.rs index 129a8497f..eb3e6a2b9 100644 --- a/examples/rp/src/bin/flash.rs +++ b/examples/rp/src/bin/flash.rs | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | 2 | ||
| 3 | #![no_std] | 3 | #![no_std] |
| 4 | #![no_main] | 4 | #![no_main] |
| 5 | #![feature(type_alias_impl_trait)] | ||
| 6 | 5 | ||
| 7 | use defmt::*; | 6 | use defmt::*; |
| 8 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
diff --git a/examples/rp/src/bin/gpio_async.rs b/examples/rp/src/bin/gpio_async.rs index 98209fe41..b79fb2a15 100644 --- a/examples/rp/src/bin/gpio_async.rs +++ b/examples/rp/src/bin/gpio_async.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #![no_std] | 5 | #![no_std] |
| 6 | #![no_main] | 6 | #![no_main] |
| 7 | #![feature(type_alias_impl_trait)] | ||
| 8 | 7 | ||
| 9 | use defmt::*; | 8 | use defmt::*; |
| 10 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
diff --git a/examples/rp/src/bin/gpout.rs b/examples/rp/src/bin/gpout.rs index 896cc15ee..011359253 100644 --- a/examples/rp/src/bin/gpout.rs +++ b/examples/rp/src/bin/gpout.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #![no_std] | 5 | #![no_std] |
| 6 | #![no_main] | 6 | #![no_main] |
| 7 | #![feature(type_alias_impl_trait)] | ||
| 8 | 7 | ||
| 9 | use defmt::*; | 8 | use defmt::*; |
| 10 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
diff --git a/examples/rp/src/bin/i2c_async.rs b/examples/rp/src/bin/i2c_async.rs index 7b53aae72..e31cc894c 100644 --- a/examples/rp/src/bin/i2c_async.rs +++ b/examples/rp/src/bin/i2c_async.rs | |||
| @@ -5,7 +5,6 @@ | |||
| 5 | 5 | ||
| 6 | #![no_std] | 6 | #![no_std] |
| 7 | #![no_main] | 7 | #![no_main] |
| 8 | #![feature(type_alias_impl_trait)] | ||
| 9 | 8 | ||
| 10 | use defmt::*; | 9 | use defmt::*; |
| 11 | use embassy_executor::Spawner; | 10 | use embassy_executor::Spawner; |
diff --git a/examples/rp/src/bin/i2c_blocking.rs b/examples/rp/src/bin/i2c_blocking.rs index 9ddb48d69..c9c8a2760 100644 --- a/examples/rp/src/bin/i2c_blocking.rs +++ b/examples/rp/src/bin/i2c_blocking.rs | |||
| @@ -5,7 +5,6 @@ | |||
| 5 | 5 | ||
| 6 | #![no_std] | 6 | #![no_std] |
| 7 | #![no_main] | 7 | #![no_main] |
| 8 | #![feature(type_alias_impl_trait)] | ||
| 9 | 8 | ||
| 10 | use defmt::*; | 9 | use defmt::*; |
| 11 | use embassy_executor::Spawner; | 10 | use embassy_executor::Spawner; |
diff --git a/examples/rp/src/bin/i2c_slave.rs b/examples/rp/src/bin/i2c_slave.rs index 151b083a4..9fffb4646 100644 --- a/examples/rp/src/bin/i2c_slave.rs +++ b/examples/rp/src/bin/i2c_slave.rs | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | //! This example shows how to use the 2040 as an i2c slave. | 1 | //! This example shows how to use the 2040 as an i2c slave. |
| 2 | #![no_std] | 2 | #![no_std] |
| 3 | #![no_main] | 3 | #![no_main] |
| 4 | #![feature(type_alias_impl_trait)] | ||
| 5 | 4 | ||
| 6 | use defmt::*; | 5 | use defmt::*; |
| 7 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| @@ -27,7 +26,7 @@ async fn device_task(mut dev: i2c_slave::I2cSlave<'static, I2C1>) -> ! { | |||
| 27 | loop { | 26 | loop { |
| 28 | let mut buf = [0u8; 128]; | 27 | let mut buf = [0u8; 128]; |
| 29 | match dev.listen(&mut buf).await { | 28 | match dev.listen(&mut buf).await { |
| 30 | Ok(i2c_slave::Command::GeneralCall(len)) => info!("Device recieved general call write: {}", buf[..len]), | 29 | Ok(i2c_slave::Command::GeneralCall(len)) => info!("Device received general call write: {}", buf[..len]), |
| 31 | Ok(i2c_slave::Command::Read) => loop { | 30 | Ok(i2c_slave::Command::Read) => loop { |
| 32 | match dev.respond_to_read(&[state]).await { | 31 | match dev.respond_to_read(&[state]).await { |
| 33 | Ok(x) => match x { | 32 | Ok(x) => match x { |
| @@ -41,9 +40,9 @@ async fn device_task(mut dev: i2c_slave::I2cSlave<'static, I2C1>) -> ! { | |||
| 41 | Err(e) => error!("error while responding {}", e), | 40 | Err(e) => error!("error while responding {}", e), |
| 42 | } | 41 | } |
| 43 | }, | 42 | }, |
| 44 | Ok(i2c_slave::Command::Write(len)) => info!("Device recieved write: {}", buf[..len]), | 43 | Ok(i2c_slave::Command::Write(len)) => info!("Device received write: {}", buf[..len]), |
| 45 | Ok(i2c_slave::Command::WriteRead(len)) => { | 44 | Ok(i2c_slave::Command::WriteRead(len)) => { |
| 46 | info!("device recieved write read: {:x}", buf[..len]); | 45 | info!("device received write read: {:x}", buf[..len]); |
| 47 | match buf[0] { | 46 | match buf[0] { |
| 48 | // Set the state | 47 | // Set the state |
| 49 | 0xC2 => { | 48 | 0xC2 => { |
| @@ -111,7 +110,7 @@ async fn main(spawner: Spawner) { | |||
| 111 | let c_sda = p.PIN_1; | 110 | let c_sda = p.PIN_1; |
| 112 | let c_scl = p.PIN_0; | 111 | let c_scl = p.PIN_0; |
| 113 | let mut config = i2c::Config::default(); | 112 | let mut config = i2c::Config::default(); |
| 114 | config.frequency = 5_000; | 113 | config.frequency = 1_000_000; |
| 115 | let controller = i2c::I2c::new_async(p.I2C0, c_sda, c_scl, Irqs, config); | 114 | let controller = i2c::I2c::new_async(p.I2C0, c_sda, c_scl, Irqs, config); |
| 116 | 115 | ||
| 117 | unwrap!(spawner.spawn(controller_task(controller))); | 116 | unwrap!(spawner.spawn(controller_task(controller))); |
diff --git a/examples/rp/src/bin/multicore.rs b/examples/rp/src/bin/multicore.rs index 43eaf8b0a..7cb546c91 100644 --- a/examples/rp/src/bin/multicore.rs +++ b/examples/rp/src/bin/multicore.rs | |||
| @@ -4,13 +4,11 @@ | |||
| 4 | 4 | ||
| 5 | #![no_std] | 5 | #![no_std] |
| 6 | #![no_main] | 6 | #![no_main] |
| 7 | #![feature(type_alias_impl_trait)] | ||
| 8 | 7 | ||
| 9 | use defmt::*; | 8 | use defmt::*; |
| 10 | use embassy_executor::Executor; | 9 | use embassy_executor::Executor; |
| 11 | use embassy_rp::gpio::{Level, Output}; | 10 | use embassy_rp::gpio::{Level, Output}; |
| 12 | use embassy_rp::multicore::{spawn_core1, Stack}; | 11 | use embassy_rp::multicore::{spawn_core1, Stack}; |
| 13 | use embassy_rp::peripherals::PIN_25; | ||
| 14 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | 12 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; |
| 15 | use embassy_sync::channel::Channel; | 13 | use embassy_sync::channel::Channel; |
| 16 | use embassy_time::Timer; | 14 | use embassy_time::Timer; |
| @@ -32,10 +30,14 @@ fn main() -> ! { | |||
| 32 | let p = embassy_rp::init(Default::default()); | 30 | let p = embassy_rp::init(Default::default()); |
| 33 | let led = Output::new(p.PIN_25, Level::Low); | 31 | let led = Output::new(p.PIN_25, Level::Low); |
| 34 | 32 | ||
| 35 | spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || { | 33 | spawn_core1( |
| 36 | let executor1 = EXECUTOR1.init(Executor::new()); | 34 | p.CORE1, |
| 37 | executor1.run(|spawner| unwrap!(spawner.spawn(core1_task(led)))); | 35 | unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) }, |
| 38 | }); | 36 | move || { |
| 37 | let executor1 = EXECUTOR1.init(Executor::new()); | ||
| 38 | executor1.run(|spawner| unwrap!(spawner.spawn(core1_task(led)))); | ||
| 39 | }, | ||
| 40 | ); | ||
| 39 | 41 | ||
| 40 | let executor0 = EXECUTOR0.init(Executor::new()); | 42 | let executor0 = EXECUTOR0.init(Executor::new()); |
| 41 | executor0.run(|spawner| unwrap!(spawner.spawn(core0_task()))); | 43 | executor0.run(|spawner| unwrap!(spawner.spawn(core0_task()))); |
| @@ -53,7 +55,7 @@ async fn core0_task() { | |||
| 53 | } | 55 | } |
| 54 | 56 | ||
| 55 | #[embassy_executor::task] | 57 | #[embassy_executor::task] |
| 56 | async fn core1_task(mut led: Output<'static, PIN_25>) { | 58 | async fn core1_task(mut led: Output<'static>) { |
| 57 | info!("Hello from core 1"); | 59 | info!("Hello from core 1"); |
| 58 | loop { | 60 | loop { |
| 59 | match CHANNEL.receive().await { | 61 | match CHANNEL.receive().await { |
diff --git a/examples/rp/src/bin/multiprio.rs b/examples/rp/src/bin/multiprio.rs index 28f621437..26b80c11d 100644 --- a/examples/rp/src/bin/multiprio.rs +++ b/examples/rp/src/bin/multiprio.rs | |||
| @@ -55,7 +55,6 @@ | |||
| 55 | 55 | ||
| 56 | #![no_std] | 56 | #![no_std] |
| 57 | #![no_main] | 57 | #![no_main] |
| 58 | #![feature(type_alias_impl_trait)] | ||
| 59 | 58 | ||
| 60 | use cortex_m_rt::entry; | 59 | use cortex_m_rt::entry; |
| 61 | use defmt::{info, unwrap}; | 60 | use defmt::{info, unwrap}; |
diff --git a/examples/rp/src/bin/pio_async.rs b/examples/rp/src/bin/pio_async.rs index a6d6144be..ee248591b 100644 --- a/examples/rp/src/bin/pio_async.rs +++ b/examples/rp/src/bin/pio_async.rs | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | 2 | ||
| 3 | #![no_std] | 3 | #![no_std] |
| 4 | #![no_main] | 4 | #![no_main] |
| 5 | #![feature(type_alias_impl_trait)] | ||
| 6 | use defmt::info; | 5 | use defmt::info; |
| 7 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 8 | use embassy_rp::bind_interrupts; | 7 | use embassy_rp::bind_interrupts; |
diff --git a/examples/rp/src/bin/pio_dma.rs b/examples/rp/src/bin/pio_dma.rs index 86e5017ac..02700269c 100644 --- a/examples/rp/src/bin/pio_dma.rs +++ b/examples/rp/src/bin/pio_dma.rs | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | 2 | ||
| 3 | #![no_std] | 3 | #![no_std] |
| 4 | #![no_main] | 4 | #![no_main] |
| 5 | #![feature(type_alias_impl_trait)] | ||
| 6 | use defmt::info; | 5 | use defmt::info; |
| 7 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 8 | use embassy_futures::join::join; | 7 | use embassy_futures::join::join; |
diff --git a/examples/rp/src/bin/pio_hd44780.rs b/examples/rp/src/bin/pio_hd44780.rs index 5e5a6f9a3..3fab7b5f2 100644 --- a/examples/rp/src/bin/pio_hd44780.rs +++ b/examples/rp/src/bin/pio_hd44780.rs | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | #![no_std] | 4 | #![no_std] |
| 5 | #![no_main] | 5 | #![no_main] |
| 6 | #![feature(type_alias_impl_trait)] | ||
| 7 | 6 | ||
| 8 | use core::fmt::Write; | 7 | use core::fmt::Write; |
| 9 | 8 | ||
diff --git a/examples/rp/src/bin/pio_i2s.rs b/examples/rp/src/bin/pio_i2s.rs new file mode 100644 index 000000000..cf60e5b30 --- /dev/null +++ b/examples/rp/src/bin/pio_i2s.rs | |||
| @@ -0,0 +1,125 @@ | |||
| 1 | //! This example shows generating audio and sending it to a connected i2s DAC using the PIO | ||
| 2 | //! module of the RP2040. | ||
| 3 | //! | ||
| 4 | //! Connect the i2s DAC as follows: | ||
| 5 | //! bclk : GPIO 18 | ||
| 6 | //! lrc : GPIO 19 | ||
| 7 | //! din : GPIO 20 | ||
| 8 | //! Then hold down the boot select button to trigger a rising triangle waveform. | ||
| 9 | |||
| 10 | #![no_std] | ||
| 11 | #![no_main] | ||
| 12 | |||
| 13 | use core::mem; | ||
| 14 | |||
| 15 | use embassy_executor::Spawner; | ||
| 16 | use embassy_rp::peripherals::PIO0; | ||
| 17 | use embassy_rp::pio::{Config, FifoJoin, InterruptHandler, Pio, ShiftConfig, ShiftDirection}; | ||
| 18 | use embassy_rp::{bind_interrupts, Peripheral}; | ||
| 19 | use fixed::traits::ToFixed; | ||
| 20 | use static_cell::StaticCell; | ||
| 21 | use {defmt_rtt as _, panic_probe as _}; | ||
| 22 | |||
| 23 | bind_interrupts!(struct Irqs { | ||
| 24 | PIO0_IRQ_0 => InterruptHandler<PIO0>; | ||
| 25 | }); | ||
| 26 | |||
| 27 | const SAMPLE_RATE: u32 = 48_000; | ||
| 28 | |||
| 29 | #[embassy_executor::main] | ||
| 30 | async fn main(_spawner: Spawner) { | ||
| 31 | let mut p = embassy_rp::init(Default::default()); | ||
| 32 | |||
| 33 | // Setup pio state machine for i2s output | ||
| 34 | let mut pio = Pio::new(p.PIO0, Irqs); | ||
| 35 | |||
| 36 | #[rustfmt::skip] | ||
| 37 | let pio_program = pio_proc::pio_asm!( | ||
| 38 | ".side_set 2", | ||
| 39 | " set x, 14 side 0b01", // side 0bWB - W = Word Clock, B = Bit Clock | ||
| 40 | "left_data:", | ||
| 41 | " out pins, 1 side 0b00", | ||
| 42 | " jmp x-- left_data side 0b01", | ||
| 43 | " out pins 1 side 0b10", | ||
| 44 | " set x, 14 side 0b11", | ||
| 45 | "right_data:", | ||
| 46 | " out pins 1 side 0b10", | ||
| 47 | " jmp x-- right_data side 0b11", | ||
| 48 | " out pins 1 side 0b00", | ||
| 49 | ); | ||
| 50 | |||
| 51 | let bit_clock_pin = p.PIN_18; | ||
| 52 | let left_right_clock_pin = p.PIN_19; | ||
| 53 | let data_pin = p.PIN_20; | ||
| 54 | |||
| 55 | let data_pin = pio.common.make_pio_pin(data_pin); | ||
| 56 | let bit_clock_pin = pio.common.make_pio_pin(bit_clock_pin); | ||
| 57 | let left_right_clock_pin = pio.common.make_pio_pin(left_right_clock_pin); | ||
| 58 | |||
| 59 | let cfg = { | ||
| 60 | let mut cfg = Config::default(); | ||
| 61 | cfg.use_program( | ||
| 62 | &pio.common.load_program(&pio_program.program), | ||
| 63 | &[&bit_clock_pin, &left_right_clock_pin], | ||
| 64 | ); | ||
| 65 | cfg.set_out_pins(&[&data_pin]); | ||
| 66 | const BIT_DEPTH: u32 = 16; | ||
| 67 | const CHANNELS: u32 = 2; | ||
| 68 | let clock_frequency = SAMPLE_RATE * BIT_DEPTH * CHANNELS; | ||
| 69 | cfg.clock_divider = (125_000_000. / clock_frequency as f64 / 2.).to_fixed(); | ||
| 70 | cfg.shift_out = ShiftConfig { | ||
| 71 | threshold: 32, | ||
| 72 | direction: ShiftDirection::Left, | ||
| 73 | auto_fill: true, | ||
| 74 | }; | ||
| 75 | // join fifos to have twice the time to start the next dma transfer | ||
| 76 | cfg.fifo_join = FifoJoin::TxOnly; | ||
| 77 | cfg | ||
| 78 | }; | ||
| 79 | pio.sm0.set_config(&cfg); | ||
| 80 | pio.sm0.set_pin_dirs( | ||
| 81 | embassy_rp::pio::Direction::Out, | ||
| 82 | &[&data_pin, &left_right_clock_pin, &bit_clock_pin], | ||
| 83 | ); | ||
| 84 | |||
| 85 | // create two audio buffers (back and front) which will take turns being | ||
| 86 | // filled with new audio data and being sent to the pio fifo using dma | ||
| 87 | const BUFFER_SIZE: usize = 960; | ||
| 88 | static DMA_BUFFER: StaticCell<[u32; BUFFER_SIZE * 2]> = StaticCell::new(); | ||
| 89 | let dma_buffer = DMA_BUFFER.init_with(|| [0u32; BUFFER_SIZE * 2]); | ||
| 90 | let (mut back_buffer, mut front_buffer) = dma_buffer.split_at_mut(BUFFER_SIZE); | ||
| 91 | |||
| 92 | // start pio state machine | ||
| 93 | pio.sm0.set_enable(true); | ||
| 94 | let tx = pio.sm0.tx(); | ||
| 95 | let mut dma_ref = p.DMA_CH0.into_ref(); | ||
| 96 | |||
| 97 | let mut fade_value: i32 = 0; | ||
| 98 | let mut phase: i32 = 0; | ||
| 99 | |||
| 100 | loop { | ||
| 101 | // trigger transfer of front buffer data to the pio fifo | ||
| 102 | // but don't await the returned future, yet | ||
| 103 | let dma_future = tx.dma_push(dma_ref.reborrow(), front_buffer); | ||
| 104 | |||
| 105 | // fade in audio when bootsel is pressed | ||
| 106 | let fade_target = if p.BOOTSEL.is_pressed() { i32::MAX } else { 0 }; | ||
| 107 | |||
| 108 | // fill back buffer with fresh audio samples before awaiting the dma future | ||
| 109 | for s in back_buffer.iter_mut() { | ||
| 110 | // exponential approach of fade_value => fade_target | ||
| 111 | fade_value += (fade_target - fade_value) >> 14; | ||
| 112 | // generate triangle wave with amplitude and frequency based on fade value | ||
| 113 | phase = (phase + (fade_value >> 22)) & 0xffff; | ||
| 114 | let triangle_sample = (phase as i16 as i32).abs() - 16384; | ||
| 115 | let sample = (triangle_sample * (fade_value >> 15)) >> 16; | ||
| 116 | // duplicate mono sample into lower and upper half of dma word | ||
| 117 | *s = (sample as u16 as u32) * 0x10001; | ||
| 118 | } | ||
| 119 | |||
| 120 | // now await the dma future. once the dma finishes, the next buffer needs to be queued | ||
| 121 | // within DMA_DEPTH / SAMPLE_RATE = 8 / 48000 seconds = 166us | ||
| 122 | dma_future.await; | ||
| 123 | mem::swap(&mut back_buffer, &mut front_buffer); | ||
| 124 | } | ||
| 125 | } | ||
diff --git a/examples/rp/src/bin/pio_rotary_encoder.rs b/examples/rp/src/bin/pio_rotary_encoder.rs index 6d9d59df6..58bdadbc0 100644 --- a/examples/rp/src/bin/pio_rotary_encoder.rs +++ b/examples/rp/src/bin/pio_rotary_encoder.rs | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | 2 | ||
| 3 | #![no_std] | 3 | #![no_std] |
| 4 | #![no_main] | 4 | #![no_main] |
| 5 | #![feature(type_alias_impl_trait)] | ||
| 6 | 5 | ||
| 7 | use defmt::info; | 6 | use defmt::info; |
| 8 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
diff --git a/examples/rp/src/bin/pio_stepper.rs b/examples/rp/src/bin/pio_stepper.rs index 02fb20699..ab9ecf623 100644 --- a/examples/rp/src/bin/pio_stepper.rs +++ b/examples/rp/src/bin/pio_stepper.rs | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | #![no_std] | 4 | #![no_std] |
| 5 | #![no_main] | 5 | #![no_main] |
| 6 | #![feature(type_alias_impl_trait)] | ||
| 7 | use core::mem::{self, MaybeUninit}; | 6 | use core::mem::{self, MaybeUninit}; |
| 8 | 7 | ||
| 9 | use defmt::info; | 8 | use defmt::info; |
diff --git a/examples/rp/src/bin/pio_uart.rs b/examples/rp/src/bin/pio_uart.rs index c0ea23607..a07f1c180 100644 --- a/examples/rp/src/bin/pio_uart.rs +++ b/examples/rp/src/bin/pio_uart.rs | |||
| @@ -8,7 +8,6 @@ | |||
| 8 | 8 | ||
| 9 | #![no_std] | 9 | #![no_std] |
| 10 | #![no_main] | 10 | #![no_main] |
| 11 | #![feature(type_alias_impl_trait)] | ||
| 12 | #![allow(async_fn_in_trait)] | 11 | #![allow(async_fn_in_trait)] |
| 13 | 12 | ||
| 14 | use defmt::{info, panic, trace}; | 13 | use defmt::{info, panic, trace}; |
diff --git a/examples/rp/src/bin/pio_ws2812.rs b/examples/rp/src/bin/pio_ws2812.rs index 7b3259538..ac145933c 100644 --- a/examples/rp/src/bin/pio_ws2812.rs +++ b/examples/rp/src/bin/pio_ws2812.rs | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | #![no_std] | 4 | #![no_std] |
| 5 | #![no_main] | 5 | #![no_main] |
| 6 | #![feature(type_alias_impl_trait)] | ||
| 7 | 6 | ||
| 8 | use defmt::*; | 7 | use defmt::*; |
| 9 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| @@ -13,7 +12,7 @@ use embassy_rp::pio::{ | |||
| 13 | Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine, | 12 | Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine, |
| 14 | }; | 13 | }; |
| 15 | use embassy_rp::{bind_interrupts, clocks, into_ref, Peripheral, PeripheralRef}; | 14 | use embassy_rp::{bind_interrupts, clocks, into_ref, Peripheral, PeripheralRef}; |
| 16 | use embassy_time::Timer; | 15 | use embassy_time::{Duration, Ticker, Timer}; |
| 17 | use fixed::types::U24F8; | 16 | use fixed::types::U24F8; |
| 18 | use fixed_macro::fixed; | 17 | use fixed_macro::fixed; |
| 19 | use smart_leds::RGB8; | 18 | use smart_leds::RGB8; |
| @@ -108,6 +107,8 @@ impl<'d, P: Instance, const S: usize, const N: usize> Ws2812<'d, P, S, N> { | |||
| 108 | 107 | ||
| 109 | // DMA transfer | 108 | // DMA transfer |
| 110 | self.sm.tx().dma_push(self.dma.reborrow(), &words).await; | 109 | self.sm.tx().dma_push(self.dma.reborrow(), &words).await; |
| 110 | |||
| 111 | Timer::after_micros(55).await; | ||
| 111 | } | 112 | } |
| 112 | } | 113 | } |
| 113 | 114 | ||
| @@ -144,6 +145,7 @@ async fn main(_spawner: Spawner) { | |||
| 144 | let mut ws2812 = Ws2812::new(&mut common, sm0, p.DMA_CH0, p.PIN_16); | 145 | let mut ws2812 = Ws2812::new(&mut common, sm0, p.DMA_CH0, p.PIN_16); |
| 145 | 146 | ||
| 146 | // Loop forever making RGB values and pushing them out to the WS2812. | 147 | // Loop forever making RGB values and pushing them out to the WS2812. |
| 148 | let mut ticker = Ticker::every(Duration::from_millis(10)); | ||
| 147 | loop { | 149 | loop { |
| 148 | for j in 0..(256 * 5) { | 150 | for j in 0..(256 * 5) { |
| 149 | debug!("New Colors:"); | 151 | debug!("New Colors:"); |
| @@ -153,7 +155,7 @@ async fn main(_spawner: Spawner) { | |||
| 153 | } | 155 | } |
| 154 | ws2812.write(&data).await; | 156 | ws2812.write(&data).await; |
| 155 | 157 | ||
| 156 | Timer::after_millis(10).await; | 158 | ticker.next().await; |
| 157 | } | 159 | } |
| 158 | } | 160 | } |
| 159 | } | 161 | } |
diff --git a/examples/rp/src/bin/pwm.rs b/examples/rp/src/bin/pwm.rs index a99e88003..4fb62546d 100644 --- a/examples/rp/src/bin/pwm.rs +++ b/examples/rp/src/bin/pwm.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #![no_std] | 5 | #![no_std] |
| 6 | #![no_main] | 6 | #![no_main] |
| 7 | #![feature(type_alias_impl_trait)] | ||
| 8 | 7 | ||
| 9 | use defmt::*; | 8 | use defmt::*; |
| 10 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
diff --git a/examples/rp/src/bin/pwm_input.rs b/examples/rp/src/bin/pwm_input.rs index 0fc2e40c3..e7bcbfbd4 100644 --- a/examples/rp/src/bin/pwm_input.rs +++ b/examples/rp/src/bin/pwm_input.rs | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | 2 | ||
| 3 | #![no_std] | 3 | #![no_std] |
| 4 | #![no_main] | 4 | #![no_main] |
| 5 | #![feature(type_alias_impl_trait)] | ||
| 6 | 5 | ||
| 7 | use defmt::*; | 6 | use defmt::*; |
| 8 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
diff --git a/examples/rp/src/bin/rosc.rs b/examples/rp/src/bin/rosc.rs index f841043b6..942b72319 100644 --- a/examples/rp/src/bin/rosc.rs +++ b/examples/rp/src/bin/rosc.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #![no_std] | 5 | #![no_std] |
| 6 | #![no_main] | 6 | #![no_main] |
| 7 | #![feature(type_alias_impl_trait)] | ||
| 8 | 7 | ||
| 9 | use defmt::*; | 8 | use defmt::*; |
| 10 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
diff --git a/examples/rp/src/bin/rtc.rs b/examples/rp/src/bin/rtc.rs index 667876db5..e9a5e43a8 100644 --- a/examples/rp/src/bin/rtc.rs +++ b/examples/rp/src/bin/rtc.rs | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | 2 | ||
| 3 | #![no_std] | 3 | #![no_std] |
| 4 | #![no_main] | 4 | #![no_main] |
| 5 | #![feature(type_alias_impl_trait)] | ||
| 6 | 5 | ||
| 7 | use defmt::*; | 6 | use defmt::*; |
| 8 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
diff --git a/examples/rp/src/bin/spi.rs b/examples/rp/src/bin/spi.rs index 602348f7a..4cc4f5210 100644 --- a/examples/rp/src/bin/spi.rs +++ b/examples/rp/src/bin/spi.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #![no_std] | 5 | #![no_std] |
| 6 | #![no_main] | 6 | #![no_main] |
| 7 | #![feature(type_alias_impl_trait)] | ||
| 8 | 7 | ||
| 9 | use defmt::*; | 8 | use defmt::*; |
| 10 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
diff --git a/examples/rp/src/bin/spi_async.rs b/examples/rp/src/bin/spi_async.rs index f5a2d334e..266584efc 100644 --- a/examples/rp/src/bin/spi_async.rs +++ b/examples/rp/src/bin/spi_async.rs | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | #![no_std] | 4 | #![no_std] |
| 5 | #![no_main] | 5 | #![no_main] |
| 6 | #![feature(type_alias_impl_trait)] | ||
| 7 | 6 | ||
| 8 | use defmt::*; | 7 | use defmt::*; |
| 9 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
diff --git a/examples/rp/src/bin/spi_display.rs b/examples/rp/src/bin/spi_display.rs index 26c258e1c..e937b9d0a 100644 --- a/examples/rp/src/bin/spi_display.rs +++ b/examples/rp/src/bin/spi_display.rs | |||
| @@ -5,7 +5,6 @@ | |||
| 5 | 5 | ||
| 6 | #![no_std] | 6 | #![no_std] |
| 7 | #![no_main] | 7 | #![no_main] |
| 8 | #![feature(type_alias_impl_trait)] | ||
| 9 | 8 | ||
| 10 | use core::cell::RefCell; | 9 | use core::cell::RefCell; |
| 11 | 10 | ||
diff --git a/examples/rp/src/bin/uart.rs b/examples/rp/src/bin/uart.rs index 451c3c396..6a2816cd0 100644 --- a/examples/rp/src/bin/uart.rs +++ b/examples/rp/src/bin/uart.rs | |||
| @@ -6,7 +6,6 @@ | |||
| 6 | 6 | ||
| 7 | #![no_std] | 7 | #![no_std] |
| 8 | #![no_main] | 8 | #![no_main] |
| 9 | #![feature(type_alias_impl_trait)] | ||
| 10 | 9 | ||
| 11 | use embassy_executor::Spawner; | 10 | use embassy_executor::Spawner; |
| 12 | use embassy_rp::uart; | 11 | use embassy_rp::uart; |
diff --git a/examples/rp/src/bin/uart_buffered_split.rs b/examples/rp/src/bin/uart_buffered_split.rs index 14e8810a4..fac61aa04 100644 --- a/examples/rp/src/bin/uart_buffered_split.rs +++ b/examples/rp/src/bin/uart_buffered_split.rs | |||
| @@ -6,7 +6,6 @@ | |||
| 6 | 6 | ||
| 7 | #![no_std] | 7 | #![no_std] |
| 8 | #![no_main] | 8 | #![no_main] |
| 9 | #![feature(type_alias_impl_trait)] | ||
| 10 | 9 | ||
| 11 | use defmt::*; | 10 | use defmt::*; |
| 12 | use embassy_executor::Spawner; | 11 | use embassy_executor::Spawner; |
| @@ -15,7 +14,7 @@ use embassy_rp::peripherals::UART0; | |||
| 15 | use embassy_rp::uart::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, Config}; | 14 | use embassy_rp::uart::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, Config}; |
| 16 | use embassy_time::Timer; | 15 | use embassy_time::Timer; |
| 17 | use embedded_io_async::{Read, Write}; | 16 | use embedded_io_async::{Read, Write}; |
| 18 | use static_cell::make_static; | 17 | use static_cell::StaticCell; |
| 19 | use {defmt_rtt as _, panic_probe as _}; | 18 | use {defmt_rtt as _, panic_probe as _}; |
| 20 | 19 | ||
| 21 | bind_interrupts!(struct Irqs { | 20 | bind_interrupts!(struct Irqs { |
| @@ -27,8 +26,10 @@ async fn main(spawner: Spawner) { | |||
| 27 | let p = embassy_rp::init(Default::default()); | 26 | let p = embassy_rp::init(Default::default()); |
| 28 | let (tx_pin, rx_pin, uart) = (p.PIN_0, p.PIN_1, p.UART0); | 27 | let (tx_pin, rx_pin, uart) = (p.PIN_0, p.PIN_1, p.UART0); |
| 29 | 28 | ||
| 30 | let tx_buf = &mut make_static!([0u8; 16])[..]; | 29 | static TX_BUF: StaticCell<[u8; 16]> = StaticCell::new(); |
| 31 | let rx_buf = &mut make_static!([0u8; 16])[..]; | 30 | let tx_buf = &mut TX_BUF.init([0; 16])[..]; |
| 31 | static RX_BUF: StaticCell<[u8; 16]> = StaticCell::new(); | ||
| 32 | let rx_buf = &mut RX_BUF.init([0; 16])[..]; | ||
| 32 | let uart = BufferedUart::new(uart, Irqs, tx_pin, rx_pin, tx_buf, rx_buf, Config::default()); | 33 | let uart = BufferedUart::new(uart, Irqs, tx_pin, rx_pin, tx_buf, rx_buf, Config::default()); |
| 33 | let (rx, mut tx) = uart.split(); | 34 | let (rx, mut tx) = uart.split(); |
| 34 | 35 | ||
diff --git a/examples/rp/src/bin/uart_unidir.rs b/examples/rp/src/bin/uart_unidir.rs index 42c8b432e..a45f40756 100644 --- a/examples/rp/src/bin/uart_unidir.rs +++ b/examples/rp/src/bin/uart_unidir.rs | |||
| @@ -7,7 +7,6 @@ | |||
| 7 | 7 | ||
| 8 | #![no_std] | 8 | #![no_std] |
| 9 | #![no_main] | 9 | #![no_main] |
| 10 | #![feature(type_alias_impl_trait)] | ||
| 11 | 10 | ||
| 12 | use defmt::*; | 11 | use defmt::*; |
| 13 | use embassy_executor::Spawner; | 12 | use embassy_executor::Spawner; |
diff --git a/examples/rp/src/bin/usb_ethernet.rs b/examples/rp/src/bin/usb_ethernet.rs index cc63029fb..01f0d5967 100644 --- a/examples/rp/src/bin/usb_ethernet.rs +++ b/examples/rp/src/bin/usb_ethernet.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #![no_std] | 5 | #![no_std] |
| 6 | #![no_main] | 6 | #![no_main] |
| 7 | #![feature(type_alias_impl_trait)] | ||
| 8 | 7 | ||
| 9 | use defmt::*; | 8 | use defmt::*; |
| 10 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| @@ -17,7 +16,7 @@ use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState | |||
| 17 | use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; | 16 | use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; |
| 18 | use embassy_usb::{Builder, Config, UsbDevice}; | 17 | use embassy_usb::{Builder, Config, UsbDevice}; |
| 19 | use embedded_io_async::Write; | 18 | use embedded_io_async::Write; |
| 20 | use static_cell::make_static; | 19 | use static_cell::StaticCell; |
| 21 | use {defmt_rtt as _, panic_probe as _}; | 20 | use {defmt_rtt as _, panic_probe as _}; |
| 22 | 21 | ||
| 23 | bind_interrupts!(struct Irqs { | 22 | bind_interrupts!(struct Irqs { |
| @@ -65,14 +64,18 @@ async fn main(spawner: Spawner) { | |||
| 65 | config.device_protocol = 0x01; | 64 | config.device_protocol = 0x01; |
| 66 | 65 | ||
| 67 | // Create embassy-usb DeviceBuilder using the driver and config. | 66 | // Create embassy-usb DeviceBuilder using the driver and config. |
| 67 | static DEVICE_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | ||
| 68 | static CONFIG_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | ||
| 69 | static BOS_DESC: StaticCell<[u8; 256]> = StaticCell::new(); | ||
| 70 | static CONTROL_BUF: StaticCell<[u8; 128]> = StaticCell::new(); | ||
| 68 | let mut builder = Builder::new( | 71 | let mut builder = Builder::new( |
| 69 | driver, | 72 | driver, |
| 70 | config, | 73 | config, |
| 71 | &mut make_static!([0; 256])[..], | 74 | &mut DEVICE_DESC.init([0; 256])[..], |
| 72 | &mut make_static!([0; 256])[..], | 75 | &mut CONFIG_DESC.init([0; 256])[..], |
| 73 | &mut make_static!([0; 256])[..], | 76 | &mut BOS_DESC.init([0; 256])[..], |
| 74 | &mut [], // no msos descriptors | 77 | &mut [], // no msos descriptors |
| 75 | &mut make_static!([0; 128])[..], | 78 | &mut CONTROL_BUF.init([0; 128])[..], |
| 76 | ); | 79 | ); |
| 77 | 80 | ||
| 78 | // Our MAC addr. | 81 | // Our MAC addr. |
| @@ -81,14 +84,16 @@ async fn main(spawner: Spawner) { | |||
| 81 | let host_mac_addr = [0x88, 0x88, 0x88, 0x88, 0x88, 0x88]; | 84 | let host_mac_addr = [0x88, 0x88, 0x88, 0x88, 0x88, 0x88]; |
| 82 | 85 | ||
| 83 | // Create classes on the builder. | 86 | // Create classes on the builder. |
| 84 | let class = CdcNcmClass::new(&mut builder, make_static!(State::new()), host_mac_addr, 64); | 87 | static STATE: StaticCell<State> = StaticCell::new(); |
| 88 | let class = CdcNcmClass::new(&mut builder, STATE.init(State::new()), host_mac_addr, 64); | ||
| 85 | 89 | ||
| 86 | // Build the builder. | 90 | // Build the builder. |
| 87 | let usb = builder.build(); | 91 | let usb = builder.build(); |
| 88 | 92 | ||
| 89 | unwrap!(spawner.spawn(usb_task(usb))); | 93 | unwrap!(spawner.spawn(usb_task(usb))); |
| 90 | 94 | ||
| 91 | let (runner, device) = class.into_embassy_net_device::<MTU, 4, 4>(make_static!(NetState::new()), our_mac_addr); | 95 | static NET_STATE: StaticCell<NetState<MTU, 4, 4>> = StaticCell::new(); |
| 96 | let (runner, device) = class.into_embassy_net_device::<MTU, 4, 4>(NET_STATE.init(NetState::new()), our_mac_addr); | ||
| 92 | unwrap!(spawner.spawn(usb_ncm_task(runner))); | 97 | unwrap!(spawner.spawn(usb_ncm_task(runner))); |
| 93 | 98 | ||
| 94 | let config = embassy_net::Config::dhcpv4(Default::default()); | 99 | let config = embassy_net::Config::dhcpv4(Default::default()); |
| @@ -102,11 +107,13 @@ async fn main(spawner: Spawner) { | |||
| 102 | let seed = 1234; // guaranteed random, chosen by a fair dice roll | 107 | let seed = 1234; // guaranteed random, chosen by a fair dice roll |
| 103 | 108 | ||
| 104 | // Init network stack | 109 | // Init network stack |
| 105 | let stack = &*make_static!(Stack::new( | 110 | static STACK: StaticCell<Stack<Device<'static, MTU>>> = StaticCell::new(); |
| 111 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||
| 112 | let stack = &*STACK.init(Stack::new( | ||
| 106 | device, | 113 | device, |
| 107 | config, | 114 | config, |
| 108 | make_static!(StackResources::<2>::new()), | 115 | RESOURCES.init(StackResources::<2>::new()), |
| 109 | seed | 116 | seed, |
| 110 | )); | 117 | )); |
| 111 | 118 | ||
| 112 | unwrap!(spawner.spawn(net_task(stack))); | 119 | unwrap!(spawner.spawn(net_task(stack))); |
diff --git a/examples/rp/src/bin/usb_hid_keyboard.rs b/examples/rp/src/bin/usb_hid_keyboard.rs index 569c9b12b..b5ac16245 100644 --- a/examples/rp/src/bin/usb_hid_keyboard.rs +++ b/examples/rp/src/bin/usb_hid_keyboard.rs | |||
| @@ -1,6 +1,5 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | 3 | ||
| 5 | use core::sync::atomic::{AtomicBool, Ordering}; | 4 | use core::sync::atomic::{AtomicBool, Ordering}; |
| 6 | 5 | ||
diff --git a/examples/rp/src/bin/usb_hid_mouse.rs b/examples/rp/src/bin/usb_hid_mouse.rs new file mode 100644 index 000000000..afebd8813 --- /dev/null +++ b/examples/rp/src/bin/usb_hid_mouse.rs | |||
| @@ -0,0 +1,182 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use core::sync::atomic::{AtomicBool, Ordering}; | ||
| 5 | |||
| 6 | use defmt::*; | ||
| 7 | use embassy_executor::Spawner; | ||
| 8 | use embassy_futures::join::join; | ||
| 9 | use embassy_rp::bind_interrupts; | ||
| 10 | use embassy_rp::clocks::RoscRng; | ||
| 11 | use embassy_rp::gpio::{Input, Pull}; | ||
| 12 | use embassy_rp::peripherals::USB; | ||
| 13 | use embassy_rp::usb::{Driver, InterruptHandler}; | ||
| 14 | use embassy_time::Timer; | ||
| 15 | use embassy_usb::class::hid::{HidReaderWriter, ReportId, RequestHandler, State}; | ||
| 16 | use embassy_usb::control::OutResponse; | ||
| 17 | use embassy_usb::{Builder, Config, Handler}; | ||
| 18 | use rand::Rng; | ||
| 19 | use usbd_hid::descriptor::{MouseReport, SerializedDescriptor}; | ||
| 20 | use {defmt_rtt as _, panic_probe as _}; | ||
| 21 | |||
| 22 | bind_interrupts!(struct Irqs { | ||
| 23 | USBCTRL_IRQ => InterruptHandler<USB>; | ||
| 24 | }); | ||
| 25 | |||
| 26 | #[embassy_executor::main] | ||
| 27 | async fn main(_spawner: Spawner) { | ||
| 28 | let p = embassy_rp::init(Default::default()); | ||
| 29 | // Create the driver, from the HAL. | ||
| 30 | let driver = Driver::new(p.USB, Irqs); | ||
| 31 | |||
| 32 | // Create embassy-usb Config | ||
| 33 | let mut config = Config::new(0xc0de, 0xcafe); | ||
| 34 | config.manufacturer = Some("Embassy"); | ||
| 35 | config.product = Some("HID keyboard example"); | ||
| 36 | config.serial_number = Some("12345678"); | ||
| 37 | config.max_power = 100; | ||
| 38 | config.max_packet_size_0 = 64; | ||
| 39 | |||
| 40 | // Create embassy-usb DeviceBuilder using the driver and config. | ||
| 41 | // It needs some buffers for building the descriptors. | ||
| 42 | let mut device_descriptor = [0; 256]; | ||
| 43 | let mut config_descriptor = [0; 256]; | ||
| 44 | let mut bos_descriptor = [0; 256]; | ||
| 45 | // You can also add a Microsoft OS descriptor. | ||
| 46 | let mut msos_descriptor = [0; 256]; | ||
| 47 | let mut control_buf = [0; 64]; | ||
| 48 | let request_handler = MyRequestHandler {}; | ||
| 49 | let mut device_handler = MyDeviceHandler::new(); | ||
| 50 | |||
| 51 | let mut state = State::new(); | ||
| 52 | |||
| 53 | let mut builder = Builder::new( | ||
| 54 | driver, | ||
| 55 | config, | ||
| 56 | &mut device_descriptor, | ||
| 57 | &mut config_descriptor, | ||
| 58 | &mut bos_descriptor, | ||
| 59 | &mut msos_descriptor, | ||
| 60 | &mut control_buf, | ||
| 61 | ); | ||
| 62 | |||
| 63 | builder.handler(&mut device_handler); | ||
| 64 | |||
| 65 | // Create classes on the builder. | ||
| 66 | let config = embassy_usb::class::hid::Config { | ||
| 67 | report_descriptor: MouseReport::desc(), | ||
| 68 | request_handler: Some(&request_handler), | ||
| 69 | poll_ms: 60, | ||
| 70 | max_packet_size: 64, | ||
| 71 | }; | ||
| 72 | let hid = HidReaderWriter::<_, 1, 8>::new(&mut builder, &mut state, config); | ||
| 73 | |||
| 74 | // Build the builder. | ||
| 75 | let mut usb = builder.build(); | ||
| 76 | |||
| 77 | // Run the USB device. | ||
| 78 | let usb_fut = usb.run(); | ||
| 79 | |||
| 80 | // Set up the signal pin that will be used to trigger the keyboard. | ||
| 81 | let mut signal_pin = Input::new(p.PIN_16, Pull::None); | ||
| 82 | |||
| 83 | // Enable the schmitt trigger to slightly debounce. | ||
| 84 | signal_pin.set_schmitt(true); | ||
| 85 | |||
| 86 | let (reader, mut writer) = hid.split(); | ||
| 87 | |||
| 88 | // Do stuff with the class! | ||
| 89 | let in_fut = async { | ||
| 90 | let mut rng = RoscRng; | ||
| 91 | |||
| 92 | loop { | ||
| 93 | // every 1 second | ||
| 94 | _ = Timer::after_secs(1).await; | ||
| 95 | let report = MouseReport { | ||
| 96 | buttons: 0, | ||
| 97 | x: rng.gen_range(-100..100), // random small x movement | ||
| 98 | y: rng.gen_range(-100..100), // random small y movement | ||
| 99 | wheel: 0, | ||
| 100 | pan: 0, | ||
| 101 | }; | ||
| 102 | // Send the report. | ||
| 103 | match writer.write_serialize(&report).await { | ||
| 104 | Ok(()) => {} | ||
| 105 | Err(e) => warn!("Failed to send report: {:?}", e), | ||
| 106 | } | ||
| 107 | } | ||
| 108 | }; | ||
| 109 | |||
| 110 | let out_fut = async { | ||
| 111 | reader.run(false, &request_handler).await; | ||
| 112 | }; | ||
| 113 | |||
| 114 | // Run everything concurrently. | ||
| 115 | // If we had made everything `'static` above instead, we could do this using separate tasks instead. | ||
| 116 | join(usb_fut, join(in_fut, out_fut)).await; | ||
| 117 | } | ||
| 118 | |||
| 119 | struct MyRequestHandler {} | ||
| 120 | |||
| 121 | impl RequestHandler for MyRequestHandler { | ||
| 122 | fn get_report(&self, id: ReportId, _buf: &mut [u8]) -> Option<usize> { | ||
| 123 | info!("Get report for {:?}", id); | ||
| 124 | None | ||
| 125 | } | ||
| 126 | |||
| 127 | fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse { | ||
| 128 | info!("Set report for {:?}: {=[u8]}", id, data); | ||
| 129 | OutResponse::Accepted | ||
| 130 | } | ||
| 131 | |||
| 132 | fn set_idle_ms(&self, id: Option<ReportId>, dur: u32) { | ||
| 133 | info!("Set idle rate for {:?} to {:?}", id, dur); | ||
| 134 | } | ||
| 135 | |||
| 136 | fn get_idle_ms(&self, id: Option<ReportId>) -> Option<u32> { | ||
| 137 | info!("Get idle rate for {:?}", id); | ||
| 138 | None | ||
| 139 | } | ||
| 140 | } | ||
| 141 | |||
| 142 | struct MyDeviceHandler { | ||
| 143 | configured: AtomicBool, | ||
| 144 | } | ||
| 145 | |||
| 146 | impl MyDeviceHandler { | ||
| 147 | fn new() -> Self { | ||
| 148 | MyDeviceHandler { | ||
| 149 | configured: AtomicBool::new(false), | ||
| 150 | } | ||
| 151 | } | ||
| 152 | } | ||
| 153 | |||
| 154 | impl Handler for MyDeviceHandler { | ||
| 155 | fn enabled(&mut self, enabled: bool) { | ||
| 156 | self.configured.store(false, Ordering::Relaxed); | ||
| 157 | if enabled { | ||
| 158 | info!("Device enabled"); | ||
| 159 | } else { | ||
| 160 | info!("Device disabled"); | ||
| 161 | } | ||
| 162 | } | ||
| 163 | |||
| 164 | fn reset(&mut self) { | ||
| 165 | self.configured.store(false, Ordering::Relaxed); | ||
| 166 | info!("Bus reset, the Vbus current limit is 100mA"); | ||
| 167 | } | ||
| 168 | |||
| 169 | fn addressed(&mut self, addr: u8) { | ||
| 170 | self.configured.store(false, Ordering::Relaxed); | ||
| 171 | info!("USB address set to: {}", addr); | ||
| 172 | } | ||
| 173 | |||
| 174 | fn configured(&mut self, configured: bool) { | ||
| 175 | self.configured.store(configured, Ordering::Relaxed); | ||
| 176 | if configured { | ||
| 177 | info!("Device configured, it may now draw up to the configured current limit from Vbus.") | ||
| 178 | } else { | ||
| 179 | info!("Device is no longer configured, the Vbus current limit is 100mA."); | ||
| 180 | } | ||
| 181 | } | ||
| 182 | } | ||
diff --git a/examples/rp/src/bin/usb_logger.rs b/examples/rp/src/bin/usb_logger.rs index 791f15e56..af401ed63 100644 --- a/examples/rp/src/bin/usb_logger.rs +++ b/examples/rp/src/bin/usb_logger.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #![no_std] | 5 | #![no_std] |
| 6 | #![no_main] | 6 | #![no_main] |
| 7 | #![feature(type_alias_impl_trait)] | ||
| 8 | 7 | ||
| 9 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 10 | use embassy_rp::bind_interrupts; | 9 | use embassy_rp::bind_interrupts; |
diff --git a/examples/rp/src/bin/usb_midi.rs b/examples/rp/src/bin/usb_midi.rs index d5cdae319..95306a35c 100644 --- a/examples/rp/src/bin/usb_midi.rs +++ b/examples/rp/src/bin/usb_midi.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #![no_std] | 5 | #![no_std] |
| 6 | #![no_main] | 6 | #![no_main] |
| 7 | #![feature(type_alias_impl_trait)] | ||
| 8 | 7 | ||
| 9 | use defmt::{info, panic}; | 8 | use defmt::{info, panic}; |
| 10 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
diff --git a/examples/rp/src/bin/usb_raw.rs b/examples/rp/src/bin/usb_raw.rs index f59262e5c..a6c8a5b2e 100644 --- a/examples/rp/src/bin/usb_raw.rs +++ b/examples/rp/src/bin/usb_raw.rs | |||
| @@ -48,7 +48,6 @@ | |||
| 48 | 48 | ||
| 49 | #![no_std] | 49 | #![no_std] |
| 50 | #![no_main] | 50 | #![no_main] |
| 51 | #![feature(type_alias_impl_trait)] | ||
| 52 | 51 | ||
| 53 | use defmt::info; | 52 | use defmt::info; |
| 54 | use embassy_executor::Spawner; | 53 | use embassy_executor::Spawner; |
diff --git a/examples/rp/src/bin/usb_raw_bulk.rs b/examples/rp/src/bin/usb_raw_bulk.rs index 288be5a4e..0dc8e9f72 100644 --- a/examples/rp/src/bin/usb_raw_bulk.rs +++ b/examples/rp/src/bin/usb_raw_bulk.rs | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | 26 | ||
| 27 | #![no_std] | 27 | #![no_std] |
| 28 | #![no_main] | 28 | #![no_main] |
| 29 | #![feature(type_alias_impl_trait)] | ||
| 30 | 29 | ||
| 31 | use defmt::info; | 30 | use defmt::info; |
| 32 | use embassy_executor::Spawner; | 31 | use embassy_executor::Spawner; |
diff --git a/examples/rp/src/bin/usb_serial.rs b/examples/rp/src/bin/usb_serial.rs index 30347d920..ab24a994c 100644 --- a/examples/rp/src/bin/usb_serial.rs +++ b/examples/rp/src/bin/usb_serial.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #![no_std] | 5 | #![no_std] |
| 6 | #![no_main] | 6 | #![no_main] |
| 7 | #![feature(type_alias_impl_trait)] | ||
| 8 | 7 | ||
| 9 | use defmt::{info, panic}; | 8 | use defmt::{info, panic}; |
| 10 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
diff --git a/examples/rp/src/bin/usb_serial_with_logger.rs b/examples/rp/src/bin/usb_serial_with_logger.rs new file mode 100644 index 000000000..4ba4fc25c --- /dev/null +++ b/examples/rp/src/bin/usb_serial_with_logger.rs | |||
| @@ -0,0 +1,117 @@ | |||
| 1 | //! This example shows how to use USB (Universal Serial Bus) in the RP2040 chip as well as how to create multiple usb classes for one device | ||
| 2 | //! | ||
| 3 | //! This creates a USB serial port that echos. It will also print out logging information on a separate serial device | ||
| 4 | |||
| 5 | #![no_std] | ||
| 6 | #![no_main] | ||
| 7 | |||
| 8 | use defmt::{info, panic}; | ||
| 9 | use embassy_executor::Spawner; | ||
| 10 | use embassy_futures::join::join; | ||
| 11 | use embassy_rp::bind_interrupts; | ||
| 12 | use embassy_rp::peripherals::USB; | ||
| 13 | use embassy_rp::usb::{Driver, Instance, InterruptHandler}; | ||
| 14 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | ||
| 15 | use embassy_usb::driver::EndpointError; | ||
| 16 | use embassy_usb::{Builder, Config}; | ||
| 17 | use {defmt_rtt as _, panic_probe as _}; | ||
| 18 | |||
| 19 | bind_interrupts!(struct Irqs { | ||
| 20 | USBCTRL_IRQ => InterruptHandler<USB>; | ||
| 21 | }); | ||
| 22 | |||
| 23 | #[embassy_executor::main] | ||
| 24 | async fn main(_spawner: Spawner) { | ||
| 25 | info!("Hello there!"); | ||
| 26 | |||
| 27 | let p = embassy_rp::init(Default::default()); | ||
| 28 | |||
| 29 | // Create the driver, from the HAL. | ||
| 30 | let driver = Driver::new(p.USB, Irqs); | ||
| 31 | |||
| 32 | // Create embassy-usb Config | ||
| 33 | let mut config = Config::new(0xc0de, 0xcafe); | ||
| 34 | config.manufacturer = Some("Embassy"); | ||
| 35 | config.product = Some("USB-serial example"); | ||
| 36 | config.serial_number = Some("12345678"); | ||
| 37 | config.max_power = 100; | ||
| 38 | config.max_packet_size_0 = 64; | ||
| 39 | |||
| 40 | // Required for windows compatibility. | ||
| 41 | // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help | ||
| 42 | config.device_class = 0xEF; | ||
| 43 | config.device_sub_class = 0x02; | ||
| 44 | config.device_protocol = 0x01; | ||
| 45 | config.composite_with_iads = true; | ||
| 46 | |||
| 47 | // Create embassy-usb DeviceBuilder using the driver and config. | ||
| 48 | // It needs some buffers for building the descriptors. | ||
| 49 | let mut device_descriptor = [0; 256]; | ||
| 50 | let mut config_descriptor = [0; 256]; | ||
| 51 | let mut bos_descriptor = [0; 256]; | ||
| 52 | let mut control_buf = [0; 64]; | ||
| 53 | |||
| 54 | let mut state = State::new(); | ||
| 55 | let mut logger_state = State::new(); | ||
| 56 | |||
| 57 | let mut builder = Builder::new( | ||
| 58 | driver, | ||
| 59 | config, | ||
| 60 | &mut device_descriptor, | ||
| 61 | &mut config_descriptor, | ||
| 62 | &mut bos_descriptor, | ||
| 63 | &mut [], // no msos descriptors | ||
| 64 | &mut control_buf, | ||
| 65 | ); | ||
| 66 | |||
| 67 | // Create classes on the builder. | ||
| 68 | let mut class = CdcAcmClass::new(&mut builder, &mut state, 64); | ||
| 69 | |||
| 70 | // Create a class for the logger | ||
| 71 | let logger_class = CdcAcmClass::new(&mut builder, &mut logger_state, 64); | ||
| 72 | |||
| 73 | // Creates the logger and returns the logger future | ||
| 74 | // Note: You'll need to use log::info! afterwards instead of info! for this to work (this also applies to all the other log::* macros) | ||
| 75 | let log_fut = embassy_usb_logger::with_class!(1024, log::LevelFilter::Info, logger_class); | ||
| 76 | |||
| 77 | // Build the builder. | ||
| 78 | let mut usb = builder.build(); | ||
| 79 | |||
| 80 | // Run the USB device. | ||
| 81 | let usb_fut = usb.run(); | ||
| 82 | |||
| 83 | // Do stuff with the class! | ||
| 84 | let echo_fut = async { | ||
| 85 | loop { | ||
| 86 | class.wait_connection().await; | ||
| 87 | log::info!("Connected"); | ||
| 88 | let _ = echo(&mut class).await; | ||
| 89 | log::info!("Disconnected"); | ||
| 90 | } | ||
| 91 | }; | ||
| 92 | |||
| 93 | // Run everything concurrently. | ||
| 94 | // If we had made everything `'static` above instead, we could do this using separate tasks instead. | ||
| 95 | join(usb_fut, join(echo_fut, log_fut)).await; | ||
| 96 | } | ||
| 97 | |||
| 98 | struct Disconnected {} | ||
| 99 | |||
| 100 | impl From<EndpointError> for Disconnected { | ||
| 101 | fn from(val: EndpointError) -> Self { | ||
| 102 | match val { | ||
| 103 | EndpointError::BufferOverflow => panic!("Buffer overflow"), | ||
| 104 | EndpointError::Disabled => Disconnected {}, | ||
| 105 | } | ||
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 109 | async fn echo<'d, T: Instance + 'd>(class: &mut CdcAcmClass<'d, Driver<'d, T>>) -> Result<(), Disconnected> { | ||
| 110 | let mut buf = [0; 64]; | ||
| 111 | loop { | ||
| 112 | let n = class.read_packet(&mut buf).await?; | ||
| 113 | let data = &buf[..n]; | ||
| 114 | info!("data: {:x}", data); | ||
| 115 | class.write_packet(data).await?; | ||
| 116 | } | ||
| 117 | } | ||
diff --git a/examples/rp/src/bin/watchdog.rs b/examples/rp/src/bin/watchdog.rs index b6af518af..b9d4ef22f 100644 --- a/examples/rp/src/bin/watchdog.rs +++ b/examples/rp/src/bin/watchdog.rs | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #![no_std] | 5 | #![no_std] |
| 6 | #![no_main] | 6 | #![no_main] |
| 7 | #![feature(type_alias_impl_trait)] | ||
| 8 | 7 | ||
| 9 | use defmt::info; | 8 | use defmt::info; |
| 10 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
diff --git a/examples/rp/src/bin/wifi_ap_tcp_server.rs b/examples/rp/src/bin/wifi_ap_tcp_server.rs index ad1fa6462..b60852359 100644 --- a/examples/rp/src/bin/wifi_ap_tcp_server.rs +++ b/examples/rp/src/bin/wifi_ap_tcp_server.rs | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | #![no_std] | 4 | #![no_std] |
| 5 | #![no_main] | 5 | #![no_main] |
| 6 | #![feature(type_alias_impl_trait)] | ||
| 7 | #![allow(async_fn_in_trait)] | 6 | #![allow(async_fn_in_trait)] |
| 8 | 7 | ||
| 9 | use core::str::from_utf8; | 8 | use core::str::from_utf8; |
| @@ -15,11 +14,11 @@ use embassy_net::tcp::TcpSocket; | |||
| 15 | use embassy_net::{Config, Stack, StackResources}; | 14 | use embassy_net::{Config, Stack, StackResources}; |
| 16 | use embassy_rp::bind_interrupts; | 15 | use embassy_rp::bind_interrupts; |
| 17 | use embassy_rp::gpio::{Level, Output}; | 16 | use embassy_rp::gpio::{Level, Output}; |
| 18 | use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; | 17 | use embassy_rp::peripherals::{DMA_CH0, PIO0}; |
| 19 | use embassy_rp::pio::{InterruptHandler, Pio}; | 18 | use embassy_rp::pio::{InterruptHandler, Pio}; |
| 20 | use embassy_time::Duration; | 19 | use embassy_time::Duration; |
| 21 | use embedded_io_async::Write; | 20 | use embedded_io_async::Write; |
| 22 | use static_cell::make_static; | 21 | use static_cell::StaticCell; |
| 23 | use {defmt_rtt as _, panic_probe as _}; | 22 | use {defmt_rtt as _, panic_probe as _}; |
| 24 | 23 | ||
| 25 | bind_interrupts!(struct Irqs { | 24 | bind_interrupts!(struct Irqs { |
| @@ -27,9 +26,7 @@ bind_interrupts!(struct Irqs { | |||
| 27 | }); | 26 | }); |
| 28 | 27 | ||
| 29 | #[embassy_executor::task] | 28 | #[embassy_executor::task] |
| 30 | async fn wifi_task( | 29 | async fn wifi_task(runner: cyw43::Runner<'static, Output<'static>, PioSpi<'static, PIO0, 0, DMA_CH0>>) -> ! { |
| 31 | runner: cyw43::Runner<'static, Output<'static, PIN_23>, PioSpi<'static, PIN_25, PIO0, 0, DMA_CH0>>, | ||
| 32 | ) -> ! { | ||
| 33 | runner.run().await | 30 | runner.run().await |
| 34 | } | 31 | } |
| 35 | 32 | ||
| @@ -59,7 +56,8 @@ async fn main(spawner: Spawner) { | |||
| 59 | let mut pio = Pio::new(p.PIO0, Irqs); | 56 | let mut pio = Pio::new(p.PIO0, Irqs); |
| 60 | let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); | 57 | let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); |
| 61 | 58 | ||
| 62 | let state = make_static!(cyw43::State::new()); | 59 | static STATE: StaticCell<cyw43::State> = StaticCell::new(); |
| 60 | let state = STATE.init(cyw43::State::new()); | ||
| 63 | let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; | 61 | let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; |
| 64 | unwrap!(spawner.spawn(wifi_task(runner))); | 62 | unwrap!(spawner.spawn(wifi_task(runner))); |
| 65 | 63 | ||
| @@ -79,11 +77,13 @@ async fn main(spawner: Spawner) { | |||
| 79 | let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random. | 77 | let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random. |
| 80 | 78 | ||
| 81 | // Init network stack | 79 | // Init network stack |
| 82 | let stack = &*make_static!(Stack::new( | 80 | static STACK: StaticCell<Stack<cyw43::NetDriver<'static>>> = StaticCell::new(); |
| 81 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||
| 82 | let stack = &*STACK.init(Stack::new( | ||
| 83 | net_device, | 83 | net_device, |
| 84 | config, | 84 | config, |
| 85 | make_static!(StackResources::<2>::new()), | 85 | RESOURCES.init(StackResources::<2>::new()), |
| 86 | seed | 86 | seed, |
| 87 | )); | 87 | )); |
| 88 | 88 | ||
| 89 | unwrap!(spawner.spawn(net_task(stack))); | 89 | unwrap!(spawner.spawn(net_task(stack))); |
diff --git a/examples/rp/src/bin/wifi_blinky.rs b/examples/rp/src/bin/wifi_blinky.rs index 14ace74e9..18eefe41f 100644 --- a/examples/rp/src/bin/wifi_blinky.rs +++ b/examples/rp/src/bin/wifi_blinky.rs | |||
| @@ -4,17 +4,16 @@ | |||
| 4 | 4 | ||
| 5 | #![no_std] | 5 | #![no_std] |
| 6 | #![no_main] | 6 | #![no_main] |
| 7 | #![feature(type_alias_impl_trait)] | ||
| 8 | 7 | ||
| 9 | use cyw43_pio::PioSpi; | 8 | use cyw43_pio::PioSpi; |
| 10 | use defmt::*; | 9 | use defmt::*; |
| 11 | use embassy_executor::Spawner; | 10 | use embassy_executor::Spawner; |
| 12 | use embassy_rp::bind_interrupts; | 11 | use embassy_rp::bind_interrupts; |
| 13 | use embassy_rp::gpio::{Level, Output}; | 12 | use embassy_rp::gpio::{Level, Output}; |
| 14 | use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; | 13 | use embassy_rp::peripherals::{DMA_CH0, PIO0}; |
| 15 | use embassy_rp::pio::{InterruptHandler, Pio}; | 14 | use embassy_rp::pio::{InterruptHandler, Pio}; |
| 16 | use embassy_time::{Duration, Timer}; | 15 | use embassy_time::{Duration, Timer}; |
| 17 | use static_cell::make_static; | 16 | use static_cell::StaticCell; |
| 18 | use {defmt_rtt as _, panic_probe as _}; | 17 | use {defmt_rtt as _, panic_probe as _}; |
| 19 | 18 | ||
| 20 | bind_interrupts!(struct Irqs { | 19 | bind_interrupts!(struct Irqs { |
| @@ -22,9 +21,7 @@ bind_interrupts!(struct Irqs { | |||
| 22 | }); | 21 | }); |
| 23 | 22 | ||
| 24 | #[embassy_executor::task] | 23 | #[embassy_executor::task] |
| 25 | async fn wifi_task( | 24 | async fn wifi_task(runner: cyw43::Runner<'static, Output<'static>, PioSpi<'static, PIO0, 0, DMA_CH0>>) -> ! { |
| 26 | runner: cyw43::Runner<'static, Output<'static, PIN_23>, PioSpi<'static, PIN_25, PIO0, 0, DMA_CH0>>, | ||
| 27 | ) -> ! { | ||
| 28 | runner.run().await | 25 | runner.run().await |
| 29 | } | 26 | } |
| 30 | 27 | ||
| @@ -46,7 +43,8 @@ async fn main(spawner: Spawner) { | |||
| 46 | let mut pio = Pio::new(p.PIO0, Irqs); | 43 | let mut pio = Pio::new(p.PIO0, Irqs); |
| 47 | let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); | 44 | let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); |
| 48 | 45 | ||
| 49 | let state = make_static!(cyw43::State::new()); | 46 | static STATE: StaticCell<cyw43::State> = StaticCell::new(); |
| 47 | let state = STATE.init(cyw43::State::new()); | ||
| 50 | let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; | 48 | let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; |
| 51 | unwrap!(spawner.spawn(wifi_task(runner))); | 49 | unwrap!(spawner.spawn(wifi_task(runner))); |
| 52 | 50 | ||
diff --git a/examples/rp/src/bin/wifi_scan.rs b/examples/rp/src/bin/wifi_scan.rs index 7adf52b88..e0f85a6b0 100644 --- a/examples/rp/src/bin/wifi_scan.rs +++ b/examples/rp/src/bin/wifi_scan.rs | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | #![no_std] | 4 | #![no_std] |
| 5 | #![no_main] | 5 | #![no_main] |
| 6 | #![feature(type_alias_impl_trait)] | ||
| 7 | #![allow(async_fn_in_trait)] | 6 | #![allow(async_fn_in_trait)] |
| 8 | 7 | ||
| 9 | use core::str; | 8 | use core::str; |
| @@ -14,9 +13,9 @@ use embassy_executor::Spawner; | |||
| 14 | use embassy_net::Stack; | 13 | use embassy_net::Stack; |
| 15 | use embassy_rp::bind_interrupts; | 14 | use embassy_rp::bind_interrupts; |
| 16 | use embassy_rp::gpio::{Level, Output}; | 15 | use embassy_rp::gpio::{Level, Output}; |
| 17 | use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; | 16 | use embassy_rp::peripherals::{DMA_CH0, PIO0}; |
| 18 | use embassy_rp::pio::{InterruptHandler, Pio}; | 17 | use embassy_rp::pio::{InterruptHandler, Pio}; |
| 19 | use static_cell::make_static; | 18 | use static_cell::StaticCell; |
| 20 | use {defmt_rtt as _, panic_probe as _}; | 19 | use {defmt_rtt as _, panic_probe as _}; |
| 21 | 20 | ||
| 22 | bind_interrupts!(struct Irqs { | 21 | bind_interrupts!(struct Irqs { |
| @@ -24,9 +23,7 @@ bind_interrupts!(struct Irqs { | |||
| 24 | }); | 23 | }); |
| 25 | 24 | ||
| 26 | #[embassy_executor::task] | 25 | #[embassy_executor::task] |
| 27 | async fn wifi_task( | 26 | async fn wifi_task(runner: cyw43::Runner<'static, Output<'static>, PioSpi<'static, PIO0, 0, DMA_CH0>>) -> ! { |
| 28 | runner: cyw43::Runner<'static, Output<'static, PIN_23>, PioSpi<'static, PIN_25, PIO0, 0, DMA_CH0>>, | ||
| 29 | ) -> ! { | ||
| 30 | runner.run().await | 27 | runner.run().await |
| 31 | } | 28 | } |
| 32 | 29 | ||
| @@ -56,7 +53,8 @@ async fn main(spawner: Spawner) { | |||
| 56 | let mut pio = Pio::new(p.PIO0, Irqs); | 53 | let mut pio = Pio::new(p.PIO0, Irqs); |
| 57 | let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); | 54 | let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); |
| 58 | 55 | ||
| 59 | let state = make_static!(cyw43::State::new()); | 56 | static STATE: StaticCell<cyw43::State> = StaticCell::new(); |
| 57 | let state = STATE.init(cyw43::State::new()); | ||
| 60 | let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; | 58 | let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; |
| 61 | unwrap!(spawner.spawn(wifi_task(runner))); | 59 | unwrap!(spawner.spawn(wifi_task(runner))); |
| 62 | 60 | ||
| @@ -65,7 +63,7 @@ async fn main(spawner: Spawner) { | |||
| 65 | .set_power_management(cyw43::PowerManagementMode::PowerSave) | 63 | .set_power_management(cyw43::PowerManagementMode::PowerSave) |
| 66 | .await; | 64 | .await; |
| 67 | 65 | ||
| 68 | let mut scanner = control.scan().await; | 66 | let mut scanner = control.scan(Default::default()).await; |
| 69 | while let Some(bss) = scanner.next().await { | 67 | while let Some(bss) = scanner.next().await { |
| 70 | if let Ok(ssid_str) = str::from_utf8(&bss.ssid) { | 68 | if let Ok(ssid_str) = str::from_utf8(&bss.ssid) { |
| 71 | info!("scanned {} == {:x}", ssid_str, bss.bssid); | 69 | info!("scanned {} == {:x}", ssid_str, bss.bssid); |
diff --git a/examples/rp/src/bin/wifi_tcp_server.rs b/examples/rp/src/bin/wifi_tcp_server.rs index ec6b4ee74..f1afc4a00 100644 --- a/examples/rp/src/bin/wifi_tcp_server.rs +++ b/examples/rp/src/bin/wifi_tcp_server.rs | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | #![no_std] | 4 | #![no_std] |
| 5 | #![no_main] | 5 | #![no_main] |
| 6 | #![feature(type_alias_impl_trait)] | ||
| 7 | #![allow(async_fn_in_trait)] | 6 | #![allow(async_fn_in_trait)] |
| 8 | 7 | ||
| 9 | use core::str::from_utf8; | 8 | use core::str::from_utf8; |
| @@ -15,11 +14,11 @@ use embassy_net::tcp::TcpSocket; | |||
| 15 | use embassy_net::{Config, Stack, StackResources}; | 14 | use embassy_net::{Config, Stack, StackResources}; |
| 16 | use embassy_rp::bind_interrupts; | 15 | use embassy_rp::bind_interrupts; |
| 17 | use embassy_rp::gpio::{Level, Output}; | 16 | use embassy_rp::gpio::{Level, Output}; |
| 18 | use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; | 17 | use embassy_rp::peripherals::{DMA_CH0, PIO0}; |
| 19 | use embassy_rp::pio::{InterruptHandler, Pio}; | 18 | use embassy_rp::pio::{InterruptHandler, Pio}; |
| 20 | use embassy_time::{Duration, Timer}; | 19 | use embassy_time::{Duration, Timer}; |
| 21 | use embedded_io_async::Write; | 20 | use embedded_io_async::Write; |
| 22 | use static_cell::make_static; | 21 | use static_cell::StaticCell; |
| 23 | use {defmt_rtt as _, panic_probe as _}; | 22 | use {defmt_rtt as _, panic_probe as _}; |
| 24 | 23 | ||
| 25 | bind_interrupts!(struct Irqs { | 24 | bind_interrupts!(struct Irqs { |
| @@ -30,9 +29,7 @@ const WIFI_NETWORK: &str = "EmbassyTest"; | |||
| 30 | const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud"; | 29 | const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud"; |
| 31 | 30 | ||
| 32 | #[embassy_executor::task] | 31 | #[embassy_executor::task] |
| 33 | async fn wifi_task( | 32 | async fn wifi_task(runner: cyw43::Runner<'static, Output<'static>, PioSpi<'static, PIO0, 0, DMA_CH0>>) -> ! { |
| 34 | runner: cyw43::Runner<'static, Output<'static, PIN_23>, PioSpi<'static, PIN_25, PIO0, 0, DMA_CH0>>, | ||
| 35 | ) -> ! { | ||
| 36 | runner.run().await | 33 | runner.run().await |
| 37 | } | 34 | } |
| 38 | 35 | ||
| @@ -62,7 +59,8 @@ async fn main(spawner: Spawner) { | |||
| 62 | let mut pio = Pio::new(p.PIO0, Irqs); | 59 | let mut pio = Pio::new(p.PIO0, Irqs); |
| 63 | let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); | 60 | let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); |
| 64 | 61 | ||
| 65 | let state = make_static!(cyw43::State::new()); | 62 | static STATE: StaticCell<cyw43::State> = StaticCell::new(); |
| 63 | let state = STATE.init(cyw43::State::new()); | ||
| 66 | let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; | 64 | let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; |
| 67 | unwrap!(spawner.spawn(wifi_task(runner))); | 65 | unwrap!(spawner.spawn(wifi_task(runner))); |
| 68 | 66 | ||
| @@ -82,11 +80,13 @@ async fn main(spawner: Spawner) { | |||
| 82 | let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random. | 80 | let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random. |
| 83 | 81 | ||
| 84 | // Init network stack | 82 | // Init network stack |
| 85 | let stack = &*make_static!(Stack::new( | 83 | static STACK: StaticCell<Stack<cyw43::NetDriver<'static>>> = StaticCell::new(); |
| 84 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||
| 85 | let stack = &*STACK.init(Stack::new( | ||
| 86 | net_device, | 86 | net_device, |
| 87 | config, | 87 | config, |
| 88 | make_static!(StackResources::<2>::new()), | 88 | RESOURCES.init(StackResources::<2>::new()), |
| 89 | seed | 89 | seed, |
| 90 | )); | 90 | )); |
| 91 | 91 | ||
| 92 | unwrap!(spawner.spawn(net_task(stack))); | 92 | unwrap!(spawner.spawn(net_task(stack))); |
