wip
This commit is contained in:
parent
d14354e47c
commit
b80a44a4d9
@ -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_ */
|
||||
|
@ -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;
|
||||
}
|
||||
|
35
source/firmware/kernel/driver/include/pwm.h
Normal file
35
source/firmware/kernel/driver/include/pwm.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* pwm.h
|
||||
*
|
||||
* Created on: Aug 9, 2016
|
||||
* Author: tkl
|
||||
*/
|
||||
|
||||
#ifndef SOURCE_FIRMWARE_KERNEL_DRIVER_INCLUDE_PWM_H_
|
||||
#define SOURCE_FIRMWARE_KERNEL_DRIVER_INCLUDE_PWM_H_
|
||||
|
||||
//! \brief Function pointer to the open function.
|
||||
typedef int (*pwm_fp_open_t)(const void*);
|
||||
|
||||
//! \brief Function pointer to the close function.
|
||||
typedef int (*pwm_fp_close_t)(const void*);
|
||||
|
||||
//! \brief Function pointer to the read function.
|
||||
typedef int (*pwm_fp_set_duty_cycle_t)(const void*, unsigned int duty_cycle_percent);
|
||||
|
||||
struct pwm_fp {
|
||||
const pwm_fp_open_t open;
|
||||
const pwm_fp_close_t close;
|
||||
const pwm_fp_set_duty_cycle_t set_duty_cycle;
|
||||
};
|
||||
|
||||
struct pwm {
|
||||
const void *arch_dep_device; //!< Architecture depended pwm device (i.e. stm32f10x_pwm_t).
|
||||
const struct pwm_fp *fp; //!< Function pointer for the pwm driver access.
|
||||
};
|
||||
|
||||
int pwm_open(const struct pwm *device);
|
||||
int pwm_close(const struct pwm *device);
|
||||
int pwm_set_duty_cycle(const struct pwm *device, unsigned int duty_cycle_percent);
|
||||
|
||||
#endif /* SOURCE_FIRMWARE_KERNEL_DRIVER_INCLUDE_PWM_H_ */
|
33
source/firmware/kernel/driver/pwm.c
Normal file
33
source/firmware/kernel/driver/pwm.c
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* pwm.c
|
||||
*
|
||||
* Created on: Aug 9, 2016
|
||||
* Author: tkl
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <pwm.h>
|
||||
|
||||
int pwm_open(const struct pwm *device)
|
||||
{
|
||||
if(NULL == device)
|
||||
return -1;
|
||||
pwm_fp_open_t open = device->fp->open;
|
||||
return open(device->arch_dep_device);
|
||||
}
|
||||
|
||||
int pwm_close(const struct pwm *device)
|
||||
{
|
||||
if(NULL == device)
|
||||
return -1;
|
||||
pwm_fp_close_t close = device->fp->close;
|
||||
return close(device->arch_dep_device);
|
||||
}
|
||||
|
||||
int pwm_set_duty_cycle(const struct pwm *device, unsigned int duty_cycle_percent)
|
||||
{
|
||||
if(NULL == device)
|
||||
return -1;
|
||||
pwm_fp_set_duty_cycle_t set = device->fp->set_duty_cycle;
|
||||
return set(device->arch_dep_device, duty_cycle_percent);
|
||||
}
|
@ -17,6 +17,8 @@
|
||||
#include "shell.h"
|
||||
|
||||
#include "stm32f4xx.h"
|
||||
|
||||
#include "pwm.h"
|
||||
#include "stm32f4_pwm.h"
|
||||
|
||||
/* apb1 clock = 84MHz */
|
||||
@ -59,6 +61,10 @@ static struct stm32f4_pwm str32f4_pwm = {
|
||||
.channel = channel_4,
|
||||
};
|
||||
|
||||
static const struct pwm pwm_ch4 = {
|
||||
.arch_dep_device = &str32f4_pwm,
|
||||
.fp = &stm32f4_pwm_fp,
|
||||
};
|
||||
|
||||
#define TH_STACK_SIZE 256
|
||||
stack_t th_stack[TH_STACK_SIZE];
|
||||
@ -66,8 +72,9 @@ struct thread_context th_ctx;
|
||||
static void th_func(void *arg)
|
||||
{
|
||||
unsigned int duty = 0;
|
||||
pwm_open(&pwm_ch4);
|
||||
while(1) {
|
||||
stm32f4_pwm_set_duty_cycle(&str32f4_pwm, duty);
|
||||
pwm_set_duty_cycle(&pwm_ch4, duty);
|
||||
sleep_ms(100);
|
||||
duty++;
|
||||
if(duty > 100)
|
||||
@ -77,7 +84,6 @@ static void th_func(void *arg)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
stm32f4_pwm_open(&str32f4_pwm);
|
||||
thread_create(&th_ctx, th_stack, TH_STACK_SIZE, th_func, NULL, THREAD_PRIO_LOW);
|
||||
|
||||
schedule_start();
|
||||
|
Loading…
Reference in New Issue
Block a user