diff options
| author | Timo Kröger <[email protected]> | 2021-01-03 11:12:11 +0100 |
|---|---|---|
| committer | Timo Kröger <[email protected]> | 2021-01-04 22:55:40 +0100 |
| commit | a7c03e4cb6a9d39d0139cb88d224a0f80fd21820 (patch) | |
| tree | 541529879e2fff5b5d2a8d35969d935490d788e0 | |
| parent | 9f28c7ab8d96d19a010246318dee1de73b3ed4ee (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.rs | 43 |
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 | ||
