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

Interrupt latency really higher that specified in the ARM specification

Good evening,

I determined the numbers of clocks necessery to fire up an interrupt from an GPIOTE event.

My debugger reports 1373 clocks ticks to go into and go back from the interrupt.

In the Cortex-M4F technical documentation, I found that to enter in the interrupt only 12 clocks ticks is needed to go into the interrupt and 10 to return from it. Even if I count the number of clock executed in the interrupt the value reported is very different.

So, where does the difference come from ?

Here's the code :

#include <stdbool.h>
#include "nrf.h"
#include "nrf_drv_gpiote.h"
#include "app_error.h"
#include "boards.h"
#include "nrf_drv_timer.h"

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "app_util_platform.h"

#define PIN_IN 33 //BUTTON_1 
#define PIN_OUT BSP_LED_0

const nrf_drv_timer_t TIMER = NRF_DRV_TIMER_INSTANCE(1);
uint8_t state = 0, state_prev=0;
uint8_t ready = 0;
uint16_t captured_value,captured_prev = 0;
float frequency = 0.0;

void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
    /************* Bypass the nrf driver to be fast as possible *****************/
    uint32_t pins_state = NRF_P1->OUT; // Read the state of the register
    
    //Toggle operation
    NRF_P1->OUTSET = (~pins_state & (1UL << 2)); // 2 for the bit 1 of the port1
    NRF_P1->OUTCLR = (pins_state & (1UL << 2));
    /****************************************************************************/
}

/**
 * @brief Function for configuring: input PIN, output PIN,
 * and configures GPIOTE to give an interrupt on pin change.
 */
static void gpio_init(void)
{
    ret_code_t err_code;

    err_code = nrf_drv_gpiote_init();
    APP_ERROR_CHECK(err_code);
    
    /* Configure output pin */
    nrf_drv_gpiote_out_config_t out_config = GPIOTE_CONFIG_OUT_SIMPLE(false);
    
    err_code = nrf_drv_gpiote_out_init(PIN_OUT, &out_config);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_gpiote_out_init(34, &out_config); //Output on P1.02 for debugging
    APP_ERROR_CHECK(err_code);
    /**************************************/

    /* Configure input for capture */
    nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
    in_config.pull = NRF_GPIO_PIN_PULLUP;

    err_code = nrf_drv_gpiote_in_init(PIN_IN, &in_config, in_pin_handler);
    APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_in_event_enable(PIN_IN, true);
    /**************************************/
}

int main(void)
{
    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    gpio_init();
    
    while (true)
    {

    }
}

Sincerely,

Sylvain.

Related