diff options
| author | xoviat <[email protected]> | 2025-11-01 19:42:03 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-11-01 19:42:03 +0000 |
| commit | cf231d461ff4b16cf7d16e4dbc5db909212c2c89 (patch) | |
| tree | 19e925bb265c20492799ade1d1ef78fbbff8e400 | |
| parent | 9b1add3d83e98c6c9ae9230bf35cd89bba530a20 (diff) | |
| parent | ac6e75c8887a6d2362cc00dbf246017d2cd1e102 (diff) | |
Merge pull request #4807 from xoviat/rb-uart
stm32/uart: fix rb uart race
| -rw-r--r-- | embassy-stm32/CHANGELOG.md | 1 | ||||
| -rw-r--r-- | embassy-stm32/src/usart/ringbuffered.rs | 34 |
2 files changed, 14 insertions, 21 deletions
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 | |||
| 37 | - change: stm32/uart: BufferedUartRx now returns all available bytes from the internal buffer | 37 | - change: stm32/uart: BufferedUartRx now returns all available bytes from the internal buffer |
| 38 | - change: timer: added output compare values | 38 | - change: timer: added output compare values |
| 39 | - feat: timer: add ability to set master mode | 39 | - feat: timer: add ability to set master mode |
| 40 | - fix: usart: fix race condition in ringbuffered usart | ||
| 40 | 41 | ||
| 41 | ## 0.4.0 - 2025-08-26 | 42 | ## 0.4.0 - 2025-08-26 |
| 42 | 43 | ||
diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs index 20bfefd9e..bac570d27 100644 --- a/embassy-stm32/src/usart/ringbuffered.rs +++ b/embassy-stm32/src/usart/ringbuffered.rs | |||
| @@ -7,7 +7,9 @@ use embassy_embedded_hal::SetConfig; | |||
| 7 | use embedded_io_async::ReadReady; | 7 | use embedded_io_async::ReadReady; |
| 8 | use futures_util::future::{Either, select}; | 8 | use futures_util::future::{Either, select}; |
| 9 | 9 | ||
| 10 | use super::{Config, ConfigError, Error, Info, State, UartRx, rdr, reconfigure, set_baudrate, sr}; | 10 | use super::{ |
| 11 | Config, ConfigError, Error, Info, State, UartRx, clear_interrupt_flags, rdr, reconfigure, set_baudrate, sr, | ||
| 12 | }; | ||
| 11 | use crate::Peri; | 13 | use crate::Peri; |
| 12 | use crate::dma::ReadableRingBuffer; | 14 | use crate::dma::ReadableRingBuffer; |
| 13 | use crate::gpio::{AnyPin, SealedPin as _}; | 15 | use crate::gpio::{AnyPin, SealedPin as _}; |
| @@ -338,26 +340,16 @@ impl Drop for RingBufferedUartRx<'_> { | |||
| 338 | /// For usart_v1 and usart_v2, all status flags must be handled together anyway because all flags | 340 | /// For usart_v1 and usart_v2, all status flags must be handled together anyway because all flags |
| 339 | /// are cleared by a single read to the RDR register. | 341 | /// are cleared by a single read to the RDR register. |
| 340 | fn check_idle_and_errors(r: Regs) -> Result<bool, Error> { | 342 | fn check_idle_and_errors(r: Regs) -> Result<bool, Error> { |
| 341 | // Critical section is required so that the flags aren't set after read and before clear | 343 | // SAFETY: read only and we only use Rx related flags |
| 342 | let sr = critical_section::with(|_| { | 344 | let sr = sr(r).read(); |
| 343 | // SAFETY: read only and we only use Rx related flags | 345 | |
| 344 | let sr = sr(r).read(); | 346 | #[cfg(not(any(usart_v3, usart_v4)))] |
| 345 | 347 | unsafe { | |
| 346 | #[cfg(any(usart_v3, usart_v4))] | 348 | // This read also clears the error and idle interrupt flags on v1 (TODO and v2?) |
| 347 | r.icr().write(|w| { | 349 | rdr(r).read_volatile() |
| 348 | w.set_idle(true); | 350 | }; |
| 349 | w.set_pe(true); | 351 | clear_interrupt_flags(r, sr); |
| 350 | w.set_fe(true); | 352 | |
| 351 | w.set_ne(true); | ||
| 352 | w.set_ore(true); | ||
| 353 | }); | ||
| 354 | #[cfg(not(any(usart_v3, usart_v4)))] | ||
| 355 | unsafe { | ||
| 356 | // This read also clears the error and idle interrupt flags on v1 (TODO and v2?) | ||
| 357 | rdr(r).read_volatile() | ||
| 358 | }; | ||
| 359 | sr | ||
| 360 | }); | ||
| 361 | if sr.pe() { | 353 | if sr.pe() { |
| 362 | Err(Error::Parity) | 354 | Err(Error::Parity) |
| 363 | } else if sr.fe() { | 355 | } else if sr.fe() { |
