aboutsummaryrefslogtreecommitdiff
path: root/examples/nrf52840/src/bin
diff options
context:
space:
mode:
Diffstat (limited to 'examples/nrf52840/src/bin')
-rw-r--r--examples/nrf52840/src/bin/channel.rs2
-rw-r--r--examples/nrf52840/src/bin/channel_sender_receiver.rs4
-rw-r--r--examples/nrf52840/src/bin/ethernet_enc28j60.rs2
-rw-r--r--examples/nrf52840/src/bin/executor_fairness_test.rs6
-rw-r--r--examples/nrf52840/src/bin/gpiote_port.rs8
-rw-r--r--examples/nrf52840/src/bin/ieee802154_receive.rs38
-rw-r--r--examples/nrf52840/src/bin/ieee802154_send.rs39
-rw-r--r--examples/nrf52840/src/bin/manually_create_executor.rs4
-rw-r--r--examples/nrf52840/src/bin/multiprio.rs6
-rw-r--r--examples/nrf52840/src/bin/mutex.rs2
-rw-r--r--examples/nrf52840/src/bin/nfct.rs274
-rw-r--r--examples/nrf52840/src/bin/pubsub.rs6
-rw-r--r--examples/nrf52840/src/bin/raw_spawn.rs4
-rwxr-xr-x[-rw-r--r--]examples/nrf52840/src/bin/rng.rs2
-rw-r--r--examples/nrf52840/src/bin/self_spawn.rs4
-rw-r--r--examples/nrf52840/src/bin/self_spawn_current_executor.rs5
-rw-r--r--examples/nrf52840/src/bin/sixlowpan.rs120
-rw-r--r--examples/nrf52840/src/bin/timer.rs4
-rw-r--r--examples/nrf52840/src/bin/uart_split.rs2
-rw-r--r--examples/nrf52840/src/bin/usb_ethernet.rs6
-rw-r--r--examples/nrf52840/src/bin/usb_serial_multitask.rs4
-rw-r--r--examples/nrf52840/src/bin/wifi_esp_hosted.rs4
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]
37async fn main(spawner: Spawner) { 37async 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
4use embassy_executor::Spawner;
5use embassy_nrf::config::{Config, HfclkSource};
6use embassy_nrf::gpio::{Level, Output, OutputDrive};
7use embassy_nrf::radio::ieee802154::{self, Packet};
8use embassy_nrf::{peripherals, radio};
9use embassy_time::Timer;
10use {defmt_rtt as _, panic_probe as _};
11
12embassy_nrf::bind_interrupts!(struct Irqs {
13 RADIO => radio::InterruptHandler<peripherals::RADIO>;
14});
15
16#[embassy_executor::main]
17async 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
4use embassy_executor::Spawner;
5use embassy_nrf::config::{Config, HfclkSource};
6use embassy_nrf::gpio::{Level, Output, OutputDrive};
7use embassy_nrf::radio::ieee802154::{self, Packet};
8use embassy_nrf::{peripherals, radio};
9use embassy_time::Timer;
10use {defmt_rtt as _, panic_probe as _};
11
12embassy_nrf::bind_interrupts!(struct Irqs {
13 RADIO => radio::InterruptHandler<peripherals::RADIO>;
14});
15
16#[embassy_executor::main]
17async 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]
31async fn main(spawner: Spawner) { 31async 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
4use defmt::*; 4use defmt::{todo, *};
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_nrf::config::HfclkSource; 6use embassy_nrf::config::HfclkSource;
7use embassy_nrf::nfct::{Config as NfcConfig, NfcId, NfcT}; 7use embassy_nrf::nfct::{Config as NfcConfig, NfcId, NfcT};
8use embassy_nrf::{bind_interrupts, nfct}; 8use embassy_nrf::{bind_interrupts, nfct};
9use iso14443_4::{Card, IsoDep};
9use {defmt_rtt as _, embassy_nrf as _, panic_probe as _}; 10use {defmt_rtt as _, embassy_nrf as _, panic_probe as _};
10 11
11bind_interrupts!(struct Irqs { 12bind_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; 121struct 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)]
131struct ApduParseError;
132
133impl<'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
158mod 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
212mod 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 {
14async fn my_task(spawner: Spawner, n: u32) { 14async 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]
21async fn main(spawner: Spawner) { 21async 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 _};
10async fn my_task(n: u32) { 10async 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]
17async fn main(spawner: Spawner) { 18async 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
4use core::net::Ipv6Addr;
5
6use defmt::{info, unwrap, warn};
7use embassy_executor::Spawner;
8use embassy_net::udp::{PacketMetadata, UdpMetadata, UdpSocket};
9use embassy_net::{IpAddress, IpEndpoint, IpListenEndpoint, Ipv6Cidr, StackResources, StaticConfigV6};
10use embassy_nrf::config::{Config, HfclkSource};
11use embassy_nrf::rng::Rng;
12use embassy_nrf::{bind_interrupts, embassy_net_802154_driver as net, peripherals, radio};
13use embassy_time::Delay;
14use embedded_hal_async::delay::DelayNs;
15use static_cell::StaticCell;
16use {defmt_rtt as _, panic_probe as _};
17
18bind_interrupts!(struct Irqs {
19 RADIO => radio::InterruptHandler<peripherals::RADIO>;
20 RNG => embassy_nrf::rng::InterruptHandler<peripherals::RNG>;
21});
22
23#[embassy_executor::task]
24async fn ieee802154_task(runner: net::Runner<'static, peripherals::RADIO>) -> ! {
25 runner.run().await
26}
27
28#[embassy_executor::task]
29async fn net_task(mut runner: embassy_net::Runner<'static, net::Device<'static>>) -> ! {
30 runner.run().await
31}
32
33#[embassy_executor::main]
34async 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]
26async fn main(spawner: Spawner) { 26async 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
83struct Disconnected {} 83struct 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