1use core::{
5 ops::Deref,
6 sync::atomic::{self, Ordering},
7};
8
9use cfg_if::cfg_if;
10
11use crate::{
12 error::{Error, Result},
13 pac::RCC,
14 util::bounded_loop,
15};
16
17cfg_if! {
18 if #[cfg(any(
19 feature = "f3x4",
20 feature = "f301",
21 all(feature = "g0", not(any(feature = "g0b0", feature = "g0b1", feature = "g0c1")))
22 ))] {
23 use crate::{pac::{dma1, DMA1}, util::rcc_en_reset};
24 } else if #[cfg(feature = "c0")] { use crate::{pac::{dma as dma1, DMA as DMA1}, util::rcc_en_reset};
26 } else {
27 use crate::{pac::{dma1, dma2, DMA1, DMA2}, util::rcc_en_reset};
28 }
29}
30#[cfg(any(feature = "g0", feature = "g4", feature = "wl"))]
33use crate::pac::DMAMUX;
34#[cfg(any(feature = "l5", feature = "wb", feature = "h7"))]
36use crate::pac::DMAMUX1 as DMAMUX;
37#[cfg(feature = "h7")]
38use crate::pac::DMAMUX2;
39
40#[non_exhaustive]
44#[cfg_attr(feature = "defmt", derive(defmt::Format))]
45#[derive(Debug, Clone, Copy, Eq, PartialEq)]
46pub enum DmaError {
47 TransferError,
48 #[cfg(any(feature = "h7", feature = "f4"))]
49 FifoError,
50 #[cfg(any(feature = "h7", feature = "f4"))]
51 DirectModeError,
52}
53
54#[derive(Clone, Copy)]
55pub enum DmaPeriph {
56 Dma1,
57 #[cfg(dma2)]
58 Dma2,
59}
60
61#[derive(Copy, Clone)]
62#[repr(usize)]
63#[cfg(not(any(feature = "h7", feature = "wl", feature = "wb", feature = "g0")))]
64pub enum DmaInput {
67 Adc1 = 5,
70 Dac1Ch1 = 6,
71 Dac1Ch2 = 7,
72 Tim6Up = 8,
73 Tim7Up = 9,
74 Spi1Rx = 10,
75 Spi1Tx = 11,
76 Spi2Rx = 12,
77 Spi2Tx = 13,
78 Spi3Rx = 14,
79 Spi3Tx = 15,
80 I2c1Rx = 16,
81 I2c1Tx = 17,
82 I2c2Rx = 18,
83 I2c2Tx = 19,
84 I2c3Rx = 20,
85 I2c3Tx = 21,
86 I2c4Rx = 22,
87 I2c4Tx = 23,
88 Usart1Rx = 24,
89 Usart1Tx = 25,
90 Usart2Rx = 26,
91 Usart2Tx = 27,
92 Usart3Rx = 28,
93 Usart3Tx = 29,
94 Uart4Rx = 30,
95 Uart4Tx = 31,
96 Uart5Rx = 32,
97 Uart5Tx = 33,
98 Lpuart1Rx = 34,
99 Lpuart1Tx = 35,
100 Adc2 = 36,
101 Adc3 = 37,
102 Adc4 = 38,
103 Adc5 = 39,
104 Quadspi = 40,
105 Dac2Ch1 = 41,
106 Tim1Ch1 = 42,
107 Tim1Ch2 = 43,
108 Tim1Ch3 = 44,
109 Tim1Ch4 = 45,
110 TimUp = 46,
111 Tim1Trig = 47,
112 Tim1Com = 48,
113 Tim8Ch1 = 49,
114 Tim8Ch2 = 50,
115 Tim8Ch3 = 51,
116 Tim8Ch4 = 52,
117 Tim8Up = 53,
118 Tim8Trig = 54,
119 Tim8Com = 55,
120 Tim2Ch1 = 56,
121 Tim2Ch2 = 57,
122 Tim2Ch3 = 58,
123 Tim2Ch4 = 59,
124 Tim2Up = 60,
125 Tim3Ch1 = 61,
126 Tim3Ch2 = 62,
127 Tim3Ch3 = 63,
128 Tim3Ch4 = 64,
129 Tim3Up = 65,
130 Tim3Trig = 66,
131 Tim4Ch1 = 67,
132 Tim4Ch2 = 68,
133 Tim4Ch3 = 69,
134 Tim4Ch4 = 70,
135 Tim4Up = 71,
136 Sai1A = 108,
137 Sai1B = 109,
138 Sai2A = 203,
140 Sai2B = 204,
141 Dfsdm1F0 = 200,
143 Dfsdm1F1 = 201,
144 Dfsdm1F2 = 205,
145 Dfsdm1F3 = 206,
146}
147
148#[derive(Copy, Clone)]
149#[repr(usize)]
150#[cfg(feature = "g0")]
151pub enum DmaInput {
154 Adc = 5,
155 AesIn = 6,
156 AesOut = 7,
157 Dac1Ch1 = 8,
158 Dac1Ch2 = 9,
159 I2c1Rx = 10,
160 I2c1Tx = 11,
161 I2c2Rx = 12,
162 I2c2Tx = 13,
163 Lpuart1Rx = 14,
164 Lpuart1Tx = 15,
165 Spi1Rx = 16,
166 Spi1Tx = 17,
167 Spi2Rx = 18,
168 Spi2Tx = 19,
169 Tim1Ch1 = 20,
170 Tim1Ch2 = 21,
171 Tim1Ch3 = 22,
172 Tim1Ch4 = 23,
173 Tim1TrigCom = 24,
174 Tim1Up = 25,
175 Tim2Ch1 = 26,
176 Tim2Ch2 = 27,
177 Tim2Ch3 = 28,
178 Tim2Ch4 = 29,
179 Tim2Trig = 30,
180 Tim2Up = 31,
181 Tim3Ch1 = 32,
182 Tim3Ch2 = 33,
183 Tim3Ch3 = 34,
184 Tim3Ch4 = 35,
185 Tim3Trig = 36,
186 Tim3Up = 37,
187 Tim6Up = 38,
188 Tim7Up = 39,
189 Tim15Ch1 = 40,
190 Tim15Ch2 = 41,
191 Tim15TrigCom = 42,
192 Tim15Up = 43,
193 Tim16Ch1 = 44,
194 Tim16Com = 45,
195 Tim16Up = 46,
196 Tim17Ch1 = 47,
197 Tim17Com = 48,
198 Tim17Up = 49,
199 Usart1Rx = 50,
200 Usart1Tx = 51,
201 Usart2Rx = 52,
202 Usart2Tx = 53,
203 Usart3Rx = 54,
204 Usart3Tx = 55,
205 Usart4Rx = 56,
206 Usart4Tx = 57,
207 Ucpd1Rx = 58,
208 Ucpd1Tx = 59,
209 Ucpd2Rx = 60,
210 Ucpd2Tx = 61,
211 I2c3Rx = 62,
212 I2c3Tx = 63,
213 Lpuart2Rx = 64,
214 Lpuart2Tx = 65,
215 Spi3Rx = 66,
216 Spi3Tx = 67,
217 Tim4Ch1 = 68,
218 Tim4Ch2 = 69,
219 Tim4Ch3 = 70,
220 Tim4Ch4 = 71,
221 Tim4Trig = 72,
222 Tim4Up = 73,
223 Usart5Rx = 74,
224 Usart5Tx = 75,
225 Usart6Rx = 76,
226 Usart6Tx = 77,
227}
228
229#[derive(Copy, Clone)]
230#[repr(usize)]
231#[cfg(feature = "wl")]
232pub enum DmaInput {
234 Adc = 5,
235 DacOut1 = 6,
236 Spi1Rx = 7,
238 Spi1Tx = 8,
239 Spi2Rx = 9,
240 Spi2Tx = 10,
241 I2c1Rx = 11,
242 I2c1Tx = 12,
243 I2c2Rx = 13,
244 I2c2Tx = 14,
245 I2c3Rx = 15,
246 I2c3Tx = 16,
247 Usart1Rx = 17,
248 Usart1Tx = 18,
249 Usart2Rx = 19,
250 Usart2Tx = 20,
251 Lpuart1Rx = 21,
252 Lpuart1Tx = 22,
253 Tim1Ch1 = 23,
254 Tim1Ch2 = 24,
255 Tim1Ch3 = 25,
256 Tim1Ch4 = 26,
257 TimUp = 27,
258 Tim1Trig = 28,
259 Tim1Com = 29,
260 Tim2Ch1 = 30,
261 Tim2Ch2 = 31,
262 Tim2Ch3 = 32,
263 Tim2Ch4 = 33,
264 Tim2Up = 34,
265 Tim16Ch1 = 35,
266 Tim16Up = 36,
267 Tim17Ch1 = 37,
268 Tim17Up = 38,
269 AesIn = 39,
270 AesOut = 40,
271 SubghzSpiRx = 41,
272 SubghzSpiTx = 42,
273}
274
275#[derive(Copy, Clone)]
276#[repr(usize)]
277#[cfg(feature = "wb")]
278pub enum DmaInput {
280 Adc1 = 5,
281 Spi1Rx = 6,
282 Spi1Tx = 7,
283 Spi2Rx = 8,
284 Spi2Tx = 9,
285 I2c1Rx = 10,
286 I2c1Tx = 11,
287 I2c3Rx = 12,
288 I2c3Tx = 13,
289 Usart1Rx = 14,
290 Usart1Tx = 15,
291 Lpuart1Rx = 16,
292 Lpuart1Tx = 17,
293 Sai1A = 18,
294 Sai1B = 19,
295 Quadspi = 20,
296 Tim1Ch1 = 21,
297 Tim1Ch2 = 22,
298 Tim1Ch3 = 23,
299 Tim1Ch4 = 24,
300 TimUp = 25,
301 Tim1Trig = 26,
302 Tim1Com = 27,
303 Tim2Ch1 = 28,
304 Tim2Ch2 = 29,
305 Tim2Ch3 = 30,
306 Tim2Ch4 = 31,
307 Tim2Up = 32,
308 Tim16Ch1 = 33,
309 Tim16Up = 34,
310 Tim17Ch1 = 35,
311 Tim17Up = 36,
312 Aes1In = 37,
313 Aes1Out = 38,
314 Aes2In = 39,
315 Aes2Out = 40,
316}
317
318#[derive(Copy, Clone)]
321#[repr(usize)]
322#[cfg(feature = "h7")]
323pub enum DmaInput {
328 Adc1 = 9,
329 Adc2 = 10,
330 Tim1Ch1 = 11,
331 Tim1Ch2 = 12,
332 Tim1Ch3 = 13,
333 Tim1Ch4 = 14,
334 Tim1Up = 15,
335 Tim1Trig = 16,
336 Tim1Com = 17,
337 Tim2Ch1 = 18,
338 Tim2Ch2 = 19,
339 Tim2Ch3 = 20,
340 Tim2Ch4 = 21,
341 Tim2Up = 22,
342 Tim3Ch1 = 23,
343 Tim3Ch2 = 24,
344 Tim3Ch3 = 25,
345 Tim3Ch4 = 26,
346 Tim3Up = 27,
347 Tim3Trig = 28,
348 Tim4Ch1 = 29,
349 Tim4Ch2 = 30,
350 Tim4Ch3 = 31,
351 Tim4Up = 32,
352 I2c1Rx = 33,
353 I2c1Tx = 34,
354 I2c2Rx = 35,
355 I2c2Tx = 36,
356 Spi1Rx = 37,
357 Spi1Tx = 38,
358 Spi2Rx = 39,
359 Spi2Tx = 40,
360 Usart1Rx = 41,
361 Usart1Tx = 42,
362 Usart2Rx = 43,
363 Usart2Tx = 44,
364 Usart3Rx = 45,
365 Usart3Tx = 46,
366 Tim8Ch1 = 47,
367 Tim8Ch2 = 48,
368 Tim8Ch3 = 49,
369 Tim8Ch4 = 50,
370 Tim8Up = 51,
371 Tim8Trig = 52,
372 Tim8Com = 53,
373 Tim5Ch1 = 55,
374 Tim5Ch2 = 56,
375 Tim5Ch3 = 57,
376 Tim5Ch4 = 58,
377 Tim5Up = 59,
378 Tim5Trig = 60,
379 Spi3Rx = 61,
380 Spi3Tx = 62,
381 Uart4Rx = 63,
382 Uart4Tx = 64,
383 Uart5Rx = 65,
384 Uart5Tx = 66,
385 DacCh1 = 67,
386 DacCh2 = 68,
387 Tim6Up = 69,
388 Tim7Up = 70,
389 Uart6Rx = 71,
390 Uart6Tx = 72,
391 I2c3Rx = 73,
392 I2c3Tx = 74,
393 Dcmi = 75,
394 CrypIn = 76,
395 CrypOut = 77,
396 HashIn = 78,
397 Uart7Rx = 79,
398 Uart7Tx = 80,
399 Uart8Rx = 81,
400 Uart8Tx = 82,
401 Sai1A = 87,
402 Sai1B = 88,
403 Sai2A = 89,
404 Sai2B = 90,
405 Dfsdm1F0 = 101,
406 Dfsdm1F1 = 102,
407 Dfsdm1F2 = 103,
408 Dfsdm1F3 = 104,
409 Sai3A = 113,
410 Sai3B = 114,
411 Adc3 = 115,
412 Uart9Rx = 116,
413 Uart9Tx = 117,
414 Uart10Rx = 118,
415 Uart10Tx = 119,
416}
417
418#[derive(Copy, Clone)]
419#[repr(usize)]
420#[cfg(feature = "h7")]
421pub enum DmaInput2 {
423 Lpuart1Rx = 9,
424 Lpuart1Tx = 10,
425 Spi6Rx = 11,
426 Spi6Tx = 12,
427 I2c4Rx = 13,
428 I3crTx = 14,
429 Sai4A = 15,
430 Sai4B = 16,
431}
432
433impl DmaInput {
434 #[cfg(any(feature = "f3", feature = "l4"))]
435 pub fn dma1_channel(&self) -> DmaChannel {
437 match self {
438 Self::Adc1 => DmaChannel::C1,
439 Self::Dac1Ch1 => DmaChannel::C3,
440 Self::Dac1Ch2 => DmaChannel::C4,
441 Self::Spi1Rx => DmaChannel::C2,
444 Self::Spi1Tx => DmaChannel::C3,
445 Self::Spi2Rx => DmaChannel::C4,
446 Self::Spi2Tx => DmaChannel::C5,
447 Self::I2c1Rx => DmaChannel::C7,
450 Self::I2c1Tx => DmaChannel::C6,
451 Self::I2c2Rx => DmaChannel::C5,
452 Self::I2c2Tx => DmaChannel::C4,
453 Self::I2c3Rx => DmaChannel::C3,
454 Self::Usart1Rx => DmaChannel::C5,
458 Self::Usart1Tx => DmaChannel::C4,
459 Self::Usart2Rx => DmaChannel::C6,
460 Self::Usart2Tx => DmaChannel::C7,
461 Self::Usart3Rx => DmaChannel::C3,
462 Self::Usart3Tx => DmaChannel::C2,
463 Self::Adc2 => DmaChannel::C2,
470 Self::Sai2A => DmaChannel::C6,
475 Self::Sai2B => DmaChannel::C7,
476 Self::Dfsdm1F0 => DmaChannel::C4,
477 Self::Dfsdm1F1 => DmaChannel::C5,
478 Self::Dfsdm1F2 => DmaChannel::C6,
479 Self::Dfsdm1F3 => DmaChannel::C7,
480 _ => unimplemented!(),
481 }
482 }
483
484 #[cfg(feature = "l4")]
485 pub fn dma1_channel_select(&self) -> u8 {
488 match self {
489 Self::Adc1 => 0b000,
490 Self::Dac1Ch1 => 0b0110,
491 Self::Dac1Ch2 => 0b0101,
492 Self::Spi1Rx => 0b001,
495 Self::Spi1Tx => 0b001,
496 Self::Spi2Rx => 0b001,
497 Self::Spi2Tx => 0b001,
498 Self::I2c1Rx => 0b011,
501 Self::I2c1Tx => 0b011,
502 Self::I2c2Rx => 0b011,
503 Self::I2c2Tx => 0b011,
504 Self::I2c3Rx => 0b011,
505 Self::Usart1Rx => 0b010,
509 Self::Usart1Tx => 0b010,
510 Self::Usart2Rx => 0b010,
511 Self::Usart2Tx => 0b010,
512 Self::Usart3Rx => 0b010,
513 Self::Usart3Tx => 0b010,
514 Self::Adc2 => 0b000,
521 Self::Dfsdm1F0 => 0b0000,
525 Self::Dfsdm1F1 => 0b0000,
526 Self::Dfsdm1F2 => 0b0000, Self::Dfsdm1F3 => 0b0000,
528 _ => unimplemented!(),
529 }
530 }
531}
532
533#[derive(Copy, Clone)]
534#[repr(u8)]
535pub enum Priority {
547 Low = 0b00,
548 Medium = 0b01,
549 High = 0b10,
550 VeryHigh = 0b11,
551}
552
553#[derive(Copy, Clone)]
555#[repr(u8)]
556#[cfg(feature = "h7")]
557pub enum DmaChannel {
561 #[cfg(feature = "h7")]
563 C0 = 0,
564 C1 = 1,
565 C2 = 2,
566 C3 = 3,
567 #[cfg(not(any(feature = "c011", feature = "c031")))]
568 C4 = 4,
569 #[cfg(not(any(feature = "c011", feature = "c031")))]
570 C5 = 5,
571 #[cfg(not(any(feature = "g0", feature = "c0")))]
574 C6 = 6,
575 #[cfg(not(any(feature = "g0", feature = "c0")))]
576 C7 = 7,
577}
578
579#[derive(Copy, Clone)]
581#[repr(u8)]
582#[cfg(not(feature = "h7"))]
583pub enum DmaChannel {
587 C1 = 0,
588 C2 = 1,
589 C3 = 2,
590 #[cfg(not(any(feature = "c011", feature = "c031")))]
591 C4 = 3,
592 #[cfg(not(any(feature = "c011", feature = "c031")))]
593 C5 = 4,
594 #[cfg(not(any(feature = "g0", feature = "c0")))]
597 C6 = 5,
598 #[cfg(not(any(feature = "g0", feature = "c0")))]
599 C7 = 6,
600 #[cfg(any(feature = "l5", feature = "g4"))]
602 C8 = 7,
603}
604
605#[derive(Copy, Clone)]
606#[repr(u8)]
607pub enum Direction {
610 ReadFromPeriph = 0,
612 ReadFromMem = 1,
614 MemToMem = 2,
615}
616
617#[derive(Copy, Clone, PartialEq)]
618#[repr(u8)]
619pub enum Circular {
622 Disabled = 0,
623 Enabled = 1,
624}
625
626#[derive(Copy, Clone)]
627#[repr(u8)]
628pub enum IncrMode {
631 Disabled = 0,
633 Enabled = 1,
634}
635
636#[derive(Copy, Clone)]
637#[repr(u8)]
638pub enum DataSize {
641 S8 = 0b00, S16 = 0b01,
643 S32 = 0b10,
644}
645
646#[derive(Copy, Clone)]
647pub enum DmaInterrupt {
650 TransferError,
651 HalfTransfer,
652 TransferComplete,
653 #[cfg(feature = "h7")]
654 DirectModeError,
655 #[cfg(feature = "h7")]
656 FifoError,
657}
658
659#[cfg(not(feature = "h7"))]
663macro_rules! set_ccr {
664 ($ccr:expr, $priority:expr, $direction:expr, $circular:expr, $periph_incr:expr, $mem_incr:expr, $periph_size:expr, $mem_size:expr) => {
665 let originally_enabled = $ccr().read().en().bit_is_set();
668
669 if originally_enabled {
670 $ccr().modify(|_, w| w.en().clear_bit());
671 bounded_loop!(
672 $ccr().read().en().bit_is_set(),
673 Error::RegisterUnchanged
674 );
675 }
676
677 if let Circular::Enabled = $circular {
678 $ccr().modify(|_, w| w.mem2mem().clear_bit());
679 }
680
681 $ccr().modify(|_, w| unsafe {
682 w.pl().bits($priority as u8);
684 w.dir().bit($direction as u8 != 0);
688 w.circ().bit($circular as u8 != 0);
690 w.pinc().bit($periph_incr as u8 != 0);
692 w.minc().bit($mem_incr as u8 != 0);
693 w.psize().bits($periph_size as u8);
695 w.msize().bits($mem_size as u8);
696 w.tcie().bit(true);
698 w.en().bit(true)
700 });
701
702 if originally_enabled {
703 $ccr().modify(|_, w| w.en().bit(true));
704 bounded_loop!($ccr().read().en().bit_is_clear(), Error::RegisterUnchanged);
705 }
706 };
707}
708
709#[cfg(not(feature = "h7"))]
711macro_rules! enable_interrupt {
712 ($ccr:expr, $interrupt_type:expr) => {
713 let originally_enabled = $ccr().read().en().bit_is_set();
715 if originally_enabled {
716 $ccr().modify(|_, w| w.en().clear_bit());
717 bounded_loop!($ccr().read().en().bit_is_set(), Error::RegisterUnchanged);
718 }
719
720 $ccr().modify(|_, w| match $interrupt_type {
721 DmaInterrupt::TransferError => w.teie().bit(true),
722 DmaInterrupt::HalfTransfer => w.htie().bit(true),
723 DmaInterrupt::TransferComplete => w.tcie().bit(true),
724 });
725
726 if originally_enabled {
727 $ccr().modify(|_, w| w.en().bit(true));
728 bounded_loop!($ccr().read().en().bit_is_clear(), Error::RegisterUnchanged);
729 }
730 };
731}
732
733#[cfg(not(feature = "h7"))]
735macro_rules! disable_interrupt {
736 ($ccr:expr, $interrupt_type:expr) => {
737 let originally_disabled = $ccr().read().en().bit_is_set();
739 if originally_disabled {
740 $ccr().modify(|_, w| w.en().clear_bit());
741 bounded_loop!($ccr().read().en().bit_is_set(), Error::RegisterUnchanged);
742 }
743
744 $ccr().modify(|_, w| match $interrupt_type {
745 DmaInterrupt::TransferError => w.teie().clear_bit(),
746 DmaInterrupt::HalfTransfer => w.htie().clear_bit(),
747 DmaInterrupt::TransferComplete => w.tcie().clear_bit(),
748 });
749
750 if originally_disabled {
751 $ccr().modify(|_, w| w.en().bit(true));
752 bounded_loop!($ccr().read().en().bit_is_clear(), Error::RegisterUnchanged);
753 }
754 };
755}
756
757#[derive(Clone)]
760pub struct ChannelCfg {
761 pub priority: Priority,
764 pub circular: Circular,
768 pub periph_incr: IncrMode,
771 pub mem_incr: IncrMode,
774}
775
776impl Default for ChannelCfg {
777 fn default() -> Self {
778 Self {
779 priority: Priority::Medium,
780 circular: Circular::Disabled,
781 periph_incr: IncrMode::Disabled,
783 mem_incr: IncrMode::Enabled,
784 }
785 }
786}
787
788pub struct Dma<D> {
790 pub regs: D,
791}
792
793impl<D> Deref for Dma<D>
794where
795 D: Deref<Target = dma1::RegisterBlock>,
796{
797 type Target = dma1::RegisterBlock;
798 fn deref(&self) -> &Self::Target {
799 &self.regs
800 }
801}
802
803impl<D> Dma<D>
804where
805 D: Deref<Target = dma1::RegisterBlock>,
806{
807 pub fn new(regs: D) -> Self {
810 let rcc = unsafe { &(*RCC::ptr()) };
812 cfg_if! {
813 if #[cfg(feature = "f3")] {
814 rcc.ahbenr().modify(|_, w| w.dma1en().bit(true)); } else if #[cfg(any(feature = "g031", feature = "g041", feature = "g051", feature = "g061", feature = "g071", feature = "g081"))] {
816 rcc_en_reset!(ahb1, dma, rcc);
817 } else {
818 rcc_en_reset!(ahb1, dma1, rcc);
819 }
820 }
821
822 Self { regs }
823 }
824
825 pub fn cfg_channel(
856 &mut self,
857 channel: DmaChannel,
858 periph_addr: u32,
859 mem_addr: u32,
860 num_data: u32,
861 direction: Direction,
862 periph_size: DataSize,
863 mem_size: DataSize,
864 cfg: ChannelCfg,
865 ) -> Result<()> {
866 cfg_channel(
867 &mut self.regs,
868 channel,
869 periph_addr,
870 mem_addr,
871 num_data,
872 direction,
873 periph_size,
874 mem_size,
875 cfg,
876 )
877 }
878
879 #[cfg(feature = "l4")]
880 pub(crate) fn channel_select(&mut self, input: DmaInput) {
881 channel_select(&mut self.regs, input);
882 }
883
884 pub fn stop(&mut self, channel: DmaChannel) -> Result<()> {
886 stop_internal(&mut self.regs, channel)
887 }
888
889 pub fn clear_interrupt(&mut self, channel: DmaChannel, interrupt: DmaInterrupt) -> Result<()> {
891 clear_interrupt_internal(&mut self.regs, channel, interrupt)
892 }
893
894 #[cfg(not(any(feature = "h7")))]
896 pub fn transfer_is_complete(&mut self, channel: DmaChannel) -> bool {
897 let isr_val = self.regs.isr().read();
898 match channel {
899 DmaChannel::C1 => isr_val.tcif1().bit_is_set(),
900 DmaChannel::C2 => isr_val.tcif2().bit_is_set(),
901 DmaChannel::C3 => isr_val.tcif3().bit_is_set(),
902 #[cfg(not(any(feature = "c011", feature = "c031")))]
903 DmaChannel::C4 => isr_val.tcif4().bit_is_set(),
904 #[cfg(not(any(feature = "c011", feature = "c031")))]
905 DmaChannel::C5 => isr_val.tcif5().bit_is_set(),
906 #[cfg(not(any(feature = "g0", feature = "c0")))]
907 DmaChannel::C6 => isr_val.tcif6().bit_is_set(),
908 #[cfg(not(any(feature = "g0", feature = "c0")))]
909 DmaChannel::C7 => isr_val.tcif7().bit_is_set(),
910 #[cfg(any(feature = "l5", feature = "g4"))]
911 DmaChannel::C8 => isr_val.tcif8().bit_is_set(),
912 }
913 }
914
915 #[cfg(feature = "h7")]
916 pub fn transfer_is_complete(&mut self, channel: DmaChannel) -> bool {
917 match channel {
918 DmaChannel::C0 => self.regs.lisr().read().tcif0().bit_is_set(),
919 DmaChannel::C1 => self.regs.lisr().read().tcif1().bit_is_set(),
920 DmaChannel::C2 => self.regs.lisr().read().tcif2().bit_is_set(),
921 DmaChannel::C3 => self.regs.lisr().read().tcif3().bit_is_set(),
922 DmaChannel::C4 => self.regs.hisr().read().tcif4().bit_is_set(),
923 DmaChannel::C5 => self.regs.hisr().read().tcif5().bit_is_set(),
924 DmaChannel::C6 => self.regs.hisr().read().tcif6().bit_is_set(),
925 DmaChannel::C7 => self.regs.hisr().read().tcif7().bit_is_set(),
926 }
927 }
928
929 pub fn enable_interrupt(&mut self, channel: DmaChannel, interrupt: DmaInterrupt) -> Result<()> {
931 enable_interrupt_internal(&mut self.regs, channel, interrupt)
932 }
933
934 pub fn disable_interrupt(
938 &mut self,
939 channel: DmaChannel,
940 interrupt: DmaInterrupt,
941 ) -> Result<()> {
942 #[cfg(feature = "h7")]
945 let cr = &self.regs.st(channel as usize).cr();
946 #[cfg(not(feature = "h7"))]
947 let cr = &self.regs.ch(channel as usize).cr();
948
949 let originally_enabled = cr.read().en().bit_is_set();
950
951 if originally_enabled {
952 cr.modify(|_, w| w.en().clear_bit());
953 bounded_loop!(cr.read().en().bit_is_set(), Error::RegisterUnchanged);
954 }
955
956 match interrupt {
957 DmaInterrupt::TransferError => cr.modify(|_, w| w.teie().clear_bit()),
958 DmaInterrupt::HalfTransfer => cr.modify(|_, w| w.htie().clear_bit()),
959 DmaInterrupt::TransferComplete => cr.modify(|_, w| w.tcie().clear_bit()),
960 #[cfg(feature = "h7")]
961 DmaInterrupt::DirectModeError => cr.modify(|_, w| w.dmeie().clear_bit()),
962 #[cfg(feature = "h7")]
963 DmaInterrupt::FifoError => self
964 .regs
965 .st(channel as usize)
966 .fcr()
967 .modify(|_, w| w.feie().clear_bit()),
968 };
969
970 if originally_enabled {
971 cr.modify(|_, w| w.en().bit(true));
972 bounded_loop!(cr.read().en().bit_is_clear(), Error::RegisterUnchanged);
973 }
974
975 Ok(())
976 }
977}
978
979pub fn cfg_channel<D>(
983 regs: &mut D,
984 channel: DmaChannel,
985 periph_addr: u32,
986 mem_addr: u32,
987 num_data: u32,
988 direction: Direction,
989 periph_size: DataSize,
990 mem_size: DataSize,
991 cfg: ChannelCfg,
992) -> Result<()>
993where
994 D: Deref<Target = dma1::RegisterBlock>,
995{
996 cfg_if! {
997 if #[cfg(feature = "h7")] {
998 let mut channel = regs.st(channel as usize);
999 } else {
1000 let mut channel = regs.ch(channel as usize);
1001 }
1002 }
1003 let originally_enabled = channel.cr().read().en().bit_is_set();
1008
1009 channel.cr().modify(|_, w| w.en().clear_bit());
1010 bounded_loop!(
1011 channel.cr().read().en().bit_is_set(),
1012 Error::RegisterUnchanged
1013 );
1014
1015 channel.par().write(|w| unsafe { w.bits(periph_addr) });
1020
1021 atomic::compiler_fence(Ordering::SeqCst);
1027
1028 #[cfg(any(feature = "h7", feature = "l5"))]
1032 channel.m0ar().write(|w| unsafe { w.bits(mem_addr) });
1033
1034 #[cfg(not(any(feature = "h7", feature = "l5")))]
1035 channel.mar().write(|w| unsafe { w.bits(mem_addr) });
1036
1037 channel.ndtr().write(|w| unsafe { w.bits(num_data) });
1042
1043 if originally_enabled {
1054 channel.cr().modify(|_, w| w.en().clear_bit());
1055 bounded_loop!(
1056 channel.cr().read().en().bit_is_set(),
1057 Error::RegisterUnchanged
1058 );
1059 }
1060
1061 channel.cr().modify(|_, w| unsafe {
1067 w.pl().bits(cfg.priority as u8);
1069 #[cfg(feature = "h7")]
1073 w.dir().bits(direction as u8);
1074 #[cfg(not(feature = "h7"))]
1075 w.dir().bit((direction as u8) != 0);
1076 w.circ().bit(cfg.circular as u8 != 0);
1078 w.pinc().bit(cfg.periph_incr as u8 != 0);
1080 w.minc().bit(cfg.mem_incr as u8 != 0);
1081 w.psize().bits(periph_size as u8);
1083 w.msize().bits(mem_size as u8);
1084 w.tcie().bit(true);
1086 w.en().bit(true)
1088 });
1089
1090 if originally_enabled {
1101 channel.cr().modify(|_, w| w.en().set_bit());
1102 bounded_loop!(
1103 channel.cr().read().en().bit_is_clear(),
1104 Error::RegisterUnchanged
1105 );
1106 }
1107
1108 Ok(())
1109}
1110
1111fn stop_internal<D>(regs: &mut D, channel: DmaChannel) -> Result<()>
1113where
1114 D: Deref<Target = dma1::RegisterBlock>,
1115{
1116 #[cfg(feature = "h7")]
1128 let cr = ®s.st(channel as usize).cr();
1129 #[cfg(not(feature = "h7"))]
1130 let cr = ®s.ch(channel as usize).cr();
1131
1132 cr.modify(|_, w| w.en().clear_bit());
1133 bounded_loop!(cr.read().en().bit_is_set(), Error::RegisterUnchanged);
1134
1135 Ok(())
1136
1137 }
1146
1147pub fn stop(periph: DmaPeriph, channel: DmaChannel) -> Result<()> {
1149 match periph {
1150 DmaPeriph::Dma1 => {
1151 let mut regs = unsafe { &(*DMA1::ptr()) };
1152 stop_internal(&mut regs, channel)
1153 }
1154 #[cfg(dma2)]
1155 DmaPeriph::Dma2 => {
1156 let mut regs = unsafe { &(*DMA2::ptr()) };
1157 stop_internal(&mut regs, channel)
1158 }
1159 }
1160}
1161
1162fn clear_interrupt_internal<D>(
1163 regs: &mut D,
1164 channel: DmaChannel,
1165 interrupt: DmaInterrupt,
1166) -> Result<()>
1167where
1168 D: Deref<Target = dma1::RegisterBlock>,
1169{
1170 cfg_if! {
1172 if #[cfg(any(feature = "g4", feature = "wl"))] {
1173 regs.ifcr().write(|w| match channel {
1174 DmaChannel::C1 => match interrupt {
1175 DmaInterrupt::TransferError => w.cteif1().bit(true),
1176 DmaInterrupt::HalfTransfer => w.chtif1().bit(true),
1177 DmaInterrupt::TransferComplete => w.ctcif1().bit(true),
1178 }
1179 DmaChannel::C2 => match interrupt {
1180 DmaInterrupt::TransferError => w.cteif2().bit(true),
1181 DmaInterrupt::HalfTransfer => w.chtif2().bit(true),
1182 DmaInterrupt::TransferComplete => w.ctcif2().bit(true),
1183 }
1184 DmaChannel::C3 => match interrupt {
1185 DmaInterrupt::TransferError => w.cteif3().bit(true),
1186 DmaInterrupt::HalfTransfer => w.chtif3().bit(true),
1187 DmaInterrupt::TransferComplete => w.ctcif3().bit(true),
1188 }
1189 DmaChannel::C4 => match interrupt {
1190 DmaInterrupt::TransferError => w.cteif4().bit(true),
1191 DmaInterrupt::HalfTransfer => w.chtif4().bit(true),
1192 DmaInterrupt::TransferComplete => w.ctcif4().bit(true),
1193 }
1194 DmaChannel::C5 => match interrupt {
1195 DmaInterrupt::TransferError => w.cteif5().bit(true),
1196 DmaInterrupt::HalfTransfer => w.chtif5().bit(true),
1197 DmaInterrupt::TransferComplete => w.ctcif5().bit(true),
1198 }
1199 DmaChannel::C6 => match interrupt {
1200 DmaInterrupt::TransferError => w.cteif6().bit(true),
1201 DmaInterrupt::HalfTransfer => w.chtif6().bit(true),
1202 DmaInterrupt::TransferComplete => w.ctcif6().bit(true),
1203 }
1204 DmaChannel::C7 => match interrupt {
1205 DmaInterrupt::TransferError => w.cteif7().bit(true),
1206 DmaInterrupt::HalfTransfer => w.chtif7().bit(true),
1207 DmaInterrupt::TransferComplete => w.ctcif7().bit(true),
1208 }
1209 #[cfg(not(feature = "wl"))]
1210 DmaChannel::C8 => match interrupt {
1211 DmaInterrupt::TransferError => w.cteif8().bit(true),
1212 DmaInterrupt::HalfTransfer => w.chtif8().bit(true),
1213 DmaInterrupt::TransferComplete => w.ctcif8().bit(true),
1214 }
1215 });
1216 } else if #[cfg(feature = "h7")] {
1217 match channel {
1218 DmaChannel::C0 => match interrupt {
1219 DmaInterrupt::TransferError => regs.lifcr().write(|w| w.cteif0().bit(true)),
1220 DmaInterrupt::HalfTransfer => regs.lifcr().write(|w| w.chtif0().bit(true)),
1221 DmaInterrupt::TransferComplete => regs.lifcr().write(|w| w.ctcif0().bit(true)),
1222 DmaInterrupt::DirectModeError => regs.lifcr().write(|w| w.cdmeif0().bit(true)),
1223 DmaInterrupt::FifoError => regs.lifcr().write(|w| w.cfeif0().bit(true)),
1224 }
1225 DmaChannel::C1 => match interrupt {
1226 DmaInterrupt::TransferError => regs.lifcr().write(|w| w.cteif1().bit(true)),
1227 DmaInterrupt::HalfTransfer => regs.lifcr().write(|w| w.chtif1().bit(true)),
1228 DmaInterrupt::TransferComplete => regs.lifcr().write(|w| w.ctcif1().bit(true)),
1229 DmaInterrupt::DirectModeError => regs.lifcr().write(|w| w.cdmeif1().bit(true)),
1230 DmaInterrupt::FifoError => regs.lifcr().write(|w| w.cfeif1().bit(true)),
1231 }
1232 DmaChannel::C2 => match interrupt {
1233 DmaInterrupt::TransferError => regs.lifcr().write(|w| w.cteif2().bit(true)),
1234 DmaInterrupt::HalfTransfer => regs.lifcr().write(|w| w.chtif2().bit(true)),
1235 DmaInterrupt::TransferComplete => regs.lifcr().write(|w| w.ctcif2().bit(true)),
1236 DmaInterrupt::DirectModeError => regs.lifcr().write(|w| w.cdmeif2().bit(true)),
1237 DmaInterrupt::FifoError => regs.lifcr().write(|w| w.cfeif2().bit(true)),
1238 }
1239 DmaChannel::C3 => match interrupt {
1240 DmaInterrupt::TransferError => regs.lifcr().write(|w| w.cteif3().bit(true)),
1241 DmaInterrupt::HalfTransfer => regs.lifcr().write(|w| w.chtif3().bit(true)),
1242 DmaInterrupt::TransferComplete => regs.lifcr().write(|w| w.ctcif3().bit(true)),
1243 DmaInterrupt::DirectModeError => regs.lifcr().write(|w| w.cdmeif3().bit(true)),
1244 DmaInterrupt::FifoError => regs.lifcr().write(|w| w.cfeif3().bit(true)),
1245 }
1246 DmaChannel::C4 => match interrupt {
1247 DmaInterrupt::TransferError => regs.hifcr().write(|w| w.cteif4().bit(true)),
1248 DmaInterrupt::HalfTransfer => regs.hifcr().write(|w| w.chtif4().bit(true)),
1249 DmaInterrupt::TransferComplete => regs.hifcr().write(|w| w.ctcif4().bit(true)),
1250 DmaInterrupt::DirectModeError => regs.hifcr().write(|w| w.cdmeif4().bit(true)),
1251 DmaInterrupt::FifoError => regs.hifcr().write(|w| w.cfeif4().bit(true)),
1252 }
1253 DmaChannel::C5 => match interrupt {
1254 DmaInterrupt::TransferError => regs.hifcr().write(|w| w.cteif5().bit(true)),
1255 DmaInterrupt::HalfTransfer => regs.hifcr().write(|w| w.chtif5().bit(true)),
1256 DmaInterrupt::TransferComplete => regs.hifcr().write(|w| w.ctcif5().bit(true)),
1257 DmaInterrupt::DirectModeError => regs.hifcr().write(|w| w.cdmeif5().bit(true)),
1258 DmaInterrupt::FifoError => regs.hifcr().write(|w| w.cfeif5().bit(true)),
1259 }
1260 DmaChannel::C6 => match interrupt {
1261 DmaInterrupt::TransferError => regs.hifcr().write(|w| w.cteif6().bit(true)),
1262 DmaInterrupt::HalfTransfer => regs.hifcr().write(|w| w.chtif6().bit(true)),
1263 DmaInterrupt::TransferComplete => regs.hifcr().write(|w| w.ctcif6().bit(true)),
1264 DmaInterrupt::DirectModeError => regs.hifcr().write(|w| w.cdmeif6().bit(true)),
1265 DmaInterrupt::FifoError => regs.hifcr().write(|w| w.cfeif6().bit(true)),
1266 }
1267 DmaChannel::C7 => match interrupt {
1268 DmaInterrupt::TransferError => regs.hifcr().write(|w| w.cteif7().bit(true)),
1269 DmaInterrupt::HalfTransfer => regs.hifcr().write(|w| w.chtif7().bit(true)),
1270 DmaInterrupt::TransferComplete => regs.hifcr().write(|w| w.ctcif7().bit(true)),
1271 DmaInterrupt::DirectModeError => regs.hifcr().write(|w| w.cdmeif7().bit(true)),
1272 DmaInterrupt::FifoError => regs.hifcr().write(|w| w.cfeif7().bit(true)),
1273 }
1274 };
1275 } else if #[cfg(not(feature = "g0"))] {
1277 regs.ifcr().write(|w| match channel {
1278 DmaChannel::C1 => match interrupt {
1279 DmaInterrupt::TransferError => w.cteif1().bit(true),
1280 DmaInterrupt::HalfTransfer => w.chtif1().bit(true),
1281 DmaInterrupt::TransferComplete => w.ctcif1().bit(true),
1282 }
1283 DmaChannel::C2 => match interrupt {
1284 DmaInterrupt::TransferError => w.cteif2().bit(true),
1285 DmaInterrupt::HalfTransfer => w.chtif2().bit(true),
1286 DmaInterrupt::TransferComplete => w.ctcif2().bit(true),
1287 }
1288 DmaChannel::C3 => match interrupt {
1289 DmaInterrupt::TransferError => w.cteif3().bit(true),
1290 DmaInterrupt::HalfTransfer => w.chtif3().bit(true),
1291 DmaInterrupt::TransferComplete => w.ctcif3().bit(true),
1292 }
1293 #[cfg(not(any(feature = "c011", feature = "c031")))]
1294 DmaChannel::C4 => match interrupt {
1295 DmaInterrupt::TransferError => w.cteif4().bit(true),
1296 DmaInterrupt::HalfTransfer => w.chtif4().bit(true),
1297 DmaInterrupt::TransferComplete => w.ctcif4().bit(true),
1298 }
1299 #[cfg(not(any(feature = "c011", feature = "c031")))]
1300 DmaChannel::C5 => match interrupt {
1301 DmaInterrupt::TransferError => w.cteif5().bit(true),
1302 DmaInterrupt::HalfTransfer => w.chtif5().bit(true),
1303 DmaInterrupt::TransferComplete => w.ctcif5().bit(true),
1304 }
1305 #[cfg(not(any(feature = "g0", feature = "c0")))]
1306 DmaChannel::C6 => match interrupt {
1307 DmaInterrupt::TransferError => w.cteif6().bit(true),
1308 DmaInterrupt::HalfTransfer => w.chtif6().bit(true),
1309 DmaInterrupt::TransferComplete => w.ctcif6().bit(true),
1310 }
1311 #[cfg(not(any(feature = "g0", feature = "c0")))]
1312 DmaChannel::C7 => match interrupt {
1313 DmaInterrupt::TransferError => w.cteif7().bit(true),
1314 DmaInterrupt::HalfTransfer => w.chtif7().bit(true),
1315 DmaInterrupt::TransferComplete => w.ctcif7().bit(true),
1316 }
1317 #[cfg(any(feature = "l5", feature = "g4"))]
1318 DmaChannel::C8 => match interrupt {
1319 DmaInterrupt::TransferError => w.cteif8().bit(true),
1320 DmaInterrupt::HalfTransfer => w.chtif8().bit(true),
1321 DmaInterrupt::TransferComplete => w.ctcif8().bit(true),
1322 }
1323 });
1324 }
1325 }
1326 Ok(())
1327}
1328
1329fn enable_interrupt_internal<D>(
1330 regs: &mut D,
1331 channel: DmaChannel,
1332 interrupt: DmaInterrupt,
1333) -> Result<()>
1334where
1335 D: Deref<Target = dma1::RegisterBlock>,
1336{
1337 #[cfg(feature = "h7")]
1339 let cr = ®s.st(channel as usize).cr();
1340 #[cfg(not(feature = "h7"))]
1341 let cr = ®s.ch(channel as usize).cr();
1342
1343 match interrupt {
1344 DmaInterrupt::TransferError => cr.modify(|_, w| w.teie().bit(true)),
1345 DmaInterrupt::HalfTransfer => cr.modify(|_, w| w.htie().bit(true)),
1346 DmaInterrupt::TransferComplete => cr.modify(|_, w| w.tcie().bit(true)),
1347 #[cfg(feature = "h7")]
1348 DmaInterrupt::DirectModeError => cr.modify(|_, w| w.dmeie().bit(true)),
1349 #[cfg(feature = "h7")]
1350 DmaInterrupt::FifoError => regs
1351 .st(channel as usize)
1352 .fcr()
1353 .modify(|_, w| w.feie().bit(true)),
1354 };
1355
1356 Ok(())
1357}
1358
1359fn disable_interrupt_internal<D>(
1360 regs: &mut D,
1361 channel: DmaChannel,
1362 interrupt: DmaInterrupt,
1363) -> Result<()>
1364where
1365 D: Deref<Target = dma1::RegisterBlock>,
1366{
1367 #[cfg(feature = "h7")]
1369 let cr = ®s.st(channel as usize).cr();
1370 #[cfg(not(feature = "h7"))]
1371 let cr = ®s.ch(channel as usize).cr();
1372
1373 match interrupt {
1374 DmaInterrupt::TransferError => cr.modify(|_, w| w.teie().clear_bit()),
1375 DmaInterrupt::HalfTransfer => cr.modify(|_, w| w.htie().clear_bit()),
1376 DmaInterrupt::TransferComplete => cr.modify(|_, w| w.tcie().clear_bit()),
1377 #[cfg(feature = "h7")]
1378 DmaInterrupt::DirectModeError => cr.modify(|_, w| w.dmeie().clear_bit()),
1379 #[cfg(feature = "h7")]
1380 DmaInterrupt::FifoError => regs
1381 .st(channel as usize)
1382 .fcr()
1383 .modify(|_, w| w.feie().clear_bit()),
1384 };
1385
1386 Ok(())
1387}
1388
1389pub fn enable_interrupt(
1391 periph: DmaPeriph,
1392 channel: DmaChannel,
1393 interrupt: DmaInterrupt,
1394) -> Result<()> {
1395 match periph {
1396 DmaPeriph::Dma1 => {
1397 let mut regs = unsafe { &(*DMA1::ptr()) };
1398 enable_interrupt_internal(&mut regs, channel, interrupt)
1399 }
1400 #[cfg(dma2)]
1401 DmaPeriph::Dma2 => {
1402 let mut regs = unsafe { &(*DMA2::ptr()) };
1403 enable_interrupt_internal(&mut regs, channel, interrupt)
1404 }
1405 }
1406}
1407
1408pub fn disable_interrupt(
1410 periph: DmaPeriph,
1411 channel: DmaChannel,
1412 interrupt: DmaInterrupt,
1413) -> Result<()> {
1414 match periph {
1415 DmaPeriph::Dma1 => {
1416 let mut regs = unsafe { &(*DMA1::ptr()) };
1417 disable_interrupt_internal(&mut regs, channel, interrupt)
1418 }
1419 #[cfg(dma2)]
1420 DmaPeriph::Dma2 => {
1421 let mut regs = unsafe { &(*DMA2::ptr()) };
1422 disable_interrupt_internal(&mut regs, channel, interrupt)
1423 }
1424 }
1425}
1426
1427pub fn clear_interrupt(
1429 periph: DmaPeriph,
1430 channel: DmaChannel,
1431 interrupt: DmaInterrupt,
1432) -> Result<()> {
1433 match periph {
1434 DmaPeriph::Dma1 => {
1435 let mut regs = unsafe { &(*DMA1::ptr()) };
1436 clear_interrupt_internal(&mut regs, channel, interrupt)
1437 }
1438 #[cfg(dma2)]
1439 DmaPeriph::Dma2 => {
1440 let mut regs = unsafe { &(*DMA2::ptr()) };
1441 clear_interrupt_internal(&mut regs, channel, interrupt)
1442 }
1443 }
1444}
1445
1446#[cfg(any(
1447 feature = "l5",
1448 feature = "g0",
1449 feature = "g4",
1450 feature = "h7",
1451 feature = "wb",
1452 feature = "wl",
1453))]
1454pub fn mux(periph: DmaPeriph, channel: DmaChannel, input: DmaInput) {
1456 unsafe {
1481 let mux = unsafe { &(*DMAMUX::ptr()) };
1482
1483 #[cfg(feature = "g4")]
1484 let rcc = unsafe { &(*RCC::ptr()) };
1485 #[cfg(feature = "g4")]
1486 rcc.ahb1enr().modify(|_, w| w.dmamux1en().bit(true));
1487
1488 #[cfg(feature = "g431")]
1503 let dma2_offset = 8;
1505 #[cfg(not(feature = "g431"))]
1506 let dma2_offset = 8;
1507
1508 match periph {
1509 DmaPeriph::Dma1 => {
1510 mux.ccr(channel as usize)
1511 .modify(|_, w| w.dmareq_id().bits(input as u8));
1512 }
1513 #[cfg(dma2)]
1514 DmaPeriph::Dma2 => {
1515 mux.ccr(channel as usize + dma2_offset)
1516 .modify(|_, w| w.dmareq_id().bits(input as u8));
1517 }
1518 }
1519 }
1520}
1521
1522#[cfg(feature = "h7")]
1523pub fn mux2(periph: DmaPeriph, channel: DmaChannel, input: DmaInput2, mux: &mut DMAMUX2) {
1525 mux.ccr(channel as usize)
1526 .modify(|_, w| unsafe { w.dmareq_id().bits(input as u8) });
1527}
1528
1529#[cfg(any(feature = "g4", feature = "wb"))]
1533pub fn enable_mux1() {
1534 let rcc = unsafe { &(*RCC::ptr()) };
1535
1536 cfg_if! {
1537 if #[cfg(feature = "g4")] {
1538 rcc.ahb1enr().modify(|_, w| w.dmamux1en().bit(true));
1540 rcc.ahb1rstr().modify(|_, w| w.dmamux1rst().bit(true));
1541 rcc.ahb1rstr().modify(|_, w| w.dmamux1rst().clear_bit());
1542 } else {
1543 rcc_en_reset!(ahb1, dmamux, rcc);
1544 }
1545 }
1546}
1547
1548#[cfg(feature = "l4")] pub(crate) fn channel_select<D>(regs: &mut D, input: DmaInput)
1552where
1553 D: Deref<Target = dma1::RegisterBlock>,
1554{
1555 let val = input.dma1_channel_select();
1557
1558 unsafe {
1559 regs.cselr().modify(|_, w| match input.dma1_channel() {
1560 DmaChannel::C1 => w.c1s().bits(val),
1561 DmaChannel::C2 => w.c2s().bits(val),
1562 DmaChannel::C3 => w.c3s().bits(val),
1563 DmaChannel::C4 => w.c4s().bits(val),
1564 DmaChannel::C5 => w.c5s().bits(val),
1565 DmaChannel::C6 => w.c6s().bits(val),
1566 DmaChannel::C7 => w.c7s().bits(val),
1567 });
1568 }
1569}
1570
1571macro_rules! make_chan_struct {
1573 ($periph: expr, $ch:expr) => {
1575 paste::paste! {
1576 pub struct [<Dma $periph Ch $ch>] {
1578 }
1581
1582 impl [<Dma $periph Ch $ch>] {
1583 pub fn new() -> Self {
1588 let rcc = unsafe { &(*RCC::ptr()) };
1590 cfg_if! {
1591 if #[cfg(feature = "f3")] {
1592 rcc.ahbenr().modify(|_, w| w.dma1en().bit(true)); } else if #[cfg(feature = "g0")] {
1594 rcc_en_reset!(ahb1, dma, rcc);
1595 } else {
1596 rcc_en_reset!(ahb1, [<dma $periph>], rcc);
1597 }
1598 }
1599
1600 Self { }
1601 }
1602
1603 fn regs(&self) -> &[<dma $periph>]::RegisterBlock {
1604 unsafe { &(*[<DMA $periph>]::ptr())}
1605 }
1606
1607 pub fn cfg_channel(
1657 &mut self,
1658 periph_addr: u32,
1659 mem_addr: u32,
1660 num_data: u32,
1661 direction: Direction,
1662 periph_size: DataSize,
1663 mem_size: DataSize,
1664 cfg: ChannelCfg,
1665 ) -> Result<()> {
1666 cfg_channel(
1667 &mut self.regs(),
1668 DmaChannel::[<C $ch>],
1669 periph_addr,
1670 mem_addr,
1671 num_data,
1672 direction,
1673 periph_size,
1674 mem_size,
1675 cfg,
1676 )
1677 }
1678
1679 pub fn stop(&mut self) -> Result<()> {
1681 #[cfg(feature = "h7")]
1682 let ccr = self.regs().st($ch).cr();
1683 #[cfg(not(feature = "h7"))]
1684 let ccr = self.regs().ch($ch).cr();
1685
1686 ccr.modify(|_, w| w.en().clear_bit());
1687 bounded_loop!(ccr.read().en().bit_is_set(), Error::RegisterUnchanged);
1688
1689 Ok(())
1690 }
1691
1692 pub fn enable_interrupt(&mut self, interrupt: DmaInterrupt) {
1694 enable_interrupt_internal(&mut self.regs(), DmaChannel::[<C $ch>], interrupt).unwrap()
1695 }
1696
1697 pub fn clear_interrupt(&mut self, interrupt: DmaInterrupt) {
1699 clear_interrupt_internal(&mut self.regs(), DmaChannel::[<C $ch>], interrupt).unwrap()
1700 }
1701 }
1703 }
1704 };
1705}
1706
1707cfg_if! {
1709 if #[cfg(not(any(feature = "f3", feature = "g0")))] {
1710 #[cfg(feature = "h7")]
1711 make_chan_struct!(1, 0);
1712 make_chan_struct!(1, 1);
1713 make_chan_struct!(1, 2);
1714 make_chan_struct!(1, 3);
1715 #[cfg(not(any(feature = "c011", feature = "c031")))]
1716 make_chan_struct!(1, 4);
1717 #[cfg(not(any(feature = "c011", feature = "c031")))]
1718 make_chan_struct!(1, 5);
1719 #[cfg(not(any(feature = "g0", feature = "c0")))]
1720 make_chan_struct!(1, 6);
1721 #[cfg(not(any(feature = "g0", feature = "c0")))]
1722 make_chan_struct!(1, 7);
1723 #[cfg(any(feature = "l5", feature = "g4"))]
1724 make_chan_struct!(1, 8);
1725
1726 #[cfg(feature = "h7")]
1727 make_chan_struct!(2, 0);
1728 #[cfg(not(any(feature = "g0", feature = "wb", feature = "c0")))]
1729 make_chan_struct!(2, 1);
1730 #[cfg(not(any(feature = "g0", feature = "wb", feature = "c0")))]
1731 make_chan_struct!(2, 2);
1732 #[cfg(not(any(feature = "g0", feature = "wb", feature = "c0")))]
1733 make_chan_struct!(2, 3);
1734 #[cfg(not(any(feature = "g0", feature = "wb", feature = "c0")))]
1735 make_chan_struct!(2, 4);
1736 #[cfg(not(any(feature = "g0", feature = "wb", feature = "c0")))]
1737 make_chan_struct!(2, 5);
1738 #[cfg(not(any(feature = "g0", feature = "wb", feature = "c0")))]
1739 make_chan_struct!(2, 6);
1740 #[cfg(not(any(feature = "g0", feature = "wb", feature = "c0")))]
1741 make_chan_struct!(2, 7);
1742 #[cfg(any(feature = "l5", feature = "g4"))]
1743 make_chan_struct!(2, 8);
1744 }
1745}