sub microsecond timing for GPS disciplined device

Status
Not open for further replies.

floating.

Well-known member
I'm working on a project that receives a 1 PPS clock signal from a GPS module, and uses that to slot align data packets.

However, the rising edge of the 1 PPS pulse has a 90 nanoseconds delay, and somehow I need to compensate for that.

What are the best options to do that? My bit level IntervalTimer is firing at every 13 microseconds, so can't do much busy wait.

I'm currently using a T3.2, but I could use either a T3.5 or a T3.6 if they would work better.
Not particularly important at this point, but it would be nice if the same code would work as-is, or with little modification on other comparable Freescale devices such as some K22.
 
I will be trying something similar soon, so i got a somehow related question for you: in case of signal loss, i understand that a lot of GPS modules have internal TXCO's to keep the timing. Did you research how precise those TXCO's are? Currently i am thinking about setting a DS3231 module to the GPS time and use the DS3231 as the "timekeeper" since there is plenty of info on the precision of the DS3231 but very little on the various GPS (I will be using a UBlox Neo M8N) modules. Also the DS3231 has the advantage that it has a 32mhz output to function as a Crystal replacement and it has configurable squarewave output that can be configured to 1 / 1024 / 2048 / 4096hz
 
I don't understand what you mean by compensating for a 90ns delay.

But I can tell you the one way to accurately acquire a timestamp for the rising edge of a signal is with the FTM timer input capture. Pretty much everything else is at sensitive to software or at least bus arbitration. Timer input capture is the one way to get the timestamp for when a signal actually changed, where other stuff won't alter the accuracy.

The FTM timers run from F_BUS, not F_CPU, so this approach is limited to a 48 MHz clock on Teensy 3.2 or 60 MHz on Teensy 3.6.

Conceptually the way it works is pretty simple. You configure the timer to clock without a prescaler and to go all the way to 65535 before rolling back to zero. Then configure one of the channels for input capture and an interrupt (or DMA!). When the edge happens, the rapidly increasing timer is captured to that channel's 16 bit register and you get an interrupt. The assumption that there will be enough time before the next edge for your interrupt to read the register is pretty easy when you know it's just 1 pulse per second!

The somewhat tricky part is you only get 16 bits, which rolls over every 1.09 ms when clocking at 60 MHz. You can also use an interrupt from the timer rollover to keep another 16 bit count, and then combine them within the capture interrupt to get a full 32 bit timestamp (again, F_BUS clock). Look at the FreqMeasure library to see how that's done, since it is a bit tricky to get right.

You could also look at the FTM chapter in the reference manual, but it's very long and filled with tons of complex info that isn't needed for input capture. The trick is ignoring the 100+ pages about complicated PWM meant for motors and AC waveform synthesis.

What you actually do with those timestamps, I'm not sure. I have no idea how you'd use that to compensate for a 90ns delay. For evgenymagata's timecode application, I'd imagine you'd use the info to compute a correction factor for the system clock, or maybe even use that same FTM timer (perhaps in the overflow interrupt) to update a timecode variable which the other code generating output could read?

Hopefully this description of how the input capture works, and the FreqMeasure code can help?
 
On another thread I've been using an isr() on the PPS output from uBlox - most 'affordable' models don't have a TXCO, including the M8N used there. But AFAIK the PPS is driven by the GPS system not a local clock for ATOMIC SPACE accuracy over time.

I've been watching that isr() against the 32 bit CycleCounter and it has great consistency, as does the T_3.6 RTC PPS signal. It does vary some few CPU cycles to perhaps 25 per second - so I've been keeping an average of the last 4 to minimize jumps from odd seconds where isr jitter was part of it - but allow it to float relative to the current but changing crystal clocking the Teensy processor - which over a day might alter +/- 250 clock cycles when I watched.

Then with PPS updates filtered in to the average the current cycle counter gives a decent way to stay in sync with seconds(/F_CPU) over time. If you started with this as a base and knew there was a 90 ns delay/offset - that could reliably be factored and measured for use.

