From 7ab9fe0522de81583592bd09c5c57910bed1c181 Mon Sep 17 00:00:00 2001 From: pennae Date: Sun, 30 Apr 2023 07:05:42 +0200 Subject: [PATCH] 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. --- embassy-rp/src/uart/buffered.rs | 86 +++++++++++++++------------------ 1 file 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> { Self { phantom: PhantomData } } - fn read<'a>(buf: &'a mut [u8]) -> impl Future> + 'a { + fn read<'a>(buf: &'a mut [u8]) -> impl Future> + 'a + where + T: 'd, + { poll_fn(move |cx| { - if buf.is_empty() { - return Poll::Ready(Ok(0)); + if let Poll::Ready(r) = Self::try_read(buf) { + return Poll::Ready(r); } - - let state = T::buffered_state(); - let mut rx_reader = unsafe { state.rx_buf.reader() }; - let n = rx_reader.pop(|data| { - let n = data.len().min(buf.len()); - buf[..n].copy_from_slice(&data[..n]); - n - }); - if n == 0 { - state.rx_waker.register(cx.waker()); - return Poll::Pending; - } - - // (Re-)Enable the interrupt to receive more data in case it was - // disabled because the buffer was full. - let regs = T::regs(); - unsafe { - regs.uartimsc().write_set(|w| { - w.set_rxim(true); - w.set_rtim(true); - }); - } - - Poll::Ready(Ok(n)) + T::buffered_state().rx_waker.register(cx.waker()); + Poll::Pending }) } - pub fn blocking_read(&mut self, buf: &mut [u8]) -> Result { + fn try_read(buf: &mut [u8]) -> Poll> { if buf.is_empty() { - return Ok(0); + return Poll::Ready(Ok(0)); } - loop { - let state = T::buffered_state(); - let mut rx_reader = unsafe { state.rx_buf.reader() }; - let n = rx_reader.pop(|data| { - let n = data.len().min(buf.len()); - buf[..n].copy_from_slice(&data[..n]); - n + let state = T::buffered_state(); + let mut rx_reader = unsafe { state.rx_buf.reader() }; + let n = rx_reader.pop(|data| { + let n = data.len().min(buf.len()); + buf[..n].copy_from_slice(&data[..n]); + n + }); + + let result = if n == 0 { + return Poll::Pending; + } else { + Ok(n) + }; + + // (Re-)Enable the interrupt to receive more data in case it was + // disabled because the buffer was full. + let regs = T::regs(); + unsafe { + regs.uartimsc().write_set(|w| { + w.set_rxim(true); + w.set_rtim(true); }); + } - if n > 0 { - // (Re-)Enable the interrupt to receive more data in case it was - // disabled because the buffer was full. - let regs = T::regs(); - unsafe { - regs.uartimsc().write_set(|w| { - w.set_rxim(true); - w.set_rtim(true); - }); - } + Poll::Ready(result) + } - return Ok(n); + pub fn blocking_read(&mut self, buf: &mut [u8]) -> Result { + loop { + match Self::try_read(buf) { + Poll::Ready(res) => return res, + Poll::Pending => continue, } } }