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 } else if #[cfg(feature = "l4")]{
367 exti.imr1().modify(|_, w| w.[<mr $num>]().bit(true));
368 }
369 }
370
371 cfg_if! {
372 if #[cfg(any(feature = "g4", feature = "wb", feature = "wl", feature = "c0", feature = "l5",
373 feature = "g030", feature = "g050", feature = "g070", feature = "g0b0", feature = "g0b1", feature = "g0c1"))] {
374 exti.rtsr1().modify(|_, w| w.[<rt $num>]().bit($rising));
375 exti.ftsr1().modify(|_, w| w.[<ft $num>]().bit($falling));
376 } else {
384 exti.rtsr1().modify(|_, w| w.[<tr $num>]().bit($rising));
385 exti.ftsr1().modify(|_, w| w.[<tr $num>]().bit($falling));
386 }
387 }
388
389 #[cfg(not(any(feature = "g0", feature = "c0", feature = "l5")))]
390 syscfg
391 .[<exticr $crnum>]()
392 .modify(|_, w| unsafe { w.[<exti $num>]().bits($val) });
393 }
394 )+
395 _ => panic!("GPIO pins must be 0 - 15."),
396 }
397 }
398 }
399}
400
401#[cfg(feature = "f4")]
402macro_rules! set_exti_f4 {
404 ($pin:expr, $rising:expr, $falling:expr, $val:expr, [$(($num:expr, $crnum:expr)),+]) => {
405 let exti = unsafe { &(*pac::EXTI::ptr()) };
406 let syscfg = unsafe { &(*pac::SYSCFG::ptr()) };
407
408 paste! {
409 match $pin {
410 $(
411 $num => {
412 exti.imr().modify(|_, w| w.[<mr $num>]().unmasked());
413 exti.rtsr().modify(|_, w| w.[<tr $num>]().bit($rising));
414 exti.ftsr().modify(|_, w| w.[<tr $num>]().bit($falling));
415 syscfg
416 .[<exticr $crnum>]()
417 .modify(|_, w| unsafe { w.[<exti $num>]().bits($val) });
418 }
419 )+
420 _ => panic!("GPIO pins must be 0 - 15."),
421 }
422 }
423 }
424}
425
426#[derive(Clone)]
427pub struct Pin {
429 pub port: Port,
431 pub pin: u8,
433}
434
435impl Pin {
436 const fn regs(&self) -> *const pac::gpioa::RegisterBlock {
438 regs(self.port)
441 }
442
443 pub fn new(port: Port, pin: u8, mode: PinMode) -> Self {
447 assert!(pin <= 15, "Pin must be 0 - 15.");
448
449 let rcc = unsafe { &(*RCC::ptr()) };
450
451 match port {
452 Port::A => {
453 cfg_if! {
454 if #[cfg(feature = "f3")] {
455 if rcc.ahbenr().read().iopaen().bit_is_clear() {
456 rcc_en_reset!(ahb1, iopa, rcc);
457 }
458 } else if #[cfg(feature = "h7")] {
459 if rcc.ahb4enr().read().gpioaen().bit_is_clear() {
460 rcc.ahb4enr().modify(|_, w| w.gpioaen().bit(true));
461 rcc.ahb4rstr().modify(|_, w| w.gpioarst().bit(true));
462 rcc.ahb4rstr().modify(|_, w| w.gpioarst().clear_bit());
463 }
464 } else if #[cfg(feature = "f4")] {
465 if rcc.ahb1enr().read().gpioaen().bit_is_clear() {
466 rcc_en_reset!(ahb1, gpioa, rcc);
467 }
468 } else if #[cfg(any(feature = "g031", feature = "g041", feature = "g051", feature = "g061", feature = "g071", feature = "g081"))] {
469 if rcc.iopenr().read().iopaen().bit_is_clear() {
470 rcc.iopenr().modify(|_, w| w.iopaen().bit(true));
471 rcc.ioprstr().modify(|_, w| w.ioparst().bit(true));
472 rcc.ioprstr().modify(|_, w| w.ioparst().clear_bit());
473 }
474 } else if #[cfg(any(feature = "g0"))] {
475 if rcc.iopenr().read().gpioaen().bit_is_clear() {
476 rcc.iopenr().modify(|_, w| w.gpioaen().bit(true));
477 rcc.ioprstr().modify(|_, w| w.gpioarst().bit(true));
478 rcc.ioprstr().modify(|_, w| w.gpioarst().clear_bit());
479 }
480 } else if #[cfg(feature = "c0")] {
481 if rcc.iopenr().read().gpioaen().bit_is_clear() {
482 rcc.iopenr().modify(|_, w| w.gpioaen().bit(true));
483 rcc.ioprstr().modify(|_, w| w.gpioarst().bit(true));
484 rcc.ioprstr().modify(|_, w| w.gpioarst().clear_bit());
485 }
486 } else { if rcc.ahb2enr().read().gpioaen().bit_is_clear() {
488 rcc_en_reset!(ahb2, gpioa, rcc);
489 }
490 }
491 }
492 }
493 Port::B => {
494 cfg_if! {
495 if #[cfg(feature = "f3")] {
496 if rcc.ahbenr().read().iopben().bit_is_clear() {
497 rcc_en_reset!(ahb1, iopb, rcc);
498 }
499 } else if #[cfg(feature = "h7")] {
500 if rcc.ahb4enr().read().gpioben().bit_is_clear() {
501 rcc.ahb4enr().modify(|_, w| w.gpioben().bit(true));
502 rcc.ahb4rstr().modify(|_, w| w.gpiobrst().bit(true));
503 rcc.ahb4rstr().modify(|_, w| w.gpiobrst().clear_bit());
504 }
505 } else if #[cfg(feature = "f4")] {
506 if rcc.ahb1enr().read().gpioben().bit_is_clear() {
507 rcc_en_reset!(ahb1, gpiob, rcc);
508 }
509 } else if #[cfg(any(feature = "g031", feature = "g041", feature = "g051", feature = "g061", feature = "g071", feature = "g081"))] {
510 if rcc.iopenr().read().iopaen().bit_is_clear() {
511 rcc.iopenr().modify(|_, w| w.iopaen().bit(true));
512 rcc.ioprstr().modify(|_, w| w.ioparst().bit(true));
513 rcc.ioprstr().modify(|_, w| w.ioparst().clear_bit());
514 }
515 } else if #[cfg(feature = "g0")] {
516 if rcc.iopenr().read().gpioben().bit_is_clear() {
517 rcc.iopenr().modify(|_, w| w.gpioben().bit(true));
518 rcc.ioprstr().modify(|_, w| w.gpiobrst().bit(true));
519 rcc.ioprstr().modify(|_, w| w.gpiobrst().clear_bit());
520 }
521 } else if #[cfg(feature = "c0")] {
522 if rcc.iopenr().read().gpioben().bit_is_clear() {
523 rcc.iopenr().modify(|_, w| w.gpioben().bit(true));
524 rcc.ioprstr().modify(|_, w| w.gpiobrst().bit(true));
525 rcc.ioprstr().modify(|_, w| w.gpiobrst().clear_bit());
526 }
527 } else { if rcc.ahb2enr().read().gpioben().bit_is_clear() {
529 rcc_en_reset!(ahb2, gpiob, rcc);
530 }
531 }
532 }
533 }
534 #[cfg(not(feature = "wl"))]
535 Port::C => {
536 cfg_if! {
537 if #[cfg(feature = "f3")] {
538 if rcc.ahbenr().read().iopcen().bit_is_clear() {
539 rcc_en_reset!(ahb1, iopc, rcc);
540 }
541 } else if #[cfg(feature = "h7")] {
542 if rcc.ahb4enr().read().gpiocen().bit_is_clear() {
543 rcc.ahb4enr().modify(|_, w| w.gpiocen().bit(true));
544 rcc.ahb4rstr().modify(|_, w| w.gpiocrst().bit(true));
545 rcc.ahb4rstr().modify(|_, w| w.gpiocrst().clear_bit());
546 }
547 } else if #[cfg(feature = "f4")] {
548 if rcc.ahb1enr().read().gpiocen().bit_is_clear() {
549 rcc_en_reset!(ahb1, gpioc, rcc);
550 }
551 } else if #[cfg(any(feature = "g031", feature = "g041", feature = "g051", feature = "g061", feature = "g071", feature = "g081"))] {
552 if rcc.iopenr().read().iopaen().bit_is_clear() {
553 rcc.iopenr().modify(|_, w| w.iopaen().bit(true));
554 rcc.ioprstr().modify(|_, w| w.ioparst().bit(true));
555 rcc.ioprstr().modify(|_, w| w.ioparst().clear_bit());
556 }
557 } else if #[cfg(feature = "g0")] {
558 if rcc.iopenr().read().gpiocen().bit_is_clear() {
559 rcc.iopenr().modify(|_, w| w.gpiocen().bit(true));
560 rcc.ioprstr().modify(|_, w| w.gpiocrst().bit(true));
561 rcc.ioprstr().modify(|_, w| w.gpiocrst().clear_bit());
562 }
563 } else if #[cfg(feature = "c0")] {
564 if rcc.iopenr().read().gpiocen().bit_is_clear() {
565 rcc.iopenr().modify(|_, w| w.gpiocen().bit(true));
566 rcc.ioprstr().modify(|_, w| w.gpiocrst().bit(true));
567 rcc.ioprstr().modify(|_, w| w.gpiocrst().clear_bit());
568 }
569 } else { if rcc.ahb2enr().read().gpiocen().bit_is_clear() {
571 rcc_en_reset!(ahb2, gpioc, rcc);
572 }
573 }
574 }
575 }
576 #[cfg(not(any(feature = "f410", feature = "wl", feature = "l412")))]
577 Port::D => {
578 cfg_if! {
579 if #[cfg(feature = "f3")] {
580 if rcc.ahbenr().read().iopden().bit_is_clear() {
581 rcc_en_reset!(ahb1, iopd, rcc);
582 }
583 } else if #[cfg(feature = "h7")] {
584 if rcc.ahb4enr().read().gpioden().bit_is_clear() {
585 rcc.ahb4enr().modify(|_, w| w.gpioden().bit(true));
586 rcc.ahb4rstr().modify(|_, w| w.gpiodrst().bit(true));
587 rcc.ahb4rstr().modify(|_, w| w.gpiodrst().clear_bit());
588 }
589 } else if #[cfg(feature = "f4")] {
590 if rcc.ahb1enr().read().gpioden().bit_is_clear() {
591 rcc_en_reset!(ahb1, gpiod, rcc);
592 }
593 } else if #[cfg(any(feature = "g031", feature = "g041", feature = "g051", feature = "g061", feature = "g071", feature = "g081"))] {
594 if rcc.iopenr().read().iopaen().bit_is_clear() {
595 rcc.iopenr().modify(|_, w| w.iopaen().bit(true));
596 rcc.ioprstr().modify(|_, w| w.ioparst().bit(true));
597 rcc.ioprstr().modify(|_, w| w.ioparst().clear_bit());
598 }
599 } else if #[cfg(feature = "g0")] {
600 if rcc.iopenr().read().gpioden().bit_is_clear() {
601 rcc.iopenr().modify(|_, w| w.gpioden().bit(true));
602 rcc.ioprstr().modify(|_, w| w.gpiodrst().bit(true));
603 rcc.ioprstr().modify(|_, w| w.gpiodrst().clear_bit());
604 }
605 } else if #[cfg(feature = "c0")] {
606 if rcc.iopenr().read().gpioden().bit_is_clear() {
607 rcc.iopenr().modify(|_, w| w.gpioden().bit(true));
608 rcc.ioprstr().modify(|_, w| w.gpiodrst().bit(true));
609 rcc.ioprstr().modify(|_, w| w.gpiodrst().clear_bit());
610 }
611 } else { if rcc.ahb2enr().read().gpioden().bit_is_clear() {
613 rcc_en_reset!(ahb2, gpiod, rcc);
614 }
615 }
616 }
617 }
618 #[cfg(not(any(
619 feature = "f301",
620 feature = "f3x4",
621 feature = "f410",
622 feature = "g0",
623 feature = "c0",
624 feature = "wb",
625 feature = "wl",
626 feature = "l412",
627 )))]
628 Port::E => {
629 cfg_if! {
630 if #[cfg(feature = "f3")] {
631 if rcc.ahbenr().read().iopeen().bit_is_clear() {
632 rcc_en_reset!(ahb1, iope, rcc);
633 }
634 } else if #[cfg(feature = "h7")] {
635 if rcc.ahb4enr().read().gpioeen().bit_is_clear() {
636 rcc.ahb4enr().modify(|_, w| w.gpioeen().bit(true));
637 rcc.ahb4rstr().modify(|_, w| w.gpioerst().bit(true));
638 rcc.ahb4rstr().modify(|_, w| w.gpioerst().clear_bit());
639 }
640 } else if #[cfg(feature = "f4")] {
641 if rcc.ahb1enr().read().gpioeen().bit_is_clear() {
642 rcc_en_reset!(ahb1, gpioe, rcc);
643 }
644 } else { if rcc.ahb2enr().read().gpioeen().bit_is_clear() {
646 rcc_en_reset!(ahb2, gpioe, rcc);
647 }
648 }
649 }
650 }
651 #[cfg(not(any(
652 feature = "f401",
653 feature = "f410",
654 feature = "f411",
655 feature = "l4x1",
656 feature = "l4x2",
657 feature = "l412",
658 feature = "l4x3",
659 feature = "wb",
660 feature = "wl",
661 )))]
662 Port::F => {
663 cfg_if! {
664 if #[cfg(feature = "f3")] {
665 if rcc.ahbenr().read().iopfen().bit_is_clear() {
666 rcc_en_reset!(ahb1, iopf, rcc);
667 }
668 } else if #[cfg(feature = "h7")] {
669 if rcc.ahb4enr().read().gpiofen().bit_is_clear() {
670 rcc.ahb4enr().modify(|_, w| w.gpiofen().bit(true));
671 rcc.ahb4rstr().modify(|_, w| w.gpiofrst().bit(true));
672 rcc.ahb4rstr().modify(|_, w| w.gpiofrst().clear_bit());
673 }
674 } else if #[cfg(feature = "f4")] {
675 if rcc.ahb1enr().read().gpiofen().bit_is_clear() {
676 rcc_en_reset!(ahb1, gpiof, rcc);
677 }
678 } else if #[cfg(any(feature = "g031", feature = "g041", feature = "g051", feature = "g061", feature = "g071", feature = "g081"))] {
679 if rcc.iopenr().read().iopaen().bit_is_clear() {
680 rcc.iopenr().modify(|_, w| w.iopaen().bit(true));
681 rcc.ioprstr().modify(|_, w| w.ioparst().bit(true));
682 rcc.ioprstr().modify(|_, w| w.ioparst().clear_bit());
683 }
684 } else if #[cfg(feature = "g0")] {
685 if rcc.iopenr().read().gpiofen().bit_is_clear() {
686 rcc.iopenr().modify(|_, w| w.gpiofen().bit(true));
687 rcc.ioprstr().modify(|_, w| w.gpiofrst().bit(true));
688 rcc.ioprstr().modify(|_, w| w.gpiofrst().clear_bit());
689 }
690 } else if #[cfg(feature = "c0")] {
691 if rcc.iopenr().read().gpiofen().bit_is_clear() {
692 rcc.iopenr().modify(|_, w| w.gpiofen().bit(true));
693 rcc.ioprstr().modify(|_, w| w.gpiofrst().bit(true));
694 rcc.ioprstr().modify(|_, w| w.gpiofrst().clear_bit());
695 }
696 } else { if rcc.ahb2enr().read().gpiofen().bit_is_clear() {
698 rcc_en_reset!(ahb2, gpiof, rcc);
699 }
700 }
701 }
702 }
703 #[cfg(not(any(
704 feature = "f373",
705 feature = "f301",
706 feature = "f3x4",
707 feature = "f401",
708 feature = "f410",
709 feature = "f411",
710 feature = "l4x1",
711 feature = "l4x2",
712 feature = "l412",
713 feature = "l4x3",
714 feature = "g0",
715 feature = "c0",
716 feature = "wb",
717 feature = "wl"
718 )))]
719 Port::G => {
720 cfg_if! {
721 if #[cfg(feature = "f3")] {
722 if rcc.ahbenr().read().iopgen().bit_is_clear() {
723 rcc_en_reset!(ahb1, iopg, rcc);
724 }
725 } else if #[cfg(feature = "h7")] {
726 if rcc.ahb4enr().read().gpiogen().bit_is_clear() {
727 rcc.ahb4enr().modify(|_, w| w.gpiogen().bit(true));
728 rcc.ahb4rstr().modify(|_, w| w.gpiogrst().bit(true));
729 rcc.ahb4rstr().modify(|_, w| w.gpiogrst().clear_bit());
730 }
731 } else if #[cfg(feature = "f4")] {
732 if rcc.ahb1enr().read().gpiogen().bit_is_clear() {
733 rcc_en_reset!(ahb1, gpiog, rcc);
734 }
735 } else { if rcc.ahb2enr().read().gpiogen().bit_is_clear() {
737 rcc_en_reset!(ahb2, gpiog, rcc);
738
739 #[cfg(feature = "l4x6")]
740 {
741 let pwr = unsafe { &(*pac::PWR::ptr()) };
742 rcc.apb1enr1().modify(|_, w| w.pwren().bit(true));
744 pwr.cr2().modify(|_, w| w.iosv().bit(true));
745 }
746 }
747 }
748 }
749 #[cfg(feature = "l5")]
750 {
754 unsafe {
755 (*crate::pac::PWR::ptr())
756 .cr2()
757 .modify(|_, w| w.iosv().bit(true));
758 }
759 }
760 }
761 #[cfg(not(any(
762 feature = "f373",
763 feature = "f301",
764 feature = "f3x4",
765 feature = "f410",
766 feature = "l4x1",
767 feature = "l4x2",
768 feature = "l412",
769 feature = "l4x3",
770 feature = "g0",
771 feature = "c0",
772 feature = "g4",
773 feature = "wb",
774 feature = "wl"
775 )))]
776 Port::H => {
777 cfg_if! {
778 if #[cfg(feature = "f3")] {
779 if rcc.ahbenr().read().iophen().bit_is_clear() {
780 rcc_en_reset!(ahb1, ioph, rcc);
781 }
782 } else if #[cfg(feature = "h7")] {
783 if rcc.ahb4enr().read().gpiohen().bit_is_clear() {
784 rcc.ahb4enr().modify(|_, w| w.gpiohen().bit(true));
785 rcc.ahb4rstr().modify(|_, w| w.gpiohrst().bit(true));
786 rcc.ahb4rstr().modify(|_, w| w.gpiohrst().clear_bit());
787 }
788 } else if #[cfg(feature = "f4")] {
789 if rcc.ahb1enr().read().gpiohen().bit_is_clear() {
790 rcc_en_reset!(ahb1, gpioh, rcc);
791 }
792 }else { if rcc.ahb2enr().read().gpiohen().bit_is_clear() {
794 rcc_en_reset!(ahb2, gpioh, rcc);
795 }
796 }
797 }
798 }
799 #[cfg(any(feature = "l4x6", feature = "h747cm4", feature = "h747cm7"))]
800 Port::I => {
801 cfg_if! {
802 if #[cfg(feature = "h7")] {
803 if rcc.ahb4enr().read().gpioien().bit_is_clear() {
804 rcc.ahb4enr().modify(|_, w| w.gpioien().bit(true));
805 rcc.ahb4rstr().modify(|_, w| w.gpioirst().bit(true));
806 rcc.ahb4rstr().modify(|_, w| w.gpioirst().clear_bit());
807 }
808 } else if #[cfg(feature = "l4")] {
809 if rcc.ahb2enr().read().gpioien().bit_is_clear() {
810 rcc.ahb2enr().modify(|_,w| w.gpioien().bit(true));
811 rcc.ahb2rstr().modify(|_, w| w.gpioirst().bit(true));
812 rcc.ahb2rstr().modify(|_, w| w.gpioirst().clear_bit());
813 }
814 }
815 }
816 }
817 }
818
819 let mut result = Self { port, pin };
820 result.mode(mode);
821
822 result
823 }
824
825 pub fn mode(&mut self, value: PinMode) {
827 #[cfg(any(feature = "h5", feature = "c0"))] set_field!(
829 self.regs(),
830 self.pin,
831 moder,
832 mode,
833 bits,
834 value.val(),
835 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
836 );
837
838 #[cfg(not(any(feature = "h5", feature = "c0")))] set_field!(
840 self.regs(),
841 self.pin,
842 moder,
843 moder,
844 bits,
845 value.val(),
846 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
847 );
848
849 if let PinMode::Alt(alt) = value {
850 self.alt_fn(alt);
851 }
852 }
853
854 pub fn output_type(&mut self, value: OutputType) {
856 set_field!(
857 self.regs(),
858 self.pin,
859 otyper,
860 ot,
861 bit,
862 value as u8 != 0,
863 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
864 );
865 }
866
867 pub fn output_speed(&mut self, value: OutputSpeed) {
869 #[cfg(not(any(feature = "h5", feature = "c0")))] set_field!(
871 self.regs(),
872 self.pin,
873 ospeedr,
874 ospeedr,
875 bits,
876 value as u8,
877 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
878 );
879 }
880
881 pub fn pull(&mut self, value: Pull) {
883 #[cfg(any(feature = "h5", feature = "c0"))]
884 set_field!(
885 self.regs(),
886 self.pin,
887 pupdr,
888 pupd,
889 bits,
890 value as u8,
891 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
892 );
893
894 #[cfg(not(any(feature = "h5", feature = "c0")))]
895 set_field!(
896 self.regs(),
897 self.pin,
898 pupdr,
899 pupdr,
900 bits,
901 value as u8,
902 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
903 );
904 }
905
906 #[cfg(not(feature = "f373"))]
908 pub fn cfg_lock(&mut self, value: CfgLock) {
910 set_field!(
911 self.regs(),
912 self.pin,
913 lckr,
914 lck,
915 bit,
916 value as u8 != 0,
917 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
918 );
919 }
920
921 pub fn get_state(&mut self) -> PinState {
924 let val = get_input_data!(
925 self.regs(),
926 self.pin,
927 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
928 );
929 if val { PinState::High } else { PinState::Low }
930 }
931
932 pub fn set_state(&mut self, value: PinState) {
935 let offset = match value {
936 PinState::Low => 16,
937 PinState::High => 0,
938 };
939
940 set_state!(
941 self.regs(),
942 self.pin,
943 offset,
944 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
945 );
946 }
947
948 fn alt_fn(&mut self, value: u8) {
950 assert!(value <= 15, "Alt function must be 0 to 15.");
951
952 cfg_if! {
953 if #[cfg(any(feature = "l5", feature = "g0", feature = "c0", feature = "wb", feature = "h5"))] {
954 set_alt!(self.regs(), self.pin, afrel, value, [(0, l), (1, l), (2, l),
955 (3, l), (4, l), (5, l), (6, l), (7, l), (8, h), (9, h), (10, h), (11, h), (12, h),
956 (13, h), (14, h), (15, h)])
957 } else if #[cfg(feature = "h7")] {
958 set_alt!(self.regs(), self.pin, afr, value, [(0, l), (1, l), (2, l),
959 (3, l), (4, l), (5, l), (6, l), (7, l), (8, h), (9, h), (10, h), (11, h), (12, h),
960 (13, h), (14, h), (15, h)])
961 } else { set_alt!(self.regs(), self.pin, afr, value, [(0, l), (1, l), (2, l),
963 (3, l), (4, l), (5, l), (6, l), (7, l), (8, h), (9, h), (10, h), (11, h), (12, h),
964 (13, h), (14, h), (15, h)])
965 }
966 }
967 }
968
969 #[cfg(not(any(feature = "f373", feature = "wl")))]
970 pub fn enable_interrupt(&mut self, edge: Edge) {
972 let rising = match edge {
973 Edge::Falling => false,
974 _ => true, };
976
977 let falling = match edge {
978 Edge::Rising => false,
979 _ => true, };
981
982 cfg_if! {
983 if #[cfg(feature = "f4")] {
984 set_exti_f4!(self.pin, rising, falling, self.port.cr_val(), [(0, 1), (1, 1), (2, 1),
985 (3, 1), (4, 2), (5, 2), (6, 2), (7, 2), (8, 3), (9, 3), (10, 3), (11, 3), (12, 4),
986 (13, 4), (14, 4), (15, 4)]
987 );
988 } else {
989 set_exti!(self.pin, rising, falling, self.port.cr_val(), [(0, 1), (1, 1), (2, 1),
990 (3, 1), (4, 2), (5, 2), (6, 2), (7, 2), (8, 3), (9, 3), (10, 3), (11, 3), (12, 4),
991 (13, 4), (14, 4), (15, 4)]
992 );
993 }
994 }
995 }
996
997 #[cfg(feature = "l4x6")]
998 pub fn connect_to_adc(&mut self) {
1005 set_field!(
1006 self.regs(),
1007 self.pin,
1008 ascr,
1009 asc,
1010 bit,
1011 true,
1012 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
1013 );
1014 }
1015
1016 pub fn is_high(&self) -> bool {
1018 get_input_data!(
1019 self.regs(),
1020 self.pin,
1021 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
1022 )
1023 }
1024
1025 pub fn is_low(&self) -> bool {
1027 !self.is_high()
1028 }
1029
1030 pub fn set_high(&mut self) {
1032 self.set_state(PinState::High);
1033 }
1034
1035 pub fn set_low(&mut self) {
1037 self.set_state(PinState::Low);
1038 }
1039
1040 pub fn toggle(&mut self) {
1042 if Pin::is_high(self) {
1044 Pin::set_low(self);
1045 } else {
1047 Pin::set_high(self);
1049 }
1050 }
1051}
1052
1053#[cfg(feature = "embedded_hal")]
1054impl ErrorType for Pin {
1055 type Error = Infallible;
1056}
1057
1058#[cfg(feature = "embedded_hal")]
1059impl InputPin for Pin {
1060 fn is_high(&mut self) -> Result<bool, Self::Error> {
1061 Ok(Pin::is_high(self))
1062 }
1063
1064 fn is_low(&mut self) -> Result<bool, Self::Error> {
1065 Ok(Pin::is_low(self))
1066 }
1067}
1068
1069#[cfg(feature = "embedded_hal")]
1070impl OutputPin for Pin {
1071 fn set_low(&mut self) -> Result<(), Self::Error> {
1072 Pin::set_low(self);
1073 Ok(())
1074 }
1075
1076 fn set_high(&mut self) -> Result<(), Self::Error> {
1077 Pin::set_high(self);
1078 Ok(())
1079 }
1080}
1081
1082#[cfg(feature = "embedded_hal")]
1083impl StatefulOutputPin for Pin {
1084 fn is_set_high(&mut self) -> Result<bool, Self::Error> {
1085 Ok(Pin::is_high(self))
1086 }
1087
1088 fn is_set_low(&mut self) -> Result<bool, Self::Error> {
1089 Ok(Pin::is_low(self))
1090 }
1091
1092 fn toggle(&mut self) -> Result<(), Self::Error> {
1093 Pin::toggle(self);
1094 Ok(())
1095 }
1096}
1097
1098pub fn is_high(port: Port, pin: u8) -> bool {
1101 get_input_data!(
1102 regs(port),
1103 pin,
1104 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
1105 )
1106}
1107
1108pub fn is_low(port: Port, pin: u8) -> bool {
1111 !is_high(port, pin)
1112}
1113
1114pub fn set_high(port: Port, pin: u8) {
1117 set_state(port, pin, PinState::High);
1118}
1119
1120pub fn set_low(port: Port, pin: u8) {
1123 set_state(port, pin, PinState::Low);
1124}
1125
1126pub fn set_state(port: Port, pin: u8, value: PinState) {
1130 let offset = match value {
1131 PinState::Low => 16,
1132 PinState::High => 0,
1133 };
1134
1135 set_state!(
1136 regs(port),
1137 pin,
1138 offset,
1139 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
1140 );
1141}
1142
1143pub fn clear_exti_interrupt_edge(line: u8, edge: Edge) {
1146 unsafe {
1148 cfg_if! {
1149 if #[cfg(any(feature = "h747cm4", feature = "h747cm7"))] {
1150 (*EXTI::ptr()).c1pr1().modify(|_, w| {
1151 match line {
1152 0 => w.pr0().bit(true),
1153 1 => w.pr1().bit(true),
1154 2 => w.pr2().bit(true),
1155 3 => w.pr3().bit(true),
1156 4 => w.pr4().bit(true),
1157 5 => w.pr5().bit(true),
1158 6 => w.pr6().bit(true),
1159 7 => w.pr7().bit(true),
1160 8 => w.pr8().bit(true),
1161 9 => w.pr9().bit(true),
1162 10 => w.pr10().bit(true),
1163 11 => w.pr11().bit(true),
1164 12 => w.pr12().bit(true),
1165 13 => w.pr13().bit(true),
1166 14 => w.pr14().bit(true),
1167 15 => w.pr15().bit(true),
1168 _ => panic!(),
1169 }
1170 });
1171 } else if #[cfg(feature = "h7")] {
1172 (*EXTI::ptr()).cpupr1().modify(|_, w| {
1173 match line {
1174 0 => w.pr0().bit(true),
1175 1 => w.pr1().bit(true),
1176 2 => w.pr2().bit(true),
1177 3 => w.pr3().bit(true),
1178 4 => w.pr4().bit(true),
1179 5 => w.pr5().bit(true),
1180 6 => w.pr6().bit(true),
1181 7 => w.pr7().bit(true),
1182 8 => w.pr8().bit(true),
1183 9 => w.pr9().bit(true),
1184 10 => w.pr10().bit(true),
1185 11 => w.pr11().bit(true),
1186 12 => w.pr12().bit(true),
1187 13 => w.pr13().bit(true),
1188 14 => w.pr14().bit(true),
1189 15 => w.pr15().bit(true),
1190 _ => panic!(),
1191 }
1192 });
1193 } else if #[cfg(any(feature = "l5", feature = "g0", feature = "c0"))] {
1194 match edge {
1195 Edge::Rising => {
1196 (*EXTI::ptr()).rpr1().modify(|_, w| {
1197 match line {
1198 0 => w.rpif0().bit(true),
1199 1 => w.rpif1().bit(true),
1200 2 => w.rpif2().bit(true),
1201 3 => w.rpif3().bit(true),
1202 4 => w.rpif4().bit(true),
1203 5 => w.rpif5().bit(true),
1204 6 => w.rpif6().bit(true),
1205 7 => w.rpif7().bit(true),
1206 8 => w.rpif8().bit(true),
1207 9 => w.rpif9().bit(true),
1208 10 => w.rpif10().bit(true),
1209 11 => w.rpif11().bit(true),
1210 12 => w.rpif12().bit(true),
1211 13 => w.rpif13().bit(true),
1212 14 => w.rpif14().bit(true),
1213 15 => w.rpif15().bit(true),
1214 _ => panic!(),
1215 }
1216 });
1217 },
1218 Edge::Falling => {
1219 (*EXTI::ptr()).fpr1().modify(|_, w| {
1220 match line {
1221 0 => w.fpif0().bit(true),
1222 1 => w.fpif1().bit(true),
1223 2 => w.fpif2().bit(true),
1224 3 => w.fpif3().bit(true),
1225 4 => w.fpif4().bit(true),
1226 5 => w.fpif5().bit(true),
1227 6 => w.fpif6().bit(true),
1228 7 => w.fpif7().bit(true),
1229 8 => w.fpif8().bit(true),
1230 9 => w.fpif9().bit(true),
1231 10 => w.fpif10().bit(true),
1232 11 => w.fpif11().bit(true),
1233 12 => w.fpif12().bit(true),
1234 13 => w.fpif13().bit(true),
1235 14 => w.fpif14().bit(true),
1236 15 => w.fpif15().bit(true),
1237 _ => panic!(),
1238 }
1239 });
1240 },
1241 Edge::Either => panic!(),
1242 }
1243 } else if #[cfg(any(feature = "f373", feature = "f4"))] {
1244 (*EXTI::ptr()).pr().modify(|_, w| {
1245 match line {
1246 0 => w.pr0().bit(true),
1247 1 => w.pr1().bit(true),
1248 2 => w.pr2().bit(true),
1249 3 => w.pr3().bit(true),
1250 4 => w.pr4().bit(true),
1251 5 => w.pr5().bit(true),
1252 6 => w.pr6().bit(true),
1253 7 => w.pr7().bit(true),
1254 8 => w.pr8().bit(true),
1255 9 => w.pr9().bit(true),
1256 10 => w.pr10().bit(true),
1257 11 => w.pr11().bit(true),
1258 12 => w.pr12().bit(true),
1259 13 => w.pr13().bit(true),
1260 14 => w.pr14().bit(true),
1261 15 => w.pr15().bit(true),
1262 _ => panic!(),
1263 }
1264 });
1265 } else if #[cfg(any(feature = "f3", feature = "l4"))] {
1266 (*EXTI::ptr()).pr1().modify(|_, w| {
1267 match line {
1268 0 => w.pr0().bit(true),
1269 1 => w.pr1().bit(true),
1270 2 => w.pr2().bit(true),
1271 3 => w.pr3().bit(true),
1272 4 => w.pr4().bit(true),
1273 5 => w.pr5().bit(true),
1274 6 => w.pr6().bit(true),
1275 7 => w.pr7().bit(true),
1276 8 => w.pr8().bit(true),
1277 9 => w.pr9().bit(true),
1278 10 => w.pr10().bit(true),
1279 11 => w.pr11().bit(true),
1280 12 => w.pr12().bit(true),
1281 13 => w.pr13().bit(true),
1282 14 => w.pr14().bit(true),
1283 15 => w.pr15().bit(true),
1284 _ => panic!(),
1285 }
1286 });
1287 } else if #[cfg(feature = "h5")] {
1288 (*EXTI::ptr()).rpr1().modify(|_, w| {
1289 match line {
1290 0 => w.rpif0().bit(true),
1291 1 => w.rpif1().bit(true),
1292 2 => w.rpif2().bit(true),
1293 3 => w.rpif3().bit(true),
1294 4 => w.rpif4().bit(true),
1295 5 => w.rpif5().bit(true),
1296 6 => w.rpif6().bit(true),
1297 7 => w.rpif7().bit(true),
1298 8 => w.rpif8().bit(true),
1299 9 => w.rpif9().bit(true),
1300 10 => w.rpif10().bit(true),
1301 11 => w.rpif11().bit(true),
1302 12 => w.rpif12().bit(true),
1303 13 => w.rpif13().bit(true),
1304 14 => w.rpif14().bit(true),
1305 15 => w.rpif15().bit(true),
1306 _ => panic!(),
1307 }
1308 });
1309 } else { (*EXTI::ptr()).pr1().modify(|_, w| {
1311 match line {
1312 0 => w.pif0().bit(true),
1313 1 => w.pif1().bit(true),
1314 2 => w.pif2().bit(true),
1315 3 => w.pif3().bit(true),
1316 4 => w.pif4().bit(true),
1317 5 => w.pif5().bit(true),
1318 6 => w.pif6().bit(true),
1319 7 => w.pif7().bit(true),
1320 8 => w.pif8().bit(true),
1321 9 => w.pif9().bit(true),
1322 10 => w.pif10().bit(true),
1323 11 => w.pif11().bit(true),
1324 12 => w.pif12().bit(true),
1325 13 => w.pif13().bit(true),
1326 14 => w.pif14().bit(true),
1327 15 => w.pif15().bit(true),
1328 _ => panic!(),
1329 }
1330 });
1331 }
1332 }
1333 }
1334}
1335
1336#[cfg(any(feature = "l5", feature = "g0", feature = "c0"))]
1339pub fn clear_exti_interrupt(line: u8, edge: Edge) {
1340 clear_exti_interrupt_edge(line, edge);
1342}
1343
1344#[cfg(not(any(feature = "l5", feature = "g0", feature = "c0")))]
1345pub fn clear_exti_interrupt(line: u8) {
1348 clear_exti_interrupt_edge(line, Edge::Rising); }
1351
1352const fn regs(port: Port) -> *const pac::gpioa::RegisterBlock {
1353 match port {
1356 Port::A => crate::pac::GPIOA::ptr(),
1357 Port::B => crate::pac::GPIOB::ptr() as _,
1358 #[cfg(not(feature = "wl"))]
1359 Port::C => crate::pac::GPIOC::ptr() as _,
1360 #[cfg(not(any(feature = "f410", feature = "wl", feature = "l412")))]
1361 Port::D => crate::pac::GPIOD::ptr() as _,
1362 #[cfg(not(any(
1363 feature = "f301",
1364 feature = "f3x4",
1365 feature = "f410",
1366 feature = "g0",
1367 feature = "c0",
1368 feature = "wb",
1369 feature = "wl",
1370 feature = "l412",
1371 )))]
1372 Port::E => crate::pac::GPIOE::ptr() as _,
1373 #[cfg(not(any(
1374 feature = "f401",
1375 feature = "f410",
1376 feature = "f411",
1377 feature = "l4x1",
1378 feature = "l4x2",
1379 feature = "l412",
1380 feature = "l4x3",
1381 feature = "wb",
1382 feature = "wl"
1383 )))]
1384 Port::F => crate::pac::GPIOF::ptr() as _,
1385 #[cfg(not(any(
1386 feature = "f373",
1387 feature = "f301",
1388 feature = "f3x4",
1389 feature = "f401",
1390 feature = "f410",
1391 feature = "f411",
1392 feature = "l4x1",
1393 feature = "l4x2",
1394 feature = "l412",
1395 feature = "l4x3",
1396 feature = "g0",
1397 feature = "c0",
1398 feature = "wb",
1399 feature = "wl"
1400 )))]
1401 Port::G => crate::pac::GPIOG::ptr() as _,
1402 #[cfg(not(any(
1403 feature = "f373",
1404 feature = "f301",
1405 feature = "f3x4",
1406 feature = "f410",
1407 feature = "l4x1",
1408 feature = "l4x2",
1409 feature = "l412",
1410 feature = "l4x3",
1411 feature = "g0",
1412 feature = "c0",
1413 feature = "g4",
1414 feature = "wb",
1415 feature = "wl"
1416 )))]
1417 Port::H => crate::pac::GPIOH::ptr() as _,
1418 #[cfg(any(feature = "h747cm4", feature = "h747cm7", feature = "l4x6"))]
1419 Port::I => crate::pac::GPIOI::ptr() as _,
1420 }
1421}
1422
1423#[cfg(not(any(
1424 feature = "f4",
1425 feature = "l5",
1426 feature = "f3",
1427 feature = "l4",
1428 feature = "h5"
1429)))]
1430pub unsafe fn write_dma(
1433 buf: &[u32],
1434 port: Port,
1435 dma_channel: DmaChannel,
1436 channel_cfg: ChannelCfg,
1437 dma_periph: dma::DmaPeriph,
1438) -> crate::error::Result<()> {
1439 let (ptr, len) = (buf.as_ptr(), buf.len());
1440
1441 let periph_addr = unsafe { &(*(regs(port))).bsrr() as *const _ as u32 };
1442
1443 let num_data = len as u32;
1444
1445 match dma_periph {
1446 dma::DmaPeriph::Dma1 => {
1447 let mut regs = unsafe { &(*DMA1::ptr()) };
1448
1449 dma::cfg_channel(
1450 &mut regs,
1451 dma_channel,
1452 periph_addr,
1453 ptr as u32,
1454 num_data,
1455 dma::Direction::ReadFromMem,
1456 dma::DataSize::S32,
1457 dma::DataSize::S32,
1458 channel_cfg,
1459 )?;
1460 }
1461 #[cfg(dma2)]
1462 dma::DmaPeriph::Dma2 => {
1463 let mut regs = unsafe { &(*pac::DMA2::ptr()) };
1464 dma::cfg_channel(
1465 &mut regs,
1466 dma_channel,
1467 periph_addr,
1468 ptr as u32,
1469 num_data,
1470 dma::Direction::ReadFromMem,
1471 dma::DataSize::S32,
1472 dma::DataSize::S32,
1473 channel_cfg,
1474 )?;
1475 }
1476 }
1477 Ok(())
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) -> crate::error::Result<()> {
1495 let (ptr, len) = (buf.as_ptr(), buf.len());
1496
1497 let periph_addr = unsafe { (*(regs(port))).idr().as_ptr() as u32 };
1499
1500 let num_data = len as u32;
1502 match dma_periph {
1506 dma::DmaPeriph::Dma1 => {
1507 let mut regs = unsafe { &(*DMA1::ptr()) };
1508
1509 dma::cfg_channel(
1510 &mut regs,
1511 dma_channel,
1512 periph_addr,
1513 ptr as u32,
1514 num_data,
1515 dma::Direction::ReadFromPeriph,
1516 dma::DataSize::S32,
1517 dma::DataSize::S32,
1518 channel_cfg,
1519 )?;
1520 }
1521 #[cfg(not(any(feature = "g0", feature = "c0", feature = "wb")))]
1522 dma::DmaPeriph::Dma2 => {
1523 let mut regs = unsafe { &(*pac::DMA2::ptr()) };
1524 dma::cfg_channel(
1525 &mut regs,
1526 dma_channel,
1527 periph_addr,
1528 ptr as u32,
1529 num_data,
1530 dma::Direction::ReadFromPeriph,
1531 dma::DataSize::S32,
1532 dma::DataSize::S32,
1533 channel_cfg,
1534 )?;
1535 }
1536 }
1537
1538 Ok(())
1539}