Teensy 4.1 GPT Timer with Interrupt

Hi All,

I am finally getting somewhere with the Teensy 4.1 board and Visual Micro software. I kinda hit a road block and need a little guidance. I used the GPT timer with interrupt in MCUXpresso like so and need something similar for Visual Micro project:

// Init
const gpt_config_t GPT1_config = {
.clockSource = kGPT_ClockSource_Periph,
.divider = 1UL,
.enableFreeRun = false,
.enableRunInWait = false,
.enableRunInStop = false,
.enableRunInDoze = false,
.enableRunInDbg = false,
.enableMode = true
};

static void GPT1_init(void) {
/* GPT device and channels initialization */
GPT_Init(GPT1_PERIPHERAL, &GPT1_config);
GPT_SetOscClockDivider(GPT1_PERIPHERAL, 1);
GPT_SetOutputCompareValue(GPT1_PERIPHERAL, kGPT_OutputCompare_Channel1, 255);
GPT_SetOutputOperationMode(GPT1_PERIPHERAL, kGPT_OutputCompare_Channel1, kGPT_OutputOperation_Disconnected);
/* Enable GPT interrupt sources */
GPT_EnableInterrupts(GPT1_PERIPHERAL, kGPT_OutputCompare1InterruptEnable);
/* Interrupt vector GPT1_IRQn priority settings in the NVIC. */
NVIC_SetPriority(GPT1_GPT_IRQN, GPT1_GPT_IRQ_PRIORITY);
/* Enable interrupt GPT1_IRQn request in the NVIC. */
EnableIRQ(GPT1_GPT_IRQN);
/* Start the GPT timer */
GPT_StartTimer(GPT1_PERIPHERAL);
}


// Enable Interrupt
GPT_EnableInterrupts(GPT1_PERIPHERAL, kGPT_OutputCompare1InterruptEnable);

// Disable Interrupt
GPT_DisableInterrupts(GPT1_PERIPHERAL, kGPT_OutputCompare1InterruptEnable);


void GPT1_GPT_IRQHANDLER(void)
{
/* Clear interrupt flag.*/
GPT_ClearStatusFlags(GPT1_PERIPHERAL, kGPT_OutputCompare1Flag);

.........
}


// Change the compare value
GPT_SetOutputCompareValue(GPT1_PERIPHERAL, kGPT_OutputCompare_Channel1, val_Comp);



Question is can I use this same code in Visual Micro and if so how or is there another way to do exactly the same thing? Please let me know.

Thanks,

Eric Norton
 
Code:
// Init
const gpt_config_t GPT1_config = {
	.clockSource = kGPT_ClockSource_Periph,
	.divider = 1UL,
	.enableFreeRun = false,
	.enableRunInWait = false,
	.enableRunInStop = false,
	.enableRunInDoze = false,
	.enableRunInDbg = false,
	.enableMode = true
};

static void GPT1_init(void) {
	/* GPT device and channels initialization */
	GPT_Init(GPT1_PERIPHERAL, &GPT1_config);
	GPT_SetOscClockDivider(GPT1_PERIPHERAL, 1);
	GPT_SetOutputCompareValue(GPT1_PERIPHERAL, kGPT_OutputCompare_Channel1, 255);
	GPT_SetOutputOperationMode(GPT1_PERIPHERAL, kGPT_OutputCompare_Channel1, kGPT_OutputOperation_Disconnected);
	/* Enable GPT interrupt sources */
	GPT_EnableInterrupts(GPT1_PERIPHERAL, kGPT_OutputCompare1InterruptEnable);
	/* Interrupt vector GPT1_IRQn priority settings in the NVIC. */
	NVIC_SetPriority(GPT1_GPT_IRQN, GPT1_GPT_IRQ_PRIORITY);
	/* Enable interrupt GPT1_IRQn request in the NVIC. */
	EnableIRQ(GPT1_GPT_IRQN);
	/* Start the GPT timer */
	GPT_StartTimer(GPT1_PERIPHERAL);
}


// Enable Interrupt
GPT_EnableInterrupts(GPT1_PERIPHERAL, kGPT_OutputCompare1InterruptEnable);

// Disable Interrupt
GPT_DisableInterrupts(GPT1_PERIPHERAL, kGPT_OutputCompare1InterruptEnable);


void GPT1_GPT_IRQHANDLER(void)
{
	/* Clear interrupt flag.*/
	GPT_ClearStatusFlags(GPT1_PERIPHERAL, kGPT_OutputCompare1Flag);

	.........
}


// Change the compare value
GPT_SetOutputCompareValue(GPT1_PERIPHERAL, kGPT_OutputCompare_Channel1, val_Comp);
Can I ask that you enclose code between CODE tags using the # button on the blog entry form.
It makes your code much easier for others to read and understand and be able to help you.
 
Yes, I am making progress just taking some time trying to find where everything is. I will let you all know if I run into any issues.
 
