1 /* Copyright 2018 Jumail Mundekkat / MxBlue
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.
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.
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/>.
17 #include QMK_KEYBOARD_H
18 #include "tmk_core/common/eeprom.h"
19 #include "tmk_core/common/action_layer.h"
22 // Variables for controlling front LED application
23 uint8_t fled_mode; // Mode for front LEDs
24 uint8_t fled_val; // Brightness for front leds (0 - 255)
25 LED_TYPE fleds[2]; // Front LED rgb values for indicator mode use
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))
32 const 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
39 __attribute__ ((weak))
40 const size_t lc_size = sizeof(layer_colors) / sizeof(uint16_t);
42 void matrix_init_kb(void) {
43 // If EEPROM config exists, load it
44 if (eeprom_is_valid()) {
45 fled_config fled_conf;
46 fled_conf.raw = eeprom_read_byte(EEPROM_FRONTLED_ADDR);
47 fled_mode = fled_conf.mode;
48 fled_val = fled_conf.val * FLED_VAL_STEP;
49 // Else, default config
52 fled_val = 10 * FLED_VAL_STEP;
53 eeprom_update_conf(); // Store default config to EEPROM
56 // Set default values for leds
57 setrgb(0, 0, 0, &fleds[0]);
58 setrgb(0, 0, 0, &fleds[1]);
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]);
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]);
76 void matrix_scan_kb(void) {
77 // put your looping keyboard code here
78 // runs every cycle (a lot)
83 bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
84 // Handle custom keycodes for front LED operation
86 case FLED_MOD: // Change between front LED operation modes (off, indicator, RGB)
87 if (record->event.pressed)
91 case FLED_VAI: // Increase the brightness of the front LEDs by FLED_VAL_STEP
92 if (record->event.pressed)
96 case FLED_VAD: // Decrease the brightness of the front LEDs by FLED_VAL_STEP
97 if (record->event.pressed)
102 break; // Process all other keycodes normally
105 return process_record_user(keycode, record);
108 void led_set_kb(uint8_t usb_led) {
109 // Set indicator LED appropriately, whether it is used or not
110 if (usb_led & (1 << USB_LED_CAPS_LOCK)) {
111 sethsv(FLED_CAPS_H, FLED_CAPS_S, fled_val, &fleds[0]);
113 setrgb(0, 0, 0, &fleds[0]);
116 led_set_user(usb_led);
119 uint32_t layer_state_set_kb(uint32_t state) {
120 // Determine and set colour of layer LED according to current layer
121 // if hue = sat = 0, leave LED off
122 uint8_t layer = biton32(state);
124 if (layer < lc_size && !(layer_colors[layer].hue == 0 && layer_colors[layer].hue == 0))
125 sethsv(layer_colors[layer].hue, layer_colors[layer].sat, fled_val, &fleds[1]);
127 setrgb(0, 0, 0, &fleds[1]);
134 // Test if magic value is present at expected location
135 bool eeprom_is_valid(void)
137 return (eeprom_read_word(EEPROM_MAGIC_ADDR) == EEPROM_MAGIC);
140 // Set magic value at expected location
141 void eeprom_set_valid(bool valid)
143 eeprom_update_word(EEPROM_MAGIC_ADDR, valid ? EEPROM_MAGIC : 0xFFFF);
146 // Store current front led config in EEPROM
147 void eeprom_update_conf(void)
149 // Create storage struct and set values
151 conf.mode = fled_mode;
153 // Small hack to ensure max value is stored correctly
155 conf.val = 256 / FLED_VAL_STEP;
157 conf.val = fled_val / FLED_VAL_STEP;
159 // Set magic value and store config
160 eeprom_set_valid(true);
161 eeprom_update_byte(EEPROM_FRONTLED_ADDR, conf.raw);
164 // Custom keycode functions
166 void fled_mode_cycle(void)
168 // FLED -> FLED_RGB -> FLED_INDI
171 fled_mode = FLED_RGB;
175 fled_mode = FLED_INDI;
179 fled_mode = FLED_OFF;
183 // Update stored config
184 eeprom_update_conf();
187 void fled_val_increase(void)
189 // Increase val by FLED_VAL_STEP, handling the upper edge case
190 if (fled_val + FLED_VAL_STEP > 255)
193 fled_val += FLED_VAL_STEP;
195 // Update stored config
196 eeprom_update_conf();
199 void fled_val_decrease(void)
201 // Decrease val by FLED_VAL_STEP, handling the lower edge case
202 if (fled_val - FLED_VAL_STEP > 255)
205 fled_val -= FLED_VAL_STEP;
207 // Update stored config
208 eeprom_update_conf();