T4.0 IntervalTimer question

OhioJim

Well-known member
I need to generate a precisely timed pulse train. For example, a 10uS pulse every 0.376467 +/- seconds.

It looks like this could be done with the IntervalTimer functionality. I see that this takes a parameter which is the time interval in microseconds.

My question is, is the resolution of this only 1.0 microsecond? Or can it go finer? The description says it can take a floating point number for the interval value.
 
A while ago, we did update the IntervalTimer to allow you to get to maybe something like 0.73 microseconds.

That was a quick and dirty fix to get us to about the same min interval as T3.2

However I did/do have a version (Pull Request) that can run a lot faster than that

By checking which clock the Interval timer is configured to use.

Currently it is hard coded to use a fixed 24mhz clock. There is the ability to run those timers off of the system clock instead of that fixed clock.
Which would allow much faster intervals, with the downside of lower maximum intervals.

I believe that @luni's timer tool allows for faster intervals
 
Thanks, Kurt. But I am not talking about the smallest interval, but the resolution.

For example, if I want something like 376967.792 microseconds, will it get rounded to 376968 or 376967.8 or 376967.79?

Another question. Can the timers be driven from an external clock source?
 
Sorry the easiest way to answer this is to do the math...
That is, if you look at the code.
Code:
	bool begin(void (*funct)(), float microseconds) {
		if (microseconds <= 0 || microseconds > MAX_PERIOD) return false;
		uint32_t cycles = (float)(24000000 / 1000000) * microseconds - 0.5f;
		if (cycles < 17) return false;
		return beginCycles(funct, cycles);
	}
So passing in your number I believe cycles is: 9,047,226.508 or as integer 9,047,226

Again timer running at 24mhz so resolution is more or less 1/24000000 or about .0416666667uf...

As for driving timer by external clock, sorry have not tried that so no ideas.
 
I believe that @luni's timer tool allows for faster intervals
Yes, you can select the PIT/GPT timer input clock (24/150MHz) and the TMR timer prescaler (1..128) in the config file. At minimum settings (GPT/PIT = 150MHz, TMR presaler = 1 and TCK @600MHz) you get the following resolutions:
Code:
TCK:          1.67 ns
PIT/GPT/TMR:  6.67 ns

However, in real life applications you will always face jitter due to other interrupts, so these values are just theoretical.
See here for the full documentation of the library: https://github.com/luni64/TeensyTimerTool/wiki
 
But I am not talking about the smallest interval, but the resolution.

It will get rounded to the nearest 1/24th of a microsecond, if the PIT timer clocks at its default 24 MHz. Or rounded to 1/150th of a microsecond if you clock the PIT at 150 MHz.


Another question. Can the timers be driven from an external clock source?

The PIT timers do not support external clock. Only the 24 MHz crystal or the peripheral clock (normally 150 MHz) can be selected.

However, the GPT timers can use external clocks. GPT1 can be clocked using pin 25 (AD_B0_13) and GPT2 can be clocked using pin 14 (AD_B1_02). The GPT timers are documented in chapter 52 of the reference manual, starting on page 2945.

https://www.pjrc.com/teensy/datasheets.html

In addition to configuring the GPT timer, you will also need to program the pin's I/O mux register (documented on page 490 and 494 for those pins) and also the timer's input select register (documented on page 936 and 939 for those timers).

The GPT timers also have output compare circuitry which will allow you to create the pulses using only hardware, which solves the variable latency of using interrupt code to pulse the pin. But using GPT does require more learning to directly configure the hardware registers, since we don't have an easy-to-use software API like IntervalTimer to access the PIT timers.
 
In case you want to give the TeensyTimerTool a try, here some working code using the GPT timers. It uses a second (one-shot-)timer to reset the pin which avoids waiting 10µs in the ISR. GPT clock was set to 150MHz in the config file.

Code:
#include "TeensyTimerTool.h"
using namespace TeensyTimerTool;

PeriodicTimer mainTimer(GPT1);
OneShotTimer pulseTimer(GPT2);

void mainISR(){
    pulseTimer.trigger(10.0us); // start the pulse timer to reset the pin after 10µs. If necessary, you can fine tune the 10µs to compensate for time needed to call the trigger function. 
    digitalWriteFast(0, HIGH);
}

void pulseISR(){
    digitalWriteFast(0, LOW); // reset the pin
}

void setup(){
    pinMode(0, OUTPUT);

    mainTimer.begin(mainISR, 0.376467s); // invoke the callback every 0.376467s
    pulseTimer.begin(pulseISR);          // attach the pulseISR callback to the oneShotTimer
}

void loop(){
}

Unfortunately my cheap (24Mhz) logic analyzer is not precise enough to measure more than 4 digits but those at least correspond nicely to the requested 0.376467s.
Screenshot 2020-10-18 134858.jpg

Please note: it looks like the newest version of the library (v0.3.1) is not yet detected by the Arduino library manager. But you can always download it from the gitHub repo.
 
However, the GPT timers can use external clocks. GPT1 can be clocked using pin 25 (AD_B0_13) and GPT2 can be clocked using pin 14 (AD_B1_02). The GPT timers are documented in chapter 52 of the reference manual, starting on page 2945.

https://www.pjrc.com/teensy/datasheets.html

In addition to configuring the GPT timer, you will also need to program the pin's I/O mux register (documented on page 490 and 494 for those pins) and also the timer's input select register (documented on page 936 and 939 for those timers).

Here are two proof-of-concept sketches clocking GPT timers from external clock.
https://github.com/manitou48/teensy4/blob/master/gpt_count.ino GPT1
https://github.com/manitou48/teensy4/blob/master/gpt2_count.ino GPT2
 
Once you figure out how to get part-per-million timing resolution, you can start to worry about stability. Since the crystals on the Teensy probably have temperature coefficients of up to 25PPM/deg C, just breathing on your Teensy is likely to change your 0.376467s time interval by 5 to 10 microseconds. Great timing resolution is nice, but doesn't help much if the frequency source to the timer doesn't have equivalent stability.
 
Back
Top