@ -14,6 +14,7 @@
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include <math.h>
# include <string.h>
# ifdef __AVR__
# include <avr/eeprom.h>
# include <avr/interrupt.h>
@ -29,23 +30,27 @@
# define RGBLIGHT_LIMIT_VAL 255
# endif
# define _RGBM_SINGLE_STATIC(sym) RGBLIGHT_MODE_ ## sym,
# define _RGBM_SINGLE_DYNAMIC(sym)
# define _RGBM_MULTI_STATIC(sym) RGBLIGHT_MODE_ ## sym,
# define _RGBM_MULTI_DYNAMIC(sym)
# define _RGBM_TMP_STATIC(sym) RGBLIGHT_MODE_ ## sym,
# define _RGBM_TMP_DYNAMIC(sym)
static uint8_t static_effect_table [ ] = {
# include "rgblight.h"
} ;
static inline int is_static_effect ( uint8_t mode ) {
return memchr ( static_effect_table , mode , sizeof ( static_effect_table ) ) ! = NULL ;
}
# define MIN(a,b) (((a)<(b))?(a):(b))
# define MAX(a,b) (((a)>(b))?(a):(b))
__attribute__ ( ( weak ) )
const uint8_t RGBLED_BREATHING_INTERVALS [ ] PROGMEM = { 30 , 20 , 10 , 5 } ;
__attribute__ ( ( weak ) )
const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS [ ] PROGMEM = { 120 , 60 , 30 } ;
__attribute__ ( ( weak ) )
const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS [ ] PROGMEM = { 100 , 50 , 20 } ;
__attribute__ ( ( weak ) )
const uint8_t RGBLED_SNAKE_INTERVALS [ ] PROGMEM = { 100 , 50 , 20 } ;
__attribute__ ( ( weak ) )
const uint8_t RGBLED_KNIGHT_INTERVALS [ ] PROGMEM = { 127 , 63 , 31 } ;
# ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
__attribute__ ( ( weak ) )
const uint16_t RGBLED_GRADIENT_RANGES [ ] PROGMEM = { 360 , 240 , 180 , 120 , 90 } ;
__attribute__ ( ( weak ) )
const uint16_t RGBLED_RGBTEST_INTERVALS [ ] PROGMEM = { 1024 } ;
# endif
rgblight_config_t rgblight_config ;
@ -129,7 +134,7 @@ void eeconfig_update_rgblight(uint32_t val) {
void eeconfig_update_rgblight_default ( void ) {
//dprintf("eeconfig_update_rgblight_default\n");
rgblight_config . enable = 1 ;
rgblight_config . mode = 1 ;
rgblight_config . mode = RGBLIGHT_MODE_STATIC_LIGHT ;
rgblight_config . hue = 0 ;
rgblight_config . sat = 255 ;
rgblight_config . val = RGBLIGHT_LIMIT_VAL ;
@ -163,9 +168,9 @@ void rgblight_init(void) {
}
eeconfig_debug_rgblight ( ) ; // display current eeprom values
# ifdef RGBLIGHT_ANIMATIONS
# ifdef RGBLIGHT_USE_TIMER
rgblight_timer_init ( ) ; // setup the timer
# endif
# endif
if ( rgblight_config . enable ) {
rgblight_mode_noeeprom ( rgblight_config . mode ) ;
@ -178,9 +183,9 @@ void rgblight_update_dword(uint32_t dword) {
if ( rgblight_config . enable )
rgblight_mode ( rgblight_config . mode ) ;
else {
# ifdef RGBLIGHT_ANIMATIONS
# ifdef RGBLIGHT_USE_TIMER
rgblight_timer_disable ( ) ;
# endif
# endif
rgblight_set ( ) ;
}
}
@ -195,7 +200,7 @@ void rgblight_increase(void) {
void rgblight_decrease ( void ) {
uint8_t mode = 0 ;
// Mode will never be < 1. If it ever is, eeprom needs to be initialized.
if ( rgblight_config . mode > 1 ) {
if ( rgblight_config . mode > RGBLIGHT_MODE_STATIC_LIGHT ) {
mode = rgblight_config . mode - 1 ;
}
rgblight_mode ( mode ) ;
@ -229,8 +234,8 @@ void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {
if ( ! rgblight_config . enable ) {
return ;
}
if ( mode < 1 ) {
rgblight_config . mode = 1 ;
if ( mode < RGBLIGHT_MODE_STATIC_LIGHT ) {
rgblight_config . mode = RGBLIGHT_MODE_STATIC_LIGHT ;
} else if ( mode > RGBLIGHT_MODES ) {
rgblight_config . mode = RGBLIGHT_MODES ;
} else {
@ -242,30 +247,14 @@ void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {
} else {
xprintf ( " rgblight mode [NOEEPROM]: %u \n " , rgblight_config . mode ) ;
}
if ( rgblight_config . mode = = 1 ) {
# ifdef RGBLIGHT_ANIMATIONS
if ( is_static_effect ( rgblight_config . mode ) ) {
# ifdef RGBLIGHT_USE_TIMER
rgblight_timer_disable ( ) ;
# endif
} else if ( ( rgblight_config . mode > = 2 & & rgblight_config . mode < = 24 ) | |
rgblight_config . mode = = 35 | | rgblight_config . mode = = 36 ) {
// MODE 2-5, breathing
// MODE 6-8, rainbow mood
// MODE 9-14, rainbow swirl
// MODE 15-20, snake
// MODE 21-23, knight
// MODE 24, xmas
// MODE 35 RGB test
// MODE 36, alterating
# ifdef RGBLIGHT_ANIMATIONS
# endif
} else {
# ifdef RGBLIGHT_USE_TIMER
rgblight_timer_enable ( ) ;
# endif
} else if ( rgblight_config . mode > = 25 & & rgblight_config . mode < = 34 ) {
// MODE 25-34, static gradient
# ifdef RGBLIGHT_ANIMATIONS
rgblight_timer_disable ( ) ;
# endif
# endif
}
rgblight_sethsv_noeeprom ( rgblight_config . hue , rgblight_config . sat , rgblight_config . val ) ;
}
@ -317,9 +306,9 @@ void rgblight_disable(void) {
rgblight_config . enable = 0 ;
eeconfig_update_rgblight ( rgblight_config . raw ) ;
xprintf ( " rgblight disable [EEPROM]: rgblight_config.enable = %u \n " , rgblight_config . enable ) ;
# ifdef RGBLIGHT_ANIMATIONS
rgblight_timer_disable ( ) ;
# endif
# ifdef RGBLIGHT_USE_TIMER
rgblight_timer_disable ( ) ;
# endif
wait_ms ( 50 ) ;
rgblight_set ( ) ;
}
@ -327,9 +316,9 @@ void rgblight_disable(void) {
void rgblight_disable_noeeprom ( void ) {
rgblight_config . enable = 0 ;
xprintf ( " rgblight disable [noEEPROM]: rgblight_config.enable = %u \n " , rgblight_config . enable ) ;
# ifdef RGBLIGHT_ANIMATIONS
# ifdef RGBLIGHT_USE_TIMER
rgblight_timer_disable ( ) ;
# endif
# endif
_delay_ms ( 50 ) ;
rgblight_set ( ) ;
}
@ -419,24 +408,43 @@ void rgblight_sethsv_noeeprom_old(uint16_t hue, uint8_t sat, uint8_t val) {
void rgblight_sethsv_eeprom_helper ( uint16_t hue , uint8_t sat , uint8_t val , bool write_to_eeprom ) {
if ( rgblight_config . enable ) {
if ( rgblight_config . mode = = 1 ) {
if ( rgblight_config . mode = = RGBLIGHT_MODE_STATIC_LIGHT ) {
// same static color
LED_TYPE tmp_led ;
sethsv ( hue , sat , val , & tmp_led ) ;
rgblight_setrgb ( tmp_led . r , tmp_led . g , tmp_led . b ) ;
} else {
// all LEDs in same color
if ( rgblight_config . mode > = 2 & & rgblight_config . mode < = 5 ) {
if ( 1 = = 0 ) { //dummy
}
# ifdef RGBLIGHT_EFFECT_BREATHING
else if ( rgblight_config . mode > = RGBLIGHT_MODE_BREATHING & &
rgblight_config . mode < = RGBLIGHT_MODE_BREATHING_end ) {
// breathing mode, ignore the change of val, use in memory value instead
val = rgblight_config . val ;
} else if ( rgblight_config . mode > = 6 & & rgblight_config . mode < = 14 ) {
// rainbow mood and rainbow swirl, ignore the change of hue
}
# endif
# ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
else if ( rgblight_config . mode > = RGBLIGHT_MODE_RAINBOW_MOOD & &
rgblight_config . mode < = RGBLIGHT_MODE_RAINBOW_MOOD_end ) {
// rainbow mood, ignore the change of hue
hue = rgblight_config . hue ;
}
# endif
# ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
else if ( rgblight_config . mode > = RGBLIGHT_MODE_RAINBOW_SWIRL & &
rgblight_config . mode < = RGBLIGHT_MODE_RAINBOW_SWIRL_end ) {
// rainbow swirl, ignore the change of hue
hue = rgblight_config . hue ;
} else if ( rgblight_config . mode > = 25 & & rgblight_config . mode < = 34 ) {
}
# endif
# ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
else if ( rgblight_config . mode > = RGBLIGHT_MODE_STATIC_GRADIENT & &
rgblight_config . mode < = RGBLIGHT_MODE_STATIC_GRADIENT_end ) {
// static gradient
uint16_t _hue ;
int8_t direction = ( ( rgblight_config . mode - 25 ) % 2 ) ? - 1 : 1 ;
uint16_t range = pgm_read_word ( & RGBLED_GRADIENT_RANGES [ ( rgblight_config . mode - 25 ) / 2 ] ) ;
int8_t direction = ( ( rgblight_config . mode - RGBLIGHT_MODE_STATIC_GRADIENT ) % 2 ) ? - 1 : 1 ;
uint16_t range = pgm_read_word ( & RGBLED_GRADIENT_RANGES [ ( rgblight_config . mode - RGBLIGHT_MODE_STATIC_GRADIENT ) / 2 ] ) ;
for ( uint8_t i = 0 ; i < RGBLED_NUM ; i + + ) {
_hue = ( range / RGBLED_NUM * i * direction + hue + 360 ) % 360 ;
dprintf ( " rgblight rainbow set hsv: %u,%u,%d,%u \n " , i , _hue , direction , range ) ;
@ -444,6 +452,7 @@ void rgblight_sethsv_eeprom_helper(uint16_t hue, uint8_t sat, uint8_t val, bool
}
rgblight_set ( ) ;
}
# endif
}
rgblight_config . hue = hue ;
rgblight_config . sat = sat ;
@ -528,7 +537,7 @@ void rgblight_set(void) {
}
# endif
# ifdef RGBLIGHT_ ANIMATIONS
# ifdef RGBLIGHT_ USE_TIMER
// Animation timer -- AVR Timer3
void rgblight_timer_init ( void ) {
@ -564,41 +573,77 @@ void rgblight_timer_toggle(void) {
void rgblight_show_solid_color ( uint8_t r , uint8_t g , uint8_t b ) {
rgblight_enable ( ) ;
rgblight_mode ( 1 ) ;
rgblight_mode ( RGBLIGHT_MODE_STATIC_LIGHT ) ;
rgblight_setrgb ( r , g , b ) ;
}
void rgblight_task ( void ) {
if ( rgblight_timer_enabled ) {
// mode = 1, static light, do nothing here
if ( rgblight_config . mode > = 2 & & rgblight_config . mode < = 5 ) {
// mode = 2 to 5, breathing mode
rgblight_effect_breathing ( rgblight_config . mode - 2 ) ;
} else if ( rgblight_config . mode > = 6 & & rgblight_config . mode < = 8 ) {
// mode = 6 to 8, rainbow mood mod
rgblight_effect_rainbow_mood ( rgblight_config . mode - 6 ) ;
} else if ( rgblight_config . mode > = 9 & & rgblight_config . mode < = 14 ) {
// mode = 9 to 14, rainbow swirl mode
rgblight_effect_rainbow_swirl ( rgblight_config . mode - 9 ) ;
} else if ( rgblight_config . mode > = 15 & & rgblight_config . mode < = 20 ) {
// mode = 15 to 20, snake mode
rgblight_effect_snake ( rgblight_config . mode - 15 ) ;
} else if ( rgblight_config . mode > = 21 & & rgblight_config . mode < = 23 ) {
// mode = 21 to 23, knight mode
rgblight_effect_knight ( rgblight_config . mode - 21 ) ;
} else if ( rgblight_config . mode = = 24 ) {
// mode = 24, christmas mode
// static light mode, do nothing here
if ( 1 = = 0 ) { //dummy
}
# ifdef RGBLIGHT_EFFECT_BREATHING
else if ( rgblight_config . mode > = RGBLIGHT_MODE_BREATHING & &
rgblight_config . mode < = RGBLIGHT_MODE_BREATHING_end ) {
// breathing mode
rgblight_effect_breathing ( rgblight_config . mode - RGBLIGHT_MODE_BREATHING ) ;
}
# endif
# ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
else if ( rgblight_config . mode > = RGBLIGHT_MODE_RAINBOW_MOOD & &
rgblight_config . mode < = RGBLIGHT_MODE_RAINBOW_MOOD_end ) {
// rainbow mood mode
rgblight_effect_rainbow_mood ( rgblight_config . mode - RGBLIGHT_MODE_RAINBOW_MOOD ) ;
}
# endif
# ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
else if ( rgblight_config . mode > = RGBLIGHT_MODE_RAINBOW_SWIRL & &
rgblight_config . mode < = RGBLIGHT_MODE_RAINBOW_SWIRL_end ) {
// rainbow swirl mode
rgblight_effect_rainbow_swirl ( rgblight_config . mode - RGBLIGHT_MODE_RAINBOW_SWIRL ) ;
}
# endif
# ifdef RGBLIGHT_EFFECT_SNAKE
else if ( rgblight_config . mode > = RGBLIGHT_MODE_SNAKE & &
rgblight_config . mode < = RGBLIGHT_MODE_SNAKE_end ) {
// snake mode
rgblight_effect_snake ( rgblight_config . mode - RGBLIGHT_MODE_SNAKE ) ;
}
# endif
# ifdef RGBLIGHT_EFFECT_KNIGHT
else if ( rgblight_config . mode > = RGBLIGHT_MODE_KNIGHT & &
rgblight_config . mode < = RGBLIGHT_MODE_KNIGHT_end ) {
// knight mode
rgblight_effect_knight ( rgblight_config . mode - RGBLIGHT_MODE_KNIGHT ) ;
}
# endif
# ifdef RGBLIGHT_EFFECT_CHRISTMAS
else if ( rgblight_config . mode = = RGBLIGHT_MODE_CHRISTMAS ) {
// christmas mode
rgblight_effect_christmas ( ) ;
} else if ( rgblight_config . mode = = 35 ) {
// mode = 35, RGB test
}
# endif
# ifdef RGBLIGHT_EFFECT_RGB_TEST
else if ( rgblight_config . mode = = RGBLIGHT_MODE_RGB_TEST ) {
// RGB test mode
rgblight_effect_rgbtest ( ) ;
} else if ( rgblight_config . mode = = 36 ) {
}
# endif
# ifdef RGBLIGHT_EFFECT_ALTERNATING
else if ( rgblight_config . mode = = RGBLIGHT_MODE_ALTERNATING ) {
rgblight_effect_alternating ( ) ;
}
# endif
}
}
# endif /* RGBLIGHT_USE_TIMER */
// Effects
# ifdef RGBLIGHT_EFFECT_BREATHING
__attribute__ ( ( weak ) )
const uint8_t RGBLED_BREATHING_INTERVALS [ ] PROGMEM = { 30 , 20 , 10 , 5 } ;
void rgblight_effect_breathing ( uint8_t interval ) {
static uint8_t pos = 0 ;
static uint16_t last_timer = 0 ;
@ -609,12 +654,17 @@ void rgblight_effect_breathing(uint8_t interval) {
}
last_timer = timer_read ( ) ;
// http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/
val = ( exp ( sin ( ( pos / 255.0 ) * M_PI ) ) - RGBLIGHT_EFFECT_BREATHE_CENTER / M_E ) * ( RGBLIGHT_EFFECT_BREATHE_MAX / ( M_E - 1 / M_E ) ) ;
rgblight_sethsv_noeeprom_old ( rgblight_config . hue , rgblight_config . sat , val ) ;
pos = ( pos + 1 ) % 256 ;
}
# endif
# ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
__attribute__ ( ( weak ) )
const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS [ ] PROGMEM = { 120 , 60 , 30 } ;
void rgblight_effect_rainbow_mood ( uint8_t interval ) {
static uint16_t current_hue = 0 ;
static uint16_t last_timer = 0 ;
@ -626,6 +676,12 @@ void rgblight_effect_rainbow_mood(uint8_t interval) {
rgblight_sethsv_noeeprom_old ( current_hue , rgblight_config . sat , rgblight_config . val ) ;
current_hue = ( current_hue + 1 ) % 360 ;
}
# endif
# ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
__attribute__ ( ( weak ) )
const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS [ ] PROGMEM = { 100 , 50 , 20 } ;
void rgblight_effect_rainbow_swirl ( uint8_t interval ) {
static uint16_t current_hue = 0 ;
static uint16_t last_timer = 0 ;
@ -651,6 +707,12 @@ void rgblight_effect_rainbow_swirl(uint8_t interval) {
}
}
}
# endif
# ifdef RGBLIGHT_EFFECT_SNAKE
__attribute__ ( ( weak ) )
const uint8_t RGBLED_SNAKE_INTERVALS [ ] PROGMEM = { 100 , 50 , 20 } ;
void rgblight_effect_snake ( uint8_t interval ) {
static uint8_t pos = 0 ;
static uint16_t last_timer = 0 ;
@ -689,6 +751,12 @@ void rgblight_effect_snake(uint8_t interval) {
pos = ( pos + 1 ) % RGBLED_NUM ;
}
}
# endif
# ifdef RGBLIGHT_EFFECT_KNIGHT
__attribute__ ( ( weak ) )
const uint8_t RGBLED_KNIGHT_INTERVALS [ ] PROGMEM = { 127 , 63 , 31 } ;
void rgblight_effect_knight ( uint8_t interval ) {
static uint16_t last_timer = 0 ;
if ( timer_elapsed ( last_timer ) < pgm_read_byte ( & RGBLED_KNIGHT_INTERVALS [ interval ] ) ) {
@ -730,8 +798,9 @@ void rgblight_effect_knight(uint8_t interval) {
increment = - increment ;
}
}
# endif
# ifdef RGBLIGHT_EFFECT_CHRISTMAS
void rgblight_effect_christmas ( void ) {
static uint16_t current_offset = 0 ;
static uint16_t last_timer = 0 ;
@ -748,6 +817,11 @@ void rgblight_effect_christmas(void) {
}
rgblight_set ( ) ;
}
# endif
# ifdef RGBLIGHT_EFFECT_RGB_TEST
__attribute__ ( ( weak ) )
const uint16_t RGBLED_RGBTEST_INTERVALS [ ] PROGMEM = { 1024 } ;
void rgblight_effect_rgbtest ( void ) {
static uint8_t pos = 0 ;
@ -774,7 +848,9 @@ void rgblight_effect_rgbtest(void) {
rgblight_setrgb ( r , g , b ) ;
pos = ( pos + 1 ) % 3 ;
}
# endif
# ifdef RGBLIGHT_EFFECT_ALTERNATING
void rgblight_effect_alternating ( void ) {
static uint16_t last_timer = 0 ;
static uint16_t pos = 0 ;
@ -795,5 +871,4 @@ void rgblight_effect_alternating(void){
rgblight_set ( ) ;
pos = ( pos + 1 ) % 2 ;
}
# endif /* RGBLIGHT_ANIMATIONS */
# endif