diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-04-10 15:11:07 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-04-10 15:11:07 +0200 |
| commit | 44b7fe45e279f713a49f92e786f358af6c68e157 (patch) | |
| tree | 495cdf6f4b4052478bf66a9cb06d19971a88c4c3 | |
| parent | dee8c71a2d57f3015fde55da28758a35fcbf7ca6 (diff) | |
stm32/gpdma: fix race condition when resetting channel when done.
| -rw-r--r-- | embassy-stm32/src/dma/gpdma.rs | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/embassy-stm32/src/dma/gpdma.rs b/embassy-stm32/src/dma/gpdma.rs index 442fee48e..6f26fd194 100644 --- a/embassy-stm32/src/dma/gpdma.rs +++ b/embassy-stm32/src/dma/gpdma.rs | |||
| @@ -190,6 +190,10 @@ mod low_level_api { | |||
| 190 | fence(Ordering::SeqCst); | 190 | fence(Ordering::SeqCst); |
| 191 | 191 | ||
| 192 | let ch = dma.ch(channel_number as _); | 192 | let ch = dma.ch(channel_number as _); |
| 193 | |||
| 194 | // Reset ch | ||
| 195 | ch.cr().write(|w| w.set_reset(true)); | ||
| 196 | |||
| 193 | ch.llr().write(|_| {}); // no linked list | 197 | ch.llr().write(|_| {}); // no linked list |
| 194 | ch.tr1().write(|w| { | 198 | ch.tr1().write(|w| { |
| 195 | w.set_sdw(data_size.into()); | 199 | w.set_sdw(data_size.into()); |
| @@ -252,7 +256,7 @@ mod low_level_api { | |||
| 252 | /// Gets the running status of the channel | 256 | /// Gets the running status of the channel |
| 253 | pub unsafe fn is_running(dma: Gpdma, ch: u8) -> bool { | 257 | pub unsafe fn is_running(dma: Gpdma, ch: u8) -> bool { |
| 254 | let ch = dma.ch(ch as _); | 258 | let ch = dma.ch(ch as _); |
| 255 | !ch.sr().read().idlef() | 259 | !ch.sr().read().tcf() |
| 256 | } | 260 | } |
| 257 | 261 | ||
| 258 | /// Gets the total remaining transfers for the channel | 262 | /// Gets the total remaining transfers for the channel |
| @@ -291,7 +295,10 @@ mod low_level_api { | |||
| 291 | } | 295 | } |
| 292 | 296 | ||
| 293 | if sr.suspf() || sr.tcf() { | 297 | if sr.suspf() || sr.tcf() { |
| 294 | ch.cr().write(|w| w.set_reset(true)); | 298 | // disable all xxIEs to prevent the irq from firing again. |
| 299 | ch.cr().write(|_| {}); | ||
| 300 | |||
| 301 | // Wake the future. It'll look at tcf and see it's set. | ||
| 295 | STATE.channels[state_index].waker.wake(); | 302 | STATE.channels[state_index].waker.wake(); |
| 296 | } | 303 | } |
| 297 | } | 304 | } |
