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 | e9783ee28e9bdd89ffaeffb24bbff207c1ceb837 (patch) | |
| tree | dcf348177241127c07d5739aea33cfff968e2dde /embassy-stm32/src/dma/gpdma | |
| parent | d3718c6d4e0a8485cdef8ecf6deb05c3eff5af08 (diff) | |
fix: build
Diffstat (limited to 'embassy-stm32/src/dma/gpdma')
| -rw-r--r-- | embassy-stm32/src/dma/gpdma/linked_list.rs | 15 | ||||
| -rw-r--r-- | embassy-stm32/src/dma/gpdma/ringbuffered.rs | 100 |
2 files changed, 29 insertions, 86 deletions
diff --git a/embassy-stm32/src/dma/gpdma/linked_list.rs b/embassy-stm32/src/dma/gpdma/linked_list.rs index f494bd5f5..627da0055 100644 --- a/embassy-stm32/src/dma/gpdma/linked_list.rs +++ b/embassy-stm32/src/dma/gpdma/linked_list.rs | |||
| @@ -163,6 +163,21 @@ impl<const ITEM_COUNT: usize> Table<ITEM_COUNT> { | |||
| 163 | Self { items } | 163 | Self { items } |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | /// Create a ping-pong linked-list table. | ||
| 167 | /// | ||
| 168 | /// This uses two linked-list items, one for each half of the buffer. | ||
| 169 | pub unsafe fn new_ping_pong<W: Word>(request: Request, peri_addr: *mut W, buffer: &mut [W]) -> Table<2> { | ||
| 170 | // Buffer halves should be the same length. | ||
| 171 | let half_len = buffer.len() / 2; | ||
| 172 | assert_eq!(half_len * 2, buffer.len()); | ||
| 173 | |||
| 174 | let items = [ | ||
| 175 | LinearItem::new_read(request, peri_addr, &mut buffer[..half_len]), | ||
| 176 | LinearItem::new_read(request, peri_addr, &mut buffer[half_len..]), | ||
| 177 | ]; | ||
| 178 | Table::new(items) | ||
| 179 | } | ||
| 180 | |||
| 166 | /// Link the table as given by the run mode. | 181 | /// Link the table as given by the run mode. |
| 167 | pub fn link(&mut self, run_mode: RunMode) { | 182 | pub fn link(&mut self, run_mode: RunMode) { |
| 168 | if matches!(run_mode, RunMode::Once | RunMode::Circular) { | 183 | if matches!(run_mode, RunMode::Once | RunMode::Circular) { |
diff --git a/embassy-stm32/src/dma/gpdma/ringbuffered.rs b/embassy-stm32/src/dma/gpdma/ringbuffered.rs index 136eca1c3..2f17a0587 100644 --- a/embassy-stm32/src/dma/gpdma/ringbuffered.rs +++ b/embassy-stm32/src/dma/gpdma/ringbuffered.rs | |||
| @@ -9,7 +9,7 @@ use core::task::Waker; | |||
| 9 | use embassy_hal_internal::Peri; | 9 | use embassy_hal_internal::Peri; |
| 10 | 10 | ||
| 11 | use super::{AnyChannel, TransferOptions, STATE}; | 11 | use super::{AnyChannel, TransferOptions, STATE}; |
| 12 | use crate::dma::gpdma::linked_list::{LinearItem, RunMode, Table}; | 12 | use crate::dma::gpdma::linked_list::{RunMode, Table}; |
| 13 | use crate::dma::ringbuffer::{DmaCtrl, Error, ReadableDmaRingBuffer, WritableDmaRingBuffer}; | 13 | use crate::dma::ringbuffer::{DmaCtrl, Error, ReadableDmaRingBuffer, WritableDmaRingBuffer}; |
| 14 | use crate::dma::word::Word; | 14 | use crate::dma::word::Word; |
| 15 | use crate::dma::{Channel, Request}; | 15 | use crate::dma::{Channel, Request}; |
| @@ -48,14 +48,14 @@ impl<'a> DmaCtrl for DmaCtrlImpl<'a> { | |||
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | /// Ringbuffer for receiving data using GPDMA linked-list mode. | 50 | /// Ringbuffer for receiving data using GPDMA linked-list mode. |
| 51 | pub struct ReadableRingBuffer<'a, W: Word, const L: usize> { | 51 | pub struct ReadableRingBuffer<'a, W: Word> { |
| 52 | channel: Peri<'a, AnyChannel>, | 52 | channel: Peri<'a, AnyChannel>, |
| 53 | ringbuf: ReadableDmaRingBuffer<'a, W>, | 53 | ringbuf: ReadableDmaRingBuffer<'a, W>, |
| 54 | table: Table<L>, | 54 | table: Table<2>, |
| 55 | options: TransferOptions, | 55 | options: TransferOptions, |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | impl<'a, W: Word> ReadableRingBuffer<'a, W, 2> { | 58 | impl<'a, W: Word> ReadableRingBuffer<'a, W> { |
| 59 | /// Create a new ring buffer. | 59 | /// Create a new ring buffer. |
| 60 | /// | 60 | /// |
| 61 | /// Transfer options are applied to the individual linked list items. | 61 | /// Transfer options are applied to the individual linked list items. |
| @@ -67,28 +67,7 @@ impl<'a, W: Word> ReadableRingBuffer<'a, W, 2> { | |||
| 67 | options: TransferOptions, | 67 | options: TransferOptions, |
| 68 | ) -> Self { | 68 | ) -> Self { |
| 69 | let channel: Peri<'a, AnyChannel> = channel.into(); | 69 | let channel: Peri<'a, AnyChannel> = channel.into(); |
| 70 | let table = Self::new_ping_pong_table(request, peri_addr, buffer); | 70 | let table = Table::<2>::new_ping_pong::<W>(request, peri_addr, buffer); |
| 71 | |||
| 72 | Self { | ||
| 73 | channel, | ||
| 74 | ringbuf: ReadableDmaRingBuffer::new(buffer), | ||
| 75 | table, | ||
| 76 | options, | ||
| 77 | } | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | impl<'a, W: Word, const L: usize> ReadableRingBuffer<'a, W, L> { | ||
| 82 | /// Create a new ring buffer with a provided linked-list table. | ||
| 83 | /// | ||
| 84 | /// Transfer options are applied to the individual linked list items. | ||
| 85 | pub fn new_with_table( | ||
| 86 | channel: Peri<'a, impl Channel>, | ||
| 87 | buffer: &'a mut [W], | ||
| 88 | options: TransferOptions, | ||
| 89 | table: Table<L>, | ||
| 90 | ) -> Self { | ||
| 91 | let channel: Peri<'a, AnyChannel> = channel.into(); | ||
| 92 | 71 | ||
| 93 | Self { | 72 | Self { |
| 94 | channel, | 73 | channel, |
| @@ -98,21 +77,6 @@ impl<'a, W: Word, const L: usize> ReadableRingBuffer<'a, W, L> { | |||
| 98 | } | 77 | } |
| 99 | } | 78 | } |
| 100 | 79 | ||
| 101 | /// Create a new simple linked-list table. | ||
| 102 | /// | ||
| 103 | /// This uses two linked-list items, one for each half of the buffer. | ||
| 104 | pub unsafe fn new_ping_pong_table(request: Request, peri_addr: *mut W, buffer: &mut [W]) -> Table<2> { | ||
| 105 | // Buffer halves should be the same length. | ||
| 106 | let half_len = buffer.len() / 2; | ||
| 107 | assert_eq!(half_len * 2, buffer.len()); | ||
| 108 | |||
| 109 | let items = [ | ||
| 110 | LinearItem::new_read(request, peri_addr, &mut buffer[..half_len]), | ||
| 111 | LinearItem::new_read(request, peri_addr, &mut buffer[half_len..]), | ||
| 112 | ]; | ||
| 113 | Table::new(items) | ||
| 114 | } | ||
| 115 | |||
| 116 | /// Start the ring buffer operation. | 80 | /// Start the ring buffer operation. |
| 117 | pub fn start(&mut self) { | 81 | pub fn start(&mut self) { |
| 118 | // Apply the default configuration to the channel. | 82 | // Apply the default configuration to the channel. |
| @@ -172,7 +136,7 @@ impl<'a, W: Word, const L: usize> ReadableRingBuffer<'a, W, L> { | |||
| 172 | /// To resume the transfer, call [`request_resume`](Self::request_resume) again. | 136 | /// To resume the transfer, call [`request_resume`](Self::request_resume) again. |
| 173 | /// | 137 | /// |
| 174 | /// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false. | 138 | /// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false. |
| 175 | pub fn request_suspend(&mut self) { | 139 | pub fn request_pause(&mut self) { |
| 176 | self.channel.request_suspend() | 140 | self.channel.request_suspend() |
| 177 | } | 141 | } |
| 178 | 142 | ||
| @@ -216,9 +180,9 @@ impl<'a, W: Word, const L: usize> ReadableRingBuffer<'a, W, L> { | |||
| 216 | } | 180 | } |
| 217 | } | 181 | } |
| 218 | 182 | ||
| 219 | impl<'a, W: Word, const L: usize> Drop for ReadableRingBuffer<'a, W, L> { | 183 | impl<'a, W: Word> Drop for ReadableRingBuffer<'a, W> { |
| 220 | fn drop(&mut self) { | 184 | fn drop(&mut self) { |
| 221 | self.request_suspend(); | 185 | self.request_pause(); |
| 222 | while self.is_running() {} | 186 | while self.is_running() {} |
| 223 | 187 | ||
| 224 | // "Subsequent reads and writes cannot be moved ahead of preceding reads." | 188 | // "Subsequent reads and writes cannot be moved ahead of preceding reads." |
| @@ -227,14 +191,14 @@ impl<'a, W: Word, const L: usize> Drop for ReadableRingBuffer<'a, W, L> { | |||
| 227 | } | 191 | } |
| 228 | 192 | ||
| 229 | /// Ringbuffer for writing data using GPDMA linked-list mode. | 193 | /// Ringbuffer for writing data using GPDMA linked-list mode. |
| 230 | pub struct WritableRingBuffer<'a, W: Word, const L: usize> { | 194 | pub struct WritableRingBuffer<'a, W: Word> { |
| 231 | channel: Peri<'a, AnyChannel>, | 195 | channel: Peri<'a, AnyChannel>, |
| 232 | ringbuf: WritableDmaRingBuffer<'a, W>, | 196 | ringbuf: WritableDmaRingBuffer<'a, W>, |
| 233 | table: Table<L>, | 197 | table: Table<2>, |
| 234 | options: TransferOptions, | 198 | options: TransferOptions, |
| 235 | } | 199 | } |
| 236 | 200 | ||
| 237 | impl<'a, W: Word> WritableRingBuffer<'a, W, 2> { | 201 | impl<'a, W: Word> WritableRingBuffer<'a, W> { |
| 238 | /// Create a new ring buffer. | 202 | /// Create a new ring buffer. |
| 239 | /// | 203 | /// |
| 240 | /// Transfer options are applied to the individual linked list items. | 204 | /// Transfer options are applied to the individual linked list items. |
| @@ -246,7 +210,7 @@ impl<'a, W: Word> WritableRingBuffer<'a, W, 2> { | |||
| 246 | options: TransferOptions, | 210 | options: TransferOptions, |
| 247 | ) -> Self { | 211 | ) -> Self { |
| 248 | let channel: Peri<'a, AnyChannel> = channel.into(); | 212 | let channel: Peri<'a, AnyChannel> = channel.into(); |
| 249 | let table = Self::new_ping_pong_table(request, peri_addr, buffer); | 213 | let table = Table::<2>::new_ping_pong::<W>(request, peri_addr, buffer); |
| 250 | 214 | ||
| 251 | Self { | 215 | Self { |
| 252 | channel, | 216 | channel, |
| @@ -255,42 +219,6 @@ impl<'a, W: Word> WritableRingBuffer<'a, W, 2> { | |||
| 255 | options, | 219 | options, |
| 256 | } | 220 | } |
| 257 | } | 221 | } |
| 258 | } | ||
| 259 | |||
| 260 | impl<'a, W: Word, const L: usize> WritableRingBuffer<'a, W, L> { | ||
| 261 | /// Create a new ring buffer with a provided linked-list table. | ||
| 262 | /// | ||
| 263 | /// Transfer options are applied to the individual linked list items. | ||
| 264 | pub fn new_with_table( | ||
| 265 | channel: Peri<'a, impl Channel>, | ||
| 266 | buffer: &'a mut [W], | ||
| 267 | options: TransferOptions, | ||
| 268 | table: Table<L>, | ||
| 269 | ) -> Self { | ||
| 270 | let channel: Peri<'a, AnyChannel> = channel.into(); | ||
| 271 | |||
| 272 | Self { | ||
| 273 | channel, | ||
| 274 | ringbuf: WritableDmaRingBuffer::new(buffer), | ||
| 275 | table, | ||
| 276 | options, | ||
| 277 | } | ||
| 278 | } | ||
| 279 | |||
| 280 | /// Create a new simple linked-list table. | ||
| 281 | /// | ||
| 282 | /// This uses two linked-list items, one for each half of the buffer. | ||
| 283 | pub unsafe fn new_ping_pong_table(request: Request, peri_addr: *mut W, buffer: &[W]) -> Table<2> { | ||
| 284 | // Buffer halves should be the same length. | ||
| 285 | let half_len = buffer.len() / 2; | ||
| 286 | assert_eq!(half_len * 2, buffer.len()); | ||
| 287 | |||
| 288 | let items = [ | ||
| 289 | LinearItem::new_write(request, &buffer[..half_len], peri_addr), | ||
| 290 | LinearItem::new_write(request, &buffer[half_len..], peri_addr), | ||
| 291 | ]; | ||
| 292 | Table::new(items) | ||
| 293 | } | ||
| 294 | 222 | ||
| 295 | /// Start the ring buffer operation. | 223 | /// Start the ring buffer operation. |
| 296 | pub fn start(&mut self) { | 224 | pub fn start(&mut self) { |
| @@ -351,7 +279,7 @@ impl<'a, W: Word, const L: usize> WritableRingBuffer<'a, W, L> { | |||
| 351 | /// To resume the transfer, call [`request_resume`](Self::request_resume) again. | 279 | /// To resume the transfer, call [`request_resume`](Self::request_resume) again. |
| 352 | /// | 280 | /// |
| 353 | /// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false. | 281 | /// This doesn't immediately stop the transfer, you have to wait until [`is_running`](Self::is_running) returns false. |
| 354 | pub fn request_suspend(&mut self) { | 282 | pub fn request_pause(&mut self) { |
| 355 | self.channel.request_suspend() | 283 | self.channel.request_suspend() |
| 356 | } | 284 | } |
| 357 | 285 | ||
| @@ -395,7 +323,7 @@ impl<'a, W: Word, const L: usize> WritableRingBuffer<'a, W, L> { | |||
| 395 | } | 323 | } |
| 396 | } | 324 | } |
| 397 | 325 | ||
| 398 | impl<'a, W: Word, const L: usize> Drop for WritableRingBuffer<'a, W, L> { | 326 | impl<'a, W: Word> Drop for WritableRingBuffer<'a, W> { |
| 399 | fn drop(&mut self) { | 327 | fn drop(&mut self) { |
| 400 | self.request_suspend(); | 328 | self.request_suspend(); |
| 401 | while self.is_running() {} | 329 | while self.is_running() {} |
