diff --git a/arch/arm/src/stm32/stm32_tim.c b/arch/arm/src/stm32/stm32_tim.c index 52db0764b76..d634ed9b64d 100644 --- a/arch/arm/src/stm32/stm32_tim.c +++ b/arch/arm/src/stm32/stm32_tim.c @@ -1,4 +1,4 @@ -/************************************************************************************ +/**************************************************************************** * arch/arm/src/stm32/stm32_tim.c * * Copyright (C) 2011 Uros Platise. All rights reserved. @@ -36,11 +36,11 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************************/ + ****************************************************************************/ -/************************************************************************************ +/**************************************************************************** * Included Files - ************************************************************************************/ + ****************************************************************************/ #include #include @@ -62,28 +62,31 @@ #include "stm32_gpio.h" #include "stm32_tim.h" -/************************************************************************************ +/**************************************************************************** * Pre-processor Definitions - ************************************************************************************/ + ****************************************************************************/ -/* Configuration ********************************************************************/ -/* Timer devices may be used for different purposes. Such special purposes include: +/* Configuration ************************************************************/ + +/* Timer devices may be used for different purposes. Such special purposes + * include: * - * - To generate modulated outputs for such things as motor control. If CONFIG_STM32_TIMn - * is defined then the CONFIG_STM32_TIMn_PWM may also be defined to indicate that - * the timer is intended to be used for pulsed output modulation. + * - To generate modulated outputs for such things as motor control. If + * CONFIG_STM32_TIMn is defined then the CONFIG_STM32_TIMn_PWM may also be + * defined to indicate that the timer is intended to be used for pulsed + * output modulation. * - * - To control periodic ADC input sampling. If CONFIG_STM32_TIMn is defined then - * CONFIG_STM32_TIMn_ADC may also be defined to indicate that timer "n" is intended - * to be used for that purpose. + * - To control periodic ADC input sampling. If CONFIG_STM32_TIMn is + * defined then CONFIG_STM32_TIMn_ADC may also be defined to indicate that + * timer "n" is intended to be used for that purpose. * * - To control periodic DAC outputs. If CONFIG_STM32_TIMn is defined then - * CONFIG_STM32_TIMn_DAC may also be defined to indicate that timer "n" is intended - * to be used for that purpose. + * CONFIG_STM32_TIMn_DAC may also be defined to indicate that timer "n" is + * intended to be used for that purpose. * * - To use a Quadrature Encoder. If CONFIG_STM32_TIMn is defined then - * CONFIG_STM32_TIMn_QE may also be defined to indicate that timer "n" is intended - * to be used for that purpose. + * CONFIG_STM32_TIMn_QE may also be defined to indicate that timer "n" is + * intended to be used for that purpose. * * In any of these cases, the timer will not be used by this timer module. */ @@ -275,8 +278,8 @@ #endif #endif -/* This module then only compiles if there are enabled timers that are not intended for - * some other purpose. +/* This module then only compiles if there are enabled timers that are not + * intended for some other purpose. */ #if defined(CONFIG_STM32_TIM1) || defined(CONFIG_STM32_TIM2) || \ @@ -289,9 +292,9 @@ defined(CONFIG_STM32_TIM15) || defined(CONFIG_STM32_TIM16) || \ defined(CONFIG_STM32_TIM17) -/************************************************************************************ +/**************************************************************************** * Private Types - ************************************************************************************/ + ****************************************************************************/ /* TIM Device Structure */ @@ -302,23 +305,23 @@ struct stm32_tim_priv_s uint32_t base; /* TIMn base address */ }; -/************************************************************************************ +/**************************************************************************** * Private Function prototypes - ************************************************************************************/ + ****************************************************************************/ /* Register helpers */ static inline uint16_t stm32_getreg16(FAR struct stm32_tim_dev_s *dev, uint8_t offset); -static inline void stm32_putreg16(FAR struct stm32_tim_dev_s *dev, uint8_t offset, - uint16_t value); +static inline void stm32_putreg16(FAR struct stm32_tim_dev_s *dev, + uint8_t offset, uint16_t value); static inline void stm32_modifyreg16(FAR struct stm32_tim_dev_s *dev, uint8_t offset, uint16_t clearbits, uint16_t setbits); static inline uint32_t stm32_getreg32(FAR struct stm32_tim_dev_s *dev, uint8_t offset); -static inline void stm32_putreg32(FAR struct stm32_tim_dev_s *dev, uint8_t offset, - uint32_t value); +static inline void stm32_putreg32(FAR struct stm32_tim_dev_s *dev, + uint8_t offset, uint32_t value); /* Timer helpers */ @@ -333,28 +336,34 @@ static void stm32_tim_gpioconfig(uint32_t cfg, stm32_tim_channel_t mode); /* Timer methods */ -static int stm32_tim_setmode(FAR struct stm32_tim_dev_s *dev, stm32_tim_mode_t mode); -static int stm32_tim_setclock(FAR struct stm32_tim_dev_s *dev, uint32_t freq); +static int stm32_tim_setmode(FAR struct stm32_tim_dev_s *dev, + stm32_tim_mode_t mode); +static int stm32_tim_setclock(FAR struct stm32_tim_dev_s *dev, + uint32_t freq); static void stm32_tim_setperiod(FAR struct stm32_tim_dev_s *dev, uint32_t period); static uint32_t stm32_tim_getcounter(FAR struct stm32_tim_dev_s *dev); -static void stm32_tim_setcounter(FAR struct stm32_tim_dev_s *dev, uint32_t count); +static void stm32_tim_setcounter(FAR struct stm32_tim_dev_s *dev, + uint32_t count); static int stm32_tim_getwidth(FAR struct stm32_tim_dev_s *dev); -static int stm32_tim_setchannel(FAR struct stm32_tim_dev_s *dev, uint8_t channel, - stm32_tim_channel_t mode); -static int stm32_tim_setcompare(FAR struct stm32_tim_dev_s *dev, uint8_t channel, - uint32_t compare); -static int stm32_tim_getcapture(FAR struct stm32_tim_dev_s *dev, uint8_t channel); -static int stm32_tim_setisr(FAR struct stm32_tim_dev_s *dev, xcpt_t handler, - void *arg, int source); -static void stm32_tim_enableint(FAR struct stm32_tim_dev_s *dev, int source); -static void stm32_tim_disableint(FAR struct stm32_tim_dev_s *dev, int source); +static int stm32_tim_setchannel(FAR struct stm32_tim_dev_s *dev, + uint8_t channel, stm32_tim_channel_t mode); +static int stm32_tim_setcompare(FAR struct stm32_tim_dev_s *dev, + uint8_t channel, uint32_t compare); +static int stm32_tim_getcapture(FAR struct stm32_tim_dev_s *dev, + uint8_t channel); +static int stm32_tim_setisr(FAR struct stm32_tim_dev_s *dev, + xcpt_t handler, void *arg, int source); +static void stm32_tim_enableint(FAR struct stm32_tim_dev_s *dev, + int source); +static void stm32_tim_disableint(FAR struct stm32_tim_dev_s *dev, + int source); static void stm32_tim_ackint(FAR struct stm32_tim_dev_s *dev, int source); static int stm32_tim_checkint(FAR struct stm32_tim_dev_s *dev, int source); -/************************************************************************************ +/**************************************************************************** * Private Data - ************************************************************************************/ + ****************************************************************************/ static const struct stm32_tim_ops_s stm32_tim_ops = { @@ -526,17 +535,17 @@ struct stm32_tim_priv_s stm32_tim17_priv = }; #endif -/************************************************************************************ +/**************************************************************************** * Private Functions - ************************************************************************************/ + ****************************************************************************/ -/************************************************************************************ +/**************************************************************************** * Name: stm32_getreg16 * * Description: * Get a 16-bit register value by offset * - ************************************************************************************/ + ****************************************************************************/ static inline uint16_t stm32_getreg16(FAR struct stm32_tim_dev_s *dev, uint8_t offset) @@ -544,43 +553,44 @@ static inline uint16_t stm32_getreg16(FAR struct stm32_tim_dev_s *dev, return getreg16(((struct stm32_tim_priv_s *)dev)->base + offset); } -/************************************************************************************ +/**************************************************************************** * Name: stm32_putreg16 * * Description: * Put a 16-bit register value by offset * - ************************************************************************************/ + ****************************************************************************/ -static inline void stm32_putreg16(FAR struct stm32_tim_dev_s *dev, uint8_t offset, - uint16_t value) +static inline void stm32_putreg16(FAR struct stm32_tim_dev_s *dev, + uint8_t offset, uint16_t value) { putreg16(value, ((struct stm32_tim_priv_s *)dev)->base + offset); } -/************************************************************************************ +/**************************************************************************** * Name: stm32_modifyreg16 * * Description: * Modify a 16-bit register value by offset * - ************************************************************************************/ + ****************************************************************************/ static inline void stm32_modifyreg16(FAR struct stm32_tim_dev_s *dev, uint8_t offset, uint16_t clearbits, uint16_t setbits) { - modifyreg16(((struct stm32_tim_priv_s *)dev)->base + offset, clearbits, setbits); + modifyreg16(((struct stm32_tim_priv_s *)dev)->base + offset, + clearbits, setbits); } -/************************************************************************************ +/**************************************************************************** * Name: stm32_getreg32 * * Description: - * Get a 32-bit register value by offset. This applies only for the STM32 F4 - * 32-bit registers (CNT, ARR, CRR1-4) in the 32-bit timers TIM2-5. + * Get a 32-bit register value by offset. This applies only for the STM32 + * F4 32-bit registers (CNT, ARR, CRR1-4) in the 32-bit timers TIM2-5. * - ************************************************************************************/ + ****************************************************************************/ static inline uint32_t stm32_getreg32(FAR struct stm32_tim_dev_s *dev, uint8_t offset) @@ -588,24 +598,24 @@ static inline uint32_t stm32_getreg32(FAR struct stm32_tim_dev_s *dev, return getreg32(((struct stm32_tim_priv_s *)dev)->base + offset); } -/************************************************************************************ +/**************************************************************************** * Name: stm32_putreg32 * * Description: - * Put a 32-bit register value by offset. This applies only for the STM32 F4 - * 32-bit registers (CNT, ARR, CRR1-4) in the 32-bit timers TIM2-5. + * Put a 32-bit register value by offset. This applies only for the STM32 + * F4 32-bit registers (CNT, ARR, CRR1-4) in the 32-bit timers TIM2-5. * - ************************************************************************************/ + ****************************************************************************/ -static inline void stm32_putreg32(FAR struct stm32_tim_dev_s *dev, uint8_t offset, - uint32_t value) +static inline void stm32_putreg32(FAR struct stm32_tim_dev_s *dev, + uint8_t offset, uint32_t value) { putreg32(value, ((struct stm32_tim_priv_s *)dev)->base + offset); } -/************************************************************************************ +/**************************************************************************** * Name: stm32_tim_reload_counter - ************************************************************************************/ + ****************************************************************************/ static void stm32_tim_reload_counter(FAR struct stm32_tim_dev_s *dev) { @@ -614,9 +624,9 @@ static void stm32_tim_reload_counter(FAR struct stm32_tim_dev_s *dev) stm32_putreg16(dev, STM32_BTIM_EGR_OFFSET, val); } -/************************************************************************************ +/**************************************************************************** * Name: stm32_tim_enable - ************************************************************************************/ + ****************************************************************************/ static void stm32_tim_enable(FAR struct stm32_tim_dev_s *dev) { @@ -626,9 +636,9 @@ static void stm32_tim_enable(FAR struct stm32_tim_dev_s *dev) stm32_putreg16(dev, STM32_BTIM_CR1_OFFSET, val); } -/************************************************************************************ +/**************************************************************************** * Name: stm32_tim_disable - ************************************************************************************/ + ****************************************************************************/ static void stm32_tim_disable(FAR struct stm32_tim_dev_s *dev) { @@ -637,13 +647,14 @@ static void stm32_tim_disable(FAR struct stm32_tim_dev_s *dev) stm32_putreg16(dev, STM32_BTIM_CR1_OFFSET, val); } -/************************************************************************************ +/**************************************************************************** * Name: stm32_tim_reset * * Description: - * Reset timer into system default state, but do not affect output/input pins + * Reset timer into system default state, but do not affect output/input + * pins * - ************************************************************************************/ + ****************************************************************************/ static void stm32_tim_reset(FAR struct stm32_tim_dev_s *dev) { @@ -651,9 +662,9 @@ static void stm32_tim_reset(FAR struct stm32_tim_dev_s *dev) stm32_tim_disable(dev); } -/************************************************************************************ +/**************************************************************************** * Name: stm32_tim_gpioconfig - ************************************************************************************/ + ****************************************************************************/ #ifdef HAVE_TIM_GPIOCONFIG static void stm32_tim_gpioconfig(uint32_t cfg, stm32_tim_channel_t mode) @@ -671,11 +682,12 @@ static void stm32_tim_gpioconfig(uint32_t cfg, stm32_tim_channel_t mode) } #endif -/************************************************************************************ +/**************************************************************************** * Name: stm32_tim_setmode - ************************************************************************************/ + ****************************************************************************/ -static int stm32_tim_setmode(FAR struct stm32_tim_dev_s *dev, stm32_tim_mode_t mode) +static int stm32_tim_setmode(FAR struct stm32_tim_dev_s *dev, + stm32_tim_mode_t mode) { uint16_t val = ATIM_CR1_CEN | ATIM_CR1_ARPE; @@ -713,8 +725,11 @@ static int stm32_tim_setmode(FAR struct stm32_tim_dev_s *dev, stm32_tim_mode_t m break; case STM32_TIM_MODE_UPDOWN: + /* Our default: + * Interrupts are generated on compare, when counting down + */ + val |= ATIM_CR1_CENTER1; - // Our default: Interrupts are generated on compare, when counting down break; case STM32_TIM_MODE_PULSE: @@ -744,9 +759,9 @@ static int stm32_tim_setmode(FAR struct stm32_tim_dev_s *dev, stm32_tim_mode_t m return OK; } -/************************************************************************************ +/**************************************************************************** * Name: stm32_tim_setclock - ************************************************************************************/ + ****************************************************************************/ static int stm32_tim_setclock(FAR struct stm32_tim_dev_s *dev, uint32_t freq) { @@ -889,9 +904,9 @@ static int stm32_tim_setclock(FAR struct stm32_tim_dev_s *dev, uint32_t freq) return prescaler; } -/************************************************************************************ +/**************************************************************************** * Name: stm32_tim_setperiod - ************************************************************************************/ + ****************************************************************************/ static void stm32_tim_setperiod(FAR struct stm32_tim_dev_s *dev, uint32_t period) @@ -900,9 +915,9 @@ static void stm32_tim_setperiod(FAR struct stm32_tim_dev_s *dev, stm32_putreg32(dev, STM32_BTIM_ARR_OFFSET, period); } -/************************************************************************************ +/**************************************************************************** * Name: stm32_tim_getcounter - ************************************************************************************/ + ****************************************************************************/ static uint32_t stm32_tim_getcounter(FAR struct stm32_tim_dev_s *dev) { @@ -912,11 +927,12 @@ static uint32_t stm32_tim_getcounter(FAR struct stm32_tim_dev_s *dev) (uint32_t)stm32_getreg16(dev, STM32_BTIM_CNT_OFFSET); } -/************************************************************************************ +/**************************************************************************** * Name: stm32_tim_setcounter - ************************************************************************************/ + ****************************************************************************/ -static void stm32_tim_setcounter(FAR struct stm32_tim_dev_s *dev, uint32_t count) +static void stm32_tim_setcounter(FAR struct stm32_tim_dev_s *dev, + uint32_t count) { DEBUGASSERT(dev != NULL); @@ -930,9 +946,9 @@ static void stm32_tim_setcounter(FAR struct stm32_tim_dev_s *dev, uint32_t count } } -/************************************************************************************ +/**************************************************************************** * Name: stm32_tim_getwidth - ************************************************************************************/ + ****************************************************************************/ static int stm32_tim_getwidth(FAR struct stm32_tim_dev_s *dev) { @@ -965,12 +981,12 @@ static int stm32_tim_getwidth(FAR struct stm32_tim_dev_s *dev) } } -/************************************************************************************ +/**************************************************************************** * Name: stm32_tim_setchannel - ************************************************************************************/ + ****************************************************************************/ -static int stm32_tim_setchannel(FAR struct stm32_tim_dev_s *dev, uint8_t channel, - stm32_tim_channel_t mode) +static int stm32_tim_setchannel(FAR struct stm32_tim_dev_s *dev, + uint8_t channel, stm32_tim_channel_t mode) { uint16_t ccmr_orig = 0; uint16_t ccmr_val = 0; @@ -1016,7 +1032,8 @@ static int stm32_tim_setchannel(FAR struct stm32_tim_dev_s *dev, uint8_t channel break; case STM32_TIM_CH_OUTPWM: - ccmr_val = (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR1_OC1M_SHIFT) + ATIM_CCMR1_OC1PE; + ccmr_val = (ATIM_CCMR_MODE_PWM1 << ATIM_CCMR1_OC1M_SHIFT) + + ATIM_CCMR1_OC1PE; ccer_val |= ATIM_CCER_CC1E << (channel << 2); break; @@ -1488,12 +1505,12 @@ static int stm32_tim_setchannel(FAR struct stm32_tim_dev_s *dev, uint8_t channel return OK; } -/************************************************************************************ +/**************************************************************************** * Name: stm32_tim_setcompare - ************************************************************************************/ + ****************************************************************************/ -static int stm32_tim_setcompare(FAR struct stm32_tim_dev_s *dev, uint8_t channel, - uint32_t compare) +static int stm32_tim_setcompare(FAR struct stm32_tim_dev_s *dev, + uint8_t channel, uint32_t compare) { DEBUGASSERT(dev != NULL); @@ -1502,26 +1519,32 @@ static int stm32_tim_setcompare(FAR struct stm32_tim_dev_s *dev, uint8_t channel case 1: stm32_putreg32(dev, STM32_GTIM_CCR1_OFFSET, compare); break; + case 2: stm32_putreg32(dev, STM32_GTIM_CCR2_OFFSET, compare); break; + case 3: stm32_putreg32(dev, STM32_GTIM_CCR3_OFFSET, compare); break; + case 4: stm32_putreg32(dev, STM32_GTIM_CCR4_OFFSET, compare); break; + default: return -EINVAL; } + return OK; } -/************************************************************************************ +/**************************************************************************** * Name: stm32_tim_getcapture - ************************************************************************************/ + ****************************************************************************/ -static int stm32_tim_getcapture(FAR struct stm32_tim_dev_s *dev, uint8_t channel) +static int stm32_tim_getcapture(FAR struct stm32_tim_dev_s *dev, + uint8_t channel) { DEBUGASSERT(dev != NULL); @@ -1540,9 +1563,9 @@ static int stm32_tim_getcapture(FAR struct stm32_tim_dev_s *dev, uint8_t channel return -EINVAL; } -/************************************************************************************ +/**************************************************************************** * Name: stm32_tim_setisr - ************************************************************************************/ + ****************************************************************************/ static int stm32_tim_setisr(FAR struct stm32_tim_dev_s *dev, xcpt_t handler, void * arg, int source) @@ -1655,15 +1678,15 @@ static int stm32_tim_setisr(FAR struct stm32_tim_dev_s *dev, xcpt_t handler, /* Otherwise set callback and enable interrupt */ - irq_attach(vectorno, handler ,arg); + irq_attach(vectorno, handler, arg); up_enable_irq(vectorno); return OK; } -/************************************************************************************ +/**************************************************************************** * Name: stm32_tim_enableint - ************************************************************************************/ + ****************************************************************************/ static void stm32_tim_enableint(FAR struct stm32_tim_dev_s *dev, int source) { @@ -1671,9 +1694,9 @@ static void stm32_tim_enableint(FAR struct stm32_tim_dev_s *dev, int source) stm32_modifyreg16(dev, STM32_BTIM_DIER_OFFSET, 0, source); } -/************************************************************************************ +/**************************************************************************** * Name: stm32_tim_disableint - ************************************************************************************/ + ****************************************************************************/ static void stm32_tim_disableint(FAR struct stm32_tim_dev_s *dev, int source) { @@ -1681,18 +1704,18 @@ static void stm32_tim_disableint(FAR struct stm32_tim_dev_s *dev, int source) stm32_modifyreg16(dev, STM32_BTIM_DIER_OFFSET, source, 0); } -/************************************************************************************ +/**************************************************************************** * Name: stm32_tim_ackint - ************************************************************************************/ + ****************************************************************************/ static void stm32_tim_ackint(FAR struct stm32_tim_dev_s *dev, int source) { stm32_putreg16(dev, STM32_BTIM_SR_OFFSET, ~source); } -/************************************************************************************ +/**************************************************************************** * Name: stm32_tim_checkint - ************************************************************************************/ + ****************************************************************************/ static int stm32_tim_checkint(FAR struct stm32_tim_dev_s *dev, int source) { @@ -1700,13 +1723,13 @@ static int stm32_tim_checkint(FAR struct stm32_tim_dev_s *dev, int source) return (regval & source) ? 1 : 0; } -/************************************************************************************ +/**************************************************************************** * Pubic Functions - ************************************************************************************/ + ****************************************************************************/ -/************************************************************************************ +/**************************************************************************** * Name: stm32_tim_init - ************************************************************************************/ + ****************************************************************************/ FAR struct stm32_tim_dev_s *stm32_tim_init(int timer) { @@ -1834,12 +1857,12 @@ FAR struct stm32_tim_dev_s *stm32_tim_init(int timer) return dev; } -/************************************************************************************ +/**************************************************************************** * Name: stm32_tim_deinit * * TODO: Detach interrupts, and close down all TIM Channels * - ************************************************************************************/ + ****************************************************************************/ int stm32_tim_deinit(FAR struct stm32_tim_dev_s * dev) {