435 lines
16 KiB
Rust
435 lines
16 KiB
Rust
//! # GPIO configuration module (ESP32-S2)
|
|
//!
|
|
//! ## Overview
|
|
//!
|
|
//! The `GPIO` module provides functions and configurations for controlling the
|
|
//! `General Purpose Input/Output` pins on the `ESP32-S2` chip. It allows you to
|
|
//! configure pins as inputs or outputs, set their state and read their state.
|
|
//!
|
|
//! Let's get through the functionality and configurations provided by this GPIO
|
|
//! module:
|
|
//! - `get_io_mux_reg(gpio_num: u8) -> &'static
|
|
//! crate::peripherals::io_mux::GPIO0:`:
|
|
//! * This function returns a reference to the GPIO register associated
|
|
//! with the given GPIO number. It uses unsafe code and transmutation to
|
|
//! access the GPIO registers based on the provided GPIO number.
|
|
//! - `gpio_intr_enable(int_enable: bool, nmi_enable: bool) -> u8`:
|
|
//! * This function enables or disables GPIO interrupts and Non-Maskable
|
|
//! Interrupts (NMI). It takes two boolean arguments int_enable and
|
|
//! nmi_enable to control the interrupt and NMI enable settings. The
|
|
//! function returns an u8 value representing the interrupt enable
|
|
//! settings.
|
|
//! - `impl_get_rtc_pad`:
|
|
//! * This macro_rule generates a function to get a specific RTC pad. It
|
|
//! takes a single argument `$pad_name`, which is an identifier
|
|
//! representing the name of the pad. Returns a reference to the
|
|
//! corresponding RTC pad.
|
|
//! - `impl_get_rtc_pad_indexed`:
|
|
//! * This macro_rule generates a function similar to the previous one but
|
|
//! for indexed RTC pads. It takes two arguments: `$pad_name`, which
|
|
//! represents the name of the pad, and `$idx`, which is the index of
|
|
//! the specific pad. Returns a reference to the indexed RTC pad.
|
|
//! - `gpio` block:
|
|
//! * Defines the pin configurations for various GPIO pins. Each line
|
|
//! represents a pin and its associated options such as input/output
|
|
//! mode, analog capability, and corresponding functions.
|
|
//! - `analog` block:
|
|
//! * Block defines the analog capabilities of various GPIO pins. Each
|
|
//! line represents a pin and its associated options such as mux
|
|
//! selection, function selection, and input enable.
|
|
//! - `enum InputSignal`:
|
|
//! * This enumeration defines input signals for the GPIO mux. Each input
|
|
//! signal is assigned a specific value.
|
|
//! - `enum OutputSignal`:
|
|
//! * This enumeration defines output signals for the GPIO mux. Each
|
|
//! output signal is assigned a specific value.
|
|
//!
|
|
//! This module also implements the `InterruptStatusRegisterAccess` trait for
|
|
//! two different banks:
|
|
//! * `InterruptStatusRegisterAccessBank0`
|
|
//! * `InterruptStatusRegisterAccessBank1`.
|
|
//! This trait provides functions to read the interrupt status and NMI status
|
|
//! registers for both the `PRO CPU` and `APP CPU`. The implementation uses the
|
|
//! `gpio` peripheral to access the appropriate registers.
|
|
|
|
use crate::{
|
|
gpio::{
|
|
AlternateFunction,
|
|
GpioPin,
|
|
InterruptStatusRegisterAccess,
|
|
InterruptStatusRegisterAccessBank0,
|
|
InterruptStatusRegisterAccessBank1,
|
|
Unknown,
|
|
},
|
|
peripherals::GPIO,
|
|
};
|
|
|
|
pub const NUM_PINS: usize = 46;
|
|
|
|
pub type OutputSignalType = u16;
|
|
pub const OUTPUT_SIGNAL_MAX: u16 = 256;
|
|
pub const INPUT_SIGNAL_MAX: u16 = 204;
|
|
|
|
pub const ONE_INPUT: u8 = 0x38;
|
|
pub const ZERO_INPUT: u8 = 0x3c;
|
|
|
|
pub(crate) const GPIO_FUNCTION: AlternateFunction = AlternateFunction::Function1;
|
|
|
|
pub(crate) const fn get_io_mux_reg(gpio_num: u8) -> &'static crate::peripherals::io_mux::GPIO0 {
|
|
unsafe {
|
|
let iomux = &*crate::peripherals::IO_MUX::PTR;
|
|
|
|
match gpio_num {
|
|
0 => core::mem::transmute(&(iomux.gpio0)),
|
|
1 => core::mem::transmute(&(iomux.gpio1)),
|
|
2 => core::mem::transmute(&(iomux.gpio2)),
|
|
3 => core::mem::transmute(&(iomux.gpio3)),
|
|
4 => core::mem::transmute(&(iomux.gpio4)),
|
|
5 => core::mem::transmute(&(iomux.gpio5)),
|
|
6 => core::mem::transmute(&(iomux.gpio6)),
|
|
7 => core::mem::transmute(&(iomux.gpio7)),
|
|
8 => core::mem::transmute(&(iomux.gpio8)),
|
|
9 => core::mem::transmute(&(iomux.gpio9)),
|
|
10 => core::mem::transmute(&(iomux.gpio10)),
|
|
11 => core::mem::transmute(&(iomux.gpio11)),
|
|
12 => core::mem::transmute(&(iomux.gpio12)),
|
|
13 => core::mem::transmute(&(iomux.gpio13)),
|
|
14 => core::mem::transmute(&(iomux.gpio14)),
|
|
15 => core::mem::transmute(&(iomux.gpio15)),
|
|
16 => core::mem::transmute(&(iomux.gpio16)),
|
|
17 => core::mem::transmute(&(iomux.gpio17)),
|
|
18 => core::mem::transmute(&(iomux.gpio18)),
|
|
19 => core::mem::transmute(&(iomux.gpio19)),
|
|
20 => core::mem::transmute(&(iomux.gpio20)),
|
|
21 => core::mem::transmute(&(iomux.gpio21)),
|
|
26 => core::mem::transmute(&(iomux.gpio26)),
|
|
27 => core::mem::transmute(&(iomux.gpio27)),
|
|
32 => core::mem::transmute(&(iomux.gpio32)),
|
|
33 => core::mem::transmute(&(iomux.gpio33)),
|
|
34 => core::mem::transmute(&(iomux.gpio34)),
|
|
35 => core::mem::transmute(&(iomux.gpio35)),
|
|
36 => core::mem::transmute(&(iomux.gpio36)),
|
|
37 => core::mem::transmute(&(iomux.gpio37)),
|
|
38 => core::mem::transmute(&(iomux.gpio38)),
|
|
39 => core::mem::transmute(&(iomux.gpio39)),
|
|
40 => core::mem::transmute(&(iomux.gpio40)),
|
|
41 => core::mem::transmute(&(iomux.gpio41)),
|
|
42 => core::mem::transmute(&(iomux.gpio42)),
|
|
43 => core::mem::transmute(&(iomux.gpio43)),
|
|
44 => core::mem::transmute(&(iomux.gpio44)),
|
|
45 => core::mem::transmute(&(iomux.gpio45)),
|
|
46 => core::mem::transmute(&(iomux.gpio46)),
|
|
_ => panic!(),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub(crate) fn gpio_intr_enable(int_enable: bool, nmi_enable: bool) -> u8 {
|
|
int_enable as u8
|
|
| ((nmi_enable as u8) << 1)
|
|
| (int_enable as u8) << 2
|
|
| ((nmi_enable as u8) << 3)
|
|
}
|
|
|
|
/// Peripheral input signals for the GPIO mux
|
|
#[allow(non_camel_case_types)]
|
|
#[derive(PartialEq, Copy, Clone)]
|
|
pub enum InputSignal {
|
|
SPIQ = 0,
|
|
SPID = 1,
|
|
SPIHD = 2,
|
|
SPIWP = 3,
|
|
SPID4 = 7,
|
|
SPID5 = 8,
|
|
SPID6 = 9,
|
|
SPID7 = 10,
|
|
SPIDQS = 11,
|
|
U0RXD = 14,
|
|
U0CTS = 15,
|
|
U0DSR = 16,
|
|
U1RXD = 17,
|
|
U1CTS = 18,
|
|
U1DSR = 21,
|
|
I2S0O_BCK = 23,
|
|
I2S0O_WS = 25,
|
|
I2S0I_BCK = 27,
|
|
I2S0I_WS = 28,
|
|
I2CEXT0_SCL = 29,
|
|
I2CEXT0_SDA = 30,
|
|
PCNT0_SIG_CH0 = 39,
|
|
PCNT0_SIG_CH1 = 40,
|
|
PCNT0_CTRL_CH0 = 41,
|
|
PCNT0_CTRL_CH1 = 42,
|
|
PCNT1_SIG_CH0 = 43,
|
|
PCNT1_SIG_CH1 = 44,
|
|
PCNT1_CTRL_CH0 = 45,
|
|
PCNT1_CTRL_CH1 = 46,
|
|
PCNT2_SIG_CH0 = 47,
|
|
PCNT2_SIG_CH1 = 48,
|
|
PCNT2_CTRL_CH0 = 49,
|
|
PCNT2_CTRL_CH1 = 50,
|
|
PCNT3_SIG_CH0 = 51,
|
|
PCNT3_SIG_CH1 = 52,
|
|
PCNT3_CTRL_CH0 = 53,
|
|
PCNT3_CTRL_CH1 = 54,
|
|
USB_OTG_IDDIG = 64,
|
|
USB_OTG_AVALID = 65,
|
|
USB_SRP_BVALID = 66,
|
|
USB_OTG_VBUSVALID = 67,
|
|
USB_SRP_SESSEND = 68,
|
|
SPI3_CLK = 72,
|
|
SPI3_Q = 73,
|
|
SPI3_D = 74,
|
|
SPI3_HD = 75,
|
|
SPI3_CS0 = 76,
|
|
RMT_SIG_0 = 83,
|
|
RMT_SIG_1 = 84,
|
|
RMT_SIG_2 = 85,
|
|
RMT_SIG_3 = 86,
|
|
I2CEXT1_SCL = 95,
|
|
I2CEXT1_SDA = 96,
|
|
FSPICLK = 108,
|
|
FSPIQ = 109,
|
|
FSPID = 110,
|
|
FSPIHD = 111,
|
|
FSPIWP = 112,
|
|
FSPIIO4 = 113,
|
|
FSPIIO5 = 114,
|
|
FSPIIO6 = 115,
|
|
FSPIIO7 = 116,
|
|
FSPICS0 = 117,
|
|
SUBSPIQ = 127,
|
|
SUBSPID = 128,
|
|
SUBSPIHD = 129,
|
|
SUBSPIWP = 130,
|
|
I2S0I_DATA_IN15 = 158,
|
|
SUBSPID4 = 167,
|
|
SUBSPID5 = 168,
|
|
SUBSPID6 = 169,
|
|
SUBSPID7 = 170,
|
|
SUBSPIDQS = 171,
|
|
PCMFSYNC = 203,
|
|
PCMCLK = 204,
|
|
}
|
|
|
|
/// Peripheral output signals for the GPIO mux
|
|
#[allow(non_camel_case_types)]
|
|
#[derive(PartialEq, Copy, Clone)]
|
|
pub enum OutputSignal {
|
|
SPIQ = 0,
|
|
SPID = 1,
|
|
SPIHD = 2,
|
|
SPIWP = 3,
|
|
SPICLK = 4,
|
|
SPICS0 = 5,
|
|
SPICS1 = 6,
|
|
SPID4 = 7,
|
|
SPID5 = 8,
|
|
SPID6 = 9,
|
|
SPID7 = 10,
|
|
SPIDQS = 11,
|
|
U0TXD = 14,
|
|
U0RTS = 15,
|
|
U0DTR = 16,
|
|
U1TXD = 17,
|
|
U1RTS = 18,
|
|
U1DTR = 21,
|
|
I2S0O_BCK = 23,
|
|
I2S0O_WS = 25,
|
|
I2S0I_BCK = 27,
|
|
I2S0I_WS = 28,
|
|
I2CEXT0_SCL = 29,
|
|
I2CEXT0_SDA = 30,
|
|
SDIO_TOHOST_INT = 31,
|
|
SPI3_CLK = 72,
|
|
SPI3_Q = 73,
|
|
SPI3_D = 74,
|
|
SPI3_HD = 75,
|
|
SPI3_CS0 = 76,
|
|
SPI3_CS1 = 77,
|
|
SPI3_CS2 = 78,
|
|
LEDC_LS_SIG0 = 79,
|
|
LEDC_LS_SIG1 = 80,
|
|
LEDC_LS_SIG2 = 81,
|
|
LEDC_LS_SIG3 = 82,
|
|
LEDC_LS_SIG4 = 83,
|
|
LEDC_LS_SIG5 = 84,
|
|
LEDC_LS_SIG6 = 85,
|
|
LEDC_LS_SIG7 = 86,
|
|
RMT_SIG_0 = 87,
|
|
RMT_SIG_1 = 88,
|
|
RMT_SIG_2 = 89,
|
|
RMT_SIG_3 = 90,
|
|
I2CEXT1_SCL = 95,
|
|
I2CEXT1_SDA = 96,
|
|
GPIO_SD0 = 100,
|
|
GPIO_SD1 = 101,
|
|
GPIO_SD2 = 102,
|
|
GPIO_SD3 = 103,
|
|
GPIO_SD4 = 104,
|
|
GPIO_SD5 = 105,
|
|
GPIO_SD6 = 106,
|
|
GPIO_SD7 = 107,
|
|
FSPICLK = 108,
|
|
FSPIQ = 109,
|
|
FSPID = 110,
|
|
FSPIHD = 111,
|
|
FSPIWP = 112,
|
|
FSPIIO4 = 113,
|
|
FSPIIO5 = 114,
|
|
FSPIIO6 = 115,
|
|
FSPIIO7 = 116,
|
|
FSPICS0 = 117,
|
|
FSPICS1 = 118,
|
|
FSPICS2 = 119,
|
|
FSPICS3 = 120,
|
|
FSPICS4 = 121,
|
|
FSPICS5 = 122,
|
|
SUBSPICLK = 126,
|
|
SUBSPIQ = 127,
|
|
SUBSPID = 128,
|
|
SUBSPIHD = 129,
|
|
SUBSPIWP = 130,
|
|
SUBSPICS0 = 131,
|
|
SUBSPICS1 = 132,
|
|
FSPIDQS = 133,
|
|
FSPI_HSYNC = 134,
|
|
FSPI_VSYNC = 135,
|
|
FSPI_DE = 136,
|
|
FSPICD = 137,
|
|
SPI3_CD = 139,
|
|
SPI3_DQS = 140,
|
|
I2S0O_DATA_OUT23 = 166,
|
|
SUBSPID4 = 167,
|
|
SUBSPID5 = 168,
|
|
SUBSPID6 = 169,
|
|
SUBSPID7 = 170,
|
|
SUBSPIDQS = 171,
|
|
PCMFSYNC = 209,
|
|
PCMCLK = 210,
|
|
CLK_I2S = 251,
|
|
GPIO = 256,
|
|
}
|
|
|
|
crate::gpio::gpio! {
|
|
(0, 0, InputOutputAnalog)
|
|
(1, 0, InputOutputAnalog)
|
|
(2, 0, InputOutputAnalog)
|
|
(3, 0, InputOutputAnalog)
|
|
(4, 0, InputOutputAnalog)
|
|
(5, 0, InputOutputAnalog)
|
|
(6, 0, InputOutputAnalog)
|
|
(7, 0, InputOutputAnalog)
|
|
(8, 0, InputOutputAnalog)
|
|
(9, 0, InputOutputAnalog)
|
|
(10, 0, InputOutputAnalog)
|
|
(11, 0, InputOutputAnalog)
|
|
(12, 0, InputOutputAnalog)
|
|
(13, 0, InputOutputAnalog)
|
|
(14, 0, InputOutputAnalog)
|
|
(15, 0, InputOutputAnalog)
|
|
(16, 0, InputOutputAnalog)
|
|
(17, 0, InputOutputAnalog)
|
|
(18, 0, InputOutputAnalog)
|
|
(19, 0, InputOutputAnalog)
|
|
(20, 0, InputOutputAnalog)
|
|
(21, 0, InputOutputAnalog)
|
|
|
|
(26, 0, InputOutput)
|
|
(27, 0, InputOutput)
|
|
(28, 0, InputOutput)
|
|
(29, 0, InputOutput)
|
|
(30, 0, InputOutput)
|
|
(31, 0, InputOutput)
|
|
(32, 1, InputOutput)
|
|
(33, 1, InputOutput)
|
|
(34, 1, InputOutput)
|
|
(35, 1, InputOutput)
|
|
(36, 1, InputOutput)
|
|
(37, 1, InputOutput)
|
|
(38, 1, InputOutput)
|
|
(39, 1, InputOutput)
|
|
(40, 1, InputOutput)
|
|
(41, 1, InputOutput)
|
|
(42, 1, InputOutput)
|
|
(43, 1, InputOutput)
|
|
(44, 1, InputOutput)
|
|
(45, 1, InputOutput)
|
|
(46, 1, InputOutput)
|
|
}
|
|
|
|
crate::gpio::analog! {
|
|
( 0, 0, touch_pad[0], mux_sel, fun_sel, fun_ie, rue, rde)
|
|
( 1, 1, touch_pad[1], mux_sel, fun_sel, fun_ie, rue, rde)
|
|
( 2, 2, touch_pad[2], mux_sel, fun_sel, fun_ie, rue, rde)
|
|
( 3, 3, touch_pad[3], mux_sel, fun_sel, fun_ie, rue, rde)
|
|
( 4, 4, touch_pad[4], mux_sel, fun_sel, fun_ie, rue, rde)
|
|
( 5, 5, touch_pad[5], mux_sel, fun_sel, fun_ie, rue, rde)
|
|
( 6, 6, touch_pad[6], mux_sel, fun_sel, fun_ie, rue, rde)
|
|
( 7, 7, touch_pad[7], mux_sel, fun_sel, fun_ie, rue, rde)
|
|
( 8, 8, touch_pad[8], mux_sel, fun_sel, fun_ie, rue, rde)
|
|
( 9, 9, touch_pad[9], mux_sel, fun_sel, fun_ie, rue, rde)
|
|
(10, 10, touch_pad[10], mux_sel, fun_sel, fun_ie, rue, rde)
|
|
(11, 11, touch_pad[11], mux_sel, fun_sel, fun_ie, rue, rde)
|
|
(12, 12, touch_pad[12], mux_sel, fun_sel, fun_ie, rue, rde)
|
|
(13, 13, touch_pad[13], mux_sel, fun_sel, fun_ie, rue, rde)
|
|
(14, 14, touch_pad[14], mux_sel, fun_sel, fun_ie, rue, rde)
|
|
(15, 15, xtal_32p_pad, x32p_mux_sel, x32p_fun_sel, x32p_fun_ie, x32p_rue, x32p_rde)
|
|
(16, 16, xtal_32n_pad, x32n_mux_sel, x32n_fun_sel, x32n_fun_ie, x32n_rue, x32n_rde)
|
|
(17, 17, pad_dac1, pdac1_mux_sel, pdac1_fun_sel, pdac1_fun_ie, pdac1_rue, pdac1_rde)
|
|
(18, 18, pad_dac2, pdac2_mux_sel, pdac2_fun_sel, pdac2_fun_ie, pdac2_rue, pdac2_rde)
|
|
(19, 19, rtc_pad19, mux_sel, fun_sel, fun_ie, rue, rde)
|
|
(20, 20, rtc_pad20, mux_sel, fun_sel, fun_ie, rue, rde)
|
|
(21, 21, rtc_pad21, mux_sel, fun_sel, fun_ie, rue, rde)
|
|
}
|
|
|
|
crate::gpio::rtc_pins! {
|
|
( 0, 0, touch_pad[0], "", touch_pad0_hold, rue, rde)
|
|
( 1, 1, touch_pad[1], "", touch_pad1_hold, rue, rde)
|
|
( 2, 2, touch_pad[2], "", touch_pad2_hold, rue, rde)
|
|
( 3, 3, touch_pad[3], "", touch_pad3_hold, rue, rde)
|
|
( 4, 4, touch_pad[4], "", touch_pad4_hold, rue, rde)
|
|
( 5, 5, touch_pad[5], "", touch_pad5_hold, rue, rde)
|
|
( 6, 6, touch_pad[6], "", touch_pad6_hold, rue, rde)
|
|
( 7, 7, touch_pad[7], "", touch_pad7_hold, rue, rde)
|
|
( 8, 8, touch_pad[8], "", touch_pad8_hold, rue, rde)
|
|
( 9, 9, touch_pad[9], "", touch_pad9_hold, rue, rde)
|
|
(10, 10, touch_pad[10], "", touch_pad10_hold, rue, rde)
|
|
(11, 11, touch_pad[11], "", touch_pad11_hold, rue, rde)
|
|
(12, 12, touch_pad[12], "", touch_pad12_hold, rue, rde)
|
|
(13, 13, touch_pad[13], "", touch_pad13_hold, rue, rde)
|
|
(14, 14, touch_pad[14], "", touch_pad14_hold, rue, rde)
|
|
(15, 15, xtal_32p_pad, x32p_, x32p_hold, x32p_rue, x32p_rde)
|
|
(16, 16, xtal_32n_pad, x32n_, x32n_hold, x32n_rue, x32n_rde)
|
|
(17, 17, pad_dac1, pdac1_, pdac1_hold, pdac1_rue, pdac1_rde)
|
|
(18, 18, pad_dac2, pdac2_, pdac2_hold, pdac2_rue, pdac2_rde)
|
|
(19, 19, rtc_pad19, "", pad19_hold, rue, rde)
|
|
(20, 20, rtc_pad20, "", pad20_hold, rue, rde)
|
|
(21, 21, rtc_pad21, "", pad21_hold, rue, rde)
|
|
}
|
|
|
|
impl InterruptStatusRegisterAccess for InterruptStatusRegisterAccessBank0 {
|
|
fn pro_cpu_interrupt_status_read() -> u32 {
|
|
unsafe { &*GPIO::PTR }.pcpu_int.read().bits()
|
|
}
|
|
|
|
fn pro_cpu_nmi_status_read() -> u32 {
|
|
unsafe { &*GPIO::PTR }.pcpu_nmi_int.read().bits()
|
|
}
|
|
}
|
|
|
|
impl InterruptStatusRegisterAccess for InterruptStatusRegisterAccessBank1 {
|
|
fn pro_cpu_interrupt_status_read() -> u32 {
|
|
unsafe { &*GPIO::PTR }.pcpu_int1.read().bits()
|
|
}
|
|
|
|
fn pro_cpu_nmi_status_read() -> u32 {
|
|
unsafe { &*GPIO::PTR }.pcpu_nmi_int1.read().bits()
|
|
}
|
|
}
|
|
|
|
// implement marker traits on USB pins
|
|
impl<T> crate::otg_fs::UsbSel for Gpio18<T> {}
|
|
impl<T> crate::otg_fs::UsbDp for Gpio19<T> {}
|
|
impl<T> crate::otg_fs::UsbDm for Gpio20<T> {}
|