This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

GPIOTE High-accuracy interrupt latency

Hello,

Our product is configured to use 3 total GPIOTE channels –– 2 sensors configured for "high accuracy" GPIOTE events, each around 10Hz refresh rate, and 1 using "low accuracy" at 1Hz rate. In our interrupt handlers for each respective sensor, we're simply setting a (volatile) data-ready flag.

We've been finding that, sporadically, we seem to be "missing" some of these interrupts. They are more heavily correlated during periods of BLE activity (which is about once per hour), but also happens even when BLE isn't active for minutes before or after. This can be broken into two main issues:

1. Latency between sensor pin being set and seeing our data ready flag get raised. As in, when we check the GPIO level for each of these sensors to test for this, we will sometimes find that the sensor's interrupt pin is set, but our data ready flag has not been set yet, meaning that somehow we are still executing non-interrupt application code in between the sensor raising its interrupt pin and the GPIOTE IRQ handler going off. Usually, the interrupt will still go off and our data ready flag  will still be set, but only after a few more lines of application code are run. Is this expected in any known scenarios? 

2. Interrupts missed completely, as in the IRQ handler for the given sensor will never actually be called as a result of the sensor interrupt pin being raised. In these instances, the sensor won't clear its interrupt pin until we retrieve data from the sensor, but since the IRQ didn't go off, we would be going an indefinite amount of time without getting sensor data if we didn't add safeguards to detect these "missed" interrupts. This happens with both the "high accuracy" and "low accuracy" GPIOTE configurations.

I've looked through the NRF52's relevant documentation to try to address these issues but haven't been able to find anything that would explain why we would be seeing the above issues. 

  • Hi,

    Just to make sure, do you have separate 'data ready' flag for each input? The IRQs are not particularly high in frequency so I wouldn't expect it to be a problem with the Softdevice. It also sounds like your ISRs are kept short, so that helps as well. 

    1. The GPIOTE IRQ will get blocked by the Softdevice interrupts from time to time, and I think it explains why the update of the flag gets delayed sometimes.  But the delay should only be in the micro-second range as long as you're not erasing flash pages. Are you doing any flash operations when this happens? Softdevice execution times inside ISRs are documented here: Bluetooth Low Energy processor usage patterns 

    2. IRQs should become pending while blocked by other higher priority IRQs and should not become lost. Could it be possible that the GPIOTE IRQ gets processed but that there some race condition that causes the program to not properly de-assert the sensor IRQ line afterward? Do you have a way to verify that the GPIOTE IRQ is not triggered when the IRQ lines go from low to high?

    Best regards,

    Vidar 

  • Thank you for the response.

    1. The issue isn't a matter of latency in terms of time but rather the fact that our own non-interrupt application code is running between polling the GPIO and seeing the ISR get triggered. I'll paste some example code below to show what I'm trying to describe (no need to set private, this is pretty generic and rudimentary):

    // Sensor interrupt callback functions
    static void imu_data_ready()
    {
        s_imu_data_ready = true;
    }
    
    
    ...
    
    
    // Check if interrupt pin is active
    
    // Interrupt active for this sensor is low logic level, so negate result
    interrupt_active = !(nrf_gpio_pin_read(ACCEL_DATA_READY_1_PIN));
    
    if(interrupt_active && !s_imu_data_ready)
    {
        interrupt_test = s_imu_data_ready;
        APP_ERROR_HANDLER(ERROR_IMU_INTERRUPT_MISSED);
        
        // Uses segger RTT to minimize effect on program execution
        // Tells us the status of data ready flag immediately after the conditional
        PRINTF_RTT("data ready flag %d\r\n", interrupt_test);
    }

    So the issue I'm describing is that we can get into this conditional and 'interrupt_test' will immediately tell us that data ready flag is now set to 1. In line 14 of this snipped we will see that the sensor's interrupt pin is active, but then in line 16 we will see that data_ready flag is still 0, meaning that the ISR hasn't run yet even though we see that the pin is high.

    In every test so far, 'interrupt_test', which is assigned in line 18, will be populated with a 1 when we go to RTT print it, meaning that the ISR was executed between the execution of the conditional (line 16) and the 'interrupt_test' assignment.

    This shows conclusively that between our polling of the GPIO and seeing the ISR go off, the conditional is still being executed.

    Is there any debouncing / trigger window on the GPIOTE_IRQHandler that would prevent the IRQ from going off as soon as the logic level on that GPIO line changes to what the GPIOTE interrupt channel is expecting?

    I understand that the processor will still execute its current operation when a hardware interrupt arrives asynchronously, but seeing a full conditional execute in between the logic level change and ISR execution seems bizarre to us. Is it possible that some optimization is combining those operations and that's why we're seeing this?

    Any ideas are welcome and appreciated. As for the #2 issue, I will be doing more testing to bring you more information on that scenario and what we know so far. Thank you!

  • Additional information, GPIOTE interrupt is configured as follows:

    nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
    
    in_config.pull = NRF_GPIO_PIN_PULLUP;

  • Is the s_imu_data_ready variable declared volatile?

Related