diff options
| author | Timo Kröger <[email protected]> | 2021-01-03 12:02:03 +0100 |
|---|---|---|
| committer | Timo Kröger <[email protected]> | 2021-01-04 22:55:40 +0100 |
| commit | a3b3305b8e9afbedde58e6c44c112335b25fa176 (patch) | |
| tree | 8fb10b8f1ac3400107c70045402a9ca320f921bb | |
| parent | a7c03e4cb6a9d39d0139cb88d224a0f80fd21820 (diff) | |
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.
| -rw-r--r-- | embassy-nrf/src/uarte.rs | 46 |
1 files changed, 27 insertions, 19 deletions
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 895ac11c3..80c31b671 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs | |||
| @@ -156,6 +156,13 @@ where | |||
| 156 | uarte.events_endtx.reset(); | 156 | uarte.events_endtx.reset(); |
| 157 | trace!("endtx"); | 157 | trace!("endtx"); |
| 158 | compiler_fence(Ordering::SeqCst); | 158 | compiler_fence(Ordering::SeqCst); |
| 159 | |||
| 160 | if uarte.events_txstarted.read().bits() != 0 { | ||
| 161 | // The ENDTX was signal triggered because DMA has finished. | ||
| 162 | uarte.events_txstarted.reset(); | ||
| 163 | try_disable = true; | ||
| 164 | } | ||
| 165 | |||
| 159 | T::state().tx_done.signal(()); | 166 | T::state().tx_done.signal(()); |
| 160 | } | 167 | } |
| 161 | 168 | ||
| @@ -211,6 +218,7 @@ impl<T: Instance> embassy::uart::Uart for Uarte<T> { | |||
| 211 | // `mem::forget()` on a previous future after polling it once. | 218 | // `mem::forget()` on a previous future after polling it once. |
| 212 | assert!(!self.tx_started()); | 219 | assert!(!self.tx_started()); |
| 213 | 220 | ||
| 221 | T::state().tx_done.reset(); | ||
| 214 | self.enable(); | 222 | self.enable(); |
| 215 | 223 | ||
| 216 | SendFuture { | 224 | SendFuture { |
| @@ -281,28 +289,28 @@ where | |||
| 281 | fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { | 289 | fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
| 282 | let Self { uarte, buf } = unsafe { self.get_unchecked_mut() }; | 290 | let Self { uarte, buf } = unsafe { self.get_unchecked_mut() }; |
| 283 | 291 | ||
| 284 | if !uarte.tx_started() { | 292 | match T::state().tx_done.poll_wait(cx) { |
| 285 | let uarte = &uarte.instance; | 293 | Poll::Pending if !uarte.tx_started() => { |
| 286 | 294 | let uarte = &uarte.instance; | |
| 287 | T::state().tx_done.reset(); | 295 | let ptr = buf.as_ptr(); |
| 296 | let len = buf.len(); | ||
| 297 | assert!(len <= EASY_DMA_SIZE); | ||
| 298 | // TODO: panic if buffer is not in SRAM | ||
| 288 | 299 | ||
| 289 | let ptr = buf.as_ptr(); | 300 | compiler_fence(Ordering::SeqCst); |
| 290 | let len = buf.len(); | 301 | uarte.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); |
| 291 | assert!(len <= EASY_DMA_SIZE); | 302 | uarte |
| 292 | // TODO: panic if buffer is not in SRAM | 303 | .txd |
| 304 | .maxcnt | ||
| 305 | .write(|w| unsafe { w.maxcnt().bits(len as _) }); | ||
| 293 | 306 | ||
| 294 | compiler_fence(Ordering::SeqCst); | 307 | trace!("starttx"); |
| 295 | uarte.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); | 308 | uarte.tasks_starttx.write(|w| unsafe { w.bits(1) }); |
| 296 | uarte | 309 | Poll::Pending |
| 297 | .txd | 310 | } |
| 298 | .maxcnt | 311 | Poll::Pending => Poll::Pending, |
| 299 | .write(|w| unsafe { w.maxcnt().bits(len as _) }); | 312 | Poll::Ready(_) => Poll::Ready(Ok(())), |
| 300 | |||
| 301 | trace!("starttx"); | ||
| 302 | uarte.tasks_starttx.write(|w| unsafe { w.bits(1) }); | ||
| 303 | } | 313 | } |
| 304 | |||
| 305 | T::state().tx_done.poll_wait(cx).map(|()| Ok(())) | ||
| 306 | } | 314 | } |
| 307 | } | 315 | } |
| 308 | 316 | ||
