aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-nrf/Cargo.toml1
-rw-r--r--embassy-nrf/src/uarte.rs95
2 files changed, 85 insertions, 11 deletions
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml
index 10f268b51..580f0e3e6 100644
--- a/embassy-nrf/Cargo.toml
+++ b/embassy-nrf/Cargo.toml
@@ -133,6 +133,7 @@ embedded-io = { version = "0.6.0" }
133embedded-io-async = { version = "0.6.1" } 133embedded-io-async = { version = "0.6.1" }
134 134
135defmt = { version = "0.3", optional = true } 135defmt = { version = "0.3", optional = true }
136bitflags = "2.4.2"
136log = { version = "0.4.14", optional = true } 137log = { version = "0.4.14", optional = true }
137cortex-m-rt = ">=0.6.15,<0.8" 138cortex-m-rt = ">=0.6.15,<0.8"
138cortex-m = "0.7.6" 139cortex-m = "0.7.6"
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs
index 95434e7a7..90d851139 100644
--- a/embassy-nrf/src/uarte.rs
+++ b/embassy-nrf/src/uarte.rs
@@ -52,6 +52,39 @@ impl Default for Config {
52 } 52 }
53} 53}
54 54
55bitflags::bitflags! {
56 /// Error source flags
57 pub struct ErrorSource: u32 {
58 /// Buffer overrun
59 const OVERRUN = 0x01;
60 /// Parity error
61 const PARITY = 0x02;
62 /// Framing error
63 const FRAMING = 0x04;
64 /// Break condition
65 const BREAK = 0x08;
66 }
67}
68
69impl TryFrom<ErrorSource> for () {
70 type Error = Error;
71
72 #[inline]
73 fn try_from(errors: ErrorSource) -> Result<Self, Self::Error> {
74 if errors.contains(ErrorSource::OVERRUN) {
75 Err(Error::Overrun)
76 } else if errors.contains(ErrorSource::PARITY) {
77 Err(Error::Parity)
78 } else if errors.contains(ErrorSource::FRAMING) {
79 Err(Error::Framing)
80 } else if errors.contains(ErrorSource::BREAK) {
81 Err(Error::Break)
82 } else {
83 Ok(())
84 }
85 }
86}
87
55/// UART error. 88/// UART error.
56#[derive(Debug, Clone, Copy, PartialEq, Eq)] 89#[derive(Debug, Clone, Copy, PartialEq, Eq)]
57#[cfg_attr(feature = "defmt", derive(defmt::Format))] 90#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -61,6 +94,14 @@ pub enum Error {
61 BufferTooLong, 94 BufferTooLong,
62 /// The buffer is not in data RAM. It's most likely in flash, and nRF's DMA cannot access flash. 95 /// The buffer is not in data RAM. It's most likely in flash, and nRF's DMA cannot access flash.
63 BufferNotInRAM, 96 BufferNotInRAM,
97 /// Framing Error
98 Framing,
99 /// Parity Error
100 Parity,
101 /// Buffer Overrun
102 Overrun,
103 /// Break condition
104 Break,
64} 105}
65 106
66/// Interrupt handler. 107/// Interrupt handler.
@@ -73,9 +114,16 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
73 let r = T::regs(); 114 let r = T::regs();
74 let s = T::state(); 115 let s = T::state();
75 116
76 if r.events_endrx.read().bits() != 0 { 117 let endrx = r.events_endrx.read().bits();
118 let error = r.events_error.read().bits();
119 if endrx != 0 || error != 0 {
77 s.endrx_waker.wake(); 120 s.endrx_waker.wake();
78 r.intenclr.write(|w| w.endrx().clear()); 121 if endrx != 0 {
122 r.intenclr.write(|w| w.endrx().clear());
123 }
124 if error != 0 {
125 r.intenclr.write(|w| w.error().clear());
126 }
79 } 127 }
80 if r.events_endtx.read().bits() != 0 { 128 if r.events_endtx.read().bits() != 0 {
81 s.endtx_waker.wake(); 129 s.endtx_waker.wake();
@@ -486,6 +534,13 @@ impl<'d, T: Instance> UarteRx<'d, T> {
486 Self::new_inner(uarte, rxd.map_into(), Some(rts.map_into()), config) 534 Self::new_inner(uarte, rxd.map_into(), Some(rts.map_into()), config)
487 } 535 }
488 536
537 fn read_and_clear_errors(&mut self) -> Result<(), Error> {
538 let r = T::regs();
539 let err_bits = r.errorsrc.read().bits();
540 r.errorsrc.write(|w| unsafe { w.bits(err_bits) });
541 ErrorSource::from_bits_truncate(err_bits).try_into()
542 }
543
489 fn new_inner( 544 fn new_inner(
490 uarte: impl Peripheral<P = T> + 'd, 545 uarte: impl Peripheral<P = T> + 'd,
491 rxd: PeripheralRef<'d, AnyPin>, 546 rxd: PeripheralRef<'d, AnyPin>,
@@ -572,7 +627,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
572 627
573 /// Read bytes until the buffer is filled. 628 /// Read bytes until the buffer is filled.
574 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { 629 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
575 if buffer.len() == 0 { 630 if buffer.is_empty() {
576 return Ok(()); 631 return Ok(());
577 } 632 }
578 if buffer.len() > EASY_DMA_SIZE { 633 if buffer.len() > EASY_DMA_SIZE {
@@ -588,8 +643,13 @@ impl<'d, T: Instance> UarteRx<'d, T> {
588 let drop = OnDrop::new(move || { 643 let drop = OnDrop::new(move || {
589 trace!("read drop: stopping"); 644 trace!("read drop: stopping");
590 645
591 r.intenclr.write(|w| w.endrx().clear()); 646 r.intenclr.write(|w| {
647 w.endrx().clear();
648 w.error().clear()
649 });
592 r.events_rxto.reset(); 650 r.events_rxto.reset();
651 r.events_error.reset();
652 r.errorsrc.reset();
593 r.tasks_stoprx.write(|w| unsafe { w.bits(1) }); 653 r.tasks_stoprx.write(|w| unsafe { w.bits(1) });
594 654
595 while r.events_endrx.read().bits() == 0 {} 655 while r.events_endrx.read().bits() == 0 {}
@@ -601,17 +661,26 @@ impl<'d, T: Instance> UarteRx<'d, T> {
601 r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); 661 r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) });
602 662
603 r.events_endrx.reset(); 663 r.events_endrx.reset();
604 r.intenset.write(|w| w.endrx().set()); 664 r.events_error.reset();
665 r.intenset.write(|w| {
666 w.endrx().set();
667 w.error().set()
668 });
605 669
606 compiler_fence(Ordering::SeqCst); 670 compiler_fence(Ordering::SeqCst);
607 671
608 trace!("startrx"); 672 trace!("startrx");
609 r.tasks_startrx.write(|w| unsafe { w.bits(1) }); 673 r.tasks_startrx.write(|w| unsafe { w.bits(1) });
610 674
611 poll_fn(|cx| { 675 let result = poll_fn(|cx| {
612 s.endrx_waker.register(cx.waker()); 676 s.endrx_waker.register(cx.waker());
677
678 let maybe_err = self.read_and_clear_errors();
679 if let Err(e) = maybe_err {
680 return Poll::Ready(Err(e));
681 }
613 if r.events_endrx.read().bits() != 0 { 682 if r.events_endrx.read().bits() != 0 {
614 return Poll::Ready(()); 683 return Poll::Ready(Ok(()));
615 } 684 }
616 Poll::Pending 685 Poll::Pending
617 }) 686 })
@@ -621,7 +690,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
621 r.events_rxstarted.reset(); 690 r.events_rxstarted.reset();
622 drop.defuse(); 691 drop.defuse();
623 692
624 Ok(()) 693 result
625 } 694 }
626 695
627 /// Read bytes until the buffer is filled. 696 /// Read bytes until the buffer is filled.
@@ -642,19 +711,23 @@ impl<'d, T: Instance> UarteRx<'d, T> {
642 r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); 711 r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) });
643 712
644 r.events_endrx.reset(); 713 r.events_endrx.reset();
645 r.intenclr.write(|w| w.endrx().clear()); 714 r.events_error.reset();
715 r.intenclr.write(|w| {
716 w.endrx().clear();
717 w.error().clear()
718 });
646 719
647 compiler_fence(Ordering::SeqCst); 720 compiler_fence(Ordering::SeqCst);
648 721
649 trace!("startrx"); 722 trace!("startrx");
650 r.tasks_startrx.write(|w| unsafe { w.bits(1) }); 723 r.tasks_startrx.write(|w| unsafe { w.bits(1) });
651 724
652 while r.events_endrx.read().bits() == 0 {} 725 while r.events_endrx.read().bits() == 0 && r.events_error.read().bits() == 0 {}
653 726
654 compiler_fence(Ordering::SeqCst); 727 compiler_fence(Ordering::SeqCst);
655 r.events_rxstarted.reset(); 728 r.events_rxstarted.reset();
656 729
657 Ok(()) 730 self.read_and_clear_errors()
658 } 731 }
659} 732}
660 733