uarte: Only stop RX forcefully when a reception is running
The STOPRX task always triggers a timeout of ~55bit times until the RXTO event is generated. Before we disabled the receiver only after the timeout. With this change the receiver is stopped right after reception has ended because the DMA buffer is full. For forced RX aborts like `stop()` or on drop still need to wait for the RXTO event before disabling the receiver.
This commit is contained in:
parent
9f28c7ab8d
commit
a7c03e4cb6
@ -170,6 +170,13 @@ where
|
|||||||
trace!("endrx");
|
trace!("endrx");
|
||||||
let len = uarte.rxd.amount.read().bits();
|
let len = uarte.rxd.amount.read().bits();
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
|
|
||||||
|
if uarte.events_rxstarted.read().bits() != 0 {
|
||||||
|
// The ENDRX was signal triggered because DMA buffer is full.
|
||||||
|
uarte.events_rxstarted.reset();
|
||||||
|
try_disable = true;
|
||||||
|
}
|
||||||
|
|
||||||
T::state().rx_done.signal(len);
|
T::state().rx_done.signal(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,6 +234,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.rx_started());
|
assert!(!self.rx_started());
|
||||||
|
|
||||||
|
T::state().rx_done.reset();
|
||||||
self.enable();
|
self.enable();
|
||||||
|
|
||||||
ReceiveFuture {
|
ReceiveFuture {
|
||||||
@ -334,11 +342,10 @@ 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.rx_started() {
|
match T::state().rx_done.poll_wait(cx) {
|
||||||
|
Poll::Pending if !uarte.rx_started() => {
|
||||||
let uarte = &uarte.instance;
|
let uarte = &uarte.instance;
|
||||||
|
|
||||||
T::state().rx_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);
|
||||||
@ -352,9 +359,11 @@ where
|
|||||||
|
|
||||||
trace!("startrx");
|
trace!("startrx");
|
||||||
uarte.tasks_startrx.write(|w| unsafe { w.bits(1) });
|
uarte.tasks_startrx.write(|w| unsafe { w.bits(1) });
|
||||||
|
Poll::Pending
|
||||||
|
}
|
||||||
|
Poll::Pending => Poll::Pending,
|
||||||
|
Poll::Ready(_) => Poll::Ready(Ok(())),
|
||||||
}
|
}
|
||||||
|
|
||||||
T::state().rx_done.poll_wait(cx).map(|_| Ok(()))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user