diff options
| author | pennae <[email protected]> | 2023-04-30 07:05:42 +0200 |
|---|---|---|
| committer | pennae <[email protected]> | 2023-05-01 15:24:03 +0200 |
| commit | 7ab9fe0522de81583592bd09c5c57910bed1c181 (patch) | |
| tree | a1941cf6840d61015d81ef78f4420a9e66761830 | |
| parent | 1c8492bab2534bd04389f055affe12c4de0e3857 (diff) | |
rp/uart: extract common code from async and blocking buffered reads
once we add error propagation the common code will become even larger,
so it makes sense to move it out.
| -rw-r--r-- | embassy-rp/src/uart/buffered.rs | 86 |
1 files changed, 39 insertions, 47 deletions
diff --git a/embassy-rp/src/uart/buffered.rs b/embassy-rp/src/uart/buffered.rs index f9fae4c50..3fe0c8c4e 100644 --- a/embassy-rp/src/uart/buffered.rs +++ b/embassy-rp/src/uart/buffered.rs | |||
| @@ -183,64 +183,56 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> { | |||
| 183 | Self { phantom: PhantomData } | 183 | Self { phantom: PhantomData } |
| 184 | } | 184 | } |
| 185 | 185 | ||
| 186 | fn read<'a>(buf: &'a mut [u8]) -> impl Future<Output = Result<usize, Error>> + 'a { | 186 | fn read<'a>(buf: &'a mut [u8]) -> impl Future<Output = Result<usize, Error>> + 'a |
| 187 | where | ||
| 188 | T: 'd, | ||
| 189 | { | ||
| 187 | poll_fn(move |cx| { | 190 | poll_fn(move |cx| { |
| 188 | if buf.is_empty() { | 191 | if let Poll::Ready(r) = Self::try_read(buf) { |
| 189 | return Poll::Ready(Ok(0)); | 192 | return Poll::Ready(r); |
| 190 | } | 193 | } |
| 191 | 194 | T::buffered_state().rx_waker.register(cx.waker()); | |
| 192 | let state = T::buffered_state(); | 195 | Poll::Pending |
| 193 | let mut rx_reader = unsafe { state.rx_buf.reader() }; | ||
| 194 | let n = rx_reader.pop(|data| { | ||
| 195 | let n = data.len().min(buf.len()); | ||
| 196 | buf[..n].copy_from_slice(&data[..n]); | ||
| 197 | n | ||
| 198 | }); | ||
| 199 | if n == 0 { | ||
| 200 | state.rx_waker.register(cx.waker()); | ||
| 201 | return Poll::Pending; | ||
| 202 | } | ||
| 203 | |||
| 204 | // (Re-)Enable the interrupt to receive more data in case it was | ||
| 205 | // disabled because the buffer was full. | ||
| 206 | let regs = T::regs(); | ||
| 207 | unsafe { | ||
| 208 | regs.uartimsc().write_set(|w| { | ||
| 209 | w.set_rxim(true); | ||
| 210 | w.set_rtim(true); | ||
| 211 | }); | ||
| 212 | } | ||
| 213 | |||
| 214 | Poll::Ready(Ok(n)) | ||
| 215 | }) | 196 | }) |
| 216 | } | 197 | } |
| 217 | 198 | ||
| 218 | pub fn blocking_read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { | 199 | fn try_read(buf: &mut [u8]) -> Poll<Result<usize, Error>> { |
| 219 | if buf.is_empty() { | 200 | if buf.is_empty() { |
| 220 | return Ok(0); | 201 | return Poll::Ready(Ok(0)); |
| 221 | } | 202 | } |
| 222 | 203 | ||
| 223 | loop { | 204 | let state = T::buffered_state(); |
| 224 | let state = T::buffered_state(); | 205 | let mut rx_reader = unsafe { state.rx_buf.reader() }; |
| 225 | let mut rx_reader = unsafe { state.rx_buf.reader() }; | 206 | let n = rx_reader.pop(|data| { |
| 226 | let n = rx_reader.pop(|data| { | 207 | let n = data.len().min(buf.len()); |
| 227 | let n = data.len().min(buf.len()); | 208 | buf[..n].copy_from_slice(&data[..n]); |
| 228 | buf[..n].copy_from_slice(&data[..n]); | 209 | n |
| 229 | n | 210 | }); |
| 211 | |||
| 212 | let result = if n == 0 { | ||
| 213 | return Poll::Pending; | ||
| 214 | } else { | ||
| 215 | Ok(n) | ||
| 216 | }; | ||
| 217 | |||
| 218 | // (Re-)Enable the interrupt to receive more data in case it was | ||
| 219 | // disabled because the buffer was full. | ||
| 220 | let regs = T::regs(); | ||
| 221 | unsafe { | ||
| 222 | regs.uartimsc().write_set(|w| { | ||
| 223 | w.set_rxim(true); | ||
| 224 | w.set_rtim(true); | ||
| 230 | }); | 225 | }); |
| 226 | } | ||
| 231 | 227 | ||
| 232 | if n > 0 { | 228 | Poll::Ready(result) |
| 233 | // (Re-)Enable the interrupt to receive more data in case it was | 229 | } |
| 234 | // disabled because the buffer was full. | ||
| 235 | let regs = T::regs(); | ||
| 236 | unsafe { | ||
| 237 | regs.uartimsc().write_set(|w| { | ||
| 238 | w.set_rxim(true); | ||
| 239 | w.set_rtim(true); | ||
| 240 | }); | ||
| 241 | } | ||
| 242 | 230 | ||
| 243 | return Ok(n); | 231 | pub fn blocking_read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { |
| 232 | loop { | ||
| 233 | match Self::try_read(buf) { | ||
| 234 | Poll::Ready(res) => return res, | ||
| 235 | Poll::Pending => continue, | ||
| 244 | } | 236 | } |
| 245 | } | 237 | } |
| 246 | } | 238 | } |
