diff --git a/arch/risc-v/src/common/espressif/Kconfig b/arch/risc-v/src/common/espressif/Kconfig index 52c5eb5f2e0..f4dd88ece0e 100644 --- a/arch/risc-v/src/common/espressif/Kconfig +++ b/arch/risc-v/src/common/espressif/Kconfig @@ -302,6 +302,13 @@ config ESPRESSIF_GPIO_IRQ ---help--- Enable support for interrupting GPIO pins +config ESPRESSIF_RTCIO_IRQ + bool "RTC IO interrupts" + default n + depends on !ARCH_CHIP_ESP32H2 && !ARCH_CHIP_ESP32C6 + ---help--- + Enable support for RTC peripherals interrupts. + config ESPRESSIF_LEDC bool "LEDC (PWM)" default n diff --git a/arch/risc-v/src/common/espressif/Make.defs b/arch/risc-v/src/common/espressif/Make.defs index 5783dcbf178..c902fa8a98c 100644 --- a/arch/risc-v/src/common/espressif/Make.defs +++ b/arch/risc-v/src/common/espressif/Make.defs @@ -31,7 +31,7 @@ CHIP_ASRCS = esp_vectors.S # Required Espressif chip's files (arch/risc-v/src/common/espressif) CHIP_CSRCS = esp_allocateheap.c esp_start.c esp_idle.c -CHIP_CSRCS += esp_irq.c esp_gpio.c esp_libc_stubs.c +CHIP_CSRCS += esp_irq.c esp_gpio.c esp_rtc_gpio.c esp_libc_stubs.c CHIP_CSRCS += esp_lowputc.c esp_serial.c CHIP_CSRCS += esp_systemreset.c @@ -107,7 +107,7 @@ endif ESP_HAL_3RDPARTY_REPO = esp-hal-3rdparty ifndef ESP_HAL_3RDPARTY_VERSION - ESP_HAL_3RDPARTY_VERSION = 581540ed0a5ce9674da44f9ece6a63d052058985 + ESP_HAL_3RDPARTY_VERSION = ee8c7b0ad6a117465312d4c9a6e654cb7b2b9469 endif ifndef ESP_HAL_3RDPARTY_URL diff --git a/arch/risc-v/src/common/espressif/esp_irq.c b/arch/risc-v/src/common/espressif/esp_irq.c index ca79bb204fd..749e80494aa 100644 --- a/arch/risc-v/src/common/espressif/esp_irq.c +++ b/arch/risc-v/src/common/espressif/esp_irq.c @@ -37,6 +37,7 @@ #include "esp_gpio.h" #include "esp_irq.h" +#include "esp_rtc_gpio.h" #include "esp_attr.h" #include "esp_bit_defs.h" @@ -320,6 +321,10 @@ void up_irqinitialize(void) esp_gpioirqinitialize(); #endif + /* Initialize RTCIO interrupt support */ + + esp_rtcioirqinitialize(); + /* Attach the common interrupt handler */ riscv_exception_attach(); diff --git a/arch/risc-v/src/common/espressif/esp_rtc_gpio.c b/arch/risc-v/src/common/espressif/esp_rtc_gpio.c new file mode 100644 index 00000000000..62dc537bd6b --- /dev/null +++ b/arch/risc-v/src/common/espressif/esp_rtc_gpio.c @@ -0,0 +1,264 @@ +/**************************************************************************** + * arch/risc-v/src/common/espressif/esp_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 "irq.h" +#include "riscv_internal.h" +#include "esp_irq.h" +#include "esp_rtc_gpio.h" +#include "soc/rtc_io_periph.h" +#include "hal/rtc_io_hal.h" +#include "soc/rtc_cntl_periph.h" +#include "soc/periph_defs.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_ARCH_CHIP_ESP32C3_GENERIC +#ifdef CONFIG_ESPRESSIF_RTCIO_IRQ +static int g_rtcio_cpuint; +static uint32_t last_status; + +#ifdef CONFIG_ARCH_CHIP_ESP32C3_GENERIC +static const int rtc_irq_reg_shift[ESP_NIRQ_RTCIO] = +{ + RTC_CNTL_SLP_WAKEUP_INT_ENA_S, + RTC_CNTL_SLP_REJECT_INT_ENA_S, + RTC_CNTL_WDT_INT_ENA_S, + RTC_CNTL_BROWN_OUT_INT_ENA_S, + RTC_CNTL_MAIN_TIMER_INT_ENA_S, + RTC_CNTL_SWD_INT_ENA_S, + RTC_CNTL_XTAL32K_DEAD_INT_ENA_S, + RTC_CNTL_GLITCH_DET_INT_ENA_S, + RTC_CNTL_BBPLL_CAL_INT_ENA_S +}; +#define RTC_IRQ_REG_SHIFT(x) rtc_irq_reg_shift[x] +#endif /* CONFIG_ARCH_CHIP_ESP32C3 */ +#endif /* CONFIG_ESPRESSIF_RTCIO_IRQ */ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rtcio_dispatch + * + * Description: + * Second level dispatch for the RTC interrupt. + * + * Input Parameters: + * irq - The IRQ number; + * reg_status - Pointer to a copy of the interrupt status register. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_ESPRESSIF_RTCIO_IRQ +static void rtcio_dispatch(int irq, uint32_t *reg_status) +{ + uint32_t status = *reg_status; + uint32_t mask; + int i; + + /* Check each bit in the status register */ + + for (i = 0; i < ESP_NIRQ_RTCIO && status != 0; i++) + { + /* Check if there is an interrupt pending for this type */ + + mask = (UINT32_C(1) << RTC_IRQ_REG_SHIFT(i)); + if ((status & mask) != 0) + { + /* Yes... perform the second level dispatch. The IRQ context will + * contain the contents of the status register. + */ + + irq_dispatch(irq + i, (void *)reg_status); + + /* Clear the bit in the status so that we might execute this loop + * sooner. + */ + + status &= ~mask; + } + } +} + +/**************************************************************************** + * Name: rtcio_interrupt + * + * Description: + * RTC interrupt handler. + * + * Input Parameters: + * irq - The IRQ number; + * context - The interrupt context; + * args - The arguments passed to the handler. + * + * Returned Value: + * Zero (OK). + * + ****************************************************************************/ + +static int rtcio_interrupt(int irq, void *context, void *arg) +{ + /* Read and clear the lower RTC interrupt status */ + + last_status = getreg32(RTC_CNTL_INT_ST_REG); + putreg32(last_status, RTC_CNTL_INT_CLR_REG); + + /* Dispatch pending interrupts in the RTC status register */ + + rtcio_dispatch(ESP_FIRST_RTCIOIRQ, &last_status); + + return OK; +} +#endif /* CONFIG_ESPRESSIF_RTCIO_IRQ */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_rtcioirqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for + * RTC IRQs. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_ESPRESSIF_RTCIO_IRQ +void esp_rtcioirqinitialize(void) +{ + /* Setup the RTCIO interrupt. */ + + g_rtcio_cpuint = esp_setup_irq(ETS_RTC_CORE_INTR_SOURCE, + 1, ESP_IRQ_TRIGGER_LEVEL); + DEBUGASSERT(g_rtcio_cpuint >= 0); + + /* Attach and enable the interrupt handler */ + + DEBUGVERIFY(irq_attach(ESP_IRQ_RTC_CORE, rtcio_interrupt, NULL)); + up_enable_irq(ESP_IRQ_RTC_CORE); +} + +/**************************************************************************** + * Name: esp_rtcioirqenable + * + * Description: + * Enable the interrupt for the specified RTC peripheral IRQ. + * + * Input Parameters: + * irq - The IRQ number. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp_rtcioirqenable(int irq) +{ + uintptr_t regaddr = RTC_CNTL_INT_ENA_REG; + uint32_t regval; + int bit; + + DEBUGASSERT(irq >= ESP_FIRST_RTCIOIRQ && + irq <= ESP_LAST_RTCIOIRQ); + + /* Convert the IRQ number to the corresponding bit */ + + bit = RTC_IRQ_REG_SHIFT(irq - ESP_FIRST_RTCIOIRQ); + + /* Get the address of the GPIO PIN register for this pin */ + + up_disable_irq(ESP_IRQ_RTC_CORE); + + regval = getreg32(regaddr) | (UINT32_C(1) << bit); + putreg32(regval, regaddr); + + up_enable_irq(ESP_IRQ_RTC_CORE); +} + +/**************************************************************************** + * Name: esp_rtcioirqdisable + * + * Description: + * Disable the interrupt for the specified RTC peripheral IRQ. + * + * Input Parameters: + * irq - The IRQ number. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp_rtcioirqdisable(int irq) +{ + uintptr_t regaddr = RTC_CNTL_INT_ENA_REG; + uint32_t regval; + int bit; + + DEBUGASSERT(irq >= ESP_FIRST_RTCIOIRQ && + irq <= ESP_LAST_RTCIOIRQ); + + /* Convert the IRQ number to the corresponding bit */ + + bit = RTC_IRQ_REG_SHIFT(irq - ESP_FIRST_RTCIOIRQ); + + /* Disable IRQ */ + + up_disable_irq(ESP_IRQ_RTC_CORE); + + regval = getreg32(regaddr) & (~(UINT32_C(1) << bit)); + putreg32(regval, regaddr); + + up_enable_irq(ESP_IRQ_RTC_CORE); +} +#endif /* CONFIG_ESPRESSIF_RTCIO_IRQ */ +#endif /* CONFIG_ARCH_CHIP_ESP32C3_GENERIC */ diff --git a/arch/risc-v/src/common/espressif/esp_rtc_gpio.h b/arch/risc-v/src/common/espressif/esp_rtc_gpio.h new file mode 100644 index 00000000000..81535aa71f5 --- /dev/null +++ b/arch/risc-v/src/common/espressif/esp_rtc_gpio.h @@ -0,0 +1,113 @@ +/**************************************************************************** + * arch/risc-v/src/common/espressif/esp_rtc_gpio.h + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_RISC_V_SRC_COMMON_ESPRESSIF_ESP_RTC_GPIO_H +#define __ARCH_RISC_V_SRC_COMMON_ESPRESSIF_ESP_RTC_GPIO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_rtcioirqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for + * RTC IRQs. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_ESPRESSIF_RTCIO_IRQ +void esp_rtcioirqinitialize(void); +#else +# define esp_rtcioirqinitialize() +#endif + +/**************************************************************************** + * Name: esp_rtcioirqenable + * + * Description: + * Enable the interrupt for the specified RTC peripheral IRQ. + * + * Input Parameters: + * irq - The IRQ number. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_ESPRESSIF_RTCIO_IRQ +void esp_rtcioirqenable(int irq); +#else +# define esp_rtcioirqenable(irq) +#endif + +/**************************************************************************** + * Name: esp_rtcioirqdisable + * + * Description: + * Disable the interrupt for the specified RTC peripheral IRQ. + * + * Input Parameters: + * irq - The IRQ number. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#ifdef CONFIG_ESPRESSIF_RTCIO_IRQ +void esp_rtcioirqdisable(int irq); +#else +# define esp_rtcioirqdisable(irq) +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISC_V_SRC_COMMON_ESPRESSIF_ESP_RTC_GPIO_H */