Pushing the limits with timers and interrupts on the Teensy 4.0

Status
Not open for further replies.

LukasFun

Member
I have experimented with the general purpose timer (GPT) and am quite pleased with how it works (except the fact that reading from and writing to the status register takes incredibly long *ahem*). There are two entirely independent GPTs (GPT1 and GPT2) that offer three output-compare channels, two input capture channels (haven't tried those yet, there simply aren't enough pins for that on the Teensy). If you're interested in using the GPTs to execute your own interrupt service routines, I encourage you to read this thread: https://forum.pjrc.com/threads/5813...-purpose-timer-(GPT)-output-conpare-interrupt

But in some instances, two independent counters just aren't enough. Reading through the manual I found that there are almost countless of them (pun totally intended), but while there are some examples (like the ones for the periodic interrupt timer in section 52.6), there is nothing that points me to the all important part of how to attach my own isr to the compare event of the timer. For the GPT1 it looks something like this (leaving out the part about configuring the timer itself):

Code:
attachInterruptVector(IRQ_GPT1, myISR);	// Specify the isr you want to be executed
					// (in this case that function is called myISR and is defined somewhere else)
NVIC_ENABLE_IRQ(IRQ_GPT1);		// Enable the interrupt in the nested vectored interrupt controller table (NVIC)

So my specific question is: How do I do this for the PIT?

And more broadly: How can you do this for all the other timers that are available on the Teensy 4.0?

Thanks!
 
I was checking out PIT recently on teensy 4.0.
Although you can setup 4 different timers. It seems that you can use only one interrupt out of four PIT timers. you can change PIT_LDVALx = (Required time period * Timer Frequency) - 1.
According to readings i got Timer Frequency is roughly 25Mhz.
This is the code I used:
Code:
volatile uint32_t curr = 0, prev = 0;

void setup() {
  Serial.begin(115200);
  PIT_SETUP();
}

void loop() {
}

void PIT_SETUP() {
  PIT_MCR = 0;  //Enable PIT
  PIT_LDVAL0 = 2499;// for 100 micro seconds
  PIT_TCTRL0 = PIT_TCTRL_TIE;// PIT Interrupt enable for Timer0
  PIT_TCTRL0 |= PIT_TCTRL_TEN;// start Timer0
  attachInterruptVector(IRQ_PIT, TIM0);// attach TIM0(isr) to Timer0 PIT interrupt
  NVIC_ENABLE_IRQ(IRQ_PIT);
}

inline void TIM0() {
  PIT_TFLG0 |= PIT_TFLG_TIF;// to enable interrupt again
  curr = micros();
  Serial.println(curr - prev);
  prev = curr;
}
 
Calling Serial.println() from this interrupt will probably work since you're not also using it from the main program. But generally it's a good idea to keep your interrupt code short and avoid calling complex functions.
 
Calling Serial.println() from this interrupt will probably work since you're not also using it from the main program. But generally it's a good idea to keep your interrupt code short and avoid calling complex functions.

Noted! thanks Paul.
But It was just for debugging. So I guess that is okay:).
 
Status
Not open for further replies.
Back
Top