diff options
| -rw-r--r-- | embassy-stm32/src/usart/ringbuffered.rs | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs index 600e72582..3a7c3adf4 100644 --- a/embassy-stm32/src/usart/ringbuffered.rs +++ b/embassy-stm32/src/usart/ringbuffered.rs | |||
| @@ -133,6 +133,20 @@ impl<'d> RingBufferedUartRx<'d> { | |||
| 133 | compiler_fence(Ordering::SeqCst); | 133 | compiler_fence(Ordering::SeqCst); |
| 134 | } | 134 | } |
| 135 | 135 | ||
| 136 | /// (Re-)start DMA and Uart if it is not running (has not been started yet or has failed), and | ||
| 137 | /// check for errors in status register. Error flags are cleared in `start_uart()` so they need | ||
| 138 | /// to be read first without returning yet. | ||
| 139 | fn start_dma_or_check_errors(&mut self) -> Result<(), Error> { | ||
| 140 | let r = self.info.regs; | ||
| 141 | |||
| 142 | let sr = clear_idle_flag(r); | ||
| 143 | let res = check_for_errors(sr); | ||
| 144 | if !r.cr3().read().dmar() { | ||
| 145 | self.start_uart(); | ||
| 146 | } | ||
| 147 | res | ||
| 148 | } | ||
| 149 | |||
| 136 | /// Read bytes that are readily available in the ring buffer. | 150 | /// Read bytes that are readily available in the ring buffer. |
| 137 | /// If no bytes are currently available in the buffer the call waits until the some | 151 | /// If no bytes are currently available in the buffer the call waits until the some |
| 138 | /// bytes are available (at least one byte and at most half the buffer size) | 152 | /// bytes are available (at least one byte and at most half the buffer size) |
| @@ -142,17 +156,7 @@ impl<'d> RingBufferedUartRx<'d> { | |||
| 142 | /// Receive in the background is terminated if an error is returned. | 156 | /// Receive in the background is terminated if an error is returned. |
| 143 | /// It must then manually be started again by calling `start()` or by re-calling `read()`. | 157 | /// It must then manually be started again by calling `start()` or by re-calling `read()`. |
| 144 | pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { | 158 | pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { |
| 145 | let r = self.info.regs; | 159 | self.start_dma_or_check_errors()?; |
| 146 | |||
| 147 | // (Re-)start DMA and Uart if it is not running (has not been started yet or has failed), | ||
| 148 | // and check for errors in status register. Error flags are cleared in `start_uart()` so | ||
| 149 | // they need to be read first without returning yet. | ||
| 150 | let sr = clear_idle_flag(r); | ||
| 151 | let res = check_for_errors(sr); | ||
| 152 | if !r.cr3().read().dmar() { | ||
| 153 | self.start_uart(); | ||
| 154 | } | ||
| 155 | res?; | ||
| 156 | 160 | ||
| 157 | loop { | 161 | loop { |
| 158 | match self.ring_buf.read(buf) { | 162 | match self.ring_buf.read(buf) { |
| @@ -281,6 +285,29 @@ impl embedded_io_async::Read for RingBufferedUartRx<'_> { | |||
| 281 | } | 285 | } |
| 282 | } | 286 | } |
| 283 | 287 | ||
| 288 | impl embedded_hal_nb::serial::Read for RingBufferedUartRx<'_> { | ||
| 289 | fn read(&mut self) -> nb::Result<u8, Self::Error> { | ||
| 290 | self.start_dma_or_check_errors()?; | ||
| 291 | |||
| 292 | let mut buf = [0u8; 1]; | ||
| 293 | match self.ring_buf.read(&mut buf) { | ||
| 294 | Ok((0, _)) => Err(nb::Error::WouldBlock), | ||
| 295 | Ok((len, _)) => { | ||
| 296 | assert!(len == 1); | ||
| 297 | Ok(buf[0]) | ||
| 298 | } | ||
| 299 | Err(_) => { | ||
| 300 | self.stop_uart(); | ||
| 301 | Err(nb::Error::Other(Error::Overrun)) | ||
| 302 | } | ||
| 303 | } | ||
| 304 | } | ||
| 305 | } | ||
| 306 | |||
| 307 | impl embedded_hal_nb::serial::ErrorType for RingBufferedUartRx<'_> { | ||
| 308 | type Error = Error; | ||
| 309 | } | ||
| 310 | |||
| 284 | impl ReadReady for RingBufferedUartRx<'_> { | 311 | impl ReadReady for RingBufferedUartRx<'_> { |
| 285 | fn read_ready(&mut self) -> Result<bool, Self::Error> { | 312 | fn read_ready(&mut self) -> Result<bool, Self::Error> { |
| 286 | let len = self.ring_buf.len().map_err(|e| match e { | 313 | let len = self.ring_buf.len().map_err(|e| match e { |
