Well my brain is fried trying to get this to work.
I have a MKRZero that I am trying to use the PPW Capture feature for the TC so I can measure the frequency and pulse width. The test signal I am trying to read is a 40ms period and 24ms width on digital pin 0.
I know the counter works cause COUNT seems to show a 1 usec rate.
It is constantly triggering the overflow interrupt, and CC0 and CC1 always read 0.
void tc4Configure(){
//counter clock is defined in GCLKConfigure()
//Serial.println("tc4Configure...");
tc4Reset();
//Port I/O Configuration for TC4
//Port PA22
PORT->Group[PORTA].CTRL.reg |= PORT_CTRL_SAMPLING(22); //Continous sampling of PA22 enabled
PORT->Group[PORTA].DIRCLR.reg |= PORT_DIRCLR_DIRCLR(22); //Configure PA22 as input
PORT->Group[PORTA].PMUX[22].reg |= PORT_PMUX_PMUXE_E; //Configurre PA22 to peripheral E (TC)
PORT->Group[PORTA].PINCFG[22].reg |= PORT_PINCFG_PMUXEN; //perpheral multiplexer enabled
//PM Configuration for TC4 and PPW
//turn on clock for TC4
PM->APBCMASK.reg |= PM_APBCMASK_TC4
| PM_APBCMASK_EVSYS;
//set tc4 to 16bits, prescaler 8, enable catpure on channel 0 and 1, not in inverted mode,
TC4->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16
| TC_CTRLA_PRESCALER_DIV8;
while(TC4->COUNT16.STATUS.bit.SYNCBUSY);
//both capture channels must be enabled to record period and pulse width
//TC4->COUNT16.READREQ |= TC_READREQ_RREQ
// | TC_READREQ_ADDR(0x06);
while(TC4->COUNT16.STATUS.bit.SYNCBUSY);
TC4->COUNT16.CTRLC.reg |= TC_CTRLC_CPTEN0
| TC_CTRLC_CPTEN1;
while(TC4->COUNT16.STATUS.bit.SYNCBUSY);
//enabled capture channel 0 and input event
TC4->COUNT16.EVCTRL.reg |= TC_EVCTRL_EVACT_PPW //PERIOD IN CC0, PULSE WIDTH IN CC1
| TC_EVCTRL_TCEI
| TC_EVCTRL_MCEO0
| TC_EVCTRL_MCEO1;
//enable interrupts for channel 0 and 1 capture, capture overflow errors
TC4->COUNT16.INTENSET.reg |= TC_INTENSET_MC0
| TC_INTENSET_MC1
| TC_INTENSET_OVF
| TC_INTENSET_ERR;
//There might be some work needed with EVSYS config
REG_EIC_EVCTRL |= EIC_EVCTRL_EXTINTEO6; //Enable event output on external interrupt 6
attachInterrupt(0, NULL, HIGH); //Attach interrupts to digital pin 0 (external interrupt 6)
REG_EVSYS_USER = EVSYS_USER_CHANNEL(1) //Attach the event user (receiver) to channel 0 (n+1)
| EVSYS_USER_USER(EVSYS_ID_USER_TC4_EVU); //Set the event user (receiver) as timer TC3
REG_EVSYS_CHANNEL = EVSYS_CHANNEL_EDGSEL_NO_EVT_OUTPUT //No event edge detection
| EVSYS_CHANNEL_PATH_ASYNCHRONOUS //Set event path as asynchronous
| EVSYS_CHANNEL_EVGEN(EVSYS_ID_GEN_EIC_EXTINT_6) //Set event generator (sender) as external interrupt 6
| EVSYS_CHANNEL_CHANNEL(0); //Attach the generator (sender) to channel 0
//enable timer
TC4->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE;
while(TC4->COUNT16.STATUS.bit.SYNCBUSY);
NVIC_SetPriority(TC4_IRQn, 4);
NVIC_EnableIRQ(TC4_IRQn);
Serial.println("Done with TC4Configure");
void loop() {
// put your main code here, to run repeatedly:
//Serial.println("loop");
uint16_t val = TC4->COUNT16.COUNT.reg;
uint16_t period = TC4->COUNT16.CC[1].reg;
uint16_t width = TC4->COUNT16.CC[0].reg;
Serial.print("Period: ");
Serial.println(period);
Serial.print("Width: ");
Serial.println(width);
Serial.print("State:");
Serial.println(digitalRead(0));
//val = TC5->COUNT16.COUNT.reg;
//Serial.print("TC5 Count:");
//Serial.println(val);
delay(1000);
}
}
[Ign and Inj Timing.ino|attachment](upload://cJD5RB6lDUzHznA5K5fQ6mr4HQe.ino) (6.3 KB)