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

Interrupts are missed while configuring multiple gpio interrupts with active softdevice

Hi,

I am using 2 gpio interrupts from 2 separate sensors with active soft device. one sensor generates interrupts at around 400-800 ms and the other comparatively lesser time in every 5 sec. my device has to wake and read data when the interrupts are triggered

i have initialized the gpio with IN_EVENT (high accuracy = true) but i am missing some interrupts frequently.

In this documentation, its mentioned to use PPI in high accuarcy mode  with a timer to count the transitions. in my case the timer may not be required as it comes only in around 400ms. i am a bit confused on the ppi part, as per my understanding from the documentation ppi is used to trigger a task of another peripheral on an event, gpio state change in my case (please correct me if i am wrong). how should i add the ppi to my application so that i dont miss any interrupts?

Parents
  • i am missing some interrupts frequently.

    Can you elaborate on this a little? How do you service the interrupts and what exactly happens when you miss one? In other words, describe a case where things go wrong.

    You say your device has to wake up and read data when the interrupts are triggered. Are you saying the device sometimes doesn't wake up?

    -Bill

  • HI Bill,

    i have not tested the case with wake up, i have connected the interrupt pin to an oscilloscope and blinking the led when interrupt is detected on nrf52. it was very clear that some of interrupts were missed. led didn't blink when oscilloscope shown a change in   level of the pin. around 10% of the interrupts were missed.

    here is my code snippet

    void drdy_interrupt_enable(void) // DRDY isr
    {
      ret_code_t err_code;
      err_code = nrf_drv_gpiote_init();
      APP_ERROR_CHECK(err_code);
      nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);
      in_config.pull = NRF_GPIO_PIN_PULLUP;
      in_config.	hi_accuracy = true;
    
      err_code = nrf_drv_gpiote_in_init(INT_PIN, &in_config, in_pin_handler);
      APP_ERROR_CHECK(err_code);
    
      nrf_drv_gpiote_in_event_enable(INT_PIN, true);
      
      err_code = nrf_drv_gpiote_in_init(17, &in_config, intr_handler);
      APP_ERROR_CHECK(err_code);
    
    nrf_drv_gpiote_in_event_enable(17, true);
    }
    
    
    void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
        intr_flag = true;
    }

  • Sorry for a delay in responding. I've been dealing with debugging some of my own problems, and I'm still a bit confused by what's going on here.

    Regarding the use of PPI with the GPIOTE module, I think there are a couple of possible use cases. One is for output, which I think covers the specific part of the documentation you highlighted. Say you want to make a GPIO pin wiggle when a PPI event is triggered. You could set up a PPI linkage with the SPI controller such that when a SPI interrupt occurs, you make a GPIO pin change state. This would occur without any involvement of the CPU. For this, you have up to 8 TASKS_SET/CLR registers, each of which corresponds to a pin that you assigned to a GPIOTE channel.

    For input, you could use PPI in the other direction. When a GPIOTE interrupt is triggered, one of the EVENTS_IN registers will indicate it. You could then use PPI to link the corresponding register to some other device. For example, maybe you could make  it start a SPI transfer (the opposite of the previous case).

    But here, you just want to use a GPIO as input and you're not using the PPI (yet?) so that doesn't matter.

    One problem here is that there are several things which may affect behavior here:

    - The behavior of the GPIOTE module hardware

    - The behavior of the ARM NVIC hardware (interrupt controller)

    - The behavior of Nordic's SDK code which supports the GPIOTE module

    - Your code

    One detail to bear in mind is that with Nordic's SDK, unless you're using FreeRTOS, you only have two execution contexts: application and ISR. In Nordic's implementation, the interrupt handler (nrfx_gpiote_irq_handler()) executes your handler function (in_pin_handler()) directly. You may need to be careful how you code your handler: you can't spend too much time in the ISR or that may affect processing of subsequent interrupts.

    The code snippet you provided only shows that you set intr_flag to true in your handler. But earlier you said:

    i have connected the interrupt pin to an oscilloscope and blinking the led when interrupt is detected on nrf52. it was very clear that some of interrupts were missed. led didn't blink

    I'm assuming then that you had some additional code somewhere to make the LED blink, but you didn't include that so I can't tell what it does.

    The nrfx_gpiote_irq_handler() function seems to check all GPIOTE channels for events and save the info into an "event" variable (and if the channel is triggered, it clears the event). Then it iterates over this set of events in another loop and calls the handler function (if any) that's registered for that channel.

    There is some question as to what happens if an event triggers while you're still executing in the ISR. The ARM NVIC should handle this: if the interrupt is triggered again during the ISR, then once you exit the ISR the interrupt will be back in the pending state, and you'll enter the ISR again.

    But I don't think this case should happen often at all. Your ISR shouldn't take anywhere near 400ms to run. With the CPU clocked at 64MHz, you should be able to execute several million instructions in 400ms.

    Anyway, I'm not sure if what's happening here is that you're missing an interrupt, or if it's maybe just being delayed. I think a lot depends on what else is going on in your application. If you build a simple demo just to test the GPIOTE behavior, whose only job is to flash the LED when your sensor pulses, then I would not expect you to ever miss any events. However I don't know what happens when you query the sensor. If that code takes too long to complete, then you could miss events periodically. Unfortunately I don't know what further advice to offer without seeing the whole body of code and being able to do some first hand analysis, other than to say keep testing and try to come up with a minimum configuration that seems to work and keep building up from there.

    -Bill

  • Thank you Bill for the detailed explanation. its really insightful.

    i got it working,the  timestamp reading through i2c was causing the issue.

Reply Children
No Data
Related