Hi,
I'm trying to generate the attached waveforms repeatedly.
GCLK5 is 2MHz and CC0 = 9 for period of 10usec in NFRQ.
To disable CC2 from altering I write it with value higher than CC1 but write not alwas succeed and the CC2 waveform is inverted every few seconds randomaly.
The write to CC2 is triggered by MC0 interrupt at CC0 = 5 and should complete before double buffer update at CC0 = 9.
I tried without success:
- Lower frequency using higher GCLK divider values or TCC period.
- Similar approach in NPWM and DSTOP.
- Disable double buffering in TCC0 initialization:
REG_TCC0_CTRLBSET = TCC_CTRLBSET_LUPD;
while (TCC0->SYNCBUSY.bit.CTRLB);
Thank you in advance for helping.
This is GCLK5:
REG_GCLK_GENDIV = GCLK_GENDIV_DIV(24) | // Set the clock divisor
GCLK_GENDIV_ID(5); // Set the clock generator ID to 5
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for the bus to synchronise
// Connect the 48MHz clock source to generic clock generator 5 and enable its outputs
REG_GCLK_GENCTRL = GCLK_GENCTRL_OE | // Enable the generic clock 5's outputs
GCLK_GENCTRL_IDC | // Ensure the duty cycle is about 50-50 high-low
GCLK_GENCTRL_GENEN | // Enable the clock generator 5
GCLK_GENCTRL_SRC_DFLL48M | // Set source to be 48MHz clock Note: for 8MHz source use GCLK_GENCTRL_SRC_OSC8M
GCLK_GENCTRL_ID(5); // Set the clock generator ID to 5
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for the bus to synchronise
This is TCC0:
// Feed GCLK5 to TCC0 and TCC1
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | // Enable the generic clock
GCLK_CLKCTRL_GEN_GCLK5 | // on GCLK5
GCLK_CLKCTRL_ID_TCC0_TCC1; // Feed the GCLK5 to TCC0 and TCC1
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
REG_TCC0_WAVE |= TCC_WAVE_WAVEGEN_NFRQ | // Setup normal frequency - toggle between 0 and top
TCC_WAVE_POL2; // invert cc2
while (TCC0->SYNCBUSY.bit.WAVE); // Wait for synchronization
REG_TCC0_PER = 9; // TCC0 period
while (TCC0->SYNCBUSY.bit.PER); // Wait for synchronization
REG_TCC0_CC0 = 5; // TCC0 CC0 - D23/PB10/WO[4]
while (TCC0->SYNCBUSY.bit.CC0); // Wait for synchronization
REG_TCC0_CC2 = 10; // TCC0 CC2 - D23/PA12/WO[6]
while (TCC0->SYNCBUSY.bit.CC2); // Wait for synchronization
// map tcc0 to port PB10
PORT->Group[g_APinDescription[23].ulPort].PINCFG[g_APinDescription[23].ulPin].bit.PMUXEN = 1;
PORT->Group[g_APinDescription[23].ulPort].PMUX[g_APinDescription[23].ulPin >> 1].reg |= PORT_PMUX_PMUXE_F; // even
// map tcc0 to port PA12
PORT->Group[g_APinDescription[22].ulPort].PINCFG[g_APinDescription[22].ulPin].bit.PMUXEN = 1;
PORT->Group[g_APinDescription[22].ulPort].PMUX[g_APinDescription[22].ulPin >> 1].reg |= PORT_PMUX_PMUXE_F; // even
// enable tcc0
REG_TCC0_CTRLA |= TCC_CTRLA_PRESCALER_DIV1 | // Set prescaler to 1
TCC_CTRLA_ENABLE; // Enable TCC0
while (TCC0->SYNCBUSY.bit.ENABLE); // Wait for synchronization
REG_TCC0_INTENSET = TCC_INTENSET_MC0; // Enable compare channel 0 (CC0) interrupt
NVIC_SetPriority(TCC0_IRQn, 0); // Set the Nested Vector Interrupt Controller (NVIC) priority for TCC0 to 0 (highest)
NVIC_EnableIRQ(TCC0_IRQn); // Connect the TCC0 timer to the Nested Vector Interrupt Controller (NVIC)
This is the interrupt handler:
void TCC0_Handler() {
volatile static int cnt = 0;
REG_TCC0_INTFLAG = TCC_INTENSET_MC0; // clear interrupt
switch(cnt) {
case 0: REG_TCC0_CC2 = 4;
break;
case 1: REG_TCC0_CC2 = 10;
break;
case 2: REG_TCC0_CC2 = 4;
break;
case 3: REG_TCC0_CC2 = 10;
break;
}
if(cnt++>20)
cnt = 0;
}
Thank you.