I am trying to send TCC0 to pins D0 and D1 for the Adafruit Feather M0 with a specific frequency of 40kHz using the 8Mhz internal oscillator. I have found a lot of code for setting up the Generic Clock from a MartinL in similar forum posts but I cannot seem to figure out why my code is not working. The main issue is that I am not great with code and trying to understand the port multiplexer and what the example code is doing is not proving to be easy. The following lines are the only lines that have direct correlation to the pins, and they deal with the port multiplexing:
// Enable the port multiplexer for the digital pin D0/PA11 (Left Forward)
PORT->Group[ PORTA ].PINCFG[ 11 ].bit.PMUXEN = 1;
PORT->Group[ PORTA ].PMUX[ 11 ].reg = PORT_PMUX_PMUXO_F | PORT_PMUX_PMUXE_F;
The only other instance I can see that there is any type of control is with the timers "control/capture" registers. The lines below set the PWM for supposedly D0/PA11 and P1/PA10 but I do not see what makes these line correlate with those specific pins, I have not been able to find a table with timers and their control/capture registers and what pins they are connected to.
// Initialize the PWM signal to output 50% duty cycle
TCC0->CC[2].reg = 50; // TCC0 CC2 - on D0/PA11
while (TCC0->SYNCBUSY.bit.CC2); //Wait for Synch
TCC0->CC[3].reg = 50; // TCC0 CC3 - on D1/PA10
while (TCC0->SYNCBUSY.bit.CC3); //Wait for Synch
In the above code it is given that for timer 0 the control/capture register number 2 is for D0 and CC3 is for D1. I'm not sure where this comes from, I will include my setup() code below, any and all help is extremely appreciated.
void setup() {
// Configure Generic Clock 4 to 8Mhz
GCLK->GENDIV.reg =
GCLK_GENDIV_ID(4) |
GCLK_GENDIV_DIV(1); // Keep 8MHz timing
while(GCLK->STATUS.bit.SYNCBUSY); //Wait for Synch
// Set up GCLK4 to use the internal 8MHz oscillator
GCLK->GENCTRL.reg =
GCLK_GENCTRL_IDC | // Duty Cycle set to 50/50 HIGH/LOW
GCLK_GENCTRL_GENEN;
GCLK_GENCTRL_SRC_OSC8M |
GCLK_GENCTRL_ID(4);
while(GCLK->STATUS.bit.SYNCBUSY); //Wait for Synch
// Enable the port multiplexer for the digital pin D0/PA11 (Left Forward)
PORT->Group[PORTA].PINCFG[11].bit.PMUXEN = 1;
// Enable the port multiplexer for the digital pin D1/PA10 (Left Backward)
PORT->Group[PORTA].PINCFG[10].bit.PMUXEN = 1;
//Send GCLK4 to TCC0
GCLK->CLKCTRL.reg =
GCLK_CLKCTRL_CLKEN | //Enable GCLK
GCLK_CLKCTRL_GEN_GCLK4 | //Select GCK4
GCLK_CLKCTRL_ID_TCC0_TCC1; //Send GCLK4 to TCC0
while(GCLK->STATUS.bit.SYNCBUSY); //Wait for Synch
//Set freq of PWM on TCC0 to 40kHz
//Freq = GCLK_Freq/(2*N*PER)
TCC0->PER.reg = 100;
while (TCC0->SYNCBUSY.bit.PER); //Wait for Synch
// Initialize the PWM signal to output 0% duty cycle
TCC0->CC[2].reg = 50; // TCC0 CC2 - on D0/PA11
while (TCC0->SYNCBUSY.bit.CC2); //Wait for Synch
TCC0->CC[3].reg = 50; // TCC0 CC3 - on D1/PA10
while (TCC0->SYNCBUSY.bit.CC3); //Wait for Synch
//Enable TCC0 output and keep the 48Mhz
TCC0->CTRLA.bit.ENABLE = 1; // Enable the TCC0 output
while (TCC0->SYNCBUSY.bit.ENABLE);
// Connect the TCC timers to the port outputs - port pins are paired odd PMUO and even PMUXE
// F & E specify the timers: TCC0 & TCC1
PORT->Group[PORTA].PMUX[11].reg = PORT_PMUX_PMUXO_F | PORT_PMUX_PMUXE_F;
PORT->Group[PORTA].PMUX[10].reg = PORT_PMUX_PMUXO_F | PORT_PMUX_PMUXE_F;