Teensy 4.0 First Beta Test

Status
Not open for further replies.
Qtimer

I have run into T4 trouble while experimenting with a QTIMER QT3_0. I am making an assumption that QT3_0 is free to use?

I am using the QTIMER as a simple upcounter from 0 to COMPARE1 and then reset 0. I want a toggled sq wave output from the OFLAG, and wish to trigger an ISR.

I'm getting a sq wave output OK on pin 19, but the ISR does not seem to be working correctly and the Serial Monitor seems broken too.

It is entering the ISR because the LED comes on permanently from digitalWriteFast (and is off if I remove the statement within the ISR), but it looks as if the flag raising the interrupt is not getting reset within the ISR. This is probably the cause of the broken Serial Monitor.

There appears to be two flags in the mechanism which I don't properly understand - a "Compare" flag in TMR3_SCTRL0, and another one "Compare1" in TMR3_CSCTRL0. As you can see in my code, I'm trying to reset both (have attempted each one separately). But all attempts have failed so far.

Appreciate any assistance.

Code:
//TESTT4005 - QTIMER TEST PROGRAM for T4
//======================================
//Author: TelephoneBill
//Date: 17 JUL 2019

//NOTES: Using QT3 as timer. Using QT3_0 OFLAG as sq wave output and triggering an ISR.

//definitions
byte Byte1;
volatile uint32_t ISRTicks = 0, LastISRTicks = 0;

//SETUP
//=====
void setup() {
  //initialise general hardware
  Serial.begin(115200);             //setup serial port
  pinMode(13, OUTPUT);              //pin 13 as digital output
  FlashLED(4);
  
  //enable clocks for QTIMER3
  CCM_CCGR6 |= 0xC0000000;                    //enable clocks to CG15 of CGR6 for QT3

  //configure QTIMER1 Timer0 for test. Period = 65,536 = 436.9 uS (times 2) - rollover
  TMR3_CTRL0 = 0b0000000000100000;  // stop all functions of timer 
  TMR3_SCTRL0 = 0b0100000000000001; // 0(TimerCompareFlag),1(TimerCompareIntEnable),000000,00(Capture Disabled),00000,1(OFLAG to Ext Pin)
  TMR3_CNTR0 = 0;
  TMR3_LOAD0 = 0;
  TMR3_COMP10 = 10000;              // 6.7nS per clock = 66.7uS for 10,000 clocks on each half cycle
  TMR3_CMPLD10 = 10000;
  TMR3_CSCTRL0 = 0b0000000001000001;  //Compare1 interrupt enable
  TMR3_CTRL0 = 0b0011000000100011;  // 001(Count rising edges Primary Source),1000(IP Bus Clock),00 (Secondart Source), 
                                    // 0(Count Once),1(Count up to Compare),0(Count Up),0(Co Channel Init),011(Toggle OFLAG on Compare)
  
  //configure Teensy pin Compare output
  IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_00 = 1;    // QT3 Timer0 is now on pin 19
  
  //enable GPT1 interrupt within NVIC table
  attachInterruptVector(IRQ_QTIMER3, QT3_isr);  //declare which routine performs the ISR function
  NVIC_ENABLE_IRQ(IRQ_QTIMER3);
}


//ISR ROUTINE FOR GPT1
//====================
//FASTRUN puts this code into RAM to run twice as fast
FASTRUN void QT3_isr(void) {
  TMR3_SCTRL0 |= 0b1000000000000000;     //reset the compare flag
  TMR3_CSCTRL0 |= 0b0000000000010000;    //Compare1 interrupt enable
  ISRTicks++;
  digitalWriteFast(13, 1); //test that ISR is being entered
  asm volatile("dsb");
}


//MAIN LOOP
//=========
void loop() {
  //call KeyInput() routine
  KeyInput();
  if (ISRTicks>LastISRTicks) {
    LastISRTicks = ISRTicks;
    delay(100);
    digitalWriteFast(13, 0);
    delay(900);
  }
}

//SUBROUTINES
//===========
//Flash LED routine
void FlashLED(int m) {
  for (int n=0;n<m;n++) {
    digitalWriteFast(13, 1);          //set pin 13 high
    delay(100);
    digitalWriteFast(13, 0);          //set pin 13 low
    delay(100);
  }
}

void KeyInput() {
  //process any keystrokes available
  if (Serial.available()>0) {
    //read the incoming byte
    Byte1 = Serial.read();
    if (Byte1>0x20) {
      switch (Byte1) {
      case 'T':  //print the ISRTicks value
        //task goes here...
        Serial.print("ISRTicks = "); Serial.println(ISRTicks);
        break;
      }
    }
  }
}
 
I have run into T4 trouble while experimenting with a QTIMER QT3_0. I am making an assumption that QT3_0 is free to use?

I am using the QTIMER as a simple upcounter from 0 to COMPARE1 and then reset 0. I want a toggled sq wave output from the OFLAG, and wish to trigger an ISR.

I'm getting a sq wave output OK on pin 19, but the ISR does not seem to be working correctly and the Serial Monitor seems broken too.

It is entering the ISR because the LED comes on permanently from digitalWriteFast (and is off if I remove the statement within the ISR), but it looks as if the flag raising the interrupt is not getting reset within the ISR. This is probably the cause of the broken Serial Monitor.

