From 6bd6afbd22fd1a3a44281c0ff3d6aa3f1fa2518e Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Sat, 25 Jun 2022 13:35:33 +0200 Subject: [PATCH 1/2] cpu/esp32: use ESP-IDF for interrupt handling --- cpu/esp32/include/irq_arch.h | 7 ++ cpu/esp32/irq_arch.c | 137 ++++++++++++++++++++++++----------- 2 files changed, 102 insertions(+), 42 deletions(-) diff --git a/cpu/esp32/include/irq_arch.h b/cpu/esp32/include/irq_arch.h index 2122a2cf8a8b..6c34bd85aafe 100644 --- a/cpu/esp32/include/irq_arch.h +++ b/cpu/esp32/include/irq_arch.h @@ -46,8 +46,15 @@ extern "C" { #define CPU_INUM_ETH 18 /**< Level interrupt with low priority 1 */ #define CPU_INUM_TIMER 19 /**< Level interrupt with medium priority 2 */ #define CPU_INUM_FRC2 20 /**< Level interrupt with medium priority 2 */ +#define CPU_INUM_SYSTIMER 20 /**< Level interrupt with medium priority 2 */ +#define CPU_INUM_CACHEERR 25 /**< Level interrupt with high priority 4 */ /** @} */ +/** + * @brief Initialize architecture specific interrupt handling + */ +void esp_irq_init(void); + #ifdef __cplusplus } #endif diff --git a/cpu/esp32/irq_arch.c b/cpu/esp32/irq_arch.c index e7b86e33ca70..37afa5d6778c 100644 --- a/cpu/esp32/irq_arch.c +++ b/cpu/esp32/irq_arch.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Gunar Schorcht + * Copyright (C) 2022 Gunar Schorcht * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -19,58 +19,101 @@ */ #include "irq_arch.h" + +#include "esp_attr.h" #include "esp_err.h" -#include "esp32/rom/ets_sys.h" -#include "soc/dport_reg.h" -#include "xtensa/xtensa_api.h" +#include "freertos/FreeRTOS.h" +#include "hal/interrupt_controller_types.h" +#include "hal/interrupt_controller_ll.h" +#include "rom/ets_sys.h" +#include "soc/periph_defs.h" +#include "esp_intr_alloc.h" #define ENABLE_DEBUG 0 #include "debug.h" -struct _irq_alloc_table_t { - int src; /* peripheral interrupt source */ - uint32_t intr; /* interrupt number */ +#ifndef ETS_CAN_INTR_SOURCE +#define ETS_CAN_INTR_SOURCE ETS_TWAI_INTR_SOURCE +#endif + +typedef struct intr_handle_data_t { + int src; /* peripheral interrupt source */ + uint8_t intr; /* interrupt number */ + uint8_t level; +} intr_handle_data_t; + +/* TODO change to a clearer approach */ +static const struct intr_handle_data_t _irq_data_table[] = { + { ETS_FROM_CPU_INTR0_SOURCE, CPU_INUM_SOFTWARE, 1 }, + { ETS_TG0_WDT_LEVEL_INTR_SOURCE, CPU_INUM_WDT, 1 }, + { ETS_TG0_T0_LEVEL_INTR_SOURCE, CPU_INUM_RTC, 1 }, +#if defined(MCU_ESP32) || defined(MCU_ESP32S2) || defined(MCU_ESP32S3) + { ETS_TG0_T1_LEVEL_INTR_SOURCE, CPU_INUM_TIMER, 2 }, +#endif +#if defined(MCU_ESP32) || defined(MCU_ESP32S2) + { ETS_TG0_LACT_LEVEL_INTR_SOURCE, CPU_INUM_TIMER, 2 }, +#endif +#if !defined(MCU_ESP32C2) + { ETS_TG1_T0_LEVEL_INTR_SOURCE, CPU_INUM_TIMER, 2 }, +#endif +#if defined(MCU_ESP32) || defined(MCU_ESP32S2) || defined(MCU_ESP32S3) + { ETS_TG1_T1_LEVEL_INTR_SOURCE, CPU_INUM_TIMER, 2 }, +#endif + { ETS_UART0_INTR_SOURCE, CPU_INUM_UART, 1 }, + { ETS_UART1_INTR_SOURCE, CPU_INUM_UART, 1 }, +#if defined(MCU_ESP32) || defined(MCU_ESP32S2) || defined(MCU_ESP32S3) + { ETS_UART2_INTR_SOURCE, CPU_INUM_UART, 1 }, +#endif + { ETS_GPIO_INTR_SOURCE, CPU_INUM_GPIO, 1 }, + { ETS_I2C_EXT0_INTR_SOURCE, CPU_INUM_I2C, 1 }, +#if defined(MCU_ESP32) || defined(MCU_ESP32S2) || defined(MCU_ESP32S3) + { ETS_I2C_EXT1_INTR_SOURCE, CPU_INUM_I2C, 1 }, +#endif +#if defined(MCU_ESP32) + { ETS_ETH_MAC_INTR_SOURCE, CPU_INUM_ETH, 1 }, +#endif +#if !defined(MCU_ESP32C2) + { ETS_TWAI_INTR_SOURCE, CPU_INUM_CAN, 1 }, + { ETS_TIMER2_INTR_SOURCE, CPU_INUM_FRC2, 2 }, +#endif +#if !defined(MCU_ESP32) + { ETS_SYSTIMER_TARGET2_EDGE_INTR_SOURCE, CPU_INUM_SYSTIMER, 2 }, +#endif }; -static const struct _irq_alloc_table_t _irq_alloc_table[] = { - { ETS_FROM_CPU_INTR0_SOURCE, CPU_INUM_SOFTWARE }, - { ETS_TG0_WDT_LEVEL_INTR_SOURCE, CPU_INUM_WDT }, - { ETS_TG0_LACT_LEVEL_INTR_SOURCE, CPU_INUM_RTC }, - { ETS_TG0_T1_LEVEL_INTR_SOURCE, CPU_INUM_TIMER }, - { ETS_TG1_T0_LEVEL_INTR_SOURCE, CPU_INUM_TIMER }, - { ETS_TG1_T1_LEVEL_INTR_SOURCE, CPU_INUM_TIMER }, - { ETS_UART0_INTR_SOURCE, CPU_INUM_UART }, - { ETS_UART1_INTR_SOURCE, CPU_INUM_UART }, - { ETS_UART2_INTR_SOURCE, CPU_INUM_UART }, - { ETS_GPIO_INTR_SOURCE, CPU_INUM_GPIO }, - { DPORT_PRO_RTC_CORE_INTR_MAP_REG, CPU_INUM_RTC }, - { ETS_I2C_EXT0_INTR_SOURCE, CPU_INUM_I2C }, - { ETS_I2C_EXT1_INTR_SOURCE, CPU_INUM_I2C }, - { ETS_ETH_MAC_INTR_SOURCE, CPU_INUM_ETH }, - { ETS_CAN_INTR_SOURCE, CPU_INUM_CAN }, - { ETS_TIMER2_INTR_SOURCE, CPU_INUM_FRC2 }, -}; +#define IRQ_DATA_TABLE_SIZE ARRAY_SIZE(_irq_data_table) -typedef void (*intr_handler_t)(void *arg); +void esp_irq_init(void) +{ +#ifdef SOC_CPU_HAS_FLEXIBLE_INTC + /* to avoid to do it in every component, we initialize levels here once */ + for (unsigned i = 0; i < IRQ_DATA_TABLE_SIZE; i++) { + intr_cntrl_ll_set_int_level(_irq_data_table[i].intr, _irq_data_table[i].level); + } +#endif +} -#define IRQ_ALLOC_TABLE_SIZE ARRAY_SIZE(_irq_alloc_table) -#define ESP_INTR_FLAG_INTRDISABLED (1<<11) +void esp_intr_enable_source(int inum) +{ + intr_cntrl_ll_enable_interrupts(BIT(inum)); +} -typedef unsigned intr_handle_t; +void esp_intr_disable_source(int inum) +{ + intr_cntrl_ll_disable_interrupts(BIT(inum)); +} esp_err_t esp_intr_enable(intr_handle_t handle) { - assert(handle < IRQ_ALLOC_TABLE_SIZE); - const struct _irq_alloc_table_t *entry = &_irq_alloc_table[handle]; - xt_ints_on(BIT(entry->intr)); + assert(handle != NULL); + esp_intr_enable_source(handle->intr); return ESP_OK; } esp_err_t esp_intr_disable(intr_handle_t handle) { - assert(handle < IRQ_ALLOC_TABLE_SIZE); - const struct _irq_alloc_table_t *entry = &_irq_alloc_table[handle]; - xt_ints_off(BIT(entry->intr)); + assert(handle != NULL); + esp_intr_disable_source(handle->intr); return ESP_OK; } @@ -88,29 +131,34 @@ esp_err_t esp_intr_alloc(int source, int flags, intr_handler_t handler, void *arg, intr_handle_t *ret_handle) { unsigned i; - for (i = 0; i < IRQ_ALLOC_TABLE_SIZE; i++) { - if (_irq_alloc_table[i].src == source) { + for (i = 0; i < IRQ_DATA_TABLE_SIZE; i++) { + if (_irq_data_table[i].src == source) { break; } } - if (i == IRQ_ALLOC_TABLE_SIZE) { + if (i == IRQ_DATA_TABLE_SIZE) { return ESP_ERR_NOT_FOUND; } /* route the interrupt source to the CPU interrupt */ - intr_matrix_set(PRO_CPU_NUM, _irq_alloc_table[i].src, _irq_alloc_table[i].intr); + intr_matrix_set(PRO_CPU_NUM, _irq_data_table[i].src, _irq_data_table[i].intr); /* set the interrupt handler */ - xt_set_interrupt_handler(_irq_alloc_table[i].intr, handler, arg); + intr_cntrl_ll_set_int_handler(_irq_data_table[i].intr, handler, arg); + +#ifdef SOC_CPU_HAS_FLEXIBLE_INTC + /* set interrupt level given by flags */ + intr_cntrl_ll_set_int_level(_irq_data_table[i].intr, esp_intr_flags_to_level(flags)); +#endif /* enable the interrupt if ESP_INTR_FLAG_INTRDISABLED is not set */ if ((flags & ESP_INTR_FLAG_INTRDISABLED) == 0) { - xt_ints_on(BIT(_irq_alloc_table[i].intr)); + intr_cntrl_ll_enable_interrupts(BIT(_irq_data_table[i].intr)); } if (ret_handle) { - *((intr_handle_t *)ret_handle) = i; + *((intr_handle_t *)ret_handle) = (const intr_handle_t)&_irq_data_table[i]; } return ESP_OK; @@ -120,3 +168,8 @@ esp_err_t esp_intr_free(intr_handle_t handle) { return esp_intr_disable(handle); } + +int esp_intr_get_cpu(intr_handle_t handle) +{ + return PRO_CPU_NUM; +} From 4be0abf41a17a9e466f1b9ec782f4005f1c6c366 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Sat, 25 Jun 2022 13:36:02 +0200 Subject: [PATCH 2/2] cpu/esp32: rename CPU_INUM_RTC to CPU_INUM_RTT --- cpu/esp32/include/irq_arch.h | 2 +- cpu/esp32/irq_arch.c | 2 +- cpu/esp32/periph/rtt_hw_rtc.c | 10 +++++----- cpu/esp32/periph/rtt_hw_sys.c | 10 +++++----- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/cpu/esp32/include/irq_arch.h b/cpu/esp32/include/irq_arch.h index 6c34bd85aafe..d4cf08109b9a 100644 --- a/cpu/esp32/include/irq_arch.h +++ b/cpu/esp32/include/irq_arch.h @@ -39,7 +39,7 @@ extern "C" { #define CPU_INUM_GPIO 2 /**< Level interrupt with low priority 1 */ #define CPU_INUM_CAN 3 /**< Level interrupt with low priority 1 */ #define CPU_INUM_UART 5 /**< Level interrupt with low priority 1 */ -#define CPU_INUM_RTC 9 /**< Level interrupt with low priority 1 */ +#define CPU_INUM_RTT 9 /**< Level interrupt with low priority 1 */ #define CPU_INUM_I2C 12 /**< Level interrupt with low priority 1 */ #define CPU_INUM_WDT 13 /**< Level interrupt with low priority 1 */ #define CPU_INUM_SOFTWARE 17 /**< Level interrupt with low priority 1 */ diff --git a/cpu/esp32/irq_arch.c b/cpu/esp32/irq_arch.c index 37afa5d6778c..be181066bc28 100644 --- a/cpu/esp32/irq_arch.c +++ b/cpu/esp32/irq_arch.c @@ -46,7 +46,7 @@ typedef struct intr_handle_data_t { static const struct intr_handle_data_t _irq_data_table[] = { { ETS_FROM_CPU_INTR0_SOURCE, CPU_INUM_SOFTWARE, 1 }, { ETS_TG0_WDT_LEVEL_INTR_SOURCE, CPU_INUM_WDT, 1 }, - { ETS_TG0_T0_LEVEL_INTR_SOURCE, CPU_INUM_RTC, 1 }, + { ETS_TG0_T0_LEVEL_INTR_SOURCE, CPU_INUM_RTT, 1 }, #if defined(MCU_ESP32) || defined(MCU_ESP32S2) || defined(MCU_ESP32S3) { ETS_TG0_T1_LEVEL_INTR_SOURCE, CPU_INUM_TIMER, 2 }, #endif diff --git a/cpu/esp32/periph/rtt_hw_rtc.c b/cpu/esp32/periph/rtt_hw_rtc.c index 809687aa00c3..16bf5bcf1673 100644 --- a/cpu/esp32/periph/rtt_hw_rtc.c +++ b/cpu/esp32/periph/rtt_hw_rtc.c @@ -74,18 +74,18 @@ static void _rtc_init(void) static void _rtc_poweron(void) { /* route all interrupt sources to the same RTT level type interrupt */ - intr_matrix_set(PRO_CPU_NUM, ETS_RTC_CORE_INTR_SOURCE, CPU_INUM_RTC); + intr_matrix_set(PRO_CPU_NUM, ETS_RTC_CORE_INTR_SOURCE, CPU_INUM_RTT); /* set interrupt handler and enable the CPU interrupt */ - xt_set_interrupt_handler(CPU_INUM_RTC, _rtc_isr, NULL); - xt_ints_on(BIT(CPU_INUM_RTC)); + xt_set_interrupt_handler(CPU_INUM_RTT, _rtc_isr, NULL); + xt_ints_on(BIT(CPU_INUM_RTT)); } static void _rtc_poweroff(void) { /* reset interrupt handler and disable the CPU interrupt */ - xt_ints_off(BIT(CPU_INUM_RTC)); - xt_set_interrupt_handler(CPU_INUM_RTC, NULL, NULL); + xt_ints_off(BIT(CPU_INUM_RTT)); + xt_set_interrupt_handler(CPU_INUM_RTT, NULL, NULL); } uint64_t _rtc_get_counter(void) diff --git a/cpu/esp32/periph/rtt_hw_sys.c b/cpu/esp32/periph/rtt_hw_sys.c index bf8b646fe937..0bb66c7a0086 100644 --- a/cpu/esp32/periph/rtt_hw_sys.c +++ b/cpu/esp32/periph/rtt_hw_sys.c @@ -74,18 +74,18 @@ static void _sys_init(void) static void _sys_poweron(void) { /* route all interrupt sources to the same RTT level type interrupt */ - intr_matrix_set(PRO_CPU_NUM, TIMER_SYSTEM_INT_SRC, CPU_INUM_RTC); + intr_matrix_set(PRO_CPU_NUM, TIMER_SYSTEM_INT_SRC, CPU_INUM_RTT); /* set interrupt handler and enable the CPU interrupt */ - xt_set_interrupt_handler(CPU_INUM_RTC, _sys_isr, NULL); - xt_ints_on(BIT(CPU_INUM_RTC)); + xt_set_interrupt_handler(CPU_INUM_RTT, _sys_isr, NULL); + xt_ints_on(BIT(CPU_INUM_RTT)); } static void _sys_poweroff(void) { /* reset interrupt handler and disable the CPU interrupt */ - xt_ints_off(BIT(CPU_INUM_RTC)); - xt_set_interrupt_handler(CPU_INUM_RTC, NULL, NULL); + xt_ints_off(BIT(CPU_INUM_RTT)); + xt_set_interrupt_handler(CPU_INUM_RTT, NULL, NULL); } static uint64_t _sys_get_counter(void)