1use core::{
17 ops::Deref,
18 sync::atomic::{self, Ordering},
19};
20
21use crate::{
22 MAX_ITERS,
23 pac::{self, RCC},
24 util::rcc_en_reset,
25};
26
27cfg_if! {
28 if #[cfg(all(feature = "g0", not(any(feature = "g0b1", feature = "g0c1"))))] {
29 use crate::pac::{dma as dma1, DMA as DMA1};
30 } else if #[cfg(feature = "f3x4")] {
31 use crate::pac::{dma1, DMA1};
32 }
33 else {
34 use crate::pac::{dma1, dma2, DMA1, DMA2};
35 }
36}
37
38use cfg_if::cfg_if;
40#[cfg(any(feature = "g0", feature = "g4", feature = "wl"))]
41use pac::DMAMUX;
42#[cfg(any(feature = "l5", feature = "wb", feature = "h7"))]
44use pac::DMAMUX1 as DMAMUX;
45#[cfg(feature = "h7")]
46use pac::DMAMUX2;
47use paste::paste;
48
49#[derive(Clone, Copy)]
52pub enum DmaPeriph {
53 Dma1,
54 #[cfg(not(any(
55 feature = "f3x4",
56 all(feature = "g0", not(any(feature = "g0b1", feature = "g0c1"))),
57 feature = "wb",
58 )))] Dma2,
60}
61
62#[derive(Copy, Clone)]
63#[repr(usize)]
64#[cfg(not(any(feature = "h7", feature = "wl")))]
65pub enum DmaInput {
68 Adc1 = 5,
71 Dac1Ch1 = 6,
72 Dac1Ch2 = 7,
73 Tim6Up = 8,
74 Tim7Up = 9,
75 Spi1Rx = 10,
76 Spi1Tx = 11,
77 Spi2Rx = 12,
78 Spi2Tx = 13,
79 Spi3Rx = 14,
80 Spi3Tx = 15,
81 I2c1Rx = 16,
82 I2c1Tx = 17,
83 I2c2Rx = 18,
84 I2c2Tx = 19,
85 I2c3Rx = 20,
86 I2c3Tx = 21,
87 I2c4Rx = 22,
88 I2c4Tx = 23,
89 Usart1Rx = 24,
90 Usart1Tx = 25,
91 Usart2Rx = 26,
92 Usart2Tx = 27,
93 Usart3Rx = 28,
94 Usart3Tx = 29,
95 Uart4Rx = 30,
96 Uart4Tx = 31,
97 Uart5Rx = 32,
98 Uart5Tx = 33,
99 Lpuart1Rx = 34,
100 Lpuart1Tx = 35,
101 Adc2 = 36,
102 Adc3 = 37,
103 Adc4 = 38,
104 Adc5 = 39,
105 Quadspi = 40,
106 Dac2Ch1 = 41,
107 Tim1Ch1 = 42,
108 Tim1Ch2 = 43,
109 Tim1Ch3 = 44,
110 Tim1Ch4 = 45,
111 TimUp = 46,
112 Tim1Trig = 47,
113 Tim1Com = 48,
114 Tim8Ch1 = 49,
115 Tim8Ch2 = 50,
116 Tim8Ch3 = 51,
117 Tim8Ch4 = 52,
118 Tim8Up = 53,
119 Tim8Trig = 54,
120 Tim8Com = 55,
121 Tim2Ch1 = 56,
122 Tim2Ch2 = 57,
123 Tim2Ch3 = 58,
124 Tim2Ch4 = 59,
125 Tim2Up = 60,
126 Tim3Ch1 = 61,
127 Tim3Ch2 = 62,
128 Tim3Ch3 = 63,
129 Tim3Ch4 = 64,
130 Tim3Up = 65,
131 Tim3Trig = 66,
132 Tim4Ch1 = 67,
133 Tim4Ch2 = 68,
134 Tim4Ch3 = 69,
135 Tim4Ch4 = 70,
136 Tim4Up = 71,
137 Sai1A = 108,
138 Sai1B = 109,
139 Sai2A = 203,
141 Sai2B = 204,
142 Dfsdm1F0 = 200,
144 Dfsdm1F1 = 201,
145 Dfsdm1F2 = 205,
146 Dfsdm1F3 = 206,
147}
148
149#[derive(Copy, Clone)]
150#[repr(usize)]
151#[cfg(feature = "wl")]
152pub enum DmaInput {
154 Adc = 5,
155 DacOut1 = 6,
156 Spi1Rx = 7,
158 Spi1Tx = 8,
159 Spi2Rx = 9,
160 Spi2Tx = 10,
161 I2c1Rx = 11,
162 I2c1Tx = 12,
163 I2c2Rx = 13,
164 I2c2Tx = 14,
165 I2c3Rx = 15,
166 I2c3Tx = 16,
167 Usart1Rx = 17,
168 Usart1Tx = 18,
169 Usart2Rx = 19,
170 Usart2Tx = 20,
171 Lpuart1Rx = 21,
172 Lpuart1Tx = 22,
173 Tim1Ch1 = 23,
174 Tim1Ch2 = 24,
175 Tim1Ch3 = 25,
176 Tim1Ch4 = 26,
177 TimUp = 27,
178 Tim1Trig = 28,
179 Tim1Com = 29,
180 Tim2Ch1 = 30,
181 Tim2Ch2 = 31,
182 Tim2Ch3 = 32,
183 Tim2Ch4 = 33,
184 Tim2Up = 34,
185 Tim16Ch1 = 35,
186 Tim16Up = 36,
187 Tim17Ch1 = 37,
188 Tim17Up = 38,
189 AesIn = 39,
190 AesOut = 40,
191 SubghzSpiRx = 41,
192 SubghzSpiTx = 42,
193}
194
195#[derive(Copy, Clone)]
198#[repr(usize)]
199#[cfg(feature = "h7")]
200pub enum DmaInput {
205 Adc1 = 9,
206 Adc2 = 10,
207 Tim1Ch1 = 11,
208 Tim1Ch2 = 12,
209 Tim1Ch3 = 13,
210 Tim1Ch4 = 14,
211 Tim1Up = 15,
212 Tim1Trig = 16,
213 Tim1Com = 17,
214 Tim2Ch1 = 18,
215 Tim2Ch2 = 19,
216 Tim2Ch3 = 20,
217 Tim2Ch4 = 21,
218 Tim2Up = 22,
219 Tim3Ch1 = 23,
220 Tim3Ch2 = 24,
221 Tim3Ch3 = 25,
222 Tim3Ch4 = 26,
223 Tim3Up = 27,
224 Tim3Trig = 28,
225 Tim4Ch1 = 29,
226 Tim4Ch2 = 30,
227 Tim4Ch3 = 31,
228 Tim4Up = 32,
229 I2c1Rx = 33,
230 I2c1Tx = 34,
231 I2c2Rx = 35,
232 I2c2Tx = 36,
233 Spi1Rx = 37,
234 Spi1Tx = 38,
235 Spi2Rx = 39,
236 Spi2Tx = 40,
237 Usart1Rx = 41,
238 Usart1Tx = 42,
239 Usart2Rx = 43,
240 Usart2Tx = 44,
241 Usart3Rx = 45,
242 Usart3Tx = 46,
243 Tim8Ch1 = 47,
244 Tim8Ch2 = 48,
245 Tim8Ch3 = 49,
246 Tim8Ch4 = 50,
247 Tim8Up = 51,
248 Tim8Trig = 52,
249 Tim8Com = 53,
250 Tim5Ch1 = 55,
251 Tim5Ch2 = 56,
252 Tim5Ch3 = 57,
253 Tim5Ch4 = 58,
254 Tim5Up = 59,
255 Tim5Trig = 60,
256 Spi3Rx = 61,
257 Spi3Tx = 62,
258 Uart4Rx = 63,
259 Uart4Tx = 64,
260 Uart5Rx = 65,
261 Uart5Tx = 66,
262 DacCh1 = 67,
263 DacCh2 = 68,
264 Tim6Up = 69,
265 Tim7Up = 70,
266 Uart6Rx = 71,
267 Uart6Tx = 72,
268 I2c3Rx = 73,
269 I2c3Tx = 74,
270 Dcmi = 75,
271 CrypIn = 76,
272 CrypOut = 77,
273 HashIn = 78,
274 Uart7Rx = 79,
275 Uart7Tx = 80,
276 Uart8Rx = 81,
277 Uart8Tx = 82,
278 Sai1A = 87,
279 Sai1B = 88,
280 Sai2A = 89,
281 Sai2B = 90,
282 Dfsdm1F0 = 101,
283 Dfsdm1F1 = 102,
284 Dfsdm1F2 = 103,
285 Dfsdm1F3 = 104,
286 Sai3A = 113,
287 Sai3B = 114,
288 Adc3 = 115,
289 Uart9Rx = 116,
290 Uart9Tx = 117,
291 Uart10Rx = 118,
292 Uart10Tx = 119,
293}
294
295#[derive(Copy, Clone)]
296#[repr(usize)]
297#[cfg(feature = "h7")]
298pub enum DmaInput2 {
300 Lpuart1Rx = 9,
301 Lpuart1Tx = 10,
302 Spi6Rx = 11,
303 Spi6Tx = 12,
304 I2c4Rx = 13,
305 I3crTx = 14,
306 Sai4A = 15,
307 Sai4B = 16,
308}
309
310impl DmaInput {
311 #[cfg(any(feature = "f3", feature = "l4"))]
312 pub fn dma1_channel(&self) -> DmaChannel {
314 match self {
315 Self::Adc1 => DmaChannel::C1,
316 Self::Dac1Ch1 => DmaChannel::C3,
317 Self::Dac1Ch2 => DmaChannel::C4,
318 Self::Spi1Rx => DmaChannel::C2,
321 Self::Spi1Tx => DmaChannel::C3,
322 Self::Spi2Rx => DmaChannel::C4,
323 Self::Spi2Tx => DmaChannel::C5,
324 Self::I2c1Rx => DmaChannel::C7,
327 Self::I2c1Tx => DmaChannel::C6,
328 Self::I2c2Rx => DmaChannel::C5,
329 Self::I2c2Tx => DmaChannel::C4,
330 Self::I2c3Rx => DmaChannel::C3,
331 Self::Usart1Rx => DmaChannel::C5,
335 Self::Usart1Tx => DmaChannel::C4,
336 Self::Usart2Rx => DmaChannel::C6,
337 Self::Usart2Tx => DmaChannel::C7,
338 Self::Usart3Rx => DmaChannel::C3,
339 Self::Usart3Tx => DmaChannel::C2,
340 Self::Adc2 => DmaChannel::C2,
347 Self::Sai2A => DmaChannel::C6,
352 Self::Sai2B => DmaChannel::C7,
353 Self::Dfsdm1F0 => DmaChannel::C4,
354 Self::Dfsdm1F1 => DmaChannel::C5,
355 Self::Dfsdm1F2 => DmaChannel::C6,
356 Self::Dfsdm1F3 => DmaChannel::C7,
357 _ => unimplemented!(),
358 }
359 }
360
361 #[cfg(feature = "l4")]
362 pub fn dma1_channel_select(&self) -> u8 {
365 match self {
366 Self::Adc1 => 0b000,
367 Self::Dac1Ch1 => 0b0110,
368 Self::Dac1Ch2 => 0b0101,
369 Self::Spi1Rx => 0b001,
372 Self::Spi1Tx => 0b001,
373 Self::Spi2Rx => 0b001,
374 Self::Spi2Tx => 0b001,
375 Self::I2c1Rx => 0b011,
378 Self::I2c1Tx => 0b011,
379 Self::I2c2Rx => 0b011,
380 Self::I2c2Tx => 0b011,
381 Self::I2c3Rx => 0b011,
382 Self::Usart1Rx => 0b010,
386 Self::Usart1Tx => 0b010,
387 Self::Usart2Rx => 0b010,
388 Self::Usart2Tx => 0b010,
389 Self::Usart3Rx => 0b010,
390 Self::Usart3Tx => 0b010,
391 Self::Adc2 => 0b000,
398 Self::Dfsdm1F0 => 0b0000,
402 Self::Dfsdm1F1 => 0b0000,
403 Self::Dfsdm1F2 => 0b0000, Self::Dfsdm1F3 => 0b0000,
405 _ => unimplemented!(),
406 }
407 }
408}
409
410#[derive(Copy, Clone)]
411#[repr(u8)]
412pub enum Priority {
424 Low = 0b00,
425 Medium = 0b01,
426 High = 0b10,
427 VeryHigh = 0b11,
428}
429
430#[derive(Copy, Clone)]
431#[repr(u8)]
432pub enum DmaChannel {
436 #[cfg(feature = "h7")]
438 C0 = 0,
439 C1 = 1,
440 C2 = 2,
441 C3 = 3,
442 C4 = 4,
443 C5 = 5,
444 #[cfg(not(feature = "g0"))]
446 C6 = 6,
447 #[cfg(not(feature = "g0"))]
448 C7 = 7,
449 #[cfg(any(feature = "l5", feature = "g4"))]
451 C8 = 8,
452}
453
454#[derive(Copy, Clone)]
455#[repr(u8)]
456pub enum Direction {
459 ReadFromPeriph = 0,
461 ReadFromMem = 1,
463 MemToMem = 2,
464}
465
466#[derive(Copy, Clone, PartialEq)]
467#[repr(u8)]
468pub enum Circular {
471 Disabled = 0,
472 Enabled = 1,
473}
474
475#[derive(Copy, Clone)]
476#[repr(u8)]
477pub enum IncrMode {
480 Disabled = 0,
482 Enabled = 1,
483}
484
485#[derive(Copy, Clone)]
486#[repr(u8)]
487pub enum DataSize {
490 S8 = 0b00, S16 = 0b01,
492 S32 = 0b10,
493}
494
495#[derive(Copy, Clone)]
496pub enum DmaInterrupt {
499 TransferError,
500 HalfTransfer,
501 TransferComplete,
502 #[cfg(feature = "h7")]
503 DirectModeError,
504 #[cfg(feature = "h7")]
505 FifoError,
506}
507
508#[cfg(not(feature = "h7"))]
512macro_rules! set_ccr {
513 ($ccr:expr, $priority:expr, $direction:expr, $circular:expr, $periph_incr:expr, $mem_incr:expr, $periph_size:expr, $mem_size:expr) => {
514 let originally_enabled = $ccr.read().en().bit_is_set();
517 if originally_enabled {
518 $ccr.modify(|_, w| w.en().clear_bit());
519 while $ccr.read().en().bit_is_set() {}
520 }
521
522 if let Circular::Enabled = $circular {
523 $ccr.modify(|_, w| w.mem2mem().clear_bit());
524 }
525
526 $ccr.modify(|_, w| unsafe {
527 w.pl().bits($priority as u8);
529 w.dir().bit($direction as u8 != 0);
533 w.circ().bit($circular as u8 != 0);
535 w.pinc().bit($periph_incr as u8 != 0);
537 w.minc().bit($mem_incr as u8 != 0);
538 w.psize().bits($periph_size as u8);
540 w.msize().bits($mem_size as u8);
541 w.tcie().set_bit();
543 w.en().set_bit()
545 });
546
547 if originally_enabled {
548 $ccr.modify(|_, w| w.en().set_bit());
549 while $ccr.read().en().bit_is_clear() {}
550 }
551 }
552}
553
554#[cfg(not(feature = "h7"))]
556macro_rules! enable_interrupt {
557 ($ccr:expr, $interrupt_type:expr) => {
558 let originally_enabled = $ccr.read().en().bit_is_set();
560 if originally_enabled {
561 $ccr.modify(|_, w| w.en().clear_bit());
562 while $ccr.read().en().bit_is_set() {}
563 }
564
565 $ccr.modify(|_, w| match $interrupt_type {
566 DmaInterrupt::TransferError => w.teie().set_bit(),
567 DmaInterrupt::HalfTransfer => w.htie().set_bit(),
568 DmaInterrupt::TransferComplete => w.tcie().set_bit(),
569 });
570
571 if originally_enabled {
572 $ccr.modify(|_, w| w.en().set_bit());
573 while $ccr.read().en().bit_is_clear() {}
574 }
575 };
576}
577
578#[cfg(not(feature = "h7"))]
580macro_rules! disable_interrupt {
581 ($ccr:expr, $interrupt_type:expr) => {
582 let originally_disabled = $ccr.read().en().bit_is_set();
584 if originally_disabled {
585 $ccr.modify(|_, w| w.en().clear_bit());
586 while $ccr.read().en().bit_is_set() {}
587 }
588
589 $ccr.modify(|_, w| match $interrupt_type {
590 DmaInterrupt::TransferError => w.teie().clear_bit(),
591 DmaInterrupt::HalfTransfer => w.htie().clear_bit(),
592 DmaInterrupt::TransferComplete => w.tcie().clear_bit(),
593 });
594
595 if originally_disabled {
596 $ccr.modify(|_, w| w.en().set_bit());
597 while $ccr.read().en().bit_is_clear() {}
598 }
599 };
600}
601
602#[derive(Clone)]
605pub struct ChannelCfg {
606 pub priority: Priority,
609 pub circular: Circular,
613 pub periph_incr: IncrMode,
616 pub mem_incr: IncrMode,
619}
620
621impl Default for ChannelCfg {
622 fn default() -> Self {
623 Self {
624 priority: Priority::Medium,
625 circular: Circular::Disabled,
626 periph_incr: IncrMode::Disabled,
628 mem_incr: IncrMode::Enabled,
629 }
630 }
631}
632
633pub struct Dma<D> {
635 pub regs: D,
636}
637
638impl<D> Dma<D>
639where
640 D: Deref<Target = dma1::RegisterBlock>,
641{
642 pub fn new(regs: D) -> Self {
645 let rcc = unsafe { &(*RCC::ptr()) };
647 cfg_if! {
648 if #[cfg(feature = "f3")] {
649 rcc.ahbenr.modify(|_, w| w.dma1en().set_bit()); } else if #[cfg(feature = "g0")] {
651 rcc_en_reset!(ahb1, dma, rcc);
652 } else {
653 rcc_en_reset!(ahb1, dma1, rcc);
654 }
655 }
656
657 Self { regs }
658 }
659
660 #[cfg(not(feature = "h7"))] pub fn cfg_channel(
664 &mut self,
665 channel: DmaChannel,
666 periph_addr: u32,
667 mem_addr: u32,
668 num_data: u16,
669 direction: Direction,
670 periph_size: DataSize,
671 mem_size: DataSize,
672 cfg: ChannelCfg,
673 ) {
674 cfg_channel(
675 &mut self.regs,
676 channel,
677 periph_addr,
678 mem_addr,
679 num_data,
680 direction,
681 periph_size,
682 mem_size,
683 cfg,
684 )
685 }
686
687 #[cfg(feature = "h7")]
688 pub fn cfg_channel(
691 &mut self,
692 channel: DmaChannel,
693 periph_addr: u32,
694 mem_addr: u32,
695 num_data: u32,
696 direction: Direction,
697 periph_size: DataSize,
698 mem_size: DataSize,
699 cfg: ChannelCfg,
700 ) {
701 cfg_channel(
702 &mut self.regs,
703 channel,
704 periph_addr,
705 mem_addr,
706 num_data,
707 direction,
708 periph_size,
709 mem_size,
710 cfg,
711 )
712 }
713
714 #[cfg(feature = "l4")]
715 pub(crate) fn channel_select(&mut self, input: DmaInput) {
716 channel_select(&mut self.regs, input);
717 }
718
719 pub fn stop(&mut self, channel: DmaChannel) {
721 stop_internal(&mut self.regs, channel);
722 }
723
724 pub fn clear_interrupt(&mut self, channel: DmaChannel, interrupt: DmaInterrupt) {
726 clear_interrupt_internal(&mut self.regs, channel, interrupt);
727 }
728
729 #[cfg(not(any(feature = "h7", feature = "g0")))]
731 pub fn transfer_is_complete(&mut self, channel: DmaChannel) -> bool {
732 let isr_val = self.regs.isr.read();
733 match channel {
734 DmaChannel::C1 => isr_val.tcif1().bit_is_set(),
735 DmaChannel::C2 => isr_val.tcif2().bit_is_set(),
736 DmaChannel::C3 => isr_val.tcif3().bit_is_set(),
737 DmaChannel::C4 => isr_val.tcif4().bit_is_set(),
738 DmaChannel::C5 => isr_val.tcif5().bit_is_set(),
739 #[cfg(not(feature = "g0"))]
740 DmaChannel::C6 => isr_val.tcif6().bit_is_set(),
741 #[cfg(not(feature = "g0"))]
742 DmaChannel::C7 => isr_val.tcif7().bit_is_set(),
743 #[cfg(any(feature = "l5", feature = "g4"))]
744 DmaChannel::C8 => isr_val.tcif8().bit_is_set(),
745 }
746 }
747
748 #[cfg(feature = "h7")]
749 pub fn transfer_is_complete(&mut self, channel: DmaChannel) -> bool {
750 match channel {
751 DmaChannel::C0 => self.regs.lisr.read().tcif0().bit_is_set(),
752 DmaChannel::C1 => self.regs.lisr.read().tcif1().bit_is_set(),
753 DmaChannel::C2 => self.regs.lisr.read().tcif2().bit_is_set(),
754 DmaChannel::C3 => self.regs.lisr.read().tcif3().bit_is_set(),
755 DmaChannel::C4 => self.regs.hisr.read().tcif4().bit_is_set(),
756 DmaChannel::C5 => self.regs.hisr.read().tcif5().bit_is_set(),
757 DmaChannel::C6 => self.regs.hisr.read().tcif6().bit_is_set(),
758 DmaChannel::C7 => self.regs.hisr.read().tcif7().bit_is_set(),
759 }
760 }
761
762 pub fn enable_interrupt(&mut self, channel: DmaChannel, interrupt: DmaInterrupt) {
764 enable_interrupt_internal(&mut self.regs, channel, interrupt);
765 }
766
767 #[cfg(feature = "h7")]
770 pub fn disable_interrupt(&mut self, channel: DmaChannel, interrupt: DmaInterrupt) {
771 let cr = &self.regs.st[channel as usize].cr;
774
775 let originally_enabled = cr.read().en().bit_is_set();
776
777 if originally_enabled {
778 cr.modify(|_, w| w.en().clear_bit());
779 while cr.read().en().bit_is_set() {}
780 }
781
782 match interrupt {
783 DmaInterrupt::TransferError => cr.modify(|_, w| w.teie().clear_bit()),
784 DmaInterrupt::HalfTransfer => cr.modify(|_, w| w.htie().clear_bit()),
785 DmaInterrupt::TransferComplete => cr.modify(|_, w| w.tcie().clear_bit()),
786 DmaInterrupt::DirectModeError => cr.modify(|_, w| w.dmeie().clear_bit()),
787 DmaInterrupt::FifoError => self.regs.st[channel as usize]
788 .fcr
789 .modify(|_, w| w.feie().clear_bit()),
790 }
791
792 if originally_enabled {
793 cr.modify(|_, w| w.en().set_bit());
794 while cr.read().en().bit_is_clear() {}
795 }
796 }
797}
798
799#[cfg(not(feature = "h7"))]
802pub fn cfg_channel<D>(
803 regs: &mut D,
804 channel: DmaChannel,
805 periph_addr: u32,
806 mem_addr: u32,
807 num_data: u16,
808 direction: Direction,
809 periph_size: DataSize,
810 mem_size: DataSize,
811 cfg: ChannelCfg,
812) where
813 D: Deref<Target = dma1::RegisterBlock>,
814{
815 unsafe {
818 match channel {
819 DmaChannel::C1 => {
820 cfg_if! {
821 if #[cfg(any(feature = "f3", feature = "g0"))] {
822 let cpar = ®s.ch1.par;
823 } else {
824 let cpar = ®s.cpar1;
825 }
826 }
827 cpar.write(|w| w.bits(periph_addr));
828 }
829 DmaChannel::C2 => {
830 cfg_if! {
831 if #[cfg(any(feature = "f3", feature = "g0"))] {
832 let cpar = ®s.ch2.par;
833 } else {
834 let cpar = ®s.cpar2;
835 }
836 }
837 cpar.write(|w| w.bits(periph_addr));
838 }
839 DmaChannel::C3 => {
840 cfg_if! {
841 if #[cfg(any(feature = "f3", feature = "g0"))] {
842 let cpar = ®s.ch3.par;
843 } else {
844 let cpar = ®s.cpar3;
845 }
846 }
847 cpar.write(|w| w.bits(periph_addr));
848 }
849 DmaChannel::C4 => {
850 cfg_if! {
851 if #[cfg(any(feature = "f3", feature = "g0"))] {
852 let cpar = ®s.ch4.par;
853 } else {
854 let cpar = ®s.cpar4;
855 }
856 }
857 cpar.write(|w| w.bits(periph_addr));
858 }
859 DmaChannel::C5 => {
860 cfg_if! {
861 if #[cfg(any(feature = "f3", feature = "g0"))] {
862 let cpar = ®s.ch5.par;
863 } else {
864 let cpar = ®s.cpar5;
865 }
866 }
867 cpar.write(|w| w.bits(periph_addr));
868 }
869 #[cfg(not(feature = "g0"))]
870 DmaChannel::C6 => {
871 cfg_if! {
872 if #[cfg(any(feature = "f3", feature = "g0"))] {
873 let cpar = ®s.ch6.par;
874 } else {
875 let cpar = ®s.cpar6;
876 }
877 }
878 cpar.write(|w| w.bits(periph_addr));
879 }
880 #[cfg(not(feature = "g0"))]
881 DmaChannel::C7 => {
882 cfg_if! {
883 if #[cfg(any(feature = "f3", feature = "g0"))] {
884 let cpar = ®s.ch7.par;
885 } else {
886 let cpar = ®s.cpar7;
887 }
888 }
889 cpar.write(|w| w.bits(periph_addr));
890 }
891 #[cfg(any(feature = "l5", feature = "g4"))]
892 DmaChannel::C8 => {
893 let cpar = ®s.cpar8;
894 cpar.write(|w| w.bits(periph_addr));
895 }
896 }
897 }
898
899 atomic::compiler_fence(Ordering::SeqCst);
900 unsafe {
901 match channel {
902 DmaChannel::C1 => {
903 cfg_if! {
904 if #[cfg(any(feature = "f3", feature = "g0"))] {
905 let cmar = ®s.ch1.mar;
906 } else if #[cfg(feature = "l5")] {
907 let cmar = ®s.cm0ar1;
908 } else {
909 let cmar = ®s.cmar1;
910 }
911 }
912 cmar.write(|w| w.bits(mem_addr));
913 }
914 DmaChannel::C2 => {
915 cfg_if! {
916 if #[cfg(any(feature = "f3", feature = "g0"))] {
917 let cmar = ®s.ch2.mar;
918 } else if #[cfg(feature = "l5")] {
919 let cmar = ®s.cm0ar2;
920 } else {
921 let cmar = ®s.cmar2;
922 }
923 }
924 cmar.write(|w| w.bits(mem_addr));
925 }
926 DmaChannel::C3 => {
927 cfg_if! {
928 if #[cfg(any(feature = "f3", feature = "g0"))] {
929 let cmar = ®s.ch3.mar;
930 } else if #[cfg(feature = "l5")] {
931 let cmar = ®s.cm0ar3;
932 } else {
933 let cmar = ®s.cmar3;
934 }
935 }
936 cmar.write(|w| w.bits(mem_addr));
937 }
938 DmaChannel::C4 => {
939 cfg_if! {
940 if #[cfg(any(feature = "f3", feature = "g0"))] {
941 let cmar = ®s.ch4.mar;
942 } else if #[cfg(feature = "l5")] {
943 let cmar = ®s.cm0ar4;
944 } else {
945 let cmar = ®s.cmar4;
946 }
947 }
948 cmar.write(|w| w.bits(mem_addr));
949 }
950 DmaChannel::C5 => {
951 cfg_if! {
952 if #[cfg(any(feature = "f3", feature = "g0"))] {
953 let cmar = ®s.ch5.mar;
954 } else if #[cfg(feature = "l5")] {
955 let cmar = ®s.cm0ar5;
956 } else {
957 let cmar = ®s.cmar5;
958 }
959 }
960 cmar.write(|w| w.bits(mem_addr));
961 }
962 #[cfg(not(feature = "g0"))]
963 DmaChannel::C6 => {
964 cfg_if! {
965 if #[cfg(any(feature = "f3", feature = "g0"))] {
966 let cmar = ®s.ch6.mar;
967 } else if #[cfg(feature = "l5")] {
968 let cmar = ®s.cm0ar6;
969 } else {
970 let cmar = ®s.cmar6;
971 }
972 }
973 cmar.write(|w| w.bits(mem_addr));
974 }
975 #[cfg(not(feature = "g0"))]
976 DmaChannel::C7 => {
977 cfg_if! {
978 if #[cfg(any(feature = "f3", feature = "g0"))] {
979 let cmar = ®s.ch7.mar;
980 } else if #[cfg(feature = "l5")] {
981 let cmar = ®s.cm0ar7;
982 } else {
983 let cmar = ®s.cmar7;
984 }
985 }
986 cmar.write(|w| w.bits(mem_addr));
987 }
988 #[cfg(any(feature = "l5", feature = "g4"))]
989 DmaChannel::C8 => {
990 #[cfg(feature = "l5")]
991 let cmar = ®s.cm0ar8;
992 #[cfg(feature = "g4")]
993 let cmar = ®s.cmar8;
994 cmar.write(|w| w.bits(mem_addr));
995 }
996 }
997 }
998
999 #[cfg(any(feature = "l5", feature = "wl"))]
1000 let num_data = num_data as u32;
1001
1002 #[cfg(not(feature = "l5"))] unsafe {
1004 match channel {
1005 DmaChannel::C1 => {
1006 cfg_if! {
1007 if #[cfg(any(feature = "f3", feature = "g0"))] {
1008 let cndtr = ®s.ch1.ndtr;
1009 } else {
1010 let cndtr = ®s.cndtr1;
1011 }
1012 }
1013 cndtr.write(|w| w.ndt().bits(num_data));
1014 }
1015 DmaChannel::C2 => {
1016 cfg_if! {
1017 if #[cfg(any(feature = "f3", feature = "g0"))] {
1018 let cndtr = ®s.ch2.ndtr;
1019 } else {
1020 let cndtr = ®s.cndtr2;
1021 }
1022 }
1023 cndtr.write(|w| w.ndt().bits(num_data));
1024 }
1025 DmaChannel::C3 => {
1026 cfg_if! {
1027 if #[cfg(any(feature = "f3", feature = "g0"))] {
1028 let cndtr = ®s.ch3.ndtr;
1029 } else {
1030 let cndtr = ®s.cndtr3;
1031 }
1032 }
1033 cndtr.write(|w| w.ndt().bits(num_data));
1034 }
1035 DmaChannel::C4 => {
1036 cfg_if! {
1037 if #[cfg(any(feature = "f3", feature = "g0"))] {
1038 let cndtr = ®s.ch4.ndtr;
1039 } else {
1040 let cndtr = ®s.cndtr4;
1041 }
1042 }
1043 cndtr.write(|w| w.ndt().bits(num_data));
1044 }
1045 DmaChannel::C5 => {
1046 cfg_if! {
1047 if #[cfg(any(feature = "f3", feature = "g0"))] {
1048 let cndtr = ®s.ch5.ndtr;
1049 } else {
1050 let cndtr = ®s.cndtr5;
1051 }
1052 }
1053 cndtr.write(|w| w.ndt().bits(num_data));
1054 }
1055 #[cfg(not(feature = "g0"))]
1056 DmaChannel::C6 => {
1057 cfg_if! {
1058 if #[cfg(any(feature = "f3", feature = "g0"))] {
1059 let cndtr = ®s.ch6.ndtr;
1060 } else {
1061 let cndtr = ®s.cndtr6;
1062 }
1063 }
1064 cndtr.write(|w| w.ndt().bits(num_data));
1065 }
1066 #[cfg(not(feature = "g0"))]
1067 DmaChannel::C7 => {
1068 cfg_if! {
1069 if #[cfg(any(feature = "f3", feature = "g0"))] {
1070 let cndtr = ®s.ch7.ndtr;
1071 } else {
1072 let cndtr = ®s.cndtr7;
1073 }
1074 }
1075 cndtr.write(|w| w.ndt().bits(num_data));
1076 }
1077 #[cfg(any(feature = "l5", feature = "g4"))]
1078 DmaChannel::C8 => {
1079 let cndtr = ®s.cndtr8;
1080 cndtr.write(|w| w.ndt().bits(num_data));
1081 }
1082 }
1083 }
1084
1085 match channel {
1086 DmaChannel::C1 => {
1087 cfg_if! {
1088 if #[cfg(any(feature = "f3", feature = "g0"))] {
1089 let ccr = ®s.ch1.cr;
1090 } else {
1091 let ccr = ®s.ccr1;
1092 }
1093 }
1094 set_ccr!(
1095 ccr,
1096 cfg.priority,
1097 direction,
1098 cfg.circular,
1099 cfg.periph_incr,
1100 cfg.mem_incr,
1101 periph_size,
1102 mem_size
1103 );
1104 }
1105 DmaChannel::C2 => {
1106 cfg_if! {
1107 if #[cfg(any(feature = "f3", feature = "g0"))] {
1108 let ccr = ®s.ch2.cr;
1109 } else {
1110 let ccr = ®s.ccr2;
1111 }
1112 }
1113 set_ccr!(
1114 ccr,
1115 cfg.priority,
1116 direction,
1117 cfg.circular,
1118 cfg.periph_incr,
1119 cfg.mem_incr,
1120 periph_size,
1121 mem_size
1122 );
1123 }
1124 DmaChannel::C3 => {
1125 cfg_if! {
1126 if #[cfg(any(feature = "f3", feature = "g0"))] {
1127 let ccr = ®s.ch3.cr;
1128 } else {
1129 let ccr = ®s.ccr3;
1130 }
1131 }
1132 set_ccr!(
1133 ccr,
1134 cfg.priority,
1135 direction,
1136 cfg.circular,
1137 cfg.periph_incr,
1138 cfg.mem_incr,
1139 periph_size,
1140 mem_size
1141 );
1142 }
1143 DmaChannel::C4 => {
1144 cfg_if! {
1145 if #[cfg(any(feature = "f3", feature = "g0"))] {
1146 let ccr = ®s.ch4.cr;
1147 } else {
1148 let ccr = ®s.ccr4;
1149 }
1150 }
1151 set_ccr!(
1152 ccr,
1153 cfg.priority,
1154 direction,
1155 cfg.circular,
1156 cfg.periph_incr,
1157 cfg.mem_incr,
1158 periph_size,
1159 mem_size
1160 );
1161 }
1162 DmaChannel::C5 => {
1163 cfg_if! {
1164 if #[cfg(any(feature = "f3", feature = "g0"))] {
1165 let ccr = ®s.ch5.cr;
1166 } else {
1167 let ccr = ®s.ccr5;
1168 }
1169 }
1170 set_ccr!(
1171 ccr,
1172 cfg.priority,
1173 direction,
1174 cfg.circular,
1175 cfg.periph_incr,
1176 cfg.mem_incr,
1177 periph_size,
1178 mem_size
1179 );
1180 }
1181 #[cfg(not(feature = "g0"))]
1182 DmaChannel::C6 => {
1183 cfg_if! {
1184 if #[cfg(any(feature = "f3", feature = "g0"))] {
1185 let ccr = ®s.ch6.cr;
1186 } else {
1187 let ccr = ®s.ccr6;
1188 }
1189 }
1190 set_ccr!(
1191 ccr,
1192 cfg.priority,
1193 direction,
1194 cfg.circular,
1195 cfg.periph_incr,
1196 cfg.mem_incr,
1197 periph_size,
1198 mem_size
1199 );
1200 }
1201 #[cfg(not(feature = "g0"))]
1202 DmaChannel::C7 => {
1203 cfg_if! {
1204 if #[cfg(any(feature = "f3", feature = "g0"))] {
1205 let ccr = ®s.ch7.cr;
1206 } else {
1207 let ccr = ®s.ccr7;
1208 }
1209 }
1210 set_ccr!(
1211 ccr,
1212 cfg.priority,
1213 direction,
1214 cfg.circular,
1215 cfg.periph_incr,
1216 cfg.mem_incr,
1217 periph_size,
1218 mem_size
1219 );
1220 }
1221 #[cfg(any(feature = "l5", feature = "g4"))]
1222 DmaChannel::C8 => {
1223 let ccr = ®s.ccr8;
1224 set_ccr!(
1225 ccr,
1226 cfg.priority,
1227 direction,
1228 cfg.circular,
1229 cfg.periph_incr,
1230 cfg.mem_incr,
1231 periph_size,
1232 mem_size
1233 );
1234 }
1235 }
1236}
1237
1238#[cfg(feature = "h7")]
1241pub fn cfg_channel<D>(
1242 regs: &mut D,
1243 channel: DmaChannel,
1244 periph_addr: u32,
1245 mem_addr: u32,
1246 num_data: u32,
1247 direction: Direction,
1248 periph_size: DataSize,
1249 mem_size: DataSize,
1250 cfg: ChannelCfg,
1251) where
1252 D: Deref<Target = dma1::RegisterBlock>,
1253{
1254 regs.st[channel as usize]
1258 .cr
1259 .modify(|_, w| w.en().clear_bit());
1260 while regs.st[channel as usize].cr.read().en().bit_is_set() {}
1261
1262 regs.st[channel as usize]
1267 .par
1268 .write(|w| unsafe { w.bits(periph_addr) });
1269
1270 atomic::compiler_fence(Ordering::SeqCst);
1271
1272 regs.st[channel as usize]
1276 .m0ar
1277 .write(|w| unsafe { w.bits(mem_addr) });
1278
1279 regs.st[channel as usize]
1284 .ndtr
1285 .write(|w| unsafe { w.bits(num_data) });
1286
1287 let cr = ®s.st[channel as usize].cr;
1318
1319 let originally_enabled = cr.read().en().bit_is_set();
1320 if originally_enabled {
1321 cr.modify(|_, w| w.en().clear_bit());
1322 while cr.read().en().bit_is_set() {}
1323 }
1324
1325 cr.modify(|_, w| unsafe {
1326 w.pl().bits(cfg.priority as u8);
1328 w.dir().bits(direction as u8);
1332 w.circ().bit(cfg.circular as u8 != 0);
1334 w.pinc().bit(cfg.periph_incr as u8 != 0);
1336 w.minc().bit(cfg.mem_incr as u8 != 0);
1337 w.psize().bits(periph_size as u8);
1339 w.msize().bits(mem_size as u8);
1340 w.tcie().set_bit();
1342 w.en().set_bit()
1344 });
1345
1346 if originally_enabled {
1347 cr.modify(|_, w| w.en().set_bit());
1348 while cr.read().en().bit_is_clear() {}
1349 }
1350}
1351
1352#[cfg(not(feature = "h7"))]
1354fn stop_internal<D>(regs: &mut D, channel: DmaChannel)
1355where
1356 D: Deref<Target = dma1::RegisterBlock>,
1357{
1358 match channel {
1366 DmaChannel::C1 => {
1367 cfg_if! {
1368 if #[cfg(any(feature = "f3", feature = "g0"))] {
1369 let ccr = ®s.ch1.cr;
1370 } else {
1371 let ccr = ®s.ccr1;
1372 }
1373 }
1374 ccr.modify(|_, w| w.en().clear_bit());
1375 while ccr.read().en().bit_is_set() {}
1376 }
1377 DmaChannel::C2 => {
1378 cfg_if! {
1379 if #[cfg(any(feature = "f3", feature = "g0"))] {
1380 let ccr = ®s.ch2.cr;
1381 } else {
1382 let ccr = ®s.ccr2;
1383 }
1384 }
1385 ccr.modify(|_, w| w.en().clear_bit());
1386 while ccr.read().en().bit_is_set() {}
1387 }
1388 DmaChannel::C3 => {
1389 cfg_if! {
1390 if #[cfg(any(feature = "f3", feature = "g0"))] {
1391 let ccr = ®s.ch3.cr;
1392 } else {
1393 let ccr = ®s.ccr3;
1394 }
1395 }
1396 ccr.modify(|_, w| w.en().clear_bit());
1397 while ccr.read().en().bit_is_set() {}
1398 }
1399 DmaChannel::C4 => {
1400 cfg_if! {
1401 if #[cfg(any(feature = "f3", feature = "g0"))] {
1402 let ccr = ®s.ch4.cr;
1403 } else {
1404 let ccr = ®s.ccr4;
1405 }
1406 }
1407 ccr.modify(|_, w| w.en().clear_bit());
1408 while ccr.read().en().bit_is_set() {}
1409 }
1410 DmaChannel::C5 => {
1411 cfg_if! {
1412 if #[cfg(any(feature = "f3", feature = "g0"))] {
1413 let ccr = ®s.ch5.cr;
1414 } else {
1415 let ccr = ®s.ccr5;
1416 }
1417 }
1418 ccr.modify(|_, w| w.en().clear_bit());
1419 while ccr.read().en().bit_is_set() {}
1420 }
1421 #[cfg(not(feature = "g0"))]
1422 DmaChannel::C6 => {
1423 cfg_if! {
1424 if #[cfg(any(feature = "f3", feature = "g0"))] {
1425 let ccr = ®s.ch6.cr;
1426 } else {
1427 let ccr = ®s.ccr6;
1428 }
1429 }
1430 ccr.modify(|_, w| w.en().clear_bit());
1431 while ccr.read().en().bit_is_set() {}
1432 }
1433 #[cfg(not(feature = "g0"))]
1434 DmaChannel::C7 => {
1435 cfg_if! {
1436 if #[cfg(any(feature = "f3", feature = "g0"))] {
1437 let ccr = ®s.ch7.cr;
1438 } else {
1439 let ccr = ®s.ccr7;
1440 }
1441 }
1442 ccr.modify(|_, w| w.en().clear_bit());
1443 while ccr.read().en().bit_is_set() {}
1444 }
1445 #[cfg(any(feature = "l5", feature = "g4"))]
1446 DmaChannel::C8 => {
1447 let ccr = ®s.ccr8;
1448 ccr.modify(|_, w| w.en().clear_bit());
1449 while ccr.read().en().bit_is_set() {}
1450 }
1451 };
1452
1453 }
1466
1467#[cfg(feature = "h7")]
1469fn stop_internal<D>(regs: &mut D, channel: DmaChannel)
1470where
1471 D: Deref<Target = dma1::RegisterBlock>,
1472{
1473 let cr = ®s.st[channel as usize].cr;
1485 cr.modify(|_, w| w.en().clear_bit());
1486 while cr.read().en().bit_is_set() {}
1487
1488 }
1497
1498pub fn stop(periph: DmaPeriph, channel: DmaChannel) {
1500 match periph {
1501 DmaPeriph::Dma1 => {
1502 let mut regs = unsafe { &(*DMA1::ptr()) };
1503 stop_internal(&mut regs, channel);
1504 }
1505 #[cfg(not(any(feature = "f3x4", feature = "g0", feature = "wb")))]
1506 DmaPeriph::Dma2 => {
1507 let mut regs = unsafe { &(*pac::DMA2::ptr()) };
1508 stop_internal(&mut regs, channel);
1509 }
1510 }
1511}
1512
1513fn clear_interrupt_internal<D>(regs: &mut D, channel: DmaChannel, interrupt: DmaInterrupt)
1514where
1515 D: Deref<Target = dma1::RegisterBlock>,
1516{
1517 cfg_if! {
1518 if #[cfg(any(feature = "g4", feature = "wl"))] {
1519 regs.ifcr.write(|w| match channel {
1520 DmaChannel::C1 => match interrupt {
1521 DmaInterrupt::TransferError => w.teif1().set_bit(),
1522 DmaInterrupt::HalfTransfer => w.htif1().set_bit(),
1523 DmaInterrupt::TransferComplete => w.tcif1().set_bit(),
1524 }
1525 DmaChannel::C2 => match interrupt {
1526 DmaInterrupt::TransferError => w.teif2().set_bit(),
1527 DmaInterrupt::HalfTransfer => w.htif2().set_bit(),
1528 DmaInterrupt::TransferComplete => w.tcif2().set_bit(),
1529 }
1530 DmaChannel::C3 => match interrupt {
1531 DmaInterrupt::TransferError => w.teif3().set_bit(),
1532 DmaInterrupt::HalfTransfer => w.htif3().set_bit(),
1533 DmaInterrupt::TransferComplete => w.tcif3().set_bit(),
1534 }
1535 DmaChannel::C4 => match interrupt {
1536 DmaInterrupt::TransferError => w.teif4().set_bit(),
1537 DmaInterrupt::HalfTransfer => w.htif4().set_bit(),
1538 DmaInterrupt::TransferComplete => w.tcif4().set_bit(),
1539 }
1540 DmaChannel::C5 => match interrupt {
1541 DmaInterrupt::TransferError => w.teif5().set_bit(),
1542 DmaInterrupt::HalfTransfer => w.htif5().set_bit(),
1543 DmaInterrupt::TransferComplete => w.tcif5().set_bit(),
1544 }
1545 DmaChannel::C6 => match interrupt {
1546 DmaInterrupt::TransferError => w.teif6().set_bit(),
1547 DmaInterrupt::HalfTransfer => w.htif6().set_bit(),
1548 DmaInterrupt::TransferComplete => w.tcif6().set_bit(),
1549 }
1550 DmaChannel::C7 => match interrupt {
1551 DmaInterrupt::TransferError => w.teif7().set_bit(),
1552 DmaInterrupt::HalfTransfer => w.htif7().set_bit(),
1553 DmaInterrupt::TransferComplete => w.tcif7().set_bit(),
1554 }
1555 #[cfg(not(feature = "wl"))]
1556 DmaChannel::C8 => match interrupt {
1557 DmaInterrupt::TransferError => w.teif8().set_bit(),
1558 DmaInterrupt::HalfTransfer => w.htif8().set_bit(),
1559 DmaInterrupt::TransferComplete => w.tcif8().set_bit(),
1560 }
1561 });
1562 } else if #[cfg(feature = "h7")] {
1563 match channel {
1564 DmaChannel::C0 => match interrupt {
1565 DmaInterrupt::TransferError => regs.lifcr.write(|w| w.cteif0().set_bit()),
1566 DmaInterrupt::HalfTransfer => regs.lifcr.write(|w| w.chtif0().set_bit()),
1567 DmaInterrupt::TransferComplete => regs.lifcr.write(|w| w.ctcif0().set_bit()),
1568 DmaInterrupt::DirectModeError => regs.lifcr.write(|w| w.cdmeif0().set_bit()),
1569 DmaInterrupt::FifoError => regs.lifcr.write(|w| w.cfeif0().set_bit()),
1570 }
1571 DmaChannel::C1 => match interrupt {
1572 DmaInterrupt::TransferError => regs.lifcr.write(|w| w.cteif1().set_bit()),
1573 DmaInterrupt::HalfTransfer => regs.lifcr.write(|w| w.chtif1().set_bit()),
1574 DmaInterrupt::TransferComplete => regs.lifcr.write(|w| w.ctcif1().set_bit()),
1575 DmaInterrupt::DirectModeError => regs.lifcr.write(|w| w.cdmeif1().set_bit()),
1576 DmaInterrupt::FifoError => regs.lifcr.write(|w| w.cfeif1().set_bit()),
1577 }
1578 DmaChannel::C2 => match interrupt {
1579 DmaInterrupt::TransferError => regs.lifcr.write(|w| w.cteif2().set_bit()),
1580 DmaInterrupt::HalfTransfer => regs.lifcr.write(|w| w.chtif2().set_bit()),
1581 DmaInterrupt::TransferComplete => regs.lifcr.write(|w| w.ctcif2().set_bit()),
1582 DmaInterrupt::DirectModeError => regs.lifcr.write(|w| w.cdmeif2().set_bit()),
1583 DmaInterrupt::FifoError => regs.lifcr.write(|w| w.cfeif2().set_bit()),
1584 }
1585 DmaChannel::C3 => match interrupt {
1586 DmaInterrupt::TransferError => regs.lifcr.write(|w| w.cteif3().set_bit()),
1587 DmaInterrupt::HalfTransfer => regs.lifcr.write(|w| w.chtif3().set_bit()),
1588 DmaInterrupt::TransferComplete => regs.lifcr.write(|w| w.ctcif3().set_bit()),
1589 DmaInterrupt::DirectModeError => regs.lifcr.write(|w| w.cdmeif3().set_bit()),
1590 DmaInterrupt::FifoError => regs.lifcr.write(|w| w.cfeif3().set_bit()),
1591 }
1592 DmaChannel::C4 => match interrupt {
1593 DmaInterrupt::TransferError => regs.hifcr.write(|w| w.cteif4().set_bit()),
1594 DmaInterrupt::HalfTransfer => regs.hifcr.write(|w| w.chtif4().set_bit()),
1595 DmaInterrupt::TransferComplete => regs.hifcr.write(|w| w.ctcif4().set_bit()),
1596 DmaInterrupt::DirectModeError => regs.hifcr.write(|w| w.cdmeif4().set_bit()),
1597 DmaInterrupt::FifoError => regs.hifcr.write(|w| w.cfeif4().set_bit()),
1598 }
1599 DmaChannel::C5 => match interrupt {
1600 DmaInterrupt::TransferError => regs.hifcr.write(|w| w.cteif5().set_bit()),
1601 DmaInterrupt::HalfTransfer => regs.hifcr.write(|w| w.chtif5().set_bit()),
1602 DmaInterrupt::TransferComplete => regs.hifcr.write(|w| w.ctcif5().set_bit()),
1603 DmaInterrupt::DirectModeError => regs.hifcr.write(|w| w.cdmeif5().set_bit()),
1604 DmaInterrupt::FifoError => regs.hifcr.write(|w| w.cfeif5().set_bit()),
1605 }
1606 DmaChannel::C6 => match interrupt {
1607 DmaInterrupt::TransferError => regs.hifcr.write(|w| w.cteif6().set_bit()),
1608 DmaInterrupt::HalfTransfer => regs.hifcr.write(|w| w.chtif6().set_bit()),
1609 DmaInterrupt::TransferComplete => regs.hifcr.write(|w| w.ctcif6().set_bit()),
1610 DmaInterrupt::DirectModeError => regs.hifcr.write(|w| w.cdmeif6().set_bit()),
1611 DmaInterrupt::FifoError => regs.hifcr.write(|w| w.cfeif6().set_bit()),
1612 }
1613 DmaChannel::C7 => match interrupt {
1614 DmaInterrupt::TransferError => regs.hifcr.write(|w| w.cteif7().set_bit()),
1615 DmaInterrupt::HalfTransfer => regs.hifcr.write(|w| w.chtif7().set_bit()),
1616 DmaInterrupt::TransferComplete => regs.hifcr.write(|w| w.ctcif7().set_bit()),
1617 DmaInterrupt::DirectModeError => regs.hifcr.write(|w| w.cdmeif7().set_bit()),
1618 DmaInterrupt::FifoError => regs.hifcr.write(|w| w.cfeif7().set_bit()),
1619 }
1620 }
1621 } else if #[cfg(not(feature = "g0"))] {
1623 regs.ifcr.write(|w| match channel {
1624 DmaChannel::C1 => match interrupt {
1625 DmaInterrupt::TransferError => w.cteif1().set_bit(),
1626 DmaInterrupt::HalfTransfer => w.chtif1().set_bit(),
1627 DmaInterrupt::TransferComplete => w.ctcif1().set_bit(),
1628 }
1629 DmaChannel::C2 => match interrupt {
1630 DmaInterrupt::TransferError => w.cteif2().set_bit(),
1631 DmaInterrupt::HalfTransfer => w.chtif2().set_bit(),
1632 DmaInterrupt::TransferComplete => w.ctcif2().set_bit(),
1633 }
1634 DmaChannel::C3 => match interrupt {
1635 DmaInterrupt::TransferError => w.cteif3().set_bit(),
1636 DmaInterrupt::HalfTransfer => w.chtif3().set_bit(),
1637 DmaInterrupt::TransferComplete => w.ctcif3().set_bit(),
1638 }
1639 DmaChannel::C4 => match interrupt {
1640 DmaInterrupt::TransferError => w.cteif4().set_bit(),
1641 DmaInterrupt::HalfTransfer => w.chtif4().set_bit(),
1642 DmaInterrupt::TransferComplete => w.ctcif4().set_bit(),
1643 }
1644 DmaChannel::C5 => match interrupt {
1645 DmaInterrupt::TransferError => w.cteif5().set_bit(),
1646 DmaInterrupt::HalfTransfer => w.chtif5().set_bit(),
1647 DmaInterrupt::TransferComplete => w.ctcif5().set_bit(),
1648 }
1649 #[cfg(not(feature = "g0"))]
1650 DmaChannel::C6 => match interrupt {
1651 DmaInterrupt::TransferError => w.cteif6().set_bit(),
1652 DmaInterrupt::HalfTransfer => w.chtif6().set_bit(),
1653 DmaInterrupt::TransferComplete => w.ctcif6().set_bit(),
1654 }
1655 #[cfg(not(feature = "g0"))]
1656 DmaChannel::C7 => match interrupt {
1657 DmaInterrupt::TransferError => w.cteif7().set_bit(),
1658 DmaInterrupt::HalfTransfer => w.chtif7().set_bit(),
1659 DmaInterrupt::TransferComplete => w.ctcif7().set_bit(),
1660 }
1661 #[cfg(any(feature = "l5", feature = "g4"))]
1662 DmaChannel::C8 => match interrupt {
1663 DmaInterrupt::TransferError => w.cteif8().set_bit(),
1664 DmaInterrupt::HalfTransfer => w.chtif8().set_bit(),
1665 DmaInterrupt::TransferComplete => w.ctcif8().set_bit(),
1666 }
1667 });
1668 }
1669 }
1670}
1671
1672#[cfg(not(feature = "h7"))]
1674fn enable_interrupt_internal<D>(regs: &mut D, channel: DmaChannel, interrupt: DmaInterrupt)
1675where
1676 D: Deref<Target = dma1::RegisterBlock>,
1677{
1678 match channel {
1680 DmaChannel::C1 => {
1681 cfg_if! {
1682 if #[cfg(any(feature = "f3", feature = "g0"))] {
1683 let ccr = ®s.ch1.cr;
1684 } else {
1685 let ccr = ®s.ccr1;
1686 }
1687 }
1688 enable_interrupt!(ccr, interrupt);
1689 }
1690 DmaChannel::C2 => {
1691 cfg_if! {
1692 if #[cfg(any(feature = "f3", feature = "g0"))] {
1693 let ccr = ®s.ch2.cr;
1694 } else {
1695 let ccr = ®s.ccr2;
1696 }
1697 }
1698 enable_interrupt!(ccr, interrupt);
1699 }
1700 DmaChannel::C3 => {
1701 cfg_if! {
1702 if #[cfg(any(feature = "f3", feature = "g0"))] {
1703 let ccr = ®s.ch3.cr;
1704 } else {
1705 let ccr = ®s.ccr3;
1706 }
1707 }
1708 enable_interrupt!(ccr, interrupt);
1709 }
1710 DmaChannel::C4 => {
1711 cfg_if! {
1712 if #[cfg(any(feature = "f3", feature = "g0"))] {
1713 let ccr = ®s.ch4.cr;
1714 } else {
1715 let ccr = ®s.ccr4;
1716 }
1717 }
1718 enable_interrupt!(ccr, interrupt);
1719 }
1720 DmaChannel::C5 => {
1721 cfg_if! {
1722 if #[cfg(any(feature = "f3", feature = "g0"))] {
1723 let ccr = ®s.ch5.cr;
1724 } else {
1725 let ccr = ®s.ccr5;
1726 }
1727 }
1728 enable_interrupt!(ccr, interrupt);
1729 }
1730 #[cfg(not(feature = "g0"))]
1731 DmaChannel::C6 => {
1732 cfg_if! {
1733 if #[cfg(any(feature = "f3", feature = "g0"))] {
1734 let ccr = ®s.ch6.cr;
1735 } else {
1736 let ccr = ®s.ccr6;
1737 }
1738 }
1739 enable_interrupt!(ccr, interrupt);
1740 }
1741 #[cfg(not(feature = "g0"))]
1742 DmaChannel::C7 => {
1743 cfg_if! {
1744 if #[cfg(any(feature = "f3", feature = "g0"))] {
1745 let ccr = ®s.ch7.cr;
1746 } else {
1747 let ccr = ®s.ccr7;
1748 }
1749 }
1750 enable_interrupt!(ccr, interrupt);
1751 }
1752 #[cfg(any(feature = "l5", feature = "g4"))]
1753 DmaChannel::C8 => {
1754 let ccr = ®s.ccr8;
1755 enable_interrupt!(ccr, interrupt);
1756 }
1757 };
1758}
1759
1760#[cfg(not(feature = "h7"))]
1762fn disable_interrupt_internal<D>(regs: &mut D, channel: DmaChannel, interrupt: DmaInterrupt)
1763where
1764 D: Deref<Target = dma1::RegisterBlock>,
1765{
1766 match channel {
1768 DmaChannel::C1 => {
1769 cfg_if! {
1770 if #[cfg(any(feature = "f3", feature = "g0"))] {
1771 let ccr = ®s.ch1.cr;
1772 } else {
1773 let ccr = ®s.ccr1;
1774 }
1775 }
1776 disable_interrupt!(ccr, interrupt);
1777 }
1778 DmaChannel::C2 => {
1779 cfg_if! {
1780 if #[cfg(any(feature = "f3", feature = "g0"))] {
1781 let ccr = ®s.ch2.cr;
1782 } else {
1783 let ccr = ®s.ccr2;
1784 }
1785 }
1786 disable_interrupt!(ccr, interrupt);
1787 }
1788 DmaChannel::C3 => {
1789 cfg_if! {
1790 if #[cfg(any(feature = "f3", feature = "g0"))] {
1791 let ccr = ®s.ch3.cr;
1792 } else {
1793 let ccr = ®s.ccr3;
1794 }
1795 }
1796 disable_interrupt!(ccr, interrupt);
1797 }
1798 DmaChannel::C4 => {
1799 cfg_if! {
1800 if #[cfg(any(feature = "f3", feature = "g0"))] {
1801 let ccr = ®s.ch4.cr;
1802 } else {
1803 let ccr = ®s.ccr4;
1804 }
1805 }
1806 disable_interrupt!(ccr, interrupt);
1807 }
1808 DmaChannel::C5 => {
1809 cfg_if! {
1810 if #[cfg(any(feature = "f3", feature = "g0"))] {
1811 let ccr = ®s.ch5.cr;
1812 } else {
1813 let ccr = ®s.ccr5;
1814 }
1815 }
1816 disable_interrupt!(ccr, interrupt);
1817 }
1818 #[cfg(not(feature = "g0"))]
1819 DmaChannel::C6 => {
1820 cfg_if! {
1821 if #[cfg(any(feature = "f3", feature = "g0"))] {
1822 let ccr = ®s.ch6.cr;
1823 } else {
1824 let ccr = ®s.ccr6;
1825 }
1826 }
1827 disable_interrupt!(ccr, interrupt);
1828 }
1829 #[cfg(not(feature = "g0"))]
1830 DmaChannel::C7 => {
1831 cfg_if! {
1832 if #[cfg(any(feature = "f3", feature = "g0"))] {
1833 let ccr = ®s.ch7.cr;
1834 } else {
1835 let ccr = ®s.ccr7;
1836 }
1837 }
1838 disable_interrupt!(ccr, interrupt);
1839 }
1840 #[cfg(any(feature = "l5", feature = "g4"))]
1841 DmaChannel::C8 => {
1842 let ccr = ®s.ccr8;
1843 disable_interrupt!(ccr, interrupt);
1844 }
1845 };
1846}
1847
1848#[cfg(feature = "h7")]
1849fn enable_interrupt_internal<D>(regs: &mut D, channel: DmaChannel, interrupt: DmaInterrupt)
1850where
1851 D: Deref<Target = dma1::RegisterBlock>,
1852{
1853 let cr = ®s.st[channel as usize].cr;
1855
1856 match interrupt {
1857 DmaInterrupt::TransferError => cr.modify(|_, w| w.teie().set_bit()),
1858 DmaInterrupt::HalfTransfer => cr.modify(|_, w| w.htie().set_bit()),
1859 DmaInterrupt::TransferComplete => cr.modify(|_, w| w.tcie().set_bit()),
1860 DmaInterrupt::DirectModeError => cr.modify(|_, w| w.dmeie().set_bit()),
1861 DmaInterrupt::FifoError => regs.st[channel as usize]
1862 .fcr
1863 .modify(|_, w| w.feie().set_bit()),
1864 }
1865}
1866
1867#[cfg(feature = "h7")]
1868fn disable_interrupt_internal<D>(regs: &mut D, channel: DmaChannel, interrupt: DmaInterrupt)
1869where
1870 D: Deref<Target = dma1::RegisterBlock>,
1871{
1872 let cr = ®s.st[channel as usize].cr;
1874
1875 match interrupt {
1878 DmaInterrupt::TransferError => cr.modify(|_, w| w.teie().clear_bit()),
1879 DmaInterrupt::HalfTransfer => cr.modify(|_, w| w.htie().clear_bit()),
1880 DmaInterrupt::TransferComplete => cr.modify(|_, w| w.tcie().clear_bit()),
1881 DmaInterrupt::DirectModeError => cr.modify(|_, w| w.dmeie().clear_bit()),
1882 DmaInterrupt::FifoError => regs.st[channel as usize]
1883 .fcr
1884 .modify(|_, w| w.feie().clear_bit()),
1885 }
1886}
1887
1888pub fn enable_interrupt(periph: DmaPeriph, channel: DmaChannel, interrupt: DmaInterrupt) {
1890 match periph {
1891 DmaPeriph::Dma1 => {
1892 let mut regs = unsafe { &(*DMA1::ptr()) };
1893 enable_interrupt_internal(&mut regs, channel, interrupt);
1894 }
1895 #[cfg(not(any(feature = "f3x4", feature = "g0", feature = "wb")))]
1896 DmaPeriph::Dma2 => {
1897 let mut regs = unsafe { &(*pac::DMA2::ptr()) };
1898 enable_interrupt_internal(&mut regs, channel, interrupt);
1899 }
1900 }
1901}
1902
1903pub fn disable_interrupt(periph: DmaPeriph, channel: DmaChannel, interrupt: DmaInterrupt) {
1905 match periph {
1906 DmaPeriph::Dma1 => {
1907 let mut regs = unsafe { &(*DMA1::ptr()) };
1908 disable_interrupt_internal(&mut regs, channel, interrupt);
1909 }
1910 #[cfg(not(any(feature = "f3x4", feature = "g0", feature = "wb")))]
1911 DmaPeriph::Dma2 => {
1912 let mut regs = unsafe { &(*pac::DMA2::ptr()) };
1913 disable_interrupt_internal(&mut regs, channel, interrupt);
1914 }
1915 }
1916}
1917
1918pub fn clear_interrupt(periph: DmaPeriph, channel: DmaChannel, interrupt: DmaInterrupt) {
1920 match periph {
1921 DmaPeriph::Dma1 => {
1922 let mut regs = unsafe { &(*DMA1::ptr()) };
1923 clear_interrupt_internal(&mut regs, channel, interrupt);
1924 }
1925 #[cfg(not(any(feature = "f3x4", feature = "g0", feature = "wb")))]
1926 DmaPeriph::Dma2 => {
1927 let mut regs = unsafe { &(*pac::DMA2::ptr()) };
1928 clear_interrupt_internal(&mut regs, channel, interrupt);
1929 }
1930 }
1931}
1932
1933#[cfg(any(
1934 feature = "l5",
1935 feature = "g0",
1936 feature = "g4",
1937 feature = "h7",
1938 feature = "wb",
1939 feature = "wl",
1940))]
1941pub fn mux(periph: DmaPeriph, channel: DmaChannel, input: DmaInput) {
1943 unsafe {
1973 let mux = unsafe { &(*DMAMUX::ptr()) };
1974
1975 #[cfg(feature = "g4")]
1976 let rcc = unsafe { &(*RCC::ptr()) };
1977 #[cfg(feature = "g4")]
1978 rcc.ahb1enr.modify(|_, w| w.dmamuxen().set_bit());
1979
1980 match periph {
1981 DmaPeriph::Dma1 => {
1982 #[cfg(not(feature = "h7"))]
1983 match channel {
1984 DmaChannel::C1 => mux.c0cr.modify(|_, w| w.dmareq_id().bits(input as u8)),
1987 DmaChannel::C2 => mux.c1cr.modify(|_, w| w.dmareq_id().bits(input as u8)),
1988 DmaChannel::C3 => mux.c2cr.modify(|_, w| w.dmareq_id().bits(input as u8)),
1989 DmaChannel::C4 => mux.c3cr.modify(|_, w| w.dmareq_id().bits(input as u8)),
1990 DmaChannel::C5 => mux.c4cr.modify(|_, w| w.dmareq_id().bits(input as u8)),
1991 #[cfg(not(feature = "g0"))]
1992 DmaChannel::C6 => mux.c5cr.modify(|_, w| w.dmareq_id().bits(input as u8)),
1993 #[cfg(not(feature = "g0"))]
1994 DmaChannel::C7 => mux.c6cr.modify(|_, w| w.dmareq_id().bits(input as u8)),
1995 #[cfg(any(feature = "l5", feature = "g4"))]
1996 DmaChannel::C8 => mux.c7cr.modify(|_, w| w.dmareq_id().bits(input as u8)),
1997 }
1998
1999 #[cfg(feature = "h7")]
2000 mux.ccr[channel as usize].modify(|_, w| w.dmareq_id().bits(input as u8));
2001 }
2002 #[cfg(not(any(
2003 all(feature = "g0", not(any(feature = "g0b1", feature = "g0c1"))),
2004 feature = "wb"
2005 )))]
2006 DmaPeriph::Dma2 => {
2007 #[cfg(not(feature = "h7"))]
2008 match channel {
2009 DmaChannel::C1 => mux.c8cr.modify(|_, w| w.dmareq_id().bits(input as u8)),
2010 DmaChannel::C2 => mux.c9cr.modify(|_, w| w.dmareq_id().bits(input as u8)),
2011 DmaChannel::C3 => mux.c10cr.modify(|_, w| w.dmareq_id().bits(input as u8)),
2012 DmaChannel::C4 => mux.c11cr.modify(|_, w| w.dmareq_id().bits(input as u8)),
2013 DmaChannel::C5 => mux.c12cr.modify(|_, w| w.dmareq_id().bits(input as u8)),
2014 #[cfg(not(feature = "g0"))]
2015 DmaChannel::C6 => mux.c13cr.modify(|_, w| w.dmareq_id().bits(input as u8)),
2016 #[cfg(not(any(feature = "g0", feature = "wb", feature = "wl")))]
2017 DmaChannel::C7 => mux.c14cr.modify(|_, w| w.dmareq_id().bits(input as u8)),
2018 #[cfg(any(feature = "wb", feature = "wl"))]
2019 DmaChannel::C7 => (), #[cfg(any(feature = "l5", feature = "g4"))]
2021 DmaChannel::C8 => mux.c15cr.modify(|_, w| w.dmareq_id().bits(input as u8)),
2022 }
2023
2024 #[cfg(feature = "h7")]
2025 mux.ccr[channel as usize + 8].modify(|_, w| w.dmareq_id().bits(input as u8));
2026 }
2027 }
2028 }
2029}
2030
2031#[cfg(feature = "h7")]
2032pub fn mux2(periph: DmaPeriph, channel: DmaChannel, input: DmaInput2, mux: &mut DMAMUX2) {
2034 mux.ccr[channel as usize].modify(|_, w| unsafe { w.dmareq_id().bits(input as u8) });
2035}
2036
2037#[cfg(any(feature = "g4", feature = "wb"))]
2041pub fn enable_mux1() {
2042 let rcc = unsafe { &(*RCC::ptr()) };
2043
2044 cfg_if! {
2045 if #[cfg(feature = "g4")] {
2046 rcc.ahb1enr.modify(|_, w| w.dmamuxen().set_bit());
2048 rcc.ahb1rstr.modify(|_, w| w.dmamux1rst().set_bit());
2049 rcc.ahb1rstr.modify(|_, w| w.dmamux1rst().clear_bit());
2050 } else {
2051 rcc_en_reset!(ahb1, dmamux, rcc);
2052 }
2053 }
2054}
2055
2056#[cfg(feature = "l4")] pub(crate) fn channel_select<D>(regs: &mut D, input: DmaInput)
2060where
2061 D: Deref<Target = dma1::RegisterBlock>,
2062{
2063 let val = input.dma1_channel_select();
2065 regs.cselr.modify(|_, w| match input.dma1_channel() {
2066 DmaChannel::C1 => w.c1s().bits(val),
2067 DmaChannel::C2 => w.c2s().bits(val),
2068 DmaChannel::C3 => w.c3s().bits(val),
2069 DmaChannel::C4 => w.c4s().bits(val),
2070 DmaChannel::C5 => w.c5s().bits(val),
2071 DmaChannel::C6 => w.c6s().bits(val),
2072 DmaChannel::C7 => w.c7s().bits(val),
2073 });
2074}
2075
2076macro_rules! make_chan_struct {
2078 ($periph: expr, $ch:expr) => {
2080 paste! {
2081 pub struct [<Dma $periph Ch $ch>] {
2083 }
2086
2087 impl [<Dma $periph Ch $ch>] {
2088 pub fn new() -> Self {
2093 let rcc = unsafe { &(*RCC::ptr()) };
2095 cfg_if! {
2096 if #[cfg(feature = "f3")] {
2097 rcc.ahbenr.modify(|_, w| w.dma1en().set_bit()); } else if #[cfg(feature = "g0")] {
2099 rcc_en_reset!(ahb1, dma, rcc);
2100 } else {
2101 rcc_en_reset!(ahb1, [<dma $periph>], rcc);
2102 }
2103 }
2104
2105 Self { }
2106 }
2107
2108 fn regs(&self) -> &[<dma $periph>]::RegisterBlock {
2109 unsafe { &(*[<DMA $periph>]::ptr())}
2110 }
2111
2112 #[cfg(feature = "h7")]
2113 fn ccr(&self) -> &[<dma $periph>]::st::CR {
2114 &self.regs().st[$ch].cr
2116 }
2117
2118 #[cfg(not(any(feature = "h7", feature = "f3", feature = "g0")))]
2119 fn ccr(&self) -> &[<dma $periph>]::[<CCR $ch>] {
2120 &self.regs().[<ccr $ch>]
2121 }
2122
2123 #[cfg(any(feature = "f3", feature = "g0"))]
2124 fn ccr(&self) -> i8 {
2126 &self.regs().[<ch $ch>].cr
2127 }
2128
2129 #[cfg(not(feature = "h7"))] pub fn cfg_channel(
2133 &mut self,
2134 periph_addr: u32,
2135 mem_addr: u32,
2136 num_data: u16,
2137 direction: Direction,
2138 periph_size: DataSize,
2139 mem_size: DataSize,
2140 cfg: ChannelCfg,
2141 ) {
2142 cfg_channel(
2143 &mut self.regs(),
2144 DmaChannel::[<C $ch>],
2145 periph_addr,
2146 mem_addr,
2147 num_data,
2148 direction,
2149 periph_size,
2150 mem_size,
2151 cfg,
2152 )
2153 }
2154
2155 #[cfg(feature = "h7")]
2156 pub fn cfg_channel(
2159 &mut self,
2160 periph_addr: u32,
2161 mem_addr: u32,
2162 num_data: u32,
2163 direction: Direction,
2164 periph_size: DataSize,
2165 mem_size: DataSize,
2166 cfg: ChannelCfg,
2167 ) {
2168 cfg_channel(
2169 &mut self.regs(),
2170 DmaChannel::[<C $ch>],
2171 periph_addr,
2172 mem_addr,
2173 num_data,
2174 direction,
2175 periph_size,
2176 mem_size,
2177 cfg,
2178 )
2179 }
2180
2181 pub fn stop(&mut self) {
2183 let ccr = self.ccr();
2184
2185 ccr.modify(|_, w| w.en().clear_bit());
2186 while ccr.read().en().bit_is_set() {}
2187 }
2188
2189 pub fn enable_interrupt(&mut self, interrupt: DmaInterrupt) {
2191 enable_interrupt_internal(&mut self.regs(), DmaChannel::[<C $ch>], interrupt);
2192 }
2193
2194 pub fn clear_interrupt(&mut self, interrupt: DmaInterrupt) {
2196 clear_interrupt_internal(&mut self.regs(), DmaChannel::[<C $ch>], interrupt);
2197 }
2198 }
2200 }
2201 };
2202}
2203
2204cfg_if! {
2208 if #[cfg(not(any(feature = "f3", feature = "g0")))] {
2209 #[cfg(feature = "h7")]
2210 make_chan_struct!(1, 0);
2211 make_chan_struct!(1, 1);
2212 make_chan_struct!(1, 2);
2213 make_chan_struct!(1, 3);
2214 make_chan_struct!(1, 4);
2215 make_chan_struct!(1, 5);
2216 #[cfg(not(feature = "g0"))]
2217 make_chan_struct!(1, 6);
2218 #[cfg(not(feature = "g0"))]
2219 make_chan_struct!(1, 7);
2220 #[cfg(any(feature = "l5", feature = "g4"))]
2221 make_chan_struct!(1, 8);
2222
2223 #[cfg(feature = "h7")]
2224 make_chan_struct!(2, 0);
2225 #[cfg(not(any(feature = "g0", feature = "wb")))]
2226 make_chan_struct!(2, 1);
2227 #[cfg(not(any(feature = "g0", feature = "wb")))]
2228 make_chan_struct!(2, 2);
2229 #[cfg(not(any(feature = "g0", feature = "wb")))]
2230 make_chan_struct!(2, 3);
2231 #[cfg(not(any(feature = "g0", feature = "wb")))]
2232 make_chan_struct!(2, 4);
2233 #[cfg(not(any(feature = "g0", feature = "wb")))]
2234 make_chan_struct!(2, 5);
2235 #[cfg(not(any(feature = "g0", feature = "wb")))]
2236 make_chan_struct!(2, 6);
2237 #[cfg(not(any(feature = "g0", feature = "wb")))]
2238 make_chan_struct!(2, 7);
2239 #[cfg(any(feature = "l5", feature = "g4"))]
2240 make_chan_struct!(2, 8);
2241 }
2242}