aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--keyboards/mxss/config.h13
-rw-r--r--keyboards/mxss/keymaps/default/keymap.c19
-rw-r--r--keyboards/mxss/keymaps/via/config.h19
-rw-r--r--keyboards/mxss/keymaps/via/keymap.c33
-rw-r--r--keyboards/mxss/keymaps/via/rules.mk1
-rw-r--r--keyboards/mxss/mxss.c205
-rw-r--r--keyboards/mxss/mxss.h19
-rw-r--r--keyboards/mxss/mxss_frontled.c264
-rw-r--r--keyboards/mxss/mxss_frontled.h57
-rw-r--r--keyboards/mxss/readme.md7
-rw-r--r--keyboards/mxss/rgblight.c1628
-rw-r--r--keyboards/mxss/rgblight.h362
-rw-r--r--keyboards/mxss/rules.mk6
-rw-r--r--keyboards/mxss/templates/keymap.c19
14 files changed, 1687 insertions, 965 deletions
diff --git a/keyboards/mxss/config.h b/keyboards/mxss/config.h
index 812f301d6..264caec97 100644
--- a/keyboards/mxss/config.h
+++ b/keyboards/mxss/config.h
@@ -21,12 +21,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
21#include "config_common.h" 21#include "config_common.h"
22 22
23/* USB Device descriptor parameter */ 23/* USB Device descriptor parameter */
24#define VENDOR_ID 0xFEED 24#define VENDOR_ID 0x4D78 // "Mx" -> MxBlue
25#define PRODUCT_ID 0x6060 25#define PRODUCT_ID 0x5353 // "SS" -> MxSS
26#define DEVICE_VER 0x0001 26#define DEVICE_VER 0x0001
27#define MANUFACTURER MxBlue 27#define MANUFACTURER MxBlue
28#define PRODUCT MxSS 28#define PRODUCT MxSS
29#define DESCRIPTION Custom Polycarb Keyboard 29#define DESCRIPTION MxSS Polycarb Keyboard
30 30
31/* key matrix size */ 31/* key matrix size */
32#define MATRIX_ROWS 5 32#define MATRIX_ROWS 5
@@ -56,6 +56,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
56/* Locking resynchronize hack */ 56/* Locking resynchronize hack */
57#define LOCKING_RESYNC_ENABLE 57#define LOCKING_RESYNC_ENABLE
58 58
59// Just for posterity, define bootlite matrix pos
60#define BOOTMAGIC_LITE_ROW 0
61#define BOOTMAGIC_LITE_COLUMN 0
62
63// FLED config takes up 1 byte, stored color count takes 1, stored colors take up to 8
64#define VIA_EEPROM_CUSTOM_CONFIG_SIZE 10
65
59/* If defined, GRAVE_ESC will always act as ESC when CTRL is held. 66/* If defined, GRAVE_ESC will always act as ESC when CTRL is held.
60 * This is userful for the Windows task manager shortcut (ctrl+shift+esc). 67 * This is userful for the Windows task manager shortcut (ctrl+shift+esc).
61 */ 68 */
diff --git a/keyboards/mxss/keymaps/default/keymap.c b/keyboards/mxss/keymaps/default/keymap.c
index 17cebe0c8..b69d91df9 100644
--- a/keyboards/mxss/keymaps/default/keymap.c
+++ b/keyboards/mxss/keymaps/default/keymap.c
@@ -15,31 +15,32 @@
15 */ 15 */
16#include QMK_KEYBOARD_H 16#include QMK_KEYBOARD_H
17 17
18hs_set caps_color = { .hue = 0, .sat = 255 };
19
18// Colors for layers 20// Colors for layers
19// Format: {hue, saturation} 21// Format: {hue, saturation}
20// {0, 0} to turn off the LED 22// {0, 0} to turn off the LED
21// Add additional rows to handle more layers 23// Add additional rows to handle more layers
22const hs_set layer_colors[] = { 24hs_set layer_colors[4] = {
23 [0] = {0, 0}, // Color for Layer 0 25 [0] = {.hue = 0, .sat = 0}, // Color for Layer 0
24 [1] = {86, 255}, // Color for Layer 1 26 [1] = {.hue = 86, .sat = 255}, // Color for Layer 1
25 [2] = {36, 255}, // Color for Layer 2 27 [2] = {.hue = 36, .sat = 255}, // Color for Layer 2
26 [3] = {185, 255}, // Color for Layer 3 28 [3] = {.hue = 185, .sat = 255}, // Color for Layer 3
27}; 29};
28const size_t lc_size = sizeof(layer_colors) / sizeof(uint16_t); 30size_t lc_size = sizeof(layer_colors) / sizeof(uint16_t);
29 31
30// Use NEW_SAFE_RANGE to define new custom keycodes in order to not overwrite the ones used for front LED control 32// Use NEW_SAFE_RANGE to define new custom keycodes in order to not overwrite the ones used for front LED control
31enum custom_keycodes { 33enum custom_keycodes {
32 MY_KEYCODE = NEW_SAFE_RANGE, 34 MY_KEYCODE = NEW_SAFE_RANGE,
33}; 35};
34 36
35
36const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { 37const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
37 LAYOUT( /* Base */ 38 LAYOUT( /* Base */
38 KC_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, 39 KC_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC,
39 KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, 40 KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL,
40 KC_CAPSLOCK, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGUP, 41 KC_CAPSLOCK, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGUP,
41 KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN, 42 KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN,
42 KC_LCTL, KC_LGUI, KC_LALT, KC_SPACE, KC_RALT, MO(1), KC_LEFT, KC_DOWN, KC_RGHT 43 KC_LCTL, KC_LGUI, KC_LALT, KC_SPACE, KC_RALT, MO(1), KC_LEFT, KC_DOWN, KC_RGHT
43), 44),
44 45
45 LAYOUT( /* L1 */ 46 LAYOUT( /* L1 */
diff --git a/keyboards/mxss/keymaps/via/config.h b/keyboards/mxss/keymaps/via/config.h
new file mode 100644
index 000000000..7451a7be4
--- /dev/null
+++ b/keyboards/mxss/keymaps/via/config.h
@@ -0,0 +1,19 @@
1/* Copyright 2018 Jumail Mundekkat / MxBlue
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#pragma once
18
19#define LAYER_STATE_8BIT
diff --git a/keyboards/mxss/keymaps/via/keymap.c b/keyboards/mxss/keymaps/via/keymap.c
new file mode 100644
index 000000000..34e40592a
--- /dev/null
+++ b/keyboards/mxss/keymaps/via/keymap.c
@@ -0,0 +1,33 @@
1/* Copyright 2018 Jumail Mundekkat / MxBlue
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include QMK_KEYBOARD_H
17
18const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
19 LAYOUT_all( /* L0 */
20 KC_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_NO, KC_BSPC,
21 KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL,
22 KC_CAPSLOCK, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NO, KC_ENT, KC_PGUP,
23 KC_LSFT, KC_NO, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN,
24 KC_LCTL, KC_LGUI, KC_LALT, KC_SPACE, KC_SPACE, KC_SPACE, KC_RALT, MO(1), KC_LEFT, KC_DOWN, KC_RGHT
25 ),
26 LAYOUT_all( /* L1 */
27 KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS, KC_TRNS,
28 KC_TRNS, KC_MPLY, KC_MPRV, KC_MNXT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_PSCR, FLED_VAD, FLED_VAI, FLED_MOD, RGB_VAI,
29 RESET, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_END, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_VAD,
30 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MUTE, KC_VOLD, KC_VOLU, KC_TRNS, RGB_MOD, RGB_SAI, RGB_TOG,
31 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_HUD, RGB_SAD, RGB_HUI
32 )
33};
diff --git a/keyboards/mxss/keymaps/via/rules.mk b/keyboards/mxss/keymaps/via/rules.mk
new file mode 100644
index 000000000..1e5b99807
--- /dev/null
+++ b/keyboards/mxss/keymaps/via/rules.mk
@@ -0,0 +1 @@
VIA_ENABLE = yes
diff --git a/keyboards/mxss/mxss.c b/keyboards/mxss/mxss.c
index 42ecdbc46..48ea46641 100644
--- a/keyboards/mxss/mxss.c
+++ b/keyboards/mxss/mxss.c
@@ -1,4 +1,4 @@
1/* Copyright 2018 Jumail Mundekkat / MxBlue 1/* Copyright 2020 Jumail Mundekkat / MxBlue
2 * 2 *
3 * This program is free software: you can redistribute it and/or modify 3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by 4 * it under the terms of the GNU General Public License as published by
@@ -12,63 +12,29 @@
12 * 12 *
13 * You should have received a copy of the GNU General Public License 13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * EEPROM management code from ../cannonkeys/stm32f072/keyboard.c
15 */ 17 */
16 18
17#include QMK_KEYBOARD_H 19#include QMK_KEYBOARD_H
18#include "tmk_core/common/eeprom.h" 20#include "tmk_core/common/eeprom.h"
19#include "tmk_core/common/action_layer.h" 21#include "tmk_core/common/action_layer.h"
20#include "rgblight.h" 22#include "rgblight.h"
23#include "via.h"
24#include "version.h" // for QMK_BUILDDATE used in EEPROM magic
21 25
22// Variables for controlling front LED application 26void via_init_kb(void) {
23uint8_t fled_mode; // Mode for front LEDs 27 fled_init();
24uint8_t fled_val; // Brightness for front leds (0 - 255) 28}
25LED_TYPE fleds[2]; // Front LED rgb values for indicator mode use
26
27// Predefined colors for layers
28// Format: {hue, saturation}
29// {0, 0} to turn off the LED
30// Add additional rows to handle more layers
31__attribute__ ((weak))
32const hs_set layer_colors[] = {
33 [0] = {0, 0}, // Color for Layer 0
34 [1] = {86, 255}, // Color for Layer 1
35 [2] = {36, 255}, // Color for Layer 2
36 [3] = {185, 255}, // Color for Layer 3
37};
38
39__attribute__ ((weak))
40const size_t lc_size = sizeof(layer_colors) / sizeof(uint16_t);
41 29
42void matrix_init_kb(void) { 30void matrix_init_kb(void) {
43 // If EEPROM config exists, load it 31 // If VIA is disabled, we still need to load settings
44 if (eeprom_is_valid()) { 32 // Call via_init_kb() the same way as via_init(), with setting
45 fled_config fled_conf; 33 // EEPROM valid afterwards.
46 fled_conf.raw = eeprom_read_byte(EEPROM_FRONTLED_ADDR); 34#ifndef VIA_ENABLE
47 fled_mode = fled_conf.mode; 35 fled_init();
48 fled_val = fled_conf.val * FLED_VAL_STEP; 36 via_eeprom_set_valid(true);
49 // Else, default config 37#endif // VIA_ENABLE
50 } else {
51 fled_mode = FLED_RGB;
52 fled_val = 10 * FLED_VAL_STEP;
53 eeprom_update_conf(); // Store default config to EEPROM
54 }
55
56 // Set default values for leds
57 setrgb(0, 0, 0, &fleds[0]);
58 setrgb(0, 0, 0, &fleds[1]);
59
60 // Handle lighting for indicator mode
61 if (fled_mode == FLED_INDI) {
62 // Enable capslock led if enabled on host
63 if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK))
64 sethsv(FLED_CAPS_H, FLED_CAPS_S, fled_val, &fleds[0]);
65
66 // Determine and set colour of layer LED according to current layer
67 // if hue = sat = 0, leave LED off
68 uint8_t layer = biton32(layer_state);
69 if (layer < lc_size && !(layer_colors[layer].hue == 0 && layer_colors[layer].hue == 0))
70 sethsv(layer_colors[layer].hue, layer_colors[layer].sat, fled_val, &fleds[1]);
71 }
72 38
73 matrix_init_user(); 39 matrix_init_user();
74} 40}
@@ -82,132 +48,35 @@ void matrix_scan_kb(void) {
82 48
83bool process_record_kb(uint16_t keycode, keyrecord_t *record) { 49bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
84 // Handle custom keycodes for front LED operation 50 // Handle custom keycodes for front LED operation
85 switch (keycode) { 51 process_record_fled(keycode, record);
86 case FLED_MOD: // Change between front LED operation modes (off, indicator, RGB)
87 if (record->event.pressed)
88 fled_mode_cycle();
89 break;
90
91 case FLED_VAI: // Increase the brightness of the front LEDs by FLED_VAL_STEP
92 if (record->event.pressed)
93 fled_val_increase();
94 break;
95
96 case FLED_VAD: // Decrease the brightness of the front LEDs by FLED_VAL_STEP
97 if (record->event.pressed)
98 fled_val_decrease();
99 break;
100
101 default:
102 break; // Process all other keycodes normally
103 }
104
105 return process_record_user(keycode, record); 52 return process_record_user(keycode, record);
106} 53}
107 54
108void led_set_kb(uint8_t usb_led) { 55bool led_update_kb(led_t led_state) {
109 // Set indicator LED appropriately, whether it is used or not 56 fled_lock_update(led_state);
110 if (usb_led & (1 << USB_LED_CAPS_LOCK)) { 57 return led_update_user(led_state);
111 sethsv(FLED_CAPS_H, FLED_CAPS_S, fled_val, &fleds[0]);
112 } else {
113 setrgb(0, 0, 0, &fleds[0]);
114 }
115
116 rgblight_set();
117 led_set_user(usb_led);
118}
119
120uint32_t layer_state_set_kb(uint32_t state) {
121 // Determine and set colour of layer LED according to current layer
122 // if hue = sat = 0, leave LED off
123 uint8_t layer = biton32(state);
124
125 if (layer < lc_size && !(layer_colors[layer].hue == 0 && layer_colors[layer].hue == 0))
126 sethsv(layer_colors[layer].hue, layer_colors[layer].sat, fled_val, &fleds[1]);
127 else
128 setrgb(0, 0, 0, &fleds[1]);
129
130 return state;
131}
132
133// EEPROM Management
134
135// Test if magic value is present at expected location
136bool eeprom_is_valid(void)
137{
138 return (eeprom_read_word(EEPROM_MAGIC_ADDR) == EEPROM_MAGIC);
139}
140
141// Set magic value at expected location
142void eeprom_set_valid(bool valid)
143{
144 eeprom_update_word(EEPROM_MAGIC_ADDR, valid ? EEPROM_MAGIC : 0xFFFF);
145} 58}
146 59
147// Store current front led config in EEPROM 60layer_state_t layer_state_set_kb(layer_state_t state) {
148void eeprom_update_conf(void) 61 fled_layer_update(state);
149{ 62 return layer_state_set_user(state);
150 // Create storage struct and set values
151 fled_config conf;
152 conf.mode = fled_mode;
153
154 // Small hack to ensure max value is stored correctly
155 if (fled_val == 255)
156 conf.val = 256 / FLED_VAL_STEP;
157 else
158 conf.val = fled_val / FLED_VAL_STEP;
159
160 // Set magic value and store config
161 eeprom_set_valid(true);
162 eeprom_update_byte(EEPROM_FRONTLED_ADDR, conf.raw);
163} 63}
164 64
165// Custom keycode functions 65// Fallback eeprom functions if VIA is not enabled
66#ifndef VIA_ENABLE
166 67
167void fled_mode_cycle(void) 68// Sets VIA/keyboard level usage of EEPROM to valid/invalid
69// Keyboard level code (eg. via_init_kb()) should not call this
70void via_eeprom_set_valid(bool valid)
168{ 71{
169 // FLED -> FLED_RGB -> FLED_INDI 72 char *p = QMK_BUILDDATE; // e.g. "2019-11-05-11:29:54"
170 switch (fled_mode) { 73 uint8_t magic0 = ( ( p[2] & 0x0F ) << 4 ) | ( p[3] & 0x0F );
171 case FLED_OFF: 74 uint8_t magic1 = ( ( p[5] & 0x0F ) << 4 ) | ( p[6] & 0x0F );
172 fled_mode = FLED_RGB; 75 uint8_t magic2 = ( ( p[8] & 0x0F ) << 4 ) | ( p[9] & 0x0F );
173 break; 76
174 77 eeprom_update_byte( (void*)VIA_EEPROM_MAGIC_ADDR+0, valid ? magic0 : 0xFF);
175 case FLED_RGB: 78 eeprom_update_byte( (void*)VIA_EEPROM_MAGIC_ADDR+1, valid ? magic1 : 0xFF);
176 fled_mode = FLED_INDI; 79 eeprom_update_byte( (void*)VIA_EEPROM_MAGIC_ADDR+2, valid ? magic2 : 0xFF);
177 break;
178
179 case FLED_INDI:
180 fled_mode = FLED_OFF;
181 break;
182 }
183
184 // Update stored config
185 eeprom_update_conf();
186 rgblight_set();
187} 80}
188 81
189void fled_val_increase(void) 82#endif
190{
191 // Increase val by FLED_VAL_STEP, handling the upper edge case
192 if (fled_val + FLED_VAL_STEP > 255)
193 fled_val = 255;
194 else
195 fled_val += FLED_VAL_STEP;
196
197 // Update stored config
198 eeprom_update_conf();
199 rgblight_set();
200}
201
202void fled_val_decrease(void)
203{
204 // Decrease val by FLED_VAL_STEP, handling the lower edge case
205 if (fled_val - FLED_VAL_STEP > 255)
206 fled_val = 255;
207 else
208 fled_val -= FLED_VAL_STEP;
209
210 // Update stored config
211 eeprom_update_conf();
212 rgblight_set();
213}
diff --git a/keyboards/mxss/mxss.h b/keyboards/mxss/mxss.h
index 3572a19cd..4074d411c 100644
--- a/keyboards/mxss/mxss.h
+++ b/keyboards/mxss/mxss.h
@@ -13,8 +13,7 @@
13 * You should have received a copy of the GNU General Public License 13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16#ifndef MXSS_H 16#pragma once
17#define MXSS_H
18 17
19#include "quantum.h" 18#include "quantum.h"
20#include "mxss_frontled.h" 19#include "mxss_frontled.h"
@@ -204,4 +203,18 @@
204 { k40, k41, k42, k43, KC_NO, KC_NO, k46, KC_NO, k48, KC_NO, k4A, k4B, k4C, k4D, k4E }, \ 203 { k40, k41, k42, k43, KC_NO, KC_NO, k46, KC_NO, k48, KC_NO, k4A, k4B, k4C, k4D, k4E }, \
205} 204}
206 205
207#endif 206// All the gubs
207#define LAYOUT_all( \
208 k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, k0E, \
209 k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E, \
210 k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k2E, \
211 k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k3D, k3E, \
212 k40, k41, k42, k43, k46, k48, k4A, k4B, k4C, k4D, k4E \
213) \
214{ \
215 { k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, k0E }, \
216 { k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E }, \
217 { k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k2E }, \
218 { k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k3D, k3E }, \
219 { k40, k41, k42, k43, KC_NO, KC_NO, k46, KC_NO, k48, KC_NO, k4A, k4B, k4C, k4D, k4E }, \
220}
diff --git a/keyboards/mxss/mxss_frontled.c b/keyboards/mxss/mxss_frontled.c
new file mode 100644
index 000000000..3f19747d2
--- /dev/null
+++ b/keyboards/mxss/mxss_frontled.c
@@ -0,0 +1,264 @@
1/* Copyright 2020 Jumail Mundekkat / MxBlue
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Extended from the work done by fcoury: https://github.com/qmk/qmk_firmware/pull/4915
17 */
18
19#include "mxss_frontled.h"
20#include "tmk_core/common/eeprom.h"
21#include "rgblight.h"
22#include "via.h"
23#include "version.h" // for QMK_BUILDDATE used in EEPROM magic
24
25// Variables for controlling front LED application
26uint8_t fled_mode; // Mode for front LEDs
27uint8_t fled_val; // Brightness for front leds (0 - 255)
28LED_TYPE fleds[2]; // Front LED rgb values for indicator mode use
29
30// Layer indicator colors
31__attribute__ ((weak))
32hs_set layer_colors[FRONTLED_COLOR_MAXCNT];
33
34// Caps lock indicator color
35__attribute__ ((weak))
36hs_set caps_color;
37
38__attribute__ ((weak))
39size_t lc_size = sizeof(layer_colors) / sizeof(hs_set);
40
41void fled_init(void) {
42 // If EEPROM config exists, load it
43 // If VIA EEPROM exists, FLED config should too
44 if (via_eeprom_is_valid()) {
45 fled_load_conf();
46 // Else, default config
47 } else {
48 // Default mode/brightness
49 fled_mode = FLED_RGB;
50 fled_val = 10 * FLED_VAL_STEP;
51
52 // Default colors
53 caps_color.hue = 0;
54 caps_color.sat = 255;
55 layer_colors[0].hue = 0;
56 layer_colors[0].sat = 0;
57 layer_colors[1].hue = 86;
58 layer_colors[1].sat = 255;
59 layer_colors[2].hue = 36;
60 layer_colors[2].sat = 255;
61 layer_colors[3].hue = 185;
62 layer_colors[3].sat = 255;
63
64 fled_update_conf(); // Store default config to EEPROM
65 }
66
67 // Set default values for leds
68 setrgb(0, 0, 0, &fleds[0]);
69 setrgb(0, 0, 0, &fleds[1]);
70
71 // Handle lighting for indicator mode
72 if (fled_mode == FLED_INDI) {
73 fled_lock_update(host_keyboard_led_state());
74 fled_layer_update(layer_state);
75 }
76}
77
78void process_record_fled(uint16_t keycode, keyrecord_t *record) {
79 // Handle custom keycodes for front LED operation
80 switch (keycode) {
81 case FLED_MOD: // Change between front LED operation modes (off, indicator, RGB)
82 if (record->event.pressed)
83 fled_mode_cycle();
84 break;
85
86 case FLED_VAI: // Increase the brightness of the front LEDs by FLED_VAL_STEP
87 if (record->event.pressed)
88 fled_val_increase();
89 break;
90
91 case FLED_VAD: // Decrease the brightness of the front LEDs by FLED_VAL_STEP
92 if (record->event.pressed)
93 fled_val_decrease();
94 break;
95
96 default:
97 break; // Process all other keycodes normally
98 }
99
100 return;
101}
102
103void fled_load_conf(void) {
104 // Load config
105 fled_config fled_conf;
106 fled_conf.raw = eeprom_read_byte(FRONTLED_CONF_ADDR);
107 fled_mode = fled_conf.mode;
108 fled_val = fled_conf.val * FLED_VAL_STEP;
109
110 // Load color data
111 uint8_t stored_cnt = eeprom_read_byte(FRONTLED_COLOR_CNT_ADDR);
112 uint16_t *color_ptr = FRONTLED_COLOR_ADDR;
113 caps_color.raw = eeprom_read_word(color_ptr); // Should always store at least 1 color
114 for (uint8_t i = 1; i < stored_cnt; i++) {
115 if (i == lc_size) // Can't load more layers than we have available
116 break;
117 layer_colors[i].raw = eeprom_read_word(&color_ptr[i]);
118 }
119 layer_colors[0].raw = 0; // hue = sat = 0 for layer 0
120}
121
122// Store current front led config in EEPROM
123void fled_update_conf(void)
124{
125 // Create storage struct and set values
126 fled_config conf;
127 conf.mode = fled_mode;
128
129 // Small hack to ensure max value is stored correctly
130 if (fled_val == 255)
131 conf.val = 256 / FLED_VAL_STEP;
132 else
133 conf.val = fled_val / FLED_VAL_STEP;
134
135 // Store config
136 eeprom_update_byte(FRONTLED_CONF_ADDR, conf.raw);
137
138 // Store color data
139 uint16_t *color_ptr = FRONTLED_COLOR_ADDR;
140 eeprom_update_word(color_ptr, caps_color.raw);
141 // Start from 1, layer 0 is not modifiable and therefore not persisted
142 uint8_t i = 1;
143 for (; i < lc_size; i++) {
144 if (i == FRONTLED_COLOR_MAXCNT) // Can't store more than the EEPROM we have available
145 break;
146 eeprom_update_word(&color_ptr[i], layer_colors[i].raw);
147 }
148 eeprom_update_byte(FRONTLED_COLOR_CNT_ADDR, i); // For safety, store the count of colors stored
149}
150
151// Custom keycode functions
152
153void fled_mode_cycle(void)
154{
155 // FLED -> FLED_RGB -> FLED_INDI
156 switch (fled_mode) {
157 case FLED_OFF:
158 fled_mode = FLED_RGB;
159 rgblight_timer_enable();
160 break;
161
162 case FLED_RGB:
163 fled_mode = FLED_INDI;
164 break;
165
166 case FLED_INDI:
167 fled_mode = FLED_OFF;
168 break;
169 }
170
171 // Update stored config
172 fled_update_conf();
173 rgblight_set();
174}
175
176void fled_val_increase(void)
177{
178 // Increase val by FLED_VAL_STEP, handling the upper edge case
179 if (fled_val + FLED_VAL_STEP > 255)
180 fled_val = 255;
181 else
182 fled_val += FLED_VAL_STEP;
183
184 // Update stored config
185 fled_update_conf();
186 rgblight_set();
187}
188
189void fled_val_decrease(void)
190{
191 // Decrease val by FLED_VAL_STEP, handling the lower edge case
192 if (fled_val - FLED_VAL_STEP > 255)
193 fled_val = 255;
194 else
195 fled_val -= FLED_VAL_STEP;
196
197 // Update stored config
198 fled_update_conf();
199 rgblight_set();
200}
201
202void fled_layer_update(layer_state_t state) {
203 // Determine and set colour of layer LED according to current layer
204 // if hue = sat = 0, leave LED off
205 uint8_t layer = get_highest_layer(state);
206
207 if (layer < lc_size && !(layer_colors[layer].hue == 0 && layer_colors[layer].sat == 0)) {
208 sethsv(layer_colors[layer].hue, layer_colors[layer].sat, fled_val, &fleds[1]);
209 } else {
210 setrgb(0, 0, 0, &fleds[1]);
211 }
212}
213
214void fled_lock_update(led_t led_state) {
215 // Set indicator LED appropriately, whether it is used or not
216 if (led_state.caps_lock) {
217 sethsv(caps_color.hue, caps_color.sat, fled_val, &fleds[0]);
218 } else {
219 setrgb(0, 0, 0, &fleds[0]);
220 }
221
222 rgblight_set();
223}
224
225void set_fled_layer_color(uint8_t layer, hs_set hs) {
226 // Update layer colors and refresh LEDs
227 layer_colors[layer] = hs;
228 fled_layer_update(layer_state);
229 fled_update_conf();
230}
231
232hs_set get_fled_layer_color(uint8_t layer) {
233 return layer_colors[layer];
234}
235
236void set_fled_caps_color(hs_set hs) {
237 // Update caplock color and refresh LEDs
238 caps_color = hs;
239 fled_lock_update(host_keyboard_led_state());
240 fled_update_conf();
241}
242
243hs_set get_fled_caps_color(void) {
244 return caps_color;
245}
246
247// Fallback eeprom functions if VIA is not enabled
248#ifndef VIA_ENABLE
249
250// Can be called in an overriding via_init_kb() to test if keyboard level code usage of
251// EEPROM is invalid and use/save defaults.
252bool via_eeprom_is_valid(void)
253{
254 char *p = QMK_BUILDDATE; // e.g. "2019-11-05-11:29:54"
255 uint8_t magic0 = ( ( p[2] & 0x0F ) << 4 ) | ( p[3] & 0x0F );
256 uint8_t magic1 = ( ( p[5] & 0x0F ) << 4 ) | ( p[6] & 0x0F );
257 uint8_t magic2 = ( ( p[8] & 0x0F ) << 4 ) | ( p[9] & 0x0F );
258
259 return (eeprom_read_byte( (void*)VIA_EEPROM_MAGIC_ADDR+0 ) == magic0 &&
260 eeprom_read_byte( (void*)VIA_EEPROM_MAGIC_ADDR+1 ) == magic1 &&
261 eeprom_read_byte( (void*)VIA_EEPROM_MAGIC_ADDR+2 ) == magic2 );
262}
263
264#endif
diff --git a/keyboards/mxss/mxss_frontled.h b/keyboards/mxss/mxss_frontled.h
index 1350266ba..366066865 100644
--- a/keyboards/mxss/mxss_frontled.h
+++ b/keyboards/mxss/mxss_frontled.h
@@ -1,4 +1,4 @@
1/* Copyright 2018 Jumail Mundekkat / MxBlue 1/* Copyright 2020 Jumail Mundekkat / MxBlue
2 * 2 *
3 * This program is free software: you can redistribute it and/or modify 3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by 4 * it under the terms of the GNU General Public License as published by
@@ -16,11 +16,12 @@
16 16
17// EEPROM management code taken from Wilba6582 17// EEPROM management code taken from Wilba6582
18// https://github.com/Wilba6582/qmk_firmware/blob/zeal60/keyboards/zeal60/zeal_eeprom.h 18// https://github.com/Wilba6582/qmk_firmware/blob/zeal60/keyboards/zeal60/zeal_eeprom.h
19
20#ifndef MXSS_FRONTLED_H
21#define MXSS_FRONTLED_H
22 19
20#pragma once
21
22#include "quantum.h"
23#include "quantum_keycodes.h" 23#include "quantum_keycodes.h"
24#include "via.h"
24 25
25// RGBLED index for front LEDs 26// RGBLED index for front LEDs
26#define RGBLIGHT_FLED1 14 27#define RGBLIGHT_FLED1 14
@@ -29,13 +30,13 @@
29// Brightness increase step for front LEDs 30// Brightness increase step for front LEDs
30#define FLED_VAL_STEP 8 31#define FLED_VAL_STEP 8
31 32
32// QMK never uses more then 32bytes of EEPROM, so our region starts there
33// Magic value to verify the state of the EEPROM
34#define EEPROM_MAGIC 0xC3E7
35#define EEPROM_MAGIC_ADDR ((void*)32)
36
37// Front LED settings 33// Front LED settings
38#define EEPROM_FRONTLED_ADDR ((void*)34) 34#define FRONTLED_CONF_ADDR ((uint8_t*) VIA_EEPROM_CUSTOM_CONFIG_ADDR)
35#define FRONTLED_COLOR_CNT_ADDR (FRONTLED_CONF_ADDR + 1)
36#define FRONTLED_COLOR_ADDR ((uint16_t*)(FRONTLED_COLOR_CNT_ADDR + 1))
37
38// No point persisting more 4, VIA only allows editing of 3 + 1 for caps
39#define FRONTLED_COLOR_MAXCNT 4
39 40
40// Modes for front LEDs 41// Modes for front LEDs
41#define FLED_OFF 0b00 42#define FLED_OFF 0b00
@@ -43,10 +44,6 @@
43#define FLED_RGB 0b10 44#define FLED_RGB 0b10
44#define FLED_UNDEF 0b11 45#define FLED_UNDEF 0b11
45 46
46// Hard-coded color for capslock indicator in FLED_INDI mode, H:0% S:100% = Red
47#define FLED_CAPS_H 0
48#define FLED_CAPS_S 255
49
50// Config storage format for EEPROM 47// Config storage format for EEPROM
51typedef union { 48typedef union {
52 uint8_t raw; 49 uint8_t raw;
@@ -57,25 +54,35 @@ typedef union {
57} fled_config; 54} fled_config;
58 55
59// Structure to store hue and saturation values 56// Structure to store hue and saturation values
60typedef struct _hs_set { 57typedef union {
61 uint16_t hue; 58 uint16_t raw;
62 uint8_t sat; 59 struct {
60 uint8_t hue;
61 uint8_t sat;
62 };
63} hs_set; 63} hs_set;
64 64
65// Custom keycodes for front LED control 65// Custom keycodes for front LED control
66enum fled_keycodes { 66enum fled_keycodes {
67 FLED_MOD = SAFE_RANGE, 67 FLED_MOD = USER00, // USER00 = VIA custom keycode start
68 FLED_VAI, 68 FLED_VAI,
69 FLED_VAD, 69 FLED_VAD,
70 NEW_SAFE_RANGE // define a new safe range 70 NEW_SAFE_RANGE // define a new safe range
71}; 71};
72 72
73bool eeprom_is_valid(void); // Check if EEPROM has been set up 73void fled_init(void); // Run init functions for front LEDs
74void eeprom_set_valid(bool valid); // Change validity state of EEPROM 74void process_record_fled(uint16_t keycode, keyrecord_t* record); // Process keycodes for front LEDs
75void eeprom_update_conf(void); // Store current front LED config to EEPROM 75void fled_load_conf(void); // Load front LED config from EEPROM
76void fled_update_conf(void); // Store current front LED config to EEPROM
76 77
77void fled_mode_cycle(void); // Cycle between the 3 modes for the front LEDs 78void fled_mode_cycle(void); // Cycle between the 3 modes for the front LEDs
78void fled_val_increase(void); // Increase the brightness of the front LEDs 79void fled_val_increase(void); // Increase the brightness of the front LEDs
79void fled_val_decrease(void); // Decrease the brightness of the front LEDs 80void fled_val_decrease(void); // Decrease the brightness of the front LEDs
80 81
81#endif //MXSS_FRONTLED_H \ No newline at end of file 82void fled_layer_update(layer_state_t state); // Process layer update for front LEDs
83void fled_lock_update(led_t led_state); // Process lock update for front LEDs
84
85void set_fled_layer_color(uint8_t layer, hs_set hs); // Set color for a given layer
86void set_fled_caps_color(hs_set hs); // Set color for the capslock indicator
87hs_set get_fled_caps_color(void); // Get color for the capslock indicator
88hs_set get_fled_layer_color(uint8_t layer); // Get color for a given layer
diff --git a/keyboards/mxss/readme.md b/keyboards/mxss/readme.md
index 181b6366a..f35709ade 100644
--- a/keyboards/mxss/readme.md
+++ b/keyboards/mxss/readme.md
@@ -2,6 +2,11 @@
2 2
3![MxSS - Polycarb 65% Kit for MX/SMK](https://i.imgur.com/WDTWcmU.jpg) 3![MxSS - Polycarb 65% Kit for MX/SMK](https://i.imgur.com/WDTWcmU.jpg)
4 4
5### Important Note:
6**This PCB supports the VIA configurator, and this is the recommended way to configure the keymap on this keyboard. Building the firmware should only be necessary if you would like to change the colours of the front LEDs in indicator mode.**
7
8**For more information about the VIA configurator, [see here](https://caniusevia.com/).**
9
5### Information: 10### Information:
6 11
7 - Case: Frosted Polycarbonate, CNC milled 12 - Case: Frosted Polycarbonate, CNC milled
@@ -51,4 +56,4 @@ Colors for FLED_INDI mode are hardcoded as hue/saturation values, the caps lock
51 56
52 # Further Notes 57 # Further Notes
53 58
54 As SAFE_RANGE is used for defining the custom keycodes seen above, please use NEW_SAFE_RANGE as the starting value for any custom keycodes in keymap.c, as per the example. \ No newline at end of file 59 As SAFE_RANGE is used for defining the custom keycodes seen above, please use NEW_SAFE_RANGE as the starting value for any custom keycodes in keymap.c, as per the example.
diff --git a/keyboards/mxss/rgblight.c b/keyboards/mxss/rgblight.c
index 73f94f3ab..9e17510b5 100644
--- a/keyboards/mxss/rgblight.c
+++ b/keyboards/mxss/rgblight.c
@@ -14,814 +14,1166 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16#include <math.h> 16#include <math.h>
17#include <avr/eeprom.h> 17#include <string.h>
18#include <avr/interrupt.h> 18#ifdef __AVR__
19#include <util/delay.h> 19# include <avr/eeprom.h>
20# include <avr/interrupt.h>
21#endif
22#ifdef STM32_EEPROM_ENABLE
23# include "hal.h"
24# include "eeprom.h"
25# include "eeprom_stm32.h"
26#endif
27#include "wait.h"
20#include "progmem.h" 28#include "progmem.h"
21#include "timer.h" 29#include "timer.h"
22#include "rgblight.h" 30#include "rgblight.h"
31#include "color.h"
23#include "debug.h" 32#include "debug.h"
24#include "led_tables.h" 33#include "led_tables.h"
34#include "lib/lib8tion/lib8tion.h"
35#ifdef VELOCIKEY_ENABLE
36# include "velocikey.h"
37#endif
38// MxSS custom
25#include "mxss_frontled.h" 39#include "mxss_frontled.h"
26 40
27#ifndef RGBLIGHT_LIMIT_VAL 41#ifdef RGBLIGHT_SPLIT
28#define RGBLIGHT_LIMIT_VAL 255 42/* for split keyboard */
43# define RGBLIGHT_SPLIT_SET_CHANGE_MODE rgblight_status.change_flags |= RGBLIGHT_STATUS_CHANGE_MODE
44# define RGBLIGHT_SPLIT_SET_CHANGE_HSVS rgblight_status.change_flags |= RGBLIGHT_STATUS_CHANGE_HSVS
45# define RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS rgblight_status.change_flags |= (RGBLIGHT_STATUS_CHANGE_MODE | RGBLIGHT_STATUS_CHANGE_HSVS)
46# define RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE rgblight_status.change_flags |= RGBLIGHT_STATUS_CHANGE_TIMER
47# define RGBLIGHT_SPLIT_ANIMATION_TICK rgblight_status.change_flags |= RGBLIGHT_STATUS_ANIMATION_TICK
48#else
49# define RGBLIGHT_SPLIT_SET_CHANGE_MODE
50# define RGBLIGHT_SPLIT_SET_CHANGE_HSVS
51# define RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS
52# define RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE
53# define RGBLIGHT_SPLIT_ANIMATION_TICK
29#endif 54#endif
30 55
31#define MIN(a,b) (((a)<(b))?(a):(b)) 56#define _RGBM_SINGLE_STATIC(sym) RGBLIGHT_MODE_##sym,
32#define MAX(a,b) (((a)>(b))?(a):(b)) 57#define _RGBM_SINGLE_DYNAMIC(sym)
33 58#define _RGBM_MULTI_STATIC(sym) RGBLIGHT_MODE_##sym,
34#define LED_PTRTOIND(ptr) ((uint32_t) (ptr - led)/sizeof(LED_TYPE)) 59#define _RGBM_MULTI_DYNAMIC(sym)
35 60#define _RGBM_TMP_STATIC(sym, msym) RGBLIGHT_MODE_##sym,
36void copyrgb(LED_TYPE *src, LED_TYPE *dst); 61#define _RGBM_TMP_DYNAMIC(sym, msym)
62static uint8_t static_effect_table[] = {
63#include "rgblight_modes.h"
64};
65
66#define _RGBM_SINGLE_STATIC(sym) RGBLIGHT_MODE_##sym,
67#define _RGBM_SINGLE_DYNAMIC(sym) RGBLIGHT_MODE_##sym,
68#define _RGBM_MULTI_STATIC(sym) RGBLIGHT_MODE_##sym,
69#define _RGBM_MULTI_DYNAMIC(sym) RGBLIGHT_MODE_##sym,
70#define _RGBM_TMP_STATIC(sym, msym) RGBLIGHT_MODE_##msym,
71#define _RGBM_TMP_DYNAMIC(sym, msym) RGBLIGHT_MODE_##msym,
72static uint8_t mode_base_table[] = {
73 0, // RGBLIGHT_MODE_zero
74#include "rgblight_modes.h"
75};
76
77static inline int is_static_effect(uint8_t mode) { return memchr(static_effect_table, mode, sizeof(static_effect_table)) != NULL; }
78
79#ifdef RGBLIGHT_LED_MAP
80const uint8_t led_map[] PROGMEM = RGBLIGHT_LED_MAP;
81#endif
37 82
38__attribute__ ((weak)) 83#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
39const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5}; 84__attribute__((weak)) const uint8_t RGBLED_GRADIENT_RANGES[] PROGMEM = {255, 170, 127, 85, 64};
40__attribute__ ((weak)) 85#endif
41const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30};
42__attribute__ ((weak))
43const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20};
44__attribute__ ((weak))
45const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20};
46__attribute__ ((weak))
47const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {127, 63, 31};
48__attribute__ ((weak))
49const uint16_t RGBLED_GRADIENT_RANGES[] PROGMEM = {360, 240, 180, 120, 90};
50__attribute__ ((weak))
51const uint16_t RGBLED_RGBTEST_INTERVALS[] PROGMEM = {1024};
52 86
53rgblight_config_t rgblight_config; 87rgblight_config_t rgblight_config;
88rgblight_status_t rgblight_status = {.timer_enabled = false};
89bool is_rgblight_initialized = false;
90
91#ifdef RGBLIGHT_USE_TIMER
92animation_status_t animation_status = {};
93#endif
54 94
95#ifndef LED_ARRAY
55LED_TYPE led[RGBLED_NUM]; 96LED_TYPE led[RGBLED_NUM];
97# define LED_ARRAY led
98#endif
56 99
57bool rgblight_timer_enabled = false; 100static uint8_t clipping_start_pos = 0;
101static uint8_t clipping_num_leds = RGBLED_NUM;
102static uint8_t effect_start_pos = 0;
103static uint8_t effect_end_pos = RGBLED_NUM;
104static uint8_t effect_num_leds = RGBLED_NUM;
58 105
106// MxSS custom
59extern uint8_t fled_mode; 107extern uint8_t fled_mode;
60extern uint8_t fled_val; 108extern uint8_t fled_val;
61extern LED_TYPE fleds[2]; 109extern LED_TYPE fleds[2];
62hs_set fled_hs[2]; 110hs_set fled_hs[2];
63 111
64void sethsv(uint16_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1) { 112void copyrgb(LED_TYPE *src, LED_TYPE *dst) {
65 uint8_t r = 0, g = 0, b = 0, base, color; 113 (*dst).r = (*src).r;
66 114 (*dst).g = (*src).g;
67 // if led is front leds, cache the hue and sat values 115 (*dst).b = (*src).b;
68 if (led1 == &led[RGBLIGHT_FLED1]) { 116}
69 fled_hs[0].hue = hue;
70 fled_hs[0].sat = sat;
71 } else if (led1 == &led[RGBLIGHT_FLED2]) {
72 fled_hs[1].hue = hue;
73 fled_hs[1].sat = sat;
74 }
75 117
76 if (val > RGBLIGHT_LIMIT_VAL) { 118void rgblight_set_clipping_range(uint8_t start_pos, uint8_t num_leds) {
77 val=RGBLIGHT_LIMIT_VAL; // limit the val 119 clipping_start_pos = start_pos;
78 } 120 clipping_num_leds = num_leds;
121}
79 122
80 if (sat == 0) { // Acromatic color (gray). Hue doesn't mind. 123void rgblight_set_effect_range(uint8_t start_pos, uint8_t num_leds) {
81 r = val; 124 if (start_pos >= RGBLED_NUM) return;
82 g = val; 125 if (start_pos + num_leds > RGBLED_NUM) return;
83 b = val; 126 effect_start_pos = start_pos;
84 } else { 127 effect_end_pos = start_pos + num_leds;
85 base = ((255 - sat) * val) >> 8; 128 effect_num_leds = num_leds;
86 color = (val - base) * (hue % 60) / 60; 129}
87
88 switch (hue / 60) {
89 case 0:
90 r = val;
91 g = base + color;
92 b = base;
93 break;
94 case 1:
95 r = val - color;
96 g = val;
97 b = base;
98 break;
99 case 2:
100 r = base;
101 g = val;
102 b = base + color;
103 break;
104 case 3:
105 r = base;
106 g = val - color;
107 b = val;
108 break;
109 case 4:
110 r = base + color;
111 g = base;
112 b = val;
113 break;
114 case 5:
115 r = val;
116 g = base;
117 b = val - color;
118 break;
119 }
120 }
121 r = pgm_read_byte(&CIE1931_CURVE[r]);
122 g = pgm_read_byte(&CIE1931_CURVE[g]);
123 b = pgm_read_byte(&CIE1931_CURVE[b]);
124 130
125 setrgb(r, g, b, led1); 131void sethsv_raw(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1) {
132 HSV hsv = {hue, sat, val};
133 // MxSS custom
134 // if led is front leds, cache the hue and sat values
135 if (led1 == &led[RGBLIGHT_FLED1]) {
136 fled_hs[0].hue = hue;
137 fled_hs[0].sat = sat;
138 } else if (led1 == &led[RGBLIGHT_FLED2]) {
139 fled_hs[1].hue = hue;
140 fled_hs[1].sat = sat;
141 } RGB rgb = hsv_to_rgb(hsv);
142 setrgb(rgb.r, rgb.g, rgb.b, led1);
126} 143}
127 144
145void sethsv(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1) { sethsv_raw(hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val, led1); }
146
128void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1) { 147void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1) {
129 (*led1).r = r; 148 (*led1).r = r;
130 (*led1).g = g; 149 (*led1).g = g;
131 (*led1).b = b; 150 (*led1).b = b;
151#ifdef RGBW
152 (*led1).w = 0;
153#endif
132} 154}
133 155
134void copyrgb(LED_TYPE *src, LED_TYPE *dst) { 156void rgblight_check_config(void) {
135 (*dst).r = (*src).r; 157 /* Add some out of bound checks for RGB light config */
136 (*dst).g = (*src).g; 158
137 (*dst).b = (*src).b; 159 if (rgblight_config.mode < RGBLIGHT_MODE_STATIC_LIGHT) {
160 rgblight_config.mode = RGBLIGHT_MODE_STATIC_LIGHT;
161 } else if (rgblight_config.mode > RGBLIGHT_MODES) {
162 rgblight_config.mode = RGBLIGHT_MODES;
163 }
164
165 if (rgblight_config.val > RGBLIGHT_LIMIT_VAL) {
166 rgblight_config.val = RGBLIGHT_LIMIT_VAL;
167 }
138} 168}
139 169
140uint32_t eeconfig_read_rgblight(void) { 170uint32_t eeconfig_read_rgblight(void) {
141 return eeprom_read_dword(EECONFIG_RGBLIGHT); 171#if defined(__AVR__) || defined(STM32_EEPROM_ENABLE) || defined(PROTOCOL_ARM_ATSAM) || defined(EEPROM_SIZE)
172 return eeprom_read_dword(EECONFIG_RGBLIGHT);
173#else
174 return 0;
175#endif
142} 176}
177
143void eeconfig_update_rgblight(uint32_t val) { 178void eeconfig_update_rgblight(uint32_t val) {
144 eeprom_update_dword(EECONFIG_RGBLIGHT, val); 179#if defined(__AVR__) || defined(STM32_EEPROM_ENABLE) || defined(PROTOCOL_ARM_ATSAM) || defined(EEPROM_SIZE)
180 rgblight_check_config();
181 eeprom_update_dword(EECONFIG_RGBLIGHT, val);
182#endif
145} 183}
184
146void eeconfig_update_rgblight_default(void) { 185void eeconfig_update_rgblight_default(void) {
147 dprintf("eeconfig_update_rgblight_default\n"); 186 rgblight_config.enable = 1;
148 rgblight_config.enable = 1; 187 rgblight_config.mode = RGBLIGHT_MODE_STATIC_LIGHT;
149 rgblight_config.mode = 1; 188 rgblight_config.hue = 0;
150 rgblight_config.hue = 0; 189 rgblight_config.sat = UINT8_MAX;
151 rgblight_config.sat = 255; 190 rgblight_config.val = RGBLIGHT_LIMIT_VAL;
152 rgblight_config.val = RGBLIGHT_LIMIT_VAL; 191 rgblight_config.speed = 0;
153 rgblight_config.speed = 0; 192 RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS;
154 eeconfig_update_rgblight(rgblight_config.raw); 193 eeconfig_update_rgblight(rgblight_config.raw);
155} 194}
195
156void eeconfig_debug_rgblight(void) { 196void eeconfig_debug_rgblight(void) {
157 dprintf("rgblight_config eprom\n"); 197 dprintf("rgblight_config EEPROM:\n");
158 dprintf("rgblight_config.enable = %d\n", rgblight_config.enable); 198 dprintf("rgblight_config.enable = %d\n", rgblight_config.enable);
159 dprintf("rghlight_config.mode = %d\n", rgblight_config.mode); 199 dprintf("rghlight_config.mode = %d\n", rgblight_config.mode);
160 dprintf("rgblight_config.hue = %d\n", rgblight_config.hue); 200 dprintf("rgblight_config.hue = %d\n", rgblight_config.hue);
161 dprintf("rgblight_config.sat = %d\n", rgblight_config.sat); 201 dprintf("rgblight_config.sat = %d\n", rgblight_config.sat);
162 dprintf("rgblight_config.val = %d\n", rgblight_config.val); 202 dprintf("rgblight_config.val = %d\n", rgblight_config.val);
163 dprintf("rgblight_config.speed = %d\n", rgblight_config.speed); 203 dprintf("rgblight_config.speed = %d\n", rgblight_config.speed);
164} 204}
165 205
166void rgblight_init(void) { 206void rgblight_init(void) {
167 debug_enable = 1; // Debug ON! 207 /* if already initialized, don't do it again.
168 dprintf("rgblight_init called.\n"); 208 If you must do it again, extern this and set to false, first.
169 dprintf("rgblight_init start!\n"); 209 This is a dirty, dirty hack until proper hooks can be added for keyboard startup. */
170 if (!eeconfig_is_enabled()) { 210 if (is_rgblight_initialized) {
171 dprintf("rgblight_init eeconfig is not enabled.\n"); 211 return;
172 eeconfig_init(); 212 }
173 eeconfig_update_rgblight_default(); 213
174 } 214 dprintf("rgblight_init called.\n");
175 rgblight_config.raw = eeconfig_read_rgblight(); 215 dprintf("rgblight_init start!\n");
176 if (!rgblight_config.mode) { 216 if (!eeconfig_is_enabled()) {
177 dprintf("rgblight_init rgblight_config.mode = 0. Write default values to EEPROM.\n"); 217 dprintf("rgblight_init eeconfig is not enabled.\n");
178 eeconfig_update_rgblight_default(); 218 eeconfig_init();
219 eeconfig_update_rgblight_default();
220 }
179 rgblight_config.raw = eeconfig_read_rgblight(); 221 rgblight_config.raw = eeconfig_read_rgblight();
180 } 222 RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS;
181 eeconfig_debug_rgblight(); // display current eeprom values 223 if (!rgblight_config.mode) {
224 dprintf("rgblight_init rgblight_config.mode = 0. Write default values to EEPROM.\n");
225 eeconfig_update_rgblight_default();
226 rgblight_config.raw = eeconfig_read_rgblight();
227 }
228 rgblight_check_config();
182 229
183 #ifdef RGBLIGHT_ANIMATIONS 230 eeconfig_debug_rgblight(); // display current eeprom values
184 rgblight_timer_init(); // setup the timer
185 #endif
186 231
187 if (rgblight_config.enable) { 232#ifdef RGBLIGHT_USE_TIMER
188 rgblight_mode_noeeprom(rgblight_config.mode); 233 rgblight_timer_init(); // setup the timer
189 } 234#endif
235
236 if (rgblight_config.enable) {
237 rgblight_mode_noeeprom(rgblight_config.mode);
238 }
239
240 is_rgblight_initialized = true;
190} 241}
191 242
243uint32_t rgblight_read_dword(void) { return rgblight_config.raw; }
244
192void rgblight_update_dword(uint32_t dword) { 245void rgblight_update_dword(uint32_t dword) {
193 rgblight_config.raw = dword; 246 RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS;
194 eeconfig_update_rgblight(rgblight_config.raw); 247 rgblight_config.raw = dword;
195 if (rgblight_config.enable) 248 if (rgblight_config.enable)
196 rgblight_mode(rgblight_config.mode); 249 rgblight_mode_noeeprom(rgblight_config.mode);
197 else { 250 else {
198 #ifdef RGBLIGHT_ANIMATIONS 251#ifdef RGBLIGHT_USE_TIMER
199 rgblight_timer_disable(); 252 rgblight_timer_disable();
200 #endif 253#endif
201 rgblight_set(); 254 rgblight_set();
202 } 255 }
203} 256}
204 257
205void rgblight_increase(void) { 258void rgblight_increase(void) {
206 uint8_t mode = 0; 259 uint8_t mode = 0;
207 if (rgblight_config.mode < RGBLIGHT_MODES) { 260 if (rgblight_config.mode < RGBLIGHT_MODES) {
208 mode = rgblight_config.mode + 1; 261 mode = rgblight_config.mode + 1;
209 } 262 }
210 rgblight_mode(mode); 263 rgblight_mode(mode);
211} 264}
212void rgblight_decrease(void) { 265void rgblight_decrease(void) {
213 uint8_t mode = 0; 266 uint8_t mode = 0;
214 // Mode will never be < 1. If it ever is, eeprom needs to be initialized. 267 // Mode will never be < 1. If it ever is, eeprom needs to be initialized.
215 if (rgblight_config.mode > 1) { 268 if (rgblight_config.mode > RGBLIGHT_MODE_STATIC_LIGHT) {
216 mode = rgblight_config.mode - 1; 269 mode = rgblight_config.mode - 1;
217 } 270 }
218 rgblight_mode(mode); 271 rgblight_mode(mode);
219} 272}
220void rgblight_step(void) { 273void rgblight_step_helper(bool write_to_eeprom) {
221 uint8_t mode = 0; 274 uint8_t mode = 0;
222 mode = rgblight_config.mode + 1; 275 mode = rgblight_config.mode + 1;
223 if (mode > RGBLIGHT_MODES) { 276 if (mode > RGBLIGHT_MODES) {
224 mode = 1; 277 mode = 1;
225 } 278 }
226 rgblight_mode(mode); 279 rgblight_mode_eeprom_helper(mode, write_to_eeprom);
227} 280}
228void rgblight_step_reverse(void) { 281void rgblight_step_noeeprom(void) { rgblight_step_helper(false); }
229 uint8_t mode = 0; 282void rgblight_step(void) { rgblight_step_helper(true); }
230 mode = rgblight_config.mode - 1; 283void rgblight_step_reverse_helper(bool write_to_eeprom) {
231 if (mode < 1) { 284 uint8_t mode = 0;
232 mode = RGBLIGHT_MODES; 285 mode = rgblight_config.mode - 1;
233 } 286 if (mode < 1) {
234 rgblight_mode(mode); 287 mode = RGBLIGHT_MODES;
288 }
289 rgblight_mode_eeprom_helper(mode, write_to_eeprom);
235} 290}
291void rgblight_step_reverse_noeeprom(void) { rgblight_step_reverse_helper(false); }
292void rgblight_step_reverse(void) { rgblight_step_reverse_helper(true); }
236 293
237uint8_t rgblight_get_mode(void) { 294uint8_t rgblight_get_mode(void) {
238 if (!rgblight_config.enable) { 295 if (!rgblight_config.enable) {
239 return false; 296 return false;
240 } 297 }
241 298
242 return rgblight_config.mode; 299 return rgblight_config.mode;
243} 300}
244 301
245void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) { 302void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {
246 if (!rgblight_config.enable) { 303 if (!rgblight_config.enable) {
247 return; 304 return;
248 } 305 }
249 if (mode < 1) { 306 if (mode < RGBLIGHT_MODE_STATIC_LIGHT) {
250 rgblight_config.mode = 1; 307 rgblight_config.mode = RGBLIGHT_MODE_STATIC_LIGHT;
251 } else if (mode > RGBLIGHT_MODES) { 308 } else if (mode > RGBLIGHT_MODES) {
252 rgblight_config.mode = RGBLIGHT_MODES; 309 rgblight_config.mode = RGBLIGHT_MODES;
253 } else { 310 } else {
254 rgblight_config.mode = mode; 311 rgblight_config.mode = mode;
255 } 312 }
256 if (write_to_eeprom) { 313 RGBLIGHT_SPLIT_SET_CHANGE_MODE;
257 eeconfig_update_rgblight(rgblight_config.raw); 314 if (write_to_eeprom) {
258 xprintf("rgblight mode [EEPROM]: %u\n", rgblight_config.mode); 315 eeconfig_update_rgblight(rgblight_config.raw);
259 } else { 316 dprintf("rgblight mode [EEPROM]: %u\n", rgblight_config.mode);
260 xprintf("rgblight mode [NOEEPROM]: %u\n", rgblight_config.mode); 317 } else {
261 } 318 dprintf("rgblight mode [NOEEPROM]: %u\n", rgblight_config.mode);
262 if (rgblight_config.mode == 1) { 319 }
263 #ifdef RGBLIGHT_ANIMATIONS 320 if (is_static_effect(rgblight_config.mode)) {
264 rgblight_timer_disable(); 321#ifdef RGBLIGHT_USE_TIMER
265 #endif 322 rgblight_timer_disable();
266 } else if ((rgblight_config.mode >= 2 && rgblight_config.mode <= 24) || 323#endif
267 rgblight_config.mode == 35 ) { 324 } else {
268 // MODE 2-5, breathing 325#ifdef RGBLIGHT_USE_TIMER
269 // MODE 6-8, rainbow mood 326 rgblight_timer_enable();
270 // MODE 9-14, rainbow swirl 327#endif
271 // MODE 15-20, snake 328 }
272 // MODE 21-23, knight 329#ifdef RGBLIGHT_USE_TIMER
273 // MODE 24, xmas 330 animation_status.restart = true;
274 // MODE 35 RGB test 331#endif
275 332 rgblight_sethsv_noeeprom(rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
276 #ifdef RGBLIGHT_ANIMATIONS
277 rgblight_timer_enable();
278 #endif
279 } else if (rgblight_config.mode >= 25 && rgblight_config.mode <= 34) {
280 // MODE 25-34, static gradient
281
282 #ifdef RGBLIGHT_ANIMATIONS
283 rgblight_timer_disable();
284 #endif
285 }
286 rgblight_sethsv_noeeprom(rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
287}
288
289void rgblight_mode(uint8_t mode) {
290 rgblight_mode_eeprom_helper(mode, true);
291} 333}
292 334
293void rgblight_mode_noeeprom(uint8_t mode) { 335void rgblight_mode(uint8_t mode) { rgblight_mode_eeprom_helper(mode, true); }
294 rgblight_mode_eeprom_helper(mode, false);
295}
296 336
337void rgblight_mode_noeeprom(uint8_t mode) { rgblight_mode_eeprom_helper(mode, false); }
297 338
298void rgblight_toggle(void) { 339void rgblight_toggle(void) {
299 xprintf("rgblight toggle [EEPROM]: rgblight_config.enable = %u\n", !rgblight_config.enable); 340 dprintf("rgblight toggle [EEPROM]: rgblight_config.enable = %u\n", !rgblight_config.enable);
300 if (rgblight_config.enable) { 341 if (rgblight_config.enable) {
301 rgblight_disable(); 342 rgblight_disable();
302 } 343 } else {
303 else { 344 rgblight_enable();
304 rgblight_enable(); 345 }
305 }
306} 346}
307 347
308void rgblight_toggle_noeeprom(void) { 348void rgblight_toggle_noeeprom(void) {
309 xprintf("rgblight toggle [NOEEPROM]: rgblight_config.enable = %u\n", !rgblight_config.enable); 349 dprintf("rgblight toggle [NOEEPROM]: rgblight_config.enable = %u\n", !rgblight_config.enable);
310 if (rgblight_config.enable) { 350 if (rgblight_config.enable) {
311 rgblight_disable_noeeprom(); 351 rgblight_disable_noeeprom();
312 } 352 } else {
313 else { 353 rgblight_enable_noeeprom();
314 rgblight_enable_noeeprom(); 354 }
315 }
316} 355}
317 356
318void rgblight_enable(void) { 357void rgblight_enable(void) {
319 rgblight_config.enable = 1; 358 rgblight_config.enable = 1;
320 // No need to update EEPROM here. rgblight_mode() will do that, actually 359 // No need to update EEPROM here. rgblight_mode() will do that, actually
321 //eeconfig_update_rgblight(rgblight_config.raw); 360 // eeconfig_update_rgblight(rgblight_config.raw);
322 xprintf("rgblight enable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable); 361 dprintf("rgblight enable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable);
323 rgblight_mode(rgblight_config.mode); 362 rgblight_mode(rgblight_config.mode);
324} 363}
325 364
326void rgblight_enable_noeeprom(void) { 365void rgblight_enable_noeeprom(void) {
327 rgblight_config.enable = 1; 366 rgblight_config.enable = 1;
328 xprintf("rgblight enable [NOEEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable); 367 dprintf("rgblight enable [NOEEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable);
329 rgblight_mode_noeeprom(rgblight_config.mode); 368 rgblight_mode_noeeprom(rgblight_config.mode);
330} 369}
331 370
332void rgblight_disable(void) { 371void rgblight_disable(void) {
333 rgblight_config.enable = 0; 372 rgblight_config.enable = 0;
334 eeconfig_update_rgblight(rgblight_config.raw); 373 eeconfig_update_rgblight(rgblight_config.raw);
335 xprintf("rgblight disable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable); 374 dprintf("rgblight disable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable);
336 #ifdef RGBLIGHT_ANIMATIONS 375#ifdef RGBLIGHT_USE_TIMER
337 //rgblight_timer_disable(); 376 rgblight_timer_disable();
338 #endif 377#endif
339 _delay_ms(50); 378 RGBLIGHT_SPLIT_SET_CHANGE_MODE;
340 rgblight_set(); 379 wait_ms(50);
380 rgblight_set();
341} 381}
342 382
343void rgblight_disable_noeeprom(void) { 383void rgblight_disable_noeeprom(void) {
344 rgblight_config.enable = 0; 384 rgblight_config.enable = 0;
345 xprintf("rgblight disable [noEEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable); 385 dprintf("rgblight disable [NOEEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable);
346 #ifdef RGBLIGHT_ANIMATIONS 386#ifdef RGBLIGHT_USE_TIMER
347 rgblight_timer_disable(); 387 rgblight_timer_disable();
348 #endif 388#endif
349 _delay_ms(50); 389 RGBLIGHT_SPLIT_SET_CHANGE_MODE;
350 rgblight_set(); 390 wait_ms(50);
391 rgblight_set();
351} 392}
352 393
353 394void rgblight_increase_hue_helper(bool write_to_eeprom) {
354// Deals with the messy details of incrementing an integer 395 uint8_t hue = rgblight_config.hue + RGBLIGHT_HUE_STEP;
355uint8_t increment( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) { 396 rgblight_sethsv_eeprom_helper(hue, rgblight_config.sat, rgblight_config.val, write_to_eeprom);
356 int16_t new_value = value;
357 new_value += step;
358 return MIN( MAX( new_value, min ), max );
359} 397}
360 398void rgblight_increase_hue_noeeprom(void) { rgblight_increase_hue_helper(false); }
361uint8_t decrement( uint8_t value, uint8_t step, uint8_t min, uint8_t max ) { 399void rgblight_increase_hue(void) { rgblight_increase_hue_helper(true); }
362 int16_t new_value = value; 400void rgblight_decrease_hue_helper(bool write_to_eeprom) {
363 new_value -= step; 401 uint8_t hue = rgblight_config.hue - RGBLIGHT_HUE_STEP;
364 return MIN( MAX( new_value, min ), max ); 402 rgblight_sethsv_eeprom_helper(hue, rgblight_config.sat, rgblight_config.val, write_to_eeprom);
365} 403}
366 404void rgblight_decrease_hue_noeeprom(void) { rgblight_decrease_hue_helper(false); }
367void rgblight_increase_hue(void) { 405void rgblight_decrease_hue(void) { rgblight_decrease_hue_helper(true); }
368 uint16_t hue; 406void rgblight_increase_sat_helper(bool write_to_eeprom) {
369 hue = (rgblight_config.hue+RGBLIGHT_HUE_STEP) % 360; 407 uint8_t sat = qadd8(rgblight_config.sat, RGBLIGHT_SAT_STEP);
370 rgblight_sethsv(hue, rgblight_config.sat, rgblight_config.val); 408 rgblight_sethsv_eeprom_helper(rgblight_config.hue, sat, rgblight_config.val, write_to_eeprom);
371} 409}
372void rgblight_decrease_hue(void) { 410void rgblight_increase_sat_noeeprom(void) { rgblight_increase_sat_helper(false); }
373 uint16_t hue; 411void rgblight_increase_sat(void) { rgblight_increase_sat_helper(true); }
374 if (rgblight_config.hue-RGBLIGHT_HUE_STEP < 0) { 412void rgblight_decrease_sat_helper(bool write_to_eeprom) {
375 hue = (rgblight_config.hue + 360 - RGBLIGHT_HUE_STEP) % 360; 413 uint8_t sat = qsub8(rgblight_config.sat, RGBLIGHT_SAT_STEP);
376 } else { 414 rgblight_sethsv_eeprom_helper(rgblight_config.hue, sat, rgblight_config.val, write_to_eeprom);
377 hue = (rgblight_config.hue - RGBLIGHT_HUE_STEP) % 360; 415}
378 } 416void rgblight_decrease_sat_noeeprom(void) { rgblight_decrease_sat_helper(false); }
379 rgblight_sethsv(hue, rgblight_config.sat, rgblight_config.val); 417void rgblight_decrease_sat(void) { rgblight_decrease_sat_helper(true); }
380} 418void rgblight_increase_val_helper(bool write_to_eeprom) {
381void rgblight_increase_sat(void) { 419 uint8_t val = qadd8(rgblight_config.val, RGBLIGHT_VAL_STEP);
382 uint8_t sat; 420 rgblight_sethsv_eeprom_helper(rgblight_config.hue, rgblight_config.sat, val, write_to_eeprom);
383 if (rgblight_config.sat + RGBLIGHT_SAT_STEP > 255) { 421}
384 sat = 255; 422void rgblight_increase_val_noeeprom(void) { rgblight_increase_val_helper(false); }
385 } else { 423void rgblight_increase_val(void) { rgblight_increase_val_helper(true); }
386 sat = rgblight_config.sat + RGBLIGHT_SAT_STEP; 424void rgblight_decrease_val_helper(bool write_to_eeprom) {
387 } 425 uint8_t val = qsub8(rgblight_config.val, RGBLIGHT_VAL_STEP);
388 rgblight_sethsv(rgblight_config.hue, sat, rgblight_config.val); 426 rgblight_sethsv_eeprom_helper(rgblight_config.hue, rgblight_config.sat, val, write_to_eeprom);
389}
390void rgblight_decrease_sat(void) {
391 uint8_t sat;
392 if (rgblight_config.sat - RGBLIGHT_SAT_STEP < 0) {
393 sat = 0;
394 } else {
395 sat = rgblight_config.sat - RGBLIGHT_SAT_STEP;
396 }
397 rgblight_sethsv(rgblight_config.hue, sat, rgblight_config.val);
398}
399void rgblight_increase_val(void) {
400 uint8_t val;
401 if (rgblight_config.val + RGBLIGHT_VAL_STEP > RGBLIGHT_LIMIT_VAL) {
402 val = RGBLIGHT_LIMIT_VAL;
403 } else {
404 val = rgblight_config.val + RGBLIGHT_VAL_STEP;
405 }
406 rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, val);
407}
408void rgblight_decrease_val(void) {
409 uint8_t val;
410 if (rgblight_config.val - RGBLIGHT_VAL_STEP < 0) {
411 val = 0;
412 } else {
413 val = rgblight_config.val - RGBLIGHT_VAL_STEP;
414 }
415 rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, val);
416} 427}
428void rgblight_decrease_val_noeeprom(void) { rgblight_decrease_val_helper(false); }
429void rgblight_decrease_val(void) { rgblight_decrease_val_helper(true); }
417void rgblight_increase_speed(void) { 430void rgblight_increase_speed(void) {
418 rgblight_config.speed = increment( rgblight_config.speed, 1, 0, 3 ); 431 if (rgblight_config.speed < 3) rgblight_config.speed++;
419 eeconfig_update_rgblight(rgblight_config.raw);//EECONFIG needs to be increased to support this 432 // RGBLIGHT_SPLIT_SET_CHANGE_HSVS; // NEED?
433 eeconfig_update_rgblight(rgblight_config.raw); // EECONFIG needs to be increased to support this
420} 434}
421 435
422void rgblight_decrease_speed(void) { 436void rgblight_decrease_speed(void) {
423 rgblight_config.speed = decrement( rgblight_config.speed, 1, 0, 3 ); 437 if (rgblight_config.speed > 0) rgblight_config.speed--;
424 eeconfig_update_rgblight(rgblight_config.raw);//EECONFIG needs to be increased to support this 438 // RGBLIGHT_SPLIT_SET_CHANGE_HSVS; // NEED??
439 eeconfig_update_rgblight(rgblight_config.raw); // EECONFIG needs to be increased to support this
425} 440}
426 441
427void rgblight_sethsv_noeeprom_old(uint16_t hue, uint8_t sat, uint8_t val) { 442void rgblight_sethsv_noeeprom_old(uint8_t hue, uint8_t sat, uint8_t val) {
428 if (rgblight_config.enable) { 443 if (rgblight_config.enable) {
429 LED_TYPE tmp_led; 444 // MxSS custom code
430 sethsv(hue, sat, val, &tmp_led); 445 fled_hs[0].hue = fled_hs[1].hue = hue;
431 fled_hs[0].hue = fled_hs[1].hue = hue; 446 fled_hs[0].sat = fled_hs[1].sat = sat;
432 fled_hs[0].sat = fled_hs[1].sat = sat; 447
433 // dprintf("rgblight set hue [MEMORY]: %u,%u,%u\n", inmem_config.hue, inmem_config.sat, inmem_config.val); 448 LED_TYPE tmp_led;
434 rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b); 449 sethsv(hue, sat, val, &tmp_led);
435 } 450 rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b);
451 }
436} 452}
437 453
438void rgblight_sethsv_eeprom_helper(uint16_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom) { 454void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom) {
439 if (rgblight_config.enable) { 455 if (rgblight_config.enable) {
440 if (rgblight_config.mode == 1) { 456 rgblight_status.base_mode = mode_base_table[rgblight_config.mode];
441 // same static color 457 if (rgblight_config.mode == RGBLIGHT_MODE_STATIC_LIGHT) {
442 LED_TYPE tmp_led; 458 // same static color
443 sethsv(hue, sat, val, &tmp_led); 459 LED_TYPE tmp_led;
444 460 sethsv(hue, sat, val, &tmp_led);
445 fled_hs[0].hue = fled_hs[1].hue = hue; 461
446 fled_hs[0].sat = fled_hs[1].sat = sat; 462 // MxSS custom
447 463 // Cache hue/sat for rgb
448 rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b); 464 fled_hs[0].hue = fled_hs[1].hue = hue;
449 } else { 465 fled_hs[0].sat = fled_hs[1].sat = sat;
450 // all LEDs in same color 466
451 if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) { 467 rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b);
452 // breathing mode, ignore the change of val, use in memory value instead 468 } else {
453 val = rgblight_config.val; 469 // all LEDs in same color
454 } else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 14) { 470 if (1 == 0) { // dummy
455 // rainbow mood and rainbow swirl, ignore the change of hue 471 }
456 hue = rgblight_config.hue; 472#ifdef RGBLIGHT_EFFECT_BREATHING
457 } else if (rgblight_config.mode >= 25 && rgblight_config.mode <= 34) { 473 else if (rgblight_status.base_mode == RGBLIGHT_MODE_BREATHING) {
458 // static gradient 474 // breathing mode, ignore the change of val, use in memory value instead
459 uint16_t _hue; 475 val = rgblight_config.val;
460 int8_t direction = ((rgblight_config.mode - 25) % 2) ? -1 : 1; 476 }
461 uint16_t range = pgm_read_word(&RGBLED_GRADIENT_RANGES[(rgblight_config.mode - 25) / 2]); 477#endif
462 for (uint8_t i = 0; i < RGBLED_NUM; i++) { 478#ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
463 _hue = (range / RGBLED_NUM * i * direction + hue + 360) % 360; 479 else if (rgblight_status.base_mode == RGBLIGHT_MODE_RAINBOW_MOOD) {
464 dprintf("rgblight rainbow set hsv: %u,%u,%d,%u\n", i, _hue, direction, range); 480 // rainbow mood, ignore the change of hue
465 sethsv(_hue, sat, val, (LED_TYPE *)&led[i]); 481 hue = rgblight_config.hue;
482 }
483#endif
484#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
485 else if (rgblight_status.base_mode == RGBLIGHT_MODE_RAINBOW_SWIRL) {
486 // rainbow swirl, ignore the change of hue
487 hue = rgblight_config.hue;
488 }
489#endif
490#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
491 else if (rgblight_status.base_mode == RGBLIGHT_MODE_STATIC_GRADIENT) {
492 // static gradient
493 uint8_t delta = rgblight_config.mode - rgblight_status.base_mode;
494 bool direction = (delta % 2) == 0;
495# ifdef __AVR__
496 // probably due to how pgm_read_word is defined for ARM, but the ARM compiler really hates this line
497 uint8_t range = pgm_read_word(&RGBLED_GRADIENT_RANGES[delta / 2]);
498# else
499 uint8_t range = RGBLED_GRADIENT_RANGES[delta / 2];
500# endif
501 for (uint8_t i = 0; i < effect_num_leds; i++) {
502 uint8_t _hue = ((uint16_t)i * (uint16_t)range) / effect_num_leds;
503 if (direction) {
504 _hue = hue + _hue;
505 } else {
506 _hue = hue - _hue;
507 }
508 dprintf("rgblight rainbow set hsv: %d,%d,%d,%u\n", i, _hue, direction, range);
509 sethsv(_hue, sat, val, (LED_TYPE *)&led[i + effect_start_pos]);
510 }
511 rgblight_set();
512 }
513#endif
514 }
515#ifdef RGBLIGHT_SPLIT
516 if (rgblight_config.hue != hue || rgblight_config.sat != sat || rgblight_config.val != val) {
517 RGBLIGHT_SPLIT_SET_CHANGE_HSVS;
518 }
519#endif
520 rgblight_config.hue = hue;
521 rgblight_config.sat = sat;
522 rgblight_config.val = val;
523 if (write_to_eeprom) {
524 eeconfig_update_rgblight(rgblight_config.raw);
525 dprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
526 } else {
527 dprintf("rgblight set hsv [NOEEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
466 } 528 }
467 rgblight_set();
468 }
469 }
470 rgblight_config.hue = hue;
471 rgblight_config.sat = sat;
472 rgblight_config.val = val;
473 if (write_to_eeprom) {
474 eeconfig_update_rgblight(rgblight_config.raw);
475 xprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
476 } else {
477 xprintf("rgblight set hsv [NOEEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
478 } 529 }
479 }
480} 530}
481 531
482void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val) { 532void rgblight_sethsv(uint8_t hue, uint8_t sat, uint8_t val) { rgblight_sethsv_eeprom_helper(hue, sat, val, true); }
483 rgblight_sethsv_eeprom_helper(hue, sat, val, true);
484}
485 533
486void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val) { 534void rgblight_sethsv_noeeprom(uint8_t hue, uint8_t sat, uint8_t val) { rgblight_sethsv_eeprom_helper(hue, sat, val, false); }
487 rgblight_sethsv_eeprom_helper(hue, sat, val, false);
488}
489 535
490uint16_t rgblight_get_hue(void) { 536uint8_t rgblight_get_hue(void) { return rgblight_config.hue; }
491 return rgblight_config.hue; 537
538uint8_t rgblight_get_sat(void) { return rgblight_config.sat; }
539
540uint8_t rgblight_get_val(void) { return rgblight_config.val; }
541
542void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) {
543 if (!rgblight_config.enable) {
544 return;
545 }
546
547 for (uint8_t i = effect_start_pos; i < effect_end_pos; i++) {
548 led[i].r = r;
549 led[i].g = g;
550 led[i].b = b;
551#ifdef RGBW
552 led[i].w = 0;
553#endif
554 }
555 rgblight_set();
492} 556}
493 557
494uint8_t rgblight_get_sat(void) { 558void rgblight_setrgb_at(uint8_t r, uint8_t g, uint8_t b, uint8_t index) {
495 return rgblight_config.sat; 559 if (!rgblight_config.enable || index >= RGBLED_NUM) {
560 return;
561 }
562
563 led[index].r = r;
564 led[index].g = g;
565 led[index].b = b;
566#ifdef RGBW
567 led[index].w = 0;
568#endif
569 rgblight_set();
496} 570}
497 571
498uint8_t rgblight_get_val(void) { 572void rgblight_sethsv_at(uint8_t hue, uint8_t sat, uint8_t val, uint8_t index) {
499 return rgblight_config.val; 573 if (!rgblight_config.enable) {
574 return;
575 }
576
577 LED_TYPE tmp_led;
578 sethsv(hue, sat, val, &tmp_led);
579 rgblight_setrgb_at(tmp_led.r, tmp_led.g, tmp_led.b, index);
500} 580}
501 581
502void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) { 582#if defined(RGBLIGHT_EFFECT_BREATHING) || defined(RGBLIGHT_EFFECT_RAINBOW_MOOD) || defined(RGBLIGHT_EFFECT_RAINBOW_SWIRL) || defined(RGBLIGHT_EFFECT_SNAKE) || defined(RGBLIGHT_EFFECT_KNIGHT)
503 if (!rgblight_config.enable) { return; }
504 583
505 for (uint8_t i = 0; i < RGBLED_NUM; i++) { 584static uint8_t get_interval_time(const uint8_t *default_interval_address, uint8_t velocikey_min, uint8_t velocikey_max) {
506 led[i].r = r; 585 return
507 led[i].g = g; 586# ifdef VELOCIKEY_ENABLE
508 led[i].b = b; 587 velocikey_enabled() ? velocikey_match_speed(velocikey_min, velocikey_max) :
509 } 588# endif
510 rgblight_set(); 589 pgm_read_byte(default_interval_address);
511} 590}
512 591
513void rgblight_setrgb_at(uint8_t r, uint8_t g, uint8_t b, uint8_t index) { 592#endif
514 if (!rgblight_config.enable || index >= RGBLED_NUM) { return; } 593
594void rgblight_setrgb_range(uint8_t r, uint8_t g, uint8_t b, uint8_t start, uint8_t end) {
595 if (!rgblight_config.enable || start < 0 || start >= end || end > RGBLED_NUM) {
596 return;
597 }
515 598
516 led[index].r = r; 599 for (uint8_t i = start; i < end; i++) {
517 led[index].g = g; 600 led[i].r = r;
518 led[index].b = b; 601 led[i].g = g;
519 rgblight_set(); 602 led[i].b = b;
603#ifdef RGBW
604 led[i].w = 0;
605#endif
606 }
607 rgblight_set();
608 wait_ms(1);
520} 609}
521 610
522void rgblight_sethsv_at(uint16_t hue, uint8_t sat, uint8_t val, uint8_t index) { 611void rgblight_sethsv_range(uint8_t hue, uint8_t sat, uint8_t val, uint8_t start, uint8_t end) {
523 if (!rgblight_config.enable) { return; } 612 if (!rgblight_config.enable) {
613 return;
614 }
524 615
525 LED_TYPE tmp_led; 616 LED_TYPE tmp_led;
526 sethsv(hue, sat, val, &tmp_led); 617 sethsv(hue, sat, val, &tmp_led);
527 rgblight_setrgb_at(tmp_led.r, tmp_led.g, tmp_led.b, index); 618 rgblight_setrgb_range(tmp_led.r, tmp_led.g, tmp_led.b, start, end);
528} 619}
529 620
621#ifndef RGBLIGHT_SPLIT
622void rgblight_setrgb_master(uint8_t r, uint8_t g, uint8_t b) { rgblight_setrgb_range(r, g, b, 0, (uint8_t)RGBLED_NUM / 2); }
623
624void 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); }
625
626void rgblight_sethsv_master(uint8_t hue, uint8_t sat, uint8_t val) { rgblight_sethsv_range(hue, sat, val, 0, (uint8_t)RGBLED_NUM / 2); }
627
628void rgblight_sethsv_slave(uint8_t hue, uint8_t sat, uint8_t val) { rgblight_sethsv_range(hue, sat, val, (uint8_t)RGBLED_NUM / 2, (uint8_t)RGBLED_NUM); }
629#endif // ifndef RGBLIGHT_SPLIT
630
631#ifndef RGBLIGHT_CUSTOM_DRIVER
530void rgblight_set(void) { 632void rgblight_set(void) {
531 if (!rgblight_config.enable) { 633 LED_TYPE *start_led;
634 uint16_t num_leds = clipping_num_leds;
635
636 if (!rgblight_config.enable) {
637 for (uint8_t i = effect_start_pos; i < effect_end_pos; i++) {
638 if (i == RGBLIGHT_FLED1 && i == RGBLIGHT_FLED2)
639 continue;
640
641 led[i].r = 0;
642 led[i].g = 0;
643 led[i].b = 0;
644# ifdef RGBW
645 led[i].w = 0;
646# endif
647 }
648 }
649
650# ifdef RGBLIGHT_LED_MAP
651 LED_TYPE led0[RGBLED_NUM];
532 for (uint8_t i = 0; i < RGBLED_NUM; i++) { 652 for (uint8_t i = 0; i < RGBLED_NUM; i++) {
533 if (i == RGBLIGHT_FLED1 && i == RGBLIGHT_FLED2) 653 led0[i] = led[pgm_read_byte(&led_map[i])];
534 continue;
535
536 led[i].r = 0;
537 led[i].g = 0;
538 led[i].b = 0;
539 } 654 }
540 } 655 start_led = led0 + clipping_start_pos;
541 656# else
542 switch (fled_mode) { 657 start_led = led + clipping_start_pos;
658# endif
659
660#ifdef RGBW
661 for (uint8_t i = 0; i < num_leds; i++) {
662 convert_rgb_to_rgbw(&start_led[i]);
663 }
664#endif
665 // MxSS custom
666 switch (fled_mode) {
543 case FLED_OFF: 667 case FLED_OFF:
544 setrgb(0, 0, 0, &led[RGBLIGHT_FLED1]); 668 setrgb(0, 0, 0, &led[RGBLIGHT_FLED1]);
545 setrgb(0, 0, 0, &led[RGBLIGHT_FLED2]); 669 setrgb(0, 0, 0, &led[RGBLIGHT_FLED2]);
546 break; 670 break;
547 671
548 case FLED_INDI: 672 case FLED_INDI:
549 copyrgb(&fleds[0], &led[RGBLIGHT_FLED1]); 673 copyrgb(&fleds[0], &led[RGBLIGHT_FLED1]);
550 copyrgb(&fleds[1], &led[RGBLIGHT_FLED2]); 674 copyrgb(&fleds[1], &led[RGBLIGHT_FLED2]);
551 break; 675 break;
552 676
553 case FLED_RGB: 677 case FLED_RGB:
554 if (fled_hs[0].hue == 0 && fled_hs[0].hue == 0 && (rgblight_config.mode >= 15 && rgblight_config.mode <= 23)) 678 if (fled_hs[0].hue == 0 && fled_hs[0].hue == 0 &&
555 setrgb(0, 0, 0, &led[RGBLIGHT_FLED1]); 679 (rgblight_status.base_mode == RGBLIGHT_MODE_SNAKE ||
556 else 680 rgblight_status.base_mode == RGBLIGHT_MODE_KNIGHT))
557 sethsv(fled_hs[0].hue, fled_hs[0].sat, fled_val, &led[RGBLIGHT_FLED1]); 681 setrgb(0, 0, 0, &led[RGBLIGHT_FLED1]);
558 682 else
559 if (fled_hs[1].hue == 0 && fled_hs[1].hue == 0 && (rgblight_config.mode >= 15 && rgblight_config.mode <= 23)) 683 sethsv(fled_hs[0].hue, fled_hs[0].sat, fled_val, &led[RGBLIGHT_FLED1]);
560 setrgb(0, 0, 0, &led[RGBLIGHT_FLED2]); 684
561 else 685 if (fled_hs[1].hue == 0 && fled_hs[1].hue == 0 &&
562 sethsv(fled_hs[1].hue, fled_hs[1].sat, fled_val, &led[RGBLIGHT_FLED2]); 686 (rgblight_status.base_mode == RGBLIGHT_MODE_SNAKE ||
687 rgblight_status.base_mode == RGBLIGHT_MODE_KNIGHT))
688 setrgb(0, 0, 0, &led[RGBLIGHT_FLED2]);
689 else
690 sethsv(fled_hs[1].hue, fled_hs[1].sat, fled_val, &led[RGBLIGHT_FLED2]);
563 break; 691 break;
564 692
565 default: 693 default:
566 break; 694 break;
567 } 695 }
568 696
569 ws2812_setleds(led, RGBLED_NUM); 697 ws2812_setleds(start_led, num_leds);
698}
699#endif
700
701#ifdef RGBLIGHT_SPLIT
702/* for split keyboard master side */
703uint8_t rgblight_get_change_flags(void) { return rgblight_status.change_flags; }
704
705void rgblight_clear_change_flags(void) { rgblight_status.change_flags = 0; }
706
707void rgblight_get_syncinfo(rgblight_syncinfo_t *syncinfo) {
708 syncinfo->config = rgblight_config;
709 syncinfo->status = rgblight_status;
710}
711
712/* for split keyboard slave side */
713void rgblight_update_sync(rgblight_syncinfo_t *syncinfo, bool write_to_eeprom) {
714 if (syncinfo->status.change_flags & RGBLIGHT_STATUS_CHANGE_MODE) {
715 if (syncinfo->config.enable) {
716 rgblight_config.enable = 1; // == rgblight_enable_noeeprom();
717 rgblight_mode_eeprom_helper(syncinfo->config.mode, write_to_eeprom);
718 } else {
719 rgblight_disable_noeeprom();
720 }
721 }
722 if (syncinfo->status.change_flags & RGBLIGHT_STATUS_CHANGE_HSVS) {
723 rgblight_sethsv_eeprom_helper(syncinfo->config.hue, syncinfo->config.sat, syncinfo->config.val, write_to_eeprom);
724 // rgblight_config.speed = config->speed; // NEED???
725 }
726# ifdef RGBLIGHT_USE_TIMER
727 if (syncinfo->status.change_flags & RGBLIGHT_STATUS_CHANGE_TIMER) {
728 if (syncinfo->status.timer_enabled) {
729 rgblight_timer_enable();
730 } else {
731 rgblight_timer_disable();
732 }
733 }
734# ifndef RGBLIGHT_SPLIT_NO_ANIMATION_SYNC
735 if (syncinfo->status.change_flags & RGBLIGHT_STATUS_ANIMATION_TICK) {
736 animation_status.restart = true;
737 }
738# endif /* RGBLIGHT_SPLIT_NO_ANIMATION_SYNC */
739# endif /* RGBLIGHT_USE_TIMER */
570} 740}
741#endif /* RGBLIGHT_SPLIT */
571 742
572#ifdef RGBLIGHT_ANIMATIONS 743#ifdef RGBLIGHT_USE_TIMER
573 744
574// Animation timer -- AVR Timer3 745typedef void (*effect_func_t)(animation_status_t *anim);
746
747// Animation timer -- use system timer (AVR Timer0)
575void rgblight_timer_init(void) { 748void rgblight_timer_init(void) {
576 // static uint8_t rgblight_timer_is_init = 0; 749 // OLD!!!! Animation timer -- AVR Timer3
577 // if (rgblight_timer_is_init) { 750 // static uint8_t rgblight_timer_is_init = 0;
578 // return; 751 // if (rgblight_timer_is_init) {
579 // } 752 // return;
580 // rgblight_timer_is_init = 1; 753 // }
581 // /* Timer 3 setup */ 754 // rgblight_timer_is_init = 1;
582 // TCCR3B = _BV(WGM32) // CTC mode OCR3A as TOP 755 // /* Timer 3 setup */
583 // | _BV(CS30); // Clock selelct: clk/1 756 // TCCR3B = _BV(WGM32) // CTC mode OCR3A as TOP
584 // /* Set TOP value */ 757 // | _BV(CS30); // Clock selelct: clk/1
585 // uint8_t sreg = SREG; 758 // /* Set TOP value */
586 // cli(); 759 // uint8_t sreg = SREG;
587 // OCR3AH = (RGBLED_TIMER_TOP >> 8) & 0xff; 760 // cli();
588 // OCR3AL = RGBLED_TIMER_TOP & 0xff; 761 // OCR3AH = (RGBLED_TIMER_TOP >> 8) & 0xff;
589 // SREG = sreg; 762 // OCR3AL = RGBLED_TIMER_TOP & 0xff;
590 763 // SREG = sreg;
591 rgblight_timer_enabled = true; 764
765 rgblight_status.timer_enabled = false;
766 RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE;
592} 767}
593void rgblight_timer_enable(void) { 768void rgblight_timer_enable(void) {
594 rgblight_timer_enabled = true; 769 if (!is_static_effect(rgblight_config.mode)) {
595 dprintf("TIMER3 enabled.\n"); 770 rgblight_status.timer_enabled = true;
771 }
772 animation_status.last_timer = timer_read();
773 RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE;
774 dprintf("rgblight timer enabled.\n");
596} 775}
597void rgblight_timer_disable(void) { 776void rgblight_timer_disable(void) {
598 rgblight_timer_enabled = false; 777 // MxSS custom code
599 dprintf("TIMER3 disabled.\n"); 778 if (fled_mode != FLED_RGB) {
779 rgblight_status.timer_enabled = false;
780 RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE;
781 dprintf("rgblight timer disable.\n");
782 }
600} 783}
601void rgblight_timer_toggle(void) { 784void rgblight_timer_toggle(void) {
602 rgblight_timer_enabled ^= rgblight_timer_enabled; 785 dprintf("rgblight timer toggle.\n");
603 dprintf("TIMER3 toggled.\n"); 786 if (rgblight_status.timer_enabled) {
787 rgblight_timer_disable();
788 } else {
789 rgblight_timer_enable();
790 }
604} 791}
605 792
606void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b) { 793void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b) {
607 rgblight_enable(); 794 rgblight_enable();
608 rgblight_mode(1); 795 rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT);
609 rgblight_setrgb(r, g, b); 796 rgblight_setrgb(r, g, b);
797}
798
799static void rgblight_effect_dummy(animation_status_t *anim) {
800 // do nothing
801 /********
802 dprintf("rgblight_task() what happened?\n");
803 dprintf("is_static_effect %d\n", is_static_effect(rgblight_config.mode));
804 dprintf("mode = %d, base_mode = %d, timer_enabled %d, ",
805 rgblight_config.mode, rgblight_status.base_mode,
806 rgblight_status.timer_enabled);
807 dprintf("last_timer = %d\n",anim->last_timer);
808 **/
610} 809}
611 810
612void rgblight_task(void) { 811void rgblight_task(void) {
613 if (rgblight_timer_enabled) { 812 if (rgblight_status.timer_enabled) {
614 // mode = 1, static light, do nothing here 813 effect_func_t effect_func = rgblight_effect_dummy;
615 if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) { 814 uint16_t interval_time = 2000; // dummy interval
616 // mode = 2 to 5, breathing mode 815 uint8_t delta = rgblight_config.mode - rgblight_status.base_mode;
617 rgblight_effect_breathing(rgblight_config.mode - 2); 816 animation_status.delta = delta;
618 } else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 8) { 817
619 // mode = 6 to 8, rainbow mood mod 818 // static light mode, do nothing here
620 rgblight_effect_rainbow_mood(rgblight_config.mode - 6); 819 if (1 == 0) { // dummy
621 } else if (rgblight_config.mode >= 9 && rgblight_config.mode <= 14) { 820 }
622 // mode = 9 to 14, rainbow swirl mode 821# ifdef RGBLIGHT_EFFECT_BREATHING
623 rgblight_effect_rainbow_swirl(rgblight_config.mode - 9); 822 else if (rgblight_status.base_mode == RGBLIGHT_MODE_BREATHING) {
624 } else if (rgblight_config.mode >= 15 && rgblight_config.mode <= 20) { 823 // breathing mode
625 // mode = 15 to 20, snake mode 824 interval_time = get_interval_time(&RGBLED_BREATHING_INTERVALS[delta], 1, 100);
626 rgblight_effect_snake(rgblight_config.mode - 15); 825 effect_func = rgblight_effect_breathing;
627 } else if (rgblight_config.mode >= 21 && rgblight_config.mode <= 23) { 826 }
628 // mode = 21 to 23, knight mode 827# endif
629 rgblight_effect_knight(rgblight_config.mode - 21); 828# ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
630 } else if (rgblight_config.mode == 24) { 829 else if (rgblight_status.base_mode == RGBLIGHT_MODE_RAINBOW_MOOD) {
631 // mode = 24, christmas mode 830 // rainbow mood mode
632 rgblight_effect_christmas(); 831 interval_time = get_interval_time(&RGBLED_RAINBOW_MOOD_INTERVALS[delta], 5, 100);
633 } else if (rgblight_config.mode == 35) { 832 effect_func = rgblight_effect_rainbow_mood;
634 // mode = 35, RGB test 833 }
635 rgblight_effect_rgbtest(); 834# endif
835# ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
836 else if (rgblight_status.base_mode == RGBLIGHT_MODE_RAINBOW_SWIRL) {
837 // rainbow swirl mode
838 interval_time = get_interval_time(&RGBLED_RAINBOW_SWIRL_INTERVALS[delta / 2], 1, 100);
839 effect_func = rgblight_effect_rainbow_swirl;
840 }
841# endif
842# ifdef RGBLIGHT_EFFECT_SNAKE
843 else if (rgblight_status.base_mode == RGBLIGHT_MODE_SNAKE) {
844 // snake mode
845 interval_time = get_interval_time(&RGBLED_SNAKE_INTERVALS[delta / 2], 1, 200);
846 effect_func = rgblight_effect_snake;
847 }
848# endif
849# ifdef RGBLIGHT_EFFECT_KNIGHT
850 else if (rgblight_status.base_mode == RGBLIGHT_MODE_KNIGHT) {
851 // knight mode
852 interval_time = get_interval_time(&RGBLED_KNIGHT_INTERVALS[delta], 5, 100);
853 effect_func = rgblight_effect_knight;
854 }
855# endif
856# ifdef RGBLIGHT_EFFECT_CHRISTMAS
857 else if (rgblight_status.base_mode == RGBLIGHT_MODE_CHRISTMAS) {
858 // christmas mode
859 interval_time = RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL;
860 effect_func = (effect_func_t)rgblight_effect_christmas;
861 }
862# endif
863# ifdef RGBLIGHT_EFFECT_RGB_TEST
864 else if (rgblight_status.base_mode == RGBLIGHT_MODE_RGB_TEST) {
865 // RGB test mode
866 interval_time = pgm_read_word(&RGBLED_RGBTEST_INTERVALS[0]);
867 effect_func = (effect_func_t)rgblight_effect_rgbtest;
868 }
869# endif
870# ifdef RGBLIGHT_EFFECT_ALTERNATING
871 else if (rgblight_status.base_mode == RGBLIGHT_MODE_ALTERNATING) {
872 interval_time = 500;
873 effect_func = (effect_func_t)rgblight_effect_alternating;
874 }
875# endif
876 if (animation_status.restart) {
877 animation_status.restart = false;
878 animation_status.last_timer = timer_read() - interval_time - 1;
879 animation_status.pos16 = 0; // restart signal to local each effect
880 }
881 if (timer_elapsed(animation_status.last_timer) >= interval_time) {
882# if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
883 static uint16_t report_last_timer = 0;
884 static bool tick_flag = false;
885 uint16_t oldpos16;
886 if (tick_flag) {
887 tick_flag = false;
888 if (timer_elapsed(report_last_timer) >= 30000) {
889 report_last_timer = timer_read();
890 dprintf("rgblight animation tick report to slave\n");
891 RGBLIGHT_SPLIT_ANIMATION_TICK;
892 }
893 }
894 oldpos16 = animation_status.pos16;
895# endif
896 animation_status.last_timer += interval_time;
897 effect_func(&animation_status);
898# if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
899 if (animation_status.pos16 == 0 && oldpos16 != 0) {
900 tick_flag = true;
901 }
902# endif
903 }
636 } 904 }
637 }
638} 905}
639 906
640// Effects 907#endif /* RGBLIGHT_USE_TIMER */
641void rgblight_effect_breathing(uint8_t interval) {
642 static uint8_t pos = 0;
643 static uint16_t last_timer = 0;
644 float val;
645 908
646 if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_BREATHING_INTERVALS[interval])) { 909// Effects
647 return; 910#ifdef RGBLIGHT_EFFECT_BREATHING
648 } 911
649 last_timer = timer_read(); 912# ifndef RGBLIGHT_EFFECT_BREATHE_CENTER
913# ifndef RGBLIGHT_BREATHE_TABLE_SIZE
914# define RGBLIGHT_BREATHE_TABLE_SIZE 256 // 256 or 128 or 64
915# endif
916# include <rgblight_breathe_table.h>
917# endif
918
919__attribute__((weak)) const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5};
920
921void rgblight_effect_breathing(animation_status_t *anim) {
922 float val;
923
924 // http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/
925# ifdef RGBLIGHT_EFFECT_BREATHE_TABLE
926 val = pgm_read_byte(&rgblight_effect_breathe_table[anim->pos / table_scale]);
927# else
928 val = (exp(sin((anim->pos / 255.0) * M_PI)) - RGBLIGHT_EFFECT_BREATHE_CENTER / M_E) * (RGBLIGHT_EFFECT_BREATHE_MAX / (M_E - 1 / M_E));
929# endif
930 rgblight_sethsv_noeeprom_old(rgblight_config.hue, rgblight_config.sat, val);
931 anim->pos = (anim->pos + 1);
932}
933#endif
650 934
935#ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
936__attribute__((weak)) const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30};
651 937
652 // http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/ 938void rgblight_effect_rainbow_mood(animation_status_t *anim) {
653 val = (exp(sin((pos/255.0)*M_PI)) - RGBLIGHT_EFFECT_BREATHE_CENTER/M_E)*(RGBLIGHT_EFFECT_BREATHE_MAX/(M_E-1/M_E)); 939 rgblight_sethsv_noeeprom_old(anim->current_hue, rgblight_config.sat, rgblight_config.val);
654 rgblight_sethsv_noeeprom_old(rgblight_config.hue, rgblight_config.sat, val); 940 anim->current_hue++;
655 pos = (pos + 1) % 256;
656} 941}
657void rgblight_effect_rainbow_mood(uint8_t interval) { 942#endif
658 static uint16_t current_hue = 0;
659 static uint16_t last_timer = 0;
660 943
661 if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_RAINBOW_MOOD_INTERVALS[interval])) { 944#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
662 return; 945# ifndef RGBLIGHT_RAINBOW_SWIRL_RANGE
663 } 946# define RGBLIGHT_RAINBOW_SWIRL_RANGE 255
664 last_timer = timer_read(); 947# endif
665 rgblight_sethsv_noeeprom_old(current_hue, rgblight_config.sat, rgblight_config.val); 948
666 current_hue = (current_hue + 1) % 360; 949__attribute__((weak)) const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20};
667} 950
668void rgblight_effect_rainbow_swirl(uint8_t interval) { 951void rgblight_effect_rainbow_swirl(animation_status_t *anim) {
669 static uint16_t current_hue = 0; 952 uint8_t hue;
670 static uint16_t last_timer = 0; 953 uint8_t i;
671 uint16_t hue; 954
672 uint8_t i; 955 for (i = 0; i < effect_num_leds; i++) {
673 if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_RAINBOW_SWIRL_INTERVALS[interval / 2])) { 956 hue = (RGBLIGHT_RAINBOW_SWIRL_RANGE / effect_num_leds * i + anim->current_hue);
674 return; 957 sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i + effect_start_pos]);
675 } 958 }
676 last_timer = timer_read(); 959 rgblight_set();
677 for (i = 0; i < RGBLED_NUM; i++) {
678 hue = (360 / RGBLED_NUM * i + current_hue) % 360;
679 sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
680 }
681 rgblight_set();
682 960
683 if (interval % 2) { 961 if (anim->delta % 2) {
684 current_hue = (current_hue + 1) % 360; 962 anim->current_hue++;
685 } else {
686 if (current_hue - 1 < 0) {
687 current_hue = 359;
688 } else { 963 } else {
689 current_hue = current_hue - 1; 964 anim->current_hue--;
690 } 965 }
691 }
692} 966}
693void rgblight_effect_snake(uint8_t interval) { 967#endif
694 static uint8_t pos = 0; 968
695 static uint16_t last_timer = 0; 969#ifdef RGBLIGHT_EFFECT_SNAKE
696 uint8_t i, j; 970__attribute__((weak)) const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20};
697 int8_t k; 971
698 int8_t increment = 1; 972void rgblight_effect_snake(animation_status_t *anim) {
699 if (interval % 2) { 973 static uint8_t pos = 0;
700 increment = -1; 974 uint8_t i, j;
701 } 975 int8_t k;
702 if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_SNAKE_INTERVALS[interval / 2])) { 976 int8_t increment = 1;
703 return; 977
704 } 978 if (anim->delta % 2) {
705 last_timer = timer_read(); 979 increment = -1;
706
707 fled_hs[0].hue = fled_hs[1].hue = 0;
708 fled_hs[0].sat = fled_hs[1].sat = 0;
709
710 for (i = 0; i < RGBLED_NUM; i++) {
711 led[i].r = 0;
712 led[i].g = 0;
713 led[i].b = 0;
714
715 for (j = 0; j < RGBLIGHT_EFFECT_SNAKE_LENGTH; j++) {
716 k = pos + j * increment;
717 if (k < 0) {
718 k = k + RGBLED_NUM;
719 }
720 if (i == k) {
721 sethsv(rgblight_config.hue, rgblight_config.sat, (uint8_t)(rgblight_config.val*(RGBLIGHT_EFFECT_SNAKE_LENGTH-j)/RGBLIGHT_EFFECT_SNAKE_LENGTH), (LED_TYPE *)&led[i]);
722 }
723 } 980 }
724 } 981
725 rgblight_set(); 982# if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
726 if (increment == 1) { 983 if (anim->pos == 0) { // restart signal
727 if (pos - 1 < 0) { 984 if (increment == 1) {
728 pos = RGBLED_NUM - 1; 985 pos = effect_num_leds - 1;
986 } else {
987 pos = 0;
988 }
989 anim->pos = 1;
990 }
991# endif
992
993 // MxSS custom
994 fled_hs[0].hue = fled_hs[1].hue = 0;
995 fled_hs[0].sat = fled_hs[1].sat = 0;
996
997 for (i = 0; i < effect_num_leds; i++) {
998 LED_TYPE *ledp = led + i + effect_start_pos;
999 ledp->r = 0;
1000 ledp->g = 0;
1001 ledp->b = 0;
1002# ifdef RGBW
1003 ledp->w = 0;
1004# endif
1005 for (j = 0; j < RGBLIGHT_EFFECT_SNAKE_LENGTH; j++) {
1006 k = pos + j * increment;
1007 if (k > RGBLED_NUM) {
1008 k = k % RGBLED_NUM;
1009 }
1010 if (k < 0) {
1011 k = k + effect_num_leds;
1012 }
1013 if (i == k) {
1014 sethsv(rgblight_config.hue, rgblight_config.sat, (uint8_t)(rgblight_config.val * (RGBLIGHT_EFFECT_SNAKE_LENGTH - j) / RGBLIGHT_EFFECT_SNAKE_LENGTH), ledp);
1015 }
1016 }
1017 }
1018 rgblight_set();
1019 if (increment == 1) {
1020 if (pos - 1 < 0) {
1021 pos = effect_num_leds - 1;
1022# if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
1023 anim->pos = 0;
1024# endif
1025 } else {
1026 pos -= 1;
1027# if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
1028 anim->pos = 1;
1029# endif
1030 }
729 } else { 1031 } else {
730 pos -= 1; 1032 pos = (pos + 1) % effect_num_leds;
1033# if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
1034 anim->pos = pos;
1035# endif
731 } 1036 }
732 } else {
733 pos = (pos + 1) % RGBLED_NUM;
734 }
735} 1037}
736void rgblight_effect_knight(uint8_t interval) { 1038#endif
737 static uint16_t last_timer = 0;
738 if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_KNIGHT_INTERVALS[interval])) {
739 return;
740 }
741 last_timer = timer_read();
742
743 static int8_t low_bound = 0;
744 static int8_t high_bound = RGBLIGHT_EFFECT_KNIGHT_LENGTH - 1;
745 static int8_t increment = 1;
746 uint8_t i, cur;
747
748 // Set all the LEDs to 0
749 for (i = 0; i < RGBLED_NUM; i++) {
750 led[i].r = 0;
751 led[i].g = 0;
752 led[i].b = 0;
753 }
754 // Determine which LEDs should be lit up
755 for (i = 0; i < RGBLIGHT_EFFECT_KNIGHT_LED_NUM; i++) {
756 cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % RGBLED_NUM;
757 1039
758 if (i >= low_bound && i <= high_bound) { 1040#ifdef RGBLIGHT_EFFECT_KNIGHT
759 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[cur]); 1041__attribute__((weak)) const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {127, 63, 31};
760 } else { 1042
761 if (i == RGBLIGHT_FLED1 || i == RGBLIGHT_FLED2) { 1043void rgblight_effect_knight(animation_status_t *anim) {
762 fled_hs[0].hue = fled_hs[1].hue = 0; 1044 static int8_t low_bound = 0;
763 fled_hs[0].sat = fled_hs[1].sat = 0; 1045 static int8_t high_bound = RGBLIGHT_EFFECT_KNIGHT_LENGTH - 1;
764 } 1046 static int8_t increment = 1;
765 1047 uint8_t i, cur;
766 led[cur].r = 0; 1048
767 led[cur].g = 0; 1049# if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
768 led[cur].b = 0; 1050 if (anim->pos == 0) { // restart signal
1051 anim->pos = 1;
1052 low_bound = 0;
1053 high_bound = RGBLIGHT_EFFECT_KNIGHT_LENGTH - 1;
1054 increment = 1;
1055 }
1056# endif
1057 // Set all the LEDs to 0
1058 for (i = effect_start_pos; i < effect_end_pos; i++) {
1059 led[i].r = 0;
1060 led[i].g = 0;
1061 led[i].b = 0;
1062# ifdef RGBW
1063 led[i].w = 0;
1064# endif
1065 }
1066 // Determine which LEDs should be lit up
1067 for (i = 0; i < RGBLIGHT_EFFECT_KNIGHT_LED_NUM; i++) {
1068 cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % effect_num_leds + effect_start_pos;
1069
1070 if (i >= low_bound && i <= high_bound) {
1071 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[cur]);
1072 } else {
1073 // MxSS custom code
1074 if (cur == RGBLIGHT_FLED1) {
1075 fled_hs[0].hue = fled_hs[0].sat = 0;
1076 } else if (cur == RGBLIGHT_FLED2) {
1077 fled_hs[1].hue = fled_hs[1].sat = 0;
1078 }
1079
1080 led[cur].r = 0;
1081 led[cur].g = 0;
1082 led[cur].b = 0;
1083# ifdef RGBW
1084 led[cur].w = 0;
1085# endif
1086 }
1087 }
1088 rgblight_set();
1089
1090 // Move from low_bound to high_bound changing the direction we increment each
1091 // time a boundary is hit.
1092 low_bound += increment;
1093 high_bound += increment;
1094
1095 if (high_bound <= 0 || low_bound >= RGBLIGHT_EFFECT_KNIGHT_LED_NUM - 1) {
1096 increment = -increment;
1097# if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
1098 if (increment == 1) {
1099 anim->pos = 0;
1100 }
1101# endif
769 } 1102 }
770 }
771 rgblight_set();
772
773 // Move from low_bound to high_bound changing the direction we increment each
774 // time a boundary is hit.
775 low_bound += increment;
776 high_bound += increment;
777
778 if (high_bound <= 0 || low_bound >= RGBLIGHT_EFFECT_KNIGHT_LED_NUM - 1) {
779 increment = -increment;
780 }
781} 1103}
1104#endif
782 1105
1106#ifdef RGBLIGHT_EFFECT_CHRISTMAS
1107void rgblight_effect_christmas(animation_status_t *anim) {
1108 uint8_t hue;
1109 uint8_t i;
783 1110
784void rgblight_effect_christmas(void) { 1111 anim->current_offset = (anim->current_offset + 1) % 2;
785 static uint16_t current_offset = 0; 1112 for (i = 0; i < effect_num_leds; i++) {
786 static uint16_t last_timer = 0; 1113 hue = 0 + ((i / RGBLIGHT_EFFECT_CHRISTMAS_STEP + anim->current_offset) % 2) * 85;
787 uint16_t hue; 1114 sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i + effect_start_pos]);
788 uint8_t i; 1115 }
789 if (timer_elapsed(last_timer) < RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL) { 1116 rgblight_set();
790 return;
791 }
792 last_timer = timer_read();
793 current_offset = (current_offset + 1) % 2;
794 for (i = 0; i < RGBLED_NUM; i++) {
795 hue = 0 + ((i/RGBLIGHT_EFFECT_CHRISTMAS_STEP + current_offset) % 2) * 120;
796 sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
797 }
798 rgblight_set();
799} 1117}
1118#endif
800 1119
801void rgblight_effect_rgbtest(void) { 1120#ifdef RGBLIGHT_EFFECT_RGB_TEST
802 static uint8_t pos = 0; 1121__attribute__((weak)) const uint16_t RGBLED_RGBTEST_INTERVALS[] PROGMEM = {1024};
803 static uint16_t last_timer = 0;
804 static uint8_t maxval = 0;
805 uint8_t g; uint8_t r; uint8_t b;
806 1122
807 if (timer_elapsed(last_timer) < pgm_read_word(&RGBLED_RGBTEST_INTERVALS[0])) { 1123void rgblight_effect_rgbtest(animation_status_t *anim) {
808 return; 1124 static uint8_t maxval = 0;
809 } 1125 uint8_t g;
1126 uint8_t r;
1127 uint8_t b;
810 1128
811 if( maxval == 0 ) { 1129 if (maxval == 0) {
812 LED_TYPE tmp_led; 1130 LED_TYPE tmp_led;
813 sethsv(0, 255, RGBLIGHT_LIMIT_VAL, &tmp_led); 1131 sethsv(0, 255, RGBLIGHT_LIMIT_VAL, &tmp_led);
814 maxval = tmp_led.r; 1132 maxval = tmp_led.r;
815 } 1133 }
816 last_timer = timer_read(); 1134 g = r = b = 0;
817 g = r = b = 0; 1135 switch (anim->pos) {
818 switch( pos ) { 1136 // MxSS custom code
819 case 0: r = maxval; break; 1137 case 0:
820 case 1: g = maxval; break; 1138 r = maxval;
821 case 2: b = maxval; break; 1139 fled_hs[0].hue = 0;
822 } 1140 fled_hs[0].sat = 255;
823 rgblight_setrgb(r, g, b); 1141 fled_hs[1].hue = 0;
824 pos = (pos + 1) % 3; 1142 fled_hs[1].sat = 255;
1143 break;
1144 case 1:
1145 g = maxval;
1146 fled_hs[0].hue = 85;
1147 fled_hs[0].sat = 255;
1148 fled_hs[1].hue = 85;
1149 fled_hs[1].sat = 255;
1150 break;
1151 case 2:
1152 b = maxval;
1153 fled_hs[0].hue = 170;
1154 fled_hs[0].sat = 255;
1155 fled_hs[1].hue = 170;
1156 fled_hs[1].sat = 255;
1157 break;
1158 }
1159 rgblight_setrgb(r, g, b);
1160 anim->pos = (anim->pos + 1) % 3;
825} 1161}
1162#endif
826 1163
827#endif /* RGBLIGHT_ANIMATIONS */ 1164#ifdef RGBLIGHT_EFFECT_ALTERNATING
1165void rgblight_effect_alternating(animation_status_t *anim) {
1166 for (int i = 0; i < effect_num_leds; i++) {
1167 LED_TYPE *ledp = led + i + effect_start_pos;
1168 if (i < effect_num_leds / 2 && anim->pos) {
1169 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, ledp);
1170 } else if (i >= effect_num_leds / 2 && !anim->pos) {
1171 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, ledp);
1172 } else {
1173 sethsv(rgblight_config.hue, rgblight_config.sat, 0, ledp);
1174 }
1175 }
1176 rgblight_set();
1177 anim->pos = (anim->pos + 1) % 2;
1178}
1179#endif
diff --git a/keyboards/mxss/rgblight.h b/keyboards/mxss/rgblight.h
index 0013a3438..e3aa098e4 100644
--- a/keyboards/mxss/rgblight.h
+++ b/keyboards/mxss/rgblight.h
@@ -16,137 +16,245 @@
16#ifndef RGBLIGHT_H 16#ifndef RGBLIGHT_H
17#define RGBLIGHT_H 17#define RGBLIGHT_H
18 18
19#ifdef RGBLIGHT_ANIMATIONS 19#include "rgblight_reconfig.h"
20 #define RGBLIGHT_MODES 35 20
21#else 21/***** rgblight_mode(mode)/rgblight_mode_noeeprom(mode) ****
22 #define RGBLIGHT_MODES 1 22
23#endif 23 old mode number (before 0.6.117) to new mode name table
24 24
25#ifndef RGBLIGHT_EFFECT_BREATHE_CENTER 25|-----------------|-----------------------------------|
26#define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 // 1-2.7 26| old mode number | new mode name |
27#endif 27|-----------------|-----------------------------------|
28 28| 1 | RGBLIGHT_MODE_STATIC_LIGHT |
29#ifndef RGBLIGHT_EFFECT_BREATHE_MAX 29| 2 | RGBLIGHT_MODE_BREATHING |
30#define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0-255 30| 3 | RGBLIGHT_MODE_BREATHING + 1 |
31#endif 31| 4 | RGBLIGHT_MODE_BREATHING + 2 |
32 32| 5 | RGBLIGHT_MODE_BREATHING + 3 |
33#ifndef RGBLIGHT_EFFECT_SNAKE_LENGTH 33| 6 | RGBLIGHT_MODE_RAINBOW_MOOD |
34#define RGBLIGHT_EFFECT_SNAKE_LENGTH 4 34| 7 | RGBLIGHT_MODE_RAINBOW_MOOD + 1 |
35#endif 35| 8 | RGBLIGHT_MODE_RAINBOW_MOOD + 2 |
36 36| 9 | RGBLIGHT_MODE_RAINBOW_SWIRL |
37#ifndef RGBLIGHT_EFFECT_KNIGHT_LENGTH 37| 10 | RGBLIGHT_MODE_RAINBOW_SWIRL + 1 |
38#define RGBLIGHT_EFFECT_KNIGHT_LENGTH 3 38| 11 | RGBLIGHT_MODE_RAINBOW_SWIRL + 2 |
39#endif 39| 12 | RGBLIGHT_MODE_RAINBOW_SWIRL + 3 |
40 40| 13 | RGBLIGHT_MODE_RAINBOW_SWIRL + 4 |
41#ifndef RGBLIGHT_EFFECT_KNIGHT_OFFSET 41| 14 | RGBLIGHT_MODE_RAINBOW_SWIRL + 5 |
42#define RGBLIGHT_EFFECT_KNIGHT_OFFSET 0 42| 15 | RGBLIGHT_MODE_SNAKE |
43#endif 43| 16 | RGBLIGHT_MODE_SNAKE + 1 |
44 44| 17 | RGBLIGHT_MODE_SNAKE + 2 |
45#ifndef RGBLIGHT_EFFECT_KNIGHT_LED_NUM 45| 18 | RGBLIGHT_MODE_SNAKE + 3 |
46#define RGBLIGHT_EFFECT_KNIGHT_LED_NUM RGBLED_NUM 46| 19 | RGBLIGHT_MODE_SNAKE + 4 |
47#endif 47| 20 | RGBLIGHT_MODE_SNAKE + 5 |
48 48| 21 | RGBLIGHT_MODE_KNIGHT |
49#ifndef RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL 49| 22 | RGBLIGHT_MODE_KNIGHT + 1 |
50#define RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL 1000 50| 23 | RGBLIGHT_MODE_KNIGHT + 2 |
51#endif 51| 24 | RGBLIGHT_MODE_CHRISTMAS |
52 52| 25 | RGBLIGHT_MODE_STATIC_GRADIENT |
53#ifndef RGBLIGHT_EFFECT_CHRISTMAS_STEP 53| 26 | RGBLIGHT_MODE_STATIC_GRADIENT + 1 |
54#define RGBLIGHT_EFFECT_CHRISTMAS_STEP 2 54| 27 | RGBLIGHT_MODE_STATIC_GRADIENT + 2 |
55#endif 55| 28 | RGBLIGHT_MODE_STATIC_GRADIENT + 3 |
56 56| 29 | RGBLIGHT_MODE_STATIC_GRADIENT + 4 |
57#ifndef RGBLIGHT_HUE_STEP 57| 30 | RGBLIGHT_MODE_STATIC_GRADIENT + 5 |
58#define RGBLIGHT_HUE_STEP 10 58| 31 | RGBLIGHT_MODE_STATIC_GRADIENT + 6 |
59#endif 59| 32 | RGBLIGHT_MODE_STATIC_GRADIENT + 7 |
60#ifndef RGBLIGHT_SAT_STEP 60| 33 | RGBLIGHT_MODE_STATIC_GRADIENT + 8 |
61#define RGBLIGHT_SAT_STEP 17 61| 34 | RGBLIGHT_MODE_STATIC_GRADIENT + 9 |
62#endif 62| 35 | RGBLIGHT_MODE_RGB_TEST |
63#ifndef RGBLIGHT_VAL_STEP 63| 36 | RGBLIGHT_MODE_ALTERNATING |
64#define RGBLIGHT_VAL_STEP 17 64|-----------------|-----------------------------------|
65#endif 65 *****/
66 66
67#define RGBLED_TIMER_TOP F_CPU/(256*64) 67#define _RGBM_SINGLE_STATIC(sym) RGBLIGHT_MODE_##sym,
68#define _RGBM_SINGLE_DYNAMIC(sym) RGBLIGHT_MODE_##sym,
69#define _RGBM_MULTI_STATIC(sym) RGBLIGHT_MODE_##sym,
70#define _RGBM_MULTI_DYNAMIC(sym) RGBLIGHT_MODE_##sym,
71#define _RGBM_TMP_STATIC(sym, msym) RGBLIGHT_MODE_##sym,
72#define _RGBM_TMP_DYNAMIC(sym, msym) RGBLIGHT_MODE_##sym,
73enum RGBLIGHT_EFFECT_MODE {
74 RGBLIGHT_MODE_zero = 0,
75#include "rgblight_modes.h"
76 RGBLIGHT_MODE_last
77};
78
79#ifndef RGBLIGHT_H_DUMMY_DEFINE
80
81# define RGBLIGHT_MODES (RGBLIGHT_MODE_last - 1)
82
83// sample: #define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85
84
85# ifndef RGBLIGHT_EFFECT_BREATHE_MAX
86# define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0-255
87# endif
88
89# ifndef RGBLIGHT_EFFECT_SNAKE_LENGTH
90# define RGBLIGHT_EFFECT_SNAKE_LENGTH 4
91# endif
92
93# ifndef RGBLIGHT_EFFECT_KNIGHT_LENGTH
94# define RGBLIGHT_EFFECT_KNIGHT_LENGTH 3
95# endif
96
97# ifndef RGBLIGHT_EFFECT_KNIGHT_OFFSET
98# define RGBLIGHT_EFFECT_KNIGHT_OFFSET 0
99# endif
100
101# ifndef RGBLIGHT_EFFECT_KNIGHT_LED_NUM
102# define RGBLIGHT_EFFECT_KNIGHT_LED_NUM (effect_num_leds)
103# endif
104
105# ifndef RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL
106# define RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL 1000
107# endif
108
109# ifndef RGBLIGHT_EFFECT_CHRISTMAS_STEP
110# define RGBLIGHT_EFFECT_CHRISTMAS_STEP 2
111# endif
112
113# ifndef RGBLIGHT_HUE_STEP
114# define RGBLIGHT_HUE_STEP 8
115# endif
116# ifndef RGBLIGHT_SAT_STEP
117# define RGBLIGHT_SAT_STEP 17
118# endif
119# ifndef RGBLIGHT_VAL_STEP
120# define RGBLIGHT_VAL_STEP 17
121# endif
122# ifndef RGBLIGHT_LIMIT_VAL
123# define RGBLIGHT_LIMIT_VAL 255
124# endif
125
126# define RGBLED_TIMER_TOP F_CPU / (256 * 64)
68// #define RGBLED_TIMER_TOP 0xFF10 127// #define RGBLED_TIMER_TOP 0xFF10
69 128
70#include <stdint.h> 129# include <stdint.h>
71#include <stdbool.h> 130# include <stdbool.h>
72#include "eeconfig.h" 131# include "eeconfig.h"
73#ifndef RGBLIGHT_CUSTOM_DRIVER 132# ifndef RGBLIGHT_CUSTOM_DRIVER
74#include "ws2812.h" 133# include "ws2812.h"
75#endif 134# endif
76#include "color.h" 135# include "color.h"
77#include "rgblight_list.h" 136# include "rgblight_list.h"
137
138# if defined(__AVR__)
139# include <avr/pgmspace.h>
140# endif
78 141
79extern LED_TYPE led[RGBLED_NUM]; 142extern LED_TYPE led[RGBLED_NUM];
80 143
81extern const uint8_t RGBLED_BREATHING_INTERVALS[4] PROGMEM; 144extern const uint8_t RGBLED_BREATHING_INTERVALS[4] PROGMEM;
82extern const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[3] PROGMEM; 145extern const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[3] PROGMEM;
83extern const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[3] PROGMEM; 146extern const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[3] PROGMEM;
84extern const uint8_t RGBLED_SNAKE_INTERVALS[3] PROGMEM; 147extern const uint8_t RGBLED_SNAKE_INTERVALS[3] PROGMEM;
85extern const uint8_t RGBLED_KNIGHT_INTERVALS[3] PROGMEM; 148extern const uint8_t RGBLED_KNIGHT_INTERVALS[3] PROGMEM;
86extern const uint16_t RGBLED_RGBTEST_INTERVALS[1] PROGMEM; 149extern const uint16_t RGBLED_RGBTEST_INTERVALS[1] PROGMEM;
150extern bool is_rgblight_initialized;
87 151
152// Should stay in sycn with rgb matrix config as we reuse eeprom storage for both (for now)
88typedef union { 153typedef union {
89 uint32_t raw; 154 uint32_t raw;
90 struct { 155 struct {
91 bool enable :1; 156 bool enable : 1;
92 uint8_t mode :6; 157 uint8_t mode : 7;
93 uint16_t hue :9; 158 uint8_t hue : 8;
94 uint8_t sat :8; 159 uint8_t sat : 8;
95 uint8_t val :8; 160 uint8_t val : 8;
96 uint8_t speed :8;//EECONFIG needs to be increased to support this 161 uint8_t speed : 8; // EECONFIG needs to be increased to support this
97 }; 162 };
98} rgblight_config_t; 163} rgblight_config_t;
99 164
100void rgblight_init(void); 165typedef struct _rgblight_status_t {
166 uint8_t base_mode;
167 bool timer_enabled;
168# ifdef RGBLIGHT_SPLIT
169 uint8_t change_flags;
170# endif
171} rgblight_status_t;
172
173/* === Utility Functions ===*/
174void sethsv(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1);
175void sethsv_raw(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1); // without RGBLIGHT_LIMIT_VAL check
176void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1);
177
178/* === Low level Functions === */
179void rgblight_set(void);
180void rgblight_set_clipping_range(uint8_t start_pos, uint8_t num_leds);
181
182/* === Effects and Animations Functions === */
183/* effect range setting */
184void rgblight_set_effect_range(uint8_t start_pos, uint8_t num_leds);
185
186/* direct operation */
187void rgblight_setrgb_at(uint8_t r, uint8_t g, uint8_t b, uint8_t index);
188void rgblight_sethsv_at(uint8_t hue, uint8_t sat, uint8_t val, uint8_t index);
189void rgblight_setrgb_range(uint8_t r, uint8_t g, uint8_t b, uint8_t start, uint8_t end);
190void rgblight_sethsv_range(uint8_t hue, uint8_t sat, uint8_t val, uint8_t start, uint8_t end);
191void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b);
192
193# ifndef RGBLIGHT_SPLIT
194void rgblight_setrgb_master(uint8_t r, uint8_t g, uint8_t b);
195void rgblight_setrgb_slave(uint8_t r, uint8_t g, uint8_t b);
196void rgblight_sethsv_master(uint8_t hue, uint8_t sat, uint8_t val);
197void rgblight_sethsv_slave(uint8_t hue, uint8_t sat, uint8_t val);
198# endif
199
200/* effect mode change */
201void rgblight_mode(uint8_t mode);
202void rgblight_mode_noeeprom(uint8_t mode);
101void rgblight_increase(void); 203void rgblight_increase(void);
102void rgblight_decrease(void); 204void rgblight_decrease(void);
205void rgblight_step(void);
206void rgblight_step_noeeprom(void);
207void rgblight_step_reverse(void);
208void rgblight_step_reverse_noeeprom(void);
209
210/* effects mode disable/enable */
103void rgblight_toggle(void); 211void rgblight_toggle(void);
212void rgblight_toggle_noeeprom(void);
104void rgblight_enable(void); 213void rgblight_enable(void);
214void rgblight_enable_noeeprom(void);
105void rgblight_disable(void); 215void rgblight_disable(void);
106void rgblight_step(void); 216void rgblight_disable_noeeprom(void);
107void rgblight_step_reverse(void); 217
108uint8_t rgblight_get_mode(void); 218/* hue, sat, val change */
109void rgblight_mode(uint8_t mode);
110void rgblight_set(void);
111void rgblight_update_dword(uint32_t dword);
112void rgblight_increase_hue(void); 219void rgblight_increase_hue(void);
220void rgblight_increase_hue_noeeprom(void);
113void rgblight_decrease_hue(void); 221void rgblight_decrease_hue(void);
222void rgblight_decrease_hue_noeeprom(void);
114void rgblight_increase_sat(void); 223void rgblight_increase_sat(void);
224void rgblight_increase_sat_noeeprom(void);
115void rgblight_decrease_sat(void); 225void rgblight_decrease_sat(void);
226void rgblight_decrease_sat_noeeprom(void);
116void rgblight_increase_val(void); 227void rgblight_increase_val(void);
228void rgblight_increase_val_noeeprom(void);
117void rgblight_decrease_val(void); 229void rgblight_decrease_val(void);
230void rgblight_decrease_val_noeeprom(void);
118void rgblight_increase_speed(void); 231void rgblight_increase_speed(void);
119void rgblight_decrease_speed(void); 232void rgblight_decrease_speed(void);
120void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val); 233void rgblight_sethsv(uint8_t hue, uint8_t sat, uint8_t val);
121uint16_t rgblight_get_hue(void); 234void rgblight_sethsv_noeeprom(uint8_t hue, uint8_t sat, uint8_t val);
235
236/* query */
237uint8_t rgblight_get_mode(void);
238uint8_t rgblight_get_hue(void);
122uint8_t rgblight_get_sat(void); 239uint8_t rgblight_get_sat(void);
123uint8_t rgblight_get_val(void); 240uint8_t rgblight_get_val(void);
124void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b);
125void rgblight_setrgb_at(uint8_t r, uint8_t g, uint8_t b, uint8_t index);
126void rgblight_sethsv_at(uint16_t hue, uint8_t sat, uint8_t val, uint8_t index);
127 241
242/* === qmk_firmware (core)internal Functions === */
243void rgblight_init(void);
244uint32_t rgblight_read_dword(void);
245void rgblight_update_dword(uint32_t dword);
128uint32_t eeconfig_read_rgblight(void); 246uint32_t eeconfig_read_rgblight(void);
129void eeconfig_update_rgblight(uint32_t val); 247void eeconfig_update_rgblight(uint32_t val);
130void eeconfig_update_rgblight_default(void); 248void eeconfig_update_rgblight_default(void);
131void eeconfig_debug_rgblight(void); 249void eeconfig_debug_rgblight(void);
132 250
133void rgb_matrix_increase(void); 251void rgb_matrix_increase(void);
134void rgb_matrix_decrease(void); 252void rgb_matrix_decrease(void);
135 253
136void sethsv(uint16_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1); 254void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom);
137void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1);
138
139void rgblight_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val);
140void rgblight_mode_noeeprom(uint8_t mode);
141void rgblight_toggle_noeeprom(void);
142void rgblight_enable_noeeprom(void);
143void rgblight_disable_noeeprom(void);
144
145void rgblight_sethsv_eeprom_helper(uint16_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom);
146void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom); 255void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom);
147 256
148 257# define EZ_RGB(val) rgblight_show_solid_color((val >> 16) & 0xFF, (val >> 8) & 0xFF, val & 0xFF)
149#define EZ_RGB(val) rgblight_show_solid_color((val >> 16) & 0xFF, (val >> 8) & 0xFF, val & 0xFF)
150void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b); 258void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b);
151 259
152void rgblight_task(void); 260void rgblight_task(void);
@@ -155,12 +263,52 @@ void rgblight_timer_init(void);
155void rgblight_timer_enable(void); 263void rgblight_timer_enable(void);
156void rgblight_timer_disable(void); 264void rgblight_timer_disable(void);
157void rgblight_timer_toggle(void); 265void rgblight_timer_toggle(void);
158void rgblight_effect_breathing(uint8_t interval); 266
159void rgblight_effect_rainbow_mood(uint8_t interval); 267# ifdef RGBLIGHT_SPLIT
160void rgblight_effect_rainbow_swirl(uint8_t interval); 268# define RGBLIGHT_STATUS_CHANGE_MODE (1 << 0)
161void rgblight_effect_snake(uint8_t interval); 269# define RGBLIGHT_STATUS_CHANGE_HSVS (1 << 1)
162void rgblight_effect_knight(uint8_t interval); 270# define RGBLIGHT_STATUS_CHANGE_TIMER (1 << 2)
163void rgblight_effect_christmas(void); 271# define RGBLIGHT_STATUS_ANIMATION_TICK (1 << 3)
164void rgblight_effect_rgbtest(void); 272
165 273typedef struct _rgblight_syncinfo_t {
166#endif 274 rgblight_config_t config;
275 rgblight_status_t status;
276} rgblight_syncinfo_t;
277
278/* for split keyboard master side */
279uint8_t rgblight_get_change_flags(void);
280void rgblight_clear_change_flags(void);
281void rgblight_get_syncinfo(rgblight_syncinfo_t *syncinfo);
282/* for split keyboard slave side */
283void rgblight_update_sync(rgblight_syncinfo_t *syncinfo, bool write_to_eeprom);
284# endif
285
286# ifdef RGBLIGHT_USE_TIMER
287
288typedef struct _animation_status_t {
289 uint16_t last_timer;
290 uint8_t delta; /* mode - base_mode */
291 bool restart;
292 union {
293 uint16_t pos16;
294 uint8_t pos;
295 int8_t current_hue;
296 uint16_t current_offset;
297 };
298} animation_status_t;
299
300extern animation_status_t animation_status;
301
302void rgblight_effect_breathing(animation_status_t *anim);
303void rgblight_effect_rainbow_mood(animation_status_t *anim);
304void rgblight_effect_rainbow_swirl(animation_status_t *anim);
305void rgblight_effect_snake(animation_status_t *anim);
306void rgblight_effect_knight(animation_status_t *anim);
307void rgblight_effect_christmas(animation_status_t *anim);
308void rgblight_effect_rgbtest(animation_status_t *anim);
309void rgblight_effect_alternating(animation_status_t *anim);
310
311# endif
312
313#endif // #ifndef RGBLIGHT_H_DUMMY_DEFINE
314#endif // RGBLIGHT_H
diff --git a/keyboards/mxss/rules.mk b/keyboards/mxss/rules.mk
index f9210319e..a1ca27ca4 100644
--- a/keyboards/mxss/rules.mk
+++ b/keyboards/mxss/rules.mk
@@ -14,7 +14,7 @@ BOOTLOADER = atmel-dfu
14# Build Options 14# Build Options
15# change yes to no to disable 15# change yes to no to disable
16# 16#
17BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000) 17BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration(+1000)
18MOUSEKEY_ENABLE = yes # Mouse keys(+4700) 18MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
19EXTRAKEY_ENABLE = yes # Audio control and System control(+450) 19EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
20CONSOLE_ENABLE = no # Console for debug(+400) 20CONSOLE_ENABLE = no # Console for debug(+400)
@@ -30,10 +30,12 @@ BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
30AUDIO_ENABLE = no # Audio output on port C6 30AUDIO_ENABLE = no # Audio output on port C6
31FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches 31FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches
32 32
33SRC += mxss_frontled.c
34
33# Remove the common RGB light code and use my iteration instead 35# Remove the common RGB light code and use my iteration instead
34OPT_DEFS += -DRGBLIGHT_ENABLE 36OPT_DEFS += -DRGBLIGHT_ENABLE
35SRC += $(QUANTUM_DIR)/process_keycode/process_rgb.c 37SRC += $(QUANTUM_DIR)/process_keycode/process_rgb.c
36SRC += rgblight.c 38SRC += rgblight.c
39SRC += color.c
37SRC += ws2812.c 40SRC += ws2812.c
38CIE1931_CURVE = yes 41CIE1931_CURVE = yes
39LED_BREATHING_TABLE = yes
diff --git a/keyboards/mxss/templates/keymap.c b/keyboards/mxss/templates/keymap.c
index 13dbb7206..a18cff77f 100644
--- a/keyboards/mxss/templates/keymap.c
+++ b/keyboards/mxss/templates/keymap.c
@@ -14,23 +14,24 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16#include QMK_KEYBOARD_H 16#include QMK_KEYBOARD_H
17#include "mxss_frontled.h"
18 17
19// Predefined colors for layers 18hs_set caps_color = { .hue = 0, .sat = 255 };
19
20// Colors for layers
20// Format: {hue, saturation} 21// Format: {hue, saturation}
21// {0, 0} to turn off the LED 22// {0, 0} to turn off the LED
22// Add additional rows to handle more layers 23// Add additional rows to handle more layers
23hs_set layer_colors[] = { 24hs_set layer_colors[4] = {
24 [0] = {0, 0}, // Color for Layer 0 25 [0] = {.hue = 0, .sat = 0}, // Color for Layer 0
25 [1] = {86, 255}, // Color for Layer 1 26 [1] = {.hue = 86, .sat = 255}, // Color for Layer 1
26 [2] = {36, 255}, // Color for Layer 2 27 [2] = {.hue = 36, .sat = 255}, // Color for Layer 2
27 [3] = {185, 255}, // Color for Layer 3 28 [3] = {.hue = 185, .sat = 255}, // Color for Layer 3
28}; 29};
29const size_t lc_size = sizeof(layer_colors) / sizeof(uint16_t); 30size_t lc_size = sizeof(layer_colors) / sizeof(uint16_t);
30 31
31// Use NEW_SAFE_RANGE to define new custom keycodes in order to not overwrite the ones used for front LED control 32// Use NEW_SAFE_RANGE to define new custom keycodes in order to not overwrite the ones used for front LED control
32enum custom_keycodes { 33enum custom_keycodes {
33 MY_KEYCODE = NEW_SAFE_RANGE, 34 MY_KEYCODE = NEW_SAFE_RANGE,
34}; 35};
35 36
36 37