aboutsummaryrefslogtreecommitdiff
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
commit277c59857bc577e8565c920861feb5b6721ac9ae (patch)
treea97a55eb5710c2ff1a34906e3723ab3f0e595d43
parentc0b8e9c7e5002a424e9ade711b085c2451a58b97 (diff)
feat: custom DMA channel configuration
See https://github.com/embassy-rs/embassy/pull/3923#issuecomment-2888810087 The default configuration of the channel which was done in `start()` is now done in `new()` this allows overriding some settings through the new `get_dma_channel` function. Only ringbuffers support this; `LinkedListTransfer` and `Transfer` do not support that yet.
-rw-r--r--embassy-stm32/src/dma/gpdma/mod.rs5
-rw-r--r--embassy-stm32/src/dma/gpdma/ringbuffered.rs28
2 files changed, 27 insertions, 6 deletions
diff --git a/embassy-stm32/src/dma/gpdma/mod.rs b/embassy-stm32/src/dma/gpdma/mod.rs
index 7c05715ee..752b39416 100644
--- a/embassy-stm32/src/dma/gpdma/mod.rs
+++ b/embassy-stm32/src/dma/gpdma/mod.rs
@@ -352,6 +352,11 @@ impl AnyChannel {
352 .store(table.transfer_count(), Ordering::Relaxed) 352 .store(table.transfer_count(), Ordering::Relaxed)
353 } 353 }
354 354
355 fn get_dma_channel(&self) -> pac::gpdma::Channel {
356 let info = self.info();
357 info.dma.ch(info.num)
358 }
359
355 fn start(&self) { 360 fn start(&self) {
356 let info = self.info(); 361 let info = self.info();
357 let ch = info.dma.ch(info.num); 362 let ch = info.dma.ch(info.num);
diff --git a/embassy-stm32/src/dma/gpdma/ringbuffered.rs b/embassy-stm32/src/dma/gpdma/ringbuffered.rs
index 4532bda57..66c4b74ec 100644
--- a/embassy-stm32/src/dma/gpdma/ringbuffered.rs
+++ b/embassy-stm32/src/dma/gpdma/ringbuffered.rs
@@ -77,6 +77,9 @@ impl<'a, W: Word> ReadableRingBuffer<'a, W> {
77 ]; 77 ];
78 let table = Table::new(items); 78 let table = Table::new(items);
79 79
80 // Apply the default configuration to the channel.
81 unsafe { channel.configure_linked_list(&table, Default::default()) };
82
80 Self { 83 Self {
81 channel, 84 channel,
82 ringbuf: ReadableDmaRingBuffer::new(buffer), 85 ringbuf: ReadableDmaRingBuffer::new(buffer),
@@ -85,14 +88,19 @@ impl<'a, W: Word> ReadableRingBuffer<'a, W> {
85 } 88 }
86 89
87 /// Start the ring buffer operation. 90 /// Start the ring buffer operation.
88 ///
89 /// You must call this after creating it for it to work.
90 pub fn start(&mut self) { 91 pub fn start(&mut self) {
91 unsafe { self.channel.configure_linked_list(&self.table, Default::default()) };
92 self.table.link(RunMode::Circular); 92 self.table.link(RunMode::Circular);
93 self.channel.start(); 93 self.channel.start();
94 } 94 }
95 95
96 /// Get a handle to the GPDMA channel for configuring the DMA.
97 ///
98 /// Usually, **this is not needed** as a default configuration is already
99 /// applied, but it may be useful to setup trigger sources, etc.
100 pub fn get_dma_channel(&mut self) -> stm32_metapac::gpdma::Channel {
101 self.channel.get_dma_channel()
102 }
103
96 /// Clear all data in the ring buffer. 104 /// Clear all data in the ring buffer.
97 pub fn clear(&mut self) { 105 pub fn clear(&mut self) {
98 self.ringbuf.reset(&mut DmaCtrlImpl(self.channel.reborrow())); 106 self.ringbuf.reset(&mut DmaCtrlImpl(self.channel.reborrow()));
@@ -226,6 +234,9 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> {
226 ]; 234 ];
227 let table = Table::new(items); 235 let table = Table::new(items);
228 236
237 // Apply the default configuration to the channel.
238 unsafe { channel.configure_linked_list(&table, Default::default()) };
239
229 let this = Self { 240 let this = Self {
230 channel, 241 channel,
231 ringbuf: WritableDmaRingBuffer::new(buffer), 242 ringbuf: WritableDmaRingBuffer::new(buffer),
@@ -236,14 +247,19 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> {
236 } 247 }
237 248
238 /// Start the ring buffer operation. 249 /// Start the ring buffer operation.
239 ///
240 /// You must call this after creating it for it to work.
241 pub fn start(&mut self) { 250 pub fn start(&mut self) {
242 unsafe { self.channel.configure_linked_list(&self.table, Default::default()) };
243 self.table.link(RunMode::Circular); 251 self.table.link(RunMode::Circular);
244 self.channel.start(); 252 self.channel.start();
245 } 253 }
246 254
255 /// Get a handle to the GPDMA channel for configuring the DMA.
256 ///
257 /// Usually, **this is not needed** as a default configuration is already
258 /// applied, but it may be useful to setup trigger sources, etc.
259 pub fn get_dma_channel(&mut self) -> stm32_metapac::gpdma::Channel {
260 self.channel.get_dma_channel()
261 }
262
247 /// Clear all data in the ring buffer. 263 /// Clear all data in the ring buffer.
248 pub fn clear(&mut self) { 264 pub fn clear(&mut self) {
249 self.ringbuf.reset(&mut DmaCtrlImpl(self.channel.reborrow())); 265 self.ringbuf.reset(&mut DmaCtrlImpl(self.channel.reborrow()));