This commit is contained in:
tkl
2016-08-09 12:28:01 +02:00
parent d14354e47c
commit b80a44a4d9
5 changed files with 128 additions and 34 deletions

View File

@@ -27,8 +27,14 @@ struct stm32f4_pwm {
};
int stm32f4_pwm_open(struct stm32f4_pwm *pwm);
int stm32f4_pwm_close(struct stm32f4_pwm *pwm);
int stm32f4_pwm_set_duty_cycle(struct stm32f4_pwm *pwm, unsigned int duty_cycle_percent);
int stm32f4_pwm_open(const void *pwm);
int stm32f4_pwm_close(const void *pwm);
int stm32f4_pwm_set_duty_cycle(const void *pwm, unsigned int duty_cycle_percent);
static const struct pwm_fp stm32f4_pwm_fp = {
.open = stm32f4_pwm_open,
.close = stm32f4_pwm_close,
.set_duty_cycle = stm32f4_pwm_set_duty_cycle,
};
#endif /* SOURCE_FIRMWARE_ARCH_STM32F4XX_DRIVER_INCLUDE_STM32F4_PWM_H_ */

View File

@@ -5,8 +5,11 @@
* Author: tkl
*/
#include <stdint.h>
#include <stddef.h>
#include "stm32f4xx.h"
#include "pwm.h"
#include "stm32f4_pwm.h"
struct stm32f4_pwm_object {
@@ -25,75 +28,86 @@ static struct stm32f4_pwm_object stm32f4_pwm_object = {
.channel_4_max_period = 0,
};
int stm32f4_pwm_open(struct stm32f4_pwm *pwm)
int stm32f4_pwm_open(const void *pwm)
{
if(NULL == pwm)
return -1;
struct stm32f4_pwm *this = (struct stm32f4_pwm *)pwm;
uint32_t clk_ahb_timer = 0, clk_ahb_gpio = 0;
uint8_t gpio_af_timer = 0;
if(pwm->timer == TIM4) {
if(this->timer == TIM4) {
clk_ahb_timer = RCC_APB1Periph_TIM4;
gpio_af_timer = GPIO_AF_TIM4;
}
RCC_APB1PeriphClockCmd(clk_ahb_timer, ENABLE);
if(pwm->port == GPIOD) {
if(this->port == GPIOD) {
clk_ahb_gpio = RCC_AHB1Periph_GPIOD;
}
RCC_AHB1PeriphClockCmd(clk_ahb_gpio, ENABLE);
GPIO_Init(pwm->port, (GPIO_InitTypeDef *)pwm->port_cfg);
GPIO_PinAFConfig(pwm->port, pwm->pin_src, gpio_af_timer);
GPIO_Init(this->port, (GPIO_InitTypeDef *)this->port_cfg);
GPIO_PinAFConfig(this->port, this->pin_src, gpio_af_timer);
TIM_TimeBaseInit(pwm->timer, (TIM_TimeBaseInitTypeDef *)pwm->timer_cfg);
TIM_TimeBaseInit(this->timer, (TIM_TimeBaseInitTypeDef *)this->timer_cfg);
switch(pwm->channel) {
switch(this->channel) {
case channel_1:
TIM_OC1Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg);
TIM_OC1PreloadConfig(pwm->timer, TIM_OCPreload_Enable);
stm32f4_pwm_object.channel_1_max_period = pwm->timer_cfg->TIM_Period + 1;
TIM_OC1Init(this->timer, (TIM_OCInitTypeDef *)this->output_compare_cfg);
TIM_OC1PreloadConfig(this->timer, TIM_OCPreload_Enable);
stm32f4_pwm_object.channel_1_max_period = this->timer_cfg->TIM_Period + 1;
break;
case channel_2:
TIM_OC2Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg);
TIM_OC2PreloadConfig(pwm->timer, TIM_OCPreload_Enable);
stm32f4_pwm_object.channel_2_max_period = pwm->timer_cfg->TIM_Period + 1;
TIM_OC2Init(this->timer, (TIM_OCInitTypeDef *)this->output_compare_cfg);
TIM_OC2PreloadConfig(this->timer, TIM_OCPreload_Enable);
stm32f4_pwm_object.channel_2_max_period = this->timer_cfg->TIM_Period + 1;
break;
case channel_3:
TIM_OC3Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg);
TIM_OC3PreloadConfig(pwm->timer, TIM_OCPreload_Enable);
stm32f4_pwm_object.channel_3_max_period = pwm->timer_cfg->TIM_Period + 1;
TIM_OC3Init(this->timer, (TIM_OCInitTypeDef *)this->output_compare_cfg);
TIM_OC3PreloadConfig(this->timer, TIM_OCPreload_Enable);
stm32f4_pwm_object.channel_3_max_period = this->timer_cfg->TIM_Period + 1;
break;
case channel_4:
TIM_OC4Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg);
TIM_OC4PreloadConfig(pwm->timer, TIM_OCPreload_Enable);
stm32f4_pwm_object.channel_4_max_period = pwm->timer_cfg->TIM_Period + 1;
TIM_OC4Init(this->timer, (TIM_OCInitTypeDef *)this->output_compare_cfg);
TIM_OC4PreloadConfig(this->timer, TIM_OCPreload_Enable);
stm32f4_pwm_object.channel_4_max_period = this->timer_cfg->TIM_Period + 1;
break;
}
TIM_ARRPreloadConfig(pwm->timer, ENABLE);
TIM_Cmd(pwm->timer, ENABLE);
TIM_ARRPreloadConfig(this->timer, ENABLE);
TIM_Cmd(this->timer, ENABLE);
stm32f4_pwm_object.used_channels++;
return 0;
}
int stm32f4_pwm_close(struct stm32f4_pwm *pwm)
int stm32f4_pwm_close(const void *pwm)
{
if(NULL == pwm)
return -1;
struct stm32f4_pwm *this = (struct stm32f4_pwm *)pwm;
stm32f4_pwm_set_duty_cycle(pwm, 0);
stm32f4_pwm_object.used_channels--;
if(stm32f4_pwm_object.used_channels == 0) {
TIM_Cmd(pwm->timer, DISABLE);
TIM_Cmd(this->timer, DISABLE);
}
return 0;
}
int stm32f4_pwm_set_duty_cycle(struct stm32f4_pwm *pwm, unsigned int duty_cycle_percent)
int stm32f4_pwm_set_duty_cycle(const void *pwm, unsigned int duty_cycle_percent)
{
switch(pwm->channel) {
if(NULL == pwm)
return -1;
struct stm32f4_pwm *this = (struct stm32f4_pwm *)pwm;
switch(this->channel) {
case channel_1:
TIM_SetCompare1(pwm->timer, stm32f4_pwm_object.channel_1_max_period * duty_cycle_percent / 100);
TIM_SetCompare1(this->timer, stm32f4_pwm_object.channel_1_max_period * duty_cycle_percent / 100);
break;
case channel_2:
TIM_SetCompare2(pwm->timer, stm32f4_pwm_object.channel_2_max_period * duty_cycle_percent / 100);
TIM_SetCompare2(this->timer, stm32f4_pwm_object.channel_2_max_period * duty_cycle_percent / 100);
break;
case channel_3:
TIM_SetCompare3(pwm->timer, stm32f4_pwm_object.channel_3_max_period * duty_cycle_percent / 100);
TIM_SetCompare3(this->timer, stm32f4_pwm_object.channel_3_max_period * duty_cycle_percent / 100);
break;
case channel_4:
TIM_SetCompare4(pwm->timer, stm32f4_pwm_object.channel_4_max_period * duty_cycle_percent / 100);
TIM_SetCompare4(this->timer, stm32f4_pwm_object.channel_4_max_period * duty_cycle_percent / 100);
break;
}
return 0;
}