/* * rgbled.c * * using TIM2 CH1-CH3 */ #include #include #include "rtc.h" #include "port_pwr.h" #define RED 0 #define GRN 1 #define BLU 2 #define BRT_RED 200 #define BRT_GRN 100 #define BRT_BLU 200 #define RGBLED_TIM TIM2 static uint8_t flash_timeout[3]; static uint8_t flash[3] = {0}; static uint8_t state[3] = {0}; void rgbled_set() { uint8_t i; // flash counters for (i = 0; i < 3; i++) { if (!flash[i]) { flash[i] = flash_timeout[i]; } else flash[i]--; switch (flash_timeout[i]) { // always on case 0x00: { state[i] = 1; break; } // always off case 0xff: { state[i] = 0; break; } // standard default: { if (flash[i] == flash_timeout[i]) { state[i] ^= 1; } } } } RGBLED_TIM->CH1CVR = state[RED] ? BRT_RED : 0; RGBLED_TIM->CH2CVR = state[GRN] ? BRT_GRN : 0; RGBLED_TIM->CH3CVR = state[BLU] ? BRT_BLU : 0; } void rgbled_update() { uint16_t w; // VCR flash if clock isn't set w = BKP_ReadBackupRegister(RTC_STATE_DR); switch (w) { case RTC_STATE_UNINITIALIZED: { flash_timeout[BLU] = 254; break; } default: { flash_timeout[BLU] = 0; break; } } flash_timeout[GRN] = gat_pwr_state() ? 0 : 0xff; flash_timeout[RED] = gat_oc_state() ? 50 : 0xff; } void rgbled_init() { TIM_TimeBaseInitTypeDef timer ={0}; TIM_OCInitTypeDef pwm = {0}; timer.TIM_Period = (1 << 10) - 1; // 10-bit timer.TIM_Prescaler = 0; timer.TIM_ClockDivision = TIM_CKD_DIV1; timer.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(RGBLED_TIM, &timer); pwm.TIM_OCMode = TIM_OCMode_PWM1; pwm.TIM_OutputState = TIM_OutputState_Enable; pwm.TIM_Pulse = 0; pwm.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(RGBLED_TIM, &pwm); TIM_OC2Init(RGBLED_TIM, &pwm); TIM_OC3Init(RGBLED_TIM, &pwm); TIM_CtrlPWMOutputs(RGBLED_TIM, ENABLE); TIM_OC1PreloadConfig(RGBLED_TIM, TIM_OCPreload_Disable); TIM_ARRPreloadConfig(RGBLED_TIM, ENABLE); TIM_Cmd(RGBLED_TIM, ENABLE); RGBLED_TIM->CH1CVR = 0; RGBLED_TIM->CH2CVR = 0; RGBLED_TIM->CH3CVR = 0; }