From d364447a34377c708fe6a7ea87aabda3ea1231ba Mon Sep 17 00:00:00 2001 From: Justin Beaurivage <justin@wearableavionics.com> Date: Wed, 31 Jan 2024 14:16:58 -0500 Subject: [PATCH] Add error handling to UarteRxWithIdle --- embassy-nrf/src/uarte.rs | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 90d851139..97c887ab2 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs @@ -534,7 +534,8 @@ impl<'d, T: Instance> UarteRx<'d, T> { Self::new_inner(uarte, rxd.map_into(), Some(rts.map_into()), config) } - fn read_and_clear_errors(&mut self) -> Result<(), Error> { + /// Check for errors and clear the error register if an error occured. + fn check_and_clear_errors(&mut self) -> Result<(), Error> { let r = T::regs(); let err_bits = r.errorsrc.read().bits(); r.errorsrc.write(|w| unsafe { w.bits(err_bits) }); @@ -675,8 +676,7 @@ impl<'d, T: Instance> UarteRx<'d, T> { let result = poll_fn(|cx| { s.endrx_waker.register(cx.waker()); - let maybe_err = self.read_and_clear_errors(); - if let Err(e) = maybe_err { + if let Err(e) = self.check_and_clear_errors() { return Poll::Ready(Err(e)); } if r.events_endrx.read().bits() != 0 { @@ -727,7 +727,7 @@ impl<'d, T: Instance> UarteRx<'d, T> { compiler_fence(Ordering::SeqCst); r.events_rxstarted.reset(); - self.read_and_clear_errors() + self.check_and_clear_errors() } } @@ -794,8 +794,12 @@ impl<'d, T: Instance, U: TimerInstance> UarteRxWithIdle<'d, T, U> { let drop = OnDrop::new(|| { self.timer.stop(); - r.intenclr.write(|w| w.endrx().clear()); + r.intenclr.write(|w| { + w.endrx().clear(); + w.error().clear() + }); r.events_rxto.reset(); + r.events_error.reset(); r.tasks_stoprx.write(|w| unsafe { w.bits(1) }); while r.events_endrx.read().bits() == 0 {} @@ -805,17 +809,23 @@ impl<'d, T: Instance, U: TimerInstance> UarteRxWithIdle<'d, T, U> { r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); r.events_endrx.reset(); - r.intenset.write(|w| w.endrx().set()); + r.events_error.reset(); + r.intenset.write(|w| {w.endrx().set(); w.error().set()}); compiler_fence(Ordering::SeqCst); r.tasks_startrx.write(|w| unsafe { w.bits(1) }); - poll_fn(|cx| { + let result = poll_fn(|cx| { s.endrx_waker.register(cx.waker()); - if r.events_endrx.read().bits() != 0 { - return Poll::Ready(()); + + if let Err(e) = self.rx.check_and_clear_errors() { + return Poll::Ready(Err(e)); } + if r.events_endrx.read().bits() != 0 { + return Poll::Ready(Ok(())); + } + Poll::Pending }) .await; @@ -828,7 +838,7 @@ impl<'d, T: Instance, U: TimerInstance> UarteRxWithIdle<'d, T, U> { drop.defuse(); - Ok(n) + result.map(|_| n) } /// Read bytes until the buffer is filled, or the line becomes idle. @@ -853,13 +863,14 @@ impl<'d, T: Instance, U: TimerInstance> UarteRxWithIdle<'d, T, U> { r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); r.events_endrx.reset(); - r.intenclr.write(|w| w.endrx().clear()); + r.events_error.reset(); + r.intenclr.write(|w| {w.endrx().clear(); w.error().clear()}); compiler_fence(Ordering::SeqCst); r.tasks_startrx.write(|w| unsafe { w.bits(1) }); - while r.events_endrx.read().bits() == 0 {} + while r.events_endrx.read().bits() == 0 && r.events_error.read().bits() == 0 {} compiler_fence(Ordering::SeqCst); let n = r.rxd.amount.read().amount().bits() as usize; @@ -867,7 +878,7 @@ impl<'d, T: Instance, U: TimerInstance> UarteRxWithIdle<'d, T, U> { self.timer.stop(); r.events_rxstarted.reset(); - Ok(n) + self.rx.check_and_clear_errors().map(|_| n) } }