embassy/embassy-stm32-wpan/src/mac/control.rs

92 lines
2.4 KiB
Rust
Raw Normal View History

2023-07-21 03:51:49 +02:00
use core::future::Future;
use core::task;
2023-07-16 02:15:01 +02:00
2023-07-21 03:51:49 +02:00
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;
2023-07-16 02:15:01 +02:00
pub struct Control<'a> {
runner: &'a Runner<'a>,
2023-07-16 02:15:01 +02:00
}
impl<'a> Control<'a> {
pub(crate) fn new(runner: &'a Runner<'a>) -> Self {
Self { runner: runner }
}
2023-07-16 02:15:01 +02:00
2023-07-21 03:51:49 +02:00
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;
});
2023-07-16 02:15:01 +02:00
}
}