diff options
Diffstat (limited to 'embassy-nrf')
| -rw-r--r-- | embassy-nrf/src/uarte.rs | 98 |
1 files changed, 25 insertions, 73 deletions
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index fc57f406b..9a6e49907 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs | |||
| @@ -1,8 +1,4 @@ | |||
| 1 | //! Async low power UARTE. | 1 | //! Async UART |
| 2 | //! | ||
| 3 | //! The peripheral is automatically enabled and disabled as required to save power. | ||
| 4 | //! Lowest power consumption can only be guaranteed if the send receive futures | ||
| 5 | //! are dropped correctly (e.g. not using `mem::forget()`). | ||
| 6 | 2 | ||
| 7 | use core::future::Future; | 3 | use core::future::Future; |
| 8 | use core::marker::PhantomData; | 4 | use core::marker::PhantomData; |
| @@ -10,12 +6,13 @@ use core::pin::Pin; | |||
| 10 | use core::sync::atomic::{compiler_fence, Ordering}; | 6 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 11 | use core::task::Poll; | 7 | use core::task::Poll; |
| 12 | use embassy::traits::uart::{Error, Read, Write}; | 8 | use embassy::traits::uart::{Error, Read, Write}; |
| 13 | use embassy::util::{wake_on_interrupt, OnDrop, PeripheralBorrow, Signal}; | 9 | use embassy::util::{wake_on_interrupt, OnDrop, PeripheralBorrow}; |
| 14 | use embassy_extras::unborrow; | 10 | use embassy_extras::unborrow; |
| 15 | use futures::future::poll_fn; | 11 | use futures::future::poll_fn; |
| 16 | 12 | ||
| 17 | use crate::fmt::{assert, *}; | 13 | use crate::fmt::{assert, *}; |
| 18 | use crate::gpio::Pin as GpioPin; | 14 | use crate::gpio::sealed::Pin as _; |
| 15 | use crate::gpio::{OptionalPin as GpioOptionalPin, Pin as GpioPin}; | ||
| 19 | use crate::hal::pac; | 16 | use crate::hal::pac; |
| 20 | use crate::hal::target_constants::EASY_DMA_SIZE; | 17 | use crate::hal::target_constants::EASY_DMA_SIZE; |
| 21 | use crate::interrupt; | 18 | use crate::interrupt; |
| @@ -62,8 +59,8 @@ impl<'d, T: Instance> Uarte<'d, T> { | |||
| 62 | irq: impl PeripheralBorrow<Target = T::Interrupt> + 'd, | 59 | irq: impl PeripheralBorrow<Target = T::Interrupt> + 'd, |
| 63 | rxd: impl PeripheralBorrow<Target = impl GpioPin> + 'd, | 60 | rxd: impl PeripheralBorrow<Target = impl GpioPin> + 'd, |
| 64 | txd: impl PeripheralBorrow<Target = impl GpioPin> + 'd, | 61 | txd: impl PeripheralBorrow<Target = impl GpioPin> + 'd, |
| 65 | cts: impl PeripheralBorrow<Target = impl GpioPin> + 'd, | 62 | cts: impl PeripheralBorrow<Target = impl GpioOptionalPin> + 'd, |
| 66 | rts: impl PeripheralBorrow<Target = impl GpioPin> + 'd, | 63 | rts: impl PeripheralBorrow<Target = impl GpioOptionalPin> + 'd, |
| 67 | config: Config, | 64 | config: Config, |
| 68 | ) -> Self { | 65 | ) -> Self { |
| 69 | unborrow!(uarte, irq, rxd, txd, cts, rts); | 66 | unborrow!(uarte, irq, rxd, txd, cts, rts); |
| @@ -72,19 +69,23 @@ impl<'d, T: Instance> Uarte<'d, T> { | |||
| 72 | 69 | ||
| 73 | assert!(r.enable.read().enable().is_disabled()); | 70 | assert!(r.enable.read().enable().is_disabled()); |
| 74 | 71 | ||
| 75 | // TODO OptionalPin for RTS/CTS. | 72 | rxd.conf().write(|w| w.input().connect().drive().h0h1()); |
| 73 | r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) }); | ||
| 76 | 74 | ||
| 77 | txd.set_high(); | 75 | txd.set_high(); |
| 78 | rts.set_high(); | ||
| 79 | rxd.conf().write(|w| w.input().connect().drive().h0h1()); | ||
| 80 | txd.conf().write(|w| w.dir().output().drive().h0h1()); | 76 | txd.conf().write(|w| w.dir().output().drive().h0h1()); |
| 81 | //cts.conf().write(|w| w.input().connect().drive().h0h1()); | ||
| 82 | //rts.conf().write(|w| w.dir().output().drive().h0h1()); | ||
| 83 | |||
| 84 | r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) }); | ||
| 85 | r.psel.txd.write(|w| unsafe { w.bits(txd.psel_bits()) }); | 77 | r.psel.txd.write(|w| unsafe { w.bits(txd.psel_bits()) }); |
| 86 | //r.psel.cts.write(|w| unsafe { w.bits(cts.psel_bits()) }); | 78 | |
| 87 | //r.psel.rts.write(|w| unsafe { w.bits(rts.psel_bits()) }); | 79 | if let Some(pin) = rts.pin_mut() { |
| 80 | pin.set_high(); | ||
| 81 | pin.conf().write(|w| w.dir().output().drive().h0h1()); | ||
| 82 | } | ||
| 83 | r.psel.cts.write(|w| unsafe { w.bits(cts.psel_bits()) }); | ||
| 84 | |||
| 85 | if let Some(pin) = cts.pin_mut() { | ||
| 86 | pin.conf().write(|w| w.input().connect().drive().h0h1()); | ||
| 87 | } | ||
| 88 | r.psel.rts.write(|w| unsafe { w.bits(rts.psel_bits()) }); | ||
| 88 | 89 | ||
| 89 | r.baudrate.write(|w| w.baudrate().variant(config.baudrate)); | 90 | r.baudrate.write(|w| w.baudrate().variant(config.baudrate)); |
| 90 | r.config.write(|w| w.parity().variant(config.parity)); | 91 | r.config.write(|w| w.parity().variant(config.parity)); |
| @@ -98,64 +99,15 @@ impl<'d, T: Instance> Uarte<'d, T> { | |||
| 98 | phantom: PhantomData, | 99 | phantom: PhantomData, |
| 99 | } | 100 | } |
| 100 | } | 101 | } |
| 102 | } | ||
| 101 | 103 | ||
| 102 | /* | 104 | impl<'d, T: Instance> Drop for Uarte<'d, T> { |
| 103 | unsafe fn on_irq(_ctx: *mut ()) { | 105 | fn drop(&mut self) { |
| 104 | let uarte = &*pac::UARTE0::ptr(); | 106 | let r = self.peri.regs(); |
| 105 | 107 | r.enable.write(|w| w.enable().disabled()); | |
| 106 | let mut try_disable = false; | ||
| 107 | |||
| 108 | if uarte.events_endtx.read().bits() != 0 { | ||
| 109 | uarte.events_endtx.reset(); | ||
| 110 | trace!("endtx"); | ||
| 111 | compiler_fence(Ordering::SeqCst); | ||
| 112 | |||
| 113 | if uarte.events_txstarted.read().bits() != 0 { | ||
| 114 | // The ENDTX was signal triggered because DMA has finished. | ||
| 115 | uarte.events_txstarted.reset(); | ||
| 116 | try_disable = true; | ||
| 117 | } | ||
| 118 | |||
| 119 | T::state().tx_done.signal(()); | ||
| 120 | } | ||
| 121 | |||
| 122 | if uarte.events_txstopped.read().bits() != 0 { | ||
| 123 | uarte.events_txstopped.reset(); | ||
| 124 | trace!("txstopped"); | ||
| 125 | try_disable = true; | ||
| 126 | } | ||
| 127 | |||
| 128 | if uarte.events_endrx.read().bits() != 0 { | ||
| 129 | uarte.events_endrx.reset(); | ||
| 130 | trace!("endrx"); | ||
| 131 | let len = uarte.rxd.amount.read().bits(); | ||
| 132 | compiler_fence(Ordering::SeqCst); | ||
| 133 | |||
| 134 | if uarte.events_rxstarted.read().bits() != 0 { | ||
| 135 | // The ENDRX was signal triggered because DMA buffer is full. | ||
| 136 | uarte.events_rxstarted.reset(); | ||
| 137 | try_disable = true; | ||
| 138 | } | ||
| 139 | |||
| 140 | T::state().rx_done.signal(len); | ||
| 141 | } | ||
| 142 | |||
| 143 | if uarte.events_rxto.read().bits() != 0 { | ||
| 144 | uarte.events_rxto.reset(); | ||
| 145 | trace!("rxto"); | ||
| 146 | try_disable = true; | ||
| 147 | } | ||
| 148 | 108 | ||
| 149 | // Disable the peripheral if not active. | 109 | // todo disable pins |
| 150 | if try_disable | ||
| 151 | && uarte.events_txstarted.read().bits() == 0 | ||
| 152 | && uarte.events_rxstarted.read().bits() == 0 | ||
| 153 | { | ||
| 154 | trace!("disable"); | ||
| 155 | uarte.enable.write(|w| w.enable().disabled()); | ||
| 156 | } | ||
| 157 | } | 110 | } |
| 158 | */ | ||
| 159 | } | 111 | } |
| 160 | 112 | ||
| 161 | impl<'d, T: Instance> Read for Uarte<'d, T> { | 113 | impl<'d, T: Instance> Read for Uarte<'d, T> { |
