Increment Timer Based On Edge Trigger From GPIOTE Using DPPI

Hello,

I'm using an nrf9160 to count the number of falling edges on a GPIO pin using a timer without any processor intervention, aside from capturing the number after some interval elsewhere. It sounds like DPPI is my best bet, but I can't seem to find any information about my specific use case outside of the Nordic documentation.

My method of capturing the timer value doesn't seem right, but I haven't found any resources telling me so. I'm experimenting with S and NS configurations since there's a line that reads "non-secure peripherals can only subscribe to non-secure channels". I'm seeing quite a lot of potential areas where my logic may be broken, so I was hoping to get some direction as to why my code doesn't work properly.

#include "pulseDriver.h"
#include <zephyr/kernel.h>
#include <nrfx_dppi.h>

#define INP_PIN 8

void pulseDriver_init(void)
{
    // Configure IO pin
    uint32_t configInt = 0;
    configInt |= 1; // event mode
    configInt |= INP_PIN << 8; // Specify pin number
    configInt |= 2 << 16; // Trigger when going from hi to lo
    
    NRF_GPIOTE1_NS->CONFIG[0] = configInt; // Assign config
    NRF_GPIOTE1_NS->PUBLISH_IN[0] = 1; // enable publishing

    // Configure timer
    NRF_TIMER1->MODE = 1; // 0: timer mode. 1: Counter mode. 2: low power counter mode
    NRF_TIMER1->SUBSCRIBE_COUNT = (1 << 31) | 0; // Enable subscription for count task, subscribe to channel 0
    // Timer's default size is 16, which seems sufficient

    // Enable the channel that the above are tied to
    NRF_DPPIC->CHENSET = (1 << 1) | (1 << 0);
    
    NRF_TIMER1->TASKS_START = 1; // Enable the timer.
}

// Gets total number of pulses since last record
uint32_t pulseDriver_getCount()
{
    uint32_t returnVar;
    // Record timer to return variable
    NRF_TIMER1->TASKS_CAPTURE[0] = 1; // Capture timer value into CC
    returnVar = NRF_TIMER1->CC[0];
    
    return returnVar;
}

Thanks in advance

  • I forgot to mention that I am using an nrf9160 dev kit and SDK 2.2.0

    Edit: I just threw the timer into timer mode, and it appears that I am actually capturing the value properly.

    Another edit: I found that the DPPI channel I was publishing GPIOTE to was set to 1, not zero. That and I had not turned on the enable bit. Adding whats below fixed my issue:

    NRF_GPIOTE1_NS->PUBLISH_IN[0] = (1 << 31) | CHANNEL_NUM; // enable publishing

Related