aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2025-03-20 00:19:14 +0000
committerGitHub <[email protected]>2025-03-20 00:19:14 +0000
commit4f2b1371f9e48ae13c6aad0618c7dcb194db2892 (patch)
treeaf3a5501eabacd3a51d97818f59e92ea86f46e36
parentfec98fa366b94ff4740d04a89344b88685a381f1 (diff)
parent71d94ad5e7e2f20e2f0a55b080677fc97b88ceb9 (diff)
Merge pull request #3979 from embedded-rust-iml/fix/ringbuffered-error-recovery
Recover from errors in ringbuffered usart
-rw-r--r--embassy-stm32/src/usart/ringbuffered.rs15
1 files changed, 10 insertions, 5 deletions
diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs
index 3631888e4..ffd4ee544 100644
--- a/embassy-stm32/src/usart/ringbuffered.rs
+++ b/embassy-stm32/src/usart/ringbuffered.rs
@@ -8,7 +8,9 @@ use embassy_hal_internal::PeripheralRef;
8use embedded_io_async::ReadReady; 8use embedded_io_async::ReadReady;
9use futures_util::future::{select, Either}; 9use futures_util::future::{select, Either};
10 10
11use super::{rdr, reconfigure, set_baudrate, sr, Config, ConfigError, Error, Info, State, UartRx}; 11use super::{
12 clear_interrupt_flags, rdr, reconfigure, set_baudrate, sr, Config, ConfigError, Error, Info, State, UartRx,
13};
12use crate::dma::ReadableRingBuffer; 14use crate::dma::ReadableRingBuffer;
13use crate::gpio::{AnyPin, SealedPin as _}; 15use crate::gpio::{AnyPin, SealedPin as _};
14use crate::mode::Async; 16use crate::mode::Async;
@@ -97,6 +99,8 @@ impl<'d> RingBufferedUartRx<'d> {
97 // enable idle line interrupt 99 // enable idle line interrupt
98 w.set_idleie(true); 100 w.set_idleie(true);
99 }); 101 });
102 // Clear all potential error interrupt flags
103 clear_interrupt_flags(r, sr(r).read());
100 r.cr3().modify(|w| { 104 r.cr3().modify(|w| {
101 // enable Error Interrupt: (Frame error, Noise error, Overrun error) 105 // enable Error Interrupt: (Frame error, Noise error, Overrun error)
102 w.set_eie(true); 106 w.set_eie(true);
@@ -140,14 +144,15 @@ impl<'d> RingBufferedUartRx<'d> {
140 pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { 144 pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
141 let r = self.info.regs; 145 let r = self.info.regs;
142 146
143 // Start DMA and Uart if it was not already started, 147 // (Re-)start DMA and Uart if it is not running (has not been started yet or has failed),
144 // otherwise check for errors in status register. 148 // and check for errors in status register. Error flags are cleared in `start_uart()` so
149 // they need to be read first without returning yet.
145 let sr = clear_idle_flag(r); 150 let sr = clear_idle_flag(r);
151 let res = check_for_errors(sr);
146 if !r.cr3().read().dmar() { 152 if !r.cr3().read().dmar() {
147 self.start_uart(); 153 self.start_uart();
148 } else {
149 check_for_errors(sr)?;
150 } 154 }
155 res?;
151 156
152 loop { 157 loop {
153 match self.ring_buf.read(buf) { 158 match self.ring_buf.read(buf) {