weizzh
weizzh

Reputation: 1

ESP32 hardware ISR sometimes not triggered when wifi is transmitting

I tried to use hardware timer to read data from an external device periodically. More specifically, I realized a custom driver using gpio to simulate SPI protocol, whenever an hardtimer interrupt happens, the driver is called to read gpio status. The timer is set to 2k.

When an interrupt happens, the isr shall put sample data into a buffer. When the buffer is full, the application will pause the timer and send these data out through mqtt protocol. Using signal generator and oscilloscope, I found the data was good. The whole process worked as expected.

The problem is that the sample process is not continual. When data is sending out through wifi, the timer is paused, and no data can be read into buffer.

To solve this problem, I create a special task responsible for transmitting data out. And then I use ping-pong buffers to store sample data. When one buffer is full, the sending task is notified to send these data out, meanwhile the timer isr is continually to put data into another buffer.
At first I wanted to send notify just from the isr (using xQueueSendFromISR()), which was proved not reliable. I found only a few notifies were able to be sent to the sending task. So I am obliged to using a flag. When one buffer is full, the flag is set to true, While a special task is looping this flag, whenever it find the flag is true, it will notify the sending task.

timer_isr()
{
    
    read_data_using_gpio;
    if(one buffer is full)
    {
        set the flag to true
    }
}

task_1()
{
    while(1)
    {
        if(the flag is true)
        {
            set the flag to false;
            xQueueSend;
        }
        vTaskDelay(50ms)//it will cost 200ms to fill up the buffer
    }

}

task_2()
{
    while(1)
    {
        xStatus = xQueueReceive;
        if(xStatus==pdPASS) // A message from other tasks is received.
        {
            transmitting data out using mqtt protocol.
        }
    }

}

Then I got the terrible data as below. terroble data I used oscilloscope to check the gpio operation in the isr. oscilloscope1 oscilloscope2 So it seems like some isr not triggered? but what happened?

More weird thing: I added another task to get data from an audio chip through i2s. Again I used ping-pong buffers and send notify to the same sending task.

timer_isr()
{
    
    read_data_using_gpio;
    if(one buffer is full)
    {
        set the flag to true
    }
}

task_1()
{
    while(1)
    {
        if(the flag is true)
        {
            set the flag to false;
            xQueueSend;
        }
        vTaskDelay(50ms)
    }

}
task_3()
{
    while(1)
    {
        i2s_read_to_buffer;
        xQueueSend;
    }
}
task_2()
{
    while(1)
    {
        xStatus = xQueueReceive;
        if(xStatus==pdPASS) // A message from other tasks is received.
        {
            if(data from task_1)
            {
                do something;
                transmitting data out using mqtt protocol
            }
            if(data from task_2)
            {
                do something;
                transmitting data out using mqtt protocol
            }
            
        }
    }

}

And this time the data from former task turned ok! data_ok

And what's more, after I commened task2-related code in the sending task, Again the data become bad! So what happened? Can somebody give any hint?

task_2()
{
    while(1)
    {
        xStatus = xQueueReceive;
        if(xStatus==pdPASS) // A message from other tasks is received.
        {
            if(data from task_1)
            {
                do something;
                transmitting data out using mqtt protocol
            }
            if(data from task_2)
            {
                // do something;
                // transmitting data out using mqtt protocol
            }
            
        }
    }

}

Upvotes: 0

Views: 868

Answers (1)

weizzh
weizzh

Reputation: 1

I have solved this problem. If you enable power management(idf.py menuconfig-->component config-->power management), the APB(advanced peripheral bus) will low its frequency automatically, which is the clock source of hardware timer.Thus you will see the timer interrupt is not stable. Just disable the power management.

Upvotes: 0

Related Questions