From ef06ff43a14fd016d271c491bd830823ee96b740 Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Thu, 18 Sep 2025 02:04:05 +0100 Subject: STM32: USART: Make BufferedUartRx return all available bytes when they wrap around the internal buffer end --- embassy-stm32/CHANGELOG.md | 3 +++ embassy-stm32/src/usart/buffered.rs | 37 +++++++++++++++++++++++-------------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/embassy-stm32/CHANGELOG.md b/embassy-stm32/CHANGELOG.md index f4cfc14cc..a6ee5c4b8 100644 --- a/embassy-stm32/CHANGELOG.md +++ b/embassy-stm32/CHANGELOG.md @@ -27,7 +27,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - fix: Cut down the capabilities of the STM32L412 and L422 RTC as those are missing binary timer mode and underflow interrupt. - fix: Allow configuration of the internal pull up/down resistors on the pins for the Qei peripheral, as well as the Qei decoder mode. - feat: stm32/rcc/mco: Added support for IO driver strength when using Master Clock Out IO. This changes signature on Mco::new taking a McoConfig struct ([#4679](https://github.com/embassy-rs/embassy/pull/4679)) +- feat: derive Clone, Copy and defmt::Format for all SPI-related configs - feat: stm32/usart: add `eager_reads` option to control if buffered readers return as soon as possible or after more data is available ([#4668](https://github.com/embassy-rs/embassy/pull/4668)) +- feat: stm32/usart: add `de_assertion_time` and `de_deassertion_time` config options +- change: stm32/uart: BufferedUartRx now returns all available bytes from the internal buffer ## 0.4.0 - 2025-08-26 diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index 83aa4439b..165f2e88e 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs @@ -565,24 +565,30 @@ impl<'d> BufferedUartRx<'d> { poll_fn(move |cx| { let state = self.state; let mut rx_reader = unsafe { state.rx_buf.reader() }; - let data = rx_reader.pop_slice(); + let mut buf_len = 0; + let mut data = rx_reader.pop_slice(); - if !data.is_empty() { - let len = data.len().min(buf.len()); - buf[..len].copy_from_slice(&data[..len]); + while !data.is_empty() && buf_len < buf.len() { + let data_len = data.len().min(buf.len() - buf_len); + buf[buf_len..buf_len + data_len].copy_from_slice(&data[..data_len]); + buf_len += data_len; let do_pend = state.rx_buf.is_full(); - rx_reader.pop_done(len); + rx_reader.pop_done(data_len); if do_pend { self.info.interrupt.pend(); } - return Poll::Ready(Ok(len)); + data = rx_reader.pop_slice(); } - state.rx_waker.register(cx.waker()); - Poll::Pending + if buf_len != 0 { + Poll::Ready(Ok(buf_len)) + } else { + state.rx_waker.register(cx.waker()); + Poll::Pending + } }) .await } @@ -591,21 +597,24 @@ impl<'d> BufferedUartRx<'d> { loop { let state = self.state; let mut rx_reader = unsafe { state.rx_buf.reader() }; - let data = rx_reader.pop_slice(); + let mut buf_len = 0; + let mut data = rx_reader.pop_slice(); - if !data.is_empty() { - let len = data.len().min(buf.len()); - buf[..len].copy_from_slice(&data[..len]); + while !data.is_empty() && buf_len < buf.len() { + let data_len = data.len().min(buf.len() - buf_len); + buf[buf_len..buf_len + data_len].copy_from_slice(&data[..data_len]); + buf_len += data_len; let do_pend = state.rx_buf.is_full(); - rx_reader.pop_done(len); + rx_reader.pop_done(data_len); if do_pend { self.info.interrupt.pend(); } - return Ok(len); + data = rx_reader.pop_slice(); } + return Ok(buf_len); } } -- cgit