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:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

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.

Fullscreen
1
2
3
4
5
6
7
8
9
10
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;
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

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

Any advice would be appreciated.