diff options
Diffstat (limited to 'examples/nrf52840/src/bin')
22 files changed, 494 insertions, 52 deletions
diff --git a/examples/nrf52840/src/bin/channel.rs b/examples/nrf52840/src/bin/channel.rs index e06ba1c73..ffa539808 100644 --- a/examples/nrf52840/src/bin/channel.rs +++ b/examples/nrf52840/src/bin/channel.rs | |||
| @@ -31,7 +31,7 @@ async fn main(spawner: Spawner) { | |||
| 31 | let p = embassy_nrf::init(Default::default()); | 31 | let p = embassy_nrf::init(Default::default()); |
| 32 | let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard); | 32 | let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard); |
| 33 | 33 | ||
| 34 | unwrap!(spawner.spawn(my_task())); | 34 | spawner.spawn(unwrap!(my_task())); |
| 35 | 35 | ||
| 36 | loop { | 36 | loop { |
| 37 | match CHANNEL.receive().await { | 37 | match CHANNEL.receive().await { |
diff --git a/examples/nrf52840/src/bin/channel_sender_receiver.rs b/examples/nrf52840/src/bin/channel_sender_receiver.rs index 74c62ca20..09050db68 100644 --- a/examples/nrf52840/src/bin/channel_sender_receiver.rs +++ b/examples/nrf52840/src/bin/channel_sender_receiver.rs | |||
| @@ -45,6 +45,6 @@ async fn main(spawner: Spawner) { | |||
| 45 | let p = embassy_nrf::init(Default::default()); | 45 | let p = embassy_nrf::init(Default::default()); |
| 46 | let channel = CHANNEL.init(Channel::new()); | 46 | let channel = CHANNEL.init(Channel::new()); |
| 47 | 47 | ||
| 48 | unwrap!(spawner.spawn(send_task(channel.sender()))); | 48 | spawner.spawn(unwrap!(send_task(channel.sender()))); |
| 49 | unwrap!(spawner.spawn(recv_task(p.P0_13.into(), channel.receiver()))); | 49 | spawner.spawn(unwrap!(recv_task(p.P0_13.into(), channel.receiver()))); |
| 50 | } | 50 | } |
diff --git a/examples/nrf52840/src/bin/ethernet_enc28j60.rs b/examples/nrf52840/src/bin/ethernet_enc28j60.rs index 0946492fe..3bb255a72 100644 --- a/examples/nrf52840/src/bin/ethernet_enc28j60.rs +++ b/examples/nrf52840/src/bin/ethernet_enc28j60.rs | |||
| @@ -70,7 +70,7 @@ async fn main(spawner: Spawner) { | |||
| 70 | static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new(); | 70 | static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new(); |
| 71 | let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed); | 71 | let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed); |
| 72 | 72 | ||
| 73 | unwrap!(spawner.spawn(net_task(runner))); | 73 | spawner.spawn(unwrap!(net_task(runner))); |
| 74 | 74 | ||
| 75 | // And now we can use it! | 75 | // And now we can use it! |
| 76 | 76 | ||
diff --git a/examples/nrf52840/src/bin/executor_fairness_test.rs b/examples/nrf52840/src/bin/executor_fairness_test.rs index df6e7af3f..70c9405f0 100644 --- a/examples/nrf52840/src/bin/executor_fairness_test.rs +++ b/examples/nrf52840/src/bin/executor_fairness_test.rs | |||
| @@ -36,7 +36,7 @@ async fn run3() { | |||
| 36 | #[embassy_executor::main] | 36 | #[embassy_executor::main] |
| 37 | async fn main(spawner: Spawner) { | 37 | async fn main(spawner: Spawner) { |
| 38 | let _p = embassy_nrf::init(Default::default()); | 38 | let _p = embassy_nrf::init(Default::default()); |
| 39 | unwrap!(spawner.spawn(run1())); | 39 | spawner.spawn(unwrap!(run1())); |
| 40 | unwrap!(spawner.spawn(run2())); | 40 | spawner.spawn(unwrap!(run2())); |
| 41 | unwrap!(spawner.spawn(run3())); | 41 | spawner.spawn(unwrap!(run3())); |
| 42 | } | 42 | } |
diff --git a/examples/nrf52840/src/bin/gpiote_port.rs b/examples/nrf52840/src/bin/gpiote_port.rs index 0dddb1a97..66dbd32dc 100644 --- a/examples/nrf52840/src/bin/gpiote_port.rs +++ b/examples/nrf52840/src/bin/gpiote_port.rs | |||
| @@ -26,8 +26,8 @@ async fn main(spawner: Spawner) { | |||
| 26 | let btn3 = Input::new(p.P0_24, Pull::Up); | 26 | let btn3 = Input::new(p.P0_24, Pull::Up); |
| 27 | let btn4 = Input::new(p.P0_25, Pull::Up); | 27 | let btn4 = Input::new(p.P0_25, Pull::Up); |
| 28 | 28 | ||
| 29 | unwrap!(spawner.spawn(button_task(1, btn1))); | 29 | spawner.spawn(unwrap!(button_task(1, btn1))); |
| 30 | unwrap!(spawner.spawn(button_task(2, btn2))); | 30 | spawner.spawn(unwrap!(button_task(2, btn2))); |
| 31 | unwrap!(spawner.spawn(button_task(3, btn3))); | 31 | spawner.spawn(unwrap!(button_task(3, btn3))); |
| 32 | unwrap!(spawner.spawn(button_task(4, btn4))); | 32 | spawner.spawn(unwrap!(button_task(4, btn4))); |
| 33 | } | 33 | } |
diff --git a/examples/nrf52840/src/bin/ieee802154_receive.rs b/examples/nrf52840/src/bin/ieee802154_receive.rs new file mode 100644 index 000000000..ede8fca65 --- /dev/null +++ b/examples/nrf52840/src/bin/ieee802154_receive.rs | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use embassy_executor::Spawner; | ||
| 5 | use embassy_nrf::config::{Config, HfclkSource}; | ||
| 6 | use embassy_nrf::gpio::{Level, Output, OutputDrive}; | ||
| 7 | use embassy_nrf::radio::ieee802154::{self, Packet}; | ||
| 8 | use embassy_nrf::{peripherals, radio}; | ||
| 9 | use embassy_time::Timer; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | ||
| 11 | |||
| 12 | embassy_nrf::bind_interrupts!(struct Irqs { | ||
| 13 | RADIO => radio::InterruptHandler<peripherals::RADIO>; | ||
| 14 | }); | ||
| 15 | |||
| 16 | #[embassy_executor::main] | ||
| 17 | async fn main(_spawner: Spawner) { | ||
| 18 | let mut config = Config::default(); | ||
| 19 | config.hfclk_source = HfclkSource::ExternalXtal; | ||
| 20 | let peripherals = embassy_nrf::init(config); | ||
| 21 | |||
| 22 | // assumes LED on P0_15 with active-high polarity | ||
| 23 | let mut gpo_led = Output::new(peripherals.P0_15, Level::Low, OutputDrive::Standard); | ||
| 24 | |||
| 25 | let mut radio = ieee802154::Radio::new(peripherals.RADIO, Irqs); | ||
| 26 | let mut packet = Packet::new(); | ||
| 27 | |||
| 28 | loop { | ||
| 29 | gpo_led.set_low(); | ||
| 30 | let rv = radio.receive(&mut packet).await; | ||
| 31 | gpo_led.set_high(); | ||
| 32 | match rv { | ||
| 33 | Err(_) => defmt::error!("receive() Err"), | ||
| 34 | Ok(_) => defmt::info!("receive() {:?}", *packet), | ||
| 35 | } | ||
| 36 | Timer::after_millis(100u64).await; | ||
| 37 | } | ||
| 38 | } | ||
diff --git a/examples/nrf52840/src/bin/ieee802154_send.rs b/examples/nrf52840/src/bin/ieee802154_send.rs new file mode 100644 index 000000000..7af9d1d06 --- /dev/null +++ b/examples/nrf52840/src/bin/ieee802154_send.rs | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use embassy_executor::Spawner; | ||
| 5 | use embassy_nrf::config::{Config, HfclkSource}; | ||
| 6 | use embassy_nrf::gpio::{Level, Output, OutputDrive}; | ||
| 7 | use embassy_nrf::radio::ieee802154::{self, Packet}; | ||
| 8 | use embassy_nrf::{peripherals, radio}; | ||
| 9 | use embassy_time::Timer; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | ||
| 11 | |||
| 12 | embassy_nrf::bind_interrupts!(struct Irqs { | ||
| 13 | RADIO => radio::InterruptHandler<peripherals::RADIO>; | ||
| 14 | }); | ||
| 15 | |||
| 16 | #[embassy_executor::main] | ||
| 17 | async fn main(_spawner: Spawner) { | ||
| 18 | let mut config = Config::default(); | ||
| 19 | config.hfclk_source = HfclkSource::ExternalXtal; | ||
| 20 | let peripherals = embassy_nrf::init(config); | ||
| 21 | |||
| 22 | // assumes LED on P0_15 with active-high polarity | ||
| 23 | let mut gpo_led = Output::new(peripherals.P0_15, Level::Low, OutputDrive::Standard); | ||
| 24 | |||
| 25 | let mut radio = ieee802154::Radio::new(peripherals.RADIO, Irqs); | ||
| 26 | let mut packet = Packet::new(); | ||
| 27 | |||
| 28 | loop { | ||
| 29 | packet.copy_from_slice(&[0_u8; 16]); | ||
| 30 | gpo_led.set_high(); | ||
| 31 | let rv = radio.try_send(&mut packet).await; | ||
| 32 | gpo_led.set_low(); | ||
| 33 | match rv { | ||
| 34 | Err(_) => defmt::error!("try_send() Err"), | ||
| 35 | Ok(_) => defmt::info!("try_send() {:?}", *packet), | ||
| 36 | } | ||
| 37 | Timer::after_millis(1000u64).await; | ||
| 38 | } | ||
| 39 | } | ||
diff --git a/examples/nrf52840/src/bin/manually_create_executor.rs b/examples/nrf52840/src/bin/manually_create_executor.rs index 7ca39348e..f0639eb23 100644 --- a/examples/nrf52840/src/bin/manually_create_executor.rs +++ b/examples/nrf52840/src/bin/manually_create_executor.rs | |||
| @@ -42,7 +42,7 @@ fn main() -> ! { | |||
| 42 | // `run` calls the closure then runs the executor forever. It never returns. | 42 | // `run` calls the closure then runs the executor forever. It never returns. |
| 43 | executor.run(|spawner| { | 43 | executor.run(|spawner| { |
| 44 | // Here we get access to a spawner to spawn the initial tasks. | 44 | // Here we get access to a spawner to spawn the initial tasks. |
| 45 | unwrap!(spawner.spawn(run1())); | 45 | spawner.spawn(unwrap!(run1())); |
| 46 | unwrap!(spawner.spawn(run2())); | 46 | spawner.spawn(unwrap!(run2())); |
| 47 | }); | 47 | }); |
| 48 | } | 48 | } |
diff --git a/examples/nrf52840/src/bin/multiprio.rs b/examples/nrf52840/src/bin/multiprio.rs index d58613da4..4d9b986d4 100644 --- a/examples/nrf52840/src/bin/multiprio.rs +++ b/examples/nrf52840/src/bin/multiprio.rs | |||
| @@ -130,16 +130,16 @@ fn main() -> ! { | |||
| 130 | // High-priority executor: EGU1_SWI1, priority level 6 | 130 | // High-priority executor: EGU1_SWI1, priority level 6 |
| 131 | interrupt::EGU1_SWI1.set_priority(Priority::P6); | 131 | interrupt::EGU1_SWI1.set_priority(Priority::P6); |
| 132 | let spawner = EXECUTOR_HIGH.start(interrupt::EGU1_SWI1); | 132 | let spawner = EXECUTOR_HIGH.start(interrupt::EGU1_SWI1); |
| 133 | unwrap!(spawner.spawn(run_high())); | 133 | spawner.spawn(unwrap!(run_high())); |
| 134 | 134 | ||
| 135 | // Medium-priority executor: EGU0_SWI0, priority level 7 | 135 | // Medium-priority executor: EGU0_SWI0, priority level 7 |
| 136 | interrupt::EGU0_SWI0.set_priority(Priority::P7); | 136 | interrupt::EGU0_SWI0.set_priority(Priority::P7); |
| 137 | let spawner = EXECUTOR_MED.start(interrupt::EGU0_SWI0); | 137 | let spawner = EXECUTOR_MED.start(interrupt::EGU0_SWI0); |
| 138 | unwrap!(spawner.spawn(run_med())); | 138 | spawner.spawn(unwrap!(run_med())); |
| 139 | 139 | ||
| 140 | // Low priority executor: runs in thread mode, using WFE/SEV | 140 | // Low priority executor: runs in thread mode, using WFE/SEV |
| 141 | let executor = EXECUTOR_LOW.init(Executor::new()); | 141 | let executor = EXECUTOR_LOW.init(Executor::new()); |
| 142 | executor.run(|spawner| { | 142 | executor.run(|spawner| { |
| 143 | unwrap!(spawner.spawn(run_low())); | 143 | spawner.spawn(unwrap!(run_low())); |
| 144 | }); | 144 | }); |
| 145 | } | 145 | } |
diff --git a/examples/nrf52840/src/bin/mutex.rs b/examples/nrf52840/src/bin/mutex.rs index 5c22279b5..a8e9a82cc 100644 --- a/examples/nrf52840/src/bin/mutex.rs +++ b/examples/nrf52840/src/bin/mutex.rs | |||
| @@ -30,7 +30,7 @@ async fn my_task() { | |||
| 30 | #[embassy_executor::main] | 30 | #[embassy_executor::main] |
| 31 | async fn main(spawner: Spawner) { | 31 | async fn main(spawner: Spawner) { |
| 32 | let _p = embassy_nrf::init(Default::default()); | 32 | let _p = embassy_nrf::init(Default::default()); |
| 33 | unwrap!(spawner.spawn(my_task())); | 33 | spawner.spawn(unwrap!(my_task())); |
| 34 | 34 | ||
| 35 | loop { | 35 | loop { |
| 36 | Timer::after_millis(300).await; | 36 | Timer::after_millis(300).await; |
diff --git a/examples/nrf52840/src/bin/nfct.rs b/examples/nrf52840/src/bin/nfct.rs index d559d006a..fafa37f48 100644 --- a/examples/nrf52840/src/bin/nfct.rs +++ b/examples/nrf52840/src/bin/nfct.rs | |||
| @@ -1,11 +1,12 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | 3 | ||
| 4 | use defmt::*; | 4 | use defmt::{todo, *}; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_nrf::config::HfclkSource; | 6 | use embassy_nrf::config::HfclkSource; |
| 7 | use embassy_nrf::nfct::{Config as NfcConfig, NfcId, NfcT}; | 7 | use embassy_nrf::nfct::{Config as NfcConfig, NfcId, NfcT}; |
| 8 | use embassy_nrf::{bind_interrupts, nfct}; | 8 | use embassy_nrf::{bind_interrupts, nfct}; |
| 9 | use iso14443_4::{Card, IsoDep}; | ||
| 9 | use {defmt_rtt as _, embassy_nrf as _, panic_probe as _}; | 10 | use {defmt_rtt as _, embassy_nrf as _, panic_probe as _}; |
| 10 | 11 | ||
| 11 | bind_interrupts!(struct Irqs { | 12 | bind_interrupts!(struct Irqs { |
| @@ -30,12 +31,28 @@ async fn main(_spawner: Spawner) { | |||
| 30 | 31 | ||
| 31 | let mut buf = [0u8; 256]; | 32 | let mut buf = [0u8; 256]; |
| 32 | 33 | ||
| 34 | let cc = &[ | ||
| 35 | 0x00, 0x0f, /* CCEN_HI, CCEN_LOW */ | ||
| 36 | 0x20, /* VERSION */ | ||
| 37 | 0x00, 0x7f, /* MLe_HI, MLe_LOW */ | ||
| 38 | 0x00, 0x7f, /* MLc_HI, MLc_LOW */ | ||
| 39 | /* TLV */ | ||
| 40 | 0x04, 0x06, 0xe1, 0x04, 0x00, 0x7f, 0x00, 0x00, | ||
| 41 | ]; | ||
| 42 | |||
| 43 | let ndef = &[ | ||
| 44 | 0x00, 0x10, 0xd1, 0x1, 0xc, 0x55, 0x4, 0x65, 0x6d, 0x62, 0x61, 0x73, 0x73, 0x79, 0x2e, 0x64, 0x65, 0x76, | ||
| 45 | ]; | ||
| 46 | let mut selected: &[u8] = cc; | ||
| 47 | |||
| 33 | loop { | 48 | loop { |
| 34 | info!("activating"); | 49 | info!("activating"); |
| 35 | nfc.activate().await; | 50 | nfc.activate().await; |
| 51 | info!("activated!"); | ||
| 52 | |||
| 53 | let mut nfc = IsoDep::new(iso14443_3::Logger(&mut nfc)); | ||
| 36 | 54 | ||
| 37 | loop { | 55 | loop { |
| 38 | info!("rxing"); | ||
| 39 | let n = match nfc.receive(&mut buf).await { | 56 | let n = match nfc.receive(&mut buf).await { |
| 40 | Ok(n) => n, | 57 | Ok(n) => n, |
| 41 | Err(e) => { | 58 | Err(e) => { |
| @@ -44,25 +61,51 @@ async fn main(_spawner: Spawner) { | |||
| 44 | } | 61 | } |
| 45 | }; | 62 | }; |
| 46 | let req = &buf[..n]; | 63 | let req = &buf[..n]; |
| 47 | info!("received frame {:02x}", req); | 64 | info!("iso-dep rx {:02x}", req); |
| 48 | 65 | ||
| 49 | let mut deselect = false; | 66 | let Ok(apdu) = Apdu::parse(req) else { |
| 50 | let resp = match req { | 67 | error!("apdu parse error"); |
| 51 | [0xe0, ..] => { | 68 | break; |
| 52 | info!("Got RATS, tx'ing ATS"); | 69 | }; |
| 53 | &[0x06, 0x77, 0x77, 0x81, 0x02, 0x80][..] | 70 | |
| 71 | info!("apdu: {:?}", apdu); | ||
| 72 | |||
| 73 | let resp = match (apdu.cla, apdu.ins, apdu.p1, apdu.p2) { | ||
| 74 | (0, 0xa4, 4, 0) => { | ||
| 75 | info!("select app"); | ||
| 76 | &[0x90, 0x00][..] | ||
| 54 | } | 77 | } |
| 55 | [0xc2] => { | 78 | (0, 0xa4, 0, 12) => { |
| 56 | info!("Got deselect!"); | 79 | info!("select df"); |
| 57 | deselect = true; | 80 | match apdu.data { |
| 58 | &[0xc2] | 81 | [0xe1, 0x03] => { |
| 82 | selected = cc; | ||
| 83 | &[0x90, 0x00][..] | ||
| 84 | } | ||
| 85 | [0xe1, 0x04] => { | ||
| 86 | selected = ndef; | ||
| 87 | &[0x90, 0x00][..] | ||
| 88 | } | ||
| 89 | _ => todo!(), // return NOT FOUND | ||
| 90 | } | ||
| 91 | } | ||
| 92 | (0, 0xb0, p1, p2) => { | ||
| 93 | info!("read"); | ||
| 94 | let offs = u16::from_be_bytes([p1 & 0x7f, p2]) as usize; | ||
| 95 | let len = if apdu.le == 0 { usize::MAX } else { apdu.le as usize }; | ||
| 96 | let n = len.min(selected.len() - offs); | ||
| 97 | buf[..n].copy_from_slice(&selected[offs..][..n]); | ||
| 98 | buf[n..][..2].copy_from_slice(&[0x90, 0x00]); | ||
| 99 | &buf[..n + 2] | ||
| 59 | } | 100 | } |
| 60 | _ => { | 101 | _ => { |
| 61 | info!("Got unknown command!"); | 102 | info!("Got unknown command!"); |
| 62 | &[0xFF] | 103 | &[0xFF, 0xFF] |
| 63 | } | 104 | } |
| 64 | }; | 105 | }; |
| 65 | 106 | ||
| 107 | info!("iso-dep tx {:02x}", resp); | ||
| 108 | |||
| 66 | match nfc.transmit(resp).await { | 109 | match nfc.transmit(resp).await { |
| 67 | Ok(()) => {} | 110 | Ok(()) => {} |
| 68 | Err(e) => { | 111 | Err(e) => { |
| @@ -70,10 +113,211 @@ async fn main(_spawner: Spawner) { | |||
| 70 | break; | 113 | break; |
| 71 | } | 114 | } |
| 72 | } | 115 | } |
| 116 | } | ||
| 117 | } | ||
| 118 | } | ||
| 73 | 119 | ||
| 74 | if deselect { | 120 | #[derive(Debug, Clone, defmt::Format)] |
| 75 | break; | 121 | struct Apdu<'a> { |
| 122 | pub cla: u8, | ||
| 123 | pub ins: u8, | ||
| 124 | pub p1: u8, | ||
| 125 | pub p2: u8, | ||
| 126 | pub data: &'a [u8], | ||
| 127 | pub le: u16, | ||
| 128 | } | ||
| 129 | |||
| 130 | #[derive(Debug, Clone, Copy, PartialEq, Eq, defmt::Format)] | ||
| 131 | struct ApduParseError; | ||
| 132 | |||
| 133 | impl<'a> Apdu<'a> { | ||
| 134 | pub fn parse(apdu: &'a [u8]) -> Result<Self, ApduParseError> { | ||
| 135 | if apdu.len() < 4 { | ||
| 136 | return Err(ApduParseError); | ||
| 137 | } | ||
| 138 | |||
| 139 | let (data, le) = match apdu.len() - 4 { | ||
| 140 | 0 => (&[][..], 0), | ||
| 141 | 1 => (&[][..], apdu[4]), | ||
| 142 | n if n == 1 + apdu[4] as usize && apdu[4] != 0 => (&apdu[5..][..apdu[4] as usize], 0), | ||
| 143 | n if n == 2 + apdu[4] as usize && apdu[4] != 0 => (&apdu[5..][..apdu[4] as usize], apdu[apdu.len() - 1]), | ||
| 144 | _ => return Err(ApduParseError), | ||
| 145 | }; | ||
| 146 | |||
| 147 | Ok(Apdu { | ||
| 148 | cla: apdu[0], | ||
| 149 | ins: apdu[1], | ||
| 150 | p1: apdu[2], | ||
| 151 | p2: apdu[3], | ||
| 152 | data, | ||
| 153 | le: le as _, | ||
| 154 | }) | ||
| 155 | } | ||
| 156 | } | ||
| 157 | |||
| 158 | mod iso14443_3 { | ||
| 159 | use core::future::Future; | ||
| 160 | |||
| 161 | use defmt::info; | ||
| 162 | use embassy_nrf::nfct::{Error, NfcT}; | ||
| 163 | |||
| 164 | pub trait Card { | ||
| 165 | type Error; | ||
| 166 | async fn receive(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error>; | ||
| 167 | async fn transmit(&mut self, buf: &[u8]) -> Result<(), Self::Error>; | ||
| 168 | } | ||
| 169 | |||
| 170 | impl<'a, T: Card> Card for &'a mut T { | ||
| 171 | type Error = T::Error; | ||
| 172 | |||
| 173 | fn receive(&mut self, buf: &mut [u8]) -> impl Future<Output = Result<usize, Self::Error>> { | ||
| 174 | T::receive(self, buf) | ||
| 175 | } | ||
| 176 | |||
| 177 | fn transmit(&mut self, buf: &[u8]) -> impl Future<Output = Result<(), Self::Error>> { | ||
| 178 | T::transmit(self, buf) | ||
| 179 | } | ||
| 180 | } | ||
| 181 | |||
| 182 | impl<'a> Card for NfcT<'a> { | ||
| 183 | type Error = Error; | ||
| 184 | |||
| 185 | fn receive(&mut self, buf: &mut [u8]) -> impl Future<Output = Result<usize, Self::Error>> { | ||
| 186 | self.receive(buf) | ||
| 187 | } | ||
| 188 | |||
| 189 | fn transmit(&mut self, buf: &[u8]) -> impl Future<Output = Result<(), Self::Error>> { | ||
| 190 | self.transmit(buf) | ||
| 191 | } | ||
| 192 | } | ||
| 193 | |||
| 194 | pub struct Logger<T: Card>(pub T); | ||
| 195 | |||
| 196 | impl<T: Card> Card for Logger<T> { | ||
| 197 | type Error = T::Error; | ||
| 198 | |||
| 199 | async fn receive(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { | ||
| 200 | let n = T::receive(&mut self.0, buf).await?; | ||
| 201 | info!("<- {:02x}", &buf[..n]); | ||
| 202 | Ok(n) | ||
| 203 | } | ||
| 204 | |||
| 205 | fn transmit(&mut self, buf: &[u8]) -> impl Future<Output = Result<(), Self::Error>> { | ||
| 206 | info!("-> {:02x}", buf); | ||
| 207 | T::transmit(&mut self.0, buf) | ||
| 208 | } | ||
| 209 | } | ||
| 210 | } | ||
| 211 | |||
| 212 | mod iso14443_4 { | ||
| 213 | use defmt::info; | ||
| 214 | |||
| 215 | use crate::iso14443_3; | ||
| 216 | |||
| 217 | #[derive(defmt::Format)] | ||
| 218 | pub enum Error<T> { | ||
| 219 | Deselected, | ||
| 220 | Protocol, | ||
| 221 | Lower(T), | ||
| 222 | } | ||
| 223 | |||
| 224 | pub trait Card { | ||
| 225 | type Error; | ||
| 226 | async fn receive(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error>; | ||
| 227 | async fn transmit(&mut self, buf: &[u8]) -> Result<(), Self::Error>; | ||
| 228 | } | ||
| 229 | |||
| 230 | pub struct IsoDep<T: iso14443_3::Card> { | ||
| 231 | nfc: T, | ||
| 232 | |||
| 233 | /// Block count spin bit: 0 or 1 | ||
| 234 | block_num: u8, | ||
| 235 | |||
| 236 | /// true if deselected. This is permanent, you must create another IsoDep | ||
| 237 | /// instance if we get selected again. | ||
| 238 | deselected: bool, | ||
| 239 | |||
| 240 | /// last response, in case we need to retransmit. | ||
| 241 | resp: [u8; 256], | ||
| 242 | resp_len: usize, | ||
| 243 | } | ||
| 244 | |||
| 245 | impl<T: iso14443_3::Card> IsoDep<T> { | ||
| 246 | pub fn new(nfc: T) -> Self { | ||
| 247 | Self { | ||
| 248 | nfc, | ||
| 249 | block_num: 1, | ||
| 250 | deselected: false, | ||
| 251 | resp: [0u8; 256], | ||
| 252 | resp_len: 0, | ||
| 76 | } | 253 | } |
| 77 | } | 254 | } |
| 78 | } | 255 | } |
| 256 | |||
| 257 | impl<T: iso14443_3::Card> Card for IsoDep<T> { | ||
| 258 | type Error = Error<T::Error>; | ||
| 259 | |||
| 260 | async fn receive(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { | ||
| 261 | if self.deselected { | ||
| 262 | return Err(Error::Deselected); | ||
| 263 | } | ||
| 264 | |||
| 265 | let mut temp = [0u8; 256]; | ||
| 266 | |||
| 267 | loop { | ||
| 268 | let n = self.nfc.receive(&mut temp).await.map_err(Error::Lower)?; | ||
| 269 | assert!(n != 0); | ||
| 270 | match temp[0] { | ||
| 271 | 0x02 | 0x03 => { | ||
| 272 | self.block_num ^= 0x01; | ||
| 273 | assert!(temp[0] == 0x02 | self.block_num); | ||
| 274 | buf[..n - 1].copy_from_slice(&temp[1..n]); | ||
| 275 | return Ok(n - 1); | ||
| 276 | } | ||
| 277 | 0xb2 | 0xb3 => { | ||
| 278 | if temp[0] & 0x01 != self.block_num { | ||
| 279 | info!("Got NAK, transmitting ACK."); | ||
| 280 | let resp = &[0xA2 | self.block_num]; | ||
| 281 | self.nfc.transmit(resp).await.map_err(Error::Lower)?; | ||
| 282 | } else { | ||
| 283 | info!("Got NAK, retransmitting."); | ||
| 284 | let resp: &[u8] = &self.resp[..self.resp_len]; | ||
| 285 | self.nfc.transmit(resp).await.map_err(Error::Lower)?; | ||
| 286 | } | ||
| 287 | } | ||
| 288 | 0xe0 => { | ||
| 289 | info!("Got RATS, tx'ing ATS"); | ||
| 290 | let resp = &[0x06, 0x77, 0x77, 0x81, 0x02, 0x80]; | ||
| 291 | self.nfc.transmit(resp).await.map_err(Error::Lower)?; | ||
| 292 | } | ||
| 293 | 0xc2 => { | ||
| 294 | info!("Got deselect!"); | ||
| 295 | self.deselected = true; | ||
| 296 | let resp = &[0xC2]; | ||
| 297 | self.nfc.transmit(resp).await.map_err(Error::Lower)?; | ||
| 298 | return Err(Error::Deselected); | ||
| 299 | } | ||
| 300 | _ => { | ||
| 301 | info!("Got unknown command {:02x}!", temp[0]); | ||
| 302 | return Err(Error::Protocol); | ||
| 303 | } | ||
| 304 | }; | ||
| 305 | } | ||
| 306 | } | ||
| 307 | |||
| 308 | async fn transmit(&mut self, buf: &[u8]) -> Result<(), Self::Error> { | ||
| 309 | if self.deselected { | ||
| 310 | return Err(Error::Deselected); | ||
| 311 | } | ||
| 312 | |||
| 313 | self.resp[0] = 0x02 | self.block_num; | ||
| 314 | self.resp[1..][..buf.len()].copy_from_slice(buf); | ||
| 315 | self.resp_len = 1 + buf.len(); | ||
| 316 | |||
| 317 | let resp: &[u8] = &self.resp[..self.resp_len]; | ||
| 318 | self.nfc.transmit(resp).await.map_err(Error::Lower)?; | ||
| 319 | |||
| 320 | Ok(()) | ||
| 321 | } | ||
| 322 | } | ||
| 79 | } | 323 | } |
diff --git a/examples/nrf52840/src/bin/pubsub.rs b/examples/nrf52840/src/bin/pubsub.rs index 5ebea9220..c0392b18c 100644 --- a/examples/nrf52840/src/bin/pubsub.rs +++ b/examples/nrf52840/src/bin/pubsub.rs | |||
| @@ -26,9 +26,9 @@ async fn main(spawner: Spawner) { | |||
| 26 | // It's good to set up the subscribers before publishing anything. | 26 | // It's good to set up the subscribers before publishing anything. |
| 27 | // A subscriber will only yield messages that have been published after its creation. | 27 | // A subscriber will only yield messages that have been published after its creation. |
| 28 | 28 | ||
| 29 | spawner.must_spawn(fast_logger(unwrap!(MESSAGE_BUS.subscriber()))); | 29 | spawner.spawn(fast_logger(unwrap!(MESSAGE_BUS.subscriber())).unwrap()); |
| 30 | spawner.must_spawn(slow_logger(unwrap!(MESSAGE_BUS.dyn_subscriber()))); | 30 | spawner.spawn(slow_logger(unwrap!(MESSAGE_BUS.dyn_subscriber())).unwrap()); |
| 31 | spawner.must_spawn(slow_logger_pure(unwrap!(MESSAGE_BUS.dyn_subscriber()))); | 31 | spawner.spawn(slow_logger_pure(unwrap!(MESSAGE_BUS.dyn_subscriber())).unwrap()); |
| 32 | 32 | ||
| 33 | // Get a publisher | 33 | // Get a publisher |
| 34 | let message_publisher = unwrap!(MESSAGE_BUS.publisher()); | 34 | let message_publisher = unwrap!(MESSAGE_BUS.publisher()); |
diff --git a/examples/nrf52840/src/bin/raw_spawn.rs b/examples/nrf52840/src/bin/raw_spawn.rs index 717b0faa6..b80954408 100644 --- a/examples/nrf52840/src/bin/raw_spawn.rs +++ b/examples/nrf52840/src/bin/raw_spawn.rs | |||
| @@ -42,8 +42,8 @@ fn main() -> ! { | |||
| 42 | let run2_task = unsafe { make_static(&run2_task) }; | 42 | let run2_task = unsafe { make_static(&run2_task) }; |
| 43 | 43 | ||
| 44 | executor.run(|spawner| { | 44 | executor.run(|spawner| { |
| 45 | unwrap!(spawner.spawn(run1_task.spawn(|| run1()))); | 45 | spawner.spawn(unwrap!(run1_task.spawn(|| run1()))); |
| 46 | unwrap!(spawner.spawn(run2_task.spawn(|| run2()))); | 46 | spawner.spawn(unwrap!(run2_task.spawn(|| run2()))); |
| 47 | }); | 47 | }); |
| 48 | } | 48 | } |
| 49 | 49 | ||
diff --git a/examples/nrf52840/src/bin/rng.rs b/examples/nrf52840/src/bin/rng.rs index 326054c9a..f32d17cd9 100644..100755 --- a/examples/nrf52840/src/bin/rng.rs +++ b/examples/nrf52840/src/bin/rng.rs | |||
| @@ -22,7 +22,7 @@ async fn main(_spawner: Spawner) { | |||
| 22 | defmt::info!("Some random bytes: {:?}", bytes); | 22 | defmt::info!("Some random bytes: {:?}", bytes); |
| 23 | 23 | ||
| 24 | // Sync API with `rand` | 24 | // Sync API with `rand` |
| 25 | defmt::info!("A random number from 1 to 10: {:?}", rng.gen_range(1..=10)); | 25 | defmt::info!("A random number from 1 to 10: {:?}", rng.random_range(1..=10)); |
| 26 | 26 | ||
| 27 | let mut bytes = [0; 1024]; | 27 | let mut bytes = [0; 1024]; |
| 28 | rng.fill_bytes(&mut bytes).await; | 28 | rng.fill_bytes(&mut bytes).await; |
diff --git a/examples/nrf52840/src/bin/self_spawn.rs b/examples/nrf52840/src/bin/self_spawn.rs index 5bfefc2af..acb44f98b 100644 --- a/examples/nrf52840/src/bin/self_spawn.rs +++ b/examples/nrf52840/src/bin/self_spawn.rs | |||
| @@ -14,12 +14,12 @@ mod config { | |||
| 14 | async fn my_task(spawner: Spawner, n: u32) { | 14 | async fn my_task(spawner: Spawner, n: u32) { |
| 15 | Timer::after_secs(1).await; | 15 | Timer::after_secs(1).await; |
| 16 | info!("Spawning self! {}", n); | 16 | info!("Spawning self! {}", n); |
| 17 | unwrap!(spawner.spawn(my_task(spawner, n + 1))); | 17 | spawner.spawn(unwrap!(my_task(spawner, n + 1))); |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | #[embassy_executor::main] | 20 | #[embassy_executor::main] |
| 21 | async fn main(spawner: Spawner) { | 21 | async fn main(spawner: Spawner) { |
| 22 | let _p = embassy_nrf::init(Default::default()); | 22 | let _p = embassy_nrf::init(Default::default()); |
| 23 | info!("Hello World!"); | 23 | info!("Hello World!"); |
| 24 | unwrap!(spawner.spawn(my_task(spawner, 0))); | 24 | spawner.spawn(unwrap!(my_task(spawner, 0))); |
| 25 | } | 25 | } |
diff --git a/examples/nrf52840/src/bin/self_spawn_current_executor.rs b/examples/nrf52840/src/bin/self_spawn_current_executor.rs index ec9569a64..d93067592 100644 --- a/examples/nrf52840/src/bin/self_spawn_current_executor.rs +++ b/examples/nrf52840/src/bin/self_spawn_current_executor.rs | |||
| @@ -10,12 +10,13 @@ use {defmt_rtt as _, panic_probe as _}; | |||
| 10 | async fn my_task(n: u32) { | 10 | async fn my_task(n: u32) { |
| 11 | Timer::after_secs(1).await; | 11 | Timer::after_secs(1).await; |
| 12 | info!("Spawning self! {}", n); | 12 | info!("Spawning self! {}", n); |
| 13 | unwrap!(Spawner::for_current_executor().await.spawn(my_task(n + 1))); | 13 | let spawner = unsafe { Spawner::for_current_executor().await }; |
| 14 | spawner.spawn(unwrap!(my_task(n + 1))); | ||
| 14 | } | 15 | } |
| 15 | 16 | ||
| 16 | #[embassy_executor::main] | 17 | #[embassy_executor::main] |
| 17 | async fn main(spawner: Spawner) { | 18 | async fn main(spawner: Spawner) { |
| 18 | let _p = embassy_nrf::init(Default::default()); | 19 | let _p = embassy_nrf::init(Default::default()); |
| 19 | info!("Hello World!"); | 20 | info!("Hello World!"); |
| 20 | unwrap!(spawner.spawn(my_task(0))); | 21 | spawner.spawn(unwrap!(my_task(0))); |
| 21 | } | 22 | } |
diff --git a/examples/nrf52840/src/bin/sixlowpan.rs b/examples/nrf52840/src/bin/sixlowpan.rs new file mode 100644 index 000000000..00a597366 --- /dev/null +++ b/examples/nrf52840/src/bin/sixlowpan.rs | |||
| @@ -0,0 +1,120 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use core::net::Ipv6Addr; | ||
| 5 | |||
| 6 | use defmt::{info, unwrap, warn}; | ||
| 7 | use embassy_executor::Spawner; | ||
| 8 | use embassy_net::udp::{PacketMetadata, UdpMetadata, UdpSocket}; | ||
| 9 | use embassy_net::{IpAddress, IpEndpoint, IpListenEndpoint, Ipv6Cidr, StackResources, StaticConfigV6}; | ||
| 10 | use embassy_nrf::config::{Config, HfclkSource}; | ||
| 11 | use embassy_nrf::rng::Rng; | ||
| 12 | use embassy_nrf::{bind_interrupts, embassy_net_802154_driver as net, peripherals, radio}; | ||
| 13 | use embassy_time::Delay; | ||
| 14 | use embedded_hal_async::delay::DelayNs; | ||
| 15 | use static_cell::StaticCell; | ||
| 16 | use {defmt_rtt as _, panic_probe as _}; | ||
| 17 | |||
| 18 | bind_interrupts!(struct Irqs { | ||
| 19 | RADIO => radio::InterruptHandler<peripherals::RADIO>; | ||
| 20 | RNG => embassy_nrf::rng::InterruptHandler<peripherals::RNG>; | ||
| 21 | }); | ||
| 22 | |||
| 23 | #[embassy_executor::task] | ||
| 24 | async fn ieee802154_task(runner: net::Runner<'static, peripherals::RADIO>) -> ! { | ||
| 25 | runner.run().await | ||
| 26 | } | ||
| 27 | |||
| 28 | #[embassy_executor::task] | ||
| 29 | async fn net_task(mut runner: embassy_net::Runner<'static, net::Device<'static>>) -> ! { | ||
| 30 | runner.run().await | ||
| 31 | } | ||
| 32 | |||
| 33 | #[embassy_executor::main] | ||
| 34 | async fn main(spawner: Spawner) { | ||
| 35 | let mut config = Config::default(); | ||
| 36 | // Necessary to run the radio nrf52840 v1.11 5.4.1 | ||
| 37 | config.hfclk_source = HfclkSource::ExternalXtal; | ||
| 38 | let p = embassy_nrf::init(config); | ||
| 39 | |||
| 40 | let mac_addr: [u8; 8] = [2, 3, 4, 5, 6, 7, 8, 9]; | ||
| 41 | static NRF802154_STATE: StaticCell<net::State<20, 20>> = StaticCell::new(); | ||
| 42 | let (device, runner) = net::new(mac_addr, p.RADIO, Irqs, NRF802154_STATE.init(net::State::new())) | ||
| 43 | .await | ||
| 44 | .unwrap(); | ||
| 45 | |||
| 46 | spawner.spawn(unwrap!(ieee802154_task(runner))); | ||
| 47 | |||
| 48 | // Swap these when flashing a second board | ||
| 49 | let peer = Ipv6Addr::new(0xfe80, 0, 0, 0, 0xd701, 0xda3f, 0x3955, 0x82a4); | ||
| 50 | let local = Ipv6Addr::new(0xfe80, 0, 0, 0, 0xd701, 0xda3f, 0x3955, 0x82a5); | ||
| 51 | |||
| 52 | let config = embassy_net::Config::ipv6_static(StaticConfigV6 { | ||
| 53 | address: Ipv6Cidr::new(local, 64), | ||
| 54 | gateway: None, | ||
| 55 | dns_servers: Default::default(), | ||
| 56 | }); | ||
| 57 | |||
| 58 | // Generate random seed | ||
| 59 | let mut rng = Rng::new(p.RNG, Irqs); | ||
| 60 | let mut seed = [0; 8]; | ||
| 61 | rng.blocking_fill_bytes(&mut seed); | ||
| 62 | let seed = u64::from_le_bytes(seed); | ||
| 63 | |||
| 64 | // Init network stack | ||
| 65 | static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new(); | ||
| 66 | let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed); | ||
| 67 | |||
| 68 | spawner.spawn(unwrap!(net_task(runner))); | ||
| 69 | |||
| 70 | let mut rx_buffer = [0; 2096]; | ||
| 71 | let mut tx_buffer = [0; 2096]; | ||
| 72 | let mut tx_m_buffer = [PacketMetadata::EMPTY; 5]; | ||
| 73 | let mut rx_m_buffer = [PacketMetadata::EMPTY; 5]; | ||
| 74 | |||
| 75 | let mut delay = Delay; | ||
| 76 | loop { | ||
| 77 | let mut socket = UdpSocket::new( | ||
| 78 | stack, | ||
| 79 | &mut tx_m_buffer, | ||
| 80 | &mut rx_buffer, | ||
| 81 | &mut rx_m_buffer, | ||
| 82 | &mut tx_buffer, | ||
| 83 | ); | ||
| 84 | socket | ||
| 85 | .bind(IpListenEndpoint { | ||
| 86 | addr: Some(IpAddress::Ipv6(local)), | ||
| 87 | port: 1234, | ||
| 88 | }) | ||
| 89 | .unwrap(); | ||
| 90 | let rep = UdpMetadata { | ||
| 91 | endpoint: IpEndpoint { | ||
| 92 | addr: IpAddress::Ipv6(peer), | ||
| 93 | port: 1234, | ||
| 94 | }, | ||
| 95 | local_address: Some(IpAddress::Ipv6(local)), | ||
| 96 | meta: Default::default(), | ||
| 97 | }; | ||
| 98 | |||
| 99 | info!("Listening on {:?} UDP:1234...", local); | ||
| 100 | |||
| 101 | let mut recv_buf = [0; 12]; | ||
| 102 | loop { | ||
| 103 | delay.delay_ms(2000).await; | ||
| 104 | if socket.may_recv() { | ||
| 105 | let n = match socket.recv_from(&mut recv_buf).await { | ||
| 106 | Ok((0, _)) => panic!(), | ||
| 107 | Ok((n, _)) => n, | ||
| 108 | Err(e) => { | ||
| 109 | warn!("read error: {:?}", e); | ||
| 110 | break; | ||
| 111 | } | ||
| 112 | }; | ||
| 113 | info!("Received {:02x}", &recv_buf[..n]); | ||
| 114 | } | ||
| 115 | |||
| 116 | info!("Sending"); | ||
| 117 | socket.send_to(b"Hello World", rep).await.unwrap(); | ||
| 118 | } | ||
| 119 | } | ||
| 120 | } | ||
diff --git a/examples/nrf52840/src/bin/timer.rs b/examples/nrf52840/src/bin/timer.rs index 365695a20..5331ac246 100644 --- a/examples/nrf52840/src/bin/timer.rs +++ b/examples/nrf52840/src/bin/timer.rs | |||
| @@ -25,6 +25,6 @@ async fn run2() { | |||
| 25 | #[embassy_executor::main] | 25 | #[embassy_executor::main] |
| 26 | async fn main(spawner: Spawner) { | 26 | async fn main(spawner: Spawner) { |
| 27 | let _p = embassy_nrf::init(Default::default()); | 27 | let _p = embassy_nrf::init(Default::default()); |
| 28 | unwrap!(spawner.spawn(run1())); | 28 | spawner.spawn(unwrap!(run1())); |
| 29 | unwrap!(spawner.spawn(run2())); | 29 | spawner.spawn(unwrap!(run2())); |
| 30 | } | 30 | } |
diff --git a/examples/nrf52840/src/bin/uart_split.rs b/examples/nrf52840/src/bin/uart_split.rs index 46be8f636..51af90727 100644 --- a/examples/nrf52840/src/bin/uart_split.rs +++ b/examples/nrf52840/src/bin/uart_split.rs | |||
| @@ -30,7 +30,7 @@ async fn main(spawner: Spawner) { | |||
| 30 | 30 | ||
| 31 | // Spawn a task responsible purely for reading | 31 | // Spawn a task responsible purely for reading |
| 32 | 32 | ||
| 33 | unwrap!(spawner.spawn(reader(rx))); | 33 | spawner.spawn(unwrap!(reader(rx))); |
| 34 | 34 | ||
| 35 | // Message must be in SRAM | 35 | // Message must be in SRAM |
| 36 | { | 36 | { |
diff --git a/examples/nrf52840/src/bin/usb_ethernet.rs b/examples/nrf52840/src/bin/usb_ethernet.rs index 49856012d..87aa4c6c5 100644 --- a/examples/nrf52840/src/bin/usb_ethernet.rs +++ b/examples/nrf52840/src/bin/usb_ethernet.rs | |||
| @@ -86,11 +86,11 @@ async fn main(spawner: Spawner) { | |||
| 86 | // Build the builder. | 86 | // Build the builder. |
| 87 | let usb = builder.build(); | 87 | let usb = builder.build(); |
| 88 | 88 | ||
| 89 | unwrap!(spawner.spawn(usb_task(usb))); | 89 | spawner.spawn(unwrap!(usb_task(usb))); |
| 90 | 90 | ||
| 91 | static NET_STATE: StaticCell<NetState<MTU, 4, 4>> = StaticCell::new(); | 91 | static NET_STATE: StaticCell<NetState<MTU, 4, 4>> = StaticCell::new(); |
| 92 | let (runner, device) = class.into_embassy_net_device::<MTU, 4, 4>(NET_STATE.init(NetState::new()), our_mac_addr); | 92 | let (runner, device) = class.into_embassy_net_device::<MTU, 4, 4>(NET_STATE.init(NetState::new()), our_mac_addr); |
| 93 | unwrap!(spawner.spawn(usb_ncm_task(runner))); | 93 | spawner.spawn(unwrap!(usb_ncm_task(runner))); |
| 94 | 94 | ||
| 95 | let config = embassy_net::Config::dhcpv4(Default::default()); | 95 | let config = embassy_net::Config::dhcpv4(Default::default()); |
| 96 | // let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 { | 96 | // let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 { |
| @@ -109,7 +109,7 @@ async fn main(spawner: Spawner) { | |||
| 109 | static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new(); | 109 | static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new(); |
| 110 | let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed); | 110 | let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed); |
| 111 | 111 | ||
| 112 | unwrap!(spawner.spawn(net_task(runner))); | 112 | spawner.spawn(unwrap!(net_task(runner))); |
| 113 | 113 | ||
| 114 | // And now we can use it! | 114 | // And now we can use it! |
| 115 | 115 | ||
diff --git a/examples/nrf52840/src/bin/usb_serial_multitask.rs b/examples/nrf52840/src/bin/usb_serial_multitask.rs index 5e5b4de35..00a91a233 100644 --- a/examples/nrf52840/src/bin/usb_serial_multitask.rs +++ b/examples/nrf52840/src/bin/usb_serial_multitask.rs | |||
| @@ -76,8 +76,8 @@ async fn main(spawner: Spawner) { | |||
| 76 | // Build the builder. | 76 | // Build the builder. |
| 77 | let usb = builder.build(); | 77 | let usb = builder.build(); |
| 78 | 78 | ||
| 79 | unwrap!(spawner.spawn(usb_task(usb))); | 79 | spawner.spawn(unwrap!(usb_task(usb))); |
| 80 | unwrap!(spawner.spawn(echo_task(class))); | 80 | spawner.spawn(unwrap!(echo_task(class))); |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | struct Disconnected {} | 83 | struct Disconnected {} |
diff --git a/examples/nrf52840/src/bin/wifi_esp_hosted.rs b/examples/nrf52840/src/bin/wifi_esp_hosted.rs index 26eaf485e..2dd9abfaa 100644 --- a/examples/nrf52840/src/bin/wifi_esp_hosted.rs +++ b/examples/nrf52840/src/bin/wifi_esp_hosted.rs | |||
| @@ -70,7 +70,7 @@ async fn main(spawner: Spawner) { | |||
| 70 | ) | 70 | ) |
| 71 | .await; | 71 | .await; |
| 72 | 72 | ||
| 73 | unwrap!(spawner.spawn(wifi_task(runner))); | 73 | spawner.spawn(unwrap!(wifi_task(runner))); |
| 74 | 74 | ||
| 75 | unwrap!(control.init().await); | 75 | unwrap!(control.init().await); |
| 76 | unwrap!(control.connect(WIFI_NETWORK, WIFI_PASSWORD).await); | 76 | unwrap!(control.connect(WIFI_NETWORK, WIFI_PASSWORD).await); |
| @@ -92,7 +92,7 @@ async fn main(spawner: Spawner) { | |||
| 92 | static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new(); | 92 | static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new(); |
| 93 | let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed); | 93 | let (stack, runner) = embassy_net::new(device, config, RESOURCES.init(StackResources::new()), seed); |
| 94 | 94 | ||
| 95 | unwrap!(spawner.spawn(net_task(runner))); | 95 | spawner.spawn(unwrap!(net_task(runner))); |
| 96 | 96 | ||
| 97 | // And now we can use it! | 97 | // And now we can use it! |
| 98 | 98 | ||
