STM32 GPSDO

What are you developing?
mlundin
Posts: 94
Joined: Wed Nov 04, 2020 1:20 pm
Answers: 6
Location: Sweden

Re: STM32 GPSDO

Post by mlundin »

Nice work, but the long term accuracy is not quite that easy, you must consider whether the clock is in PPS disciplined mode, in which case the long tern drift is equal to that of the GPS satellites, or if its in holdover mode, non disciplined ... thats another matter with temperature induced variations and crystal aging.

Still keep up the work :)
dannyf
Posts: 447
Joined: Sat Jul 04, 2020 7:46 pm

Re: STM32 GPSDO

Post by dannyf »

glad the code helped.

Some random ideas - none tested:
1. pretty much any mcu can be configured into a (arbitrary integer) divider: between the timer prescaler and pwm generator / output compare, and you can cascade them as well.

2. given #1 above, you can pretty much generate a 1pps signal from a mcu.

3. so you have two 1pps trains, one from the gps, and another from your local oscillator. a phase detector can be used to generate a control voltage reflecting the phase differences.

4. that control voltage can be applied to speed up or slow down the local oscillator.

viola, you have a hardware gpsdo. all the logic can be done in software or via hardware.

there are other ways as well:
1. PIC32 chips have a fancy reference clock generator (with or without PLL). you can use that to generate reference frequencies;
2. new gps modules can generate really fast user-specified signals. that could negative the entire local oscillator.
3. for practical purposes, I have used high stability tcxo and calibrate its control voltage on via a gps. after that it is to hold the control voltage to that calibrated value, without a gps.
4. you can design a generic piece of software calibrated to discipline an control pwm train by a 1pps signal so to hold the desired target frequency.

would be interesting to play around when timer permits.
AndrewBCN
Posts: 105
Joined: Sun Apr 25, 2021 3:50 pm
Answers: 1
Location: Strasbourg, France

Re: STM32 GPSDO

Post by AndrewBCN »

Thank you both very much, mlundin and dannyf.

I have had my GPSDO running for more than 24 hours now and it hasn't locked up or lost its accuracy, it's still running fine. So I will upload version 0.01 of my STM32 GPSDO sketch to my GitHub account this weekend. The code certainly needs a lot of cleanup and beautifying, but it works...
I mentioned earlier that the frequency measuring timer setup was really simple and consisted of just 6 lines of C - well, it's seven lines of C, actually, but they are fairly easy to understand:

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();
EDIT: fixed syntax, better naming of variables in code above
Last edited by AndrewBCN on Tue May 11, 2021 11:01 am, edited 3 times in total.
AndrewBCN
Posts: 105
Joined: Sun Apr 25, 2021 3:50 pm
Answers: 1
Location: Strasbourg, France

STM32 GPSDO on GitHub

Post by AndrewBCN »

GPSDO project now on GitHub, here: https://github.com/AndrewBCN/STM32-GPSDO

Code is ugly as hell but at least it works and gets me 10MHz +/- 1ppb, and it should be pretty easy to improve upon.

The minimum configuration only requires an STM32F411CEU6 "Black Pill" (5€), a u-blox Neo-M8 GPS module (8€), an MCP4725 I2C DAC module (1€) and of course a used 10MHz 5V square wave OCXO (<10€).
mlundin
Posts: 94
Joined: Wed Nov 04, 2020 1:20 pm
Answers: 6
Location: Sweden

Re: STM32 GPSDO

Post by mlundin »

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 ??
AndrewBCN
Posts: 105
Joined: Sun Apr 25, 2021 3:50 pm
Answers: 1
Location: Strasbourg, France

Re: STM32 GPSDO

Post by AndrewBCN »

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 ??
Hi mlundin,

That is the purpose of the code I posted separately above, where I setup Timer 2 in input capture mode, and clocked by the OCXO. Note that when I set the ECE bit in the SMCR register, the timer is clocked externally by the OCXO signal, and not by the HSE anymore.
The rising edge of the 1pps output from the GPS is used to automatically latch the counter contents into the counter capture register, exactly once per second (+/- 30ns jitter). The difference between the new count and the previous count is exactly the OCXO frequency in Hz over the last second. Then I get extra resolution by averaging the frequency over 10s (which gives me 0.1Hz resolution) and 100s (0.01Hz resolution) using two ring buffers that save previous counter values.

The advantage of this frequency measurement method is its extreme simplicity: it doesn't require DMA or interrupts and the timer setup is just 7 lines of C code. As I wrote before, since Timer 2 is identical on the STM32F411CEU6 and the STM32L432, you can try the above frequency measurement method on your board, if you have a GPS module at hand and any oscillator that you need to measure the frequency of.

Note that when the control loop is closed - by adjusting the DAC output as a function of the measured frequency - we have a digital frequency locked loop (DFLL). Most (but not all) DIY GPSDO projects use some form of a phase locked loop (PLL) to adjust the OCXO output frequency. Each control method has its advantages and disadvantages, but since my primary objective was a simple design with acceptable performance, I went with the DFLL control method.
AndrewBCN
Posts: 105
Joined: Sun Apr 25, 2021 3:50 pm
Answers: 1
Location: Strasbourg, France

Firmware rewrite

Post by AndrewBCN »

Right now I am rewriting some parts of the firmware. The idea is to improve its modularity and ease of maintenance, as well as the quality of the data the GPSDO reports through USB serial, Bluetooth serial and on the OLED display.
The initial release 0.01 can be considered obsolete.
This major rewrite, release 0.02, is recommended for anyone wanting to understand how this GPSDO project works.

EDIT: v0.02c pushed to GitHub.
EDIT 2: v0.02d pushed to GitHub.
EDIT 3: v0.02e pushed to GitHub.
EDIT 4: v0.02f pushed to GitHub.
EDIT 5: v0.02g pushed to GitHub.
EDIT 6: v0.02h pushed to GitHub.
EDIT 7: v0.02i pushed to GitHub. --> New release created
Last edited by AndrewBCN on Mon May 17, 2021 10:50 am, edited 6 times in total.
dannyf
Posts: 447
Joined: Sat Jul 04, 2020 7:46 pm

Re: STM32 GPSDO

Post by dannyf »

using two ring buffers that save previous counter values.
here is a way to do that while saving space.

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;
}
it will smooth out the measurement with an infinite window where the most current measurements have the highest weight.
AndrewBCN
Posts: 105
Joined: Sun Apr 25, 2021 3:50 pm
Answers: 1
Location: Strasbourg, France

Re: STM32 GPSDO

Post by AndrewBCN »

Hi dannyf,
Thank you very much, I will probably include this exponential smoothing code in a future version, as an option.
But I don't really need to save space in RAM with the STM32F411CEU6, I have 128kB, and the two ring buffers require < 1/2 kB. :D
BTW I have posted a better picture of the GPSDO breadboard prototype, with labels for the various modules, on the GitHub page:
https://github.com/AndrewBCN/STM32-GPSD ... boarda.jpg
AndrewBCN
Posts: 105
Joined: Sun Apr 25, 2021 3:50 pm
Answers: 1
Location: Strasbourg, France

Command parser added

Post by AndrewBCN »

I have just pushed to GitHub version v0.03b of the STM32 GPSDO firmware and the most important change, which led to bumping the version number, is the addition of a command parser, so now the GPSDO accepts commands from either the USB serial or the Bluetooth serial interfaces. And this opens a whole new world of possibilities for this project. :ugeek:
I am using the SerialCommands library by Pedro Pereira, it is rather easy to understand and use. And it works fine, as far as I can tell, with my STM32 development board.
Post Reply

Return to “Projects”