gpsAssistedCounter works but don't understand why

Status
Not open for further replies.

bicycleguy

Well-known member
Combined manitou48 gpsgpt.ino
https://github.com/manitou48/teensy4/blob/master/gpsgpt.ino
and Pauls FrequencyCount
https://www.pjrc.com/teensy/td_libs_FreqCount.html

To make a GPS assisted counter. Works from 1MHz to 58MHz within +/- 1 ppm even though my T4.1 is ~27ppm.
Here's output of a 2.1234567 MHz signal from a ~.3ppm signal generator:
Code:
starting
1 secs 149996091 ticks  -26.060  -26.060 ppm  43.8 C 2123512.500 Hz
2 secs 149996096 ticks  -26.027  -26.043 ppm  43.8 C 2123450.000 Hz
3 secs 149996090 ticks  -26.067  -26.051 ppm  43.8 C 2123450.000 Hz
4 secs 149996094 ticks  -26.040  -26.048 ppm  43.8 C 2123456.250 Hz
5 secs 149996093 ticks  -26.047  -26.048 ppm  43.8 C 2123456.250 Hz
6 secs 149996089 ticks  -26.073  -26.052 ppm  43.8 C 2123456.250 Hz
7 secs 149996093 ticks  -26.047  -26.051 ppm  44.4 C 2123456.250 Hz
8 secs 149996093 ticks  -26.047  -26.051 ppm  43.8 C 2123456.250 Hz
...and some more after a few minutes of drifting
2365 secs 149996045 ticks  -26.367  -26.234 ppm  45.7 C 2123456.250 Hz
2366 secs 149996047 ticks  -26.353  -26.234 ppm  45.7 C 2123456.250 Hz
2367 secs 149996048 ticks  -26.347  -26.234 ppm  45.1 C 2123456.250 Hz
2368 secs 149996047 ticks  -26.353  -26.235 ppm  45.7 C 2123456.250 Hz
(I know the 3 places are nonsense)

I'm still months away, (if ever) :confused: from understanding the T4 timers, I/O ect. but have looked at FreqCount.h, IntervalTimer.h, cores and the manual and can't understand why I need the 6.25 (in red below) to make
this work. 6.25 is 150MHz/24MHz but can't figure where its changing it and why it doesn't mess up other stuff.
Code:
//gpsAssistedCounter.ino
//pin 35 to point per second(pps) of a GPS reciever
//pin 9  to signal generator

#include <FreqCount.h>

#define CLKSRC 1 
#define TPS 150000000
#define PREDIV 0

volatile uint32_t tick, ticks;
void pinisr() {
  tick = 1;
  ticks = GPT1_CNT;
}

void setup() {
  Serial.begin(9600);
  while (!Serial);
  delay(3000);
  Serial.println("starting");
  CCM_CSCMR1 &= ~CCM_CSCMR1_PERCLK_CLK_SEL; // turn off 24mhz mode
  CCM_CCGR1 |= CCM_CCGR1_GPT(CCM_CCGR_ON) ;  // enable GPT1 module
  GPT1_CR = 0;
  GPT1_PR = PREDIV;   // prescale+1 /1 for 32k,  /24 for 24mhz   /24 clock 1
  GPT1_SR = 0x3F; // clear all prior status
  GPT1_CR = GPT_CR_EN | GPT_CR_CLKSRC(CLKSRC) | GPT_CR_FRR ;// 1 ipg 24mhz  4 32khz
  attachInterrupt(35, pinisr, RISING);  //35 for GPS pps, 22 for sg
  FreqCount.begin(1000000);  //Time in microseconds
}

void loop() {
  static uint32_t n = 1,  prev = 0;
  static float sum = 0;
  static unsigned long count=0;
  
  if (FreqCount.available()){
    count = FreqCount.read();
    //Serial.println(count*.99997305);
  }
  if (tick)  {
    if (prev != 0) {
      int d = ticks - prev;
      float e = (float)(d - TPS) / TPS;
      float ppm = 1000000. * e;
      sum += ppm;
      Serial.printf("%d secs %d ticks  %.3f  %.3f ppm  %.1f C %.3f Hz\n", n, d, ppm, sum / n, tempmonGetTemp(), (float)count*[COLOR="#FF0000"]6.25[/COLOR]);//*1000000.0/(1000000.0-ppm)
      n++;
      FreqCount.begin(1000000.0/(1.0-e));
    }
    tick = 0;
    prev = ticks;
  }
}

My ultimate goal is to combine the excellent NTP server:
https://forum.pjrc.com/threads/61581-Teensy-4-1-NTP-server?p=244574&viewfull=1#post244574
with some T4 relevant code to discipline a 10MHz OCXO all in one unit with a pretty display.
 
Here's my guess, though I haven't done the math.

On the T4, FreqCount uses pin 9 to clock quad timer 4 (channels 2 and 3, atomic). Your signal generator is connected to pin 9. To measure the gate interval. FreqCount uses the Teensy IntervalTimer library which, in turn, uses the PIT timer to do a callback very N microseconds (N from FreqCount begin(N)). Both the GPT and PIT timers run from the same clock, and the IntervalTimer library expects that clock to run at 24 MHz, BUT your setup() configures that clock to run at 150 MHz with
CCM_CSCMR1 &= ~CCM_CSCMR1_PERCLK_CLK_SEL
Comment that out if you don't need the 150mhz GPT/PPS precision and set TPS to 24000000. Otherwise adjust interval timer to deal with 150mhz clock -- which is what your 6.25 (150/24) is doing

FreqCount.begin(1000000.0/(1.0-e)) -- Every second you change the FreqCount gate interval (restarts interval timer), I guess that will work ...?

tuning interval timer see https://forum.pjrc.com/threads/65941-IntervalTimer-inaccuracy-Discipline-Scope-Video-included
 
Last edited:
@manitou, thanks for the response and info. I need to study for a while.

I'm trying to make a T4 disciplined 10MHz Oven controlled crystal oscillator with less parts and more glitz than what the very clever Lars managed with a lowly Arduino nano:

https://www.eevblog.com/forum/projects/lars-diy-gpsdo-with-arduino-and-1ns-resolution-tic/msg1278672/#msg1278672

So far, not so good on his main point:

1ns resolution TIC (Time Interval Counter) --Thought I could save a bunch of parts with the T4's 600MHz clock and 1.6ns resolution which would be good enough. So far it looks like I can't use that resolution and can't catch the interval between the 1pps gps and the 10MHz OCXO, or more specifically which cycle of the 10MHz OCXO. Dividing the OCXO by 10 with a HC390 looks like it might work but had hoped to not need it. I'll post some code and maybe video.
 
Status
Not open for further replies.
Back
Top