diff options
| author | elagil <[email protected]> | 2025-08-25 21:10:59 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2025-09-05 14:43:29 +0200 |
| commit | 2baa4399a7dc4c38ed478f723bbf3b7417dcc0f5 (patch) | |
| tree | 4e65795d39e929737c46d225c4246206270d6c50 /embassy-stm32/src/dma | |
| parent | 50224583db79fcbfe340056eef855414c884f281 (diff) | |
fix: wip gpdma
Diffstat (limited to 'embassy-stm32/src/dma')
| -rw-r--r-- | embassy-stm32/src/dma/gpdma/mod.rs | 6 | ||||
| -rw-r--r-- | embassy-stm32/src/dma/gpdma/ringbuffered.rs | 25 |
2 files changed, 16 insertions, 15 deletions
diff --git a/embassy-stm32/src/dma/gpdma/mod.rs b/embassy-stm32/src/dma/gpdma/mod.rs index a158d30b8..9868ce52d 100644 --- a/embassy-stm32/src/dma/gpdma/mod.rs +++ b/embassy-stm32/src/dma/gpdma/mod.rs | |||
| @@ -199,10 +199,8 @@ impl AnyChannel { | |||
| 199 | } | 199 | } |
| 200 | 200 | ||
| 201 | if sr.suspf() { | 201 | if sr.suspf() { |
| 202 | // disable all xxIEs to prevent the irq from firing again. | 202 | // Disable all xxIEs to prevent the irq from firing again. |
| 203 | ch.cr().write(|_| {}); | 203 | ch.cr().write(|_| {}); |
| 204 | |||
| 205 | // Wake the future. It'll look at tcf and see it's set. | ||
| 206 | } | 204 | } |
| 207 | state.waker.wake(); | 205 | state.waker.wake(); |
| 208 | } | 206 | } |
| @@ -366,7 +364,7 @@ impl AnyChannel { | |||
| 366 | 364 | ||
| 367 | let sr = ch.sr().read(); | 365 | let sr = ch.sr().read(); |
| 368 | 366 | ||
| 369 | !sr.tcf() && !sr.suspf() && !sr.idlef() | 367 | !sr.suspf() && !sr.idlef() |
| 370 | } | 368 | } |
| 371 | 369 | ||
| 372 | fn poll_stop(&self) -> Poll<()> { | 370 | fn poll_stop(&self) -> Poll<()> { |
diff --git a/embassy-stm32/src/dma/gpdma/ringbuffered.rs b/embassy-stm32/src/dma/gpdma/ringbuffered.rs index 20f46b103..5ba45358b 100644 --- a/embassy-stm32/src/dma/gpdma/ringbuffered.rs +++ b/embassy-stm32/src/dma/gpdma/ringbuffered.rs | |||
| @@ -23,11 +23,14 @@ impl<'a> DmaCtrl for DmaCtrlImpl<'a> { | |||
| 23 | let lli_count = state.lli_state.count.load(Ordering::Acquire); | 23 | let lli_count = state.lli_state.count.load(Ordering::Acquire); |
| 24 | 24 | ||
| 25 | if lli_count > 0 { | 25 | if lli_count > 0 { |
| 26 | // In linked-list mode, the remaining transfers are the sum of the full lengths of LLIs that follow, | ||
| 27 | // and the remaining transfers for the current LLI. | ||
| 26 | let lli_index = state.lli_state.index.load(Ordering::Acquire); | 28 | let lli_index = state.lli_state.index.load(Ordering::Acquire); |
| 27 | let single_transfer_count = state.lli_state.transfer_count.load(Ordering::Acquire) / lli_count; | 29 | let single_transfer_count = state.lli_state.transfer_count.load(Ordering::Acquire) / lli_count; |
| 28 | 30 | ||
| 29 | (lli_count - lli_index - 1) * single_transfer_count + current_remaining | 31 | (lli_count - lli_index - 1) * single_transfer_count + current_remaining |
| 30 | } else { | 32 | } else { |
| 33 | // No linked-list mode. | ||
| 31 | current_remaining | 34 | current_remaining |
| 32 | } | 35 | } |
| 33 | } | 36 | } |
| @@ -81,6 +84,7 @@ impl<'a, W: Word> ReadableRingBuffer<'a, W> { | |||
| 81 | into_ref!(channel); | 84 | into_ref!(channel); |
| 82 | let channel: PeripheralRef<'a, AnyChannel> = channel.map_into(); | 85 | let channel: PeripheralRef<'a, AnyChannel> = channel.map_into(); |
| 83 | 86 | ||
| 87 | // Buffer halves should be the same length. | ||
| 84 | let half_len = buffer.len() / 2; | 88 | let half_len = buffer.len() / 2; |
| 85 | assert_eq!(half_len * 2, buffer.len()); | 89 | assert_eq!(half_len * 2, buffer.len()); |
| 86 | 90 | ||
| @@ -227,6 +231,7 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> { | |||
| 227 | into_ref!(channel); | 231 | into_ref!(channel); |
| 228 | let channel: PeripheralRef<'a, AnyChannel> = channel.map_into(); | 232 | let channel: PeripheralRef<'a, AnyChannel> = channel.map_into(); |
| 229 | 233 | ||
| 234 | // Buffer halves should be the same length. | ||
| 230 | let half_len = buffer.len() / 2; | 235 | let half_len = buffer.len() / 2; |
| 231 | assert_eq!(half_len * 2, buffer.len()); | 236 | assert_eq!(half_len * 2, buffer.len()); |
| 232 | 237 | ||
| @@ -258,8 +263,8 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> { | |||
| 258 | self.table.unlink(); | 263 | self.table.unlink(); |
| 259 | 264 | ||
| 260 | match self.user_buffer_half { | 265 | match self.user_buffer_half { |
| 261 | BufferHalf::First => self.table.link_indices(0, 1), | 266 | BufferHalf::First => self.table.link_indices(1, 0), |
| 262 | BufferHalf::Second => self.table.link_indices(1, 0), | 267 | BufferHalf::Second => self.table.link_indices(0, 1), |
| 263 | } | 268 | } |
| 264 | 269 | ||
| 265 | self.user_buffer_half.toggle(); | 270 | self.user_buffer_half.toggle(); |
| @@ -298,48 +303,46 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> { | |||
| 298 | .write_exact(&mut DmaCtrlImpl(self.channel.reborrow()), buffer) | 303 | .write_exact(&mut DmaCtrlImpl(self.channel.reborrow()), buffer) |
| 299 | .await; | 304 | .await; |
| 300 | 305 | ||
| 301 | let mut remaining = buffer.len(); | 306 | let mut writable_length = buffer.len(); |
| 302 | 307 | ||
| 303 | let mut remaining_cap = 0; | 308 | let mut remaining_cap = 0; |
| 304 | let cap = self.ringbuf.cap(); | 309 | let cap = self.ringbuf.cap(); |
| 305 | 310 | ||
| 306 | while remaining > 0 { | 311 | while writable_length > 0 { |
| 307 | let dma_buffer_half = self.dma_buffer_half(); | 312 | let dma_buffer_half = self.dma_buffer_half(); |
| 308 | if dma_buffer_half == self.user_buffer_half { | 313 | if dma_buffer_half == self.user_buffer_half { |
| 309 | self.link_next_buffer(); | 314 | self.link_next_buffer(); |
| 310 | } | 315 | } |
| 311 | 316 | ||
| 312 | let write_index = self.ringbuf.write_index(0); | 317 | let write_index = self.ringbuf.write_index(0); |
| 313 | let len = match dma_buffer_half { | 318 | let write_length = match dma_buffer_half { |
| 314 | BufferHalf::First => { | 319 | BufferHalf::First => { |
| 315 | // if write_index < cap / 2 { | 320 | // if write_index < cap / 2 { |
| 316 | // error!("write index: {}", write_index); | 321 | // error!("write index: {}", write_index); |
| 317 | // panic!() | 322 | // panic!() |
| 318 | // } | 323 | // } |
| 319 | info!("Write second"); | ||
| 320 | 324 | ||
| 321 | // Fill up second buffer half when DMA reads the first. | 325 | // Fill up second buffer half when DMA reads the first. |
| 322 | cap - write_index | 326 | cap / 2 - write_index |
| 323 | } | 327 | } |
| 324 | BufferHalf::Second => { | 328 | BufferHalf::Second => { |
| 325 | // if write_index >= cap / 2 { | 329 | // if write_index >= cap / 2 { |
| 326 | // error!("write index: {}", write_index); | 330 | // error!("write index: {}", write_index); |
| 327 | // panic!() | 331 | // panic!() |
| 328 | // } | 332 | // } |
| 329 | info!("Write first"); | ||
| 330 | 333 | ||
| 331 | // Fill up first buffer half when DMA reads the second. | 334 | // Fill up first buffer half when DMA reads the second. |
| 332 | cap / 2 - write_index | 335 | cap - write_index |
| 333 | } | 336 | } |
| 334 | } | 337 | } |
| 335 | .min(remaining); | 338 | .min(writable_length); |
| 336 | 339 | ||
| 337 | remaining_cap = self | 340 | remaining_cap = self |
| 338 | .ringbuf | 341 | .ringbuf |
| 339 | .write_exact(&mut DmaCtrlImpl(self.channel.reborrow()), buffer) | 342 | .write_exact(&mut DmaCtrlImpl(self.channel.reborrow()), buffer) |
| 340 | .await?; | 343 | .await?; |
| 341 | 344 | ||
| 342 | remaining -= len; | 345 | writable_length -= write_length; |
| 343 | } | 346 | } |
| 344 | 347 | ||
| 345 | Ok(remaining_cap) | 348 | Ok(remaining_cap) |
