I have a project which uses high-level (level 5) GPIO interrupt and high-level timer interrupt. Previously it works very well with ESP-IDF V4.4. This week I updated the IDF to V5.0 release, after compiling and flashing, neither GPIO interrupt nor timer interrupt works anymore. Does anyone have any clue what could be wrong, or could it be a bug of idf v5.0? Is there any documentation I can refer to about the high-level interrupt?
Here are details:
Chip: ESP32S3-N8R2.
IDF updated from v4.4 to v5.0.
language: c++ and Assembly
level 5 GPIO interrupt id: 31,
level 5 timer interrupt id 16, using CCOMPARE_2.
The registering of GPIO or timer interrupts succeed, but once GPIO or timer interrupt triggers, both of the CPU cores are stuck somewhere. There is code in the level-5 intr handler to clear the GPIO interrupt flag and set the ccompare_2, but somehow it may not work with idf v5.
The code of main.cpp and Sampling_Int.S is attached below. The code works well with idf v4, no matter which CPU cores the interrupt handler and system main task run at.
main.cpp:
Code: Select all
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "xtensa/core-macros.h"
#include "driver/gpio.h"
#include "soc/soc.h"
#include "soc/periph_defs.h"
#include "esp_log.h"
//#include "esp_rom_gpio.h"
#include "rom/ets_sys.h"
#define PPS_PIN 8
uint32_t AlarmValue = 240000000;
uint32_t IntCounter[2];
void RegisterInt(void *you_need_this)
{
gpio_set_intr_type((gpio_num_t)PPS_PIN, GPIO_INTR_POSEDGE);
gpio_intr_enable((gpio_num_t)PPS_PIN);
gpio_config_t cfg;
cfg.intr_type=GPIO_INTR_POSEDGE;
cfg.pin_bit_mask=(1ULL<<PPS_PIN);
cfg.mode=GPIO_MODE_INPUT;
cfg.pull_up_en=GPIO_PULLUP_DISABLE;
cfg.pull_down_en=GPIO_PULLDOWN_DISABLE;
ESP_ERROR_CHECK(gpio_config(&cfg));
WSR(CCOMPARE_2, 2400000);
ESP_LOGE("Intr", "Try to enable Timer intr.");
xt_ints_on(1 << 16);
ESP_LOGE("Intr", "Try to enable PPS intr.");
xt_ints_on(1 << 31);
ESP_LOGE("Intr", "Try to register PPS intr.");
intr_matrix_set(0, ETS_GPIO_INTR_SOURCE, 31);
ESP_LOGE("Intr", "Register Intr done.");
vTaskDelete(NULL);
}
void Output(void *you_need_this)
{
int iii=0;
while(1)
{
printf("\n[%d]Interrupt Counter =%lu",++iii,IntCounter[0]);
vTaskDelay(500/portTICK_PERIOD_MS);
}
}
extern "C"
void app_main(void)
{
xTaskCreatePinnedToCore(Output,"Out",4096,NULL,0,NULL,0);
vTaskDelay(3000/portTICK_PERIOD_MS);
xTaskCreatePinnedToCore(RegisterInt,"allocEXTGPIOINT",4096,NULL,0,NULL,0);
while(1)
vTaskDelay(1000/portTICK_PERIOD_MS);
}
Code: Select all
#include <xtensa/coreasm.h>
#include <xtensa/corebits.h>
#include <xtensa/config/system.h>
#include "soc/gpio_reg.h"
#define PPS_PIN 8
#define PPS_INT_Sta_REG GPIO_STATUS_REG
#define PPS_INT_W1TC_REG GPIO_STATUS_W1TC_REG
#define PPS_Mask (1<<PPS_PIN)
.section .iram1,"ax"
_l5_intr_stack:
.space 64
//Interrupt Handler
.section .iram1,"ax"
.global xt_highint5
.type xt_highint5,@function
.align 4
xt_highint5:
/////////////////////////////////////////////////////////////////////////////////////////////////////
//save register values. It takes around 15 cpu cycles to save the register valeus.
movi a0, _l5_intr_stack
s32i a5, a0, 0
s32i a6, a0, 4
s32i a7, a0, 8
s32i a4, a0, 44
s32i a3, a0, 48
s32i a2, a0, 52
s32i a1, a0, 56
rsr a1, SAR
s32i a1, a0, 60
//////////////////Interrupt handling start////////////////////////////////
YourCodeHere:
//----------------------------
//increase ccompare_2 by 60M
movi a5, AlarmValue
l32i a7, a5, 0
movi a6, 60000000
add a7, a7, a6
wsr a7, CCOMPARE_2
s32i a7, a5, 0
//---------------------------
//reset intr flag (no matter if it is gpio interrupt)
movi a3, GPIO_STATUS_W1TC_REG //get REG to clear the interrupt status
movi a4, PPS_Mask //load Pin mask
s32i a4, a3, 0 //write the mask to Int clear REG
memw
//increase IntCounter[0] by 1
movi a3, IntCounter
l32i a4, a3, 0
addi a4, a4, 1
s32i a4, a3, 0
SAVE_EXIT:
movi a0, _l5_intr_stack
l32i a5, a0, 60
wsr a5, SAR //restore shift register
l32i a5, a0, 0
l32i a6, a0, 4
l32i a7, a0, 8
l32i a4, a0, 44
l32i a3, a0, 48
l32i a2, a0, 52
l32i a1, a0, 56
//---------------------------------------------------------------
//return
EXIT:
rsr a0, EXCSAVE_5 /* restore a0 */
rfi 5
.global ld_include_highint_hdl_my
ld_include_highint_hdl_my:
Code: Select all
idf_component_register(SRCS
"main.cpp"
"Sampling_Int.S"
INCLUDE_DIRS ".")
target_link_libraries(${COMPONENT_TARGET} "-u ld_include_highint_hdl_my")