diff --git a/boards/arduino-mkr-common/include/periph_conf.h b/boards/arduino-mkr-common/include/periph_conf.h index 6fc69bec0d306..eca16a3caaafd 100644 --- a/boards/arduino-mkr-common/include/periph_conf.h +++ b/boards/arduino-mkr-common/include/periph_conf.h @@ -33,14 +33,15 @@ extern "C" { /** * @name External oscillator and clock configuration * - * For selection of the used CORECLOCK, we have implemented two choices: + * There are three choices for selection of CORECLOCK: * + * - usage of the 48 MHz DFLL fed by external oscillator running at 32 kHz * - usage of the PLL fed by the internal 8MHz oscillator divided by 8 * - usage of the internal 8MHz oscillator directly, divided by N if needed * * * The PLL option allows for the usage of a wider frequency range and a more - * stable clock with less jitter. This is why we use this option as default. + * stable clock with less jitter. This is why this option is default. * * The target frequency is computed from the PLL multiplier and the PLL divisor. * Use the following formula to compute your values: @@ -61,19 +62,28 @@ extern "C" { * * @{ */ -#define CLOCK_USE_PLL (1) +#define CLOCK_USE_PLL (1) +#define CLOCK_USE_XOSC32_DFLL (0) +#define CLOCK_USE_8MHZ_DEFAULT (0) #if CLOCK_USE_PLL -/* edit these values to adjust the PLL output frequency */ + /* edit these values to adjust the PLL output frequency */ #define CLOCK_PLL_MUL (47U) /* must be >= 31 & <= 95 */ #define CLOCK_PLL_DIV (1U) /* adjust to your needs */ -/* generate the actual used core clock frequency */ + /* generate the actual used core clock frequency */ #define CLOCK_CORECLOCK (((CLOCK_PLL_MUL + 1) * 1000000U) / CLOCK_PLL_DIV) -#else -/* edit this value to your needs */ +#elif CLOCK_USE_XOSC32_DFLL + /* Settings for 32 kHz external oscillator and 48 MHz DFLL */ +#define CLOCK_CORECLOCK (48000000UL) +#define CLOCK_XOSC32K (32768UL) +#define GEN2_XOSC32 (1) +#elif CLOCK_USE_8MHZ_DEFAULT + /* edit this value to your needs */ #define CLOCK_DIV (1U) -/* generate the actual core clock frequency */ + /* generate the actual core clock frequency */ #define CLOCK_CORECLOCK (8000000 / CLOCK_DIV) +#else +#error Need to select a core clock #endif /** @} */ @@ -230,7 +240,7 @@ static const spi_conf_t spi_config[] = { #define I2C_0_SCL GPIO_PIN(PA, 9) /* SERCOM0-SCL, on-board pull-up */ #define I2C_0_MUX GPIO_MUX_C /** @} */ - + /** * @name RTC configuration * @{ @@ -250,7 +260,7 @@ static const spi_conf_t spi_config[] = { #define RTT_ISR isr_rtc #define RTT_MAX_VALUE (0xffffffff) #define RTT_FREQUENCY (32768U) /* in Hz. For changes see `rtt.c` */ -#define RTT_RUNSTDBY (1) /* Keep RTT running in sleep states */ +#define XOSC32_RUNSTDBY (1) /* Keep RTT running in sleep states */ /** @} */ #ifdef __cplusplus diff --git a/boards/arduino-zero/include/periph_conf.h b/boards/arduino-zero/include/periph_conf.h index 773ada0dd2674..c59b803bd3346 100644 --- a/boards/arduino-zero/include/periph_conf.h +++ b/boards/arduino-zero/include/periph_conf.h @@ -33,16 +33,17 @@ extern "C" { #endif /** - * @brief External oscillator and clock configuration + * @name External oscillator and clock configuration * - * For selection of the used CORECLOCK, we have implemented two choices: + * There are three choices for selection of CORECLOCK: * + * - usage of the 48 MHz DFLL fed by external oscillator running at 32 kHz * - usage of the PLL fed by the internal 8MHz oscillator divided by 8 * - usage of the internal 8MHz oscillator directly, divided by N if needed * * * The PLL option allows for the usage of a wider frequency range and a more - * stable clock with less jitter. This is why we use this option as default. + * stable clock with less jitter. This is why this option is default. * * The target frequency is computed from the PLL multiplier and the PLL divisor. * Use the following formula to compute your values: @@ -63,19 +64,28 @@ extern "C" { * * @{ */ -#define CLOCK_USE_PLL (1) - +#define CLOCK_USE_PLL (1) +#define CLOCK_USE_XOSC32_DFLL (0) +#define CLOCK_USE_8MHZ_DEFAULT (0) + #if CLOCK_USE_PLL -/* edit these values to adjust the PLL output frequency */ + /* edit these values to adjust the PLL output frequency */ #define CLOCK_PLL_MUL (47U) /* must be >= 31 & <= 95 */ #define CLOCK_PLL_DIV (1U) /* adjust to your needs */ -/* generate the actual used core clock frequency */ + /* generate the actual used core clock frequency */ #define CLOCK_CORECLOCK (((CLOCK_PLL_MUL + 1) * 1000000U) / CLOCK_PLL_DIV) -#else -/* edit this value to your needs */ +#elif CLOCK_USE_XOSC32_DFLL + /* Settings for 32 kHz external oscillator and 48 MHz DFLL */ +#define CLOCK_CORECLOCK (48000000UL) +#define CLOCK_XOSC32K (32768UL) +#define GEN2_XOSC32 (1) +#elif CLOCK_USE_8MHZ_DEFAULT + /* edit this value to your needs */ #define CLOCK_DIV (1U) -/* generate the actual core clock frequency */ + /* generate the actual core clock frequency */ #define CLOCK_CORECLOCK (8000000 / CLOCK_DIV) +#else +#error Need to select a core clock #endif /** @} */ @@ -233,7 +243,7 @@ static const spi_conf_t spi_config[] = { #define RTT_ISR isr_rtc #define RTT_MAX_VALUE (0xffffffff) #define RTT_FREQUENCY (32768U) /* in Hz. For changes see `rtt.c` */ -#define RTT_RUNSTDBY (1) /* Keep RTT running in sleep states */ +#define XOSC32_RUNSTDBY (1) /* Keep RTT running in sleep states */ /** @} */ #ifdef __cplusplus diff --git a/boards/samd21-xpro/include/periph_conf.h b/boards/samd21-xpro/include/periph_conf.h index 33a080b404ece..748ef201abb0a 100644 --- a/boards/samd21-xpro/include/periph_conf.h +++ b/boards/samd21-xpro/include/periph_conf.h @@ -63,7 +63,9 @@ extern "C" { * * @{ */ -#define CLOCK_USE_PLL (1) +#define CLOCK_USE_PLL (1) +#define CLOCK_USE_XOSC32_DFLL (0) +#define CLOCK_USE_8MHZ_DEFAULT (0) #if CLOCK_USE_PLL /* edit these values to adjust the PLL output frequency */ @@ -73,15 +75,16 @@ extern "C" { #define CLOCK_CORECLOCK (((CLOCK_PLL_MUL + 1) * 1000000U) / CLOCK_PLL_DIV) #elif CLOCK_USE_XOSC32_DFLL /* Settings for 32 kHz external oscillator and 48 MHz DFLL */ -#define CLOCK_CORECLOCK (48000000U) +#define CLOCK_CORECLOCK (48000000UL) #define CLOCK_XOSC32K (32768UL) -#define CLOCK_8MHZ (1) -#define GEN2_ULP32K (1) -#else +#define GEN2_XOSC32 (1) +#elif CLOCK_USE_8MHZ_DEFAULT /* edit this value to your needs */ #define CLOCK_DIV (1U) /* generate the actual core clock frequency */ #define CLOCK_CORECLOCK (8000000 / CLOCK_DIV) +#else +#error Need to select a core clock #endif /** @} */ @@ -271,7 +274,7 @@ static const spi_conf_t spi_config[] = { #define RTT_ISR isr_rtc #define RTT_MAX_VALUE (0xffffffff) #define RTT_FREQUENCY (32768U) /* in Hz. For changes see `rtt.c` */ -#define RTT_RUNSTDBY (1) /* Keep RTT running in sleep states */ +#define XOSC32_RUNSTDBY (1) /* Keep RTT running in sleep states */ /** @} */ /** diff --git a/boards/samr21-xpro/include/periph_conf.h b/boards/samr21-xpro/include/periph_conf.h index aae2a47786c0c..63421ccded994 100644 --- a/boards/samr21-xpro/include/periph_conf.h +++ b/boards/samr21-xpro/include/periph_conf.h @@ -63,7 +63,9 @@ extern "C" { * * @{ */ -#define CLOCK_USE_PLL (1) +#define CLOCK_USE_PLL (1) +#define CLOCK_USE_XOSC32_DFLL (0) +#define CLOCK_USE_8MHZ_DEFAULT (0) #if CLOCK_USE_PLL /* edit these values to adjust the PLL output frequency */ @@ -72,16 +74,17 @@ extern "C" { /* generate the actual used core clock frequency */ #define CLOCK_CORECLOCK (((CLOCK_PLL_MUL + 1) * 1000000U) / CLOCK_PLL_DIV) #elif CLOCK_USE_XOSC32_DFLL - /* Settings for 32 kHz external oscillator and 48 MHz DFLL */ -#define CLOCK_CORECLOCK (48000000U) +/* Settings for 32 kHz external oscillator and 48 MHz DFLL */ +#define CLOCK_CORECLOCK (48000000UL) #define CLOCK_XOSC32K (32768UL) -#define CLOCK_8MHZ (1) -#define GEN2_ULP32K (1) -#else +#define GEN2_XOSC32 (1) +#elif CLOCK_USE_8MHZ_DEFAULT /* edit this value to your needs */ #define CLOCK_DIV (1U) /* generate the actual core clock frequency */ #define CLOCK_CORECLOCK (8000000 / CLOCK_DIV) +#else +#error Need to select a core clock #endif /** @} */ @@ -244,7 +247,7 @@ static const spi_conf_t spi_config[] = { #define RTT_ISR isr_rtc #define RTT_MAX_VALUE (0xffffffff) #define RTT_FREQUENCY (32768U) /* in Hz. For changes see `rtt.c` */ -#define RTT_RUNSTDBY (1) /* Keep RTT running in sleep states */ +#define XOSC32_RUNSTDBY (1) /* Keep RTT running in sleep states */ /** @} */ /** diff --git a/boards/sodaq-autonomo/include/periph_conf.h b/boards/sodaq-autonomo/include/periph_conf.h index c4a272ef5271e..add9b30a0f3c2 100644 --- a/boards/sodaq-autonomo/include/periph_conf.h +++ b/boards/sodaq-autonomo/include/periph_conf.h @@ -29,16 +29,17 @@ extern "C" { #endif /** - * @name External oscillator and clock configuration + * @name External oscillator and clock configuration * - * For selection of the used CORECLOCK, we have implemented two choices: + * There are three choices for selection of CORECLOCK: * + * - usage of the 48 MHz DFLL fed by external oscillator running at 32 kHz * - usage of the PLL fed by the internal 8MHz oscillator divided by 8 * - usage of the internal 8MHz oscillator directly, divided by N if needed * * * The PLL option allows for the usage of a wider frequency range and a more - * stable clock with less jitter. This is why we use this option as default. + * stable clock with less jitter. This is why this option is default. * * The target frequency is computed from the PLL multiplier and the PLL divisor. * Use the following formula to compute your values: @@ -59,19 +60,28 @@ extern "C" { * * @{ */ -#define CLOCK_USE_PLL (1) +#define CLOCK_USE_PLL (1) +#define CLOCK_USE_XOSC32_DFLL (0) +#define CLOCK_USE_8MHZ_DEFAULT (0) #if CLOCK_USE_PLL -/* edit these values to adjust the PLL output frequency */ + /* edit these values to adjust the PLL output frequency */ #define CLOCK_PLL_MUL (47U) /* must be >= 31 & <= 95 */ #define CLOCK_PLL_DIV (1U) /* adjust to your needs */ -/* generate the actual used core clock frequency */ + /* generate the actual used core clock frequency */ #define CLOCK_CORECLOCK (((CLOCK_PLL_MUL + 1) * 1000000U) / CLOCK_PLL_DIV) -#else -/* edit this value to your needs */ +#elif CLOCK_USE_XOSC32_DFLL + /* Settings for 32 kHz external oscillator and 48 MHz DFLL */ +#define CLOCK_CORECLOCK (48000000UL) +#define CLOCK_XOSC32K (32768UL) +#define GEN2_XOSC32 (1) +#elif CLOCK_USE_8MHZ_DEFAULT + /* edit this value to your needs */ #define CLOCK_DIV (1U) -/* generate the actual core clock frequency */ + /* generate the actual core clock frequency */ #define CLOCK_CORECLOCK (8000000 / CLOCK_DIV) +#else +#error Need to select a core clock #endif /** @} */ @@ -242,7 +252,7 @@ static const spi_conf_t spi_config[] = { #define RTT_ISR isr_rtc #define RTT_MAX_VALUE (0xffffffff) #define RTT_FREQUENCY (32768U) /* in Hz. For changes see `rtt.c` */ -#define RTT_RUNSTDBY (1) /* Keep RTT running in sleep states */ +#define XOSC32_RUNSTDBY (1) /* Keep RTT running in sleep states */ /** @} */ #ifdef __cplusplus diff --git a/cpu/samd21/cpu.c b/cpu/samd21/cpu.c index f6c59bccb258b..e796b7695468f 100644 --- a/cpu/samd21/cpu.c +++ b/cpu/samd21/cpu.c @@ -15,21 +15,15 @@ * * @author Thomas Eichinger * @author Hauke Petersen + * @author Dan Evans * @} */ #include "cpu.h" #include "periph_conf.h" +#include "periph_clock_config.h" #include "periph/init.h" -#ifndef CLOCK_8MHZ -#define CLOCK_8MHZ 1 -#endif - -#ifndef GEN2_ULP32K -#define GEN2_ULP32K 1 -#endif - #ifndef VDD /** * @brief Set system voltage level in mV (determines flash wait states) @@ -71,71 +65,93 @@ static void clk_init(void) while (!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_OSC8MRDY)) {} #endif -#if CLOCK_USE_PLL +#if CLOCK_XOSC32K + /* Use External 32.768KHz Oscillator */ + SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_ONDEMAND | + SYSCTRL_XOSC32K_EN32K | + SYSCTRL_XOSC32K_XTALEN | + SYSCTRL_XOSC32K_STARTUP(6) | + SYSCTRL_XOSC32K_RUNSTDBY; + /* Enable with Seperate Call */ + SYSCTRL->XOSC32K.bit.ENABLE = 1; +#endif + /* reset the GCLK module so it is in a known state */ GCLK->CTRL.reg = GCLK_CTRL_SWRST; while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {} - /* setup generic clock 1 to feed DPLL with 1MHz */ - GCLK->GENDIV.reg = (GCLK_GENDIV_DIV(8) | - GCLK_GENDIV_ID(1)); +#if GEN1_1MHZ +#if CLOCK_8MHZ == 0 +#error Must turn on CLOCK_8MHZ to use GEN1_1MHZ +#endif + /* Setup GCLK1 with 1MHz */ + GCLK->GENDIV.reg = (GCLK_GENDIV_DIV(8) | + GCLK_GENDIV_ID(1)); GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSC8M | GCLK_GENCTRL_ID(1)); - GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_GEN(1) | - GCLK_CLKCTRL_ID(1) | - GCLK_CLKCTRL_CLKEN); while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {} +#endif + +#if GEN2_XOSC32 +#if CLOCK_XOSC32K == 0 +#error Must turn on CLOCK_XOSC32K to use GEN2_XOSC32 +#endif + /* Setup GCLK2 with XOSC32 */ + GCLK->GENDIV.reg = (GCLK_GENDIV_DIV(1) | + GCLK_GENDIV_ID(2)); + GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN | + GCLK_GENCTRL_SRC_XOSC32K | +#if XOSC32_RUNSTDBY + GCLK_GENCTRL_RUNSTDBY | +#endif + GCLK_GENCTRL_ID(2)); + while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {} +#endif + +#if GEN3_ULP32K + /* Setup Clock generator 3 with divider 32 (32.768kHz/32 = 1.024 kHz) */ + GCLK->GENDIV.reg = (GCLK_GENDIV_DIV(4) | + GCLK_GENDIV_ID(3)); + GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN | + GCLK_GENCTRL_SRC_OSCULP32K | + GCLK_GENCTRL_RUNSTDBY | + GCLK_GENCTRL_DIVSEL | + GCLK_GENCTRL_ID(3)); + + while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {} +#endif - /* enable PLL */ +#if CLOCK_USE_PLL +#if GEN1_1MHZ == 0 +#error Must turn on GEN1_1MHZ to use CLOCK_USE_PLL +#endif + /* Set GEN1_1MHZ as source for DFLL */ + GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_GEN_GCLK1 | + GCLK_CLKCTRL_ID_FDPLL | + GCLK_CLKCTRL_CLKEN); + while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {} + + /* Enable PLL */ SYSCTRL->DPLLRATIO.reg = (SYSCTRL_DPLLRATIO_LDR(CLOCK_PLL_MUL)); SYSCTRL->DPLLCTRLB.reg = (SYSCTRL_DPLLCTRLB_REFCLK_GCLK); SYSCTRL->DPLLCTRLA.reg = (SYSCTRL_DPLLCTRLA_ENABLE); while(!(SYSCTRL->DPLLSTATUS.reg & - (SYSCTRL_DPLLSTATUS_CLKRDY | SYSCTRL_DPLLSTATUS_LOCK))) {} - - /* select the PLL as source for clock generator 0 (CPU core clock) */ + (SYSCTRL_DPLLSTATUS_CLKRDY | + SYSCTRL_DPLLSTATUS_LOCK))) {} + + /* Select the PLL as source for clock generator 0 (CPU core clock) */ GCLK->GENDIV.reg = (GCLK_GENDIV_DIV(CLOCK_PLL_DIV) | - GCLK_GENDIV_ID(0)); + GCLK_GENDIV_ID(0)); GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_FDPLL | GCLK_GENCTRL_ID(0)); #elif CLOCK_USE_XOSC32_DFLL - /* Use External 32.768KHz Oscillator */ - SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_ONDEMAND | - SYSCTRL_XOSC32K_EN32K | - SYSCTRL_XOSC32K_XTALEN | - SYSCTRL_XOSC32K_STARTUP(6) | - SYSCTRL_XOSC32K_RUNSTDBY; - - /* Enable with Seperate Call */ - SYSCTRL->XOSC32K.bit.ENABLE = 1; - - /* reset the GCLK module so it is in a known state */ - GCLK->CTRL.reg = GCLK_CTRL_SWRST; - while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {} - - /* setup generic clock 1 as 1MHz for timer.c */ - GCLK->GENDIV.reg = (GCLK_GENDIV_DIV(8) | - GCLK_GENDIV_ID(1)); - GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN | - GCLK_GENCTRL_SRC_OSC8M | - GCLK_GENCTRL_ID(1)); - while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {} - - /* Setup clock GCLK3 with divider 1 */ - GCLK->GENDIV.reg = GCLK_GENDIV_ID(3) | GCLK_GENDIV_DIV(1); - while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {} - - /* Enable GCLK3 with XOSC32K as source */ - GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(3) | - GCLK_GENCTRL_GENEN | - GCLK_GENCTRL_RUNSTDBY | - GCLK_GENCTRL_SRC_XOSC32K; - while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {} - - /* set GCLK3 as source for DFLL */ - GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_GEN_GCLK3 | +#if CLOCK_XOSC32K == 0 +#error Must turn on CLOCK_XOSC32K to use CLOCK_USE_XOSC32_DFLL +#endif + /* Set GEN2_XOSC32 as source for DFLL */ + GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_GEN_GCLK2 | GCLK_CLKCTRL_ID_DFLL48 | GCLK_CLKCTRL_CLKEN); while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {} @@ -155,7 +171,7 @@ static void clk_init(void) SYSCTRL_DFLLMUL_MUL(CLOCK_CORECLOCK / CLOCK_XOSC32K); SYSCTRL->DFLLVAL.reg = SYSCTRL_DFLLVAL_COARSE(coarse) | SYSCTRL_DFLLVAL_FINE(fine); - SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_MODE; + SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_MODE; while ((SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0) { /* Wait for DFLL sync */ } @@ -168,40 +184,40 @@ static void clk_init(void) } /* select the DFLL as source for clock generator 0 (CPU core clock) */ - GCLK->GENDIV.reg = (GCLK_GENDIV_DIV(1U) | GCLK_GENDIV_ID(0)); - GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_DFLL48M | GCLK_GENCTRL_ID(0)); - GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0; + GCLK->GENDIV.reg = (GCLK_GENDIV_DIV(1) | + GCLK_GENDIV_ID(0)); + GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN | + GCLK_GENCTRL_SRC_DFLL48M | + GCLK_GENCTRL_ID(0)); while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {} SYSCTRL->DFLLCTRL.bit.ONDEMAND = 1; while ((SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0) { /* Wait for DFLL sync */ } -#else /* do not use PLL, use internal 8MHz oscillator directly */ +#elif CLOCK_USE_8MHZ_DEFAULT +#if CLOCK_8MHZ == 0 +#error Must turn on CLOCK_8MHZ to use CLOCK_USE_8MHZ_DEFAULT +#endif + /* use internal 8MHz oscillator directly */ GCLK->GENDIV.reg = (GCLK_GENDIV_DIV(CLOCK_DIV) | - GCLK_GENDIV_ID(0)); + GCLK_GENDIV_ID(0)); GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSC8M | GCLK_GENCTRL_ID(0)); +#else +#error Must setup GCLK0 #endif - - /* make sure we synchronize clock generator 0 before we go on */ + /* Make sure GCLK0 is on */ + GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_CLKEN | + GCLK_CLKCTRL_GEN_GCLK0); while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {} -#if GEN2_ULP32K - /* Setup Clock generator 2 with divider 1 (32.768kHz) */ - GCLK->GENDIV.reg = (GCLK_GENDIV_ID(2) | GCLK_GENDIV_DIV(0)); - GCLK->GENCTRL.reg = (GCLK_GENCTRL_ID(2) | GCLK_GENCTRL_GENEN | - GCLK_GENCTRL_RUNSTDBY | - GCLK_GENCTRL_SRC_OSCULP32K); - - while (GCLK->STATUS.bit.SYNCBUSY) {} -#endif - /* 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) {} + GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_ID(i) | + GCLK_CLKCTRL_GEN_GCLK7); + while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {} } } diff --git a/cpu/samd21/include/periph_clock_config.h b/cpu/samd21/include/periph_clock_config.h new file mode 100644 index 0000000000000..73e988a806c60 --- /dev/null +++ b/cpu/samd21/include/periph_clock_config.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2017 Daniel Evans + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_samd21 + * @{ + * + * @file + * @brief CPU specific definitions for default clock configuration + * + * @author Daniel Evans + */ + +#ifndef PERIPH_CLOCK_CONFIG_H +#define PERIPH_CLOCK_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Default Clock configurations + */ + +/* If RTC or RTT is on Need XOSC32 */ +#if RTC_NUMOF || RTT_NUMOF +#ifndef CLOCK_XOSC32K +#define CLOCK_XOSC32K (32768UL) +#endif +#ifndef GEN2_XOSC32 +#define GEN2_XOSC32 (1) +#endif +#endif + +/* If never set then use these defaults */ +#ifndef CLOCK_8MHZ +#define CLOCK_8MHZ (8000000UL) +#endif + +#ifndef CLOCK_XOSC32K +#define CLOCK_XOSC32K (0) +#endif + +#ifndef XOSC32_RUNSTDBY +#define XOSC32_RUNSTDBY (0) +#endif + +#ifndef GEN1_1MHZ +#define GEN1_1MHZ (1) +#endif + +#ifndef GEN2_XOSC32 +#define GEN2_XOSC32 (0) +#endif + +#ifndef GEN3_ULP32K +#define GEN3_ULP32K (0) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PERIPH_CLOCK_CONFIG_H */ +/** @} */ diff --git a/cpu/samd21/periph/rtc.c b/cpu/samd21/periph/rtc.c index 96bf878d2bba1..18e1ab078013b 100644 --- a/cpu/samd21/periph/rtc.c +++ b/cpu/samd21/periph/rtc.c @@ -23,10 +23,16 @@ #include "cpu.h" #include "periph/rtc.h" #include "periph_conf.h" +#include "periph_clock_config.h" + /* guard file in case no RTC device was specified */ #if RTC_NUMOF +#if GEN2_XOSC32 == 0 +#error Set GEN2_XOSC32 in periph_conf.h to use RTC +#endif + typedef struct { rtc_alarm_cb_t cb; /**< callback called from RTC interrupt */ void *arg; /**< argument passed to the callback */ @@ -35,8 +41,8 @@ typedef struct { static rtc_state_t rtc_callback; /* At 1Hz, RTC goes till 63 years (2^5, see 17.8.22 in datasheet) -* reference_year is set to 100 (offset) to be in our current time (2000) -* Thanks to this, the user will be able to set time in 2000's*/ + * reference_year is set to 100 (offset) to be in our current time (2000) + * Thanks to this, the user will be able to set time in 2000's*/ static uint16_t reference_year = 100; void rtc_init(void) @@ -46,19 +52,11 @@ void rtc_init(void) /* Turn on power manager for RTC */ PM->APBAMASK.reg |= PM_APBAMASK_RTC; - /* RTC uses External 32,768KHz Oscillator (OSC32K isn't accurate enough p1075/1138)*/ - SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_ONDEMAND | - SYSCTRL_XOSC32K_EN32K | - SYSCTRL_XOSC32K_XTALEN | - SYSCTRL_XOSC32K_STARTUP(6) | - SYSCTRL_XOSC32K_ENABLE; - - /* Setup clock GCLK2 with OSC32K divided by 32 */ - GCLK->GENDIV.reg = GCLK_GENDIV_ID(2)|GCLK_GENDIV_DIV(4); - while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {} - GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_XOSC32K | GCLK_GENCTRL_ID(2) | GCLK_GENCTRL_DIVSEL ); - while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {} - GCLK->CLKCTRL.reg = (uint32_t)((GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK2 | (RTC_GCLK_ID << GCLK_CLKCTRL_ID_Pos))); + /* RTC uses GEN2_XOSC32 because OSC32K isn't accurate + * enough (p1075/1138). */ + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_GEN_GCLK2 | + GCLK_CLKCTRL_CLKEN | + GCLK_CLKCTRL_ID(RTC_GCLK_ID); while (GCLK->STATUS.bit.SYNCBUSY) {} /* DISABLE RTC MASTER */ @@ -71,7 +69,8 @@ void rtc_init(void) while (rtcMode2->STATUS.bit.SYNCBUSY) {} /* RTC config with RTC_MODE2_CTRL_CLKREP = 0 (24h) */ - rtcMode2->CTRL.reg = RTC_MODE2_CTRL_PRESCALER_DIV1024|RTC_MODE2_CTRL_MODE_CLOCK; + rtcMode2->CTRL.reg = RTC_MODE2_CTRL_PRESCALER_DIV1024 | + RTC_MODE2_CTRL_MODE_CLOCK; while (rtcMode2->STATUS.bit.SYNCBUSY) {} rtcMode2->INTENSET.reg = RTC_MODE2_INTENSET_OVF; while (rtcMode2->STATUS.bit.SYNCBUSY) {} @@ -81,16 +80,18 @@ void rtc_init(void) int rtc_set_time(struct tm *time) { RtcMode2 *rtcMode2 = &(RTC_DEV); - if ((time->tm_year < reference_year) || (time->tm_year > reference_year + 63)) { + if ((time->tm_year < reference_year) || + (time->tm_year > reference_year + 63)) { return -1; } else { - rtcMode2->CLOCK.reg = RTC_MODE2_CLOCK_YEAR(time->tm_year - reference_year) - | RTC_MODE2_CLOCK_MONTH(time->tm_mon + 1) - | RTC_MODE2_CLOCK_DAY(time->tm_mday) - | RTC_MODE2_CLOCK_HOUR(time->tm_hour) - | RTC_MODE2_CLOCK_MINUTE(time->tm_min) - | RTC_MODE2_CLOCK_SECOND(time->tm_sec); + rtcMode2->CLOCK.reg = + RTC_MODE2_CLOCK_YEAR(time->tm_year - reference_year) | + RTC_MODE2_CLOCK_MONTH(time->tm_mon + 1) | + RTC_MODE2_CLOCK_DAY(time->tm_mday) | + RTC_MODE2_CLOCK_HOUR(time->tm_hour) | + RTC_MODE2_CLOCK_MINUTE(time->tm_min) | + RTC_MODE2_CLOCK_SECOND(time->tm_sec); } while (rtcMode2->STATUS.bit.SYNCBUSY) {} return 0; @@ -100,7 +101,8 @@ int rtc_get_time(struct tm *time) { RtcMode2 *rtcMode2 = &(RTC_DEV); time->tm_year = rtcMode2->CLOCK.bit.YEAR + reference_year; - if ((time->tm_year < reference_year) || (time->tm_year > (reference_year + 63))) { + if ((time->tm_year < reference_year) || + (time->tm_year > (reference_year + 63))) { return -1; } time->tm_mon = rtcMode2->CLOCK.bit.MONTH - 1; @@ -116,16 +118,18 @@ int rtc_set_alarm(struct tm *time, rtc_alarm_cb_t cb, void *arg) { RtcMode2 *rtcMode2 = &(RTC_DEV); rtc_clear_alarm(); - if ((time->tm_year < reference_year) || (time->tm_year > (reference_year + 63))) { + if ((time->tm_year < reference_year) || + (time->tm_year > (reference_year + 63))) { return -2; } else { - rtcMode2->Mode2Alarm[0].ALARM.reg = RTC_MODE2_ALARM_YEAR(time->tm_year - reference_year) - | RTC_MODE2_ALARM_MONTH(time->tm_mon + 1) - | RTC_MODE2_ALARM_DAY(time->tm_mday) - | RTC_MODE2_ALARM_HOUR(time->tm_hour) - | RTC_MODE2_ALARM_MINUTE(time->tm_min) - | RTC_MODE2_ALARM_SECOND(time->tm_sec); + rtcMode2->Mode2Alarm[0].ALARM.reg = + RTC_MODE2_ALARM_YEAR(time->tm_year - reference_year) | + RTC_MODE2_ALARM_MONTH(time->tm_mon + 1) | + RTC_MODE2_ALARM_DAY(time->tm_mday) | + RTC_MODE2_ALARM_HOUR(time->tm_hour) | + RTC_MODE2_ALARM_MINUTE(time->tm_min) | + RTC_MODE2_ALARM_SECOND(time->tm_sec); rtcMode2->Mode2Alarm[0].MASK.reg = RTC_MODE2_MASK_SEL(6); } while (rtcMode2->STATUS.bit.SYNCBUSY) {} @@ -148,7 +152,8 @@ int rtc_get_alarm(struct tm *time) { RtcMode2 *rtcMode2 = &(RTC_DEV); time->tm_year = rtcMode2->Mode2Alarm[0].ALARM.bit.YEAR + reference_year; - if ((time->tm_year < reference_year) || (time->tm_year > (reference_year + 63))) { + if ((time->tm_year < reference_year) || + (time->tm_year > (reference_year + 63))) { return -1; } time->tm_mon = rtcMode2->Mode2Alarm[0].ALARM.bit.MONTH - 1; @@ -193,7 +198,9 @@ void isr_rtc(void) } if (status & RTC_MODE2_INTFLAG_OVF) { /* At 1Hz, RTC goes till 63 years (2^5, see 17.8.22 in datasheet) - * Start RTC again with reference_year 64 years more (Be careful with alarm set) */ + * Start RTC again with reference_year 64 years more + * (Be careful with alarm set) + */ reference_year += 64; rtcMode2->INTFLAG.reg = RTC_MODE2_INTFLAG_OVF; } diff --git a/cpu/samd21/periph/rtt.c b/cpu/samd21/periph/rtt.c index 8919f43d8392b..dbaa17977ced1 100644 --- a/cpu/samd21/periph/rtt.c +++ b/cpu/samd21/periph/rtt.c @@ -23,10 +23,14 @@ #include "cpu.h" #include "periph/rtt.h" #include "periph_conf.h" +#include "periph_clock_config.h" /* guard file in case no RTT device was specified */ #if RTT_NUMOF +#if GEN2_XOSC32 == 0 +#error Set GEN2_XOSC32 in periph_conf.h to use RTT +#endif typedef struct { rtt_cb_t overflow_cb; /**< called from RTT interrupt on overflow */ @@ -46,7 +50,8 @@ static rtt_state_t rtt_callback; * divider. There are 2 cascaded dividers in the clock path: * * - GCLK_GENDIV_DIV(n): between 1 and 31 - * - RTC_MODE0_CTRL_PRESCALER_DIVn: between 1 and 1024, see defines in `component_rtc.h` + * - RTC_MODE0_CTRL_PRESCALER_DIVn: between 1 and 1024, + * see defines in `component_rtc.h` * * However the division scheme of GCLK_GENDIV_DIV can be changed by setting * GCLK_GENCTRL_DIVSEL: @@ -61,32 +66,8 @@ void rtt_init(void) /* Turn on power manager for RTC */ PM->APBAMASK.reg |= PM_APBAMASK_RTC; - /* RTC uses External 32,768KHz Oscillator because OSC32K isn't accurate + /* RTC uses GEN2_XOSC32 because OSC32K isn't accurate * enough (p1075/1138). Also keep running in standby. */ - SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_ONDEMAND | - SYSCTRL_XOSC32K_EN32K | - SYSCTRL_XOSC32K_XTALEN | - SYSCTRL_XOSC32K_STARTUP(6) | -#if RTT_RUNSTDBY - SYSCTRL_XOSC32K_RUNSTDBY | -#endif - SYSCTRL_XOSC32K_ENABLE; - - /* Setup clock GCLK2 with divider 1 */ - GCLK->GENDIV.reg = GCLK_GENDIV_ID(2) | GCLK_GENDIV_DIV(1); - while (GCLK->STATUS.bit.SYNCBUSY) {} - - /* Enable GCLK2 with XOSC32K as source. Use divider without modification - * and keep running in standby. */ - GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(2) | - GCLK_GENCTRL_GENEN | -#if RTT_RUNSTDBY - GCLK_GENCTRL_RUNSTDBY | -#endif - GCLK_GENCTRL_SRC_XOSC32K; - while (GCLK->STATUS.bit.SYNCBUSY) {} - - /* Connect GCLK2 to RTC */ GCLK->CLKCTRL.reg = GCLK_CLKCTRL_GEN_GCLK2 | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_ID(RTC_GCLK_ID); @@ -99,8 +80,10 @@ void rtt_init(void) rtcMode0->CTRL.bit.SWRST = 1; while (rtcMode0->STATUS.bit.SYNCBUSY || rtcMode0->CTRL.bit.SWRST) {} - /* Configure as 32bit counter with no prescaler and no clear on match compare */ - rtcMode0->CTRL.reg = RTC_MODE0_CTRL_MODE_COUNT32 | RTC_MODE0_CTRL_PRESCALER_DIV1; + /* Configure as 32bit counter with no prescaler and + * no clear on match compare */ + rtcMode0->CTRL.reg = RTC_MODE0_CTRL_MODE_COUNT32 | + RTC_MODE0_CTRL_PRESCALER_DIV1; while (rtcMode0->STATUS.bit.SYNCBUSY) {} /* Setup interrupt */ @@ -194,12 +177,14 @@ void RTT_ISR(void) RtcMode0 *rtcMode0 = &(RTT_DEV); uint8_t status = rtcMode0->INTFLAG.reg; - if ( (status & RTC_MODE0_INTFLAG_CMP0) && (rtt_callback.alarm_cb != NULL) ) { + if ((status & RTC_MODE0_INTFLAG_CMP0) && + (rtt_callback.alarm_cb != NULL) ) { rtt_callback.alarm_cb(rtt_callback.alarm_arg); rtcMode0->INTFLAG.bit.CMP0 = 1; } - if ( (status & RTC_MODE0_INTFLAG_OVF) && (rtt_callback.overflow_cb != NULL) ) { + if ((status & RTC_MODE0_INTFLAG_OVF) && + (rtt_callback.overflow_cb != NULL) ) { rtt_callback.overflow_cb(rtt_callback.overflow_arg); rtcMode0->INTFLAG.bit.OVF = 1; } @@ -207,5 +192,4 @@ void RTT_ISR(void) cortexm_isr_end(); } - #endif /* RTT_NUMOF */ diff --git a/cpu/samd21/periph/timer.c b/cpu/samd21/periph/timer.c index 8b2738a1879a5..b4208b644ee6c 100644 --- a/cpu/samd21/periph/timer.c +++ b/cpu/samd21/periph/timer.c @@ -27,6 +27,7 @@ #include "periph/timer.h" #include "periph_conf.h" +#include "periph_clock_config.h" #define ENABLE_DEBUG (0) #include "debug.h" @@ -49,74 +50,60 @@ int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg) return -1; } -/* select the clock generator depending on the main clock source: - * GCLK0 (1MHz) if we use the internal 8MHz oscillator - * GCLK1 (8MHz) if we use the PLL */ -#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL - /* configure GCLK1 (configured to 1MHz) to feed TC3, TC4 and TC5 */; + /* Run using the 1 MHZ clock source */ +#if GEN1_1MHZ == 0 +#error Set GEN1_1MHZ in periph_conf.h to use timer +#endif + /* USE GEN1_1MHZ to feed TC3, TC4 and TC5 */; /* configure GCLK1 to feed TC3, TC4 and TC5 */; - GCLK->CLKCTRL.reg = (uint16_t)((GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK1 | (TC3_GCLK_ID << GCLK_CLKCTRL_ID_Pos))); + GCLK->CLKCTRL.reg = ((GCLK_CLKCTRL_CLKEN | + GCLK_CLKCTRL_GEN_GCLK1 | + (TC3_GCLK_ID << GCLK_CLKCTRL_ID_Pos))); while (GCLK->STATUS.bit.SYNCBUSY) {} /* TC4 and TC5 share the same channel */ - GCLK->CLKCTRL.reg = (uint16_t)((GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK1 | (TC4_GCLK_ID << GCLK_CLKCTRL_ID_Pos))); -#else - /* configure GCLK0 to feed TC3, TC4 and TC5 */; - GCLK->CLKCTRL.reg = (uint16_t)((GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | (TC3_GCLK_ID << GCLK_CLKCTRL_ID_Pos))); - /* TC4 and TC5 share the same channel */ - GCLK->CLKCTRL.reg = (uint16_t)((GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | (TC4_GCLK_ID << GCLK_CLKCTRL_ID_Pos))); -#endif + GCLK->CLKCTRL.reg = ((GCLK_CLKCTRL_CLKEN | + GCLK_CLKCTRL_GEN_GCLK1 | + (TC4_GCLK_ID << GCLK_CLKCTRL_ID_Pos))); while (GCLK->STATUS.bit.SYNCBUSY) {} switch (dev) { #if TIMER_0_EN - case TIMER_0: - if (TIMER_0_DEV.CTRLA.bit.ENABLE) { - return 0; - } - PM->APBCMASK.reg |= PM_APBCMASK_TC3; - /* reset timer */ - TIMER_0_DEV.CTRLA.bit.SWRST = 1; - while (TIMER_0_DEV.CTRLA.bit.SWRST) {} - /* choosing 16 bit mode */ - TIMER_0_DEV.CTRLA.bit.MODE = TC_CTRLA_MODE_COUNT16_Val; -#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL - /* PLL/DFLL: sourced by 1MHz and prescaler 1 to reach 1MHz */ - TIMER_0_DEV.CTRLA.bit.PRESCALER = TC_CTRLA_PRESCALER_DIV1_Val; -#else - /* sourced by 8MHz with Presc 8 results in 1MHz clk */ - TIMER_0_DEV.CTRLA.bit.PRESCALER = TC_CTRLA_PRESCALER_DIV8_Val; -#endif - /* choose normal frequency operation */ - TIMER_0_DEV.CTRLA.bit.WAVEGEN = TC_CTRLA_WAVEGEN_NFRQ_Val; - break; + case TIMER_0: + if (TIMER_0_DEV.CTRLA.bit.ENABLE) { + return 0; + } + PM->APBCMASK.reg |= PM_APBCMASK_TC3; + /* reset timer */ + TIMER_0_DEV.CTRLA.bit.SWRST = 1; + while (TIMER_0_DEV.CTRLA.bit.SWRST) {} + /* choosing 16 bit mode */ + TIMER_0_DEV.CTRLA.bit.MODE = TC_CTRLA_MODE_COUNT16_Val; + /* Sourced by 1MHz, thus no divide */ + TIMER_0_DEV.CTRLA.bit.PRESCALER = TC_CTRLA_PRESCALER_DIV1_Val; + /* choose normal frequency operation */ + TIMER_0_DEV.CTRLA.bit.WAVEGEN = TC_CTRLA_WAVEGEN_NFRQ_Val; + break; #endif #if TIMER_1_EN - case TIMER_1: - if (TIMER_1_DEV.CTRLA.bit.ENABLE) { - return 0; - } - PM->APBCMASK.reg |= PM_APBCMASK_TC4; - /* reset timer */ - TIMER_1_DEV.CTRLA.bit.SWRST = 1; - - while (TIMER_1_DEV.CTRLA.bit.SWRST) {} - - - TIMER_1_DEV.CTRLA.bit.MODE = TC_CTRLA_MODE_COUNT32_Val; -#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL - /* PLL/DFLL: sourced by 1MHz and prescaler 1 to reach 1MHz */ - TIMER_1_DEV.CTRLA.bit.PRESCALER = TC_CTRLA_PRESCALER_DIV1_Val; -#else - /* sourced by 8MHz with Presc 8 results in 1Mhz clk */ - TIMER_1_DEV.CTRLA.bit.PRESCALER = TC_CTRLA_PRESCALER_DIV8_Val; -#endif - /* choose normal frequency operation */ - TIMER_1_DEV.CTRLA.bit.WAVEGEN = TC_CTRLA_WAVEGEN_NFRQ_Val; - break; + case TIMER_1: + if (TIMER_1_DEV.CTRLA.bit.ENABLE) { + return 0; + } + PM->APBCMASK.reg |= PM_APBCMASK_TC4; + /* reset timer */ + TIMER_1_DEV.CTRLA.bit.SWRST = 1; + while (TIMER_1_DEV.CTRLA.bit.SWRST) {} + /* choosing 32 bit mode */ + TIMER_1_DEV.CTRLA.bit.MODE = TC_CTRLA_MODE_COUNT32_Val; + /* Sourced by 1MHz, thus no divide */ + TIMER_1_DEV.CTRLA.bit.PRESCALER = TC_CTRLA_PRESCALER_DIV1_Val; + /* choose normal frequency operation */ + TIMER_1_DEV.CTRLA.bit.WAVEGEN = TC_CTRLA_WAVEGEN_NFRQ_Val; + break; #endif - case TIMER_UNDEFINED: - default: - return -1; + case TIMER_UNDEFINED: + default: + return -1; } /* save callback */ @@ -138,46 +125,46 @@ int timer_set_absolute(tim_t dev, int channel, unsigned int value) /* get timer base register address */ switch (dev) { #if TIMER_0_EN - case TIMER_0: - /* set timeout value */ - switch (channel) { - case 0: - TIMER_0_DEV.INTFLAG.bit.MC0 = 1; - TIMER_0_DEV.CC[0].reg = value; - TIMER_0_DEV.INTENSET.bit.MC0 = 1; - break; - case 1: - TIMER_0_DEV.INTFLAG.bit.MC1 = 1; - TIMER_0_DEV.CC[1].reg = value; - TIMER_0_DEV.INTENSET.bit.MC1 = 1; + case TIMER_0: + /* set timeout value */ + switch (channel) { + case 0: + TIMER_0_DEV.INTFLAG.bit.MC0 = 1; + TIMER_0_DEV.CC[0].reg = value; + TIMER_0_DEV.INTENSET.bit.MC0 = 1; + break; + case 1: + TIMER_0_DEV.INTFLAG.bit.MC1 = 1; + TIMER_0_DEV.CC[1].reg = value; + TIMER_0_DEV.INTENSET.bit.MC1 = 1; + break; + default: + return -1; + } break; - default: - return -1; - } - break; #endif #if TIMER_1_EN - case TIMER_1: - /* set timeout value */ - switch (channel) { - case 0: - TIMER_1_DEV.INTFLAG.bit.MC0 = 1; - TIMER_1_DEV.CC[0].reg = value; - TIMER_1_DEV.INTENSET.bit.MC0 = 1; - break; - case 1: - TIMER_1_DEV.INTFLAG.bit.MC1 = 1; - TIMER_1_DEV.CC[1].reg = value; - TIMER_1_DEV.INTENSET.bit.MC1 = 1; + case TIMER_1: + /* set timeout value */ + switch (channel) { + case 0: + TIMER_1_DEV.INTFLAG.bit.MC0 = 1; + TIMER_1_DEV.CC[0].reg = value; + TIMER_1_DEV.INTENSET.bit.MC0 = 1; + break; + case 1: + TIMER_1_DEV.INTFLAG.bit.MC1 = 1; + TIMER_1_DEV.CC[1].reg = value; + TIMER_1_DEV.INTENSET.bit.MC1 = 1; + break; + default: + return -1; + } break; +#endif + case TIMER_UNDEFINED: default: return -1; - } - break; -#endif - case TIMER_UNDEFINED: - default: - return -1; } return 1; @@ -188,40 +175,40 @@ int timer_clear(tim_t dev, int channel) /* get timer base register address */ switch (dev) { #if TIMER_0_EN - case TIMER_0: - switch (channel) { - case 0: - TIMER_0_DEV.INTFLAG.bit.MC0 = 1; - TIMER_0_DEV.INTENCLR.bit.MC0 = 1; - break; - case 1: - TIMER_0_DEV.INTFLAG.bit.MC1 = 1; - TIMER_0_DEV.INTENCLR.bit.MC1 = 1; + case TIMER_0: + switch (channel) { + case 0: + TIMER_0_DEV.INTFLAG.bit.MC0 = 1; + TIMER_0_DEV.INTENCLR.bit.MC0 = 1; + break; + case 1: + TIMER_0_DEV.INTFLAG.bit.MC1 = 1; + TIMER_0_DEV.INTENCLR.bit.MC1 = 1; + break; + default: + return -1; + } break; - default: - return -1; - } - break; #endif #if TIMER_1_EN - case TIMER_1: - switch (channel) { - case 0: - TIMER_1_DEV.INTFLAG.bit.MC0 = 1; - TIMER_1_DEV.INTENCLR.bit.MC0 = 1; - break; - case 1: - TIMER_1_DEV.INTFLAG.bit.MC1 = 1; - TIMER_1_DEV.INTENCLR.bit.MC1 = 1; + case TIMER_1: + switch (channel) { + case 0: + TIMER_1_DEV.INTFLAG.bit.MC0 = 1; + TIMER_1_DEV.INTENCLR.bit.MC0 = 1; + break; + case 1: + TIMER_1_DEV.INTFLAG.bit.MC1 = 1; + TIMER_1_DEV.INTENCLR.bit.MC1 = 1; + break; + default: + return -1; + } break; +#endif + case TIMER_UNDEFINED: default: return -1; - } - break; -#endif - case TIMER_UNDEFINED: - default: - return -1; } return 1; @@ -231,24 +218,22 @@ unsigned int timer_read(tim_t dev) { switch (dev) { #if TIMER_0_EN - case TIMER_0: - /* request syncronisation */ - TIMER_0_DEV.READREQ.reg = TC_READREQ_RREQ | TC_READREQ_ADDR(0x10); - while (TIMER_0_DEV.STATUS.bit.SYNCBUSY) {} - return TIMER_0_DEV.COUNT.reg; + case TIMER_0: + /* request syncronisation */ + TIMER_0_DEV.READREQ.reg = TC_READREQ_RREQ | TC_READREQ_ADDR(0x10); + while (TIMER_0_DEV.STATUS.bit.SYNCBUSY) {} + return TIMER_0_DEV.COUNT.reg; #endif #if TIMER_1_EN - case TIMER_1: - /* request syncronisation */ - TIMER_1_DEV.READREQ.reg = TC_READREQ_RREQ | TC_READREQ_ADDR(0x10); - while (TIMER_1_DEV.STATUS.bit.SYNCBUSY) {} - return TIMER_1_DEV.COUNT.reg; + case TIMER_1: + /* request syncronisation */ + TIMER_1_DEV.READREQ.reg = TC_READREQ_RREQ | TC_READREQ_ADDR(0x10); + while (TIMER_1_DEV.STATUS.bit.SYNCBUSY) {} + return TIMER_1_DEV.COUNT.reg; #endif - default: - return 0; + default: + return 0; } - - } void timer_stop(tim_t dev) @@ -322,12 +307,11 @@ void TIMER_0_ISR(void) config[TIMER_0].cb(config[TIMER_0].arg, 1); } } - + cortexm_isr_end(); } #endif /* TIMER_0_EN */ - #if TIMER_1_EN void TIMER_1_ISR(void) { @@ -345,7 +329,7 @@ void TIMER_1_ISR(void) config[TIMER_1].cb(config[TIMER_1].arg, 1); } } - + cortexm_isr_end(); } #endif /* TIMER_1_EN */