diff options
| author | Ulf Lilleengen <[email protected]> | 2025-03-06 07:21:08 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-03-06 07:21:08 +0000 |
| commit | d378dca352914fd3c1efea57e02dfce4106952d0 (patch) | |
| tree | 0d3f7e6b73cfe3a8d9e4b8b1da03c40dfd7c5df9 | |
| parent | 6af79f00e8fd5a32119a87870c8cb485f2513b5b (diff) | |
| parent | db44679e7541e67360d92a5e576d97a75c93ea67 (diff) | |
Merge pull request #3930 from meowcakes/fix_uart
Fix STM32 UART: Add separate TX waker and only clear idle flag in RingBufferedUartRx
| -rw-r--r-- | embassy-stm32/src/usart/mod.rs | 5 | ||||
| -rw-r--r-- | embassy-stm32/src/usart/ringbuffered.rs | 13 |
2 files changed, 13 insertions, 5 deletions
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index de7b3c8df..568067360 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs | |||
| @@ -85,6 +85,7 @@ unsafe fn on_interrupt(r: Regs, s: &'static State) { | |||
| 85 | 85 | ||
| 86 | compiler_fence(Ordering::SeqCst); | 86 | compiler_fence(Ordering::SeqCst); |
| 87 | s.rx_waker.wake(); | 87 | s.rx_waker.wake(); |
| 88 | s.tx_waker.wake(); | ||
| 88 | } | 89 | } |
| 89 | 90 | ||
| 90 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] | 91 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] |
| @@ -592,7 +593,7 @@ async fn flush(info: &Info, state: &State) -> Result<(), Error> { | |||
| 592 | 593 | ||
| 593 | // future which completes when Transmission complete is detected | 594 | // future which completes when Transmission complete is detected |
| 594 | let abort = poll_fn(move |cx| { | 595 | let abort = poll_fn(move |cx| { |
| 595 | state.rx_waker.register(cx.waker()); | 596 | state.tx_waker.register(cx.waker()); |
| 596 | 597 | ||
| 597 | let sr = sr(r).read(); | 598 | let sr = sr(r).read(); |
| 598 | if sr.tc() { | 599 | if sr.tc() { |
| @@ -2019,6 +2020,7 @@ enum Kind { | |||
| 2019 | 2020 | ||
| 2020 | struct State { | 2021 | struct State { |
| 2021 | rx_waker: AtomicWaker, | 2022 | rx_waker: AtomicWaker, |
| 2023 | tx_waker: AtomicWaker, | ||
| 2022 | tx_rx_refcount: AtomicU8, | 2024 | tx_rx_refcount: AtomicU8, |
| 2023 | } | 2025 | } |
| 2024 | 2026 | ||
| @@ -2026,6 +2028,7 @@ impl State { | |||
| 2026 | const fn new() -> Self { | 2028 | const fn new() -> Self { |
| 2027 | Self { | 2029 | Self { |
| 2028 | rx_waker: AtomicWaker::new(), | 2030 | rx_waker: AtomicWaker::new(), |
| 2031 | tx_waker: AtomicWaker::new(), | ||
| 2029 | tx_rx_refcount: AtomicU8::new(0), | 2032 | tx_rx_refcount: AtomicU8::new(0), |
| 2030 | } | 2033 | } |
| 2031 | } | 2034 | } |
diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs index 560ce4e8f..3631888e4 100644 --- a/embassy-stm32/src/usart/ringbuffered.rs +++ b/embassy-stm32/src/usart/ringbuffered.rs | |||
| @@ -8,12 +8,12 @@ use embassy_hal_internal::PeripheralRef; | |||
| 8 | use embedded_io_async::ReadReady; | 8 | use embedded_io_async::ReadReady; |
| 9 | use futures_util::future::{select, Either}; | 9 | use futures_util::future::{select, Either}; |
| 10 | 10 | ||
| 11 | use super::{ | 11 | use super::{rdr, reconfigure, set_baudrate, sr, Config, ConfigError, Error, Info, State, UartRx}; |
| 12 | clear_interrupt_flags, rdr, reconfigure, set_baudrate, sr, Config, ConfigError, Error, Info, State, UartRx, | ||
| 13 | }; | ||
| 14 | use crate::dma::ReadableRingBuffer; | 12 | use crate::dma::ReadableRingBuffer; |
| 15 | use crate::gpio::{AnyPin, SealedPin as _}; | 13 | use crate::gpio::{AnyPin, SealedPin as _}; |
| 16 | use crate::mode::Async; | 14 | use crate::mode::Async; |
| 15 | #[cfg(any(usart_v3, usart_v4))] | ||
| 16 | use crate::pac::usart::regs; | ||
| 17 | use crate::time::Hertz; | 17 | use crate::time::Hertz; |
| 18 | use crate::usart::{Regs, Sr}; | 18 | use crate::usart::{Regs, Sr}; |
| 19 | 19 | ||
| @@ -254,7 +254,12 @@ fn clear_idle_flag(r: Regs) -> Sr { | |||
| 254 | 254 | ||
| 255 | // This read also clears the error and idle interrupt flags on v1. | 255 | // This read also clears the error and idle interrupt flags on v1. |
| 256 | unsafe { rdr(r).read_volatile() }; | 256 | unsafe { rdr(r).read_volatile() }; |
| 257 | clear_interrupt_flags(r, sr); | 257 | #[cfg(any(usart_v3, usart_v4))] |
| 258 | { | ||
| 259 | let mut clear_idle = regs::Icr(0); | ||
| 260 | clear_idle.set_idle(true); | ||
| 261 | r.icr().write_value(clear_idle); | ||
| 262 | } | ||
| 258 | 263 | ||
| 259 | r.cr1().modify(|w| w.set_idleie(true)); | 264 | r.cr1().modify(|w| w.set_idleie(true)); |
| 260 | 265 | ||
