diff --git a/source/test/pwm/main.c b/source/test/pwm/main.c index 343676f..6e381a3 100644 --- a/source/test/pwm/main.c +++ b/source/test/pwm/main.c @@ -16,17 +16,163 @@ #include "list.h" #include "shell.h" +#include "stm32f4xx.h" + +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; +}; + +static const TIM_TimeBaseInitTypeDef timer_4_cfg = { + .TIM_RepetitionCounter = 0x0000, + .TIM_Prescaler = ((168000000 / 2 ) / 1000000) - 1, + .TIM_ClockDivision = TIM_CKD_DIV1, + .TIM_CounterMode = TIM_CounterMode_Up, + .TIM_Period = 20000 +}; + +static const TIM_OCInitTypeDef t4_output_compare_cfg = { + .TIM_OutputNState = TIM_OutputNState_Disable, + .TIM_OCNPolarity = TIM_OCPolarity_High, + .TIM_OCIdleState = TIM_OCIdleState_Reset, + .TIM_OCNIdleState = TIM_OCNIdleState_Set, + .TIM_OCMode = TIM_OCMode_PWM1, + .TIM_OCPolarity = TIM_OCPolarity_High, + .TIM_OutputState = TIM_OutputState_Enable, + .TIM_Pulse = 1500 // Initiale Pulsweite in Millisekunden +}; + +static const TIM_BDTRInitTypeDef t4_bdtr_cfg = { + .TIM_OSSRState = TIM_OSSRState_Disable, + .TIM_OSSIState = TIM_OSSIState_Disable, + .TIM_LOCKLevel = TIM_LOCKLevel_OFF, + .TIM_DeadTime = 0x00, + .TIM_Break = TIM_Break_Disable, + .TIM_BreakPolarity = TIM_BreakPolarity_Low, + .TIM_AutomaticOutput = TIM_AutomaticOutput_Disable, + + + .TIM_AutomaticOutput = TIM_AutomaticOutput_Enable, +}; + +static const GPIO_InitTypeDef port_cfg = { + .GPIO_Pin = GPIO_Pin_12, + .GPIO_Mode = GPIO_Mode_AF, + .GPIO_OType = GPIO_OType_PP, + .GPIO_PuPd = GPIO_PuPd_UP, + .GPIO_Speed = GPIO_Speed_50MHz, +}; + +static struct stm32f4_pwm str32f4_pwm = { + .timer = TIM4, + .timer_cfg = &timer_4_cfg, + .output_compare_cfg = &t4_output_compare_cfg, + .bdtr_cfg = &t4_bdtr_cfg, + .port = GPIOD, + .pin_src = GPIO_PinSource12, + .port_cfg = &port_cfg, +}; + +extern uint32_t SystemCoreClock; +void pwm_open(struct stm32f4_pwm *pwm) +{ + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; + TIM_OCInitTypeDef TIM_OCInitStructure; + + /* TIM config */ + GPIO_InitTypeDef GPIO_InitStructure; + + /* TIM4 clock enable */ + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); + + /* LEDs are on GPIOD */ + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; + GPIO_Init(GPIOD, &GPIO_InitStructure); + GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4); + GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4); + GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_TIM4); + GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_TIM4); + + /* pwm set up */ + /* Compute the prescaler value */ + uint16_t PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 21000000) - 1; + + /* apb1 clock = 84MHz */ + /* period_reg = src_clk / presc / cnt_clk */ + /* 4199 = 84MHZ / (0 + 1) / 20kHz - 1 */ + + /* Time base configuration */ + TIM_TimeBaseStructure.TIM_Period = 4199;//665; + TIM_TimeBaseStructure.TIM_Prescaler = 0;//PrescalerValue; + TIM_TimeBaseStructure.TIM_ClockDivision = 1; + TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; + TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); + + /* PWM1 Mode configuration: Channel1 */ + TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; + TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; + TIM_OCInitStructure.TIM_Pulse = 0; + TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; + TIM_OC1Init(TIM4, &TIM_OCInitStructure); + TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); + + /* PWM1 Mode configuration: Channel2 */ + TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; + TIM_OCInitStructure.TIM_Pulse = 0; + TIM_OC2Init(TIM4, &TIM_OCInitStructure); + TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); + + /* PWM1 Mode configuration: Channel3 */ + TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; + TIM_OCInitStructure.TIM_Pulse = 0; + TIM_OC3Init(TIM4, &TIM_OCInitStructure); + TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); + + /* PWM1 Mode configuration: Channel4 */ + TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; + TIM_OCInitStructure.TIM_Pulse = 0; + TIM_OC4Init(TIM4, &TIM_OCInitStructure); + TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); + TIM_ARRPreloadConfig(TIM4, ENABLE); + + /* TIM4 enable counter */ + TIM_Cmd(TIM4, ENABLE); +} + #define TH_STACK_SIZE 256 stack_t th_stack[TH_STACK_SIZE]; struct thread_context th_ctx; static void th_func(void *arg) { + uint32_t brightness = 4200 / 2; + TIM4->CCR4 = brightness; while(1) { + brightness++; + if(brightness == UINT32_MAX) + brightness = 0; +#if 0 + TIM4->CCR3 = 333 - (brightness + 0) % 333; // set brightness + 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) { + pwm_open(&str32f4_pwm); thread_create(&th_ctx, th_stack, TH_STACK_SIZE, th_func, NULL, THREAD_PRIO_LOW); schedule_start();