diff options
| author | Timo Kröger <[email protected]> | 2021-01-03 17:05:04 +0100 |
|---|---|---|
| committer | Timo Kröger <[email protected]> | 2021-01-04 22:55:40 +0100 |
| commit | 0631623b511d2906993bf2fa3799ea7eec3d7f4a (patch) | |
| tree | ff187ea42e47ed86a0fff17e382e5d38cb369672 | |
| parent | 93780fa31d3c563e05fac6cd6ff8f15e43dc80fa (diff) | |
uarte: Low power wait for RX drop
| -rw-r--r-- | embassy-nrf/src/uarte.rs | 13 | ||||
| -rw-r--r-- | embassy-nrf/src/util/mod.rs | 10 | ||||
| -rw-r--r-- | embassy/src/util/signal.rs | 9 |
3 files changed, 20 insertions, 12 deletions
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index dc2093c38..bfebf5cab 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs | |||
| @@ -17,8 +17,8 @@ use crate::hal::gpio::Port as GpioPort; | |||
| 17 | use crate::hal::pac; | 17 | use crate::hal::pac; |
| 18 | use crate::hal::prelude::*; | 18 | use crate::hal::prelude::*; |
| 19 | use crate::hal::target_constants::EASY_DMA_SIZE; | 19 | use crate::hal::target_constants::EASY_DMA_SIZE; |
| 20 | use crate::interrupt; | ||
| 21 | use crate::interrupt::OwnedInterrupt; | 20 | use crate::interrupt::OwnedInterrupt; |
| 21 | use crate::{interrupt, util}; | ||
| 22 | 22 | ||
| 23 | pub use crate::hal::uarte::Pins; | 23 | pub use crate::hal::uarte::Pins; |
| 24 | // Re-export SVD variants to allow user to directly set values. | 24 | // Re-export SVD variants to allow user to directly set values. |
| @@ -275,7 +275,9 @@ where | |||
| 275 | .instance | 275 | .instance |
| 276 | .tasks_stoptx | 276 | .tasks_stoptx |
| 277 | .write(|w| unsafe { w.bits(1) }); | 277 | .write(|w| unsafe { w.bits(1) }); |
| 278 | T::state().tx_done.blocking_wait(); | 278 | |
| 279 | // TX is stopped almost instantly, spinning is fine. | ||
| 280 | while !T::state().tx_done.signaled() {} | ||
| 279 | } | 281 | } |
| 280 | } | 282 | } |
| 281 | } | 283 | } |
| @@ -342,7 +344,8 @@ where | |||
| 342 | .instance | 344 | .instance |
| 343 | .tasks_stoprx | 345 | .tasks_stoprx |
| 344 | .write(|w| unsafe { w.bits(1) }); | 346 | .write(|w| unsafe { w.bits(1) }); |
| 345 | T::state().rx_done.blocking_wait(); | 347 | |
| 348 | util::low_power_wait_until(|| T::state().rx_done.signaled()) | ||
| 346 | } | 349 | } |
| 347 | } | 350 | } |
| 348 | } | 351 | } |
| @@ -361,7 +364,7 @@ where | |||
| 361 | let ptr = buf.as_ptr(); | 364 | let ptr = buf.as_ptr(); |
| 362 | let len = buf.len(); | 365 | let len = buf.len(); |
| 363 | assert!(len <= EASY_DMA_SIZE); | 366 | assert!(len <= EASY_DMA_SIZE); |
| 364 | 367 | ||
| 365 | uarte.enable(); | 368 | uarte.enable(); |
| 366 | 369 | ||
| 367 | compiler_fence(Ordering::SeqCst); | 370 | compiler_fence(Ordering::SeqCst); |
| @@ -394,7 +397,7 @@ where | |||
| 394 | T: Instance, | 397 | T: Instance, |
| 395 | { | 398 | { |
| 396 | /// Stops the ongoing reception and returns the number of bytes received. | 399 | /// Stops the ongoing reception and returns the number of bytes received. |
| 397 | pub async fn stop(mut self) -> usize { | 400 | pub async fn stop(self) -> usize { |
| 398 | let len = if self.uarte.rx_started() { | 401 | let len = if self.uarte.rx_started() { |
| 399 | trace!("stoprx (stop)"); | 402 | trace!("stoprx (stop)"); |
| 400 | 403 | ||
diff --git a/embassy-nrf/src/util/mod.rs b/embassy-nrf/src/util/mod.rs index 2fd5453d3..cf3306545 100644 --- a/embassy-nrf/src/util/mod.rs +++ b/embassy-nrf/src/util/mod.rs | |||
| @@ -1,2 +1,12 @@ | |||
| 1 | pub mod peripheral; | 1 | pub mod peripheral; |
| 2 | pub mod ring_buffer; | 2 | pub mod ring_buffer; |
| 3 | |||
| 4 | /// Low power blocking wait loop using WFE/SEV. | ||
| 5 | pub fn low_power_wait_until(mut condition: impl FnMut() -> bool) { | ||
| 6 | while !condition() { | ||
| 7 | // WFE might "eat" an event that would have otherwise woken the executor. | ||
| 8 | cortex_m::asm::wfe(); | ||
| 9 | } | ||
| 10 | // Retrigger an event to be transparent to the executor. | ||
| 11 | cortex_m::asm::sev(); | ||
| 12 | } | ||
diff --git a/embassy/src/util/signal.rs b/embassy/src/util/signal.rs index cb6410611..8e778d1e3 100644 --- a/embassy/src/util/signal.rs +++ b/embassy/src/util/signal.rs | |||
| @@ -63,12 +63,7 @@ impl<T: Send> Signal<T> { | |||
| 63 | futures::future::poll_fn(move |cx| self.poll_wait(cx)) | 63 | futures::future::poll_fn(move |cx| self.poll_wait(cx)) |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | /// Blocks until the signal has been received. | 66 | pub fn signaled(&self) -> bool { |
| 67 | /// | 67 | cortex_m::interrupt::free(|_| matches!(unsafe { &*self.state.get() }, State::Signaled(_))) |
| 68 | /// Returns immediately when [`poll_wait()`] has not been called before. | ||
| 69 | pub fn blocking_wait(&self) { | ||
| 70 | while cortex_m::interrupt::free(|_| { | ||
| 71 | matches!(unsafe { &*self.state.get() }, State::Waiting(_)) | ||
| 72 | }) {} | ||
| 73 | } | 68 | } |
| 74 | } | 69 | } |
