TeensyTimerTool

Checked and can confirm this. There was a bug in the GPT implementation which leads to calling the ISR two times for very fast interrupt service routines. The bug was already fixed but for some reason the fix was commented out. I updated the GitHub repo already, but if you don't want to update you can also add a "DSB" instruction at the end of your ISR.

Code:
void tRun(){
  state = 1 - state;
  digitalWriteFast(pin, state);  
  asm volatile("dsb"); // <---------------------------------
  return;
}


Alternatively you can do

Code:
void tRun()
{
  digitalWriteFast(pin, !digitalReadFast(pin));  
}

which is a little bit less efficient than your code which makes it work as expected.

THANKs for spotting that!

Excellent! I’m glad my tests have been useful. I will be focusing my attention on the OneShotTimer next as I am curious to see if that might suit my needs better :)
 
A slightly different question:

Can we be more flexible with the frequency of the clock source? That is to ask, do all the clocks need to be a multiple of the 24MHz master clock, or could I have a 151Mhz clock, for example?
 
PLL2 is fixed to 528MHZ, the USB PLL to 480MHz. Their PFDs can be changed, but - depends what is connected to them - may influence other peripherals.
I have no idea what is connected where... (and, in theory, it can change @runtime).

@Luni: Would be perfect if your lib would consider that (or does it already?)
 
PLL2 is fixed to 528MHZ, the USB PLL to 480MHz. Their PFDs can be changed, but - depends what is connected to them - may influence other peripherals.
I have no idea what is connected where... (and, in theory, it can change @runtime).

@Luni: Would be perfect if your lib would consider that (or does it already?)

If I’ve understood the document Luni linked, PLL4 and PLL5 generate pretty much any frequency, but how to use them as a clock source for interrupt generation?
 
They can clock the timers which in turn can generate interrupts.
If a timer is connected to one of the PFDs, it may be possible to change the PFD setting (but keep in mind that other peripherals may use the same PFD.)
 
...(and, in theory, it can change @runtime).

@Luni: Would be perfect if your lib would consider that (or does it already?)

@Frank: I assume you mean consider the change @runtime to have a correct timer period regardless of the clock setting? No, it currently only takes the 150/24MHz switch for the GPTs and PITs into account. I'm not sure if the cost-benefit ratio of extending this is small enough to dig into it.

@bloodline: If you found out how to change the timer clock I can have a look if there is a doable way to make that configurable. But, as Frank mentioned, changing the clock might have influence on other peripherals as well.... Generally, the 150MHz clock for the GPTs gives a 6.6ns granularity. I don't know your application but I do not understand how tweaking the clock (150-151 MHz) will solve any problem? Care to explain what you want to achieve?
 
@bloodline: If you found out how to change the timer clock I can have a look if there is a doable way to make that configurable. But, as Frank mentioned, changing the clock might have influence on other peripherals as well.... Generally, the 150MHz clock for the GPTs gives a 6.6ns granularity. I don't know your application but I do not understand how tweaking the clock (150-151 MHz) will solve any problem? Care to explain what you want to achieve?

I've avoided reading the technical documents until you linked to them, as these modern uCs are so complex it would take me weeks to understand how their peripherals work... I'll try and work out what registers do what...

I like to use microcontrollers to interact with and emulate vintage computer hardware, and the systems of the '80s were very tightly bound with their system clocks. If I could have the Teensy running at a perfect multiple of the old hardware clock, it makes life much easier to get timing correct, without having to correct for drift or push the timings to the limit of the spec...
 
Hi Luni

The latest version (downloaded yesterday) will not compile for me without the files src/Teensy/GPT/GPTchannel.h and src/Teensy/TMR/TMRchannel.h being renamed GPTChannel.h and TMRChannel.h respectively.

Excellent work though. Thanks
 
he latest version (downloaded yesterday) will not compile for me without the files src/Teensy/GPT/GPTchannel.h and src/Teensy/TMR/TMRchannel.h being renamed GPTChannel.h and TMRChannel.h respectively.
Sorry, fixed and uploaded (v0.1.2). Looks like I finally need to install Linux somewhere to detect those issues. (Was not the first time...)
 
I like to use microcontrollers to interact with and emulate vintage computer hardware, and the systems of the '80s were very tightly bound with their system clocks. If I could have the Teensy running at a perfect multiple of the old hardware clock, it makes life much easier to get timing correct, without having to correct for drift or push the timings to the limit of the spec...

Got you, unfortunately I'll be quite busy the next weeks and will hardly find time to read into that...
 
Got you, unfortunately I'll be quite busy the next weeks and will hardly find time to read into that...

No problem! I’m in the same situation.

Teensy Timer Tool is really good already, thank you for your efforts. I look forward to any features you are able to add in future :)
 