There appears to be two flags in the mechanism which I don't properly understand - a "Compare" flag in TMR3_SCTRL0, and another one "Compare1" in TMR3_CSCTRL0. As you can see in my code, I'm trying to reset both (have attempted each one separately). But all attempts have failed so far.

Appreciate any assistance.
...

@TelephoneBill - I ran your code and saw what you saw. But Auto Upload works - so USB is active and aware. The _isr()'s just repeat too fast to let loop() run as written AFAIK.

I gave the QT3_isr() some personality with blink wait blink. That shows it is running and resetting. But it effectively never leaves because of the rate of triggering?

I added a quick disable to show that loop() is ready and active - just being ignored. Then loop() runs and starts the QT3_isr() again.


Try this code for your next steps:
Code:
//TESTT4005 - QTIMER TEST PROGRAM for T4
//======================================
//Author: TelephoneBill
//Date: 17 JUL 2019

//NOTES: Using QT3 as timer. Using QT3_0 OFLAG as sq wave output and triggering an ISR.

//definitions
byte Byte1;
volatile uint32_t ISRTicks = 0, LastISRTicks = 0;
#define qBlink() digitalWriteFast( LED_BUILTIN, !digitalReadFast( LED_BUILTIN ) )

//SETUP
//=====
void setup() {
	//initialise general hardware
	Serial.begin(115200);             //setup serial port
	while (!Serial && millis() < 4000 );
	Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
	pinMode(13, OUTPUT);              //pin 13 as digital output
	FlashLED(4);

	//enable clocks for QTIMER3
	CCM_CCGR6 |= 0xC0000000;                    //enable clocks to CG15 of CGR6 for QT3

	//configure QTIMER1 Timer0 for test. Period = 65,536 = 436.9 uS (times 2) - rollover
	TMR3_CTRL0 = 0b0000000000100000;  // stop all functions of timer
	TMR3_SCTRL0 = 0b0100000000000001; // 0(TimerCompareFlag),1(TimerCompareIntEnable),000000,00(Capture Disabled),00000,1(OFLAG to Ext Pin)
	TMR3_CNTR0 = 0;
	TMR3_LOAD0 = 0;
	TMR3_COMP10 = 10000;              // 6.7nS per clock = 66.7uS for 10,000 clocks on each half cycle
	TMR3_CMPLD10 = 10000;
	TMR3_CSCTRL0 = 0b0000000001000001;  //Compare1 interrupt enable
	TMR3_CTRL0 = 0b0011000000100011;  // 001(Count rising edges Primary Source),1000(IP Bus Clock),00 (Secondart Source),
	// 0(Count Once),1(Count up to Compare),0(Count Up),0(Co Channel Init),011(Toggle OFLAG on Compare)

	//configure Teensy pin Compare output
	IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_00 = 1;    // QT3 Timer0 is now on pin 19

	//enable GPT1 interrupt within NVIC table
	attachInterruptVector(IRQ_QTIMER3, QT3_isr);  //declare which routine performs the ISR function
	NVIC_ENABLE_IRQ(IRQ_QTIMER3);
}


//ISR ROUTINE FOR GPT1
//====================
//FASTRUN puts this code into RAM to run twice as fast
FASTRUN void QT3_isr(void) {
	TMR3_SCTRL0 |= 0b1000000000000000;     //reset the compare flag
	TMR3_CSCTRL0 |= 0b0000000000010000;    //Compare1 interrupt enable
	ISRTicks++;
	if ( !(ISRTicks % 10))
		NVIC_DISABLE_IRQ(IRQ_QTIMER3);
	//digitalWriteFast(13, 1); //test that ISR is being entered
	qBlink();
	delayMicroseconds(10000);
	qBlink();
	delayMicroseconds(10000);
	qBlink();
	asm volatile("dsb");
}


//MAIN LOOP
//=========
void loop() {
	//call KeyInput() routine
	KeyInput();
	if (ISRTicks > LastISRTicks) {
		LastISRTicks = ISRTicks;
		delay(100);
		Serial.println( LastISRTicks );
		digitalWriteFast(13, 0);
		delay(900);
		NVIC_ENABLE_IRQ(IRQ_QTIMER3);
	}
}

//SUBROUTINES
//===========
//Flash LED routine
void FlashLED(int m) {
	for (int n = 0; n < m; n++) {
		digitalWriteFast(13, 1);          //set pin 13 high
		delay(100);
		digitalWriteFast(13, 0);          //set pin 13 low
		delay(100);
	}
}

void KeyInput() {
	//process any keystrokes available
	if (Serial.available() > 0) {
		//read the incoming byte
		Byte1 = Serial.read();
		if (Byte1 > 0x20) {
			switch (Byte1) {
			case 'T':  //print the ISRTicks value
				//task goes here...
				Serial.print("ISRTicks = "); Serial.println(ISRTicks);
				break;
			}
		}
	}
}
 
I have run into T4 trouble while experimenting with a QTIMER QT3_0. I am making an assumption that QT3_0 is free to use?

I am using the QTIMER as a simple upcounter from 0 to COMPARE1 and then reset 0. I want a toggled sq wave output from the OFLAG, and wish to trigger an ISR.

I'm getting a sq wave output OK on pin 19, but the ISR does not seem to be working correctly and the Serial Monitor seems broken too.

