Hi all,
For some background on this:
I have made some backpacks for Adafruit Trinket M0, Feather M9 and ItsyBitsy M0. I was successful in modifying the variant.h and vatiant.cpp files to tweak some of the pin mapping to allow me to get 4 (trinket M0) and 8 (feather and ItsyBitsy M0) independent PWM channels. I then re-worked the analogWrite() funtion to be fastAnalogWrite() so I could have higher resolution at higher frequencies. This was successful with all the M0 chips I've used and even created a custom board based on the trinket M0's SAMD21E18A chip.
So where I am at now:
Since the ItsyBitsy had an M4 variant I thought why not use the existing backpack for the M0 variant and see if I can do the same with a SAMD51 chip. I modified the variant.h and variant.cpp files (could only get 6 PWM without reworking the backpack but to some minor timer pin changes). I am also now updating my fastAnalogWrite() function to update the correct registers on the SAMD51. I have had luck with 5 of the PWM channels but am banging my head against the wall with the 6th. I don't know if I am missing something, but here what I have so far.
I am using the following pin/time combo:
PA18 TCC0/WO[6]
PA19 TCC1/WO[3]
PA21 TCC0/WO[1]
PA22 TCC1/WO[6]
PA23 TCC0/WO[3]
PA30 TCC2/WO[0]
I can get all working except for PA18 TCC0/WO[6]. I can toggle the pic on an doff so I know it's physically wired. The interesting thing is that PA22 happens to have an alternate TCC that is TCC0/WO[2] which is functionally the same TCC output. SO if I modify PA22 to use TCC2/WO[2] it works. And it works when I write to PA18 or PA22. But nothing happens on the PA18 pin. But writing to PA18 TCC0/WO[6] updates PA22 TCC0/WO[2]. So the code in theory is updating the registers properly and since it works with PA21 TCC0/WO[1] and PA23 TCC0/WO[3] it is working with the TCC0 timer module. I just can't figure out why I am not getting any PWM output on PA18 TCC0/WO[6]
variant.cpp definitions for above port/tccx
{ PORTA, 18, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH2, NOT_ON_TIMER, EXTERNAL_INT_2 }, // D7
{ PORTA, 19, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH3, TC3_CH1, EXTERNAL_INT_3 }, // D9
{ PORTA, 21, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH1, NOT_ON_TIMER, EXTERNAL_INT_5 }, // D11
{ PORTA, 22, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH2, NOT_ON_TIMER, EXTERNAL_INT_6 }, // D13
{ PORTA, 23, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH3, NOT_ON_TIMER, EXTERNAL_INT_7 }, // D12
fastAnalogWrite (SAMD51 TCCx section)
else {
// -- Configure TCC
if (showInit) Serial.print(" Configure TCC");
Tcc* TCCx = (Tcc*) GetTC(pinDesc.ulPWMChannel);
TCCx->CTRLA.bit.SWRST = 1;
while (TCCx->SYNCBUSY.bit.SWRST);
// Disable TCCx
TCCx->CTRLA.bit.ENABLE = 0;
while (TCCx->SYNCBUSY.bit.ENABLE);
// Set prescaler to 1/256
TCCx->CTRLA.reg = TCC_CTRLA_PRESCALER_DIV1 | TCC_CTRLA_PRESCSYNC_GCLK;
if (showInit) Serial.println(" TCC_CTRLA_PRESCALER_DIV1");
// Set TCCx as normal PWM
TCCx->WAVE.reg = TCC_WAVE_WAVEGEN_NPWM;
while ( TCCx->SYNCBUSY.bit.WAVE );
while (TCCx->SYNCBUSY.bit.CC0 || TCCx->SYNCBUSY.bit.CC1);
// Set the initial value
TCCx->CC[tcChannel].reg = (uint16_t) dutyCycle;
while (TCCx->SYNCBUSY.bit.CC0 || TCCx->SYNCBUSY.bit.CC1);
// Set PER to required resolution (10, 12 or 13 bit)
TCCx->PER.reg = (uint16_t) pwmResolution;
while (TCCx->SYNCBUSY.bit.PER);
// Enable TCCx
TCCx->CTRLA.bit.ENABLE = 1;
while (TCCx->SYNCBUSY.bit.ENABLE);
}
Any help to point out something I may not be aware of or not thought to check. I have tried putting the PWM initialization code at the end of setup() to make sure nothing is overwriting the output configuration. I am at a loss as to why this particular pin is giving me grief. D7 (PA18) is not used for any SERCOM functions and is only defined in the variant files as a digital pin with PWM capability.
Thank you in advance.
Darren