Skip to content

SAMD21 TC3 & TC4 issue when using TCC2 #6261

Description

@spiderkeys

Ran into a bug in the pwm driver tonight that led to a bunch of odd observations; things working when they shouldn't be and the like. I'll break down everything the best I can.

What I did:
Created a new board that uses the SAMD21 CPU. Configured PWM0 to use TCC2. When pwm_init is called for PWM0, xtimer starts exhibiting very strange behavior and reports time elapsing much faster than it ought to. I commented out code in pwm_init until I narrowed it down to the GCLK configuration step in pwm_poweron(). I noticed here that it was enabling the clock ID for TCC0/TCC1 or TCC2/TC3 on GCLK0, whereas TC3, TC4, and TC5 are configured to use GCLK1 if you are running on the PLL. Added the following code and everything started working normally again:

    #if CLOCK_USE_PLL
        GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_CLKEN |
                            GCLK_CLKCTRL_GEN_GCLK1 |
                            GCLK_CLKCTRL_ID(_clk_id(dev)));
    #else
        GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_CLKEN |
                            GCLK_CLKCTRL_GEN_GCLK0 |
                            GCLK_CLKCTRL_ID(_clk_id(dev)));
    #endif
    
    while (GCLK->STATUS.bit.SYNCBUSY) {}

Observations of things working that maybe shouldn't:

  1. I have another custom board which is identical in all ways except that it doesn't use TCC2 and is configured to use TC3 for XTIMER. PWM somehow works without my above code which checks CLOCK_USE_PLL, despite the fact that the TCC0/TCC1 clocks are being enabled on GCLK0 instead of GCLK1.
  2. To my knowledge, TC4 is not in any way tied to TCC2. I know TC3 and TCC2 share the same clock ID, so I changed my XTIMER to point to TIMER_1 which is defined to use TC4. TC4 is configured by timer_init() to use GCLK1 as it is configured to use the PLL. Configuring the clock for TCC2 should not have affected TC4, and thus should not have affected xtimer_now() results in any way.

Any ideas?

Some additional details concerning my setup:

Hardware:
SAMD21J18A using an external oscillator to drive the PLL and give me a 48MHz clock (same clock configuration as the Arduino Zero board and Sodaq Autonomo board).

PWM configuration:

// PWM Configuration
#define PWM_0_EN            1
#define PWM_1_EN            1
#define PWM_MAX_CHANNELS    4

/* for compatibility with test application */
#define PWM_0_CHANNELS      PWM_MAX_CHANNELS
#define PWM_1_CHANNELS      PWM_MAX_CHANNELS

/* PWM device configuration */
static const pwm_conf_t pwm_config[] = 
{
#if PWM_0_EN
    {   TCC2, 
        {
            /* GPIO pin, MUX value, TCC channel */
            { GPIO_PIN(PA, 16), GPIO_MUX_E, 0 }, // Lights
            { GPIO_UNDEF, (gpio_mux_t)0, 1 },
            { GPIO_UNDEF, (gpio_mux_t)0, 2 },
            { GPIO_UNDEF, (gpio_mux_t)0, 3 }
        }
    }
#endif
#if PWM_1_EN
    ,{  TCC0, 
        {
            /* GPIO pin, MUX value, TCC channel */
            { GPIO_PIN(PB, 10), GPIO_MUX_F, 0 },    // MotorA
            { GPIO_PIN(PB, 11), GPIO_MUX_F, 1 },    // MotorB
            { GPIO_PIN(PB, 12), GPIO_MUX_F, 2 },    // MotorC
            { GPIO_UNDEF, (gpio_mux_t)0, 3 }     
        }
    }
#endif
};

// PWM Device count
#define PWM_NUMOF           (2U)

Timer Config:

#define XTIMER              TIMER_1
#define XTIMER_CHAN         (0)
// Configure Timer Peripherals
#define TIMER_NUMOF         (2U)
#define TIMER_0_EN          1
#define TIMER_1_EN          1

// Timer 0 configuration
#define TIMER_0_DEV         TC3->COUNT16
#define TIMER_0_CHANNELS    2
#define TIMER_0_MAX_VALUE   (0xffff)
#define TIMER_0_ISR         isr_tc3

// Timer 1 configuration
#define TIMER_1_DEV         TC4->COUNT32
#define TIMER_1_CHANNELS    2
#define TIMER_1_MAX_VALUE   (0xffffffff)
#define TIMER_1_ISR         isr_tc4

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Area: driversArea: Device driversPlatform: ARMPlatform: This PR/issue effects ARM-based platformsState: archivedState: The PR has been archived for possible future re-adaptationType: bugThe issue reports a bug / The PR fixes a bug (including spelling errors)

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions