1#[cfg(feature = "embedded_hal")]
13use core::convert::Infallible;
14
15#[cfg(feature = "embedded_hal")]
16use embedded_hal::digital::{ErrorType, InputPin, OutputPin, StatefulOutputPin};
17
18use crate::pac::{self, EXTI, RCC};
19#[cfg(not(feature = "h7"))]
20use crate::util::rcc_en_reset;
21
22cfg_if! {
32 if #[cfg(all(feature = "g0", not(any(feature = "g0b1", feature = "g0c1"))))] {
33 use crate::pac::DMA as DMA1;
34 } else if #[cfg(any(feature = "f4", feature = "h5"))] {} else {
35 use crate::pac::DMA1;
36 }
37}
38
39use cfg_if::cfg_if;
40use paste::paste;
41
42#[cfg(not(any(feature = "f4", feature = "l552", feature = "h5")))]
43use crate::dma::{self, ChannelCfg, DmaChannel};
44
45#[derive(Copy, Clone)]
46#[repr(u8)]
47pub enum PinMode {
49 Input,
51 Output,
53 Alt(u8),
56 Analog,
59}
60
61impl PinMode {
62 fn val(&self) -> u8 {
65 match self {
66 Self::Input => 0b00,
67 Self::Output => 0b01,
68 Self::Alt(_) => 0b10,
69 Self::Analog => 0b11,
70 }
71 }
72}
73
74#[derive(Copy, Clone)]
75#[repr(u8)]
76pub enum OutputType {
78 PushPull = 0,
79 OpenDrain = 1,
80}
81
82#[derive(Copy, Clone)]
83#[repr(u8)]
84pub enum OutputSpeed {
88 Low = 0b00,
89 Medium = 0b01,
90 #[cfg(not(feature = "f3"))]
91 High = 0b10, VeryHigh = 0b11, }
94
95#[derive(Copy, Clone)]
96#[repr(u8)]
97pub enum Pull {
100 Floating = 0b00,
101 Up = 0b01,
102 Dn = 0b10,
103}
104
105#[derive(Copy, Clone)]
106#[repr(u8)]
107pub enum PinState {
109 High = 1,
110 Low = 0,
111}
112
113#[derive(Copy, Clone)]
114#[repr(u8)]
115pub enum CfgLock {
117 NotLocked = 0,
118 Locked = 1,
119}
120
121#[derive(Copy, Clone)]
122#[repr(u8)]
123pub enum ResetState {
125 NoAction = 0,
126 Reset = 1,
127}
128
129#[derive(Copy, Clone, PartialEq)]
131pub enum Port {
133 A,
134 B,
135 #[cfg(not(feature = "wl"))]
136 C,
137 #[cfg(not(any(feature = "f410", feature = "wl")))]
138 D,
139 #[cfg(not(any(
140 feature = "f301",
141 feature = "f3x4",
142 feature = "f410",
143 feature = "g0",
144 feature = "wb",
145 feature = "wl"
146 )))]
147 E,
148 #[cfg(not(any(
149 feature = "f401",
150 feature = "f410",
151 feature = "f411",
152 feature = "l4x1",
153 feature = "l4x2",
154 feature = "l412",
155 feature = "l4x3",
156 feature = "wb",
157 feature = "wl"
158 )))]
159 F,
160 #[cfg(not(any(
161 feature = "f373",
162 feature = "f301",
163 feature = "f3x4",
164 feature = "f401",
165 feature = "f410",
166 feature = "f411",
167 feature = "l4x1",
168 feature = "l4x2",
169 feature = "l412",
170 feature = "l4x3",
171 feature = "g0",
172 feature = "wb",
173 feature = "wl"
174 )))]
175 G,
176 #[cfg(not(any(
177 feature = "f373",
178 feature = "f301",
179 feature = "f3x4",
180 feature = "f410",
181 feature = "l4x1",
182 feature = "l4x2",
183 feature = "l412",
184 feature = "l4x3",
185 feature = "g0",
186 feature = "g4",
187 feature = "wb",
188 feature = "wl"
189 )))]
190 H,
191 #[cfg(any(feature = "h747cm4", feature = "h747cm7", feature = "l4x6",))]
192 I,
193}
194
195impl Port {
196 fn cr_val(&self) -> u8 {
198 match self {
199 Self::A => 0,
200 Self::B => 1,
201 #[cfg(not(feature = "wl"))]
202 Self::C => 2,
203 #[cfg(not(any(feature = "f410", feature = "wl")))]
204 Self::D => 3,
205 #[cfg(not(any(
206 feature = "f301",
207 feature = "f3x4",
208 feature = "f410",
209 feature = "g0",
210 feature = "wb",
211 feature = "wl"
212 )))]
213 Self::E => 4,
214 #[cfg(not(any(
215 feature = "f401",
216 feature = "f410",
217 feature = "f411",
218 feature = "l4x1",
219 feature = "l4x2",
220 feature = "l412",
221 feature = "l4x3",
222 feature = "wb",
223 feature = "wl"
224 )))]
225 Self::F => 5,
226 #[cfg(not(any(
227 feature = "f373",
228 feature = "f301",
229 feature = "f3x4",
230 feature = "f401",
231 feature = "f410",
232 feature = "f411",
233 feature = "l4x1",
234 feature = "l4x2",
235 feature = "l412",
236 feature = "l4x3",
237 feature = "g0",
238 feature = "wb",
240 feature = "wl"
241 )))]
242 Self::G => 6,
243 #[cfg(not(any(
244 feature = "f373",
245 feature = "f301",
246 feature = "f3x4",
247 feature = "f410",
248 feature = "l4x1",
249 feature = "l4x2",
250 feature = "l412",
251 feature = "l4x3",
252 feature = "g0",
253 feature = "g4",
254 feature = "wb",
255 feature = "wl"
256 )))]
257 Self::H => 7,
258 #[cfg(any(feature = "h747cm4", feature = "h747cm7", feature = "l4x6",))]
259 Self::I => 8,
260 }
261 }
262}
263
264#[derive(Copy, Clone, Debug)]
265pub enum Edge {
267 Rising,
269 Falling,
271 Either,
273}
274
275macro_rules! set_field {
277 ($regs:expr, $pin:expr, $reg:ident,$field:ident, $bit:ident, $val:expr, [$($num:expr),+]) => {
278 paste! {
279 unsafe {
280 match $pin {
281 $(
282 $num => (*$regs).$reg.modify(|_, w| w.[<$field $num>]().$bit($val)),
283 )+
284 _ => panic!("GPIO pins must be 0 - 15."),
285 }
286 }
287 }
288 }
289}
290
291macro_rules! set_alt {
292 ($regs: expr, $pin:expr, $field_af:ident, $val:expr, [$(($num:expr, $lh:ident)),+]) => {
293 paste! {
294 unsafe {
295 match $pin {
296 $(
297 $num => {
298 #[cfg(feature = "h5")]
299 (*$regs).moder.modify(|_, w| w.[<mode $num>]().bits(PinMode::Alt(0).val()));
300 #[cfg(not(feature = "h5"))]
301 (*$regs).moder.modify(|_, w| w.[<moder $num>]().bits(PinMode::Alt(0).val()));
302 #[cfg(any(feature = "l5", feature = "g0", feature = "h5", feature = "h7", feature = "wb"))]
303 (*$regs).[<afr $lh>].modify(|_, w| w.[<$field_af $num>]().bits($val));
304 #[cfg(not(any(feature = "l5", feature = "g0", feature = "h5", feature = "h7", feature = "wb")))]
305 (*$regs).[<afr $lh>].modify(|_, w| w.[<$field_af $lh $num>]().bits($val));
306 }
307 )+
308 _ => panic!("GPIO pins must be 0 - 15."),
309 }
310 }
311 }
312 }
313}
314
315macro_rules! get_input_data {
316 ($regs: expr, $pin:expr, [$($num:expr),+]) => {
317 paste! {
318 unsafe {
319 match $pin {
320 $(
321 #[cfg(feature = "h5")]
322 $num => (*$regs).idr.read().[<id $num>]().bit_is_set(),
323 #[cfg(not(feature = "h5"))]
324 $num => (*$regs).idr.read().[<idr $num>]().bit_is_set(),
325 )+
326 _ => panic!("GPIO pins must be 0 - 15."),
327 }
328 }
329 }
330 }
331}
332
333macro_rules! set_state {
334 ($regs: expr, $pin:expr, $offset: expr, [$($num:expr),+]) => {
335 paste! {
336 unsafe {
337 match $pin {
338 $(
339 $num => (*$regs).bsrr.write(|w| w.bits(1 << ($offset + $num))),
340 )+
341 _ => panic!("GPIO pins must be 0 - 15."),
342 }
343 }
344 }
345 }
346}
347
348macro_rules! set_exti {
352 ($pin:expr, $rising:expr, $falling:expr, $val:expr, [$(($num:expr, $crnum:expr)),+]) => {
353 let exti = unsafe { &(*pac::EXTI::ptr()) };
354 let syscfg = unsafe { &(*pac::SYSCFG::ptr()) };
355
356 paste! {
357 match $pin {
358 $(
359 $num => {
360 cfg_if! {
362 if #[cfg(all(feature = "h7", not(any(feature = "h747cm4", feature = "h747cm7"))))] {
363 exti.cpuimr1.modify(|_, w| w.[<mr $num>]().set_bit());
364 } else if #[cfg(any(feature = "h747cm4", feature = "h747cm7"))] {
365 exti.c1imr1.modify(|_, w| w.[<mr $num>]().set_bit());
366 } else if #[cfg(any(feature = "g4", feature = "wb", feature = "wl"))] {
367 exti.imr1.modify(|_, w| w.[<im $num>]().set_bit());
368 } else {
369 exti.imr1.modify(|_, w| w.[<mr $num>]().set_bit());
370 }
371 }
372
373 cfg_if! {
374 if #[cfg(any(feature = "g4", feature = "wb", feature = "wl"))] {
375 exti.rtsr1.modify(|_, w| w.[<rt $num>]().bit($rising));
376 exti.ftsr1.modify(|_, w| w.[<ft $num>]().bit($falling));
377 } else {
385 exti.rtsr1.modify(|_, w| w.[<tr $num>]().bit($rising));
386 exti.ftsr1.modify(|_, w| w.[<tr $num>]().bit($falling));
387 }
388 }
389 syscfg
390 .[<exticr $crnum>]
391 .modify(|_, w| unsafe { w.[<exti $num>]().bits($val) });
392 }
393 )+
394 _ => panic!("GPIO pins must be 0 - 15."),
395 }
396 }
397 }
398}
399
400#[cfg(feature = "f4")]
401macro_rules! set_exti_f4 {
403 ($pin:expr, $rising:expr, $falling:expr, $val:expr, [$(($num:expr, $crnum:expr)),+]) => {
404 let exti = unsafe { &(*pac::EXTI::ptr()) };
405 let syscfg = unsafe { &(*pac::SYSCFG::ptr()) };
406
407 paste! {
408 match $pin {
409 $(
410 $num => {
411 exti.imr.modify(|_, w| w.[<mr $num>]().unmasked());
412 exti.rtsr.modify(|_, w| w.[<tr $num>]().bit($rising));
413 exti.ftsr.modify(|_, w| w.[<tr $num>]().bit($falling));
414 syscfg
415 .[<exticr $crnum>]
416 .modify(|_, w| unsafe { w.[<exti $num>]().bits($val) });
417 }
418 )+
419 _ => panic!("GPIO pins must be 0 - 15."),
420 }
421 }
422 }
423}
424
425#[cfg(any(feature = "l5", feature = "h5"))]
426macro_rules! set_exti_l5 {
428 ($pin:expr, $rising:expr, $falling:expr, $val:expr, [$(($num:expr, $crnum:expr, $num2:expr)),+]) => {
429 let exti = unsafe { &(*pac::EXTI::ptr()) };
430
431 paste! {
432 match $pin {
433 $(
434 $num => {
435 exti.imr1.modify(|_, w| w.[<im $num>]().set_bit()); exti.rtsr1.modify(|_, w| w.[<rt $num>]().bit($rising)); exti.ftsr1.modify(|_, w| w.[<ft $num>]().bit($falling)); #[cfg(feature = "l5")]
440 exti
441 .[<exticr $crnum>]
442 .modify(|_, w| unsafe { w.[<exti $num2>]().bits($val) });
443
444 #[cfg(feature = "h5")]
445 exti
446 .[<exticr $crnum>]
447 .modify(|_, w| unsafe { w.[<exti $num>]().bits($val) });
448 }
449 )+
450 _ => panic!("GPIO pins must be 0 - 15."),
451 }
452 }
453 }
454}
455
456#[cfg(feature = "g0")]
457macro_rules! set_exti_g0 {
459 ($pin:expr, $rising:expr, $falling:expr, $val:expr, [$(($num:expr, $crnum:expr, $num2:expr)),+]) => {
460 let exti = unsafe { &(*pac::EXTI::ptr()) };
461
462 paste! {
463 match $pin {
464 $(
465 $num => {
466 exti.imr1.modify(|_, w| w.[<im $num>]().set_bit()); exti.rtsr1.modify(|_, w| w.[<tr $num>]().bit($rising)); exti.ftsr1.modify(|_, w| w.[<tr $num>]().bit($falling)); exti
471 .[<exticr $crnum>]
472 .modify(|_, w| unsafe { w.[<exti $num2>]().bits($val) });
473 }
474 )+
475 _ => panic!("GPIO pins must be 0 - 15."),
476 }
477 }
478 }
479}
480
481#[derive(Clone)]
482pub struct Pin {
484 pub port: Port,
486 pub pin: u8,
488}
489
490impl Pin {
491 const fn regs(&self) -> *const pac::gpioa::RegisterBlock {
493 regs(self.port)
496 }
497
498 pub fn new(port: Port, pin: u8, mode: PinMode) -> Self {
502 assert!(pin <= 15, "Pin must be 0 - 15.");
503
504 let rcc = unsafe { &(*RCC::ptr()) };
505
506 match port {
507 Port::A => {
508 cfg_if! {
509 if #[cfg(feature = "f3")] {
510 if rcc.ahbenr.read().iopaen().bit_is_clear() {
511 rcc_en_reset!(ahb1, iopa, rcc);
512 }
513 } else if #[cfg(feature = "h7")] {
514 if rcc.ahb4enr.read().gpioaen().bit_is_clear() {
515 rcc.ahb4enr.modify(|_, w| w.gpioaen().set_bit());
516 rcc.ahb4rstr.modify(|_, w| w.gpioarst().set_bit());
517 rcc.ahb4rstr.modify(|_, w| w.gpioarst().clear_bit());
518 }
519 } else if #[cfg(feature = "f4")] {
520 if rcc.ahb1enr.read().gpioaen().bit_is_clear() {
521 rcc_en_reset!(ahb1, gpioa, rcc);
522 }
523 } else if #[cfg(feature = "g0")] {
524 if rcc.iopenr.read().iopaen().bit_is_clear() {
525 rcc.iopenr.modify(|_, w| w.iopaen().set_bit());
526 rcc.ioprstr.modify(|_, w| w.ioparst().set_bit());
527 rcc.ioprstr.modify(|_, w| w.ioparst().clear_bit());
528 }
529 } else { if rcc.ahb2enr.read().gpioaen().bit_is_clear() {
531 rcc_en_reset!(ahb2, gpioa, rcc);
532 }
533 }
534 }
535 }
536 Port::B => {
537 cfg_if! {
538 if #[cfg(feature = "f3")] {
539 if rcc.ahbenr.read().iopben().bit_is_clear() {
540 rcc_en_reset!(ahb1, iopb, rcc);
541 }
542 } else if #[cfg(feature = "h7")] {
543 if rcc.ahb4enr.read().gpioben().bit_is_clear() {
544 rcc.ahb4enr.modify(|_, w| w.gpioben().set_bit());
545 rcc.ahb4rstr.modify(|_, w| w.gpiobrst().set_bit());
546 rcc.ahb4rstr.modify(|_, w| w.gpiobrst().clear_bit());
547 }
548 } else if #[cfg(feature = "f4")] {
549 if rcc.ahb1enr.read().gpioben().bit_is_clear() {
550 rcc_en_reset!(ahb1, gpiob, rcc);
551 }
552 } else if #[cfg(feature = "g0")] {
553 if rcc.iopenr.read().iopben().bit_is_clear() {
554 rcc.iopenr.modify(|_, w| w.iopben().set_bit());
555 rcc.ioprstr.modify(|_, w| w.iopbrst().set_bit());
556 rcc.ioprstr.modify(|_, w| w.iopbrst().clear_bit());
557 }
558 } else { if rcc.ahb2enr.read().gpioben().bit_is_clear() {
560 rcc_en_reset!(ahb2, gpiob, rcc);
561 }
562 }
563 }
564 }
565 #[cfg(not(feature = "wl"))]
566 Port::C => {
567 cfg_if! {
568 if #[cfg(feature = "f3")] {
569 if rcc.ahbenr.read().iopcen().bit_is_clear() {
570 rcc_en_reset!(ahb1, iopc, rcc);
571 }
572 } else if #[cfg(feature = "h7")] {
573 if rcc.ahb4enr.read().gpiocen().bit_is_clear() {
574 rcc.ahb4enr.modify(|_, w| w.gpiocen().set_bit());
575 rcc.ahb4rstr.modify(|_, w| w.gpiocrst().set_bit());
576 rcc.ahb4rstr.modify(|_, w| w.gpiocrst().clear_bit());
577 }
578 } else if #[cfg(feature = "f4")] {
579 if rcc.ahb1enr.read().gpiocen().bit_is_clear() {
580 rcc_en_reset!(ahb1, gpioc, rcc);
581 }
582 } else if #[cfg(feature = "g0")] {
583 if rcc.iopenr.read().iopcen().bit_is_clear() {
584 rcc.iopenr.modify(|_, w| w.iopcen().set_bit());
585 rcc.ioprstr.modify(|_, w| w.iopcrst().set_bit());
586 rcc.ioprstr.modify(|_, w| w.iopcrst().clear_bit());
587 }
588 } else { if rcc.ahb2enr.read().gpiocen().bit_is_clear() {
590 rcc_en_reset!(ahb2, gpioc, rcc);
591 }
592 }
593 }
594 }
595 #[cfg(not(any(feature = "f410", feature = "wl")))]
596 Port::D => {
597 cfg_if! {
598 if #[cfg(feature = "f3")] {
599 if rcc.ahbenr.read().iopden().bit_is_clear() {
600 rcc_en_reset!(ahb1, iopd, rcc);
601 }
602 } else if #[cfg(feature = "h7")] {
603 if rcc.ahb4enr.read().gpioden().bit_is_clear() {
604 rcc.ahb4enr.modify(|_, w| w.gpioden().set_bit());
605 rcc.ahb4rstr.modify(|_, w| w.gpiodrst().set_bit());
606 rcc.ahb4rstr.modify(|_, w| w.gpiodrst().clear_bit());
607 }
608 } else if #[cfg(feature = "f4")] {
609 if rcc.ahb1enr.read().gpioden().bit_is_clear() {
610 rcc_en_reset!(ahb1, gpiod, rcc);
611 }
612 } else if #[cfg(feature = "g0")] {
613 if rcc.iopenr.read().iopden().bit_is_clear() {
614 rcc.iopenr.modify(|_, w| w.iopden().set_bit());
615 rcc.ioprstr.modify(|_, w| w.iopdrst().set_bit());
616 rcc.ioprstr.modify(|_, w| w.iopdrst().clear_bit());
617 }
618 } else { if rcc.ahb2enr.read().gpioden().bit_is_clear() {
620 rcc_en_reset!(ahb2, gpiod, rcc);
621 }
622 }
623 }
624 }
625 #[cfg(not(any(
626 feature = "f301",
627 feature = "f3x4",
628 feature = "f410",
629 feature = "g0",
630 feature = "wb",
631 feature = "wl"
632 )))]
633 Port::E => {
634 cfg_if! {
635 if #[cfg(feature = "f3")] {
636 if rcc.ahbenr.read().iopeen().bit_is_clear() {
637 rcc_en_reset!(ahb1, iope, rcc);
638 }
639 } else if #[cfg(feature = "h7")] {
640 if rcc.ahb4enr.read().gpioeen().bit_is_clear() {
641 rcc.ahb4enr.modify(|_, w| w.gpioeen().set_bit());
642 rcc.ahb4rstr.modify(|_, w| w.gpioerst().set_bit());
643 rcc.ahb4rstr.modify(|_, w| w.gpioerst().clear_bit());
644 }
645 } else if #[cfg(feature = "f4")] {
646 if rcc.ahb1enr.read().gpioeen().bit_is_clear() {
647 rcc_en_reset!(ahb1, gpioe, rcc);
648 }
649 } else if #[cfg(feature = "g0")] {
650 if rcc.iopenr.read().iopeen().bit_is_clear() {
651 rcc.iopenr.modify(|_, w| w.iopeen().set_bit());
652 rcc.ioprstr.modify(|_, w| w.ioperst().set_bit());
653 rcc.ioprstr.modify(|_, w| w.ioperst().clear_bit());
654 }
655 } else { if rcc.ahb2enr.read().gpioeen().bit_is_clear() {
657 rcc_en_reset!(ahb2, gpioe, rcc);
658 }
659 }
660 }
661 }
662 #[cfg(not(any(
663 feature = "f401",
664 feature = "f410",
665 feature = "f411",
666 feature = "l4x1",
667 feature = "l4x2",
668 feature = "l412",
669 feature = "l4x3",
670 feature = "wb",
671 feature = "wl"
672 )))]
673 Port::F => {
674 cfg_if! {
675 if #[cfg(feature = "f3")] {
676 if rcc.ahbenr.read().iopfen().bit_is_clear() {
677 rcc_en_reset!(ahb1, iopf, rcc);
678 }
679 } else if #[cfg(feature = "h7")] {
680 if rcc.ahb4enr.read().gpiofen().bit_is_clear() {
681 rcc.ahb4enr.modify(|_, w| w.gpiofen().set_bit());
682 rcc.ahb4rstr.modify(|_, w| w.gpiofrst().set_bit());
683 rcc.ahb4rstr.modify(|_, w| w.gpiofrst().clear_bit());
684 }
685 } else if #[cfg(feature = "f4")] {
686 if rcc.ahb1enr.read().gpiofen().bit_is_clear() {
687 rcc_en_reset!(ahb1, gpiof, rcc);
688 }
689 } else if #[cfg(feature = "g0")] {
690 if rcc.iopenr.read().iopfen().bit_is_clear() {
691 rcc.iopenr.modify(|_, w| w.iopfen().set_bit());
692 rcc.ioprstr.modify(|_, w| w.iopfrst().set_bit());
693 rcc.ioprstr.modify(|_, w| w.iopfrst().clear_bit());
694 }
695 } else { if rcc.ahb2enr.read().gpiofen().bit_is_clear() {
697 rcc_en_reset!(ahb2, gpiof, rcc);
698 }
699 }
700 }
701 }
702 #[cfg(not(any(
703 feature = "f373",
704 feature = "f301",
705 feature = "f3x4",
706 feature = "f401",
707 feature = "f410",
708 feature = "f411",
709 feature = "l4x1",
710 feature = "l4x2",
711 feature = "l412",
712 feature = "l4x3",
713 feature = "g0",
714 feature = "wb",
715 feature = "wl"
716 )))]
717 Port::G => {
718 cfg_if! {
719 if #[cfg(feature = "f3")] {
720 if rcc.ahbenr.read().iopgen().bit_is_clear() {
721 rcc_en_reset!(ahb1, iopg, rcc);
722 }
723 } else if #[cfg(feature = "h7")] {
724 if rcc.ahb4enr.read().gpiogen().bit_is_clear() {
725 rcc.ahb4enr.modify(|_, w| w.gpiogen().set_bit());
726 rcc.ahb4rstr.modify(|_, w| w.gpiogrst().set_bit());
727 rcc.ahb4rstr.modify(|_, w| w.gpiogrst().clear_bit());
728 }
729 } else if #[cfg(feature = "f4")] {
730 if rcc.ahb1enr.read().gpiogen().bit_is_clear() {
731 rcc_en_reset!(ahb1, gpiog, rcc);
732 }
733 } else if #[cfg(feature = "g0")] {
734 if rcc.iopenr.read().iopgen().bit_is_clear() {
735 rcc.iopenr.modify(|_, w| w.iopgen().set_bit());
736 rcc.ioprstr.modify(|_, w| w.iopgrst().set_bit());
737 rcc.ioprstr.modify(|_, w| w.iopgrst().clear_bit());
738 }
739 } else { if rcc.ahb2enr.read().gpiogen().bit_is_clear() {
741 rcc_en_reset!(ahb2, gpiog, rcc);
742
743 #[cfg(feature = "l4x6")]
744 {
745 let pwr = unsafe { &(*pac::PWR::ptr()) };
746 rcc.apb1enr1.modify(|_, w| w.pwren().set_bit());
748 pwr.cr2.modify(|_, w| w.iosv().set_bit());
749 }
750 }
751 }
752 }
753 #[cfg(feature = "l5")]
754 {
758 unsafe {
759 (*crate::pac::PWR::ptr())
760 .cr2
761 .modify(|_, w| w.iosv().set_bit());
762 }
763 }
764 }
765 #[cfg(not(any(
766 feature = "f373",
767 feature = "f301",
768 feature = "f3x4",
769 feature = "f410",
770 feature = "l4x1",
771 feature = "l4x2",
772 feature = "l412",
773 feature = "l4x3",
774 feature = "g0",
775 feature = "g4",
776 feature = "wb",
777 feature = "wl"
778 )))]
779 Port::H => {
780 cfg_if! {
781 if #[cfg(feature = "f3")] {
782 if rcc.ahbenr.read().iophen().bit_is_clear() {
783 rcc_en_reset!(ahb1, ioph, rcc);
784 }
785 } else if #[cfg(feature = "h7")] {
786 if rcc.ahb4enr.read().gpiohen().bit_is_clear() {
787 rcc.ahb4enr.modify(|_, w| w.gpiohen().set_bit());
788 rcc.ahb4rstr.modify(|_, w| w.gpiohrst().set_bit());
789 rcc.ahb4rstr.modify(|_, w| w.gpiohrst().clear_bit());
790 }
791 } else if #[cfg(feature = "f4")] {
792 if rcc.ahb1enr.read().gpiohen().bit_is_clear() {
793 rcc_en_reset!(ahb1, gpioh, rcc);
794 }
795 } else if #[cfg(feature = "g0")] {
796 if rcc.iopenr.read().iophen().bit_is_clear() {
797 rcc.iopenr.modify(|_, w| w.iophen().set_bit());
798 rcc.ioprstr.modify(|_, w| w.iophrst().set_bit());
799 rcc.ioprstr.modify(|_, w| w.iophrst().clear_bit());
800 }
801 } else { if rcc.ahb2enr.read().gpiohen().bit_is_clear() {
803 rcc_en_reset!(ahb2, gpioh, rcc);
804 }
805 }
806 }
807 }
808 #[cfg(any(feature = "l4x6", feature = "h747cm4", feature = "h747cm7"))]
809 Port::I => {
810 cfg_if! {
811 if #[cfg(feature = "h7")] {
812 if rcc.ahb4enr.read().gpioien().bit_is_clear() {
813 rcc.ahb4enr.modify(|_, w| w.gpioien().set_bit());
814 rcc.ahb4rstr.modify(|_, w| w.gpioirst().set_bit());
815 rcc.ahb4rstr.modify(|_, w| w.gpioirst().clear_bit());
816 }
817 } else if #[cfg(feature = "l4")] {
818 if rcc.ahb2enr.read().gpioien().bit_is_clear() {
819 rcc.ahb2enr.modify(|_,w| w.gpioien().set_bit());
820 rcc.ahb2rstr.modify(|_, w| w.gpioirst().set_bit());
821 rcc.ahb2rstr.modify(|_, w| w.gpioirst().clear_bit());
822 }
823 }
824 }
825 }
826 }
827
828 let mut result = Self { port, pin };
829 result.mode(mode);
830
831 result
832 }
833
834 pub fn mode(&mut self, value: PinMode) {
836 #[cfg(feature = "h5")] set_field!(
838 self.regs(),
839 self.pin,
840 moder,
841 mode,
842 bits,
843 value.val(),
844 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
845 );
846
847 #[cfg(not(feature = "h5"))] set_field!(
849 self.regs(),
850 self.pin,
851 moder,
852 moder,
853 bits,
854 value.val(),
855 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
856 );
857
858 if let PinMode::Alt(alt) = value {
859 self.alt_fn(alt);
860 }
861 }
862
863 pub fn output_type(&mut self, value: OutputType) {
865 set_field!(
866 self.regs(),
867 self.pin,
868 otyper,
869 ot,
870 bit,
871 value as u8 != 0,
872 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
873 );
874 }
875
876 pub fn output_speed(&mut self, value: OutputSpeed) {
878 #[cfg(not(feature = "h5"))] set_field!(
880 self.regs(),
881 self.pin,
882 ospeedr,
883 ospeedr,
884 bits,
885 value as u8,
886 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
887 );
888 }
889
890 pub fn pull(&mut self, value: Pull) {
892 #[cfg(feature = "h5")] set_field!(
894 self.regs(),
895 self.pin,
896 pupdr,
897 pupd,
898 bits,
899 value as u8,
900 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
901 );
902
903 #[cfg(not(feature = "h5"))] set_field!(
905 self.regs(),
906 self.pin,
907 pupdr,
908 pupdr,
909 bits,
910 value as u8,
911 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
912 );
913 }
914
915 #[cfg(not(feature = "f373"))]
917 pub fn cfg_lock(&mut self, value: CfgLock) {
919 set_field!(
920 self.regs(),
921 self.pin,
922 lckr,
923 lck,
924 bit,
925 value as u8 != 0,
926 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
927 );
928 }
929
930 pub fn get_state(&mut self) -> PinState {
933 let val = get_input_data!(
934 self.regs(),
935 self.pin,
936 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
937 );
938 if val { PinState::High } else { PinState::Low }
939 }
940
941 pub fn set_state(&mut self, value: PinState) {
944 let offset = match value {
945 PinState::Low => 16,
946 PinState::High => 0,
947 };
948
949 set_state!(
950 self.regs(),
951 self.pin,
952 offset,
953 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
954 );
955 }
956
957 fn alt_fn(&mut self, value: u8) {
959 assert!(value <= 15, "Alt function must be 0 to 15.");
960
961 cfg_if! {
962 if #[cfg(any(feature = "l5", feature = "g0", feature = "wb", feature = "h5"))] {
963 set_alt!(self.regs(), self.pin, afsel, value, [(0, l), (1, l), (2, l),
964 (3, l), (4, l), (5, l), (6, l), (7, l), (8, h), (9, h), (10, h), (11, h), (12, h),
965 (13, h), (14, h), (15, h)])
966 } else if #[cfg(feature = "h7")] {
967 set_alt!(self.regs(), self.pin, afr, value, [(0, l), (1, l), (2, l),
968 (3, l), (4, l), (5, l), (6, l), (7, l), (8, h), (9, h), (10, h), (11, h), (12, h),
969 (13, h), (14, h), (15, h)])
970 } else { set_alt!(self.regs(), self.pin, afr, value, [(0, l), (1, l), (2, l),
972 (3, l), (4, l), (5, l), (6, l), (7, l), (8, h), (9, h), (10, h), (11, h), (12, h),
973 (13, h), (14, h), (15, h)])
974 }
975 }
976 }
977
978 #[cfg(not(any(feature = "f373", feature = "wl")))]
979 pub fn enable_interrupt(&mut self, edge: Edge) {
981 let rising = match edge {
982 Edge::Falling => false,
983 _ => true, };
985
986 let falling = match edge {
987 Edge::Rising => false,
988 _ => true, };
990
991 cfg_if! {
992 if #[cfg(feature = "g0")] {
993 set_exti_g0!(self.pin, rising, falling, self.port.cr_val(), [(0, 1, 0_7), (1, 1, 0_7), (2, 1, 0_7),
994 (3, 1, 0_7), (4, 2, 0_7), (5, 2, 0_7), (6, 2, 0_7), (7, 2, 0_7), (8, 3, 8_15),
995 (9, 3, 8_15), (10, 3, 8_15), (11, 3, 8_15), (12, 4, 8_15),
996 (13, 4, 8_15), (14, 4, 8_15), (15, 4, 8_15)]
997 );
998 } else if #[cfg(any(feature = "l5", feature = "h5"))] {
999 set_exti_l5!(self.pin, rising, falling, self.port.cr_val(), [(0, 1, 0_7), (1, 1, 0_7), (2, 1, 0_7),
1000 (3, 1, 0_7), (4, 2, 0_7), (5, 2, 0_7), (6, 2, 0_7), (7, 2, 0_7), (8, 3, 8_15),
1001 (9, 3, 8_15), (10, 3, 8_15), (11, 3, 8_15), (12, 4, 8_15),
1002 (13, 4, 8_15), (14, 4, 8_15), (15, 4, 8_15)]
1003 );
1004 } else if #[cfg(feature = "f4")] {
1005 set_exti_f4!(self.pin, rising, falling, self.port.cr_val(), [(0, 1), (1, 1), (2, 1),
1006 (3, 1), (4, 2), (5, 2), (6, 2), (7, 2), (8, 3), (9, 3), (10, 3), (11, 3), (12, 4),
1007 (13, 4), (14, 4), (15, 4)]
1008 );
1009 } else {
1010 set_exti!(self.pin, rising, falling, self.port.cr_val(), [(0, 1), (1, 1), (2, 1),
1011 (3, 1), (4, 2), (5, 2), (6, 2), (7, 2), (8, 3), (9, 3), (10, 3), (11, 3), (12, 4),
1012 (13, 4), (14, 4), (15, 4)]
1013 );
1014 }
1015 }
1016 }
1017
1018 #[cfg(feature = "l4x6")]
1019 pub fn connect_to_adc(&mut self) {
1026 set_field!(
1027 self.regs(),
1028 self.pin,
1029 ascr,
1030 asc,
1031 bit,
1032 true,
1033 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
1034 );
1035 }
1036
1037 pub fn is_high(&self) -> bool {
1039 get_input_data!(
1040 self.regs(),
1041 self.pin,
1042 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
1043 )
1044 }
1045
1046 pub fn is_low(&self) -> bool {
1048 !self.is_high()
1049 }
1050
1051 pub fn set_high(&mut self) {
1053 self.set_state(PinState::High);
1054 }
1055
1056 pub fn set_low(&mut self) {
1058 self.set_state(PinState::Low);
1059 }
1060
1061 pub fn toggle(&mut self) {
1063 if Pin::is_high(self) {
1065 Pin::set_low(self);
1066 } else {
1068 Pin::set_high(self);
1070 }
1071 }
1072}
1073
1074#[cfg(feature = "embedded_hal")]
1075impl ErrorType for Pin {
1076 type Error = Infallible;
1077}
1078
1079#[cfg(feature = "embedded_hal")]
1080impl InputPin for Pin {
1081 fn is_high(&mut self) -> Result<bool, Self::Error> {
1082 Ok(Pin::is_high(self))
1083 }
1084
1085 fn is_low(&mut self) -> Result<bool, Self::Error> {
1086 Ok(Pin::is_low(self))
1087 }
1088}
1089
1090#[cfg(feature = "embedded_hal")]
1091impl OutputPin for Pin {
1092 fn set_low(&mut self) -> Result<(), Self::Error> {
1093 Pin::set_low(self);
1094 Ok(())
1095 }
1096
1097 fn set_high(&mut self) -> Result<(), Self::Error> {
1098 Pin::set_high(self);
1099 Ok(())
1100 }
1101}
1102
1103#[cfg(feature = "embedded_hal")]
1104impl StatefulOutputPin for Pin {
1105 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
1106 Ok(Pin::is_high(self))
1107 }
1108
1109 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
1110 Ok(Pin::is_low(self))
1111 }
1112
1113 fn toggle(&mut self) -> Result<(), Self::Error> {
1114 Pin::toggle(self);
1115 Ok(())
1116 }
1117}
1118
1119pub fn is_high(port: Port, pin: u8) -> bool {
1122 get_input_data!(
1123 regs(port),
1124 pin,
1125 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
1126 )
1127}
1128
1129pub fn is_low(port: Port, pin: u8) -> bool {
1132 !is_high(port, pin)
1133}
1134
1135pub fn set_high(port: Port, pin: u8) {
1138 set_state(port, pin, PinState::High);
1139}
1140
1141pub fn set_low(port: Port, pin: u8) {
1144 set_state(port, pin, PinState::Low);
1145}
1146
1147pub fn set_state(port: Port, pin: u8, value: PinState) {
1151 let offset = match value {
1152 PinState::Low => 16,
1153 PinState::High => 0,
1154 };
1155
1156 set_state!(
1157 regs(port),
1158 pin,
1159 offset,
1160 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
1161 );
1162}
1163
1164pub fn clear_exti_interrupt(line: u8) {
1167 unsafe {
1169 cfg_if! {
1170 if #[cfg(any(feature = "h747cm4", feature = "h747cm7"))] {
1171 (*EXTI::ptr()).c1pr1.modify(|_, w| {
1172 match line {
1173 0 => w.pr0().set_bit(),
1174 1 => w.pr1().set_bit(),
1175 2 => w.pr2().set_bit(),
1176 3 => w.pr3().set_bit(),
1177 4 => w.pr4().set_bit(),
1178 5 => w.pr5().set_bit(),
1179 6 => w.pr6().set_bit(),
1180 7 => w.pr7().set_bit(),
1181 8 => w.pr8().set_bit(),
1182 9 => w.pr9().set_bit(),
1183 10 => w.pr10().set_bit(),
1184 11 => w.pr11().set_bit(),
1185 12 => w.pr12().set_bit(),
1186 13 => w.pr13().set_bit(),
1187 14 => w.pr14().set_bit(),
1188 15 => w.pr15().set_bit(),
1189 _ => panic!(),
1190 }
1191 });
1192 } else if #[cfg(feature = "h7")] {
1193 (*EXTI::ptr()).cpupr1.modify(|_, w| {
1194 match line {
1195 0 => w.pr0().set_bit(),
1196 1 => w.pr1().set_bit(),
1197 2 => w.pr2().set_bit(),
1198 3 => w.pr3().set_bit(),
1199 4 => w.pr4().set_bit(),
1200 5 => w.pr5().set_bit(),
1201 6 => w.pr6().set_bit(),
1202 7 => w.pr7().set_bit(),
1203 8 => w.pr8().set_bit(),
1204 9 => w.pr9().set_bit(),
1205 10 => w.pr10().set_bit(),
1206 11 => w.pr11().set_bit(),
1207 12 => w.pr12().set_bit(),
1208 13 => w.pr13().set_bit(),
1209 14 => w.pr14().set_bit(),
1210 15 => w.pr15().set_bit(),
1211 _ => panic!(),
1212 }
1213 });
1214 } else if #[cfg(any(feature = "l5", feature = "g0"))] {
1215 (*EXTI::ptr()).rpr1.modify(|_, w| {
1216 match line {
1217 0 => w.rpif0().set_bit(),
1218 1 => w.rpif1().set_bit(),
1219 2 => w.rpif2().set_bit(),
1220 3 => w.rpif3().set_bit(),
1221 4 => w.rpif4().set_bit(),
1222 5 => w.rpif5().set_bit(),
1223 6 => w.rpif6().set_bit(),
1224 7 => w.rpif7().set_bit(),
1225 8 => w.rpif8().set_bit(),
1226 9 => w.rpif9().set_bit(),
1227 10 => w.rpif10().set_bit(),
1228 11 => w.rpif11().set_bit(),
1229 12 => w.rpif12().set_bit(),
1230 13 => w.rpif13().set_bit(),
1231 14 => w.rpif14().set_bit(),
1232 15 => w.rpif15().set_bit(),
1233 _ => panic!(),
1234 }
1235 });
1236 } else if #[cfg(any(feature = "f373", feature = "f4"))] {
1237 (*EXTI::ptr()).pr.modify(|_, w| {
1238 match line {
1239 0 => w.pr0().set_bit(),
1240 1 => w.pr1().set_bit(),
1241 2 => w.pr2().set_bit(),
1242 3 => w.pr3().set_bit(),
1243 4 => w.pr4().set_bit(),
1244 5 => w.pr5().set_bit(),
1245 6 => w.pr6().set_bit(),
1246 7 => w.pr7().set_bit(),
1247 8 => w.pr8().set_bit(),
1248 9 => w.pr9().set_bit(),
1249 10 => w.pr10().set_bit(),
1250 11 => w.pr11().set_bit(),
1251 12 => w.pr12().set_bit(),
1252 13 => w.pr13().set_bit(),
1253 14 => w.pr14().set_bit(),
1254 15 => w.pr15().set_bit(),
1255 _ => panic!(),
1256 }
1257 });
1258 } else if #[cfg(any(feature = "f3", feature = "l4"))] {
1259 (*EXTI::ptr()).pr1.modify(|_, w| {
1260 match line {
1261 0 => w.pr0().set_bit(),
1262 1 => w.pr1().set_bit(),
1263 2 => w.pr2().set_bit(),
1264 3 => w.pr3().set_bit(),
1265 4 => w.pr4().set_bit(),
1266 5 => w.pr5().set_bit(),
1267 6 => w.pr6().set_bit(),
1268 7 => w.pr7().set_bit(),
1269 8 => w.pr8().set_bit(),
1270 9 => w.pr9().set_bit(),
1271 10 => w.pr10().set_bit(),
1272 11 => w.pr11().set_bit(),
1273 12 => w.pr12().set_bit(),
1274 13 => w.pr13().set_bit(),
1275 14 => w.pr14().set_bit(),
1276 15 => w.pr15().set_bit(),
1277 _ => panic!(),
1278 }
1279 });
1280 } else if #[cfg(feature = "h5")] {
1281 (*EXTI::ptr()).rpr1.modify(|_, w| {
1282 match line {
1283 0 => w.rpif0().set_bit(),
1284 1 => w.rpif1().set_bit(),
1285 2 => w.rpif2().set_bit(),
1286 3 => w.rpif3().set_bit(),
1287 4 => w.rpif4().set_bit(),
1288 5 => w.rpif5().set_bit(),
1289 6 => w.rpif6().set_bit(),
1290 7 => w.rpif7().set_bit(),
1291 8 => w.rpif8().set_bit(),
1292 9 => w.rpif9().set_bit(),
1293 10 => w.rpif10().set_bit(),
1294 11 => w.rpif11().set_bit(),
1295 12 => w.rpif12().set_bit(),
1296 13 => w.rpif13().set_bit(),
1297 14 => w.rpif14().set_bit(),
1298 15 => w.rpif15().set_bit(),
1299 _ => panic!(),
1300 }
1301 });
1302 } else { (*EXTI::ptr()).pr1.modify(|_, w| {
1304 match line {
1305 0 => w.pif0().set_bit(),
1306 1 => w.pif1().set_bit(),
1307 2 => w.pif2().set_bit(),
1308 3 => w.pif3().set_bit(),
1309 4 => w.pif4().set_bit(),
1310 5 => w.pif5().set_bit(),
1311 6 => w.pif6().set_bit(),
1312 7 => w.pif7().set_bit(),
1313 8 => w.pif8().set_bit(),
1314 9 => w.pif9().set_bit(),
1315 10 => w.pif10().set_bit(),
1316 11 => w.pif11().set_bit(),
1317 12 => w.pif12().set_bit(),
1318 13 => w.pif13().set_bit(),
1319 14 => w.pif14().set_bit(),
1320 15 => w.pif15().set_bit(),
1321 _ => panic!(),
1322 }
1323 });
1324 }
1325 }
1326 }
1327}
1328
1329const fn regs(port: Port) -> *const pac::gpioa::RegisterBlock {
1330 match port {
1333 Port::A => crate::pac::GPIOA::ptr(),
1334 Port::B => crate::pac::GPIOB::ptr() as _,
1335 #[cfg(not(feature = "wl"))]
1336 Port::C => crate::pac::GPIOC::ptr() as _,
1337 #[cfg(not(any(feature = "f410", feature = "wl")))]
1338 Port::D => crate::pac::GPIOD::ptr() as _,
1339 #[cfg(not(any(
1340 feature = "f301",
1341 feature = "f3x4",
1342 feature = "f410",
1343 feature = "g0",
1344 feature = "wb",
1345 feature = "wl"
1346 )))]
1347 Port::E => crate::pac::GPIOE::ptr() as _,
1348 #[cfg(not(any(
1349 feature = "f401",
1350 feature = "f410",
1351 feature = "f411",
1352 feature = "l4x1",
1353 feature = "l4x2",
1354 feature = "l412",
1355 feature = "l4x3",
1356 feature = "wb",
1357 feature = "wl"
1358 )))]
1359 Port::F => crate::pac::GPIOF::ptr() as _,
1360 #[cfg(not(any(
1361 feature = "f373",
1362 feature = "f301",
1363 feature = "f3x4",
1364 feature = "f401",
1365 feature = "f410",
1366 feature = "f411",
1367 feature = "l4x1",
1368 feature = "l4x2",
1369 feature = "l412",
1370 feature = "l4x3",
1371 feature = "g0",
1372 feature = "wb",
1373 feature = "wl"
1374 )))]
1375 Port::G => crate::pac::GPIOG::ptr() as _,
1376 #[cfg(not(any(
1377 feature = "f373",
1378 feature = "f301",
1379 feature = "f3x4",
1380 feature = "f410",
1381 feature = "l4x1",
1382 feature = "l4x2",
1383 feature = "l412",
1384 feature = "l4x3",
1385 feature = "g0",
1386 feature = "g4",
1387 feature = "wb",
1388 feature = "wl"
1389 )))]
1390 Port::H => crate::pac::GPIOH::ptr() as _,
1391 #[cfg(any(feature = "h747cm4", feature = "h747cm7", feature = "l4x6"))]
1392 Port::I => crate::pac::GPIOI::ptr() as _,
1393 }
1394}
1395
1396#[cfg(not(any(
1397 feature = "f4",
1398 feature = "l5",
1399 feature = "f3",
1400 feature = "l4",
1401 feature = "h5"
1402)))]
1403pub unsafe fn write_dma(
1406 buf: &[u32],
1407 port: Port,
1408 dma_channel: DmaChannel,
1409 channel_cfg: ChannelCfg,
1410 dma_periph: dma::DmaPeriph,
1411) {
1412 let (ptr, len) = (buf.as_ptr(), buf.len());
1413
1414 let periph_addr = &(*(regs(port))).bsrr as *const _ as u32;
1415
1416 #[cfg(feature = "h7")]
1417 let num_data = len as u32;
1418 #[cfg(not(feature = "h7"))]
1419 let num_data = len as u16;
1420
1421 match dma_periph {
1422 dma::DmaPeriph::Dma1 => {
1423 let mut regs = unsafe { &(*DMA1::ptr()) };
1424 dma::cfg_channel(
1425 &mut regs,
1426 dma_channel,
1427 periph_addr,
1428 ptr as u32,
1429 num_data,
1430 dma::Direction::ReadFromMem,
1431 dma::DataSize::S32,
1432 dma::DataSize::S32,
1433 channel_cfg,
1434 );
1435 }
1436 #[cfg(not(any(feature = "g0", feature = "wb")))]
1437 dma::DmaPeriph::Dma2 => {
1438 let mut regs = unsafe { &(*pac::DMA2::ptr()) };
1439 dma::cfg_channel(
1440 &mut regs,
1441 dma_channel,
1442 periph_addr,
1443 ptr as u32,
1444 num_data,
1445 dma::Direction::ReadFromMem,
1446 dma::DataSize::S32,
1447 dma::DataSize::S32,
1448 channel_cfg,
1449 );
1450 }
1451 }
1452}
1453
1454#[cfg(not(any(
1455 feature = "f4",
1456 feature = "l5",
1457 feature = "f3",
1458 feature = "l4",
1459 feature = "h5"
1460)))]
1461pub unsafe fn read_dma(
1463 buf: &[u32],
1464 port: Port,
1465 dma_channel: DmaChannel,
1466 channel_cfg: ChannelCfg,
1467 dma_periph: dma::DmaPeriph,
1468) {
1469 let (ptr, len) = (buf.as_ptr(), buf.len());
1470
1471 let periph_addr = &(*(regs(port))).idr as *const _ as u32;
1472
1473 #[cfg(feature = "h7")]
1474 let num_data = len as u32;
1475 #[cfg(not(feature = "h7"))]
1476 let num_data = len as u16;
1477
1478 match dma_periph {
1479 dma::DmaPeriph::Dma1 => {
1480 let mut regs = unsafe { &(*DMA1::ptr()) };
1481 dma::cfg_channel(
1482 &mut regs,
1483 dma_channel,
1484 periph_addr,
1485 ptr as u32,
1486 num_data,
1487 dma::Direction::ReadFromPeriph,
1488 dma::DataSize::S32,
1489 dma::DataSize::S32,
1490 channel_cfg,
1491 );
1492 }
1493 #[cfg(not(any(feature = "g0", feature = "wb")))]
1494 dma::DmaPeriph::Dma2 => {
1495 let mut regs = unsafe { &(*pac::DMA2::ptr()) };
1496 dma::cfg_channel(
1497 &mut regs,
1498 dma_channel,
1499 periph_addr,
1500 ptr as u32,
1501 num_data,
1502 dma::Direction::ReadFromPeriph,
1503 dma::DataSize::S32,
1504 dma::DataSize::S32,
1505 channel_cfg,
1506 );
1507 }
1508 }
1509}