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]);
117 led_set_user(usb_led);
120 uint32_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);
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]);
128 setrgb(0, 0, 0, &fleds[1]);
135 // Test if magic value is present at expected location
136 bool eeprom_is_valid(void)
138 return (eeprom_read_word(EEPROM_MAGIC_ADDR) == EEPROM_MAGIC);
141 // Set magic value at expected location
142 void eeprom_set_valid(bool valid)
144 eeprom_update_word(EEPROM_MAGIC_ADDR, valid ? EEPROM_MAGIC : 0xFFFF);
147 // Store current front led config in EEPROM
148 void eeprom_update_conf(void)
150 // Create storage struct and set values
152 conf.mode = fled_mode;
154 // Small hack to ensure max value is stored correctly
156 conf.val = 256 / FLED_VAL_STEP;
158 conf.val = fled_val / FLED_VAL_STEP;
160 // Set magic value and store config
161 eeprom_set_valid(true);
162 eeprom_update_byte(EEPROM_FRONTLED_ADDR, conf.raw);
165 // Custom keycode functions
167 void fled_mode_cycle(void)
169 // FLED -> FLED_RGB -> FLED_INDI
172 fled_mode = FLED_RGB;
176 fled_mode = FLED_INDI;
180 fled_mode = FLED_OFF;
184 // Update stored config
185 eeprom_update_conf();
189 void fled_val_increase(void)
191 // Increase val by FLED_VAL_STEP, handling the upper edge case
192 if (fled_val + FLED_VAL_STEP > 255)
195 fled_val += FLED_VAL_STEP;
197 // Update stored config
198 eeprom_update_conf();
202 void fled_val_decrease(void)
204 // Decrease val by FLED_VAL_STEP, handling the lower edge case
205 if (fled_val - FLED_VAL_STEP > 255)
208 fled_val -= FLED_VAL_STEP;
210 // Update stored config
211 eeprom_update_conf();