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
No Data
Related