Merge pull request #3968 from embedded-rust-iml/feature/ringbuffered-embedded-hal-nb
Add embedded_hal_nb::serial::Read impl for RingBufferedUartRx
This commit is contained in:
commit
aadd4e5513
@ -133,6 +133,20 @@ impl<'d> RingBufferedUartRx<'d> {
|
|||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// (Re-)start DMA and Uart if it is not running (has not been started yet or has failed), and
|
||||||
|
/// check for errors in status register. Error flags are cleared in `start_uart()` so they need
|
||||||
|
/// to be read first without returning yet.
|
||||||
|
fn start_dma_or_check_errors(&mut self) -> Result<(), Error> {
|
||||||
|
let r = self.info.regs;
|
||||||
|
|
||||||
|
let sr = clear_idle_flag(r);
|
||||||
|
let res = check_for_errors(sr);
|
||||||
|
if !r.cr3().read().dmar() {
|
||||||
|
self.start_uart();
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
/// Read bytes that are readily available in the ring buffer.
|
/// Read bytes that are readily available in the ring buffer.
|
||||||
/// If no bytes are currently available in the buffer the call waits until the some
|
/// If no bytes are currently available in the buffer the call waits until the some
|
||||||
/// bytes are available (at least one byte and at most half the buffer size)
|
/// bytes are available (at least one byte and at most half the buffer size)
|
||||||
@ -142,17 +156,7 @@ impl<'d> RingBufferedUartRx<'d> {
|
|||||||
/// Receive in the background is terminated if an error is returned.
|
/// Receive in the background is terminated if an error is returned.
|
||||||
/// It must then manually be started again by calling `start()` or by re-calling `read()`.
|
/// It must then manually be started again by calling `start()` or by re-calling `read()`.
|
||||||
pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
|
pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
|
||||||
let r = self.info.regs;
|
self.start_dma_or_check_errors()?;
|
||||||
|
|
||||||
// (Re-)start DMA and Uart if it is not running (has not been started yet or has failed),
|
|
||||||
// and check for errors in status register. Error flags are cleared in `start_uart()` so
|
|
||||||
// they need to be read first without returning yet.
|
|
||||||
let sr = clear_idle_flag(r);
|
|
||||||
let res = check_for_errors(sr);
|
|
||||||
if !r.cr3().read().dmar() {
|
|
||||||
self.start_uart();
|
|
||||||
}
|
|
||||||
res?;
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match self.ring_buf.read(buf) {
|
match self.ring_buf.read(buf) {
|
||||||
@ -281,6 +285,29 @@ impl embedded_io_async::Read for RingBufferedUartRx<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl embedded_hal_nb::serial::Read for RingBufferedUartRx<'_> {
|
||||||
|
fn read(&mut self) -> nb::Result<u8, Self::Error> {
|
||||||
|
self.start_dma_or_check_errors()?;
|
||||||
|
|
||||||
|
let mut buf = [0u8; 1];
|
||||||
|
match self.ring_buf.read(&mut buf) {
|
||||||
|
Ok((0, _)) => Err(nb::Error::WouldBlock),
|
||||||
|
Ok((len, _)) => {
|
||||||
|
assert!(len == 1);
|
||||||
|
Ok(buf[0])
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
self.stop_uart();
|
||||||
|
Err(nb::Error::Other(Error::Overrun))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl embedded_hal_nb::serial::ErrorType for RingBufferedUartRx<'_> {
|
||||||
|
type Error = Error;
|
||||||
|
}
|
||||||
|
|
||||||
impl ReadReady for RingBufferedUartRx<'_> {
|
impl ReadReady for RingBufferedUartRx<'_> {
|
||||||
fn read_ready(&mut self) -> Result<bool, Self::Error> {
|
fn read_ready(&mut self) -> Result<bool, Self::Error> {
|
||||||
let len = self.ring_buf.len().map_err(|e| match e {
|
let len = self.ring_buf.len().map_err(|e| match e {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user