aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-nrf/src/uarte.rs13
-rw-r--r--embassy-nrf/src/util/mod.rs10
-rw-r--r--embassy/src/util/signal.rs9
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;
17use crate::hal::pac; 17use crate::hal::pac;
18use crate::hal::prelude::*; 18use crate::hal::prelude::*;
19use crate::hal::target_constants::EASY_DMA_SIZE; 19use crate::hal::target_constants::EASY_DMA_SIZE;
20use crate::interrupt;
21use crate::interrupt::OwnedInterrupt; 20use crate::interrupt::OwnedInterrupt;
21use crate::{interrupt, util};
22 22
23pub use crate::hal::uarte::Pins; 23pub 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 @@
1pub mod peripheral; 1pub mod peripheral;
2pub mod ring_buffer; 2pub mod ring_buffer;
3
4/// Low power blocking wait loop using WFE/SEV.
5pub 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}