From e31bf67eb1a2137aa0f7119fc27039bf3e44595b Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Thu, 11 Jul 2024 11:44:43 +0100 Subject: [PATCH 1/2] Add read_bytes method to uart --- esp-hal/src/uart.rs | 31 ++++++++++++++++++++++++++++++- hil-test/tests/uart_tx_rx.rs | 14 ++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/esp-hal/src/uart.rs b/esp-hal/src/uart.rs index 4f0112a163a..8c15b8ab256 100644 --- a/esp-hal/src/uart.rs +++ b/esp-hal/src/uart.rs @@ -519,6 +519,30 @@ where self } + /// Fill a buffer with received bytes + pub fn read_bytes(&mut self, mut buf: &mut [u8]) -> Result<(), Error> { + if buf.is_empty() { + return Ok(()); + } + let cap = buf.len(); + let mut total = 0; + loop { + while T::get_rx_fifo_count() == 0 { + // Block until we received at least one byte + } + let read = self.drain_fifo(buf); + total += read; + // drain_fifo only drains bytes that will fit in buf, + // so we will always have an exact total + if total == cap { + break; + } + // update the buffer position based on the bytes read + buf = &mut buf[read..]; + } + Ok(()) + } + /// Read a byte from the UART pub fn read_byte(&mut self) -> nb::Result { // On the ESP32-S2 we need to use PeriBus2 to read the FIFO: @@ -832,6 +856,11 @@ where self.tx.write_bytes(data) } + /// Fill a buffer with received bytes + pub fn read_bytes(&mut self, buf: &mut [u8]) -> Result<(), Error> { + self.rx.read_bytes(buf) + } + /// Configures the AT-CMD detection settings #[allow(clippy::useless_conversion)] pub fn set_at_cmd(&mut self, config: config::AtCmdConfig) { @@ -1681,7 +1710,7 @@ where M: Mode, { fn read(&mut self, buf: &mut [u8]) -> Result { - if buf.len() == 0 { + if buf.is_empty() { return Ok(0); } diff --git a/hil-test/tests/uart_tx_rx.rs b/hil-test/tests/uart_tx_rx.rs index df478a82046..48bb5a82607 100644 --- a/hil-test/tests/uart_tx_rx.rs +++ b/hil-test/tests/uart_tx_rx.rs @@ -67,4 +67,18 @@ mod tests { assert_eq!(read, Ok(0x42)); } + + #[test] + #[timeout(3)] + fn test_send_receive_bytes(mut ctx: Context) { + let bytes = [0x42, 0x43, 0x44]; + let mut buf = [0u8; 3]; + + ctx.tx.flush_tx().unwrap(); + ctx.tx.write_bytes(&bytes).unwrap(); + + ctx.rx.read_bytes(&mut buf).unwrap(); + + assert_eq!(buf, bytes); + } } From dff5fd66c4b15ef1dfc16fafa859ddd4ab3141f5 Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Thu, 11 Jul 2024 11:46:52 +0100 Subject: [PATCH 2/2] Changelog --- esp-hal/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index fd6d4d960bb..747f59c3c7a 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `#[ram(persistent)]` option to replace the unsound `uninitialized` option (#1677) - uart: Make `rx_timeout` optional in Config struct (#1759) - Add interrupt related functions to `PeriodicTimer`/`OneShotTimer`, added `ErasedTimer` (#1753) +- Added blocking `read_bytes` method to `Uart` and `UartRx` (#1784) ### Fixed