Shop OBEX P1 Docs P2 Docs Learn Events
Feasability of GPS disciplined oscillator with integrated frequency counter, witha a P2 MCU — Parallax Forums

Feasability of GPS disciplined oscillator with integrated frequency counter, witha a P2 MCU

Hi,

I wanted to implement a GPS disciplined TCXO. I'm choosi g a P2 because of the interrupts. The GPS module I have outputs a 1bps signal, but no 10MHz signal. So, I'm planning to use a P2 to count the frequency from the VCTCXO, using the positive edge from the 1bps coming from the GPS module.

The P2 will also monitor the lock signal from the same module, pass SPI communication to that module, and output to a low noise DAC that controls the Vref of the VCTCXO to fine tune it.

In essence, I need to use a counter to count the 10MHz ish frequency from the VCTCXO, triggered by the rising edge of the same signal. The counter needs to be started and then stopped by the rising edge of the 1bps signal from the GPS module. I would prefer to implement an interrupt for that start/stop function, to ensure accuracy and no latency.

Is it feasable? I would choose the P1, but I think I need an interrupt.

Kind regards, Samuel Lourenço

Comments

  • The P1 should be able to measure the 1hz signal just fine.
        ' counter A used to count rising edges of 10Mhz 
    
         waitpeq    pps_mask,pps_mask     ' wait for rising edge from 1Hz 
         mov        new_count,phsa        ' sample the current counter value
    
         mov        count_10M,new_count   ' 
         sub        count_10M,old_count   ' compute the difference 
         mov        old_count,new_count   ' 
                          ' I think there's a method to do this in 2 instructions, but 
                          ' this is easier to understand. 
    
    Waitpeq triggers with 1 sysclock cycle resolution. You are likely to loose a cycle here and there if you start and stop the counter. If you stop the counter to read it, there will be 8 clocks where the counter does not advance. That guarantees 1 missed 10MHz cycle, but it could be 2. If you stop the counter to read and clear, that takes 12 cycles and you'll miss between 1 and 2 rising edges at 10MHz.

    Trying to read and reset PHSA without stopping the counter is a bad idea here. If you study the propeller's execution pipeline, reads happen 3 cycles before writes (special purpose registers like PHSA are only accessible as source). So we would still miss edges in a 7 clock window between source read and destination write. I've had good success with simply reading the counter and computing the delta.

    If I understand correctly the propeller will operate with from its own independent clock source. This could add some sampling uncertainty, or not. YMMV. I've thought about building a GPSDO with a propeller. What I though would be a clever thing to do would be to drive the propeller with an 80MHz or 100MHz low noise VCXO so it could double as a programmable clock divider. The propeller PLL's phase noise is not quite good enough for RF applications, running directly from a crystal oscillator is fine. I don't know if phase noise is important to you. Would clocking the propeller from the 10MHz improve the performance? I think so but I can't prove it.
  • kwinnkwinn Posts: 8,697
    It sounds like it should be feasible for a P1 or a P2. In either case there would be some few cycles latency (interrupt service routine or WAITxx code) but that can be compensated for. Another approach would be to add a small amount of external logic to gate the 10MHz in to the counter so the counter receives the 10MHz for the entire one second period between the rising edges of two of the 1pps signal.
  • samuellsamuell Posts: 554
    edited 2019-08-13 20:13
    The P1 should be able to measure the 1hz signal just fine.
    I want to achieve precisely the opposite. The 1bps signal from the GPS module is assumed to be precise. I want to use it to activate the counter. The counter will increment on each pulse of the 10MHz signal from the VCTCXO. It will be used to count the pulses during the 1s defined by the GPS module.

    However, the duration of the high state of the 1bps signal is not well established. Probably, I'll have to use a latch/divider to get a 0.5Hz signal having precisely equal 1sec high and 1s low periods, if a low to high trigger cannot be used to start and stop the counter. This probably has to be done with interrupts, as this cannot be affected by the CPU clock or have any latency (in order not to miss any cycles from the 10MHz VCTCXO).
    If I understand correctly the propeller will operate with from its own independent clock source. This could add some sampling uncertainty, or not. YMMV. I've thought about building a GPSDO with a propeller. What I though would be a clever thing to do would be to drive the propeller with an 80MHz or 100MHz low noise VCXO so it could double as a programmable clock divider. The propeller PLL's phase noise is not quite good enough for RF applications, running directly from a crystal oscillator is fine. I don't know if phase noise is important to you. Would clocking the propeller from the 10MHz improve the performance? I think so but I can't prove it.
    The P2 clock is independent, and shouldn't have effect on the measurement. A higher clock should increase granularity, up to a certain point.
    kwinn wrote: »
    It sounds like it should be feasible for a P1 or a P2. In either case there would be some few cycles latency (interrupt service routine or WAITxx code) but that can be compensated for. Another approach would be to add a small amount of external logic to gate the 10MHz in to the counter so the counter receives the 10MHz for the entire one second period between the rising edges of two of the 1pps signal.
    Affording any latency will cause the frequency to be incorrectly measured as low, and thus leading to an improper tuning of the VCTCXO.

    About the gating, it is a great idea. Probably I'll have to add a latch, so one more AND gate wouldn't be a tall order.

    Kind regards, Samuel Lourenço
  • jmgjmg Posts: 15,145
    samuell wrote: »
    I wanted to implement a GPS disciplined TCXO. I'm choosi g a P2 because of the interrupts. The GPS module I have outputs a 1bps signal, but no 10MHz signal. So, I'm planning to use a P2 to count the frequency from the VCTCXO, using the positive edge from the 1bps coming from the GPS module.

    The P2 will also monitor the lock signal from the same module, pass SPI communication to that module, and output to a low noise DAC that controls the Vref of the VCTCXO to fine tune it.

    In essence, I need to use a counter to count the 10MHz ish frequency from the VCTCXO, triggered by the rising edge of the same signal. The counter needs to be started and then stopped by the rising edge of the 1bps signal from the GPS module. I would prefer to implement an interrupt for that start/stop function, to ensure accuracy and no latency.

    Is it feasable? I would choose the P1, but I think I need an interrupt.

    Interrupts are not essential.
    P2 can do this with higher precision, and can use the inbuilt DAC, but it's quite an over kill...

    See this :
    https://forums.parallax.com/discussion/123170/propbasic-reciprocal-frequency-counter-0-5hz-to-40mhz-40mhz-now
    Note the 0.5Hz, that's there specifically to manage 1pps from GPS systems.
    samuell wrote: »
    The counter needs to be started and then stopped by the rising edge of the 1bps signal from the GPS module. I would prefer to implement an interrupt for that start/stop function, to ensure accuracy and no latency.
    I would avoid start/stop and instead capture a running counter. P1 can WAIT on a pin-state, with 1 SysCLK granularity, so a WAIT then READ is 12.5ns precise.
    The big advantage of using capture, is you never lose any clock edges, so captures over 10s and 100s give you more precision.
    80MHz is 12.5ppb in 1 second, and 1.25ppb in 10 seconds.

    Do you plan to clock the P1 from the VCTCXO, or is that in a separate unit ?
  • samuellsamuell Posts: 554
    edited 2019-08-13 20:27
    Hi jmg,

    The MCU will be clocked independently, for sure. SaucySolition gave me an idea, of gating the 10MHz clock with the 1s signal derived from the 1bps signal. No rising edge triggering needed, as well as no interrupt. I'll use the P1, therefore.

    I'll be using an external, low-noise precision DAC. P2 is definitely overkill.

    By the way, using Saucy's idea I can run the counter continuously, since the gating is external. So, your sugestion will be implemented too. I'm planning to use two counters, gated in alternate fashions, so while one is counting, the other can be read and set to zero. This will save time between readings.

    Kind regards, Samuel Lourenço
  • jmgjmg Posts: 15,145
    edited 2019-08-13 20:53
    samuell wrote: »
    The MCU will be clocked independently, for sure. SaucySolition gave me an idea, of gating the 10MHz clock with the 1s signal derived from the 1bps signal. No rising edge triggering needed, as well as no interrupt. I'll use the P1, therefore.

    By the way, using Saucy's idea I can run the counter continuously, since the gating is external. So, your sugestion will be implemented too. I'm planning to use two counters, gated in alternate fashions, so while one is counting, the other can be read and set to zero. This will save time between readings.

    I would avoid any gating, as that removes being able to run long term averages, and you do not need it. Just capture on edge and run differences, as shown above.

    If you look at the reciprocal-frequency-counter link above, that uses two counters, one measures time and one measures cycles.
    In P1 you can clock a counter on slower external edges, so a 80MHz P1 can clock a counter at 10MHz External.

    That's slightly less ppb/second than using eg (10MHz/2) to clock the P1, and using the PLL to 80MHz
    samuell wrote: »
    I'll be using an external, low-noise precision DAC. P2 is definitely overkill.
    The EFM8BB3/LB1 have useful DACs, and cost the same/less than an equivalent standalone DAC.

    If you want to chase precision, I found useful links a while ago here :
    http://www.simonsdialogs.com/2018/10/u-blox-gps-receiver-a-self-regulating-clock-and-a-gpsdo-and-all-of-this-for-the-lowest-cost/222/

    The interesting bit here is this :
    "This program reads the NAV-CLOCK message from the u-blox receiver, does a magic calculation, and then sets the EFC voltage of the OCXO, which in turn determines the 26.000 MHz clock for the same u-blox receiver. And after not too long time, all is frequency looked."
    ie apparently, on GPS modules you can read the NAV-CLOCK message which reports the local GPS error from ideal time, and using that you can get more accurate than the local GPS time.
    In you case you use 1pps, and 10MHz TCXO, but also read NAV-CLOCK messages to determine how accurate that 1pps really is...
  • samuellsamuell Posts: 554
    edited 2019-08-13 21:33
    Hi,

    I've drawn a schematic for the gating, using an 74HC107 and three very fast NAND gates (have to pick the family). Please see the attached file.
    jmg wrote: »
    ...
    I would avoid any gating, as that removes being able to run long term averages, and you do not need it. Just capture on edge and run differences, as shown above.

    If you look at the reciprocal-frequency-counter link above, that uses two counters, one measures time and one measures cycles.
    In P1 you can clock a counter on slower external edges, so a 80MHz P1 can clock a counter at 10MHz External.

    That's slightly less ppb/second than using eg (10MHz/2) to clock the P1, and using the PLL to 80MHz...
    So, it is essentially using the positive edge as a trigger to capture the counter value? That would be ideal, but how do you avoid counter turnover? Plus, how do you account for the latency caused by an eventual MCU delay (for example, between seeing a positive edge of the 1bps signal and actually reading the counter)?

    Kind regards, Samuel Lourenço
    1024 x 768 - 382K
  • jmgjmg Posts: 15,145
    samuell wrote: »
    So, it is essentially using the positive edge as a trigger to capture the counter value? That would be ideal, but how do you avoid counter turnover? Plus, how do you account for the latency caused by an eventual MCU delay (for example, between seeing a positive edge of the 1bps signal and actually reading the counter)?
    Latency is always the same (within 1 SysCLK) so it does not matter if it is 5 or 8 etc sysclks.
    You can add code to check for turnover, but usually a simple difference works ok on unsigned numbers. Check Bean's code in the Freq Ctr.

    samuell wrote: »
    I've drawn a schematic for the gating, using an 74HC107 and three very fast NAND gates.
    There is no need to externally gate anything, if you use capture.

  • samuell wrote: »
    The P1 should be able to measure the 1hz signal just fine.
    I want to achieve precisely the opposite. The 1bps signal from the GPS module is assumed to be precise. I want to use it to activate the counter. The counter will increment on each pulse of the 10MHz signal from the VCTCXO. It will be used to count the pulses during the 1s defined by the GPS module.

    However, the duration of the high state of the 1bps signal is not well established. Probably, I'll have to use a latch/divider to get a 0.5Hz signal having precisely equal 1sec high and 1s low periods, if a low to high trigger cannot be used to start and stop the counter. This probably has to be done with interrupts, as this cannot be affected by the CPU clock or have any latency (in order not to miss any cycles from the 10MHz VCTCXO).
    The first sentence was poorly worded. The code, I believe, does exactly what you want.

    If we wanted to measure the 1Hz signal (or Pulse Per Second) against the propeller's system clock we could do it like this. The CNT register increments every clock cycle. We can't reset it. The code is triggered by the rising edge of PPS, so it runs once per second. This code take much less time than the duration of the PPS pulse. So we also wait for the falling edge, to make sure that we don't loop continuously while PPS is high.
    repeat 
       wait for PPS low 
       wait for PPS high 
       record cnt value 
       calculate difference 
       write difference to hub 
    

    However, we actually want to measure against the 10MHz VCXO. We can configure a counter to increment on each rising edge of the 10MHz signal. We let it run and record its value as quickly as we can after each rising edge of PPS.
    set up counter,  POSEDGE mode on 10MHz pin,  FRQx=1
    repeat 
       wait for PPS low 
       wait for PPS high 
       record PHSx value 
       calculate difference 
       write difference to hub 
    

    Counter turnover is not a problem when calculating the difference. As long as the actual difference value does not overflow the registers. The count values for your application would be in the 10 million range, well within the (2^32) -1 limit for a 32 bit register. For example: new-old=difference: $0000_000a - $ffff_fff6 = 20
  • Hi,

    I have to weight all the possibilities and perform some testing.

    I don't know a thing about Spin. Is there any chance of manipulating the counters in C?

    Kind regards, Samuel Lourenço
  • Yes, C will work just fine.

    Here is some sample code the is an SBUS decoder for RC equipment.
    void doRecSBus(void *par)
    {
      int rxmask;
      int rxbits;
      int rxdata;
      int baud;
      int wcnt;
      int c;
      
      rxmask = 1 << _SBPin;
      baud = 800;
      c = 0;
      
      while (1)
      {
        waitpne(0, rxmask);       // Wait for Start Bit
        rxbits = 10;
        rxdata = 0;
        wcnt = baud >> 1;
        wcnt = wcnt + CNT;
        while (rxbits > 0)
        {
          wcnt += baud;
          waitcnt2(wcnt, baud);   // Wait for Center of Next bit
          rxdata = rxdata << 1;
          if ((rxmask & INA) != rxmask)  // Reverse Bit value
            rxdata = rxdata | 1;
    
          rxbits--;
        }
        rxdata = rxdata >> 2;    // Dump Parity and Stop
        if (rxdata == 0xf0)      // SBus Start Byte Frame value
          c = 0;
        _Dc[c] = rxdata;
        if (c++ > 25)            // Just in case
          c = 25;
        if (c == 24)
          doChannel();
      }
    }
    

    Mike
  • Cluso99Cluso99 Posts: 18,069
    Spin is one of the simplest languages I’ve used in my almost 50 years of programming. You don’t need to learn much to be able to use the basics. Just indent the code, no braces etc.
    if you already know any language, spin will be easy.
  • There's always spin2cpp to convert Spin code to C or C++.
  • Thanks, guys. I'm away from my P1s, for now, but once I get my hands on a VCTCXO (already have one in mind: it ts the DOT050F-010.0M) and a DAC, I will start the coding and testing. Probably I'll design a breakout board for both the VCTCXO and its DAC, plus a clock buffer to eliminate variations due to loading.

    Kind regards, Samuel Lourenço
  • jmg wrote:
    Latency is always the same (within 1 SysCLK) so it does not matter if it is 5 or 8 etc sysclks.
    That's only true in PASM and maybe some compiled C code. Latency can vary when interpreted opcodes are being pulled from hub RAM, as in Spin.

    -Phil
  • jmgjmg Posts: 15,145
    jmg wrote:
    Latency is always the same (within 1 SysCLK) so it does not matter if it is 5 or 8 etc sysclks.
    That's only true in PASM and maybe some compiled C code. Latency can vary when interpreted opcodes are being pulled from hub RAM, as in Spin.

    Fair point, I was thinking of Bean's Reciprocal Frequency Counter code, which is in PropBASIC, which compiles to COG.


  • jmgjmg Posts: 15,145
    As well as Bean's Reciprocal Frequency Counter in PropBASIC I linked above
    jmg wrote: »
    See this :
    https://forums.parallax.com/discussion/123170/propbasic-reciprocal-frequency-counter-0-5hz-to-40mhz-40mhz-now
    Note the 0.5Hz, that's there specifically to manage 1pps from GPS systems.

    This new Basic/C/Spin tool suite from ersmith could be worth a look too... I see his Basic compiler (P1 & P2) is improved again...

    https://forums.parallax.com/discussion/comment/1476010/#Comment_1476010
    "There's a new release of fastspin with improved BASIC support. This round I've added much better support for objects, including inline class definitions (they no longer have to be in a separate file) and passing objects to functions. There's also a STR$() function for converting numbers to strings, and a new template syntax for generic functions.
    I've made an announcement in the fastspin thread, but also wanted to post here because (a) the BASIC language is considerably updated, and (b) it works on P1 as well as P2, and some people may not follow the P2 threads."


    IIRC he ported Bean's Reciprocal Frequency Counter, as an early test.

  • BeanBean Posts: 8,129
    edited 2019-08-15 01:15
    Be advised that the GPS 1pps output will have quantization error.
    The serial output of timing GPS receivers will send what the quantization error is (calculated).
    Something like the M12+ would be a good GPS to use.

    It is almost not worth doing for a TCXO (even a 50ppB one) because you will most likely be chasing it all the time and never be able to hold less than a couple ppB. Partly because of the 1pps error and partly because the TCXO will be moving.

    I'd get an OCXO if you want to create a frequency standard.

    If you are just doing this as an experiment, then feel free to use whatever you wish.

    Bean

    P.S. The DOT050F-010.0M does not have adjust. You would want the DOT050V-010.0M to be able to connect to the DAC.
  • Bean wrote: »
    Be advised that the GPS 1pps output will have quantization error.
    The serial output of timing GPS receivers will send what the quantization error is (calculated).
    Something like the M12+ would be a good GPS to use.

    It is almost not worth doing for a TCXO (even a 50ppB one) because you will most likely be chasing it all the time and never be able to hold less than a couple ppB. Partly because of the 1pps error and partly because the TCXO will be moving.

    I'd get an OCXO if you want to create a frequency standard.

    If you are just doing this as an experiment, then feel free to use whatever you wish.

    Bean

    P.S. The DOT050F-010.0M does not have adjust. You would want the DOT050V-010.0M to be able to connect to the DAC.
    Thanks. Posted the wrong part number. I thought that the OXCO would be as unstable as well. At least those tiny AOCJYR ones from Abracon are not much more stable.

    I can say that I once built a 10MHz clock reference with one of those, and the deviation was 800ppb, which is way more than the 25ppb that they advertise. Another one, using the same OCXO, showed a deviation of 200pbb.

    Kind regards, Samuel Lourenço
  • jmgjmg Posts: 15,145
    samuell wrote: »
    Thanks. Posted the wrong part number. I thought that the OXCO would be as unstable as well. At least those tiny AOCJYR ones from Abracon are not much more stable.
    I can say that I once built a 10MHz clock reference with one of those, and the deviation was 800ppb, which is way more than the 25ppb that they advertise. Another one, using the same OCXO, showed a deviation of 200pbb.

    On the topic of TCXO stability, I recalled this link I found a while ago.
    https://nt7s.com/2016/04/si5351a-breakout-board-tcxo-upgrade/
    Shows all TCXOs are not equal and some correct more in a sawtooth fashion.


    Murata have some new VCTCXOs here, I might try sometime...
    https://www.murata.com/search/productsearch?cate=cgsubCrystalOscillators&partno=XTCLH*J
  • Nice link, jmg. That TCXO could induce some oscilatory behaviour inside a control loop. Not ideal for a GPSDO. The latter one is much nicer.

    As for those Murata TCXOs, they are tiny. The AST3TQ series offers similarly rated oscillators. See option 2 in the datasheet: https://abracon.com/Oscillators/AST3TQ.pdf. You may want to consider one of those too.

    Kind regards, Samuel Lourenço
Sign In or Register to comment.