aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-02-05 23:36:42 +0000
committerGitHub <[email protected]>2024-02-05 23:36:42 +0000
commitad7d4494fad12f98c7e8e2b776bc12453a66be9a (patch)
tree1219ae0fbef953c26e00a7afda6c7925b89b3e44
parentf9cba604a51b81209efa1a81123928bb876f2033 (diff)
parent2575f597cc3aafeb9925511b12adf30f6a67bccb (diff)
Merge pull request #2502 from jbeaurivage/nrf-uarte-errors
NRF: handle `uarte` RX errors
-rw-r--r--embassy-nrf/Cargo.toml1
-rw-r--r--embassy-nrf/src/uarte.rs128
2 files changed, 110 insertions, 19 deletions
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml
index a682e1227..7e161df9b 100644
--- a/embassy-nrf/Cargo.toml
+++ b/embassy-nrf/Cargo.toml
@@ -138,6 +138,7 @@ embedded-io = { version = "0.6.0" }
138embedded-io-async = { version = "0.6.1" } 138embedded-io-async = { version = "0.6.1" }
139 139
140defmt = { version = "0.3", optional = true } 140defmt = { version = "0.3", optional = true }
141bitflags = "2.4.2"
141log = { version = "0.4.14", optional = true } 142log = { version = "0.4.14", optional = true }
142cortex-m-rt = ">=0.6.15,<0.8" 143cortex-m-rt = ">=0.6.15,<0.8"
143cortex-m = "0.7.6" 144cortex-m = "0.7.6"
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs
index 95434e7a7..de2966ba5 100644
--- a/embassy-nrf/src/uarte.rs
+++ b/embassy-nrf/src/uarte.rs
@@ -52,6 +52,37 @@ 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 ErrorSource {
70 #[inline]
71 fn check(self) -> Result<(), Error> {
72 if self.contains(ErrorSource::OVERRUN) {
73 Err(Error::Overrun)
74 } else if self.contains(ErrorSource::PARITY) {
75 Err(Error::Parity)
76 } else if self.contains(ErrorSource::FRAMING) {
77 Err(Error::Framing)
78 } else if self.contains(ErrorSource::BREAK) {
79 Err(Error::Break)
80 } else {
81 Ok(())
82 }
83 }
84}
85
55/// UART error. 86/// UART error.
56#[derive(Debug, Clone, Copy, PartialEq, Eq)] 87#[derive(Debug, Clone, Copy, PartialEq, Eq)]
57#[cfg_attr(feature = "defmt", derive(defmt::Format))] 88#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -61,6 +92,14 @@ pub enum Error {
61 BufferTooLong, 92 BufferTooLong,
62 /// The buffer is not in data RAM. It's most likely in flash, and nRF's DMA cannot access flash. 93 /// The buffer is not in data RAM. It's most likely in flash, and nRF's DMA cannot access flash.
63 BufferNotInRAM, 94 BufferNotInRAM,
95 /// Framing Error
96 Framing,
97 /// Parity Error
98 Parity,
99 /// Buffer Overrun
100 Overrun,
101 /// Break condition
102 Break,
64} 103}
65 104
66/// Interrupt handler. 105/// Interrupt handler.
@@ -73,9 +112,16 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
73 let r = T::regs(); 112 let r = T::regs();
74 let s = T::state(); 113 let s = T::state();
75 114
76 if r.events_endrx.read().bits() != 0 { 115 let endrx = r.events_endrx.read().bits();
116 let error = r.events_error.read().bits();
117 if endrx != 0 || error != 0 {
77 s.endrx_waker.wake(); 118 s.endrx_waker.wake();
78 r.intenclr.write(|w| w.endrx().clear()); 119 if endrx != 0 {
120 r.intenclr.write(|w| w.endrx().clear());
121 }
122 if error != 0 {
123 r.intenclr.write(|w| w.error().clear());
124 }
79 } 125 }
80 if r.events_endtx.read().bits() != 0 { 126 if r.events_endtx.read().bits() != 0 {
81 s.endtx_waker.wake(); 127 s.endtx_waker.wake();
@@ -486,6 +532,14 @@ impl<'d, T: Instance> UarteRx<'d, T> {
486 Self::new_inner(uarte, rxd.map_into(), Some(rts.map_into()), config) 532 Self::new_inner(uarte, rxd.map_into(), Some(rts.map_into()), config)
487 } 533 }
488 534
535 /// Check for errors and clear the error register if an error occured.
536 fn check_and_clear_errors(&mut self) -> Result<(), Error> {
537 let r = T::regs();
538 let err_bits = r.errorsrc.read().bits();
539 r.errorsrc.write(|w| unsafe { w.bits(err_bits) });
540 ErrorSource::from_bits_truncate(err_bits).check()
541 }
542
489 fn new_inner( 543 fn new_inner(
490 uarte: impl Peripheral<P = T> + 'd, 544 uarte: impl Peripheral<P = T> + 'd,
491 rxd: PeripheralRef<'d, AnyPin>, 545 rxd: PeripheralRef<'d, AnyPin>,
@@ -572,7 +626,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
572 626
573 /// Read bytes until the buffer is filled. 627 /// Read bytes until the buffer is filled.
574 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { 628 pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
575 if buffer.len() == 0 { 629 if buffer.is_empty() {
576 return Ok(()); 630 return Ok(());
577 } 631 }
578 if buffer.len() > EASY_DMA_SIZE { 632 if buffer.len() > EASY_DMA_SIZE {
@@ -588,8 +642,13 @@ impl<'d, T: Instance> UarteRx<'d, T> {
588 let drop = OnDrop::new(move || { 642 let drop = OnDrop::new(move || {
589 trace!("read drop: stopping"); 643 trace!("read drop: stopping");
590 644
591 r.intenclr.write(|w| w.endrx().clear()); 645 r.intenclr.write(|w| {
646 w.endrx().clear();
647 w.error().clear()
648 });
592 r.events_rxto.reset(); 649 r.events_rxto.reset();
650 r.events_error.reset();
651 r.errorsrc.reset();
593 r.tasks_stoprx.write(|w| unsafe { w.bits(1) }); 652 r.tasks_stoprx.write(|w| unsafe { w.bits(1) });
594 653
595 while r.events_endrx.read().bits() == 0 {} 654 while r.events_endrx.read().bits() == 0 {}
@@ -601,17 +660,26 @@ impl<'d, T: Instance> UarteRx<'d, T> {
601 r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); 660 r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) });
602 661
603 r.events_endrx.reset(); 662 r.events_endrx.reset();
604 r.intenset.write(|w| w.endrx().set()); 663 r.events_error.reset();
664 r.intenset.write(|w| {
665 w.endrx().set();
666 w.error().set()
667 });
605 668
606 compiler_fence(Ordering::SeqCst); 669 compiler_fence(Ordering::SeqCst);
607 670
608 trace!("startrx"); 671 trace!("startrx");
609 r.tasks_startrx.write(|w| unsafe { w.bits(1) }); 672 r.tasks_startrx.write(|w| unsafe { w.bits(1) });
610 673
611 poll_fn(|cx| { 674 let result = poll_fn(|cx| {
612 s.endrx_waker.register(cx.waker()); 675 s.endrx_waker.register(cx.waker());
676
677 if let Err(e) = self.check_and_clear_errors() {
678 r.tasks_stoprx.write(|w| unsafe { w.bits(1) });
679 return Poll::Ready(Err(e));
680 }
613 if r.events_endrx.read().bits() != 0 { 681 if r.events_endrx.read().bits() != 0 {
614 return Poll::Ready(()); 682 return Poll::Ready(Ok(()));
615 } 683 }
616 Poll::Pending 684 Poll::Pending
617 }) 685 })
@@ -621,7 +689,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
621 r.events_rxstarted.reset(); 689 r.events_rxstarted.reset();
622 drop.defuse(); 690 drop.defuse();
623 691
624 Ok(()) 692 result
625 } 693 }
626 694
627 /// Read bytes until the buffer is filled. 695 /// Read bytes until the buffer is filled.
@@ -642,19 +710,23 @@ impl<'d, T: Instance> UarteRx<'d, T> {
642 r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); 710 r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) });
643 711
644 r.events_endrx.reset(); 712 r.events_endrx.reset();
645 r.intenclr.write(|w| w.endrx().clear()); 713 r.events_error.reset();
714 r.intenclr.write(|w| {
715 w.endrx().clear();
716 w.error().clear()
717 });
646 718
647 compiler_fence(Ordering::SeqCst); 719 compiler_fence(Ordering::SeqCst);
648 720
649 trace!("startrx"); 721 trace!("startrx");
650 r.tasks_startrx.write(|w| unsafe { w.bits(1) }); 722 r.tasks_startrx.write(|w| unsafe { w.bits(1) });
651 723
652 while r.events_endrx.read().bits() == 0 {} 724 while r.events_endrx.read().bits() == 0 && r.events_error.read().bits() == 0 {}
653 725
654 compiler_fence(Ordering::SeqCst); 726 compiler_fence(Ordering::SeqCst);
655 r.events_rxstarted.reset(); 727 r.events_rxstarted.reset();
656 728
657 Ok(()) 729 self.check_and_clear_errors()
658 } 730 }
659} 731}
660 732
@@ -721,8 +793,12 @@ impl<'d, T: Instance, U: TimerInstance> UarteRxWithIdle<'d, T, U> {
721 let drop = OnDrop::new(|| { 793 let drop = OnDrop::new(|| {
722 self.timer.stop(); 794 self.timer.stop();
723 795
724 r.intenclr.write(|w| w.endrx().clear()); 796 r.intenclr.write(|w| {
797 w.endrx().clear();
798 w.error().clear()
799 });
725 r.events_rxto.reset(); 800 r.events_rxto.reset();
801 r.events_error.reset();
726 r.tasks_stoprx.write(|w| unsafe { w.bits(1) }); 802 r.tasks_stoprx.write(|w| unsafe { w.bits(1) });
727 803
728 while r.events_endrx.read().bits() == 0 {} 804 while r.events_endrx.read().bits() == 0 {}
@@ -732,17 +808,27 @@ impl<'d, T: Instance, U: TimerInstance> UarteRxWithIdle<'d, T, U> {
732 r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); 808 r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) });
733 809
734 r.events_endrx.reset(); 810 r.events_endrx.reset();
735 r.intenset.write(|w| w.endrx().set()); 811 r.events_error.reset();
812 r.intenset.write(|w| {
813 w.endrx().set();
814 w.error().set()
815 });
736 816
737 compiler_fence(Ordering::SeqCst); 817 compiler_fence(Ordering::SeqCst);
738 818
739 r.tasks_startrx.write(|w| unsafe { w.bits(1) }); 819 r.tasks_startrx.write(|w| unsafe { w.bits(1) });
740 820
741 poll_fn(|cx| { 821 let result = poll_fn(|cx| {
742 s.endrx_waker.register(cx.waker()); 822 s.endrx_waker.register(cx.waker());
823
824 if let Err(e) = self.rx.check_and_clear_errors() {
825 r.tasks_stoprx.write(|w| unsafe { w.bits(1) });
826 return Poll::Ready(Err(e));
827 }
743 if r.events_endrx.read().bits() != 0 { 828 if r.events_endrx.read().bits() != 0 {
744 return Poll::Ready(()); 829 return Poll::Ready(Ok(()));
745 } 830 }
831
746 Poll::Pending 832 Poll::Pending
747 }) 833 })
748 .await; 834 .await;
@@ -755,7 +841,7 @@ impl<'d, T: Instance, U: TimerInstance> UarteRxWithIdle<'d, T, U> {
755 841
756 drop.defuse(); 842 drop.defuse();
757 843
758 Ok(n) 844 result.map(|_| n)
759 } 845 }
760 846
761 /// Read bytes until the buffer is filled, or the line becomes idle. 847 /// Read bytes until the buffer is filled, or the line becomes idle.
@@ -780,13 +866,17 @@ impl<'d, T: Instance, U: TimerInstance> UarteRxWithIdle<'d, T, U> {
780 r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); 866 r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) });
781 867
782 r.events_endrx.reset(); 868 r.events_endrx.reset();
783 r.intenclr.write(|w| w.endrx().clear()); 869 r.events_error.reset();
870 r.intenclr.write(|w| {
871 w.endrx().clear();
872 w.error().clear()
873 });
784 874
785 compiler_fence(Ordering::SeqCst); 875 compiler_fence(Ordering::SeqCst);
786 876
787 r.tasks_startrx.write(|w| unsafe { w.bits(1) }); 877 r.tasks_startrx.write(|w| unsafe { w.bits(1) });
788 878
789 while r.events_endrx.read().bits() == 0 {} 879 while r.events_endrx.read().bits() == 0 && r.events_error.read().bits() == 0 {}
790 880
791 compiler_fence(Ordering::SeqCst); 881 compiler_fence(Ordering::SeqCst);
792 let n = r.rxd.amount.read().amount().bits() as usize; 882 let n = r.rxd.amount.read().amount().bits() as usize;
@@ -794,7 +884,7 @@ impl<'d, T: Instance, U: TimerInstance> UarteRxWithIdle<'d, T, U> {
794 self.timer.stop(); 884 self.timer.stop();
795 r.events_rxstarted.reset(); 885 r.events_rxstarted.reset();
796 886
797 Ok(n) 887 self.rx.check_and_clear_errors().map(|_| n)
798 } 888 }
799} 889}
800 890