arch/xtensa/esp32: Add support for RTC IRQs
This commit is contained in:
parent
454570532e
commit
39162ebafb
@ -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.
|
||||
*
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -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() */
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
418
arch/xtensa/src/esp32/esp32_rtc_gpio.c
Normal file
418
arch/xtensa/src/esp32/esp32_rtc_gpio.c
Normal file
@ -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 <nuttx/config.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <arch/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#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
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user