Hi BriComp,

Ok so I have some success. I am able to initialize the code and can communicate with the menus etc. so USB serial and the i2c eeprom is working great. There is one thing that I am not entirely sure of and that is the GPT timer and how I am using it.

I have this:
Code:
// Enable Interrupts
NVIC_ENABLE_IRQ(IRQ_GPT1);


// Disable Interrupts
NVIC_DISABLE_IRQ(IRQ_GPT1);

void GPT1_IRQHANDLER(void)
{
     GPT1_SR |= GPT_SR_OF3; // Clear GPT1 interrupt

     while (GPT1_SR & GPT_SR_OF1); // Wait for GPT1 clear

     ......code 
}


// Init timer
CCM_CCGR1 |= CCM_CCGR1_GPT(CCM_CCGR_ON); // Enable GPT1 module
GPT1_CR = 0;
GPT1_PR = 23; // Prescale+1
GPT1_OCR1 = 0;
GPT1_SR = 0x3F; // CLear all prior status
GPT1_IR = GPT_IR_OF1IE;
GPT1_CR = GPT_CR_EN | GPT_CR_CLKSRC(1);// 1 ipg 24mhz  4 32khz

attachInterruptVector(IRQ_GPT1, GPT1_IRQHANDLER);

NVIC_ENABLE_IRQ(IRQ_GPT1); // Enable interrupt

Now I use the delay() function and delayMicroseconds() functions and would like to know if GPT1 is used for these delays? What is GPT1 used for if it is not used for the delays? I tried using GPT1 for my periodic timer and it keeps resetting the microcontroller so something is conflicting with it. Also if GPT1 is free to use, is the GPT1 timer clock frequency 24 MHz? I need to know what the clock is set to so I can use it for my calculations elsewhere in my code.

Thanks,

Eric Norton
 
Also how do I start the timer? In my previous code I use:

Code:
/* Start the GPT timer */
GPT_StartTimer(GPT1_PERIPHERAL);

Im still a bit rusty on how all this is configured in Visual Micro so please all bear with me :D
 
You should experiment with the sketch gpt_isr.ino from the repository in post #3.

GPT1_CR = GPT_CR_EN | GPT_CR_CLKSRC(1); starts GPT1 using 24 mhz as the clock source, but GPT1_PR = 23 ; scales the clock to run at 1mhz (24mhz/24).

You will want to set GPT1_OCR1 to some meaningful value for the interrupt compare threshold, e.g 1000 will interrupt every 1 millisecond

GPT1 is not used for delay() or delayMicroseconds(), GPT is just a "general purpose timer"

you might also read about teensy IntervalTimer

For proper assistance, in your posts provide a small compilable/runnable sketch that demonstrates your problem ...
 
Last edited:
If you just want to use the timer, you might consider using the TimerTool: https://github.com/luni64/TeensyTimerTool.

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

PeriodicTimer t1(GPT1);

void onTimer(){
    Serial.printf("triggered at %d\n", millis());
}

void setup(){
    t1.begin(onTimer, 10ms);
}

void loop(){
}

which prints:
Code:
triggered at 1028
triggered at 1038
triggered at 1048
triggered at 1058
triggered at 1068
triggered at 1078
triggered at 1088

This works for most of the Teensy hardware timers (GPT, TMR, PIT, FTM) and software based timers (TCK, TCK64, RTC)
Documentation: https://github.com/luni64/TeensyTimerTool/wiki
 
Hi All,

Just thought I'd mention the GPT1 timer bit twiddling works, but it seems like it doesn't like a lot of code in the ISR routine. If I uncomment the long amount of code in the ISR the MIMXRT1062 chip resets and then boots back up and then resets constantly over and over so there is something going on that I can't see. When I comment the code out and leave a little bit of code the ISR runs happily all day long. What am I missing? After doing a google search someone said something about FASTRUN and some other things too for inline if that is what it is. I think and this is just thinking here that it could be a RAM1 and RAM2 thing. Am I on the right track here???

If I can't get this to work, I found a way to use MCUXpresso with the Teensy 4.1 board so I will do that as a last resort.

Thanks,

Eric
 
By default, T_4.x code is all FASTRUN - unless marked for storage in flash.

Put a CrashReport test and print in setup() after Serial is online and before starting the timer.

Not sure how fast the timer is triggering? But long code and the code involved might be at fault.

Code:
void setup() {

  Serial.begin(38400); //USB
  delay(10);

  while (!Serial && millis() < 10000);
  Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
  if (CrashReport)
    Serial.print(CrashReport);

//...
 
Very cool... Can't wait to give it a go and find out what is causing me all this headache. I got the same code I ported over to MIMXRT1062 Visual Micro (Arduino) to work on the NXP RT1010 board through MCUXpresso so I know the crossover MCU can do this I just needed the extra ram the MIMXRT1011 device didn't have.
 
Back
Top