It is entering the ISR because the LED comes on permanently from digitalWriteFast (and is off if I remove the statement within the ISR), but it looks as if the flag raising the interrupt is not getting reset within the ISR. This is probably the cause of the broken Serial Monitor.

There appears to be two flags in the mechanism which I don't properly understand - a "Compare" flag in TMR3_SCTRL0, and another one "Compare1" in TMR3_CSCTRL0. As you can see in my code, I'm trying to reset both (have attempted each one separately). But all attempts have failed so far.

Appreciate any assistance.

The interrupts are cleared by writing a zero.
A "|=" is: load - logical "or" - store
so any "1" stays "1", and the interrupts get not reset.

53.10.2.1.1 Timer Compare 1 Interrupts (Available with Compare Load
Feature)
These interrupts are generated when a successful compare occurs between a counter and
its COMP1 register while CSCTRL[TCF1EN] is set. These interrupts are cleared by
writing a zero to the appropriate CSCTRL[TCF1]
.
53.10.2.1.2 Timer Compare 2 Interrupts (Available with Compare Load
Feature)
These interrupts are generated when a successful compare occurs between a counter and
its COMP2 register while CSCTRL[TCF2EN] is set. These interrupts are cleared by
writing a zero to the appropriate CSCTRL[TCF2].
53.10.2.2 Timer Overflow Interrupts
These interrupts are generated when a counter rolls over its maximum value while
SCTRL[TOFIE] is set. These interrupts are cleared by writing zero to the appropriate
SCTRL[TOF].

I stripped the sketch and let only the important parts in:
Code:
void setup() {
  pinMode(13, OUTPUT);              //pin 13 as digital output

  
  //enable clocks for QTIMER3
  CCM_CCGR6 |= 0xC0000000;                    //enable clocks to CG15 of CGR6 for QT3

  //configure QTIMER1 Timer0 for test. Period = 65,536 = 436.9 uS (times 2) - rollover
  TMR3_CTRL0 = 0b0000000000100000;  // stop all functions of timer 
  TMR3_SCTRL0 = 0b0100000000000001; // 0(TimerCompareFlag),1(TimerCompareIntEnable),000000,00(Capture Disabled),00000,1(OFLAG to Ext Pin)
  TMR3_CNTR0 = 0;
  TMR3_LOAD0 = 0;
  TMR3_COMP10 = 10000;              // 6.7nS per clock = 66.7uS for 10,000 clocks on each half cycle
  TMR3_CMPLD10 = 10000;
  TMR3_CSCTRL0 = 0b0000000001000001;  //Compare1 interrupt enable
  TMR3_CTRL0 = 0b0011000000100011;  // 001(Count rising edges Primary Source),1000(IP Bus Clock),00 (Secondart Source), 
                                    // 0(Count Once),1(Count up to Compare),0(Count Up),0(Co Channel Init),011(Toggle OFLAG on Compare)
  
  //configure Teensy pin Compare output
  IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_00 = 1;    // QT3 Timer0 is now on pin 19
  
  //enable GPT1 interrupt within NVIC table
  attachInterruptVector(IRQ_QTIMER3, QT3_isr);  //declare which routine performs the ISR function
  NVIC_ENABLE_IRQ(IRQ_QTIMER3);
}

void QT3_isr(void) {
  digitalWriteFast(13, 1);
  TMR3_SCTRL0 = 0b0100000000000001;
  TMR3_CSCTRL0 = 0b0000000001000001;
  digitalWriteFast(13, 0);
  asm volatile("dsb");
}


//MAIN LOOP
//=========
void loop() {
}

With the scope, I now see a nice 15kHz pulse on Pin 13 .
 
Last edited:
Nice @Frank B.

Swapping out the_isr code above with this allows loop() to run normally.
No need to disable the IRQ { or to enable it in loop() }
Code:
FASTRUN void QT3_isr(void) {
//	TMR3_SCTRL0 |= 0b1000000000000000;     //reset the compare flag
//	TMR3_CSCTRL0 |= 0b0000000000010000;    //Compare1 interrupt enable
	TMR3_SCTRL0 = 0b0100000000000001;
	TMR3_CSCTRL0 = 0b0000000001000001;
	ISRTicks++;
	if ( !(ISRTicks % 15000)) {
		qBlink();
	}
	asm volatile("dsb");
}
 
I was wondering if we can output 150MHz at pin 19 - yes, we can!

In the program, above remove all but the setup:
Code:
void setup() {
  
  //enable clocks for QTIMER3
  CCM_CCGR6 |= 0xC0000000;                    //enable clocks to CG15 of CGR6 for QT3

  //configure QTIMER1 Timer0 for test. Period = 65,536 = 436.9 uS (times 2) - rollover
  TMR3_CTRL0 = 0b0000000000100000;  // stop all functions of timer 
  TMR3_SCTRL0 = 0b0100000000000001; // 0(TimerCompareFlag),1(TimerCompareIntEnable),000000,00(Capture Disabled),00000,1(OFLAG to Ext Pin)
  TMR3_CNTR0 = 0;
  TMR3_LOAD0 = 0;
  TMR3_COMP10 = 1;              // 6.7nS per clock = 66.7uS for 10,000 clocks on each half cycle
  [COLOR=#ff0000]TMR3_CMPLD10 = 0;[/COLOR]
  TMR3_CSCTRL0 = 0b0000000001000001;  //Compare1 interrupt enable
  TMR3_CTRL0 = 0b0011000000100011;  // 001(Count rising edges Primary Source),1000(IP Bus Clock),00 (Secondart Source), 
                                    // 0(Count Once),1(Count up to Compare),0(Count Up),0(Co Channel Init),011(Toggle OFLAG on Compare)
  
  //configure Teensy pin Compare output
  IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_00 = 1;    // QT3 Timer0 is now on pin 19
  
}
void loop() {}

This gives 75MHZ. Then, increase the bus speed to 300MHz, by editing clockspeed.c , line 146 to
Code:
    if (div_ipg > 2) div_ipg = 2;

Voilà.. 150MHz on Pin 19 :)

