Page 1 of 1

High frequency GPIO Interrupt

Posted: Sat Feb 09, 2019 5:03 am
by dragondgold
I'm having a problem with "high-frequency" GPIO interrupt. I have a signal coming from another microcontroller that generates a 50us low pulse every 12ms and I capture this pulse using a falling-edge interrupt to send a task notification to a task with the highest priority in all my program.

The GPIO ISR service is placed in IRAM using:

Code: Select all

gpio_install_isr_service(ESP_INTR_FLAG_IRAM);
The interrupt type is GPIO_INTR_NEGEDGE and the ISR handler looks like this:

Code: Select all

static void IRAM_ATTR scl_isr_handler(void* arg)
{
    static BaseType_t xHigherPriorityTaskWoken = pdFALSE;

    if(!gpio_get_level(PIC16_PIN))
    {
        vTaskNotifyGiveFromISR(task_handle, &xHigherPriorityTaskWoken);

        if(xHigherPriorityTaskWoken)
        {
            portYIELD_FROM_ISR();
        }
    }
}
The problem is, this works for around 250 ms after ESP32 boot and then the interrupt stops being fired (I'm checking everything with a logic analyzer and logs). However, if I increase the time to generate a 50us low pulse every 100ms instead of 12ms, it works as expected. How can I diagnose this problem? Can't the ESP32 handle an interrupt every 12ms? Even the RTOS tick rate is faster than that.

Re: High frequency GPIO Interrupt

Posted: Sat Feb 09, 2019 10:32 am
by ESP_Sprite
It should indeed have no issue handling that. What ESP-IDF version are you using? Do you happen to have the full code for this available somewhere?

Re: High frequency GPIO Interrupt

Posted: Sat Feb 09, 2019 5:14 pm
by dragondgold
Hi, thank you for your response! I'm using the latest release/v3.1 branch. Here is some more code:

main.c: https://pastebin.com/iG74a6wi
power_monitor.c: https://pastebin.com/vc52Yqnj
sdkconfig: https://pastebin.com/E6C7h5GG

The ESP32 is communicating with a PIC16 microcontroller through an I2C bus. There isn't any other device on the bus so when the PIC16 has new data available it generates a 50us low pulse on the SCL line, the ESP32 detects this pulse and starts reading data. At first, I thought the I2C was hanging in the ESP32 but I can see that the problem is indeed that the interrupt is not firing because I inserted an ets_printf() in it to check.

Here is a capture from the logic analyzer:

Image

The red circles are the pulses generated by the PIC16. As you can see the ESP32 works as expected in the beginning but after 50ms it simply stops.