aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32-wpan/src/mac/driver.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-stm32-wpan/src/mac/driver.rs')
-rw-r--r--embassy-stm32-wpan/src/mac/driver.rs120
1 files changed, 101 insertions, 19 deletions
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> {