From fec36e3be36f11ecdb14e159d6d79bb633e68237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Fri, 25 Apr 2025 09:54:58 +0200 Subject: [PATCH] Implement ReadReady and WriteReady (#3423) --- esp-hal/CHANGELOG.md | 4 +++ esp-hal/src/uart.rs | 56 ++++++++++++++++++++++++++++++++++++++++-- hil-test/tests/uart.rs | 8 ++++++ 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index d3638b010..1ce736bca 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -23,6 +23,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bump Rust edition to 2024, bump MSRV to 1.85. (#3391) - Added `Flex::enable_output` (#3387) - Added `Flex::set_output_enable` (#3387) +- Added `{Uart, UartRx}::read_ready` (#3423) +- Added `{Uart, UartTx}::write_ready` (#3423) +- Implemented `embedded_io::ReadReady` for `Uart` and `UartRx` (#3423) +- Implemented `embedded_io::WriteReady` for `Uart` and `UartTx` (#3423) ### Changed diff --git a/esp-hal/src/uart.rs b/esp-hal/src/uart.rs index 08d6a629c..6256dd37b 100644 --- a/esp-hal/src/uart.rs +++ b/esp-hal/src/uart.rs @@ -713,6 +713,14 @@ where Ok(()) } + /// Returns whether the UART buffer is ready to accept more data. + /// + /// If this function returns `true`, [`Self::write`] will not block. + #[instability::unstable] + pub fn write_ready(&mut self) -> bool { + self.uart.info().tx_fifo_count() < Info::UART_FIFO_SIZE + } + /// Write bytes. /// /// This function writes data to the internal TX FIFO of the UART @@ -1056,6 +1064,14 @@ where self.uart.info().check_for_errors() } + /// Returns whether the UART buffer has data. + /// + /// If this function returns `true`, [`Self::read`] will not block. + #[instability::unstable] + pub fn read_ready(&mut self) -> bool { + self.uart.info().rx_fifo_count() > 0 + } + /// Read bytes. /// /// The UART hardware continuously receives bytes and stores them in the RX @@ -1409,6 +1425,14 @@ where self.tx.uart.info().regs() } + /// Returns whether the UART buffer is ready to accept more data. + /// + /// If this function returns `true`, [`Self::write`] will not block. + #[instability::unstable] + pub fn write_ready(&mut self) -> bool { + self.tx.write_ready() + } + /// Writes bytes. /// /// This function writes data to the internal TX FIFO of the UART @@ -1445,6 +1469,14 @@ where self.tx.flush() } + /// Returns whether the UART buffer has data. + /// + /// If this function returns `true`, [`Self::read`] will not block. + #[instability::unstable] + pub fn read_ready(&mut self) -> bool { + self.rx.read_ready() + } + /// Read received bytes. /// /// The UART hardware continuously receives bytes and stores them in the RX @@ -1804,7 +1836,7 @@ where Dm: DriverMode, { fn read_ready(&mut self) -> Result { - self.rx.read_ready().map_err(IoError::Rx) + Ok(self.rx.read_ready()) } } @@ -1814,7 +1846,7 @@ where Dm: DriverMode, { fn read_ready(&mut self) -> Result { - Ok(self.uart.info().rx_fifo_count() > 0) + Ok(self.read_ready()) } } @@ -1846,6 +1878,26 @@ where } } +#[instability::unstable] +impl embedded_io::WriteReady for UartTx<'_, Dm> +where + Dm: DriverMode, +{ + fn write_ready(&mut self) -> Result { + Ok(self.write_ready()) + } +} + +#[instability::unstable] +impl embedded_io::WriteReady for Uart<'_, Dm> +where + Dm: DriverMode, +{ + fn write_ready(&mut self) -> Result { + Ok(self.tx.write_ready()) + } +} + #[derive(Debug, EnumSetType)] pub(crate) enum TxEvent { Done, diff --git a/hil-test/tests/uart.rs b/hil-test/tests/uart.rs index 70ee53ba7..5057eb4e9 100644 --- a/hil-test/tests/uart.rs +++ b/hil-test/tests/uart.rs @@ -63,6 +63,9 @@ mod tests { fn flush_waits_for_data_to_be_transmitted(ctx: Context) { let mut uart = ctx.uart1.with_tx(ctx.tx).with_rx(ctx.rx); + assert!(uart.write_ready()); + assert!(!uart.read_ready()); + let bauds = [1000, 5000000]; for baud in bauds { uart.apply_config(&uart::Config::default().with_baudrate(baud)) @@ -72,7 +75,12 @@ mod tests { uart.write(&[i as u8]).unwrap(); uart.flush().unwrap(); + assert!(uart.write_ready()); + assert!(uart.read_ready()); + let read = uart.read_buffered(&mut byte).unwrap(); + + assert!(!uart.read_ready()); assert_eq!(read, 1, "Baud rate {}, iteration {}", baud, i); assert_eq!(byte[0], i as u8, "Baud rate {}, iteration {}", baud, i); }