I am using an Adafruit Feather M0 RFM69 Packet Radio 433MHz, Part-No.3177 (AT-SAMD21-G18 ARM Cortex M0)
and I am pretty helpless with the TCC (Timer Counter for Control Applications). I have found some code-examples on internet but can't understand the effects of some codelines due to the lack of a reasonable manual or learning script. Maybe you have an idea, where to find one? (The following document didn't really help me: http://ww1.microchip.com/downloads/en/D ... T07058.pdf)
What I would like to do with my Controller is a Timer-Interrupt-Routine, within this I can change the time (Duration). I don't understand the difference respectively impact of the Interrupt between TCC1->CC[0].reg = 0xFFFFFF; and TCC1->PER.reg = 0xFFFFFF; TCC1 has no influence on the interrupt call!?
void setup()
{
//Divide the 48MHz system clock by 1 = 48MHz. Set division on Generic Clock Generator (GCLK) 4
GCLK->GENDIV.reg = GCLK_GENDIV_DIV(1) | GCLK_GENDIV_ID(4);
while (GCLK->STATUS.bit.SYNCBUSY);
//Set the duty cycle to 50/50 HIGH/LOW. Enable GCLK 4. Set the clock source to 48MHz. Set clock source on GCLK 4
GCLK->GENCTRL.reg = GCLK_GENCTRL_IDC | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(4);
while (GCLK->STATUS.bit.SYNCBUSY);
//Enable the generic clock on GCLK4. Feed the GCLK4 to TCC1 and TCC1
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK4 | GCLK_CLKCTRL_ID_TCC0_TCC1;
while (GCLK->STATUS.bit.SYNCBUSY);
//Set prescaler to 1, 48Mhz. Reload timer on next prescaler clock, use if prescaler DIV is more than 1
TCC1->CTRLA.reg = TC_CTRLA_PRESCSYNC_PRESC | TCC_CTRLA_PRESCALER_DIV1;
//Set the Nested Vector Interrupt Controller (NVIC) priority for TCC1 to 0 (highest)
NVIC_SetPriority(TCC1_IRQn, 0);
//Connect TCC1 to Nested Vector Interrupt Controller (NVIC)
NVIC_EnableIRQ(TCC1_IRQn);
//Enable TCC1 MC0-interrupt
TCC1->INTENSET.reg = TCC_INTENSET_MC0;
//Setup normal frequency operation on TCC1
TCC1->WAVE.reg |= TCC_WAVE_WAVEGEN_NFRQ;
while (TCC1->SYNCBUSY.bit.WAVE);
//Set the frequency of the timer
TCC1->PER.reg = 0xFFFFFF;
while(TCC1->SYNCBUSY.bit.PER);
//Set counter compare to 58usec
TCC1->CC[0].reg = 0xFFFFFF;
//TCC1->CC[0].reg = 0x000000;
while(TCC1->SYNCBUSY.bit.CC0);
//Enable timer TCC1
TCC1->CTRLA.bit.ENABLE = 1;
while (TCC1->SYNCBUSY.bit.ENABLE);
pinMode(5, OUTPUT);
}
void loop(){}
void TCC1_Handler() {
static boolean toggle = true;
if (TCC1->INTFLAG.bit.MC0) // Test if an MC0 interrupt has occured
{
TCC1->INTFLAG.bit.MC0 = 1; // Clear the interrupt flag
digitalWrite(5, toggle); // Toggle the LED test output
toggle = !toggle;
}
}
I am grateful for a hint (also for existing Manuals ;-)
void setup() //TCC1 Timer-Setup AT-SAMD21-G18 ARM Cortex M0
{
pinMode(LED_BUILTIN, OUTPUT);
//Divide 48MHz Systemclock by1 =48MHz. Set Division on GenericClockGenerator (GCLK) 4
GCLK->GENDIV.reg = GCLK_GENDIV_DIV(1) | GCLK_GENDIV_ID(4);
while (GCLK->STATUS.bit.SYNCBUSY);
//Set DutyCycle 50/50 HI/LO. Enable GCLK 4. Set ClockSource 48MHz. Set ClockSource GCLK 4
GCLK->GENCTRL.reg=GCLK_GENCTRL_IDC | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(4);
while (GCLK->STATUS.bit.SYNCBUSY);
//Enable the generic clock on GCLK4. Feed the GCLK4 to TCC1 and TCC1
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK4 | GCLK_CLKCTRL_ID_TCC0_TCC1;
while (GCLK->STATUS.bit.SYNCBUSY);
//Set prescaler to 1, 48Mhz. Enable TCC1
//Reload timer on next prescaler clock, use if prescaler DIV is more than
//TCC1->CTRLA.reg = TC_CTRLA_PRESCSYNC_PRESC | TCC_CTRLA_PRESCALER_DIV1;
//Set the Nested Vector Interrupt Controller (NVIC) priority for TCC1 to 0 (highest)
NVIC_SetPriority(TCC1_IRQn, 0);
//Connect TCC1 to Nested Vector Interrupt Controller (NVIC)
NVIC_EnableIRQ(TCC1_IRQn);
//Enable TCC1 OVF and MC0-Interrupt
TCC1->INTENSET.reg = TCC_INTENSET_OVF | TCC_INTENSET_MC0;
//Setup normal frequency operation on TCC1
TCC1->WAVE.reg |= TCC_WAVE_WAVEGEN_NFRQ;
while (TCC1->SYNCBUSY.bit.WAVE);
//Set the frequency of the timer
//Timer-Frequency = Generic-Clock-Frequency / (Timer-Prescaler * (Value-PER-Register + 1))
TCC1->PER.reg = 0xFFFFFF;
while(TCC1->SYNCBUSY.bit.PER);
//Set CounterCompare. Increasing Value of CC0-Register, increases the On-Time of the LED.
TCC1->CC[0].reg = 0x00056F;
while(TCC1->SYNCBUSY.bit.CC0);
//Enable timer TCC1 and wait for synchronization
TCC1->CTRLA.bit.ENABLE = 1;
while (TCC1->SYNCBUSY.bit.ENABLE);
}
//Timer TCC1 ISR. LED is cleared to LOW at the Beginning of the TimerCycle during an Overflow (OVF)
//and set to HIGH during a Match-Compare on channel 0 (MC0).
void TCC1_Handler()
{
if (TCC1->INTFLAG.bit.OVF) //Test if an OVF-Interrupt has occured
{
TCC1->INTFLAG.bit.OVF = 1; //Clear the Interrupt-Flag
digitalWrite(LED_BUILTIN, LOW); //Clear the LED-Output
}
if (TCC1->INTFLAG.bit.MC0) //Test if an MC0-Interrupt has occured
{
TCC1->INTFLAG.bit.MC0 = 1; //Clear the Interrupt-Flag
digitalWrite(LED_BUILTIN, HIGH); //Set the LED-Output
}
}
void loop() {}
I have a feather M4 Express board
I am looking to set up TCC0 W05 as a capture input
I was not getting the interrupt to trigger
looking at your code sample I forgot the NVIC Enable
when I added it I received a compile error on the NVIC lines
void setup() {
Ser.begin(9600);
Have a look in your ArduinoData-Directory:
e.g.:
Homedirectory->Documents->ArduinoData->adafruit->hardware->samd->Versionsnumber->bootloaders->mzero->Bootloader_D21->src->ASF->sam0->utils->cmsis->samd21->include
samd21xxx.h