diff --git a/components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_interrupt.h b/components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_interrupt.h new file mode 100644 index 0000000000..b452707379 --- /dev/null +++ b/components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_interrupt.h @@ -0,0 +1,44 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include +#include "esp_err.h" +#include "riscv/interrupt.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* ULP RISC-V Interrupt sources */ +typedef enum { + ULP_RISCV_MAX_INTR_SOURCE, /**< Total number of ULP RISC-V interrupt sources */ +} ulp_riscv_interrupt_source_t; + +/** + * @brief Allocate interrupt handler for a ULP RISC-V interrupt source + * + * @param source ULP RISC-V interrupt source + * @param handler Interrupt handler + * @param arg Interrupt handler argument + * + * @return esp_err_t ESP_OK when successful + */ +esp_err_t ulp_riscv_intr_alloc(ulp_riscv_interrupt_source_t source, intr_handler_t handler, void *arg); + +/** + * @brief Free ULP RISC-V interrupt handler + * + * @param source ULP RISC-V interrupt source + * + * @return esp_err_t ESP_OK when successful + */ +esp_err_t ulp_riscv_intr_free(ulp_riscv_interrupt_source_t source); + +#ifdef __cplusplus +} +#endif diff --git a/components/ulp/ulp_riscv/ulp_core/ulp_riscv_interrupt.c b/components/ulp/ulp_riscv/ulp_core/ulp_riscv_interrupt.c index b3a5e052de..1c105383fa 100644 --- a/components/ulp/ulp_riscv/ulp_core/ulp_riscv_interrupt.c +++ b/components/ulp/ulp_riscv/ulp_core/ulp_riscv_interrupt.c @@ -5,6 +5,7 @@ */ #include #include "ulp_riscv_register_ops.h" +#include "ulp_riscv_interrupt.h" #define ULP_RISCV_TIMER_INT (1 << 0U) /* Internal Timer Interrupt */ #define ULP_RISCV_EBREAK_ECALL_ILLEGAL_INSN_INT (1 << 1U) /* EBREAK, ECALL or Illegal instruction */ @@ -12,6 +13,50 @@ #define ULP_RISCV_PERIPHERAL_INTERRUPT (1 << 31U) /* RTC Peripheral Interrupt */ #define ULP_RISCV_INTERNAL_INTERRUPT (ULP_RISCV_TIMER_INT | ULP_RISCV_EBREAK_ECALL_ILLEGAL_INSN_INT | ULP_RISCV_BUS_ERROR_INT) +/* Interrupt handler structure */ +typedef struct { + intr_handler_t handler; + void *arg; +} ulp_riscv_intr_handler_t; + +/* Statically store all interrupt handlers */ +static ulp_riscv_intr_handler_t s_intr_handlers[ULP_RISCV_MAX_INTR_SOURCE]; + +esp_err_t ulp_riscv_intr_alloc(ulp_riscv_interrupt_source_t source, intr_handler_t handler, void *arg) +{ + /* Check the validity of the interrupt source */ + if (source < 0 || source >= ULP_RISCV_MAX_INTR_SOURCE || handler == NULL) { + return ESP_ERR_INVALID_ARG; + } + + /* Register interrupt handler */ + if (s_intr_handlers[source].handler == NULL) { + s_intr_handlers[source].handler = handler; + s_intr_handlers[source].arg = arg; + } else { + /* Error: The interrupt handler for this interrupt source has already been allocated */ + return ESP_ERR_NOT_FOUND; + } + + return ESP_OK; +} + +esp_err_t ulp_riscv_intr_free(ulp_riscv_interrupt_source_t source) +{ + /* Check the validity of the interrupt source */ + if (source < 0 || source >= ULP_RISCV_MAX_INTR_SOURCE) { + return ESP_ERR_INVALID_ARG; + } + + /* De-register interrupt handler */ + if (s_intr_handlers[source].handler != NULL) { + s_intr_handlers[source].handler = NULL; + s_intr_handlers[source].arg = NULL; + } + + return ESP_OK; +} + /* This is the global interrupt handler for ULP RISC-V. * It is called from ulp_riscv_vectors.S */ @@ -26,12 +71,10 @@ void __attribute__((weak)) _ulp_riscv_interrupt_handler(uint32_t q1) /* External/Peripheral interrupts */ if (q1 & ULP_RISCV_PERIPHERAL_INTERRUPT) { - // TODO + /* TODO: RTC Peripheral interrupts */ - /* Peripheral interrupts */ + /* TODO: RTC IO interrupts */ - /* RTC I2C interrupt */ - - /* RTC IO interrupt */ + /* TODO: RTC I2C interrupt */ } }