aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32-wpan/src/wb55/mac/driver.rs
diff options
context:
space:
mode:
authorRaul Alimbekov <[email protected]>2025-12-16 09:05:22 +0300
committerGitHub <[email protected]>2025-12-16 09:05:22 +0300
commitc9a04b4b732b7a3b696eb8223664c1a7942b1875 (patch)
tree6dbe5c02e66eed8d8762f13f95afd24f8db2b38c /embassy-stm32-wpan/src/wb55/mac/driver.rs
parentcde24a3ef1117653ba5ed4184102b33f745782fb (diff)
parent5ae6e060ec1c90561719aabdc29d5b6e7b8b0a82 (diff)
Merge branch 'main' into main
Diffstat (limited to 'embassy-stm32-wpan/src/wb55/mac/driver.rs')
-rw-r--r--embassy-stm32-wpan/src/wb55/mac/driver.rs213
1 files changed, 213 insertions, 0 deletions
diff --git a/embassy-stm32-wpan/src/wb55/mac/driver.rs b/embassy-stm32-wpan/src/wb55/mac/driver.rs
new file mode 100644
index 000000000..41171ce3d
--- /dev/null
+++ b/embassy-stm32-wpan/src/wb55/mac/driver.rs
@@ -0,0 +1,213 @@
1#![deny(unused_must_use)]
2
3use core::cell::RefCell;
4use core::task::Context;
5
6use embassy_net_driver::{Capabilities, HardwareAddress, LinkState};
7use embassy_sync::blocking_mutex;
8use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
9use embassy_sync::channel::Channel;
10use embassy_sync::mutex::Mutex;
11use embassy_sync::waitqueue::AtomicWaker;
12
13use crate::mac::event::MacEvent;
14use crate::mac::indications::{write_frame_from_beacon_indication, write_frame_from_data_indication};
15use crate::mac::runner::{BUF_SIZE, ZeroCopyPubSub};
16use crate::mac::{Control, MTU, Runner};
17use crate::sub::mac::{Mac, MacRx, MacTx};
18
19pub struct NetworkState {
20 pub mac_addr: [u8; 8],
21 pub short_addr: [u8; 2],
22 pub pan_id: [u8; 2],
23 pub link_state: LinkState,
24 pub link_waker: AtomicWaker,
25}
26
27impl NetworkState {
28 pub const fn new() -> Self {
29 Self {
30 mac_addr: [0u8; 8],
31 short_addr: [0u8; 2],
32 pan_id: [0u8; 2],
33 link_state: LinkState::Down,
34 link_waker: AtomicWaker::new(),
35 }
36 }
37}
38
39pub struct DriverState<'d> {
40 pub mac_tx: Mutex<CriticalSectionRawMutex, MacTx<'d>>,
41 pub mac_rx: MacRx<'d>,
42 pub rx_event_channel: ZeroCopyPubSub<CriticalSectionRawMutex, MacEvent<'d>>,
43 pub rx_data_channel: Channel<CriticalSectionRawMutex, MacEvent<'d>, 1>,
44 pub tx_data_channel: Channel<CriticalSectionRawMutex, (&'d mut [u8; MTU], usize), BUF_SIZE>,
45 pub tx_buf_channel: Channel<CriticalSectionRawMutex, &'d mut [u8; MTU], BUF_SIZE>,
46 pub tx_buf_queue: [[u8; MTU]; BUF_SIZE],
47 pub network_state: blocking_mutex::Mutex<CriticalSectionRawMutex, RefCell<NetworkState>>,
48}
49
50impl<'d> DriverState<'d> {
51 pub const fn new(mac: Mac<'d>) -> Self {
52 let (mac_rx, mac_tx) = mac.split();
53 let mac_tx = Mutex::new(mac_tx);
54
55 Self {
56 mac_tx,
57 mac_rx,
58 rx_event_channel: ZeroCopyPubSub::new(RefCell::new(None)),
59 rx_data_channel: Channel::new(),
60 tx_data_channel: Channel::new(),
61 tx_buf_channel: Channel::new(),
62 tx_buf_queue: [[0u8; MTU]; BUF_SIZE],
63 network_state: blocking_mutex::Mutex::new(RefCell::new(NetworkState::new())),
64 }
65 }
66}
67
68pub struct Driver<'d> {
69 tx_data_channel: &'d Channel<CriticalSectionRawMutex, (&'d mut [u8; MTU], usize), BUF_SIZE>,
70 tx_buf_channel: &'d Channel<CriticalSectionRawMutex, &'d mut [u8; MTU], BUF_SIZE>,
71 rx_data_channel: &'d Channel<CriticalSectionRawMutex, MacEvent<'d>, 1>,
72 network_state: &'d blocking_mutex::Mutex<CriticalSectionRawMutex, RefCell<NetworkState>>,
73}
74
75impl<'d> Driver<'d> {
76 pub fn new(
77 driver_state: &'d mut DriverState<'d>,
78 short_address: [u8; 2],
79 mac_address: [u8; 8],
80 ) -> (Self, Runner<'d>, Control<'d>) {
81 (
82 Self {
83 tx_data_channel: &driver_state.tx_data_channel,
84 tx_buf_channel: &driver_state.tx_buf_channel,
85 rx_data_channel: &driver_state.rx_data_channel,
86 network_state: &driver_state.network_state,
87 },
88 Runner::new(
89 &driver_state.rx_event_channel,
90 &driver_state.rx_data_channel,
91 &mut driver_state.mac_rx,
92 &driver_state.tx_data_channel,
93 &driver_state.tx_buf_channel,
94 &driver_state.mac_tx,
95 &mut driver_state.tx_buf_queue,
96 &driver_state.network_state,
97 short_address,
98 mac_address,
99 ),
100 Control::new(
101 &driver_state.rx_event_channel,
102 &driver_state.mac_tx,
103 &driver_state.network_state,
104 ),
105 )
106 }
107}
108
109impl<'d> embassy_net_driver::Driver for Driver<'d> {
110 // type RxToken<'a> = RxToken<'a, 'd> where Self: 'a;
111 // type TxToken<'a> = TxToken<'a, 'd> where Self: 'a;
112 type RxToken<'a>
113 = RxToken<'d>
114 where
115 Self: 'a;
116 type TxToken<'a>
117 = TxToken<'d>
118 where
119 Self: 'a;
120
121 fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
122 if self.rx_data_channel.poll_ready_to_receive(cx).is_ready()
123 && self.tx_buf_channel.poll_ready_to_receive(cx).is_ready()
124 {
125 Some((
126 RxToken {
127 rx: self.rx_data_channel,
128 },
129 TxToken {
130 tx: self.tx_data_channel,
131 tx_buf: self.tx_buf_channel,
132 },
133 ))
134 } else {
135 None
136 }
137 }
138
139 fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>> {
140 if self.tx_buf_channel.poll_ready_to_receive(cx).is_ready() {
141 Some(TxToken {
142 tx: self.tx_data_channel,
143 tx_buf: self.tx_buf_channel,
144 })
145 } else {
146 None
147 }
148 }
149
150 fn capabilities(&self) -> Capabilities {
151 let mut caps = Capabilities::default();
152 caps.max_transmission_unit = MTU;
153 // caps.max_burst_size = Some(self.tx.len());
154 caps
155 }
156
157 fn link_state(&mut self, cx: &mut Context) -> LinkState {
158 critical_section::with(|cs| {
159 let network_state = self.network_state.borrow(cs).borrow_mut();
160
161 // Unconditionally register the waker to avoid a race
162 network_state.link_waker.register(cx.waker());
163 network_state.link_state
164 })
165 }
166
167 fn hardware_address(&self) -> HardwareAddress {
168 HardwareAddress::Ieee802154(critical_section::with(|cs| {
169 self.network_state.borrow(cs).borrow().mac_addr
170 }))
171 }
172}
173
174pub struct RxToken<'d> {
175 rx: &'d Channel<CriticalSectionRawMutex, MacEvent<'d>, 1>,
176}
177
178impl<'d> embassy_net_driver::RxToken for RxToken<'d> {
179 fn consume<R, F>(self, f: F) -> R
180 where
181 F: FnOnce(&mut [u8]) -> R,
182 {
183 let mut buffer = [0u8; MTU];
184 match self.rx.try_receive().unwrap() {
185 MacEvent::McpsDataInd(data_event) => write_frame_from_data_indication(data_event, &mut buffer),
186 MacEvent::MlmeBeaconNotifyInd(data_event) => write_frame_from_beacon_indication(data_event, &mut buffer),
187 _ => {}
188 };
189
190 f(&mut buffer[..])
191 }
192}
193
194pub struct TxToken<'d> {
195 tx: &'d Channel<CriticalSectionRawMutex, (&'d mut [u8; MTU], usize), BUF_SIZE>,
196 tx_buf: &'d Channel<CriticalSectionRawMutex, &'d mut [u8; MTU], BUF_SIZE>,
197}
198
199impl<'d> embassy_net_driver::TxToken for TxToken<'d> {
200 fn consume<R, F>(self, len: usize, f: F) -> R
201 where
202 F: FnOnce(&mut [u8]) -> R,
203 {
204 // Only valid tx buffers should be put into the queue
205 let buf = self.tx_buf.try_receive().unwrap();
206 let r = f(&mut buf[..len]);
207
208 // The tx channel should always be of equal capacity to the tx_buf channel
209 self.tx.try_send((buf, len)).unwrap();
210
211 r
212 }
213}