diff --git a/cpu/samd21/cpu.c b/cpu/samd21/cpu.c index da5291b25f..96c8e15ee6 100644 --- a/cpu/samd21/cpu.c +++ b/cpu/samd21/cpu.c @@ -83,6 +83,12 @@ static void clk_init(void) /* make sure we synchronize clock generator 0 before we go on */ while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY); + + /* redirect all peripherals to a disabled clock generator (7) by default */ + for (int i = 0x3; i <= 0x22; i++) { + GCLK->CLKCTRL.reg = ( GCLK_CLKCTRL_ID(i) | GCLK_CLKCTRL_GEN_GCLK7 ); + while (GCLK->STATUS.bit.SYNCBUSY); + } } void cpu_init(void) diff --git a/cpu/samd21/periph/gpio.c b/cpu/samd21/periph/gpio.c index 1824b4b3b6..8e5395560b 100644 --- a/cpu/samd21/periph/gpio.c +++ b/cpu/samd21/periph/gpio.c @@ -146,7 +146,10 @@ int gpio_init_int(gpio_t pin, gpio_pp_t pullup, gpio_flank_t flank, gpio_init_mux(pin, GPIO_MUX_A); /* enable clocks for the EIC module */ PM->APBAMASK.reg |= PM_APBAMASK_EIC; - GCLK->CLKCTRL.reg = (EIC_GCLK_ID | GCLK_CLKCTRL_CLKEN); + GCLK->CLKCTRL.reg = (EIC_GCLK_ID | + GCLK_CLKCTRL_CLKEN | + GCLK_CLKCTRL_GEN_GCLK0); + while (GCLK->STATUS.bit.SYNCBUSY); /* configure the active flank */ EIC->CONFIG[exti >> 3].reg &= ~(0xf << ((exti & 0x7) * 4)); EIC->CONFIG[exti >> 3].reg |= (flank << ((exti & 0x7) * 4)); diff --git a/cpu/samd21/periph/i2c.c b/cpu/samd21/periph/i2c.c index e4df2411a9..f4615bc128 100644 --- a/cpu/samd21/periph/i2c.c +++ b/cpu/samd21/periph/i2c.c @@ -102,14 +102,14 @@ int i2c_init_master(i2c_t dev, i2c_speed_t speed) PM->APBCMASK.reg |= (PM_APBCMASK_SERCOM0 << (sercom_core - 20)); /* I2C using CLK GEN 0 */ - GCLK->CLKCTRL.reg = (uint32_t)(GCLK_CLKCTRL_CLKEN - | GCLK_CLKCTRL_GEN_GCLK0 << GCLK_CLKCTRL_GEN_Pos - | (sercom_core << GCLK_CLKCTRL_ID_Pos)); + GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_CLKEN | + GCLK_CLKCTRL_GEN_GCLK0 | + GCLK_CLKCTRL_ID(sercom_core)); while (GCLK->STATUS.bit.SYNCBUSY); - GCLK->CLKCTRL.reg = (uint16_t)(GCLK_CLKCTRL_CLKEN - | GCLK_CLKCTRL_GEN_GCLK0 << GCLK_CLKCTRL_GEN_Pos - | (sercom_gclk_id_slow << GCLK_CLKCTRL_ID_Pos)); + GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_CLKEN | + GCLK_CLKCTRL_GEN_GCLK0 | + GCLK_CLKCTRL_ID(sercom_gclk_id_slow)); while (GCLK->STATUS.bit.SYNCBUSY); diff --git a/cpu/samd21/periph/pwm.c b/cpu/samd21/periph/pwm.c index ebb9b887c9..6e6e23846a 100644 --- a/cpu/samd21/periph/pwm.c +++ b/cpu/samd21/periph/pwm.c @@ -121,11 +121,7 @@ int pwm_init(pwm_t dev, pwm_mode_t mode, /* power on the device */ pwm_poweron(dev); - /* configure generic clock 0 to feed the PWM */ - GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_CLKEN - | GCLK_CLKCTRL_GEN_GCLK0 - | (_clk_id(dev) << GCLK_CLKCTRL_ID_Pos)); - while (GCLK->STATUS.bit.SYNCBUSY); + /* reset TCC module */ _tcc(dev)->CTRLA.reg = TCC_CTRLA_SWRST; while (_tcc(dev)->SYNCBUSY.reg & TCC_SYNCBUSY_SWRST); @@ -184,9 +180,11 @@ void pwm_poweron(pwm_t dev) if (num < 0) { return; } - GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_CLKEN - | (_clk_id(dev) << GCLK_CLKCTRL_ID_Pos)); PM->APBCMASK.reg |= (PM_APBCMASK_TCC0 << num); + GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_CLKEN | + GCLK_CLKCTRL_GEN_GCLK0 | + GCLK_CLKCTRL_ID(_clk_id(dev))); + while (GCLK->STATUS.bit.SYNCBUSY); } void pwm_poweroff(pwm_t dev) @@ -195,8 +193,10 @@ void pwm_poweroff(pwm_t dev) if (num < 0) { return; } - GCLK->CLKCTRL.reg = ((_clk_id(dev) << GCLK_CLKCTRL_ID_Pos)); - PM->APBCMASK.reg &= ~(1 << num); + PM->APBCMASK.reg &= ~(PM_APBCMASK_TCC0 << num); + GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_GEN_GCLK7 | + GCLK_CLKCTRL_ID(_clk_id(dev))); + while (GCLK->STATUS.bit.SYNCBUSY); } #endif /* PWM_NUMOF */