(My Scope, which was updated to 200MHz (Thanks to @MJS) but still has 100MHZ probes displays a sine only - so, I'll not post a screenshot..)
 
Last edited:
Gentlemen - Thankyou both. I could have stared at those ISR lines for days and not spotted it. So many other places where you write a '1' to clear a flag (familiarity breeds contempt). And the manual - can't see wood for digital trees.

Will play more now... looking forward to VHF on pin 19 :)... It would be useful to write a novice guide some time, and include these examples.

By the way, QTIMERS look easy to cascade, so will try a 64 bit counter soon. Also, the "alternate COMPARE" (switching from Compare1 to Compare2 and back) looks interesting.
 
Havn't looked at the QTIMERS in detail.. but yes, they look interesting.
Can you do two outputs?
This would be great for SDRs (Radios) as local oszillator without need for the normally used 7474 johnson counter (->2 outputs with 90° phase shift)- Hm, we might need an even higher IPG speed for a better resolution... anyone tried 600MHZ for IPG-BUS?
 
Re: QTIMER

in my testing, i think the compare values loaded into regs need to be n-1
Code:
  TMR3_COMP10 = 10000 -1;              // 6.7nS per clock = 66.7uS for 10,000 clocks on each half cycle 	
  TMR3_CMPLD10 = 10000 - 1;
Also, somewhere i have a post where i discussed never getting the QTIMER overflow interrupt to work ??
see https://forum.pjrc.com/threads/54711-Teensy-4-0-First-Beta-Test?p=199536&viewfull=1#post199536

@TelephoneBill I'm amazed at your ability to parse 32-bit binary numbers! There are symbols for all those bits in imxrt.h

various qtimer tests in qtmrtst.ino
 
Not studied yet but there is a QUADRATURE option. One of the control bits can also invert.

I did get a QUAD output from GPT2 as well. Set Compare1 for frequency, then Compare2 and Compare3 can be any integer "phase" you choose from 0 to 360 deg. If we could get Compare1 (GPT2) out via the XBAR on another pin, then we could even have three phases.
 
@TelephoneBill I'm amazed at your ability to parse 32-bit binary numbers! There are symbols for all those bits in imxrt.h

Yes - I should use the symbols - even just to find any errors that might have crept in. I do find it educational, though, going through the registers bit by bit - it sticks in the brain better with me!
 
Re: QTIMER

in my testing, i think the compare values loaded into regs need to be n-1
Code:
  TMR3_COMP10 = 10000 -1;              // 6.7nS per clock = 66.7uS for 10,000 clocks on each half cycle 	
  TMR3_CMPLD10 = 10000 - 1;
Also, somewhere i have a post where i discussed never getting the QTIMER overflow interrupt to work ??
see https://forum.pjrc.com/threads/54711-Teensy-4-0-First-Beta-Test?p=199536&viewfull=1#post199536

@TelephoneBill I'm amazed at your ability to parse 32-bit binary numbers! There are symbols for all those bits in imxrt.h

various qtimer tests in qtmrtst.ino

THANK YOU @manitou! :) You are absolutely correct.

I altered code above to print millis/micros on each 15000 count and it was slipping 100us each set!

This code runs and the 15,000 interval matches the millis/micros! Which is good as it shows the micros() resolution work done stays in sync with Millis!

Code:
//TESTT4005 - QTIMER TEST PROGRAM for T4
//======================================
//Author: TelephoneBill
//Date: 17 JUL 2019

//NOTES: Using QT3 as timer. Using QT3_0 OFLAG as sq wave output and triggering an ISR.

//definitions
byte Byte1;
volatile uint32_t ISRTicks = 0, iISRTicks = 0, LastISRTicks = 0;
#define qBlink() digitalWriteFast( LED_BUILTIN, !digitalReadFast( LED_BUILTIN ) )

