stm32f3xx_hal/
gpio.rs

1//! # General Purpose Input / Output
2//!
3//! To use the GPIO pins, you first need to configure the GPIO port (GPIOA, GPIOB, ...) that you
4//! are interested in. This is done using the [`GpioExt::split`] function.
5//!
6//! ```
7//! let dp = pac::Peripherals::take().unwrap();
8//! let rcc = dp.RCC.constrain();
9//!
10//! let mut gpioa = dp.GPIOA.split(&mut rcc.ahb);
11//! ```
12//!
13//! The resulting [Parts](gpioa::Parts) struct contains one field for each pin, as well as some
14//! shared registers. Every pin type is a specialized version of generic [pin](Pin) struct.
15//!
16//! To use a pin, first use the relevant `into_...` method of the [pin](Pin).
17//!
18//! ```rust
19//! let pa0 = gpioa.pa0.into_push_pull_output(&mut gpioa.moder, &mut gpioa.otyper);
20//! ```
21//!
22//! And finally, you can use the functions from the [`InputPin`] or [`OutputPin`] traits in
23//! `embedded_hal`
24//!
25//! For a complete example, see [examples/toggle.rs]
26//!
27//! ## Pin Configuration
28//!
29//! ### Mode
30//!
31//! Each GPIO pin can be set to various modes by corresponding `into_...` method:
32//!
33//! - `Input`: The output buffer is disabled and the schmitt trigger input is activated
34//! - `Output`: Both the output buffer and the schmitt trigger input is enabled
35//!     - `PushPull`: Output which either drives the pin high or low
36//!     - `OpenDrain`: Output which leaves the gate floating, or pulls it to ground in drain
37//!     mode. Can be used as an input in the `open` configuration
38//! - `Alternate`: Pin mode required when the pin is driven by other peripherals. The schmitt
39//! trigger input is activated. The Output buffer is automatically enabled and disabled by
40//! peripherals. Output behavior is same as the output mode
41//!     - `PushPull`: Output which either drives the pin high or low
42//!     - `OpenDrain`: Output which leaves the gate floating, or pulls it to ground in drain
43//!     mode
44//! - `Analog`: Pin mode required for ADC, DAC, OPAMP, and COMP peripherals. It is also suitable
45//! for minimize energy consumption as the output buffer and the schmitt trigger input is disabled
46//!
47//! ### Output Speed
48//!
49//! Output speed (slew rate) for each pin is selectable from low, medium, and high by calling
50//! [`set_speed`](Pin::set_speed) method. Refer to the device datasheet for specifications for each
51//!  speed.
52//!
53//! ### Internal Resistor
54//!
55//! Weak internal pull-up and pull-down resistors for each pin is configurable by calling
56//! [`set_internal_resistor`](Pin::set_internal_resistor) method. `into_..._input` methods are also
57//! available for convenience.
58//!
59//! [InputPin]: embedded_hal::digital::v2::InputPin
60//! [OutputPin]: embedded_hal::digital::v2::OutputPin
61//! [examples/toggle.rs]: https://github.com/stm32-rs/stm32f3xx-hal/blob/v0.10.0/examples/toggle.rs
62
63use core::{convert::Infallible, marker::PhantomData};
64
65use crate::{
66    hal::digital::v2::OutputPin,
67    pac::{Interrupt, EXTI},
68    rcc::AHB,
69    Switch,
70};
71
72use crate::hal::digital::v2::{toggleable, InputPin, StatefulOutputPin};
73
74/// Extension trait to split a GPIO peripheral in independent pins and registers
75#[allow(clippy::module_name_repetitions)]
76pub trait GpioExt {
77    /// The Parts to split the GPIO peripheral into
78    type Parts;
79
80    /// Splits the GPIO block into independent pins and registers
81    fn split(self, ahb: &mut AHB) -> Self::Parts;
82}
83
84/// GPIO Register interface traits private to this module
85mod private {
86    pub trait GpioRegExt {
87        fn is_low(&self, i: u8) -> bool;
88        fn is_set_low(&self, i: u8) -> bool;
89        fn set_high(&self, i: u8);
90        fn set_low(&self, i: u8);
91    }
92
93    pub trait Moder {
94        fn input(&mut self, i: u8);
95        fn output(&mut self, i: u8);
96        fn alternate(&mut self, i: u8);
97        fn analog(&mut self, i: u8);
98    }
99
100    pub trait Otyper {
101        fn push_pull(&mut self, i: u8);
102        fn open_drain(&mut self, i: u8);
103    }
104
105    pub trait Ospeedr {
106        fn low(&mut self, i: u8);
107        fn medium(&mut self, i: u8);
108        fn high(&mut self, i: u8);
109    }
110
111    pub trait Pupdr {
112        fn floating(&mut self, i: u8);
113        fn pull_up(&mut self, i: u8);
114        fn pull_down(&mut self, i: u8);
115    }
116
117    pub trait Afr {
118        fn afx(&mut self, i: u8, x: u8);
119    }
120
121    pub trait Gpio {
122        type Reg: GpioRegExt + ?Sized;
123
124        fn ptr(&self) -> *const Self::Reg;
125        fn port_index(&self) -> u8;
126    }
127}
128
129use private::{Afr, GpioRegExt, Moder, Ospeedr, Otyper, Pupdr};
130
131/// Marker traits used in this module
132pub mod marker {
133    /// Marker trait for GPIO ports
134    pub trait Gpio: super::private::Gpio {}
135
136    /// Marker trait for compile time defined GPIO ports
137    pub trait GpioStatic: Gpio {
138        /// Associated MODER register
139        type MODER: super::Moder;
140        /// Associated OTYPER register
141        type OTYPER: super::Otyper;
142        /// Associated OSPEEDR register
143        type OSPEEDR: super::Ospeedr;
144        /// Associated PUPDR register
145        type PUPDR: super::Pupdr;
146    }
147
148    /// Marker trait for pin number
149    pub trait Index {
150        #[doc(hidden)]
151        fn index(&self) -> u8;
152    }
153
154    /// Marker trait for readable pin modes
155    pub trait Readable {}
156
157    /// Marker trait for slew rate configurable pin modes
158    pub trait OutputSpeed {}
159
160    /// Marker trait for active pin modes
161    pub trait Active {}
162
163    /// Marker trait for pins with alternate function `A` mapping
164    pub trait IntoAf<const A: u8> {
165        /// Associated AFR register
166        type AFR: super::Afr;
167    }
168}
169
170/// Runtime defined GPIO port (type state)
171#[derive(Debug)]
172pub struct Gpiox {
173    ptr: *const dyn GpioRegExt,
174    index: u8,
175}
176
177#[cfg(feature = "defmt")]
178impl defmt::Format for Gpiox {
179    fn format(&self, f: defmt::Formatter) {
180        defmt::write!(f, "Gpiox {{ ptr: GpioRegExt , index: {:?} }}", self.index);
181    }
182}
183
184// SAFETY:
185// As Gpiox uses `dyn GpioRegExt` pointer internally, `Send` is not auto-implemented.
186// But since GpioExt does only do atomic operations without side-effects we can assume
187// that it safe to `Send` this type.
188unsafe impl Send for Gpiox {}
189
190// SAFETY:
191// As Gpiox uses `dyn GpioRegExt` pointer internally, `Sync` is not auto-implemented.
192// But since GpioExt does only do atomic operations without side-effects we can assume
193// that it safe to `Send` this type.
194unsafe impl Sync for Gpiox {}
195
196impl private::Gpio for Gpiox {
197    type Reg = dyn GpioRegExt;
198
199    fn ptr(&self) -> *const Self::Reg {
200        self.ptr
201    }
202
203    fn port_index(&self) -> u8 {
204        self.index
205    }
206}
207
208impl marker::Gpio for Gpiox {}
209
210/// Runtime defined pin number (type state)
211// TODO(Sh3Rm4n): If the pin number wouldn't be runtime defined, the implementation for all
212// statically defined pins would be much easier (and withless overhead). What could be the
213// solution?
214#[derive(Debug)]
215#[cfg_attr(feature = "defmt", derive(defmt::Format))]
216pub struct Ux(u8);
217
218impl marker::Index for Ux {
219    fn index(&self) -> u8 {
220        self.0
221    }
222}
223
224/// Compile time defined pin number (type state)
225#[derive(Debug)]
226#[cfg_attr(feature = "defmt", derive(defmt::Format))]
227pub struct U<const X: u8>;
228
229impl<const X: u8> marker::Index for U<X> {
230    fn index(&self) -> u8 {
231        X
232    }
233}
234
235/// Input mode (type state)
236#[derive(Debug)]
237#[cfg_attr(feature = "defmt", derive(defmt::Format))]
238pub struct Input;
239/// Output mode (type state)
240#[derive(Debug)]
241#[cfg_attr(feature = "defmt", derive(defmt::Format))]
242pub struct Output<Otype>(PhantomData<Otype>);
243/// Alternate function (type state)
244#[derive(Debug)]
245#[cfg_attr(feature = "defmt", derive(defmt::Format))]
246pub struct Alternate<Otype, const AF: u8>(PhantomData<Otype>);
247/// Analog mode (type state)
248#[derive(Debug)]
249#[cfg_attr(feature = "defmt", derive(defmt::Format))]
250pub struct Analog;
251
252/// Push-pull output (type state)
253#[derive(Debug)]
254#[cfg_attr(feature = "defmt", derive(defmt::Format))]
255pub struct PushPull;
256/// Open-drain output (type state)
257#[derive(Debug)]
258#[cfg_attr(feature = "defmt", derive(defmt::Format))]
259pub struct OpenDrain;
260
261impl marker::Readable for Input {}
262impl marker::Readable for Output<OpenDrain> {}
263impl<Otype> marker::OutputSpeed for Output<Otype> {}
264impl<Otype, const AF: u8> marker::OutputSpeed for Alternate<Otype, AF> {}
265impl marker::Active for Input {}
266impl<Otype> marker::Active for Output<Otype> {}
267impl<Otype, const AF: u8> marker::Active for Alternate<Otype, AF> {}
268
269/// Slew rate configuration
270#[derive(Copy, Clone, PartialEq, Eq)]
271#[cfg_attr(feature = "defmt", derive(defmt::Format))]
272pub enum Speed {
273    /// Low speed
274    Low,
275    /// Medium speed
276    Medium,
277    /// High speed
278    High,
279}
280
281/// Internal pull-up and pull-down resistor configuration
282#[derive(Copy, Clone, PartialEq, Eq)]
283#[cfg_attr(feature = "defmt", derive(defmt::Format))]
284pub enum Resistor {
285    /// Floating
286    Floating,
287    /// Pulled up
288    PullUp,
289    /// Pulled down
290    PullDown,
291}
292
293/// GPIO interrupt trigger edge selection
294#[derive(Debug, Copy, Clone, PartialEq, Eq)]
295#[cfg_attr(feature = "defmt", derive(defmt::Format))]
296pub enum Edge {
297    /// Rising edge of voltage
298    Rising,
299    /// Falling edge of voltage
300    Falling,
301    /// Rising and falling edge of voltage
302    RisingFalling,
303}
304
305/// Generic pin
306#[derive(Debug)]
307#[cfg_attr(feature = "defmt", derive(defmt::Format))]
308pub struct Pin<Gpio, Index, Mode> {
309    pub(crate) gpio: Gpio,
310    pub(crate) index: Index,
311    _mode: PhantomData<Mode>,
312}
313
314// Make all GPIO peripheral trait extensions sealable.
315impl<Gpio, Index, Mode> crate::private::Sealed for Pin<Gpio, Index, Mode> {}
316
317/// Fully erased pin
318///
319/// This moves the pin type information to be known
320/// at runtime, and erases the specific compile time type of the GPIO.
321/// The only compile time information of the GPIO pin is it's Mode.
322///
323/// See [examples/gpio_erased.rs] as an example.
324///
325/// [examples/gpio_erased.rs]: https://github.com/stm32-rs/stm32f3xx-hal/blob/v0.10.0/examples/gpio_erased.rs
326pub type PXx<Mode> = Pin<Gpiox, Ux, Mode>;
327
328impl<Gpio, Mode, const X: u8> Pin<Gpio, U<X>, Mode> {
329    /// Erases the pin number from the type
330    ///
331    /// This is useful when you want to collect the pins into an array where you
332    /// need all the elements to have the same type
333    pub fn downgrade(self) -> Pin<Gpio, Ux, Mode> {
334        Pin {
335            gpio: self.gpio,
336            index: Ux(X),
337            _mode: self._mode,
338        }
339    }
340}
341
342impl<Gpio, Mode> Pin<Gpio, Ux, Mode>
343where
344    Gpio: marker::GpioStatic,
345    Gpio::Reg: 'static + Sized,
346{
347    /// Erases the port letter from the type
348    ///
349    /// This is useful when you want to collect the pins into an array where you
350    /// need all the elements to have the same type
351    pub fn downgrade(self) -> PXx<Mode> {
352        PXx {
353            gpio: Gpiox {
354                ptr: self.gpio.ptr(),
355                index: self.gpio.port_index(),
356            },
357            index: self.index,
358            _mode: self._mode,
359        }
360    }
361}
362
363impl<Gpio, Index, Mode> Pin<Gpio, Index, Mode> {
364    fn into_mode<NewMode>(self) -> Pin<Gpio, Index, NewMode> {
365        Pin {
366            gpio: self.gpio,
367            index: self.index,
368            _mode: PhantomData,
369        }
370    }
371}
372
373impl<Gpio, Index, Mode> Pin<Gpio, Index, Mode>
374where
375    Gpio: marker::GpioStatic,
376    Index: marker::Index,
377{
378    /// Configures the pin to operate as an input pin
379    pub fn into_input(self, moder: &mut Gpio::MODER) -> Pin<Gpio, Index, Input> {
380        moder.input(self.index.index());
381        self.into_mode()
382    }
383
384    /// Convenience method to configure the pin to operate as an input pin
385    /// and set the internal resistor floating
386    pub fn into_floating_input(
387        self,
388        moder: &mut Gpio::MODER,
389        pupdr: &mut Gpio::PUPDR,
390    ) -> Pin<Gpio, Index, Input> {
391        moder.input(self.index.index());
392        pupdr.floating(self.index.index());
393        self.into_mode()
394    }
395
396    /// Convenience method to configure the pin to operate as an input pin
397    /// and set the internal resistor pull-up
398    pub fn into_pull_up_input(
399        self,
400        moder: &mut Gpio::MODER,
401        pupdr: &mut Gpio::PUPDR,
402    ) -> Pin<Gpio, Index, Input> {
403        moder.input(self.index.index());
404        pupdr.pull_up(self.index.index());
405        self.into_mode()
406    }
407
408    /// Convenience method to configure the pin to operate as an input pin
409    /// and set the internal resistor pull-down
410    pub fn into_pull_down_input(
411        self,
412        moder: &mut Gpio::MODER,
413        pupdr: &mut Gpio::PUPDR,
414    ) -> Pin<Gpio, Index, Input> {
415        moder.input(self.index.index());
416        pupdr.pull_down(self.index.index());
417        self.into_mode()
418    }
419
420    /// Configures the pin to operate as a push-pull output pin
421    pub fn into_push_pull_output(
422        self,
423        moder: &mut Gpio::MODER,
424        otyper: &mut Gpio::OTYPER,
425    ) -> Pin<Gpio, Index, Output<PushPull>> {
426        moder.output(self.index.index());
427        otyper.push_pull(self.index.index());
428        self.into_mode()
429    }
430
431    /// Configures the pin to operate as an open-drain output pin
432    pub fn into_open_drain_output(
433        self,
434        moder: &mut Gpio::MODER,
435        otyper: &mut Gpio::OTYPER,
436    ) -> Pin<Gpio, Index, Output<OpenDrain>> {
437        moder.output(self.index.index());
438        otyper.open_drain(self.index.index());
439        self.into_mode()
440    }
441
442    /// Configures the pin to operate as an analog pin, with disabled schmitt trigger.
443    pub fn into_analog(
444        self,
445        moder: &mut Gpio::MODER,
446        pupdr: &mut Gpio::PUPDR,
447    ) -> Pin<Gpio, Index, Analog> {
448        moder.analog(self.index.index());
449        pupdr.floating(self.index.index());
450        self.into_mode()
451    }
452}
453
454impl<Gpio, Index, Mode> Pin<Gpio, Index, Mode>
455where
456    Gpio: marker::GpioStatic,
457    Index: marker::Index,
458    Mode: marker::OutputSpeed,
459{
460    /// Set pin output slew rate
461    pub fn set_speed(&mut self, ospeedr: &mut Gpio::OSPEEDR, speed: Speed) {
462        match speed {
463            Speed::Low => ospeedr.low(self.index.index()),
464            Speed::Medium => ospeedr.medium(self.index.index()),
465            Speed::High => ospeedr.high(self.index.index()),
466        }
467    }
468}
469
470impl<Gpio, Index, Mode> Pin<Gpio, Index, Mode>
471where
472    Gpio: marker::GpioStatic,
473    Index: marker::Index,
474    Mode: marker::Active,
475{
476    /// Set the internal pull-up and pull-down resistor
477    pub fn set_internal_resistor(&mut self, pupdr: &mut Gpio::PUPDR, resistor: Resistor) {
478        match resistor {
479            Resistor::Floating => pupdr.floating(self.index.index()),
480            Resistor::PullUp => pupdr.pull_up(self.index.index()),
481            Resistor::PullDown => pupdr.pull_down(self.index.index()),
482        }
483    }
484
485    /// Enables / disables the internal pull up (Provided for compatibility with other stm32 HALs)
486    pub fn internal_pull_up(&mut self, pupdr: &mut Gpio::PUPDR, on: bool) {
487        if on {
488            pupdr.pull_up(self.index.index());
489        } else {
490            pupdr.floating(self.index.index());
491        }
492    }
493}
494
495impl<Gpio, Index, Otype> OutputPin for Pin<Gpio, Index, Output<Otype>>
496where
497    Gpio: marker::Gpio,
498    Index: marker::Index,
499{
500    type Error = Infallible;
501
502    fn set_high(&mut self) -> Result<(), Self::Error> {
503        // SAFETY: atomic write to a stateless register
504        unsafe { (*self.gpio.ptr()).set_high(self.index.index()) };
505        Ok(())
506    }
507
508    fn set_low(&mut self) -> Result<(), Self::Error> {
509        // SAFETY: atomic write to a stateless register
510        unsafe { (*self.gpio.ptr()).set_low(self.index.index()) };
511        Ok(())
512    }
513}
514
515impl<Gpio, Index, Mode> InputPin for Pin<Gpio, Index, Mode>
516where
517    Gpio: marker::Gpio,
518    Index: marker::Index,
519    Mode: marker::Readable,
520{
521    type Error = Infallible;
522
523    fn is_high(&self) -> Result<bool, Self::Error> {
524        Ok(!self.is_low()?)
525    }
526
527    fn is_low(&self) -> Result<bool, Self::Error> {
528        // SAFETY: atomic read with no side effects
529        Ok(unsafe { (*self.gpio.ptr()).is_low(self.index.index()) })
530    }
531}
532
533impl<Gpio, Index, Otype> StatefulOutputPin for Pin<Gpio, Index, Output<Otype>>
534where
535    Gpio: marker::Gpio,
536    Index: marker::Index,
537{
538    fn is_set_high(&self) -> Result<bool, Self::Error> {
539        Ok(!self.is_set_low()?)
540    }
541
542    fn is_set_low(&self) -> Result<bool, Self::Error> {
543        // SAFETY: atomic read with no side effects
544        Ok(unsafe { (*self.gpio.ptr()).is_set_low(self.index.index()) })
545    }
546}
547
548impl<Gpio, Index, Otype> toggleable::Default for Pin<Gpio, Index, Output<Otype>>
549where
550    Gpio: marker::Gpio,
551    Index: marker::Index,
552{
553}
554
555/// Return an EXTI register for the current CPU
556#[cfg(feature = "svd-f373")]
557macro_rules! reg_for_cpu {
558    ($exti:expr, $xr:ident) => {
559        $exti.$xr
560    };
561}
562
563/// Return an EXTI register for the current CPU
564#[cfg(not(feature = "svd-f373"))]
565macro_rules! reg_for_cpu {
566    ($exti:expr, $xr:ident) => {
567        paste::paste! {
568            $exti.[<$xr 1>]
569        }
570    };
571}
572
573impl<Gpio, Index, Mode> Pin<Gpio, Index, Mode>
574where
575    Gpio: marker::Gpio,
576    Index: marker::Index,
577    Mode: marker::Active,
578{
579    /// NVIC interrupt number of interrupt from this pin
580    ///
581    /// Used to unmask / enable the interrupt with [`cortex_m::peripheral::NVIC::unmask()`].
582    /// This is also useful for all other [`cortex_m::peripheral::NVIC`] functions.
583    // TODO(Sh3rm4n): It would be cool to have this either const or have a const function.
584    // But this is currenlty not possible, because index() is runtime defined.
585    pub fn interrupt(&self) -> Interrupt {
586        match self.index.index() {
587            0 => Interrupt::EXTI0,
588            1 => Interrupt::EXTI1,
589            #[cfg(feature = "svd-f373")]
590            2 => Interrupt::EXTI2_TS,
591            #[cfg(not(feature = "svd-f373"))]
592            2 => Interrupt::EXTI2_TSC,
593            3 => Interrupt::EXTI3,
594            4 => Interrupt::EXTI4,
595            #[cfg(feature = "svd-f373")]
596            5..=9 => Interrupt::EXTI5_9,
597            #[cfg(not(feature = "svd-f373"))]
598            5..=9 => Interrupt::EXTI9_5,
599            10..=15 => Interrupt::EXTI15_10,
600            _ => crate::unreachable!(),
601        }
602    }
603
604    /// Generate interrupt on rising edge, falling edge, or both
605    pub fn trigger_on_edge(&mut self, exti: &mut EXTI, edge: Edge) {
606        const BITWIDTH: u8 = 1;
607        let index = self.index.index();
608        let (rise, fall) = match edge {
609            Edge::Rising => (u32::from(true), u32::from(false)),
610            Edge::Falling => (u32::from(false), u32::from(true)),
611            Edge::RisingFalling => (u32::from(true), u32::from(true)),
612        };
613        // SAFETY: Unguarded write to the register, but behind a &mut
614        unsafe {
615            crate::modify_at!(reg_for_cpu!(exti, rtsr), BITWIDTH, index, rise);
616            crate::modify_at!(reg_for_cpu!(exti, ftsr), BITWIDTH, index, fall);
617        }
618    }
619
620    /// Configure external interrupts from this pin
621    ///
622    /// # Note
623    ///
624    /// Remeber to also configure the interrupt pin on
625    /// the `SysCfg` site, with [`crate::syscfg::SysCfg::select_exti_interrupt_source()`]
626    pub fn configure_interrupt(&mut self, exti: &mut EXTI, enable: impl Into<Switch>) {
627        const BITWIDTH: u8 = 1;
628
629        let enable: Switch = enable.into();
630        let enable: bool = enable.into();
631
632        let index = self.index.index();
633        let value = u32::from(enable);
634        // SAFETY: Unguarded write to the register, but behind a &mut
635        unsafe { crate::modify_at!(reg_for_cpu!(exti, imr), BITWIDTH, index, value) };
636    }
637
638    /// Enable external interrupts from this pin
639    ///
640    /// # Note
641    ///
642    /// Remeber to also configure the interrupt pin on
643    /// the `SysCfg` site, with [`crate::syscfg::SysCfg::select_exti_interrupt_source()`]
644    pub fn enable_interrupt(&mut self, exti: &mut EXTI) {
645        self.configure_interrupt(exti, Switch::On);
646    }
647
648    /// Disable external interrupts from this pin
649    pub fn disable_interrupt(&mut self, exti: &mut EXTI) {
650        self.configure_interrupt(exti, Switch::Off);
651    }
652
653    /// Clear the interrupt pending bit for this pin
654    pub fn clear_interrupt(&mut self) {
655        // SAFETY: Atomic write to register without side-effects.
656        unsafe { reg_for_cpu!((*EXTI::ptr()), pr).write(|w| w.bits(1 << self.index.index())) };
657    }
658
659    /// Reads the interrupt pending bit for this pin
660    pub fn is_interrupt_pending(&self) -> bool {
661        // SAFETY: Atomic write to register without side-effects.
662        unsafe { reg_for_cpu!((*EXTI::ptr()), pr).read().bits() & (1 << self.index.index()) != 0 }
663    }
664}
665
666impl<Gpio, Index, Mode> Pin<Gpio, Index, Mode>
667where
668    Gpio: marker::GpioStatic,
669    Index: marker::Index,
670{
671    /// Configures the pin to operate as an alternate function push-pull output pin
672    pub fn into_af_push_pull<const A: u8>(
673        self,
674        moder: &mut Gpio::MODER,
675        otyper: &mut Gpio::OTYPER,
676        afr: &mut <Self as marker::IntoAf<A>>::AFR,
677    ) -> Pin<Gpio, Index, Alternate<PushPull, A>>
678    where
679        Self: marker::IntoAf<A>,
680    {
681        moder.alternate(self.index.index());
682        otyper.push_pull(self.index.index());
683        afr.afx(self.index.index(), A);
684        self.into_mode()
685    }
686
687    /// Configures the pin to operate as an alternate function open-drain output pin
688    pub fn into_af_open_drain<const A: u8>(
689        self,
690        moder: &mut Gpio::MODER,
691        otyper: &mut Gpio::OTYPER,
692        afr: &mut <Self as marker::IntoAf<A>>::AFR,
693    ) -> Pin<Gpio, Index, Alternate<OpenDrain, A>>
694    where
695        Self: marker::IntoAf<A>,
696    {
697        moder.alternate(self.index.index());
698        otyper.open_drain(self.index.index());
699        afr.afx(self.index.index(), A);
700        self.into_mode()
701    }
702}
703
704macro_rules! af {
705    ($i:literal, $AFi:ident, $into_afi_push_pull:ident, $into_afi_open_drain:ident) => {
706        #[doc = concat!("Alternate function ", $i, " (type state)" )]
707        pub type $AFi<Otype> = Alternate<Otype, $i>;
708
709        impl<Gpio, Index, Mode> Pin<Gpio, Index, Mode>
710        where
711            Self: marker::IntoAf<$i>,
712            Gpio: marker::GpioStatic,
713            Index: marker::Index,
714        {
715            /// Configures the pin to operate as an alternate function push-pull output pin
716            #[deprecated(since = "0.9.0", note = "Will be removed with the next version. Use `into_af_push_pull()` instead")]
717            pub fn $into_afi_push_pull(
718                self,
719                moder: &mut Gpio::MODER,
720                otyper: &mut Gpio::OTYPER,
721                afr: &mut <Self as marker::IntoAf<$i>>::AFR,
722            ) -> Pin<Gpio, Index, $AFi<PushPull>> {
723                self.into_af_push_pull::<$i>(moder, otyper, afr)
724            }
725
726            /// Configures the pin to operate as an alternate function open-drain output pin
727            #[deprecated(since = "0.9.0", note = "Will be removed with the next version. Use `into_af_open_drain()` instead")]
728            pub fn $into_afi_open_drain(
729                self,
730                moder: &mut Gpio::MODER,
731                otyper: &mut Gpio::OTYPER,
732                afr: &mut <Self as marker::IntoAf<$i>>::AFR,
733            ) -> Pin<Gpio, Index, $AFi<OpenDrain>> {
734                self.into_af_open_drain::<$i>(moder, otyper, afr)
735            }
736        }
737    };
738
739    ([$($i:literal),+ $(,)?]) => {
740        paste::paste! {
741            $(
742                af!($i, [<AF $i>],  [<into_af $i _push_pull>],  [<into_af $i _open_drain>]);
743            )+
744        }
745    };
746}
747
748af!([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
749
750macro_rules! gpio_trait {
751    ([$($gpioy:ident),+ $(,)?]) => {
752        $(
753            impl GpioRegExt for crate::pac::$gpioy::RegisterBlock {
754                #[inline(always)]
755                fn is_low(&self, i: u8) -> bool {
756                    self.idr.read().bits() & (1 << i) == 0
757                }
758
759                #[inline(always)]
760                fn is_set_low(&self, i: u8) -> bool {
761                    self.odr.read().bits() & (1 << i) == 0
762                }
763
764                #[inline(always)]
765                fn set_high(&self, i: u8) {
766                    // SAFETY: atomic write to a stateless register
767                    unsafe { self.bsrr.write(|w| w.bits(1 << i)) };
768                }
769
770                #[inline(always)]
771                fn set_low(&self, i: u8) {
772                    // SAFETY: atomic write to a stateless register
773                    unsafe { self.bsrr.write(|w| w.bits(1 << (16 + i))) };
774                }
775            }
776        )+
777    };
778}
779
780/// Implement `private::{Moder, Ospeedr, Otyper, Pupdr}` traits for each opaque register structs
781macro_rules! r_trait {
782    (
783        ($GPIOX:ident, $gpioy:ident::$xr:ident::$enum:ident, $bitwidth:expr);
784        impl $Xr:ident for $XR:ty {
785            $(
786                fn $fn:ident { $VARIANT:ident }
787            )+
788        }
789    ) => {
790        impl $Xr for $XR {
791            $(
792                #[inline]
793                fn $fn(&mut self, i: u8) {
794                    let value = $gpioy::$xr::$enum::$VARIANT as u32;
795                    // SAFETY: The &mut abstracts all accesses to the register itself,
796                    // which makes sure that this register accesss is exclusive
797                    unsafe { crate::modify_at!((*$GPIOX::ptr()).$xr, $bitwidth, i, value) };
798                }
799            )+
800        }
801    };
802}
803
804macro_rules! gpio {
805    ({
806        GPIO: $GPIOX:ident,
807        gpio: $gpiox:ident,
808        Gpio: $Gpiox:ident,
809        port_index: $port_index:literal,
810        gpio_mapped: $gpioy:ident,
811        partially_erased_pin: $PXx:ident,
812        pins: [$(
813            $i:literal => (
814                $PXi:ident, $pxi:ident, $MODE:ty, $AFR:ident, [$($af:literal),*],
815            ),
816        )+],
817    }) => {
818        #[doc = concat!("GPIO port ", stringify!($GPIOX), " (type state)")]
819        #[derive(Debug)]
820        #[cfg_attr(feature = "defmt", derive(defmt::Format))]
821        pub struct $Gpiox;
822
823        impl private::Gpio for $Gpiox {
824            type Reg = crate::pac::$gpioy::RegisterBlock;
825
826            #[inline(always)]
827            fn ptr(&self) -> *const Self::Reg {
828                crate::pac::$GPIOX::ptr()
829            }
830
831            #[inline(always)]
832            fn port_index(&self) -> u8 {
833                $port_index
834            }
835        }
836
837        impl marker::Gpio for $Gpiox {}
838
839        impl marker::GpioStatic for $Gpiox {
840            type MODER = $gpiox::MODER;
841            type OTYPER = $gpiox::OTYPER;
842            type OSPEEDR = $gpiox::OSPEEDR;
843            type PUPDR = $gpiox::PUPDR;
844        }
845
846        $(
847            #[doc = concat!("Pin ", stringify!($PXi))]
848            pub type $PXi<Mode> = Pin<$Gpiox, U<$i>, Mode>;
849
850            $(
851                impl<Mode> marker::IntoAf<$af> for $PXi<Mode> {
852                    type AFR = $gpiox::$AFR;
853                }
854            )*
855        )+
856
857        #[doc = concat!("Partially erased pin for ", stringify!($GPIOX))]
858        pub type $PXx<Mode> = Pin<$Gpiox, Ux, Mode>;
859
860        #[doc = concat!("All Pins and associated registers for GPIO port ", stringify!($GPIOX))]
861        pub mod $gpiox {
862            use core::marker::PhantomData;
863
864            use crate::{
865                pac::{$gpioy, $GPIOX},
866                rcc::{AHB, Enable, Reset},
867            };
868
869            use super::{Afr, $Gpiox, GpioExt, Moder, Ospeedr, Otyper, Pupdr, U};
870
871            #[allow(unused_imports)]
872            use super::{
873                Input, Output, Analog, PushPull, OpenDrain,
874                AF0, AF1, AF2, AF3, AF4, AF5, AF6, AF7, AF8, AF9, AF10, AF11, AF12, AF13, AF14, AF15,
875            };
876
877            pub use super::{
878                $PXx,
879                $(
880                    $PXi,
881                )+
882            };
883
884            /// GPIO parts
885            pub struct Parts {
886                /// Opaque AFRH register
887                pub afrh: AFRH,
888                /// Opaque AFRL register
889                pub afrl: AFRL,
890                /// Opaque MODER register
891                pub moder: MODER,
892                /// Opaque OSPEEDR register
893                pub ospeedr: OSPEEDR,
894                /// Opaque OTYPER register
895                pub otyper: OTYPER,
896                /// Opaque PUPDR register
897                pub pupdr: PUPDR,
898                $(
899                    #[doc = concat!("Pin ", stringify!($PXi))]
900                    pub $pxi: $PXi<$MODE>,
901                )+
902            }
903
904            impl GpioExt for $GPIOX {
905                type Parts = Parts;
906
907                fn split(self, ahb: &mut AHB) -> Parts {
908                    <$GPIOX>::enable(ahb);
909                    <$GPIOX>::reset(ahb);
910
911                    Parts {
912                        afrh: AFRH(()),
913                        afrl: AFRL(()),
914                        moder: MODER(()),
915                        ospeedr: OSPEEDR(()),
916                        otyper: OTYPER(()),
917                        pupdr: PUPDR(()),
918                        $(
919                            $pxi: $PXi {
920                                gpio: $Gpiox,
921                                index: U::<$i>,
922                                _mode: PhantomData,
923                            },
924                        )+
925                    }
926                }
927            }
928
929            /// Opaque AFRH register
930            pub struct AFRH(());
931
932            impl Afr for AFRH {
933                #[inline]
934                fn afx(&mut self, i: u8, x: u8) {
935                    const BITWIDTH: u8 = 4;
936                    // SAFETY: the abstraction of AFRL should ensure exclusive access in addition
937                    // to the &mut exclusive reference
938                    unsafe { crate::modify_at!((*$GPIOX::ptr()).afrh, BITWIDTH, i - 8, x as u32) };
939                }
940            }
941
942            /// Opaque AFRL register
943            pub struct AFRL(());
944
945            impl Afr for AFRL {
946                #[inline]
947                fn afx(&mut self, i: u8, x: u8) {
948                    const BITWIDTH: u8 = 4;
949                    // SAFETY: the abstraction of AFRL should ensure exclusive access in addition
950                    // to the &mut exclusive reference
951                    unsafe { crate::modify_at!((*$GPIOX::ptr()).afrl, BITWIDTH, i, x as u32) };
952                }
953            }
954
955            /// Opaque MODER register
956            pub struct MODER(());
957
958            r_trait! {
959                ($GPIOX, $gpioy::moder::MODER15_A, 2);
960                impl Moder for MODER {
961                    fn input { Input }
962                    fn output { Output }
963                    fn alternate { Alternate }
964                    fn analog { Analog }
965                }
966            }
967
968            /// Opaque OSPEEDR register
969            pub struct OSPEEDR(());
970
971            r_trait! {
972                ($GPIOX, $gpioy::ospeedr::OSPEEDR15_A, 2);
973                impl Ospeedr for OSPEEDR {
974                    fn low { LowSpeed }
975                    fn medium { MediumSpeed }
976                    fn high { HighSpeed }
977                }
978            }
979
980            /// Opaque OTYPER register
981            pub struct OTYPER(());
982
983            r_trait! {
984                ($GPIOX, $gpioy::otyper::OT15_A, 1);
985                impl Otyper for OTYPER {
986                    fn push_pull { PushPull }
987                    fn open_drain { OpenDrain }
988                }
989            }
990
991            /// Opaque PUPDR register
992            pub struct PUPDR(());
993
994            r_trait! {
995                ($GPIOX, $gpioy::pupdr::PUPDR15_A, 2);
996                impl Pupdr for PUPDR {
997                    fn floating { Floating }
998                    fn pull_up { PullUp }
999                    fn pull_down { PullDown }
1000                }
1001            }
1002        }
1003    };
1004
1005    ({
1006        pacs: $pacs:tt,
1007        ports: [$(
1008            {
1009                port: ($X:ident/$x:ident, $port_index:literal, $gpioy:ident),
1010                pins: [$(
1011                    $i:literal => {
1012                        reset: $MODE:ty,
1013                        afr: $LH:ident,
1014                        af: [$($af:literal),*]
1015                    },
1016                )+],
1017            },
1018        )+],
1019    }) => {
1020        paste::paste! {
1021            gpio_trait!($pacs);
1022            $(
1023                gpio!({
1024                    GPIO: [<GPIO $X>],
1025                    gpio: [<gpio $x>],
1026                    Gpio: [<Gpio $x>],
1027                    port_index: $port_index,
1028                    gpio_mapped: $gpioy,
1029                    partially_erased_pin: [<P $X x>],
1030                    pins: [$(
1031                        $i => (
1032                            [<P $X $i>], [<p $x $i>], $MODE, [<AFR $LH>], [$($af),*],
1033                        ),
1034                    )+],
1035                });
1036            )+
1037        }
1038    };
1039}
1040// auto-generated using codegen
1041// STM32CubeMX DB release: DB.6.0.10
1042
1043#[cfg(feature = "gpio-f302")]
1044gpio!({
1045    pacs: [gpioa, gpiob, gpioc],
1046    ports: [
1047        {
1048            port: (A/a, 0, gpioa),
1049            pins: [
1050                0 => { reset: Input, afr: L, af: [1, 3, 7, 15] },
1051                1 => { reset: Input, afr: L, af: [0, 1, 3, 7, 9, 15] },
1052                2 => { reset: Input, afr: L, af: [1, 3, 7, 8, 9, 15] },
1053                3 => { reset: Input, afr: L, af: [1, 3, 7, 9, 15] },
1054                4 => { reset: Input, afr: L, af: [3, 6, 7, 15] },
1055                5 => { reset: Input, afr: L, af: [1, 3, 15] },
1056                6 => { reset: Input, afr: L, af: [1, 3, 6, 15] },
1057                7 => { reset: Input, afr: L, af: [1, 3, 6, 15] },
1058                8 => { reset: Input, afr: H, af: [0, 3, 4, 5, 6, 7, 15] },
1059                9 => { reset: Input, afr: H, af: [2, 3, 4, 5, 6, 7, 9, 10, 15] },
1060                10 => { reset: Input, afr: H, af: [1, 3, 4, 5, 6, 7, 8, 10, 15] },
1061                11 => { reset: Input, afr: H, af: [5, 6, 7, 9, 11, 12, 15] },
1062                12 => { reset: Input, afr: H, af: [1, 5, 6, 7, 8, 9, 11, 15] },
1063                13 => { reset: AF0<PushPull>, afr: H, af: [0, 1, 3, 5, 7, 15] },
1064                14 => { reset: AF0<PushPull>, afr: H, af: [0, 3, 4, 6, 7, 15] },
1065                15 => { reset: AF0<PushPull>, afr: H, af: [0, 1, 3, 4, 6, 7, 9, 15] },
1066            ],
1067        },
1068        {
1069            port: (B/b, 1, gpiob),
1070            pins: [
1071                0 => { reset: Input, afr: L, af: [3, 6, 15] },
1072                1 => { reset: Input, afr: L, af: [3, 6, 8, 15] },
1073                2 => { reset: Input, afr: L, af: [3, 15] },
1074                3 => { reset: AF0<PushPull>, afr: L, af: [0, 1, 3, 6, 7, 15] },
1075                4 => { reset: AF0<PushPull>, afr: L, af: [0, 1, 3, 6, 7, 10, 15] },
1076                5 => { reset: Input, afr: L, af: [1, 4, 6, 7, 8, 10, 15] },
1077                6 => { reset: Input, afr: L, af: [1, 3, 4, 7, 15] },
1078                7 => { reset: Input, afr: L, af: [1, 3, 4, 7, 15] },
1079                8 => { reset: Input, afr: H, af: [1, 3, 4, 7, 9, 12, 15] },
1080                9 => { reset: Input, afr: H, af: [1, 4, 6, 7, 8, 9, 15] },
1081                10 => { reset: Input, afr: H, af: [1, 3, 7, 15] },
1082                11 => { reset: Input, afr: H, af: [1, 3, 7, 15] },
1083                12 => { reset: Input, afr: H, af: [3, 4, 5, 6, 7, 15] },
1084                13 => { reset: Input, afr: H, af: [3, 5, 6, 7, 15] },
1085                14 => { reset: Input, afr: H, af: [1, 3, 5, 6, 7, 15] },
1086                15 => { reset: Input, afr: H, af: [0, 1, 2, 4, 5, 15] },
1087            ],
1088        },
1089        {
1090            port: (C/c, 2, gpioc),
1091            pins: [
1092                0 => { reset: Input, afr: L, af: [1, 2] },
1093                1 => { reset: Input, afr: L, af: [1, 2] },
1094                2 => { reset: Input, afr: L, af: [1, 2] },
1095                3 => { reset: Input, afr: L, af: [1, 2, 6] },
1096                4 => { reset: Input, afr: L, af: [1, 2, 7] },
1097                5 => { reset: Input, afr: L, af: [1, 2, 3, 7] },
1098                6 => { reset: Input, afr: L, af: [1, 6, 7] },
1099                7 => { reset: Input, afr: L, af: [1, 6] },
1100                8 => { reset: Input, afr: H, af: [1] },
1101                9 => { reset: Input, afr: H, af: [1, 3, 5] },
1102                10 => { reset: Input, afr: H, af: [1, 6, 7] },
1103                11 => { reset: Input, afr: H, af: [1, 6, 7] },
1104                12 => { reset: Input, afr: H, af: [1, 6, 7] },
1105                13 => { reset: Input, afr: H, af: [4] },
1106                14 => { reset: Input, afr: H, af: [] },
1107                15 => { reset: Input, afr: H, af: [] },
1108            ],
1109        },
1110        {
1111            port: (D/d, 3, gpioc),
1112            pins: [
1113                2 => { reset: Input, afr: L, af: [1] },
1114            ],
1115        },
1116        {
1117            port: (F/f, 5, gpioc),
1118            pins: [
1119                0 => { reset: Input, afr: L, af: [4, 5, 6] },
1120                1 => { reset: Input, afr: L, af: [4, 5] },
1121            ],
1122        },
1123    ],
1124});
1125
1126#[cfg(feature = "gpio-f303e")]
1127gpio!({
1128    pacs: [gpioa, gpiob, gpioc],
1129    ports: [
1130        {
1131            port: (A/a, 0, gpioa),
1132            pins: [
1133                0 => { reset: Input, afr: L, af: [1, 3, 7, 8, 9, 10, 15] },
1134                1 => { reset: Input, afr: L, af: [0, 1, 3, 7, 9, 15] },
1135                2 => { reset: Input, afr: L, af: [1, 3, 7, 8, 9, 15] },
1136                3 => { reset: Input, afr: L, af: [1, 3, 7, 9, 15] },
1137                4 => { reset: Input, afr: L, af: [2, 3, 5, 6, 7, 15] },
1138                5 => { reset: Input, afr: L, af: [1, 3, 5, 15] },
1139                6 => { reset: Input, afr: L, af: [1, 2, 3, 4, 5, 6, 8, 15] },
1140                7 => { reset: Input, afr: L, af: [1, 2, 3, 4, 5, 6, 15] },
1141                8 => { reset: Input, afr: H, af: [0, 3, 4, 5, 6, 7, 8, 10, 15] },
1142                9 => { reset: Input, afr: H, af: [2, 3, 4, 5, 6, 7, 8, 9, 10, 15] },
1143                10 => { reset: Input, afr: H, af: [1, 3, 4, 5, 6, 7, 8, 10, 11, 15] },
1144                11 => { reset: Input, afr: H, af: [5, 6, 7, 8, 9, 10, 11, 12, 15] },
1145                12 => { reset: Input, afr: H, af: [1, 5, 6, 7, 8, 9, 10, 11, 15] },
1146                13 => { reset: AF0<PushPull>, afr: H, af: [0, 1, 3, 5, 7, 10, 15] },
1147                14 => { reset: AF0<PushPull>, afr: H, af: [0, 3, 4, 5, 6, 7, 15] },
1148                15 => { reset: AF0<PushPull>, afr: H, af: [0, 1, 2, 3, 4, 5, 6, 7, 9, 15] },
1149            ],
1150        },
1151        {
1152            port: (B/b, 1, gpiob),
1153            pins: [
1154                0 => { reset: Input, afr: L, af: [2, 3, 4, 6, 15] },
1155                1 => { reset: Input, afr: L, af: [2, 3, 4, 6, 8, 15] },
1156                2 => { reset: Input, afr: L, af: [3, 15] },
1157                3 => { reset: AF0<PushPull>, afr: L, af: [0, 1, 2, 3, 4, 5, 6, 7, 10, 15] },
1158                4 => { reset: AF0<PushPull>, afr: L, af: [0, 1, 2, 3, 4, 5, 6, 7, 10, 15] },
1159                5 => { reset: Input, afr: L, af: [1, 2, 3, 4, 5, 6, 7, 8, 10, 15] },
1160                6 => { reset: Input, afr: L, af: [1, 2, 3, 4, 5, 6, 7, 10, 15] },
1161                7 => { reset: Input, afr: L, af: [1, 2, 3, 4, 5, 7, 10, 12, 15] },
1162                8 => { reset: Input, afr: H, af: [1, 2, 3, 4, 7, 8, 9, 10, 12, 15] },
1163                9 => { reset: Input, afr: H, af: [1, 2, 4, 6, 7, 8, 9, 10, 15] },
1164                10 => { reset: Input, afr: H, af: [1, 3, 7, 15] },
1165                11 => { reset: Input, afr: H, af: [1, 3, 7, 15] },
1166                12 => { reset: Input, afr: H, af: [3, 4, 5, 6, 7, 15] },
1167                13 => { reset: Input, afr: H, af: [3, 5, 6, 7, 15] },
1168                14 => { reset: Input, afr: H, af: [1, 3, 5, 6, 7, 15] },
1169                15 => { reset: Input, afr: H, af: [0, 1, 2, 4, 5, 15] },
1170            ],
1171        },
1172        {
1173            port: (C/c, 2, gpioc),
1174            pins: [
1175                0 => { reset: Input, afr: L, af: [1, 2] },
1176                1 => { reset: Input, afr: L, af: [1, 2] },
1177                2 => { reset: Input, afr: L, af: [1, 2, 3] },
1178                3 => { reset: Input, afr: L, af: [1, 2, 6] },
1179                4 => { reset: Input, afr: L, af: [1, 2, 7] },
1180                5 => { reset: Input, afr: L, af: [1, 2, 3, 7] },
1181                6 => { reset: Input, afr: L, af: [1, 2, 4, 6, 7] },
1182                7 => { reset: Input, afr: L, af: [1, 2, 4, 6, 7] },
1183                8 => { reset: Input, afr: H, af: [1, 2, 4, 7] },
1184                9 => { reset: Input, afr: H, af: [1, 2, 3, 4, 5, 6] },
1185                10 => { reset: Input, afr: H, af: [1, 4, 5, 6, 7] },
1186                11 => { reset: Input, afr: H, af: [1, 4, 5, 6, 7] },
1187                12 => { reset: Input, afr: H, af: [1, 4, 5, 6, 7] },
1188                13 => { reset: Input, afr: H, af: [1, 4] },
1189                14 => { reset: Input, afr: H, af: [1] },
1190                15 => { reset: Input, afr: H, af: [1] },
1191            ],
1192        },
1193        {
1194            port: (D/d, 3, gpioc),
1195            pins: [
1196                0 => { reset: Input, afr: L, af: [1, 7, 12] },
1197                1 => { reset: Input, afr: L, af: [1, 4, 6, 7, 12] },
1198                2 => { reset: Input, afr: L, af: [1, 2, 4, 5] },
1199                3 => { reset: Input, afr: L, af: [1, 2, 7, 12] },
1200                4 => { reset: Input, afr: L, af: [1, 2, 7, 12] },
1201                5 => { reset: Input, afr: L, af: [1, 7, 12] },
1202                6 => { reset: Input, afr: L, af: [1, 2, 7, 12] },
1203                7 => { reset: Input, afr: L, af: [1, 2, 7, 12] },
1204                8 => { reset: Input, afr: H, af: [1, 7, 12] },
1205                9 => { reset: Input, afr: H, af: [1, 7, 12] },
1206                10 => { reset: Input, afr: H, af: [1, 7, 12] },
1207                11 => { reset: Input, afr: H, af: [1, 7, 12] },
1208                12 => { reset: Input, afr: H, af: [1, 2, 3, 7, 12] },
1209                13 => { reset: Input, afr: H, af: [1, 2, 3, 12] },
1210                14 => { reset: Input, afr: H, af: [1, 2, 3, 12] },
1211                15 => { reset: Input, afr: H, af: [1, 2, 3, 6, 12] },
1212            ],
1213        },
1214        {
1215            port: (E/e, 4, gpioc),
1216            pins: [
1217                0 => { reset: Input, afr: L, af: [1, 2, 4, 6, 7, 12] },
1218                1 => { reset: Input, afr: L, af: [1, 4, 6, 7, 12] },
1219                2 => { reset: Input, afr: L, af: [0, 1, 2, 3, 5, 6, 12] },
1220                3 => { reset: Input, afr: L, af: [0, 1, 2, 3, 5, 6, 12] },
1221                4 => { reset: Input, afr: L, af: [0, 1, 2, 3, 5, 6, 12] },
1222                5 => { reset: Input, afr: L, af: [0, 1, 2, 3, 5, 6, 12] },
1223                6 => { reset: Input, afr: L, af: [0, 1, 5, 6, 12] },
1224                7 => { reset: Input, afr: L, af: [1, 2, 12] },
1225                8 => { reset: Input, afr: H, af: [1, 2, 12] },
1226                9 => { reset: Input, afr: H, af: [1, 2, 12] },
1227                10 => { reset: Input, afr: H, af: [1, 2, 12] },
1228                11 => { reset: Input, afr: H, af: [1, 2, 5, 12] },
1229                12 => { reset: Input, afr: H, af: [1, 2, 5, 12] },
1230                13 => { reset: Input, afr: H, af: [1, 2, 5, 12] },
1231                14 => { reset: Input, afr: H, af: [1, 2, 5, 6, 12] },
1232                15 => { reset: Input, afr: H, af: [1, 2, 7, 12] },
1233            ],
1234        },
1235        {
1236            port: (F/f, 5, gpioc),
1237            pins: [
1238                0 => { reset: Input, afr: L, af: [1, 4, 5, 6] },
1239                1 => { reset: Input, afr: L, af: [1, 4, 5] },
1240                2 => { reset: Input, afr: L, af: [1, 2, 12] },
1241                3 => { reset: Input, afr: L, af: [1, 2, 12] },
1242                4 => { reset: Input, afr: L, af: [1, 2, 3, 12] },
1243                5 => { reset: Input, afr: L, af: [1, 2, 12] },
1244                6 => { reset: Input, afr: L, af: [1, 2, 4, 7, 12] },
1245                7 => { reset: Input, afr: L, af: [1, 2, 12] },
1246                8 => { reset: Input, afr: H, af: [1, 2, 12] },
1247                9 => { reset: Input, afr: H, af: [1, 2, 3, 5, 12] },
1248                10 => { reset: Input, afr: H, af: [1, 2, 3, 5, 12] },
1249                11 => { reset: Input, afr: H, af: [1, 2] },
1250                12 => { reset: Input, afr: H, af: [1, 2, 12] },
1251                13 => { reset: Input, afr: H, af: [1, 2, 12] },
1252                14 => { reset: Input, afr: H, af: [1, 2, 12] },
1253                15 => { reset: Input, afr: H, af: [1, 2, 12] },
1254            ],
1255        },
1256        {
1257            port: (G/g, 6, gpioc),
1258            pins: [
1259                0 => { reset: Input, afr: L, af: [1, 2, 12] },
1260                1 => { reset: Input, afr: L, af: [1, 2, 12] },
1261                2 => { reset: Input, afr: L, af: [1, 2, 12] },
1262                3 => { reset: Input, afr: L, af: [1, 2, 12] },
1263                4 => { reset: Input, afr: L, af: [1, 2, 12] },
1264                5 => { reset: Input, afr: L, af: [1, 2, 12] },
1265                6 => { reset: Input, afr: L, af: [1, 12] },
1266                7 => { reset: Input, afr: L, af: [1, 12] },
1267                8 => { reset: Input, afr: H, af: [1] },
1268                9 => { reset: Input, afr: H, af: [1, 12] },
1269                10 => { reset: Input, afr: H, af: [1, 12] },
1270                11 => { reset: Input, afr: H, af: [1, 12] },
1271                12 => { reset: Input, afr: H, af: [1, 12] },
1272                13 => { reset: Input, afr: H, af: [1, 12] },
1273                14 => { reset: Input, afr: H, af: [1, 12] },
1274                15 => { reset: Input, afr: H, af: [1] },
1275            ],
1276        },
1277        {
1278            port: (H/h, 7, gpioc),
1279            pins: [
1280                0 => { reset: Input, afr: L, af: [1, 2, 12] },
1281                1 => { reset: Input, afr: L, af: [1, 2, 12] },
1282                2 => { reset: Input, afr: L, af: [1] },
1283            ],
1284        },
1285    ],
1286});
1287
1288#[cfg(feature = "gpio-f303")]
1289gpio!({
1290    pacs: [gpioa, gpiob, gpioc],
1291    ports: [
1292        {
1293            port: (A/a, 0, gpioa),
1294            pins: [
1295                0 => { reset: Input, afr: L, af: [1, 3, 7, 8, 9, 10, 15] },
1296                1 => { reset: Input, afr: L, af: [0, 1, 3, 7, 9, 15] },
1297                2 => { reset: Input, afr: L, af: [1, 3, 7, 8, 9, 15] },
1298                3 => { reset: Input, afr: L, af: [1, 3, 7, 9, 15] },
1299                4 => { reset: Input, afr: L, af: [2, 3, 5, 6, 7, 15] },
1300                5 => { reset: Input, afr: L, af: [1, 3, 5, 15] },
1301                6 => { reset: Input, afr: L, af: [1, 2, 3, 4, 5, 6, 8, 15] },
1302                7 => { reset: Input, afr: L, af: [1, 2, 3, 4, 5, 6, 8, 15] },
1303                8 => { reset: Input, afr: H, af: [0, 4, 5, 6, 7, 8, 10, 15] },
1304                9 => { reset: Input, afr: H, af: [3, 4, 5, 6, 7, 8, 9, 10, 15] },
1305                10 => { reset: Input, afr: H, af: [1, 3, 4, 6, 7, 8, 10, 11, 15] },
1306                11 => { reset: Input, afr: H, af: [6, 7, 8, 9, 10, 11, 12, 14, 15] },
1307                12 => { reset: Input, afr: H, af: [1, 6, 7, 8, 9, 10, 11, 14, 15] },
1308                13 => { reset: AF0<PushPull>, afr: H, af: [0, 1, 3, 5, 7, 10, 15] },
1309                14 => { reset: AF0<PushPull>, afr: H, af: [0, 3, 4, 5, 6, 7, 15] },
1310                15 => { reset: AF0<PushPull>, afr: H, af: [0, 1, 2, 4, 5, 6, 7, 9, 15] },
1311            ],
1312        },
1313        {
1314            port: (B/b, 1, gpiob),
1315            pins: [
1316                0 => { reset: Input, afr: L, af: [2, 3, 4, 6, 15] },
1317                1 => { reset: Input, afr: L, af: [2, 3, 4, 6, 8, 15] },
1318                2 => { reset: Input, afr: L, af: [3, 15] },
1319                3 => { reset: AF0<PushPull>, afr: L, af: [0, 1, 2, 3, 4, 5, 6, 7, 10, 15] },
1320                4 => { reset: AF0<PushPull>, afr: L, af: [0, 1, 2, 3, 4, 5, 6, 7, 10, 15] },
1321                5 => { reset: Input, afr: L, af: [1, 2, 3, 4, 5, 6, 7, 10, 15] },
1322                6 => { reset: Input, afr: L, af: [1, 2, 3, 4, 5, 6, 7, 10, 15] },
1323                7 => { reset: Input, afr: L, af: [1, 2, 3, 4, 5, 7, 10, 15] },
1324                8 => { reset: Input, afr: H, af: [1, 2, 3, 4, 8, 9, 10, 12, 15] },
1325                9 => { reset: Input, afr: H, af: [1, 2, 4, 6, 8, 9, 10, 15] },
1326                10 => { reset: Input, afr: H, af: [1, 3, 7, 15] },
1327                11 => { reset: Input, afr: H, af: [1, 3, 7, 15] },
1328                12 => { reset: Input, afr: H, af: [3, 4, 5, 6, 7, 15] },
1329                13 => { reset: Input, afr: H, af: [3, 5, 6, 7, 15] },
1330                14 => { reset: Input, afr: H, af: [1, 3, 5, 6, 7, 15] },
1331                15 => { reset: Input, afr: H, af: [0, 1, 2, 4, 5, 15] },
1332            ],
1333        },
1334        {
1335            port: (C/c, 2, gpioc),
1336            pins: [
1337                0 => { reset: Input, afr: L, af: [1] },
1338                1 => { reset: Input, afr: L, af: [1] },
1339                2 => { reset: Input, afr: L, af: [1, 3] },
1340                3 => { reset: Input, afr: L, af: [1, 6] },
1341                4 => { reset: Input, afr: L, af: [1, 7] },
1342                5 => { reset: Input, afr: L, af: [1, 3, 7] },
1343                6 => { reset: Input, afr: L, af: [1, 2, 4, 6, 7] },
1344                7 => { reset: Input, afr: L, af: [1, 2, 4, 6, 7] },
1345                8 => { reset: Input, afr: H, af: [1, 2, 4, 7] },
1346                9 => { reset: Input, afr: H, af: [1, 2, 4, 5, 6] },
1347                10 => { reset: Input, afr: H, af: [1, 4, 5, 6, 7] },
1348                11 => { reset: Input, afr: H, af: [1, 4, 5, 6, 7] },
1349                12 => { reset: Input, afr: H, af: [1, 4, 5, 6, 7] },
1350                13 => { reset: Input, afr: H, af: [4] },
1351                14 => { reset: Input, afr: H, af: [] },
1352                15 => { reset: Input, afr: H, af: [] },
1353            ],
1354        },
1355        {
1356            port: (D/d, 3, gpioc),
1357            pins: [
1358                0 => { reset: Input, afr: L, af: [1, 7] },
1359                1 => { reset: Input, afr: L, af: [1, 4, 6, 7] },
1360                2 => { reset: Input, afr: L, af: [1, 2, 4, 5] },
1361                3 => { reset: Input, afr: L, af: [1, 2, 7] },
1362                4 => { reset: Input, afr: L, af: [1, 2, 7] },
1363                5 => { reset: Input, afr: L, af: [1, 7] },
1364                6 => { reset: Input, afr: L, af: [1, 2, 7] },
1365                7 => { reset: Input, afr: L, af: [1, 2, 7] },
1366                8 => { reset: Input, afr: H, af: [1, 7] },
1367                9 => { reset: Input, afr: H, af: [1, 7] },
1368                10 => { reset: Input, afr: H, af: [1, 7] },
1369                11 => { reset: Input, afr: H, af: [1, 7] },
1370                12 => { reset: Input, afr: H, af: [1, 2, 3, 7] },
1371                13 => { reset: Input, afr: H, af: [1, 2, 3] },
1372                14 => { reset: Input, afr: H, af: [1, 2, 3] },
1373                15 => { reset: Input, afr: H, af: [1, 2, 3, 6] },
1374            ],
1375        },
1376        {
1377            port: (E/e, 4, gpioc),
1378            pins: [
1379                0 => { reset: Input, afr: L, af: [1, 2, 4, 7] },
1380                1 => { reset: Input, afr: L, af: [1, 4, 7] },
1381                2 => { reset: Input, afr: L, af: [0, 1, 2, 3] },
1382                3 => { reset: Input, afr: L, af: [0, 1, 2, 3] },
1383                4 => { reset: Input, afr: L, af: [0, 1, 2, 3] },
1384                5 => { reset: Input, afr: L, af: [0, 1, 2, 3] },
1385                6 => { reset: Input, afr: L, af: [0, 1] },
1386                7 => { reset: Input, afr: L, af: [1, 2] },
1387                8 => { reset: Input, afr: H, af: [1, 2] },
1388                9 => { reset: Input, afr: H, af: [1, 2] },
1389                10 => { reset: Input, afr: H, af: [1, 2] },
1390                11 => { reset: Input, afr: H, af: [1, 2] },
1391                12 => { reset: Input, afr: H, af: [1, 2] },
1392                13 => { reset: Input, afr: H, af: [1, 2] },
1393                14 => { reset: Input, afr: H, af: [1, 2, 6] },
1394                15 => { reset: Input, afr: H, af: [1, 2, 7] },
1395            ],
1396        },
1397        {
1398            port: (F/f, 5, gpioc),
1399            pins: [
1400                0 => { reset: Input, afr: L, af: [4, 6] },
1401                1 => { reset: Input, afr: L, af: [4] },
1402                2 => { reset: Input, afr: L, af: [1] },
1403                4 => { reset: Input, afr: L, af: [1, 2] },
1404                6 => { reset: Input, afr: L, af: [1, 2, 4, 7] },
1405                9 => { reset: Input, afr: H, af: [1, 3, 5] },
1406                10 => { reset: Input, afr: H, af: [1, 3, 5] },
1407            ],
1408        },
1409    ],
1410});
1411
1412#[cfg(feature = "gpio-f333")]
1413gpio!({
1414    pacs: [gpioa, gpiob, gpioc],
1415    ports: [
1416        {
1417            port: (A/a, 0, gpioa),
1418            pins: [
1419                0 => { reset: Input, afr: L, af: [1, 3, 7, 15] },
1420                1 => { reset: Input, afr: L, af: [1, 3, 7, 9, 15] },
1421                2 => { reset: Input, afr: L, af: [1, 3, 7, 8, 9, 15] },
1422                3 => { reset: Input, afr: L, af: [1, 3, 7, 9, 15] },
1423                4 => { reset: Input, afr: L, af: [2, 3, 5, 7, 15] },
1424                5 => { reset: Input, afr: L, af: [1, 3, 5, 15] },
1425                6 => { reset: Input, afr: L, af: [1, 2, 3, 5, 6, 13, 15] },
1426                7 => { reset: Input, afr: L, af: [1, 2, 3, 5, 6, 15] },
1427                8 => { reset: Input, afr: H, af: [0, 6, 7, 13, 15] },
1428                9 => { reset: Input, afr: H, af: [3, 6, 7, 9, 10, 13, 15] },
1429                10 => { reset: Input, afr: H, af: [1, 3, 6, 7, 8, 10, 13, 15] },
1430                11 => { reset: Input, afr: H, af: [6, 7, 9, 11, 12, 13, 15] },
1431                12 => { reset: Input, afr: H, af: [1, 6, 7, 8, 9, 11, 13, 15] },
1432                13 => { reset: AF0<PushPull>, afr: H, af: [0, 1, 3, 5, 7, 15] },
1433                14 => { reset: AF0<PushPull>, afr: H, af: [0, 3, 4, 6, 7, 15] },
1434                15 => { reset: AF0<PushPull>, afr: H, af: [0, 1, 3, 4, 5, 7, 9, 13, 15] },
1435            ],
1436        },
1437        {
1438            port: (B/b, 1, gpiob),
1439            pins: [
1440                0 => { reset: Input, afr: L, af: [2, 3, 6, 15] },
1441                1 => { reset: Input, afr: L, af: [2, 3, 6, 8, 13, 15] },
1442                2 => { reset: Input, afr: L, af: [3, 13, 15] },
1443                3 => { reset: AF0<PushPull>, afr: L, af: [0, 1, 3, 5, 7, 10, 12, 13, 15] },
1444                4 => { reset: AF0<PushPull>, afr: L, af: [0, 1, 2, 3, 5, 7, 10, 13, 15] },
1445                5 => { reset: Input, afr: L, af: [1, 2, 4, 5, 7, 10, 13, 15] },
1446                6 => { reset: Input, afr: L, af: [1, 3, 4, 7, 12, 13, 15] },
1447                7 => { reset: Input, afr: L, af: [1, 3, 4, 7, 10, 13, 15] },
1448                8 => { reset: Input, afr: H, af: [1, 3, 4, 7, 9, 12, 13, 15] },
1449                9 => { reset: Input, afr: H, af: [1, 4, 6, 7, 8, 9, 13, 15] },
1450                10 => { reset: Input, afr: H, af: [1, 3, 7, 13, 15] },
1451                11 => { reset: Input, afr: H, af: [1, 3, 7, 13, 15] },
1452                12 => { reset: Input, afr: H, af: [3, 6, 7, 13, 15] },
1453                13 => { reset: Input, afr: H, af: [3, 6, 7, 13, 15] },
1454                14 => { reset: Input, afr: H, af: [1, 3, 6, 7, 13, 15] },
1455                15 => { reset: Input, afr: H, af: [1, 2, 4, 13, 15] },
1456            ],
1457        },
1458        {
1459            port: (C/c, 2, gpioc),
1460            pins: [
1461                0 => { reset: Input, afr: L, af: [1, 2] },
1462                1 => { reset: Input, afr: L, af: [1, 2] },
1463                2 => { reset: Input, afr: L, af: [1, 2] },
1464                3 => { reset: Input, afr: L, af: [1, 2, 6] },
1465                4 => { reset: Input, afr: L, af: [1, 2, 7] },
1466                5 => { reset: Input, afr: L, af: [1, 2, 3, 7] },
1467                6 => { reset: Input, afr: L, af: [1, 2, 3, 7] },
1468                7 => { reset: Input, afr: L, af: [1, 2, 3] },
1469                8 => { reset: Input, afr: H, af: [1, 2, 3] },
1470                9 => { reset: Input, afr: H, af: [1, 2, 3] },
1471                10 => { reset: Input, afr: H, af: [1, 7] },
1472                11 => { reset: Input, afr: H, af: [1, 3, 7] },
1473                12 => { reset: Input, afr: H, af: [1, 3, 7] },
1474                13 => { reset: Input, afr: H, af: [4] },
1475                14 => { reset: Input, afr: H, af: [] },
1476                15 => { reset: Input, afr: H, af: [] },
1477            ],
1478        },
1479        {
1480            port: (D/d, 3, gpioc),
1481            pins: [
1482                2 => { reset: Input, afr: L, af: [1, 2] },
1483            ],
1484        },
1485        {
1486            port: (F/f, 5, gpioc),
1487            pins: [
1488                0 => { reset: Input, afr: L, af: [6] },
1489                1 => { reset: Input, afr: L, af: [] },
1490            ],
1491        },
1492    ],
1493});
1494
1495#[cfg(feature = "gpio-f373")]
1496gpio!({
1497    pacs: [gpioa, gpiob, gpioc, gpiod],
1498    ports: [
1499        {
1500            port: (A/a, 0, gpioa),
1501            pins: [
1502                0 => { reset: Input, afr: L, af: [1, 2, 3, 7, 8, 11, 15] },
1503                1 => { reset: Input, afr: L, af: [0, 1, 2, 3, 6, 7, 9, 11, 15] },
1504                2 => { reset: Input, afr: L, af: [1, 2, 3, 6, 7, 8, 9, 11, 15] },
1505                3 => { reset: Input, afr: L, af: [1, 2, 3, 6, 7, 9, 11, 15] },
1506                4 => { reset: Input, afr: L, af: [2, 3, 5, 6, 7, 10, 15] },
1507                5 => { reset: Input, afr: L, af: [1, 3, 5, 7, 9, 10, 15] },
1508                6 => { reset: Input, afr: L, af: [1, 2, 3, 5, 8, 9, 15] },
1509                7 => { reset: Input, afr: L, af: [1, 2, 3, 5, 8, 9, 15] },
1510                8 => { reset: Input, afr: H, af: [0, 2, 4, 5, 7, 10, 15] },
1511                9 => { reset: Input, afr: H, af: [2, 3, 4, 5, 7, 9, 10, 15] },
1512                10 => { reset: Input, afr: H, af: [1, 3, 4, 5, 7, 9, 10, 15] },
1513                11 => { reset: Input, afr: H, af: [2, 5, 6, 7, 8, 9, 10, 14, 15] },
1514                12 => { reset: Input, afr: H, af: [1, 2, 6, 7, 8, 9, 10, 14, 15] },
1515                13 => { reset: AF0<PushPull>, afr: H, af: [0, 1, 2, 3, 5, 6, 7, 10, 15] },
1516                14 => { reset: AF0<PushPull>, afr: H, af: [0, 3, 4, 10, 15] },
1517                15 => { reset: AF0<PushPull>, afr: H, af: [0, 1, 3, 4, 5, 6, 10, 15] },
1518            ],
1519        },
1520        {
1521            port: (B/b, 1, gpiob),
1522            pins: [
1523                0 => { reset: Input, afr: L, af: [2, 3, 5, 10, 15] },
1524                1 => { reset: Input, afr: L, af: [2, 3, 15] },
1525                2 => { reset: Input, afr: L, af: [15] },
1526                3 => { reset: AF0<PushPull>, afr: L, af: [0, 1, 2, 3, 5, 6, 7, 9, 10, 15] },
1527                4 => { reset: AF0<PushPull>, afr: L, af: [0, 1, 2, 3, 5, 6, 7, 9, 10, 15] },
1528                5 => { reset: Input, afr: L, af: [1, 2, 4, 5, 6, 7, 10, 11, 15] },
1529                6 => { reset: Input, afr: L, af: [1, 2, 3, 4, 7, 9, 10, 11, 15] },
1530                7 => { reset: Input, afr: L, af: [1, 2, 3, 4, 7, 9, 10, 11, 15] },
1531                8 => { reset: Input, afr: H, af: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 15] },
1532                9 => { reset: Input, afr: H, af: [1, 2, 4, 5, 6, 7, 8, 9, 11, 15] },
1533                10 => { reset: Input, afr: H, af: [1, 3, 5, 6, 7, 15] },
1534                14 => { reset: Input, afr: H, af: [1, 3, 5, 7, 9, 15] },
1535                15 => { reset: Input, afr: H, af: [0, 1, 2, 3, 5, 9, 15] },
1536            ],
1537        },
1538        {
1539            port: (C/c, 2, gpioc),
1540            pins: [
1541                0 => { reset: Input, afr: L, af: [1, 2] },
1542                1 => { reset: Input, afr: L, af: [1, 2] },
1543                2 => { reset: Input, afr: L, af: [1, 2, 5] },
1544                3 => { reset: Input, afr: L, af: [1, 2, 5] },
1545                4 => { reset: Input, afr: L, af: [1, 2, 3, 7] },
1546                5 => { reset: Input, afr: L, af: [1, 3, 7] },
1547                6 => { reset: Input, afr: L, af: [1, 2, 5] },
1548                7 => { reset: Input, afr: L, af: [1, 2, 5] },
1549                8 => { reset: Input, afr: H, af: [1, 2, 5] },
1550                9 => { reset: Input, afr: H, af: [1, 2, 5] },
1551                10 => { reset: Input, afr: H, af: [1, 2, 6, 7] },
1552                11 => { reset: Input, afr: H, af: [1, 2, 6, 7] },
1553                12 => { reset: Input, afr: H, af: [1, 2, 6, 7] },
1554                13 => { reset: Input, afr: H, af: [] },
1555                14 => { reset: Input, afr: H, af: [] },
1556                15 => { reset: Input, afr: H, af: [] },
1557            ],
1558        },
1559        {
1560            port: (D/d, 3, gpiod),
1561            pins: [
1562                0 => { reset: Input, afr: L, af: [1, 2, 7] },
1563                1 => { reset: Input, afr: L, af: [1, 2, 7] },
1564                2 => { reset: Input, afr: L, af: [1, 2] },
1565                3 => { reset: Input, afr: L, af: [1, 5, 7] },
1566                4 => { reset: Input, afr: L, af: [1, 5, 7] },
1567                5 => { reset: Input, afr: L, af: [1, 7] },
1568                6 => { reset: Input, afr: L, af: [1, 5, 7] },
1569                7 => { reset: Input, afr: L, af: [1, 5, 7] },
1570                8 => { reset: Input, afr: H, af: [1, 3, 5, 7] },
1571                9 => { reset: Input, afr: H, af: [1, 3, 7] },
1572                10 => { reset: Input, afr: H, af: [1, 7] },
1573                11 => { reset: Input, afr: H, af: [1, 7] },
1574                12 => { reset: Input, afr: H, af: [1, 2, 3, 7] },
1575                13 => { reset: Input, afr: H, af: [1, 2, 3] },
1576                14 => { reset: Input, afr: H, af: [1, 2, 3] },
1577                15 => { reset: Input, afr: H, af: [1, 2, 3] },
1578            ],
1579        },
1580        {
1581            port: (E/e, 4, gpioc),
1582            pins: [
1583                0 => { reset: Input, afr: L, af: [1, 2, 7] },
1584                1 => { reset: Input, afr: L, af: [1, 7] },
1585                2 => { reset: Input, afr: L, af: [0, 1, 3] },
1586                3 => { reset: Input, afr: L, af: [0, 1, 3] },
1587                4 => { reset: Input, afr: L, af: [0, 1, 3] },
1588                5 => { reset: Input, afr: L, af: [0, 1, 3] },
1589                6 => { reset: Input, afr: L, af: [0, 1] },
1590                7 => { reset: Input, afr: L, af: [1] },
1591                8 => { reset: Input, afr: H, af: [1] },
1592                9 => { reset: Input, afr: H, af: [1] },
1593                10 => { reset: Input, afr: H, af: [1] },
1594                11 => { reset: Input, afr: H, af: [1] },
1595                12 => { reset: Input, afr: H, af: [1] },
1596                13 => { reset: Input, afr: H, af: [1] },
1597                14 => { reset: Input, afr: H, af: [1] },
1598                15 => { reset: Input, afr: H, af: [1, 7] },
1599            ],
1600        },
1601        {
1602            port: (F/f, 5, gpioc),
1603            pins: [
1604                0 => { reset: Input, afr: L, af: [4] },
1605                1 => { reset: Input, afr: L, af: [4] },
1606                2 => { reset: Input, afr: L, af: [1, 4] },
1607                4 => { reset: Input, afr: L, af: [1] },
1608                6 => { reset: Input, afr: L, af: [1, 2, 4, 5, 7] },
1609                7 => { reset: Input, afr: L, af: [1, 4, 7] },
1610                9 => { reset: Input, afr: H, af: [1, 2] },
1611                10 => { reset: Input, afr: H, af: [1] },
1612            ],
1613        },
1614    ],
1615});