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.

  • Hello,

    I've created an example that uses GPIOTE with 2 input pins. Please see attached. I may be able to expand this sample if you could describe what you are trying to monitor. Is it a signal input you want to measure on each pin as discussed in this thread:  GPIOTE + PPI SDK v2.5.2 issue + zephyr ? If so, you may need to use TIMER+PPI to accurately time signal periods.

    The Zephyr GPIO API also supports use IN events instead of PORT events if you change the triggering flag from *_LEVEL_* to _EDGE_ triggering. 

    Test sample

    hello_world_gpiote.zip

    Best regards,

    Vidar

  • Thank you Vidar.

    That example worked perfectly!

    To expand on this, I did try to use Zephyr GPIO _EDGE_ triggering in combination with the Zephyr timing functions in my pin event handlers (ie. timing_init, timing_start, timing_counter_get, timing_cycles_get), but found the values I was getting sometimes inconsistent as compared to the edge to edge times on my oscilloscope.

    Is this the wrong approach?

    Ultimately I would like to monitor the pulse widths on 4 GPIO pins where the widths can be as lows as 30 microseconds.

    Perhaps I need to move to timing with PPI. Is there an example of using PPI to get accurate GPIO edge to edge timing?

    Thanks again,

    Adam

  • Hi Adam,

    I'm glad to hear that it worked, and thanks for the additional information. With that many inputs, which I assume you will want to sample simultaneously, it might be better to continuously poll the input pins if the inputs are only going to be sampled for a limited amount of time. The appcore has three TIMER instances, so you cannot allocate one TIMER for each pin, which would be necessary if you were going to use PPI for triggering the TIMER start and stop tasks. Maybe you could use pin interrupts to start the polling? The pin states can be read with nrf_gpio_pin_read() from <hal/nrf_gpio.h>. With polling, you will not experience the interrupt latencies.

  • Vidar,

    Actually you raise a good point.

    To further detail... two of the pins (relatively wide pulse widths in the millisecond range) are used to start precision timing of the other two pins (tens of microseconds range), so I can probably get away with just two TIMERs.

    Is there is an example of how to use PPI triggering to use a TIMER for the fast pins?

    Basically I want to be able to accurately capture the low to high and high to low edge to edge time in microseconds. Can this be done using PPI triggering of the TIMER without software having to directly read the TIMER counter value (risk of interrupt latency) and do the math manually?

    Best regards,

    Adam

  • Adam,

    My coworker Torbjørn has created an example of pulse counting with GPIOTE and a TIMER which seems relevant for this: https://github.com/too1/ncs-nrfx-pulse-count-example.

    Adam K. said:
    Basically I want to be able to accurately capture the low to high and high to low edge to edge time in microseconds. Can this be done using PPI triggering of the TIMER without software having to directly read the TIMER counter value (risk of interrupt latency) and do the math manually?

    You can let the timer run freely and trigger a capture task when the pulse begins and another when it ends. However, each PPI endpoint must be connected to a specific capture task, so the CPU must be able to read the timer capture values before the next capture is triggered through PPI.

    Best regards,

    Vidar

Related