wip
This commit is contained in:
parent
c44104b301
commit
d14354e47c
34
source/firmware/arch/stm32f4xx/driver/include/stm32f4_pwm.h
Normal file
34
source/firmware/arch/stm32f4xx/driver/include/stm32f4_pwm.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* 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_
|
||||||
|
|
||||||
|
enum stm32f4_pwm_channel {
|
||||||
|
channel_1 = 1,
|
||||||
|
channel_2,
|
||||||
|
channel_3,
|
||||||
|
channel_4
|
||||||
|
};
|
||||||
|
|
||||||
|
struct stm32f4_pwm {
|
||||||
|
TIM_TypeDef *timer;
|
||||||
|
const TIM_TimeBaseInitTypeDef *timer_cfg;
|
||||||
|
const TIM_OCInitTypeDef *output_compare_cfg;
|
||||||
|
const TIM_BDTRInitTypeDef *bdtr_cfg;
|
||||||
|
GPIO_TypeDef *port;
|
||||||
|
uint8_t pin_src;
|
||||||
|
const GPIO_InitTypeDef *port_cfg;
|
||||||
|
enum stm32f4_pwm_channel channel;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
#endif /* SOURCE_FIRMWARE_ARCH_STM32F4XX_DRIVER_INCLUDE_STM32F4_PWM_H_ */
|
99
source/firmware/arch/stm32f4xx/driver/stm32f4_pwm.c
Normal file
99
source/firmware/arch/stm32f4xx/driver/stm32f4_pwm.c
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* stm32f4_pwm.c
|
||||||
|
*
|
||||||
|
* Created on: Aug 9, 2016
|
||||||
|
* Author: tkl
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "stm32f4xx.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(struct stm32f4_pwm *pwm)
|
||||||
|
{
|
||||||
|
uint32_t clk_ahb_timer = 0, clk_ahb_gpio = 0;
|
||||||
|
uint8_t gpio_af_timer = 0;
|
||||||
|
if(pwm->timer == TIM4) {
|
||||||
|
clk_ahb_timer = RCC_APB1Periph_TIM4;
|
||||||
|
gpio_af_timer = GPIO_AF_TIM4;
|
||||||
|
}
|
||||||
|
RCC_APB1PeriphClockCmd(clk_ahb_timer, ENABLE);
|
||||||
|
if(pwm->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);
|
||||||
|
|
||||||
|
TIM_TimeBaseInit(pwm->timer, (TIM_TimeBaseInitTypeDef *)pwm->timer_cfg);
|
||||||
|
|
||||||
|
switch(pwm->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;
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
TIM_ARRPreloadConfig(pwm->timer, ENABLE);
|
||||||
|
TIM_Cmd(pwm->timer, ENABLE);
|
||||||
|
stm32f4_pwm_object.used_channels++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int stm32f4_pwm_close(struct stm32f4_pwm *pwm)
|
||||||
|
{
|
||||||
|
stm32f4_pwm_object.used_channels--;
|
||||||
|
if(stm32f4_pwm_object.used_channels == 0) {
|
||||||
|
TIM_Cmd(pwm->timer, DISABLE);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int stm32f4_pwm_set_duty_cycle(struct stm32f4_pwm *pwm, unsigned int duty_cycle_percent)
|
||||||
|
{
|
||||||
|
switch(pwm->channel) {
|
||||||
|
case channel_1:
|
||||||
|
TIM_SetCompare1(pwm->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);
|
||||||
|
break;
|
||||||
|
case channel_3:
|
||||||
|
TIM_SetCompare3(pwm->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);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
@ -17,24 +17,7 @@
|
|||||||
#include "shell.h"
|
#include "shell.h"
|
||||||
|
|
||||||
#include "stm32f4xx.h"
|
#include "stm32f4xx.h"
|
||||||
|
#include "stm32f4_pwm.h"
|
||||||
enum stm32f4_pwm_channel {
|
|
||||||
channel_1 = 1,
|
|
||||||
channel_2,
|
|
||||||
channel_3,
|
|
||||||
channel_4
|
|
||||||
};
|
|
||||||
|
|
||||||
struct stm32f4_pwm {
|
|
||||||
TIM_TypeDef *timer;
|
|
||||||
const TIM_TimeBaseInitTypeDef *timer_cfg;
|
|
||||||
const TIM_OCInitTypeDef *output_compare_cfg;
|
|
||||||
const TIM_BDTRInitTypeDef *bdtr_cfg;
|
|
||||||
GPIO_TypeDef *port;
|
|
||||||
uint8_t pin_src;
|
|
||||||
const GPIO_InitTypeDef *port_cfg;
|
|
||||||
enum stm32f4_pwm_channel channel;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* apb1 clock = 84MHz */
|
/* apb1 clock = 84MHz */
|
||||||
/* period_reg = src_clk / presc / cnt_clk */
|
/* period_reg = src_clk / presc / cnt_clk */
|
||||||
@ -76,74 +59,25 @@ static struct stm32f4_pwm str32f4_pwm = {
|
|||||||
.channel = channel_4,
|
.channel = channel_4,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern uint32_t SystemCoreClock;
|
|
||||||
void pwm_open(struct stm32f4_pwm *pwm)
|
|
||||||
{
|
|
||||||
|
|
||||||
uint32_t clk_ahb_timer = 0, clk_ahb_gpio = 0;
|
|
||||||
uint8_t gpio_af_timer = 0;
|
|
||||||
if(pwm->timer == TIM4) {
|
|
||||||
clk_ahb_timer = RCC_APB1Periph_TIM4;
|
|
||||||
gpio_af_timer = GPIO_AF_TIM4;
|
|
||||||
}
|
|
||||||
RCC_APB1PeriphClockCmd(clk_ahb_timer, ENABLE);
|
|
||||||
if(pwm->port == GPIOD) {
|
|
||||||
clk_ahb_gpio = RCC_AHB1Periph_GPIOD;
|
|
||||||
}
|
|
||||||
/* LEDs are on 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);
|
|
||||||
|
|
||||||
/* Time base configuration */
|
|
||||||
TIM_TimeBaseInit(pwm->timer, (TIM_TimeBaseInitTypeDef *)pwm->timer_cfg);
|
|
||||||
|
|
||||||
switch(pwm->channel) {
|
|
||||||
case channel_1:
|
|
||||||
TIM_OC1Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg);
|
|
||||||
TIM_OC1PreloadConfig(pwm->timer, TIM_OCPreload_Enable);
|
|
||||||
break;
|
|
||||||
case channel_2:
|
|
||||||
TIM_OC2Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg);
|
|
||||||
TIM_OC2PreloadConfig(pwm->timer, TIM_OCPreload_Enable);
|
|
||||||
break;
|
|
||||||
case channel_3:
|
|
||||||
TIM_OC3Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg);
|
|
||||||
TIM_OC3PreloadConfig(pwm->timer, TIM_OCPreload_Enable);
|
|
||||||
break;
|
|
||||||
case channel_4:
|
|
||||||
TIM_OC4Init(pwm->timer, (TIM_OCInitTypeDef *)pwm->output_compare_cfg);
|
|
||||||
TIM_OC4PreloadConfig(pwm->timer, TIM_OCPreload_Enable);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
TIM_ARRPreloadConfig(pwm->timer, ENABLE);
|
|
||||||
TIM_Cmd(pwm->timer, ENABLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define TH_STACK_SIZE 256
|
#define TH_STACK_SIZE 256
|
||||||
stack_t th_stack[TH_STACK_SIZE];
|
stack_t th_stack[TH_STACK_SIZE];
|
||||||
struct thread_context th_ctx;
|
struct thread_context th_ctx;
|
||||||
static void th_func(void *arg)
|
static void th_func(void *arg)
|
||||||
{
|
{
|
||||||
uint32_t brightness = 4200 / 2;
|
unsigned int duty = 0;
|
||||||
TIM4->CCR4 = brightness;
|
|
||||||
while(1) {
|
while(1) {
|
||||||
brightness++;
|
stm32f4_pwm_set_duty_cycle(&str32f4_pwm, duty);
|
||||||
if(brightness == UINT32_MAX)
|
sleep_ms(100);
|
||||||
brightness = 0;
|
duty++;
|
||||||
#if 0
|
if(duty > 100)
|
||||||
TIM4->CCR3 = 333 - (brightness + 0) % 333; // set brightness
|
duty = 0;
|
||||||
TIM4->CCR4 = 333 - (brightness + 166/2) % 333; // set brightness
|
|
||||||
TIM4->CCR1 = 333 - (brightness + 333/2) % 333; // set brightness
|
|
||||||
TIM4->CCR2 = 333 - (brightness + 499/2) % 333; // set brightness
|
|
||||||
#endif
|
|
||||||
sleep_ms(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
pwm_open(&str32f4_pwm);
|
stm32f4_pwm_open(&str32f4_pwm);
|
||||||
thread_create(&th_ctx, th_stack, TH_STACK_SIZE, th_func, NULL, THREAD_PRIO_LOW);
|
thread_create(&th_ctx, th_stack, TH_STACK_SIZE, th_func, NULL, THREAD_PRIO_LOW);
|
||||||
|
|
||||||
schedule_start();
|
schedule_start();
|
||||||
|
Loading…
Reference in New Issue
Block a user