aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Kröger <[email protected]>2021-01-03 11:12:11 +0100
committerTimo Kröger <[email protected]>2021-01-04 22:55:40 +0100
commita7c03e4cb6a9d39d0139cb88d224a0f80fd21820 (patch)
tree541529879e2fff5b5d2a8d35969d935490d788e0
parent9f28c7ab8d96d19a010246318dee1de73b3ed4ee (diff)
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.
-rw-r--r--embassy-nrf/src/uarte.rs43
1 files changed, 26 insertions, 17 deletions
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs
index 494b92df3..895ac11c3 100644
--- a/embassy-nrf/src/uarte.rs
+++ b/embassy-nrf/src/uarte.rs
@@ -170,6 +170,13 @@ where
170 trace!("endrx"); 170 trace!("endrx");
171 let len = uarte.rxd.amount.read().bits(); 171 let len = uarte.rxd.amount.read().bits();
172 compiler_fence(Ordering::SeqCst); 172 compiler_fence(Ordering::SeqCst);
173
174 if uarte.events_rxstarted.read().bits() != 0 {
175 // The ENDRX was signal triggered because DMA buffer is full.
176 uarte.events_rxstarted.reset();
177 try_disable = true;
178 }
179
173 T::state().rx_done.signal(len); 180 T::state().rx_done.signal(len);
174 } 181 }
175 182
@@ -227,6 +234,7 @@ impl<T: Instance> embassy::uart::Uart for Uarte<T> {
227 // `mem::forget()` on a previous future after polling it once. 234 // `mem::forget()` on a previous future after polling it once.
228 assert!(!self.rx_started()); 235 assert!(!self.rx_started());
229 236
237 T::state().rx_done.reset();
230 self.enable(); 238 self.enable();
231 239
232 ReceiveFuture { 240 ReceiveFuture {
@@ -334,27 +342,28 @@ where
334 fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { 342 fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
335 let Self { uarte, buf } = unsafe { self.get_unchecked_mut() }; 343 let Self { uarte, buf } = unsafe { self.get_unchecked_mut() };
336 344
337 if !uarte.rx_started() { 345 match T::state().rx_done.poll_wait(cx) {
338 let uarte = &uarte.instance; 346 Poll::Pending if !uarte.rx_started() => {
347 let uarte = &uarte.instance;
339 348
340 T::state().rx_done.reset(); 349 let ptr = buf.as_ptr();
341 350 let len = buf.len();
342 let ptr = buf.as_ptr(); 351 assert!(len <= EASY_DMA_SIZE);
343 let len = buf.len();
344 assert!(len <= EASY_DMA_SIZE);
345 352
346 compiler_fence(Ordering::SeqCst); 353 compiler_fence(Ordering::SeqCst);
347 uarte.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); 354 uarte.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) });
348 uarte 355 uarte
349 .rxd 356 .rxd
350 .maxcnt 357 .maxcnt
351 .write(|w| unsafe { w.maxcnt().bits(len as _) }); 358 .write(|w| unsafe { w.maxcnt().bits(len as _) });
352 359
353 trace!("startrx"); 360 trace!("startrx");
354 uarte.tasks_startrx.write(|w| unsafe { w.bits(1) }); 361 uarte.tasks_startrx.write(|w| unsafe { w.bits(1) });
362 Poll::Pending
363 }
364 Poll::Pending => Poll::Pending,
365 Poll::Ready(_) => Poll::Ready(Ok(())),
355 } 366 }
356
357 T::state().rx_done.poll_wait(cx).map(|_| Ok(()))
358 } 367 }
359} 368}
360 369