stm32: can: fd: write: if in TX FIFO mode & bufs full, then abort

This commit is contained in:
Torin Cooper-Bennun 2024-02-28 10:10:15 +00:00 committed by Corey Schuhen
parent 30606f9782
commit befbb2845a
2 changed files with 24 additions and 8 deletions

View file

@ -288,7 +288,7 @@ impl Default for GlobalFilter {
} }
/// TX buffer operation mode /// TX buffer operation mode
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum TxBufferMode { pub enum TxBufferMode {
/// TX FIFO operation /// TX FIFO operation
Fifo, Fifo,
@ -305,6 +305,15 @@ impl From<TxBufferMode> for crate::pac::can::vals::Tfqm {
} }
} }
impl From<crate::pac::can::vals::Tfqm> for TxBufferMode {
fn from(value: crate::pac::can::vals::Tfqm) -> Self {
match value {
crate::pac::can::vals::Tfqm::QUEUE => Self::Queue,
crate::pac::can::vals::Tfqm::FIFO => Self::Fifo,
}
}
}
/// FdCan Config Struct /// FdCan Config Struct
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct FdCanConfig { pub struct FdCanConfig {

View file

@ -114,6 +114,12 @@ impl Registers {
self.regs.txfqs().read().tfqf() self.regs.txfqs().read().tfqf()
} }
/// Returns the current TX buffer operation mode (queue or FIFO)
#[inline]
pub fn tx_queue_mode(&self) -> TxBufferMode {
self.regs.txbc().read().tfqm().into()
}
#[inline] #[inline]
pub fn has_pending_frame(&self, idx: usize) -> bool { pub fn has_pending_frame(&self, idx: usize) -> bool {
self.regs.txbrp().read().trp(idx) self.regs.txbrp().read().trp(idx)
@ -197,13 +203,14 @@ impl Registers {
} }
pub fn write<F: embedded_can::Frame + CanHeader>(&self, frame: &F) -> nb::Result<Option<F>, Infallible> { pub fn write<F: embedded_can::Frame + CanHeader>(&self, frame: &F) -> nb::Result<Option<F>, Infallible> {
let queue_is_full = self.tx_queue_is_full(); let (idx, pending_frame) = if self.tx_queue_is_full() {
if self.tx_queue_mode() == TxBufferMode::Fifo {
let id = frame.header().id(); // Does not make sense to cancel a pending frame when using FIFO
return Err(nb::Error::WouldBlock);
// If the queue is full, }
// Discard the first slot with a lower priority message // If the queue is full,
let (idx, pending_frame) = if queue_is_full { // Discard the first slot with a lower priority message
let id = frame.header().id();
if self.is_available(0, id) { if self.is_available(0, id) {
(0, self.abort_pending_mailbox_generic(0)) (0, self.abort_pending_mailbox_generic(0))
} else if self.is_available(1, id) { } else if self.is_available(1, id) {