From 39162ebafb81533a64514c1d596ee3ac0a6966d5 Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz Date: Fri, 20 Jan 2023 14:00:02 -0300 Subject: [PATCH] arch/xtensa/esp32: Add support for RTC IRQs --- arch/xtensa/include/esp32/irq.h | 35 +- arch/xtensa/src/esp32/Kconfig | 7 + arch/xtensa/src/esp32/Make.defs | 2 +- arch/xtensa/src/esp32/esp32_gpio.c | 412 +++++++----------- arch/xtensa/src/esp32/esp32_gpio.h | 81 ++-- arch/xtensa/src/esp32/esp32_irq.c | 5 + arch/xtensa/src/esp32/esp32_rtc_gpio.c | 418 +++++++++++++++++++ arch/xtensa/src/esp32/esp32_rtc_gpio.h | 112 ++++- arch/xtensa/src/esp32/esp32_touch.c | 6 +- arch/xtensa/src/esp32/esp32_touch.h | 22 +- arch/xtensa/src/esp32/esp32_wdt.c | 88 ++-- arch/xtensa/src/esp32/hardware/esp32_touch.h | 31 +- 12 files changed, 853 insertions(+), 366 deletions(-) create mode 100644 arch/xtensa/src/esp32/esp32_rtc_gpio.c diff --git a/arch/xtensa/include/esp32/irq.h b/arch/xtensa/include/esp32/irq.h index 2ccb8fdcdc..1b71bfac9b 100644 --- a/arch/xtensa/include/esp32/irq.h +++ b/arch/xtensa/include/esp32/irq.h @@ -312,9 +312,42 @@ # define ESP32_NIRQ_GPIO 0 #endif +#ifdef CONFIG_ESP32_RTCIO_IRQ + +/* Second level RTC interrupts. RTC interrupts are decoded and dispatched + * as a second level of decoding: The first level dispatches to the RTC + * interrupt handler. The second to the decoded RTC interrupt handler. + * A third level might be required to be implemented on the driver (e.g. + * Touch pads) + */ + +# define ESP32_NIRQ_RTCIO_PERIPH 9 +# define ESP32_NIRQ_RTCIO_TOUCHPAD 10 +# define ESP32_NIRQ_RTCIO (ESP32_NIRQ_RTCIO_PERIPH+ESP32_NIRQ_RTCIO_TOUCHPAD) + +# define ESP32_FIRST_RTCIOIRQ_PERIPH (XTENSA_NIRQ_INTERNAL+ESP32_NIRQ_PERIPH+ESP32_NIRQ_GPIO) +# define ESP32_LAST_RTCIOIRQ_PERIPH (ESP32_FIRST_RTCIOIRQ_PERIPH+ESP32_NIRQ_RTCIO_PERIPH-1) +# define ESP32_IRQ_RTC_SLP_WAKEUP (ESP32_FIRST_RTCIOIRQ_PERIPH+0) +# define ESP32_IRQ_RTC_SLP_REJECT (ESP32_FIRST_RTCIOIRQ_PERIPH+1) +# define ESP32_IRQ_RTC_SDIO_IDLE (ESP32_FIRST_RTCIOIRQ_PERIPH+2) +# define ESP32_IRQ_RTC_WDT (ESP32_FIRST_RTCIOIRQ_PERIPH+3) +# define ESP32_IRQ_RTC_TIME_VALID (ESP32_FIRST_RTCIOIRQ_PERIPH+4) +# define ESP32_IRQ_RTC_SAR (ESP32_FIRST_RTCIOIRQ_PERIPH+5) +# define ESP32_IRQ_RTC_TOUCH (ESP32_FIRST_RTCIOIRQ_PERIPH+6) +# define ESP32_IRQ_RTC_BROWN_OUT (ESP32_FIRST_RTCIOIRQ_PERIPH+7) +# define ESP32_IRQ_RTC_MAIN_TIMER (ESP32_FIRST_RTCIOIRQ_PERIPH+8) + +# define ESP32_FIRST_RTCIOIRQ_TOUCHPAD (ESP32_LAST_RTCIOIRQ_PERIPH+1) +# define ESP32_LAST_RTCIOIRQ_TOUCHPAD (ESP32_FIRST_RTCIOIRQ_TOUCHPAD+ESP32_NIRQ_RTCIO_TOUCHPAD-1) +# define ESP32_TOUCHPAD2IRQ(t) ((t) + ESP32_FIRST_RTCIOIRQ_TOUCHPAD) +# define ESP32_IRQ2TOUCHPAD(i) ((i) - ESP32_FIRST_RTCIOIRQ_TOUCHPAD) +#else +# define ESP32_NIRQ_RTCIO 0 +#endif + /* Total number of interrupts */ -#define NR_IRQS (XTENSA_NIRQ_INTERNAL+ESP32_NIRQ_PERIPH+ESP32_NIRQ_GPIO) +#define NR_IRQS (XTENSA_NIRQ_INTERNAL+ESP32_NIRQ_PERIPH+ESP32_NIRQ_GPIO+ESP32_NIRQ_RTCIO) /* Xtensa CPU Interrupts. * diff --git a/arch/xtensa/src/esp32/Kconfig b/arch/xtensa/src/esp32/Kconfig index da92b64e8d..5e5305fdb6 100644 --- a/arch/xtensa/src/esp32/Kconfig +++ b/arch/xtensa/src/esp32/Kconfig @@ -647,6 +647,7 @@ config ESP32_RWDT bool "RTC Watchdog Timer" default n select ESP32_WDT + select ESP32_RTCIO_IRQ ---help--- Includes RWDT. This watchdog timer is from the RTC module. When it is selected, if the developer sets it to reset on expiration @@ -796,6 +797,12 @@ config ESP32_GPIO_IRQ ---help--- Enable support for interrupting GPIO pins +config ESP32_RTCIO_IRQ + bool "RTC IO interrupts" + default n + ---help--- + Enable support for interrupting RTC peripherals + menu "UART Configuration" depends on ESP32_UART diff --git a/arch/xtensa/src/esp32/Make.defs b/arch/xtensa/src/esp32/Make.defs index f232f29c4d..a536c78274 100644 --- a/arch/xtensa/src/esp32/Make.defs +++ b/arch/xtensa/src/esp32/Make.defs @@ -33,7 +33,7 @@ endif CHIP_CSRCS = esp32_allocateheap.c esp32_clockconfig.c esp32_gpio.c CHIP_CSRCS += esp32_systemreset.c esp32_resetcause.c -CHIP_CSRCS += esp32_irq.c esp32_region.c +CHIP_CSRCS += esp32_irq.c esp32_region.c esp32_rtc_gpio.c CHIP_CSRCS += esp32_user.c CHIP_CSRCS += esp32_dma.c diff --git a/arch/xtensa/src/esp32/esp32_gpio.c b/arch/xtensa/src/esp32/esp32_gpio.c index 3ae2b715fa..e6af92aba9 100644 --- a/arch/xtensa/src/esp32/esp32_gpio.c +++ b/arch/xtensa/src/esp32/esp32_gpio.c @@ -37,7 +37,6 @@ #include "hardware/esp32_iomux.h" #include "hardware/esp32_gpio.h" -#include "hardware/esp32_soc.h" #include "esp32_irq.h" #include "esp32_rtc_gpio.h" @@ -48,11 +47,9 @@ * Pre-processor Definitions ****************************************************************************/ -#define NGPIO_HPINS (ESP32_NIRQ_GPIO - 32) -#define NGPIO_HMASK ((UINT32_C(1) << NGPIO_HPINS) - 1) -#define _NA_ 0xff -#define setbits(a, bs) modifyreg32(a, 0, bs) -#define resetbits(a, bs) modifyreg32(a, bs, 0) +#define NGPIO_HPINS (ESP32_NIRQ_GPIO - 32) +#define NGPIO_HMASK ((UINT32_C(1) << NGPIO_HPINS) - 1) +#define _NA_ 0xff /**************************************************************************** * Private Data @@ -71,45 +68,48 @@ static const uint8_t g_pin2func[40] = 0x1c, 0x20, 0x14, 0x18, 0x04, 0x08, 0x0c, 0x10 /* 32-39 */ }; -static const uint32_t rtc_gpio_to_addr[] = -{ - RTC_GPIO_PIN0_REG, - RTC_GPIO_PIN1_REG, - RTC_GPIO_PIN2_REG, - RTC_GPIO_PIN3_REG, - RTC_GPIO_PIN4_REG, - RTC_GPIO_PIN5_REG, - RTC_GPIO_PIN6_REG, - RTC_GPIO_PIN7_REG, - RTC_GPIO_PIN8_REG, - RTC_GPIO_PIN9_REG, - RTC_GPIO_PIN10_REG, - RTC_GPIO_PIN11_REG, - RTC_GPIO_PIN12_REG, - RTC_GPIO_PIN13_REG, - RTC_GPIO_PIN14_REG, - RTC_GPIO_PIN15_REG, - RTC_GPIO_PIN16_REG, - RTC_GPIO_PIN17_REG -}; - -static bool g_pin_rtc_controlled[RTC_GPIO_NUMBER]; - /**************************************************************************** * Private Functions ****************************************************************************/ /**************************************************************************** - * Name: rtc_gpio_is_valid_gpio + * Name: gpio_is_valid_rtc_gpio * * Description: * Determine if the specified GPIO is a valid RTC GPIO. * + * Input Parameters: + * gpio_num - GPIO pin to be checked. + * + * Returned Value: + * True if valid. False otherwise. + * ****************************************************************************/ -static inline bool rtc_gpio_is_valid_gpio(uint32_t gpio_num) +static inline bool gpio_is_valid_rtc_gpio(uint32_t gpio_num) { - return (gpio_num < GPIO_PIN_COUNT && g_rtc_io_num_map[gpio_num] >= 0); + return (gpio_num < GPIO_PIN_COUNT && g_gpio_to_rtcio_map[gpio_num] >= 0); +} + +/**************************************************************************** + * Name: rtc_gpio_is_pull_supported + * + * Description: + * Determine if the specified rtcio_num supports pull-up/pull-down. + * + * Input Parameters: + * rtcio_num - RTC GPIO to be checked. + * + * Returned Value: + * True if pull-up/pull-down supported. False otherwise. + * + ****************************************************************************/ + +static inline bool rtc_gpio_is_pull_supported(uint32_t rtcio_num) +{ + /* Pins 34 through 39 use RTC channels 0 to 5 and don't support PU/PD */ + + return (rtcio_num > 5); } /**************************************************************************** @@ -212,8 +212,6 @@ int esp32_configgpio(int pin, gpio_pinattr_t attr) uintptr_t regaddr; uint32_t func; uint32_t cntrl; - uint32_t rtc_gpio_idx; - rtc_io_desc_t rtc_reg_desc; DEBUGASSERT(pin >= 0 && pin <= ESP32_NGPIOS); @@ -222,258 +220,142 @@ int esp32_configgpio(int pin, gpio_pinattr_t attr) func = 0; cntrl = 0; - if ((attr & FUNCTION_MASK) == FUNCTION_RTC) /* RTCIO */ + if ((attr & INPUT) != 0) { - if (rtc_gpio_is_valid_gpio(pin) == 0) + if (pin < 32) { - gpioerr("Pin %d is not a valid RTC pin!\n", pin); - return -1; - } - - rtc_gpio_idx = g_rtc_io_num_map[pin]; - rtc_reg_desc = g_rtc_io_desc[rtc_gpio_idx]; - g_pin_rtc_controlled[rtc_gpio_idx] = true; - - setbits(rtc_reg_desc.reg, rtc_reg_desc.mux); - - modifyreg32(rtc_reg_desc.reg, - ((RTC_IO_TOUCH_PAD1_FUN_SEL_V) << (rtc_reg_desc.func)), - (((RTCIO_PIN_FUNC) & RTC_IO_TOUCH_PAD1_FUN_SEL_V) << - (rtc_reg_desc.func))); - - if (rtc_reg_desc.pulldown) - { - resetbits(rtc_reg_desc.reg, rtc_reg_desc.pulldown); - } - - if (rtc_reg_desc.pullup) - { - resetbits(rtc_reg_desc.reg, rtc_reg_desc.pullup); - } - - if ((attr & PULLUP) != 0) - { - if (rtc_reg_desc.pullup) - { - setbits(rtc_reg_desc.reg, rtc_reg_desc.pullup); - } - } - else if ((attr & PULLDOWN) != 0) - { - if (rtc_reg_desc.pulldown) - { - setbits(rtc_reg_desc.reg, rtc_reg_desc.pulldown); - } - } - - if ((attr & INPUT) != 0) - { - /* Enable Input */ - - setbits(rtc_reg_desc.reg, rtc_reg_desc.ie); - - /* Disable Output */ - - putreg32((UINT32_C(1) << pin), RTC_GPIO_ENABLE_W1TC_REG); - } - else if ((attr & OUTPUT) != 0) - { - /* Disable Input */ - - resetbits(rtc_reg_desc.reg, rtc_reg_desc.ie); - - /* Enable Output */ - - putreg32((UINT32_C(1) << pin), RTC_GPIO_ENABLE_W1TS_REG); + putreg32((UINT32_C(1) << pin), GPIO_ENABLE_W1TC_REG); } else { - resetbits(rtc_reg_desc.reg, rtc_reg_desc.ie); - putreg32((UINT32_C(1) << pin), RTC_GPIO_ENABLE_W1TC_REG); + putreg32((UINT32_C(1) << (pin - 32)), GPIO_ENABLE1_W1TC_REG); } - if ((attr & DRIVE_MASK) != 0) + /* Input enable */ + + func |= FUN_IE; + + /* Some pins only support Pull-Up and Pull-Down resistor on RTC GPIO */ + + if (gpio_is_valid_rtc_gpio(pin)) { - if (rtc_reg_desc.drv_v) + uint32_t rtc_gpio_idx = g_gpio_to_rtcio_map[pin]; + uint32_t regval; + uint32_t rtc_gpio_pin; + bool en_pu = false; + bool en_pd = false; + + if ((attr & PULLUP) != 0) { - uint32_t val = ((attr & DRIVE_MASK) >> DRIVE_SHIFT) - 1; - modifyreg32(rtc_reg_desc.reg, - ((rtc_reg_desc.drv_v) << (rtc_reg_desc.drv_s)), - (((val) & rtc_reg_desc.drv_v) << (rtc_reg_desc.drv_s))); + ASSERT(rtc_gpio_is_pull_supported(rtc_gpio_idx)); + en_pu = true; } - } - - if ((attr & OPEN_DRAIN) != 0) - { - /* All RTC GPIOs have the same position for the drive bits. - * We can use any RTC_GPIO_PINn_PAD_DRIVER. - */ - - REG_SET_FIELD(rtc_gpio_to_addr[rtc_gpio_idx], - RTC_GPIO_PIN0_PAD_DRIVER, - true); - } - else - { - REG_SET_FIELD(rtc_gpio_to_addr[rtc_gpio_idx], - RTC_GPIO_PIN0_PAD_DRIVER, - false); - } - - return OK; - } - else /* GPIO */ - { - if ((attr & INPUT) != 0) - { - if (pin < 32) + else if ((attr & PULLDOWN) != 0) { - putreg32((UINT32_C(1) << pin), GPIO_ENABLE_W1TC_REG); + ASSERT(rtc_gpio_is_pull_supported(rtc_gpio_idx)); + en_pd = true; + } + + /* Get the pin register */ + + rtc_gpio_pin = g_rtc_io_desc[rtc_gpio_idx].reg; + + /* Read the current value from RTC GPIO pin */ + + regval = getreg32(rtc_gpio_pin); + + /* RTC_IO_X32P (GPIO32) uses different PU/PD bits */ + + if (rtc_gpio_idx == RTCIO_GPIO32_CHANNEL) + { + /* First, disable PU/PD */ + + regval &= ~SPECIAL_RTC_PU_BIT; + regval &= ~SPECIAL_RTC_PD_BIT; + + /* Enable PU/PD, if needed */ + + regval |= en_pu ? SPECIAL_RTC_PU_BIT : 0; + regval |= en_pd ? SPECIAL_RTC_PD_BIT : 0; } else { - putreg32((UINT32_C(1) << (pin - 32)), GPIO_ENABLE1_W1TC_REG); + /* First, disable PU/PD */ + + regval &= ~DEFAULT_RTC_PU_BIT; + regval &= ~DEFAULT_RTC_PD_BIT; + + /* Enable PU/PD, if needed */ + + regval |= en_pu ? DEFAULT_RTC_PU_BIT : 0; + regval |= en_pd ? DEFAULT_RTC_PD_BIT : 0; } - /* Input enable */ - - func |= FUN_IE; - - /* Some pins only support Pull-Up/Pull-Down resistor on RTC GPIO */ - - if (rtc_gpio_is_valid_gpio(pin)) - { - rtc_gpio_idx = g_rtc_io_num_map[pin]; - rtc_reg_desc = g_rtc_io_desc[rtc_gpio_idx]; - g_pin_rtc_controlled[rtc_gpio_idx] = false; - - /* Disable RTC control */ - - resetbits(rtc_reg_desc.reg, rtc_reg_desc.mux); - - if (rtc_reg_desc.pullup == 0) - { - gpioerr("Pins 34-39 don't support PullUp/PullDown\n"); - assert(0); - } - else - { - uint32_t regval; - uint32_t rtc_gpio_reg; - bool en_pu = false; - bool en_pd = false; - - if ((attr & PULLUP) != 0) - { - en_pu = true; - } - else if ((attr & PULLDOWN) != 0) - { - en_pd = true; - } - - /* Get the pin register */ - - rtc_gpio_reg = g_rtc_io_desc[rtc_gpio_idx].reg; - - /* Read the current value from RTC GPIO pin */ - - regval = getreg32(rtc_gpio_reg); - - /* RTC_IO_X32P (GPIO32) uses different PU/PD bits */ - - if (rtc_gpio_idx == RTCIO_GPIO32_CHANNEL) - { - /* First, disable PU/PD */ - - regval &= ~SPECIAL_RTC_PU_BIT; - regval &= ~SPECIAL_RTC_PD_BIT; - - /* Enable PU/PD, if needed */ - - regval |= en_pu ? SPECIAL_RTC_PU_BIT : 0; - regval |= en_pd ? SPECIAL_RTC_PD_BIT : 0; - } - else - { - /* First, disable PU/PD */ - - regval &= ~DEFAULT_RTC_PU_BIT; - regval &= ~DEFAULT_RTC_PD_BIT; - - /* Enable PU/PD, if needed */ - - regval |= en_pu ? DEFAULT_RTC_PU_BIT : 0; - regval |= en_pd ? DEFAULT_RTC_PD_BIT : 0; - } - - putreg32(regval, rtc_gpio_reg); - } - } - else if ((attr & PULLUP) != 0) - { - func |= FUN_PU; - } - else if (attr & PULLDOWN) - { - func |= FUN_PD; - } + putreg32(regval, rtc_gpio_pin); } - - /* Handle output pins */ - - if ((attr & OUTPUT) != 0) + else if ((attr & PULLUP) != 0) { - if (pin < 32) - { - putreg32((UINT32_C(1) << pin), GPIO_ENABLE_W1TS_REG); - } - else - { - putreg32((UINT32_C(1) << (pin - 32)), GPIO_ENABLE1_W1TS_REG); - } + func |= FUN_PU; } - - /* Configure the pad's function */ - - if ((attr & FUNCTION_MASK) != 0) + else if (attr & PULLDOWN) { - uint32_t val = ((attr & FUNCTION_MASK) >> FUNCTION_SHIFT) - 1; - func |= val << MCU_SEL_S; + func |= FUN_PD; } - else - { - /* Function not provided, assuming function GPIO by default */ - - func |= (uint32_t)(PIN_FUNC_GPIO << MCU_SEL_S); - } - - /* Configure the pad's drive strength */ - - if ((attr & DRIVE_MASK) != 0) - { - uint32_t val = ((attr & DRIVE_MASK) >> DRIVE_SHIFT) - 1; - func |= val << FUN_DRV_S; - } - else - { - /* Drive strength not provided, assuming strength 2 by default */ - - func |= UINT32_C(2) << FUN_DRV_S; - } - - if ((attr & OPEN_DRAIN) != 0) - { - cntrl |= (1 << GPIO_PIN_PAD_DRIVER_S); - } - - regaddr = DR_REG_IO_MUX_BASE + g_pin2func[pin]; - putreg32(func, regaddr); - - regaddr = GPIO_REG(pin); - putreg32(cntrl, regaddr); - return OK; } + + /* Handle output pins */ + + if ((attr & OUTPUT) != 0) + { + if (pin < 32) + { + putreg32((UINT32_C(1) << pin), GPIO_ENABLE_W1TS_REG); + } + else + { + putreg32((UINT32_C(1) << (pin - 32)), GPIO_ENABLE1_W1TS_REG); + } + } + + /* Configure the pad's function */ + + if ((attr & FUNCTION_MASK) != 0) + { + uint32_t val = ((attr & FUNCTION_MASK) >> FUNCTION_SHIFT) - 1; + func |= val << MCU_SEL_S; + } + else + { + /* Function not provided, assuming function GPIO by default */ + + func |= (uint32_t)(PIN_FUNC_GPIO << MCU_SEL_S); + } + + /* Configure the pad's drive strength */ + + if ((attr & DRIVE_MASK) != 0) + { + uint32_t val = ((attr & DRIVE_MASK) >> DRIVE_SHIFT) - 1; + func |= val << FUN_DRV_S; + } + else + { + /* Drive strength not provided, assuming strength 2 by default */ + + func |= UINT32_C(2) << FUN_DRV_S; + } + + if ((attr & OPEN_DRAIN) != 0) + { + cntrl |= (1 << GPIO_PIN_PAD_DRIVER_S); + } + + regaddr = DR_REG_IO_MUX_BASE + g_pin2func[pin]; + putreg32(func, regaddr); + + regaddr = GPIO_REG(pin); + putreg32(cntrl, regaddr); + return OK; } /**************************************************************************** diff --git a/arch/xtensa/src/esp32/esp32_gpio.h b/arch/xtensa/src/esp32/esp32_gpio.h index 650281c926..5d7cc8518e 100644 --- a/arch/xtensa/src/esp32/esp32_gpio.h +++ b/arch/xtensa/src/esp32/esp32_gpio.h @@ -47,52 +47,49 @@ * FN FN FN OD PD PU F O I */ -#define PINMODE_SHIFT 0 -#define PINMODE_MASK (7 << PINMODE_SHIFT) -# define INPUT (1 << 0) -# define OUTPUT (1 << 1) -# define FUNCTION (1 << 2) +#define PINMODE_SHIFT 0 +#define PINMODE_MASK (7 << PINMODE_SHIFT) +# define INPUT (1 << 0) +# define OUTPUT (1 << 1) +# define FUNCTION (1 << 2) -#define PULLUP (1 << 3) -#define PULLDOWN (1 << 4) -#define OPEN_DRAIN (1 << 5) +#define PULLUP (1 << 3) +#define PULLDOWN (1 << 4) +#define OPEN_DRAIN (1 << 5) -#define FUNCTION_SHIFT 6 -#define FUNCTION_MASK (7 << FUNCTION_SHIFT) -# define FUNCTION_1 (1 << FUNCTION_SHIFT) -# define FUNCTION_2 (2 << FUNCTION_SHIFT) -# define FUNCTION_3 (3 << FUNCTION_SHIFT) -# define FUNCTION_4 (4 << FUNCTION_SHIFT) -# define FUNCTION_5 (5 << FUNCTION_SHIFT) -# define FUNCTION_6 (6 << FUNCTION_SHIFT) -# define FUNCTION_RTC (7 << FUNCTION_SHIFT) +#define FUNCTION_SHIFT 6 +#define FUNCTION_MASK (7 << FUNCTION_SHIFT) +# define FUNCTION_1 (1 << FUNCTION_SHIFT) +# define FUNCTION_2 (2 << FUNCTION_SHIFT) +# define FUNCTION_3 (3 << FUNCTION_SHIFT) +# define FUNCTION_4 (4 << FUNCTION_SHIFT) +# define FUNCTION_5 (5 << FUNCTION_SHIFT) +# define FUNCTION_6 (6 << FUNCTION_SHIFT) -#define DRIVE_SHIFT 9 -#define DRIVE_MASK (7 << DRIVE_SHIFT) -# define DRIVE_0 (1 << DRIVE_SHIFT) -# define DRIVE_1 (2 << DRIVE_SHIFT) -# define DRIVE_2 (3 << DRIVE_SHIFT) -# define DRIVE_3 (4 << DRIVE_SHIFT) +#define DRIVE_SHIFT 9 +#define DRIVE_MASK (7 << DRIVE_SHIFT) +# define DRIVE_0 (1 << DRIVE_SHIFT) +# define DRIVE_1 (2 << DRIVE_SHIFT) +# define DRIVE_2 (3 << DRIVE_SHIFT) +# define DRIVE_3 (4 << DRIVE_SHIFT) -#define INPUT_PULLUP (INPUT | PULLUP) -#define INPUT_PULLDOWN (INPUT | PULLDOWN) -#define OUTPUT_OPEN_DRAIN (OUTPUT | OPEN_DRAIN) -#define INPUT_FUNCTION (INPUT | FUNCTION) -# define INPUT_FUNCTION_1 (INPUT_FUNCTION | FUNCTION_1) -# define INPUT_FUNCTION_2 (INPUT_FUNCTION | FUNCTION_2) -# define INPUT_FUNCTION_3 (INPUT_FUNCTION | FUNCTION_3) -# define INPUT_FUNCTION_4 (INPUT_FUNCTION | FUNCTION_4) -# define INPUT_FUNCTION_5 (INPUT_FUNCTION | FUNCTION_5) -# define INPUT_FUNCTION_6 (INPUT_FUNCTION | FUNCTION_6) -# define INPUT_FUNCTION_RTC (INPUT_FUNCTION | FUNCTION_RTC) -#define OUTPUT_FUNCTION (OUTPUT | FUNCTION) -# define OUTPUT_FUNCTION_1 (OUTPUT_FUNCTION | FUNCTION_1) -# define OUTPUT_FUNCTION_2 (OUTPUT_FUNCTION | FUNCTION_2) -# define OUTPUT_FUNCTION_3 (OUTPUT_FUNCTION | FUNCTION_3) -# define OUTPUT_FUNCTION_4 (OUTPUT_FUNCTION | FUNCTION_4) -# define OUTPUT_FUNCTION_5 (OUTPUT_FUNCTION | FUNCTION_5) -# define OUTPUT_FUNCTION_6 (OUTPUT_FUNCTION | FUNCTION_6) -# define OUTPUT_FUNCTION_RTC (OUTPUT_FUNCTION | FUNCTION_RTC) +#define INPUT_PULLUP (INPUT | PULLUP) +#define INPUT_PULLDOWN (INPUT | PULLDOWN) +#define OUTPUT_OPEN_DRAIN (OUTPUT | OPEN_DRAIN) +#define INPUT_FUNCTION (INPUT | FUNCTION) +# define INPUT_FUNCTION_1 (INPUT_FUNCTION | FUNCTION_1) +# define INPUT_FUNCTION_2 (INPUT_FUNCTION | FUNCTION_2) +# define INPUT_FUNCTION_3 (INPUT_FUNCTION | FUNCTION_3) +# define INPUT_FUNCTION_4 (INPUT_FUNCTION | FUNCTION_4) +# define INPUT_FUNCTION_5 (INPUT_FUNCTION | FUNCTION_5) +# define INPUT_FUNCTION_6 (INPUT_FUNCTION | FUNCTION_6) +#define OUTPUT_FUNCTION (OUTPUT | FUNCTION) +# define OUTPUT_FUNCTION_1 (OUTPUT_FUNCTION | FUNCTION_1) +# define OUTPUT_FUNCTION_2 (OUTPUT_FUNCTION | FUNCTION_2) +# define OUTPUT_FUNCTION_3 (OUTPUT_FUNCTION | FUNCTION_3) +# define OUTPUT_FUNCTION_4 (OUTPUT_FUNCTION | FUNCTION_4) +# define OUTPUT_FUNCTION_5 (OUTPUT_FUNCTION | FUNCTION_5) +# define OUTPUT_FUNCTION_6 (OUTPUT_FUNCTION | FUNCTION_6) /* Interrupt type used with esp32_gpioirqenable() */ diff --git a/arch/xtensa/src/esp32/esp32_irq.c b/arch/xtensa/src/esp32/esp32_irq.c index 616f046042..ba90c9efd4 100644 --- a/arch/xtensa/src/esp32/esp32_irq.c +++ b/arch/xtensa/src/esp32/esp32_irq.c @@ -42,6 +42,7 @@ #include "esp32_smp.h" #include "esp32_gpio.h" +#include "esp32_rtc_gpio.h" #include "esp32_irq.h" @@ -497,6 +498,10 @@ void up_irqinitialize(void) esp32_gpioirqinitialize(0); #endif + /* Initialize RTCIO interrupt support */ + + esp32_rtcioirqinitialize(); + #ifndef CONFIG_SUPPRESS_INTERRUPTS /* And finally, enable interrupts. Also clears PS.EXCM */ diff --git a/arch/xtensa/src/esp32/esp32_rtc_gpio.c b/arch/xtensa/src/esp32/esp32_rtc_gpio.c new file mode 100644 index 0000000000..9aad6837b6 --- /dev/null +++ b/arch/xtensa/src/esp32/esp32_rtc_gpio.c @@ -0,0 +1,418 @@ +/**************************************************************************** + * arch/xtensa/src/esp32/esp32_rtc_gpio.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "xtensa.h" +#include "esp32_irq.h" +#include "esp32_rtc_gpio.h" +#include "hardware/esp32_pinmap.h" +#include "hardware/esp32_rtc_io.h" +#include "hardware/esp32_sens.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define setbits(a, bs) modifyreg32(a, 0, bs) +#define resetbits(a, bs) modifyreg32(a, bs, 0) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +enum rtcio_lh_out_mode_e +{ + RTCIO_OUTPUT_NORMAL = 0, /* RTCIO output mode is normal. */ + RTCIO_OUTPUT_OD = 0x1, /* RTCIO output mode is open-drain. */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_ESP32_RTCIO_IRQ +static int g_rtcio_cpuint; +#endif + +static const uint32_t rtc_gpio_to_addr[] = +{ + RTC_GPIO_PIN0_REG, + RTC_GPIO_PIN1_REG, + RTC_GPIO_PIN2_REG, + RTC_GPIO_PIN3_REG, + RTC_GPIO_PIN4_REG, + RTC_GPIO_PIN5_REG, + RTC_GPIO_PIN6_REG, + RTC_GPIO_PIN7_REG, + RTC_GPIO_PIN8_REG, + RTC_GPIO_PIN9_REG, + RTC_GPIO_PIN10_REG, + RTC_GPIO_PIN11_REG, + RTC_GPIO_PIN12_REG, + RTC_GPIO_PIN13_REG, + RTC_GPIO_PIN14_REG, + RTC_GPIO_PIN15_REG, + RTC_GPIO_PIN16_REG, + RTC_GPIO_PIN17_REG +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: is_valid_rtc_gpio + * + * Description: + * Determine if the specified rtcio_num is a valid RTC GPIO. + * + * Input Parameters: + * rtcio_num - RTC GPIO to be checked. + * + * Returned Value: + * True if valid. False otherwise. + * + ****************************************************************************/ + +static inline bool is_valid_rtc_gpio(uint32_t rtcio_num) +{ + return (rtcio_num < RTC_GPIO_NUMBER); +} + +/**************************************************************************** + * Name: rtcio_dispatch + * + * Description: + * Second level dispatch for RTC interrupt handling. + * + * Input Parameters: + * irq - The IRQ number; + * status - The interruption status register; + * context - The interruption context. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32_RTCIO_IRQ +static void rtcio_dispatch(int irq, uint32_t status, uint32_t *context) +{ + uint32_t mask; + int i; + + /* Check each bit in the status register */ + + for (i = 0; i < ESP32_NIRQ_RTCIO_PERIPH && status != 0; i++) + { + /* Check if there is an interrupt pending for this type */ + + mask = (UINT32_C(1) << i); + if ((status & mask) != 0) + { + /* Yes... perform the second level dispatch */ + + irq_dispatch(irq + i, context); + + /* Clear the bit in the status so that we might execute this loop + * sooner. + */ + + status &= ~mask; + } + } +} +#endif + +/**************************************************************************** + * Name: rtcio_interrupt + * + * Description: + * RTC interrupt handler. + * + * Input Parameters: + * irq - The IRQ number; + * context - The interruption context; + * args - The arguments passed to the handler. + * + * Returned Value: + * Zero (OK). + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32_RTCIO_IRQ +static int rtcio_interrupt(int irq, void *context, void *arg) +{ + uint32_t status; + + /* Read and clear the lower RTC interrupt status */ + + status = getreg32(RTC_CNTL_INT_ST_REG); + putreg32(status, RTC_CNTL_INT_CLR_REG); + + /* Dispatch pending interrupts in the RTC status register */ + + rtcio_dispatch(ESP32_FIRST_RTCIOIRQ_PERIPH, status, (uint32_t *)context); + + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32_configrtcio + * + * Description: + * Configure a RTCIO rtcio_num based on encoded rtcio_num attributes. + * + * Input Parameters: + * rtcio_num - RTC GPIO to be configured. + * attr - Attributes to be configured for the selected rtcio_num. + * The following attributes are accepted: + * - Direction (OUTPUT or INPUT) + * - Pull (PULLUP, PULLDOWN or OPENDRAIN) + * - Function (if not provided, assume function RTCIO by + * default) + * - Drive strength (if not provided, assume DRIVE_2 by + * default) + * + * Returned Value: + * Zero (OK) on success, or -1 (ERROR) in case of failure. + * + ****************************************************************************/ + +int esp32_configrtcio(int rtcio_num, rtcio_pinattr_t attr) +{ + ASSERT(is_valid_rtc_gpio(rtcio_num)); + + rtc_io_desc_t rtc_reg_desc = g_rtc_io_desc[rtcio_num]; + + /* Configure the pad's function */ + + if ((attr & RTC_FUNCTION_MASK) == RTC_FUNCTION_DIGITAL) + { + resetbits(rtc_reg_desc.reg, rtc_reg_desc.mux); + } + else + { + setbits(rtc_reg_desc.reg, rtc_reg_desc.mux); + + modifyreg32(rtc_reg_desc.reg, + ((RTC_IO_TOUCH_PAD1_FUN_SEL_V) << (rtc_reg_desc.func)), + (((RTCIO_PIN_FUNC) & RTC_IO_TOUCH_PAD1_FUN_SEL_V) << + (rtc_reg_desc.func))); + + if (rtc_reg_desc.pulldown) + { + if ((attr & RTC_PULLDOWN) != 0) + { + setbits(rtc_reg_desc.reg, rtc_reg_desc.pulldown); + } + else + { + resetbits(rtc_reg_desc.reg, rtc_reg_desc.pulldown); + } + } + + if (rtc_reg_desc.pullup) + { + if ((attr & RTC_PULLUP) != 0) + { + setbits(rtc_reg_desc.reg, rtc_reg_desc.pullup); + } + else + { + resetbits(rtc_reg_desc.reg, rtc_reg_desc.pullup); + } + } + + if ((attr & RTC_INPUT) != 0) + { + /* Enable Input */ + + setbits(rtc_reg_desc.reg, rtc_reg_desc.ie); + + /* Disable Output */ + + REG_SET_FIELD(RTC_GPIO_ENABLE_W1TC_REG, + RTC_GPIO_ENABLE_W1TC, + (UINT32_C(1) << rtcio_num)); + } + else if ((attr & RTC_OUTPUT) != 0) + { + /* Disable Input */ + + resetbits(rtc_reg_desc.reg, rtc_reg_desc.ie); + + /* Enable Output */ + + REG_SET_FIELD(RTC_GPIO_ENABLE_W1TS_REG, + RTC_GPIO_ENABLE_W1TS, + (UINT32_C(1) << rtcio_num)); + } + else + { + resetbits(rtc_reg_desc.reg, rtc_reg_desc.ie); + REG_SET_FIELD(RTC_GPIO_ENABLE_W1TC_REG, + RTC_GPIO_ENABLE_W1TC, + (UINT32_C(1) << rtcio_num)); + } + + if ((attr & RTC_DRIVE_MASK) != 0) + { + if (rtc_reg_desc.drv_v) + { + uint32_t val = ((attr & RTC_DRIVE_MASK) >> + RTC_DRIVE_SHIFT) - 1; + modifyreg32(rtc_reg_desc.reg, + ((rtc_reg_desc.drv_v) << (rtc_reg_desc.drv_s)), + (((val) & rtc_reg_desc.drv_v) << (rtc_reg_desc.drv_s))); + } + } + + if ((attr & RTC_OPEN_DRAIN) != 0) + { + /* All RTC GPIOs have the same position for the drive bits. + * We can use any RTC_GPIO_PINn_PAD_DRIVER. + */ + + REG_SET_FIELD(rtc_gpio_to_addr[rtcio_num], + RTC_GPIO_PIN0_PAD_DRIVER, + RTCIO_OUTPUT_OD); + } + else + { + REG_SET_FIELD(rtc_gpio_to_addr[rtcio_num], + RTC_GPIO_PIN0_PAD_DRIVER, + RTCIO_OUTPUT_NORMAL); + } + } + + return OK; +} + +/**************************************************************************** + * Name: esp32_rtcioirqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for + * RTC interruptions. + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32_RTCIO_IRQ +void esp32_rtcioirqinitialize(void) +{ + /* Setup the RTCIO interrupt. */ + + int cpu = up_cpu_index(); + g_rtcio_cpuint = esp32_setup_irq(cpu, ESP32_PERIPH_RTC_CORE, + 1, ESP32_CPUINT_LEVEL); + DEBUGASSERT(g_rtcio_cpuint >= 0); + + /* Attach and enable the interrupt handler */ + + DEBUGVERIFY(irq_attach(ESP32_IRQ_RTC_CORE, rtcio_interrupt, NULL)); + up_enable_irq(ESP32_IRQ_RTC_CORE); +} +#endif + +/**************************************************************************** + * Name: esp32_rtcioirqenable + * + * Description: + * Enable the interrupt for a specified RTC IRQ + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32_RTCIO_IRQ +void esp32_rtcioirqenable(int irq) +{ + uintptr_t regaddr = RTC_CNTL_INT_ENA_REG; + uint32_t regval; + int bit; + + DEBUGASSERT(irq >= ESP32_FIRST_RTCIOIRQ_PERIPH && + irq <= ESP32_LAST_RTCIOIRQ_PERIPH); + + /* Convert the IRQ number to the corresponding bit */ + + bit = irq - ESP32_FIRST_RTCIOIRQ_PERIPH; + + /* Get the address of the GPIO PIN register for this pin */ + + up_disable_irq(ESP32_IRQ_RTC_CORE); + + regval = getreg32(regaddr) | (UINT32_C(1) << bit); + putreg32(regval, regaddr); + + up_enable_irq(ESP32_IRQ_RTC_CORE); +} +#endif + +/**************************************************************************** + * Name: esp32_rtcioirqdisable + * + * Description: + * Disable the interrupt for a specified RTC IRQ + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32_RTCIO_IRQ +void esp32_rtcioirqdisable(int irq) +{ + uintptr_t regaddr = RTC_CNTL_INT_ENA_REG; + uint32_t regval; + int bit; + + DEBUGASSERT(irq >= ESP32_FIRST_RTCIOIRQ_PERIPH && + irq <= ESP32_LAST_RTCIOIRQ_PERIPH); + + /* Convert the IRQ number to the corresponding bit */ + + bit = irq - ESP32_FIRST_RTCIOIRQ_PERIPH; + + /* Disable IRQ */ + + up_disable_irq(ESP32_IRQ_RTC_CORE); + + regval = getreg32(regaddr) & (~(UINT32_C(1) << bit)); + putreg32(regval, regaddr); + + up_enable_irq(ESP32_IRQ_RTC_CORE); +} +#endif diff --git a/arch/xtensa/src/esp32/esp32_rtc_gpio.h b/arch/xtensa/src/esp32/esp32_rtc_gpio.h index 62faeb8e2c..bad6cd4a50 100644 --- a/arch/xtensa/src/esp32/esp32_rtc_gpio.h +++ b/arch/xtensa/src/esp32/esp32_rtc_gpio.h @@ -38,7 +38,38 @@ #define SPECIAL_RTC_PU_BIT (1 << 22) #define SPECIAL_RTC_PD_BIT (1 << 23) -#define RTCIO_PIN_FUNC 0 +#define RTCIO_PIN_FUNC 0 + +#define RTC_MODE_SHIFT 0 +#define RTC_MODE_MASK (3 << RTC_MODE_SHIFT) +# define RTC_INPUT (1 << (RTC_MODE_SHIFT + 0)) +# define RTC_OUTPUT (1 << (RTC_MODE_SHIFT + 1)) + +#define RTC_PULL_SHIFT 2 +#define RTC_PULL_MASK (7 << RTC_PULL_SHIFT) +# define RTC_PULLUP (1 << (RTC_PULL_SHIFT + 0)) +# define RTC_PULLDOWN (1 << (RTC_PULL_SHIFT + 1)) +# define RTC_OPEN_DRAIN (1 << (RTC_PULL_SHIFT + 2)) + +#define RTC_FUNCTION_SHIFT 5 +#define RTC_FUNCTION_MASK (3 << RTC_FUNCTION_SHIFT) +# define RTC_FUNCTION_RTCIO (1 << RTC_FUNCTION_SHIFT) +# define RTC_FUNCTION_DIGITAL (2 << RTC_FUNCTION_SHIFT) + +#define RTC_DRIVE_SHIFT 7 +#define RTC_DRIVE_MASK (7 << RTC_DRIVE_SHIFT) +# define RTC_DRIVE_0 (1 << RTC_DRIVE_SHIFT) +# define RTC_DRIVE_1 (2 << RTC_DRIVE_SHIFT) +# define RTC_DRIVE_2 (3 << RTC_DRIVE_SHIFT) +# define RTC_DRIVE_3 (4 << RTC_DRIVE_SHIFT) + +#define RTC_INPUT_PULLUP (RTC_INPUT | RTC_PULLUP) +#define RTC_INPUT_PULLDOWN (RTC_INPUT | RTC_PULLDOWN) +#define RTC_OUTPUT_OPEN_DRAIN (RTC_OUTPUT | RTC_OPEN_DRAIN) +#define RTC_INPUT_FUNCTION_RTCIO (RTC_INPUT | RTC_FUNCTION_RTCIO) +#define RTC_INPUT_FUNCTION_DIGITAL (RTC_INPUT | RTC_FUNCTION_DIGITAL) +#define RTC_OUTPUT_FUNCTION_RTCIO (RTC_OUTPUT | RTC_FUNCTION_RTCIO) +#define RTC_OUTPUT_FUNCTION_DIGITAL (RTC_OUTPUT | RTC_FUNCTION_DIGITAL) /* RTC GPIO channels */ @@ -102,7 +133,7 @@ * Public Types ****************************************************************************/ -typedef struct +typedef struct rtc_io_desc_s { uint32_t reg; /* Register of RTC pad, or 0 if not an RTC GPIO */ uint32_t mux; /* Bit mask for selecting digital pad or RTC pad */ @@ -124,11 +155,15 @@ typedef struct int rtc_num; /* GPIO number (corresponds to RTC pad) */ } rtc_io_desc_t; +/* Must be big enough to hold the pin attributes */ + +typedef uint16_t rtcio_pinattr_t; + /**************************************************************************** * Public Data ****************************************************************************/ -static const int g_rtc_io_num_map[GPIO_PIN_COUNT + 1] = +static const int g_gpio_to_rtcio_map[GPIO_PIN_COUNT + 1] = { RTCIO_GPIO0_CHANNEL, /* GPIO0 */ -1, /* GPIO1 not supported */ @@ -478,4 +513,75 @@ static const rtc_io_desc_t g_rtc_io_desc[RTC_GPIO_NUMBER] = } }; +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32_configrtcio + * + * Description: + * Configure a RTCIO pin based on encoded pin attributes. + * + * Input Parameters: + * rtcio_num - RTCIO pin to be configured. + * attr - Attributes to be configured for the selected RTCIO pin. + * The following attributes are accepted: + * - Direction (OUTPUT or INPUT) + * - Pull (PULLUP, PULLDOWN or OPENDRAIN) + * - Function (if not provided, assume function RTCIO by + * default) + * - Drive strength (if not provided, assume DRIVE_2 by + * default) + * + * Returned Value: + * Zero (OK) on success, or -1 (ERROR) in case of failure. + * + ****************************************************************************/ + +int esp32_configrtcio(int rtcio_num, rtcio_pinattr_t attr); + +/**************************************************************************** + * Name: esp32_rtcioirqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for + * RTC IRQs. + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32_RTCIO_IRQ +void esp32_rtcioirqinitialize(void); +#else +# define esp32_rtcioirqinitialize() +#endif + +/**************************************************************************** + * Name: esp32_rtcioirqenable + * + * Description: + * Enable the interrupt for the specified RTC peripheral IRQ + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32_RTCIO_IRQ +void esp32_rtcioirqenable(int irq); +#else +# define esp32_rtcioirqenable(irq) +#endif + +/**************************************************************************** + * Name: esp32_rtcioirqdisable + * + * Description: + * Disable the interrupt for the specified RTC peripheral IRQ + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32_RTCIO_IRQ +void esp32_rtcioirqdisable(int irq); +#else +# define esp32_rtcioirqdisable(irq) +#endif + #endif /* __ARCH_XTENSA_SRC_ESP32_ESP32_RTC_GPIO_H */ diff --git a/arch/xtensa/src/esp32/esp32_touch.c b/arch/xtensa/src/esp32/esp32_touch.c index bffca15673..4ecc24210d 100644 --- a/arch/xtensa/src/esp32/esp32_touch.c +++ b/arch/xtensa/src/esp32/esp32_touch.c @@ -51,7 +51,7 @@ #define TOUCH_PAD_FILTER_FACTOR_DEFAULT (4) /* IIR filter coefficient */ #define TOUCH_PAD_SHIFT_DEFAULT (4) /* Increase computing accuracy */ #define TOUCH_PAD_SHIFT_ROUND_DEFAULT (8) /* ROUND = 2^(n-1) */ -#define TOUCH_GET_IO_NUM(channel) (touch_channel_to_gpio[channel]) +#define TOUCH_GET_RTCIO_NUM(channel) (touch_channel_to_rtcio[channel]) /**************************************************************************** * Private Types @@ -540,8 +540,8 @@ static void touch_io_init(enum touch_pad_e tp) { DEBUGASSERT(tp < TOUCH_SENSOR_PINS); - uint8_t gpio_num = TOUCH_GET_IO_NUM(tp); - esp32_configgpio(gpio_num, FUNCTION_RTC); + uint8_t rtcio_num = TOUCH_GET_RTCIO_NUM(tp); + esp32_configrtcio(rtcio_num, RTC_FUNCTION_RTCIO); } /**************************************************************************** diff --git a/arch/xtensa/src/esp32/esp32_touch.h b/arch/xtensa/src/esp32/esp32_touch.h index 7dee46ae18..85d0e87f2a 100644 --- a/arch/xtensa/src/esp32/esp32_touch.h +++ b/arch/xtensa/src/esp32/esp32_touch.h @@ -72,18 +72,18 @@ struct touch_config_s * Public Data ****************************************************************************/ -static const uint8_t touch_channel_to_gpio[] = +static const uint8_t touch_channel_to_rtcio[] = { - TOUCH_PAD_NUM0_GPIO_NUM, - TOUCH_PAD_NUM1_GPIO_NUM, - TOUCH_PAD_NUM2_GPIO_NUM, - TOUCH_PAD_NUM3_GPIO_NUM, - TOUCH_PAD_NUM4_GPIO_NUM, - TOUCH_PAD_NUM5_GPIO_NUM, - TOUCH_PAD_NUM6_GPIO_NUM, - TOUCH_PAD_NUM7_GPIO_NUM, - TOUCH_PAD_NUM8_GPIO_NUM, - TOUCH_PAD_NUM9_GPIO_NUM + TOUCH_PAD_NUM0_CHANNEL_NUM, + TOUCH_PAD_NUM1_CHANNEL_NUM, + TOUCH_PAD_NUM2_CHANNEL_NUM, + TOUCH_PAD_NUM3_CHANNEL_NUM, + TOUCH_PAD_NUM4_CHANNEL_NUM, + TOUCH_PAD_NUM5_CHANNEL_NUM, + TOUCH_PAD_NUM6_CHANNEL_NUM, + TOUCH_PAD_NUM7_CHANNEL_NUM, + TOUCH_PAD_NUM8_CHANNEL_NUM, + TOUCH_PAD_NUM9_CHANNEL_NUM }; #undef EXTERN diff --git a/arch/xtensa/src/esp32/esp32_wdt.c b/arch/xtensa/src/esp32/esp32_wdt.c index ef9381559b..1adb4e41d4 100644 --- a/arch/xtensa/src/esp32/esp32_wdt.c +++ b/arch/xtensa/src/esp32/esp32_wdt.c @@ -33,6 +33,7 @@ #include "esp32_wdt.h" #include "esp32_irq.h" #include "esp32_rtc.h" +#include "esp32_rtc_gpio.h" /**************************************************************************** * Pre-processor Definitions @@ -166,7 +167,7 @@ struct esp32_wdt_priv_s g_esp32_rwdt_priv = .ops = &esp32_rwdt_ops, .base = RTC_CNTL_OPTIONS0_REG, .periph = ESP32_PERIPH_RTC_CORE, /* Peripheral ID */ - .irq = ESP32_IRQ_RTC_CORE, /* Interrupt ID */ + .irq = ESP32_IRQ_RTC_WDT, /* Interrupt ID */ .cpuint = -ENOMEM, /* CPU interrupt assigned to this wdt */ .inuse = false, }; @@ -714,19 +715,28 @@ static int esp32_wdt_setisr(struct esp32_wdt_dev_s *dev, xcpt_t handler, { /* If a CPU Interrupt was previously allocated, then deallocate it */ - if (wdt->cpuint >= 0) +#ifdef CONFIG_ESP32_RWDT + if (wdt->irq == ESP32_IRQ_RTC_WDT) { - /* Disable CPU Interrupt, free a previously allocated - * CPU Interrupt - */ - - up_disable_irq(wdt->irq); - esp32_teardown_irq(wdt->cpu, wdt->periph, wdt->cpuint); + esp32_rtcioirqdisable(wdt->irq); irq_detach(wdt->irq); } + else +#endif + { + if (wdt->cpuint >= 0) + { + /* Disable CPU Interrupt, free a previously allocated + * CPU Interrupt + */ - ret = OK; - goto errout; + up_disable_irq(wdt->irq); + esp32_teardown_irq(wdt->cpu, wdt->periph, wdt->cpuint); + irq_detach(wdt->irq); + } + + goto errout; + } } /* Otherwise set callback and enable interrupt */ @@ -735,30 +745,48 @@ static int esp32_wdt_setisr(struct esp32_wdt_dev_s *dev, xcpt_t handler, { /* Set up to receive peripheral interrupts on the current CPU */ - wdt->cpu = up_cpu_index(); - wdt->cpuint = esp32_setup_irq(wdt->cpu, wdt->periph, - 1, ESP32_CPUINT_LEVEL); - if (wdt->cpuint < 0) +#ifdef CONFIG_ESP32_RWDT + if (wdt->irq == ESP32_IRQ_RTC_WDT) { - tmrerr("ERROR: No CPU Interrupt available"); - ret = wdt->cpuint; - goto errout; + ret = irq_attach(wdt->irq, handler, arg); + + if (ret != OK) + { + esp32_rtcioirqdisable(wdt->irq); + tmrerr("ERROR: Failed to associate an IRQ Number"); + goto errout; + } + + esp32_rtcioirqenable(wdt->irq); } - - /* Associate an IRQ Number (from the WDT) to an ISR */ - - ret = irq_attach(wdt->irq, handler, arg); - - if (ret != OK) + else +#endif { - esp32_teardown_irq(wdt->cpu, wdt->periph, wdt->cpuint); - tmrerr("ERROR: Failed to associate an IRQ Number"); - goto errout; + wdt->cpu = up_cpu_index(); + wdt->cpuint = esp32_setup_irq(wdt->cpu, wdt->periph, + 1, ESP32_CPUINT_LEVEL); + if (wdt->cpuint < 0) + { + tmrerr("ERROR: No CPU Interrupt available"); + ret = wdt->cpuint; + goto errout; + } + + /* Associate an IRQ Number (from the WDT) to an ISR */ + + ret = irq_attach(wdt->irq, handler, arg); + + if (ret != OK) + { + esp32_teardown_irq(wdt->cpu, wdt->periph, wdt->cpuint); + tmrerr("ERROR: Failed to associate an IRQ Number"); + goto errout; + } + + /* Enable the CPU Interrupt that is linked to the wdt */ + + up_enable_irq(wdt->irq); } - - /* Enable the CPU Interrupt that is linked to the wdt */ - - up_enable_irq(wdt->irq); } errout: diff --git a/arch/xtensa/src/esp32/hardware/esp32_touch.h b/arch/xtensa/src/esp32/hardware/esp32_touch.h index 05aa32ef95..752fd8e8af 100644 --- a/arch/xtensa/src/esp32/hardware/esp32_touch.h +++ b/arch/xtensa/src/esp32/hardware/esp32_touch.h @@ -34,16 +34,27 @@ /* Touch channel to GPIO */ -#define TOUCH_PAD_NUM0_GPIO_NUM 4 -#define TOUCH_PAD_NUM1_GPIO_NUM 0 -#define TOUCH_PAD_NUM2_GPIO_NUM 2 -#define TOUCH_PAD_NUM3_GPIO_NUM 15 -#define TOUCH_PAD_NUM4_GPIO_NUM 13 -#define TOUCH_PAD_NUM5_GPIO_NUM 12 -#define TOUCH_PAD_NUM6_GPIO_NUM 14 -#define TOUCH_PAD_NUM7_GPIO_NUM 27 -#define TOUCH_PAD_NUM8_GPIO_NUM 33 -#define TOUCH_PAD_NUM9_GPIO_NUM 32 +#define TOUCH_PAD_NUM0_GPIO_NUM 4 +#define TOUCH_PAD_NUM1_GPIO_NUM 0 +#define TOUCH_PAD_NUM2_GPIO_NUM 2 +#define TOUCH_PAD_NUM3_GPIO_NUM 15 +#define TOUCH_PAD_NUM4_GPIO_NUM 13 +#define TOUCH_PAD_NUM5_GPIO_NUM 12 +#define TOUCH_PAD_NUM6_GPIO_NUM 14 +#define TOUCH_PAD_NUM7_GPIO_NUM 27 +#define TOUCH_PAD_NUM8_GPIO_NUM 33 +#define TOUCH_PAD_NUM9_GPIO_NUM 32 + +#define TOUCH_PAD_NUM0_CHANNEL_NUM 10 +#define TOUCH_PAD_NUM1_CHANNEL_NUM 11 +#define TOUCH_PAD_NUM2_CHANNEL_NUM 12 +#define TOUCH_PAD_NUM3_CHANNEL_NUM 13 +#define TOUCH_PAD_NUM4_CHANNEL_NUM 14 +#define TOUCH_PAD_NUM5_CHANNEL_NUM 15 +#define TOUCH_PAD_NUM6_CHANNEL_NUM 16 +#define TOUCH_PAD_NUM7_CHANNEL_NUM 17 +#define TOUCH_PAD_NUM8_CHANNEL_NUM 8 +#define TOUCH_PAD_NUM9_CHANNEL_NUM 9 /**************************************************************************** * Public Types