aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-04-18 14:48:13 +0000
committerGitHub <[email protected]>2024-04-18 14:48:13 +0000
commit0ee7748811914a0a5abdc2ea41ce9965aff1105b (patch)
tree03b835f71297179e10d4eed86582c6dbf2a7e6a7
parent78ca904e96e44619ceccff7a71caed5b3bc72b0b (diff)
parent80b3db4ea6b5b85ab87ec002c2029b868515f8ef (diff)
Merge pull request #2832 from MaxiluxSystems/feature/fdcan-bus-off
stm32: can: fd: implement bus-off recovery
-rw-r--r--embassy-stm32/src/can/fd/peripheral.rs1
-rw-r--r--embassy-stm32/src/can/fdcan.rs60
2 files changed, 30 insertions, 31 deletions
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 {
368 w.set_rfne(0, true); // Rx Fifo 0 New Msg 368 w.set_rfne(0, true); // Rx Fifo 0 New Msg
369 w.set_rfne(1, true); // Rx Fifo 1 New Msg 369 w.set_rfne(1, true); // Rx Fifo 1 New Msg
370 w.set_tce(true); // Tx Complete 370 w.set_tce(true); // Tx Complete
371 w.set_boe(true); // Bus-Off Status Changed
371 }); 372 });
372 self.regs.ile().modify(|w| { 373 self.regs.ile().modify(|w| {
373 w.set_eint0(true); // Interrupt Line 0 374 w.set_eint0(true); // Interrupt Line 0
diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs
index e31821ca2..563f542d4 100644
--- a/embassy-stm32/src/can/fdcan.rs
+++ b/embassy-stm32/src/can/fdcan.rs
@@ -44,53 +44,51 @@ impl<T: Instance> interrupt::typelevel::Handler<T::IT0Interrupt> for IT0Interrup
44 44
45 let ir = regs.ir().read(); 45 let ir = regs.ir().read();
46 46
47 { 47 if ir.tc() {
48 if ir.tc() { 48 regs.ir().write(|w| w.set_tc(true));
49 regs.ir().write(|w| w.set_tc(true)); 49 }
50 } 50 if ir.tefn() {
51 if ir.tefn() { 51 regs.ir().write(|w| w.set_tefn(true));
52 regs.ir().write(|w| w.set_tefn(true)); 52 }
53 }
54 53
55 match &T::state().tx_mode { 54 match &T::state().tx_mode {
56 TxMode::NonBuffered(waker) => waker.wake(), 55 TxMode::NonBuffered(waker) => waker.wake(),
57 TxMode::ClassicBuffered(buf) => { 56 TxMode::ClassicBuffered(buf) => {
58 if !T::registers().tx_queue_is_full() { 57 if !T::registers().tx_queue_is_full() {
59 match buf.tx_receiver.try_receive() { 58 match buf.tx_receiver.try_receive() {
60 Ok(frame) => { 59 Ok(frame) => {
61 _ = T::registers().write(&frame); 60 _ = T::registers().write(&frame);
62 }
63 Err(_) => {}
64 } 61 }
62 Err(_) => {}
65 } 63 }
66 } 64 }
67 TxMode::FdBuffered(buf) => { 65 }
68 if !T::registers().tx_queue_is_full() { 66 TxMode::FdBuffered(buf) => {
69 match buf.tx_receiver.try_receive() { 67 if !T::registers().tx_queue_is_full() {
70 Ok(frame) => { 68 match buf.tx_receiver.try_receive() {
71 _ = T::registers().write(&frame); 69 Ok(frame) => {
72 } 70 _ = T::registers().write(&frame);
73 Err(_) => {}
74 } 71 }
72 Err(_) => {}
75 } 73 }
76 } 74 }
77 } 75 }
78 } 76 }
79 77
80 if ir.ped() || ir.pea() {
81 regs.ir().write(|w| {
82 w.set_ped(true);
83 w.set_pea(true);
84 });
85 }
86
87 if ir.rfn(0) { 78 if ir.rfn(0) {
88 T::state().rx_mode.on_interrupt::<T>(0); 79 T::state().rx_mode.on_interrupt::<T>(0);
89 } 80 }
90
91 if ir.rfn(1) { 81 if ir.rfn(1) {
92 T::state().rx_mode.on_interrupt::<T>(1); 82 T::state().rx_mode.on_interrupt::<T>(1);
93 } 83 }
84
85 if ir.bo() {
86 regs.ir().write(|w| w.set_bo(true));
87 if regs.psr().read().bo() {
88 // Initiate bus-off recovery sequence by resetting CCCR.INIT
89 regs.cccr().modify(|w| w.set_init(false));
90 }
91 }
94 } 92 }
95} 93}
96 94