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.
This commit is contained in:
@ -183,8 +183,20 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> {
|
|||||||
Self { phantom: PhantomData }
|
Self { phantom: PhantomData }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read<'a>(buf: &'a mut [u8]) -> impl Future<Output = Result<usize, Error>> + 'a {
|
fn read<'a>(buf: &'a mut [u8]) -> impl Future<Output = Result<usize, Error>> + 'a
|
||||||
|
where
|
||||||
|
T: 'd,
|
||||||
|
{
|
||||||
poll_fn(move |cx| {
|
poll_fn(move |cx| {
|
||||||
|
if let Poll::Ready(r) = Self::try_read(buf) {
|
||||||
|
return Poll::Ready(r);
|
||||||
|
}
|
||||||
|
T::buffered_state().rx_waker.register(cx.waker());
|
||||||
|
Poll::Pending
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_read(buf: &mut [u8]) -> Poll<Result<usize, Error>> {
|
||||||
if buf.is_empty() {
|
if buf.is_empty() {
|
||||||
return Poll::Ready(Ok(0));
|
return Poll::Ready(Ok(0));
|
||||||
}
|
}
|
||||||
@ -196,10 +208,12 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> {
|
|||||||
buf[..n].copy_from_slice(&data[..n]);
|
buf[..n].copy_from_slice(&data[..n]);
|
||||||
n
|
n
|
||||||
});
|
});
|
||||||
if n == 0 {
|
|
||||||
state.rx_waker.register(cx.waker());
|
let result = if n == 0 {
|
||||||
return Poll::Pending;
|
return Poll::Pending;
|
||||||
}
|
} else {
|
||||||
|
Ok(n)
|
||||||
|
};
|
||||||
|
|
||||||
// (Re-)Enable the interrupt to receive more data in case it was
|
// (Re-)Enable the interrupt to receive more data in case it was
|
||||||
// disabled because the buffer was full.
|
// disabled because the buffer was full.
|
||||||
@ -211,36 +225,14 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Poll::Ready(Ok(n))
|
Poll::Ready(result)
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn blocking_read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
|
pub fn blocking_read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
|
||||||
if buf.is_empty() {
|
|
||||||
return Ok(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let state = T::buffered_state();
|
match Self::try_read(buf) {
|
||||||
let mut rx_reader = unsafe { state.rx_buf.reader() };
|
Poll::Ready(res) => return res,
|
||||||
let n = rx_reader.pop(|data| {
|
Poll::Pending => continue,
|
||||||
let n = data.len().min(buf.len());
|
|
||||||
buf[..n].copy_from_slice(&data[..n]);
|
|
||||||
n
|
|
||||||
});
|
|
||||||
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(n);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user