wpan: impl. draft control scheme
This commit is contained in:
parent
c80c232a72
commit
899a68325c
4 changed files with 109 additions and 12 deletions
|
@ -1,12 +1,16 @@
|
||||||
|
use core::future::Future;
|
||||||
|
use core::task;
|
||||||
|
|
||||||
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
|
use embassy_sync::mutex::MutexGuard;
|
||||||
|
use embassy_sync::signal::Signal;
|
||||||
|
use futures::FutureExt;
|
||||||
|
|
||||||
|
use super::commands::MacCommand;
|
||||||
|
use super::typedefs::MacError;
|
||||||
use crate::mac::runner::Runner;
|
use crate::mac::runner::Runner;
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Error {
|
|
||||||
pub status: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Control<'a> {
|
pub struct Control<'a> {
|
||||||
#[allow(dead_code)]
|
|
||||||
runner: &'a Runner<'a>,
|
runner: &'a Runner<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +19,73 @@ impl<'a> Control<'a> {
|
||||||
Self { runner: runner }
|
Self { runner: runner }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn init(&mut self) {
|
pub async fn send_command<T>(&self, cmd: &T) -> Result<(), MacError>
|
||||||
// TODO
|
where
|
||||||
|
T: MacCommand,
|
||||||
|
{
|
||||||
|
let _wm = self.runner.write_mutex.lock().await;
|
||||||
|
|
||||||
|
self.runner.mac_subsystem.send_command(cmd).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn send_command_and_get_response<T>(&self, cmd: &T) -> Result<EventToken<'a>, MacError>
|
||||||
|
where
|
||||||
|
T: MacCommand,
|
||||||
|
{
|
||||||
|
let _wm = self.runner.write_mutex.lock().await;
|
||||||
|
let rm = self.runner.read_mutex.lock().await;
|
||||||
|
let token = EventToken::new(self.runner, rm);
|
||||||
|
|
||||||
|
self.runner.mac_subsystem.send_command(cmd).await?;
|
||||||
|
|
||||||
|
Ok(token)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct EventToken<'a> {
|
||||||
|
runner: &'a Runner<'a>,
|
||||||
|
_mutex_guard: MutexGuard<'a, CriticalSectionRawMutex, ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> EventToken<'a> {
|
||||||
|
pub(crate) fn new(runner: &'a Runner<'a>, mutex_guard: MutexGuard<'a, CriticalSectionRawMutex, ()>) -> Self {
|
||||||
|
// Enable event receiving
|
||||||
|
runner.rx_event_channel.lock(|s| {
|
||||||
|
*s.borrow_mut() = Some(Signal::new());
|
||||||
|
});
|
||||||
|
|
||||||
|
Self {
|
||||||
|
runner: runner,
|
||||||
|
_mutex_guard: mutex_guard,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Future for EventToken<'a> {
|
||||||
|
// TODO: output something
|
||||||
|
type Output = ();
|
||||||
|
|
||||||
|
fn poll(self: core::pin::Pin<&mut Self>, cx: &mut task::Context<'_>) -> task::Poll<Self::Output> {
|
||||||
|
self.get_mut().runner.rx_event_channel.lock(|s| {
|
||||||
|
let signal = s.borrow_mut();
|
||||||
|
let signal = match &*signal {
|
||||||
|
Some(s) => s,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let _ = signal.wait().poll_unpin(cx);
|
||||||
|
});
|
||||||
|
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Drop for EventToken<'a> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
// Disable event receiving
|
||||||
|
// This will also drop the contained event, if it exists, and will free up receiving the next event
|
||||||
|
self.runner.rx_event_channel.lock(|s| {
|
||||||
|
*s.borrow_mut() = None;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,6 +144,8 @@ impl<'a> MacEvent<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl<'a> Send for MacEvent<'a> {}
|
||||||
|
|
||||||
impl<'a> Drop for MacEvent<'a> {
|
impl<'a> Drop for MacEvent<'a> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe { mac::Mac::drop_event_packet(ptr::null_mut()) };
|
unsafe { mac::Mac::drop_event_packet(ptr::null_mut()) };
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub mod responses;
|
||||||
pub mod runner;
|
pub mod runner;
|
||||||
pub mod typedefs;
|
pub mod typedefs;
|
||||||
|
|
||||||
pub use crate::mac::control::{Control, Error as ControlError};
|
pub use crate::mac::control::Control;
|
||||||
use crate::mac::driver::Driver;
|
use crate::mac::driver::Driver;
|
||||||
pub use crate::mac::runner::Runner;
|
pub use crate::mac::runner::Runner;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
|
use core::cell::RefCell;
|
||||||
|
|
||||||
use embassy_futures::join;
|
use embassy_futures::join;
|
||||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
use embassy_sync::blocking_mutex;
|
||||||
|
use embassy_sync::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex};
|
||||||
use embassy_sync::channel::Channel;
|
use embassy_sync::channel::Channel;
|
||||||
|
use embassy_sync::mutex::Mutex;
|
||||||
|
use embassy_sync::signal::Signal;
|
||||||
|
|
||||||
use crate::mac::commands::DataRequest;
|
use crate::mac::commands::DataRequest;
|
||||||
use crate::mac::event::MacEvent;
|
use crate::mac::event::MacEvent;
|
||||||
|
@ -9,7 +14,13 @@ use crate::mac::MTU;
|
||||||
use crate::sub::mac::Mac;
|
use crate::sub::mac::Mac;
|
||||||
|
|
||||||
pub struct Runner<'a> {
|
pub struct Runner<'a> {
|
||||||
mac_subsystem: Mac,
|
pub(crate) mac_subsystem: Mac,
|
||||||
|
|
||||||
|
// rx event backpressure is already provided through the MacEvent drop mechanism
|
||||||
|
pub(crate) rx_event_channel:
|
||||||
|
blocking_mutex::Mutex<CriticalSectionRawMutex, RefCell<Option<Signal<NoopRawMutex, MacEvent<'a>>>>>,
|
||||||
|
pub(crate) read_mutex: Mutex<CriticalSectionRawMutex, ()>,
|
||||||
|
pub(crate) write_mutex: Mutex<CriticalSectionRawMutex, ()>,
|
||||||
pub(crate) rx_channel: Channel<CriticalSectionRawMutex, MacEvent<'a>, 1>,
|
pub(crate) rx_channel: Channel<CriticalSectionRawMutex, MacEvent<'a>, 1>,
|
||||||
pub(crate) tx_channel: Channel<CriticalSectionRawMutex, (&'a mut [u8; MTU], usize), 5>,
|
pub(crate) tx_channel: Channel<CriticalSectionRawMutex, (&'a mut [u8; MTU], usize), 5>,
|
||||||
pub(crate) tx_buf_channel: Channel<CriticalSectionRawMutex, &'a mut [u8; MTU], 5>,
|
pub(crate) tx_buf_channel: Channel<CriticalSectionRawMutex, &'a mut [u8; MTU], 5>,
|
||||||
|
@ -19,6 +30,9 @@ impl<'a> Runner<'a> {
|
||||||
pub fn new(mac: Mac, tx_buf_queue: [&'a mut [u8; MTU]; 5]) -> Self {
|
pub fn new(mac: Mac, tx_buf_queue: [&'a mut [u8; MTU]; 5]) -> Self {
|
||||||
let this = Self {
|
let this = Self {
|
||||||
mac_subsystem: mac,
|
mac_subsystem: mac,
|
||||||
|
rx_event_channel: blocking_mutex::Mutex::new(RefCell::new(None)),
|
||||||
|
read_mutex: Mutex::new(()),
|
||||||
|
write_mutex: Mutex::new(()),
|
||||||
rx_channel: Channel::new(),
|
rx_channel: Channel::new(),
|
||||||
tx_channel: Channel::new(),
|
tx_channel: Channel::new(),
|
||||||
tx_buf_channel: Channel::new(),
|
tx_buf_channel: Channel::new(),
|
||||||
|
@ -40,7 +54,16 @@ impl<'a> Runner<'a> {
|
||||||
MacEvent::McpsDataInd(_) => {
|
MacEvent::McpsDataInd(_) => {
|
||||||
self.rx_channel.send(mac_event).await;
|
self.rx_channel.send(mac_event).await;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {
|
||||||
|
self.rx_event_channel.lock(|s| {
|
||||||
|
match &*s.borrow() {
|
||||||
|
Some(signal) => {
|
||||||
|
signal.signal(mac_event);
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +73,9 @@ impl<'a> Runner<'a> {
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let (buf, len) = self.tx_channel.recv().await;
|
let (buf, len) = self.tx_channel.recv().await;
|
||||||
|
let _wm = self.write_mutex.lock().await;
|
||||||
|
|
||||||
|
// The mutex should be dropped on the next loop iteration
|
||||||
self.mac_subsystem
|
self.mac_subsystem
|
||||||
.send_command(
|
.send_command(
|
||||||
DataRequest {
|
DataRequest {
|
||||||
|
|
Loading…
Reference in a new issue