Hello,
I am generating PWM using analogWrite and would like to count the number of ticks using Quad Timer Capture.
So far, I cascaded TMR1 and TMR2 channels to extend it to 32bits. Using PIT and an interval of 1s, the system evaluates the counts and raises a flag to put it on serial in the main loop.
The code was tested by wiring the output of the analogwrite (pin 8) to the input of the quadtimer (pin9) using a jumper. Everything is working fine so far.
Next, I would like to use XBAR to replace the jumper wire between pin 8 and pin9 and instead connect PWM output to the input to the Quad Timer in software, using XBAR.
I guess this should be possible, but I don't know how to set it up.
Any advice?
Here is the code I have so far:
I am generating PWM using analogWrite and would like to count the number of ticks using Quad Timer Capture.
So far, I cascaded TMR1 and TMR2 channels to extend it to 32bits. Using PIT and an interval of 1s, the system evaluates the counts and raises a flag to put it on serial in the main loop.
The code was tested by wiring the output of the analogwrite (pin 8) to the input of the quadtimer (pin9) using a jumper. Everything is working fine so far.
Next, I would like to use XBAR to replace the jumper wire between pin 8 and pin9 and instead connect PWM output to the input to the Quad Timer in software, using XBAR.
I guess this should be possible, but I don't know how to set it up.
Any advice?
Here is the code I have so far:
Code:
// this code counts ticks from external pin with QTIMER4 chnl 2 pin 9 GPIO_B0_11
// test with PWM on pin 8 jumper to 9
#define PRREG(x) Serial.print(#x" 0x"); Serial.println(x,HEX)
IMXRT_TMR_t * TMRx = (IMXRT_TMR_t *)&IMXRT_TMR4;
uint32_t prev1,prev2;
IntervalTimer it1;
volatile uint32_t ticks12, dataReady;
int i=0;
// This is the interrupt handlign routine,called by PIT on a// regular interval.it calculates the counter value (here TMR1 and TMR2 are cascaded to 32 bit value)
// and raises the flag to be read in the main loop
void it1cb() {
ticks12=TMRx->CH[1].CNTR | TMRx->CH[2].CNTR<<16; //cascaded 1 and 2 for 32bit coutners!
dataReady = 1;
}
void setup() {
int cnt;
Serial.begin(9600); //sets up the serial communication
while (!Serial);
delay(1000);
//turn on the PWM ping using 5khz frequency
analogWriteFrequency(8, 5000); // test jumper 8 to 9, max 75mhz
analogWrite(8, 128); //set the PWM to 50%
//timer configuration
CCM_CCGR6 |= CCM_CCGR6_QTIMER4(CCM_CCGR_ON); //enable QTMR4
IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_11 = 1; // QT4 Timer2 on pin 9
cnt = 65536 ; // full cycle
TMRx->CH[1].CTRL = 0; // stop
TMRx->CH[1].CNTR = 0; // set count to 0
TMRx->CH[1].LOAD = 0; // start val after compare
TMRx->CH[1].COMP1 = cnt - 1; // count up to this val and start again
TMRx->CH[1].CMPLD1 = cnt - 1;
TMRx->CH[1].SCTRL = 0 ; // enable oflow interrupt
TMRx->CH[2].CTRL = 0; // stop
TMRx->CH[2].CNTR = 0; // set count to 0
TMRx->CH[2].LOAD = 0; // start val after compare
TMRx->CH[2].COMP1 = cnt - 1; // count up to this val and start again
TMRx->CH[2].CMPLD1 = cnt - 1;
TMRx->CH[2].SCTRL = 0 ; // enable oflow interrupt
// control
TMRx->CH[1].CTRL |= TMR_CTRL_CM(1); // count mode: count rising edges of primary source
TMRx->CH[1].CTRL |= TMR_CTRL_PCS(2); // primary count source counter 2 input pin
TMRx->CH[2].CTRL = TMR_CTRL_CM(7); // Count Mode: Cascaded counter mode
TMRx->CH[2].CTRL |= TMR_CTRL_PCS(5); //Primary Count Source: CH[1] output
it1.begin(it1cb, 1000000); // 1s interval
}
void loop() {
if (dataReady) {
i = i + 1;
Serial.print("ticks: ");
Serial.println(ticks12);
dataReady = 0;
//just for fun, turn the counting direction every 30s.
if (i > 30){
i = 0;
Serial.println("Changed counting direction");
TMRx->CH[1].CTRL ^= TMR_CTRL_DIR; // change the direction of the counting
TMRx->CH[2].CTRL ^= TMR_CTRL_DIR; // change the direction of the
}
}
}
Last edited: