|
|
@@ -17,26 +17,25 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
|
|
|
|
#include <avr/pgmspace.h> |
|
|
|
#include <avr/eeprom.h> |
|
|
|
#include "softpwm_led.h" |
|
|
|
#include "backlight.h" |
|
|
|
#include "rgb.h" |
|
|
|
#include "light_ws2812.h" |
|
|
|
|
|
|
|
static const uint8_t rgb_table[RGB_LEVELS][3] PROGMEM = { |
|
|
|
{ 0, 0, 0 }, |
|
|
|
{ 255, 0, 0 }, |
|
|
|
{ 255, 127, 0 }, |
|
|
|
{ 255, 255, 0 }, |
|
|
|
{ 0, 255, 0 }, |
|
|
|
{ 0, 255, 255 }, |
|
|
|
{ 0, 0, 255 }, |
|
|
|
{ 143, 0, 255 }, |
|
|
|
{ 255, 255, 255 } |
|
|
|
}; |
|
|
|
|
|
|
|
volatile static uint8_t rgb_fading_enable = 0; |
|
|
|
static rgb_config_t rgb_config; |
|
|
|
static uint16_t rgb_hue = 0; |
|
|
|
static uint8_t rgb_saturation = 255; |
|
|
|
static uint8_t rgb_brightness = 16; |
|
|
|
|
|
|
|
extern backlight_config_t backlight_config; |
|
|
|
extern uint8_t backlight_brightness; |
|
|
|
|
|
|
|
void rgb_write_config(void); |
|
|
|
void rgb_read_config(void); |
|
|
|
void rgb_set(uint8_t level); |
|
|
|
static void rgb_write_config(void); |
|
|
|
static void rgb_read_config(void); |
|
|
|
static void rgb_set_level(uint8_t level); |
|
|
|
static void hue_to_rgb(uint16_t hue, struct cRGB *rgb); |
|
|
|
static void hsb_to_rgb(uint16_t hue, uint8_t saturation, uint8_t brightness, struct cRGB *rgb); |
|
|
|
|
|
|
|
void rgb_init(void) |
|
|
|
{ |
|
|
@@ -47,7 +46,7 @@ void rgb_init(void) |
|
|
|
rgb_write_config(); |
|
|
|
} |
|
|
|
if (rgb_config.enable) { |
|
|
|
rgb_set(rgb_config.level); |
|
|
|
rgb_set_level(rgb_config.level); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -74,14 +73,14 @@ void rgb_toggle(void) |
|
|
|
void rgb_on(void) |
|
|
|
{ |
|
|
|
rgb_config.enable = 1; |
|
|
|
rgb_set(rgb_config.level); |
|
|
|
rgb_set_level(rgb_config.level); |
|
|
|
rgb_write_config(); |
|
|
|
} |
|
|
|
|
|
|
|
void rgb_off(void) |
|
|
|
{ |
|
|
|
rgb_config.enable = 0; |
|
|
|
rgb_set(RGB_OFF); |
|
|
|
rgb_set_level(RGB_OFF); |
|
|
|
rgb_write_config(); |
|
|
|
} |
|
|
|
|
|
|
@@ -92,35 +91,121 @@ void rgb_decrease(void) |
|
|
|
rgb_config.enable = (rgb_config.level != 0); |
|
|
|
rgb_write_config(); |
|
|
|
} |
|
|
|
rgb_set(rgb_config.level); |
|
|
|
rgb_set_level(rgb_config.level); |
|
|
|
} |
|
|
|
|
|
|
|
void rgb_increase(void) |
|
|
|
{ |
|
|
|
if(rgb_config.level < RGB_LEVELS - 1) { |
|
|
|
if(rgb_config.level < RGB_LEVELS) { |
|
|
|
rgb_config.level++; |
|
|
|
rgb_config.enable = 1; |
|
|
|
rgb_write_config(); |
|
|
|
} |
|
|
|
rgb_set(rgb_config.level); |
|
|
|
rgb_set_level(rgb_config.level); |
|
|
|
} |
|
|
|
|
|
|
|
void rgb_step(void) |
|
|
|
{ |
|
|
|
rgb_config.level++; |
|
|
|
if(rgb_config.level >= RGB_LEVELS) |
|
|
|
if(rgb_config.level > RGB_LEVELS) |
|
|
|
{ |
|
|
|
rgb_config.level = 0; |
|
|
|
} |
|
|
|
rgb_config.enable = (rgb_config.level != 0); |
|
|
|
rgb_set(rgb_config.level); |
|
|
|
rgb_set_level(rgb_config.level); |
|
|
|
} |
|
|
|
|
|
|
|
void rgb_set_level(uint8_t level) |
|
|
|
{ |
|
|
|
if (level <= RGB_WHITE) { |
|
|
|
rgb_fading_enable = 0; |
|
|
|
if (level == RGB_OFF) { |
|
|
|
rgb_brightness = 0; |
|
|
|
} |
|
|
|
else { |
|
|
|
if (level == RGB_WHITE) { |
|
|
|
rgb_saturation = 0; |
|
|
|
} |
|
|
|
else { |
|
|
|
rgb_hue = (level - 1) * 128; |
|
|
|
rgb_saturation = 255; |
|
|
|
} |
|
|
|
if (backlight_config.enable) { |
|
|
|
if (backlight_config.level >= 1 && backlight_config.level <= 3) { |
|
|
|
rgb_brightness = backlight_brightness; |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
rgb_brightness = 16; |
|
|
|
} |
|
|
|
} |
|
|
|
rgb_refresh(); |
|
|
|
} |
|
|
|
else { |
|
|
|
rgb_saturation = 255; |
|
|
|
rgb_fading_enable = 3 - (level - RGB_FADE_SLOW); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void rgb_set_brightness(uint8_t brightness) |
|
|
|
{ |
|
|
|
rgb_brightness = brightness; |
|
|
|
rgb_refresh(); |
|
|
|
} |
|
|
|
|
|
|
|
void rgb_set(uint8_t level) |
|
|
|
void rgb_refresh(void) |
|
|
|
{ |
|
|
|
struct cRGB rgb[1]; |
|
|
|
rgb[0].r = pgm_read_byte(&rgb_table[level][0]); |
|
|
|
rgb[0].g = pgm_read_byte(&rgb_table[level][1]); |
|
|
|
rgb[0].b = pgm_read_byte(&rgb_table[level][2]); |
|
|
|
ws2812_setleds(rgb, 1); |
|
|
|
struct cRGB rgb_color[1]; |
|
|
|
hsb_to_rgb(rgb_hue, rgb_saturation, rgb_brightness, rgb_color); |
|
|
|
ws2812_setleds(rgb_color, 1); |
|
|
|
} |
|
|
|
|
|
|
|
void hue_to_rgb(uint16_t hue, struct cRGB *rgb) |
|
|
|
{ |
|
|
|
uint8_t hi = hue / 60; |
|
|
|
uint16_t f = (hue % 60) * 425 / 100; |
|
|
|
uint8_t q = 255 - f; |
|
|
|
switch (hi) { |
|
|
|
case 0: rgb->r = 255; rgb->g = f; rgb->b = 0; break; |
|
|
|
case 1: rgb->r = q; rgb->g = 255; rgb->b = 0; break; |
|
|
|
case 2: rgb->r = 0; rgb->g = 255; rgb->b = f; break; |
|
|
|
case 3: rgb->r = 0; rgb->g = q; rgb->b = 255; break; |
|
|
|
case 4: rgb->r = f; rgb->g = 0; rgb->b = 255; break; |
|
|
|
case 5: rgb->r = 255; rgb->g = 0; rgb->b = q; break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
|
* original code: https://blog.adafruit.com/2012/03/14/constant-brightness-hsb-to-rgb-algorithm/ |
|
|
|
*/ |
|
|
|
void hsb_to_rgb(uint16_t hue, uint8_t saturation, uint8_t brightness, struct cRGB *rgb) |
|
|
|
{ |
|
|
|
uint8_t temp[5]; |
|
|
|
uint8_t n = (hue >> 8) % 3; |
|
|
|
uint8_t x = ((((hue & 255) * saturation) >> 8) * brightness) >> 8; |
|
|
|
uint8_t s = ((256 - saturation) * brightness) >> 8; |
|
|
|
temp[0] = temp[3] = s; |
|
|
|
temp[1] = temp[4] = x + s; |
|
|
|
temp[2] = brightness - x; |
|
|
|
rgb->r = temp[n + 2]; |
|
|
|
rgb->g = temp[n + 1]; |
|
|
|
rgb->b = temp[n]; |
|
|
|
} |
|
|
|
|
|
|
|
#ifdef CUSTOM_LED_ENABLE |
|
|
|
void softpwm_led_custom(void) |
|
|
|
{ |
|
|
|
static uint8_t step = 0; |
|
|
|
static uint16_t hue = 0; |
|
|
|
if (rgb_fading_enable) { |
|
|
|
if (++step > rgb_fading_enable) { |
|
|
|
step = 0; |
|
|
|
rgb_hue = hue; |
|
|
|
rgb_refresh(); |
|
|
|
if (++hue >= 768) { |
|
|
|
hue = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
#endif |