Recover from errors in ringbuffered usart

This commit is contained in:
Tobias Naumann 2025-03-20 00:35:11 +01:00
parent fec98fa366
commit 71d94ad5e7

View File

@ -8,7 +8,9 @@ use embassy_hal_internal::PeripheralRef;
use embedded_io_async::ReadReady; use embedded_io_async::ReadReady;
use futures_util::future::{select, Either}; use futures_util::future::{select, Either};
use super::{rdr, reconfigure, set_baudrate, sr, Config, ConfigError, Error, Info, State, UartRx}; use super::{
clear_interrupt_flags, rdr, reconfigure, set_baudrate, sr, Config, ConfigError, Error, Info, State, UartRx,
};
use crate::dma::ReadableRingBuffer; use crate::dma::ReadableRingBuffer;
use crate::gpio::{AnyPin, SealedPin as _}; use crate::gpio::{AnyPin, SealedPin as _};
use crate::mode::Async; use crate::mode::Async;
@ -97,6 +99,8 @@ impl<'d> RingBufferedUartRx<'d> {
// enable idle line interrupt // enable idle line interrupt
w.set_idleie(true); w.set_idleie(true);
}); });
// Clear all potential error interrupt flags
clear_interrupt_flags(r, sr(r).read());
r.cr3().modify(|w| { r.cr3().modify(|w| {
// enable Error Interrupt: (Frame error, Noise error, Overrun error) // enable Error Interrupt: (Frame error, Noise error, Overrun error)
w.set_eie(true); w.set_eie(true);
@ -140,14 +144,15 @@ impl<'d> RingBufferedUartRx<'d> {
pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
let r = self.info.regs; let r = self.info.regs;
// Start DMA and Uart if it was not already started, // (Re-)start DMA and Uart if it is not running (has not been started yet or has failed),
// otherwise check for errors in status register. // and check for errors in status register. Error flags are cleared in `start_uart()` so
// they need to be read first without returning yet.
let sr = clear_idle_flag(r); let sr = clear_idle_flag(r);
let res = check_for_errors(sr);
if !r.cr3().read().dmar() { if !r.cr3().read().dmar() {
self.start_uart(); self.start_uart();
} else {
check_for_errors(sr)?;
} }
res?;
loop { loop {
match self.ring_buf.read(buf) { match self.ring_buf.read(buf) {