Hi LeCrAm,
Here's an example of using timer TC4 in oneshot mode to generate an interrupt 5ms after the software trigger. To measure the "time to interrupt", the code uses GPIO to generate sets digital pin D7 HIGH prior to the retrigger and clears to LOW in the interrupt:
// Set timer TC4 to call the TC4_Handler 5ms after oneshot software re-trigger
void setup() {
PORT->Group[PORTA].DIRSET.reg = PORT_PA21; // Set D7 as a digital output
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | // Enable GCLK0
GCLK_CLKCTRL_GEN_GCLK0 | // Select GCLK0 at 48MHz
GCLK_CLKCTRL_ID_TC4_TC5; // Connecto to timers TC4 and TC5
NVIC_SetPriority(TC4_IRQn, 0); // Set the Nested Vector Interrupt Controller (NVIC) priority for TC4 to 0 (highest)
NVIC_EnableIRQ(TC4_IRQn); // Connect TC4 to Nested Vector Interrupt Controller (NVIC)
TC4->COUNT16.INTENSET.reg = TC_INTENSET_MC0; // Enable TC4 match conpare 0 (MC0) interrupt
TC4->COUNT16.CTRLBSET.reg = TC_CTRLBSET_ONESHOT; // Set the TC4 timer to Oneshot mode
while (TC4->COUNT16.STATUS.bit.SYNCBUSY); // Wait for synchronization
TC4->COUNT16.CC[0].reg = 29999; // Set timer TC4 to call the TC4_Handler after 5ms: (8 * (29999 + 1)) / 48MHz = 5ms
while (TC4->COUNT16.STATUS.bit.SYNCBUSY); // Wait for synchronization
TC4->COUNT16.CTRLA.reg = TC_CTRLA_PRESCSYNC_PRESC | // Reset timer on the next prescaler clock
TC_CTRLA_PRESCALER_DIV8; // Set prescaler to 8, 48MHz/8 = 6MHz
TC4->COUNT16.CTRLA.bit.ENABLE = 1; // Enable the TC4 timer
while (TC4->COUNT16.STATUS.bit.SYNCBUSY); // Wait for synchronization
}
void loop()
{
PORT->Group[PORTA].OUTSET.reg = PORT_PA21; // Set the D7 output to HIGH
TC4->COUNT16.CTRLBSET.reg = TC_CTRLBSET_CMD_RETRIGGER; // Retrigger the TC4 timer
while (TC4->COUNT16.STATUS.bit.SYNCBUSY); // Wait for synchronization
//delay(3); // Wait for 3 milliseconds to test if retriggering works before interrupt called
//TC4->COUNT16.CTRLBSET.reg = TC_CTRLBSET_CMD_RETRIGGER; // Retrigger the TC4 timer
//while (TC4->COUNT16.STATUS.bit.SYNCBUSY); // Wait for synchronization
delay(1000); // Wait for 1 second
}
void TC4_Handler() // Interrupt Service Routine (ISR) for timer TC4
{
TC4->COUNT16.INTFLAG.bit.MC0 = 1; // Clear the MC0 interrupt flag
PORT->Group[PORTA].OUTCLR.reg = PORT_PA21; // Clear the D7 output to LOW - should generate 5ms pulse output
}
Just to test the retriggering before the interrupt occurs, I added the commented out lines. This code waits for 3ms before initiating a second retrigger. As anticipated, this extends the pulse by a further 3ms (to 8ms), indicating that the second retrigger has indeed reset the timer.