diff --git a/boards/arduino-zero/include/board.h b/boards/arduino-zero/include/board.h index d3e209a67872a..c9310a85fedf2 100644 --- a/boards/arduino-zero/include/board.h +++ b/boards/arduino-zero/include/board.h @@ -33,7 +33,7 @@ extern "C" { * @name xtimer configuration * @{ */ -#define XTIMER TIMER_DEV(1) +#define XTIMER_DEV TIMER_DEV(1) #define XTIMER_CHAN (0) /** @} */ diff --git a/boards/arduino-zero/include/periph_conf.h b/boards/arduino-zero/include/periph_conf.h index b3a64798ce701..09eed72b8c459 100644 --- a/boards/arduino-zero/include/periph_conf.h +++ b/boards/arduino-zero/include/periph_conf.h @@ -83,22 +83,44 @@ extern "C" { * @name Timer peripheral configuration * @{ */ -#define TIMER_NUMOF (2U) -#define TIMER_0_EN 1 -#define TIMER_1_EN 1 +static const tc32_conf_t timer_config[] = { + { /* Timer 0 - System Clock */ + .dev = TC3, + .irq = TC3_IRQn, + .pm_mask = PM_APBCMASK_TC3, + .gclk_ctrl = GCLK_CLKCTRL_ID_TCC2_TC3, +#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL + .gclk_src = GCLK_CLKCTRL_GEN(1), + .prescaler = TC_CTRLA_PRESCALER_DIV1, +#else + .gclk_src = GCLK_CLKCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER_DIV8, +#endif + .flags = TC_CTRLA_MODE_COUNT16, + }, + { /* Timer 1 */ + .dev = TC4, + .irq = TC4_IRQn, + .pm_mask = PM_APBCMASK_TC4 | PM_APBCMASK_TC5, + .gclk_ctrl = GCLK_CLKCTRL_ID_TC4_TC5, +#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL + .gclk_src = GCLK_CLKCTRL_GEN(1), + .prescaler = TC_CTRLA_PRESCALER_DIV1, +#else + .gclk_src = GCLK_CLKCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER_DIV8, +#endif + .flags = TC_CTRLA_MODE_COUNT32, + } +}; -/* 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 +#define TIMER_0_MAX_VALUE 0xffff -/* Timer 1 configuration */ -#define TIMER_1_DEV TC4->COUNT32 -#define TIMER_1_CHANNELS 2 -#define TIMER_1_MAX_VALUE (0xffffffff) +/* interrupt function name mapping */ +#define TIMER_0_ISR isr_tc3 #define TIMER_1_ISR isr_tc4 +#define TIMER_NUMOF (sizeof(timer_config) / sizeof(timer_config[0])) /** @} */ /** diff --git a/boards/common/arduino-mkr/include/periph_conf.h b/boards/common/arduino-mkr/include/periph_conf.h index 5949d249248bc..7df029386e988 100644 --- a/boards/common/arduino-mkr/include/periph_conf.h +++ b/boards/common/arduino-mkr/include/periph_conf.h @@ -81,21 +81,44 @@ extern "C" { * @name Timer peripheral configuration * @{ */ -#define TIMER_NUMOF (2U) -#define TIMER_0_EN 1 -#define TIMER_1_EN 1 +static const tc32_conf_t timer_config[] = { + { /* Timer 0 - System Clock */ + .dev = TC3, + .irq = TC3_IRQn, + .pm_mask = PM_APBCMASK_TC3, + .gclk_ctrl = GCLK_CLKCTRL_ID_TCC2_TC3, +#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL + .gclk_src = GCLK_CLKCTRL_GEN(1), + .prescaler = TC_CTRLA_PRESCALER_DIV1, +#else + .gclk_src = GCLK_CLKCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER_DIV8, +#endif + .flags = TC_CTRLA_MODE_COUNT16, + }, + { /* Timer 1 */ + .dev = TC4, + .irq = TC4_IRQn, + .pm_mask = PM_APBCMASK_TC4 | PM_APBCMASK_TC5, + .gclk_ctrl = GCLK_CLKCTRL_ID_TC4_TC5, +#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL + .gclk_src = GCLK_CLKCTRL_GEN(1), + .prescaler = TC_CTRLA_PRESCALER_DIV1, +#else + .gclk_src = GCLK_CLKCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER_DIV8, +#endif + .flags = TC_CTRLA_MODE_COUNT32, + } +}; -/* 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 +#define TIMER_0_MAX_VALUE 0xffff -/* Timer 1 configuration */ -#define TIMER_1_DEV TC4->COUNT32 -#define TIMER_1_CHANNELS 2 -#define TIMER_1_MAX_VALUE (0xffffffff) +/* interrupt function name mapping */ +#define TIMER_0_ISR isr_tc3 #define TIMER_1_ISR isr_tc4 + +#define TIMER_NUMOF (sizeof(timer_config) / sizeof(timer_config[0])) /** @} */ /** diff --git a/boards/common/saml1x/include/periph_conf.h b/boards/common/saml1x/include/periph_conf.h index b060916b5aa6e..56fbe2e3ebd2e 100644 --- a/boards/common/saml1x/include/periph_conf.h +++ b/boards/common/saml1x/include/periph_conf.h @@ -35,14 +35,23 @@ extern "C" { * @name Timer peripheral configuration * @{ */ -#define TIMER_NUMOF (1U) -#define TIMER_0_EN 1 +static const tc32_conf_t timer_config[] = { + { /* Timer 0 - System Clock */ + .dev = TC0, + .irq = TC0_IRQn, + .mclk = &MCLK->APBCMASK.reg, + .mclk_mask = MCLK_APBCMASK_TC0 | MCLK_APBCMASK_TC1, + .gclk_id = TC0_GCLK_ID, + .gclk_src = GCLK_PCHCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER(4), + .flags = TC_CTRLA_MODE_COUNT32, + } +}; /* Timer 0 configuration */ -#define TIMER_0_DEV TC0->COUNT32 -#define TIMER_0_CHANNELS 1 -#define TIMER_0_MAX_VALUE (0xffffffff) -#define TIMER_0_ISR isr_tc0 +#define TIMER_0_CHANNELS 2 +#define TIMER_0_ISR isr_tc0 +#define TIMER_NUMOF (sizeof(timer_config)/sizeof(timer_config[0])) /** @} */ /** diff --git a/boards/feather-m0/include/periph_conf.h b/boards/feather-m0/include/periph_conf.h index 61bdb06118eec..4fc23a1cd09f9 100644 --- a/boards/feather-m0/include/periph_conf.h +++ b/boards/feather-m0/include/periph_conf.h @@ -78,21 +78,44 @@ extern "C" { * @name Timer peripheral configuration * @{ */ -#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 +static const tc32_conf_t timer_config[] = { + { /* Timer 0 - System Clock */ + .dev = TC3, + .irq = TC3_IRQn, + .pm_mask = PM_APBCMASK_TC3, + .gclk_ctrl = GCLK_CLKCTRL_ID_TCC2_TC3, +#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL + .gclk_src = GCLK_CLKCTRL_GEN(1), + .prescaler = TC_CTRLA_PRESCALER_DIV1, +#else + .gclk_src = GCLK_CLKCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER_DIV8, +#endif + .flags = TC_CTRLA_MODE_COUNT16, + }, + { /* Timer 1 */ + .dev = TC4, + .irq = TC4_IRQn, + .pm_mask = PM_APBCMASK_TC4 | PM_APBCMASK_TC5, + .gclk_ctrl = GCLK_CLKCTRL_ID_TC4_TC5, +#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL + .gclk_src = GCLK_CLKCTRL_GEN(1), + .prescaler = TC_CTRLA_PRESCALER_DIV1, +#else + .gclk_src = GCLK_CLKCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER_DIV8, +#endif + .flags = TC_CTRLA_MODE_COUNT32, + } +}; + +#define TIMER_0_MAX_VALUE 0xffff -/* Timer 1 configuration */ -#define TIMER_1_DEV TC4->COUNT32 -#define TIMER_1_CHANNELS 2 -#define TIMER_1_MAX_VALUE (0xffffffff) +/* interrupt function name mapping */ +#define TIMER_0_ISR isr_tc3 #define TIMER_1_ISR isr_tc4 + +#define TIMER_NUMOF (sizeof(timer_config) / sizeof(timer_config[0])) /** @} */ /** diff --git a/boards/hamilton/include/periph_conf.h b/boards/hamilton/include/periph_conf.h index f1d2057ec3d4b..c1bf3c6c80573 100644 --- a/boards/hamilton/include/periph_conf.h +++ b/boards/hamilton/include/periph_conf.h @@ -113,21 +113,44 @@ extern "C" { * @name Timer peripheral configuration * @{ */ -#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 +static const tc32_conf_t timer_config[] = { + { /* Timer 0 - System Clock */ + .dev = TC3, + .irq = TC3_IRQn, + .pm_mask = PM_APBCMASK_TC3, + .gclk_ctrl = GCLK_CLKCTRL_ID_TCC2_TC3, +#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL + .gclk_src = GCLK_CLKCTRL_GEN(1), + .prescaler = TC_CTRLA_PRESCALER_DIV1, +#else + .gclk_src = GCLK_CLKCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER_DIV8, +#endif + .flags = TC_CTRLA_MODE_COUNT16, + }, + { /* Timer 1 */ + .dev = TC4, + .irq = TC4_IRQn, + .pm_mask = PM_APBCMASK_TC4 | PM_APBCMASK_TC5, + .gclk_ctrl = GCLK_CLKCTRL_ID_TC4_TC5, +#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL + .gclk_src = GCLK_CLKCTRL_GEN(1), + .prescaler = TC_CTRLA_PRESCALER_DIV1, +#else + .gclk_src = GCLK_CLKCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER_DIV8, +#endif + .flags = TC_CTRLA_MODE_COUNT32, + } +}; + +#define TIMER_0_MAX_VALUE 0xffff -/* Timer 1 configuration */ -#define TIMER_1_DEV TC4->COUNT32 -#define TIMER_1_CHANNELS 2 -#define TIMER_1_MAX_VALUE (0xffffffff) +/* interrupt function name mapping */ +#define TIMER_0_ISR isr_tc3 #define TIMER_1_ISR isr_tc4 + +#define TIMER_NUMOF (sizeof(timer_config) / sizeof(timer_config[0])) /** @} */ /** diff --git a/boards/samd21-xpro/include/board.h b/boards/samd21-xpro/include/board.h index 368cca7da50be..8b0c4b2395f54 100644 --- a/boards/samd21-xpro/include/board.h +++ b/boards/samd21-xpro/include/board.h @@ -32,7 +32,7 @@ extern "C" { #endif /** - * @name xtimer configuration + * @name xtimer configuration * @{ */ #define XTIMER_DEV TIMER_DEV(1) diff --git a/boards/samd21-xpro/include/periph_conf.h b/boards/samd21-xpro/include/periph_conf.h index b65ee51a2c5e1..ce3231ba4d97c 100644 --- a/boards/samd21-xpro/include/periph_conf.h +++ b/boards/samd21-xpro/include/periph_conf.h @@ -89,21 +89,44 @@ extern "C" { * @name Timer peripheral configuration * @{ */ -#define TIMER_NUMOF (2U) -#define TIMER_0_EN 1 -#define TIMER_1_EN 1 +static const tc32_conf_t timer_config[] = { + { /* Timer 0 - System Clock */ + .dev = TC3, + .irq = TC3_IRQn, + .pm_mask = PM_APBCMASK_TC3, + .gclk_ctrl = GCLK_CLKCTRL_ID_TCC2_TC3, +#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL + .gclk_src = GCLK_CLKCTRL_GEN(1), + .prescaler = TC_CTRLA_PRESCALER_DIV1, +#else + .gclk_src = GCLK_CLKCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER_DIV8, +#endif + .flags = TC_CTRLA_MODE_COUNT16, + }, + { /* Timer 1 */ + .dev = TC4, + .irq = TC4_IRQn, + .pm_mask = PM_APBCMASK_TC4 | PM_APBCMASK_TC5, + .gclk_ctrl = GCLK_CLKCTRL_ID_TC4_TC5, +#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL + .gclk_src = GCLK_CLKCTRL_GEN(1), + .prescaler = TC_CTRLA_PRESCALER_DIV1, +#else + .gclk_src = GCLK_CLKCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER_DIV8, +#endif + .flags = TC_CTRLA_MODE_COUNT32, + } +}; -/* 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 +#define TIMER_0_MAX_VALUE 0xffff -/* Timer 1 configuration */ -#define TIMER_1_DEV TC4->COUNT32 -#define TIMER_1_CHANNELS 2 -#define TIMER_1_MAX_VALUE (0xffffffff) +/* interrupt function name mapping */ +#define TIMER_0_ISR isr_tc3 #define TIMER_1_ISR isr_tc4 + +#define TIMER_NUMOF (sizeof(timer_config) / sizeof(timer_config[0])) /** @} */ /** diff --git a/boards/saml21-xpro/include/periph_conf.h b/boards/saml21-xpro/include/periph_conf.h index baeca4aa49362..95c4b8b2ed89d 100644 --- a/boards/saml21-xpro/include/periph_conf.h +++ b/boards/saml21-xpro/include/periph_conf.h @@ -38,14 +38,23 @@ extern "C" { * @name Timer peripheral configuration * @{ */ -#define TIMER_NUMOF (1U) -#define TIMER_0_EN 1 +static const tc32_conf_t timer_config[] = { + { /* Timer 0 - System Clock */ + .dev = TC0, + .irq = TC0_IRQn, + .mclk = &MCLK->APBCMASK.reg, + .mclk_mask = MCLK_APBCMASK_TC0 | MCLK_APBCMASK_TC1, + .gclk_id = TC0_GCLK_ID, + .gclk_src = GCLK_PCHCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER(4), + .flags = TC_CTRLA_MODE_COUNT32, + } +}; /* Timer 0 configuration */ -#define TIMER_0_DEV TC0->COUNT32 -#define TIMER_0_CHANNELS 1 -#define TIMER_0_MAX_VALUE (0xffffffff) -#define TIMER_0_ISR isr_tc0 +#define TIMER_0_CHANNELS 2 +#define TIMER_0_ISR isr_tc0 +#define TIMER_NUMOF (sizeof(timer_config)/sizeof(timer_config[0])) /** @} */ /** diff --git a/boards/samr21-xpro/include/periph_conf.h b/boards/samr21-xpro/include/periph_conf.h index 3f1894b0658c6..c405144baf5f6 100644 --- a/boards/samr21-xpro/include/periph_conf.h +++ b/boards/samr21-xpro/include/periph_conf.h @@ -89,21 +89,44 @@ extern "C" { * @name Timer peripheral configuration * @{ */ -#define TIMER_NUMOF (2U) -#define TIMER_0_EN 1 -#define TIMER_1_EN 1 +static const tc32_conf_t timer_config[] = { + { /* Timer 0 - System Clock */ + .dev = TC3, + .irq = TC3_IRQn, + .pm_mask = PM_APBCMASK_TC3, + .gclk_ctrl = GCLK_CLKCTRL_ID_TCC2_TC3, +#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL + .gclk_src = GCLK_CLKCTRL_GEN(1), + .prescaler = TC_CTRLA_PRESCALER_DIV1, +#else + .gclk_src = GCLK_CLKCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER_DIV8, +#endif + .flags = TC_CTRLA_MODE_COUNT16, + }, + { /* Timer 1 */ + .dev = TC4, + .irq = TC4_IRQn, + .pm_mask = PM_APBCMASK_TC4 | PM_APBCMASK_TC5, + .gclk_ctrl = GCLK_CLKCTRL_ID_TC4_TC5, +#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL + .gclk_src = GCLK_CLKCTRL_GEN(1), + .prescaler = TC_CTRLA_PRESCALER_DIV1, +#else + .gclk_src = GCLK_CLKCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER_DIV8, +#endif + .flags = TC_CTRLA_MODE_COUNT32, + } +}; -/* 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 +#define TIMER_0_MAX_VALUE 0xffff -/* Timer 1 configuration */ -#define TIMER_1_DEV TC4->COUNT32 -#define TIMER_1_CHANNELS 2 -#define TIMER_1_MAX_VALUE (0xffffffff) +/* interrupt function name mapping */ +#define TIMER_0_ISR isr_tc3 #define TIMER_1_ISR isr_tc4 + +#define TIMER_NUMOF (sizeof(timer_config) / sizeof(timer_config[0])) /** @} */ /** diff --git a/boards/samr30-xpro/include/periph_conf.h b/boards/samr30-xpro/include/periph_conf.h index 4401c4d320d7a..1ff3d224ef767 100644 --- a/boards/samr30-xpro/include/periph_conf.h +++ b/boards/samr30-xpro/include/periph_conf.h @@ -34,14 +34,23 @@ extern "C" { * @name Timer peripheral configuration * @{ */ -#define TIMER_NUMOF (1U) -#define TIMER_0_EN 1 +static const tc32_conf_t timer_config[] = { + { /* Timer 0 - System Clock */ + .dev = TC0, + .irq = TC0_IRQn, + .mclk = &MCLK->APBCMASK.reg, + .mclk_mask = MCLK_APBCMASK_TC0 | MCLK_APBCMASK_TC1, + .gclk_id = TC0_GCLK_ID, + .gclk_src = GCLK_PCHCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER(4), + .flags = TC_CTRLA_MODE_COUNT32, + } +}; /* Timer 0 configuration */ -#define TIMER_0_DEV TC0->COUNT32 -#define TIMER_0_CHANNELS 1 -#define TIMER_0_MAX_VALUE (0xffffffff) -#define TIMER_0_ISR isr_tc0 +#define TIMER_0_CHANNELS 2 +#define TIMER_0_ISR isr_tc0 +#define TIMER_NUMOF (sizeof(timer_config)/sizeof(timer_config[0])) /** @} */ /** diff --git a/boards/sensebox_samd21/include/periph_conf.h b/boards/sensebox_samd21/include/periph_conf.h index e0c844e1e16d7..e1d21a97af73c 100644 --- a/boards/sensebox_samd21/include/periph_conf.h +++ b/boards/sensebox_samd21/include/periph_conf.h @@ -79,21 +79,44 @@ extern "C" { * @name Timer peripheral configuration * @{ */ -#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 +static const tc32_conf_t timer_config[] = { + { /* Timer 0 - System Clock */ + .dev = TC3, + .irq = TC3_IRQn, + .pm_mask = PM_APBCMASK_TC3, + .gclk_ctrl = GCLK_CLKCTRL_ID_TCC2_TC3, +#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL + .gclk_src = GCLK_CLKCTRL_GEN(1), + .prescaler = TC_CTRLA_PRESCALER_DIV1, +#else + .gclk_src = GCLK_CLKCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER_DIV8, +#endif + .flags = TC_CTRLA_MODE_COUNT16, + }, + { /* Timer 1 */ + .dev = TC4, + .irq = TC4_IRQn, + .pm_mask = PM_APBCMASK_TC4 | PM_APBCMASK_TC5, + .gclk_ctrl = GCLK_CLKCTRL_ID_TC4_TC5, +#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL + .gclk_src = GCLK_CLKCTRL_GEN(1), + .prescaler = TC_CTRLA_PRESCALER_DIV1, +#else + .gclk_src = GCLK_CLKCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER_DIV8, +#endif + .flags = TC_CTRLA_MODE_COUNT32, + } +}; + +#define TIMER_0_MAX_VALUE 0xffff -/* Timer 1 configuration */ -#define TIMER_1_DEV TC4->COUNT32 -#define TIMER_1_CHANNELS 2 -#define TIMER_1_MAX_VALUE (0xffffffff) +/* interrupt function name mapping */ +#define TIMER_0_ISR isr_tc3 #define TIMER_1_ISR isr_tc4 + +#define TIMER_NUMOF (sizeof(timer_config) / sizeof(timer_config[0])) /** @} */ /** diff --git a/boards/sodaq-autonomo/include/periph_conf.h b/boards/sodaq-autonomo/include/periph_conf.h index ca0a02a9f188d..d713e2508687e 100644 --- a/boards/sodaq-autonomo/include/periph_conf.h +++ b/boards/sodaq-autonomo/include/periph_conf.h @@ -79,21 +79,44 @@ extern "C" { * @name Timer peripheral configuration * @{ */ -#define TIMER_NUMOF (2U) -#define TIMER_0_EN 1 -#define TIMER_1_EN 1 +static const tc32_conf_t timer_config[] = { + { /* Timer 0 - System Clock */ + .dev = TC3, + .irq = TC3_IRQn, + .pm_mask = PM_APBCMASK_TC3, + .gclk_ctrl = GCLK_CLKCTRL_ID_TCC2_TC3, +#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL + .gclk_src = GCLK_CLKCTRL_GEN(1), + .prescaler = TC_CTRLA_PRESCALER_DIV1, +#else + .gclk_src = GCLK_CLKCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER_DIV8, +#endif + .flags = TC_CTRLA_MODE_COUNT16, + }, + { /* Timer 1 */ + .dev = TC4, + .irq = TC4_IRQn, + .pm_mask = PM_APBCMASK_TC4 | PM_APBCMASK_TC5, + .gclk_ctrl = GCLK_CLKCTRL_ID_TC4_TC5, +#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL + .gclk_src = GCLK_CLKCTRL_GEN(1), + .prescaler = TC_CTRLA_PRESCALER_DIV1, +#else + .gclk_src = GCLK_CLKCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER_DIV8, +#endif + .flags = TC_CTRLA_MODE_COUNT32, + } +}; -/* 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 +#define TIMER_0_MAX_VALUE 0xffff -/* Timer 1 configuration */ -#define TIMER_1_DEV TC4->COUNT32 -#define TIMER_1_CHANNELS 2 -#define TIMER_1_MAX_VALUE (0xffffffff) +/* interrupt function name mapping */ +#define TIMER_0_ISR isr_tc3 #define TIMER_1_ISR isr_tc4 + +#define TIMER_NUMOF (sizeof(timer_config) / sizeof(timer_config[0])) /** @} */ /** diff --git a/boards/sodaq-explorer/include/board.h b/boards/sodaq-explorer/include/board.h index 437c354d122b6..e727f09fb72ce 100644 --- a/boards/sodaq-explorer/include/board.h +++ b/boards/sodaq-explorer/include/board.h @@ -26,13 +26,6 @@ extern "C" { #endif -/** - * @name xtimer configuration - * @{ - */ -#define XTIMER_WIDTH (16) -/** @} */ - /** * @name LED pin definitions and handlers * @{ diff --git a/boards/sodaq-explorer/include/periph_conf.h b/boards/sodaq-explorer/include/periph_conf.h index 2cbe5761d066a..2415d46d666fd 100644 --- a/boards/sodaq-explorer/include/periph_conf.h +++ b/boards/sodaq-explorer/include/periph_conf.h @@ -76,21 +76,27 @@ extern "C" { * @name Timer peripheral configuration * @{ */ -#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 +static const tc32_conf_t timer_config[] = { + { /* Timer 0 - System Clock */ + .dev = TC4, + .irq = TC4_IRQn, + .pm_mask = PM_APBCMASK_TC4 | PM_APBCMASK_TC5, + .gclk_ctrl = GCLK_CLKCTRL_ID_TC4_TC5, +#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL + .gclk_src = GCLK_CLKCTRL_GEN(1), + .prescaler = TC_CTRLA_PRESCALER_DIV1, +#else + .gclk_src = GCLK_CLKCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER_DIV8, +#endif + .flags = TC_CTRLA_MODE_COUNT32, + } +}; + +/* interrupt function name mapping */ +#define TIMER_0_ISR isr_tc4 + +#define TIMER_NUMOF (sizeof(timer_config) / sizeof(timer_config[0])) /** @} */ /** diff --git a/boards/sodaq-one/include/periph_conf.h b/boards/sodaq-one/include/periph_conf.h index 5c4cc4c78a813..fc331aecad68a 100644 --- a/boards/sodaq-one/include/periph_conf.h +++ b/boards/sodaq-one/include/periph_conf.h @@ -79,21 +79,44 @@ extern "C" { * @name Timer peripheral configuration * @{ */ -#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 +static const tc32_conf_t timer_config[] = { + { /* Timer 0 - System Clock */ + .dev = TC3, + .irq = TC3_IRQn, + .pm_mask = PM_APBCMASK_TC3, + .gclk_ctrl = GCLK_CLKCTRL_ID_TCC2_TC3, +#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL + .gclk_src = GCLK_CLKCTRL_GEN(1), + .prescaler = TC_CTRLA_PRESCALER_DIV1, +#else + .gclk_src = GCLK_CLKCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER_DIV8, +#endif + .flags = TC_CTRLA_MODE_COUNT16, + }, + { /* Timer 1 */ + .dev = TC4, + .irq = TC4_IRQn, + .pm_mask = PM_APBCMASK_TC4 | PM_APBCMASK_TC5, + .gclk_ctrl = GCLK_CLKCTRL_ID_TC4_TC5, +#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL + .gclk_src = GCLK_CLKCTRL_GEN(1), + .prescaler = TC_CTRLA_PRESCALER_DIV1, +#else + .gclk_src = GCLK_CLKCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER_DIV8, +#endif + .flags = TC_CTRLA_MODE_COUNT32, + } +}; + +#define TIMER_0_MAX_VALUE 0xffff -/* Timer 1 configuration */ -#define TIMER_1_DEV TC4->COUNT32 -#define TIMER_1_CHANNELS 2 -#define TIMER_1_MAX_VALUE (0xffffffff) +/* interrupt function name mapping */ +#define TIMER_0_ISR isr_tc3 #define TIMER_1_ISR isr_tc4 + +#define TIMER_NUMOF (sizeof(timer_config) / sizeof(timer_config[0])) /** @} */ /** diff --git a/boards/sodaq-sara-aff/include/periph_conf.h b/boards/sodaq-sara-aff/include/periph_conf.h index 65fe8070c35b8..320275387d549 100644 --- a/boards/sodaq-sara-aff/include/periph_conf.h +++ b/boards/sodaq-sara-aff/include/periph_conf.h @@ -81,21 +81,44 @@ extern "C" { * @name Timer peripheral configuration * @{ */ -#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 +static const tc32_conf_t timer_config[] = { + { /* Timer 0 - System Clock */ + .dev = TC3, + .irq = TC3_IRQn, + .pm_mask = PM_APBCMASK_TC3, + .gclk_ctrl = GCLK_CLKCTRL_ID_TCC2_TC3, +#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL + .gclk_src = GCLK_CLKCTRL_GEN(1), + .prescaler = TC_CTRLA_PRESCALER_DIV1, +#else + .gclk_src = GCLK_CLKCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER_DIV8, +#endif + .flags = TC_CTRLA_MODE_COUNT16, + }, + { /* Timer 1 */ + .dev = TC4, + .irq = TC4_IRQn, + .pm_mask = PM_APBCMASK_TC4 | PM_APBCMASK_TC5, + .gclk_ctrl = GCLK_CLKCTRL_ID_TC4_TC5, +#if CLOCK_USE_PLL || CLOCK_USE_XOSC32_DFLL + .gclk_src = GCLK_CLKCTRL_GEN(1), + .prescaler = TC_CTRLA_PRESCALER_DIV1, +#else + .gclk_src = GCLK_CLKCTRL_GEN(0), + .prescaler = TC_CTRLA_PRESCALER_DIV8, +#endif + .flags = TC_CTRLA_MODE_COUNT32, + } +}; + +#define TIMER_0_MAX_VALUE 0xffff -/* Timer 1 configuration */ -#define TIMER_1_DEV TC4->COUNT32 -#define TIMER_1_CHANNELS 2 -#define TIMER_1_MAX_VALUE (0xffffffff) +/* interrupt function name mapping */ +#define TIMER_0_ISR isr_tc3 #define TIMER_1_ISR isr_tc4 + +#define TIMER_NUMOF (sizeof(timer_config) / sizeof(timer_config[0])) /** @} */ /** diff --git a/cpu/sam0_common/include/periph_cpu_common.h b/cpu/sam0_common/include/periph_cpu_common.h index 2472337e14d09..215ff32e1cb21 100644 --- a/cpu/sam0_common/include/periph_cpu_common.h +++ b/cpu/sam0_common/include/periph_cpu_common.h @@ -289,6 +289,25 @@ typedef struct { uint8_t flags; /**< allow SERCOM to run in standby mode */ } i2c_conf_t; +/** + * @brief Timer device configuration + */ +typedef struct { + Tc *dev; /**< pointer to the used Timer device */ + IRQn_Type irq; /**< IRQ# of Timer Interrupt */ +#ifdef MCLK + volatile uint32_t *mclk;/**< Pointer to MCLK->APBxMASK.reg */ + uint32_t mclk_mask; /**< MCLK_APBxMASK bits to enable Timer */ + uint16_t gclk_id; /**< TCn_GCLK_ID */ +#else + uint32_t pm_mask; /**< PM_APBCMASK bits to enable Timer */ + uint16_t gclk_ctrl; /**< GCLK_CLKCTRL_ID for the Timer */ +#endif + uint16_t gclk_src; /**< GCLK source which supplys Timer */ + uint16_t prescaler; /**< prescaler used by the Timer */ + uint16_t flags; /**< flags for CTRA, e.g. TC_CTRLA_MODE_COUNT32 */ +} tc32_conf_t; + /** * @brief Set up alternate function (PMUX setting) for a PORT pin * diff --git a/cpu/sam0_common/periph/timer.c b/cpu/sam0_common/periph/timer.c new file mode 100644 index 0000000000000..15e6f5d430b3b --- /dev/null +++ b/cpu/sam0_common/periph/timer.c @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2019 ML!PA Consulting GmbH + * + * + * 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_sam0_common + * @ingroup drivers_periph_timer + * @{ + * + * @file timer.c + * @brief Low-level timer driver implementation + * + * @author Benjamin Valentin + * + * @} + */ + +#include +#include + +#include "board.h" +#include "cpu.h" + +#include "periph/timer.h" +#include "periph_conf.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +/** + * @brief Timer state memory + */ +static timer_isr_ctx_t config[TIMER_NUMOF]; + +static inline TcCount32 *dev(tim_t tim) +{ + return &timer_config[tim].dev->COUNT32; +} + +static inline TcCount16 *dev16(tim_t tim) +{ + return &timer_config[tim].dev->COUNT16; +} + +static inline TcCount8 *dev8(tim_t tim) +{ + return &timer_config[tim].dev->COUNT8; +} + +static inline void wait_synchronization(tim_t tim) +{ +#if defined(TC_SYNCBUSY_MASK) + /* SYNCBUSY is a register */ + while ((dev(tim)->SYNCBUSY.reg & TC_SYNCBUSY_MASK) != 0) {} +#elif defined(TC_STATUS_SYNCBUSY) + /* SYNCBUSY is a bit */ + while ((dev(tim)->STATUS.reg & TC_STATUS_SYNCBUSY) != 0) {} +#else +#error Unsupported device +#endif +} + +/* enable timer interrupts */ +static inline void _irq_enable(tim_t tim) +{ + NVIC_EnableIRQ(timer_config[tim].irq); +} + +/** + * @brief Setup the given timer + */ +int timer_init(tim_t tim, unsigned long freq, timer_cb_t cb, void *arg) +{ + const tc32_conf_t *cfg = &timer_config[tim]; + + /* make sure given device is valid */ + if (tim >= TIMER_NUMOF) { + return -1; + } + + /* at the moment, the timer can only run at 1MHz */ + if (freq != 1000000ul) { + return -1; + } + + /* make sure the timer is not running */ + timer_stop(tim); + +#ifdef MCLK + GCLK->PCHCTRL[cfg->gclk_id].reg = cfg->gclk_src | GCLK_PCHCTRL_CHEN; + *cfg->mclk |= cfg->mclk_mask; +#else + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | cfg->gclk_src | cfg->gclk_ctrl; + PM->APBCMASK.reg |= cfg->pm_mask; +#endif + + /* reset the timer */ + dev(tim)->CTRLA.bit.SWRST = 1; + while (dev(tim)->CTRLA.bit.SWRST) {} + + dev(tim)->CTRLA.reg = cfg->flags +#ifdef TC_CTRLA_WAVEGEN_NFRQ + | TC_CTRLA_WAVEGEN_NFRQ +#endif + | cfg->prescaler + | TC_CTRLA_PRESCSYNC_RESYNC; + +#ifdef TC_WAVE_WAVEGEN_NFRQ + dev(tim)->WAVE.reg = TC_WAVE_WAVEGEN_NFRQ; +#endif + + wait_synchronization(tim); + + dev(tim)->INTENCLR.reg = TC_INTENCLR_MASK; + + /* save callback */ + config[tim].cb = cb; + config[tim].arg = arg; + + timer_start(tim); + + /* enable interrupts for given timer */ + _irq_enable(tim); + + return 0; +} + +static void _set_cc(tim_t tim, int cc, unsigned int value) +{ + const uint16_t flags = timer_config[tim].flags; + + if (flags & TC_CTRLA_MODE_COUNT32) { + dev(tim)->CC[cc].reg = value; + return; + } + + if (flags & TC_CTRLA_MODE_COUNT8) { + dev8(tim)->CC[cc].reg = value; + return; + } + + /* 16 bit is the default */ + dev16(tim)->CC[cc].reg = value; +} + +int timer_set_absolute(tim_t tim, int channel, unsigned int value) +{ + DEBUG("Setting timer %i channel %i to %i\n", tim, channel, value); + + /* set timeout value */ + switch (channel) { + case 0: + dev(tim)->INTFLAG.reg = TC_INTFLAG_MC0; + _set_cc(tim, 0, value); + dev(tim)->INTENSET.bit.MC0 = 1; + break; + case 1: + dev(tim)->INTFLAG.reg = TC_INTFLAG_MC1; + _set_cc(tim, 1, value); + dev(tim)->INTENSET.bit.MC1 = 1; + break; + default: + return -1; + } + + return 1; +} + +int timer_clear(tim_t tim, int channel) +{ + switch (channel) { + case 0: + dev(tim)->INTFLAG.reg = TC_INTFLAG_MC0; + dev(tim)->INTENCLR.bit.MC0 = 1; + break; + case 1: + dev(tim)->INTFLAG.reg = TC_INTFLAG_MC1; + dev(tim)->INTENCLR.bit.MC1 = 1; + break; + default: + return -1; + } + + return 1; +} + +unsigned int timer_read(tim_t tim) +{ + /* WORKAROUND to prevent being stuck there if timer not init */ + if (!dev(tim)->CTRLA.bit.ENABLE) { + return 0; + } + + /* request syncronisation */ +#ifdef TC_CTRLBSET_CMD_READSYNC_Val + dev(tim)->CTRLBSET.bit.CMD = TC_CTRLBSET_CMD_READSYNC_Val; +#else + dev(tim)->READREQ.reg = TC_READREQ_RREQ | TC_READREQ_ADDR(0x10); +#endif + wait_synchronization(tim); + + return dev(tim)->COUNT.reg; +} + +void timer_stop(tim_t tim) +{ + dev(tim)->CTRLA.bit.ENABLE = 0; +} + +void timer_start(tim_t tim) +{ + dev(tim)->CTRLA.bit.ENABLE = 1; +} + +static inline void timer_isr(tim_t tim) +{ + TcCount32 *tc = dev(tim); + uint8_t status = tc->INTFLAG.reg; + + /* Acknowledge all interrupts */ + tc->INTFLAG.reg = status; + + if ((status & TC_INTFLAG_MC0) && tc->INTENSET.bit.MC0) { + tc->INTENCLR.reg = TC_INTENCLR_MC0; + if (config[tim].cb) { + config[tim].cb(config[tim].arg, 0); + } + } + if ((status & TC_INTFLAG_MC1) && tc->INTENSET.bit.MC1) { + tc->INTENCLR.reg = TC_INTENCLR_MC1; + if (config[tim].cb) { + config[tim].cb(config[tim].arg, 1); + } + } +} + +#ifdef TIMER_0_ISR +void TIMER_0_ISR(void) +{ + timer_isr(0); + cortexm_isr_end(); +} +#endif +#ifdef TIMER_1_ISR +void TIMER_1_ISR(void) +{ + timer_isr(1); + cortexm_isr_end(); +} +#endif +#ifdef TIMER_2_ISR +void TIMER_2_ISR(void) +{ + timer_isr(2); + cortexm_isr_end(); +} +#endif +#ifdef TIMER_3_ISR +void TIMER_3_ISR(void) +{ + timer_isr(3); + cortexm_isr_end(); +} +#endif diff --git a/cpu/samd21/periph/timer.c b/cpu/samd21/periph/timer.c deleted file mode 100644 index 689d9bc73387f..0000000000000 --- a/cpu/samd21/periph/timer.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright (C) 2014 Freie Universität Berlin - * - * 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 - * @ingroup drivers_periph_timer - * @{ - * - * @file - * @brief Low-level timer driver implementation - * - * @author Thomas Eichinger - * - * @} - */ - -#include -#include - -#include "board.h" -#include "cpu.h" - -#include "periph/timer.h" -#include "periph_conf.h" - -#define ENABLE_DEBUG (0) -#include "debug.h" - -/** - * @brief Timer state memory - */ -static timer_isr_ctx_t config[TIMER_NUMOF]; - -/* enable timer interrupts */ -static inline void _irq_enable(tim_t dev); - -/** - * @brief Setup the given timer - */ -int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg) -{ - /* at the moment, the timer can only run at 1MHz */ - if (freq != 1000000ul) { - 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 */; - /* 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))); - 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 - 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; -#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; -#endif - case TIMER_UNDEFINED: - default: - return -1; - } - - /* save callback */ - config[dev].cb = cb; - config[dev].arg = arg; - - /* enable interrupts for given timer */ - _irq_enable(dev); - - timer_start(dev); - - return 0; -} - -int timer_set_absolute(tim_t dev, int channel, unsigned int value) -{ - DEBUG("Setting timer %i channel %i to %i\n", dev, channel, 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.reg = TC_INTFLAG_MC0; - TIMER_0_DEV.CC[0].reg = value; - TIMER_0_DEV.INTENSET.reg = TC_INTENSET_MC0; - break; - case 1: - TIMER_0_DEV.INTFLAG.reg = TC_INTFLAG_MC1; - TIMER_0_DEV.CC[1].reg = value; - TIMER_0_DEV.INTENSET.reg = TC_INTENSET_MC1; - break; - default: - return -1; - } - break; -#endif -#if TIMER_1_EN - case TIMER_1: - /* set timeout value */ - switch (channel) { - case 0: - TIMER_1_DEV.INTFLAG.reg = TC_INTFLAG_MC0; - TIMER_1_DEV.CC[0].reg = value; - TIMER_1_DEV.INTENSET.reg = TC_INTENSET_MC0; - break; - case 1: - TIMER_1_DEV.INTFLAG.reg = TC_INTFLAG_MC1; - TIMER_1_DEV.CC[1].reg = value; - TIMER_1_DEV.INTENSET.reg = TC_INTENSET_MC1; - break; - default: - return -1; - } - break; -#endif - case TIMER_UNDEFINED: - default: - return -1; - } - - return 1; -} - -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.reg = TC_INTFLAG_MC0; - TIMER_0_DEV.INTENCLR.reg = TC_INTENCLR_MC0; - break; - case 1: - TIMER_0_DEV.INTFLAG.reg = TC_INTFLAG_MC1; - TIMER_0_DEV.INTENCLR.reg = TC_INTENCLR_MC1; - break; - default: - return -1; - } - break; -#endif -#if TIMER_1_EN - case TIMER_1: - switch (channel) { - case 0: - TIMER_1_DEV.INTFLAG.reg = TC_INTFLAG_MC0; - TIMER_1_DEV.INTENCLR.reg = TC_INTENCLR_MC0; - break; - case 1: - TIMER_1_DEV.INTFLAG.reg = TC_INTFLAG_MC1; - TIMER_1_DEV.INTENCLR.reg = TC_INTENCLR_MC1; - break; - default: - return -1; - } - break; -#endif - case TIMER_UNDEFINED: - default: - return -1; - } - - return 1; -} - -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; -#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; -#endif - default: - return 0; - } - - -} - -void timer_stop(tim_t dev) -{ - switch (dev) { -#if TIMER_0_EN - case TIMER_0: - TIMER_0_DEV.CTRLA.bit.ENABLE = 0; - break; -#endif -#if TIMER_1_EN - case TIMER_1: - TIMER_1_DEV.CTRLA.bit.ENABLE = 0; - break; -#endif - case TIMER_UNDEFINED: - break; - } -} - -void timer_start(tim_t dev) -{ - switch (dev) { -#if TIMER_0_EN - case TIMER_0: - TIMER_0_DEV.CTRLA.bit.ENABLE = 1; - break; -#endif -#if TIMER_1_EN - case TIMER_1: - TIMER_1_DEV.CTRLA.bit.ENABLE = 1; - break; -#endif - case TIMER_UNDEFINED: - break; - } -} - -static inline void _irq_enable(tim_t dev) -{ - switch (dev) { -#if TIMER_0_EN - case TIMER_0: - NVIC_EnableIRQ(TC3_IRQn); - break; -#endif -#if TIMER_1_EN - case TIMER_1: - NVIC_EnableIRQ(TC4_IRQn); - break; -#endif - case TIMER_UNDEFINED: - break; - } -} - -#if TIMER_0_EN -void TIMER_0_ISR(void) -{ - if (TIMER_0_DEV.INTFLAG.bit.MC0 && TIMER_0_DEV.INTENSET.bit.MC0) { - TIMER_0_DEV.INTFLAG.reg = TC_INTFLAG_MC0; - TIMER_0_DEV.INTENCLR.reg = TC_INTENCLR_MC0; - if(config[TIMER_0].cb) { - config[TIMER_0].cb(config[TIMER_0].arg, 0); - } - } - if (TIMER_0_DEV.INTFLAG.bit.MC1 && TIMER_0_DEV.INTENSET.bit.MC1) { - TIMER_0_DEV.INTFLAG.reg = TC_INTFLAG_MC1; - TIMER_0_DEV.INTENCLR.reg = TC_INTENCLR_MC1; - if(config[TIMER_0].cb) { - 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) -{ - if (TIMER_1_DEV.INTFLAG.bit.MC0 && TIMER_1_DEV.INTENSET.bit.MC0) { - TIMER_1_DEV.INTFLAG.reg = TC_INTFLAG_MC0; - TIMER_1_DEV.INTENCLR.reg = TC_INTENCLR_MC0; - if (config[TIMER_1].cb) { - config[TIMER_1].cb(config[TIMER_1].arg, 0); - } - } - if (TIMER_1_DEV.INTFLAG.bit.MC1 && TIMER_1_DEV.INTENSET.bit.MC1) { - TIMER_1_DEV.INTFLAG.reg = TC_INTFLAG_MC1; - TIMER_1_DEV.INTENCLR.reg = TC_INTENCLR_MC1; - if(config[TIMER_1].cb) { - config[TIMER_1].cb(config[TIMER_1].arg, 1); - } - } - - cortexm_isr_end(); -} -#endif /* TIMER_1_EN */ diff --git a/cpu/saml1x/periph/timer.c b/cpu/saml1x/periph/timer.c deleted file mode 100644 index bf0a13f4b1753..0000000000000 --- a/cpu/saml1x/periph/timer.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (C) 2018 Mesotic SAS - * - * - * 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_saml1x - * @ingroup drivers_periph_timer - * @{ - * - * @file timer.c - * @brief Low-level timer driver implementation - * - * @author Dylan Laduranty - * - * @} - */ - -#include -#include - -#include "board.h" -#include "cpu.h" - -#include "periph/timer.h" -#include "periph_conf.h" - -#define ENABLE_DEBUG (0) -#include "debug.h" - -/** - * @brief Timer state memory - */ -static timer_isr_ctx_t config[TIMER_NUMOF]; - -/* enable timer interrupts */ -static inline void _irq_enable(tim_t dev); - - -/** - * @brief Setup the given timer - */ -int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg) -{ - /* at the moment, the timer can only run at 1MHz */ - if (freq != 1000000ul) { - return -1; - } - /* configure GCLK0 to feed TC0 & TC1*/ - GCLK->PCHCTRL[TC0_GCLK_ID].reg |= GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK0; - while (!(GCLK->PCHCTRL[TC0_GCLK_ID].reg & GCLK_PCHCTRL_CHEN)) {} - - /* select the timer and enable the timer specific peripheral clocks */ - switch (dev) { -#if TIMER_0_EN - case TIMER_0: - if (TIMER_0_DEV.CTRLA.bit.ENABLE) { - return 0; - } - MCLK->APBCMASK.reg |= MCLK_APBCMASK_TC0; - /* reset timer */ - TIMER_0_DEV.CTRLA.bit.SWRST = 1; - while (TIMER_0_DEV.SYNCBUSY.bit.SWRST) {} - TIMER_0_DEV.CTRLA.reg |= TC_CTRLA_MODE_COUNT32 | /* choosing 32 bit mode */ - TC_CTRLA_PRESCALER(4) | /* sourced by 4MHz with Presc 4 results in 1MHz*/ - TC_CTRLA_PRESCSYNC_RESYNC; /* initial prescaler resync */ - break; -#endif - case TIMER_UNDEFINED: - default: - return -1; - } - - /* save callback */ - config[dev].cb = cb; - config[dev].arg = arg; - - /* enable interrupts for given timer */ - _irq_enable(dev); - - timer_start(dev); - - return 0; -} - -int timer_set_absolute(tim_t dev, int channel, unsigned int value) -{ - DEBUG("Setting timer %i channel %i to %i\n", dev, channel, 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.reg |= TC_INTFLAG_MC0; - TIMER_0_DEV.CC[0].reg = value; - TIMER_0_DEV.INTENSET.bit.MC0 = 1; - break; - case 1: - TIMER_0_DEV.INTFLAG.reg |= TC_INTFLAG_MC1; - TIMER_0_DEV.CC[1].reg = value; - TIMER_0_DEV.INTENSET.bit.MC1 = 1; - break; - default: - return -1; - } - break; -#endif - case TIMER_UNDEFINED: - default: - return -1; - } - - return 1; -} - -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.reg |= TC_INTFLAG_MC0; - TIMER_0_DEV.INTENCLR.bit.MC0 = 1; - break; - case 1: - TIMER_0_DEV.INTFLAG.reg |= TC_INTFLAG_MC1; - TIMER_0_DEV.INTENCLR.bit.MC1 = 1; - break; - default: - return -1; - } - break; -#endif - case TIMER_UNDEFINED: - default: - return -1; - } - - return 1; -} - -unsigned int timer_read(tim_t dev) -{ - switch (dev) { -#if TIMER_0_EN - case TIMER_0: - /* request syncronisation */ - TIMER_0_DEV.CTRLBSET.bit.CMD = TC_CTRLBSET_CMD_READSYNC_Val; - while (TIMER_0_DEV.SYNCBUSY.bit.CTRLB) { - /* WORKAROUND to prevent being stuck there if timer not init */ - if(!TIMER_0_DEV.CTRLA.bit.ENABLE) { - return 0; - } - } - return TIMER_0_DEV.COUNT.reg; -#endif - default: - return 0; - } - - -} - -void timer_stop(tim_t dev) -{ - switch (dev) { -#if TIMER_0_EN - case TIMER_0: - TIMER_0_DEV.CTRLA.bit.ENABLE = 0; - break; -#endif - case TIMER_UNDEFINED: - break; - } -} - -void timer_start(tim_t dev) -{ - switch (dev) { -#if TIMER_0_EN - case TIMER_0: - TIMER_0_DEV.CTRLA.bit.ENABLE = 1; - break; -#endif - case TIMER_UNDEFINED: - break; - } -} - -static inline void _irq_enable(tim_t dev) -{ - switch (dev) { -#if TIMER_0_EN - case TIMER_0: - NVIC_EnableIRQ(TC0_IRQn); - break; -#endif - case TIMER_UNDEFINED: - break; - } -} - -#if TIMER_0_EN -void TIMER_0_ISR(void) -{ - if (TIMER_0_DEV.INTFLAG.bit.MC0 && TIMER_0_DEV.INTENSET.bit.MC0) { - if(config[TIMER_0].cb) { - TIMER_0_DEV.INTFLAG.reg |= TC_INTFLAG_MC0; - TIMER_0_DEV.INTENCLR.reg = TC_INTENCLR_MC0; - config[TIMER_0].cb(config[TIMER_0].arg, 0); - } - } - else if (TIMER_0_DEV.INTFLAG.bit.MC1 && TIMER_0_DEV.INTENSET.bit.MC1) { - if(config[TIMER_0].cb) { - TIMER_0_DEV.INTFLAG.reg |= TC_INTFLAG_MC1; - TIMER_0_DEV.INTENCLR.reg = TC_INTENCLR_MC1; - config[TIMER_0].cb(config[TIMER_0].arg, 1); - } - } - cortexm_isr_end(); -} -#endif /* TIMER_0_EN */ diff --git a/cpu/saml21/periph/timer.c b/cpu/saml21/periph/timer.c deleted file mode 100644 index 71449637f5ee3..0000000000000 --- a/cpu/saml21/periph/timer.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (C) 2015 Kaspar Schleiser - * 2015 FreshTemp, LLC. - * 2014 Freie Universität Berlin - * - * - * 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_saml21 - * @ingroup drivers_periph_timer - * @{ - * - * @file timer.c - * @brief Low-level timer driver implementation - * - * @author Thomas Eichinger - * @author Kaspar Schleiser - * - * @} - */ - -#include -#include - -#include "board.h" -#include "cpu.h" - -#include "periph/timer.h" -#include "periph_conf.h" - -#define ENABLE_DEBUG (0) -#include "debug.h" - -/** - * @brief Timer state memory - */ -static timer_isr_ctx_t config[TIMER_NUMOF]; - -/* enable timer interrupts */ -static inline void _irq_enable(tim_t dev); - -/** - * @brief Setup the given timer - */ -int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg) -{ - /* at the moment, the timer can only run at 1MHz */ - if (freq != 1000000ul) { - return -1; - } - /* configure GCLK0 to feed TC0 & TC1*/; - GCLK->PCHCTRL[TC0_GCLK_ID].reg |= GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN_GCLK0; - while (!(GCLK->PCHCTRL[TC0_GCLK_ID].reg & GCLK_PCHCTRL_CHEN)) {} - - /* select the timer and enable the timer specific peripheral clocks */ - switch (dev) { -#if TIMER_0_EN - case TIMER_0: - if (TIMER_0_DEV.CTRLA.bit.ENABLE) { - return 0; - } - MCLK->APBCMASK.reg |= MCLK_APBCMASK_TC0; - /* reset timer */ - TIMER_0_DEV.CTRLA.bit.SWRST = 1; - while (TIMER_0_DEV.SYNCBUSY.bit.SWRST) {} - TIMER_0_DEV.CTRLA.reg |= TC_CTRLA_MODE_COUNT32 | /* choosing 32 bit mode */ - TC_CTRLA_PRESCALER(4) | /* sourced by 4MHz with Presc 4 results in 1MHz*/ - TC_CTRLA_PRESCSYNC_RESYNC; /* initial prescaler resync */ - break; -#endif - case TIMER_UNDEFINED: - default: - return -1; - } - - /* save callback */ - config[dev].cb = cb; - config[dev].arg = arg; - - /* enable interrupts for given timer */ - _irq_enable(dev); - - timer_start(dev); - - return 0; -} - -int timer_set_absolute(tim_t dev, int channel, unsigned int value) -{ - DEBUG("Setting timer %i channel %i to %i\n", dev, channel, 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.reg |= TC_INTFLAG_MC0; - TIMER_0_DEV.CC[0].reg = value; - TIMER_0_DEV.INTENSET.bit.MC0 = 1; - break; - case 1: - TIMER_0_DEV.INTFLAG.reg |= TC_INTFLAG_MC1; - TIMER_0_DEV.CC[1].reg = value; - TIMER_0_DEV.INTENSET.bit.MC1 = 1; - break; - default: - return -1; - } - break; -#endif - case TIMER_UNDEFINED: - default: - return -1; - } - - return 1; -} - -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.reg |= TC_INTFLAG_MC0; - TIMER_0_DEV.INTENCLR.bit.MC0 = 1; - break; - case 1: - TIMER_0_DEV.INTFLAG.reg |= TC_INTFLAG_MC1; - TIMER_0_DEV.INTENCLR.bit.MC1 = 1; - break; - default: - return -1; - } - break; -#endif - case TIMER_UNDEFINED: - default: - return -1; - } - - return 1; -} - -unsigned int timer_read(tim_t dev) -{ - switch (dev) { -#if TIMER_0_EN - case TIMER_0: - /* request syncronisation */ - TIMER_0_DEV.CTRLBSET.bit.CMD = TC_CTRLBSET_CMD_READSYNC_Val; - while (TIMER_0_DEV.SYNCBUSY.bit.STATUS) {} - return TIMER_0_DEV.COUNT.reg; -#endif - default: - return 0; - } - - -} - -void timer_stop(tim_t dev) -{ - switch (dev) { -#if TIMER_0_EN - case TIMER_0: - TIMER_0_DEV.CTRLA.bit.ENABLE = 0; - break; -#endif - case TIMER_UNDEFINED: - break; - } -} - -void timer_start(tim_t dev) -{ - switch (dev) { -#if TIMER_0_EN - case TIMER_0: - TIMER_0_DEV.CTRLA.bit.ENABLE = 1; - break; -#endif - case TIMER_UNDEFINED: - break; - } -} - -static inline void _irq_enable(tim_t dev) -{ - switch (dev) { -#if TIMER_0_EN - case TIMER_0: - NVIC_EnableIRQ(TC0_IRQn); - break; -#endif - case TIMER_UNDEFINED: - break; - } -} - -#if TIMER_0_EN -void TIMER_0_ISR(void) -{ - if (TIMER_0_DEV.INTFLAG.bit.MC0 && TIMER_0_DEV.INTENSET.bit.MC0) { - if(config[TIMER_0].cb) { - TIMER_0_DEV.INTFLAG.reg |= TC_INTFLAG_MC0; - TIMER_0_DEV.INTENCLR.reg = TC_INTENCLR_MC0; - config[TIMER_0].cb(config[TIMER_0].arg, 0); - } - } - else if (TIMER_0_DEV.INTFLAG.bit.MC1 && TIMER_0_DEV.INTENSET.bit.MC1) { - if(config[TIMER_0].cb) { - TIMER_0_DEV.INTFLAG.reg |= TC_INTFLAG_MC1; - TIMER_0_DEV.INTENCLR.reg = TC_INTENCLR_MC1; - config[TIMER_0].cb(config[TIMER_0].arg, 1); - } - } - cortexm_isr_end(); -} -#endif /* TIMER_0_EN */