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

Timer capture 'noise' or sync/race condition on CC read?

Hi,

I've a timer configured by gpiote to capture with a second 'overflow' capture should the signal stop. I'm not using an interrupt instead the CC[0] value is being used elsewhere (more on that in a second). The input signal is a square wave at ~150Hz. From oscilloscope I can see there is almost zero slew and no noise at all.

  NRF_GPIO->PIN_CNF[CFG_PIN_MOTION_NUM] = PIN_MOTION_CONF;
  NRF_GPIOTE->CONFIG[CFG_GPIOTE_CHANNEL_MOTION] = GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos | CFG_PIN_MOTION_NUM << GPIOTE_CONFIG_PSEL_Pos | GPIOTE_CONFIG_POLARITY_LoToHi << GPIOTE_CONFIG_POLARITY_Pos;
  CFG_TIMER_MOTION->PRESCALER = CFG_MOTION_PRESCALER << TIMER_PRESCALER_PRESCALER_Pos;
  CFG_TIMER_MOTION->BITMODE = TIMER_BITMODE_BITMODE_32Bit << TIMER_BITMODE_BITMODE_Pos;
  CFG_TIMER_MOTION->CC[1] = CFG_MOTION_ONE_SECOND >> 1;
  CFG_TIMER_MOTION->SHORTS = TIMER_SHORTS_COMPARE1_CLEAR_Enabled << TIMER_SHORTS_COMPARE1_CLEAR_Pos;
  NRF_PPI->CH[CFG_PPI_MOTION_TIMER_COMPARE].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[CFG_GPIOTE_CHANNEL_MOTION];
  NRF_PPI->CH[CFG_PPI_MOTION_TIMER_COMPARE].TEP = (uint32_t)&CFG_TIMER_MOTION->TASKS_CAPTURE[0];
  NRF_PPI->FORK[CFG_PPI_MOTION_TIMER_COMPARE].TEP = (uint32_t)&CFG_TIMER_MOTION->TASKS_CLEAR;
  NRF_PPI->CH[CFG_PPI_MOTION_TIMER_OVERFLOW].EEP = (uint32_t)&CFG_TIMER_MOTION->EVENTS_COMPARE[1];
  NRF_PPI->CH[CFG_PPI_MOTION_TIMER_OVERFLOW].TEP = (uint32_t)&CFG_TIMER_MOTION->TASKS_CAPTURE[0];
  NRF_PPI->CHENSET = 1 << CFG_PPI_MOTION_TIMER_COMPARE | 1 << CFG_PPI_MOTION_TIMER_OVERFLOW;
  CFG_TIMER_MOTION->TASKS_START = 1;


So the above runs and the timer is continuously updating the CC value.

I then have a second timer at a set frequency (currently 120Hz) which is used for PID control. It uses the CC[0] value in it's calculations however randomly the value is much lower than the real thing, as if there's noise. It's never higher from what I can tell.

The only plausible explanation I have is that while the second timer interrupt is accessing the CC[0] value the hardware may be updating it. My understanding is this is resolved normally by double buffering but I may be incorrect. Anyway, I couldn't find anything on the CC values being buffered.

Any advice much appreciated. I'd like to avoid copying the CC value in another interrupt, if that's possible.



Parents Reply Children
Related