Björn Quentin 213dde9304
Add a new RMT driver (#653)
* Add a new RMT driver

* Add CHANGELOG entry

* Fix typos
2023-07-19 10:54:52 -07:00

430 lines
15 KiB
Rust

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)
}
// on ESP32-S2 the touch_pad registers are indexed and the fields are weirdly
// named
macro_rules! impl_get_rtc_pad {
($pad_name:ident) => {
paste::paste! {
pub(crate) fn [<esp32s2_get_rtc_pad_ $pad_name >]() -> &'static crate::peripherals::rtc_io::[< $pad_name:upper >] {
use crate::peripherals::RTC_IO;
let rtc_io = unsafe{ &*RTC_IO::ptr() };
&rtc_io.$pad_name
}
}
};
}
macro_rules! impl_get_rtc_pad_indexed {
($pad_name:ident, $idx:literal) => {
paste::paste! {
pub(crate) fn [<esp32s2_get_rtc_pad_ $pad_name $idx>]() -> &'static crate::peripherals::rtc_io::[< $pad_name:upper >] {
use crate::peripherals::RTC_IO;
let rtc_io = unsafe{ &*RTC_IO::ptr() };
&rtc_io.$pad_name[$idx]
}
}
};
}
impl_get_rtc_pad_indexed!(touch_pad, 0);
impl_get_rtc_pad_indexed!(touch_pad, 1);
impl_get_rtc_pad_indexed!(touch_pad, 2);
impl_get_rtc_pad_indexed!(touch_pad, 3);
impl_get_rtc_pad_indexed!(touch_pad, 4);
impl_get_rtc_pad_indexed!(touch_pad, 5);
impl_get_rtc_pad_indexed!(touch_pad, 6);
impl_get_rtc_pad_indexed!(touch_pad, 7);
impl_get_rtc_pad_indexed!(touch_pad, 8);
impl_get_rtc_pad_indexed!(touch_pad, 9);
impl_get_rtc_pad_indexed!(touch_pad, 10);
impl_get_rtc_pad_indexed!(touch_pad, 11);
impl_get_rtc_pad_indexed!(touch_pad, 12);
impl_get_rtc_pad_indexed!(touch_pad, 13);
impl_get_rtc_pad_indexed!(touch_pad, 14);
impl_get_rtc_pad!(xtal_32p_pad);
impl_get_rtc_pad!(xtal_32n_pad);
impl_get_rtc_pad!(pad_dac1);
impl_get_rtc_pad!(pad_dac2);
impl_get_rtc_pad!(rtc_pad19);
impl_get_rtc_pad!(rtc_pad20);
impl_get_rtc_pad!(rtc_pad21);
crate::gpio::analog! {
( 0, 0, touch_pad0, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_rue, touch_pad0_rde)
( 1, 1, touch_pad1, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_rue, touch_pad0_rde)
( 2, 2, touch_pad2, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_rue, touch_pad0_rde)
( 3, 3, touch_pad3, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_rue, touch_pad0_rde)
( 4, 4, touch_pad4, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_rue, touch_pad0_rde)
( 5, 5, touch_pad5, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_rue, touch_pad0_rde)
( 6, 6, touch_pad6, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_rue, touch_pad0_rde)
( 7, 7, touch_pad7, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_rue, touch_pad0_rde)
( 8, 8, touch_pad8, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_rue, touch_pad0_rde)
( 9, 9, touch_pad9, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_rue, touch_pad0_rde)
(10, 10, touch_pad10, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_rue, touch_pad0_rde)
(11, 11, touch_pad11, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_rue, touch_pad0_rde)
(12, 12, touch_pad12, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_rue, touch_pad0_rde)
(13, 13, touch_pad13, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_rue, touch_pad0_rde)
(14, 14, touch_pad14, touch_pad0_mux_sel, touch_pad0_fun_sel, touch_pad0_fun_ie, touch_pad0_rue, touch_pad0_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_)
( 1, 1, touch_pad[1], touch_pad0_)
( 2, 2, touch_pad[2], touch_pad0_)
( 3, 3, touch_pad[3], touch_pad0_)
( 4, 4, touch_pad[4], touch_pad0_)
( 5, 5, touch_pad[5], touch_pad0_)
( 6, 6, touch_pad[6], touch_pad0_)
( 7, 7, touch_pad[7], touch_pad0_)
( 8, 8, touch_pad[8], touch_pad0_)
( 9, 9, touch_pad[9], touch_pad0_)
(10, 10, touch_pad[10], touch_pad0_)
(11, 11, touch_pad[11], touch_pad0_)
(12, 12, touch_pad[12], touch_pad0_)
(13, 13, touch_pad[13], touch_pad0_)
(14, 14, touch_pad[14], touch_pad0_)
(15, 15, xtal_32p_pad, x32p_)
(16, 16, xtal_32n_pad, x32n_)
(17, 17, pad_dac1, pdac1_)
(18, 18, pad_dac2, pdac2_)
(19, 19, rtc_pad19, "")
(20, 20, rtc_pad20, "")
(21, 21, rtc_pad21, "")
}
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> {}