1use super::{
4 config,
5 traits::sealed::{Bits, Sealed},
6 traits::*,
7 DmaDirection,
8};
9use core::marker::PhantomData;
10
11use crate::rcc::Rcc;
12use crate::stm32;
13
14use stm32::{DMA1, DMA2, DMAMUX};
15
16use crate::dma::config::DmaConfig;
17use core::ops::Deref;
18
19impl Sealed for DMA1 {}
20impl Sealed for DMA2 {}
21
22pub type DMARegisterBlock = stm32::dma1::RegisterBlock;
24pub type DMAMUXRegisterBlock = stm32::dmamux::RegisterBlock;
25
26pub trait Instance: Deref<Target = DMARegisterBlock> + Sealed {
28 fn ptr() -> *const DMARegisterBlock;
30
31 fn mux_ptr() -> *const DMAMUXRegisterBlock;
33}
34
35impl Instance for DMA1 {
36 #[inline(always)]
37 fn ptr() -> *const DMARegisterBlock {
38 DMA1::ptr()
39 }
40
41 #[inline(always)]
42 fn mux_ptr() -> *const DMAMUXRegisterBlock {
43 DMAMUX::ptr()
44 }
45}
46
47impl Instance for DMA2 {
48 #[inline(always)]
49 fn ptr() -> *const DMARegisterBlock {
50 DMA2::ptr()
51 }
52
53 #[inline(always)]
54 fn mux_ptr() -> *const DMAMUXRegisterBlock {
55 DMAMUX::ptr()
56 }
57}
58
59#[derive(Debug, Clone, Copy)]
61pub struct DmaInterrupts {
62 transfer_complete: bool,
63 transfer_error: bool,
64 half_transfer: bool,
65}
66
67pub struct Stream0<DMA> {
69 _dma: PhantomData<DMA>,
70}
71pub struct Stream1<DMA> {
73 _dma: PhantomData<DMA>,
74}
75pub struct Stream2<DMA> {
77 _dma: PhantomData<DMA>,
78}
79pub struct Stream3<DMA> {
81 _dma: PhantomData<DMA>,
82}
83pub struct Stream4<DMA> {
85 _dma: PhantomData<DMA>,
86}
87pub struct Stream5<DMA> {
89 _dma: PhantomData<DMA>,
90}
91pub struct Stream6<DMA> {
93 _dma: PhantomData<DMA>,
94}
95pub struct Stream7<DMA> {
97 _dma: PhantomData<DMA>,
98}
99
100impl<DMA> Sealed for Stream0<DMA> {}
101impl<DMA> Sealed for Stream1<DMA> {}
102impl<DMA> Sealed for Stream2<DMA> {}
103impl<DMA> Sealed for Stream3<DMA> {}
104impl<DMA> Sealed for Stream4<DMA> {}
105impl<DMA> Sealed for Stream5<DMA> {}
106impl<DMA> Sealed for Stream6<DMA> {}
107impl<DMA> Sealed for Stream7<DMA> {}
108
109pub struct StreamsTuple<T>(
111 pub Stream0<T>,
112 pub Stream1<T>,
113 pub Stream2<T>,
114 pub Stream3<T>,
115 pub Stream4<T>,
116 pub Stream5<T>,
117 #[cfg(not(any(feature = "stm32g431", feature = "stm32g441",)))] pub Stream6<T>,
118 #[cfg(not(any(feature = "stm32g431", feature = "stm32g441",)))] pub Stream7<T>,
119);
120
121pub trait DMAExt<I> {
122 fn split(self, rcc: &Rcc) -> StreamsTuple<I>;
123}
124
125impl DMAExt<Self> for DMA1 {
126 fn split(self, rcc: &Rcc) -> StreamsTuple<DMA1> {
127 if !rcc.rb.ahb1enr.read().dmamuxen().bit_is_set() {
129 rcc.rb.ahb1enr.modify(|_, w| w.dmamuxen().set_bit());
131 }
132
133 rcc.rb.ahb1enr.modify(|_, w| w.dma1en().set_bit());
135
136 StreamsTuple::new(self)
137 }
138}
139
140impl DMAExt<Self> for DMA2 {
141 fn split(self, rcc: &Rcc) -> StreamsTuple<DMA2> {
142 if !rcc.rb.ahb1enr.read().dmamuxen().bit_is_set() {
144 rcc.rb.ahb1enr.modify(|_, w| w.dmamuxen().set_bit());
146 }
147
148 rcc.rb.ahb1enr.modify(|_, w| w.dma2en().set_bit());
150
151 StreamsTuple::new(self)
152 }
153}
154
155impl<I: Instance> StreamsTuple<I> {
156 pub(crate) fn new(_regs: I) -> Self {
158 Self(
159 Stream0 { _dma: PhantomData },
160 Stream1 { _dma: PhantomData },
161 Stream2 { _dma: PhantomData },
162 Stream3 { _dma: PhantomData },
163 Stream4 { _dma: PhantomData },
164 Stream5 { _dma: PhantomData },
165 #[cfg(not(any(feature = "stm32g431", feature = "stm32g441",)))]
166 Stream6 { _dma: PhantomData },
167 #[cfg(not(any(feature = "stm32g431", feature = "stm32g441",)))]
168 Stream7 { _dma: PhantomData },
169 )
170 }
171}
172
173macro_rules! dma_stream {
178 ($(($name:ident, $number:expr,
179 regs => $ccr:ident, $cparX:ident, $cmarX:ident, $cndtrX:ident,
180 fields => $tcif:ident, $htif:ident, $teif:ident, $gif:ident, $tcisr:ident, $htisr:ident, $teisr:ident, $gisr:ident,
181 dmamux => $cXcr:ident,)
182 ),+$(,)*) => {
183 $(
184 impl<I: Instance> Stream for $name<I> {
185
186 const NUMBER: usize = $number;
187 type Config = DmaConfig;
188 type Interrupts = DmaInterrupts;
189
190 fn apply_config(&mut self, config: DmaConfig) {
191 self.set_priority(config.priority);
192 self.set_memory_increment(config.memory_increment);
193 self.set_peripheral_increment(config.peripheral_increment);
194 self.set_circular_buffer(config.circular_buffer);
195 self.set_transfer_complete_interrupt_enable(
196 config.transfer_complete_interrupt
197 );
198 self.set_half_transfer_interrupt_enable(config.half_transfer_interrupt);
199 self.set_transfer_error_interrupt_enable(
200 config.transfer_error_interrupt
201 );
202 }
203
204 #[inline(always)]
205 fn clear_interrupts(&mut self) {
206 let dma = unsafe { &*I::ptr() };
209 dma.ifcr.write(|w| w
210 .$tcif().set_bit() .$htif().set_bit() .$teif().set_bit() .$gif().set_bit() );
215 let _ = dma.isr.read();
216 let _ = dma.isr.read(); }
218
219 #[inline(always)]
220 fn clear_transfer_complete_flag(&mut self) {
221 let dma = unsafe { &*I::ptr() };
224 dma.ifcr.write(|w| w.$tcif().set_bit());
225 }
226
227 #[inline(always)]
228 fn clear_transfer_complete_interrupt(&mut self) {
229 self.clear_transfer_complete_flag();
230 let dma = unsafe { &*I::ptr() };
232 let _ = dma.isr.read();
233 let _ = dma.isr.read(); }
235
236 #[inline(always)]
237 fn clear_transfer_error_interrupt(&mut self) {
238 let dma = unsafe { &*I::ptr() };
241 dma.ifcr.write(|w| w.$teif().set_bit());
242 let _ = dma.isr.read();
243 let _ = dma.isr.read(); }
245
246 #[inline(always)]
247 fn get_transfer_complete_flag() -> bool {
248 let dma = unsafe { &*I::ptr() };
250 dma.isr.read().$tcisr().bit_is_set()
251 }
252
253 #[inline(always)]
254 unsafe fn enable(&mut self) {
255 let dma = &*I::ptr();
257 dma.$ccr.modify(|_, w| w.en().set_bit());
258 }
259
260 #[inline(always)]
261 fn is_enabled() -> bool {
262 let dma = unsafe { &*I::ptr() };
264 dma.$ccr.read().en().bit_is_set()
265 }
266
267 fn disable(&mut self) {
268 if Self::is_enabled() {
269 let dma = unsafe { &*I::ptr() };
271
272 let interrupts = Self::get_interrupts_enable();
275 self.disable_interrupts();
276
277 dma.$ccr.modify(|_, w| w.en().clear_bit());
278 while Self::is_enabled() {}
279
280 self.clear_interrupts();
281 self.enable_interrupts(interrupts);
282 }
283 }
284
285 #[inline(always)]
286 fn set_request_line(&mut self, request_line: u8) {
287 let dmamux = unsafe { &*I::mux_ptr() };
289 unsafe {
290 dmamux.$cXcr
291 .modify(|_, w| w.dmareq_id().bits(request_line));
292 }
293 }
294
295 #[inline(always)]
296 fn set_priority(&mut self, priority: config::Priority) {
297 let dma = unsafe { &*I::ptr() };
299 dma.$ccr.modify(|_, w| unsafe { w.pl().bits(priority.bits()) });
300 }
301
302 #[inline(always)]
303 fn disable_interrupts(&mut self) {
304 let dmacr = &unsafe { &*I::ptr() }.$ccr;
306 dmacr.modify(|_, w| w
307 .tcie().clear_bit()
308 .teie().clear_bit()
309 .htie().clear_bit());
310 let _ = dmacr.read();
311 let _ = dmacr.read(); }
313
314 #[inline(always)]
315 fn enable_interrupts(&mut self, interrupt: Self::Interrupts) {
316 let dma = unsafe { &*I::ptr() };
318 dma.$ccr.modify(|_, w| w
319 .tcie().bit(interrupt.transfer_complete)
320 .teie().bit(interrupt.transfer_error)
321 .htie().bit(interrupt.half_transfer)
322 );
323 }
324
325 #[inline(always)]
326 fn get_interrupts_enable() -> Self::Interrupts {
327 let dma = unsafe { &*I::ptr() };
329 let cr = dma.$ccr.read();
330
331 DmaInterrupts {
332 transfer_complete: cr.tcie().bit_is_set(),
333 half_transfer: cr.htie().bit_is_set(),
334 transfer_error: cr.teie().bit_is_set()
335 }
336 }
337
338
339 #[inline(always)]
340 fn set_transfer_complete_interrupt_enable(&mut self, transfer_complete_interrupt: bool) {
341 let dmacr = &unsafe { &*I::ptr() }.$ccr;
343 dmacr.modify(|_, w| w.tcie().bit(transfer_complete_interrupt));
344 let _ = dmacr.read();
345 let _ = dmacr.read(); }
347
348 #[inline(always)]
349 fn set_transfer_error_interrupt_enable(&mut self, transfer_error_interrupt: bool) {
350 let dmacr = &unsafe { &*I::ptr() }.$ccr;
352 dmacr.modify(|_, w| w.teie().bit(transfer_error_interrupt));
353 let _ = dmacr.read();
354 let _ = dmacr.read(); }
356
357 #[inline(always)]
358 fn set_half_transfer_interrupt_enable(&mut self, half_transfer_interrupt: bool) {
359 let dmacr = &unsafe { &*I::ptr() }.$ccr;
361 dmacr.modify(|_, w| w.htie().bit(half_transfer_interrupt));
362 let _ = dmacr.read();
363 let _ = dmacr.read(); }
365
366 #[inline(always)]
367 fn get_half_transfer_flag() -> bool {
368 let dma = unsafe { &*I::ptr() };
370 dma.isr.read().$htisr().bit_is_set()
371 }
372
373 #[inline(always)]
374 fn clear_half_transfer_interrupt(&mut self) {
375 let dma = unsafe { &*I::ptr() };
378 dma.ifcr.write(|w| w.$htif().set_bit());
379 let _ = dma.isr.read();
380 let _ = dma.isr.read(); }
382
383 #[inline(always)]
384 unsafe fn set_peripheral_address(&mut self, value: u32) {
385 let dma = &*I::ptr();
387 dma.$cparX.write(|w| w.pa().bits(value));
388 }
389
390 #[inline(always)]
391 unsafe fn set_memory_address(&mut self, value: u32) {
392 let dma = &*I::ptr();
394 dma.$cmarX.write(|w| w.ma().bits(value) );
395 }
396
397 #[inline(always)]
398 fn get_memory_address(&self) -> u32 {
399 let dma = unsafe { &*I::ptr() };
401 dma.$cmarX.read().ma().bits()
402 }
403
404 #[inline(always)]
405 fn set_number_of_transfers(&mut self, value: u16) {
406 let dma = unsafe { &*I::ptr() };
408 dma.$cndtrX.write(|w| unsafe {w.ndt().bits(value) });
409 }
410
411 #[inline(always)]
412 fn get_number_of_transfers() -> u16 {
413 let dma = unsafe { &*I::ptr() };
415 dma.$cndtrX.read().ndt().bits()
416 }
417 #[inline(always)]
418 unsafe fn set_memory_size(&mut self, size: u8) {
419 let dma = &*I::ptr();
421 dma.$ccr.modify(|_, w| w.msize().bits(size));
422 }
423
424 #[inline(always)]
425 unsafe fn set_peripheral_size(&mut self, size: u8) {
426 let dma = &*I::ptr();
428 dma.$ccr.modify(|_, w| w.psize().bits(size));
429 }
430
431 #[inline(always)]
432 fn set_memory_increment(&mut self, increment: bool) {
433 let dma = unsafe { &*I::ptr() };
435 dma.$ccr.modify(|_, w| w.minc().bit(increment));
436 }
437
438 #[inline(always)]
439 fn set_peripheral_increment(&mut self, increment: bool) {
440 let dma = unsafe { &*I::ptr() };
442 dma.$ccr.modify(|_, w| w.pinc().bit(increment));
443 }
444
445 #[inline(always)]
446 fn set_direction(&mut self, direction: DmaDirection) {
447 let dma = unsafe { &*I::ptr() };
449 dma.$ccr.modify(|_, w| {
450 match direction {
451 DmaDirection::PeripheralToMemory =>
452 w.dir().clear_bit().mem2mem().clear_bit(),
453 DmaDirection::MemoryToPeripheral =>
454 w.dir().set_bit().mem2mem().clear_bit(),
455 DmaDirection::MemoryToMemory =>
456 w.mem2mem().set_bit().dir().clear_bit(),
457 }
458 });
459 }
460
461 #[inline(always)]
462 fn set_circular_buffer(&mut self, circular_buffer: bool) {
463 let dma = unsafe { &*I::ptr() };
465 dma.$ccr.modify(|_, w| w.circ().bit(circular_buffer));
466 }
467 }
468
469 impl<I: Instance> $name<I> {
470 #[inline(always)]
471 pub fn clear_half_transfer_interrupt(&mut self) {
472 let dma = unsafe { &*I::ptr() };
475 dma.ifcr.write(|w| w.$htif().set_bit());
476 let _ = dma.isr.read();
477 let _ = dma.isr.read(); }
479
480 #[inline(always)]
481 pub fn get_half_transfer_flag() -> bool {
482 let dma = unsafe { &*I::ptr() };
484 dma.isr.read().$htisr().bit_is_set()
485 }
486
487 #[inline(always)]
488 pub fn set_half_transfer_interrupt_enable(&mut self, half_transfer_interrupt: bool) {
489 let dmacr = &unsafe { &*I::ptr() }.$ccr;
491 dmacr.modify(|_, w| w.htie().bit(half_transfer_interrupt));
492 let _ = dmacr.read();
493 let _ = dmacr.read(); }
495 }
496 )+
497 };
498}
499
500dma_stream!(
501 (
504 Stream0, 0,
505 regs => ccr1, cpar1, cmar1, cndtr1,
506 fields => tcif1, htif1, teif1, gif1, tcif1, htif1, teif1, gif1,
507 dmamux => c0cr,
508 ),
509 (
510 Stream1, 1,
511 regs => ccr2, cpar2, cmar2, cndtr2,
512 fields => tcif2, htif2, teif2, gif2, tcif2, htif2, teif2, gif2,
513 dmamux => c1cr,
514 ),
515 (
516 Stream2, 2,
517 regs => ccr3, cpar3, cmar3, cndtr3,
518 fields => tcif3, htif3, teif3, gif3, tcif3, htif3, teif3, gif3,
519 dmamux => c2cr,
520 ),
521 (
522 Stream3, 3,
523 regs => ccr4, cpar4, cmar4, cndtr4,
524 fields => tcif4, htif4, teif4, gif4, tcif4, htif4, teif4, gif4,
525 dmamux => c3cr,
526 ),
527 (
528 Stream4, 4,
529 regs => ccr5, cpar5, cmar5, cndtr5,
530 fields => tcif5, htif5, teif5, gif5, tcif5, htif5, teif5, gif5,
531 dmamux => c4cr,
532 ),
533 (
534 Stream5, 5,
535 regs => ccr6, cpar6, cmar6, cndtr6,
536 fields => tcif6, htif6, teif6, gif6, tcif6, htif6, teif6, gif6,
537 dmamux => c5cr,
538 ),
539 (
540 Stream6, 6,
541 regs => ccr7, cpar7, cmar7, cndtr7,
542 fields => tcif7, htif7, teif7, gif7, tcif7, htif7, teif7, gif7,
543 dmamux => c6cr,
544 ),
545 (
546 Stream7, 7,
547 regs => ccr8, cpar8, cmar8, cndtr8,
548 fields => tcif8, htif8, teif8, gif8, tcif8, htif8, teif8, gif8,
549 dmamux => c7cr,
550 ),
551);