From cc2bb1c348b595c9bd17e0807f377d04406367dd Mon Sep 17 00:00:00 2001 From: xoviat Date: Wed, 29 Oct 2025 17:46:44 -0500 Subject: stm32/uart: fix rb uart race closes #4682 --- embassy-stm32/src/usart/ringbuffered.rs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs index 20bfefd9e..710272e4e 100644 --- a/embassy-stm32/src/usart/ringbuffered.rs +++ b/embassy-stm32/src/usart/ringbuffered.rs @@ -7,7 +7,9 @@ use embassy_embedded_hal::SetConfig; use embedded_io_async::ReadReady; use futures_util::future::{Either, select}; -use super::{Config, ConfigError, Error, Info, State, UartRx, rdr, reconfigure, set_baudrate, sr}; +use super::{ + Config, ConfigError, Error, Info, State, UartRx, clear_interrupt_flags, rdr, reconfigure, set_baudrate, sr, +}; use crate::Peri; use crate::dma::ReadableRingBuffer; use crate::gpio::{AnyPin, SealedPin as _}; @@ -343,19 +345,12 @@ fn check_idle_and_errors(r: Regs) -> Result { // SAFETY: read only and we only use Rx related flags let sr = sr(r).read(); - #[cfg(any(usart_v3, usart_v4))] - r.icr().write(|w| { - w.set_idle(true); - w.set_pe(true); - w.set_fe(true); - w.set_ne(true); - w.set_ore(true); - }); #[cfg(not(any(usart_v3, usart_v4)))] unsafe { // This read also clears the error and idle interrupt flags on v1 (TODO and v2?) rdr(r).read_volatile() }; + clear_interrupt_flags(r, sr); sr }); if sr.pe() { -- cgit From 575eae0631dee2052569616521b6f3db6f969ac1 Mon Sep 17 00:00:00 2001 From: xoviat Date: Wed, 29 Oct 2025 17:49:14 -0500 Subject: stm32: usart changelog --- embassy-stm32/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/embassy-stm32/CHANGELOG.md b/embassy-stm32/CHANGELOG.md index 0c1c97665..99808c233 100644 --- a/embassy-stm32/CHANGELOG.md +++ b/embassy-stm32/CHANGELOG.md @@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - change: stm32/uart: BufferedUartRx now returns all available bytes from the internal buffer - change: timer: added output compare values - feat: timer: add ability to set master mode +- fix: usart: fix race condition in ringbuffered usart ## 0.4.0 - 2025-08-26 -- cgit From ac6e75c8887a6d2362cc00dbf246017d2cd1e102 Mon Sep 17 00:00:00 2001 From: xoviat Date: Thu, 30 Oct 2025 21:18:04 -0500 Subject: remove cs --- embassy-stm32/src/usart/ringbuffered.rs | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs index 710272e4e..bac570d27 100644 --- a/embassy-stm32/src/usart/ringbuffered.rs +++ b/embassy-stm32/src/usart/ringbuffered.rs @@ -340,19 +340,16 @@ impl Drop for RingBufferedUartRx<'_> { /// For usart_v1 and usart_v2, all status flags must be handled together anyway because all flags /// are cleared by a single read to the RDR register. fn check_idle_and_errors(r: Regs) -> Result { - // Critical section is required so that the flags aren't set after read and before clear - let sr = critical_section::with(|_| { - // SAFETY: read only and we only use Rx related flags - let sr = sr(r).read(); - - #[cfg(not(any(usart_v3, usart_v4)))] - unsafe { - // This read also clears the error and idle interrupt flags on v1 (TODO and v2?) - rdr(r).read_volatile() - }; - clear_interrupt_flags(r, sr); - sr - }); + // SAFETY: read only and we only use Rx related flags + let sr = sr(r).read(); + + #[cfg(not(any(usart_v3, usart_v4)))] + unsafe { + // This read also clears the error and idle interrupt flags on v1 (TODO and v2?) + rdr(r).read_volatile() + }; + clear_interrupt_flags(r, sr); + if sr.pe() { Err(Error::Parity) } else if sr.fe() { -- cgit