wpan: impl. draft control scheme
This commit is contained in:
		@@ -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 {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user