diff options
| -rw-r--r-- | embassy-nrf/src/uarte.rs | 398 | ||||
| -rw-r--r-- | examples/nrf/src/bin/uart_idle.rs | 7 |
2 files changed, 135 insertions, 270 deletions
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index d99599112..636d6c7a3 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs | |||
| @@ -173,6 +173,61 @@ impl<'d, T: Instance> Uarte<'d, T> { | |||
| 173 | (self.tx, self.rx) | 173 | (self.tx, self.rx) |
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | /// Split the Uarte into a transmitter and receiver that will | ||
| 177 | /// return on idle, which is determined as the time it takes | ||
| 178 | /// for two bytes to be received. | ||
| 179 | pub fn split_with_idle<U: TimerInstance>( | ||
| 180 | self, | ||
| 181 | timer: impl Peripheral<P = U> + 'd, | ||
| 182 | ppi_ch1: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd, | ||
| 183 | ppi_ch2: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd, | ||
| 184 | ) -> (UarteTx<'d, T>, UarteRxWithIdle<'d, T, U>) { | ||
| 185 | let mut timer = Timer::new(timer); | ||
| 186 | |||
| 187 | into_ref!(ppi_ch1, ppi_ch2); | ||
| 188 | |||
| 189 | let r = T::regs(); | ||
| 190 | |||
| 191 | // BAUDRATE register values are `baudrate * 2^32 / 16000000` | ||
| 192 | // source: https://devzone.nordicsemi.com/f/nordic-q-a/391/uart-baudrate-register-values | ||
| 193 | // | ||
| 194 | // We want to stop RX if line is idle for 2 bytes worth of time | ||
| 195 | // That is 20 bits (each byte is 1 start bit + 8 data bits + 1 stop bit) | ||
| 196 | // This gives us the amount of 16M ticks for 20 bits. | ||
| 197 | let baudrate = r.baudrate.read().baudrate().variant().unwrap(); | ||
| 198 | let timeout = 0x8000_0000 / (baudrate as u32 / 40); | ||
| 199 | |||
| 200 | timer.set_frequency(Frequency::F16MHz); | ||
| 201 | timer.cc(0).write(timeout); | ||
| 202 | timer.cc(0).short_compare_clear(); | ||
| 203 | timer.cc(0).short_compare_stop(); | ||
| 204 | |||
| 205 | let mut ppi_ch1 = Ppi::new_one_to_two( | ||
| 206 | ppi_ch1.map_into(), | ||
| 207 | Event::from_reg(&r.events_rxdrdy), | ||
| 208 | timer.task_clear(), | ||
| 209 | timer.task_start(), | ||
| 210 | ); | ||
| 211 | ppi_ch1.enable(); | ||
| 212 | |||
| 213 | let mut ppi_ch2 = Ppi::new_one_to_one( | ||
| 214 | ppi_ch2.map_into(), | ||
| 215 | timer.cc(0).event_compare(), | ||
| 216 | Task::from_reg(&r.tasks_stoprx), | ||
| 217 | ); | ||
| 218 | ppi_ch2.enable(); | ||
| 219 | |||
| 220 | ( | ||
| 221 | self.tx, | ||
| 222 | UarteRxWithIdle { | ||
| 223 | rx: self.rx, | ||
| 224 | timer, | ||
| 225 | ppi_ch1: ppi_ch1, | ||
| 226 | _ppi_ch2: ppi_ch2, | ||
| 227 | }, | ||
| 228 | ) | ||
| 229 | } | ||
| 230 | |||
| 176 | /// Return the endtx event for use with PPI | 231 | /// Return the endtx event for use with PPI |
| 177 | pub fn event_endtx(&self) -> Event { | 232 | pub fn event_endtx(&self) -> Event { |
| 178 | let r = T::regs(); | 233 | let r = T::regs(); |
| @@ -597,236 +652,14 @@ impl<'a, T: Instance> Drop for UarteRx<'a, T> { | |||
| 597 | } | 652 | } |
| 598 | } | 653 | } |
| 599 | 654 | ||
| 600 | #[cfg(not(any(feature = "_nrf9160", feature = "nrf5340")))] | 655 | pub struct UarteRxWithIdle<'d, T: Instance, U: TimerInstance> { |
| 601 | pub(crate) fn apply_workaround_for_enable_anomaly(_r: &crate::pac::uarte0::RegisterBlock) { | 656 | rx: UarteRx<'d, T>, |
| 602 | // Do nothing | 657 | timer: Timer<'d, U>, |
| 603 | } | ||
| 604 | |||
| 605 | #[cfg(any(feature = "_nrf9160", feature = "nrf5340"))] | ||
| 606 | pub(crate) fn apply_workaround_for_enable_anomaly(r: &crate::pac::uarte0::RegisterBlock) { | ||
| 607 | use core::ops::Deref; | ||
| 608 | |||
| 609 | // Apply workaround for anomalies: | ||
| 610 | // - nRF9160 - anomaly 23 | ||
| 611 | // - nRF5340 - anomaly 44 | ||
| 612 | let rxenable_reg: *const u32 = ((r.deref() as *const _ as usize) + 0x564) as *const u32; | ||
| 613 | let txenable_reg: *const u32 = ((r.deref() as *const _ as usize) + 0x568) as *const u32; | ||
| 614 | |||
| 615 | // NB Safety: This is taken from Nordic's driver - | ||
| 616 | // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197 | ||
| 617 | if unsafe { core::ptr::read_volatile(txenable_reg) } == 1 { | ||
| 618 | r.tasks_stoptx.write(|w| unsafe { w.bits(1) }); | ||
| 619 | } | ||
| 620 | |||
| 621 | // NB Safety: This is taken from Nordic's driver - | ||
| 622 | // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197 | ||
| 623 | if unsafe { core::ptr::read_volatile(rxenable_reg) } == 1 { | ||
| 624 | r.enable.write(|w| w.enable().enabled()); | ||
| 625 | r.tasks_stoprx.write(|w| unsafe { w.bits(1) }); | ||
| 626 | |||
| 627 | let mut workaround_succeded = false; | ||
| 628 | // The UARTE is able to receive up to four bytes after the STOPRX task has been triggered. | ||
| 629 | // On lowest supported baud rate (1200 baud), with parity bit and two stop bits configured | ||
| 630 | // (resulting in 12 bits per data byte sent), this may take up to 40 ms. | ||
| 631 | for _ in 0..40000 { | ||
| 632 | // NB Safety: This is taken from Nordic's driver - | ||
| 633 | // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197 | ||
| 634 | if unsafe { core::ptr::read_volatile(rxenable_reg) } == 0 { | ||
| 635 | workaround_succeded = true; | ||
| 636 | break; | ||
| 637 | } else { | ||
| 638 | // Need to sleep for 1us here | ||
| 639 | } | ||
| 640 | } | ||
| 641 | |||
| 642 | if !workaround_succeded { | ||
| 643 | panic!("Failed to apply workaround for UART"); | ||
| 644 | } | ||
| 645 | |||
| 646 | let errors = r.errorsrc.read().bits(); | ||
| 647 | // NB Safety: safe to write back the bits we just read to clear them | ||
| 648 | r.errorsrc.write(|w| unsafe { w.bits(errors) }); | ||
| 649 | r.enable.write(|w| w.enable().disabled()); | ||
| 650 | } | ||
| 651 | } | ||
| 652 | |||
| 653 | pub(crate) fn drop_tx_rx(r: &pac::uarte0::RegisterBlock, s: &sealed::State) { | ||
| 654 | if s.tx_rx_refcount.fetch_sub(1, Ordering::Relaxed) == 1 { | ||
| 655 | // Finally we can disable, and we do so for the peripheral | ||
| 656 | // i.e. not just rx concerns. | ||
| 657 | r.enable.write(|w| w.enable().disabled()); | ||
| 658 | |||
| 659 | gpio::deconfigure_pin(r.psel.rxd.read().bits()); | ||
| 660 | gpio::deconfigure_pin(r.psel.txd.read().bits()); | ||
| 661 | gpio::deconfigure_pin(r.psel.rts.read().bits()); | ||
| 662 | gpio::deconfigure_pin(r.psel.cts.read().bits()); | ||
| 663 | |||
| 664 | trace!("uarte tx and rx drop: done"); | ||
| 665 | } | ||
| 666 | } | ||
| 667 | |||
| 668 | /// Interface to an UARTE peripheral that uses an additional timer and two PPI channels, | ||
| 669 | /// allowing it to implement the ReadUntilIdle trait. | ||
| 670 | pub struct UarteWithIdle<'d, U: Instance, T: TimerInstance> { | ||
| 671 | tx: UarteTx<'d, U>, | ||
| 672 | rx: UarteRxWithIdle<'d, U, T>, | ||
| 673 | } | ||
| 674 | |||
| 675 | impl<'d, U: Instance, T: TimerInstance> UarteWithIdle<'d, U, T> { | ||
| 676 | /// Create a new UARTE without hardware flow control | ||
| 677 | pub fn new( | ||
| 678 | uarte: impl Peripheral<P = U> + 'd, | ||
| 679 | timer: impl Peripheral<P = T> + 'd, | ||
| 680 | ppi_ch1: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd, | ||
| 681 | ppi_ch2: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd, | ||
| 682 | irq: impl Peripheral<P = U::Interrupt> + 'd, | ||
| 683 | rxd: impl Peripheral<P = impl GpioPin> + 'd, | ||
| 684 | txd: impl Peripheral<P = impl GpioPin> + 'd, | ||
| 685 | config: Config, | ||
| 686 | ) -> Self { | ||
| 687 | into_ref!(rxd, txd); | ||
| 688 | Self::new_inner( | ||
| 689 | uarte, | ||
| 690 | timer, | ||
| 691 | ppi_ch1, | ||
| 692 | ppi_ch2, | ||
| 693 | irq, | ||
| 694 | rxd.map_into(), | ||
| 695 | txd.map_into(), | ||
| 696 | None, | ||
| 697 | None, | ||
| 698 | config, | ||
| 699 | ) | ||
| 700 | } | ||
| 701 | |||
| 702 | /// Create a new UARTE with hardware flow control (RTS/CTS) | ||
| 703 | pub fn new_with_rtscts( | ||
| 704 | uarte: impl Peripheral<P = U> + 'd, | ||
| 705 | timer: impl Peripheral<P = T> + 'd, | ||
| 706 | ppi_ch1: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd, | ||
| 707 | ppi_ch2: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd, | ||
| 708 | irq: impl Peripheral<P = U::Interrupt> + 'd, | ||
| 709 | rxd: impl Peripheral<P = impl GpioPin> + 'd, | ||
| 710 | txd: impl Peripheral<P = impl GpioPin> + 'd, | ||
| 711 | cts: impl Peripheral<P = impl GpioPin> + 'd, | ||
| 712 | rts: impl Peripheral<P = impl GpioPin> + 'd, | ||
| 713 | config: Config, | ||
| 714 | ) -> Self { | ||
| 715 | into_ref!(rxd, txd, cts, rts); | ||
| 716 | Self::new_inner( | ||
| 717 | uarte, | ||
| 718 | timer, | ||
| 719 | ppi_ch1, | ||
| 720 | ppi_ch2, | ||
| 721 | irq, | ||
| 722 | rxd.map_into(), | ||
| 723 | txd.map_into(), | ||
| 724 | Some(cts.map_into()), | ||
| 725 | Some(rts.map_into()), | ||
| 726 | config, | ||
| 727 | ) | ||
| 728 | } | ||
| 729 | |||
| 730 | fn new_inner( | ||
| 731 | uarte: impl Peripheral<P = U> + 'd, | ||
| 732 | timer: impl Peripheral<P = T> + 'd, | ||
| 733 | ppi_ch1: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd, | ||
| 734 | ppi_ch2: impl Peripheral<P = impl ConfigurableChannel + 'd> + 'd, | ||
| 735 | irq: impl Peripheral<P = U::Interrupt> + 'd, | ||
| 736 | rxd: PeripheralRef<'d, AnyPin>, | ||
| 737 | txd: PeripheralRef<'d, AnyPin>, | ||
| 738 | cts: Option<PeripheralRef<'d, AnyPin>>, | ||
| 739 | rts: Option<PeripheralRef<'d, AnyPin>>, | ||
| 740 | config: Config, | ||
| 741 | ) -> Self { | ||
| 742 | let baudrate = config.baudrate; | ||
| 743 | let (tx, rx) = Uarte::new_inner(uarte, irq, rxd, txd, cts, rts, config).split(); | ||
| 744 | |||
| 745 | let mut timer = Timer::new(timer); | ||
| 746 | |||
| 747 | into_ref!(ppi_ch1, ppi_ch2); | ||
| 748 | |||
| 749 | let r = U::regs(); | ||
| 750 | |||
| 751 | // BAUDRATE register values are `baudrate * 2^32 / 16000000` | ||
| 752 | // source: https://devzone.nordicsemi.com/f/nordic-q-a/391/uart-baudrate-register-values | ||
| 753 | // | ||
| 754 | // We want to stop RX if line is idle for 2 bytes worth of time | ||
| 755 | // That is 20 bits (each byte is 1 start bit + 8 data bits + 1 stop bit) | ||
| 756 | // This gives us the amount of 16M ticks for 20 bits. | ||
| 757 | let timeout = 0x8000_0000 / (baudrate as u32 / 40); | ||
| 758 | |||
| 759 | timer.set_frequency(Frequency::F16MHz); | ||
| 760 | timer.cc(0).write(timeout); | ||
| 761 | timer.cc(0).short_compare_clear(); | ||
| 762 | timer.cc(0).short_compare_stop(); | ||
| 763 | |||
| 764 | let mut ppi_ch1 = Ppi::new_one_to_two( | ||
| 765 | ppi_ch1.map_into(), | ||
| 766 | Event::from_reg(&r.events_rxdrdy), | ||
| 767 | timer.task_clear(), | ||
| 768 | timer.task_start(), | ||
| 769 | ); | ||
| 770 | ppi_ch1.enable(); | ||
| 771 | |||
| 772 | let mut ppi_ch2 = Ppi::new_one_to_one( | ||
| 773 | ppi_ch2.map_into(), | ||
| 774 | timer.cc(0).event_compare(), | ||
| 775 | Task::from_reg(&r.tasks_stoprx), | ||
| 776 | ); | ||
| 777 | ppi_ch2.enable(); | ||
| 778 | |||
| 779 | Self { | ||
| 780 | tx, | ||
| 781 | rx: UarteRxWithIdle { | ||
| 782 | rx, | ||
| 783 | timer, | ||
| 784 | ppi_ch1: ppi_ch1, | ||
| 785 | _ppi_ch2: ppi_ch2, | ||
| 786 | }, | ||
| 787 | } | ||
| 788 | } | ||
| 789 | |||
| 790 | /// Split the Uarte into a transmitter and receiver, which is | ||
| 791 | /// particuarly useful when having two tasks correlating to | ||
| 792 | /// transmitting and receiving. | ||
| 793 | pub fn split(self) -> (UarteTx<'d, U>, UarteRxWithIdle<'d, U, T>) { | ||
| 794 | (self.tx, self.rx) | ||
| 795 | } | ||
| 796 | |||
| 797 | pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { | ||
| 798 | self.rx.read(buffer).await | ||
| 799 | } | ||
| 800 | |||
| 801 | pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { | ||
| 802 | self.tx.write(buffer).await | ||
| 803 | } | ||
| 804 | |||
| 805 | pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { | ||
| 806 | self.rx.blocking_read(buffer) | ||
| 807 | } | ||
| 808 | |||
| 809 | pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> { | ||
| 810 | self.tx.blocking_write(buffer) | ||
| 811 | } | ||
| 812 | |||
| 813 | pub async fn read_until_idle(&mut self, buffer: &mut [u8]) -> Result<usize, Error> { | ||
| 814 | self.rx.read_until_idle(buffer).await | ||
| 815 | } | ||
| 816 | |||
| 817 | pub fn blocking_read_until_idle(&mut self, buffer: &mut [u8]) -> Result<usize, Error> { | ||
| 818 | self.rx.blocking_read_until_idle(buffer) | ||
| 819 | } | ||
| 820 | } | ||
| 821 | |||
| 822 | pub struct UarteRxWithIdle<'d, U: Instance, T: TimerInstance> { | ||
| 823 | rx: UarteRx<'d, U>, | ||
| 824 | timer: Timer<'d, T>, | ||
| 825 | ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 2>, | 658 | ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 2>, |
| 826 | _ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 1>, | 659 | _ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 1>, |
| 827 | } | 660 | } |
| 828 | 661 | ||
| 829 | impl<'d, U: Instance, T: TimerInstance> UarteRxWithIdle<'d, U, T> { | 662 | impl<'d, T: Instance, U: TimerInstance> UarteRxWithIdle<'d, T, U> { |
| 830 | pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { | 663 | pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { |
| 831 | self.ppi_ch1.disable(); | 664 | self.ppi_ch1.disable(); |
| 832 | self.rx.read(buffer).await | 665 | self.rx.read(buffer).await |
| @@ -848,8 +681,8 @@ impl<'d, U: Instance, T: TimerInstance> UarteRxWithIdle<'d, U, T> { | |||
| 848 | let ptr = buffer.as_ptr(); | 681 | let ptr = buffer.as_ptr(); |
| 849 | let len = buffer.len(); | 682 | let len = buffer.len(); |
| 850 | 683 | ||
| 851 | let r = U::regs(); | 684 | let r = T::regs(); |
| 852 | let s = U::state(); | 685 | let s = T::state(); |
| 853 | 686 | ||
| 854 | self.ppi_ch1.enable(); | 687 | self.ppi_ch1.enable(); |
| 855 | 688 | ||
| @@ -904,7 +737,7 @@ impl<'d, U: Instance, T: TimerInstance> UarteRxWithIdle<'d, U, T> { | |||
| 904 | let ptr = buffer.as_ptr(); | 737 | let ptr = buffer.as_ptr(); |
| 905 | let len = buffer.len(); | 738 | let len = buffer.len(); |
| 906 | 739 | ||
| 907 | let r = U::regs(); | 740 | let r = T::regs(); |
| 908 | 741 | ||
| 909 | self.ppi_ch1.enable(); | 742 | self.ppi_ch1.enable(); |
| 910 | 743 | ||
| @@ -929,6 +762,75 @@ impl<'d, U: Instance, T: TimerInstance> UarteRxWithIdle<'d, U, T> { | |||
| 929 | Ok(n) | 762 | Ok(n) |
| 930 | } | 763 | } |
| 931 | } | 764 | } |
| 765 | |||
| 766 | #[cfg(not(any(feature = "_nrf9160", feature = "nrf5340")))] | ||
| 767 | pub(crate) fn apply_workaround_for_enable_anomaly(_r: &crate::pac::uarte0::RegisterBlock) { | ||
| 768 | // Do nothing | ||
| 769 | } | ||
| 770 | |||
| 771 | #[cfg(any(feature = "_nrf9160", feature = "nrf5340"))] | ||
| 772 | pub(crate) fn apply_workaround_for_enable_anomaly(r: &crate::pac::uarte0::RegisterBlock) { | ||
| 773 | use core::ops::Deref; | ||
| 774 | |||
| 775 | // Apply workaround for anomalies: | ||
| 776 | // - nRF9160 - anomaly 23 | ||
| 777 | // - nRF5340 - anomaly 44 | ||
| 778 | let rxenable_reg: *const u32 = ((r.deref() as *const _ as usize) + 0x564) as *const u32; | ||
| 779 | let txenable_reg: *const u32 = ((r.deref() as *const _ as usize) + 0x568) as *const u32; | ||
| 780 | |||
| 781 | // NB Safety: This is taken from Nordic's driver - | ||
| 782 | // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197 | ||
| 783 | if unsafe { core::ptr::read_volatile(txenable_reg) } == 1 { | ||
| 784 | r.tasks_stoptx.write(|w| unsafe { w.bits(1) }); | ||
| 785 | } | ||
| 786 | |||
| 787 | // NB Safety: This is taken from Nordic's driver - | ||
| 788 | // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197 | ||
| 789 | if unsafe { core::ptr::read_volatile(rxenable_reg) } == 1 { | ||
| 790 | r.enable.write(|w| w.enable().enabled()); | ||
| 791 | r.tasks_stoprx.write(|w| unsafe { w.bits(1) }); | ||
| 792 | |||
| 793 | let mut workaround_succeded = false; | ||
| 794 | // The UARTE is able to receive up to four bytes after the STOPRX task has been triggered. | ||
| 795 | // On lowest supported baud rate (1200 baud), with parity bit and two stop bits configured | ||
| 796 | // (resulting in 12 bits per data byte sent), this may take up to 40 ms. | ||
| 797 | for _ in 0..40000 { | ||
| 798 | // NB Safety: This is taken from Nordic's driver - | ||
| 799 | // https://github.com/NordicSemiconductor/nrfx/blob/master/drivers/src/nrfx_uarte.c#L197 | ||
| 800 | if unsafe { core::ptr::read_volatile(rxenable_reg) } == 0 { | ||
| 801 | workaround_succeded = true; | ||
| 802 | break; | ||
| 803 | } else { | ||
| 804 | // Need to sleep for 1us here | ||
| 805 | } | ||
| 806 | } | ||
| 807 | |||
| 808 | if !workaround_succeded { | ||
| 809 | panic!("Failed to apply workaround for UART"); | ||
| 810 | } | ||
| 811 | |||
| 812 | let errors = r.errorsrc.read().bits(); | ||
| 813 | // NB Safety: safe to write back the bits we just read to clear them | ||
| 814 | r.errorsrc.write(|w| unsafe { w.bits(errors) }); | ||
| 815 | r.enable.write(|w| w.enable().disabled()); | ||
| 816 | } | ||
| 817 | } | ||
| 818 | |||
| 819 | pub(crate) fn drop_tx_rx(r: &pac::uarte0::RegisterBlock, s: &sealed::State) { | ||
| 820 | if s.tx_rx_refcount.fetch_sub(1, Ordering::Relaxed) == 1 { | ||
| 821 | // Finally we can disable, and we do so for the peripheral | ||
| 822 | // i.e. not just rx concerns. | ||
| 823 | r.enable.write(|w| w.enable().disabled()); | ||
| 824 | |||
| 825 | gpio::deconfigure_pin(r.psel.rxd.read().bits()); | ||
| 826 | gpio::deconfigure_pin(r.psel.txd.read().bits()); | ||
| 827 | gpio::deconfigure_pin(r.psel.rts.read().bits()); | ||
| 828 | gpio::deconfigure_pin(r.psel.cts.read().bits()); | ||
| 829 | |||
| 830 | trace!("uarte tx and rx drop: done"); | ||
| 831 | } | ||
| 832 | } | ||
| 833 | |||
| 932 | pub(crate) mod sealed { | 834 | pub(crate) mod sealed { |
| 933 | use core::sync::atomic::AtomicU8; | 835 | use core::sync::atomic::AtomicU8; |
| 934 | 836 | ||
| @@ -1006,18 +908,6 @@ mod eh02 { | |||
| 1006 | Ok(()) | 908 | Ok(()) |
| 1007 | } | 909 | } |
| 1008 | } | 910 | } |
| 1009 | |||
| 1010 | impl<'d, U: Instance, T: TimerInstance> embedded_hal_02::blocking::serial::Write<u8> for UarteWithIdle<'d, U, T> { | ||
| 1011 | type Error = Error; | ||
| 1012 | |||
| 1013 | fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { | ||
| 1014 | self.blocking_write(buffer) | ||
| 1015 | } | ||
| 1016 | |||
| 1017 | fn bflush(&mut self) -> Result<(), Self::Error> { | ||
| 1018 | Ok(()) | ||
| 1019 | } | ||
| 1020 | } | ||
| 1021 | } | 911 | } |
| 1022 | 912 | ||
| 1023 | #[cfg(feature = "unstable-traits")] | 913 | #[cfg(feature = "unstable-traits")] |
| @@ -1067,10 +957,6 @@ mod eh1 { | |||
| 1067 | impl<'d, T: Instance> embedded_hal_1::serial::ErrorType for UarteRx<'d, T> { | 957 | impl<'d, T: Instance> embedded_hal_1::serial::ErrorType for UarteRx<'d, T> { |
| 1068 | type Error = Error; | 958 | type Error = Error; |
| 1069 | } | 959 | } |
| 1070 | |||
| 1071 | impl<'d, U: Instance, T: TimerInstance> embedded_hal_1::serial::ErrorType for UarteWithIdle<'d, U, T> { | ||
| 1072 | type Error = Error; | ||
| 1073 | } | ||
| 1074 | } | 960 | } |
| 1075 | 961 | ||
| 1076 | #[cfg(all( | 962 | #[cfg(all( |
| @@ -1126,26 +1012,4 @@ mod eha { | |||
| 1126 | self.read(buffer) | 1012 | self.read(buffer) |
| 1127 | } | 1013 | } |
| 1128 | } | 1014 | } |
| 1129 | |||
| 1130 | impl<'d, U: Instance, T: TimerInstance> embedded_hal_async::serial::Read for UarteWithIdle<'d, U, T> { | ||
| 1131 | type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a; | ||
| 1132 | |||
| 1133 | fn read<'a>(&'a mut self, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { | ||
| 1134 | self.read(buffer) | ||
| 1135 | } | ||
| 1136 | } | ||
| 1137 | |||
| 1138 | impl<'d, U: Instance, T: TimerInstance> embedded_hal_async::serial::Write for UarteWithIdle<'d, U, T> { | ||
| 1139 | type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a; | ||
| 1140 | |||
| 1141 | fn write<'a>(&'a mut self, buffer: &'a [u8]) -> Self::WriteFuture<'a> { | ||
| 1142 | self.write(buffer) | ||
| 1143 | } | ||
| 1144 | |||
| 1145 | type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a; | ||
| 1146 | |||
| 1147 | fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { | ||
| 1148 | async move { Ok(()) } | ||
| 1149 | } | ||
| 1150 | } | ||
| 1151 | } | 1015 | } |
diff --git a/examples/nrf/src/bin/uart_idle.rs b/examples/nrf/src/bin/uart_idle.rs index 09ec624c0..6af4f7097 100644 --- a/examples/nrf/src/bin/uart_idle.rs +++ b/examples/nrf/src/bin/uart_idle.rs | |||
| @@ -15,7 +15,8 @@ async fn main(_spawner: Spawner) { | |||
| 15 | config.baudrate = uarte::Baudrate::BAUD115200; | 15 | config.baudrate = uarte::Baudrate::BAUD115200; |
| 16 | 16 | ||
| 17 | let irq = interrupt::take!(UARTE0_UART0); | 17 | let irq = interrupt::take!(UARTE0_UART0); |
| 18 | let mut uart = uarte::UarteWithIdle::new(p.UARTE0, p.TIMER0, p.PPI_CH0, p.PPI_CH1, irq, p.P0_08, p.P0_06, config); | 18 | let uart = uarte::Uarte::new(p.UARTE0, irq, p.P0_08, p.P0_06, config); |
| 19 | let (mut tx, mut rx) = uart.split_with_idle(p.TIMER0, p.PPI_CH0, p.PPI_CH1); | ||
| 19 | 20 | ||
| 20 | info!("uarte initialized!"); | 21 | info!("uarte initialized!"); |
| 21 | 22 | ||
| @@ -23,12 +24,12 @@ async fn main(_spawner: Spawner) { | |||
| 23 | let mut buf = [0; 8]; | 24 | let mut buf = [0; 8]; |
| 24 | buf.copy_from_slice(b"Hello!\r\n"); | 25 | buf.copy_from_slice(b"Hello!\r\n"); |
| 25 | 26 | ||
| 26 | unwrap!(uart.write(&buf).await); | 27 | unwrap!(tx.write(&buf).await); |
| 27 | info!("wrote hello in uart!"); | 28 | info!("wrote hello in uart!"); |
| 28 | 29 | ||
| 29 | loop { | 30 | loop { |
| 30 | info!("reading..."); | 31 | info!("reading..."); |
| 31 | let n = unwrap!(uart.read_until_idle(&mut buf).await); | 32 | let n = unwrap!(rx.read_until_idle(&mut buf).await); |
| 32 | info!("got {} bytes", n); | 33 | info!("got {} bytes", n); |
| 33 | } | 34 | } |
| 34 | } | 35 | } |
