diff options
| author | Peter Krull <[email protected]> | 2024-09-19 19:21:34 +0200 |
|---|---|---|
| committer | Peter Krull <[email protected]> | 2024-09-19 19:21:34 +0200 |
| commit | 4fcc8e39d6b3e486d2b94aa45d255d9c645d028a (patch) | |
| tree | ddc93e01f10332f2988e23eb9c5a7881b9948ff4 | |
| parent | 2a9cdaabaa315795722886f94fa553e8f3e3c14d (diff) | |
stm32: Only check errors on running RingBufferedUartRx, reduce number of small one-time functions
| -rw-r--r-- | embassy-stm32/src/usart/ringbuffered.rs | 49 |
1 files changed, 19 insertions, 30 deletions
diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs index bb95af966..2d9c63820 100644 --- a/embassy-stm32/src/usart/ringbuffered.rs +++ b/embassy-stm32/src/usart/ringbuffered.rs | |||
| @@ -71,33 +71,18 @@ impl<'d> UartRx<'d, Async> { | |||
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | impl<'d> RingBufferedUartRx<'d> { | 73 | impl<'d> RingBufferedUartRx<'d> { |
| 74 | /// Clear the ring buffer and start receiving in the background | ||
| 75 | pub fn start(&mut self) -> Result<(), Error> { | ||
| 76 | // Clear the ring buffer so that it is ready to receive data | ||
| 77 | self.ring_buf.clear(); | ||
| 78 | |||
| 79 | self.setup_uart(); | ||
| 80 | |||
| 81 | Ok(()) | ||
| 82 | } | ||
| 83 | |||
| 84 | fn stop(&mut self, err: Error) -> Result<usize, Error> { | ||
| 85 | self.teardown_uart(); | ||
| 86 | |||
| 87 | Err(err) | ||
| 88 | } | ||
| 89 | |||
| 90 | /// Reconfigure the driver | 74 | /// Reconfigure the driver |
| 91 | pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { | 75 | pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { |
| 92 | reconfigure(self.info, self.kernel_clock, config) | 76 | reconfigure(self.info, self.kernel_clock, config) |
| 93 | } | 77 | } |
| 94 | 78 | ||
| 95 | /// Start uart background receive | 79 | /// Configure and start the DMA backed UART receiver |
| 96 | fn setup_uart(&mut self) { | 80 | /// |
| 97 | // fence before starting DMA. | 81 | /// Note: This is also done automatically by [`read()`] if required. |
| 82 | pub fn start_uart(&mut self) { | ||
| 83 | // Clear the buffer so that it is ready to receive data | ||
| 84 | self.ring_buf.clear(); | ||
| 98 | compiler_fence(Ordering::SeqCst); | 85 | compiler_fence(Ordering::SeqCst); |
| 99 | |||
| 100 | // start the dma controller | ||
| 101 | self.ring_buf.start(); | 86 | self.ring_buf.start(); |
| 102 | 87 | ||
| 103 | let r = self.info.regs; | 88 | let r = self.info.regs; |
| @@ -118,8 +103,8 @@ impl<'d> RingBufferedUartRx<'d> { | |||
| 118 | }); | 103 | }); |
| 119 | } | 104 | } |
| 120 | 105 | ||
| 121 | /// Stop uart background receive | 106 | /// Stop DMA backed UART receiver |
| 122 | fn teardown_uart(&mut self) { | 107 | fn stop_uart(&mut self) { |
| 123 | self.ring_buf.request_pause(); | 108 | self.ring_buf.request_pause(); |
| 124 | 109 | ||
| 125 | let r = self.info.regs; | 110 | let r = self.info.regs; |
| @@ -153,13 +138,15 @@ impl<'d> RingBufferedUartRx<'d> { | |||
| 153 | pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { | 138 | pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { |
| 154 | let r = self.info.regs; | 139 | let r = self.info.regs; |
| 155 | 140 | ||
| 156 | // Start background receive if it was not already started | 141 | // Start DMA and Uart if it was not already started, |
| 142 | // otherwise check for errors in status register. | ||
| 143 | let sr = clear_idle_flag(r); | ||
| 157 | if !r.cr3().read().dmar() { | 144 | if !r.cr3().read().dmar() { |
| 158 | self.start()?; | 145 | self.start_uart(); |
| 146 | } else { | ||
| 147 | check_for_errors(sr)?; | ||
| 159 | } | 148 | } |
| 160 | 149 | ||
| 161 | check_for_errors(clear_idle_flag(r))?; | ||
| 162 | |||
| 163 | loop { | 150 | loop { |
| 164 | match self.ring_buf.read(buf) { | 151 | match self.ring_buf.read(buf) { |
| 165 | Ok((0, _)) => {} | 152 | Ok((0, _)) => {} |
| @@ -167,14 +154,16 @@ impl<'d> RingBufferedUartRx<'d> { | |||
| 167 | return Ok(len); | 154 | return Ok(len); |
| 168 | } | 155 | } |
| 169 | Err(_) => { | 156 | Err(_) => { |
| 170 | return self.stop(Error::Overrun); | 157 | self.stop_uart(); |
| 158 | return Err(Error::Overrun); | ||
| 171 | } | 159 | } |
| 172 | } | 160 | } |
| 173 | 161 | ||
| 174 | match self.wait_for_data_or_idle().await { | 162 | match self.wait_for_data_or_idle().await { |
| 175 | Ok(_) => {} | 163 | Ok(_) => {} |
| 176 | Err(err) => { | 164 | Err(err) => { |
| 177 | return self.stop(err); | 165 | self.stop_uart(); |
| 166 | return Err(err); | ||
| 178 | } | 167 | } |
| 179 | } | 168 | } |
| 180 | } | 169 | } |
| @@ -228,7 +217,7 @@ impl<'d> RingBufferedUartRx<'d> { | |||
| 228 | 217 | ||
| 229 | impl Drop for RingBufferedUartRx<'_> { | 218 | impl Drop for RingBufferedUartRx<'_> { |
| 230 | fn drop(&mut self) { | 219 | fn drop(&mut self) { |
| 231 | self.teardown_uart(); | 220 | self.stop_uart(); |
| 232 | self.rx.as_ref().map(|x| x.set_as_disconnected()); | 221 | self.rx.as_ref().map(|x| x.set_as_disconnected()); |
| 233 | self.rts.as_ref().map(|x| x.set_as_disconnected()); | 222 | self.rts.as_ref().map(|x| x.set_as_disconnected()); |
| 234 | super::drop_tx_rx(self.info, self.state); | 223 | super::drop_tx_rx(self.info, self.state); |
