From d8420eb83a4b843ad23d0fbe77fea36272adc525 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 1 Apr 2011 13:06:44 +0000 Subject: [PATCH] Added advanced mode and BTRD handling to the STM32 PWM driver. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2861 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/ARMCM3-STM32F100-DISCOVERY/main.c | 3 + demos/ARMCM3-STM32F100-DISCOVERY/mcuconf.h | 1 + demos/ARMCM3-STM32F103-FATFS-GCC/mcuconf.h | 1 + demos/ARMCM3-STM32F103/mcuconf.h | 1 + demos/ARMCM3-STM32F107/mcuconf.h | 1 + os/hal/platforms/STM32/pwm_lld.c | 42 +++++++++-- os/hal/platforms/STM32/pwm_lld.h | 83 +++++++++++++++++++--- readme.txt | 1 + testhal/STM32/ADC/mcuconf.h | 1 + testhal/STM32/CAN/mcuconf.h | 1 + testhal/STM32/GPT/mcuconf.h | 1 + testhal/STM32/IRQ_STORM/mcuconf.h | 1 + testhal/STM32/PWM-ICU/main.c | 3 + testhal/STM32/PWM-ICU/mcuconf.h | 1 + testhal/STM32/SPI/mcuconf.h | 1 + testhal/STM32/UART/mcuconf.h | 1 + testhal/STM32/USB_CDC/mcuconf.h | 1 + testhal/STM32/USB_MSC/mcuconf.h | 1 + 18 files changed, 131 insertions(+), 14 deletions(-) diff --git a/demos/ARMCM3-STM32F100-DISCOVERY/main.c b/demos/ARMCM3-STM32F100-DISCOVERY/main.c index bc7e5f632..ff9c4ec70 100644 --- a/demos/ARMCM3-STM32F100-DISCOVERY/main.c +++ b/demos/ARMCM3-STM32F100-DISCOVERY/main.c @@ -73,7 +73,10 @@ static PWMConfig pwmcfg = { {PWM_OUTPUT_ACTIVE_HIGH, NULL} }, /* HW dependent part.*/ + 0, +#if STM32_PWM_USE_ADVANCED 0 +#endif }; /* diff --git a/demos/ARMCM3-STM32F100-DISCOVERY/mcuconf.h b/demos/ARMCM3-STM32F100-DISCOVERY/mcuconf.h index fcbfa6948..9bc43776c 100644 --- a/demos/ARMCM3-STM32F100-DISCOVERY/mcuconf.h +++ b/demos/ARMCM3-STM32F100-DISCOVERY/mcuconf.h @@ -90,6 +90,7 @@ /* * PWM driver system settings. */ +#define STM32_PWM_USE_ADVANCED FALSE #define STM32_PWM_USE_TIM1 FALSE #define STM32_PWM_USE_TIM2 FALSE #define STM32_PWM_USE_TIM3 TRUE diff --git a/demos/ARMCM3-STM32F103-FATFS-GCC/mcuconf.h b/demos/ARMCM3-STM32F103-FATFS-GCC/mcuconf.h index bd96de17b..94e9c5d15 100644 --- a/demos/ARMCM3-STM32F103-FATFS-GCC/mcuconf.h +++ b/demos/ARMCM3-STM32F103-FATFS-GCC/mcuconf.h @@ -91,6 +91,7 @@ /* * PWM driver system settings. */ +#define STM32_PWM_USE_ADVANCED TRUE #define STM32_PWM_USE_TIM1 TRUE #define STM32_PWM_USE_TIM2 FALSE #define STM32_PWM_USE_TIM3 FALSE diff --git a/demos/ARMCM3-STM32F103/mcuconf.h b/demos/ARMCM3-STM32F103/mcuconf.h index bd96de17b..94e9c5d15 100644 --- a/demos/ARMCM3-STM32F103/mcuconf.h +++ b/demos/ARMCM3-STM32F103/mcuconf.h @@ -91,6 +91,7 @@ /* * PWM driver system settings. */ +#define STM32_PWM_USE_ADVANCED TRUE #define STM32_PWM_USE_TIM1 TRUE #define STM32_PWM_USE_TIM2 FALSE #define STM32_PWM_USE_TIM3 FALSE diff --git a/demos/ARMCM3-STM32F107/mcuconf.h b/demos/ARMCM3-STM32F107/mcuconf.h index bff96c226..613541da4 100644 --- a/demos/ARMCM3-STM32F107/mcuconf.h +++ b/demos/ARMCM3-STM32F107/mcuconf.h @@ -98,6 +98,7 @@ /* * PWM driver system settings. */ +#define STM32_PWM_USE_ADVANCED TRUE #define STM32_PWM_USE_TIM1 TRUE #define STM32_PWM_USE_TIM2 FALSE #define STM32_PWM_USE_TIM3 FALSE diff --git a/os/hal/platforms/STM32/pwm_lld.c b/os/hal/platforms/STM32/pwm_lld.c index 6b05b66aa..2f125b345 100644 --- a/os/hal/platforms/STM32/pwm_lld.c +++ b/os/hal/platforms/STM32/pwm_lld.c @@ -394,7 +394,7 @@ void pwm_lld_start(PWMDriver *pwmp) { /* Output enables and polarities setup.*/ ccer = 0; - switch (pwmp->config->channels[0].mode) { + switch (pwmp->config->channels[0].mode & PWM_OUTPUT_MASK) { case PWM_OUTPUT_ACTIVE_LOW: ccer |= TIM_CCER_CC1P; case PWM_OUTPUT_ACTIVE_HIGH: @@ -402,7 +402,7 @@ void pwm_lld_start(PWMDriver *pwmp) { default: ; } - switch (pwmp->config->channels[1].mode) { + switch (pwmp->config->channels[1].mode & PWM_OUTPUT_MASK) { case PWM_OUTPUT_ACTIVE_LOW: ccer |= TIM_CCER_CC2P; case PWM_OUTPUT_ACTIVE_HIGH: @@ -410,7 +410,7 @@ void pwm_lld_start(PWMDriver *pwmp) { default: ; } - switch (pwmp->config->channels[2].mode) { + switch (pwmp->config->channels[2].mode & PWM_OUTPUT_MASK) { case PWM_OUTPUT_ACTIVE_LOW: ccer |= TIM_CCER_CC3P; case PWM_OUTPUT_ACTIVE_HIGH: @@ -418,7 +418,7 @@ void pwm_lld_start(PWMDriver *pwmp) { default: ; } - switch (pwmp->config->channels[3].mode) { + switch (pwmp->config->channels[3].mode & PWM_OUTPUT_MASK) { case PWM_OUTPUT_ACTIVE_LOW: ccer |= TIM_CCER_CC4P; case PWM_OUTPUT_ACTIVE_HIGH: @@ -426,11 +426,44 @@ void pwm_lld_start(PWMDriver *pwmp) { default: ; } +#if STM32_PWM_USE_ADVANCED + if (&PWMD1 == pwmp) { + switch (pwmp->config->channels[0].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) { + case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW: + ccer |= TIM_CCER_CC1NP; + case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH: + ccer |= TIM_CCER_CC1NE; + default: + ; + } + switch (pwmp->config->channels[1].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) { + case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW: + ccer |= TIM_CCER_CC2NP; + case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH: + ccer |= TIM_CCER_CC2NE; + default: + ; + } + switch (pwmp->config->channels[2].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) { + case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW: + ccer |= TIM_CCER_CC3NP; + case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH: + ccer |= TIM_CCER_CC3NE; + default: + ; + } + } +#endif /* STM32_PWM_USE_ADVANCED*/ + pwmp->tim->CCER = ccer; pwmp->tim->EGR = TIM_EGR_UG; /* Update event. */ pwmp->tim->SR = 0; /* Clear pending IRQs. */ pwmp->tim->DIER = pwmp->config->callback == NULL ? 0 : TIM_DIER_UIE; +#if STM32_PWM_USE_ADVANCED + pwmp->tim->BDTR = pwmp->config->bdtr | TIM_BDTR_MOE; +#else pwmp->tim->BDTR = TIM_BDTR_MOE; +#endif /* Timer configured and started.*/ pwmp->tim->CR1 = TIM_CR1_ARPE | TIM_CR1_URS | TIM_CR1_CEN; } @@ -450,6 +483,7 @@ void pwm_lld_stop(PWMDriver *pwmp) { pwmp->tim->CR1 = 0; /* Timer disabled. */ pwmp->tim->DIER = 0; /* All IRQs disabled. */ pwmp->tim->SR = 0; /* Clear eventual pending IRQs. */ + pwmp->tim->BDTR = 0; #if STM32_PWM_USE_TIM1 if (&PWMD1 == pwmp) { diff --git a/os/hal/platforms/STM32/pwm_lld.h b/os/hal/platforms/STM32/pwm_lld.h index d8e1754c9..e36b6f1f6 100644 --- a/os/hal/platforms/STM32/pwm_lld.h +++ b/os/hal/platforms/STM32/pwm_lld.h @@ -38,12 +38,68 @@ /** * @brief Number of PWM channels per PWM driver. */ -#define PWM_CHANNELS 4 +#define PWM_CHANNELS 4 + +/** + * @brief Standard output modes mask. + */ +#define PWM_OUTPUT_MASK 0x07 + +/** + * @brief Output not driven, callback only. + */ +#define PWM_OUTPUT_DISABLED 0x00 + +/** + * @brief Positive PWM logic, active is logic level one. + */ +#define PWM_OUTPUT_ACTIVE_HIGH 0x01 + +/** + * @brief Inverse PWM logic, active is logic level zero. + */ +#define PWM_OUTPUT_ACTIVE_LOW 0x02 + +/** + * @brief Complementary output modes mask. + */ +#define PWM_COMPLEMENTARY_OUTPUT_MASK 0x70 + +/** + * @brief Complementary output not driven. + */ +#define PWM_COMPLEMENTARY_OUTPUT_DISABLED 0x00 + +/** + * @brief Complementary output, active is logic level one. + * @note This setting is only available if the configuration option + * @p STM32_PWM_USE_ADVANCED is set to TRUE and only for advanced + * timers TIM1 and TIM8. + */ +#define PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH 0x10 + +/** + * @brief Complementary output, active is logic level zero. + * @note This setting is only available if the configuration option + * @p STM32_PWM_USE_ADVANCED is set to TRUE and only for advanced + * timers TIM1 and TIM8. + */ +#define PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW 0x20 /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @brief If advanced timer features switch. + * @details If set to @p TRUE the advanced features for TIM1 and TIM8 are + * enabled. + * @note The default is @p TRUE. + */ +#if !defined(STM32_PWM_USE_ADVANCED) || defined(__DOXYGEN__) +#define STM32_PWM_USE_ADVANCED TRUE +#endif + /** * @brief PWMD1 driver enable switch. * @details If set to @p TRUE the support for PWMD1 is included. @@ -154,10 +210,19 @@ #error "PWM driver activated but no TIM peripheral assigned" #endif +#if STM32_PWM_USE_ADVANCED && !STM32_PWM_USE_TIM1 +#error "advanced mode selected but no advanced timer assigned" +#endif + /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ +/** + * @brief PWM mode type. + */ +typedef uint32_t pwmmode_t; + /** * @brief PWM channel type. */ @@ -168,15 +233,6 @@ typedef uint8_t pwmchannel_t; */ typedef uint16_t pwmcnt_t; -/** - * @brief PWM logic mode. - */ -typedef enum { - PWM_OUTPUT_DISABLED = 0, /**< Output not driven, callback only. */ - PWM_OUTPUT_ACTIVE_HIGH = 1, /**< Idle is logic level 0. */ - PWM_OUTPUT_ACTIVE_LOW = 2 /**< Idle is logic level 1. */ -} pwmmode_t; - /** * @brief PWM driver channel configuration structure. */ @@ -226,6 +282,13 @@ typedef struct { * @note The value of this field should normally be equal to zero. */ uint16_t cr2; +#if STM32_PWM_USE_ADVANCED || defined(__DOXYGEN__) + /** + * @brief TIM BDTR (break & dead-time) register initialization data. + * @note The value of this field should normally be equal to zero. + */ \ + uint16_t bdtr; +#endif } PWMConfig; /** diff --git a/readme.txt b/readme.txt index b0c085811..775279bbb 100644 --- a/readme.txt +++ b/readme.txt @@ -86,6 +86,7 @@ even from within callbacks. Formerly it was required to stop and restart the driver. - Improved driver documentation. +- NEW: Added advanced mode to the STM32 PWM driver (TIM1 only). - NEW: Added new ICU driver model, Input Capture Unit. - NEW: ICU driver implementation for STM32. - NEW: Implemented stack checking in the Cortex-Mx RVCT port (backported diff --git a/testhal/STM32/ADC/mcuconf.h b/testhal/STM32/ADC/mcuconf.h index bd96de17b..94e9c5d15 100644 --- a/testhal/STM32/ADC/mcuconf.h +++ b/testhal/STM32/ADC/mcuconf.h @@ -91,6 +91,7 @@ /* * PWM driver system settings. */ +#define STM32_PWM_USE_ADVANCED TRUE #define STM32_PWM_USE_TIM1 TRUE #define STM32_PWM_USE_TIM2 FALSE #define STM32_PWM_USE_TIM3 FALSE diff --git a/testhal/STM32/CAN/mcuconf.h b/testhal/STM32/CAN/mcuconf.h index bd96de17b..94e9c5d15 100644 --- a/testhal/STM32/CAN/mcuconf.h +++ b/testhal/STM32/CAN/mcuconf.h @@ -91,6 +91,7 @@ /* * PWM driver system settings. */ +#define STM32_PWM_USE_ADVANCED TRUE #define STM32_PWM_USE_TIM1 TRUE #define STM32_PWM_USE_TIM2 FALSE #define STM32_PWM_USE_TIM3 FALSE diff --git a/testhal/STM32/GPT/mcuconf.h b/testhal/STM32/GPT/mcuconf.h index 90a7e9fc7..c7dc8742c 100644 --- a/testhal/STM32/GPT/mcuconf.h +++ b/testhal/STM32/GPT/mcuconf.h @@ -91,6 +91,7 @@ /* * PWM driver system settings. */ +#define STM32_PWM_USE_ADVANCED TRUE #define STM32_PWM_USE_TIM1 FALSE #define STM32_PWM_USE_TIM2 FALSE #define STM32_PWM_USE_TIM3 FALSE diff --git a/testhal/STM32/IRQ_STORM/mcuconf.h b/testhal/STM32/IRQ_STORM/mcuconf.h index 52ca1d806..d27660a12 100644 --- a/testhal/STM32/IRQ_STORM/mcuconf.h +++ b/testhal/STM32/IRQ_STORM/mcuconf.h @@ -91,6 +91,7 @@ /* * PWM driver system settings. */ +#define STM32_PWM_USE_ADVANCED TRUE #define STM32_PWM_USE_TIM1 FALSE #define STM32_PWM_USE_TIM2 FALSE #define STM32_PWM_USE_TIM3 FALSE diff --git a/testhal/STM32/PWM-ICU/main.c b/testhal/STM32/PWM-ICU/main.c index c89b71988..3f7b6423e 100644 --- a/testhal/STM32/PWM-ICU/main.c +++ b/testhal/STM32/PWM-ICU/main.c @@ -43,7 +43,10 @@ static PWMConfig pwmcfg = { {PWM_OUTPUT_DISABLED, NULL}, {PWM_OUTPUT_DISABLED, NULL} }, + 0, +#if STM32_PWM_USE_ADVANCED 0 +#endif }; icucnt_t last_width, last_period; diff --git a/testhal/STM32/PWM-ICU/mcuconf.h b/testhal/STM32/PWM-ICU/mcuconf.h index bd96de17b..94e9c5d15 100644 --- a/testhal/STM32/PWM-ICU/mcuconf.h +++ b/testhal/STM32/PWM-ICU/mcuconf.h @@ -91,6 +91,7 @@ /* * PWM driver system settings. */ +#define STM32_PWM_USE_ADVANCED TRUE #define STM32_PWM_USE_TIM1 TRUE #define STM32_PWM_USE_TIM2 FALSE #define STM32_PWM_USE_TIM3 FALSE diff --git a/testhal/STM32/SPI/mcuconf.h b/testhal/STM32/SPI/mcuconf.h index cd2052da7..d1f919486 100644 --- a/testhal/STM32/SPI/mcuconf.h +++ b/testhal/STM32/SPI/mcuconf.h @@ -91,6 +91,7 @@ /* * PWM driver system settings. */ +#define STM32_PWM_USE_ADVANCED TRUE #define STM32_PWM_USE_TIM1 TRUE #define STM32_PWM_USE_TIM2 FALSE #define STM32_PWM_USE_TIM3 FALSE diff --git a/testhal/STM32/UART/mcuconf.h b/testhal/STM32/UART/mcuconf.h index bd96de17b..94e9c5d15 100644 --- a/testhal/STM32/UART/mcuconf.h +++ b/testhal/STM32/UART/mcuconf.h @@ -91,6 +91,7 @@ /* * PWM driver system settings. */ +#define STM32_PWM_USE_ADVANCED TRUE #define STM32_PWM_USE_TIM1 TRUE #define STM32_PWM_USE_TIM2 FALSE #define STM32_PWM_USE_TIM3 FALSE diff --git a/testhal/STM32/USB_CDC/mcuconf.h b/testhal/STM32/USB_CDC/mcuconf.h index bd96de17b..94e9c5d15 100644 --- a/testhal/STM32/USB_CDC/mcuconf.h +++ b/testhal/STM32/USB_CDC/mcuconf.h @@ -91,6 +91,7 @@ /* * PWM driver system settings. */ +#define STM32_PWM_USE_ADVANCED TRUE #define STM32_PWM_USE_TIM1 TRUE #define STM32_PWM_USE_TIM2 FALSE #define STM32_PWM_USE_TIM3 FALSE diff --git a/testhal/STM32/USB_MSC/mcuconf.h b/testhal/STM32/USB_MSC/mcuconf.h index bd96de17b..94e9c5d15 100644 --- a/testhal/STM32/USB_MSC/mcuconf.h +++ b/testhal/STM32/USB_MSC/mcuconf.h @@ -91,6 +91,7 @@ /* * PWM driver system settings. */ +#define STM32_PWM_USE_ADVANCED TRUE #define STM32_PWM_USE_TIM1 TRUE #define STM32_PWM_USE_TIM2 FALSE #define STM32_PWM_USE_TIM3 FALSE