From 3dea38d9549dae5956b8753e824b3e855e91fdee Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 19 Dec 2009 09:05:40 +0000 Subject: STM32 PWM driver done. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1440 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/pwm_lld.c | 169 +++++++++++++++++++++++++++++++++++- os/hal/platforms/STM32/pwm_lld.h | 71 +++++++++++++++ os/hal/platforms/STM32/serial_lld.c | 8 ++ os/hal/platforms/STM32/serial_lld.h | 2 +- 4 files changed, 245 insertions(+), 5 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/STM32/pwm_lld.c b/os/hal/platforms/STM32/pwm_lld.c index 76199e48a..34a988037 100644 --- a/os/hal/platforms/STM32/pwm_lld.c +++ b/os/hal/platforms/STM32/pwm_lld.c @@ -29,14 +29,41 @@ #if CH_HAL_USE_PWM || defined(__DOXYGEN__) -/** @brief PWM1 driver identifier.*/ +/*===========================================================================*/ +/* Low Level Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief PWM1 driver identifier. + * @note The driver PWM1 allocates the complex timer TIM1 when enabled. + */ #if defined(USE_STM32_PWM1) || defined(__DOXYGEN__) PWMDriver PWMD1; #endif -/*===========================================================================*/ -/* Low Level Driver exported variables. */ -/*===========================================================================*/ +/** + * @brief PWM2 driver identifier. + * @note The driver PWM2 allocates the timer TIM2 when enabled. + */ +#if defined(USE_STM32_PWM2) || defined(__DOXYGEN__) +PWMDriver PWMD2; +#endif + +/** + * @brief PWM3 driver identifier. + * @note The driver PWM3 allocates the timer TIM3 when enabled. + */ +#if defined(USE_STM32_PWM3) || defined(__DOXYGEN__) +PWMDriver PWMD3; +#endif + +/** + * @brief PWM4 driver identifier. + * @note The driver PWM4 allocates the timer TIM4 when enabled. + */ +#if defined(USE_STM32_PWM4) || defined(__DOXYGEN__) +PWMDriver PWMD4; +#endif /*===========================================================================*/ /* Low Level Driver local variables. */ @@ -63,6 +90,30 @@ void stop_channels(PWMDriver *pwmp) { pwmp->pd_tim->CCMR2 = 0; /* Channels 3 and 4 frozen. */ } +/** + * @brief Common TIM2...TIM4 IRQ 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. + */ +static void serve_interrupt(PWMDriver *pwmp) { + uint16_t sr; + + sr = pwmp->pd_tim->SR & pwmp->pd_tim->DIER; + pwmp->pd_tim->SR = ~(TIM_SR_CC1IF | TIM_SR_CC2IF | TIM_SR_CC3IF | + TIM_SR_CC4IF | TIM_SR_UIF); + if ((sr & TIM_SR_CC1IF) != 0) + pwmp->pd_config->pc_channels[0].pcc_callback(); + if ((sr & TIM_SR_CC2IF) != 0) + pwmp->pd_config->pc_channels[1].pcc_callback(); + if ((sr & TIM_SR_CC3IF) != 0) + pwmp->pd_config->pc_channels[2].pcc_callback(); + if ((sr & TIM_SR_CC4IF) != 0) + pwmp->pd_config->pc_channels[3].pcc_callback(); + if ((sr & TIM_SR_UIF) != 0) + pwmp->pd_config->pc_callback(); +} + /*===========================================================================*/ /* Low Level Driver interrupt handlers. */ /*===========================================================================*/ @@ -110,6 +161,48 @@ CH_IRQ_HANDLER(VectorAC) { } #endif /* USE_STM32_PWM1 */ +#if USE_STM32_PWM2 +/** + * @brief TIM2 interrupt handler. + */ +CH_IRQ_HANDLER(VectorB0) { + + CH_IRQ_PROLOGUE(); + + serve_interrupt(&PWMD2); + + CH_IRQ_EPILOGUE(); +} +#endif /* USE_STM32_PWM2 */ + +#if USE_STM32_PWM3 +/** + * @brief TIM3 interrupt handler. + */ +CH_IRQ_HANDLER(VectorB4) { + + CH_IRQ_PROLOGUE(); + + serve_interrupt(&PWMD3); + + CH_IRQ_EPILOGUE(); +} +#endif /* USE_STM32_PWM3 */ + +#if USE_STM32_PWM4 +/** + * @brief TIM4 interrupt handler. + */ +CH_IRQ_HANDLER(VectorB8) { + + CH_IRQ_PROLOGUE(); + + serve_interrupt(&PWMD4); + + CH_IRQ_EPILOGUE(); +} +#endif /* USE_STM32_PWM4 */ + /*===========================================================================*/ /* Low Level Driver exported functions. */ /*===========================================================================*/ @@ -130,6 +223,38 @@ void pwm_lld_init(void) { PWMD1.pd_tim = TIM1; #endif +#if USE_STM32_PWM2 + /* TIM2 reset, ensures reset state in order to avoid trouble with JTAGs.*/ + RCC->APB1RSTR = RCC_APB1RSTR_TIM2RST; + RCC->APB1RSTR = 0; + + /* Driver initialization.*/ + pwmObjectInit(&PWMD2); + PWMD2.pd_enabled_channels = 0; + PWMD2.pd_tim = TIM2; +#endif + +#if USE_STM32_PWM3 + /* TIM2 reset, ensures reset state in order to avoid trouble with JTAGs.*/ + RCC->APB1RSTR = RCC_APB1RSTR_TIM3RST; + RCC->APB1RSTR = 0; + + /* Driver initialization.*/ + pwmObjectInit(&PWMD3); + PWMD3.pd_enabled_channels = 0; + PWMD3.pd_tim = TIM3; +#endif + +#if USE_STM32_PWM4 + /* TIM2 reset, ensures reset state in order to avoid trouble with JTAGs.*/ + RCC->APB1RSTR = RCC_APB1RSTR_TIM4RST; + RCC->APB1RSTR = 0; + + /* Driver initialization.*/ + pwmObjectInit(&PWMD4); + PWMD4.pd_enabled_channels = 0; + PWMD4.pd_tim = TIM4; +#endif } /** @@ -148,6 +273,24 @@ void pwm_lld_start(PWMDriver *pwmp) { NVICEnableVector(TIM1_CC_IRQn, STM32_PWM1_IRQ_PRIORITY); RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; } +#endif +#if USE_STM32_PWM2 + if (&PWMD2 == pwmp) { + NVICEnableVector(TIM2_IRQn, STM32_PWM2_IRQ_PRIORITY); + RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; + } +#endif +#if USE_STM32_PWM3 + if (&PWMD3 == pwmp) { + NVICEnableVector(TIM3_IRQn, STM32_PWM3_IRQ_PRIORITY); + RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; + } +#endif +#if USE_STM32_PWM4 + if (&PWMD4 == pwmp) { + NVICEnableVector(TIM4_IRQn, STM32_PWM4_IRQ_PRIORITY); + RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; + } #endif } /* Reset channels.*/ @@ -222,6 +365,24 @@ void pwm_lld_stop(PWMDriver *pwmp) { NVICDisableVector(TIM1_CC_IRQn); RCC->APB2ENR &= ~RCC_APB2ENR_TIM1EN; } +#endif +#if USE_STM32_PWM2 + if (&PWMD2 == pwmp) { + NVICDisableVector(TIM2_IRQn); + RCC->APB1ENR &= ~RCC_APB1ENR_TIM2EN; + } +#endif +#if USE_STM32_PWM3 + if (&PWMD3 == pwmp) { + NVICDisableVector(TIM3_IRQn); + RCC->APB1ENR &= ~RCC_APB1ENR_TIM3EN; + } +#endif +#if USE_STM32_PWM2 + if (&PWMD4 == pwmp) { + NVICDisableVector(TIM4_IRQn); + RCC->APB1ENR &= ~RCC_APB1ENR_TIM4EN; + } #endif } } diff --git a/os/hal/platforms/STM32/pwm_lld.h b/os/hal/platforms/STM32/pwm_lld.h index d44c1fdbf..e8eef9d8c 100644 --- a/os/hal/platforms/STM32/pwm_lld.h +++ b/os/hal/platforms/STM32/pwm_lld.h @@ -51,6 +51,33 @@ #define USE_STM32_PWM1 TRUE #endif +/** + * @brief PWM2 driver enable switch. + * @details If set to @p TRUE the support for PWM2 is included. + * @note The default is @p TRUE. + */ +#if !defined(USE_STM32_PWM2) || defined(__DOXYGEN__) +#define USE_STM32_PWM2 TRUE +#endif + +/** + * @brief PWM3 driver enable switch. + * @details If set to @p TRUE the support for PWM3 is included. + * @note The default is @p TRUE. + */ +#if !defined(USE_STM32_PWM3) || defined(__DOXYGEN__) +#define USE_STM32_PWM3 TRUE +#endif + +/** + * @brief PWM4 driver enable switch. + * @details If set to @p TRUE the support for PWM4 is included. + * @note The default is @p TRUE. + */ +#if !defined(USE_STM32_PWM4) || defined(__DOXYGEN__) +#define USE_STM32_PWM4 TRUE +#endif + /** * @brief PWM1 interrupt priority level setting. * @note @p BASEPRI_KERNEL >= @p STM32_PWM1_IRQ_PRIORITY > @p PRIORITY_PENDSV. @@ -59,6 +86,38 @@ #define STM32_PWM1_IRQ_PRIORITY 0x80 #endif +/** + * @brief PWM2 interrupt priority level setting. + * @note @p BASEPRI_KERNEL >= @p STM32_PWM2_IRQ_PRIORITY > @p PRIORITY_PENDSV. + */ +#if !defined(STM32_PWM2_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_PWM2_IRQ_PRIORITY 0x80 +#endif + +/** + * @brief PWM3 interrupt priority level setting. + * @note @p BASEPRI_KERNEL >= @p STM32_PWM3_IRQ_PRIORITY > @p PRIORITY_PENDSV. + */ +#if !defined(STM32_PWM3_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_PWM3_IRQ_PRIORITY 0x80 +#endif + +/** + * @brief PWM4 interrupt priority level setting. + * @note @p BASEPRI_KERNEL >= @p STM32_PWM4_IRQ_PRIORITY > @p PRIORITY_PENDSV. + */ +#if !defined(STM32_PWM4_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_PWM4_IRQ_PRIORITY 0x80 +#endif + +/*===========================================================================*/ +/* Configuration checks. */ +/*===========================================================================*/ + +#if USE_STM32_PWM4 && defined(STM32F10X_LD) +#error "TIM4 not present in low density STM32 devices" +#endif + /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ @@ -154,6 +213,18 @@ typedef struct { extern PWMDriver PWMD1; #endif +#if defined(USE_STM32_PWM2) +extern PWMDriver PWMD2; +#endif + +#if defined(USE_STM32_PWM3) +extern PWMDriver PWMD3; +#endif + +#if defined(USE_STM32_PWM4) +extern PWMDriver PWMD4; +#endif + #ifdef __cplusplus extern "C" { #endif diff --git a/os/hal/platforms/STM32/serial_lld.c b/os/hal/platforms/STM32/serial_lld.c index 5d2aea67a..e2d893761 100644 --- a/os/hal/platforms/STM32/serial_lld.c +++ b/os/hal/platforms/STM32/serial_lld.c @@ -29,6 +29,10 @@ #if CH_HAL_USE_SERIAL || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Low Level Driver exported variables. */ +/*===========================================================================*/ + #if USE_STM32_USART1 || defined(__DOXYGEN__) /** @brief USART1 serial driver identifier.*/ SerialDriver SD1; @@ -44,6 +48,10 @@ SerialDriver SD2; SerialDriver SD3; #endif +/*===========================================================================*/ +/* Low Level Driver local variables. */ +/*===========================================================================*/ + /** @brief Driver default configuration.*/ static const SerialDriverConfig default_config = { diff --git a/os/hal/platforms/STM32/serial_lld.h b/os/hal/platforms/STM32/serial_lld.h index b681fd9ba..774c97c81 100644 --- a/os/hal/platforms/STM32/serial_lld.h +++ b/os/hal/platforms/STM32/serial_lld.h @@ -107,7 +107,7 @@ #define USART_CR2_STOP1P5_BITS (3 << 12) /**< @brief CR2 1.5 stop bit value.*/ /*===========================================================================*/ -/* Driver data structures. */ +/* Driver data structures and types. */ /*===========================================================================*/ /** -- cgit v1.2.3