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

NRF_TIMER drifts consistently at 2850 ppm relative to the same code on a different DK

I'm using two nRF52840 dev kits, both running with the same code.

void timer_init() {
  NVIC_SetPriority(TIMER1_IRQn, 1);

  NRF_TIMER1->TASKS_STOP = 1;
  NRF_TIMER1->TASKS_SHUTDOWN = 1;
  NRF_TIMER1->MODE = TIMER_MODE_MODE_Timer;
  NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_32Bit;
  NRF_TIMER1->PRESCALER = 4; /* 1us accuracy */
  NRF_TIMER1->TASKS_CLEAR = 1;

  NRF_TIMER1->CC[0] = 0;
  NRF_TIMER1->INTENSET = TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos;

  NVIC_EnableIRQ(TIMER1_IRQn);
}

void SetTimer() {
  NRF_TIMER1->TASKS_STOP = 1;
  NRF_TIMER1->TASKS_SHUTDOWN = 1;

  NRF_TIMER1->CC[0] = 20000;
  NRF_TIMER1->TASKS_START = 1;
}

void TIMER1_IRQHandler(void) {
  if (NRF_TIMER1->EVENTS_COMPARE[0] != 0) {
    NRF_TIMER1->TASKS_STOP = 1;
    NRF_TIMER1->TASKS_SHUTDOWN = 1;
    NRF_TIMER1->TASKS_CLEAR = 1;

    NRF_TIMER1->INTENCLR = 1;
    NRF_TIMER1->CC[0] = 0;
    NRF_TIMER1->EVENTS_COMPARE[0] = 0;

    handler();
    SetTimer();
  }
}

I start the timer and every 20 ms, when the timer expires, I set a new 20ms timer, and in handler(), I increment a number. When that number reaches a multiple of 256, I drive a GPIO pin.

I'm seeing that between the two devkits, the GPIO pulses drift apart fairly quickly. The drift is very constant, and it's always the same dev kit drifting in the same direction at the same rate. The rate is 2.85 milliseconds per second, or about 2850 ppm. I need to be closer to the ~20ppm range.

Is there something I need to be doing to bring the drift down? Do I need to explicitly enable HFCLK or LFCK or calibration?

Many thanks!

Related