aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src
diff options
context:
space:
mode:
authoretiennecollin <[email protected]>2025-08-25 21:10:59 +0200
committerDario Nieuwenhuis <[email protected]>2025-09-05 14:43:29 +0200
commitfec14213ea7b79badc14eae38c4a0b0197499f3f (patch)
tree8e2abe6de562d98cead117cbcc7321198fa0577a /embassy-stm32/src
parent7d224d94c47e4e457aed7c4832be8b4a52dfcef8 (diff)
fix: modified dma channel state management
See https://github.com/embassy-rs/embassy/pull/3923#discussion_r2094570176
Diffstat (limited to 'embassy-stm32/src')
-rw-r--r--embassy-stm32/src/dma/gpdma/mod.rs66
-rw-r--r--embassy-stm32/src/dma/gpdma/ringbuffered.rs54
-rw-r--r--embassy-stm32/src/ucpd.rs4
-rw-r--r--embassy-stm32/src/usart/ringbuffered.rs2
4 files changed, 80 insertions, 46 deletions
diff --git a/embassy-stm32/src/dma/gpdma/mod.rs b/embassy-stm32/src/dma/gpdma/mod.rs
index 2132f070a..d06eac60e 100644
--- a/embassy-stm32/src/dma/gpdma/mod.rs
+++ b/embassy-stm32/src/dma/gpdma/mod.rs
@@ -341,21 +341,25 @@ impl AnyChannel {
341 ch.cr().modify(|w| w.set_en(true)); 341 ch.cr().modify(|w| w.set_en(true));
342 } 342 }
343 343
344 fn request_stop(&self) { 344 fn request_suspend(&self) {
345 let info = self.info(); 345 let info = self.info();
346 let ch = info.dma.ch(info.num); 346 let ch = info.dma.ch(info.num);
347 347
348 ch.cr().modify(|w| w.set_susp(true)) 348 ch.cr().modify(|w| w.set_susp(true))
349 } 349 }
350 350
351 fn request_pause(&self) { 351 fn request_resume(&self) {
352 let info = self.info(); 352 let info = self.info();
353 let ch = info.dma.ch(info.num); 353 let ch = info.dma.ch(info.num);
354 354
355 // Disable the channel without overwriting the existing configuration 355 ch.cr().modify(|w| w.set_susp(false));
356 ch.cr().modify(|w| { 356 }
357 w.set_en(false); 357
358 }); 358 fn request_reset(&self) {
359 let info = self.info();
360 let ch = info.dma.ch(info.num);
361
362 ch.cr().modify(|w| w.set_reset(true));
359 } 363 }
360 364
361 fn is_running(&self) -> bool { 365 fn is_running(&self) -> bool {
@@ -406,11 +410,26 @@ impl<'a, const ITEM_COUNT: usize> LinkedListTransfer<'a, ITEM_COUNT> {
406 Self { channel } 410 Self { channel }
407 } 411 }
408 412
409 /// Request the transfer to stop. 413 /// Request the transfer to suspend.
414 ///
415 /// To resume the transfer, call [`request_resume`](Self::request_resume) again.
410 /// 416 ///
411 /// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false. 417 /// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false.
412 pub fn request_stop(&mut self) { 418 pub fn request_suspend(&mut self) {
413 self.channel.request_stop() 419 self.channel.request_suspend()
420 }
421
422 /// Request the transfer to resume after being suspended.
423 pub fn request_resume(&mut self) {
424 self.channel.request_resume()
425 }
426
427 /// Request the DMA to reset.
428 ///
429 /// The configuration for this channel will **not be preserved**. If you need to restart the transfer
430 /// at a later point with the same configuration, see [`request_suspend`](Self::request_suspend) instead.
431 pub fn request_reset(&mut self) {
432 self.channel.request_reset()
414 } 433 }
415 434
416 /// Return whether this transfer is still running. 435 /// Return whether this transfer is still running.
@@ -440,7 +459,7 @@ impl<'a, const ITEM_COUNT: usize> LinkedListTransfer<'a, ITEM_COUNT> {
440 459
441impl<'a, const ITEM_COUNT: usize> Drop for LinkedListTransfer<'a, ITEM_COUNT> { 460impl<'a, const ITEM_COUNT: usize> Drop for LinkedListTransfer<'a, ITEM_COUNT> {
442 fn drop(&mut self) { 461 fn drop(&mut self) {
443 self.request_stop(); 462 self.request_suspend();
444 while self.is_running() {} 463 while self.is_running() {}
445 464
446 // "Subsequent reads and writes cannot be moved ahead of preceding reads." 465 // "Subsequent reads and writes cannot be moved ahead of preceding reads."
@@ -589,21 +608,26 @@ impl<'a> Transfer<'a> {
589 Self { channel } 608 Self { channel }
590 } 609 }
591 610
592 /// Request the transfer to stop. 611 /// Request the transfer to suspend.
593 /// The configuration for this channel will **not be preserved**. If you need to restart the transfer 612 ///
594 /// at a later point with the same configuration, see [`request_pause`](Self::request_pause) instead. 613 /// To resume the transfer, call [`request_resume`](Self::request_resume) again.
595 /// 614 ///
596 /// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false. 615 /// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false.
597 pub fn request_stop(&mut self) { 616 pub fn request_suspend(&mut self) {
598 self.channel.request_stop() 617 self.channel.request_suspend()
599 } 618 }
600 619
601 /// Request the transfer to pause, keeping the existing configuration for this channel. 620 /// Request the transfer to resume after being suspended.
602 /// To restart the transfer, call [`start`](Self::start) again. 621 pub fn request_resume(&mut self) {
622 self.channel.request_resume()
623 }
624
625 /// Request the DMA to reset.
603 /// 626 ///
604 /// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false. 627 /// The configuration for this channel will **not be preserved**. If you need to restart the transfer
605 pub fn request_pause(&mut self) { 628 /// at a later point with the same configuration, see [`request_suspend`](Self::request_suspend) instead.
606 self.channel.request_pause() 629 pub fn request_reset(&mut self) {
630 self.channel.request_reset()
607 } 631 }
608 632
609 /// Return whether this transfer is still running. 633 /// Return whether this transfer is still running.
@@ -633,7 +657,7 @@ impl<'a> Transfer<'a> {
633 657
634impl<'a> Drop for Transfer<'a> { 658impl<'a> Drop for Transfer<'a> {
635 fn drop(&mut self) { 659 fn drop(&mut self) {
636 self.request_stop(); 660 self.request_suspend();
637 while self.is_running() {} 661 while self.is_running() {}
638 662
639 // "Subsequent reads and writes cannot be moved ahead of preceding reads." 663 // "Subsequent reads and writes cannot be moved ahead of preceding reads."
diff --git a/embassy-stm32/src/dma/gpdma/ringbuffered.rs b/embassy-stm32/src/dma/gpdma/ringbuffered.rs
index 87c482bfb..4532bda57 100644
--- a/embassy-stm32/src/dma/gpdma/ringbuffered.rs
+++ b/embassy-stm32/src/dma/gpdma/ringbuffered.rs
@@ -139,21 +139,26 @@ impl<'a, W: Word> ReadableRingBuffer<'a, W> {
139 DmaCtrlImpl(self.channel.reborrow()).set_waker(waker); 139 DmaCtrlImpl(self.channel.reborrow()).set_waker(waker);
140 } 140 }
141 141
142 /// Request the DMA to stop. 142 /// Request the DMA to suspend.
143 /// The configuration for this channel will **not be preserved**. If you need to restart the transfer 143 ///
144 /// at a later point with the same configuration, see [`request_pause`](Self::request_pause) instead. 144 /// To resume the transfer, call [`request_resume`](Self::request_resume) again.
145 /// 145 ///
146 /// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false. 146 /// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false.
147 pub fn request_stop(&mut self) { 147 pub fn request_suspend(&mut self) {
148 self.channel.request_stop() 148 self.channel.request_suspend()
149 }
150
151 /// Request the DMA to resume transfers after being suspended.
152 pub fn request_resume(&mut self) {
153 self.channel.request_resume()
149 } 154 }
150 155
151 /// Request the transfer to pause, keeping the existing configuration for this channel. 156 /// Request the DMA to reset.
152 /// To restart the transfer, call [`start`](Self::start) again.
153 /// 157 ///
154 /// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false. 158 /// The configuration for this channel will **not be preserved**. If you need to restart the transfer
155 pub fn request_pause(&mut self) { 159 /// at a later point with the same configuration, see [`request_suspend`](Self::request_suspend) instead.
156 self.channel.request_pause() 160 pub fn request_reset(&mut self) {
161 self.channel.request_reset()
157 } 162 }
158 163
159 /// Return whether DMA is still running. 164 /// Return whether DMA is still running.
@@ -185,7 +190,7 @@ impl<'a, W: Word> ReadableRingBuffer<'a, W> {
185 190
186impl<'a, W: Word> Drop for ReadableRingBuffer<'a, W> { 191impl<'a, W: Word> Drop for ReadableRingBuffer<'a, W> {
187 fn drop(&mut self) { 192 fn drop(&mut self) {
188 self.request_stop(); 193 self.request_suspend();
189 while self.is_running() {} 194 while self.is_running() {}
190 195
191 // "Subsequent reads and writes cannot be moved ahead of preceding reads." 196 // "Subsequent reads and writes cannot be moved ahead of preceding reads."
@@ -285,21 +290,26 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> {
285 DmaCtrlImpl(self.channel.reborrow()).set_waker(waker); 290 DmaCtrlImpl(self.channel.reborrow()).set_waker(waker);
286 } 291 }
287 292
288 /// Request the DMA to stop. 293 /// Request the DMA to suspend.
289 /// The configuration for this channel will **not be preserved**. If you need to restart the transfer 294 ///
290 /// at a later point with the same configuration, see [`request_pause`](Self::request_pause) instead. 295 /// To resume the transfer, call [`request_resume`](Self::request_resume) again.
291 /// 296 ///
292 /// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false. 297 /// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false.
293 pub fn request_stop(&mut self) { 298 pub fn request_suspend(&mut self) {
294 self.channel.request_stop() 299 self.channel.request_suspend()
300 }
301
302 /// Request the DMA to resume transfers after being suspended.
303 pub fn request_resume(&mut self) {
304 self.channel.request_resume()
295 } 305 }
296 306
297 /// Request the transfer to pause, keeping the existing configuration for this channel. 307 /// Request the DMA to reset.
298 /// To restart the transfer, call [`start`](Self::start) again.
299 /// 308 ///
300 /// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false. 309 /// The configuration for this channel will **not be preserved**. If you need to restart the transfer
301 pub fn request_pause(&mut self) { 310 /// at a later point with the same configuration, see [`request_suspend`](Self::request_suspend) instead.
302 self.channel.request_pause() 311 pub fn request_reset(&mut self) {
312 self.channel.request_reset()
303 } 313 }
304 314
305 /// Return whether DMA is still running. 315 /// Return whether DMA is still running.
@@ -331,7 +341,7 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> {
331 341
332impl<'a, W: Word> Drop for WritableRingBuffer<'a, W> { 342impl<'a, W: Word> Drop for WritableRingBuffer<'a, W> {
333 fn drop(&mut self) { 343 fn drop(&mut self) {
334 self.request_stop(); 344 self.request_suspend();
335 while self.is_running() {} 345 while self.is_running() {}
336 346
337 // "Subsequent reads and writes cannot be moved ahead of preceding reads." 347 // "Subsequent reads and writes cannot be moved ahead of preceding reads."
diff --git a/embassy-stm32/src/ucpd.rs b/embassy-stm32/src/ucpd.rs
index 0a80adb8f..967e43a8a 100644
--- a/embassy-stm32/src/ucpd.rs
+++ b/embassy-stm32/src/ucpd.rs
@@ -490,14 +490,14 @@ impl<'d, T: Instance> PdPhy<'d, T> {
490 let sr = r.sr().read(); 490 let sr = r.sr().read();
491 491
492 if sr.rxhrstdet() { 492 if sr.rxhrstdet() {
493 dma.request_stop(); 493 dma.request_suspend();
494 494
495 // Clean and re-enable hard reset receive interrupt. 495 // Clean and re-enable hard reset receive interrupt.
496 r.icr().write(|w| w.set_rxhrstdetcf(true)); 496 r.icr().write(|w| w.set_rxhrstdetcf(true));
497 r.imr().modify(|w| w.set_rxhrstdetie(true)); 497 r.imr().modify(|w| w.set_rxhrstdetie(true));
498 Poll::Ready(Err(RxError::HardReset)) 498 Poll::Ready(Err(RxError::HardReset))
499 } else if sr.rxmsgend() { 499 } else if sr.rxmsgend() {
500 dma.request_stop(); 500 dma.request_suspend();
501 // Should be read immediately on interrupt. 501 // Should be read immediately on interrupt.
502 rxpaysz = r.rx_payszr().read().rxpaysz().into(); 502 rxpaysz = r.rx_payszr().read().rxpaysz().into();
503 503
diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs
index 5f4e87834..bea56c991 100644
--- a/embassy-stm32/src/usart/ringbuffered.rs
+++ b/embassy-stm32/src/usart/ringbuffered.rs
@@ -165,7 +165,7 @@ impl<'d> RingBufferedUartRx<'d> {
165 165
166 /// Stop DMA backed UART receiver 166 /// Stop DMA backed UART receiver
167 fn stop_uart(&mut self) { 167 fn stop_uart(&mut self) {
168 self.ring_buf.request_pause(); 168 self.ring_buf.request_suspend();
169 169
170 let r = self.info.regs; 170 let r = self.info.regs;
171 // clear all interrupts and DMA Rx Request 171 // clear all interrupts and DMA Rx Request