From 901bdfc7b8d8e1dc5d04b28a69feb50b99d0be57 Mon Sep 17 00:00:00 2001 From: Torin Cooper-Bennun Date: Wed, 17 Apr 2024 14:54:47 +0100 Subject: [PATCH 1/2] stm32: can: fd: on_interrupt: simplify, rm redundant code PED, PEA are never enabled in the interrupt enable code in peripheral.rs; no need to process the flags here --- embassy-stm32/src/can/fdcan.rs | 64 ++++++++++++++-------------------- 1 file changed, 27 insertions(+), 37 deletions(-) diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs index e31821ca2..23a35168b 100644 --- a/embassy-stm32/src/can/fdcan.rs +++ b/embassy-stm32/src/can/fdcan.rs @@ -44,50 +44,40 @@ impl interrupt::typelevel::Handler for IT0Interrup let ir = regs.ir().read(); - { - if ir.tc() { - regs.ir().write(|w| w.set_tc(true)); - } - if ir.tefn() { - regs.ir().write(|w| w.set_tefn(true)); - } - - match &T::state().tx_mode { - TxMode::NonBuffered(waker) => waker.wake(), - TxMode::ClassicBuffered(buf) => { - if !T::registers().tx_queue_is_full() { - match buf.tx_receiver.try_receive() { - Ok(frame) => { - _ = T::registers().write(&frame); - } - Err(_) => {} - } - } - } - TxMode::FdBuffered(buf) => { - if !T::registers().tx_queue_is_full() { - match buf.tx_receiver.try_receive() { - Ok(frame) => { - _ = T::registers().write(&frame); - } - Err(_) => {} - } - } - } - } + if ir.tc() { + regs.ir().write(|w| w.set_tc(true)); + } + if ir.tefn() { + regs.ir().write(|w| w.set_tefn(true)); } - if ir.ped() || ir.pea() { - regs.ir().write(|w| { - w.set_ped(true); - w.set_pea(true); - }); + match &T::state().tx_mode { + TxMode::NonBuffered(waker) => waker.wake(), + TxMode::ClassicBuffered(buf) => { + if !T::registers().tx_queue_is_full() { + match buf.tx_receiver.try_receive() { + Ok(frame) => { + _ = T::registers().write(&frame); + } + Err(_) => {} + } + } + } + TxMode::FdBuffered(buf) => { + if !T::registers().tx_queue_is_full() { + match buf.tx_receiver.try_receive() { + Ok(frame) => { + _ = T::registers().write(&frame); + } + Err(_) => {} + } + } + } } if ir.rfn(0) { T::state().rx_mode.on_interrupt::(0); } - if ir.rfn(1) { T::state().rx_mode.on_interrupt::(1); } From 80b3db4ea6b5b85ab87ec002c2029b868515f8ef Mon Sep 17 00:00:00 2001 From: Torin Cooper-Bennun Date: Wed, 17 Apr 2024 14:58:08 +0100 Subject: [PATCH 2/2] stm32: can: fd: implement bus-off recovery as per RM0492 and other relevant RMs, bus-off recovery is not automatic. CCCR.INIT is set by the device upon bus-off; the CPU must reset CCCR.INIT to initiate the recovery. --- embassy-stm32/src/can/fd/peripheral.rs | 1 + embassy-stm32/src/can/fdcan.rs | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/embassy-stm32/src/can/fd/peripheral.rs b/embassy-stm32/src/can/fd/peripheral.rs index e32f19d91..e5cfee528 100644 --- a/embassy-stm32/src/can/fd/peripheral.rs +++ b/embassy-stm32/src/can/fd/peripheral.rs @@ -368,6 +368,7 @@ impl Registers { w.set_rfne(0, true); // Rx Fifo 0 New Msg w.set_rfne(1, true); // Rx Fifo 1 New Msg w.set_tce(true); // Tx Complete + w.set_boe(true); // Bus-Off Status Changed }); self.regs.ile().modify(|w| { w.set_eint0(true); // Interrupt Line 0 diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs index 23a35168b..563f542d4 100644 --- a/embassy-stm32/src/can/fdcan.rs +++ b/embassy-stm32/src/can/fdcan.rs @@ -81,6 +81,14 @@ impl interrupt::typelevel::Handler for IT0Interrup if ir.rfn(1) { T::state().rx_mode.on_interrupt::(1); } + + if ir.bo() { + regs.ir().write(|w| w.set_bo(true)); + if regs.psr().read().bo() { + // Initiate bus-off recovery sequence by resetting CCCR.INIT + regs.cccr().modify(|w| w.set_init(false)); + } + } } }