Doing something simple wrong here...
Code below essentially sets up single phase PWM and when there is a match, enables a signal on pin 6. There is commented out code, that allows pin 5 to be used as well. All worked.
I changed the code so that instead of using a match/compare to set pin 5, I tried to output a HIGH/LOW signal on the pin from within the ISR. This did not work.
I 'fixed' it by setting up the pin by calling pinMode(5, OUTPUT) first, which is OK, but I thought setting up the pins and peripherals in the code below did that. I don't understand why a match/compare can toggle the pin to generate a signal but I cannot do it directly from code by calling digitalWrite.
Code follows:
unsigned long CPUTime;
unsigned long CPUSpeed = F_CPU;
unsigned int mytest = 0;
#define ledPin 13
void setup()
{
//************************************** Clock Setting ********************************************************//
// Feed GCLK0 at 48MHz to TCC0 and TCC1
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | // Enable GCLK0 as a clock source
GCLK_CLKCTRL_GEN_GCLK0 | // Select GCLK0 at 48MHz
GCLK_GENDIV_DIV(3) | // Divide clock by 3 yielding 16Mhz
GCLK_CLKCTRL_ID_TCC0_TCC1; // Route GCLK0 to TCC0 and TCC1
//************************************** PORT Enabling ********************************************************//
//I thought the code immediately below also setup the pins for OUTPUT...
// Enable the port multiplexer for pins D6
PORT->Group[g_APinDescription[6].ulPort].PINCFG[g_APinDescription[6].ulPin].bit.PMUXEN = 1;
PORT->Group[g_APinDescription[5].ulPort].PINCFG[g_APinDescription[5].ulPin].bit.PMUXEN = 1;
// D6 is on EVEN port pin PA04, D5 is on the odd port of E
PORT->Group[g_APinDescription[6].ulPort].PMUX[g_APinDescription[6].ulPin >> 1].reg = PORT_PMUX_PMUXO_E | PORT_PMUX_PMUXE_E;
//************************************** TIMER Setting ********************************************************//
//Fast PWM
REG_TCC0_WAVE = TCC_WAVE_WAVEGEN_NPWM | TCC_WAVE_POL0 | TCC_WAVE_POL1 ; // Setup dual slope PWM on TCC0, inverting signal
while (TCC0->SYNCBUSY.bit.WAVE); // Wait for synchronization
REG_TCC0_CTRLA |= TCC_CTRLA_PRESCALER_DIV16; // Divide timer clock by 16, yielding 1MHz.
REG_TCC0_PER = 1000000; // PER = 1M; this equals 1 second / 1Hz
while (TCC0->SYNCBUSY.bit.PER); // Wait for synchronization
//CC0 aligns to pin 6
REG_TCC0_CC0 = REG_TCC0_PER / 2; // TCC0 CC0 - 50% duty cycle - 1/2 second
while (TCC0->SYNCBUSY.bit.CC0); // Wait for synchronization
//CC1 aligns to pin 5
//REG_TCC0_CC1 = 150000; // TCC0 CC1 - 65% duty cycle
//while (TCC0->SYNCBUSY.bit.CC1); // Wait for synchronization
TCC0->INTENSET.reg = 0; // disable all interrupts
TCC0->INTENSET.bit.OVF = 1; // enable overfollow
// Enable InterruptVector
NVIC_EnableIRQ(TCC0_IRQn);
TCC0->CTRLA.bit.ENABLE = 1; // Enable the TCC0 counter
while (TCC0->SYNCBUSY.bit.ENABLE); // Wait for synchronization
//I added this code and now Pin 5 can be set HIGH/LOW
pinMode(ledPin, OUTPUT);
pinMode(5, OUTPUT);
digitalWrite(ledPin, LOW);
digitalWrite(5, LOW);
Serial.begin(115200);
while (!Serial);
Serial.println("Starting...");
}
void loop()
{
static long InterruptCount = 1000000;
static bool first = true;
if (first)
{
Serial.print("\nCPU Speed: ");
Serial.println(CPUSpeed);
Serial.print("Ticks in period: ");
Serial.println(REG_TCC0_PER); //Ticks in the period
Serial.print("Ticks level when CC0 is toggled: ");
Serial.println(REG_TCC0_CC0); //Ticks when port is toggled
Serial.print("Ticks level when CC1 is toggled: ");
Serial.println(REG_TCC0_CC1); //Ticks when port is toggled
Serial.print("Sizeof CC0: ");
Serial.println(sizeof(REG_TCC0_CC0));
first = false;
}
InterruptCount++;
if (InterruptCount >= 1000000)
{
InterruptCount = 1;
first = true;
}
}
void TCC0_Handler()
{
Tcc* TC = (Tcc*) TCC0; // get timer struct
static bool bVal = false;
Serial.println("TCC0 Handler");
if (TC->INTFLAG.bit.OVF == 1) // An overflow caused the interrupt
{
Serial.println("OVF");
TC->INTFLAG.bit.OVF = 1; // writing a one clears the flag ovf flag
if (bVal)
{
Serial.println("HIGH");
digitalWrite(5, HIGH);
digitalWrite(ledPin, HIGH);
}
else
{
Serial.println("LOW");
digitalWrite(5, LOW);
digitalWrite(ledPin, LOW);
}
bVal = !bVal;
}
}