StanfordEE
Well-known member
I have been working on a lot of low-jitter, fast interrupt applications (mostly precision digital synthesis) using the Teensy 3.6. It's been a great learning experience, and when I come across something that isn't easy to explain (usually needs the code gurus, as I'm mainly a hardware person), I post it here.
This is about the wonderful IntervalTimer function (https://www.pjrc.com/teensy/td_timing_IntervalTimer.html). While it does not yet list support for the 4.0, it does work, except that there is a puzzling issue.
On the Teensy 3.6, I have implemented a full 16-bit direct digital synthesizer (using port writes, and data pre-scrambled to compensate for all of the re-mapped pins) using the 1 us minimum interrupt interval. This works wonderfully at the 256 MHz overclock setting.
So, when the Teensy 4.0 came out, I was very curious. After looking at the schematic, it was clear there was no real way to do the fast port write stuff, but I wanted to know how fast I could get IntervalTimer to run. Oddly, for any clock setting from 600 MHz to 1.008 GHz (cooling required!), the shortest period is 1.6 us (yes, you can pass IntervalTimer a float and it ends up internally as an integer).
Here is the (very simple) code to test this:
Looking at the code, the output on pin 14 should be a squarewave at 1/2 of the interrupt rate, and it is... Here we get 315.8 kHz, for an interrupt rate of 631.6 kHz. Not bad at all.
Here is the output on pin 14, seen using a Digilent Electronics Explorer:
Here is where it gets interesting. The same code, on a Teensy 3.6 overclocked at 256 MHz works down to 0.6 us (!!!!!), which is way faster than the Teensy 4.0. The output (shown below) is a 842 kHz squarewave, corresponding to an interrupt rate of 1.68 MHz. Now that's cooking.
So... What is going on here? I've read all of the threads on the F_BUS stuff, but at the end of that, it seems like there is a big opportunity here. If someone could take a look at IntervalTimer to see if it can be optimized for the Teensy 4.0, I (and I suspect a lot of others) would be very, very grateful.
Thanks for reading!
This is about the wonderful IntervalTimer function (https://www.pjrc.com/teensy/td_timing_IntervalTimer.html). While it does not yet list support for the 4.0, it does work, except that there is a puzzling issue.
On the Teensy 3.6, I have implemented a full 16-bit direct digital synthesizer (using port writes, and data pre-scrambled to compensate for all of the re-mapped pins) using the 1 us minimum interrupt interval. This works wonderfully at the 256 MHz overclock setting.
So, when the Teensy 4.0 came out, I was very curious. After looking at the schematic, it was clear there was no real way to do the fast port write stuff, but I wanted to know how fast I could get IntervalTimer to run. Oddly, for any clock setting from 600 MHz to 1.008 GHz (cooling required!), the shortest period is 1.6 us (yes, you can pass IntervalTimer a float and it ends up internally as an integer).
Here is the (very simple) code to test this:
Code:
// IntervalTimer Max Frequency Test
// Uses float arguments that are converted to allowable int multiples of F_BUS
// G. Kovacs 1/23/20
//
// Tested using Teensyduino Version 1.49
// For Teensy 4.0 minimum IntervalTimer period = 1.6 us *regardless* from 600MHz to 1.008 GHZ (overclock).
// These results are independent of compiler optimization settings but are presented here for "Fastest" (not default).
IntervalTimer sampleRate;
const int outPin = 14; //Output pin
const float samplePeriod = 1.6; //Interrupt period in microseconds. May be a float - is internally converted to int.
boolean outputState = HIGH;
void setup() {
pinMode(outPin, OUTPUT);
sampleRate.begin(ISR, samplePeriod); // Theoretical interrupt period in us as float
}
FASTRUN void ISR() {
digitalWrite(outPin, outputState);
outputState = !outputState;
}
void loop() {
while (1) {} // Do nothing...
}
Looking at the code, the output on pin 14 should be a squarewave at 1/2 of the interrupt rate, and it is... Here we get 315.8 kHz, for an interrupt rate of 631.6 kHz. Not bad at all.
Here is the output on pin 14, seen using a Digilent Electronics Explorer:
Here is where it gets interesting. The same code, on a Teensy 3.6 overclocked at 256 MHz works down to 0.6 us (!!!!!), which is way faster than the Teensy 4.0. The output (shown below) is a 842 kHz squarewave, corresponding to an interrupt rate of 1.68 MHz. Now that's cooking.
So... What is going on here? I've read all of the threads on the F_BUS stuff, but at the end of that, it seems like there is a big opportunity here. If someone could take a look at IntervalTimer to see if it can be optimized for the Teensy 4.0, I (and I suspect a lot of others) would be very, very grateful.
Thanks for reading!