hi everyone,
I'm trying to use TCC2 timer to generate an interrupt, but compiling this sketch I get this error:
test:36:20: error: 'TCC2_IRQn' was not declared in this scope; did you mean 'TC2_IRQn'?
36 | NVIC_SetPriority(TCC2_IRQn, 0);
| ^~~~~~~~~
| TC2_IRQn
exit status 1
'TCC2_IRQn' was not declared in this scope; did you mean 'TC2_IRQn'?
this is the sketch:
void setup() {
MCLK->APBBMASK.reg |= MCLK_APBCMASK_TC4;
GCLK->GENCTRL[7].reg = GCLK_GENCTRL_DIV(1) | GCLK_GENCTRL_IDC | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL;
while (GCLK->SYNCBUSY.bit.GENCTRL7);
GCLK->GENCTRL[6].reg = GCLK_GENCTRL_DIV(1) | GCLK_GENCTRL_IDC | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL;
while (GCLK->SYNCBUSY.bit.GENCTRL6);
GCLK->PCHCTRL[30].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK6;
GCLK->PCHCTRL[29].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK7;
TCC2->CTRLA.reg = TC_CTRLA_PRESCALER_DIV8 | TC_CTRLA_PRESCSYNC_PRESC;
TCC2->WAVE.reg = TC_WAVE_WAVEGEN_NPWM;
while (TCC2->SYNCBUSY.bit.WAVE);
TCC2->PER.reg = 6818;
while (TCC2->SYNCBUSY.bit.PER);
TCC2->CC[0].reg = 3409;
while (TCC2->SYNCBUSY.bit.CC0);
TCC2->CTRLA.bit.ENABLE = 1;
while (TCC2->SYNCBUSY.bit.ENABLE);
TC4->COUNT16.CTRLA.reg = TC_CTRLA_PRESCALER_DIV16 | TC_CTRLA_PRESCSYNC_PRESC | TC_CTRLA_MODE_COUNT16;
TC4->COUNT16.WAVE.reg = TC_WAVE_WAVEGEN_MPWM;
TC4->COUNT16.CC[0].reg = 264;
while (TC4->COUNT16.SYNCBUSY.bit.CC0);
TC4->COUNT16.CC[1].reg = 132;
while (TC4->COUNT16.SYNCBUSY.bit.CC1);
TC4->COUNT16.INTENSET.bit.MC0 = 0x1;
TC4->COUNT16.CTRLA.bit.ENABLE = 1;
while (TC4->COUNT16.SYNCBUSY.bit.ENABLE);
void __disable_irq(void);
NVIC_SetPriority(TCC2_IRQn, 0);
NVIC_EnableIRQ(TCC2_IRQn);
TCC2->INTENSET.reg |= TCC_INTENSET_OVF;
NVIC_SetPriority(TC4_IRQn, 0);
NVIC_EnableIRQ(TC4_IRQn);
void __enable_irq(void);
}
void TC4_Handler(void) {
//do something here
TC4->COUNT16.INTFLAG.reg |= 0b00010000;
}
void TCC2_Handler(void) {
//do something here
TCC2->INTFLAG.bit.OVF = 1;
}
void loop() {
}
if I remove that two lines, the rest of the sketch compiles correctly, and I can use TC4, but not TCC2.
Do you know what the issue could be?
the board I'm using is Adafruit Hallowing M4 (SAMD51)
thank you
Looking through the SAMD51 headers, I noticed the following:
TCC2_0_IRQn = 97, /**< 97 SAMD51G19A Timer Counter Control 2 (TCC2): TCC2_CNT_A, TCC2_DFS_A, TCC2_ERR_A, TCC2_FAULT0_A, TCC2_FAULT1_A, TCC2_FAULTA_A, TCC2_FAULTB_A, TCC2_OVF, TCC2_TRG, TCC2_UFS_A */
TCC2_1_IRQn = 98, /**< 98 SAMD51G19A Timer Counter Control 2 (TCC2): TCC2_MC_0 */
TCC2_2_IRQn = 99, /**< 99 SAMD51G19A Timer Counter Control 2 (TCC2): TCC2_MC_1 */
TCC2_3_IRQn = 100, /**< 100 SAMD51G19A Timer Counter Control 2 (TCC2): TCC2_MC_2 */
TC0_IRQn = 107, /**< 107 SAMD51G19A Basic Timer Counter 0 (TC0) */
TC1_IRQn = 108, /**< 108 SAMD51G19A Basic Timer Counter 1 (TC1) */
whereas in the SAMD21 headers, it's just:
TCC2_IRQn = 19, /**< 19 SAMC21E18A Timer Counter Control 2 (TCC2) */
TC0_IRQn = 20, /**< 20 SAMC21E18A Basic Timer Counter 0 (TC0) */
TC1_IRQn = 21, /**< 21 SAMC21E18A Basic Timer Counter 1 (TC1) */
westfw
March 17, 2024, 8:21am
3
Looking through the SAMD51 headers, I noticed the following:
TCC2_0_IRQn = 97, /**< 97 SAMD51G19A Timer Counter Control 2 (TCC2): TCC2_CNT_A, TCC2_DFS_A, TCC2_ERR_A, TCC2_FAULT0_A, TCC2_FAULT1_A, TCC2_FAULTA_A, TCC2_FAULTB_A, TCC2_OVF, TCC2_TRG, TCC2_UFS_A */
TCC2_1_IRQn = 98, /**< 98 SAMD51G19A Timer Counter Control 2 (TCC2): TCC2_MC_0 */
TCC2_2_IRQn = 99, /**< 99 SAMD51G19A Timer Counter Control 2 (TCC2): TCC2_MC_1 */
TCC2_3_IRQn = 100, /**< 100 SAMD51G19A Timer Counter Control 2 (TCC2): TCC2_MC_2 */
The Cortex M4 CPU allows many more interrupt vectors than an M0, and Atmel took advantage of this on the SAMD51 by having some of the peripherals be capable of generating more than one interrupt, depending on cause, whereas on an M0 you'd have to put up with a single interrupt and decode the details in your ISR.
I guess the TCC timers are one of those peripherals. (The other example that shows up a lot is the SERCOM UARTS, which now have separate vectors for RX and TX and (other).)
The mapping is described in the datahsheet section describing the NVIC
thank you both,
this is the fixed/working sketch.
I have a question,
in the sketch TC4 is handling the DAC output, based on the value/frequency of TCC2.
Obviously TC4 is running at much higher frequency that TCC2.
Is there a way to "read" the TCC2 frequency/status inside TC4 handler, without having to use a handler for TCC2 and to toggle a volatile variable, like I'm doing right now, and achieving the same result?
Of course this sketch isn't doing any useful thing right now, I'm just using it to familiarise with those concepts.
Thanks
#define DAC0 14
volatile boolean tcc2flag = false;
void setup() {
/* test DAC */
pinMode(DAC0, OUTPUT);
DAC->DACCTRL[0].bit.CCTRL = 1;
analogWriteResolution(12);
analogWrite(DAC0, 0);
MCLK->APBBMASK.reg |= MCLK_APBCMASK_TC4;
GCLK->GENCTRL[7].reg = GCLK_GENCTRL_DIV(1) | GCLK_GENCTRL_IDC | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL;
while (GCLK->SYNCBUSY.bit.GENCTRL7);
GCLK->GENCTRL[6].reg = GCLK_GENCTRL_DIV(1) | GCLK_GENCTRL_IDC | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL;
while (GCLK->SYNCBUSY.bit.GENCTRL6);
GCLK->PCHCTRL[30].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK6;
GCLK->PCHCTRL[29].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK7;
TCC2->CTRLA.reg = TC_CTRLA_PRESCALER_DIV8 | TC_CTRLA_PRESCSYNC_PRESC;
TCC2->WAVE.reg = TC_WAVE_WAVEGEN_NPWM;
while (TCC2->SYNCBUSY.bit.WAVE);
TCC2->PER.reg = 6800;
while (TCC2->SYNCBUSY.bit.PER);
TCC2->CC[0].reg = 3400;
while (TCC2->SYNCBUSY.bit.CC0);
TCC2->CTRLA.bit.ENABLE = 1;
while (TCC2->SYNCBUSY.bit.ENABLE);
TC4->COUNT16.CTRLA.reg = TC_CTRLA_PRESCALER_DIV16 | TC_CTRLA_PRESCSYNC_PRESC | TC_CTRLA_MODE_COUNT16;
TC4->COUNT16.WAVE.reg = TC_WAVE_WAVEGEN_MPWM;
TC4->COUNT16.CC[0].reg = 60;
while (TC4->COUNT16.SYNCBUSY.bit.CC0);
TC4->COUNT16.CC[1].reg = 30;
while (TC4->COUNT16.SYNCBUSY.bit.CC1);
TC4->COUNT16.INTENSET.bit.MC0 = 0x1;
TC4->COUNT16.CTRLA.bit.ENABLE = 1;
while (TC4->COUNT16.SYNCBUSY.bit.ENABLE);
void __disable_irq(void);
NVIC_SetPriority(TCC2_1_IRQn, 0);
NVIC_EnableIRQ(TCC2_1_IRQn);
TCC2->INTENSET.bit.MC0 = 1;
while (TCC2->SYNCBUSY.reg > 0);
NVIC_SetPriority(TC4_IRQn, 0);
NVIC_EnableIRQ(TC4_IRQn);
void __enable_irq(void);
}
void TC4_Handler(void) {
TC4->COUNT16.INTFLAG.reg |= 0b00010000;
analogWrite(DAC0, 4095*tcc2flag);
}
void TCC2_1_Handler(void) {
TCC2->INTFLAG.bit.MC0 = 1;
tcc2flag = !tcc2flag;
}
void loop() {
}
system
Closed
September 13, 2024, 8:57pm
5
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.