Hi all,
i'm wanting to do 48-bit timing on a Teensy 4.0. The only way i can do that is to use the QUADTimers and cascade them. After testing the QUADTimers i was able to determine that they run at 150MHz and based on the largest value i will need to use i have decided to run the timer at a pre-scaler of 1 with 3 timer channels cascaded. See code below.
I've based my code on this post...
https://forum.pjrc.com/threads/61462...=cascade+timer
I've gotten the QTimer and it's ISR to run ok and i can get it to run for the lengths of time i need. The counter values being printed to the serial port all look good. The problem i am having is trying to figure out how to get a timer to activate an ISR at the right time. As you can see in the code below, i have a function named calcBinary(). This function is my way of trying to get the binary values for each timer to match a value of 9,000,000,000 clock ticks. This is just a test value within my expected range. The printout of the values for the 3 timers works fine (16-bits binary) and i get an accurate result that matches my own calculations. These binary values would be used for compare matching. The problem is that all 3 timer channels would then be compare matching and activating their interrupts when they get a match. I just want 1 of the 3 channels to activate an ISR.
So how do i go about doing that? I don't want to have any code in the loop() function as that would negate the point of running hardware timers in the first place. I want accuracy in the low nanoseconds. With a 150MHz timer clock i can get 6.67r nanoseconds per timer clock tick which is great. That will produce nice, stable and accurate square waves.
Does anyone (maybe manitou?) have a suggestion for me to figure out when a certain number of timer clock ticks have passed?
Any help is appreciated.
Also, what does the code below do?
Code:IMXRT_TMR_t * TMR4 = (IMXRT_TMR_t *)&IMXRT_TMR4; #define IRQ_QTIMERx IRQ_QTIMER4
CheersCode:#include <SPI.h> #include <elapsedMillis.h> IMXRT_TMR_t * TMR4 = (IMXRT_TMR_t *)&IMXRT_TMR4; #define IRQ_QTIMERx IRQ_QTIMER4 elapsedMillis freerunTimer; uint32_t timed = 0; uint16_t countTimeMillis = 0; uint16_t prevCountTimeMillis = 0; void my_isr() { TMR4->CH[1].CSCTRL &= ~(TMR_CSCTRL_TCF1); // clear countTimeMillis = freerunTimer; Serial.println("my_isr() CALLED !!!"); } void setup() { Serial.begin(115200); Serial.println("================="); Serial.println(" Teensy 4 Timers "); Serial.println("================="); // set up QuadTimer4 CCM_CCGR6 |= CCM_CCGR6_QTIMER4(CCM_CCGR_ON); // enable QTMR4 clock TMR4->CH[0].CTRL = 0; // stop TMR4->CH[1].CTRL = 0; // stop TMR4->CH[2].CTRL = 0; // stop TMR4->CH[0].CNTR = 0; // set count to 0 TMR4->CH[1].CNTR = 0; // set count to 0 TMR4->CH[2].CNTR = 0; // set count to 0 TMR4->CH[0].COMP1 = 0xffff; // send count signal to next counter on overflow at 0xffff TMR4->CH[1].COMP1 = 0xffff; // send count signal to next counter on overflow at 0xffff TMR4->CH[2].COMP1 = 0xffff; // send count signal to next counter on overflow at 0xffff TMR4->CH[0].CMPLD1 = 0xffff; TMR4->CH[1].CMPLD1 = 0xffff; TMR4->CH[2].CMPLD1 = 0xffff; TMR4->CH[2].CTRL = TMR_CTRL_CM (7); // Count Mode: Cascaded counter mode TMR4->CH[2].CTRL |= TMR_CTRL_PCS(5); // Primary Count Source: CH[1] output TMR4->CH[1].CTRL = TMR_CTRL_CM (7); // Count Mode: Cascaded counter mode TMR4->CH[1].CTRL |= TMR_CTRL_PCS(4); // Primary Count Source: CH[0] output TMR4->CH[0].CTRL = TMR_CTRL_CM (1); // Count Mode: Count rising edges of primary source TMR4->CH[0].CTRL |= TMR_CTRL_PCS(8); // Primary Count Source: IP bus clock divide by 1 prescaler attachInterruptVector(IRQ_QTIMERx, my_isr); TMR4->CH[1].CSCTRL &= ~(TMR_CSCTRL_TCF1); // clear TMR4->CH[1].CSCTRL |= TMR_CSCTRL_TCF1EN; // enable interrupt NVIC_ENABLE_IRQ(IRQ_QTIMERx); calcBinary(); freerunTimer = 0; } void calcBinary() { uint64_t thisNumber = 9000000000; uint16_t timer1Number = thisNumber; uint16_t timer2Number = thisNumber >> 16; uint16_t timer3Number = thisNumber >> 32; Serial.print("timer1Number = "); Serial.print(timer1Number); Serial.print(", "); Serial.println(timer1Number, BIN); Serial.print("timer2Number = "); Serial.print(timer2Number); Serial.print(", "); Serial.println(timer2Number, BIN); Serial.print("timer3Number = "); Serial.print(timer3Number); Serial.print(", "); Serial.println(timer3Number, BIN); } void loop() { if (countTimeMillis != prevCountTimeMillis) { Serial.println("TMR4->CH[1] OVERFLOW "); Serial.print("countTimeMillis = "); Serial.println(countTimeMillis); prevCountTimeMillis = countTimeMillis; } Serial.println(TMR4->CH[0].CNTR); Serial.println(TMR4->CH[1].CNTR); Serial.println(TMR4->CH[2].CNTR); Serial.println(); delay(200); }
NM