//SETUP
//=====
void setup() {
	//initialise general hardware
	Serial.begin(115200);             //setup serial port
	while (!Serial && millis() < 4000 );
	Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
	pinMode(13, OUTPUT);              //pin 13 as digital output
	FlashLED(4);

	//enable clocks for QTIMER3
	CCM_CCGR6 |= 0xC0000000;                    //enable clocks to CG15 of CGR6 for QT3

	//configure QTIMER1 Timer0 for test. Period = 65,536 = 436.9 uS (times 2) - rollover
	TMR3_CTRL0 = 0b0000000000100000;  // stop all functions of timer
	TMR3_SCTRL0 = 0b0100000000000001; // 0(TimerCompareFlag),1(TimerCompareIntEnable),000000,00(Capture Disabled),00000,1(OFLAG to Ext Pin)
	TMR3_CNTR0 = 0;
	TMR3_LOAD0 = 0;
	TMR3_COMP10 = 10000-1;              // 6.7nS per clock = 66.7uS for 10,000 clocks on each half cycle
	TMR3_CMPLD10 = 10000-1;
	TMR3_CSCTRL0 = 0b0000000001000001;  //Compare1 interrupt enable
	TMR3_CTRL0 = 0b0011000000100011;  // 001(Count rising edges Primary Source),1000(IP Bus Clock),00 (Secondart Source),
	// 0(Count Once),1(Count up to Compare),0(Count Up),0(Co Channel Init),011(Toggle OFLAG on Compare)

	//configure Teensy pin Compare output
	IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_00 = 1;    // QT3 Timer0 is now on pin 19

	//enable GPT1 interrupt within NVIC table
	attachInterruptVector(IRQ_QTIMER3, QT3_isr);  //declare which routine performs the ISR function
	NVIC_ENABLE_IRQ(IRQ_QTIMER3);
}


//ISR ROUTINE FOR GPT1
//====================
//FASTRUN puts this code into RAM to run twice as fast
FASTRUN void QT3_isr(void) {
	TMR3_SCTRL0 = 0b0100000000000001;
	TMR3_CSCTRL0 = 0b0000000001000001;
	iISRTicks++;
	if ( !(iISRTicks % 15000)) {
		ISRTicks = iISRTicks;
	}
	asm volatile("dsb");
}


//MAIN LOOP
//=========
void loop() {
	if (ISRTicks > LastISRTicks) {
		qBlink();
		LastISRTicks = ISRTicks;
		Serial.print( micros() );
		Serial.print(  "us @ " );
		Serial.print( millis() );
		Serial.print(  "ms cnt =" );
		Serial.println( LastISRTicks );
	}
}

//SUBROUTINES
//===========
//Flash LED routine
void FlashLED(int m) {
	for (int n = 0; n < m; n++) {
		digitalWriteFast(13, 1);          //set pin 13 high
		delay(100);
		digitalWriteFast(13, 0);          //set pin 13 low
		delay(100);
	}
}

Output snippet:
29459000us @ 29459ms cnt =420000
30459000us @ 30459ms cnt =435000
31459000us @ 31459ms cnt =450000
32459000us @ 32459ms cnt =465000
33459000us @ 33459ms cnt =480000
34459000us @ 34459ms cnt =495000
 
Yup, can confirm that.

Good, I wondered how I was messing up the timing but such a constant 100us amount.

Also odd that the micros() always ended in 000 on each run I did. So decided to show ARM_CycCnt too - and this run micros() is off by one 1us! {oddly the change has 4 runs starting off by 1 us} ::
600000031=d CYCCNT 409491001us @ 409491ms cnt =6120000
599999969=d CYCCNT 410491001us @ 410491ms cnt =6135000
600000031=d CYCCNT 411491001us @ 411491ms cnt =6150000
599999969=d CYCCNT 412491001us @ 412491ms cnt =6165000
600000032=d CYCCNT 413491001us @ 413491ms cnt =6180000
599999968=d CYCCNT 414491001us @ 414491ms cnt =6195000
600000032=d CYCCNT 415491001us @ 415491ms cnt =6210000
599999968=d CYCCNT 416491001us @ 416491ms cnt =6225000
600000031=d CYCCNT 417491001us @ 417491ms cnt =6240000
599999969=d CYCCNT 418491001us @ 418491ms cnt =6255000
600000031=d CYCCNT 419491001us @ 419491ms cnt =6270000
ARM_CycCnt here is printed from loop - so the jitter is return to loop seeing the change - not the _isr pe se.

For ref the T4 is doing 7.6478M loop()'s second here.
And defining a void yield() bumps that to 13,310,710 loop()'s /second.


With that void yield() the loop() jitter goes away except for this one time in 700 seconds::
600000000=d CYCCNT 13310708=loop() Cnt 124453002us @ 124453ms cnt =1845000
600000000=d CYCCNT 13310708=loop() Cnt 125453002us @ 125453ms cnt =1860000
600000000=d CYCCNT 13310709=loop() Cnt 126453002us @ 126453ms cnt =1875000
600000000=d CYCCNT 13310709=loop() Cnt 127453002us @ 127453ms cnt =1890000
600000000=d CYCCNT 13310709=loop() Cnt 128453002us @ 128453ms cnt =1905000
600000032=d CYCCNT 13310709=loop() Cnt 129453002us @ 129453ms cnt =1920000
599999968=d CYCCNT 13310709=loop() Cnt 130453002us @ 130453ms cnt =1935000
600000000=d CYCCNT 13310710=loop() Cnt 131453002us @ 131453ms cnt =1950000
600000000=d CYCCNT 13310708=loop() Cnt 132453002us @ 132453ms cnt =1965000
600000000=d CYCCNT 13310709=loop() Cnt 133453002us @ 133453ms cnt =1980000
… cool here after edit the micros() is now showing 002, so the clock and start must just be synchronized.
 
Hey there,

I was reading at the 1060 specs, it looks like it has 3 I2S interfaces, of which one has 4 tx/rx pairs, and the other two have 1 tx/rx pair, total of 6 rx/tx pairs, and it also looks like all of the I2S modules support TDM... does it mean that it MAY be possible to implement something like 24 channels of audio (where each interface is set in TDM with two codecs on each pair)?
If that's the case I'd be impressed
 
