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:
parent
a7c03e4cb6
commit
a3b3305b8e
@ -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,28 +289,28 @@ 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) {
|
||||||
let uarte = &uarte.instance;
|
Poll::Pending if !uarte.tx_started() => {
|
||||||
|
let uarte = &uarte.instance;
|
||||||
|
let ptr = buf.as_ptr();
|
||||||
|
let len = buf.len();
|
||||||
|
assert!(len <= EASY_DMA_SIZE);
|
||||||
|
// TODO: panic if buffer is not in SRAM
|
||||||
|
|
||||||
T::state().tx_done.reset();
|
compiler_fence(Ordering::SeqCst);
|
||||||
|
uarte.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) });
|
||||||
|
uarte
|
||||||
|
.txd
|
||||||
|
.maxcnt
|
||||||
|
.write(|w| unsafe { w.maxcnt().bits(len as _) });
|
||||||
|
|
||||||
let ptr = buf.as_ptr();
|
trace!("starttx");
|
||||||
let len = buf.len();
|
uarte.tasks_starttx.write(|w| unsafe { w.bits(1) });
|
||||||
assert!(len <= EASY_DMA_SIZE);
|
Poll::Pending
|
||||||
// TODO: panic if buffer is not in SRAM
|
}
|
||||||
|
Poll::Pending => Poll::Pending,
|
||||||
compiler_fence(Ordering::SeqCst);
|
Poll::Ready(_) => Poll::Ready(Ok(())),
|
||||||
uarte.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) });
|
|
||||||
uarte
|
|
||||||
.txd
|
|
||||||
.maxcnt
|
|
||||||
.write(|w| unsafe { w.maxcnt().bits(len as _) });
|
|
||||||
|
|
||||||
trace!("starttx");
|
|
||||||
uarte.tasks_starttx.write(|w| unsafe { w.bits(1) });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
T::state().tx_done.poll_wait(cx).map(|()| Ok(()))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user