use crate::message::TxEvent;
use crate::reg;
use core::marker::PhantomData;
use reg::AccessRegisterBlock as _;
use vcell::VolatileCell;
pub struct TxEventFifo<'a, P> {
memory: &'a mut [VolatileCell<TxEvent>],
_markers: PhantomData<P>,
}
pub trait DynTxEventFifo {
type Id;
fn len(&self) -> usize;
fn is_empty(&self) -> bool;
fn capacity(&self) -> usize;
fn pop(&mut self) -> Option<TxEvent>;
}
impl<'a, P: mcan_core::CanId> TxEventFifo<'a, P> {
pub(crate) unsafe fn new(memory: &'a mut [VolatileCell<TxEvent>]) -> Self {
Self {
memory,
_markers: PhantomData,
}
}
unsafe fn regs(&self) -> ®::RegisterBlock {
&(*P::register_block())
}
fn txefs(&self) -> ®::TXEFS {
unsafe { &self.regs().txefs }
}
fn txefa(&self) -> ®::TXEFA {
unsafe { &self.regs().txefa }
}
}
impl<P: mcan_core::CanId> DynTxEventFifo for TxEventFifo<'_, P> {
type Id = P;
fn len(&self) -> usize {
self.txefs().read().effl().bits() as usize
}
fn is_empty(&self) -> bool {
self.len() == 0
}
fn capacity(&self) -> usize {
self.memory.len()
}
fn pop(&mut self) -> Option<TxEvent> {
let status = self.txefs().read();
if status.effl().bits() == 0 {
None
} else {
let get_index = status.efgi().bits();
let event = self.memory.get(get_index as usize)?.get();
unsafe {
self.txefa().write(|w| w.efai().bits(get_index));
}
Some(event)
}
}
}