diff options
| -rw-r--r-- | embassy-stm32-wpan/src/mac/control.rs | 86 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mac/event.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mac/mod.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mac/runner.rs | 31 |
4 files changed, 109 insertions, 12 deletions
diff --git a/embassy-stm32-wpan/src/mac/control.rs b/embassy-stm32-wpan/src/mac/control.rs index c45f6407a..fd8c22b26 100644 --- a/embassy-stm32-wpan/src/mac/control.rs +++ b/embassy-stm32-wpan/src/mac/control.rs | |||
| @@ -1,12 +1,16 @@ | |||
| 1 | use crate::mac::runner::Runner; | 1 | use core::future::Future; |
| 2 | use core::task; | ||
| 2 | 3 | ||
| 3 | #[derive(Debug)] | 4 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; |
| 4 | pub struct Error { | 5 | use embassy_sync::mutex::MutexGuard; |
| 5 | pub status: u32, | 6 | use embassy_sync::signal::Signal; |
| 6 | } | 7 | use futures::FutureExt; |
| 8 | |||
| 9 | use super::commands::MacCommand; | ||
| 10 | use super::typedefs::MacError; | ||
| 11 | use crate::mac::runner::Runner; | ||
| 7 | 12 | ||
| 8 | pub struct Control<'a> { | 13 | pub struct Control<'a> { |
| 9 | #[allow(dead_code)] | ||
| 10 | runner: &'a Runner<'a>, | 14 | runner: &'a Runner<'a>, |
| 11 | } | 15 | } |
| 12 | 16 | ||
| @@ -15,7 +19,73 @@ impl<'a> Control<'a> { | |||
| 15 | Self { runner: runner } | 19 | Self { runner: runner } |
| 16 | } | 20 | } |
| 17 | 21 | ||
| 18 | pub async fn init(&mut self) { | 22 | pub async fn send_command<T>(&self, cmd: &T) -> Result<(), MacError> |
| 19 | // TODO | 23 | where |
| 24 | T: MacCommand, | ||
| 25 | { | ||
| 26 | let _wm = self.runner.write_mutex.lock().await; | ||
| 27 | |||
| 28 | self.runner.mac_subsystem.send_command(cmd).await | ||
| 29 | } | ||
| 30 | |||
| 31 | pub async fn send_command_and_get_response<T>(&self, cmd: &T) -> Result<EventToken<'a>, MacError> | ||
| 32 | where | ||
| 33 | T: MacCommand, | ||
| 34 | { | ||
| 35 | let _wm = self.runner.write_mutex.lock().await; | ||
| 36 | let rm = self.runner.read_mutex.lock().await; | ||
| 37 | let token = EventToken::new(self.runner, rm); | ||
| 38 | |||
| 39 | self.runner.mac_subsystem.send_command(cmd).await?; | ||
| 40 | |||
| 41 | Ok(token) | ||
| 42 | } | ||
| 43 | } | ||
| 44 | |||
| 45 | pub struct EventToken<'a> { | ||
| 46 | runner: &'a Runner<'a>, | ||
| 47 | _mutex_guard: MutexGuard<'a, CriticalSectionRawMutex, ()>, | ||
| 48 | } | ||
| 49 | |||
| 50 | impl<'a> EventToken<'a> { | ||
| 51 | pub(crate) fn new(runner: &'a Runner<'a>, mutex_guard: MutexGuard<'a, CriticalSectionRawMutex, ()>) -> Self { | ||
| 52 | // Enable event receiving | ||
| 53 | runner.rx_event_channel.lock(|s| { | ||
| 54 | *s.borrow_mut() = Some(Signal::new()); | ||
| 55 | }); | ||
| 56 | |||
| 57 | Self { | ||
| 58 | runner: runner, | ||
| 59 | _mutex_guard: mutex_guard, | ||
| 60 | } | ||
| 61 | } | ||
| 62 | } | ||
| 63 | |||
| 64 | impl<'a> Future for EventToken<'a> { | ||
| 65 | // TODO: output something | ||
| 66 | type Output = (); | ||
| 67 | |||
| 68 | fn poll(self: core::pin::Pin<&mut Self>, cx: &mut task::Context<'_>) -> task::Poll<Self::Output> { | ||
| 69 | self.get_mut().runner.rx_event_channel.lock(|s| { | ||
| 70 | let signal = s.borrow_mut(); | ||
| 71 | let signal = match &*signal { | ||
| 72 | Some(s) => s, | ||
| 73 | _ => unreachable!(), | ||
| 74 | }; | ||
| 75 | |||
| 76 | let _ = signal.wait().poll_unpin(cx); | ||
| 77 | }); | ||
| 78 | |||
| 79 | todo!() | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | impl<'a> Drop for EventToken<'a> { | ||
| 84 | fn drop(&mut self) { | ||
| 85 | // Disable event receiving | ||
| 86 | // This will also drop the contained event, if it exists, and will free up receiving the next event | ||
| 87 | self.runner.rx_event_channel.lock(|s| { | ||
| 88 | *s.borrow_mut() = None; | ||
| 89 | }); | ||
| 20 | } | 90 | } |
| 21 | } | 91 | } |
diff --git a/embassy-stm32-wpan/src/mac/event.rs b/embassy-stm32-wpan/src/mac/event.rs index 8415bc119..9ca4f5a2a 100644 --- a/embassy-stm32-wpan/src/mac/event.rs +++ b/embassy-stm32-wpan/src/mac/event.rs | |||
| @@ -144,6 +144,8 @@ impl<'a> MacEvent<'a> { | |||
| 144 | } | 144 | } |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | unsafe impl<'a> Send for MacEvent<'a> {} | ||
| 148 | |||
| 147 | impl<'a> Drop for MacEvent<'a> { | 149 | impl<'a> Drop for MacEvent<'a> { |
| 148 | fn drop(&mut self) { | 150 | fn drop(&mut self) { |
| 149 | unsafe { mac::Mac::drop_event_packet(ptr::null_mut()) }; | 151 | unsafe { mac::Mac::drop_event_packet(ptr::null_mut()) }; |
diff --git a/embassy-stm32-wpan/src/mac/mod.rs b/embassy-stm32-wpan/src/mac/mod.rs index a93f7a695..c847a5cca 100644 --- a/embassy-stm32-wpan/src/mac/mod.rs +++ b/embassy-stm32-wpan/src/mac/mod.rs | |||
| @@ -10,7 +10,7 @@ pub mod responses; | |||
| 10 | pub mod runner; | 10 | pub mod runner; |
| 11 | pub mod typedefs; | 11 | pub mod typedefs; |
| 12 | 12 | ||
| 13 | pub use crate::mac::control::{Control, Error as ControlError}; | 13 | pub use crate::mac::control::Control; |
| 14 | use crate::mac::driver::Driver; | 14 | use crate::mac::driver::Driver; |
| 15 | pub use crate::mac::runner::Runner; | 15 | pub use crate::mac::runner::Runner; |
| 16 | 16 | ||
diff --git a/embassy-stm32-wpan/src/mac/runner.rs b/embassy-stm32-wpan/src/mac/runner.rs index 007544c67..f964d6b3d 100644 --- a/embassy-stm32-wpan/src/mac/runner.rs +++ b/embassy-stm32-wpan/src/mac/runner.rs | |||
| @@ -1,6 +1,11 @@ | |||
| 1 | use core::cell::RefCell; | ||
| 2 | |||
| 1 | use embassy_futures::join; | 3 | use embassy_futures::join; |
| 2 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | 4 | use embassy_sync::blocking_mutex; |
| 5 | use embassy_sync::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex}; | ||
| 3 | use embassy_sync::channel::Channel; | 6 | use embassy_sync::channel::Channel; |
| 7 | use embassy_sync::mutex::Mutex; | ||
| 8 | use embassy_sync::signal::Signal; | ||
| 4 | 9 | ||
| 5 | use crate::mac::commands::DataRequest; | 10 | use crate::mac::commands::DataRequest; |
| 6 | use crate::mac::event::MacEvent; | 11 | use crate::mac::event::MacEvent; |
| @@ -9,7 +14,13 @@ use crate::mac::MTU; | |||
| 9 | use crate::sub::mac::Mac; | 14 | use crate::sub::mac::Mac; |
| 10 | 15 | ||
| 11 | pub struct Runner<'a> { | 16 | pub struct Runner<'a> { |
| 12 | mac_subsystem: Mac, | 17 | pub(crate) mac_subsystem: Mac, |
| 18 | |||
| 19 | // rx event backpressure is already provided through the MacEvent drop mechanism | ||
| 20 | pub(crate) rx_event_channel: | ||
| 21 | blocking_mutex::Mutex<CriticalSectionRawMutex, RefCell<Option<Signal<NoopRawMutex, MacEvent<'a>>>>>, | ||
| 22 | pub(crate) read_mutex: Mutex<CriticalSectionRawMutex, ()>, | ||
| 23 | pub(crate) write_mutex: Mutex<CriticalSectionRawMutex, ()>, | ||
| 13 | pub(crate) rx_channel: Channel<CriticalSectionRawMutex, MacEvent<'a>, 1>, | 24 | pub(crate) rx_channel: Channel<CriticalSectionRawMutex, MacEvent<'a>, 1>, |
| 14 | pub(crate) tx_channel: Channel<CriticalSectionRawMutex, (&'a mut [u8; MTU], usize), 5>, | 25 | pub(crate) tx_channel: Channel<CriticalSectionRawMutex, (&'a mut [u8; MTU], usize), 5>, |
| 15 | pub(crate) tx_buf_channel: Channel<CriticalSectionRawMutex, &'a mut [u8; MTU], 5>, | 26 | pub(crate) tx_buf_channel: Channel<CriticalSectionRawMutex, &'a mut [u8; MTU], 5>, |
| @@ -19,6 +30,9 @@ impl<'a> Runner<'a> { | |||
| 19 | pub fn new(mac: Mac, tx_buf_queue: [&'a mut [u8; MTU]; 5]) -> Self { | 30 | pub fn new(mac: Mac, tx_buf_queue: [&'a mut [u8; MTU]; 5]) -> Self { |
| 20 | let this = Self { | 31 | let this = Self { |
| 21 | mac_subsystem: mac, | 32 | mac_subsystem: mac, |
| 33 | rx_event_channel: blocking_mutex::Mutex::new(RefCell::new(None)), | ||
| 34 | read_mutex: Mutex::new(()), | ||
| 35 | write_mutex: Mutex::new(()), | ||
| 22 | rx_channel: Channel::new(), | 36 | rx_channel: Channel::new(), |
| 23 | tx_channel: Channel::new(), | 37 | tx_channel: Channel::new(), |
| 24 | tx_buf_channel: Channel::new(), | 38 | tx_buf_channel: Channel::new(), |
| @@ -40,7 +54,16 @@ impl<'a> Runner<'a> { | |||
| 40 | MacEvent::McpsDataInd(_) => { | 54 | MacEvent::McpsDataInd(_) => { |
| 41 | self.rx_channel.send(mac_event).await; | 55 | self.rx_channel.send(mac_event).await; |
| 42 | } | 56 | } |
| 43 | _ => {} | 57 | _ => { |
| 58 | self.rx_event_channel.lock(|s| { | ||
| 59 | match &*s.borrow() { | ||
| 60 | Some(signal) => { | ||
| 61 | signal.signal(mac_event); | ||
| 62 | } | ||
| 63 | None => {} | ||
| 64 | }; | ||
| 65 | }); | ||
| 66 | } | ||
| 44 | } | 67 | } |
| 45 | } | 68 | } |
| 46 | } | 69 | } |
| @@ -50,7 +73,9 @@ impl<'a> Runner<'a> { | |||
| 50 | 73 | ||
| 51 | loop { | 74 | loop { |
| 52 | let (buf, len) = self.tx_channel.recv().await; | 75 | let (buf, len) = self.tx_channel.recv().await; |
| 76 | let _wm = self.write_mutex.lock().await; | ||
| 53 | 77 | ||
| 78 | // The mutex should be dropped on the next loop iteration | ||
| 54 | self.mac_subsystem | 79 | self.mac_subsystem |
| 55 | .send_command( | 80 | .send_command( |
| 56 | DataRequest { | 81 | DataRequest { |
