mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-25 16:23:10 +00:00
Merge pull request #3174 from JomerDev/add-count-to-read_to_break
RP2040: Add read_to_break_with_count
This commit is contained in:
commit
f2c29ba9d8
@ -490,6 +490,36 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
|
|||||||
/// * The first call to `read_to_break()` will return `Ok(20)`.
|
/// * The first call to `read_to_break()` will return `Ok(20)`.
|
||||||
/// * The next call to `read_to_break()` will work as expected
|
/// * The next call to `read_to_break()` will work as expected
|
||||||
pub async fn read_to_break(&mut self, buffer: &mut [u8]) -> Result<usize, ReadToBreakError> {
|
pub async fn read_to_break(&mut self, buffer: &mut [u8]) -> Result<usize, ReadToBreakError> {
|
||||||
|
self.read_to_break_with_count(buffer, 0).await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read from the UART, waiting for a line break as soon as at least `min_count` bytes have been read.
|
||||||
|
///
|
||||||
|
/// We read until one of the following occurs:
|
||||||
|
///
|
||||||
|
/// * We read `buffer.len()` bytes without a line break
|
||||||
|
/// * returns `Err(ReadToBreakError::MissingBreak(buffer.len()))`
|
||||||
|
/// * We read `n > min_count` bytes then a line break occurs
|
||||||
|
/// * returns `Ok(n)`
|
||||||
|
/// * We encounter some error OTHER than a line break
|
||||||
|
/// * returns `Err(ReadToBreakError::Other(error))`
|
||||||
|
///
|
||||||
|
/// If a line break occurs before `min_count` bytes have been read, the break will be ignored and the read will continue
|
||||||
|
///
|
||||||
|
/// **NOTE**: you MUST provide a buffer one byte larger than your largest expected
|
||||||
|
/// message to reliably detect the framing on one single call to `read_to_break()`.
|
||||||
|
///
|
||||||
|
/// * If you expect a message of 20 bytes + line break, and provide a 20-byte buffer:
|
||||||
|
/// * The first call to `read_to_break()` will return `Err(ReadToBreakError::MissingBreak(20))`
|
||||||
|
/// * The next call to `read_to_break()` will immediately return `Ok(0)`, from the "stale" line break
|
||||||
|
/// * If you expect a message of 20 bytes + line break, and provide a 21-byte buffer:
|
||||||
|
/// * The first call to `read_to_break()` will return `Ok(20)`.
|
||||||
|
/// * The next call to `read_to_break()` will work as expected
|
||||||
|
pub async fn read_to_break_with_count(
|
||||||
|
&mut self,
|
||||||
|
buffer: &mut [u8],
|
||||||
|
min_count: usize,
|
||||||
|
) -> Result<usize, ReadToBreakError> {
|
||||||
// clear error flags before we drain the fifo. errors that have accumulated
|
// clear error flags before we drain the fifo. errors that have accumulated
|
||||||
// in the flags will also be present in the fifo.
|
// in the flags will also be present in the fifo.
|
||||||
T::dma_state().rx_errs.store(0, Ordering::Relaxed);
|
T::dma_state().rx_errs.store(0, Ordering::Relaxed);
|
||||||
@ -502,7 +532,7 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
|
|||||||
|
|
||||||
// then drain the fifo. we need to read at most 32 bytes. errors that apply
|
// then drain the fifo. we need to read at most 32 bytes. errors that apply
|
||||||
// to fifo bytes will be reported directly.
|
// to fifo bytes will be reported directly.
|
||||||
let sbuffer = match {
|
let mut sbuffer = match {
|
||||||
let limit = buffer.len().min(32);
|
let limit = buffer.len().min(32);
|
||||||
self.drain_fifo(&mut buffer[0..limit])
|
self.drain_fifo(&mut buffer[0..limit])
|
||||||
} {
|
} {
|
||||||
@ -511,7 +541,13 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
|
|||||||
// Drained (some/all of the fifo), no room left
|
// Drained (some/all of the fifo), no room left
|
||||||
Ok(len) => return Err(ReadToBreakError::MissingBreak(len)),
|
Ok(len) => return Err(ReadToBreakError::MissingBreak(len)),
|
||||||
// We got a break WHILE draining the FIFO, return what we did get before the break
|
// We got a break WHILE draining the FIFO, return what we did get before the break
|
||||||
Err((i, Error::Break)) => return Ok(i),
|
Err((len, Error::Break)) => {
|
||||||
|
if len < min_count && len < buffer.len() {
|
||||||
|
&mut buffer[len..]
|
||||||
|
} else {
|
||||||
|
return Ok(len);
|
||||||
|
}
|
||||||
|
}
|
||||||
// Some other error, just return the error
|
// Some other error, just return the error
|
||||||
Err((_i, e)) => return Err(ReadToBreakError::Other(e)),
|
Err((_i, e)) => return Err(ReadToBreakError::Other(e)),
|
||||||
};
|
};
|
||||||
@ -530,6 +566,8 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
|
|||||||
reg.set_rxdmae(true);
|
reg.set_rxdmae(true);
|
||||||
reg.set_dmaonerr(true);
|
reg.set_dmaonerr(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
loop {
|
||||||
let transfer = unsafe {
|
let transfer = unsafe {
|
||||||
// If we don't assign future to a variable, the data register pointer
|
// If we don't assign future to a variable, the data register pointer
|
||||||
// is held across an await and makes the future non-Send.
|
// is held across an await and makes the future non-Send.
|
||||||
@ -588,6 +626,11 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
|
|||||||
unreachable!("UART DMA reported invalid `write_addr`");
|
unreachable!("UART DMA reported invalid `write_addr`");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (next_addr - sval) < min_count {
|
||||||
|
sbuffer = &mut buffer[(next_addr - sval)..];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let regs = T::regs();
|
let regs = T::regs();
|
||||||
let all_full = next_addr == eval;
|
let all_full = next_addr == eval;
|
||||||
|
|
||||||
@ -636,6 +679,7 @@ impl<'d, T: Instance> UartRx<'d, T, Async> {
|
|||||||
unreachable!("unrecognized rx error");
|
unreachable!("unrecognized rx error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> Uart<'d, T, Blocking> {
|
impl<'d, T: Instance> Uart<'d, T, Blocking> {
|
||||||
/// Create a new UART without hardware flow control
|
/// Create a new UART without hardware flow control
|
||||||
@ -997,6 +1041,17 @@ impl<'d, T: Instance> Uart<'d, T, Async> {
|
|||||||
pub async fn read_to_break<'a>(&mut self, buf: &'a mut [u8]) -> Result<usize, ReadToBreakError> {
|
pub async fn read_to_break<'a>(&mut self, buf: &'a mut [u8]) -> Result<usize, ReadToBreakError> {
|
||||||
self.rx.read_to_break(buf).await
|
self.rx.read_to_break(buf).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read until the buffer is full or a line break occurs after at least `min_count` bytes have been read.
|
||||||
|
///
|
||||||
|
/// See [`UartRx::read_to_break_with_count()`] for more details
|
||||||
|
pub async fn read_to_break_with_count<'a>(
|
||||||
|
&mut self,
|
||||||
|
buf: &'a mut [u8],
|
||||||
|
min_count: usize,
|
||||||
|
) -> Result<usize, ReadToBreakError> {
|
||||||
|
self.rx.read_to_break_with_count(buf, min_count).await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance, M: Mode> embedded_hal_02::serial::Read<u8> for UartRx<'d, T, M> {
|
impl<'d, T: Instance, M: Mode> embedded_hal_02::serial::Read<u8> for UartRx<'d, T, M> {
|
||||||
|
Loading…
Reference in New Issue
Block a user