Skip to content

Commit 885de2e

Browse files
authoredJul 27, 2024
Merge pull request #798 from jannic/issue-782
Avoid discarding already read bytes on error
2 parents 186cce2 + 4c50e94 commit 885de2e

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed
 

‎rp2040-hal/src/uart/peripheral.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub struct UartPeripheral<S: State, D: UartDevice, P: ValidUartPinout<D>> {
2121
device: D,
2222
_state: S,
2323
pins: P,
24+
read_error: Option<ReadErrorType>,
2425
}
2526

2627
impl<S: State, D: UartDevice, P: ValidUartPinout<D>> UartPeripheral<S, D, P> {
@@ -29,6 +30,7 @@ impl<S: State, D: UartDevice, P: ValidUartPinout<D>> UartPeripheral<S, D, P> {
2930
device: self.device,
3031
pins: self.pins,
3132
_state: state,
33+
read_error: None,
3234
}
3335
}
3436

@@ -48,6 +50,7 @@ impl<D: UartDevice, P: ValidUartPinout<D>> UartPeripheral<Disabled, D, P> {
4850
device,
4951
_state: Disabled,
5052
pins,
53+
read_error: None,
5154
}
5255
}
5356

@@ -88,6 +91,7 @@ impl<D: UartDevice, P: ValidUartPinout<D>> UartPeripheral<Disabled, D, P> {
8891
device,
8992
pins,
9093
_state: Enabled,
94+
read_error: None,
9195
})
9296
}
9397
}
@@ -247,6 +251,7 @@ impl<D: UartDevice, P: ValidUartPinout<D>> UartPeripheral<Enabled, D, P> {
247251
device: reader.device,
248252
_state: Enabled,
249253
pins: reader.pins,
254+
read_error: reader.read_error,
250255
}
251256
}
252257
}
@@ -257,6 +262,7 @@ impl<P: ValidUartPinout<UART0>> UartPeripheral<Enabled, UART0, P> {
257262
let reader = Reader {
258263
device: self.device,
259264
pins: self.pins,
265+
read_error: self.read_error,
260266
};
261267
// Safety: reader and writer will never write to the same address
262268
let device_copy = unsafe { Peripherals::steal().UART0 };
@@ -275,6 +281,7 @@ impl<P: ValidUartPinout<UART1>> UartPeripheral<Enabled, UART1, P> {
275281
let reader = Reader {
276282
device: self.device,
277283
pins: self.pins,
284+
read_error: self.read_error,
278285
};
279286
// Safety: reader and writer will never write to the same address
280287
let device_copy = unsafe { Peripherals::steal().UART1 };
@@ -466,7 +473,21 @@ impl<D: UartDevice, P: ValidUartPinout<D>> embedded_io::ErrorType
466473
}
467474
impl<D: UartDevice, P: ValidUartPinout<D>> embedded_io::Read for UartPeripheral<Enabled, D, P> {
468475
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
469-
nb::block!(self.read_raw(buf)).map_err(|e| e.err_type)
476+
// If the last read stored an error, report it now
477+
if let Some(err) = self.read_error.take() {
478+
return Err(err);
479+
}
480+
match nb::block!(self.read_raw(buf)) {
481+
Ok(bytes_read) => Ok(bytes_read),
482+
Err(err) if !err.discarded.is_empty() => {
483+
// If an error was reported but some bytes were already read,
484+
// return the data now and store the error for the next
485+
// invocation.
486+
self.read_error = Some(err.err_type);
487+
Ok(err.discarded.len())
488+
}
489+
Err(err) => Err(err.err_type),
490+
}
470491
}
471492
}
472493
impl<D: UartDevice, P: ValidUartPinout<D>> embedded_io::Write for UartPeripheral<Enabled, D, P> {

‎rp2040-hal/src/uart/reader.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ pub(crate) fn read_full_blocking<D: UartDevice>(
187187
pub struct Reader<D: UartDevice, P: ValidUartPinout<D>> {
188188
pub(super) device: D,
189189
pub(super) pins: P,
190+
pub(super) read_error: Option<ReadErrorType>,
190191
}
191192

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

226227
impl<D: UartDevice, P: ValidUartPinout<D>> embedded_io::Read for Reader<D, P> {
227228
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
228-
nb::block!(self.read_raw(buf)).map_err(|e| e.err_type)
229+
// If the last read stored an error, report it now
230+
if let Some(err) = self.read_error.take() {
231+
return Err(err);
232+
}
233+
match nb::block!(self.read_raw(buf)) {
234+
Ok(bytes_read) => Ok(bytes_read),
235+
Err(err) if !err.discarded.is_empty() => {
236+
// If an error was reported but some bytes were already read,
237+
// return the data now and store the error for the next
238+
// invocation.
239+
self.read_error = Some(err.err_type);
240+
Ok(err.discarded.len())
241+
}
242+
Err(err) => Err(err.err_type),
243+
}
229244
}
230245
}
231246

0 commit comments

Comments
 (0)