Is there a simple example of how to enable two GPIOTE interrupts for fast timing?

I would like to monitor the states of switches sw0 and sw1 on my nrf7002dk board using GPIOTE interrupts.

Initially this is just for example purposes.

I eventually need to assign two other GPIO pins where I need to have the ability to time ~30 microsecond accuracy and I am finding that the standard Zephyr PORT interrupts not fast enough for my timing purposes.

The nrfx example that I looked at assigns just one GPIOTE pin and I am having difficulty assigning another pin. Specifically when it comes time to IRQ_CONNECT and nrfx_gpiote_in_init the second GPIO pin.

Thank you.

  • Hi Adam,

    The clock_init() function is not required, but it will make the TIMER run off the more accurate HFXO clock source instead of HFINT, which has a worst-case tolerance of +-8%.

    Interrupt latency is likely a factor for the poor measurements results. I recommend connecting the GPIOTE IRQ as a zero latency interrupt to see if that improves the timing:

    https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/kernel/services/interrupts.html#zero-latency-interrupts 

    The other alternative is to disable the GPIOTE interrupt and instead poll the inputs using the gpio HAL (<hal/nrf_gpio.h>)

    Best regards,

    Vidar

  • Thank you Vidar,

    I switched to using GPIOTE and NRFX_GPIOTE_TRIGGER_LOTOHI for that pin and now I am seeing the correct number of low to high edges for 135KHz for roughly 2 seconds of counting.

    uart:~$ start
    started: 1970/01/01 00:00:09 UTC
    uart:~$ stop
    stopped: 1970/01/01 00:00:11 UTC
    rising_edges: 288872
    falling_edges: 0

    Clearly GPIO interrupts have too much latency.

    However, I need to capture LOTOHI and HITOLO edges and then read the timer on every interrupt. Is this also possible?

    If I change the trigger to NRFX_GPIOTE_TRIGGER_TOGGLE how will I know which edge is causing the interrupt? I suspect that calling nrfx_gpiote_in_is_set( pin ) in the pin event handler will not work.

    Best regards,

    Adam

  • Hi Adam,

    The latency will also increase as you start adding adding more signal inputs, so I think your best option may be to disable the GPIOTE interrupt after the first event. Then, use the GPIO HALs to read the pin states in a loop until the transfer is complete. The polling should happen outside of the interrupt context if you need to sample for longer periods to avoid blocking other parts of the app.

    Best regards,

    Vidar

  • Hi. I have similar problem, I try to do autobaud for my uart. I have to measure low level signal, so I need to use NRFX_GPIOTE_TRIGGER_TOGGLE. Is it possible to configure timer using PPI to start (capture) on falling edge and stop (capture) on rising?
    Best regards,
    PW  
         

  • Hi,

    You need to connect two input pins to detect raising and falling edge, where one channel is configured to detect falling edge, and the other to detect rising edge. This is because a pin can only be assigned to one GPIOTE channel at a time. Failing to do so may result in unpredictable behavior.

    The TOGGLE event will trigger on any change (falling or rising) and can still be used to measure the frequency.

Related