Merge pull request #1561 from petegibson/stm32-buffereduart-int-flags-fix

Ensure idle & ove flags are cleared in BufferedUart ISR on STM32
This commit is contained in:
Dario Nieuwenhuis 2023-06-18 10:40:22 +00:00 committed by GitHub
commit adaed307b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -21,9 +21,16 @@ impl<T: BasicInstance> interrupt::typelevel::Handler<T::Interrupt> for Interrupt
// RX // RX
unsafe { unsafe {
let sr = sr(r).read(); let sr = sr(r).read();
// On v1 & v2, reading DR clears the rxne, error and idle interrupt
// flags. Keep this close to the SR read to reduce the chance of a
// flag being set in-between.
let dr = if sr.rxne() || cfg!(any(usart_v1, usart_v2)) && (sr.ore() || sr.idle()) {
Some(rdr(r).read_volatile())
} else {
None
};
clear_interrupt_flags(r, sr); clear_interrupt_flags(r, sr);
if sr.rxne() {
if sr.pe() { if sr.pe() {
warn!("Parity error"); warn!("Parity error");
} }
@ -36,12 +43,11 @@ impl<T: BasicInstance> interrupt::typelevel::Handler<T::Interrupt> for Interrupt
if sr.ore() { if sr.ore() {
warn!("Overrun error"); warn!("Overrun error");
} }
if sr.rxne() {
let mut rx_writer = state.rx_buf.writer(); let mut rx_writer = state.rx_buf.writer();
let buf = rx_writer.push_slice(); let buf = rx_writer.push_slice();
if !buf.is_empty() { if !buf.is_empty() {
// This read also clears the error and idle interrupt flags on v1. buf[0] = dr.unwrap();
buf[0] = rdr(r).read_volatile();
rx_writer.push_done(1); rx_writer.push_done(1);
} else { } else {
// FIXME: Should we disable any further RX interrupts when the buffer becomes full. // FIXME: Should we disable any further RX interrupts when the buffer becomes full.
@ -54,7 +60,7 @@ impl<T: BasicInstance> interrupt::typelevel::Handler<T::Interrupt> for Interrupt
if sr.idle() { if sr.idle() {
state.rx_waker.wake(); state.rx_waker.wake();
}; }
} }
// TX // TX