aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpennae <[email protected]>2023-04-30 07:05:42 +0200
committerpennae <[email protected]>2023-05-01 15:24:03 +0200
commit7ab9fe0522de81583592bd09c5c57910bed1c181 (patch)
treea1941cf6840d61015d81ef78f4420a9e66761830
parent1c8492bab2534bd04389f055affe12c4de0e3857 (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.rs86
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 }