/* * main.c * * Created on: Aug 2, 2016 * Author: tkl */ #include #include "driver.h" #include "board.h" #include "stack.h" #include "queue.h" #include "kernel.h" #include "driver.h" #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(); return 0; }