stm32f429_hal/
gpio.rs

1//! General Purpose Input / Output
2
3// TODO the pins here currently correspond to the LQFP-100 package. There should be Cargo features
4// that let you select different microcontroller packages
5
6use core::marker::PhantomData;
7
8use rcc::AHB1;
9
10/// Extension trait to split a GPIO peripheral in independent pins and registers
11pub trait GpioExt {
12    /// The to split the GPIO into
13    type Parts;
14
15    /// Splits the GPIO block into independent pins and registers
16    fn split(self, ahb: &mut AHB1) -> Self::Parts;
17}
18
19/// Input mode (type state)
20pub struct Input<MODE> {
21    _mode: PhantomData<MODE>,
22}
23
24/// Floating input (type state)
25pub struct Floating;
26/// Pulled down input (type state)
27pub struct PullDown;
28/// Pulled up input (type state)
29pub struct PullUp;
30
31/// Output mode (type state)
32pub struct Output<MODE> {
33    _mode: PhantomData<MODE>,
34}
35
36/// Push pull output (type state)
37pub struct PushPull;
38/// Open drain output (type state)
39pub struct OpenDrain;
40
41/// Alternate function 0 (type state)
42pub struct AF0;
43
44/// Alternate function 1 (type state)
45pub struct AF1;
46
47/// Alternate function 2 (type state)
48pub struct AF2;
49
50/// Alternate function 3 (type state)
51pub struct AF3;
52
53/// Alternate function 4 (type state)
54pub struct AF4;
55
56/// Alternate function 5 (type state)
57pub struct AF5;
58
59/// Alternate function 6 (type state)
60pub struct AF6;
61
62/// Alternate function 7 (type state)
63pub struct AF7;
64
65/// Alternate function 8 (type state)
66pub struct AF8;
67
68/// Alternate function 9 (type state)
69pub struct AF9;
70
71/// Alternate function 10 (type state)
72pub struct AF10;
73
74/// Alternate function 11 (type state)
75pub struct AF11;
76
77/// Alternate function 12 (type state)
78pub struct AF12;
79
80/// Alternate function 13 (type state)
81pub struct AF13;
82
83/// Alternate function 14 (type state)
84pub struct AF14;
85
86/// Alternate function 15 (type state)
87pub struct AF15;
88
89macro_rules! gpio {
90    ($GPIOX:ident, $gpiox:ident, $gpioy:ident, $iopxenr:ident, $iopxrst:ident, $PXx:ident, [
91        $($PXi:ident: ($pxi:ident, $i:expr, $MODE:ty, $AFR:ident),)+
92    ]) => {
93        /// GPIO
94        pub mod $gpiox {
95            use core::marker::PhantomData;
96
97            use hal::digital::{InputPin, OutputPin};
98            use stm32f429::{$gpioy, $GPIOX};
99
100            use rcc::AHB1;
101            use super::{
102                AF4, AF5, AF6, AF7, Floating, GpioExt, Input, OpenDrain, Output,
103                PullDown, PullUp, PushPull,
104            };
105
106            /// GPIO parts
107            pub struct Parts {
108                /// Opaque AFRH register
109                pub afrh: AFRH,
110                /// Opaque AFRL register
111                pub afrl: AFRL,
112                /// Opaque MODER register
113                pub moder: MODER,
114                /// Opaque OTYPER register
115                pub otyper: OTYPER,
116                /// Opaque PUPDR register
117                pub pupdr: PUPDR,
118                $(
119                    /// Pin
120                    pub $pxi: $PXi<$MODE>,
121                )+
122            }
123
124            impl GpioExt for $GPIOX {
125                type Parts = Parts;
126
127                fn split(self, ahb: &mut AHB1) -> Parts {
128                    ahb.enr().modify(|_, w| w.$iopxenr().set_bit());
129                    ahb.rstr().modify(|_, w| w.$iopxrst().set_bit());
130                    ahb.rstr().modify(|_, w| w.$iopxrst().clear_bit());
131
132                    Parts {
133                        afrh: AFRH { _0: () },
134                        afrl: AFRL { _0: () },
135                        moder: MODER { _0: () },
136                        otyper: OTYPER { _0: () },
137                        pupdr: PUPDR { _0: () },
138                        $(
139                            $pxi: $PXi { _mode: PhantomData },
140                        )+
141                    }
142                }
143            }
144
145            /// Opaque AFRL register
146            pub struct AFRL {
147                _0: (),
148            }
149
150            impl AFRL {
151                pub(crate) fn afr(&mut self) -> &$gpioy::AFRL {
152                    unsafe { &(*$GPIOX::ptr()).afrl }
153                }
154            }
155
156            /// Opaque AFRH register
157            pub struct AFRH {
158                _0: (),
159            }
160
161            impl AFRH {
162                pub(crate) fn afr(&mut self) -> &$gpioy::AFRH {
163                    unsafe { &(*$GPIOX::ptr()).afrh }
164                }
165            }
166
167            /// Opaque MODER register
168            pub struct MODER {
169                _0: (),
170            }
171
172            impl MODER {
173                pub(crate) fn moder(&mut self) -> &$gpioy::MODER {
174                    unsafe { &(*$GPIOX::ptr()).moder }
175                }
176            }
177
178            /// Opaque OTYPER register
179            pub struct OTYPER {
180                _0: (),
181            }
182
183            impl OTYPER {
184                pub(crate) fn otyper(&mut self) -> &$gpioy::OTYPER {
185                    unsafe { &(*$GPIOX::ptr()).otyper }
186                }
187            }
188
189            /// Opaque PUPDR register
190            pub struct PUPDR {
191                _0: (),
192            }
193
194            impl PUPDR {
195                pub(crate) fn pupdr(&mut self) -> &$gpioy::PUPDR {
196                    unsafe { &(*$GPIOX::ptr()).pupdr }
197                }
198            }
199
200            /// Partially erased pin
201            pub struct $PXx<MODE> {
202                i: u8,
203                _mode: PhantomData<MODE>,
204            }
205
206            impl<MODE> InputPin for $PXx<Input<MODE>> {
207                fn is_high(&self) -> bool {
208                    !self.is_low()
209                }
210
211                fn is_low(&self) -> bool {
212                    // NOTE(unsafe) atomic read with no side effects
213                    unsafe { (*$GPIOX::ptr()).odr.read().bits() & (1 << self.i) == 0 }
214                }
215            }
216
217            impl<MODE> OutputPin for $PXx<Output<MODE>> {
218                fn set_high(&mut self) {
219                    // NOTE(unsafe) atomic write to a stateless register
220                    unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << self.i)) }
221                }
222
223                fn set_low(&mut self) {
224                    // NOTE(unsafe) atomic write to a stateless register
225                    unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << (16 + self.i))) }
226                }
227            }
228
229            $(
230                /// Pin
231                pub struct $PXi<MODE> {
232                    _mode: PhantomData<MODE>,
233                }
234
235                impl<MODE> $PXi<MODE> {
236                    /// Configures the pin to serve as alternate function 4 (AF4)
237                    pub fn into_af4(
238                        self,
239                        moder: &mut MODER,
240                        afr: &mut $AFR,
241                    ) -> $PXi<AF4> {
242                        let offset = 2 * $i;
243
244                        // alternate function mode
245                        let mode = 0b10;
246                        moder.moder().modify(|r, w| unsafe {
247                            w.bits((r.bits() & !(0b11 << offset)) | (mode << offset))
248                        });
249
250                        let af = 4;
251                        let offset = 4 * ($i % 8);
252                        afr.afr().modify(|r, w| unsafe {
253                            w.bits((r.bits() & !(0b1111 << offset)) | (af << offset))
254                        });
255
256                        $PXi { _mode: PhantomData }
257                    }
258
259                    /// Configures the pin to serve as alternate function 5 (AF5)
260                    pub fn into_af5(
261                        self,
262                        moder: &mut MODER,
263                        afr: &mut $AFR,
264                    ) -> $PXi<AF5> {
265                        let offset = 2 * $i;
266
267                        // alternate function mode
268                        let mode = 0b10;
269                        moder.moder().modify(|r, w| unsafe {
270                            w.bits((r.bits() & !(0b11 << offset)) | (mode << offset))
271                        });
272
273                        let af = 5;
274                        let offset = 4 * ($i % 8);
275                        afr.afr().modify(|r, w| unsafe {
276                            w.bits((r.bits() & !(0b1111 << offset)) | (af << offset))
277                        });
278
279                        $PXi { _mode: PhantomData }
280                    }
281
282                    /// Configures the pin to serve as alternate function 6 (AF6)
283                    pub fn into_af6(
284                        self,
285                        moder: &mut MODER,
286                        afr: &mut $AFR,
287                    ) -> $PXi<AF6> {
288                        let offset = 2 * $i;
289
290                        // alternate function mode
291                        let mode = 0b10;
292                        moder.moder().modify(|r, w| unsafe {
293                            w.bits((r.bits() & !(0b11 << offset)) | (mode << offset))
294                        });
295
296                        let af = 6;
297                        let offset = 4 * ($i % 8);
298                        afr.afr().modify(|r, w| unsafe {
299                            w.bits((r.bits() & !(0b1111 << offset)) | (af << offset))
300                        });
301
302                        $PXi { _mode: PhantomData }
303                    }
304
305                    /// Configures the pin to serve as alternate function 7 (AF7)
306                    pub fn into_af7(
307                        self,
308                        moder: &mut MODER,
309                        afr: &mut $AFR,
310                    ) -> $PXi<AF7> {
311                        let offset = 2 * $i;
312
313                        // alternate function mode
314                        let mode = 0b10;
315                        moder.moder().modify(|r, w| unsafe {
316                            w.bits((r.bits() & !(0b11 << offset)) | (mode << offset))
317                        });
318
319                        let af = 7;
320                        let offset = 4 * ($i % 8);
321
322                        afr.afr().modify(|r, w| unsafe {
323                            w.bits((r.bits() & !(0b1111 << offset)) | (af << offset))
324                        });
325
326                        $PXi { _mode: PhantomData }
327                    }
328
329                    /// Configures the pin to operate as a floating input pin
330                    pub fn into_floating_input(
331                        self,
332                        moder: &mut MODER,
333                        pupdr: &mut PUPDR,
334                    ) -> $PXi<Input<Floating>> {
335                        let offset = 2 * $i;
336
337                        // input mode
338                        moder
339                            .moder()
340                            .modify(|r, w| unsafe { w.bits(r.bits() & !(0b11 << offset)) });
341
342                        // no pull-up or pull-down
343                        pupdr
344                            .pupdr()
345                            .modify(|r, w| unsafe { w.bits(r.bits() & !(0b11 << offset)) });
346
347                        $PXi { _mode: PhantomData }
348                    }
349
350                    /// Configures the pin to operate as a pulled down input pin
351                    pub fn into_pull_down_input(
352                        self,
353                        moder: &mut MODER,
354                        pupdr: &mut PUPDR,
355                    ) -> $PXi<Input<PullDown>> {
356                        let offset = 2 * $i;
357
358                        // input mode
359                        moder
360                            .moder()
361                            .modify(|r, w| unsafe { w.bits(r.bits() & !(0b11 << offset)) });
362
363                        // pull-down
364                        pupdr.pupdr().modify(|r, w| unsafe {
365                            w.bits((r.bits() & !(0b11 << offset)) | (0b10 << offset))
366                        });
367
368                        $PXi { _mode: PhantomData }
369                    }
370
371                    /// Configures the pin to operate as a pulled up input pin
372                    pub fn into_pull_up_input(
373                        self,
374                        moder: &mut MODER,
375                        pupdr: &mut PUPDR,
376                    ) -> $PXi<Input<PullUp>> {
377                        let offset = 2 * $i;
378
379                        // input mode
380                        moder
381                            .moder()
382                            .modify(|r, w| unsafe { w.bits(r.bits() & !(0b11 << offset)) });
383
384                        // pull-up
385                        pupdr.pupdr().modify(|r, w| unsafe {
386                            w.bits((r.bits() & !(0b11 << offset)) | (0b01 << offset))
387                        });
388
389                        $PXi { _mode: PhantomData }
390                    }
391
392                    /// Configures the pin to operate as an open drain output pin
393                    pub fn into_open_drain_output(
394                        self,
395                        moder: &mut MODER,
396                        otyper: &mut OTYPER,
397                    ) -> $PXi<Output<OpenDrain>> {
398                        let offset = 2 * $i;
399
400                        // general purpose output mode
401                        let mode = 0b01;
402                        moder.moder().modify(|r, w| unsafe {
403                            w.bits((r.bits() & !(0b11 << offset)) | (mode << offset))
404                        });
405
406                        // open drain output
407                        otyper
408                            .otyper()
409                            .modify(|r, w| unsafe { w.bits(r.bits() | (0b1 << $i)) });
410
411                        $PXi { _mode: PhantomData }
412                    }
413
414                    /// Configures the pin to operate as an push pull output pin
415                    pub fn into_push_pull_output(
416                        self,
417                        moder: &mut MODER,
418                        otyper: &mut OTYPER,
419                    ) -> $PXi<Output<PushPull>> {
420                        let offset = 2 * $i;
421
422                        // general purpose output mode
423                        let mode = 0b01;
424                        moder.moder().modify(|r, w| unsafe {
425                            w.bits((r.bits() & !(0b11 << offset)) | (mode << offset))
426                        });
427
428                        // push pull output
429                        otyper
430                            .otyper()
431                            .modify(|r, w| unsafe { w.bits(r.bits() & !(0b1 << $i)) });
432
433                        $PXi { _mode: PhantomData }
434                    }
435                }
436
437                impl $PXi<Output<OpenDrain>> {
438                    /// Enables / disables the internal pull up
439                    pub fn internal_pull_up(&mut self, pupdr: &mut PUPDR, on: bool) {
440                        let offset = 2 * $i;
441
442                        pupdr.pupdr().modify(|r, w| unsafe {
443                            w.bits(
444                                (r.bits() & !(0b11 << offset)) | if on {
445                                    0b01 << offset
446                                } else {
447                                    0
448                                },
449                            )
450                        });
451                    }
452                }
453
454                impl<MODE> $PXi<Output<MODE>> {
455                    /// Erases the pin number from the type
456                    ///
457                    /// This is useful when you want to collect the pins into an array where you
458                    /// need all the elements to have the same type
459                    pub fn downgrade(self) -> $PXx<Output<MODE>> {
460                        $PXx {
461                            i: $i,
462                            _mode: self._mode,
463                        }
464                    }
465                }
466
467                impl<MODE> InputPin for $PXi<Input<MODE>> {
468                    fn is_high(&self) -> bool {
469                        !self.is_low()
470                    }
471
472                    fn is_low(&self) -> bool {
473                        // NOTE(unsafe) atomic read with no side effects
474                        unsafe { (*$GPIOX::ptr()).odr.read().bits() & (1 << $i) == 0 }
475                    }
476                }
477
478                impl<MODE> OutputPin for $PXi<Output<MODE>> {
479                    fn set_high(&mut self) {
480                        // NOTE(unsafe) atomic write to a stateless register
481                        unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << $i)) }
482                    }
483
484                    fn set_low(&mut self) {
485                        // NOTE(unsafe) atomic write to a stateless register
486                        unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << (16 + $i))) }
487                    }
488                }
489            )+
490        }
491    }
492}
493
494gpio!(GPIOA, gpioa, gpioa, gpioaen, gpioarst, PAx, [
495    PA0: (pa0, 0, Input<Floating>, AFRL),
496    PA1: (pa1, 1, Input<Floating>, AFRL),
497    PA2: (pa2, 2, Input<Floating>, AFRL),
498    PA3: (pa3, 3, Input<Floating>, AFRL),
499    PA4: (pa4, 4, Input<Floating>, AFRL),
500    PA5: (pa5, 5, Input<Floating>, AFRL),
501    PA6: (pa6, 6, Input<Floating>, AFRL),
502    PA7: (pa7, 7, Input<Floating>, AFRL),
503    PA8: (pa8, 8, Input<Floating>, AFRH),
504    PA9: (pa9, 9, Input<Floating>, AFRH),
505    PA10: (pa10, 10, Input<Floating>, AFRH),
506    PA11: (pa11, 11, Input<Floating>, AFRH),
507    PA12: (pa12, 12, Input<Floating>, AFRH),
508    // TODO these are configured as JTAG pins
509    // PA13: (13, Input<Floating>),
510    // PA14: (14, Input<Floating>),
511    // PA15: (15, Input<Floating>),
512]);
513
514gpio!(GPIOB, gpiob, gpiob, gpioben, gpiobrst, PBx, [
515    PB0: (pb0, 0, Input<Floating>, AFRL),
516    PB1: (pb1, 1, Input<Floating>, AFRL),
517    PB2: (pb2, 2, Input<Floating>, AFRL),
518    // TODO these are configured as JTAG pins
519    // PB3: (3, Input<Floating>),
520    // PB4: (4, Input<Floating>),
521    PB5: (pb5, 5, Input<Floating>, AFRL),
522    PB6: (pb6, 6, Input<Floating>, AFRL),
523    PB7: (pb7, 7, Input<Floating>, AFRL),
524    PB8: (pb8, 8, Input<Floating>, AFRH),
525    PB9: (pb9, 9, Input<Floating>, AFRH),
526    PB10: (pb10, 10, Input<Floating>, AFRH),
527    PB11: (pb11, 11, Input<Floating>, AFRH),
528    PB12: (pb12, 12, Input<Floating>, AFRH),
529    PB13: (pb13, 13, Input<Floating>, AFRH),
530    PB14: (pb14, 14, Input<Floating>, AFRH),
531    PB15: (pb15, 15, Input<Floating>, AFRH),
532]);
533
534gpio!(GPIOC, gpioc, gpiok, gpiocen, gpiocrst, PCx, [
535    PC0: (pc0, 0, Input<Floating>, AFRL),
536    PC1: (pc1, 1, Input<Floating>, AFRL),
537    PC2: (pc2, 2, Input<Floating>, AFRL),
538    PC3: (pc3, 3, Input<Floating>, AFRL),
539    PC4: (pc4, 4, Input<Floating>, AFRL),
540    PC5: (pc5, 5, Input<Floating>, AFRL),
541    PC6: (pc6, 6, Input<Floating>, AFRL),
542    PC7: (pc7, 7, Input<Floating>, AFRL),
543    PC8: (pc8, 8, Input<Floating>, AFRH),
544    PC9: (pc9, 9, Input<Floating>, AFRH),
545    PC10: (pc10, 10, Input<Floating>, AFRH),
546    PC11: (pc11, 11, Input<Floating>, AFRH),
547    PC12: (pc12, 12, Input<Floating>, AFRH),
548    PC13: (pc13, 13, Input<Floating>, AFRH),
549    PC14: (pc14, 14, Input<Floating>, AFRH),
550    PC15: (pc15, 15, Input<Floating>, AFRH),
551]);
552
553gpio!(GPIOD, gpiod, gpiok, gpioden, gpiodrst, PDx, [
554    PD0: (pd0, 0, Input<Floating>, AFRL),
555    PD1: (pd1, 1, Input<Floating>, AFRL),
556    PD2: (pd2, 2, Input<Floating>, AFRL),
557    PD3: (pd3, 3, Input<Floating>, AFRL),
558    PD4: (pd4, 4, Input<Floating>, AFRL),
559    PD5: (pd5, 5, Input<Floating>, AFRL),
560    PD6: (pd6, 6, Input<Floating>, AFRL),
561    PD7: (pd7, 7, Input<Floating>, AFRL),
562    PD8: (pd8, 8, Input<Floating>, AFRH),
563    PD9: (pd9, 9, Input<Floating>, AFRH),
564    PD10: (pd10, 10, Input<Floating>, AFRH),
565    PD11: (pd11, 11, Input<Floating>, AFRH),
566    PD12: (pd12, 12, Input<Floating>, AFRH),
567    PD13: (pd13, 13, Input<Floating>, AFRH),
568    PD14: (pd14, 14, Input<Floating>, AFRH),
569    PD15: (pd15, 15, Input<Floating>, AFRH),
570]);
571
572gpio!(GPIOE, gpioe, gpiok, gpioeen, gpioerst, PEx, [
573    PE0: (pe0, 0, Input<Floating>, AFRL),
574    PE1: (pe1, 1, Input<Floating>, AFRL),
575    PE2: (pe2, 2, Input<Floating>, AFRL),
576    PE3: (pe3, 3, Input<Floating>, AFRL),
577    PE4: (pe4, 4, Input<Floating>, AFRL),
578    PE5: (pe5, 5, Input<Floating>, AFRL),
579    PE6: (pe6, 6, Input<Floating>, AFRL),
580    PE7: (pe7, 7, Input<Floating>, AFRL),
581    PE8: (pe8, 8, Input<Floating>, AFRH),
582    PE9: (pe9, 9, Input<Floating>, AFRH),
583    PE10: (pe10, 10, Input<Floating>, AFRH),
584    PE11: (pe11, 11, Input<Floating>, AFRH),
585    PE12: (pe12, 12, Input<Floating>, AFRH),
586    PE13: (pe13, 13, Input<Floating>, AFRH),
587    PE14: (pe14, 14, Input<Floating>, AFRH),
588    PE15: (pe15, 15, Input<Floating>, AFRH),
589]);
590
591gpio!(GPIOF, gpiof, gpiok, gpiofen, gpiofrst, PFx, [
592    PF0: (pf0, 0, Input<Floating>, AFRL),
593    PF1: (pf1, 1, Input<Floating>, AFRL),
594    PF2: (pf2, 2, Input<Floating>, AFRL),
595    PF3: (pf3, 3, Input<Floating>, AFRL),
596    PF4: (pf4, 4, Input<Floating>, AFRL),
597    PF5: (pf5, 5, Input<Floating>, AFRL),
598    PF6: (pf6, 6, Input<Floating>, AFRL),
599    PF7: (pf7, 7, Input<Floating>, AFRL),
600    PF8: (pf8, 8, Input<Floating>, AFRL),
601    PF9: (pf9, 9, Input<Floating>, AFRH),
602    PF10: (pf10, 10, Input<Floating>, AFRH),
603    PF11: (pf11, 11, Input<Floating>, AFRH),
604    PF12: (pf12, 12, Input<Floating>, AFRH),
605    PF13: (pf13, 13, Input<Floating>, AFRH),
606    PF14: (pf14, 14, Input<Floating>, AFRH),
607    PF15: (pf15, 15, Input<Floating>, AFRH),
608]);
609
610gpio!(GPIOG, gpiog, gpiok, gpiogen, gpiogrst, PGx, [
611    PG0: (pg0, 0, Input<Floating>, AFRL),
612    PG1: (pg1, 1, Input<Floating>, AFRL),
613    PG2: (pg2, 2, Input<Floating>, AFRL),
614    PG3: (pg3, 3, Input<Floating>, AFRL),
615    PG4: (pg4, 4, Input<Floating>, AFRL),
616    PG5: (pg5, 5, Input<Floating>, AFRL),
617    PG6: (pg6, 6, Input<Floating>, AFRL),
618    PG7: (pg7, 7, Input<Floating>, AFRL),
619    PG8: (pg8, 8, Input<Floating>, AFRL),
620    PG9: (pg9, 9, Input<Floating>, AFRH),
621    PG10: (pg10, 10, Input<Floating>, AFRH),
622    PG11: (pg11, 11, Input<Floating>, AFRH),
623    PG12: (pg12, 12, Input<Floating>, AFRH),
624    PG13: (pg13, 13, Input<Floating>, AFRH),
625    PG14: (pg14, 14, Input<Floating>, AFRH),
626    PG15: (pg15, 15, Input<Floating>, AFRH),
627]);
628
629gpio!(GPIOH, gpioh, gpiok, gpiohen, gpiohrst, PHx, [
630    PH0: (ph0, 0, Input<Floating>, AFRL),
631    PH1: (ph1, 1, Input<Floating>, AFRL),
632    PH2: (ph2, 2, Input<Floating>, AFRL),
633    PH3: (ph3, 3, Input<Floating>, AFRL),
634    PH4: (ph4, 4, Input<Floating>, AFRL),
635    PH5: (ph5, 5, Input<Floating>, AFRL),
636    PH6: (ph6, 6, Input<Floating>, AFRL),
637    PH7: (ph7, 7, Input<Floating>, AFRL),
638    PH8: (ph8, 8, Input<Floating>, AFRL),
639    PH9: (ph9, 9, Input<Floating>, AFRH),
640    PH10: (ph10, 10, Input<Floating>, AFRH),
641    PH11: (ph11, 11, Input<Floating>, AFRH),
642    PH12: (ph12, 12, Input<Floating>, AFRH),
643    PH13: (ph13, 13, Input<Floating>, AFRH),
644    PH14: (ph14, 14, Input<Floating>, AFRH),
645    PH15: (ph15, 15, Input<Floating>, AFRH),
646]);
647
648gpio!(GPIOI, gpioi, gpiok, gpioien, gpioirst, PIx, [
649    PI0: (pi0, 0, Input<Floating>, AFRL),
650    PI1: (pi1, 1, Input<Floating>, AFRL),
651    PI2: (pi2, 2, Input<Floating>, AFRL),
652    PI3: (pi3, 3, Input<Floating>, AFRL),
653    PI4: (pi4, 4, Input<Floating>, AFRL),
654    PI5: (pi5, 5, Input<Floating>, AFRL),
655    PI6: (pi6, 6, Input<Floating>, AFRL),
656    PI7: (pi7, 7, Input<Floating>, AFRL),
657    PI8: (pi8, 8, Input<Floating>, AFRL),
658    PI9: (pi9, 9, Input<Floating>, AFRH),
659    PI10: (pi10, 10, Input<Floating>, AFRH),
660    PI11: (pi11, 11, Input<Floating>, AFRH),
661    PI12: (pi12, 12, Input<Floating>, AFRH),
662    PI13: (pi13, 13, Input<Floating>, AFRH),
663    PI14: (pi14, 14, Input<Floating>, AFRH),
664    PI15: (pi15, 15, Input<Floating>, AFRH),
665]);
666
667// gpio!(GPIOJ, gpioj, gpiok, gpiojen, gpiojrst, PJx, [
668//     PJ0: (pj0, 0, Input<Floating>, AFRL),
669//     PJ1: (pj1, 1, Input<Floating>, AFRL),
670//     PJ2: (pj2, 2, Input<Floating>, AFRL),
671//     PJ3: (pj3, 3, Input<Floating>, AFRL),
672//     PJ4: (pj4, 4, Input<Floating>, AFRL),
673//     PJ5: (pj5, 5, Input<Floating>, AFRL),
674//     PJ6: (pj6, 6, Input<Floating>, AFRL),
675//     PJ7: (pj7, 7, Input<Floating>, AFRL),
676//     PJ8: (pj8, 8, Input<Floating>, AFRL),
677//     PJ9: (pj9, 9, Input<Floating>, AFRH),
678//     PJ10: (pj10, 10, Input<Floating>, AFRH),
679//     PJ11: (pj11, 11, Input<Floating>, AFRH),
680//     PJ12: (pj12, 12, Input<Floating>, AFRH),
681//     PJ13: (pj13, 13, Input<Floating>, AFRH),
682//     PJ14: (pj14, 14, Input<Floating>, AFRH),
683//     PJ15: (pj15, 15, Input<Floating>, AFRH),
684// ]);
685
686// gpio!(GPIOK, gpiok, gpiok, gpioken, gpiokrst, PKx, [
687//     PK0: (pk0, 0, Input<Floating>, AFRL),
688//     PK1: (pk1, 1, Input<Floating>, AFRL),
689//     PK2: (pk2, 2, Input<Floating>, AFRL),
690//     PK3: (pk3, 3, Input<Floating>, AFRL),
691//     PK4: (pk4, 4, Input<Floating>, AFRL),
692//     PK5: (pk5, 5, Input<Floating>, AFRL),
693//     PK6: (pk6, 6, Input<Floating>, AFRL),
694//     PK7: (pk7, 7, Input<Floating>, AFRL),
695//     PK8: (pk8, 8, Input<Floating>, AFRL),
696//     PK9: (pk9, 9, Input<Floating>, AFRH),
697//     PK10: (pk10, 10, Input<Floating>, AFRH),
698//     PK11: (pk11, 11, Input<Floating>, AFRH),
699//     PK12: (pk12, 12, Input<Floating>, AFRH),
700//     PK13: (pk13, 13, Input<Floating>, AFRH),
701//     PK14: (pk14, 14, Input<Floating>, AFRH),
702//     PK15: (pk15, 15, Input<Floating>, AFRH),
703// ]);