uarte: Low power wait for RX drop
This commit is contained in:
parent
93780fa31d
commit
0631623b51
@ -17,8 +17,8 @@ use crate::hal::gpio::Port as GpioPort;
|
|||||||
use crate::hal::pac;
|
use crate::hal::pac;
|
||||||
use crate::hal::prelude::*;
|
use crate::hal::prelude::*;
|
||||||
use crate::hal::target_constants::EASY_DMA_SIZE;
|
use crate::hal::target_constants::EASY_DMA_SIZE;
|
||||||
use crate::interrupt;
|
|
||||||
use crate::interrupt::OwnedInterrupt;
|
use crate::interrupt::OwnedInterrupt;
|
||||||
|
use crate::{interrupt, util};
|
||||||
|
|
||||||
pub use crate::hal::uarte::Pins;
|
pub use crate::hal::uarte::Pins;
|
||||||
// Re-export SVD variants to allow user to directly set values.
|
// Re-export SVD variants to allow user to directly set values.
|
||||||
@ -275,7 +275,9 @@ where
|
|||||||
.instance
|
.instance
|
||||||
.tasks_stoptx
|
.tasks_stoptx
|
||||||
.write(|w| unsafe { w.bits(1) });
|
.write(|w| unsafe { w.bits(1) });
|
||||||
T::state().tx_done.blocking_wait();
|
|
||||||
|
// TX is stopped almost instantly, spinning is fine.
|
||||||
|
while !T::state().tx_done.signaled() {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -342,7 +344,8 @@ where
|
|||||||
.instance
|
.instance
|
||||||
.tasks_stoprx
|
.tasks_stoprx
|
||||||
.write(|w| unsafe { w.bits(1) });
|
.write(|w| unsafe { w.bits(1) });
|
||||||
T::state().rx_done.blocking_wait();
|
|
||||||
|
util::low_power_wait_until(|| T::state().rx_done.signaled())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -361,7 +364,7 @@ where
|
|||||||
let ptr = buf.as_ptr();
|
let ptr = buf.as_ptr();
|
||||||
let len = buf.len();
|
let len = buf.len();
|
||||||
assert!(len <= EASY_DMA_SIZE);
|
assert!(len <= EASY_DMA_SIZE);
|
||||||
|
|
||||||
uarte.enable();
|
uarte.enable();
|
||||||
|
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
@ -394,7 +397,7 @@ where
|
|||||||
T: Instance,
|
T: Instance,
|
||||||
{
|
{
|
||||||
/// Stops the ongoing reception and returns the number of bytes received.
|
/// Stops the ongoing reception and returns the number of bytes received.
|
||||||
pub async fn stop(mut self) -> usize {
|
pub async fn stop(self) -> usize {
|
||||||
let len = if self.uarte.rx_started() {
|
let len = if self.uarte.rx_started() {
|
||||||
trace!("stoprx (stop)");
|
trace!("stoprx (stop)");
|
||||||
|
|
||||||
|
@ -1,2 +1,12 @@
|
|||||||
pub mod peripheral;
|
pub mod peripheral;
|
||||||
pub mod ring_buffer;
|
pub mod ring_buffer;
|
||||||
|
|
||||||
|
/// Low power blocking wait loop using WFE/SEV.
|
||||||
|
pub 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();
|
||||||
|
}
|
||||||
|
@ -63,12 +63,7 @@ impl<T: Send> Signal<T> {
|
|||||||
futures::future::poll_fn(move |cx| self.poll_wait(cx))
|
futures::future::poll_fn(move |cx| self.poll_wait(cx))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Blocks until the signal has been received.
|
pub fn signaled(&self) -> bool {
|
||||||
///
|
cortex_m::interrupt::free(|_| matches!(unsafe { &*self.state.get() }, State::Signaled(_)))
|
||||||
/// Returns immediately when [`poll_wait()`] has not been called before.
|
|
||||||
pub fn blocking_wait(&self) {
|
|
||||||
while cortex_m::interrupt::free(|_| {
|
|
||||||
matches!(unsafe { &*self.state.get() }, State::Waiting(_))
|
|
||||||
}) {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user