Merge pull request #3930 from meowcakes/fix_uart

Fix STM32 UART: Add separate TX waker and only clear idle flag in RingBufferedUartRx
This commit is contained in:
Ulf Lilleengen 2025-03-06 07:21:08 +00:00 committed by GitHub
commit d378dca352
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 13 additions and 5 deletions

View File

@ -85,6 +85,7 @@ unsafe fn on_interrupt(r: Regs, s: &'static State) {
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
s.rx_waker.wake(); s.rx_waker.wake();
s.tx_waker.wake();
} }
#[derive(Clone, Copy, PartialEq, Eq, Debug)] #[derive(Clone, Copy, PartialEq, Eq, Debug)]
@ -592,7 +593,7 @@ async fn flush(info: &Info, state: &State) -> Result<(), Error> {
// future which completes when Transmission complete is detected // future which completes when Transmission complete is detected
let abort = poll_fn(move |cx| { let abort = poll_fn(move |cx| {
state.rx_waker.register(cx.waker()); state.tx_waker.register(cx.waker());
let sr = sr(r).read(); let sr = sr(r).read();
if sr.tc() { if sr.tc() {
@ -2019,6 +2020,7 @@ enum Kind {
struct State { struct State {
rx_waker: AtomicWaker, rx_waker: AtomicWaker,
tx_waker: AtomicWaker,
tx_rx_refcount: AtomicU8, tx_rx_refcount: AtomicU8,
} }
@ -2026,6 +2028,7 @@ impl State {
const fn new() -> Self { const fn new() -> Self {
Self { Self {
rx_waker: AtomicWaker::new(), rx_waker: AtomicWaker::new(),
tx_waker: AtomicWaker::new(),
tx_rx_refcount: AtomicU8::new(0), tx_rx_refcount: AtomicU8::new(0),
} }
} }

View File

@ -8,12 +8,12 @@ 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::{ use super::{rdr, reconfigure, set_baudrate, sr, Config, ConfigError, Error, Info, State, UartRx};
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;
#[cfg(any(usart_v3, usart_v4))]
use crate::pac::usart::regs;
use crate::time::Hertz; use crate::time::Hertz;
use crate::usart::{Regs, Sr}; use crate::usart::{Regs, Sr};
@ -254,7 +254,12 @@ fn clear_idle_flag(r: Regs) -> Sr {
// This read also clears the error and idle interrupt flags on v1. // This read also clears the error and idle interrupt flags on v1.
unsafe { rdr(r).read_volatile() }; unsafe { rdr(r).read_volatile() };
clear_interrupt_flags(r, sr); #[cfg(any(usart_v3, usart_v4))]
{
let mut clear_idle = regs::Icr(0);
clear_idle.set_idle(true);
r.icr().write_value(clear_idle);
}
r.cr1().modify(|w| w.set_idleie(true)); r.cr1().modify(|w| w.set_idleie(true));