Skip to main content

esp_idf_hal/
gpio.rs

1//! GPIO and pin configuration
2
3use core::marker::PhantomData;
4
5#[cfg(feature = "alloc")]
6extern crate alloc;
7
8use esp_idf_sys::*;
9
10use crate::adc::AdcChannel;
11
12pub use chip::*;
13
14pub type PinId = u8;
15
16/// A trait implemented by every pin instance
17pub trait Pin: Sized + Send {
18    /// Return the pin ID
19    fn pin(&self) -> PinId;
20}
21
22/// A marker trait designating a pin which is capable of
23/// operating as an input pin
24pub trait InputPin: Pin {}
25
26/// A marker trait designating a pin which is capable of
27/// operating as an output pin
28pub trait OutputPin: Pin {}
29
30/// A marker trait designating a pin which is capable of
31/// operating as an RTC pin
32pub trait RTCPin: Pin {
33    /// Return the RTC pin ID
34    fn rtc_pin(&self) -> PinId;
35}
36
37/// A marker trait designating a pin which is capable of
38/// operating as an ADC pin
39pub trait ADCPin: Pin {
40    /// Return the ADC channel for this pin
41    type AdcChannel: AdcChannel;
42}
43
44/// A marker trait designating a pin which is capable of
45/// operating as a DAC pin
46#[cfg(any(esp32, esp32s2))]
47pub trait DacChannel: 'static {
48    /// Return the DAC channel for this pin
49    fn dac_channel(&self) -> dac_channel_t;
50}
51
52#[cfg(any(esp32, esp32s2))]
53pub struct DACCH<const N: dac_channel_t>;
54
55#[cfg(any(esp32, esp32s2))]
56impl<const N: dac_channel_t> DacChannel for DACCH<N> {
57    fn dac_channel(&self) -> dac_channel_t {
58        N
59    }
60}
61
62/// A marker trait designating a pin which is capable of
63/// operating as a DAC pin
64#[cfg(any(esp32, esp32s2))]
65pub trait DACPin: Pin {
66    /// Return the DAC channel for this pin
67    type DacChannel: DacChannel;
68}
69
70/// A marker trait designating a pin which is capable of
71/// operating as a touch pin
72#[cfg(any(esp32, esp32s2, esp32s3))]
73pub trait TouchChannel: 'static {
74    /// Return the touch channel for this pin
75    fn touch_channel(&self) -> touch_pad_t;
76}
77
78#[cfg(any(esp32, esp32s2, esp32s3))]
79pub struct TOUCHCH<const N: touch_pad_t>;
80
81#[cfg(any(esp32, esp32s2, esp32s3))]
82impl<const N: touch_pad_t> TouchChannel for TOUCHCH<N> {
83    fn touch_channel(&self) -> touch_pad_t {
84        N
85    }
86}
87
88/// A marker trait designating a pin which is capable of
89/// operating as a touch pin
90#[cfg(any(esp32, esp32s2, esp32s3))]
91pub trait TouchPin: Pin {
92    /// Return the touch channel for this pin
93    type TouchChannel: TouchChannel;
94}
95
96#[allow(unused_macros)]
97macro_rules! impl_any {
98    ($name:ident) => {
99        pub struct $name<'a> {
100            pin: PinId,
101            _t: ::core::marker::PhantomData<&'a mut ()>,
102        }
103
104        impl $name<'_> {
105            /// Unsafely create an instance of this peripheral out of thin air.
106            ///
107            /// # Safety
108            ///
109            /// You must ensure that you're only using one instance of this type at a time.
110            #[inline(always)]
111            pub unsafe fn steal(pin: PinId) -> Self {
112                Self {
113                    pin,
114                    _t: ::core::marker::PhantomData,
115                }
116            }
117
118            /// Creates a new peripheral reference with a shorter lifetime.
119            ///
120            /// Use this method if you would like to keep working with the peripheral after
121            /// you dropped the driver that consumes this.
122            ///
123            /// # Safety
124            ///
125            /// You must ensure that you are not using reborrowed peripherals in drivers which are
126            /// forgotten via `core::mem::forget`.
127            #[inline]
128            #[allow(dead_code)]
129            pub unsafe fn reborrow(&mut self) -> $name<'_> {
130                $name {
131                    pin: self.pin,
132                    _t: ::core::marker::PhantomData,
133                }
134            }
135
136            /// Return `Option::None` for an unconfigured instance of that pin
137            pub const fn none() -> Option<Self> {
138                None
139            }
140        }
141
142        unsafe impl Send for $name<'_> {}
143
144        impl Pin for $name<'_> {
145            fn pin(&self) -> PinId {
146                self.pin as _
147            }
148        }
149    };
150}
151
152impl_any!(AnyIOPin);
153
154impl InputPin for AnyIOPin<'_> {}
155impl OutputPin for AnyIOPin<'_> {}
156
157impl_any!(AnyInputPin);
158
159impl InputPin for AnyInputPin<'_> {}
160
161impl<'a> From<AnyIOPin<'a>> for AnyInputPin<'a> {
162    fn from(pin: AnyIOPin<'a>) -> Self {
163        unsafe { Self::steal(pin.pin()) }
164    }
165}
166
167impl_any!(AnyOutputPin);
168
169impl OutputPin for AnyOutputPin<'_> {}
170
171impl<'a> From<AnyIOPin<'a>> for AnyOutputPin<'a> {
172    fn from(pin: AnyIOPin<'a>) -> Self {
173        unsafe { Self::steal(pin.pin()) }
174    }
175}
176
177/// Interrupt types
178#[derive(Debug, Eq, PartialEq, Copy, Clone)]
179pub enum InterruptType {
180    PosEdge,
181    NegEdge,
182    AnyEdge,
183    LowLevel,
184    HighLevel,
185}
186
187impl From<InterruptType> for gpio_int_type_t {
188    fn from(interrupt_type: InterruptType) -> gpio_int_type_t {
189        match interrupt_type {
190            InterruptType::PosEdge => gpio_int_type_t_GPIO_INTR_POSEDGE,
191            InterruptType::NegEdge => gpio_int_type_t_GPIO_INTR_NEGEDGE,
192            InterruptType::AnyEdge => gpio_int_type_t_GPIO_INTR_ANYEDGE,
193            InterruptType::LowLevel => gpio_int_type_t_GPIO_INTR_LOW_LEVEL,
194            InterruptType::HighLevel => gpio_int_type_t_GPIO_INTR_HIGH_LEVEL,
195        }
196    }
197}
198
199impl From<InterruptType> for u8 {
200    fn from(interrupt_type: InterruptType) -> u8 {
201        let int_type: gpio_int_type_t = interrupt_type.into();
202
203        int_type as u8
204    }
205}
206
207/// Drive strength (values are approximates)
208#[derive(Debug, Eq, PartialEq, Copy, Clone)]
209pub enum DriveStrength {
210    I5mA = 0,
211    I10mA = 1,
212    I20mA = 2,
213    I40mA = 3,
214}
215
216impl From<DriveStrength> for gpio_drive_cap_t {
217    fn from(strength: DriveStrength) -> gpio_drive_cap_t {
218        match strength {
219            DriveStrength::I5mA => gpio_drive_cap_t_GPIO_DRIVE_CAP_0,
220            DriveStrength::I10mA => gpio_drive_cap_t_GPIO_DRIVE_CAP_1,
221            DriveStrength::I20mA => gpio_drive_cap_t_GPIO_DRIVE_CAP_2,
222            DriveStrength::I40mA => gpio_drive_cap_t_GPIO_DRIVE_CAP_3,
223        }
224    }
225}
226
227impl From<gpio_drive_cap_t> for DriveStrength {
228    #[allow(non_upper_case_globals)]
229    fn from(cap: gpio_drive_cap_t) -> DriveStrength {
230        match cap {
231            gpio_drive_cap_t_GPIO_DRIVE_CAP_0 => DriveStrength::I5mA,
232            gpio_drive_cap_t_GPIO_DRIVE_CAP_1 => DriveStrength::I10mA,
233            gpio_drive_cap_t_GPIO_DRIVE_CAP_2 => DriveStrength::I20mA,
234            gpio_drive_cap_t_GPIO_DRIVE_CAP_3 => DriveStrength::I40mA,
235            other => panic!("Unknown GPIO pin drive capability: {other}"),
236        }
237    }
238}
239
240// Pull setting for an input.
241#[derive(Debug, Eq, PartialEq, Copy, Clone)]
242pub enum Pull {
243    Floating,
244    Up,
245    Down,
246    UpDown,
247}
248
249impl From<Pull> for gpio_pull_mode_t {
250    fn from(pull: Pull) -> gpio_pull_mode_t {
251        match pull {
252            Pull::Floating => gpio_pull_mode_t_GPIO_FLOATING,
253            Pull::Up => gpio_pull_mode_t_GPIO_PULLUP_ONLY,
254            Pull::Down => gpio_pull_mode_t_GPIO_PULLDOWN_ONLY,
255            Pull::UpDown => gpio_pull_mode_t_GPIO_PULLUP_PULLDOWN,
256        }
257    }
258}
259
260/// Digital input or output level.
261#[derive(Debug, Eq, PartialEq, Copy, Clone)]
262pub enum Level {
263    Low,
264    High,
265}
266
267impl From<bool> for Level {
268    fn from(val: bool) -> Self {
269        match val {
270            true => Self::High,
271            false => Self::Low,
272        }
273    }
274}
275
276impl From<Level> for bool {
277    fn from(val: Level) -> bool {
278        match val {
279            Level::Low => false,
280            Level::High => true,
281        }
282    }
283}
284
285impl core::ops::Not for Level {
286    type Output = Level;
287
288    fn not(self) -> Self::Output {
289        match self {
290            Level::Low => Level::High,
291            Level::High => Level::Low,
292        }
293    }
294}
295
296impl From<embedded_hal_0_2::digital::v2::PinState> for Level {
297    fn from(state: embedded_hal_0_2::digital::v2::PinState) -> Self {
298        match state {
299            embedded_hal_0_2::digital::v2::PinState::Low => Self::Low,
300            embedded_hal_0_2::digital::v2::PinState::High => Self::High,
301        }
302    }
303}
304
305impl From<Level> for embedded_hal_0_2::digital::v2::PinState {
306    fn from(level: Level) -> Self {
307        match level {
308            Level::Low => Self::Low,
309            Level::High => Self::High,
310        }
311    }
312}
313
314impl From<embedded_hal::digital::PinState> for Level {
315    fn from(state: embedded_hal::digital::PinState) -> Self {
316        match state {
317            embedded_hal::digital::PinState::Low => Self::Low,
318            embedded_hal::digital::PinState::High => Self::High,
319        }
320    }
321}
322
323impl From<Level> for embedded_hal::digital::PinState {
324    fn from(level: Level) -> Self {
325        match level {
326            Level::Low => Self::Low,
327            Level::High => Self::High,
328        }
329    }
330}
331
332pub trait GPIOMode {}
333
334#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
335pub trait RTCMode {}
336
337pub trait InputMode {
338    const RTC: bool;
339}
340
341pub trait OutputMode {
342    const RTC: bool;
343}
344
345pub struct Disabled;
346pub struct Input;
347pub struct Output;
348pub struct InputOutput;
349#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
350pub struct RtcDisabled;
351#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
352pub struct RtcInput;
353#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
354pub struct RtcOutput;
355#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
356pub struct RtcInputOutput;
357
358impl GPIOMode for Disabled {}
359
360impl GPIOMode for Input {}
361
362impl InputMode for Input {
363    const RTC: bool = false;
364}
365
366impl GPIOMode for InputOutput {}
367
368impl InputMode for InputOutput {
369    const RTC: bool = false;
370}
371
372impl OutputMode for InputOutput {
373    const RTC: bool = false;
374}
375
376impl GPIOMode for Output {}
377
378impl OutputMode for Output {
379    const RTC: bool = false;
380}
381
382#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
383impl RTCMode for RtcDisabled {}
384
385#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
386impl RTCMode for RtcInput {}
387
388#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
389impl InputMode for RtcInput {
390    const RTC: bool = true;
391}
392
393#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
394impl RTCMode for RtcInputOutput {}
395
396#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
397impl InputMode for RtcInputOutput {
398    const RTC: bool = true;
399}
400
401#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
402impl OutputMode for RtcInputOutput {
403    const RTC: bool = true;
404}
405
406#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
407impl RTCMode for RtcOutput {}
408
409#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
410impl OutputMode for RtcOutput {
411    const RTC: bool = true;
412}
413
414/// A driver for a GPIO pin.
415///
416/// The driver can set the pin as a disconnected/disabled one, input, or output pin, or both or analog.
417/// On some chips (i.e. esp32 and esp32s*), the driver can also set the pin in RTC IO mode.
418/// Depending on the current operating mode, different sets of functions are available.
419///
420/// The mode-setting depends on the capabilities of the pin as well, i.e. input-only pins cannot be set
421/// into output or input-output mode.
422pub struct PinDriver<'d, MODE> {
423    pin: PinId,
424    _mode: PhantomData<MODE>,
425    _t: PhantomData<&'d mut ()>,
426}
427
428impl<'d, MODE> PinDriver<'d, MODE> {
429    /// Try to convert the pin driver into a disabled pin driver.
430    ///
431    /// Return an error if the pin cannot be disabled.
432    #[inline]
433    pub fn try_into_disabled(self) -> Result<PinDriver<'d, Disabled>, EspError> {
434        PinDriver::new_gpio(self.pin as _, gpio_mode_t_GPIO_MODE_DISABLE)
435    }
436
437    /// Try to convert the pin driver into an input pin driver.
438    ///
439    /// Return an error if the pin cannot be set as input.
440    #[inline]
441    pub fn try_into_input(self, pull: Pull) -> Result<PinDriver<'d, Input>, EspError> {
442        let mut pin = PinDriver::new_gpio(self.pin as _, gpio_mode_t_GPIO_MODE_INPUT)?;
443
444        pin.set_pull(pull)?;
445
446        Ok(pin)
447    }
448
449    /// Try to convert the pin driver into an output pin driver.
450    ///
451    /// Return an error if the pin cannot be set as output.
452    #[inline]
453    pub fn try_into_output(self) -> Result<PinDriver<'d, Output>, EspError> {
454        PinDriver::new_gpio(self.pin as _, gpio_mode_t_GPIO_MODE_OUTPUT)
455    }
456
457    /// Try to convert the pin driver into an input-output pin driver.
458    ///
459    /// Return an error if the pin cannot be set as input-output.
460    #[inline]
461    pub fn try_into_input_output(self, pull: Pull) -> Result<PinDriver<'d, InputOutput>, EspError> {
462        let mut pin = PinDriver::new_gpio(self.pin as _, gpio_mode_t_GPIO_MODE_INPUT_OUTPUT)?;
463
464        pin.set_pull(pull)?;
465
466        Ok(pin)
467    }
468
469    /// Try to convert the pin driver into an output open-drain pin driver.
470    ///
471    /// Return an error if the pin cannot be set as output open-drain.
472    #[inline]
473    pub fn try_into_output_od(self) -> Result<PinDriver<'d, Output>, EspError> {
474        PinDriver::new_gpio(self.pin as _, gpio_mode_t_GPIO_MODE_OUTPUT_OD)
475    }
476
477    /// Try to convert the pin driver into an input-output open-drain pin driver.
478    ///
479    /// Return an error if the pin cannot be set as input-output open-drain.
480    #[inline]
481    pub fn try_into_input_output_od(
482        self,
483        pull: Pull,
484    ) -> Result<PinDriver<'d, InputOutput>, EspError> {
485        let mut pin = PinDriver::new_gpio(self.pin as _, gpio_mode_t_GPIO_MODE_INPUT_OUTPUT_OD)?;
486
487        pin.set_pull(pull)?;
488
489        Ok(pin)
490    }
491
492    /// Try to convert the pin driver into an RTC disabled pin driver.
493    ///
494    /// Return an error if the pin cannot be disabled.
495    #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
496    #[inline]
497    pub fn try_into_rtc_disabled(self) -> Result<PinDriver<'d, RtcDisabled>, EspError> {
498        PinDriver::new_rtc(self.pin as _, rtc_gpio_mode_t_RTC_GPIO_MODE_DISABLED)
499    }
500
501    /// Try to convert the pin driver into an RTC input pin driver.
502    ///
503    /// Return an error if the pin cannot be set as RTC input.
504    #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
505    #[inline]
506    pub fn try_into_rtc_input(self, pull: Pull) -> Result<PinDriver<'d, RtcInput>, EspError> {
507        let mut pin = PinDriver::new_rtc(self.pin as _, rtc_gpio_mode_t_RTC_GPIO_MODE_INPUT_ONLY)?;
508
509        pin.set_pull(pull)?;
510
511        Ok(pin)
512    }
513
514    /// Try to convert the pin driver into an RTC output pin driver.
515    ///
516    /// Return an error if the pin cannot be set as RTC output.
517    #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
518    #[inline]
519    pub fn try_into_rtc_output(self) -> Result<PinDriver<'d, RtcOutput>, EspError> {
520        PinDriver::new_rtc(self.pin as _, rtc_gpio_mode_t_RTC_GPIO_MODE_OUTPUT_ONLY)
521    }
522
523    /// Try to convert the pin driver into an RTC output open-drain pin driver.
524    ///
525    /// Return an error if the pin cannot be set as RTC output open-drain.
526    #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
527    #[inline]
528    pub fn try_into_rtc_output_od(self) -> Result<PinDriver<'d, RtcOutput>, EspError> {
529        PinDriver::new_rtc(self.pin as _, rtc_gpio_mode_t_RTC_GPIO_MODE_OUTPUT_OD)
530    }
531
532    /// Try to convert the pin driver into an RTC input-output pin driver.
533    ///
534    /// Return an error if the pin cannot be set as RTC input-output.
535    #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
536    #[inline]
537    pub fn try_into_rtc_input_output(
538        self,
539        pull: Pull,
540    ) -> Result<PinDriver<'d, RtcInputOutput>, EspError> {
541        let mut pin =
542            PinDriver::new_rtc(self.pin as _, rtc_gpio_mode_t_RTC_GPIO_MODE_INPUT_OUTPUT)?;
543
544        pin.set_pull(pull)?;
545
546        Ok(pin)
547    }
548
549    /// Try to convert the pin driver into an RTC input-output open-drain pin driver.
550    ///
551    /// Return an error if the pin cannot be set as RTC input-output open-drain.
552    #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
553    #[inline]
554    pub fn try_into_rtc_input_output_od(
555        self,
556        pull: Pull,
557    ) -> Result<PinDriver<'d, RtcInputOutput>, EspError> {
558        let mut pin =
559            PinDriver::new_rtc(self.pin as _, rtc_gpio_mode_t_RTC_GPIO_MODE_INPUT_OUTPUT_OD)?;
560
561        pin.set_pull(pull)?;
562
563        Ok(pin)
564    }
565}
566
567impl<'d> PinDriver<'d, Disabled> {
568    /// Creates the driver for a pin in disabled state.
569    #[inline]
570    pub fn disabled<T: Pin + 'd>(pin: T) -> Result<Self, EspError> {
571        Self::new_gpio(pin.pin(), gpio_mode_t_GPIO_MODE_DISABLE)
572    }
573}
574
575impl<'d> PinDriver<'d, Input> {
576    /// Creates the driver for a pin in input state.
577    #[inline]
578    pub fn input<T: InputPin + 'd>(pin: T, pull: Pull) -> Result<Self, EspError> {
579        let mut pin = Self::new_gpio(pin.pin(), gpio_mode_t_GPIO_MODE_INPUT)?;
580
581        pin.set_pull(pull)?;
582
583        Ok(pin)
584    }
585}
586
587impl<'d> PinDriver<'d, InputOutput> {
588    /// Creates the driver for a pin in input-output state.
589    #[inline]
590    pub fn input_output<T: InputPin + OutputPin + 'd>(
591        pin: T,
592        pull: Pull,
593    ) -> Result<Self, EspError> {
594        let mut pin = Self::new_gpio(pin.pin(), gpio_mode_t_GPIO_MODE_INPUT_OUTPUT)?;
595
596        pin.set_pull(pull)?;
597
598        Ok(pin)
599    }
600
601    /// Creates the driver for a pin in input-output open-drain state.
602    #[inline]
603    pub fn input_output_od<T: InputPin + OutputPin + 'd>(
604        pin: T,
605        pull: Pull,
606    ) -> Result<Self, EspError> {
607        let mut pin = Self::new_gpio(pin.pin(), gpio_mode_t_GPIO_MODE_INPUT_OUTPUT_OD)?;
608
609        pin.set_pull(pull)?;
610
611        Ok(pin)
612    }
613}
614
615impl<'d> PinDriver<'d, Output> {
616    /// Creates the driver for a pin in output state.
617    #[inline]
618    pub fn output<T: OutputPin + 'd>(pin: T) -> Result<Self, EspError> {
619        Self::new_gpio(pin.pin(), gpio_mode_t_GPIO_MODE_OUTPUT)
620    }
621
622    /// Creates the driver for a pin in output open-drain state.
623    #[inline]
624    pub fn output_od<T: OutputPin + 'd>(pin: T) -> Result<Self, EspError> {
625        Self::new_gpio(pin.pin(), gpio_mode_t_GPIO_MODE_OUTPUT_OD)
626    }
627}
628
629#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
630impl<'d> PinDriver<'d, RtcDisabled> {
631    /// Creates the driver for a pin in disabled state.
632    #[inline]
633    pub fn rtc_disabled<T: Pin + RTCPin + 'd>(pin: T) -> Result<Self, EspError> {
634        Self::new_rtc(pin.pin(), rtc_gpio_mode_t_RTC_GPIO_MODE_DISABLED)
635    }
636}
637
638#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
639impl<'d> PinDriver<'d, RtcInput> {
640    /// Creates the driver for a pin in RTC input state.
641    #[inline]
642    pub fn rtc_input<T: InputPin + RTCPin + 'd>(pin: T, pull: Pull) -> Result<Self, EspError> {
643        let mut pin = Self::new_rtc(pin.pin(), rtc_gpio_mode_t_RTC_GPIO_MODE_INPUT_ONLY)?;
644
645        pin.set_pull(pull)?;
646
647        Ok(pin)
648    }
649}
650
651#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
652impl<'d> PinDriver<'d, RtcInputOutput> {
653    /// Creates the driver for a pin in RTC input-output state.
654    #[inline]
655    pub fn rtc_input_output<T: InputPin + OutputPin + RTCPin + 'd>(
656        pin: T,
657        pull: Pull,
658    ) -> Result<Self, EspError> {
659        let mut pin = Self::new_rtc(pin.pin(), rtc_gpio_mode_t_RTC_GPIO_MODE_INPUT_OUTPUT)?;
660
661        pin.set_pull(pull)?;
662
663        Ok(pin)
664    }
665
666    /// Creates the driver for a pin in RTC input-output open-drain state.
667    #[inline]
668    pub fn rtc_input_output_od<T: InputPin + OutputPin + RTCPin + 'd>(
669        pin: T,
670        pull: Pull,
671    ) -> Result<Self, EspError> {
672        let mut pin = Self::new_rtc(pin.pin(), rtc_gpio_mode_t_RTC_GPIO_MODE_INPUT_OUTPUT_OD)?;
673
674        pin.set_pull(pull)?;
675
676        Ok(pin)
677    }
678}
679
680#[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
681impl<'d> PinDriver<'d, RtcOutput> {
682    /// Creates the driver for a pin in RTC output state.
683    #[inline]
684    pub fn rtc_output<T: OutputPin + RTCPin + 'd>(pin: T) -> Result<Self, EspError> {
685        Self::new_rtc(pin.pin(), rtc_gpio_mode_t_RTC_GPIO_MODE_OUTPUT_ONLY)
686    }
687
688    /// Creates the driver for a pin in RTC output open-drain state.
689    #[inline]
690    pub fn rtc_output_od<T: OutputPin + RTCPin + 'd>(pin: T) -> Result<Self, EspError> {
691        Self::new_rtc(pin.pin(), rtc_gpio_mode_t_RTC_GPIO_MODE_OUTPUT_OD)
692    }
693}
694
695impl<'d, MODE> PinDriver<'d, MODE> {
696    /// Returns the pin number.
697    pub fn pin(&self) -> PinId {
698        self.pin
699    }
700
701    #[inline]
702    pub fn get_drive_strength(&self) -> Result<DriveStrength, EspError>
703    where
704        MODE: OutputMode,
705    {
706        let mut cap: gpio_drive_cap_t = 0;
707
708        if MODE::RTC {
709            #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
710            esp!(unsafe { rtc_gpio_get_drive_capability(self.pin as _, &mut cap) })?;
711
712            #[cfg(any(esp32c3, esp32c2, esp32h2, esp32h4))]
713            unreachable!();
714        } else {
715            esp!(unsafe { gpio_get_drive_capability(self.pin as _, &mut cap) })?;
716        }
717
718        Ok(cap.into())
719    }
720
721    #[inline]
722    pub fn set_drive_strength(&mut self, strength: DriveStrength) -> Result<(), EspError>
723    where
724        MODE: OutputMode,
725    {
726        if MODE::RTC {
727            #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
728            esp!(unsafe { rtc_gpio_set_drive_capability(self.pin as _, strength.into()) })?;
729
730            #[cfg(any(esp32c3, esp32c2, esp32h2, esp32h4))]
731            unreachable!();
732        } else {
733            esp!(unsafe { gpio_set_drive_capability(self.pin as _, strength.into()) })?;
734        }
735
736        Ok(())
737    }
738
739    #[inline]
740    pub fn is_high(&self) -> bool
741    where
742        MODE: InputMode,
743    {
744        self.get_level().into()
745    }
746
747    #[inline]
748    pub fn is_low(&self) -> bool
749    where
750        MODE: InputMode,
751    {
752        !self.is_high()
753    }
754
755    #[inline]
756    pub fn get_level(&self) -> Level
757    where
758        MODE: InputMode,
759    {
760        let res;
761
762        if MODE::RTC {
763            #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
764            {
765                res = if unsafe { rtc_gpio_get_level(self.pin as _) } != 0 {
766                    Level::High
767                } else {
768                    Level::Low
769                };
770            }
771
772            #[cfg(any(esp32c3, esp32c2, esp32h2, esp32h4))]
773            unreachable!();
774        } else if unsafe { gpio_get_level(self.pin as _) } != 0 {
775            res = Level::High;
776        } else {
777            res = Level::Low;
778        }
779
780        res
781    }
782
783    #[inline]
784    pub fn is_set_high(&self) -> bool
785    where
786        MODE: OutputMode,
787    {
788        !self.is_set_low()
789    }
790
791    /// Is the output pin set as low?
792    #[inline]
793    pub fn is_set_low(&self) -> bool
794    where
795        MODE: OutputMode,
796    {
797        self.get_output_level() == Level::Low
798    }
799
800    /// What level output is set to
801    #[inline]
802    fn get_output_level(&self) -> Level
803    where
804        MODE: OutputMode,
805    {
806        // TODO: Implement for RTC mode
807
808        let pin = self.pin as u32;
809
810        #[cfg(any(esp32c3, esp32c2, esp32h2, esp32h4))]
811        let is_set_high = unsafe { (*(GPIO_OUT_REG as *const u32) >> pin) & 0x01 != 0 };
812        #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
813        let is_set_high = if pin <= 31 {
814            // GPIO0 - GPIO31
815            unsafe { (*(GPIO_OUT_REG as *const u32) >> pin) & 0x01 != 0 }
816        } else {
817            // GPIO32+
818            unsafe { (*(GPIO_OUT1_REG as *const u32) >> (pin - 32)) & 0x01 != 0 }
819        };
820
821        if is_set_high {
822            Level::High
823        } else {
824            Level::Low
825        }
826    }
827
828    #[inline]
829    pub fn set_high(&mut self) -> Result<(), EspError>
830    where
831        MODE: OutputMode,
832    {
833        self.set_level(Level::High)
834    }
835
836    /// Set the output as low.
837    #[inline]
838    pub fn set_low(&mut self) -> Result<(), EspError>
839    where
840        MODE: OutputMode,
841    {
842        self.set_level(Level::Low)
843    }
844
845    #[inline]
846    pub fn set_level(&mut self, level: Level) -> Result<(), EspError>
847    where
848        MODE: OutputMode,
849    {
850        let on = match level {
851            Level::Low => 0,
852            Level::High => 1,
853        };
854
855        if MODE::RTC {
856            #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
857            esp!(unsafe { rtc_gpio_set_level(self.pin as _, on) })?;
858
859            #[cfg(any(esp32c3, esp32c2, esp32h2, esp32h4))]
860            unreachable!();
861        } else {
862            esp!(unsafe { gpio_set_level(self.pin as _, on) })?;
863        }
864
865        Ok(())
866    }
867
868    /// Toggle pin output
869    #[inline]
870    pub fn toggle(&mut self) -> Result<(), EspError>
871    where
872        MODE: OutputMode,
873    {
874        if self.is_set_low() {
875            self.set_high()
876        } else {
877            self.set_low()
878        }
879    }
880
881    fn set_pull(&mut self, pull: Pull) -> Result<(), EspError>
882    where
883        MODE: InputMode,
884    {
885        if MODE::RTC {
886            #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
887            unsafe {
888                match pull {
889                    Pull::Down => {
890                        esp!(rtc_gpio_pulldown_en(self.pin as _))?;
891                        esp!(rtc_gpio_pullup_dis(self.pin as _))?;
892                    }
893                    Pull::Up => {
894                        esp!(rtc_gpio_pulldown_dis(self.pin as _))?;
895                        esp!(rtc_gpio_pullup_en(self.pin as _))?;
896                    }
897                    Pull::UpDown => {
898                        esp!(rtc_gpio_pulldown_en(self.pin as _))?;
899                        esp!(rtc_gpio_pullup_en(self.pin as _))?;
900                    }
901                    Pull::Floating => {
902                        esp!(rtc_gpio_pulldown_dis(self.pin as _))?;
903                        esp!(rtc_gpio_pullup_dis(self.pin as _))?;
904                    }
905                }
906            }
907
908            #[cfg(any(esp32c3, esp32c2, esp32h2, esp32h4))]
909            unreachable!();
910        } else {
911            esp!(unsafe { gpio_set_pull_mode(self.pin as _, pull.into()) })?;
912        }
913
914        Ok(())
915    }
916
917    /// Subscribes the provided callback for ISR notifications.
918    /// As a side effect, interrupts will be disabled, so to receive a notification, one has
919    /// to also call `PinDriver::enable_interrupt` after calling this method.
920    ///
921    /// Note that `PinDriver::enable_interrupt` should also be called after
922    /// each received notification **from non-ISR context**, because the driver will automatically
923    /// disable ISR interrupts on each received ISR notification (so as to avoid IWDT triggers).
924    ///
925    /// # Safety
926    ///
927    /// Care should be taken not to call STD, libc or FreeRTOS APIs (except for a few allowed ones)
928    /// in the callback passed to this function, as it is executed in an ISR context.
929    #[cfg(feature = "alloc")]
930    pub unsafe fn subscribe<F: FnMut() + Send + 'static>(
931        &mut self,
932        callback: F,
933    ) -> Result<(), EspError>
934    where
935        MODE: InputMode,
936    {
937        self.internal_subscribe(callback)
938    }
939
940    /// Subscribes the provided callback for ISR notifications.
941    /// As a side effect, interrupts will be disabled, so to receive a notification, one has
942    /// to also call `PinDriver::enable_interrupt` after calling this method.
943    ///
944    /// Note that `PinDriver::enable_interrupt` should also be called after
945    /// each received notification **from non-ISR context**, because the driver will automatically
946    /// disable ISR interrupts on each received ISR notification (so as to avoid IWDT triggers).
947    ///
948    /// # Safety
949    ///
950    /// Care should be taken not to call STD, libc or FreeRTOS APIs (except for a few allowed ones)
951    /// in the callback passed to this function, as it is executed in an ISR context.
952    ///
953    /// Additionally, this method - in contrast to method `subscribe` - allows
954    /// the passed-in callback/closure to be non-`'static`. This enables users to borrow
955    /// - in the closure - variables that live on the stack - or more generally - in the same
956    ///   scope where the driver is created.
957    ///
958    /// HOWEVER: care should be taken NOT to call `core::mem::forget()` on the driver,
959    /// as that would immediately lead to an UB (crash).
960    /// Also note that forgetting the driver might happen with `Rc` and `Arc`
961    /// when circular references are introduced: https://github.com/rust-lang/rust/issues/24456
962    ///
963    /// The reason is that the closure is actually sent and owned by an ISR routine,
964    /// which means that if the driver is forgotten, Rust is free to e.g. unwind the stack
965    /// and the ISR routine will end up with references to variables that no longer exist.
966    ///
967    /// The destructor of the driver takes care - prior to the driver being dropped and e.g.
968    /// the stack being unwind - to unsubscribe the ISR routine.
969    /// Unfortunately, when the driver is forgotten, the un-subscription does not happen
970    /// and invalid references are left dangling.
971    ///
972    /// This "local borrowing" will only be possible to express in a safe way once/if `!Leak` types
973    /// are introduced to Rust (i.e. the impossibility to "forget" a type and thus not call its destructor).
974    #[cfg(feature = "alloc")]
975    pub unsafe fn subscribe_nonstatic<F: FnMut() + Send + 'd>(
976        &mut self,
977        callback: F,
978    ) -> Result<(), EspError>
979    where
980        MODE: InputMode,
981    {
982        self.internal_subscribe(callback)
983    }
984
985    #[cfg(feature = "alloc")]
986    fn internal_subscribe(&mut self, callback: impl FnMut() + Send + 'd) -> Result<(), EspError>
987    where
988        MODE: InputMode,
989    {
990        extern crate alloc;
991
992        self.disable_interrupt()?;
993
994        let callback: alloc::boxed::Box<dyn FnMut() + Send + 'd> = alloc::boxed::Box::new(callback);
995        unsafe {
996            chip::PIN_ISR_HANDLER[self.pin as usize] = Some(core::mem::transmute::<
997                alloc::boxed::Box<dyn FnMut() + Send>,
998                alloc::boxed::Box<dyn FnMut() + Send>,
999            >(callback));
1000        }
1001
1002        Ok(())
1003    }
1004
1005    pub fn unsubscribe(&mut self) -> Result<(), EspError>
1006    where
1007        MODE: InputMode,
1008    {
1009        unsafe {
1010            unsubscribe_pin(self.pin as _)?;
1011        }
1012
1013        Ok(())
1014    }
1015
1016    /// Enables or re-enables the interrupt
1017    ///
1018    /// Note that the interrupt is automatically disabled each time an interrupt is triggered
1019    /// (or else we risk entering a constant interrupt processing loop while the pin is in low/high state
1020    /// and the interrupt type is set to non-edge)
1021    ///
1022    /// Therefore - to continue receiving ISR interrupts - user needs to call `enable_interrupt`
1023    /// - **from a non-ISR context** - after each successful interrupt triggering.
1024    pub fn enable_interrupt(&mut self) -> Result<(), EspError>
1025    where
1026        MODE: InputMode,
1027    {
1028        enable_isr_service()?;
1029
1030        unsafe {
1031            esp!(gpio_isr_handler_add(
1032                self.pin as _,
1033                Some(Self::handle_isr),
1034                self.pin as u32 as *mut core::ffi::c_void,
1035            ))
1036        }
1037    }
1038
1039    pub fn disable_interrupt(&mut self) -> Result<(), EspError>
1040    where
1041        MODE: InputMode,
1042    {
1043        use core::sync::atomic::Ordering;
1044
1045        if ISR_SERVICE_ENABLED.load(Ordering::SeqCst) {
1046            esp!(unsafe { gpio_isr_handler_remove(self.pin as _) })?;
1047        }
1048
1049        Ok(())
1050    }
1051
1052    pub fn set_interrupt_type(&mut self, interrupt_type: InterruptType) -> Result<(), EspError>
1053    where
1054        MODE: InputMode,
1055    {
1056        esp!(unsafe { gpio_set_intr_type(self.pin as _, interrupt_type.into()) })?;
1057
1058        Ok(())
1059    }
1060
1061    #[inline]
1062    fn new_gpio(pin: PinId, mode: gpio_mode_t) -> Result<Self, EspError>
1063    where
1064        MODE: GPIOMode,
1065    {
1066        if mode != gpio_mode_t_GPIO_MODE_DISABLE {
1067            esp!(unsafe { gpio_set_direction(pin as _, mode) })?;
1068        }
1069
1070        Ok(Self {
1071            pin,
1072            _mode: PhantomData,
1073            _t: PhantomData,
1074        })
1075    }
1076
1077    #[inline]
1078    #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
1079    fn new_rtc(pin: PinId, mode: rtc_gpio_mode_t) -> Result<Self, EspError>
1080    where
1081        MODE: RTCMode,
1082    {
1083        esp!(unsafe { rtc_gpio_init(pin as _) })?;
1084        esp!(unsafe { rtc_gpio_set_direction(pin as _, mode) })?;
1085
1086        Ok(PinDriver {
1087            pin,
1088            _mode: PhantomData,
1089            _t: PhantomData,
1090        })
1091    }
1092
1093    unsafe extern "C" fn handle_isr(user_ctx: *mut core::ffi::c_void) {
1094        let pin = user_ctx as u32;
1095
1096        // IMPORTANT: MUST be done or else the ESP IDF GPIO driver will continue calling us in a loop
1097        // - particularly when the interrupt type is set to non-edge triggering (pin high or low) -
1098        // which will eventually cause the Interrupt WatchDog to kick in
1099        gpio_intr_disable(pin as _);
1100
1101        PIN_NOTIF[pin as usize].notify_lsb();
1102
1103        #[cfg(feature = "alloc")]
1104        {
1105            if let Some(unsafe_callback) = unsafe { &mut PIN_ISR_HANDLER[pin as usize] } {
1106                (unsafe_callback)();
1107            }
1108        }
1109    }
1110}
1111
1112impl<MODE: InputMode> PinDriver<'_, MODE> {
1113    pub async fn wait_for(&mut self, interrupt_type: InterruptType) -> Result<(), EspError> {
1114        self.disable_interrupt()?;
1115
1116        let notif = &chip::PIN_NOTIF[self.pin as usize];
1117
1118        notif.reset();
1119
1120        match interrupt_type {
1121            InterruptType::LowLevel if self.is_low() => return Ok(()),
1122            InterruptType::HighLevel if self.is_high() => return Ok(()),
1123            _ => (),
1124        }
1125
1126        self.set_interrupt_type(interrupt_type)?;
1127        self.enable_interrupt()?;
1128
1129        notif.wait().await;
1130
1131        Ok(())
1132    }
1133
1134    pub async fn wait_for_high(&mut self) -> Result<(), EspError> {
1135        self.wait_for(InterruptType::HighLevel).await
1136    }
1137
1138    pub async fn wait_for_low(&mut self) -> Result<(), EspError> {
1139        self.wait_for(InterruptType::LowLevel).await
1140    }
1141
1142    pub async fn wait_for_rising_edge(&mut self) -> Result<(), EspError> {
1143        self.wait_for(InterruptType::PosEdge).await
1144    }
1145
1146    pub async fn wait_for_falling_edge(&mut self) -> Result<(), EspError> {
1147        self.wait_for(InterruptType::NegEdge).await
1148    }
1149
1150    pub async fn wait_for_any_edge(&mut self) -> Result<(), EspError> {
1151        self.wait_for(InterruptType::AnyEdge).await
1152    }
1153}
1154
1155impl<MODE> Drop for PinDriver<'_, MODE> {
1156    fn drop(&mut self) {
1157        gpio_reset_without_pull(self.pin as _).unwrap();
1158    }
1159}
1160
1161unsafe impl<MODE> Send for PinDriver<'_, MODE> {}
1162
1163impl<MODE> embedded_hal_0_2::digital::v2::InputPin for PinDriver<'_, MODE>
1164where
1165    MODE: InputMode,
1166{
1167    type Error = EspError;
1168
1169    fn is_high(&self) -> Result<bool, Self::Error> {
1170        Ok(PinDriver::is_high(self))
1171    }
1172
1173    fn is_low(&self) -> Result<bool, Self::Error> {
1174        Ok(PinDriver::is_low(self))
1175    }
1176}
1177
1178use crate::embedded_hal_error;
1179embedded_hal_error!(
1180    GpioError,
1181    embedded_hal::digital::Error,
1182    embedded_hal::digital::ErrorKind
1183);
1184
1185fn to_gpio_err(err: EspError) -> GpioError {
1186    GpioError::other(err)
1187}
1188
1189impl<MODE> embedded_hal::digital::ErrorType for PinDriver<'_, MODE> {
1190    type Error = GpioError;
1191}
1192
1193impl<MODE> embedded_hal::digital::InputPin for PinDriver<'_, MODE>
1194where
1195    MODE: InputMode,
1196{
1197    fn is_high(&mut self) -> Result<bool, Self::Error> {
1198        Ok(PinDriver::is_high(self))
1199    }
1200
1201    fn is_low(&mut self) -> Result<bool, Self::Error> {
1202        Ok(PinDriver::is_low(self))
1203    }
1204}
1205
1206impl<MODE> embedded_hal::digital::InputPin for &PinDriver<'_, MODE>
1207where
1208    MODE: InputMode,
1209{
1210    fn is_high(&mut self) -> Result<bool, Self::Error> {
1211        Ok(PinDriver::is_high(self))
1212    }
1213
1214    fn is_low(&mut self) -> Result<bool, Self::Error> {
1215        Ok(PinDriver::is_low(self))
1216    }
1217}
1218
1219impl<MODE> embedded_hal_0_2::digital::v2::OutputPin for PinDriver<'_, MODE>
1220where
1221    MODE: OutputMode,
1222{
1223    type Error = EspError;
1224
1225    fn set_high(&mut self) -> Result<(), Self::Error> {
1226        self.set_level(Level::High)
1227    }
1228
1229    fn set_low(&mut self) -> Result<(), Self::Error> {
1230        self.set_level(Level::Low)
1231    }
1232}
1233
1234impl<MODE> embedded_hal::digital::OutputPin for PinDriver<'_, MODE>
1235where
1236    MODE: OutputMode,
1237{
1238    fn set_high(&mut self) -> Result<(), Self::Error> {
1239        self.set_level(Level::High).map_err(to_gpio_err)
1240    }
1241
1242    fn set_low(&mut self) -> Result<(), Self::Error> {
1243        self.set_level(Level::Low).map_err(to_gpio_err)
1244    }
1245}
1246
1247impl<MODE> embedded_hal::digital::StatefulOutputPin for PinDriver<'_, MODE>
1248where
1249    MODE: OutputMode,
1250{
1251    fn is_set_high(&mut self) -> Result<bool, Self::Error> {
1252        Ok(self.get_output_level().into())
1253    }
1254
1255    fn is_set_low(&mut self) -> Result<bool, Self::Error> {
1256        Ok(!bool::from(self.get_output_level()))
1257    }
1258}
1259
1260// TODO: Will become possible once the `PinDriver::setXXX`` methods become non-`&mut`, which they really are, internally
1261// impl<'d, T: Pin, MODE> embedded_hal::digital::StatefulOutputPin for &PinDriver<'d, T, MODE>
1262// where
1263//     MODE: OutputMode,
1264// {
1265//     fn is_set_high(&mut self) -> Result<bool, Self::Error> {
1266//         Ok(self.get_output_level().into())
1267//     }
1268
1269//     fn is_set_low(&mut self) -> Result<bool, Self::Error> {
1270//         Ok(!bool::from(self.get_output_level()))
1271//     }
1272// }
1273
1274impl<MODE> embedded_hal_0_2::digital::v2::StatefulOutputPin for PinDriver<'_, MODE>
1275where
1276    MODE: OutputMode,
1277{
1278    fn is_set_high(&self) -> Result<bool, Self::Error> {
1279        Ok(self.get_output_level().into())
1280    }
1281
1282    fn is_set_low(&self) -> Result<bool, Self::Error> {
1283        Ok(!bool::from(self.get_output_level()))
1284    }
1285}
1286
1287impl<MODE> embedded_hal_0_2::digital::v2::ToggleableOutputPin for PinDriver<'_, MODE>
1288where
1289    MODE: OutputMode,
1290{
1291    type Error = EspError;
1292
1293    fn toggle(&mut self) -> Result<(), Self::Error> {
1294        self.set_level(Level::from(!bool::from(self.get_output_level())))
1295    }
1296}
1297
1298impl<MODE: InputMode> embedded_hal_async::digital::Wait for PinDriver<'_, MODE> {
1299    async fn wait_for_high(&mut self) -> Result<(), GpioError> {
1300        self.wait_for_high().await?;
1301
1302        Ok(())
1303    }
1304
1305    async fn wait_for_low(&mut self) -> Result<(), GpioError> {
1306        self.wait_for_low().await?;
1307
1308        Ok(())
1309    }
1310
1311    async fn wait_for_rising_edge(&mut self) -> Result<(), GpioError> {
1312        self.wait_for_rising_edge().await?;
1313
1314        Ok(())
1315    }
1316
1317    async fn wait_for_falling_edge(&mut self) -> Result<(), GpioError> {
1318        self.wait_for_falling_edge().await?;
1319
1320        Ok(())
1321    }
1322
1323    async fn wait_for_any_edge(&mut self) -> Result<(), GpioError> {
1324        self.wait_for_any_edge().await?;
1325
1326        Ok(())
1327    }
1328}
1329
1330static ISR_ALLOC_FLAGS: core::sync::atomic::AtomicU32 = core::sync::atomic::AtomicU32::new(0);
1331
1332static ISR_SERVICE_ENABLED: core::sync::atomic::AtomicBool =
1333    core::sync::atomic::AtomicBool::new(false);
1334
1335static ISR_SERVICE_ENABLED_CS: crate::task::CriticalSection = crate::task::CriticalSection::new();
1336
1337pub fn init_isr_alloc_flags(flags: enumset::EnumSet<crate::interrupt::InterruptType>) {
1338    ISR_ALLOC_FLAGS.store(
1339        crate::interrupt::InterruptType::to_native(flags),
1340        core::sync::atomic::Ordering::SeqCst,
1341    );
1342}
1343
1344pub fn enable_isr_service() -> Result<(), EspError> {
1345    use core::sync::atomic::Ordering;
1346
1347    if !ISR_SERVICE_ENABLED.load(Ordering::SeqCst) {
1348        let _guard = ISR_SERVICE_ENABLED_CS.enter();
1349
1350        if !ISR_SERVICE_ENABLED.load(Ordering::SeqCst) {
1351            esp!(unsafe { gpio_install_isr_service(ISR_ALLOC_FLAGS.load(Ordering::SeqCst) as _) })?;
1352
1353            ISR_SERVICE_ENABLED.store(true, Ordering::SeqCst);
1354        }
1355    }
1356
1357    Ok(())
1358}
1359
1360/// Notifies this GPIO driver that the GPIO ISR service has already been initialized.
1361/// This prevents an error as this driver would otherwise attempt to initialize it again.
1362///
1363/// # Safety
1364///
1365/// The caller must ensure that `gpio_install_isr_service` has already
1366/// been invoked elsewhere. This should only be ever needed when
1367/// interfacing external code that touches the GPIO ISR service.
1368pub unsafe fn set_isr_service_flag_unchecked() {
1369    ISR_SERVICE_ENABLED.store(true, core::sync::atomic::Ordering::SeqCst);
1370}
1371
1372pub(crate) unsafe fn rtc_reset_pin(pin: i32) -> Result<(), EspError> {
1373    gpio_reset_without_pull(pin)?;
1374
1375    #[cfg(not(any(esp32c3, esp32c2, esp32h2, esp32h4)))]
1376    esp!(rtc_gpio_init(pin))?;
1377
1378    Ok(())
1379}
1380
1381// The default esp-idf gpio_reset function sets a pull-up. If that behaviour is
1382// not desired this function can be used instead.
1383#[inline]
1384fn gpio_reset_without_pull(pin: gpio_num_t) -> Result<(), EspError> {
1385    let cfg = gpio_config_t {
1386        pin_bit_mask: (1u64 << pin),
1387        mode: esp_idf_sys::gpio_mode_t_GPIO_MODE_DISABLE,
1388        pull_up_en: esp_idf_sys::gpio_pullup_t_GPIO_PULLUP_DISABLE,
1389        pull_down_en: esp_idf_sys::gpio_pulldown_t_GPIO_PULLDOWN_DISABLE,
1390        intr_type: esp_idf_sys::gpio_int_type_t_GPIO_INTR_DISABLE,
1391        #[cfg(all(
1392            esp_idf_soc_gpio_support_pin_hys_filter,
1393            not(esp_idf_version_major = "4")
1394        ))]
1395        hys_ctrl_mode: esp_idf_sys::gpio_hys_ctrl_mode_t_GPIO_HYS_SOFT_DISABLE,
1396    };
1397
1398    unsafe {
1399        unsubscribe_pin(pin)?;
1400        esp!(gpio_config(&cfg))?;
1401    }
1402    Ok(())
1403}
1404
1405unsafe fn unsubscribe_pin(pin: gpio_num_t) -> Result<(), EspError> {
1406    use core::sync::atomic::Ordering;
1407
1408    if ISR_SERVICE_ENABLED.load(Ordering::SeqCst) {
1409        esp!(gpio_isr_handler_remove(pin as _))?;
1410
1411        chip::PIN_NOTIF[pin as usize].reset();
1412
1413        #[cfg(feature = "alloc")]
1414        {
1415            chip::PIN_ISR_HANDLER[pin as usize] = None;
1416        }
1417    }
1418
1419    Ok(())
1420}
1421
1422#[cfg(feature = "alloc")]
1423#[allow(clippy::declare_interior_mutable_const)] // OK because this is only used as an array initializer
1424const PIN_ISR_INIT: Option<alloc::boxed::Box<dyn FnMut() + Send + 'static>> = None;
1425
1426#[allow(clippy::declare_interior_mutable_const)] // OK because this is only used as an array initializer
1427const PIN_NOTIF_INIT: crate::interrupt::asynch::HalIsrNotification =
1428    crate::interrupt::asynch::HalIsrNotification::new();
1429
1430macro_rules! impl_input {
1431    ($pxi:ident: $pin:expr) => {
1432        $crate::impl_peripheral!($pxi);
1433
1434        impl $pxi<'static> {
1435            /// Return `Option::None` for an unconfigured instance of that pin
1436            pub const fn none() -> Option<Self> {
1437                None
1438            }
1439        }
1440
1441        impl Pin for $pxi<'_> {
1442            fn pin(&self) -> PinId {
1443                $pin as _
1444            }
1445        }
1446
1447        impl InputPin for $pxi<'_> {}
1448
1449        impl<'a> From<$pxi<'a>> for AnyInputPin<'a> {
1450            fn from(pin: $pxi) -> Self {
1451                unsafe { Self::steal(pin.pin()) }
1452            }
1453        }
1454
1455        impl<'a> $pxi<'a> {
1456            pub fn degrade_input(self) -> AnyInputPin<'a> {
1457                self.into()
1458            }
1459        }
1460    };
1461}
1462
1463macro_rules! impl_input_output {
1464    ($pxi:ident: $pin:expr) => {
1465        impl_input!($pxi: $pin);
1466
1467        impl<'a> $pxi<'a> {
1468            pub fn degrade_output(self) -> AnyOutputPin<'a> {
1469                self.into()
1470            }
1471
1472            pub fn degrade_input_output(self) -> AnyIOPin<'a> {
1473                self.into()
1474            }
1475        }
1476
1477        impl OutputPin for $pxi<'_> {}
1478
1479        impl<'a> From<$pxi<'a>> for AnyOutputPin<'a> {
1480            fn from(pin: $pxi) -> Self {
1481                unsafe { Self::steal(pin.pin()) }
1482            }
1483        }
1484
1485        impl<'a> From<$pxi<'a>> for AnyIOPin<'a> {
1486            fn from(pin: $pxi) -> Self {
1487                unsafe { Self::steal(pin.pin()) }
1488            }
1489        }
1490    };
1491}
1492
1493macro_rules! impl_rtc {
1494    ($pxi:ident: $pin:expr, RTC: $rtc:expr) => {
1495        impl RTCPin for $pxi<'_> {
1496            fn rtc_pin(&self) -> PinId {
1497                $rtc
1498            }
1499        }
1500    };
1501
1502    ($pxi:ident: $pin:expr, NORTC: $rtc:expr) => {};
1503}
1504
1505macro_rules! impl_adc {
1506    ($pxi:ident: $pin:expr, ADC1: $channel:ident) => {
1507        impl ADCPin for $pxi<'_> {
1508            type AdcChannel = $crate::adc::$channel<$crate::adc::ADCU1>;
1509        }
1510    };
1511
1512    ($pxi:ident: $pin:expr, ADC2: $channel:ident) => {
1513        impl ADCPin for $pxi<'_> {
1514            type AdcChannel = $crate::adc::$channel<$crate::adc::ADCU2>;
1515        }
1516    };
1517
1518    ($pxi:ident: $pin:expr, NOADC: $channel:ident) => {};
1519}
1520
1521macro_rules! impl_dac {
1522    ($pxi:ident: $pin:expr, DAC: $dac:expr) => {
1523        #[cfg(any(esp32, esp32s2))]
1524        impl DACPin for $pxi<'_> {
1525            type DacChannel = DACCH<$dac>;
1526        }
1527    };
1528
1529    ($pxi:ident: $pin:expr, NODAC: $dac:expr) => {};
1530}
1531
1532macro_rules! impl_touch {
1533    ($pxi:ident: $pin:expr, TOUCH: $touch:expr) => {
1534        #[cfg(any(esp32, esp32s2, esp32s3))]
1535        impl TouchPin for $pxi<'_> {
1536            type TouchChannel = TOUCHCH<$touch>;
1537        }
1538    };
1539
1540    ($pxi:ident: $pin:expr, NOTOUCH: $touch:expr) => {};
1541}
1542
1543macro_rules! pin {
1544    ($pxi:ident: $pin:expr, Input, $rtc:ident: $rtcno:expr, $adc:ident: $adcno:ident, $dac:ident: $dacno:expr, $touch:ident: $touchno:expr) => {
1545        impl_input!($pxi: $pin);
1546        impl_rtc!($pxi: $pin, $rtc: $rtcno);
1547        impl_adc!($pxi: $pin, $adc: $adcno);
1548        impl_dac!($pxi: $pin, $dac: $dacno);
1549        impl_touch!($pxi: $pin, $touch: $touchno);
1550    };
1551
1552    ($pxi:ident: $pin:expr, IO, $rtc:ident: $rtcno:expr, $adc:ident: $adcno:ident, $dac:ident: $dacno:expr, $touch:ident: $touchno:expr) => {
1553        impl_input_output!($pxi: $pin);
1554        impl_rtc!($pxi: $pin, $rtc: $rtcno);
1555        impl_adc!($pxi: $pin, $adc: $adcno);
1556        impl_dac!($pxi: $pin, $dac: $dacno);
1557        impl_touch!($pxi: $pin, $touch: $touchno);
1558    };
1559}
1560
1561#[cfg(esp32)]
1562mod chip {
1563    #[cfg(feature = "alloc")]
1564    extern crate alloc;
1565
1566    #[cfg(feature = "alloc")]
1567    use alloc::boxed::Box;
1568
1569    use crate::interrupt::asynch::HalIsrNotification;
1570
1571    use super::*;
1572
1573    #[allow(clippy::type_complexity)]
1574    #[cfg(feature = "alloc")]
1575    pub(crate) static mut PIN_ISR_HANDLER: [Option<Box<dyn FnMut() + Send + 'static>>; 40] =
1576        [PIN_ISR_INIT; 40];
1577
1578    #[allow(clippy::type_complexity)]
1579    pub(crate) static PIN_NOTIF: [HalIsrNotification; 40] = [PIN_NOTIF_INIT; 40];
1580
1581    // NOTE: Gpio26 - Gpio32 are used by SPI0/SPI1 for external PSRAM/SPI Flash and
1582    //       are not recommended for other uses
1583    pin!(Gpio0:0, IO, RTC:11, ADC2:ADCCH1, NODAC:0, TOUCH:1);
1584    pin!(Gpio1:1, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1585    pin!(Gpio2:2, IO, RTC:12, ADC2:ADCCH2, NODAC:0, TOUCH:2);
1586    pin!(Gpio3:3, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1587    pin!(Gpio4:4, IO, RTC:10, ADC2:ADCCH0, NODAC:0, TOUCH:0);
1588    pin!(Gpio5:5, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1589    pin!(Gpio6:6, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1590    pin!(Gpio7:7, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1591    pin!(Gpio8:8, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1592    pin!(Gpio9:9, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1593    pin!(Gpio10:10, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1594    pin!(Gpio11:11, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1595    pin!(Gpio12:12, IO, RTC:15, ADC2:ADCCH5, NODAC:0, TOUCH:5);
1596    pin!(Gpio13:13, IO, RTC:14, ADC2:ADCCH4, NODAC:0, TOUCH:4);
1597    pin!(Gpio14:14, IO, RTC:16, ADC2:ADCCH6, NODAC:0, TOUCH:6);
1598    pin!(Gpio15:15, IO, RTC:13, ADC2:ADCCH3, NODAC:0, TOUCH:3);
1599    pin!(Gpio16:16, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1600    pin!(Gpio17:17, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1601    pin!(Gpio18:18, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1602    pin!(Gpio19:19, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1603    pin!(Gpio20:20, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1604    pin!(Gpio21:21, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1605    pin!(Gpio22:22, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1606    pin!(Gpio23:23, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1607    pin!(Gpio25:25, IO, RTC:6, ADC2:ADCCH8, DAC:1, NOTOUCH:0);
1608    pin!(Gpio26:26, IO, RTC:7, ADC2:ADCCH9, DAC:2, NOTOUCH:0);
1609    pin!(Gpio27:27, IO, RTC:17, ADC2:ADCCH7, NODAC:0, TOUCH:7);
1610    pin!(Gpio32:32, IO, RTC:9, ADC1:ADCCH4, NODAC:0, TOUCH:9);
1611    pin!(Gpio33:33, IO, RTC:8, ADC1:ADCCH5, NODAC:0, TOUCH:8);
1612    pin!(Gpio34:34, Input, RTC:4, ADC1:ADCCH6, NODAC:0, NOTOUCH:0);
1613    pin!(Gpio35:35, Input, RTC:5, ADC1:ADCCH7, NODAC:0, NOTOUCH:0);
1614    pin!(Gpio36:36, Input, RTC:0, ADC1:ADCCH0, NODAC:0, NOTOUCH:0);
1615    pin!(Gpio37:37, Input, RTC:1, ADC1:ADCCH1, NODAC:0, NOTOUCH:0);
1616    pin!(Gpio38:38, Input, RTC:2, ADC1:ADCCH2, NODAC:0, NOTOUCH:0);
1617    pin!(Gpio39:39, Input, RTC:3, ADC1:ADCCH3, NODAC:0, NOTOUCH:0);
1618
1619    pub struct Pins {
1620        pub gpio0: Gpio0<'static>,
1621        pub gpio1: Gpio1<'static>,
1622        pub gpio2: Gpio2<'static>,
1623        pub gpio3: Gpio3<'static>,
1624        pub gpio4: Gpio4<'static>,
1625        pub gpio5: Gpio5<'static>,
1626        pub gpio6: Gpio6<'static>,
1627        pub gpio7: Gpio7<'static>,
1628        pub gpio8: Gpio8<'static>,
1629        pub gpio9: Gpio9<'static>,
1630        pub gpio10: Gpio10<'static>,
1631        pub gpio11: Gpio11<'static>,
1632        pub gpio12: Gpio12<'static>,
1633        pub gpio13: Gpio13<'static>,
1634        pub gpio14: Gpio14<'static>,
1635        pub gpio15: Gpio15<'static>,
1636        pub gpio16: Gpio16<'static>,
1637        pub gpio17: Gpio17<'static>,
1638        pub gpio18: Gpio18<'static>,
1639        pub gpio19: Gpio19<'static>,
1640        pub gpio20: Gpio20<'static>,
1641        pub gpio21: Gpio21<'static>,
1642        pub gpio22: Gpio22<'static>,
1643        pub gpio23: Gpio23<'static>,
1644        pub gpio25: Gpio25<'static>,
1645        pub gpio26: Gpio26<'static>,
1646        pub gpio27: Gpio27<'static>,
1647        pub gpio32: Gpio32<'static>,
1648        pub gpio33: Gpio33<'static>,
1649        pub gpio34: Gpio34<'static>,
1650        pub gpio35: Gpio35<'static>,
1651        pub gpio36: Gpio36<'static>,
1652        pub gpio37: Gpio37<'static>,
1653        pub gpio38: Gpio38<'static>,
1654        pub gpio39: Gpio39<'static>,
1655    }
1656
1657    impl Pins {
1658        /// # Safety
1659        ///
1660        /// Care should be taken not to instantiate the Pins structure, if it is
1661        /// already instantiated and used elsewhere
1662        pub unsafe fn new() -> Self {
1663            Self {
1664                gpio0: Gpio0::steal(),
1665                gpio1: Gpio1::steal(),
1666                gpio2: Gpio2::steal(),
1667                gpio3: Gpio3::steal(),
1668                gpio4: Gpio4::steal(),
1669                gpio5: Gpio5::steal(),
1670                gpio6: Gpio6::steal(),
1671                gpio7: Gpio7::steal(),
1672                gpio8: Gpio8::steal(),
1673                gpio9: Gpio9::steal(),
1674                gpio10: Gpio10::steal(),
1675                gpio11: Gpio11::steal(),
1676                gpio12: Gpio12::steal(),
1677                gpio13: Gpio13::steal(),
1678                gpio14: Gpio14::steal(),
1679                gpio15: Gpio15::steal(),
1680                gpio16: Gpio16::steal(),
1681                gpio17: Gpio17::steal(),
1682                gpio18: Gpio18::steal(),
1683                gpio19: Gpio19::steal(),
1684                gpio20: Gpio20::steal(),
1685                gpio21: Gpio21::steal(),
1686                gpio22: Gpio22::steal(),
1687                gpio23: Gpio23::steal(),
1688                gpio25: Gpio25::steal(),
1689                gpio26: Gpio26::steal(),
1690                gpio27: Gpio27::steal(),
1691                gpio32: Gpio32::steal(),
1692                gpio33: Gpio33::steal(),
1693                gpio34: Gpio34::steal(),
1694                gpio35: Gpio35::steal(),
1695                gpio36: Gpio36::steal(),
1696                gpio37: Gpio37::steal(),
1697                gpio38: Gpio38::steal(),
1698                gpio39: Gpio39::steal(),
1699            }
1700        }
1701    }
1702}
1703
1704#[cfg(any(esp32s2, esp32s3))]
1705mod chip {
1706    #[cfg(feature = "alloc")]
1707    extern crate alloc;
1708
1709    #[cfg(feature = "alloc")]
1710    use alloc::boxed::Box;
1711
1712    use crate::interrupt::asynch::HalIsrNotification;
1713
1714    use super::*;
1715
1716    #[allow(clippy::type_complexity)]
1717    #[cfg(feature = "alloc")]
1718    pub(crate) static mut PIN_ISR_HANDLER: [Option<Box<dyn FnMut() + Send + 'static>>; 49] =
1719        [PIN_ISR_INIT; 49];
1720
1721    #[allow(clippy::type_complexity)]
1722    pub(crate) static PIN_NOTIF: [HalIsrNotification; 49] = [PIN_NOTIF_INIT; 49];
1723
1724    // NOTE: Gpio26 - Gpio32 (and Gpio33 - Gpio37 if using Octal RAM/Flash) are used
1725    //       by SPI0/SPI1 for external PSRAM/SPI Flash and are not recommended for
1726    //       other uses
1727    pin!(Gpio0:0, IO, RTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1728    pin!(Gpio1:1, IO, RTC:1, ADC1:ADCCH0, NODAC:0, TOUCH:1);
1729    pin!(Gpio2:2, IO, RTC:2, ADC1:ADCCH1, NODAC:0, TOUCH:2);
1730    pin!(Gpio3:3, IO, RTC:3, ADC1:ADCCH2, NODAC:0, TOUCH:3);
1731    pin!(Gpio4:4, IO, RTC:4, ADC1:ADCCH3, NODAC:0, TOUCH:4);
1732    pin!(Gpio5:5, IO, RTC:5, ADC1:ADCCH4, NODAC:0, TOUCH:5);
1733    pin!(Gpio6:6, IO, RTC:6, ADC1:ADCCH5, NODAC:0, TOUCH:6);
1734    pin!(Gpio7:7, IO, RTC:7, ADC1:ADCCH6, NODAC:0, TOUCH:7);
1735    pin!(Gpio8:8, IO, RTC:8, ADC1:ADCCH7, NODAC:0, TOUCH:8);
1736    pin!(Gpio9:9, IO, RTC:9, ADC1:ADCCH8, NODAC:0, TOUCH:9);
1737    pin!(Gpio10:10, IO, RTC:10, ADC1:ADCCH9, NODAC:0, TOUCH:10);
1738    pin!(Gpio11:11, IO, RTC:11, ADC2:ADCCH0, NODAC:0, TOUCH:11);
1739    pin!(Gpio12:12, IO, RTC:12, ADC2:ADCCH1, NODAC:0, TOUCH:12);
1740    pin!(Gpio13:13, IO, RTC:13, ADC2:ADCCH2, NODAC:0, TOUCH:13);
1741    pin!(Gpio14:14, IO, RTC:14, ADC2:ADCCH3, NODAC:0, TOUCH:14);
1742    pin!(Gpio15:15, IO, RTC:15, ADC2:ADCCH4, NODAC:0, NOTOUCH:0);
1743    pin!(Gpio16:16, IO, RTC:16, ADC2:ADCCH5, NODAC:0, NOTOUCH:0);
1744    #[cfg(esp32s2)]
1745    pin!(Gpio17:17, IO, RTC:17, ADC2:ADCCH6, DAC:1, NOTOUCH:0);
1746    #[cfg(esp32s3)]
1747    pin!(Gpio17:17, IO, RTC:17, ADC2:ADCCH6, NODAC:0, NOTOUCH:0);
1748    #[cfg(esp32s2)]
1749    pin!(Gpio18:18, IO, RTC:18, ADC2:ADCCH7, DAC:2, NOTOUCH:0);
1750    #[cfg(esp32s3)]
1751    pin!(Gpio18:18, IO, RTC:18, ADC2:ADCCH7, NODAC:0, NOTOUCH:0);
1752    pin!(Gpio19:19, IO, RTC:19, ADC2:ADCCH8, NODAC:0, NOTOUCH:0);
1753    pin!(Gpio20:20, IO, RTC:20, ADC2:ADCCH9, NODAC:0, NOTOUCH:0);
1754    pin!(Gpio21:21, IO, RTC:21, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1755    pin!(Gpio26:26, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1756    pin!(Gpio27:27, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1757    pin!(Gpio28:28, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1758    pin!(Gpio29:29, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1759    pin!(Gpio30:30, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1760    pin!(Gpio31:31, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1761    pin!(Gpio32:32, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1762    pin!(Gpio33:33, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1763    pin!(Gpio34:34, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1764    pin!(Gpio35:35, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1765    pin!(Gpio36:36, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1766    pin!(Gpio37:37, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1767    pin!(Gpio38:38, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1768    pin!(Gpio39:39, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1769    pin!(Gpio40:40, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1770    pin!(Gpio41:41, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1771    pin!(Gpio42:42, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1772    pin!(Gpio43:43, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1773    pin!(Gpio44:44, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1774    pin!(Gpio45:45, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1775    #[cfg(esp32s2)]
1776    pin!(Gpio46:46, Input, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1777    #[cfg(esp32s3)]
1778    pin!(Gpio46:46, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1779    #[cfg(esp32s3)]
1780    pin!(Gpio47:47, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1781    #[cfg(esp32s3)]
1782    pin!(Gpio48:48, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1783
1784    pub struct Pins {
1785        pub gpio0: Gpio0<'static>,
1786        pub gpio1: Gpio1<'static>,
1787        pub gpio2: Gpio2<'static>,
1788        pub gpio3: Gpio3<'static>,
1789        pub gpio4: Gpio4<'static>,
1790        pub gpio5: Gpio5<'static>,
1791        pub gpio6: Gpio6<'static>,
1792        pub gpio7: Gpio7<'static>,
1793        pub gpio8: Gpio8<'static>,
1794        pub gpio9: Gpio9<'static>,
1795        pub gpio10: Gpio10<'static>,
1796        pub gpio11: Gpio11<'static>,
1797        pub gpio12: Gpio12<'static>,
1798        pub gpio13: Gpio13<'static>,
1799        pub gpio14: Gpio14<'static>,
1800        pub gpio15: Gpio15<'static>,
1801        pub gpio16: Gpio16<'static>,
1802        pub gpio17: Gpio17<'static>,
1803        pub gpio18: Gpio18<'static>,
1804        pub gpio19: Gpio19<'static>,
1805        pub gpio20: Gpio20<'static>,
1806        pub gpio21: Gpio21<'static>,
1807        pub gpio26: Gpio26<'static>,
1808        pub gpio27: Gpio27<'static>,
1809        pub gpio28: Gpio28<'static>,
1810        pub gpio29: Gpio29<'static>,
1811        pub gpio30: Gpio30<'static>,
1812        pub gpio31: Gpio31<'static>,
1813        pub gpio32: Gpio32<'static>,
1814        pub gpio33: Gpio33<'static>,
1815        pub gpio34: Gpio34<'static>,
1816        pub gpio35: Gpio35<'static>,
1817        pub gpio36: Gpio36<'static>,
1818        pub gpio37: Gpio37<'static>,
1819        pub gpio38: Gpio38<'static>,
1820        pub gpio39: Gpio39<'static>,
1821        pub gpio40: Gpio40<'static>,
1822        pub gpio41: Gpio41<'static>,
1823        pub gpio42: Gpio42<'static>,
1824        pub gpio43: Gpio43<'static>,
1825        pub gpio44: Gpio44<'static>,
1826        pub gpio45: Gpio45<'static>,
1827        pub gpio46: Gpio46<'static>,
1828        #[cfg(esp32s3)]
1829        pub gpio47: Gpio47<'static>,
1830        #[cfg(esp32s3)]
1831        pub gpio48: Gpio48<'static>,
1832    }
1833
1834    impl Pins {
1835        /// # Safety
1836        ///
1837        /// Care should be taken not to instantiate the Pins structure, if it is
1838        /// already instantiated and used elsewhere
1839        pub unsafe fn new() -> Self {
1840            Self {
1841                gpio0: Gpio0::steal(),
1842                gpio1: Gpio1::steal(),
1843                gpio2: Gpio2::steal(),
1844                gpio3: Gpio3::steal(),
1845                gpio4: Gpio4::steal(),
1846                gpio5: Gpio5::steal(),
1847                gpio6: Gpio6::steal(),
1848                gpio7: Gpio7::steal(),
1849                gpio8: Gpio8::steal(),
1850                gpio9: Gpio9::steal(),
1851                gpio10: Gpio10::steal(),
1852                gpio11: Gpio11::steal(),
1853                gpio12: Gpio12::steal(),
1854                gpio13: Gpio13::steal(),
1855                gpio14: Gpio14::steal(),
1856                gpio15: Gpio15::steal(),
1857                gpio16: Gpio16::steal(),
1858                gpio17: Gpio17::steal(),
1859                gpio18: Gpio18::steal(),
1860                gpio19: Gpio19::steal(),
1861                gpio20: Gpio20::steal(),
1862                gpio21: Gpio21::steal(),
1863                gpio26: Gpio26::steal(),
1864                gpio27: Gpio27::steal(),
1865                gpio28: Gpio28::steal(),
1866                gpio29: Gpio29::steal(),
1867                gpio30: Gpio30::steal(),
1868                gpio31: Gpio31::steal(),
1869                gpio32: Gpio32::steal(),
1870                gpio33: Gpio33::steal(),
1871                gpio34: Gpio34::steal(),
1872                gpio35: Gpio35::steal(),
1873                gpio36: Gpio36::steal(),
1874                gpio37: Gpio37::steal(),
1875                gpio38: Gpio38::steal(),
1876                gpio39: Gpio39::steal(),
1877                gpio40: Gpio40::steal(),
1878                gpio41: Gpio41::steal(),
1879                gpio42: Gpio42::steal(),
1880                gpio43: Gpio43::steal(),
1881                gpio44: Gpio44::steal(),
1882                gpio45: Gpio45::steal(),
1883                gpio46: Gpio46::steal(),
1884                #[cfg(esp32s3)]
1885                gpio47: Gpio47::steal(),
1886                #[cfg(esp32s3)]
1887                gpio48: Gpio48::steal(),
1888            }
1889        }
1890    }
1891}
1892
1893#[cfg(esp32c3)]
1894mod chip {
1895    #[cfg(feature = "alloc")]
1896    extern crate alloc;
1897
1898    #[cfg(feature = "alloc")]
1899    use alloc::boxed::Box;
1900
1901    use crate::interrupt::asynch::HalIsrNotification;
1902
1903    use super::*;
1904
1905    #[allow(clippy::type_complexity)]
1906    #[cfg(feature = "alloc")]
1907    pub(crate) static mut PIN_ISR_HANDLER: [Option<Box<dyn FnMut() + Send + 'static>>; 22] =
1908        [PIN_ISR_INIT; 22];
1909
1910    pub(crate) static PIN_NOTIF: [HalIsrNotification; 22] = [PIN_NOTIF_INIT; 22];
1911
1912    // NOTE: Gpio12 - Gpio17 are used by SPI0/SPI1 for external PSRAM/SPI Flash and
1913    //       are not recommended for other uses
1914    pin!(Gpio0:0,   IO,   RTC:0, ADC1:ADCCH0, NODAC:0, NOTOUCH:0);
1915    pin!(Gpio1:1,   IO,   RTC:1, ADC1:ADCCH1, NODAC:0, NOTOUCH:0);
1916    pin!(Gpio2:2,   IO,   RTC:2, ADC1:ADCCH2, NODAC:0, NOTOUCH:0);
1917    pin!(Gpio3:3,   IO,   RTC:3, ADC1:ADCCH3, NODAC:0, NOTOUCH:0);
1918    pin!(Gpio4:4,   IO,   RTC:4, ADC1:ADCCH4, NODAC:0, NOTOUCH:0);
1919    pin!(Gpio5:5,   IO,   RTC:5, ADC2:ADCCH0, NODAC:0, NOTOUCH:0);
1920    pin!(Gpio6:6,   IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1921    pin!(Gpio7:7,   IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1922    pin!(Gpio8:8,   IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1923    pin!(Gpio9:9,   IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1924    pin!(Gpio10:10, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1925    pin!(Gpio11:11, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1926    pin!(Gpio12:12, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1927    pin!(Gpio13:13, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1928    pin!(Gpio14:14, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1929    pin!(Gpio15:15, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1930    pin!(Gpio16:16, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1931    pin!(Gpio17:17, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1932    pin!(Gpio18:18, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1933    pin!(Gpio19:19, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1934    pin!(Gpio20:20, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1935    pin!(Gpio21:21, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
1936
1937    pub struct Pins {
1938        pub gpio0: Gpio0<'static>,
1939        pub gpio1: Gpio1<'static>,
1940        pub gpio2: Gpio2<'static>,
1941        pub gpio3: Gpio3<'static>,
1942        pub gpio4: Gpio4<'static>,
1943        pub gpio5: Gpio5<'static>,
1944        pub gpio6: Gpio6<'static>,
1945        pub gpio7: Gpio7<'static>,
1946        pub gpio8: Gpio8<'static>,
1947        pub gpio9: Gpio9<'static>,
1948        pub gpio10: Gpio10<'static>,
1949        pub gpio11: Gpio11<'static>,
1950        pub gpio12: Gpio12<'static>,
1951        pub gpio13: Gpio13<'static>,
1952        pub gpio14: Gpio14<'static>,
1953        pub gpio15: Gpio15<'static>,
1954        pub gpio16: Gpio16<'static>,
1955        pub gpio17: Gpio17<'static>,
1956        pub gpio18: Gpio18<'static>,
1957        pub gpio19: Gpio19<'static>,
1958        pub gpio20: Gpio20<'static>,
1959        pub gpio21: Gpio21<'static>,
1960    }
1961
1962    impl Pins {
1963        pub(crate) unsafe fn new() -> Self {
1964            Self {
1965                gpio0: Gpio0::steal(),
1966                gpio1: Gpio1::steal(),
1967                gpio2: Gpio2::steal(),
1968                gpio3: Gpio3::steal(),
1969                gpio4: Gpio4::steal(),
1970                gpio5: Gpio5::steal(),
1971                gpio6: Gpio6::steal(),
1972                gpio7: Gpio7::steal(),
1973                gpio8: Gpio8::steal(),
1974                gpio9: Gpio9::steal(),
1975                gpio10: Gpio10::steal(),
1976                gpio11: Gpio11::steal(),
1977                gpio12: Gpio12::steal(),
1978                gpio13: Gpio13::steal(),
1979                gpio14: Gpio14::steal(),
1980                gpio15: Gpio15::steal(),
1981                gpio16: Gpio16::steal(),
1982                gpio17: Gpio17::steal(),
1983                gpio18: Gpio18::steal(),
1984                gpio19: Gpio19::steal(),
1985                gpio20: Gpio20::steal(),
1986                gpio21: Gpio21::steal(),
1987            }
1988        }
1989    }
1990}
1991
1992#[cfg(esp32c2)]
1993mod chip {
1994    #[cfg(feature = "alloc")]
1995    extern crate alloc;
1996
1997    #[cfg(feature = "alloc")]
1998    use alloc::boxed::Box;
1999
2000    use crate::interrupt::asynch::HalIsrNotification;
2001
2002    use super::*;
2003
2004    #[allow(clippy::type_complexity)]
2005    #[cfg(feature = "alloc")]
2006    pub(crate) static mut PIN_ISR_HANDLER: [Option<Box<dyn FnMut() + Send + 'static>>; 21] =
2007        [PIN_ISR_INIT; 21];
2008
2009    pub(crate) static PIN_NOTIF: [HalIsrNotification; 21] = [PIN_NOTIF_INIT; 21];
2010
2011    // NOTE: Gpio12 - Gpio17 are used by SPI0/SPI1 for external PSRAM/SPI Flash and
2012    //       are not recommended for other uses
2013    pin!(Gpio0:0,   IO,   RTC:0,  ADC1:ADCCH0, NODAC:0, NOTOUCH:0);
2014    pin!(Gpio1:1,   IO,   RTC:1,  ADC1:ADCCH1, NODAC:0, NOTOUCH:0);
2015    pin!(Gpio2:2,   IO,   RTC:2,  ADC1:ADCCH2, NODAC:0, NOTOUCH:0);
2016    pin!(Gpio3:3,   IO,   RTC:3,  ADC1:ADCCH3, NODAC:0, NOTOUCH:0);
2017    pin!(Gpio4:4,   IO,   RTC:4,  ADC1:ADCCH4, NODAC:0, NOTOUCH:0);
2018    pin!(Gpio5:5,   IO,   RTC:5, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2019    pin!(Gpio6:6,   IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2020    pin!(Gpio7:7,   IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2021    pin!(Gpio8:8,   IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2022    pin!(Gpio9:9,   IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2023    pin!(Gpio10:10, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2024    pin!(Gpio11:11, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2025    pin!(Gpio12:12, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2026    pin!(Gpio13:13, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2027    pin!(Gpio14:14, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2028    pin!(Gpio15:15, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2029    pin!(Gpio16:16, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2030    pin!(Gpio17:17, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2031    pin!(Gpio18:18, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2032    pin!(Gpio19:19, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2033    pin!(Gpio20:20, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2034
2035    pub struct Pins {
2036        pub gpio0: Gpio0<'static>,
2037        pub gpio1: Gpio1<'static>,
2038        pub gpio2: Gpio2<'static>,
2039        pub gpio3: Gpio3<'static>,
2040        pub gpio4: Gpio4<'static>,
2041        pub gpio5: Gpio5<'static>,
2042        pub gpio6: Gpio6<'static>,
2043        pub gpio7: Gpio7<'static>,
2044        pub gpio8: Gpio8<'static>,
2045        pub gpio9: Gpio9<'static>,
2046        pub gpio10: Gpio10<'static>,
2047        pub gpio11: Gpio11<'static>,
2048        pub gpio12: Gpio12<'static>,
2049        pub gpio13: Gpio13<'static>,
2050        pub gpio14: Gpio14<'static>,
2051        pub gpio15: Gpio15<'static>,
2052        pub gpio16: Gpio16<'static>,
2053        pub gpio17: Gpio17<'static>,
2054        pub gpio18: Gpio18<'static>,
2055        pub gpio19: Gpio19<'static>,
2056        pub gpio20: Gpio20<'static>,
2057    }
2058
2059    impl Pins {
2060        /// # Safety
2061        ///
2062        /// Care should be taken not to instantiate the Pins structure, if it is
2063        /// already instantiated and used elsewhere
2064        pub unsafe fn new() -> Self {
2065            Self {
2066                gpio0: Gpio0::steal(),
2067                gpio1: Gpio1::steal(),
2068                gpio2: Gpio2::steal(),
2069                gpio3: Gpio3::steal(),
2070                gpio4: Gpio4::steal(),
2071                gpio5: Gpio5::steal(),
2072                gpio6: Gpio6::steal(),
2073                gpio7: Gpio7::steal(),
2074                gpio8: Gpio8::steal(),
2075                gpio9: Gpio9::steal(),
2076                gpio10: Gpio10::steal(),
2077                gpio11: Gpio11::steal(),
2078                gpio12: Gpio12::steal(),
2079                gpio13: Gpio13::steal(),
2080                gpio14: Gpio14::steal(),
2081                gpio15: Gpio15::steal(),
2082                gpio16: Gpio16::steal(),
2083                gpio17: Gpio17::steal(),
2084                gpio18: Gpio18::steal(),
2085                gpio19: Gpio19::steal(),
2086                gpio20: Gpio20::steal(),
2087            }
2088        }
2089    }
2090}
2091
2092#[cfg(any(esp32h2, esp32h4))]
2093mod chip {
2094    #[cfg(feature = "alloc")]
2095    extern crate alloc;
2096
2097    #[cfg(feature = "alloc")]
2098    use alloc::boxed::Box;
2099
2100    use crate::interrupt::asynch::HalIsrNotification;
2101
2102    use super::*;
2103
2104    #[allow(clippy::type_complexity)]
2105    #[cfg(feature = "alloc")]
2106    pub(crate) static mut PIN_ISR_HANDLER: [Option<Box<dyn FnMut() + Send + 'static>>; 28] =
2107        [PIN_ISR_INIT; 28];
2108
2109    pub(crate) static PIN_NOTIF: [HalIsrNotification; 28] = [PIN_NOTIF_INIT; 28];
2110
2111    // NOTE: Following pins have special meaning and are not recommended for other uses. But one may use them with care.
2112    //  - Gpio12 - Gpio17 are used by SPI0/SPI1 for external PSRAM/SPI Flash
2113    //  - Gpio21 seems not to be exposed physically
2114    //  - Gpio23 + Gpio24 are used by serial debug interface
2115    //  - Gpio26 + Gpio27 are used by USB debug interface
2116    pin!(Gpio0:0,   IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2117    pin!(Gpio1:1,   IO, NORTC:0,  ADC1:ADCCH0, NODAC:0, NOTOUCH:0);
2118    pin!(Gpio2:2,   IO, NORTC:0,  ADC1:ADCCH1, NODAC:0, NOTOUCH:0);
2119    pin!(Gpio3:3,   IO, NORTC:0,  ADC1:ADCCH2, NODAC:0, NOTOUCH:0);
2120    pin!(Gpio4:4,   IO, NORTC:0,  ADC1:ADCCH3, NODAC:0, NOTOUCH:0);
2121    pin!(Gpio5:5,   IO, NORTC:0,  ADC1:ADCCH4, NODAC:0, NOTOUCH:0);
2122    pin!(Gpio6:6,   IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2123    pin!(Gpio7:7,   IO,   RTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2124    pin!(Gpio8:8,   IO,   RTC:1, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2125    pin!(Gpio9:9,   IO,   RTC:2, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2126    pin!(Gpio10:10, IO,   RTC:3, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2127    pin!(Gpio11:11, IO,   RTC:4, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2128    pin!(Gpio12:12, IO,   RTC:5, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2129    pin!(Gpio13:13, IO,   RTC:6, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2130    pin!(Gpio14:14, IO,   RTC:7, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2131    pin!(Gpio15:15, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2132    pin!(Gpio16:16, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2133    pin!(Gpio17:17, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2134    pin!(Gpio18:18, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2135    pin!(Gpio19:19, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2136    pin!(Gpio20:20, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2137    pin!(Gpio21:21, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2138    pin!(Gpio22:22, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2139    pin!(Gpio23:23, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2140    pin!(Gpio24:24, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2141    pin!(Gpio25:25, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2142    pin!(Gpio26:26, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2143    pin!(Gpio27:27, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2144
2145    pub struct Pins {
2146        pub gpio0: Gpio0<'static>,
2147        pub gpio1: Gpio1<'static>,
2148        pub gpio2: Gpio2<'static>,
2149        pub gpio3: Gpio3<'static>,
2150        pub gpio4: Gpio4<'static>,
2151        pub gpio5: Gpio5<'static>,
2152        pub gpio6: Gpio6<'static>,
2153        pub gpio7: Gpio7<'static>,
2154        pub gpio8: Gpio8<'static>,
2155        pub gpio9: Gpio9<'static>,
2156        pub gpio10: Gpio10<'static>,
2157        pub gpio11: Gpio11<'static>,
2158        pub gpio12: Gpio12<'static>,
2159        pub gpio13: Gpio13<'static>,
2160        pub gpio14: Gpio14<'static>,
2161        pub gpio15: Gpio15<'static>,
2162        pub gpio16: Gpio16<'static>,
2163        pub gpio17: Gpio17<'static>,
2164        pub gpio18: Gpio18<'static>,
2165        pub gpio19: Gpio19<'static>,
2166        pub gpio20: Gpio20<'static>,
2167        pub gpio21: Gpio21<'static>,
2168        pub gpio22: Gpio22<'static>,
2169        pub gpio23: Gpio23<'static>,
2170        pub gpio24: Gpio24<'static>,
2171        pub gpio25: Gpio25<'static>,
2172        pub gpio26: Gpio26<'static>,
2173        pub gpio27: Gpio27<'static>,
2174    }
2175
2176    impl Pins {
2177        /// # Safety
2178        ///
2179        /// Care should be taken not to instantiate the Pins structure, if it is
2180        /// already instantiated and used elsewhere
2181        pub unsafe fn new() -> Self {
2182            Self {
2183                gpio0: Gpio0::steal(),
2184                gpio1: Gpio1::steal(),
2185                gpio2: Gpio2::steal(),
2186                gpio3: Gpio3::steal(),
2187                gpio4: Gpio4::steal(),
2188                gpio5: Gpio5::steal(),
2189                gpio6: Gpio6::steal(),
2190                gpio7: Gpio7::steal(),
2191                gpio8: Gpio8::steal(),
2192                gpio9: Gpio9::steal(),
2193                gpio10: Gpio10::steal(),
2194                gpio11: Gpio11::steal(),
2195                gpio12: Gpio12::steal(),
2196                gpio13: Gpio13::steal(),
2197                gpio14: Gpio14::steal(),
2198                gpio15: Gpio15::steal(),
2199                gpio16: Gpio16::steal(),
2200                gpio17: Gpio17::steal(),
2201                gpio18: Gpio18::steal(),
2202                gpio19: Gpio19::steal(),
2203                gpio20: Gpio20::steal(),
2204                gpio21: Gpio21::steal(),
2205                gpio22: Gpio22::steal(),
2206                gpio23: Gpio23::steal(),
2207                gpio24: Gpio24::steal(),
2208                gpio25: Gpio25::steal(),
2209                gpio26: Gpio26::steal(),
2210                gpio27: Gpio27::steal(),
2211            }
2212        }
2213    }
2214}
2215
2216#[cfg(esp32c5)]
2217mod chip {
2218    #[cfg(feature = "alloc")]
2219    extern crate alloc;
2220
2221    #[cfg(feature = "alloc")]
2222    use alloc::boxed::Box;
2223
2224    use crate::interrupt::asynch::HalIsrNotification;
2225
2226    use super::*;
2227
2228    #[allow(clippy::type_complexity)]
2229    #[cfg(feature = "alloc")]
2230    pub(crate) static mut PIN_ISR_HANDLER: [Option<Box<dyn FnMut() + Send + 'static>>; 29] =
2231        [PIN_ISR_INIT; 29];
2232
2233    #[allow(clippy::type_complexity)]
2234    pub(crate) static PIN_NOTIF: [HalIsrNotification; 29] = [PIN_NOTIF_INIT; 29];
2235
2236    // NOTE: Gpio26 - Gpio32 (and Gpio33 - Gpio37 if using Octal RAM/Flash) are used
2237    //       by SPI0/SPI1 for external PSRAM/SPI Flash and are not recommended for
2238    //       other uses
2239    pin!(Gpio0:0, IO, RTC:0, ADC1:ADCCH0, NODAC:0, NOTOUCH:0);
2240    pin!(Gpio1:1, IO, RTC:1, ADC1:ADCCH1, NODAC:0, NOTOUCH:0);
2241    pin!(Gpio2:2, IO, RTC:2, ADC1:ADCCH2, NODAC:0, NOTOUCH:0);
2242    pin!(Gpio3:3, IO, RTC:3, ADC1:ADCCH3, NODAC:0, NOTOUCH:0);
2243    pin!(Gpio4:4, IO, RTC:4, ADC1:ADCCH4, NODAC:0, NOTOUCH:0);
2244    pin!(Gpio5:5, IO, RTC:5, ADC1:ADCCH5, NODAC:0, NOTOUCH:0);
2245    pin!(Gpio6:6, IO, RTC:6, ADC1:ADCCH6, NODAC:0, NOTOUCH:0);
2246    pin!(Gpio7:7, IO, RTC:7, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2247    pin!(Gpio8:8, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2248    pin!(Gpio9:9, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2249    pin!(Gpio10:10, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2250    pin!(Gpio11:11, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2251    pin!(Gpio12:12, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2252    pin!(Gpio13:13, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2253    pin!(Gpio14:14, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2254    pin!(Gpio15:15, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2255    pin!(Gpio16:16, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2256    pin!(Gpio17:17, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2257    pin!(Gpio18:18, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2258    pin!(Gpio19:19, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2259    pin!(Gpio20:20, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2260    pin!(Gpio21:21, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2261    pin!(Gpio22:22, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2262    pin!(Gpio23:23, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2263    pin!(Gpio24:24, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2264    pin!(Gpio25:25, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2265    pin!(Gpio26:26, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2266    pin!(Gpio27:27, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2267    pin!(Gpio28:28, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2268
2269    pub struct Pins {
2270        pub gpio0: Gpio0<'static>,
2271        pub gpio1: Gpio1<'static>,
2272        pub gpio2: Gpio2<'static>,
2273        pub gpio3: Gpio3<'static>,
2274        pub gpio4: Gpio4<'static>,
2275        pub gpio5: Gpio5<'static>,
2276        pub gpio6: Gpio6<'static>,
2277        pub gpio7: Gpio7<'static>,
2278        pub gpio8: Gpio8<'static>,
2279        pub gpio9: Gpio9<'static>,
2280        pub gpio10: Gpio10<'static>,
2281        pub gpio11: Gpio11<'static>,
2282        pub gpio12: Gpio12<'static>,
2283        pub gpio13: Gpio13<'static>,
2284        pub gpio14: Gpio14<'static>,
2285        pub gpio15: Gpio15<'static>,
2286        pub gpio16: Gpio16<'static>,
2287        pub gpio17: Gpio17<'static>,
2288        pub gpio18: Gpio18<'static>,
2289        pub gpio19: Gpio19<'static>,
2290        pub gpio20: Gpio20<'static>,
2291        pub gpio21: Gpio21<'static>,
2292        pub gpio22: Gpio22<'static>,
2293        pub gpio23: Gpio23<'static>,
2294        pub gpio24: Gpio24<'static>,
2295        pub gpio25: Gpio25<'static>,
2296        pub gpio26: Gpio26<'static>,
2297        pub gpio27: Gpio27<'static>,
2298        pub gpio28: Gpio28<'static>,
2299    }
2300
2301    impl Pins {
2302        /// # Safety
2303        ///
2304        /// Care should be taken not to instantiate the Pins structure, if it is
2305        /// already instantiated and used elsewhere
2306        pub unsafe fn new() -> Self {
2307            Self {
2308                gpio0: Gpio0::steal(),
2309                gpio1: Gpio1::steal(),
2310                gpio2: Gpio2::steal(),
2311                gpio3: Gpio3::steal(),
2312                gpio4: Gpio4::steal(),
2313                gpio5: Gpio5::steal(),
2314                gpio6: Gpio6::steal(),
2315                gpio7: Gpio7::steal(),
2316                gpio8: Gpio8::steal(),
2317                gpio9: Gpio9::steal(),
2318                gpio10: Gpio10::steal(),
2319                gpio11: Gpio11::steal(),
2320                gpio12: Gpio12::steal(),
2321                gpio13: Gpio13::steal(),
2322                gpio14: Gpio14::steal(),
2323                gpio15: Gpio15::steal(),
2324                gpio16: Gpio16::steal(),
2325                gpio17: Gpio17::steal(),
2326                gpio18: Gpio18::steal(),
2327                gpio19: Gpio19::steal(),
2328                gpio20: Gpio20::steal(),
2329                gpio21: Gpio21::steal(),
2330                gpio22: Gpio22::steal(),
2331                gpio23: Gpio23::steal(),
2332                gpio24: Gpio24::steal(),
2333                gpio25: Gpio25::steal(),
2334                gpio26: Gpio26::steal(),
2335                gpio27: Gpio27::steal(),
2336                gpio28: Gpio28::steal(),
2337            }
2338        }
2339    }
2340}
2341
2342#[cfg(esp32c6)]
2343mod chip {
2344    // TODO: Implement esp32c6 glitch filters
2345
2346    #[cfg(feature = "alloc")]
2347    extern crate alloc;
2348
2349    #[cfg(feature = "alloc")]
2350    use alloc::boxed::Box;
2351
2352    use crate::interrupt::asynch::HalIsrNotification;
2353
2354    use super::*;
2355
2356    #[allow(clippy::type_complexity)]
2357    #[cfg(feature = "alloc")]
2358    pub(crate) static mut PIN_ISR_HANDLER: [Option<Box<dyn FnMut() + Send + 'static>>; 31] =
2359        [PIN_ISR_INIT; 31];
2360
2361    #[allow(clippy::type_complexity)]
2362    pub(crate) static PIN_NOTIF: [HalIsrNotification; 31] = [PIN_NOTIF_INIT; 31];
2363
2364    pin!(Gpio0:0, IO, RTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2365    pin!(Gpio1:1, IO, RTC:1, ADC1:ADCCH0, NODAC:0, NOTOUCH:0);
2366    pin!(Gpio2:2, IO, RTC:2, ADC1:ADCCH1, NODAC:0, NOTOUCH:0);
2367    pin!(Gpio3:3, IO, RTC:3, ADC1:ADCCH2, NODAC:0, NOTOUCH:0);
2368    pin!(Gpio4:4, IO, RTC:4, ADC1:ADCCH3, NODAC:0, NOTOUCH:0);
2369    pin!(Gpio5:5, IO, RTC:5, ADC1:ADCCH4, NODAC:0, NOTOUCH:0);
2370    pin!(Gpio6:6, IO, RTC:6, ADC1:ADCCH5, NODAC:0, NOTOUCH:0);
2371    pin!(Gpio7:7, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2372    pin!(Gpio8:8, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2373    pin!(Gpio9:9, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2374    pin!(Gpio10:10, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2375    pin!(Gpio11:11, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2376    pin!(Gpio12:12, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2377    pin!(Gpio13:13, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2378    pin!(Gpio14:14, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2379    pin!(Gpio15:15, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2380    pin!(Gpio16:16, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2381    pin!(Gpio17:17, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2382    pin!(Gpio18:18, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2383    pin!(Gpio19:19, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2384    pin!(Gpio20:20, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2385    pin!(Gpio21:21, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2386    pin!(Gpio22:22, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2387    pin!(Gpio23:23, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2388    pin!(Gpio24:24, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2389    pin!(Gpio25:25, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2390    pin!(Gpio26:26, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2391    pin!(Gpio27:27, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2392    pin!(Gpio28:28, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2393    pin!(Gpio29:29, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2394    pin!(Gpio30:30, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2395
2396    pub struct Pins {
2397        pub gpio0: Gpio0<'static>,
2398        pub gpio1: Gpio1<'static>,
2399        pub gpio2: Gpio2<'static>,
2400        pub gpio3: Gpio3<'static>,
2401        pub gpio4: Gpio4<'static>,
2402        pub gpio5: Gpio5<'static>,
2403        pub gpio6: Gpio6<'static>,
2404        pub gpio7: Gpio7<'static>,
2405        pub gpio8: Gpio8<'static>,
2406        pub gpio9: Gpio9<'static>,
2407        pub gpio10: Gpio10<'static>,
2408        pub gpio11: Gpio11<'static>,
2409        pub gpio12: Gpio12<'static>,
2410        pub gpio13: Gpio13<'static>,
2411        pub gpio14: Gpio14<'static>,
2412        pub gpio15: Gpio15<'static>,
2413        pub gpio16: Gpio16<'static>,
2414        pub gpio17: Gpio17<'static>,
2415        pub gpio18: Gpio18<'static>,
2416        pub gpio19: Gpio19<'static>,
2417        pub gpio20: Gpio20<'static>,
2418        pub gpio21: Gpio21<'static>,
2419        pub gpio22: Gpio22<'static>,
2420        pub gpio23: Gpio23<'static>,
2421        pub gpio24: Gpio24<'static>,
2422        pub gpio25: Gpio25<'static>,
2423        pub gpio26: Gpio26<'static>,
2424        pub gpio27: Gpio27<'static>,
2425        pub gpio28: Gpio28<'static>,
2426        pub gpio29: Gpio29<'static>,
2427        pub gpio30: Gpio30<'static>,
2428    }
2429
2430    impl Pins {
2431        /// # Safety
2432        ///
2433        /// Care should be taken not to instantiate the Pins structure, if it is
2434        /// already instantiated and used elsewhere
2435        pub unsafe fn new() -> Self {
2436            Self {
2437                gpio0: Gpio0::steal(),
2438                gpio1: Gpio1::steal(),
2439                gpio2: Gpio2::steal(),
2440                gpio3: Gpio3::steal(),
2441                gpio4: Gpio4::steal(),
2442                gpio5: Gpio5::steal(),
2443                gpio6: Gpio6::steal(),
2444                gpio7: Gpio7::steal(),
2445                gpio8: Gpio8::steal(),
2446                gpio9: Gpio9::steal(),
2447                gpio10: Gpio10::steal(),
2448                gpio11: Gpio11::steal(),
2449                gpio12: Gpio12::steal(),
2450                gpio13: Gpio13::steal(),
2451                gpio14: Gpio14::steal(),
2452                gpio15: Gpio15::steal(),
2453                gpio16: Gpio16::steal(),
2454                gpio17: Gpio17::steal(),
2455                gpio18: Gpio18::steal(),
2456                gpio19: Gpio19::steal(),
2457                gpio20: Gpio20::steal(),
2458                gpio21: Gpio21::steal(),
2459                gpio22: Gpio22::steal(),
2460                gpio23: Gpio23::steal(),
2461                gpio24: Gpio24::steal(),
2462                gpio25: Gpio25::steal(),
2463                gpio26: Gpio26::steal(),
2464                gpio27: Gpio27::steal(),
2465                gpio28: Gpio28::steal(),
2466                gpio29: Gpio29::steal(),
2467                gpio30: Gpio30::steal(),
2468            }
2469        }
2470    }
2471}
2472
2473#[cfg(esp32c61)]
2474mod chip {
2475    #[cfg(feature = "alloc")]
2476    extern crate alloc;
2477
2478    #[cfg(feature = "alloc")]
2479    use alloc::boxed::Box;
2480
2481    use crate::interrupt::asynch::HalIsrNotification;
2482
2483    use super::*;
2484
2485    #[allow(clippy::type_complexity)]
2486    #[cfg(feature = "alloc")]
2487    pub(crate) static mut PIN_ISR_HANDLER: [Option<Box<dyn FnMut() + Send + 'static>>; 30] =
2488        [PIN_ISR_INIT; 30];
2489
2490    #[allow(clippy::type_complexity)]
2491    pub(crate) static PIN_NOTIF: [HalIsrNotification; 30] = [PIN_NOTIF_INIT; 30];
2492
2493    pin!(Gpio0:0, IO, RTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2494    pin!(Gpio1:1, IO, RTC:1, ADC1:ADCCH0, NODAC:0, NOTOUCH:0);
2495    pin!(Gpio2:2, IO, RTC:2, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2496    pin!(Gpio3:3, IO, RTC:3, ADC1:ADCCH1, NODAC:0, NOTOUCH:0);
2497    pin!(Gpio4:4, IO, RTC:4, ADC1:ADCCH2, NODAC:0, NOTOUCH:0);
2498    pin!(Gpio5:5, IO, RTC:5, ADC1:ADCCH3, NODAC:0, NOTOUCH:0);
2499    pin!(Gpio6:6, IO, RTC:6, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2500    pin!(Gpio7:7, IO, RTC:7, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2501    pin!(Gpio8:8, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2502    pin!(Gpio9:9, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2503    pin!(Gpio10:10, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2504    pin!(Gpio11:11, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2505    pin!(Gpio12:12, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2506    pin!(Gpio13:13, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2507    pin!(Gpio14:14, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2508    pin!(Gpio15:15, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2509    pin!(Gpio16:16, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2510    pin!(Gpio17:17, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2511    pin!(Gpio18:18, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2512    pin!(Gpio19:19, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2513    pin!(Gpio20:20, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2514    pin!(Gpio21:21, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2515    pin!(Gpio22:22, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2516    pin!(Gpio23:23, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2517    pin!(Gpio24:24, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2518    pin!(Gpio25:25, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2519    pin!(Gpio26:26, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2520    pin!(Gpio27:27, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2521    pin!(Gpio28:28, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2522    pin!(Gpio29:29, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2523
2524    pub struct Pins {
2525        pub gpio0: Gpio0<'static>,
2526        pub gpio1: Gpio1<'static>,
2527        pub gpio2: Gpio2<'static>,
2528        pub gpio3: Gpio3<'static>,
2529        pub gpio4: Gpio4<'static>,
2530        pub gpio5: Gpio5<'static>,
2531        pub gpio6: Gpio6<'static>,
2532        pub gpio7: Gpio7<'static>,
2533        pub gpio8: Gpio8<'static>,
2534        pub gpio9: Gpio9<'static>,
2535        pub gpio10: Gpio10<'static>,
2536        pub gpio11: Gpio11<'static>,
2537        pub gpio12: Gpio12<'static>,
2538        pub gpio13: Gpio13<'static>,
2539        pub gpio14: Gpio14<'static>,
2540        pub gpio15: Gpio15<'static>,
2541        pub gpio16: Gpio16<'static>,
2542        pub gpio17: Gpio17<'static>,
2543        pub gpio18: Gpio18<'static>,
2544        pub gpio19: Gpio19<'static>,
2545        pub gpio20: Gpio20<'static>,
2546        pub gpio21: Gpio21<'static>,
2547        pub gpio22: Gpio22<'static>,
2548        pub gpio23: Gpio23<'static>,
2549        pub gpio24: Gpio24<'static>,
2550        pub gpio25: Gpio25<'static>,
2551        pub gpio26: Gpio26<'static>,
2552        pub gpio27: Gpio27<'static>,
2553        pub gpio28: Gpio28<'static>,
2554        pub gpio29: Gpio29<'static>,
2555    }
2556
2557    impl Pins {
2558        /// # Safety
2559        ///
2560        /// Care should be taken not to instantiate the Pins structure, if it is
2561        /// already instantiated and used elsewhere
2562        pub unsafe fn new() -> Self {
2563            Self {
2564                gpio0: Gpio0::steal(),
2565                gpio1: Gpio1::steal(),
2566                gpio2: Gpio2::steal(),
2567                gpio3: Gpio3::steal(),
2568                gpio4: Gpio4::steal(),
2569                gpio5: Gpio5::steal(),
2570                gpio6: Gpio6::steal(),
2571                gpio7: Gpio7::steal(),
2572                gpio8: Gpio8::steal(),
2573                gpio9: Gpio9::steal(),
2574                gpio10: Gpio10::steal(),
2575                gpio11: Gpio11::steal(),
2576                gpio12: Gpio12::steal(),
2577                gpio13: Gpio13::steal(),
2578                gpio14: Gpio14::steal(),
2579                gpio15: Gpio15::steal(),
2580                gpio16: Gpio16::steal(),
2581                gpio17: Gpio17::steal(),
2582                gpio18: Gpio18::steal(),
2583                gpio19: Gpio19::steal(),
2584                gpio20: Gpio20::steal(),
2585                gpio21: Gpio21::steal(),
2586                gpio22: Gpio22::steal(),
2587                gpio23: Gpio23::steal(),
2588                gpio24: Gpio24::steal(),
2589                gpio25: Gpio25::steal(),
2590                gpio26: Gpio26::steal(),
2591                gpio27: Gpio27::steal(),
2592                gpio28: Gpio28::steal(),
2593                gpio29: Gpio29::steal(),
2594            }
2595        }
2596    }
2597}
2598
2599#[cfg(esp32p4)]
2600mod chip {
2601    #[cfg(feature = "alloc")]
2602    extern crate alloc;
2603
2604    #[cfg(feature = "alloc")]
2605    use alloc::boxed::Box;
2606
2607    use crate::interrupt::asynch::HalIsrNotification;
2608
2609    use super::*;
2610
2611    #[allow(clippy::type_complexity)]
2612    #[cfg(feature = "alloc")]
2613    pub(crate) static mut PIN_ISR_HANDLER: [Option<Box<dyn FnMut() + Send + 'static>>; 54] =
2614        [PIN_ISR_INIT; 54];
2615
2616    #[allow(clippy::type_complexity)]
2617    pub(crate) static PIN_NOTIF: [HalIsrNotification; 54] = [PIN_NOTIF_INIT; 54];
2618
2619    pin!(Gpio0:0, IO, RTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2620    pin!(Gpio1:1, IO, RTC:1, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2621    pin!(Gpio2:2, IO, RTC:2, NOADC:NOADC, NODAC:0, TOUCH:0);
2622    pin!(Gpio3:3, IO, RTC:3, NOADC:NOADC, NODAC:0, TOUCH:1);
2623    pin!(Gpio4:4, IO, RTC:4, NOADC:NOADC, NODAC:0, TOUCH:2);
2624    pin!(Gpio5:5, IO, RTC:5, NOADC:NOADC, NODAC:0, TOUCH:3);
2625    pin!(Gpio6:6, IO, RTC:6, NOADC:NOADC, NODAC:0, TOUCH:4);
2626    pin!(Gpio7:7, IO, RTC:7, NOADC:NOADC, NODAC:0, TOUCH:5);
2627    pin!(Gpio8:8, IO, RTC:8, NOADC:NOADC, NODAC:0, TOUCH:6);
2628    pin!(Gpio9:9, IO, RTC:9, NOADC:NOADC, NODAC:0, TOUCH:7);
2629
2630    pin!(Gpio10:10, IO, RTC:10, NOADC:NOADC, NODAC:0, TOUCH:8);
2631    pin!(Gpio11:11, IO, RTC:11, NOADC:NOADC, NODAC:0, TOUCH:9);
2632    pin!(Gpio12:12, IO, RTC:12, NOADC:NOADC, NODAC:0, TOUCH:10);
2633    pin!(Gpio13:13, IO, RTC:13, NOADC:NOADC, NODAC:0, TOUCH:11);
2634    pin!(Gpio14:14, IO, RTC:14, NOADC:NOADC, NODAC:0, TOUCH:12);
2635    pin!(Gpio15:15, IO, RTC:15, NOADC:NOADC, NODAC:0, TOUCH:13);
2636    pin!(Gpio16:16, IO, NORTC:0, ADC1:ADCCH0, NODAC:0, NOTOUCH:0);
2637    pin!(Gpio17:17, IO, NORTC:0, ADC1:ADCCH1, NODAC:0, NOTOUCH:0);
2638    pin!(Gpio18:18, IO, NORTC:0, ADC1:ADCCH2, NODAC:0, NOTOUCH:0);
2639    pin!(Gpio19:19, IO, NORTC:0, ADC1:ADCCH3, NODAC:0, NOTOUCH:0);
2640
2641    pin!(Gpio20:20, IO, NORTC:0, ADC1:ADCCH4, NODAC:0, NOTOUCH:0);
2642    pin!(Gpio21:21, IO, NORTC:0, ADC1:ADCCH5, NODAC:0, NOTOUCH:0);
2643    pin!(Gpio22:22, IO, NORTC:0, ADC1:ADCCH6, NODAC:0, NOTOUCH:0);
2644    pin!(Gpio23:23, IO, NORTC:0, ADC1:ADCCH7, NODAC:0, NOTOUCH:0);
2645    pin!(Gpio24:24, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2646    pin!(Gpio25:25, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2647    pin!(Gpio26:26, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2648    pin!(Gpio27:27, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2649    pin!(Gpio28:28, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2650    pin!(Gpio29:29, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2651
2652    pin!(Gpio30:30, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2653    pin!(Gpio31:31, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2654    pin!(Gpio32:32, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2655    pin!(Gpio33:33, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2656    pin!(Gpio34:34, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2657    pin!(Gpio35:35, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2658    pin!(Gpio36:36, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2659    pin!(Gpio37:37, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2660    pin!(Gpio38:38, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2661    pin!(Gpio39:39, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2662
2663    pin!(Gpio40:40, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2664    pin!(Gpio41:41, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2665    pin!(Gpio42:42, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2666    pin!(Gpio43:43, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2667    pin!(Gpio44:44, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2668    pin!(Gpio45:45, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2669    pin!(Gpio46:46, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2670    pin!(Gpio47:47, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2671    pin!(Gpio48:48, IO, NORTC:0, NOADC:NOADC, NODAC:0, NOTOUCH:0);
2672    pin!(Gpio49:49, IO, NORTC:0, ADC2:ADCCH0, NODAC:0, NOTOUCH:0);
2673
2674    pin!(Gpio50:50, IO, NORTC:0, ADC2:ADCCH1, NODAC:0, NOTOUCH:0);
2675    pin!(Gpio51:51, IO, NORTC:0, ADC2:ADCCH2, NODAC:0, NOTOUCH:0);
2676    pin!(Gpio52:52, IO, NORTC:0, ADC2:ADCCH3, NODAC:0, NOTOUCH:0);
2677    pin!(Gpio53:53, IO, NORTC:0, ADC2:ADCCH4, NODAC:0, NOTOUCH:0);
2678    pin!(Gpio54:54, IO, NORTC:0, ADC2:ADCCH5, NODAC:0, NOTOUCH:0);
2679
2680    pub struct Pins {
2681        pub gpio0: Gpio0<'static>,
2682        pub gpio1: Gpio1<'static>,
2683        pub gpio2: Gpio2<'static>,
2684        pub gpio3: Gpio3<'static>,
2685        pub gpio4: Gpio4<'static>,
2686        pub gpio5: Gpio5<'static>,
2687        pub gpio6: Gpio6<'static>,
2688        pub gpio7: Gpio7<'static>,
2689        pub gpio8: Gpio8<'static>,
2690        pub gpio9: Gpio9<'static>,
2691
2692        pub gpio10: Gpio10<'static>,
2693        pub gpio11: Gpio11<'static>,
2694        pub gpio12: Gpio12<'static>,
2695        pub gpio13: Gpio13<'static>,
2696        pub gpio14: Gpio14<'static>,
2697        pub gpio15: Gpio15<'static>,
2698        pub gpio16: Gpio16<'static>,
2699        pub gpio17: Gpio17<'static>,
2700        pub gpio18: Gpio18<'static>,
2701        pub gpio19: Gpio19<'static>,
2702
2703        pub gpio20: Gpio20<'static>,
2704        pub gpio21: Gpio21<'static>,
2705        pub gpio22: Gpio22<'static>,
2706        pub gpio23: Gpio23<'static>,
2707        pub gpio24: Gpio24<'static>,
2708        pub gpio25: Gpio25<'static>,
2709        pub gpio26: Gpio26<'static>,
2710        pub gpio27: Gpio27<'static>,
2711        pub gpio28: Gpio28<'static>,
2712        pub gpio29: Gpio29<'static>,
2713
2714        pub gpio30: Gpio30<'static>,
2715        pub gpio31: Gpio31<'static>,
2716        pub gpio32: Gpio32<'static>,
2717        pub gpio33: Gpio33<'static>,
2718        pub gpio34: Gpio34<'static>,
2719        pub gpio35: Gpio35<'static>,
2720        pub gpio36: Gpio36<'static>,
2721        pub gpio37: Gpio37<'static>,
2722        pub gpio38: Gpio38<'static>,
2723        pub gpio39: Gpio39<'static>,
2724
2725        pub gpio40: Gpio40<'static>,
2726        pub gpio41: Gpio41<'static>,
2727        pub gpio42: Gpio42<'static>,
2728        pub gpio43: Gpio43<'static>,
2729        pub gpio44: Gpio44<'static>,
2730        pub gpio45: Gpio45<'static>,
2731        pub gpio46: Gpio46<'static>,
2732        pub gpio47: Gpio47<'static>,
2733        pub gpio48: Gpio48<'static>,
2734        pub gpio49: Gpio49<'static>,
2735
2736        pub gpio50: Gpio50<'static>,
2737        pub gpio51: Gpio51<'static>,
2738        pub gpio52: Gpio52<'static>,
2739        pub gpio53: Gpio53<'static>,
2740        pub gpio54: Gpio54<'static>,
2741    }
2742
2743    impl Pins {
2744        /// # Safety
2745        ///
2746        /// Care should be taken not to instantiate the Pins structure, if it is
2747        /// already instantiated and used elsewhere
2748        pub unsafe fn new() -> Self {
2749            Self {
2750                gpio0: Gpio0::steal(),
2751                gpio1: Gpio1::steal(),
2752                gpio2: Gpio2::steal(),
2753                gpio3: Gpio3::steal(),
2754                gpio4: Gpio4::steal(),
2755                gpio5: Gpio5::steal(),
2756                gpio6: Gpio6::steal(),
2757                gpio7: Gpio7::steal(),
2758                gpio8: Gpio8::steal(),
2759                gpio9: Gpio9::steal(),
2760
2761                gpio10: Gpio10::steal(),
2762                gpio11: Gpio11::steal(),
2763                gpio12: Gpio12::steal(),
2764                gpio13: Gpio13::steal(),
2765                gpio14: Gpio14::steal(),
2766                gpio15: Gpio15::steal(),
2767                gpio16: Gpio16::steal(),
2768                gpio17: Gpio17::steal(),
2769                gpio18: Gpio18::steal(),
2770                gpio19: Gpio19::steal(),
2771
2772                gpio20: Gpio20::steal(),
2773                gpio21: Gpio21::steal(),
2774                gpio22: Gpio22::steal(),
2775                gpio23: Gpio23::steal(),
2776                gpio24: Gpio24::steal(),
2777                gpio25: Gpio25::steal(),
2778                gpio26: Gpio26::steal(),
2779                gpio27: Gpio27::steal(),
2780                gpio28: Gpio28::steal(),
2781                gpio29: Gpio29::steal(),
2782
2783                gpio30: Gpio30::steal(),
2784                gpio31: Gpio31::steal(),
2785                gpio32: Gpio32::steal(),
2786                gpio33: Gpio33::steal(),
2787                gpio34: Gpio34::steal(),
2788                gpio35: Gpio35::steal(),
2789                gpio36: Gpio36::steal(),
2790                gpio37: Gpio37::steal(),
2791                gpio38: Gpio38::steal(),
2792                gpio39: Gpio39::steal(),
2793
2794                gpio40: Gpio40::steal(),
2795                gpio41: Gpio41::steal(),
2796                gpio42: Gpio42::steal(),
2797                gpio43: Gpio43::steal(),
2798                gpio44: Gpio44::steal(),
2799                gpio45: Gpio45::steal(),
2800                gpio46: Gpio46::steal(),
2801                gpio47: Gpio47::steal(),
2802                gpio48: Gpio48::steal(),
2803                gpio49: Gpio49::steal(),
2804
2805                gpio50: Gpio50::steal(),
2806                gpio51: Gpio51::steal(),
2807                gpio52: Gpio52::steal(),
2808                gpio53: Gpio53::steal(),
2809                gpio54: Gpio54::steal(),
2810            }
2811        }
2812    }
2813}