wpan: impl. draft control scheme
This commit is contained in:
parent
c80c232a72
commit
899a68325c
@ -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;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Error {
|
||||
pub status: u32,
|
||||
}
|
||||
|
||||
pub struct Control<'a> {
|
||||
#[allow(dead_code)]
|
||||
runner: &'a Runner<'a>,
|
||||
}
|
||||
|
||||
@ -15,7 +19,73 @@ impl<'a> Control<'a> {
|
||||
Self { runner: runner }
|
||||
}
|
||||
|
||||
pub async fn init(&mut self) {
|
||||
// TODO
|
||||
pub async fn send_command<T>(&self, cmd: &T) -> Result<(), MacError>
|
||||
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> {
|
||||
fn drop(&mut self) {
|
||||
unsafe { mac::Mac::drop_event_packet(ptr::null_mut()) };
|
||||
|
@ -10,7 +10,7 @@ pub mod responses;
|
||||
pub mod runner;
|
||||
pub mod typedefs;
|
||||
|
||||
pub use crate::mac::control::{Control, Error as ControlError};
|
||||
pub use crate::mac::control::Control;
|
||||
use crate::mac::driver::Driver;
|
||||
pub use crate::mac::runner::Runner;
|
||||
|
||||
|
@ -1,6 +1,11 @@
|
||||
use core::cell::RefCell;
|
||||
|
||||
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::mutex::Mutex;
|
||||
use embassy_sync::signal::Signal;
|
||||
|
||||
use crate::mac::commands::DataRequest;
|
||||
use crate::mac::event::MacEvent;
|
||||
@ -9,7 +14,13 @@ use crate::mac::MTU;
|
||||
use crate::sub::mac::Mac;
|
||||
|
||||
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) tx_channel: Channel<CriticalSectionRawMutex, (&'a mut [u8; MTU], usize), 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 {
|
||||
let this = Self {
|
||||
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(),
|
||||
tx_channel: Channel::new(),
|
||||
tx_buf_channel: Channel::new(),
|
||||
@ -40,7 +54,16 @@ impl<'a> Runner<'a> {
|
||||
MacEvent::McpsDataInd(_) => {
|
||||
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 {
|
||||
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
|
||||
.send_command(
|
||||
DataRequest {
|
||||
|
Loading…
Reference in New Issue
Block a user