Skip to content

Commit d378dca

Browse files
authored
Merge pull request #3930 from meowcakes/fix_uart
Fix STM32 UART: Add separate TX waker and only clear idle flag in RingBufferedUartRx
2 parents 6af79f0 + db44679 commit d378dca

File tree

2 files changed

+13
-5
lines changed

2 files changed

+13
-5
lines changed

embassy-stm32/src/usart/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ unsafe fn on_interrupt(r: Regs, s: &'static State) {
8585

8686
compiler_fence(Ordering::SeqCst);
8787
s.rx_waker.wake();
88+
s.tx_waker.wake();
8889
}
8990

9091
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
@@ -592,7 +593,7 @@ async fn flush(info: &Info, state: &State) -> Result<(), Error> {
592593

593594
// future which completes when Transmission complete is detected
594595
let abort = poll_fn(move |cx| {
595-
state.rx_waker.register(cx.waker());
596+
state.tx_waker.register(cx.waker());
596597

597598
let sr = sr(r).read();
598599
if sr.tc() {
@@ -2019,13 +2020,15 @@ enum Kind {
20192020

20202021
struct State {
20212022
rx_waker: AtomicWaker,
2023+
tx_waker: AtomicWaker,
20222024
tx_rx_refcount: AtomicU8,
20232025
}
20242026

20252027
impl State {
20262028
const fn new() -> Self {
20272029
Self {
20282030
rx_waker: AtomicWaker::new(),
2031+
tx_waker: AtomicWaker::new(),
20292032
tx_rx_refcount: AtomicU8::new(0),
20302033
}
20312034
}

embassy-stm32/src/usart/ringbuffered.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ use embassy_hal_internal::PeripheralRef;
88
use embedded_io_async::ReadReady;
99
use futures_util::future::{select, Either};
1010

11-
use super::{
12-
clear_interrupt_flags, rdr, reconfigure, set_baudrate, sr, Config, ConfigError, Error, Info, State, UartRx,
13-
};
11+
use super::{rdr, reconfigure, set_baudrate, sr, Config, ConfigError, Error, Info, State, UartRx};
1412
use crate::dma::ReadableRingBuffer;
1513
use crate::gpio::{AnyPin, SealedPin as _};
1614
use crate::mode::Async;
15+
#[cfg(any(usart_v3, usart_v4))]
16+
use crate::pac::usart::regs;
1717
use crate::time::Hertz;
1818
use crate::usart::{Regs, Sr};
1919

@@ -254,7 +254,12 @@ fn clear_idle_flag(r: Regs) -> Sr {
254254

255255
// This read also clears the error and idle interrupt flags on v1.
256256
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+
}
258263

259264
r.cr1().modify(|w| w.set_idleie(true));
260265

0 commit comments

Comments
 (0)