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

Large delay when using app scheduler in GPIOTE interrupt

Hello,

I have an external chip in SPI slave mode and connected to 52840 through SPI interface. When data is ready it will notify 52840 through its dedicated IRQ pin (connected to one of GPIO of 52840), and then 52840 will read the data back through SPI bus., using SPIM driver.

the software is composed like this:

1. Setup GPIOTE to sense the GPIO/IRQ pin (low to high)

2. in GPIOTE interrupt handler, use app_scheduler to transfer execution to main context.

3. in main context, use SPIM driver to read data back to 52840's RAM.

the above process can run fine and the data read back are all correct. However, a problem is Step 2. has a large delay about 2ms. that is, after app_sched_event_put is called, the data event handler is executed only after 2ms. My application can not tolerant such big delay.

Is this delay normal? if not, what could be the possible reason why it happen?

Major code snippet:

Main.c

int main(void)
{
    bool erase_bonds;
    
    // Initialize.
    log_init();

    NRF_LOG_INFO("Starting nrf52840...");
    
    timers_init();
    buttons_leds_init(&erase_bonds);
    power_management_init();

    //init event scheduler;
    APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE);
    
    
    // Enter main loop.
    for (;;)
    {
        //handle usbd event sperately;
        //app_usbd_event_queue_process();
        
        app_sched_execute();
        if (NRF_LOG_PROCESS() == false)
        {
			idle_state_handle();
            //power_manage();
        }
    }
}

GPIOTE init:

{
    ...
    ret_code_t err_code;
    UNUSED_VARIABLE(err_code);
    if(!nrf_drv_gpiote_is_init())
    {
        err_code = nrf_drv_gpiote_init();
        APP_ERROR_CHECK(err_code);
    }
    nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);
    //in_config.pull = NRF_GPIO_PIN_PULLUP;
    UNUSED_VARIABLE(in_config);
    err_code = nrf_drv_gpiote_in_init(EXT_DATA_IRQ_PIN, &in_config, gpiote_irq_handler);
    //APP_ERROR_CHECK(err_code);
    nrf_drv_gpiote_in_event_enable(EXT_DATA_IRQ_PIN, true);
    ...
}

GPIO interrupt handler

void gpiote_irq_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
    
    if (pin == EXT_DATA_IRQ_PIN) {
     

        ex_data_event_t evt;
        //fill in data evt;
        ....
        app_sched_event_put(&evt, sizeof(evt), data_event_dispatch);

    }
    
}

app scheduler event hander:

void data_event_dispatch(void *p_event_data, uint16_t event_size) {
    ex_data_event_t* p_evt = (ex_data_event_t*)p_event_data;
    switch (p_evt->pa_ops) {
        case DATA_OPS_TYPE_EXT_PA_ON:
            //NRF_LOG_DEBUG("[ext]\tswitch PA on...");
            break;
    }
    ...

}

Parents
  • Hi,

    The app scheduler is just a queue that you pop ad process in the main loop. Your main loop does not do much else, and the queue is processed before logs (assuming you use deferred logging), so I do not see an explanation there. Could it be caused by other interrupts that are processed at the same time, and that takes some time? (they happen at the same time for some reason)?

  • thx for the swift reply @Einar Thorsrud. this also seems the same strange to me.

    I could not think of what the processor is really doing during this 2ms. I added log at the end of gpiote_irq_handler and the first beginning of app_sched_execute, this delay appears exactly between every GPIOTE interrupt ends and the beginning of app_sched_execute. And this delay does not happen whenever app_shed_event_put is not called from GPIOTE interrupt, for example, a timer interrupt context.

    I did have few other timers defined, but the intervals are all above 30ms, so seems not possible this inteference can happen in this accuracy.

    I tried to tap into the scheduler queue to see if any other events blocked there. From the output I can see when this delay happens there is only 1 event in queue, i.e., the GPIOTE interrupt generated event itself. So the queue is really quite empty.

    I also tried to config different GPIOTE/SPIM priority, but the result is just the same.

    I tend to guess this delay is somewhat related with GPIOTE module specificly. Do you have any suggestions on how to debug further that I can find out what CPU is really doing in this 2ms delay?

    My setup:

    SDK v15.2 with softdevice v610 presented.

Reply
  • thx for the swift reply @Einar Thorsrud. this also seems the same strange to me.

    I could not think of what the processor is really doing during this 2ms. I added log at the end of gpiote_irq_handler and the first beginning of app_sched_execute, this delay appears exactly between every GPIOTE interrupt ends and the beginning of app_sched_execute. And this delay does not happen whenever app_shed_event_put is not called from GPIOTE interrupt, for example, a timer interrupt context.

    I did have few other timers defined, but the intervals are all above 30ms, so seems not possible this inteference can happen in this accuracy.

    I tried to tap into the scheduler queue to see if any other events blocked there. From the output I can see when this delay happens there is only 1 event in queue, i.e., the GPIOTE interrupt generated event itself. So the queue is really quite empty.

    I also tried to config different GPIOTE/SPIM priority, but the result is just the same.

    I tend to guess this delay is somewhat related with GPIOTE module specificly. Do you have any suggestions on how to debug further that I can find out what CPU is really doing in this 2ms delay?

    My setup:

    SDK v15.2 with softdevice v610 presented.

Children
No Data
Related