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