diff options
| -rw-r--r-- | embassy-nrf/Cargo.toml | 1 | ||||
| -rw-r--r-- | embassy-nrf/src/uarte.rs | 95 |
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" } | |||
| 133 | embedded-io-async = { version = "0.6.1" } | 133 | embedded-io-async = { version = "0.6.1" } |
| 134 | 134 | ||
| 135 | defmt = { version = "0.3", optional = true } | 135 | defmt = { version = "0.3", optional = true } |
| 136 | bitflags = "2.4.2" | ||
| 136 | log = { version = "0.4.14", optional = true } | 137 | log = { version = "0.4.14", optional = true } |
| 137 | cortex-m-rt = ">=0.6.15,<0.8" | 138 | cortex-m-rt = ">=0.6.15,<0.8" |
| 138 | cortex-m = "0.7.6" | 139 | cortex-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 | ||
| 55 | bitflags::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 | |||
| 69 | impl 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 | ||
