From 346b51d9fa0c8edf4a121d1c92a705b6c36b37d0 Mon Sep 17 00:00:00 2001 From: Hauke Petersen <hauke.petersen@fu-berlin.de> Date: Tue, 17 Jan 2017 14:08:13 +0100 Subject: [PATCH] cpu/stm32/pwm: made channel config more flexible --- cpu/stm32_common/include/periph_cpu_common.h | 20 +++++++++++++------ cpu/stm32_common/periph/pwm.c | 21 ++++++++++++++------ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/cpu/stm32_common/include/periph_cpu_common.h b/cpu/stm32_common/include/periph_cpu_common.h index 98f1eb2d14..a18d5792a0 100644 --- a/cpu/stm32_common/include/periph_cpu_common.h +++ b/cpu/stm32_common/include/periph_cpu_common.h @@ -129,16 +129,24 @@ typedef struct { uint8_t irqn; /**< global IRQ channel */ } timer_conf_t; +/** + * @brief PWM channel + */ +typedef struct { + gpio_t pin; /**< GPIO pin mapped to this channel */ + uint8_t cc_chan; /**< capture compare channel used */ +} pwm_chan_t; + /** * @brief PWM configuration */ typedef struct { - TIM_TypeDef *dev; /**< Timer used */ - uint32_t rcc_mask; /**< bit in clock enable register */ - gpio_t pins[4]; /**< pins used, set to GPIO_UNDEF if not used */ - gpio_af_t af; /**< alternate function used */ - uint8_t chan; /**< number of configured channels */ - uint8_t bus; /**< APB bus */ + TIM_TypeDef *dev; /**< Timer used */ + uint32_t rcc_mask; /**< bit in clock enable register */ + pwm_chan_t chan[TIMER_CHAN]; /**< channel mapping, set to {GPIO_UNDEF, 0} + * if not used */ + gpio_af_t af; /**< alternate function used */ + uint8_t bus; /**< APB bus */ } pwm_conf_t; /** diff --git a/cpu/stm32_common/periph/pwm.c b/cpu/stm32_common/periph/pwm.c index f7009ddd65..511ecf71ff 100644 --- a/cpu/stm32_common/periph/pwm.c +++ b/cpu/stm32_common/periph/pwm.c @@ -58,9 +58,11 @@ uint32_t pwm_init(pwm_t pwm, pwm_mode_t mode, uint32_t freq, uint16_t res) } /* configure the used pins */ - for (unsigned i = 0; i < pwm_config[pwm].chan; i++) { - gpio_init(pwm_config[pwm].pins[i], GPIO_OUT); - gpio_init_af(pwm_config[pwm].pins[i], pwm_config[pwm].af); + unsigned i = 0; + while ((i < TIMER_CHAN) && (pwm_config[pwm].chan[i].pin != GPIO_UNDEF)) { + gpio_init(pwm_config[pwm].chan[i].pin, GPIO_OUT); + gpio_init_af(pwm_config[pwm].chan[i].pin, pwm_config[pwm].af); + i++; } /* configure the PWM frequency and resolution by setting the auto-reload @@ -100,19 +102,26 @@ uint32_t pwm_init(pwm_t pwm, pwm_mode_t mode, uint32_t freq, uint16_t res) uint8_t pwm_channels(pwm_t pwm) { assert(pwm < PWM_NUMOF); - return pwm_config[pwm].chan; + + unsigned i = 0; + while ((i < TIMER_CHAN) && (pwm_config[pwm].chan[i].pin != GPIO_UNDEF)) { + i++; + } + return (uint8_t)i; } void pwm_set(pwm_t pwm, uint8_t channel, uint16_t value) { - assert((pwm < PWM_NUMOF) && (channel < pwm_config[pwm].chan)); + assert((pwm < PWM_NUMOF) && + (channel < TIMER_CHAN) && + (pwm_config[pwm].chan[channel].pin != GPIO_UNDEF)); /* norm value to maximum possible value */ if (value > dev(pwm)->ARR) { value = (uint16_t)dev(pwm)->ARR; } /* set new value */ - dev(pwm)->CCR[channel] = value; + dev(pwm)->CCR[pwm_config[pwm].chan[channel].cc_chan] = value; } void pwm_start(pwm_t pwm) -- GitLab