aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32-wpan/src/mac/driver.rs8
-rw-r--r--embassy-stm32-wpan/src/mac/mod.rs9
-rw-r--r--embassy-stm32-wpan/src/mac/runner.rs75
-rw-r--r--examples/stm32wb/src/bin/mac_ffd_net.rs180
4 files changed, 255 insertions, 17 deletions
diff --git a/embassy-stm32-wpan/src/mac/driver.rs b/embassy-stm32-wpan/src/mac/driver.rs
index 00072749b..118f6908f 100644
--- a/embassy-stm32-wpan/src/mac/driver.rs
+++ b/embassy-stm32-wpan/src/mac/driver.rs
@@ -25,6 +25,8 @@ impl<'d> embassy_net_driver::Driver for Driver<'d> {
25 type TxToken<'a> = TxToken where Self: 'a; 25 type TxToken<'a> = TxToken where Self: 'a;
26 26
27 fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { 27 fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
28 self.runner.rx_waker.register(cx.waker());
29
28 // WAKER.register(cx.waker()); 30 // WAKER.register(cx.waker());
29 // if self.rx.available().is_some() && self.tx.available().is_some() { 31 // if self.rx.available().is_some() && self.tx.available().is_some() {
30 // Some((RxToken { rx: &mut self.rx }, TxToken { tx: &mut self.tx })) 32 // Some((RxToken { rx: &mut self.rx }, TxToken { tx: &mut self.tx }))
@@ -36,6 +38,8 @@ impl<'d> embassy_net_driver::Driver for Driver<'d> {
36 } 38 }
37 39
38 fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>> { 40 fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>> {
41 self.runner.tx_waker.register(cx.waker());
42
39 // WAKER.register(cx.waker()); 43 // WAKER.register(cx.waker());
40 // / if self.tx.available().is_some() { 44 // / if self.tx.available().is_some() {
41 // / Some(TxToken { tx: &mut self.tx }) 45 // / Some(TxToken { tx: &mut self.tx })
@@ -84,7 +88,7 @@ impl embassy_net_driver::RxToken for RxToken {
84 // NOTE(unwrap): we checked the queue wasn't full when creating the token. 88 // NOTE(unwrap): we checked the queue wasn't full when creating the token.
85 // let pkt = unwrap!(self.rx.available()); 89 // let pkt = unwrap!(self.rx.available());
86 90
87 let pkt = &[]; 91 let pkt = &mut [];
88 let r = f(&mut pkt[0..]); 92 let r = f(&mut pkt[0..]);
89 // self.rx.pop_packet(); 93 // self.rx.pop_packet();
90 r 94 r
@@ -102,7 +106,7 @@ impl embassy_net_driver::TxToken for TxToken {
102 { 106 {
103 // NOTE(unwrap): we checked the queue wasn't full when creating the token. 107 // NOTE(unwrap): we checked the queue wasn't full when creating the token.
104 // let pkt = unwrap!(self.tx.available()); 108 // let pkt = unwrap!(self.tx.available());
105 let pkt = &[]; 109 let pkt = &mut [];
106 let r = f(&mut pkt[..len]); 110 let r = f(&mut pkt[..len]);
107 // self.tx.transmit(len); 111 // self.tx.transmit(len);
108 r 112 r
diff --git a/embassy-stm32-wpan/src/mac/mod.rs b/embassy-stm32-wpan/src/mac/mod.rs
index e024aeae3..2f9d1c81e 100644
--- a/embassy-stm32-wpan/src/mac/mod.rs
+++ b/embassy-stm32-wpan/src/mac/mod.rs
@@ -15,16 +15,11 @@ use core::slice;
15pub use crate::mac::control::{Control, Error as ControlError}; 15pub use crate::mac::control::{Control, Error as ControlError};
16use crate::mac::driver::Driver; 16use crate::mac::driver::Driver;
17pub use crate::mac::runner::Runner; 17pub use crate::mac::runner::Runner;
18use crate::sub::mac::Mac;
19 18
20const MTU: usize = 127; 19const MTU: usize = 127;
21 20
22pub async fn new<'a>(mac: Mac) -> (Runner, Control<'a>, Driver<'a>) { 21pub async fn new<'a>(runner: &'a Runner) -> (Control<'a>, Driver<'a>) {
23 let runner = Runner::new(mac); 22 (Control::new(runner), Driver::new(runner))
24 let control = Control::new(&runner);
25 let driver = Driver::new(&runner);
26
27 (runner, control, driver)
28} 23}
29 24
30fn slice8_mut(x: &mut [u32]) -> &mut [u8] { 25fn slice8_mut(x: &mut [u32]) -> &mut [u8] {
diff --git a/embassy-stm32-wpan/src/mac/runner.rs b/embassy-stm32-wpan/src/mac/runner.rs
index e97c9c8e2..d545d6c96 100644
--- a/embassy-stm32-wpan/src/mac/runner.rs
+++ b/embassy-stm32-wpan/src/mac/runner.rs
@@ -1,27 +1,86 @@
1use embassy_futures::select::{select3, Either3}; 1use embassy_futures::select::{select3, Either3};
2use embassy_sync::waitqueue::AtomicWaker;
2 3
4use crate::mac::event::{Event, MacEvent};
3use crate::mac::MTU; 5use crate::mac::MTU;
4use crate::sub::mac::Mac; 6use crate::sub::mac::Mac;
5 7
8pub(crate) struct TxRing {
9 // stores n packets of up to mtu size
10 ring: [[u8; MTU]; 5],
11 pending: bool,
12 // start: u8,
13 // end: u8,
14}
15
16impl TxRing {
17 pub(crate) fn new() -> Self {
18 Self {
19 ring: [[0; MTU]; 5],
20 pending: false,
21 }
22 }
23
24 // wait for a free packet to become available
25 pub fn is_packet_free(&self) -> bool {
26 !self.pending
27 }
28
29 // get the next available free packet
30 pub fn get_free_packet<'a>(&'a mut self) -> &'a mut [u8] {
31 self.pending = true;
32
33 &mut self.ring[0]
34 }
35
36 pub fn get_packet_to_transmit<'a>(&'a mut self) -> Option<&'a [u8]> {
37 if self.pending {
38 self.pending = false;
39
40 Some(&self.ring[0])
41 } else {
42 None
43 }
44 }
45}
46
6pub struct Runner { 47pub struct Runner {
7 mac: Mac, 48 mac_subsystem: Mac,
8 // TODO: tx_ring 49 pub(crate) rx_ring: Option<Event>,
9 // TODO: rx_buf 50 pub(crate) tx_ring: TxRing,
51 pub(crate) rx_waker: AtomicWaker,
52 pub(crate) tx_waker: AtomicWaker,
10} 53}
11 54
12impl Runner { 55impl Runner {
13 pub(crate) fn new(mac: Mac) -> Self { 56 pub fn new(mac: Mac) -> Self {
14 Self { mac } 57 Self {
58 mac_subsystem: mac,
59 rx_ring: None,
60 tx_ring: TxRing::new(),
61 rx_waker: AtomicWaker::new(),
62 tx_waker: AtomicWaker::new(),
63 }
15 } 64 }
16 65
17 pub(crate) async fn init(&mut self, firmware: &[u8]) { 66 pub(crate) async fn init(&mut self, firmware: &[u8]) {
18 debug!("wifi init done"); 67 debug!("wifi init done");
19 } 68 }
20 69
21 pub async fn run(mut self) -> ! { 70 pub async fn run(&self) -> ! {
22 let mut buf = [0; 512];
23 loop { 71 loop {
24 // TODO 72 let event = self.mac_subsystem.read().await;
73 if let Ok(evt) = event.mac_event() {
74 match evt {
75 MacEvent::McpsDataInd(data_ind) => {
76 // TODO: store mac_event in rx_ring
77 self.rx_waker.wake();
78 }
79 _ => {}
80 }
81 }
82
83 // TODO: select tx event
25 } 84 }
26 } 85 }
27} 86}
diff --git a/examples/stm32wb/src/bin/mac_ffd_net.rs b/examples/stm32wb/src/bin/mac_ffd_net.rs
new file mode 100644
index 000000000..b1cf051bf
--- /dev/null
+++ b/examples/stm32wb/src/bin/mac_ffd_net.rs
@@ -0,0 +1,180 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5use defmt::*;
6use embassy_executor::Spawner;
7use embassy_stm32::bind_interrupts;
8use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
9use embassy_stm32_wpan::mac::commands::{AssociateResponse, ResetRequest, SetRequest, StartRequest};
10use embassy_stm32_wpan::mac::typedefs::{MacChannel, MacStatus, PanId, PibId, SecurityLevel};
11use embassy_stm32_wpan::mac::{self, Runner};
12use embassy_stm32_wpan::sub::mm;
13use embassy_stm32_wpan::TlMbox;
14use static_cell::make_static;
15use {defmt_rtt as _, panic_probe as _};
16
17bind_interrupts!(struct Irqs{
18 IPCC_C1_RX => ReceiveInterruptHandler;
19 IPCC_C1_TX => TransmitInterruptHandler;
20});
21
22#[embassy_executor::task]
23async fn run_mm_queue(memory_manager: mm::MemoryManager) {
24 memory_manager.run_queue().await;
25}
26
27#[embassy_executor::task]
28async fn run_mac(runner: &'static Runner) {
29 runner.run().await;
30}
31
32#[embassy_executor::main]
33async fn main(spawner: Spawner) {
34 /*
35 How to make this work:
36
37 - Obtain a NUCLEO-STM32WB55 from your preferred supplier.
38 - Download and Install STM32CubeProgrammer.
39 - Download stm32wb5x_FUS_fw.bin, stm32wb5x_BLE_Stack_full_fw.bin, and Release_Notes.html from
40 gh:STMicroelectronics/STM32CubeWB@2234d97/Projects/STM32WB_Copro_Wireless_Binaries/STM32WB5x
41 - Open STM32CubeProgrammer
42 - On the right-hand pane, click "firmware upgrade" to upgrade the st-link firmware.
43 - Once complete, click connect to connect to the device.
44 - On the left hand pane, click the RSS signal icon to open "Firmware Upgrade Services".
45 - In the Release_Notes.html, find the memory address that corresponds to your device for the stm32wb5x_FUS_fw.bin file
46 - Select that file, the memory address, "verify download", and then "Firmware Upgrade".
47 - Once complete, in the Release_Notes.html, find the memory address that corresponds to your device for the
48 stm32wb5x_BLE_Stack_full_fw.bin file. It should not be the same memory address.
49 - Select that file, the memory address, "verify download", and then "Firmware Upgrade".
50 - Select "Start Wireless Stack".
51 - Disconnect from the device.
52 - In the examples folder for stm32wb, modify the memory.x file to match your target device.
53 - Run this example.
54
55 Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name.
56 */
57
58 let p = embassy_stm32::init(Default::default());
59 info!("Hello World!");
60
61 let config = Config::default();
62 let mbox = TlMbox::init(p.IPCC, Irqs, config);
63
64 spawner.spawn(run_mm_queue(mbox.mm_subsystem)).unwrap();
65
66 let sys_event = mbox.sys_subsystem.read().await;
67 info!("sys event: {}", sys_event.payload());
68
69 core::mem::drop(sys_event);
70
71 let result = mbox.sys_subsystem.shci_c2_mac_802_15_4_init().await;
72 info!("initialized mac: {}", result);
73
74 info!("resetting");
75 mbox.mac_subsystem
76 .send_command(&ResetRequest {
77 set_default_pib: true,
78 ..Default::default()
79 })
80 .await
81 .unwrap();
82 {
83 let evt = mbox.mac_subsystem.read().await;
84 defmt::info!("{:#x}", evt.mac_event());
85 }
86
87 info!("setting extended address");
88 let extended_address: u64 = 0xACDE480000000001;
89 mbox.mac_subsystem
90 .send_command(&SetRequest {
91 pib_attribute_ptr: &extended_address as *const _ as *const u8,
92 pib_attribute: PibId::ExtendedAddress,
93 })
94 .await
95 .unwrap();
96 {
97 let evt = mbox.mac_subsystem.read().await;
98 defmt::info!("{:#x}", evt.mac_event());
99 }
100
101 info!("setting short address");
102 let short_address: u16 = 0x1122;
103 mbox.mac_subsystem
104 .send_command(&SetRequest {
105 pib_attribute_ptr: &short_address as *const _ as *const u8,
106 pib_attribute: PibId::ShortAddress,
107 })
108 .await
109 .unwrap();
110 {
111 let evt = mbox.mac_subsystem.read().await;
112 defmt::info!("{:#x}", evt.mac_event());
113 }
114
115 info!("setting association permit");
116 let association_permit: bool = true;
117 mbox.mac_subsystem
118 .send_command(&SetRequest {
119 pib_attribute_ptr: &association_permit as *const _ as *const u8,
120 pib_attribute: PibId::AssociationPermit,
121 })
122 .await
123 .unwrap();
124 {
125 let evt = mbox.mac_subsystem.read().await;
126 defmt::info!("{:#x}", evt.mac_event());
127 }
128
129 info!("setting TX power");
130 let transmit_power: i8 = 2;
131 mbox.mac_subsystem
132 .send_command(&SetRequest {
133 pib_attribute_ptr: &transmit_power as *const _ as *const u8,
134 pib_attribute: PibId::TransmitPower,
135 })
136 .await
137 .unwrap();
138 {
139 let evt = mbox.mac_subsystem.read().await;
140 defmt::info!("{:#x}", evt.mac_event());
141 }
142
143 info!("starting FFD device");
144 mbox.mac_subsystem
145 .send_command(&StartRequest {
146 pan_id: PanId([0x1A, 0xAA]),
147 channel_number: MacChannel::Channel16,
148 beacon_order: 0x0F,
149 superframe_order: 0x0F,
150 pan_coordinator: true,
151 battery_life_extension: false,
152 ..Default::default()
153 })
154 .await
155 .unwrap();
156 {
157 let evt = mbox.mac_subsystem.read().await;
158 defmt::info!("{:#x}", evt.mac_event());
159 }
160
161 info!("setting RX on when idle");
162 let rx_on_while_idle: bool = true;
163 mbox.mac_subsystem
164 .send_command(&SetRequest {
165 pib_attribute_ptr: &rx_on_while_idle as *const _ as *const u8,
166 pib_attribute: PibId::RxOnWhenIdle,
167 })
168 .await
169 .unwrap();
170 {
171 let evt = mbox.mac_subsystem.read().await;
172 defmt::info!("{:#x}", evt.mac_event());
173 }
174
175 let runner = make_static!(Runner::new(mbox.mac_subsystem));
176
177 spawner.spawn(run_mac(runner)).unwrap();
178
179 let (driver, control) = mac::new(runner).await;
180}