pwm driver hal'd
This commit is contained in:
32
source/firmware/arch/stm32f4xx/driver/include/stm32f4_pwm.h
Normal file
32
source/firmware/arch/stm32f4xx/driver/include/stm32f4_pwm.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* stm32f4_pwm.h
|
||||
*
|
||||
* Created on: Aug 9, 2016
|
||||
* Author: tkl
|
||||
*/
|
||||
|
||||
#ifndef SOURCE_FIRMWARE_ARCH_STM32F4XX_DRIVER_INCLUDE_STM32F4_PWM_H_
|
||||
#define SOURCE_FIRMWARE_ARCH_STM32F4XX_DRIVER_INCLUDE_STM32F4_PWM_H_
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
struct stm32f4_pwm {
|
||||
const struct stm32f4_gpio *pwm_gpio;
|
||||
TIM_HandleTypeDef *timer_handle;
|
||||
TIM_OC_InitTypeDef *output_compare_cfg;
|
||||
uint32_t channel;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
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_ */
|
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* stm32f4_pwm.c
|
||||
*
|
||||
* Created on: Aug 9, 2016
|
||||
* Author: tkl
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "stm32f4xx.h"
|
||||
|
||||
#include "pwm.h"
|
||||
#include "stm32f4_pwm.h"
|
||||
|
||||
struct stm32f4_pwm_object {
|
||||
uint8_t used_channels;
|
||||
uint32_t channel_1_max_period;
|
||||
uint32_t channel_2_max_period;
|
||||
uint32_t channel_3_max_period;
|
||||
uint32_t channel_4_max_period;
|
||||
};
|
||||
|
||||
static struct stm32f4_pwm_object stm32f4_pwm_object = {
|
||||
.used_channels = 0,
|
||||
.channel_1_max_period = 0,
|
||||
.channel_2_max_period = 0,
|
||||
.channel_3_max_period = 0,
|
||||
.channel_4_max_period = 0,
|
||||
};
|
||||
|
||||
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(this->timer == TIM4) {
|
||||
clk_ahb_timer = RCC_APB1Periph_TIM4;
|
||||
gpio_af_timer = GPIO_AF_TIM4;
|
||||
}
|
||||
RCC_APB1PeriphClockCmd(clk_ahb_timer, ENABLE);
|
||||
if(this->port == GPIOD) {
|
||||
clk_ahb_gpio = RCC_AHB1Periph_GPIOD;
|
||||
}
|
||||
RCC_AHB1PeriphClockCmd(clk_ahb_gpio, ENABLE);
|
||||
GPIO_Init(this->port, (GPIO_InitTypeDef *)this->port_cfg);
|
||||
GPIO_PinAFConfig(this->port, this->pin_src, gpio_af_timer);
|
||||
|
||||
TIM_TimeBaseInit(this->timer, (TIM_TimeBaseInitTypeDef *)this->timer_cfg);
|
||||
|
||||
switch(this->channel) {
|
||||
case channel_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(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(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(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(this->timer, ENABLE);
|
||||
TIM_Cmd(this->timer, ENABLE);
|
||||
stm32f4_pwm_object.used_channels++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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(this->timer, DISABLE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int stm32f4_pwm_set_duty_cycle(const void *pwm, unsigned int duty_cycle_percent)
|
||||
{
|
||||
if(NULL == pwm)
|
||||
return -1;
|
||||
struct stm32f4_pwm *this = (struct stm32f4_pwm *)pwm;
|
||||
switch(this->channel) {
|
||||
case channel_1:
|
||||
TIM_SetCompare1(this->timer, stm32f4_pwm_object.channel_1_max_period * duty_cycle_percent / 100);
|
||||
break;
|
||||
case channel_2:
|
||||
TIM_SetCompare2(this->timer, stm32f4_pwm_object.channel_2_max_period * duty_cycle_percent / 100);
|
||||
break;
|
||||
case channel_3:
|
||||
TIM_SetCompare3(this->timer, stm32f4_pwm_object.channel_3_max_period * duty_cycle_percent / 100);
|
||||
break;
|
||||
case channel_4:
|
||||
TIM_SetCompare4(this->timer, stm32f4_pwm_object.channel_4_max_period * duty_cycle_percent / 100);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
83
source/firmware/arch/stm32f4xx/driver/stm32f4_pwm.c
Normal file
83
source/firmware/arch/stm32f4xx/driver/stm32f4_pwm.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* stm32f4_pwm.c
|
||||
*
|
||||
* Created on: Aug 9, 2016
|
||||
* Author: tkl
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "stm32f4xx.h"
|
||||
|
||||
#include "gpio.h"
|
||||
#include "stm32f4_gpio.h"
|
||||
|
||||
#include "pwm.h"
|
||||
#include "stm32f4_pwm.h"
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
struct stm32f4_pwm_object {
|
||||
uint8_t used_channels;
|
||||
uint32_t channel_1_max_period;
|
||||
uint32_t channel_2_max_period;
|
||||
uint32_t channel_3_max_period;
|
||||
uint32_t channel_4_max_period;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
int stm32f4_pwm_open(const void *pwm)
|
||||
{
|
||||
if(NULL == pwm)
|
||||
return -1;
|
||||
struct stm32f4_pwm *this = (struct stm32f4_pwm *)pwm;
|
||||
stm32f4_gpio_open(this->pwm_gpio);
|
||||
if(this->timer_handle->Instance == TIM4) {
|
||||
__HAL_RCC_TIM4_CLK_ENABLE();
|
||||
}
|
||||
HAL_TIM_PWM_Init(this->timer_handle);
|
||||
HAL_TIM_PWM_ConfigChannel(this->timer_handle, this->output_compare_cfg, this->channel);
|
||||
|
||||
TIM_MasterConfigTypeDef sMasterConfig;
|
||||
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
||||
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
||||
HAL_TIMEx_MasterConfigSynchronization(this->timer_handle, &sMasterConfig);
|
||||
|
||||
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig;
|
||||
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
|
||||
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
|
||||
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
|
||||
sBreakDeadTimeConfig.DeadTime = 0;
|
||||
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
|
||||
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
|
||||
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
|
||||
HAL_TIMEx_ConfigBreakDeadTime(this->timer_handle, &sBreakDeadTimeConfig);
|
||||
|
||||
|
||||
HAL_TIM_Base_Start(this->timer_handle);
|
||||
HAL_TIM_PWM_Start(this->timer_handle, this->channel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int stm32f4_pwm_close(const void *pwm)
|
||||
{
|
||||
if(NULL == pwm)
|
||||
return -1;
|
||||
stm32f4_pwm_set_duty_cycle(pwm, 0);
|
||||
struct stm32f4_pwm *this = (struct stm32f4_pwm *)pwm;
|
||||
HAL_TIM_Base_Stop(this->timer_handle);
|
||||
HAL_TIM_PWM_Stop(this->timer_handle, this->channel);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int stm32f4_pwm_set_duty_cycle(const void *pwm, unsigned int duty_cycle_percent)
|
||||
{
|
||||
if(NULL == pwm)
|
||||
return -1;
|
||||
|
||||
struct stm32f4_pwm *this = (struct stm32f4_pwm *)pwm;
|
||||
__HAL_TIM_SET_COMPARE(this->timer_handle, this->channel, this->timer_handle->Init.Period * duty_cycle_percent / 100);
|
||||
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user