@PaulStoffregen and @all...

Yesterday I started playing with partially assembled breakout board :D

The board includes a Neopixel - which I thought I would test out.

Some things are my own hardware issue: like the neopixel starts up with a blue color whenever I startup the board. Wonder how to stop it... I had this with previous board as well, thought maybe a Pull down resistor on the data line might help... Nope. Will try looking at schematic of prop shield and see what it does. My guess is, it uses another IO pin to control turning power on...

But more to the point. I started a simple sketch:

Code:
#include <SD.h>
#include <SD_t3.h>

//#include <WireKinetis.h>

#include <EEPROM.h>
#include <Arduino.h>
#include <Adafruit_NeoPixel.h>

//====================================================================================
// Globals
Adafruit_NeoPixel strip = Adafruit_NeoPixel(1, 33, NEO_RGB + NEO_KHZ800);
//====================================================================================
// Setup
//====================================================================================
void setup() {
  pinMode(13, OUTPUT);
  pinMode(33, OUTPUT);
  for(int i=0;i<10;i++) {
    digitalWrite(33, !digitalRead(33));
    delay(100);
  }

  while (!Serial && (millis() < 3000)) ;
  Serial.begin(115200);

  strip.begin();
  strip.show(); // Initialize all pixels to 'off'

  strip.setPixelColor(0, strip.Color(255, 0, 0));
  strip.show();
  delay(125);
  strip.setPixelColor(0, strip.Color(0, 255, 0));
  strip.show();
  delay(125);
  strip.setPixelColor(0, strip.Color(0, 0, 255));
  strip.show();
  delay(125);
  strip.setPixelColor(0, strip.Color(0, 0, 0));
  strip.show();
}
void loop() {
  digitalWrite(13, !digitalRead(13));
  delay(500);
  
}
I built it and tried it out and nothing happened to the neopixel.

I checked posting #4 and see: works Adafruit_NeoPixel post #279 tested with Simple example and 8 LED stick

Looked at posting #279 which has an updated adafruit_NeoPixel.cpp file ...

Tried to copy that file into my version in: <arduino sketches folder>/libraries/Adafruit_NeoPixel

And tried to rebuild and I get many compile errors.

So figured it was probably the version in the Teensyduino install, so I removed my private version (Fork of Adafruit github), copied the updated file Teensyduino installed version and now my Neopixel does change colors :D

@PaulStoffregen - I see you have a Fork of this library: https://github.com/PaulStoffregen/Adafruit_NeoPixel
Which shows that you are 47 commits behind the master, and the last update to your version was in 2017.


Now the questions:

Where is the version that goes into the Teensyduino installs come from?

I don't see any Open or Closed PR requests on the Adafruit project: I assume one of us needs to try to integrate the stuff in the copy you posted in #279 into the Adafruit sources and do a Pull Request.

In cases like this, do we need to have tables #4 and #6 differentiate the Teensyduino install version works, versus the main (like Adafruit) version works?
 
@PaulStoffregen

...

I don't see any Open or Closed PR requests on the Adafruit project: I assume one of us needs to try to integrate the stuff in the copy you posted in #279 into the Adafruit sources and do a Pull Request.


In this case, I added the code block for IMXRT1052/1062 to the current adafruit code base, tried it out on my board with one Neopixel and still works...

Maybe others might want to try as well: Code is in the PR: https://github.com/adafruit/Adafruit_NeoPixel/pull/196
Or you can try out my fork/branch: https://github.com/KurtE/Adafruit_NeoPixel/tree/T4_beta

Update: Merged by LadyAda...
 
Last edited:
Re: neopixel
I again hooked up 8-LED neopixel stick to T4B2R (3v3, gnd, pin 1) and ran simple example (with pin 1) from hardware/teensy/avr/libraries/Adafruit_NeoPixel, and it still works for me. 1.8.8 1.47-beta4
you can see (defined(__IMXRT1052__) || defined(__IMXRT1062__)) in Adafruit_NeoPixel.cpp

i also have a hacked FastLED that works for me on T4 with neopixel or dotstar
https://forum.pjrc.com/threads/54711-Teensy-4-0-First-Beta-Test?p=202885&viewfull=1#post202885
 
Last edited:
Qtimer

Been playing around again tonight with QTimers. Interesting idea of using QT3 in quadrature - employing QT3_Timer0 on pin 19 and QT3_Timer1 on pin 18.

This example also uses the "Alternating Compare1 and Compare2" mode to get a particular Mark/Space ratio of 1us/9uS. The basic idea here is that Compare1 OFLAG output sets the "Space" timing and Compare2 OFLAG output sets the "Mark" timing. The "software model" counts up to Compare1 first and resets to zero, before switching and counting to Compare2 then resets to zero... ad infinitum. The clock is the peripheral clock of 150 MHz.

With QT3_Timer2 and QT3_Timer3 also available on pins 14 and 15, then the option of three phase or four phase signals is possible too. The preset count for QT3_Timer1 was obtain by simple trial and error. Perhaps a common trigger signal might be available to kick them off in a more professional way.

Edit. Not really "quadrature" in the true sense, but you get the gist (is it two phase?).

QT3Timers01.jpg