That code is buried in the project ZIP posted here (mostly in file T_timeBase.ino. Currently running off the T_3.6/3.5 RTC PPS because many uBlox units don't provide the PPS pin - I pulled off the LED. A T_3.2 with added crystal for RTC should work the same. That crystal can be adjusted - but I haven't done that as it is all relative?

It is just a trivial compilation of the efforts of others:
> Start the CPU cycle counter that runs at 1/F_CPU [ rolls over at 240 MHz in 18.7 seconds ]
> trivial isr() on the PPS interrupt [ or similar RTC PPS with that interrupt started ] - trivial except a short code bit to keep the AVG observed cycle counts.
> any read of the ARM_DWT_CYCCNT can be tracked in time relative to the last/running PPS.
 
I don't understand what you mean by compensating for a 90ns delay.
The 'second' starts 90 ns before indicated by the rising edge of the 1 PPS signal, so if I want slot and bit timing precisely aligned, somehow I need to take that 90 ns into account.

One possibility is that I might just wait 999999910 nanoseconds from the rising edge when starting my slotTimer.... :p

And will do some reading on the other info you posted.

Did you research how precise those TXCO's are?
1. I'm not there yet
2. We have an EE to worry about that ;) (at least on the HW side)

Then with PPS updates filtered in to the average the current cycle counter gives a decent way to stay in sync with seconds(/F_CPU) over time. If you started with this as a base and knew there was a 90 ns delay/offset - that could reliably be factored and measured for use.
Will take a look at.

Thanks to all...
 
Interesting the PPS is triggered 90 ns after the true start of the second - but it is busy doing a lot of math and then has to hit the mark.

The messages used on the other thread come out with a timestamp and have a nano second offset of the message - and the first message of the second has a variable negative nano offset ... back to when it was calculated.

In looking at the uBlox part #'s it seemed only the Automotive class devices had a TXCO - temp comp crystal - it seemed because they have to keep time when the GPS is lost and be autonomous and functional in all cases. The lesser uBlox's hava a std crystal and their time is as accurate as the last GPS FIX data - and will fall to non-TXCO accuracy when FIX is lost?

@evgenymagata:: There is a uBlox thread as well - and on that they were getting high freq clock from the uBlox like was noted for : DS3231. For my use with cycle counter it seemed lower overhead of one PPS int was as needed.
 
@evgenymagata:: There is a uBlox thread as well - and on that they were getting high freq clock from the uBlox like was noted for : DS3231. For my use with cycle counter it seemed lower overhead of one PPS int was as needed.

According to the specs, the Ublox Neo M8N is supposed to have a TXCO (in contrast to the M8M - not the best naming scheme for the products).
I found this in the specs sheet for the UBlox Neo M8 Series

Accuracy of time pulse signal

RMS 30 ns
99% 60 ns

Frequency of time pulse signal 0.25 Hz…10 MHz (configurable)

... also this:
1.14.1 Oscillators
NEO-M8 GNSS modules are available in TCXO and crystal versions. The TCXO allows accelerated weak signal
acquisition, enabling faster start and reacquisition times.
Oscillators used on NEO-M8 module are carefully selected and screened for stability and against frequency
perturbations across the full operating range (–40° to +85°C).
The careful selection and qualification of critical parts, such as GNSS oscillators, has resulted in u-blox modules
being the most reliable positioning modules in the industry, particularly in challenging conditions.
1.14.2 Real-Time Clock (RTC)
The RTC is driven by a 32 kHz oscillator using an RTC crystal. If the main supply voltage fails, and a battery is
connected to V_BCKP, parts of the receiver switch off, but the RTC still runs providing a timing reference for the
receiver. This operating mode is called Hardware Backup Mode, which enables all relevant data to be saved in
the backup RAM to allow a hot or warm start later.

But unfortunately no info about the info about the TXCO's precision
 
Status
Not open for further replies.
Back
Top