diff options
| author | Tobias Naumann <[email protected]> | 2025-03-20 00:35:11 +0100 |
|---|---|---|
| committer | Tobias Naumann <[email protected]> | 2025-03-20 00:43:38 +0100 |
| commit | 71d94ad5e7e2f20e2f0a55b080677fc97b88ceb9 (patch) | |
| tree | af3a5501eabacd3a51d97818f59e92ea86f46e36 /embassy-stm32/src | |
| parent | fec98fa366b94ff4740d04a89344b88685a381f1 (diff) | |
Recover from errors in ringbuffered usart
Diffstat (limited to 'embassy-stm32/src')
| -rw-r--r-- | embassy-stm32/src/usart/ringbuffered.rs | 15 |
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; | |||
| 8 | use embedded_io_async::ReadReady; | 8 | use embedded_io_async::ReadReady; |
| 9 | use futures_util::future::{select, Either}; | 9 | use futures_util::future::{select, Either}; |
| 10 | 10 | ||
| 11 | use super::{rdr, reconfigure, set_baudrate, sr, Config, ConfigError, Error, Info, State, UartRx}; | 11 | use super::{ |
| 12 | clear_interrupt_flags, rdr, reconfigure, set_baudrate, sr, Config, ConfigError, Error, Info, State, UartRx, | ||
| 13 | }; | ||
| 12 | use crate::dma::ReadableRingBuffer; | 14 | use crate::dma::ReadableRingBuffer; |
| 13 | use crate::gpio::{AnyPin, SealedPin as _}; | 15 | use crate::gpio::{AnyPin, SealedPin as _}; |
| 14 | use crate::mode::Async; | 16 | use 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) { |
