backlight.c \ | backlight.c \ | ||||
ledmap.c \ | ledmap.c \ | ||||
twimaster.c \ | twimaster.c \ | ||||
kimera.c | |||||
kimera.c \ | |||||
light_ws2812.c \ | |||||
rgb.c | |||||
ifdef KEYMAP | ifdef KEYMAP | ||||
SRC := keymap_$(KEYMAP).c $(SRC) | SRC := keymap_$(KEYMAP).c $(SRC) |
#endif | #endif | ||||
#include "action.h" | #include "action.h" | ||||
#include "kimera.h" | #include "kimera.h" | ||||
#include "rgb.h" | |||||
#ifdef BACKLIGHT_ENABLE | #ifdef BACKLIGHT_ENABLE | ||||
0, 16, 128, 255 | 0, 16, 128, 255 | ||||
}; | }; | ||||
#ifdef SOFTPWM_LED_ENABLE | |||||
#ifdef FADING_LED_ENABLE | |||||
static uint8_t backlight_mode; | |||||
#endif | |||||
#endif | |||||
extern backlight_config_t backlight_config; | |||||
uint8_t backlight_brightness; | |||||
/* Backlight pin configuration | /* Backlight pin configuration | ||||
* LED4: PB6 (D10) OC1B | * LED4: PB6 (D10) OC1B | ||||
void backlight_set(uint8_t level) | void backlight_set(uint8_t level) | ||||
{ | { | ||||
#ifdef FADING_LED_ENABLE | |||||
backlight_mode = level; | |||||
#ifdef SOFTPWM_LED_ENABLE | |||||
softpwm_led_enable(); | |||||
#endif | #endif | ||||
#ifdef BREATHING_LED_ENABLE | #ifdef BREATHING_LED_ENABLE | ||||
switch (level) { | switch (level) { | ||||
case 1: | case 1: | ||||
case 2: | case 2: | ||||
case 3: | case 3: | ||||
#ifdef SOFTPWM_LED_ENABLE | #ifdef SOFTPWM_LED_ENABLE | ||||
softpwm_led_enable(); | |||||
#ifdef FADING_LED_ENABLE | #ifdef FADING_LED_ENABLE | ||||
fading_led_disable_all(); | fading_led_disable_all(); | ||||
#endif | #endif | ||||
backlight_enable(); | backlight_enable(); | ||||
breathing_led_disable(); | breathing_led_disable(); | ||||
#endif | #endif | ||||
backlight_set_raw(pgm_read_byte(&backlight_table[level])); | |||||
backlight_brightness = pgm_read_byte(&backlight_table[level]); | |||||
#ifdef RGB_LED_ENABLE | |||||
rgb_set_brightness(backlight_brightness); | |||||
#endif | |||||
backlight_set_raw(backlight_brightness); | |||||
break; | break; | ||||
case 4: | case 4: | ||||
case 5: | case 5: | ||||
case 6: | case 6: | ||||
#ifdef SOFTPWM_LED_ENABLE | #ifdef SOFTPWM_LED_ENABLE | ||||
softpwm_led_enable(); | |||||
#ifdef FADING_LED_ENABLE | #ifdef FADING_LED_ENABLE | ||||
fading_led_disable_all(); | fading_led_disable_all(); | ||||
#endif | #endif | ||||
#ifdef SOFTPWM_LED_ENABLE | #ifdef SOFTPWM_LED_ENABLE | ||||
#ifdef FADING_LED_ENABLE | #ifdef FADING_LED_ENABLE | ||||
case 7: | case 7: | ||||
softpwm_led_enable(); | |||||
fading_led_enable_all(); | fading_led_enable_all(); | ||||
breathing_led_disable_all(); | breathing_led_disable_all(); | ||||
fading_led_set_direction_all(FADING_LED_FADE_IN); | fading_led_set_direction_all(FADING_LED_FADE_IN); | ||||
fading_led_set_duration(3); | fading_led_set_duration(3); | ||||
break; | break; | ||||
case 8: | case 8: | ||||
softpwm_led_enable(); | |||||
fading_led_enable_all(); | fading_led_enable_all(); | ||||
breathing_led_disable_all(); | breathing_led_disable_all(); | ||||
fading_led_set_direction_all(FADING_LED_FADE_OUT); | fading_led_set_direction_all(FADING_LED_FADE_OUT); | ||||
fading_led_disable_all(); | fading_led_disable_all(); | ||||
#endif | #endif | ||||
breathing_led_disable_all(); | breathing_led_disable_all(); | ||||
softpwm_led_disable(); | |||||
backlight_brightness = 0; | |||||
backlight_set_raw(backlight_brightness); | |||||
#else | #else | ||||
breathing_led_disable(); | breathing_led_disable(); | ||||
backlight_disable(); | backlight_disable(); | ||||
#ifdef FADING_LED_ENABLE | #ifdef FADING_LED_ENABLE | ||||
void action_keyevent(keyevent_t event) | void action_keyevent(keyevent_t event) | ||||
{ | { | ||||
if (backlight_mode == 7) { | |||||
if (event.pressed) { | |||||
softpwm_led_decrease_all(32); | |||||
if (backlight_config.enable) { | |||||
if (backlight_config.level == 7) { | |||||
if (event.pressed) { | |||||
fading_led_set_delay_all(64); | |||||
softpwm_led_decrease_all(32); | |||||
} | |||||
} | } | ||||
} | |||||
if (backlight_mode == 8) { | |||||
if (event.pressed) { | |||||
softpwm_led_increase_all(32); | |||||
if (backlight_config.level == 8) { | |||||
if (event.pressed) { | |||||
fading_led_set_delay_all(64); | |||||
softpwm_led_increase_all(32); | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } | ||||
#endif | #endif | ||||
#ifdef RGB_LED_ENABLE | |||||
#ifdef CUSTOM_LED_ENABLE | |||||
void softpwm_led_custom(void) | |||||
{ | |||||
rgb_fading(); | |||||
} | |||||
void fading_led_custom(uint8_t *value) | |||||
{ | |||||
rgb_set_brightness(value[0]); | |||||
} | |||||
void breathing_led_custom(uint8_t *value) | |||||
{ | |||||
rgb_set_brightness(value[0]); | |||||
} | |||||
#endif | |||||
#endif | |||||
#endif | #endif | ||||
#endif | #endif |
#define FN_ACTIONS_COUNT 32 | #define FN_ACTIONS_COUNT 32 | ||||
#define KEYMAPS_COUNT 3 | #define KEYMAPS_COUNT 3 | ||||
#ifndef TWO_HEADED_KIMERA | #ifndef TWO_HEADED_KIMERA | ||||
#define EECONFIG_KEYMAP_IN_EEPROM 49 | |||||
#define EECONFIG_KEYMAP_IN_EEPROM 50 | |||||
#else | #else | ||||
#define EECONFIG_KEYMAP_IN_EEPROM 81 | |||||
#define EECONFIG_KEYMAP_IN_EEPROM 82 | |||||
#endif | #endif | ||||
/* define if matrix has ghost */ | /* define if matrix has ghost */ | ||||
/* enable customized backlight logic */ | /* enable customized backlight logic */ | ||||
#define BACKLIGHT_CUSTOM | #define BACKLIGHT_CUSTOM | ||||
#define CUSTOM_LED_ENABLE | |||||
#define RGB_LED_ENABLE | |||||
/* number of leds */ | /* number of leds */ | ||||
#define LED_COUNT 4 | #define LED_COUNT 4 |
#include "keymap_common.h" | #include "keymap_common.h" | ||||
#include "rgb.h" | |||||
// Default | // Default | ||||
#ifdef KEYMAP_SECTION_ENABLE | #ifdef KEYMAP_SECTION_ENABLE | ||||
return sizeof(fn_actions) / sizeof(fn_actions[0]); | return sizeof(fn_actions) / sizeof(fn_actions[0]); | ||||
} | } | ||||
#endif | #endif | ||||
#ifndef NO_ACTION_FUNCTION | |||||
enum function_id { | |||||
AF_RGB_TOGGLE = 0, | |||||
AF_RGB_DECREASE, | |||||
AF_RGB_INCREASE, | |||||
AF_RGB_STEP | |||||
}; | |||||
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) | |||||
{ | |||||
if (record->event.pressed) { | |||||
switch (id) { | |||||
case AF_RGB_TOGGLE: | |||||
rgb_toggle(); | |||||
break; | |||||
case AF_RGB_DECREASE: | |||||
rgb_decrease(); | |||||
break; | |||||
case AF_RGB_INCREASE: | |||||
rgb_increase(); | |||||
break; | |||||
case AF_RGB_STEP: | |||||
rgb_step(); | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
#endif |
/* Matrix Mapping in EEPROM */ | /* Matrix Mapping in EEPROM */ | ||||
#define EECONFIG_ROW_COUNT (uint8_t *)15 | |||||
#define EECONFIG_COL_COUNT (uint8_t *)16 | |||||
#define EECONFIG_ROW_COL_MAPPING (uint8_t *)17 | |||||
#define EECONFIG_ROW_COUNT (uint8_t *)16 | |||||
#define EECONFIG_COL_COUNT (uint8_t *)17 | |||||
#define EECONFIG_ROW_COL_MAPPING (uint8_t *)18 | |||||
#define UNCONFIGURED 0xFF | #define UNCONFIGURED 0xFF | ||||
/* Functions */ | /* Functions */ |
LED2_PORT &= ~(1<<LED2_BIT); | LED2_PORT &= ~(1<<LED2_BIT); | ||||
break; | break; | ||||
case 2: | case 2: | ||||
#if 0 | |||||
LED3_PORT &= ~(1<<LED3_BIT); | LED3_PORT &= ~(1<<LED3_BIT); | ||||
#endif | |||||
break; | break; | ||||
case 3: | case 3: | ||||
LED4_PORT |= (1<<LED4_BIT); | LED4_PORT |= (1<<LED4_BIT); | ||||
LED2_PORT |= (1<<LED2_BIT); | LED2_PORT |= (1<<LED2_BIT); | ||||
break; | break; | ||||
case 2: | case 2: | ||||
#if 0 | |||||
LED3_PORT |= (1<<LED3_BIT); | LED3_PORT |= (1<<LED3_BIT); | ||||
#endif | |||||
break; | break; | ||||
case 3: | case 3: | ||||
LED4_PORT &= ~(1<<LED4_BIT); | LED4_PORT &= ~(1<<LED4_BIT); |
/* | |||||
* light weight WS2812 lib V2.0b | |||||
* | |||||
* Controls WS2811/WS2812/WS2812B RGB-LEDs | |||||
* Author: Tim ([email protected]) | |||||
* | |||||
* Jan 18th, 2014 v2.0b Initial Version | |||||
* | |||||
* License: GNU GPL v2 (see License.txt) | |||||
*/ | |||||
#include "light_ws2812.h" | |||||
#include <avr/interrupt.h> | |||||
#include <avr/io.h> | |||||
#include <util/delay.h> | |||||
void inline ws2812_setleds(struct cRGB *ledarray, uint16_t leds) | |||||
{ | |||||
ws2812_setleds_pin(ledarray,leds, _BV(ws2812_pin)); | |||||
} | |||||
void inline ws2812_setleds_pin(struct cRGB *ledarray, uint16_t leds, uint8_t pinmask) | |||||
{ | |||||
ws2812_DDRREG |= pinmask; // Enable DDR | |||||
ws2812_sendarray_mask((uint8_t*)ledarray,leds+leds+leds,pinmask); | |||||
_delay_us(50); | |||||
} | |||||
void ws2812_sendarray(uint8_t *data,uint16_t datlen) | |||||
{ | |||||
ws2812_sendarray_mask(data,datlen,_BV(ws2812_pin)); | |||||
} | |||||
/* | |||||
This routine writes an array of bytes with RGB values to the Dataout pin | |||||
using the fast 800kHz clockless WS2811/2812 protocol. | |||||
*/ | |||||
// Timing in ns | |||||
#define w_zeropulse 350 | |||||
#define w_onepulse 900 | |||||
#define w_totalperiod 1250 | |||||
// Fixed cycles used by the inner loop | |||||
#define w_fixedlow 2 | |||||
#define w_fixedhigh 4 | |||||
#define w_fixedtotal 8 | |||||
// Insert NOPs to match the timing, if possible | |||||
#define w_zerocycles (((F_CPU/1000)*w_zeropulse )/1000000) | |||||
#define w_onecycles (((F_CPU/1000)*w_onepulse +500000)/1000000) | |||||
#define w_totalcycles (((F_CPU/1000)*w_totalperiod +500000)/1000000) | |||||
// w1 - nops between rising edge and falling edge - low | |||||
#define w1 (w_zerocycles-w_fixedlow) | |||||
// w2 nops between fe low and fe high | |||||
#define w2 (w_onecycles-w_fixedhigh-w1) | |||||
// w3 nops to complete loop | |||||
#define w3 (w_totalcycles-w_fixedtotal-w1-w2) | |||||
#if w1>0 | |||||
#define w1_nops w1 | |||||
#else | |||||
#define w1_nops 0 | |||||
#endif | |||||
// The only critical timing parameter is the minimum pulse length of the "0" | |||||
// Warn or throw error if this timing can not be met with current F_CPU settings. | |||||
#define w_lowtime ((w1_nops+w_fixedlow)*1000000)/(F_CPU/1000) | |||||
#if w_lowtime>550 | |||||
#error "Light_ws2812: Sorry, the clock speed is too low. Did you set F_CPU correctly?" | |||||
#elif w_lowtime>450 | |||||
#warning "Light_ws2812: The timing is critical and may only work on WS2812B, not on WS2812(S)." | |||||
#warning "Please consider a higher clockspeed, if possible" | |||||
#endif | |||||
#if w2>0 | |||||
#define w2_nops w2 | |||||
#else | |||||
#define w2_nops 0 | |||||
#endif | |||||
#if w3>0 | |||||
#define w3_nops w3 | |||||
#else | |||||
#define w3_nops 0 | |||||
#endif | |||||
#define w_nop1 "nop \n\t" | |||||
#define w_nop2 "rjmp .+0 \n\t" | |||||
#define w_nop4 w_nop2 w_nop2 | |||||
#define w_nop8 w_nop4 w_nop4 | |||||
#define w_nop16 w_nop8 w_nop8 | |||||
void inline ws2812_sendarray_mask(uint8_t *data,uint16_t datlen,uint8_t maskhi) | |||||
{ | |||||
uint8_t curbyte,ctr,masklo; | |||||
uint8_t sreg_prev; | |||||
masklo =~maskhi&ws2812_PORTREG; | |||||
maskhi |= ws2812_PORTREG; | |||||
sreg_prev=SREG; | |||||
cli(); | |||||
while (datlen--) { | |||||
curbyte=*data++; | |||||
asm volatile( | |||||
" ldi %0,8 \n\t" | |||||
"loop%=: \n\t" | |||||
" out %2,%3 \n\t" // '1' [01] '0' [01] - re | |||||
#if (w1_nops&1) | |||||
w_nop1 | |||||
#endif | |||||
#if (w1_nops&2) | |||||
w_nop2 | |||||
#endif | |||||
#if (w1_nops&4) | |||||
w_nop4 | |||||
#endif | |||||
#if (w1_nops&8) | |||||
w_nop8 | |||||
#endif | |||||
#if (w1_nops&16) | |||||
w_nop16 | |||||
#endif | |||||
" sbrs %1,7 \n\t" // '1' [03] '0' [02] | |||||
" out %2,%4 \n\t" // '1' [--] '0' [03] - fe-low | |||||
" lsl %1 \n\t" // '1' [04] '0' [04] | |||||
#if (w2_nops&1) | |||||
w_nop1 | |||||
#endif | |||||
#if (w2_nops&2) | |||||
w_nop2 | |||||
#endif | |||||
#if (w2_nops&4) | |||||
w_nop4 | |||||
#endif | |||||
#if (w2_nops&8) | |||||
w_nop8 | |||||
#endif | |||||
#if (w2_nops&16) | |||||
w_nop16 | |||||
#endif | |||||
" out %2,%4 \n\t" // '1' [+1] '0' [+1] - fe-high | |||||
#if (w3_nops&1) | |||||
w_nop1 | |||||
#endif | |||||
#if (w3_nops&2) | |||||
w_nop2 | |||||
#endif | |||||
#if (w3_nops&4) | |||||
w_nop4 | |||||
#endif | |||||
#if (w3_nops&8) | |||||
w_nop8 | |||||
#endif | |||||
#if (w3_nops&16) | |||||
w_nop16 | |||||
#endif | |||||
" dec %0 \n\t" // '1' [+2] '0' [+2] | |||||
" brne loop%=\n\t" // '1' [+3] '0' [+4] | |||||
: "=&d" (ctr) | |||||
: "r" (curbyte), "I" (_SFR_IO_ADDR(ws2812_PORTREG)), "r" (maskhi), "r" (masklo) | |||||
); | |||||
} | |||||
SREG=sreg_prev; | |||||
} |
/* | |||||
* light weight WS2812 lib include | |||||
* | |||||
* Version 2.0a3 - Jan 18th 2014 | |||||
* Author: Tim ([email protected]) | |||||
* | |||||
* Please do not change this file! All configuration is handled in "ws2812_config.h" | |||||
* | |||||
* License: GNU GPL v2 (see License.txt) | |||||
+ | |||||
*/ | |||||
#ifndef LIGHT_WS2812_H_ | |||||
#define LIGHT_WS2812_H_ | |||||
#include <avr/io.h> | |||||
#include <avr/interrupt.h> | |||||
#include "ws2812_config.h" | |||||
/* | |||||
* Structure of the LED array | |||||
*/ | |||||
struct cRGB { uint8_t g; uint8_t r; uint8_t b; }; | |||||
/* User Interface | |||||
* | |||||
* Input: | |||||
* ledarray: An array of GRB data describing the LED colors | |||||
* number_of_leds: The number of LEDs to write | |||||
* pinmask (optional): Bitmask describing the output bin. e.g. _BV(PB0) | |||||
* | |||||
* The functions will perform the following actions: | |||||
* - Set the data-out pin as output | |||||
* - Send out the LED data | |||||
* - Wait 50µs to reset the LEDs | |||||
*/ | |||||
void ws2812_setleds (struct cRGB *ledarray, uint16_t number_of_leds); | |||||
void ws2812_setleds_pin(struct cRGB *ledarray, uint16_t number_of_leds,uint8_t pinmask); | |||||
/* | |||||
* Old interface / Internal functions | |||||
* | |||||
* The functions take a byte-array and send to the data output as WS2812 bitstream. | |||||
* The length is the number of bytes to send - three per LED. | |||||
*/ | |||||
void ws2812_sendarray (uint8_t *array,uint16_t length); | |||||
void ws2812_sendarray_mask(uint8_t *array,uint16_t length, uint8_t pinmask); | |||||
/* | |||||
* Internal defines | |||||
*/ | |||||
#define CONCAT(a, b) a ## b | |||||
#define CONCAT_EXP(a, b) CONCAT(a, b) | |||||
#define ws2812_PORTREG CONCAT_EXP(PORT,ws2812_port) | |||||
#define ws2812_DDRREG CONCAT_EXP(DDR,ws2812_port) | |||||
#endif /* LIGHT_WS2812_H_ */ |
/* | |||||
Copyright 2016 Kai Ryu <[email protected]> | |||||
This program is free software: you can redistribute it and/or modify | |||||
it under the terms of the GNU General Public License as published by | |||||
the Free Software Foundation, either version 2 of the License, or | |||||
(at your option) any later version. | |||||
This program is distributed in the hope that it will be useful, | |||||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
GNU General Public License for more details. | |||||
You should have received a copy of the GNU General Public License | |||||
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" | |||||
#include "debug.h" | |||||
#ifdef RGB_LED_ENABLE | |||||
volatile static uint8_t rgb_fading_enable = 0; | |||||
static rgb_config_t rgb_config; | |||||
static struct cRGB rgb_color[RGB_LED_COUNT]; | |||||
static uint16_t rgb_hue = 0; | |||||
static uint8_t rgb_saturation = 255; | |||||
static uint8_t rgb_brightness = 16; | |||||
static uint8_t rgb_rainbow = 0; | |||||
extern backlight_config_t backlight_config; | |||||
extern uint8_t backlight_brightness; | |||||
static void rgb_write_config(void); | |||||
static void rgb_read_config(void); | |||||
static void rgb_set_level(uint8_t level); | |||||
static void rgb_refresh(void); | |||||
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) | |||||
{ | |||||
rgb_read_config(); | |||||
if (rgb_config.raw == RGB_UNCONFIGURED) { | |||||
rgb_config.enable = 0; | |||||
rgb_config.level = RGB_OFF; | |||||
rgb_write_config(); | |||||
} | |||||
if (rgb_config.enable) { | |||||
rgb_set_level(rgb_config.level); | |||||
} | |||||
} | |||||
void rgb_read_config(void) | |||||
{ | |||||
rgb_config.raw = eeprom_read_byte(EECONFIG_RGB); | |||||
} | |||||
void rgb_write_config(void) | |||||
{ | |||||
eeprom_write_byte(EECONFIG_RGB, rgb_config.raw); | |||||
} | |||||
void rgb_toggle(void) | |||||
{ | |||||
if (rgb_config.enable) { | |||||
rgb_off(); | |||||
} | |||||
else { | |||||
rgb_on(); | |||||
} | |||||
} | |||||
void rgb_on(void) | |||||
{ | |||||
rgb_config.enable = 1; | |||||
rgb_set_level(rgb_config.level); | |||||
rgb_write_config(); | |||||
} | |||||
void rgb_off(void) | |||||
{ | |||||
rgb_config.enable = 0; | |||||
rgb_set_level(RGB_OFF); | |||||
rgb_write_config(); | |||||
} | |||||
void rgb_decrease(void) | |||||
{ | |||||
if(rgb_config.level > 0) { | |||||
rgb_config.level--; | |||||
rgb_config.enable = (rgb_config.level != 0); | |||||
rgb_write_config(); | |||||
} | |||||
rgb_set_level(rgb_config.level); | |||||
} | |||||
void rgb_increase(void) | |||||
{ | |||||
if(rgb_config.level < RGB_LEVELS) { | |||||
rgb_config.level++; | |||||
rgb_config.enable = 1; | |||||
rgb_write_config(); | |||||
} | |||||
rgb_set_level(rgb_config.level); | |||||
} | |||||
void rgb_step(void) | |||||
{ | |||||
rgb_config.level++; | |||||
if(rgb_config.level > RGB_LEVELS) | |||||
{ | |||||
rgb_config.level = 0; | |||||
} | |||||
rgb_config.enable = (rgb_config.level != 0); | |||||
rgb_set_level(rgb_config.level); | |||||
} | |||||
void rgb_set_level(uint8_t level) | |||||
{ | |||||
dprintf("RGB Level: %d\n", level); | |||||
if (level <= RGB_WHITE) { | |||||
rgb_fading_enable = 0; | |||||
rgb_rainbow = 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 = 1; | |||||
rgb_rainbow = (level >= RGB_RAINBOW) ? 1 : 0; | |||||
} | |||||
} | |||||
void rgb_set_brightness(uint8_t brightness) | |||||
{ | |||||
if (rgb_config.enable) { | |||||
rgb_brightness = brightness; | |||||
rgb_refresh(); | |||||
} | |||||
} | |||||
void rgb_refresh(void) | |||||
{ | |||||
struct cRGB rgb; | |||||
uint16_t hue; | |||||
uint8_t i; | |||||
if (rgb_rainbow) { | |||||
for (i = 0; i < RGB_LED_COUNT; i++) { | |||||
hue = rgb_hue + (768 / RGB_LED_COUNT) * i; | |||||
hsb_to_rgb(hue, rgb_saturation, rgb_brightness, &rgb); | |||||
rgb_color[i] = rgb; | |||||
} | |||||
} | |||||
else { | |||||
hsb_to_rgb(rgb_hue, rgb_saturation, rgb_brightness, &rgb); | |||||
for (i = 0; i < RGB_LED_COUNT; i++) { | |||||
rgb_color[i] = rgb; | |||||
} | |||||
} | |||||
/* xprintf("R%d G%d B%d\n", rgb_color[0].r, rgb_color[0].g, rgb_color[0].b); */ | |||||
ws2812_setleds(rgb_color, RGB_LED_COUNT); | |||||
} | |||||
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]; | |||||
} | |||||
void rgb_fading(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 |
/* | |||||
Copyright 2016 Kai Ryu <[email protected]> | |||||
This program is free software: you can redistribute it and/or modify | |||||
it under the terms of the GNU General Public License as published by | |||||
the Free Software Foundation, either version 2 of the License, or | |||||
(at your option) any later version. | |||||
This program is distributed in the hope that it will be useful, | |||||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
GNU General Public License for more details. | |||||
You should have received a copy of the GNU General Public License | |||||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#ifndef RGB_H | |||||
#define RGB_H | |||||
#include <stdint.h> | |||||
#include <stdbool.h> | |||||
typedef union { | |||||
uint8_t raw; | |||||
struct { | |||||
uint8_t level :7; | |||||
bool enable :1; | |||||
}; | |||||
} rgb_config_t; | |||||
enum { | |||||
RGB_OFF = 0, | |||||
RGB_RED, | |||||
RGB_YELLOW, | |||||
RGB_GREEN, | |||||
RGB_CYAN, | |||||
RGB_BLUE, | |||||
RGB_MAGENTA, | |||||
RGB_WHITE, | |||||
RGB_FADE, | |||||
RGB_RAINBOW, | |||||
RGB_LEVELS = RGB_RAINBOW | |||||
}; | |||||
#define EECONFIG_RGB (uint8_t *)15 | |||||
#define RGB_UNCONFIGURED 0xFF | |||||
#define RGB_LED_COUNT 16 | |||||
void rgb_init(void); | |||||
void rgb_toggle(void); | |||||
void rgb_on(void); | |||||
void rgb_off(void); | |||||
void rgb_decrease(void); | |||||
void rgb_increase(void); | |||||
void rgb_step(void); | |||||
void rgb_set_brightness(uint8_t brightness); | |||||
void rgb_fading(void); | |||||
#endif |
/* | |||||
* light_ws2812_config.h | |||||
* | |||||
* Created: 18.01.2014 09:58:15 | |||||
* | |||||
* User Configuration file for the light_ws2812_lib | |||||
* | |||||
*/ | |||||
#ifndef WS2812_CONFIG_H_ | |||||
#define WS2812_CONFIG_H_ | |||||
/////////////////////////////////////////////////////////////////////// | |||||
// Define I/O pin | |||||
/////////////////////////////////////////////////////////////////////// | |||||
#define ws2812_port C // Data port | |||||
#define ws2812_pin 6 // Data out pin | |||||
#endif /* WS2812_CONFIG_H_ */ |