High-level interrupt doesn't work with IDF V5.0?

yuwenpeng
Posts: 30
Joined: Tue Apr 12, 2022 6:25 am

High-level interrupt doesn't work with IDF V5.0?

Postby yuwenpeng » Thu Jan 12, 2023 4:59 am

Hi There,

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);
}
Sampling_Int.S:

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:
CMakeLists.txt:

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")

yuwenpeng
Posts: 30
Joined: Tue Apr 12, 2022 6:25 am

Re: High-level interrupt doesn't work with IDF V5.0?

Postby yuwenpeng » Fri Jan 13, 2023 8:21 pm

Does anyone have any clue?

Antares
Posts: 1
Joined: Sun Oct 29, 2023 12:38 pm

Re: High-level interrupt doesn't work with IDF V5.0?

Postby Antares » Sun Oct 29, 2023 12:44 pm

Hi all there,
I have the very same issue. Has anyone found a fix, or how th handle high level interrupt in version greater than V5.
Any help is highly appreciated.
Best regards
Anteras

Who is online

Users browsing this forum: iryna7 and 276 guests