// // Created by enik on 15.07.22. // //#include "led_rgb.h" #include "math.h" #include "main.h" extern TIM_HandleTypeDef htim2; static TIM_HandleTypeDef *htim; static void HSV2RGB(uint8_t hue, uint8_t sat, uint8_t val, uint8_t *_r, uint8_t *_g, uint8_t *_b); /** * @brief Initialize LED Timer * @param[in] tmr Handler to HAL Timer * @param[in] ch_r Red Channel * @param[in] ch_g Green Channel * @param[in] ch_b Blue Channel */ void led_init(TIM_HandleTypeDef *tmr, uint32_t ch_r, uint32_t ch_g, uint32_t ch_b) { // htim = tmr; TIM2->PSC = 100 - 1; // 32 MHz TIM2->ARR = 320 - 1; // 32.000.000 / 32.000 = 1.000 Hz led_setRGB(0, 0, 0); HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2); HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3); } /** * @brief Set LED Color in RGB * @param[in] r Red component * @param[in] g Green component * @param[in] b Blue component */ void led_setRGB(uint8_t r, uint8_t g, uint8_t b) { // uint32_t r_val = 720 - (r * 320 / 256); // uint32_t g_val = 720 - (g * 320 / 256); // uint32_t b_val = 720 - (b * 320 / 256); uint32_t r_val = (r * 320 / 256); uint32_t g_val = (g * 320 / 256); uint32_t b_val = (b * 320 / 256); // TIM2->CCR1 = b_val; // TIM2->CCR2 = r_val; // TIM2->CCR3 = g_val; TIM2->CCR1 = r_val; TIM2->CCR2 = g_val; TIM2->CCR3 = b_val; } /** * @brief Set LED Color in HSV * @param hue * @param sat * @param val */ void led_setHSV(uint8_t hue, uint8_t sat, uint8_t val) { uint8_t r, g, b; HSV2RGB(hue, sat, val, &r, &g, &b); led_setRGB(r, g, b); } /** * @brief Convert color in HSV to RGB * @param[in] hue HUE (color) [0..255] * @param[in] sat Saturation [0..255] * @param[in] val Value (brightness) [0..255] * @param[out] _r Pointer to RED component value * @param[out] _g Pointer to GREEN component value * @param[out] _b Pointer to BLUE component value */ static void HSV2RGB(uint8_t hue, uint8_t sat, uint8_t val, uint8_t *_r, uint8_t *_g, uint8_t *_b) { if (sat == 0) { // if white color *_r = *_g = *_b = val; return; } // Float is smoother but check for FPU (Floating point unit) in your MCU // Otherwise it will take longer time in the code // FPU is in: F3/L3 and greater // Src: https://github.com/Inseckto/HSV-to-RGB float h = (float) hue / 255; float s = (float) sat / 255; float v = (float) val / 255; int i = (int) floorf(h * 6); float f = h * 6 - (float) i; uint8_t p = (uint8_t) (v * (1 - s) * 255.0); uint8_t q = (uint8_t) (v * (1 - f * s) * 255.0); uint8_t t = (uint8_t) (v * (1 - (1 - f) * s) * 255.0); switch (i % 6) { // Src: https://stackoverflow.com/questions/3018313 // uint8_t reg = hue / 43; // uint8_t rem = (hue - (reg * 43)) * 6; // uint8_t p = (val * (255 - sat)) >> 8; // uint8_t q = (val * (255 - ((sat * rem) >> 8))) >> 8; // uint8_t t = (val * (255 - ((sat * (255 - rem)) >> 8))) >> 8; // switch (reg) { case 0: *_r = val, *_g = t, *_b = p; break; case 1: *_r = q, *_g = val, *_b = p; break; case 2: *_r = p, *_g = val, *_b = t; break; case 3: *_r = p, *_g = q, *_b = val; break; case 4: *_r = t, *_g = p, *_b = val; break; default: *_r = val, *_g = p, *_b = q; break; } }