Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 3 of 3

Thread: FreqMeasure.read on Teensy 3.1 @ 96MHz

  1. #1
    Junior Member
    Join Date
    Apr 2015
    Posts
    1

    FreqMeasure.read on Teensy 3.1 @ 96MHz

    Hello,

    I've been experimenting with (and possibly abusing?) the FreqMeasure library on a Teensy 3.1. I'm using it to read an encoded pulse stream that encodes binary data as a series of 16us and 24us pulses (idle = high, 16us with 8 us low pulse followed by 8us high = bit “0”, and 24us with 16us low followed by 8us high = bit "1"). I'm compiling my code in the IDE with clock speed set to 96 MHz.

    The documentation at https://www.pjrc.com/teensy/td_libs_FreqMeasure.html states the following for FreqMeasure.read:
    FreqMeasure.read();
    Read a measurement. An unsigned long (32 bits) containing the number of CPU clock cycles that elapsed during one cycle of the waveform. Each measurement begins immediately after the prior one without any delay, so several measurements may be averaged together for better resolution.


    From this I expect FreqMeasure.read() to give me (more or less) a series of 16*96=1536 and 24*96=2304 values indicating the pulse with. Instead it gives me a series of ~768 and ~1152 pulse widths. So almost exactly half of what I expected based on the function description. The great news is that it works quite reliably. But I would like to better understand why I get the values that I am seeing.

    1.) I assume FreqMeasure.read() gives the elapsed time from rising to rising or falling to falling clock edges. Is this a correct assumption and is this an adjustable setting?
    2.) Is the actual .read clock frequency indeed 1/2 of the CPU clock speed?
    3.) Is there a more appropriate library to do what I am attempting to do here?

    I've started going over the library code at the detail level but I have a ways to go understanding the FTM registers. Any help or pointers would be greatly appreciated.

    I am using the following code (a lightly modified version of the Serial_Output example).

    Code:
    /* FreqMeasure - Example with serial output
     * http://www.pjrc.com/teensy/td_libs_FreqMeasure.html
     *
     * This example code is in the public domain.
     */
    #include <FreqMeasure.h>
    
    void setup() {
      Serial.begin(115200);
      FreqMeasure.begin();
    }
    
    double f=0;
    int count=0;
    
    void loop() {
      if (FreqMeasure.available()) {
        // average several reading together
        f = FreqMeasure.read();
        count = count + 1;
        if (count > 30) {
          //float frequency = FreqMeasure.countToFrequency(sum / count);
          Serial.println(f);
          f = 0;
          count = 0;
        }
      }
    }
    And I get this as typical serial stream output:
    Code:
    768
    765
    768
    768
    1155
    765
    768
    768
    768
    1152
    771
    768
    768
    1149
    1149
    768
    1155
    771
    768
    1152
    1152
    771
    768
    768
    768
    292225
    768
    765
    768
    1152
    774
    765
    1146
    771
    768
    1155
    762
    Thanks!
    George

    Pulse stream on Chn0 (ignore the rest) as measured on my Saleae Logic analyzer:
    Click image for larger version. 

Name:	screenshot.jpg 
Views:	210 
Size:	99.5 KB 
ID:	4208
    Last edited by MGeo; 05-02-2015 at 10:22 PM.

  2. #2
    Senior Member
    Join Date
    Aug 2013
    Location
    Gothenburg, Sweden
    Posts
    306
    I think, and it looks like so from a quick peek at the code, that FreqMeasure on Teensy 3.1 uses flex timer 1 and is clocked at the
    periperal bus frquency 48MHz, not the core CPU frequency of 96MHz.

  3. #3
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,704
    Quote Originally Posted by MGeo View Post
    From this I expect FreqMeasure.read() to give me (more or less) a series of 16*96=1536 and 24*96=2304 values indicating the pulse with. Instead it gives me a series of ~768 and ~1152 pulse widths. So almost exactly half of what I expected based on the function description. The great news is that it works quite reliably. But I would like to better understand why I get the values that I am seeing.
    On Teensy 3.1, the timers (and almost all on-chip peripherals) run from from F_BUS, not F_CPU.

    F_BUS is created using an integer division of F_CPU, and the chip has a maximum spec of 50 MHz for F_BUS. When Teensy runs at 96 MHz, F_BUS is 48 MHz.

    If you run Teensy 3.1 at 72 MHz, F_BUS will be 36 MHz. However, at F_CPU = 48 MHz, divide-by-1 will be used, so F_BUS will be 48 MHz.

    If you uncomment the faster overclocking options in boards.txt, 120 MHz mode will use divide-by-2, which is the highest resolution you can get for this measurement (and many people have reported 120 MHz mode very stable). However, 144 MHz mode will use divide-by-3 for F_CPU, so you're back to 48 MHz.

    This applies to Teensy 3.1, and also Teensy 3.0. I should mention for completeness, and anyone who later finds this info by searching, that Teensy-LC works differently!

    On Teensy-LC, these timers run by the F_PLL clock divided by 2. F_PLL is always 96 MHz on Teensy-LC, because that's the only option which makes the USB port work. So the timer always runs at 48 MHz, even when F_CPU is only 24 MHz.

    In the future, slower modes might be enabled on Teensy-LC, where F_PLL isn't used at all (and USB doesn't work). In those modes, there are a few different options for how the timer clock can be configured. Today, I just don't know how we'll end up configuring the timer when/if such modes are implemented. But something to keep in mind is Teensy-LC's timers to support async operation, where the timer can run from a much faster or much slower clock than the CPU, which isn't necessary phase synchronized.

    The situation on Teensy 3.1 is much simpler. The timers always run from F_BUS, which is always an integer divide from F_CPU.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •