Skip to content

Commit

Permalink
Merge pull request #798 from jannic/issue-782
Browse files Browse the repository at this point in the history
Avoid discarding already read bytes on error
  • Loading branch information
jannic authored Jul 27, 2024
2 parents 186cce2 + 4c50e94 commit 885de2e
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
23 changes: 22 additions & 1 deletion rp2040-hal/src/uart/peripheral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub struct UartPeripheral<S: State, D: UartDevice, P: ValidUartPinout<D>> {
device: D,
_state: S,
pins: P,
read_error: Option<ReadErrorType>,
}

impl<S: State, D: UartDevice, P: ValidUartPinout<D>> UartPeripheral<S, D, P> {
Expand All @@ -29,6 +30,7 @@ impl<S: State, D: UartDevice, P: ValidUartPinout<D>> UartPeripheral<S, D, P> {
device: self.device,
pins: self.pins,
_state: state,
read_error: None,
}
}

Expand All @@ -48,6 +50,7 @@ impl<D: UartDevice, P: ValidUartPinout<D>> UartPeripheral<Disabled, D, P> {
device,
_state: Disabled,
pins,
read_error: None,
}
}

Expand Down Expand Up @@ -88,6 +91,7 @@ impl<D: UartDevice, P: ValidUartPinout<D>> UartPeripheral<Disabled, D, P> {
device,
pins,
_state: Enabled,
read_error: None,
})
}
}
Expand Down Expand Up @@ -247,6 +251,7 @@ impl<D: UartDevice, P: ValidUartPinout<D>> UartPeripheral<Enabled, D, P> {
device: reader.device,
_state: Enabled,
pins: reader.pins,
read_error: reader.read_error,
}
}
}
Expand All @@ -257,6 +262,7 @@ impl<P: ValidUartPinout<UART0>> UartPeripheral<Enabled, UART0, P> {
let reader = Reader {
device: self.device,
pins: self.pins,
read_error: self.read_error,
};
// Safety: reader and writer will never write to the same address
let device_copy = unsafe { Peripherals::steal().UART0 };
Expand All @@ -275,6 +281,7 @@ impl<P: ValidUartPinout<UART1>> UartPeripheral<Enabled, UART1, P> {
let reader = Reader {
device: self.device,
pins: self.pins,
read_error: self.read_error,
};
// Safety: reader and writer will never write to the same address
let device_copy = unsafe { Peripherals::steal().UART1 };
Expand Down Expand Up @@ -466,7 +473,21 @@ impl<D: UartDevice, P: ValidUartPinout<D>> embedded_io::ErrorType
}
impl<D: UartDevice, P: ValidUartPinout<D>> embedded_io::Read for UartPeripheral<Enabled, D, P> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
nb::block!(self.read_raw(buf)).map_err(|e| e.err_type)
// If the last read stored an error, report it now
if let Some(err) = self.read_error.take() {
return Err(err);
}
match nb::block!(self.read_raw(buf)) {
Ok(bytes_read) => Ok(bytes_read),
Err(err) if !err.discarded.is_empty() => {
// If an error was reported but some bytes were already read,
// return the data now and store the error for the next
// invocation.
self.read_error = Some(err.err_type);
Ok(err.discarded.len())
}
Err(err) => Err(err.err_type),
}
}
}
impl<D: UartDevice, P: ValidUartPinout<D>> embedded_io::Write for UartPeripheral<Enabled, D, P> {
Expand Down
17 changes: 16 additions & 1 deletion rp2040-hal/src/uart/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ pub(crate) fn read_full_blocking<D: UartDevice>(
pub struct Reader<D: UartDevice, P: ValidUartPinout<D>> {
pub(super) device: D,
pub(super) pins: P,
pub(super) read_error: Option<ReadErrorType>,
}

impl<D: UartDevice, P: ValidUartPinout<D>> Reader<D, P> {
Expand Down Expand Up @@ -225,7 +226,21 @@ impl<D: UartDevice, P: ValidUartPinout<D>> embedded_io::ErrorType for Reader<D,

impl<D: UartDevice, P: ValidUartPinout<D>> embedded_io::Read for Reader<D, P> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
nb::block!(self.read_raw(buf)).map_err(|e| e.err_type)
// If the last read stored an error, report it now
if let Some(err) = self.read_error.take() {
return Err(err);
}
match nb::block!(self.read_raw(buf)) {
Ok(bytes_read) => Ok(bytes_read),
Err(err) if !err.discarded.is_empty() => {
// If an error was reported but some bytes were already read,
// return the data now and store the error for the next
// invocation.
self.read_error = Some(err.err_type);
Ok(err.discarded.len())
}
Err(err) => Err(err.err_type),
}
}
}

Expand Down

0 comments on commit 885de2e

Please sign in to comment.