]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/mxss/mxss.c
b16348c7bd59a5079b242b7d48aa4e2c0cfe396f
[qmk_firmware.git] / keyboards / mxss / mxss.c
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 #include QMK_KEYBOARD_H
18 #include "tmk_core/common/eeprom.h"
19 #include "tmk_core/common/action_layer.h"
20 #include "rgblight.h"
21
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
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))
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
37 };
38
39 __attribute__ ((weak))
40 const size_t lc_size = sizeof(layer_colors) / sizeof(uint16_t);
41
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
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
73         matrix_init_user();
74 }
75
76 void matrix_scan_kb(void) {
77         // put your looping keyboard code here
78         // runs every cycle (a lot)
79
80         matrix_scan_user();
81 }
82
83 bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
84     // Handle custom keycodes for front LED operation
85     switch (keycode) {
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);
106 }
107
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]);
112     } else {
113         setrgb(0, 0, 0, &fleds[0]);
114     }
115
116         led_set_user(usb_led);
117 }
118
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);
123     
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]);
126     else
127         setrgb(0, 0, 0, &fleds[1]);
128     
129     return state;
130 }
131
132 // EEPROM Management
133
134 // Test if magic value is present at expected location
135 bool eeprom_is_valid(void)
136 {
137         return (eeprom_read_word(EEPROM_MAGIC_ADDR) == EEPROM_MAGIC);
138 }
139
140 // Set magic value at expected location
141 void eeprom_set_valid(bool valid)
142 {
143         eeprom_update_word(EEPROM_MAGIC_ADDR, valid ? EEPROM_MAGIC : 0xFFFF);
144 }
145
146 // Store current front led config in EEPROM
147 void eeprom_update_conf(void)
148 {
149     // Create storage struct and set values
150     fled_config conf;
151     conf.mode = fled_mode;
152     
153     // Small hack to ensure max value is stored correctly
154     if (fled_val == 255)
155         conf.val = 256 / FLED_VAL_STEP;
156     else
157         conf.val = fled_val / FLED_VAL_STEP;
158     
159     // Set magic value and store config
160     eeprom_set_valid(true);
161         eeprom_update_byte(EEPROM_FRONTLED_ADDR, conf.raw);
162 }
163
164 // Custom keycode functions
165
166 void fled_mode_cycle(void)
167 {
168     // FLED -> FLED_RGB -> FLED_INDI
169     switch (fled_mode) {
170         case FLED_OFF:
171         fled_mode = FLED_RGB;
172         break;
173         
174         case FLED_RGB:
175         fled_mode = FLED_INDI;
176         break;
177         
178         case FLED_INDI:
179         fled_mode = FLED_OFF;
180         break;
181     }
182     
183     // Update stored config
184     eeprom_update_conf();
185 }
186
187 void fled_val_increase(void)
188 {
189     // Increase val by FLED_VAL_STEP, handling the upper edge case
190     if (fled_val + FLED_VAL_STEP > 255)
191         fled_val = 255;
192     else
193         fled_val += FLED_VAL_STEP;
194     
195     // Update stored config
196     eeprom_update_conf();
197 }
198
199 void fled_val_decrease(void)
200 {
201     // Decrease val by FLED_VAL_STEP, handling the lower edge case
202     if (fled_val - FLED_VAL_STEP > 255)
203         fled_val = 255;
204     else
205         fled_val -= FLED_VAL_STEP;
206     
207     // Update stored config
208     eeprom_update_conf();
209 }