]> git.donarmstrong.com Git - qmk_firmware.git/blobdiff - quantum/rgblight.c
fix rgblight_effect_breathing interval time (#5213)
[qmk_firmware.git] / quantum / rgblight.c
index ae5dca18844e239c56f3940e1de9941bc9c8032c..52e0be8ba01604e7a63ef8b3fa33eaedd3d29031 100644 (file)
   #include <avr/eeprom.h>
   #include <avr/interrupt.h>
 #endif
+#ifdef STM32_EEPROM_ENABLE
+  #include "hal.h"
+  #include "eeprom.h"
+  #include "eeprom_stm32.h"
+#endif
 #include "wait.h"
 #include "progmem.h"
 #include "timer.h"
 #include "rgblight.h"
 #include "debug.h"
 #include "led_tables.h"
-
-#ifndef RGBLIGHT_LIMIT_VAL
-#define RGBLIGHT_LIMIT_VAL 255
+#ifdef VELOCIKEY_ENABLE
+  #include "velocikey.h"
 #endif
 
 #define _RGBM_SINGLE_STATIC(sym)   RGBLIGHT_MODE_ ## sym,
@@ -53,6 +57,7 @@ const uint16_t RGBLED_GRADIENT_RANGES[] PROGMEM = {360, 240, 180, 120, 90};
 #endif
 
 rgblight_config_t rgblight_config;
+bool is_rgblight_initialized = false;
 
 LED_TYPE led[RGBLED_NUM];
 bool rgblight_timer_enabled = false;
@@ -118,19 +123,51 @@ void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1) {
   (*led1).b = b;
 }
 
+void rgblight_check_config(void) {
+  /* Add some out of bound checks for RGB light config */
+
+  if (rgblight_config.mode < RGBLIGHT_MODE_STATIC_LIGHT) {
+    rgblight_config.mode = RGBLIGHT_MODE_STATIC_LIGHT;
+  }
+  else if (rgblight_config.mode > RGBLIGHT_MODES) {
+    rgblight_config.mode = RGBLIGHT_MODES;
+  }
+
+  if (rgblight_config.hue < 0) {
+    rgblight_config.hue = 0;
+  } else if (rgblight_config.hue > 360) {
+    rgblight_config.hue %= 360;
+  }
+
+  if (rgblight_config.sat < 0) {
+    rgblight_config.sat = 0;
+  } else if (rgblight_config.sat > 255) {
+    rgblight_config.sat = 255;
+  }
+
+  if (rgblight_config.val < 0) {
+    rgblight_config.val = 0;
+  } else if (rgblight_config.val > RGBLIGHT_LIMIT_VAL) {
+    rgblight_config.val = RGBLIGHT_LIMIT_VAL;
+  }
+
+}
 
 uint32_t eeconfig_read_rgblight(void) {
-  #ifdef __AVR__
+  #if defined(__AVR__) || defined(STM32_EEPROM_ENABLE) || defined(PROTOCOL_ARM_ATSAM) || defined(EEPROM_SIZE)
     return eeprom_read_dword(EECONFIG_RGBLIGHT);
   #else
     return 0;
   #endif
 }
+
 void eeconfig_update_rgblight(uint32_t val) {
-  #ifdef __AVR__
+  #if defined(__AVR__) || defined(STM32_EEPROM_ENABLE) || defined(PROTOCOL_ARM_ATSAM) || defined(EEPROM_SIZE)
+    rgblight_check_config();
     eeprom_update_dword(EECONFIG_RGBLIGHT, val);
   #endif
 }
