From be50b62677f04f0d30727a9168b435b90584f06c Mon Sep 17 00:00:00 2001 From: dvdsk Date: Wed, 23 Oct 2024 21:06:58 +0200 Subject: [PATCH 1/3] stm32/uart impl ReadReady for RingbufferdUart --- embassy-stm32/src/usart/mod.rs | 3 +++ embassy-stm32/src/usart/ringbuffered.rs | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 333e01e36..86c94789a 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -260,6 +260,8 @@ pub enum Error { Parity, /// Buffer too large for DMA BufferTooLong, + // TODO: ask what this is and document it (dvdsk) + DmaUnsynced, } enum ReadCompletionEvent { @@ -1689,6 +1691,7 @@ impl embedded_hal_nb::serial::Error for Error { Self::Overrun => embedded_hal_nb::serial::ErrorKind::Overrun, Self::Parity => embedded_hal_nb::serial::ErrorKind::Parity, Self::BufferTooLong => embedded_hal_nb::serial::ErrorKind::Other, + Self::DmaUnsynced => embedded_hal_nb::serial::ErrorKind::Other, } } } diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs index eb2399d9c..f1914e1bf 100644 --- a/embassy-stm32/src/usart/ringbuffered.rs +++ b/embassy-stm32/src/usart/ringbuffered.rs @@ -5,6 +5,7 @@ use core::task::Poll; use embassy_embedded_hal::SetConfig; use embassy_hal_internal::PeripheralRef; +use embedded_io_async::ReadReady; use futures_util::future::{select, Either}; use super::{clear_interrupt_flags, rdr, reconfigure, sr, Config, ConfigError, Error, Info, State, UartRx}; @@ -262,3 +263,13 @@ impl embedded_io_async::Read for RingBufferedUartRx<'_> { self.read(buf).await } } + +impl ReadReady for RingBufferedUartRx<'_> { + fn read_ready(&mut self) -> Result { + let len = self.ring_buf.len().map_err(|e| match e { + crate::dma::ringbuffer::Error::Overrun => Self::Error::Overrun, + crate::dma::ringbuffer::Error::DmaUnsynced => Self::Error::DmaUnsynced, + })?; + Ok(len > 0) + } +} From edac7cc6304c724c9626f73a35a22b074588c012 Mon Sep 17 00:00:00 2001 From: dvdsk Date: Sat, 26 Oct 2024 12:38:10 +0200 Subject: [PATCH 2/3] stm32/uart remove DmaUnsynced from public api Its an internal error which should never be exposed. It should only occur with wrong driver implementations. We log to the user and return an Overrun error since handling DmaUnsynced as an Overrun will resolve it. --- embassy-stm32/src/dma/ringbuffer/mod.rs | 4 ++++ embassy-stm32/src/usart/mod.rs | 2 -- embassy-stm32/src/usart/ringbuffered.rs | 9 ++++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/embassy-stm32/src/dma/ringbuffer/mod.rs b/embassy-stm32/src/dma/ringbuffer/mod.rs index 12d418414..0da8c374f 100644 --- a/embassy-stm32/src/dma/ringbuffer/mod.rs +++ b/embassy-stm32/src/dma/ringbuffer/mod.rs @@ -21,6 +21,10 @@ pub trait DmaCtrl { #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { Overrun, + /// the newly read DMA positions don't make sense compared to the previous + /// ones. This can usually only occur due to wrong Driver implementation, if + /// the driver author (or the user using raw metapac code) directly resets + /// the channel for instance. DmaUnsynced, } diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 86c94789a..aaf7b41e6 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -260,8 +260,6 @@ pub enum Error { Parity, /// Buffer too large for DMA BufferTooLong, - // TODO: ask what this is and document it (dvdsk) - DmaUnsynced, } enum ReadCompletionEvent { diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs index f1914e1bf..a791ac2a9 100644 --- a/embassy-stm32/src/usart/ringbuffered.rs +++ b/embassy-stm32/src/usart/ringbuffered.rs @@ -268,7 +268,14 @@ impl ReadReady for RingBufferedUartRx<'_> { fn read_ready(&mut self) -> Result { let len = self.ring_buf.len().map_err(|e| match e { crate::dma::ringbuffer::Error::Overrun => Self::Error::Overrun, - crate::dma::ringbuffer::Error::DmaUnsynced => Self::Error::DmaUnsynced, + crate::dma::ringbuffer::Error::DmaUnsynced => { + error!( + "Ringbuffer error: DmaUNsynced, driver implementation is + probably bugged please open an issue" + ); + // we report this as overrun since its recoverable in the same way + Self::Error::Overrun + } })?; Ok(len > 0) } From 43ff5a9b286c8864d7c623362322a6027980b24d Mon Sep 17 00:00:00 2001 From: dvdsk Date: Sat, 2 Nov 2024 14:00:27 +0100 Subject: [PATCH 3/3] stm32/uart fix leftover DmaUnsynced public api --- embassy-stm32/src/usart/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index aaf7b41e6..333e01e36 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -1689,7 +1689,6 @@ impl embedded_hal_nb::serial::Error for Error { Self::Overrun => embedded_hal_nb::serial::ErrorKind::Overrun, Self::Parity => embedded_hal_nb::serial::ErrorKind::Parity, Self::BufferTooLong => embedded_hal_nb::serial::ErrorKind::Other, - Self::DmaUnsynced => embedded_hal_nb::serial::ErrorKind::Other, } } }