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