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

Measuring Pulse Width using PPI and GPIOTE

Just as the title says, I'm trying to measure an input pulse width using PPI and GPIOTE.  I am currently measuring the pulse width using timer interrupts, but I would like to move to PPI to avoid issues when I start to use the Soft Device.

From looking at the forums, here is the start of my code:

NRF_GPIOTE->CONFIG[0] =  GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos | 
                                         GPIOTE_CONFIG_POLARITY_LoToHi << GPIOTE_CONFIG_POLARITY_Pos | 
                                         V_SENSOR << 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 | 
                                         V_SENSOR << GPIOTE_CONFIG_PSEL_Pos | 
                                         GPIOTE_CONFIG_OUTINIT_High << GPIOTE_CONFIG_OUTINIT_Pos;    // ignored when gpio is set to event mode

        //////////////////
        NRF_PPI->CH[5].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[0];  //What happens on the LotoHi transition from CONFIG[0]
        NRF_PPI->CH[5].TEP = (uint32_t)&NRF_TIMER3->TASKS_START;
        NRF_PPI->FORK[5].TEP = (uint32_t)&NRF_TIMER3->TASKS_CLEAR;

        NRF_PPI->CH[6].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[1];  //What happens on the HitoLo transition from CONFIG[1]
        NRF_PPI->CH[6].TEP = (uint32_t)&NRF_TIMER3->TASKS_CAPTURE[3]; //value of timer will be stored in NRF_TIMER3->CC[3]
        NRF_PPI->FORK[6].TEP = (uint32_t)&NRF_TIMER3->TASKS_STOP;

I am assuming the code should do the following:

V_SENSOR is P0.30, which has a periodic pulse of unknown pulse width.  The pulse will come every second, and the width will be between 100-400ms. On the LotoHi transition the timer will clear and begin to count, and on the HitoLo transition the timer will store the value so I can read it into a variable.

I have a 1 second interrupt where I try to grab the value of the timer, value = NRF_TIMER3->CC[3]; but that never seems to give me anything useful.

I configure and start my timer like so.

void timer_init()
{
    NRF_TIMER3->BITMODE                 = TIMER_BITMODE_BITMODE_24Bit << TIMER_BITMODE_BITMODE_Pos;
    NRF_TIMER3->PRESCALER               = 4;
    NRF_TIMER3->SHORTS                  = TIMER_SHORTS_COMPARE0_CLEAR_Msk << 5;
    NRF_TIMER3->MODE                    = TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos;
    NRF_TIMER3->CC[5]                   = 16;        
    
    NRF_TIMER3->CC[0] = 6;
}

In my main program I initialize the timer, initialize the GPIOE, and then start the timer.

Any advice would be appreciated.

Related