mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
components/doc: Update doc about high-level interrupt
some bugfix.
This commit is contained in:
parent
57eeb4d953
commit
006a10b050
@ -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.
|
||||
Using Level 4 interrupt for Bluetooth.
|
||||
|
@ -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;
|
||||
|
@ -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 <string.h>
|
||||
#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;
|
||||
|
@ -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 <stdint.h>
|
||||
#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 ***/
|
||||
|
@ -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 <xtensa/coreasm.h>
|
||||
#include <xtensa/corebits.h>
|
||||
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
/*
|
||||
--------------------------------------------------------------------------------
|
||||
|
@ -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
|
||||
|
@ -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 */
|
@ -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) <hlinterrupts-pin-notes>`
|
||||
5 xt_highint5 Normally used by ESP-IDF debug logic :ref:`(See 1) <hlinterrupts-pin-notes>`
|
||||
NMI xt_nmi Free to use
|
||||
dbg xt_debugexception Debug exception. Called on e.g. a BREAK instruction. :ref:`(See 2) <hlinterrupts-pin-notes>`
|
||||
===== ================= ====================================================
|
||||
|
||||
|
||||
.. _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 <https://www.espressif.com/sites/default/files/documentation/eco_and_workarounds_for_bugs_in_esp32_en.pdf>`_ 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::
|
||||
|
Loading…
x
Reference in New Issue
Block a user