From 006a10b0507d1cea88c9560cd15735711a046e7f Mon Sep 17 00:00:00 2001 From: baohongde Date: Thu, 24 Dec 2020 21:30:36 +0800 Subject: [PATCH] components/doc: Update doc about high-level interrupt some bugfix. --- components/bt/controller/esp32/Kconfig.in | 4 +- components/bt/controller/esp32/bt.c | 3 +- components/bt/controller/esp32/hli_api.c | 28 +++++--- components/bt/controller/esp32/hli_api.h | 24 +++++-- components/bt/controller/esp32/hli_vectors.S | 31 ++++++--- .../test/test_dport_xt_highint5.S | 3 + .../src/esp_ipc_isr/esp_ipc_isr_handler.S | 65 ++++++++++++------- components/esp_system/Kconfig | 3 +- .../esp_system/port/soc/esp32/highint_hdl.S | 42 +++++++----- .../port/xtensa/xtensa_vector_defaults.S | 21 ++++-- components/soc/esp32/include/soc/soc.h | 14 +--- docs/en/api-guides/hlinterrupts.rst | 47 +++++++++++--- 12 files changed, 192 insertions(+), 93 deletions(-) diff --git a/components/bt/controller/esp32/Kconfig.in b/components/bt/controller/esp32/Kconfig.in index 84f205dcc1..aad88aad5a 100644 --- a/components/bt/controller/esp32/Kconfig.in +++ b/components/bt/controller/esp32/Kconfig.in @@ -417,8 +417,8 @@ config BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD may cause adv packets lost more. config BTDM_CTRL_HLI - bool "High level interrut" + bool "High level interrupt" depends on BT_ENABLED default y help - Using Level 4 interrupt for Bluetooth. \ No newline at end of file + Using Level 4 interrupt for Bluetooth. diff --git a/components/bt/controller/esp32/bt.c b/components/bt/controller/esp32/bt.c index 60c3aa1535..fbd229771e 100644 --- a/components/bt/controller/esp32/bt.c +++ b/components/bt/controller/esp32/bt.c @@ -569,6 +569,7 @@ static xt_handler set_isr_hlevel_wrapper(int mask, xt_handler f, void *arg) static void IRAM_ATTR interrupt_hlevel_disable(void) { assert(xPortGetCoreID() == CONFIG_BTDM_CTRL_PINNED_TO_CORE); + assert(hli_cb.nested != ~0); uint32_t status = hli_intr_disable(); if (hli_cb.nested++ == 0) { hli_cb.status = status; @@ -947,7 +948,7 @@ static int32_t queue_recv_hlevel_wrapper(void *queue, void *item, uint32_t block if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) { ret = xQueueReceive(((hli_queue_handle_t)queue)->downstream, item, portMAX_DELAY); } else { - ret =xQueueReceive(((hli_queue_handle_t)queue)->downstream, item, block_time_ms / portTICK_PERIOD_MS); + ret = xQueueReceive(((hli_queue_handle_t)queue)->downstream, item, block_time_ms / portTICK_PERIOD_MS); } return (int32_t)ret; diff --git a/components/bt/controller/esp32/hli_api.c b/components/bt/controller/esp32/hli_api.c index 9e4c8951d1..e1444c2bb0 100644 --- a/components/bt/controller/esp32/hli_api.c +++ b/components/bt/controller/esp32/hli_api.c @@ -1,5 +1,17 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// All rights reserved. +// Copyright 2015-2021 Espressif Systems (Shanghai) CO LTD +// +// Licensed 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. + #include #include "esp_log.h" @@ -47,7 +59,6 @@ static void IRAM_ATTR customer_swisr_handle(customer_swisr_t *cus_swisr) } static DRAM_ATTR hli_handler_info_t s_hli_handlers[HLI_MAX_HANDLERS]; -// static const char* TAG = "hli_queue"; esp_err_t hli_intr_register(intr_handler_t handler, void* arg, uint32_t intr_reg, uint32_t intr_mask) { @@ -91,14 +102,13 @@ void IRAM_ATTR hli_c_handler(void) } } if (!handled) { - // esp_rom_printf(DRAM_STR("hli_c_handler: no handler found!\n")); - // abort(); + /* no handler found, it is OK in this case. */ } } uint32_t IRAM_ATTR hli_intr_disable(void) { - // disable level 4 and below + /* disable level 4 and below */ return XTOS_SET_INTLEVEL(XCHAL_DEBUGLEVEL - 2); } @@ -115,7 +125,7 @@ void IRAM_ATTR hli_intr_restore(uint32_t state) #define HLI_QUEUE_FLAG_CUSTOMER BIT(1) static DRAM_ATTR struct hli_queue_t *s_meta_queue_ptr = NULL; -intr_handle_t ret_handle; +static intr_handle_t ret_handle; static inline char* IRAM_ATTR wrap_ptr(hli_queue_handle_t queue, char *ptr) { @@ -150,7 +160,7 @@ static void IRAM_ATTR queue_isr_handler(void* arg) res = xQueueSendFromISR(queue->downstream, scratch, &do_yield); } if (res == pdFAIL) { - // ESP_EARLY_LOGE(TAG, "Failed to send to %s %p", (queue->flags & HLI_QUEUE_FLAG_SEMAPHORE) == 0 ? "queue" : "semaphore", queue->downstream); + /* Failed to send to downstream queue, it is OK in this case. */ } } } @@ -222,7 +232,7 @@ hli_queue_handle_t hli_queue_create(size_t nelem, size_t elem_size, QueueHandle_ return NULL; } size_t buf_size = buf_elem * elem_size; - hli_queue_handle_t res = (hli_queue_handle_t) heap_caps_malloc(sizeof(*res) + buf_size, + hli_queue_handle_t res = (hli_queue_handle_t) heap_caps_malloc(sizeof(struct hli_queue_t) + buf_size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); if (res == NULL) { return NULL; diff --git a/components/bt/controller/esp32/hli_api.h b/components/bt/controller/esp32/hli_api.h index 03d32e2803..e0049aab32 100644 --- a/components/bt/controller/esp32/hli_api.h +++ b/components/bt/controller/esp32/hli_api.h @@ -1,12 +1,20 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// All rights reserved. +// Copyright 2015-2021 Espressif Systems (Shanghai) CO LTD +// +// Licensed 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. + #pragma once -#ifdef __cplusplus -extern "C" { -#endif - #include #include "esp_err.h" #include "esp_intr_alloc.h" @@ -14,6 +22,10 @@ extern "C" { #include "freertos/queue.h" #include "freertos/semphr.h" +#ifdef __cplusplus +extern "C" { +#endif + #if CONFIG_BTDM_CTRL_HLI /*** Queues ***/ diff --git a/components/bt/controller/esp32/hli_vectors.S b/components/bt/controller/esp32/hli_vectors.S index 72978f7135..9b8a0dd9e1 100644 --- a/components/bt/controller/esp32/hli_vectors.S +++ b/components/bt/controller/esp32/hli_vectors.S @@ -1,5 +1,17 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// All rights reserved. +// Copyright 2015-2021 Espressif Systems (Shanghai) CO LTD +// +// Licensed 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. + #include #include @@ -21,13 +33,13 @@ * - WINDOWBASE, WINDOWSTART — only WINDOWSTART is truly needed * - SAR, LBEG, LEND, LCOUNT — since the C code might use these * - EPC1 — since the C code might cause window overflow exceptions - * This is not laid out a standard exception frame structure + * This is not laid out as standard exception frame structure * for simplicity of the save/restore code. */ #define REG_FILE_SIZE (64 * 4) #define SPECREG_OFFSET REG_FILE_SIZE #define SPECREG_SIZE (7 * 4) -#define REG_SAVE_AREA_SIZE (SPECREG_OFFSET * SPECREG_SIZE) +#define REG_SAVE_AREA_SIZE (SPECREG_OFFSET + SPECREG_SIZE) .data _l4_intr_stack: @@ -46,7 +58,7 @@ xt_highint4: /* Here, Timer2 is used to count a little time(50us). The subsequent dram0 write operation is blocked due to live lock, which will - cause timer2 to timeout and trigger a l5 interrupt. + cause timer2 to timeout and trigger a level 5 interrupt. */ rsr.ccount a0 addmi a0, a0, (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ*50) @@ -57,12 +69,13 @@ xt_highint4: extui a0, a0, 16, 1 bnez a0, 1f movi a0, 0 - xsr a0, INTENABLE // disable all interrupts + xsr a0, INTENABLE /* disable all interrupts */ + /* And a0 with (1 << 16) for Timer 2 interrupt mask */ addmi a0, a0, (1<<14) addmi a0, a0, (1<<14) addmi a0, a0, (1<<14) addmi a0, a0, (1<<14) - wsr a0, INTENABLE + wsr a0, INTENABLE /* Enable Timer 2 */ 1: #endif @@ -93,14 +106,14 @@ xt_highint4: #if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX movi a0, 0 - xsr a0, INTENABLE // disable all interrupts + xsr a0, INTENABLE /* disable all interrupts */ movi a2, ~(1<<16) and a0, a2, a0 wsr a0, INTENABLE #endif /* disable exception mode, window overflow */ - movi a0, PS_INTLEVEL(5) | PS_EXCM /*TOCHECK*/ + movi a0, PS_INTLEVEL(5) | PS_EXCM wsr a0, PS rsync diff --git a/components/esp_hw_support/test/test_dport_xt_highint5.S b/components/esp_hw_support/test/test_dport_xt_highint5.S index 223a2a8924..197d7c8cc4 100644 --- a/components/esp_hw_support/test/test_dport_xt_highint5.S +++ b/components/esp_hw_support/test/test_dport_xt_highint5.S @@ -10,6 +10,7 @@ #include "soc/dport_reg.h" #ifndef CONFIG_FREERTOS_UNICORE +#ifndef CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 #define L5_INTR_STACK_SIZE 12 #define L5_INTR_A2_OFFSET 0 @@ -77,6 +78,8 @@ xt_highint5: .global ld_include_test_dport_xt_highint5 ld_include_test_dport_xt_highint5: + +#endif // CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 #endif // CONFIG_FREERTOS_UNICORE #endif // CONFIG_IDF_TARGET_ESP32 diff --git a/components/esp_ipc/src/esp_ipc_isr/esp_ipc_isr_handler.S b/components/esp_ipc/src/esp_ipc_isr/esp_ipc_isr_handler.S index 292bbc50dd..0fb4ae676a 100644 --- a/components/esp_ipc/src/esp_ipc_isr/esp_ipc_isr_handler.S +++ b/components/esp_ipc/src/esp_ipc_isr/esp_ipc_isr_handler.S @@ -15,14 +15,30 @@ /* High-priority interrupt - IPC_ISR handler */ -#define L5_INTR_STACK_SIZE 16 -#define L5_INTR_A0_OFFSET 0 -#define L5_INTR_A2_OFFSET 4 -#define L5_INTR_A3_OFFSET 8 -#define L5_INTR_A4_OFFSET 12 +#if CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 +#define LX_INTR_STACK_SIZE 16 +#define LX_INTR_A0_OFFSET 0 +#define LX_INTR_A2_OFFSET 4 +#define LX_INTR_A3_OFFSET 8 +#define LX_INTR_A4_OFFSET 12 +#define EXCSAVE_X EXCSAVE_5 +#define RFI_X 5 + +#elif CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4 + +#define LX_INTR_STACK_SIZE 16 +#define LX_INTR_A0_OFFSET 0 +#define LX_INTR_A2_OFFSET 4 +#define LX_INTR_A3_OFFSET 8 +#define LX_INTR_A4_OFFSET 12 +#define EXCSAVE_X EXCSAVE_4 +#define RFI_X 4 + +#endif /* CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 */ + .data -_l5_intr_stack: - .space L5_INTR_STACK_SIZE +_lx_intr_stack: + .space LX_INTR_STACK_SIZE .section .iram1,"ax" .global esp_ipc_isr_handler .type esp_ipc_isr_handler,@function @@ -30,17 +46,17 @@ _l5_intr_stack: esp_ipc_isr_handler: /* Allocate exception frame and save minimal context. */ /* Because the interrupt cause code has protection that only - allows one cpu to enter in the IPC_ISR section of the L4 + allows one cpu to enter in the IPC_ISR section of the LX interrupt at one time, there's no need to have two - _l5_intr_stack for each cpu */ + _lx_intr_stack for each cpu */ /* Save A0, A2, A3, A4 so we can use those registers further*/ - movi a0, _l5_intr_stack - s32i a2, a0, L5_INTR_A2_OFFSET - s32i a3, a0, L5_INTR_A3_OFFSET - s32i a4, a0, L5_INTR_A4_OFFSET - rsr a2, EXCSAVE_5 - s32i a2, a0, L5_INTR_A0_OFFSET + movi a0, _lx_intr_stack + s32i a2, a0, LX_INTR_A2_OFFSET + s32i a3, a0, LX_INTR_A3_OFFSET + s32i a4, a0, LX_INTR_A4_OFFSET + rsr a2, EXCSAVE_X + s32i a2, a0, LX_INTR_A0_OFFSET /* disable nested iterrupts */ /* PS.EXCM is changed from 1 to 0 . It allows using usually exception handler instead of the Double exception handler. */ @@ -53,9 +69,14 @@ esp_ipc_isr_handler: /* * Reset isr interrupt flags */ +#if CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 + /* This int is level-triggered and doesn't need clearing. + Do nothing here and clear int status by peripheral register later.*/ +#elif CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4 /* This int is edge-triggered and needs clearing. */ movi a3, (1 << ETS_IPC_ISR_INUM) wsr a3, INTCLEAR +#endif /* CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 */ /* get CORE_ID */ getcoreid a3 @@ -85,16 +106,16 @@ esp_ipc_isr_handler: callx0 a0 /* Done. Restore registers and return. */ - movi a0, _l5_intr_stack - l32i a2, a0, L5_INTR_A2_OFFSET - l32i a3, a0, L5_INTR_A3_OFFSET - l32i a4, a0, L5_INTR_A4_OFFSET + movi a0, _lx_intr_stack + l32i a2, a0, LX_INTR_A2_OFFSET + l32i a3, a0, LX_INTR_A3_OFFSET + l32i a4, a0, LX_INTR_A4_OFFSET /* set the end flag */ movi a0, esp_ipc_isr_end_fl s32i a0, a0, 0 /* restore a0 */ - rsr a0, EXCSAVE_5 - /* restores PS from EPS[5] and jumps to the address in EPC[5] */ - rfi 5 + rsr a0, EXCSAVE_X + /* restores PS from EPS[X] and jumps to the address in EPC[X] */ + rfi RFI_X diff --git a/components/esp_system/Kconfig b/components/esp_system/Kconfig index 60ee6be5da..adc769a13d 100644 --- a/components/esp_system/Kconfig +++ b/components/esp_system/Kconfig @@ -464,12 +464,13 @@ menu "ESP System Settings" choice ESP_SYSTEM_CHECK_INT_LEVEL prompt "Interrupt level to use for Interrupt Watchdog and other system checks" - default ESP_SYSTEM_CHECK_INT_LEVEL_5 + default ESP_SYSTEM_CHECK_INT_LEVEL_4 help Interrupt level to use for Interrupt Watchdog and other system checks. config ESP_SYSTEM_CHECK_INT_LEVEL_5 bool "Level 5 interrupt" + depends on IDF_TARGET_ESP32 help Using level 5 interrupt for Interrupt Watchdog and other system checks. diff --git a/components/esp_system/port/soc/esp32/highint_hdl.S b/components/esp_system/port/soc/esp32/highint_hdl.S index 9571e3e6a6..3ae31686d2 100644 --- a/components/esp_system/port/soc/esp32/highint_hdl.S +++ b/components/esp_system/port/soc/esp32/highint_hdl.S @@ -76,6 +76,7 @@ Interrupt , a high-priority interrupt, is used for several things: #define TIMG1_WDT_STG0_HOLD_OFFSET TIMG1_REG_OFFSET(TIMG_WDTCONFIG2_REG(1)) #define TIMG1_WDT_STG1_HOLD_OFFSET TIMG1_REG_OFFSET(TIMG_WDTCONFIG3_REG(1)) #define TIMG1_WDT_FEED_OFFSET TIMG1_REG_OFFSET(TIMG_WDTFEED_REG(1)) +#define UART0_DATA_REG (0x3FF40078) .macro wdt_clr_intr_status dev movi a2, \dev @@ -120,24 +121,24 @@ Interrupt , a high-priority interrupt, is used for several things: .macro get_int_status_tg1wdt reg rsr \reg, INTERRUPT extui \reg, \reg, ETS_T1_WDT_CACHEERR_INUM, 1 - beqz \reg, 99f // not ETS_T1_WDT_INUM or ETS_CACHEERR_INUM + beqz \reg, 99f /* not ETS_T1_WDT_INUM or ETS_CACHEERR_INUM */ getcoreid \reg bnez \reg, 98f - // core 0 - movi \reg, 0x3FF40078 - l32i \reg, \reg, 0 // Workaround for DPORT read error, for silicon revision 0~2 (ECO V0 ~ ECO V2). + /* core 0 */ + movi \reg, UART0_DATA_REG + l32i \reg, \reg, 0 /* Workaround for DPORT read error, for silicon revision 0~2 (ECO V0 ~ ECO V2). */ movi \reg, DPORT_PRO_INTR_STATUS_0_REG l32i \reg, \reg, 0 - extui \reg, \reg, 20, 1 // ETS_TG1_WDT_LEVEL_INTR_SOURCE + extui \reg, \reg, ETS_TG1_WDT_LEVEL_INTR_SOURCE, 1 j 99f -98: // core 1 - movi \reg, 0x3FF40078 - l32i \reg, \reg, 0 // Workaround for DPORT read error, for silicon revision 0~2 (ECO V0 ~ ECO V2). +98: /* core 1 */ + movi \reg, UART0_DATA_REG + l32i \reg, \reg, 0 /* Workaround for DPORT read error, for silicon revision 0~2 (ECO V0 ~ ECO V2). */ movi \reg, DPORT_APP_INTR_STATUS_0_REG l32i \reg, \reg, 0 - extui \reg, \reg, 20, 1 // ETS_TG1_WDT_LEVEL_INTR_SOURCE + extui \reg, \reg, ETS_TG1_WDT_LEVEL_INTR_SOURCE, 1 99: .endm @@ -171,12 +172,14 @@ xt_highintx: /* See if we're here for the IPC_ISR interrupt */ rsr a0, INTERRUPT extui a0, a0, ETS_IPC_ISR_INUM, 1 - bnez a0, esp_ipc_isr_handler -#endif // not CONFIG_FREERTOS_UNICORE + beqz a0, 1f + j esp_ipc_isr_handler +1: +#endif /* not CONFIG_FREERTOS_UNICORE */ - - // ETS_T1_WDT_INUM #if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX && CONFIG_ESP_INT_WDT + +#if CONFIG_BTDM_CTRL_HLI /* Timer 2 interrupt */ rsr a0, INTENABLE extui a0, a0, 16, 1 @@ -185,6 +188,9 @@ xt_highintx: extui a0, a0, 16, 1 bnez a0, .handle_multicore_debug_int 1: +#endif /* CONFIG_BTDM_CTRL_HLI */ + + /* ETS_T1_WDT_INUM */ #if CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 get_int_status_tg1wdt a0 #elif CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4 @@ -204,7 +210,7 @@ xt_highintx: rsr a5, depc /* restore a5 */ #endif -1: //ETS_CACHEERR_INUM or ETS_T1_WDT_INUM +1: /* ETS_CACHEERR_INUM or ETS_T1_WDT_INUM */ /* Allocate exception frame and save minimal context. */ mov a0, sp addi sp, sp, -XT_STK_FRMSZ @@ -276,7 +282,7 @@ xt_highintx: movi a0, PS_INTLEVEL(5) | PS_UM | PS_WOE wsr a0, PS - //Call panic handler + /* Call panic handler */ mov a6,sp call4 panicHandler @@ -294,6 +300,7 @@ xt_highintx: #if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX && CONFIG_ESP_INT_WDT +#if CONFIG_BTDM_CTRL_HLI #define APB_ITCTRL (0x3f00) #define APB_DCRSET (0x200c) @@ -326,7 +333,7 @@ xt_highintx: nop .endr - /* Enable Normally Mode */ + /* Enable Normal Mode */ movi a2, ERI_ADDR(APB_ITCTRL) rer a0, a2 movi a2, ~0x1 @@ -336,8 +343,9 @@ xt_highintx: rsr a2, depc - rsr a0, EXCSAVE_X /* restore a0 */ + rsr a0, EXCSAVE_5 /* restore a0 */ rfi 5 +#endif /* CONFIG_BTDM_CTRL_HLI */ /* -------------------------------------------------------------------------------- diff --git a/components/freertos/port/xtensa/xtensa_vector_defaults.S b/components/freertos/port/xtensa/xtensa_vector_defaults.S index 52d4a3e83e..791116cfbc 100644 --- a/components/freertos/port/xtensa/xtensa_vector_defaults.S +++ b/components/freertos/port/xtensa/xtensa_vector_defaults.S @@ -63,10 +63,21 @@ _xt_debugexception: .align 4 _xt_debug_di_exc: -/* After testing, - In 80 MHz, it will task 5us to loop 45 times; - In 160 MHz, it will task 5us to loop 90 times; - In 240 MHz, it will task 5us to loop 135 times;*/ + /* + The delay time can be calculated by the following formula: + T = ceil(0.25 + max(t1, t2)) us + + t1 = 80 / f1, t2 = (1 + 14/N) * 20 / f2 + + f1: PSRAM access frequency, unit: MHz. + f2: Flash access frequency, unit: MHz. + + When flash is slow/fast read, N = 1. + When flash is DOUT/DIO read, N = 2. + When flash is QOUT/QIO read, N = 4. + + And after testing, when CPU frequency is 240 MHz, it will take 1us to loop 27 times. + */ #if defined(CONFIG_ESPTOOLPY_FLASHMODE_QIO) || defined(CONFIG_ESPTOOLPY_FLASHMODE_QOUT) # if defined(CONFIG_ESPTOOLPY_FLASHFREQ_80M) && defined(CONFIG_SPIRAM_SPEED_80M) @@ -99,7 +110,7 @@ _xt_debug_di_exc: movi a0, 243 #endif -1: addi a0, a0, -1 +1: addi a0, a0, -1 /* delay_us(N) */ .rept 4 nop .endr diff --git a/components/soc/esp32/include/soc/soc.h b/components/soc/esp32/include/soc/soc.h index 4f744ff5e1..f9e3e87593 100644 --- a/components/soc/esp32/include/soc/soc.h +++ b/components/soc/esp32/include/soc/soc.h @@ -371,7 +371,7 @@ * 13 1 extern level * 14 7 nmi Reserved Reserved * 15 3 timer FreeRTOS Tick(L3) FreeRTOS Tick(L3) - * 16 5 timer + * 16 5 timer Reserved Reserved * 17 1 extern level * 18 1 extern level * 19 2 extern level @@ -403,15 +403,6 @@ #define ETS_CACHEERR_INUM ETS_MEMACCESS_ERR_INUM #define ETS_IPC_ISR_INUM 31 -//CPU0 Interrupt number used in ROM, should be cancelled in SDK -#define ETS_SLC_INUM 1 -#define ETS_UART0_INUM 5 -#define ETS_UART1_INUM 5 -//Other interrupt number should be managed by the user - -//Invalid interrupt for number interrupt matrix -#define ETS_INVALID_INUM 6 - #elif CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4 //interrupt cpu using table, Please see the core-isa.h @@ -464,6 +455,8 @@ #define ETS_CACHEERR_INUM ETS_MEMACCESS_ERR_INUM #define ETS_IPC_ISR_INUM 28 +#endif /* CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 */ + //CPU0 Interrupt number used in ROM, should be cancelled in SDK #define ETS_SLC_INUM 1 #define ETS_UART0_INUM 5 @@ -472,4 +465,3 @@ //Invalid interrupt for number interrupt matrix #define ETS_INVALID_INUM 6 -#endif /* CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 */ \ No newline at end of file diff --git a/docs/en/api-guides/hlinterrupts.rst b/docs/en/api-guides/hlinterrupts.rst index 9b75efa964..abb65aaf94 100644 --- a/docs/en/api-guides/hlinterrupts.rst +++ b/docs/en/api-guides/hlinterrupts.rst @@ -9,16 +9,39 @@ The Xtensa architecture has support for 32 interrupts, divided over 8 levels, pl Interrupt Levels ---------------- -===== ================= ==================================================== -Level Symbol Remark -===== ================= ==================================================== -1 N/A Exception and level 0 interrupts. Handled by ESP-IDF -2-3 N/A Medium level interrupts. Handled by ESP-IDF -4 xt_highint4 Normally used by ESP-IDF debug logic -5 xt_highint5 Free to use -NMI xt_nmi Free to use -dbg xt_debugexception Debug exception. Called on e.g. a BREAK instruction. -===== ================= ==================================================== +.. only:: esp32 + + ===== ================= ==================================================== + Level Symbol Remark + ===== ================= ==================================================== + 1 N/A Exception and level 0 interrupts. Handled by ESP-IDF + 2-3 N/A Medium level interrupts. Handled by ESP-IDF + 4 xt_highint4 Free to use :ref:`(See 1) ` + 5 xt_highint5 Normally used by ESP-IDF debug logic :ref:`(See 1) ` + NMI xt_nmi Free to use + dbg xt_debugexception Debug exception. Called on e.g. a BREAK instruction. :ref:`(See 2) ` + ===== ================= ==================================================== + + + .. _hlinterrupts-pin-notes: + + The following notes give more information about the items in the tables above. + + 1. ESP-IDF debug logic can be configured to run on `xt_highint4` or `xt_highint5` in :ref:`CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL`. Bluetooth's interrupt can be configured to run on level 4 by enabling :ref:`CONFIG_BTDM_CTRL_HLI`. If :ref:`CONFIG_BTDM_CTRL_HLI` is enabled, ESP-IDF debug logic must be running on level 5 interrupt. + 2. If :ref:`CONFIG_BTDM_CTRL_HLI` is enabled, `xt_debugexception` is used to fix `live lock issue `_ in ESP32 ECO3. + +.. only:: not esp32 + + ===== ================= ==================================================== + Level Symbol Remark + ===== ================= ==================================================== + 1 N/A Exception and level 0 interrupts. Handled by ESP-IDF + 2-3 N/A Medium level interrupts. Handled by ESP-IDF + 4 xt_highint4 Normally used by ESP-IDF debug logic + 5 xt_highint5 Free to use + NMI xt_nmi Free to use + dbg xt_debugexception Debug exception. Called on e.g. a BREAK instruction. + ===== ================= ==================================================== Using these symbols is done by creating an assembly file (suffix .S) and defining the named symbols, like this:: @@ -41,6 +64,10 @@ Notes (The panic handler interrupt does call normal C code, but this is OK because there is no intention of returning to the normal code flow afterwards.) + .. only:: esp32 + + And if :ref:`CONFIG_BTDM_CTRL_HLI` is enabled, it does call normal C code in high-level interrupt, but this is OK becase we add some protection for it. + - Make sure your assembly code gets linked in. If the interrupt handler symbol is the only symbol the rest of the code uses from this file, the linker will take the default ISR instead and not link the assembly file into the final project. To get around this, in the assembly file, define a symbol, like this::