Why isn't this interrupt printing 'paused'?

shookti

Member
Code:
volatile bool pauseInterruptPrints = false;
IntervalTimer timer1;
IntervalTimer timer2;

void setup() {
  Serial.begin(500000);
  timer1.priority(50);
  timer2.priority(100);
  timer1.begin(spam, 1000000);
  timer2.begin(bacon, 2000000);
}

void loop() {

}

void spam() {
  if (pauseInterruptPrints) {
    Serial.println("paused");
    return;
  }
  Serial.println("spammed");
}

void bacon() {
  pauseInterruptPrints = true;
  Serial.println("pausing");
  delay(1000);
  Serial.println("resuming");
  pauseInterruptPrints = false;
}

Running on a Teensy 4.1.
Shouldn't the 'spam' interrupt print 'paused' when bacon sets 'pauseInterruptPrints' to true?
Instead, this is the output:

1699952527522.png
 
Last edited:
On a T4.x all four interval timers generate the same interrupt and thus have the same priority. Setting priority for one sets it for all. So you can't interrupt a intervalTimer ISR by another one. You could use the GPT timers instead if you need this behaviour.
 
I see, thank you for responding.
Could you point me to some beginner friendly resources that explain how to use GPT timers?
 
Here how your example would look like using the TimerTool:

C++:
#include "TeensyTimerTool.h"
using namespace TeensyTimerTool;

volatile bool pauseInterruptPrints = false;
PeriodicTimer timer1(GPT1);
PeriodicTimer timer2(GPT2);

void spam(){
    if (pauseInterruptPrints){
        Serial.println("paused");
        return;
    }
    Serial.println("spammed");
}

void bacon(){
    pauseInterruptPrints = true;
    Serial.println("pausing");
    delay(1000);
    Serial.println("resuming");
    pauseInterruptPrints = false;
}

void setup(){
    while (!Serial) {}

    timer1.begin(spam, 1s);
    timer2.begin(bacon, 2s);

    NVIC_SET_PRIORITY(IRQ_GPT1, 50);
    NVIC_SET_PRIORITY(IRQ_GPT2, 100);
}

void loop(){
}

Which prints:
Code:
spammed
spammed
pausing
paused
resuming
spammed
pausing
paused
resuming
spammed
pausing
paused
resuming
spammed
pausing
paused
resuming
spammed
pausing
 
Just curious... if the Teensy 4.1 cannot set different priorities for multiple timer interrupts, how does it decide which one to run?
 
Follow up question; if I do not require interrupts with priorities assigned (say if I have only one interrupt), are there any drawbacks / advantages to using TeensyTimerTool as opposed to good old IntervalTimer?
 
Here a biased :) and not necessarily complete list of advantages / drawbacks
  • + covers PIT (1x4), GPT(2x1), TMR(4x4), RTC(1x1) and software timers, (TCK32 and TCK64 1x20) with exactly the same API
  • + provides periodic and one-shot functionality for all supported timers
  • + has a modern std::function like callback interface which allows for easy timer integration in user classes, using lambdas etc. (IntervalTimer will probably have the same interface in the next version)
  • + user configurable, e.g. switch GPT/PIT clocks from 24MHz to 150MHz, set prescalers for the TMR timers,
  • + accepts std::chrono time literals for delay and period input e.g. 17us, 32.42ms, 2s+500ns etc.
  • - depending on your usage it will have a larger memory footprint
  • - adds a library dependency to your code
 
I'm a bit of a noob when it comes to things like this.. I would appreciate it if you could clarify some things....

I notice that you've used the GPT timers as indicated by these lines:
PeriodicTimer timer1(GPT1);
PeriodicTimer timer2(GPT2);

Why have you chosen these instead of using any of the other timers (PIT, TMR, RTC, software) you've listed?
I'm guessing the RTC isn't useful here because there's only one.

What is the notation you've used while mentioning the number of timers present? I am confused by what GPT (2x1) might mean, does it mean that there are 2 GPT timers or 1 timer register emulating 2 of them?
 
Because the two GPT timers have dedicated interrupts (which you requested) and are 32bit as the IntervalTimer (PIT) you originally used.

Notation means: (modules x channels), modules share one interrupt. -> GPT has two modules, one channel per module -> two independend interrupts. TMR has 4 modules with 4 channels each ->4 independend interrupts which are shared by 4 channels (total number = 16 timers) ...

See here: https://github.com/luni64/TeensyTimerTool/wiki/Supported-Timers

Hope that helps
 
Last edited:
Back
Top