aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32-wpan
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-stm32-wpan')
-rw-r--r--embassy-stm32-wpan/Cargo.toml1
-rw-r--r--embassy-stm32-wpan/src/mac/control.rs171
-rw-r--r--embassy-stm32-wpan/src/mac/driver.rs120
-rw-r--r--embassy-stm32-wpan/src/mac/mod.rs6
-rw-r--r--embassy-stm32-wpan/src/mac/runner.rs73
-rw-r--r--embassy-stm32-wpan/src/sub/mac.rs83
6 files changed, 354 insertions, 100 deletions
diff --git a/embassy-stm32-wpan/Cargo.toml b/embassy-stm32-wpan/Cargo.toml
index 0802b7328..75d978d1a 100644
--- a/embassy-stm32-wpan/Cargo.toml
+++ b/embassy-stm32-wpan/Cargo.toml
@@ -40,6 +40,7 @@ log = { version = "0.4.17", optional = true }
40cortex-m = "0.7.6" 40cortex-m = "0.7.6"
41heapless = "0.8" 41heapless = "0.8"
42aligned = "0.4.1" 42aligned = "0.4.1"
43critical-section = "1.1"
43 44
44bit_field = "0.10.2" 45bit_field = "0.10.2"
45stm32-device-signature = { version = "0.3.3", features = ["stm32wb5x"] } 46stm32-device-signature = { version = "0.3.3", features = ["stm32wb5x"] }
diff --git a/embassy-stm32-wpan/src/mac/control.rs b/embassy-stm32-wpan/src/mac/control.rs
index e8d2f9f7b..fae00c6dc 100644
--- a/embassy-stm32-wpan/src/mac/control.rs
+++ b/embassy-stm32-wpan/src/mac/control.rs
@@ -1,65 +1,186 @@
1use core::cell::RefCell;
1use core::future::Future; 2use core::future::Future;
3use core::sync::atomic::{Ordering, compiler_fence};
2use core::task; 4use core::task;
3use core::task::Poll; 5use core::task::Poll;
4 6
7use embassy_net_driver::LinkState;
8use embassy_sync::blocking_mutex;
5use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 9use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
6use embassy_sync::mutex::MutexGuard; 10use embassy_sync::mutex::Mutex;
7use embassy_sync::signal::Signal; 11use embassy_sync::signal::Signal;
8use futures_util::FutureExt; 12use futures_util::FutureExt;
9 13
10use super::commands::MacCommand; 14use crate::mac::commands::MacCommand;
11use super::event::MacEvent; 15use crate::mac::commands::*;
12use super::typedefs::MacError; 16use crate::mac::driver::NetworkState;
13use crate::mac::runner::Runner; 17use crate::mac::event::MacEvent;
18use crate::mac::runner::ZeroCopyPubSub;
19use crate::mac::typedefs::MacError;
20use crate::mac::typedefs::*;
21use crate::sub::mac::MacTx;
14 22
15pub struct Control<'a> { 23pub struct Control<'a> {
16 runner: &'a Runner<'a>, 24 rx_event_channel: &'a ZeroCopyPubSub<CriticalSectionRawMutex, MacEvent<'a>>,
25 mac_tx: &'a Mutex<CriticalSectionRawMutex, MacTx>,
26 #[allow(unused)]
27 network_state: &'a blocking_mutex::Mutex<CriticalSectionRawMutex, RefCell<NetworkState>>,
17} 28}
18 29
19impl<'a> Control<'a> { 30impl<'a> Control<'a> {
20 pub(crate) fn new(runner: &'a Runner<'a>) -> Self { 31 pub(crate) fn new(
21 Self { runner: runner } 32 rx_event_channel: &'a ZeroCopyPubSub<CriticalSectionRawMutex, MacEvent<'a>>,
33 mac_tx: &'a Mutex<CriticalSectionRawMutex, MacTx>,
34 network_state: &'a blocking_mutex::Mutex<CriticalSectionRawMutex, RefCell<NetworkState>>,
35 ) -> Self {
36 Self {
37 rx_event_channel,
38 mac_tx,
39 network_state,
40 }
41 }
42
43 pub async fn init_link(&mut self, short_address: [u8; 2], extended_address: [u8; 8], pan_id: [u8; 2]) {
44 debug!("resetting");
45
46 debug!(
47 "{:#x}",
48 self.send_command_and_get_response(&ResetRequest {
49 set_default_pib: true,
50 ..Default::default()
51 })
52 .await
53 .unwrap()
54 .await
55 );
56
57 debug!("setting extended address");
58 let extended_address: u64 = u64::from_be_bytes(extended_address);
59 debug!(
60 "{:#x}",
61 self.send_command_and_get_response(&SetRequest {
62 pib_attribute_ptr: &extended_address as *const _ as *const u8,
63 pib_attribute: PibId::ExtendedAddress,
64 })
65 .await
66 .unwrap()
67 .await
68 );
69
70 debug!("setting short address");
71 let short_address: u16 = u16::from_be_bytes(short_address);
72 debug!(
73 "{:#x}",
74 self.send_command_and_get_response(&SetRequest {
75 pib_attribute_ptr: &short_address as *const _ as *const u8,
76 pib_attribute: PibId::ShortAddress,
77 })
78 .await
79 .unwrap()
80 .await
81 );
82
83 critical_section::with(|cs| {
84 self.network_state.borrow(cs).borrow_mut().mac_addr = extended_address.to_be_bytes();
85 });
86
87 debug!("setting association permit");
88 let association_permit: bool = true;
89 debug!(
90 "{:#x}",
91 self.send_command_and_get_response(&SetRequest {
92 pib_attribute_ptr: &association_permit as *const _ as *const u8,
93 pib_attribute: PibId::AssociationPermit,
94 })
95 .await
96 .unwrap()
97 .await
98 );
99
100 debug!("setting TX power");
101 let transmit_power: i8 = 2;
102 debug!(
103 "{:#x}",
104 self.send_command_and_get_response(&SetRequest {
105 pib_attribute_ptr: &transmit_power as *const _ as *const u8,
106 pib_attribute: PibId::TransmitPower,
107 })
108 .await
109 .unwrap()
110 .await
111 );
112
113 debug!("starting FFD device");
114 debug!(
115 "{:#x}",
116 self.send_command_and_get_response(&StartRequest {
117 pan_id: PanId(pan_id),
118 channel_number: MacChannel::Channel16,
119 beacon_order: 0x0F,
120 superframe_order: 0x0F,
121 pan_coordinator: true,
122 battery_life_extension: false,
123 ..Default::default()
124 })
125 .await
126 .unwrap()
127 .await
128 );
129
130 debug!("setting RX on when idle");
131 let rx_on_while_idle: bool = true;
132 debug!(
133 "{:#x}",
134 self.send_command_and_get_response(&SetRequest {
135 pib_attribute_ptr: &rx_on_while_idle as *const _ as *const u8,
136 pib_attribute: PibId::RxOnWhenIdle,
137 })
138 .await
139 .unwrap()
140 .await
141 );
142
143 critical_section::with(|cs| {
144 let mut network_state = self.network_state.borrow(cs).borrow_mut();
145
146 network_state.link_state = LinkState::Up;
147 network_state.link_waker.wake();
148 });
22 } 149 }
23 150
24 pub async fn send_command<T>(&self, cmd: &T) -> Result<(), MacError> 151 pub async fn send_command<T>(&self, cmd: &T) -> Result<(), MacError>
25 where 152 where
26 T: MacCommand, 153 T: MacCommand,
27 { 154 {
28 let _wm = self.runner.write_mutex.lock().await; 155 self.mac_tx.lock().await.send_command(cmd).await
29
30 self.runner.mac_subsystem.send_command(cmd).await
31 } 156 }
32 157
33 pub async fn send_command_and_get_response<T>(&self, cmd: &T) -> Result<EventToken<'a>, MacError> 158 pub async fn send_command_and_get_response<T>(&self, cmd: &T) -> Result<EventToken<'a>, MacError>
34 where 159 where
35 T: MacCommand, 160 T: MacCommand,
36 { 161 {
37 let rm = self.runner.read_mutex.lock().await; 162 let token = EventToken::new(self.rx_event_channel);
38 let _wm = self.runner.write_mutex.lock().await; 163
39 let token = EventToken::new(self.runner, rm); 164 compiler_fence(Ordering::Release);
40 165
41 self.runner.mac_subsystem.send_command(cmd).await?; 166 self.mac_tx.lock().await.send_command(cmd).await?;
42 167
43 Ok(token) 168 Ok(token)
44 } 169 }
45} 170}
46 171
47pub struct EventToken<'a> { 172pub struct EventToken<'a> {
48 runner: &'a Runner<'a>, 173 rx_event_channel: &'a ZeroCopyPubSub<CriticalSectionRawMutex, MacEvent<'a>>,
49 _mutex_guard: MutexGuard<'a, CriticalSectionRawMutex, ()>,
50} 174}
51 175
52impl<'a> EventToken<'a> { 176impl<'a> EventToken<'a> {
53 pub(crate) fn new(runner: &'a Runner<'a>, mutex_guard: MutexGuard<'a, CriticalSectionRawMutex, ()>) -> Self { 177 pub(crate) fn new(rx_event_channel: &'a ZeroCopyPubSub<CriticalSectionRawMutex, MacEvent<'a>>) -> Self {
54 // Enable event receiving 178 // Enable event receiving
55 runner.rx_event_channel.lock(|s| { 179 rx_event_channel.lock(|s| {
56 *s.borrow_mut() = Some(Signal::new()); 180 *s.borrow_mut() = Some(Signal::new());
57 }); 181 });
58 182
59 Self { 183 Self { rx_event_channel }
60 runner: runner,
61 _mutex_guard: mutex_guard,
62 }
63 } 184 }
64} 185}
65 186
@@ -67,7 +188,7 @@ impl<'a> Future for EventToken<'a> {
67 type Output = MacEvent<'a>; 188 type Output = MacEvent<'a>;
68 189
69 fn poll(self: core::pin::Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> { 190 fn poll(self: core::pin::Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> {
70 self.get_mut().runner.rx_event_channel.lock(|s| { 191 self.rx_event_channel.lock(|s| {
71 let signal = s.borrow_mut(); 192 let signal = s.borrow_mut();
72 let signal = match &*signal { 193 let signal = match &*signal {
73 Some(s) => s, 194 Some(s) => s,
@@ -88,7 +209,7 @@ impl<'a> Drop for EventToken<'a> {
88 fn drop(&mut self) { 209 fn drop(&mut self) {
89 // Disable event receiving 210 // Disable event receiving
90 // This will also drop the contained event, if it exists, and will free up receiving the next event 211 // This will also drop the contained event, if it exists, and will free up receiving the next event
91 self.runner.rx_event_channel.lock(|s| { 212 self.rx_event_channel.lock(|s| {
92 *s.borrow_mut() = None; 213 *s.borrow_mut() = None;
93 }); 214 });
94 } 215 }
diff --git a/embassy-stm32-wpan/src/mac/driver.rs b/embassy-stm32-wpan/src/mac/driver.rs
index 480ac3790..819299b48 100644
--- a/embassy-stm32-wpan/src/mac/driver.rs
+++ b/embassy-stm32-wpan/src/mac/driver.rs
@@ -1,22 +1,97 @@
1#![deny(unused_must_use)] 1#![deny(unused_must_use)]
2 2
3use core::cell::RefCell;
3use core::task::Context; 4use core::task::Context;
4 5
5use embassy_net_driver::{Capabilities, HardwareAddress, LinkState}; 6use embassy_net_driver::{Capabilities, HardwareAddress, LinkState};
7use embassy_sync::blocking_mutex;
6use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 8use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
7use embassy_sync::channel::Channel; 9use embassy_sync::channel::Channel;
10use embassy_sync::mutex::Mutex;
11use embassy_sync::waitqueue::AtomicWaker;
8 12
9use crate::mac::MTU;
10use crate::mac::event::MacEvent; 13use crate::mac::event::MacEvent;
11use crate::mac::runner::Runner; 14use crate::mac::runner::{BUF_SIZE, ZeroCopyPubSub};
15use crate::mac::{Control, MTU, Runner};
16use crate::sub::mac::{Mac, MacRx, MacTx};
17
18pub struct NetworkState {
19 pub mac_addr: [u8; 8],
20 pub link_state: LinkState,
21 pub link_waker: AtomicWaker,
22}
23
24impl NetworkState {
25 pub const fn new() -> Self {
26 Self {
27 mac_addr: [0u8; 8],
28 link_state: LinkState::Down,
29 link_waker: AtomicWaker::new(),
30 }
31 }
32}
33
34pub struct DriverState<'d> {
35 pub mac_tx: Mutex<CriticalSectionRawMutex, MacTx>,
36 pub mac_rx: MacRx,
37 pub rx_event_channel: ZeroCopyPubSub<CriticalSectionRawMutex, MacEvent<'d>>,
38 pub rx_data_channel: Channel<CriticalSectionRawMutex, MacEvent<'d>, 1>,
39 pub tx_data_channel: Channel<CriticalSectionRawMutex, (&'d mut [u8; MTU], usize), BUF_SIZE>,
40 pub tx_buf_channel: Channel<CriticalSectionRawMutex, &'d mut [u8; MTU], BUF_SIZE>,
41 pub tx_buf_queue: [[u8; MTU]; BUF_SIZE],
42 pub network_state: blocking_mutex::Mutex<CriticalSectionRawMutex, RefCell<NetworkState>>,
43}
44
45impl<'d> DriverState<'d> {
46 pub const fn new(mac: Mac) -> Self {
47 let (mac_rx, mac_tx) = mac.split();
48 let mac_tx = Mutex::new(mac_tx);
49
50 Self {
51 mac_tx,
52 mac_rx,
53 rx_event_channel: ZeroCopyPubSub::new(RefCell::new(None)),
54 rx_data_channel: Channel::new(),
55 tx_data_channel: Channel::new(),
56 tx_buf_channel: Channel::new(),
57 tx_buf_queue: [[0u8; MTU]; BUF_SIZE],
58 network_state: blocking_mutex::Mutex::new(RefCell::new(NetworkState::new())),
59 }
60 }
61}
12 62
13pub struct Driver<'d> { 63pub struct Driver<'d> {
14 runner: &'d Runner<'d>, 64 tx_data_channel: &'d Channel<CriticalSectionRawMutex, (&'d mut [u8; MTU], usize), BUF_SIZE>,
65 tx_buf_channel: &'d Channel<CriticalSectionRawMutex, &'d mut [u8; MTU], BUF_SIZE>,
66 rx_data_channel: &'d Channel<CriticalSectionRawMutex, MacEvent<'d>, 1>,
67 network_state: &'d blocking_mutex::Mutex<CriticalSectionRawMutex, RefCell<NetworkState>>,
15} 68}
16 69
17impl<'d> Driver<'d> { 70impl<'d> Driver<'d> {
18 pub(crate) fn new(runner: &'d Runner<'d>) -> Self { 71 pub fn new(driver_state: &'d mut DriverState<'d>) -> (Self, Runner<'d>, Control<'d>) {
19 Self { runner: runner } 72 (
73 Self {
74 tx_data_channel: &driver_state.tx_data_channel,
75 tx_buf_channel: &driver_state.tx_buf_channel,
76 rx_data_channel: &driver_state.rx_data_channel,
77 network_state: &driver_state.network_state,
78 },
79 Runner::new(
80 &driver_state.rx_event_channel,
81 &driver_state.rx_data_channel,
82 &mut driver_state.mac_rx,
83 &driver_state.tx_data_channel,
84 &driver_state.tx_buf_channel,
85 &driver_state.mac_tx,
86 &mut driver_state.tx_buf_queue,
87 &driver_state.network_state,
88 ),
89 Control::new(
90 &driver_state.rx_event_channel,
91 &driver_state.mac_tx,
92 &driver_state.network_state,
93 ),
94 )
20 } 95 }
21} 96}
22 97
@@ -33,16 +108,16 @@ impl<'d> embassy_net_driver::Driver for Driver<'d> {
33 Self: 'a; 108 Self: 'a;
34 109
35 fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { 110 fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
36 if self.runner.rx_channel.poll_ready_to_receive(cx).is_ready() 111 if self.rx_data_channel.poll_ready_to_receive(cx).is_ready()
37 && self.runner.tx_buf_channel.poll_ready_to_receive(cx).is_ready() 112 && self.tx_buf_channel.poll_ready_to_receive(cx).is_ready()
38 { 113 {
39 Some(( 114 Some((
40 RxToken { 115 RxToken {
41 rx: &self.runner.rx_channel, 116 rx: self.rx_data_channel,
42 }, 117 },
43 TxToken { 118 TxToken {
44 tx: &self.runner.tx_channel, 119 tx: self.tx_data_channel,
45 tx_buf: &self.runner.tx_buf_channel, 120 tx_buf: self.tx_buf_channel,
46 }, 121 },
47 )) 122 ))
48 } else { 123 } else {
@@ -51,10 +126,10 @@ impl<'d> embassy_net_driver::Driver for Driver<'d> {
51 } 126 }
52 127
53 fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>> { 128 fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>> {
54 if self.runner.tx_buf_channel.poll_ready_to_receive(cx).is_ready() { 129 if self.tx_buf_channel.poll_ready_to_receive(cx).is_ready() {
55 Some(TxToken { 130 Some(TxToken {
56 tx: &self.runner.tx_channel, 131 tx: self.tx_data_channel,
57 tx_buf: &self.runner.tx_buf_channel, 132 tx_buf: self.tx_buf_channel,
58 }) 133 })
59 } else { 134 } else {
60 None 135 None
@@ -68,13 +143,20 @@ impl<'d> embassy_net_driver::Driver for Driver<'d> {
68 caps 143 caps
69 } 144 }
70 145
71 fn link_state(&mut self, _cx: &mut Context) -> LinkState { 146 fn link_state(&mut self, cx: &mut Context) -> LinkState {
72 LinkState::Down 147 critical_section::with(|cs| {
148 let network_state = self.network_state.borrow(cs).borrow_mut();
149
150 // Unconditionally register the waker to avoid a race
151 network_state.link_waker.register(cx.waker());
152 network_state.link_state
153 })
73 } 154 }
74 155
75 fn hardware_address(&self) -> HardwareAddress { 156 fn hardware_address(&self) -> HardwareAddress {
76 // self.mac_addr 157 HardwareAddress::Ieee802154(critical_section::with(|cs| {
77 HardwareAddress::Ieee802154([0; 8]) 158 self.network_state.borrow(cs).borrow().mac_addr
159 }))
78 } 160 }
79} 161}
80 162
@@ -99,8 +181,8 @@ impl<'d> embassy_net_driver::RxToken for RxToken<'d> {
99} 181}
100 182
101pub struct TxToken<'d> { 183pub struct TxToken<'d> {
102 tx: &'d Channel<CriticalSectionRawMutex, (&'d mut [u8; MTU], usize), 5>, 184 tx: &'d Channel<CriticalSectionRawMutex, (&'d mut [u8; MTU], usize), BUF_SIZE>,
103 tx_buf: &'d Channel<CriticalSectionRawMutex, &'d mut [u8; MTU], 5>, 185 tx_buf: &'d Channel<CriticalSectionRawMutex, &'d mut [u8; MTU], BUF_SIZE>,
104} 186}
105 187
106impl<'d> embassy_net_driver::TxToken for TxToken<'d> { 188impl<'d> embassy_net_driver::TxToken for TxToken<'d> {
diff --git a/embassy-stm32-wpan/src/mac/mod.rs b/embassy-stm32-wpan/src/mac/mod.rs
index c847a5cca..ac50a6b29 100644
--- a/embassy-stm32-wpan/src/mac/mod.rs
+++ b/embassy-stm32-wpan/src/mac/mod.rs
@@ -11,11 +11,7 @@ pub mod runner;
11pub mod typedefs; 11pub mod typedefs;
12 12
13pub use crate::mac::control::Control; 13pub use crate::mac::control::Control;
14use crate::mac::driver::Driver; 14pub use crate::mac::driver::{Driver, DriverState};
15pub use crate::mac::runner::Runner; 15pub use crate::mac::runner::Runner;
16 16
17const MTU: usize = 127; 17const MTU: usize = 127;
18
19pub async fn new<'a>(runner: &'a Runner<'a>) -> (Control<'a>, Driver<'a>) {
20 (Control::new(runner), Driver::new(runner))
21}
diff --git a/embassy-stm32-wpan/src/mac/runner.rs b/embassy-stm32-wpan/src/mac/runner.rs
index 2409f994d..26fdf23e0 100644
--- a/embassy-stm32-wpan/src/mac/runner.rs
+++ b/embassy-stm32-wpan/src/mac/runner.rs
@@ -8,52 +8,65 @@ use embassy_sync::mutex::Mutex;
8use embassy_sync::signal::Signal; 8use embassy_sync::signal::Signal;
9 9
10use crate::mac::MTU; 10use crate::mac::MTU;
11use crate::mac::commands::DataRequest; 11use crate::mac::commands::*;
12use crate::mac::driver::NetworkState;
12use crate::mac::event::MacEvent; 13use crate::mac::event::MacEvent;
13use crate::mac::typedefs::{AddressMode, MacAddress, PanId, SecurityLevel}; 14use crate::mac::typedefs::*;
14use crate::sub::mac::Mac; 15use crate::sub::mac::{MacRx, MacTx};
15 16
16type ZeroCopyPubSub<M, T> = blocking_mutex::Mutex<M, RefCell<Option<Signal<NoopRawMutex, T>>>>; 17pub type ZeroCopyPubSub<M, T> = blocking_mutex::Mutex<M, RefCell<Option<Signal<NoopRawMutex, T>>>>;
18
19pub const BUF_SIZE: usize = 3;
17 20
18pub struct Runner<'a> { 21pub struct Runner<'a> {
19 pub(crate) mac_subsystem: Mac,
20 // rx event backpressure is already provided through the MacEvent drop mechanism 22 // rx event backpressure is already provided through the MacEvent drop mechanism
21 // therefore, we don't need to worry about overwriting events 23 // therefore, we don't need to worry about overwriting events
22 pub(crate) rx_event_channel: ZeroCopyPubSub<CriticalSectionRawMutex, MacEvent<'a>>, 24 rx_event_channel: &'a ZeroCopyPubSub<CriticalSectionRawMutex, MacEvent<'a>>,
23 pub(crate) read_mutex: Mutex<CriticalSectionRawMutex, ()>, 25 rx_data_channel: &'a Channel<CriticalSectionRawMutex, MacEvent<'a>, 1>,
24 pub(crate) write_mutex: Mutex<CriticalSectionRawMutex, ()>, 26 mac_rx: &'a mut MacRx,
25 pub(crate) rx_channel: Channel<CriticalSectionRawMutex, MacEvent<'a>, 1>, 27
26 pub(crate) tx_channel: Channel<CriticalSectionRawMutex, (&'a mut [u8; MTU], usize), 5>, 28 tx_data_channel: &'a Channel<CriticalSectionRawMutex, (&'a mut [u8; MTU], usize), BUF_SIZE>,
27 pub(crate) tx_buf_channel: Channel<CriticalSectionRawMutex, &'a mut [u8; MTU], 5>, 29 tx_buf_channel: &'a Channel<CriticalSectionRawMutex, &'a mut [u8; MTU], BUF_SIZE>,
30 mac_tx: &'a Mutex<CriticalSectionRawMutex, MacTx>,
31
32 #[allow(unused)]
33 network_state: &'a blocking_mutex::Mutex<CriticalSectionRawMutex, RefCell<NetworkState>>,
28} 34}
29 35
30impl<'a> Runner<'a> { 36impl<'a> Runner<'a> {
31 pub fn new(mac: Mac, tx_buf_queue: [&'a mut [u8; MTU]; 5]) -> Self { 37 pub fn new(
32 let this = Self { 38 rx_event_channel: &'a ZeroCopyPubSub<CriticalSectionRawMutex, MacEvent<'a>>,
33 mac_subsystem: mac, 39 rx_data_channel: &'a Channel<CriticalSectionRawMutex, MacEvent<'a>, 1>,
34 rx_event_channel: blocking_mutex::Mutex::new(RefCell::new(None)), 40 mac_rx: &'a mut MacRx,
35 read_mutex: Mutex::new(()), 41 tx_data_channel: &'a Channel<CriticalSectionRawMutex, (&'a mut [u8; MTU], usize), BUF_SIZE>,
36 write_mutex: Mutex::new(()), 42 tx_buf_channel: &'a Channel<CriticalSectionRawMutex, &'a mut [u8; MTU], BUF_SIZE>,
37 rx_channel: Channel::new(), 43 mac_tx: &'a Mutex<CriticalSectionRawMutex, MacTx>,
38 tx_channel: Channel::new(), 44 tx_buf_queue: &'a mut [[u8; MTU]; BUF_SIZE],
39 tx_buf_channel: Channel::new(), 45 network_state: &'a blocking_mutex::Mutex<CriticalSectionRawMutex, RefCell<NetworkState>>,
40 }; 46 ) -> Self {
41
42 for buf in tx_buf_queue { 47 for buf in tx_buf_queue {
43 this.tx_buf_channel.try_send(buf).unwrap(); 48 tx_buf_channel.try_send(buf).unwrap();
44 } 49 }
45 50
46 this 51 Self {
52 rx_event_channel,
53 rx_data_channel,
54 mac_rx,
55 tx_data_channel,
56 tx_buf_channel,
57 mac_tx,
58 network_state,
59 }
47 } 60 }
48 61
49 pub async fn run(&'a self) -> ! { 62 pub async fn run(&'a self) -> ! {
50 join::join( 63 join::join(
51 async { 64 async {
52 loop { 65 loop {
53 if let Ok(mac_event) = self.mac_subsystem.read().await { 66 if let Ok(mac_event) = self.mac_rx.read().await {
54 match mac_event { 67 match mac_event {
55 MacEvent::McpsDataInd(_) => { 68 MacEvent::McpsDataInd(_) => {
56 self.rx_channel.send(mac_event).await; 69 self.rx_data_channel.send(mac_event).await;
57 } 70 }
58 _ => { 71 _ => {
59 self.rx_event_channel.lock(|s| { 72 self.rx_event_channel.lock(|s| {
@@ -73,11 +86,13 @@ impl<'a> Runner<'a> {
73 let mut msdu_handle = 0x02; 86 let mut msdu_handle = 0x02;
74 87
75 loop { 88 loop {
76 let (buf, len) = self.tx_channel.receive().await; 89 let (buf, len) = self.tx_data_channel.receive().await;
77 let _wm = self.write_mutex.lock().await; 90 let mac_tx = self.mac_tx.lock().await;
91
92 // TODO: skip this if the link state is down
78 93
79 // The mutex should be dropped on the next loop iteration 94 // The mutex should be dropped on the next loop iteration
80 self.mac_subsystem 95 mac_tx
81 .send_command( 96 .send_command(
82 DataRequest { 97 DataRequest {
83 src_addr_mode: AddressMode::Short, 98 src_addr_mode: AddressMode::Short,
diff --git a/embassy-stm32-wpan/src/sub/mac.rs b/embassy-stm32-wpan/src/sub/mac.rs
index baf4da979..93cafbc72 100644
--- a/embassy-stm32-wpan/src/sub/mac.rs
+++ b/embassy-stm32-wpan/src/sub/mac.rs
@@ -28,32 +28,39 @@ impl Mac {
28 Self { _private: () } 28 Self { _private: () }
29 } 29 }
30 30
31 /// `HW_IPCC_MAC_802_15_4_EvtNot` 31 pub const fn split(self) -> (MacRx, MacTx) {
32 /// 32 (MacRx { _private: () }, MacTx { _private: () })
33 /// This function will stall if the previous `EvtBox` has not been dropped 33 }
34 pub async fn tl_read(&self) -> EvtBox<Self> {
35 // Wait for the last event box to be dropped
36 poll_fn(|cx| {
37 MAC_WAKER.register(cx.waker());
38 if MAC_EVT_OUT.load(Ordering::SeqCst) {
39 Poll::Pending
40 } else {
41 Poll::Ready(())
42 }
43 })
44 .await;
45 34
46 // Return a new event box 35 pub async fn tl_write_and_get_response(&self, opcode: u16, payload: &[u8]) -> u8 {
47 Ipcc::receive(channels::cpu2::IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL, || unsafe { 36 MacTx { _private: () }.tl_write_and_get_response(opcode, payload).await
48 // The closure is not async, therefore the closure must execute to completion (cannot be dropped) 37 }
49 // Therefore, the event box is guaranteed to be cleaned up if it's not leaked
50 MAC_EVT_OUT.store(true, Ordering::SeqCst);
51 38
52 Some(EvtBox::new(MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr() as *mut _)) 39 pub async fn tl_write(&self, opcode: u16, payload: &[u8]) {
53 }) 40 MacTx { _private: () }.tl_write(opcode, payload).await
54 .await
55 } 41 }
56 42
43 pub async fn send_command<T>(&self, cmd: &T) -> Result<(), MacError>
44 where
45 T: MacCommand,
46 {
47 MacTx { _private: () }.send_command(cmd).await
48 }
49
50 pub async fn tl_read(&self) -> EvtBox<Mac> {
51 MacRx { _private: () }.tl_read().await
52 }
53
54 pub async fn read(&self) -> Result<MacEvent<'_>, ()> {
55 MacRx { _private: () }.read().await
56 }
57}
58
59pub struct MacTx {
60 _private: (),
61}
62
63impl MacTx {
57 /// `HW_IPCC_MAC_802_15_4_CmdEvtNot` 64 /// `HW_IPCC_MAC_802_15_4_CmdEvtNot`
58 pub async fn tl_write_and_get_response(&self, opcode: u16, payload: &[u8]) -> u8 { 65 pub async fn tl_write_and_get_response(&self, opcode: u16, payload: &[u8]) -> u8 {
59 self.tl_write(opcode, payload).await; 66 self.tl_write(opcode, payload).await;
@@ -92,6 +99,38 @@ impl Mac {
92 Err(MacError::from(response)) 99 Err(MacError::from(response))
93 } 100 }
94 } 101 }
102}
103
104pub struct MacRx {
105 _private: (),
106}
107
108impl MacRx {
109 /// `HW_IPCC_MAC_802_15_4_EvtNot`
110 ///
111 /// This function will stall if the previous `EvtBox` has not been dropped
112 pub async fn tl_read(&self) -> EvtBox<Mac> {
113 // Wait for the last event box to be dropped
114 poll_fn(|cx| {
115 MAC_WAKER.register(cx.waker());
116 if MAC_EVT_OUT.load(Ordering::SeqCst) {
117 Poll::Pending
118 } else {
119 Poll::Ready(())
120 }
121 })
122 .await;
123
124 // Return a new event box
125 Ipcc::receive(channels::cpu2::IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL, || unsafe {
126 // The closure is not async, therefore the closure must execute to completion (cannot be dropped)
127 // Therefore, the event box is guaranteed to be cleaned up if it's not leaked
128 MAC_EVT_OUT.store(true, Ordering::SeqCst);
129
130 Some(EvtBox::new(MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr() as *mut _))
131 })
132 .await
133 }
95 134
96 pub async fn read(&self) -> Result<MacEvent<'_>, ()> { 135 pub async fn read(&self) -> Result<MacEvent<'_>, ()> {
97 MacEvent::new(self.tl_read().await) 136 MacEvent::new(self.tl_read().await)