Open KonssnoK opened 7 months ago
@KonssnoK Hi, you are right that these tables do indeed contain some information that is no longer correct on later chips.
Cleaning this up is a high-priority task in our backlog and we should get to it soon. I'll make sure to link and close this issue as well when we create that fix.
hello @ESP-Marius , could you give a us a preview with the correct table for esp32s3 core0?
we are currently blocked because updating the master branch of v4.4 consumed an additional interrupt which we didnt expect.
Or at least tell us if there are more level-trigger interrupts available, like 10, 22.
This would be the table according to the technical reference manual
//This is basically a software-readable version of the interrupt usage table in include/soc/soc.h
const static int_desc_t interrupt_descriptor_table [32]={
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //0
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //1
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //2
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //3
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //4
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //5
{ 1, INTTP_NA, {INT6RES, INT6RES } }, //6
{ 1, INTTP_NA, {INTDESC_SPECIAL,INTDESC_SPECIAL}}, //7
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL } }, //8
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //9
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //10
{ 3, INTTP_NA, {INTDESC_SPECIAL,INTDESC_SPECIAL}}, //11
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //12
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //13
{ 7, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //14, NMI
{ 3, INTTP_NA, {INT15RES, INT15RES } }, //15
{ 5, INTTP_NA, {INTDESC_SPECIAL,INTDESC_SPECIAL}}, //16
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //17
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //18
{ 2, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //19
{ 2, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //20
{ 2, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //21
{ 3, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //22
{ 3, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //23
{ 4, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //24
{ 4, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //25
{ 5, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //26
{ 3, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //27
{ 4, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //28
{ 3, INTTP_NA, {INTDESC_SPECIAL,INTDESC_SPECIAL}}, //29
{ 4, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //30
{ 5, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //31
};
EDIT: apparently the CORE1 has int0 1 as reserved, the wifi doesn't work if they are used for peripherals.
This means that both the document and the code are wrong..
New table based on soc.h
Please note that in this table, the amount of interrupts that can be allocated with intr_alloc is the same as the original table, which means you cannot allocate more than 11 interrupts (-3 for RTOS, -2 for WDT). Basically the customer has 6 interrupts (out of 32) available on core0
//This is basically a software-readable version of the interrupt usage table in include/soc/soc.h
const static int_desc_t interrupt_descriptor_table [32]={
{ 1, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //0 WMAC Reserved
{ 1, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //1 BT/BLE Host HCI DMA BT/BLE Host HCI DMA
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //2
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //3
{ 1, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_NORMAL} }, //4 WBB
{ 1, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //5 BT/BLE Controller BT/BLE Controller
{ 1, INTTP_NA, {INT6RES, INT6RES } }, //6 FreeRTOS Tick(L1) FreeRTOS Tick(L1)
{ 1, INTTP_NA, {INTDESC_SPECIAL,INTDESC_SPECIAL}}, //7 BT/BLE VHCI BT/BLE VHCI
{ 1, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //8 BT/BLE BB(RX/TX) BT/BLE BB(RX/TX)
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //9
{ 1, INTTP_EDGE, {INTDESC_NORMAL, INTDESC_NORMAL} }, //10
{ 3, INTTP_NA, {INTDESC_SPECIAL,INTDESC_SPECIAL}}, //11
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //12
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //13
{ 7, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //14 NMI Reserved Reserved
{ 3, INTTP_NA, {INT15RES, INT15RES } }, //15 FreeRTOS Tick(L3) FreeRTOS Tick(L3)
{ 5, INTTP_NA, {INTDESC_SPECIAL,INTDESC_SPECIAL}}, //16
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //17
{ 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //18
{ 2, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //19
{ 2, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //20
{ 2, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //21
{ 3, INTTP_EDGE , {INTDESC_NORMAL, INTDESC_NORMAL} }, //22
{ 3, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //23
{ 4, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_NORMAL} }, //24 TG1_WDT
{ 4, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_NORMAL} }, //25 CACHEERR
{ 5, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //26
{ 3, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //27 Reserved Reserved
{ 4, INTTP_EDGE, {INTDESC_RESVD, INTDESC_RESVD } }, //28 IPC_ISR IPC_ISR
{ 3, INTTP_NA, {INTDESC_SPECIAL,INTDESC_SPECIAL}}, //29 Reserved Reserved
{ 4, INTTP_EDGE, {INTDESC_RESVD, INTDESC_RESVD } }, //30 Reserved Reserved
{ 5, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //31
};
is there any update on this issue?
Just 2c, I think the TRM might be incorrect here, considering these definitions — they were auto-generated at the time the CPU was configured, and it's unlikely there is a mistake there.
Sharing the interrupts between multiple peripherals is probably the best option to try if you are running out of interrupts. For more info, please see this section of the docs: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-reference/system/intr_alloc.html#troubleshooting-interrupt-allocation.
Just 2c, I think the TRM might be incorrect here, considering these definitions — they were auto-generated at the time the CPU was configured, and it's unlikely there is a mistake there.
Sharing the interrupts between multiple peripherals is probably the best option to try if you are running out of interrupts. For more info, please see this section of the docs: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-reference/system/intr_alloc.html#troubleshooting-interrupt-allocation.
sharing interrupts becomes difficult when we use a lot of esp-idf components. All these components use interrupts which are not set as shared, and to change this we need to touch esp-idf. The quickest way we have to solve the issue we currently face is to revert part of your changes that take exclusive interrupts for SPI event when they are not necessary.
Here is a list of our interrupts, to show that we don t really have much custom stuff:
(cpu 0) ETS_SYSTIMER_TARGET2_EDGE_INTR_SOURCE freeRTOS
(cpu 0) ETS_FROM_CPU_INTR0_SOURCE freeRTOS
(cpu 0) ETS_SYSTIMER_TARGET0_EDGE_INTR_SOURCE freeRTOS
(cpu 1) ETS_FROM_CPU_INTR1_SOURCE freeRTOS
(cpu 1) ETS_SYSTIMER_TARGET1_EDGE_INTR_SOURCE freeRTOS
(cpu 0) ETS_TG0_WDT_LEVEL_INTR_SOURCE esp_task_wdt_init
(cpu 0) ETS_GPIO_INTR_SOURCE gpio_isr_register gpio_install_isr_service
(cpu 0) ETS_I2C_EXT0_INTR_SOURCE i2c
(cpu 0) ETS_DMA_IN_CH0_INTR_SOURCE metering_init -> custom
(cpu 0) ETS_SPI3_INTR_SOURCE NAND spi interrupt -> not used
(cpu 0) ETS_DMA_OUT_CH2_INTR_SOURCE NAND DMA
(cpu 0) ETS_DMA_IN_CH3_INTR_SOURCE NAND DMA
(cpu 0) ETS_RTC_CORE_INTR_SOURCE rtc_isr_register esp_xt_wdt_init startup
(cpu 1) ETS_UART1_INTR_SOURCE esp_modem
(cpu 1) ETS_UART1_INTR_SOURCE esp_modem
in alternative we will have to try to allocate more interrupts on the second core, but that is more architecturally demanding
Also please note that the esp-idf drivers do not allow allocation of interrupts higher than level 3, meaning that some available interrupts are not actually used.
Any update on this? we had to solve by creating a CORE1 init task that initializes part of our system putting interrupts on CORE1
@KonssnoK
What is the truth? Is the documentation wrong or is the code a copypaste from the code of esp32 ?
In this case, the soc.h
is the source of truth regarding level vs edge triggered interrupts on the ESP32-S3. The XCHAL_INTTYPE_MASK_EXTERN_EDGE bit mask indicates which of the 32 interrupts on the Xtensa core are edge triggered. This mask matches the information in soc.h
. I'll pend a fix for the TRM.
Also please note that the esp-idf drivers do not allow allocation of interrupts higher than level 3, meaning that some available interrupts are not actually used.
This is intentional. On Xtensa arch ESP32 targets, critical sections do not mask out interrupts higher than level 3. Thus they are reserved for either low latency user interrupts written in assembly or internal system use.
Any update on this? we had to solve by creating a CORE1 init task that initializes part of our system putting interrupts on CORE1
If you are unable to share interrupts between various drivers/system services, then this will be the only solution.
However, sharing interrupts between drivers/system services is the easier option. Some system services (e.g., TWDT) won't share interrupts due to latency reasons. However, most drivers can be configured to share interrupts on install. Look for the intr_alloc_flags
argument passed to the driver's install function. Setting the ESP_INTR_FLAG_SHARED
flag will instruct the driver to use a shared interrupt.
For example
#include "esp_intr_alloc.h"
#include "driver/uart.h"
#include "driver/i2c.h
uart_driver_install(..., intr_alloc_flags=ESP_INTR_FLAG_SHARED, ...);
i2c_driver_install(..., intr_alloc_flags=ESP_INTR_FLAG_SHARED, ...);
thanks @Dazza0 , we will look into the shared interrupts, but the main focus of the issue is on knowing with certainty which are the interrupts of the device we have in production. As said in my previous post, the allocation of the interrupts is solved for now, distributing to the second core some of the allocations.
Hello @KonssnoK ,
This has been fixed on master
, the interrupt types and usage are now correct for all the chips, including the ESP32-S3. Please check this file: https://github.com/espressif/esp-idf/blob/master/components/esp_hw_support/port/esp32s3/esp_cpu_intr.c
thanks @o-marshmallow , i'll check it out. I expect this to be propagated to all branches including 4.4, please let me know if not.
Answers checklist.
General issue report
Hello, following the issue https://github.com/espressif/esp-idf/issues/12830
i started looking at documentation and code for the 32 theoretic interrupts available PER CORE in ESP32-S3
in the doc it is pretty straight-forward: https://www.espressif.com/sites/default/files/documentation/esp32-s3_technical_reference_manual_en.pdf
If it is not reserved, it s a level-triggered interrupt.
In the code instead: interrupt_descriptor_table.c
both EDGE and LEVEL interrupts are defined. I am used to chipset having a register to define if an interrupts should be level or edge, but the esp32s3 doesn t seems to have one.
What is the truth? Is the documentation wrong or is the code a copypaste from the code of esp32 ?
Thanks