esp_hal/soc/esp32c2/
gpio.rs

1//! # GPIO configuration module (ESP32-C2)
2//!
3//! ## Overview
4//!
5//! The `GPIO` module provides functions and configurations for controlling the
6//! `General Purpose Input/Output` pins on the `ESP32-C2` chip. It allows you to
7//! configure pins as inputs or outputs, set their state and read their state.
8//!
9//! Let's get through the functionality and configurations provided by this GPIO
10//! module:
11//!   - `io_mux_reg(gpio_num: u8) -> &'static crate::peripherals::io_mux::GPIO`:
12//!       * Returns the IO_MUX register for the specified GPIO pin number.
13//!   - `gpio_intr_enable(int_enable: bool, nmi_enable: bool) -> u8`:
14//!       * This function enables or disables GPIO interrupts and Non-Maskable
15//!         Interrupts (NMI). It takes two boolean arguments int_enable and
16//!         nmi_enable to control the interrupt and NMI enable settings. The
17//!         function returns an u8 value representing the interrupt enable
18//!         settings.
19//!   - `gpio` block:
20//!       * Defines the pin configurations for various GPIO pins. Each line
21//!         represents a pin and its associated options such as input/output
22//!         mode, analog capability, and corresponding functions.
23//!   - `analog` block:
24//!       * Block defines the analog capabilities of various GPIO pins. Each
25//!         line represents a pin and its associated options such as mux
26//!         selection, function selection, and input enable.
27//!   - `enum InputSignal`:
28//!       * This enumeration defines input signals for the GPIO mux. Each input
29//!         signal is assigned a specific value.
30//!   - `enum OutputSignal`:
31//!       * This enumeration defines output signals for the GPIO mux. Each
32//!         output signal is assigned a specific value.
33//!
34//! This trait provides functions to read the interrupt status and NMI status
35//! registers for both the `PRO CPU` and `APP CPU`. The implementation uses the
36//! `gpio` peripheral to access the appropriate registers.
37use crate::{
38    gpio::{AlternateFunction, GpioPin},
39    pac::io_mux,
40    peripherals::{GPIO, IO_MUX},
41};
42
43/// The total number of GPIO pins available.
44pub const NUM_PINS: usize = 21;
45
46pub(crate) const FUNC_IN_SEL_OFFSET: usize = 0;
47
48pub(crate) type InputSignalType = u8;
49pub(crate) type OutputSignalType = u8;
50pub(crate) const OUTPUT_SIGNAL_MAX: u8 = 128;
51pub(crate) const INPUT_SIGNAL_MAX: u8 = 100;
52
53pub(crate) const ONE_INPUT: u8 = 0x1e;
54pub(crate) const ZERO_INPUT: u8 = 0x1f;
55
56pub(crate) const GPIO_FUNCTION: AlternateFunction = AlternateFunction::_1;
57
58pub(crate) fn io_mux_reg(gpio_num: u8) -> &'static io_mux::GPIO {
59    IO_MUX::regs().gpio(gpio_num as usize)
60}
61
62pub(crate) fn gpio_intr_enable(int_enable: bool, nmi_enable: bool) -> u8 {
63    int_enable as u8 | ((nmi_enable as u8) << 1)
64}
65
66/// Peripheral input signals for the GPIO mux
67#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
68#[derive(Debug, PartialEq, Copy, Clone)]
69#[cfg_attr(feature = "defmt", derive(defmt::Format))]
70#[doc(hidden)]
71pub enum InputSignal {
72    SPIQ          = 0,
73    SPID          = 1,
74    SPIHD         = 2,
75    SPIWP         = 3,
76    U0RXD         = 6,
77    U0CTS         = 7,
78    U0DSR         = 8,
79    U1RXD         = 9,
80    U1CTS         = 10,
81    U1DSR         = 11,
82    CPU_GPIO_0    = 28,
83    CPU_GPIO_1    = 29,
84    CPU_GPIO_2    = 30,
85    CPU_GPIO_3    = 31,
86    CPU_GPIO_4    = 32,
87    CPU_GPIO_5    = 33,
88    CPU_GPIO_6    = 34,
89    CPU_GPIO_7    = 35,
90    EXT_ADC_START = 45,
91    RMT_SIG_0     = 51,
92    RMT_SIG_1     = 52,
93    I2CEXT0_SCL   = 53,
94    I2CEXT0_SDA   = 54,
95    FSPICLK       = 63,
96    FSPIQ         = 64,
97    FSPID         = 65,
98    FSPIHD        = 66,
99    FSPIWP        = 67,
100    FSPICS0       = 68,
101    SIG_FUNC_97   = 97,
102    SIG_FUNC_98   = 98,
103    SIG_FUNC_99   = 99,
104    SIG_FUNC_100  = 100,
105}
106
107/// Peripheral output signals for the GPIO mux
108#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
109#[derive(Debug, PartialEq, Copy, Clone)]
110#[cfg_attr(feature = "defmt", derive(defmt::Format))]
111#[doc(hidden)]
112pub enum OutputSignal {
113    SPIQ          = 0,
114    SPID          = 1,
115    SPIHD         = 2,
116    SPIWP         = 3,
117    SPICLK_MUX    = 4,
118    SPICS0        = 5,
119    U0TXD         = 6,
120    U0RTS         = 7,
121    U0DTR         = 8,
122    U1TXD         = 9,
123    U1RTS         = 10,
124    U1DTR         = 11,
125    SPIQ_MONITOR  = 15,
126    SPID_MONITOR  = 16,
127    SPIHD_MONITOR = 17,
128    SPIWP_MONITOR = 18,
129    SPICS1        = 19,
130    CPU_GPIO_0    = 28,
131    CPU_GPIO_1    = 29,
132    CPU_GPIO_2    = 30,
133    CPU_GPIO_3    = 31,
134    CPU_GPIO_4    = 32,
135    CPU_GPIO_5    = 33,
136    CPU_GPIO_6    = 34,
137    CPU_GPIO_7    = 35,
138    LEDC_LS_SIG0  = 45,
139    LEDC_LS_SIG1  = 46,
140    LEDC_LS_SIG2  = 47,
141    LEDC_LS_SIG3  = 48,
142    LEDC_LS_SIG4  = 49,
143    LEDC_LS_SIG5  = 50,
144    RMT_SIG_0     = 51,
145    RMT_SIG_1     = 52,
146    I2CEXT0_SCL   = 53,
147    I2CEXT0_SDA   = 54,
148    FSPICLK_MUX   = 63,
149    FSPIQ         = 64,
150    FSPID         = 65,
151    FSPIHD        = 66,
152    FSPIWP        = 67,
153    FSPICS0       = 68,
154    FSPICS1       = 69,
155    FSPICS3       = 70,
156    FSPICS2       = 71,
157    FSPICS4       = 72,
158    FSPICS5       = 73,
159    ANT_SEL0      = 89,
160    ANT_SEL1      = 90,
161    ANT_SEL2      = 91,
162    ANT_SEL3      = 92,
163    ANT_SEL4      = 93,
164    ANT_SEL5      = 94,
165    ANT_SEL6      = 95,
166    ANT_SEL7      = 96,
167    SIG_FUNC_97   = 97,
168    SIG_FUNC_98   = 98,
169    SIG_FUNC_99   = 99,
170    SIG_FUNC_100  = 100,
171    CLK_OUT1      = 123,
172    CLK_OUT2      = 124,
173    CLK_OUT3      = 125,
174    GPIO          = 128,
175}
176
177macro_rules! rtc_pins {
178    ( $( $pin_num:expr )+ ) => {
179        $(
180            impl $crate::gpio::RtcPin for GpioPin<$pin_num> {
181                unsafe fn apply_wakeup(&self, wakeup: bool, level: u8) {
182                    let gpio_wakeup = $crate::peripherals::LPWR::regs().cntl_gpio_wakeup();
183                    paste::paste! {
184                        gpio_wakeup.modify(|_, w| w.[< gpio_pin $pin_num _wakeup_enable >]().bit(wakeup));
185                        gpio_wakeup.modify(|_, w| w.[< gpio_pin $pin_num _int_type >]().bits(level));
186                    }
187                }
188
189                fn rtcio_pad_hold(&self, enable: bool) {
190                    paste::paste! {
191                        $crate::peripherals::LPWR::regs()
192                            .pad_hold().modify(|_, w| w.[< gpio_pin $pin_num _hold >]().bit(enable));
193                    }
194                }
195            }
196        )+
197    };
198}
199
200impl<const N: u8> crate::gpio::RtcPinWithResistors for GpioPin<N>
201where
202    Self: crate::gpio::RtcPin,
203{
204    fn rtcio_pullup(&self, enable: bool) {
205        IO_MUX::regs()
206            .gpio(N as usize)
207            .modify(|_, w| w.fun_wpu().bit(enable));
208    }
209
210    fn rtcio_pulldown(&self, enable: bool) {
211        IO_MUX::regs()
212            .gpio(N as usize)
213            .modify(|_, w| w.fun_wpd().bit(enable));
214    }
215}
216
217rtc_pins! {
218    0
219    1
220    2
221    3
222    4
223    5
224}
225
226#[derive(Clone, Copy)]
227pub(crate) enum InterruptStatusRegisterAccess {
228    Bank0,
229}
230
231impl InterruptStatusRegisterAccess {
232    pub(crate) fn interrupt_status_read(self) -> u32 {
233        GPIO::regs().pcpu_int().read().bits()
234    }
235}