From 3d708a459c9c5f18ddd5c63a06f272371b6225c8 Mon Sep 17 00:00:00 2001 From: Zoey Riordan Date: Wed, 21 Sep 2022 10:47:49 +0200 Subject: [PATCH 1/5] Implement proper `Drop` for `BufferedUarte` --- embassy-nrf/src/buffered_uarte.rs | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index c3cba2470..84ef86c96 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs @@ -27,7 +27,7 @@ use futures::future::poll_fn; // Re-export SVD variants to allow user to directly set values pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; -use crate::gpio::Pin as GpioPin; +use crate::gpio::{self, Pin as GpioPin}; use crate::interrupt::InterruptExt; use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; use crate::timer::{Frequency, Instance as TimerInstance, Timer}; @@ -427,23 +427,26 @@ impl<'u, 'd: 'u, U: UarteInstance, T: TimerInstance> embedded_io::asynch::Write impl<'a, U: UarteInstance, T: TimerInstance> Drop for StateInner<'a, U, T> { fn drop(&mut self) { + debug!("oh no, dropping uarte"); let r = U::regs(); // TODO this probably deadlocks. do like Uarte instead. + r.inten.reset(); + r.events_rxto.reset(); + r.tasks_stoprx.write(|w| w.tasks_stoprx().set_bit()); - self.timer.stop(); - if let RxState::Receiving = self.rx_state { - r.tasks_stoprx.write(|w| unsafe { w.bits(1) }); - } - if let TxState::Transmitting(_) = self.tx_state { - r.tasks_stoptx.write(|w| unsafe { w.bits(1) }); - } - if let RxState::Receiving = self.rx_state { - low_power_wait_until(|| r.events_endrx.read().bits() == 1); - } - if let TxState::Transmitting(_) = self.tx_state { - low_power_wait_until(|| r.events_endtx.read().bits() == 1); - } + r.events_txstopped.reset(); + r.tasks_stoptx.write(|w| w.tasks_stoptx().set_bit()); + while !r.events_txstopped.read().events_txstopped().bit_is_set() {} + + while !r.events_rxto.read().events_rxto().bit_is_set() {} + + r.enable.write(|w| w.enable().disabled()); + + gpio::deconfigure_pin(r.psel.rxd.read().bits()); + gpio::deconfigure_pin(r.psel.txd.read().bits()); + gpio::deconfigure_pin(r.psel.rts.read().bits()); + gpio::deconfigure_pin(r.psel.cts.read().bits()); } } From 0f55f5a73d356dc991dbc3c4bc102e7d652c5fc5 Mon Sep 17 00:00:00 2001 From: Zoey Riordan Date: Wed, 21 Sep 2022 11:06:06 +0200 Subject: [PATCH 2/5] Remove left-in comments and logs --- embassy-nrf/src/buffered_uarte.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 84ef86c96..3ee3e9477 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs @@ -427,10 +427,8 @@ impl<'u, 'd: 'u, U: UarteInstance, T: TimerInstance> embedded_io::asynch::Write impl<'a, U: UarteInstance, T: TimerInstance> Drop for StateInner<'a, U, T> { fn drop(&mut self) { - debug!("oh no, dropping uarte"); let r = U::regs(); - // TODO this probably deadlocks. do like Uarte instead. r.inten.reset(); r.events_rxto.reset(); r.tasks_stoprx.write(|w| w.tasks_stoprx().set_bit()); From 15b4f9db9000cfb402357c5ac2c84876a3ad27c3 Mon Sep 17 00:00:00 2001 From: Zoey Riordan Date: Wed, 21 Sep 2022 11:19:47 +0200 Subject: [PATCH 3/5] Remove unused function --- embassy-nrf/src/buffered_uarte.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 3ee3e9477..e212e9897 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs @@ -550,13 +550,3 @@ impl<'a, U: UarteInstance, T: TimerInstance> PeripheralState for StateInner<'a, trace!("irq: end"); } } - -/// Low power blocking wait loop using WFE/SEV. -fn low_power_wait_until(mut condition: impl FnMut() -> bool) { - while !condition() { - // WFE might "eat" an event that would have otherwise woken the executor. - cortex_m::asm::wfe(); - } - // Retrigger an event to be transparent to the executor. - cortex_m::asm::sev(); -} From 5f7e0eb2aea6f7f6e23d9a5b7400b29377e57d8e Mon Sep 17 00:00:00 2001 From: Zoey Riordan Date: Wed, 21 Sep 2022 14:06:56 +0200 Subject: [PATCH 4/5] Fix builds on other nrf pacs --- embassy-nrf/src/buffered_uarte.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index e212e9897..eb0b1b0cd 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs @@ -431,13 +431,13 @@ impl<'a, U: UarteInstance, T: TimerInstance> Drop for StateInner<'a, U, T> { r.inten.reset(); r.events_rxto.reset(); - r.tasks_stoprx.write(|w| w.tasks_stoprx().set_bit()); + r.tasks_stoprx.write(|w| unsafe { w.bits(1) }); r.events_txstopped.reset(); - r.tasks_stoptx.write(|w| w.tasks_stoptx().set_bit()); - while !r.events_txstopped.read().events_txstopped().bit_is_set() {} + r.tasks_stoptx.write(|w| unsafe { w.bits(1) }); + while r.events_txstopped.read().bits() == 0 {} - while !r.events_rxto.read().events_rxto().bit_is_set() {} + while r.events_rxto.read().bits() == 0 {} r.enable.write(|w| w.enable().disabled()); From b4f2c2a05ebe736de1faaf5541f1913ac3c4eff6 Mon Sep 17 00:00:00 2001 From: Zoey Riordan Date: Fri, 23 Sep 2022 12:34:02 +0200 Subject: [PATCH 5/5] Re-add timer.stop() --- embassy-nrf/src/buffered_uarte.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index eb0b1b0cd..47f32fac8 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs @@ -429,14 +429,15 @@ impl<'a, U: UarteInstance, T: TimerInstance> Drop for StateInner<'a, U, T> { fn drop(&mut self) { let r = U::regs(); + self.timer.stop(); + r.inten.reset(); r.events_rxto.reset(); r.tasks_stoprx.write(|w| unsafe { w.bits(1) }); - r.events_txstopped.reset(); r.tasks_stoptx.write(|w| unsafe { w.bits(1) }); - while r.events_txstopped.read().bits() == 0 {} + while r.events_txstopped.read().bits() == 0 {} while r.events_rxto.read().bits() == 0 {} r.enable.write(|w| w.enable().disabled());