Recover from errors in ringbuffered usart
This commit is contained in:
parent
fec98fa366
commit
71d94ad5e7
@ -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) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user