feat(ulp-riscv): Added support for RTC IO interrupts for ULP RISC-V

This commit adds a feature to register RTC IO interrupt handlers for the
ULP RISC-V co-processor.
pull/13090/head
Sudeep Mohanty 2023-12-14 13:26:00 +01:00
rodzic b9ecc1e57a
commit 94e2516f6c
5 zmienionych plików z 120 dodań i 3 usunięć

Wyświetl plik

@ -66,6 +66,7 @@ if(ULP_COCPU_IS_RISCV)
"${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/ulp_riscv_i2c.c"
"${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/ulp_riscv_utils.c"
"${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/ulp_riscv_touch.c"
"${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/ulp_riscv_gpio.c"
"${IDF_PATH}/components/ulp/ulp_riscv/ulp_core/ulp_riscv_interrupt.c")
target_link_options(${ULP_APP_NAME} PRIVATE "-nostartfiles")

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -13,6 +13,7 @@ extern "C" {
#include "soc/rtc_io_reg.h"
#include "soc/sens_reg.h"
#include "ulp_riscv_register_ops.h"
#include "ulp_riscv_interrupt.h"
typedef enum {
GPIO_NUM_0 = 0, /*!< GPIO0, input and output */
@ -35,10 +36,21 @@ typedef enum {
GPIO_NUM_17 = 17, /*!< GPIO17, input and output */
GPIO_NUM_18 = 18, /*!< GPIO18, input and output */
GPIO_NUM_19 = 19, /*!< GPIO19, input and output */
GPIO_NUM_20 = 20,
GPIO_NUM_20 = 20, /*!< GPIO20, input and output */
GPIO_NUM_21 = 21, /*!< GPIO21, input and output */
GPIO_NUM_MAX,
} gpio_num_t;
typedef enum {
ULP_RISCV_GPIO_INTR_DISABLE = 0, /*!< Disable RTC GPIO interrupt */
ULP_RISCV_GPIO_INTR_POSEDGE = 1, /*!< RTC GPIO interrupt type : rising edge */
ULP_RISCV_GPIO_INTR_NEGEDGE = 2, /*!< RTC GPIO interrupt type : falling edge */
ULP_RISCV_GPIO_INTR_ANYEDGE = 3, /*!< RTC GPIO interrupt type : both rising and falling edge */
ULP_RISCV_GPIO_INTR_LOW_LEVEL = 4, /*!< RTC GPIO interrupt type : input low level trigger */
ULP_RISCV_GPIO_INTR_HIGH_LEVEL = 5, /*!< RTC GPIO interrupt type : input high level trigger */
ULP_RISCV_GPIO_INTR_MAX
} ulp_riscv_gpio_int_type_t;
typedef enum {
RTCIO_MODE_OUTPUT = 0,
RTCIO_MODE_OUTPUT_OD = 1,
@ -119,6 +131,27 @@ static inline void ulp_riscv_gpio_pulldown_disable(gpio_num_t gpio_num)
CLEAR_PERI_REG_MASK(RTC_IO_TOUCH_PAD0_REG + gpio_num*4, RTC_IO_TOUCH_PAD0_RDE);
}
/**
* @brief Set RTC IO interrupt type and handler
*
* @param gpio_num GPIO number
* @param intr_type Interrupt type (See rtc_io_types.h)
* @param handler Interrupt handler
* @param arg Interrupt handler argument
*
* @return ESP_OK on success
*/
esp_err_t ulp_riscv_gpio_isr_register(gpio_num_t gpio_num, ulp_riscv_gpio_int_type_t intr_type, intr_handler_t handler, void *arg);
/**
* @brief Remove RTC IO interrupt handler
*
* @param gpio_num GPIO number
*
* @return ESP_OK on success
*/
esp_err_t ulp_riscv_gpio_isr_deregister(gpio_num_t gpio_num);
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -17,6 +17,28 @@ extern "C"
/* ULP RISC-V Interrupt sources */
typedef enum {
ULP_RISCV_SW_INTR_SOURCE = 0, /**< Interrupt triggered by SW */
ULP_RISCV_RTCIO0_INTR_SOURCE, /**< Interrupt triggered by RTCIO 0 */
ULP_RISCV_RTCIO1_INTR_SOURCE, /**< Interrupt triggered by RTCIO 1 */
ULP_RISCV_RTCIO2_INTR_SOURCE, /**< Interrupt triggered by RTCIO 2 */
ULP_RISCV_RTCIO3_INTR_SOURCE, /**< Interrupt triggered by RTCIO 3 */
ULP_RISCV_RTCIO4_INTR_SOURCE, /**< Interrupt triggered by RTCIO 4 */
ULP_RISCV_RTCIO5_INTR_SOURCE, /**< Interrupt triggered by RTCIO 5 */
ULP_RISCV_RTCIO6_INTR_SOURCE, /**< Interrupt triggered by RTCIO 6 */
ULP_RISCV_RTCIO7_INTR_SOURCE, /**< Interrupt triggered by RTCIO 7 */
ULP_RISCV_RTCIO8_INTR_SOURCE, /**< Interrupt triggered by RTCIO 8 */
ULP_RISCV_RTCIO9_INTR_SOURCE, /**< Interrupt triggered by RTCIO 9 */
ULP_RISCV_RTCIO10_INTR_SOURCE, /**< Interrupt triggered by RTCIO 10 */
ULP_RISCV_RTCIO11_INTR_SOURCE, /**< Interrupt triggered by RTCIO 11 */
ULP_RISCV_RTCIO12_INTR_SOURCE, /**< Interrupt triggered by RTCIO 12 */
ULP_RISCV_RTCIO13_INTR_SOURCE, /**< Interrupt triggered by RTCIO 13 */
ULP_RISCV_RTCIO14_INTR_SOURCE, /**< Interrupt triggered by RTCIO 14 */
ULP_RISCV_RTCIO15_INTR_SOURCE, /**< Interrupt triggered by RTCIO 15 */
ULP_RISCV_RTCIO16_INTR_SOURCE, /**< Interrupt triggered by RTCIO 16 */
ULP_RISCV_RTCIO17_INTR_SOURCE, /**< Interrupt triggered by RTCIO 17 */
ULP_RISCV_RTCIO18_INTR_SOURCE, /**< Interrupt triggered by RTCIO 18 */
ULP_RISCV_RTCIO19_INTR_SOURCE, /**< Interrupt triggered by RTCIO 19 */
ULP_RISCV_RTCIO20_INTR_SOURCE, /**< Interrupt triggered by RTCIO 20 */
ULP_RISCV_RTCIO21_INTR_SOURCE, /**< Interrupt triggered by RTCIO 21 */
ULP_RISCV_MAX_INTR_SOURCE, /**< Total number of ULP RISC-V interrupt sources */
} ulp_riscv_interrupt_source_t;

Wyświetl plik

@ -0,0 +1,33 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "ulp_riscv_gpio.h"
#include "include/ulp_riscv_gpio.h"
esp_err_t ulp_riscv_gpio_isr_register(gpio_num_t gpio_num, ulp_riscv_gpio_int_type_t intr_type, intr_handler_t handler, void *arg)
{
if (gpio_num < 0 || gpio_num >= GPIO_NUM_MAX) {
return ESP_ERR_INVALID_ARG;
}
if (intr_type < 0 || intr_type >= ULP_RISCV_GPIO_INTR_MAX) {
return ESP_ERR_INVALID_ARG;
}
if (!handler) {
return ESP_ERR_INVALID_ARG;
}
/* Set the interrupt type */
REG_SET_FIELD(RTC_GPIO_PIN0_REG + 4*gpio_num, RTC_GPIO_PIN0_INT_TYPE, intr_type);
/* Set the interrupt handler */
return ulp_riscv_intr_alloc(ULP_RISCV_RTCIO0_INTR_SOURCE + gpio_num, handler, arg);
}
esp_err_t ulp_riscv_gpio_isr_deregister(gpio_num_t gpio_num)
{
return ulp_riscv_intr_free(ULP_RISCV_RTCIO0_INTR_SOURCE + gpio_num);
}

Wyświetl plik

@ -4,8 +4,10 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "include/ulp_riscv_interrupt.h"
#include "ulp_riscv_register_ops.h"
#include "ulp_riscv_interrupt.h"
#include "ulp_riscv_gpio.h"
#include "soc/sens_reg.h"
#define ULP_RISCV_TIMER_INT (1 << 0U) /* Internal Timer Interrupt */
@ -77,6 +79,28 @@ static inline void ulp_riscv_handle_rtc_periph_intr(uint32_t status)
}
}
/* This function -
* - Checks if one or more RTC IO interrupt status bits are set
* - Calls the interrupt handler for the RTC IO if it is registered
* - Clears all interrupt bits
*/
static inline void ulp_riscv_handle_rtc_io_intr(uint32_t status)
{
uint32_t handler_idx = 0;
for (int i = 0; i < GPIO_NUM_MAX; i++) {
if (status & (1U << i)) {
handler_idx = ULP_RISCV_RTCIO0_INTR_SOURCE + i;
ulp_riscv_intr_handler_t* entry = &s_intr_handlers[handler_idx];
if (entry->handler) {
entry->handler(entry->arg);
}
}
}
REG_SET_FIELD(RTC_GPIO_STATUS_W1TC_REG, RTC_GPIO_STATUS_INT_W1TC, status);
}
/* This is the global interrupt handler for ULP RISC-V.
* It is called from ulp_riscv_vectors.S
*/
@ -97,7 +121,11 @@ void __attribute__((weak)) _ulp_riscv_interrupt_handler(uint32_t q1)
ulp_riscv_handle_rtc_periph_intr(cocpu_int_st);
}
/* TODO: RTC IO interrupts */
/* RTC IO interrupts */
uint32_t rtcio_int_st = REG_GET_FIELD(RTC_GPIO_STATUS_REG, RTC_GPIO_STATUS_INT);
if (rtcio_int_st) {
ulp_riscv_handle_rtc_io_intr(rtcio_int_st);
}
/* TODO: RTC I2C interrupt */
}