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

How to count timer overflows on a synchronized clock?

I am working with a modified project based on the time sync example using two nRF52832 DKs.

I want to capture how many times the timer overflows on the receiving board, while being synchronized to the sending board.

I created high_freq_timer[2] to be NRF_TIMER4 and configured it in counter mode, just after sync_timer_start

m_params.high_freq_timer[2]->TASKS_STOP  = 1;
m_params.high_freq_timer[2]->TASKS_CLEAR = 1;
m_params.high_freq_timer[2]->MODE = TIMER_MODE_MODE_Counter;
m_params.high_freq_timer[2]->CC[0]       = 0;
m_params.high_freq_timer[2]->TASKS_START = 1;

I added a PPI connection on channel 5 to fire NRF_TIMER4 inside ppi_configure

NRF_PPI->CHENCLR      = (1 << 5);
NRF_PPI->CH[5].EEP = (uint32_t) &m_params.high_freq_timer[0]->EVENTS_COMPARE[2];
NRF_PPI->CH[5].TEP = (uint32_t) &m_params.high_freq_timer[2]->TASKS_COUNT;
NRF_PPI->CHENSET         = (1 << 5);

This fires whenever the NRF_TIMER2 rolls over on its synchronized value (read on to discover why this doesn't work)

// Write offset to timer compare register
m_params.high_freq_timer[0]->CC[2] = (TIMER_MAX_VAL - timer_offset);

I also changed NRF_TIMER2 to be 24 bits instead of 16 bits.

m_params.high_freq_timer[0]->BITMODE     = TIMER_BITMODE_BITMODE_24Bit << TIMER_BITMODE_BITMODE_Pos;

set the max value

#define TIMER_MAX_VAL (0xFFFFFF)

Separated the handler for button 4 to capture and print the value. I'm reading it over UART, but NRF_LOG_INFO while debugging probably works too.

case BSP_EVENT_KEY_3:
{
    NRF_TIMER4->TASKS_CAPTURE[0] = 1;
    printf("%d\r\n", NRF_TIMER4->CC[0]);
}
break;

This works properly when the clock is not being synchronized to the sender. When the sender starts sending synch packets, the receiver clock resets barely earlier or later (later = wait until the new cycle then reset very fast)

If I print out some of the timer offsets that the receiving board's timer is resetting it's count at, I see it sometimes causes the timer to reset extremely rapidly (depending on if the clock is ahead or behind the sender) resulting in a double increase on the counter because the counter is counting whenever the timer compare value event is fired and the timer reset.

16777214
16777213
1
2
16777211
1
16777213
5

How can I best count this synchronized clock's overflows (not whenever it actually resets as the current implementation does, but at the overflow rate of the sender's clock) without getting extra counts?