+
 void eeconfig_update_rgblight_default(void) {
   //dprintf("eeconfig_update_rgblight_default\n");
   rgblight_config.enable = 1;
@@ -141,6 +178,7 @@ void eeconfig_update_rgblight_default(void) {
   rgblight_config.speed = 0;
   eeconfig_update_rgblight(rgblight_config.raw);
 }
+
 void eeconfig_debug_rgblight(void) {
   dprintf("rgblight_config eprom\n");
   dprintf("rgblight_config.enable = %d\n", rgblight_config.enable);
@@ -152,6 +190,11 @@ void eeconfig_debug_rgblight(void) {
 }
 
 void rgblight_init(void) {
+  /* if already initialized, don't do it again.
+     If you must do it again, extern this and set to false, first.
+     This is a dirty, dirty hack until proper hooks can be added for keyboard startup. */
+  if (is_rgblight_initialized) { return; }
+
   debug_enable = 1; // Debug ON!
   dprintf("rgblight_init called.\n");
   dprintf("rgblight_init start!\n");
@@ -166,6 +209,8 @@ void rgblight_init(void) {
     eeconfig_update_rgblight_default();
     rgblight_config.raw = eeconfig_read_rgblight();
   }
+  rgblight_check_config();
+
   eeconfig_debug_rgblight(); // display current eeprom values
 
 #ifdef RGBLIGHT_USE_TIMER
@@ -175,6 +220,9 @@ void rgblight_init(void) {
   if (rgblight_config.enable) {
     rgblight_mode_noeeprom(rgblight_config.mode);
   }
+
+  is_rgblight_initialized = true;
+
 }
 
 void rgblight_update_dword(uint32_t dword) {
@@ -234,7 +282,7 @@ void rgblight_step_reverse(void) {
   rgblight_step_reverse_helper(true);
 }
 
-uint32_t rgblight_get_mode(void) {
+uint8_t rgblight_get_mode(void) {
   if (!rgblight_config.enable) {
     return false;
   }
@@ -331,7 +379,7 @@ void rgblight_disable_noeeprom(void) {
 #ifdef RGBLIGHT_USE_TIMER
     rgblight_timer_disable();
 #endif
-  _delay_ms(50);
+  wait_ms(50);
   rgblight_set();
 }
 
@@ -562,6 +610,55 @@ void rgblight_sethsv_at(uint16_t hue, uint8_t sat, uint8_t val, uint8_t index) {
   rgblight_setrgb_at(tmp_led.r, tmp_led.g, tmp_led.b, index);
 }
 
+#if defined(RGBLIGHT_EFFECT_BREATHING) || defined(RGBLIGHT_EFFECT_RAINBOW_MOOD) || defined(RGBLIGHT_EFFECT_RAINBOW_SWIRL) \
+  || defined(RGBLIGHT_EFFECT_SNAKE) || defined(RGBLIGHT_EFFECT_KNIGHT)
+
+static uint8_t get_interval_time(const uint8_t* default_interval_address, uint8_t velocikey_min, uint8_t velocikey_max) {
+  return 
+#ifdef VELOCIKEY_ENABLE
+    velocikey_enabled() ? velocikey_match_speed(velocikey_min, velocikey_max) :
+#endif
+    pgm_read_byte(default_interval_address);
+}
+
+#endif
+
+void rgblight_setrgb_range(uint8_t r, uint8_t g, uint8_t b, uint8_t start, uint8_t end) {
+  if (!rgblight_config.enable || start < 0 || start >= end || end > RGBLED_NUM) { return; }
+
+  for (uint8_t i = start; i < end; i++) {
+    led[i].r = r;
+    led[i].g = g;
+    led[i].b = b;
+  }
+  rgblight_set();
+  wait_ms(1);
+}
+
+void rgblight_sethsv_range(uint16_t hue, uint8_t sat, uint8_t val, uint8_t start, uint8_t end) {
+  if (!rgblight_config.enable) { return; }
+
+  LED_TYPE tmp_led;
+  sethsv(hue, sat, val, &tmp_led);
+  rgblight_setrgb_range(tmp_led.r, tmp_led.g, tmp_led.b, start, end);
+}
+
+void rgblight_setrgb_master(uint8_t r, uint8_t g, uint8_t b) {
+  rgblight_setrgb_range(r, g, b, 0 , (uint8_t) RGBLED_NUM/2);
+}
+
+void rgblight_setrgb_slave(uint8_t r, uint8_t g, uint8_t b) {
+  rgblight_setrgb_range(r, g, b, (uint8_t) RGBLED_NUM/2, (uint8_t) RGBLED_NUM);
+}
+
+void rgblight_sethsv_master(uint16_t hue, uint8_t sat, uint8_t val) {
+  rgblight_sethsv_range(hue, sat, val, 0, (uint8_t) RGBLED_NUM/2);
+}
+
+void rgblight_sethsv_slave(uint16_t hue, uint8_t sat, uint8_t val) {
+  rgblight_sethsv_range(hue, sat, val, (uint8_t) RGBLED_NUM/2, (uint8_t) RGBLED_NUM);
+}
+
 #ifndef RGBLIGHT_CUSTOM_DRIVER
 void rgblight_set(void) {
   if (rgblight_config.enable) {
@@ -626,6 +723,7 @@ void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b) {
 }
 
 void rgblight_task(void) {
+
   if (rgblight_timer_enabled) {
     // static light mode, do nothing here
     if ( 1 == 0 ) { //dummy
@@ -697,7 +795,9 @@ void rgblight_effect_breathing(uint8_t interval) {
   static uint16_t last_timer = 0;
   float val;
 
-  if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_BREATHING_INTERVALS[interval])) {
+  uint8_t interval_time = get_interval_time(&RGBLED_BREATHING_INTERVALS[interval], 1, 100);
+  
+  if (timer_elapsed(last_timer) < interval_time) {
     return;
   }
   last_timer = timer_read();
@@ -717,7 +817,9 @@ void rgblight_effect_rainbow_mood(uint8_t interval) {
   static uint16_t current_hue = 0;
   static uint16_t last_timer = 0;
 
-  if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_RAINBOW_MOOD_INTERVALS[interval])) {
+  uint8_t interval_time = get_interval_time(&RGBLED_RAINBOW_MOOD_INTERVALS[interval], 5, 100);
+
+  if (timer_elapsed(last_timer) < interval_time) {
     return;
   }
   last_timer = timer_read();
@@ -739,7 +841,10 @@ void rgblight_effect_rainbow_swirl(uint8_t interval) {
   static uint16_t last_timer = 0;
   uint16_t hue;
   uint8_t i;
-  if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_RAINBOW_SWIRL_INTERVALS[interval / 2])) {
+
+  uint8_t interval_time = get_interval_time(&RGBLED_RAINBOW_SWIRL_INTERVALS[interval / 2], 1, 100);
+
+  if (timer_elapsed(last_timer) < interval_time) {
     return;
   }
   last_timer = timer_read();
@@ -774,7 +879,10 @@ void rgblight_effect_snake(uint8_t interval) {
   if (interval % 2) {
     increment = -1;
   }
-  if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_SNAKE_INTERVALS[interval / 2])) {
+
+  uint8_t interval_time = get_interval_time(&RGBLED_SNAKE_INTERVALS[interval / 2], 1, 200);
+
+  if (timer_elapsed(last_timer) < interval_time) {
     return;
   }
   last_timer = timer_read();
@@ -811,7 +919,10 @@ 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])) {
+
+  uint8_t interval_time = get_interval_time(&RGBLED_KNIGHT_INTERVALS[interval], 5, 100);
+
+  if (timer_elapsed(last_timer) < interval_time) {
     return;
   }
   last_timer = timer_read();