From 30dd0fdc1605baf4b81fce2b6fd9898de07f2ea1 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 29 Jun 2011 11:59:15 +0000 Subject: TIM8 support for STM32. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3098 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/gpt_lld.c | 59 +++++++++++++---- os/hal/platforms/STM32/gpt_lld.h | 26 +++++++- os/hal/platforms/STM32/hal_lld.h | 29 +++++++-- os/hal/platforms/STM32/hal_lld_f105_f107.h | 2 +- os/hal/platforms/STM32/icu_lld.c | 51 ++++++++++++++- os/hal/platforms/STM32/icu_lld.h | 26 +++++++- os/hal/platforms/STM32/pwm_lld.c | 100 +++++++++++++++++++++++++---- os/hal/platforms/STM32/pwm_lld.h | 28 +++++++- 8 files changed, 285 insertions(+), 36 deletions(-) (limited to 'os') diff --git a/os/hal/platforms/STM32/gpt_lld.c b/os/hal/platforms/STM32/gpt_lld.c index 8419cad68..f7a9226ad 100644 --- a/os/hal/platforms/STM32/gpt_lld.c +++ b/os/hal/platforms/STM32/gpt_lld.c @@ -31,18 +31,6 @@ #if HAL_USE_GPT || defined(__DOXYGEN__) -/* There are differences in vector names in the ST header for devices - including TIM15, TIM16, TIM17.*/ -#if STM32_HAS_TIM15 -#define TIM1_BRK_IRQn TIM1_BRK_TIM15_IRQn -#endif -#if STM32_HAS_TIM16 -#define TIM1_UP_IRQn TIM1_UP_TIM16_IRQn -#endif -#if STM32_HAS_TIM17 -#define TIM1_TRG_COM_IRQn TIM1_TRG_COM_TIM17_IRQn -#endif - /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ @@ -87,6 +75,14 @@ GPTDriver GPTD4; GPTDriver GPTD5; #endif +/** + * @brief GPTD8 driver identifier. + * @note The driver GPTD8 allocates the timer TIM8 when enabled. + */ +#if STM32_GPT_USE_TIM8 || defined(__DOXYGEN__) +GPTDriver GPTD8; +#endif + /*===========================================================================*/ /* Driver local variables. */ /*===========================================================================*/ @@ -194,6 +190,22 @@ CH_IRQ_HANDLER(TIM5_IRQHandler) { } #endif /* STM32_GPT_USE_TIM5 */ +#if STM32_GPT_USE_TIM8 +/** + * @brief TIM5 interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(TIM8_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + gpt_lld_serve_interrupt(&GPTD8); + + CH_IRQ_EPILOGUE(); +} +#endif /* STM32_GPT_USE_TIM8 */ + /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ @@ -234,6 +246,12 @@ void gpt_lld_init(void) { GPTD5.tim = TIM5; gptObjectInit(&GPTD5); #endif + +#if STM32_GPT_USE_TIM8 + /* Driver initialization.*/ + GPTD5.tim = TIM8; + gptObjectInit(&GPTD8); +#endif } /** @@ -299,6 +317,17 @@ void gpt_lld_start(GPTDriver *gptp) { gptp->clock = STM32_TIMCLK1; } #endif + +#if STM32_GPT_USE_TIM8 + if (&GPTD8 == gptp) { + RCC->APB2ENR |= RCC_APB2ENR_TIM8EN; + RCC->APB2RSTR = RCC_APB2RSTR_TIM8RST; + RCC->APB2RSTR = 0; + NVICEnableVector(TIM8_UP_IRQn, + CORTEX_PRIORITY_MASK(STM32_GPT_TIM8_IRQ_PRIORITY)); + gptp->clock = STM32_TIMCLK2; + } +#endif } /* Prescaler value calculation.*/ @@ -356,6 +385,12 @@ void gpt_lld_stop(GPTDriver *gptp) { NVICDisableVector(TIM5_IRQn); RCC->APB1ENR &= ~RCC_APB1ENR_TIM5EN; } +#endif +#if STM32_GPT_USE_TIM8 + if (&GPTD8 == gptp) { + NVICDisableVector(TIM8_UP_IRQn); + RCC->APB2ENR &= ~RCC_APB2ENR_TIM8EN; + } #endif } } diff --git a/os/hal/platforms/STM32/gpt_lld.h b/os/hal/platforms/STM32/gpt_lld.h index cf749077f..ef00c23a9 100644 --- a/os/hal/platforms/STM32/gpt_lld.h +++ b/os/hal/platforms/STM32/gpt_lld.h @@ -84,6 +84,15 @@ #define STM32_GPT_USE_TIM5 TRUE #endif +/** + * @brief GPTD8 driver enable switch. + * @details If set to @p TRUE the support for GPTD8 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM32_GPT_USE_TIM8) || defined(__DOXYGEN__) +#define STM32_GPT_USE_TIM8 TRUE +#endif + /** * @brief GPTD1 interrupt priority level setting. */ @@ -119,6 +128,13 @@ #define STM32_GPT_TIM5_IRQ_PRIORITY 7 #endif +/** + * @brief GPTD5 interrupt priority level setting. + */ +#if !defined(STM32_GPT_TIM8_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_GPT_TIM8_IRQ_PRIORITY 7 +#endif + /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ @@ -143,9 +159,13 @@ #error "TIM5 not present in the selected device" #endif +#if STM32_GPT_USE_TIM8 && !STM32_HAS_TIM8 +#error "TIM8 not present in the selected device" +#endif + #if !STM32_GPT_USE_TIM1 && !STM32_GPT_USE_TIM2 && \ !STM32_GPT_USE_TIM3 && !STM32_GPT_USE_TIM4 && \ - !STM32_GPT_USE_TIM5 + !STM32_GPT_USE_TIM5 && !STM32_GPT_USE_TIM8 #error "GPT driver activated but no TIM peripheral assigned" #endif @@ -236,6 +256,10 @@ extern GPTDriver GPTD4; extern GPTDriver GPTD5; #endif +#if STM32_GPT_USE_TIM8 && !defined(__DOXYGEN__) +extern GPTDriver GPTD8; +#endif + #ifdef __cplusplus extern "C" { #endif diff --git a/os/hal/platforms/STM32/hal_lld.h b/os/hal/platforms/STM32/hal_lld.h index 374aad63f..44e179f49 100644 --- a/os/hal/platforms/STM32/hal_lld.h +++ b/os/hal/platforms/STM32/hal_lld.h @@ -382,12 +382,12 @@ #define STM32_HAS_TIM6 TRUE #define STM32_HAS_TIM7 TRUE #define STM32_HAS_TIM8 TRUE -#define STM32_HAS_TIM9 FALSE -#define STM32_HAS_TIM10 FALSE -#define STM32_HAS_TIM11 FALSE -#define STM32_HAS_TIM12 FALSE -#define STM32_HAS_TIM13 FALSE -#define STM32_HAS_TIM14 FALSE +#define STM32_HAS_TIM9 TRUE +#define STM32_HAS_TIM10 TRUE +#define STM32_HAS_TIM11 TRUE +#define STM32_HAS_TIM12 TRUE +#define STM32_HAS_TIM13 TRUE +#define STM32_HAS_TIM14 TRUE #define STM32_HAS_TIM15 FALSE #define STM32_HAS_TIM16 FALSE #define STM32_HAS_TIM17 FALSE @@ -541,6 +541,23 @@ #error "unspecified, unsupported or invalid STM32 platform" #endif +/* There are differences in vector names in the various sub-families, + normalizing.*/ +#if defined(STM32F10X_XL) +#define TIM1_BRK_IRQn TIM1_BRK_TIM9_IRQn +#define TIM1_UP_IRQn TIM1_UP_TIM10_IRQn +#define TIM1_TRG_COM_IRQn TIM1_TRG_COM_TIM11_IRQn +#define TIM8_BRK_IRQn TIM8_BRK_TIM12_IRQn +#define TIM8_UP_IRQn TIM8_UP_TIM13_IRQn +#define TIM8_TRG_COM_IRQn TIM8_TRG_COM_TIM14_IRQn + +#elif defined(STM32F10X_LD_VL)|| defined(STM32F10X_MD_VL) || \ + defined(STM32F10X_HD_VL) +#define TIM1_BRK_IRQn TIM1_BRK_TIM15_IRQn +#define TIM1_UP_IRQn TIM1_UP_TIM16_IRQn +#define TIM1_TRG_COM_IRQn TIM1_TRG_COM_TIM17_IRQn +#endif + /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32/hal_lld_f105_f107.h b/os/hal/platforms/STM32/hal_lld_f105_f107.h index ce8147ae0..27a840ba8 100644 --- a/os/hal/platforms/STM32/hal_lld_f105_f107.h +++ b/os/hal/platforms/STM32/hal_lld_f105_f107.h @@ -626,7 +626,7 @@ #endif /** - * @brief Timer 1 clock. + * @brief Timers 1, 8 clock. */ #if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) #define STM32_TIMCLK2 (STM32_PCLK2 * 1) diff --git a/os/hal/platforms/STM32/icu_lld.c b/os/hal/platforms/STM32/icu_lld.c index ae3287ef9..054ce1e3d 100644 --- a/os/hal/platforms/STM32/icu_lld.c +++ b/os/hal/platforms/STM32/icu_lld.c @@ -75,6 +75,14 @@ ICUDriver ICUD4; ICUDriver ICUD5; #endif +/** + * @brief ICUD8 driver identifier. + * @note The driver ICUD8 allocates the timer TIM8 when enabled. + */ +#if STM32_ICU_USE_TIM8 || defined(__DOXYGEN__) +ICUDriver ICUD8; +#endif + /*===========================================================================*/ /* Driver local variables. */ /*===========================================================================*/ @@ -198,6 +206,25 @@ CH_IRQ_HANDLER(TIM5_IRQHandler) { } #endif /* STM32_ICU_USE_TIM5 */ +#if STM32_ICU_USE_TIM8 +/** + * @brief TIM8 compare interrupt handler. + * @note It is assumed that the various sources are only activated if the + * associated callback pointer is not equal to @p NULL in order to not + * perform an extra check in a potentially critical interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(TIM8_CC_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + icu_lld_serve_interrupt(&ICUD8); + + CH_IRQ_EPILOGUE(); +} +#endif /* STM32_ICU_USE_TIM8 */ + /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ @@ -238,6 +265,12 @@ void icu_lld_init(void) { icuObjectInit(&ICUD5); ICUD5.tim = TIM5; #endif + +#if STM32_ICU_USE_TIM8 + /* Driver initialization.*/ + icuObjectInit(&ICUD8); + ICUD5.tim = TIM8; +#endif } /** @@ -302,6 +335,16 @@ void icu_lld_start(ICUDriver *icup) { CORTEX_PRIORITY_MASK(STM32_ICU_TIM5_IRQ_PRIORITY)); clock = STM32_TIMCLK1; } +#endif +#if STM32_ICU_USE_TIM8 + if (&ICUD8 == icup) { + RCC->APB2ENR |= RCC_APB2ENR_TIM8EN; + RCC->APB2RSTR = RCC_APB2RSTR_TIM8RST; + RCC->APB2RSTR = 0; + NVICEnableVector(TIM8_CC_IRQn, + CORTEX_PRIORITY_MASK(STM32_ICU_TIM8_IRQ_PRIORITY)); + clock = STM32_TIMCLK2; + } #endif } else { @@ -362,7 +405,6 @@ void icu_lld_stop(ICUDriver *icup) { RCC->APB2ENR &= ~RCC_APB2ENR_TIM1EN; } #endif - } #if STM32_ICU_USE_TIM2 if (&ICUD2 == icup) { NVICDisableVector(TIM2_IRQn); @@ -386,6 +428,13 @@ void icu_lld_stop(ICUDriver *icup) { NVICDisableVector(TIM5_IRQn); RCC->APB1ENR &= ~RCC_APB1ENR_TIM5EN; } +#endif + } +#if STM32_ICU_USE_TIM8 + if (&ICUD8 == icup) { + NVICDisableVector(TIM8_CC_IRQn); + RCC->APB2ENR &= ~RCC_APB2ENR_TIM8EN; + } #endif } diff --git a/os/hal/platforms/STM32/icu_lld.h b/os/hal/platforms/STM32/icu_lld.h index b98b8bf86..e7321e794 100644 --- a/os/hal/platforms/STM32/icu_lld.h +++ b/os/hal/platforms/STM32/icu_lld.h @@ -84,6 +84,15 @@ #define STM32_ICU_USE_TIM5 TRUE #endif +/** + * @brief ICUD8 driver enable switch. + * @details If set to @p TRUE the support for ICUD8 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM32_ICU_USE_TIM8) || defined(__DOXYGEN__) +#define STM32_ICU_USE_TIM8 TRUE +#endif + /** * @brief ICUD1 interrupt priority level setting. */ @@ -119,6 +128,13 @@ #define STM32_ICU_TIM5_IRQ_PRIORITY 7 #endif +/** + * @brief ICUD8 interrupt priority level setting. + */ +#if !defined(STM32_ICU_TIM8_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_ICU_TIM8_IRQ_PRIORITY 7 +#endif + /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ @@ -143,9 +159,13 @@ #error "TIM5 not present in the selected device" #endif +#if STM32_ICU_USE_TIM8 && !STM32_HAS_TIM8 +#error "TIM8 not present in the selected device" +#endif + #if !STM32_ICU_USE_TIM1 && !STM32_ICU_USE_TIM2 && \ !STM32_ICU_USE_TIM3 && !STM32_ICU_USE_TIM4 && \ - !STM32_ICU_USE_TIM5 + !STM32_ICU_USE_TIM5 && !STM32_ICU_USE_TIM8 #error "ICU driver activated but no TIM peripheral assigned" #endif @@ -271,6 +291,10 @@ extern ICUDriver ICUD4; extern ICUDriver ICUD5; #endif +#if STM32_ICU_USE_TIM8 && !defined(__DOXYGEN__) +extern ICUDriver ICUD8; +#endif + #ifdef __cplusplus extern "C" { #endif diff --git a/os/hal/platforms/STM32/pwm_lld.c b/os/hal/platforms/STM32/pwm_lld.c index bb6dad8f2..85cef0553 100644 --- a/os/hal/platforms/STM32/pwm_lld.c +++ b/os/hal/platforms/STM32/pwm_lld.c @@ -31,18 +31,6 @@ #if HAL_USE_PWM || defined(__DOXYGEN__) -/* There are differences in vector names in the ST header for devices - including TIM15, TIM16, TIM17.*/ -#if STM32_HAS_TIM15 -#define TIM1_BRK_IRQn TIM1_BRK_TIM15_IRQn -#endif -#if STM32_HAS_TIM16 -#define TIM1_UP_IRQn TIM1_UP_TIM16_IRQn -#endif -#if STM32_HAS_TIM17 -#define TIM1_TRG_COM_IRQn TIM1_TRG_COM_TIM17_IRQn -#endif - /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ @@ -87,6 +75,14 @@ PWMDriver PWMD4; PWMDriver PWMD5; #endif +/** + * @brief PWMD8 driver identifier. + * @note The driver PWMD5 allocates the timer TIM5 when enabled. + */ +#if STM32_PWM_USE_TIM8 || defined(__DOXYGEN__) +PWMDriver PWMD8; +#endif + /*===========================================================================*/ /* Driver local variables. */ /*===========================================================================*/ @@ -240,6 +236,53 @@ CH_IRQ_HANDLER(TIM5_IRQHandler) { } #endif /* STM32_PWM_USE_TIM5 */ +#if STM32_PWM_USE_TIM8 +/** + * @brief TIM8 update interrupt handler. + * @note It is assumed that this interrupt is only activated if the callback + * pointer is not equal to @p NULL in order to not perform an extra + * check in a potentially critical interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(TIM8_UP_IRQHandler) { + + CH_IRQ_PROLOGUE(); + + TIM8->SR = ~TIM_SR_UIF; + PWMD1.config->callback(&PWMD8); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief TIM1 compare interrupt handler. + * @note It is assumed that the various sources are only activated if the + * associated callback pointer is not equal to @p NULL in order to not + * perform an extra check in a potentially critical interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(TIM8_CC_IRQHandler) { + uint16_t sr; + + CH_IRQ_PROLOGUE(); + + sr = TIM8->SR & TIM8->DIER; + TIM8->SR = ~(TIM_SR_CC1IF | TIM_SR_CC2IF | TIM_SR_CC3IF | TIM_SR_CC4IF); + if ((sr & TIM_SR_CC1IF) != 0) + PWMD8.config->channels[0].callback(&PWMD8); + if ((sr & TIM_SR_CC2IF) != 0) + PWMD8.config->channels[1].callback(&PWMD8); + if ((sr & TIM_SR_CC3IF) != 0) + PWMD8.config->channels[2].callback(&PWMD8); + if ((sr & TIM_SR_CC4IF) != 0) + PWMD8.config->channels[3].callback(&PWMD8); + + CH_IRQ_EPILOGUE(); +} +#endif /* STM32_PWM_USE_TIM8 */ + /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ @@ -280,6 +323,12 @@ void pwm_lld_init(void) { pwmObjectInit(&PWMD5); PWMD5.tim = TIM5; #endif + +#if STM32_PWM_USE_TIM8 + /* Driver initialization.*/ + pwmObjectInit(&PWMD8); + PWMD5.tim = TIM8; +#endif } /** @@ -350,6 +399,18 @@ void pwm_lld_start(PWMDriver *pwmp) { clock = STM32_TIMCLK1; } #endif +#if STM32_PWM_USE_TIM8 + if (&PWMD8 == pwmp) { + RCC->APB2ENR |= RCC_APB2ENR_TIM8EN; + RCC->APB2RSTR = RCC_APB2RSTR_TIM8RST; + RCC->APB2RSTR = 0; + NVICEnableVector(TIM8_UP_IRQn, + CORTEX_PRIORITY_MASK(STM32_PWM_TIM8_IRQ_PRIORITY)); + NVICEnableVector(TIM8_CC_IRQn, + CORTEX_PRIORITY_MASK(STM32_PWM_TIM8_IRQ_PRIORITY)); + clock = STM32_TIMCLK2; + } +#endif /* All channels configured in PWM1 mode with preload enabled and will stay that way until the driver is stopped.*/ @@ -418,7 +479,15 @@ void pwm_lld_start(PWMDriver *pwmp) { ; } #if STM32_PWM_USE_ADVANCED +#if STM32_PWM_USE_TIM1 && !STM32_PWM_USE_TIM8 if (&PWMD1 == pwmp) { +#endif +#if !STM32_PWM_USE_TIM1 && STM32_PWM_USE_TIM8 + if (&PWMD8 == pwmp) { +#endif +#if STM32_PWM_USE_TIM1 && STM32_PWM_USE_TIM8 + if ((&PWMD1 == pwmp) || (&PWMD8 == pwmp)) { +#endif switch (pwmp->config->channels[0].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) { case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW: ccer |= TIM_CCER_CC1NP; @@ -505,6 +574,13 @@ void pwm_lld_stop(PWMDriver *pwmp) { NVICDisableVector(TIM5_IRQn); RCC->APB1ENR &= ~RCC_APB1ENR_TIM5EN; } +#endif +#if STM32_PWM_USE_TIM8 + if (&PWMD8 == pwmp) { + NVICDisableVector(TIM8_UP_IRQn); + NVICDisableVector(TIM8_CC_IRQn); + RCC->APB2ENR &= ~RCC_APB2ENR_TIM8EN; + } #endif } } diff --git a/os/hal/platforms/STM32/pwm_lld.h b/os/hal/platforms/STM32/pwm_lld.h index 2b3ce7183..fb5a83790 100644 --- a/os/hal/platforms/STM32/pwm_lld.h +++ b/os/hal/platforms/STM32/pwm_lld.h @@ -129,6 +129,15 @@ #define STM32_PWM_USE_TIM5 TRUE #endif +/** + * @brief PWMD8 driver enable switch. + * @details If set to @p TRUE the support for PWMD8 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM32_PWM_USE_TIM8) || defined(__DOXYGEN__) +#define STM32_PWM_USE_TIM8 TRUE +#endif + /** * @brief PWMD1 interrupt priority level setting. */ @@ -164,6 +173,13 @@ #define STM32_PWM_TIM5_IRQ_PRIORITY 7 #endif +/** + * @brief PWMD8 interrupt priority level setting. + */ +#if !defined(STM32_PWM_TIM8_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_PWM_TIM8_IRQ_PRIORITY 7 +#endif + /*===========================================================================*/ /* Configuration checks. */ /*===========================================================================*/ @@ -188,13 +204,17 @@ #error "TIM5 not present in the selected device" #endif +#if STM32_PWM_USE_TIM8 && !STM32_HAS_TIM8 +#error "TIM8 not present in the selected device" +#endif + #if !STM32_PWM_USE_TIM1 && !STM32_PWM_USE_TIM2 && \ !STM32_PWM_USE_TIM3 && !STM32_PWM_USE_TIM4 && \ - !STM32_PWM_USE_TIM5 + !STM32_PWM_USE_TIM5 && !STM32_PWM_USE_TIM8 #error "PWM driver activated but no TIM peripheral assigned" #endif -#if STM32_PWM_USE_ADVANCED && !STM32_PWM_USE_TIM1 +#if STM32_PWM_USE_ADVANCED && !STM32_PWM_USE_TIM1 && !STM32_PWM_USE_TIM8 #error "advanced mode selected but no advanced timer assigned" #endif @@ -348,6 +368,10 @@ extern PWMDriver PWMD4; extern PWMDriver PWMD5; #endif +#if STM32_PWM_USE_TIM8 && !defined(__DOXYGEN__) +extern PWMDriver PWMD8; +#endif + #ifdef __cplusplus extern "C" { #endif -- cgit v1.2.3