Code:
//TestT4007 - QTIMER TEST PROGRAM for T4
//======================================
//Author: TelephoneBill
//Date: 19 JUL 2019

//NOTES: Using QT3 as timer. Testing alternate Compare1 and Compare2 for sq wave output and ISR.
//Compare1 determines '0' (space) period, Compare2 determines '1' (mark) period - these alternate.
//Output Pulse = 1uS wide every 10uS (100 KHz). Uses QT3Timer0 and QT3Timer1 in quadrature.

//definitions
bool PrintISRTicksOn;
byte Byte1;
volatile uint32_t ISRTicks = 0;


//SETUP
//=====
void setup() {
  //initialise general hardware
  Serial.begin(115200);             //setup serial port
  pinMode(13, OUTPUT);              //pin 13 as digital output
  FlashLED(4);                      //confidence boost on startup
  
  //enable clocks for QTIMER3
  CCM_CCGR6 |= 0xC0000000;              //enable clocks to CG15 of CGR6 for QT3

  //configure QTIMER3 Timer0 for test of alternating Compare1 and Compare2
  TMR3_CTRL0 = 0b0000000000100000;      //stop all functions of timer 
  TMR3_SCTRL0 = 0b0000000000000001;     //0(TimerCompareFlag),0(TimerCompareIntEnable),00(TimerOverflow)0000(NoCapture),0000(Capture Disabled),00, 0,1(OFLAG to Ext Pin)
  TMR3_CNTR0 = 0;
  TMR3_LOAD0 = 0;
  TMR3_COMP10 = 1350-1;                 //6.7nS per clock = 9uS for 1350 clocks on first half cycle (space)
  TMR3_CMPLD10 = 1350-1;
  TMR3_COMP20 = 150-1;                  //6.7nS per clock = 1uS for 150 clocks on second half cycle (mark) = 10uS total for Compare1 and Compare2 alternating
  TMR3_CMPLD20 = 150-1;
  TMR3_CSCTRL0 = 0b0000000010000101;    //Compare1 only enabled - Compare Load1 control and Compare Load2 control both on
  TMR3_CTRL0 = 0b0011000000100100;      // 001(Count rising edges Primary Source),1000(IP Bus Clock),00 (Secondary Source), 
                                        // 0(Count Once),1(Count up to Compare),0(Count Up),0(Co Channel Init),100(Toggle OFLAG on alternating Compare1/Compare2)
  
  //configure QTIMER3 Timer1 for test of alternating Compare1 and Compare2
  TMR3_CTRL1 = 0b0000000000100000;      //stop all functions of timer 
  TMR3_SCTRL1 = 0b0000000000000001;     //0(TimerCompareFlag),0(TimerCompareIntEnable),00(TimerOverflow)0000(NoCapture),0000(Capture Disabled),00, 0,1(OFLAG to Ext Pin)
  TMR3_CNTR1 = 325;
  TMR3_LOAD1 = 0;
  TMR3_COMP11 = 1350-1;                 //6.7nS per clock = 9uS for 1350 clocks on first half cycle (space)
  TMR3_CMPLD11 = 1350-1;
  TMR3_COMP21 = 150-1;                  //6.7nS per clock = 1uS for 150 clocks on second half cycle (mark) = 10uS total for Compare1 and Compare2 alternating
  TMR3_CMPLD21 = 150-1;
  TMR3_CSCTRL1 = 0b0000000010000101;    //Compare1 only enabled - Compare Load1 control and Compare Load2 control both on
  TMR3_CTRL1 = 0b0011000000100100;      // 001(Count rising edges Primary Source),1000(IP Bus Clock),00 (Secondary Source), 
                                        // 0(Count Once),1(Count up to Compare),0(Count Up),0(Co Channel Init),100(Toggle OFLAG on alternating Compare1/Compare2)
  //configure Teensy pin Compare output
  IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_00 = 1;      // QT3 Timer0 is now on pin 19
  IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_01 = 1;      // QT3 Timer1 is now on pin 18
  
  //enable QT3 interrupt within NVIC table
  attachInterruptVector(IRQ_QTIMER3, QT3_isr);  //declare which routine performs the ISR function
  NVIC_ENABLE_IRQ(IRQ_QTIMER3);
}


//ISR ROUTINE FOR QT3
//====================
//FASTRUN puts this code into RAM to run twice as fast
FASTRUN void QT3_isr(void) {
  TMR3_SCTRL0 &= ~(TMR_SCTRL_TCF);
  TMR3_CSCTRL0 &= ~(TMR_CSCTRL_TCF1|TMR_CSCTRL_TCF2);
  TMR3_SCTRL1 &= ~(TMR_SCTRL_TCF);
  TMR3_CSCTRL1 &= ~(TMR_CSCTRL_TCF1|TMR_CSCTRL_TCF2);
  ISRTicks++;
  asm volatile("dsb");
}


//MAIN LOOP
//=========
void loop() {
  //call KeyInput() routine
  KeyInput();
  if ((ISRTicks%10000)==0) {
    digitalWriteFast(13, 1);
    delay(10);
    digitalWriteFast(13, 0);
    if (PrintISRTicksOn) {
      Serial.print("ISRTicks = "); Serial.println(ISRTicks);    
    }
  }
}

