uarte: Only stop TX forcefully when a transmissions is running

This comes with insignificant power consumption improvements but makes
the code of the RX and TX case symmetric.
This commit is contained in:
Timo Kröger 2021-01-03 12:02:03 +01:00
parent a7c03e4cb6
commit a3b3305b8e

View File

@ -156,6 +156,13 @@ where
uarte.events_endtx.reset(); uarte.events_endtx.reset();
trace!("endtx"); trace!("endtx");
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
if uarte.events_txstarted.read().bits() != 0 {
// The ENDTX was signal triggered because DMA has finished.
uarte.events_txstarted.reset();
try_disable = true;
}
T::state().tx_done.signal(()); T::state().tx_done.signal(());
} }
@ -211,6 +218,7 @@ impl<T: Instance> embassy::uart::Uart for Uarte<T> {
// `mem::forget()` on a previous future after polling it once. // `mem::forget()` on a previous future after polling it once.
assert!(!self.tx_started()); assert!(!self.tx_started());
T::state().tx_done.reset();
self.enable(); self.enable();
SendFuture { SendFuture {
@ -281,11 +289,9 @@ where
fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let Self { uarte, buf } = unsafe { self.get_unchecked_mut() }; let Self { uarte, buf } = unsafe { self.get_unchecked_mut() };
if !uarte.tx_started() { match T::state().tx_done.poll_wait(cx) {
Poll::Pending if !uarte.tx_started() => {
let uarte = &uarte.instance; let uarte = &uarte.instance;
T::state().tx_done.reset();
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);
@ -300,9 +306,11 @@ where
trace!("starttx"); trace!("starttx");
uarte.tasks_starttx.write(|w| unsafe { w.bits(1) }); uarte.tasks_starttx.write(|w| unsafe { w.bits(1) });
Poll::Pending
}
Poll::Pending => Poll::Pending,
Poll::Ready(_) => Poll::Ready(Ok(())),
} }
T::state().tx_done.poll_wait(cx).map(|()| Ok(()))
} }
} }