Sorry, fixed and uploaded (v0.1.2). Looks like I finally need to install Linux somewhere to detect those issues. (Was not the first time...)

Ha, despite being a complete Linux noob I actually managed to install the Arduino IDE and Teensyduino on the Win10 Linux Subsystem (WSL) :).
 
Ha, despite being a complete Linux noob I actually managed to install the Arduino IDE and Teensyduino on the Win10 Linux Subsystem (WSL) :).

@luni - Interesting on the WSL! I have WSL running here - not sure of IDE install - but couldn't map the USB to actually see a Teensy. If you see that you might start a thread with shortcut to steps for install and connect. Most I've used Linux … was mostly one step then web searches to progress … repeat for more progress.
 
Ha, despite being a complete Linux noob I actually managed to install the Arduino IDE and Teensyduino on the Win10 Linux Subsystem (WSL) :).

You didn't have to install Linux, I don't mind checking for such things (there's probably only me that uses it anyway). It is nice to know you care though.
 
I would like to move to TeensyTimerTool from TeensyDelay. I tried HelloPeriodic but the longest periodic callback I can get is ~56ms. When I was using TeensyDelay, I changed the prescaler from 7 to 6. I don't understand if I need to do that with this library or where. I tried creating a userConfig.h file in the sketch directory. In that I set TMR_DEFAULT_PSC to 6, but that didn't affect the period time.

I am using a Teensy 3.2.
 
The TMR_DEFFAULT_PSC setting is for the TMR timers of a Teensy 4. T3.2s use the FTM timers instead so that won't work. Unfortuantely, I simply forgot to implement this setting for the FTMs... Sorry for that. I try to add the setting for the FTMs tomorrow and post an update on GitHub.

As a quick workaround you can give the software based TCK timers a try. Just use 'Timer t1(TCK)' in line 19 of the example (see here https://github.com/luni64/TeensyTim.../examples/HelloPeriodic/HelloPeriodic.ino#L19)
The readme describes the TCK timers here https://github.com/luni64/TeensyTimerTool#tck---tick-timer They have a (theoretical) resolution of about 2ns and a max period of about 7s.
 
I am setting a OneShotTimer trigger from within the callback of a PeriodicTimer. That isn't working. Is it expected to work?
 
.. I try to add the setting for the FTMs tomorrow and post an update on GitHub.

I added the FTM_DEFAULT_PSC setting to override the auto prescaling value for the FTM timers. See here https://github.com/luni64/TeensyTimerTool#configuration for the documentation.

You can query the TeensyTimerTool timers for their max period as shown here:

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

PeriodicTimer t1(FTM0);
PeriodicTimer t2(TCK);

void setup()
{
    while (!Serial) {}
    TeensyTimerTool::attachErrFunc(ErrorHandler(Serial));

    t1.begin([] { Serial.printf("ISR t1 %d\n", millis()); }, 40'000);
    t2.begin([] { Serial.printf("  ISR t2 %d\n", millis()); }, 80'000);

    Serial.printf("t1 (FTM) max Period: %.3fs, resolution %.4fµs\n", t1.getMaxPeriod(), t1.getMaxPeriod() / 0xFFFF * 1E6);
    Serial.printf("t2 (TCK) max Period: %.3fs, resolution %.4fµs\n", t2.getMaxPeriod(), t2.getMaxPeriod() / 0xFFFF'FFFF * 1E6);
}

void loop()
{
}

Which prints for a T3.2 @96MHz and auto prescaler:

getmaxperiod.jpg
 
Last edited:
I added the FTM_DEFAULT_PSC setting to override the auto prescaling value for the FTM timers. See here https://github.com/luni64/TeensyTimerTool#configuration for the documentation.

You can query the TeensyTimerTool timers for their max period as shown here:

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

PeriodicTimer t1(FTM0);
PeriodicTimer t2(TCK);

void setup()
{
    while (!Serial) {}
    TeensyTimerTool::attachErrFunc(ErrorHandler(Serial));

    t1.begin([] { Serial.printf("ISR t1 %d\n", millis()); }, 40'000);
    t2.begin([] { Serial.printf("  ISR t2 %d\n", millis()); }, 80'000);

    Serial.printf("t1 (FTM) max Period: %.3fs, resolution %.4fµs\n", t1.getMaxPeriod(), t1.getMaxPeriod() / 0xFFFF * 1E6);
    Serial.printf("t2 (TCK) max Period: %.3fs, resolution %.4fµs\n", t2.getMaxPeriod(), t2.getMaxPeriod() / 0xFFFF'FFFF * 1E6);
}

void loop()
{
}

Which prints for a T3.2 @96MHz and auto prescaler:

View attachment 19520

I was trying same example to check it's working on Teensy 4.0 but I am getting this error.
'FTM0' was not declared in this scope

I updated TeensyTimerTools to 0.1.3. Any other library still missing?
 
Back
Top