Hello,
I am using an Arduino Nano-ble-33 and I am having issue counting edges. The values seem to be roughly 0.4% higher than they should be. If I put a 1000Hz clock, I get roughly 1004, at 10kHz I get ~10040, at 100KHz I get ~100400, etc. It gets worse the higher the freq. I read the errata and implemented the recommended fix. The input signal is spot on, measured with two scopes.
I believe it is set up correctly according to the spec. I just don't see where the extra pulses are coming from.
Below is a snippet of the output. I am running two timers with the same signal as input. The first value is the time in microseconds. As you can see, the variation in time can't account for the extra counts. I am assuming micros() is accurate.
---1000005,100385,100385 ---1000004,100386,100386 ---1000005,100412,100412 ---1000005,100423,100423 ---1000001,100424,100424 ---1000006,100417,100417 ---1000007,100407,100407 ---1000006,100426,100426 ---1000000,100413,100413 ---1000008,100429,100429 ---1000003,100447,100447 ---1000009,100414,100414
Below is my code.
#include "Arduino.h" #include <nrf_timer.h> #define TIMER3 NRF_TIMER3 #define TIMER4 NRF_TIMER4 static uint8_t InitCounter(NRF_TIMER_Type* timer, uint8_t pin); static uint8_t _compChan[2]; static uint32_t _compCaptureIntervalUs = 1000000; // 1 sec void setup() { Serial.begin(115200); _compChan[0] = InitCounter(TIMER3, 2); _compChan[1] = InitCounter(TIMER4, 3); // this comes from an errata, it allows the ports to run faster than 2.6MHz *(volatile uint32_t*)(NRF_GPIOTE_BASE + 0x600 + (4 * _compChan[0])) = 1; *(volatile uint32_t*)(NRF_GPIOTE_BASE + 0x600 + (4 * _compChan[1])) = 1; // start the timers TIMER3->TASKS_START = 1; TIMER4->TASKS_START = 1; } void loop(void) { static ulong prevMicros = micros(); static ulong curMicros = micros(); curMicros = micros(); uint32_t diff = (curMicros - prevMicros); if (diff >= _compCaptureIntervalUs) { TIMER3->TASKS_CAPTURE[_compChan[0]] = 1; TIMER4->TASKS_CAPTURE[_compChan[1]] = 1; TIMER3->TASKS_CLEAR = 1; TIMER4->TASKS_CLEAR = 1; prevMicros = micros(); Serial.print("---"); Serial.print(diff); Serial.print(","); Serial.print(TIMER3->CC[_compChan[0]]); Serial.print(","); Serial.println(TIMER4->CC[_compChan[1]]); } } static uint8_t InitCounter( NRF_TIMER_Type* timer, uint8_t pin ) { static uint8_t chan = 0; uint8_t currentChan = chan; pinMode( pin, INPUT ); // timer init timer->MODE = TIMER_MODE_MODE_Counter; timer->TASKS_CLEAR = 1; timer->BITMODE = TIMER_BITMODE_BITMODE_32Bit; // Set counter to 32 bit resolution // gpio init NRF_GPIOTE->CONFIG[chan] = GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos | GPIOTE_CONFIG_POLARITY_LoToHi << GPIOTE_CONFIG_POLARITY_Pos | digitalPinToPinName(pin) << GPIOTE_CONFIG_PSEL_Pos; // ppi init NRF_PPI->CH[chan].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[chan]; NRF_PPI->CH[chan].TEP = (uint32_t)&timer->TASKS_COUNT; NRF_PPI->CHENSET = 1 << chan; chan++; return currentChan; }
Thanks,
Anthony