cpu/stm32/pwm: made channel config more flexible

This commit is contained in:
Hauke Petersen 2017-01-17 14:08:13 +01:00
parent b24be6a6ae
commit 346b51d9fa
2 changed files with 29 additions and 12 deletions

View File

@ -129,16 +129,24 @@ typedef struct {
uint8_t irqn; /**< global IRQ channel */ uint8_t irqn; /**< global IRQ channel */
} timer_conf_t; } 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 * @brief PWM configuration
*/ */
typedef struct { typedef struct {
TIM_TypeDef *dev; /**< Timer used */ TIM_TypeDef *dev; /**< Timer used */
uint32_t rcc_mask; /**< bit in clock enable register */ uint32_t rcc_mask; /**< bit in clock enable register */
gpio_t pins[4]; /**< pins used, set to GPIO_UNDEF if not used */ pwm_chan_t chan[TIMER_CHAN]; /**< channel mapping, set to {GPIO_UNDEF, 0}
gpio_af_t af; /**< alternate function used */ * if not used */
uint8_t chan; /**< number of configured channels */ gpio_af_t af; /**< alternate function used */
uint8_t bus; /**< APB bus */ uint8_t bus; /**< APB bus */
} pwm_conf_t; } pwm_conf_t;
/** /**

View File

@ -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 */ /* configure the used pins */
for (unsigned i = 0; i < pwm_config[pwm].chan; i++) { unsigned i = 0;
gpio_init(pwm_config[pwm].pins[i], GPIO_OUT); while ((i < TIMER_CHAN) && (pwm_config[pwm].chan[i].pin != GPIO_UNDEF)) {
gpio_init_af(pwm_config[pwm].pins[i], pwm_config[pwm].af); 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 /* 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) uint8_t pwm_channels(pwm_t pwm)
{ {
assert(pwm < PWM_NUMOF); 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) 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 */ /* norm value to maximum possible value */
if (value > dev(pwm)->ARR) { if (value > dev(pwm)->ARR) {
value = (uint16_t)dev(pwm)->ARR; value = (uint16_t)dev(pwm)->ARR;
} }
/* set new value */ /* 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) void pwm_start(pwm_t pwm)