//SUBROUTINES
//===========
//Flash LED routine
void FlashLED(int m) {
  for (int n=0;n<m;n++) {
    digitalWriteFast(13, 1);          //set pin 13 high
    delay(100);
    digitalWriteFast(13, 0);          //set pin 13 low
    delay(100);
  }
}

//KeyInput routine
void KeyInput() {
  //process any keystrokes available
  if (Serial.available()>0) {
    //read the incoming byte
    Byte1 = Serial.read();
    if (Byte1>0x20) {
      switch (Byte1) {
      case 'T':  //print the ISRTicks value
        //task goes here...
        PrintISRTicksOn = !PrintISRTicksOn; //toggle print status
        break;
      }
    }
  }
}
 
Last edited:
@Kurt:

Which libs do I need to make ILI9341_t3n work?
Code:
c:\temp\arduino_build_238836\libraries\SPIN-master\SPI.cpp.o: In function `_spi_dma_rxISR1()':

C:\Users\Frank\Documents\Arduino\libraries\SPIN-master/SPI.cpp:1416: multiple definition of `_spi_dma_rxISR1()'

c:\temp\arduino_build_238836\libraries\SPI\SPI.cpp.o:C:\Arduino\hardware\teensy\avr\libraries\SPI/SPI.cpp:1416: first defined here
Downloaded ILI9341_t3n, SPIN and SPI libs from github - shows the errors above :confused:

Edit: Does the framebuffer work?
 
@PaulStoffregen (@KurtE, @defragster. @Frank B)

@PaulStoffregen (@mjs513, @defragster) - As has been mentioned in the thread: https://forum.pjrc.com/threads/5573...3-x-and-beyond?p=210184&viewfull=1#post210184

There is a sketch that if include @defragsters debug library the app (uncannyeyes) runs. But without it, the app dies and disables USB. Earlier with this one, after that happened I could not reprogram either with simple push button. But later did get it to recover...

When I was debugging it earlier, If I added Serial.print at start of setup(), even waiting: while (!Serial && millis()< 5000) ; Serial.begin(115200);

And if I put in a delay... still the Serial terminal never was valid nothing printed... And then later Message from windows saying Serial device is invalid...


A few posts up from there @mjs513 posted the sketch.

Wondering in cases like this, Would posting a zip file of the build directory help. Which contains the hex file, elf file, list file,

Some different outputs from objdump? But one can get these from using the objdump installed with arduino on the elf file...

@defragster provided a tone more detail in posts 3701, 3702, 3710 and me in 3703. Also see #3723-3725 @Frank B also provided some info that the error doesn't occur with GCC6 (post #3727). In the other thread (ili9488... and beyond) I wound up doing some more debugging and tried to isolate the code that was causing the USB issue, post #459.

I did a test of the sketch on the T3.2 and it did show the same issue with lock up. So....

After fiddling I did find something that resolved the problem but not sure why, see post #472. Repeated here so you have to jump to other thread:
@KurtE - @defragster - @MichaelMeissner

I did try to change the SPI clock down to 12Mhz but still exhibited the same behavior. Even tried at lower CPU clocks with no luck. However, playing around a little more I got it working by adding a single print statement to the eye movement loop, and fixed the whole issue:
Code:
    if (dt >= eyeMoveDuration) {          // Time up?  Destination reached.
      eyeInMotion      = false;           // Stop moving
      eyeMoveDuration  = random(1,3000000); // 0-3 sec stop
      eyeMoveStartTime = t;               // Save initial time of stop
      eyeX = eyeOldX = eyeNewX;           // Save position
      eyeY = eyeOldY = eyeNewY;
      [B][COLOR="#FF0000"]Serial.printf("%d(eMD)\n", eyeMoveDuration);[/COLOR][/B]
    }

EDIT: @KurtE got me thinking so I tried something else that worked but... See post #475
 
Last edited:
Somebody else may have mentioned this, but just in case....

Paul, I was looking at the printed card, as well as the card image in message #3, and you appear to be missing pin #0 also being CS1 and pin #1 also being MISO1. I compared it to the pinout listed in article 1917. Unfortunately since it would add another column on the ground, pins 0-12 side, it might be problematical to add.

Obviously since the first printing has been done, we will need to live with it, but it would be helpful to eventually change the online image and when you do a second printing, update it then.
 
Somebody else may have mentioned this, but just in case....

Paul, I was looking at the printed card, as well as the card image in message #3, and you appear to be missing pin #0 also being CS1 and pin #1 also being MISO1. I compared it to the pinout listed in article 1917. Unfortunately since it would add another column on the ground, pins 0-12 side, it might be problematical to add.

Obviously since the first printing has been done, we will need to live with it, but it would be helpful to eventually change the online image and when you do a second printing, update it then.

Yep: https://forum.pjrc.com/threads/54711-Teensy-4-0-First-Beta-Test?p=209852&viewfull=1#post209852
But does not hurt to remind..

Also thought about adding something to #4 or #6 message about it, but have not yet.
 
I was successful to use olikraus' U8G2_Arduino library with Teensy 4.0 for an i2c 128x32 SSD1306 OLED display.
I used these settings for i2c port 0:
Code:
U8G2_SSD1306_128X32_UNIVISION_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ 19, /* data=*/ 18, /* reset=*/ U8X8_PIN_NONE);
The font looks nicer but it is much slower than the Adafruit SSD1306 library with a simple integer counter application.
 
Last edited:
Status
Not open for further replies.
Back
Top