Issues with Trinket M0 D0 and D2 pins for PWM using TCC1

Adafruit's tiny microcontroller platform. Please tell us which board you are using.
For CircuitPython issues, ask in the Adafruit CircuitPython forum.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
n8ur
 
Posts: 16
Joined: Thu Apr 09, 2015 1:30 pm

Issues with Trinket M0 D0 and D2 pins for PWM using TCC1

Post by n8ur »

I've been working with PWM using the SAMD21 timer/counters and have found that two of the pins don't seem to work as they should. According to the SAMD21 data sheets, ports PA08 and PA09 , mapped to Trinket pins D0 and D2 respectively, should support both function E and function F to allow those pins to be mapped to either TCC0 or TCC1 respectively.

What I've found is that on both those pins only function E, for TCC0, works. Trying to initialize function F results in no PWM output and also seems to wedge the processor, requiring a reboot before allowing USB communications.

One thing I notice is that both these ports use higher values for the wo[] register -- 2 and 3 -- than the other pin mappings which work fine and all use 0 or 1 for wo[]. That may be just a red herring, but I thought it was interesting.

I'm wondering if the Trinket isn't setting these pins up to do something else that blocks function F.

Attached is some code showing this. Has anyone experienced this, or have any insight into it?

Thanks!

Code: Select all

/*
       The Trinket M0 has these pins, mapped to these timers: 
       Digital 0 PA08, SAMD pin 11, E=TCC0/W0[0], F=TCC1/WO[2]
       Digital 1 PA02, SAMD pin 3, no timers
       Digital 2 PA09, SAMD pin 12, E=TCC0/WO[1], F=TCC1/WO[3]
       Digital 3 PA07, SAMD pin 8, E=TCC1/WO[1], F= N/A
       Digital 4 PA06, SAMD pin 7, E=TCC1/WO[0], F= N/A
       Digital 13 (LED) PA10, SAMD pin 13, E=TCC1/WO[0], F = TCC0/WO[2]
*/


uint8_t map_d0_tcc1() {     // NOTE: this doesn't seem to work
    /* D0 is PA08 */
    /* Configure pin as output. */
    PORT->Group[0].DIRSET.reg = PORT_PA08;
    PORT->Group[0].OUTCLR.reg = PORT_PA08;  
    /* Enable the peripheral multiplexer. */
    PORT->Group[0].PINCFG[8].reg |= PORT_PINCFG_PMUXEN;
    /* Set PA08's function to function F -- TCC1/WO[2] 
     * Function E is TCC0/WO[0]. 
     * Because it's an even numbered pin the PMUX is E 
     * (even) and the PMUX index is pin number / 2, so 4.
     */
    PORT->Group[0].PMUX[4].reg = PORT_PMUX_PMUXE_F;
    return 2;
}


uint8_t map_d2_tcc1() {     // NOTE: this doesn't seem to work
    /* D2 is PA09 */
    /* Configure pin as output. */
    PORT->Group[0].DIRSET.reg = PORT_PA09;
    PORT->Group[0].OUTCLR.reg = PORT_PA09;  
    /* Enable the peripheral multiplexer. */
    PORT->Group[0].PINCFG[9].reg |= PORT_PINCFG_PMUXEN;
    /* Set PA09's function to function F. Function F is 
     * TCC1/WO[3] for PA09.  Function E is TCC0/WO[1]. 
     * Because it's an even numbered pin the PMUX is E 
     * (even) and the PMUX index is pin number / 2, so 4.
     */
    PORT->Group[0].PMUX[4].reg = PORT_PMUX_PMUXO_F;
    return 3;
}

void setup() {
    
PM->APBCMASK.reg |= PM_APBCMASK_TCC0 | PM_APBCMASK_TCC1;

GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN |
                    GCLK_CLKCTRL_GEN_GCLK1 |
                    GCLK_CLKCTRL_ID_TCC0_TCC1;
while (GCLK->STATUS.bit.SYNCBUSY) {};

TCC1->CTRLA.reg |= TCC_CTRLA_PRESCALER(TCC_CTRLA_PRESCALER_DIV16_Val);

TCC1->WAVE.reg = TCC_WAVE_WAVEGEN_NPWM;
while (TCC1->SYNCBUSY.bit.WAVE) {};

uint32_t period = 512;
TCC1->PER.reg = period;
while (TCC1->SYNCBUSY.bit.PER) {};

// functions return the wo[] register number
// that's needed to set the CC register to
// set the duty cycle
uint8_t w1 = map_d0_tcc1();     // doesn't work
//nt8_t w1 = map_d2_tcc1();     // doesn't work

TCC1->CC[w1].reg = period / 2;
while (TCC1->SYNCBUSY.bit.CC2) {};

TCC1->CTRLA.reg |= (TCC_CTRLA_ENABLE);
while (TCC1->SYNCBUSY.bit.ENABLE) {};
}

void loop() {
    // put your main code here, to run repeatedly:
    }

Locked
Please be positive and constructive with your questions and comments.

Return to “Trinket ATTiny, Trinket M0”