diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index f287ad99de..87a22fb214 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Full-duplex SPI works when mixed with half-duplex SPI (#3176) +- `Uart::flush_async` should no longer return prematurely (#3186) ### Removed diff --git a/esp-hal/src/uart.rs b/esp-hal/src/uart.rs index ff56451ee9..1caec93c97 100644 --- a/esp-hal/src/uart.rs +++ b/esp-hal/src/uart.rs @@ -1935,7 +1935,7 @@ impl UartTx<'_, Async> { /// /// This function is cancellation safe. pub async fn flush_async(&mut self) -> Result<(), TxError> { - if self.tx_fifo_count() > 0 { + while self.tx_fifo_count() > 0 { UartTxFuture::new(self.uart.reborrow(), TxEvent::Done).await; } diff --git a/hil-test/tests/uart_tx_rx_async.rs b/hil-test/tests/uart_tx_rx_async.rs index 27086b46aa..963605d937 100644 --- a/hil-test/tests/uart_tx_rx_async.rs +++ b/hil-test/tests/uart_tx_rx_async.rs @@ -75,6 +75,25 @@ mod tests { } } + #[test] + async fn flush_async_does_not_return_prematurely(mut ctx: Context) { + // Force TX_DONE to be set + ctx.tx.write_async(&[0u8; 10]).await.unwrap(); + + let mut read = [0u8; 10]; + ctx.rx.read_exact_async(&mut read).await.unwrap(); + + // The flush should not return until the data is actually sent, regardless of + // previous TX_DONE status. + ctx.tx.write_async(&[1u8; 10]).await.unwrap(); + ctx.tx.flush_async().await.unwrap(); + + let read_count = ctx.rx.read_buffered(&mut read).unwrap(); + + assert_eq!(read_count, 10); + assert_eq!(&read, &[1u8; 10]); + } + #[test] async fn rx_overflow_is_detected(mut ctx: Context) { let mut to_send: &[u8] = &[0; 250];