aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Kröger <[email protected]>2021-01-03 12:02:03 +0100
committerTimo Kröger <[email protected]>2021-01-04 22:55:40 +0100
commita3b3305b8e9afbedde58e6c44c112335b25fa176 (patch)
tree8fb10b8f1ac3400107c70045402a9ca320f921bb
parenta7c03e4cb6a9d39d0139cb88d224a0f80fd21820 (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.rs46
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