aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmil Fresk <[email protected]>2024-10-27 09:55:00 +0100
committerEmil Fresk <[email protected]>2024-10-27 10:10:46 +0100
commit917f1d1f4de6f7e25f483561001a9b5b36cbce7e (patch)
tree7186e7987c8797036d70cda91ec680b8b771ca22
parent8f273497453d3ca3f297465b67820d4d36705d11 (diff)
This fixes 2 issues where STM32 BXCAN would hang
1. If one received frames under an `interrupt_free` section, in my case `init` in RTIC, the RX IRQ will fire and clear it's enable bit after `interrupt_free` is complete. There is no frame to read so RX is now unconditionally disabled forever. 2. On clearing of RX IRQ, TX stops silently. This happens due to the use of `write` instead of `modify` when modifying IRQ enable bits. Solution 1: Enable RX IRQs on every call to `try_read` that return no data. This solution also solves the issue of very delayed handling of the RX IRQ which would cause the same issue. Solution 2: Use `modify` instead of `write`.
-rw-r--r--embassy-stm32/src/can/bxcan/mod.rs10
1 files changed, 7 insertions, 3 deletions
diff --git a/embassy-stm32/src/can/bxcan/mod.rs b/embassy-stm32/src/can/bxcan/mod.rs
index baa4bee79..19f1cea29 100644
--- a/embassy-stm32/src/can/bxcan/mod.rs
+++ b/embassy-stm32/src/can/bxcan/mod.rs
@@ -893,7 +893,7 @@ impl RxMode {
893 RxFifo::Fifo0 => 0usize, 893 RxFifo::Fifo0 => 0usize,
894 RxFifo::Fifo1 => 1usize, 894 RxFifo::Fifo1 => 1usize,
895 }; 895 };
896 T::regs().ier().write(|w| { 896 T::regs().ier().modify(|w| {
897 w.set_fmpie(fifo_idx, false); 897 w.set_fmpie(fifo_idx, false);
898 }); 898 });
899 waker.wake(); 899 waker.wake();
@@ -936,18 +936,22 @@ impl RxMode {
936 Self::NonBuffered(_) => { 936 Self::NonBuffered(_) => {
937 let registers = &info.regs; 937 let registers = &info.regs;
938 if let Some(msg) = registers.receive_fifo(RxFifo::Fifo0) { 938 if let Some(msg) = registers.receive_fifo(RxFifo::Fifo0) {
939 registers.0.ier().write(|w| { 939 registers.0.ier().modify(|w| {
940 w.set_fmpie(0, true); 940 w.set_fmpie(0, true);
941 }); 941 });
942 Ok(msg) 942 Ok(msg)
943 } else if let Some(msg) = registers.receive_fifo(RxFifo::Fifo1) { 943 } else if let Some(msg) = registers.receive_fifo(RxFifo::Fifo1) {
944 registers.0.ier().write(|w| { 944 registers.0.ier().modify(|w| {
945 w.set_fmpie(1, true); 945 w.set_fmpie(1, true);
946 }); 946 });
947 Ok(msg) 947 Ok(msg)
948 } else if let Some(err) = registers.curr_error() { 948 } else if let Some(err) = registers.curr_error() {
949 Err(TryReadError::BusError(err)) 949 Err(TryReadError::BusError(err))
950 } else { 950 } else {
951 registers.0.ier().modify(|w| {
952 w.set_fmpie(0, true);
953 w.set_fmpie(1, true);
954 });
951 Err(TryReadError::Empty) 955 Err(TryReadError::Empty)
952 } 956 }
953 } 957 }