I'm trying to measure the pulse ON time of an input signal which has a variable duty cycle with the help of the GPIOTE/PPI/Timer interfaces.
#include <Arduino.h>
#include <hal/nrf_timer.h>
#include <hal/nrf_gpiote.h>
#include <hal/nrf_gpio.h>
#include <hal/nrf_ppi.h>
static uint8_t pin = 5;
void setup() {
// put your setup code here, to run once:
// timer init
NRF_TIMER4->MODE = TIMER_MODE_MODE_Timer;
NRF_TIMER4->TASKS_CLEAR = 1;
NRF_TIMER4->PRESCALER = 4; // 1MHz
NRF_TIMER4->BITMODE = TIMER_BITMODE_BITMODE_16Bit; //Set counter to 16 bit resolution
// gpio init
NRF_GPIOTE->CONFIG[0] = GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos |
GPIOTE_CONFIG_POLARITY_LoToHi << GPIOTE_CONFIG_POLARITY_Pos |
digitalPinToPinName(pin) << GPIOTE_CONFIG_PSEL_Pos |
GPIOTE_CONFIG_OUTINIT_High << GPIOTE_CONFIG_OUTINIT_Pos; //
ignored when gpio is set to event mode
NRF_GPIOTE->CONFIG[1] = GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos |
GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos |
digitalPinToPinName(pin) << GPIOTE_CONFIG_PSEL_Pos |
GPIOTE_CONFIG_OUTINIT_High << GPIOTE_CONFIG_OUTINIT_Pos; //
ignored when gpio is set to event mode
// ppi init
// start timer on rising edge
NRF_PPI->CH[0].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[0];
NRF_PPI->CH[0].TEP = (uint32_t)&NRF_TIMER4->TASKS_CLEAR;
NRF_PPI->FORK[0].TEP = (uint32_t)&NRF_TIMER4->TASKS_START;
NRF_PPI->CHENSET = PPI_CHENSET_CH0_Enabled << PPI_CHENSET_CH0_Pos;
// stop timer on falling edge
NRF_PPI->CH[1].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[1];
NRF_PPI->CH[1].TEP = (uint32_t)&NRF_TIMER4->TASKS_CAPTURE[1];
NRF_PPI->FORK[1].TEP = (uint32_t)&NRF_TIMER4->TASKS_STOP;
NRF_PPI->CHENSET = PPI_CHENSET_CH1_Enabled << PPI_CHENSET_CH1_Pos;
}
void loop() {
// put your main code here, to run repeatedly:
Serial.print("Event 0 status - "); Serial.println(NRF_GPIOTE->EVENTS_IN[0]);
Serial.print("Event 1 status - "); Serial.println(NRF_GPIOTE->EVENTS_IN[1]);
Serial.print("CC value - "); Serial.println(NRF_TIMER4->CC[1]);
}
The code works fine for slower signals but when I give a signal in the KHz range I get a lot less timer count that expected. In the above code the timer is ticking at 1us, so for a signal with ON time of 60us, I was expecting 60 ticks, but the NRFTIMER->CC[1] register is showing only 5 ticks.
Is this a limitation from the GPIOTE/PPI peripherals? Has anyone tried this approach?