Still keep up the work

Code: Select all
// Setup and start Timer 2 which measures OCXO frequency
// setup pin used as ETR (10MHz external clock from OCXO)
pinMode(PA15, INPUT_PULLUP); // setup PA15 as input pin
pinModeAF(PA15, GPIO_AF1_TIM2); // setup PA15 as TIM2 channel 1 / ETR
// setup Timer 2 in input capture mode, active input channel 3
// to latch counter value on rising edge
// Instantiate HardwareTimer object. Thanks to 'new' instantiation, the HardwareTimer object is not destructed when setup() function is finished.
HardwareTimer *FreqMeasTim = new HardwareTimer(TIM2);
// Configure rising edge detection to measure frequency
FreqMeasTim->setMode(3, TIMER_INPUT_CAPTURE_RISING, PB10);
// Configure 32-bit auto-reload register (ARR) with maximum possible value
TIM2->ARR = 0xffffffff; // count to 2^32, then wraparound (approximately every 429 seconds)
// select external clock source mode 2 by writing ECE=1 in the TIM2_SMCR register
TIM2->SMCR |= TIM_SMCR_ECE; // 0x4000
// start the timer
FreqMeasTim->resume();
Hi mlundin,mlundin wrote: Mon May 10, 2021 10:15 am I dont quite understand how you measure the frequency and relates it to the GPS timing (1pps). Reading the code, briefly, it seems you are using the HSE as reference, not GPS ??
here is a way to do that while saving space.using two ring buffers that save previous counter values.
Code: Select all
//exponential smoothing
#define EXP_LENGTH 16 //length of memory (mostly weight for the current measurement)
uint32_t exp_smooth(uint32_t dat) {
static uint32_t dat_acc=0; //accumulator
uint32_t dat_es; //smoothed output
//initialization
if (dat_acc==0) dat_acc = dat * EXP_LENGTH; //initialize dat_acc
dat_es = dat_acc / EXP_LENGTH; //calculate the average
dat_acc += dat - dat_es;
return dat_es;
}