* Added basic MxSS support * Fixed split RSHFT for ISO layouts * Updated readme.md for MxSS * Added initial support for individual control of front RGB LEDs * Changed RGBLED color selection to work using hue and saturation rather than RGB Added code for LED state change on layer change * Avoid needing an entire 8 bits to store the brightness value * Added custom keycodes, along with their handlers * Added EEPROM storage for front LED config * Fixed up ability to use QMK Configurator and updated readme.md * Applied suggested changes from pull request: https://github.com/standard/standard/issues/452 Updated name in license descriptions Updated layouts to snake case Corrected mistakes in info.json Updated layer_colors to a weak attributed array in mxss.c * Defined a new safe range for custom keycodes in keymap.c * Fixed up issues with front LED Fixed LEDs not always updating in indicator mode Added support for the other RGBLIGHT modes in RGB mode * Attempted fix for ISO layouts for QMK configurator
		
			
				
	
	
		
			214 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			214 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* Copyright 2018 Jumail Mundekkat / MxBlue
 | |
|  *
 | |
|  * This program is free software: you can redistribute it and/or modify
 | |
|  * it under the terms of the GNU General Public License as published by
 | |
|  * the Free Software Foundation, either version 2 of the License, or
 | |
|  * (at your option) any later version.
 | |
|  *
 | |
|  * This program is distributed in the hope that it will be useful,
 | |
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|  * GNU General Public License for more details.
 | |
|  *
 | |
|  * You should have received a copy of the GNU General Public License
 | |
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | |
|  */
 | |
|  
 | |
| #include QMK_KEYBOARD_H
 | |
| #include "tmk_core/common/eeprom.h"
 | |
| #include "tmk_core/common/action_layer.h"
 | |
| #include "rgblight.h"
 | |
| 
 | |
| // Variables for controlling front LED application
 | |
| uint8_t fled_mode;  // Mode for front LEDs
 | |
| uint8_t fled_val;   // Brightness for front leds (0 - 255)
 | |
| LED_TYPE fleds[2];  // Front LED rgb values for indicator mode use
 | |
| 
 | |
| // Predefined colors for layers
 | |
| // Format: {hue, saturation}
 | |
| // {0, 0} to turn off the LED
 | |
| // Add additional rows to handle more layers
 | |
| __attribute__ ((weak))
 | |
| const hs_set layer_colors[] = {
 | |
|     [0] = {0,     0},  // Color for Layer 0
 | |
|     [1] = {86,    255},  // Color for Layer 1
 | |
|     [2] = {36,    255},  // Color for Layer 2
 | |
|     [3] = {185,   255},  // Color for Layer 3
 | |
| };
 | |
| 
 | |
| __attribute__ ((weak))
 | |
| const size_t lc_size = sizeof(layer_colors) / sizeof(uint16_t);
 | |
| 
 | |
| void matrix_init_kb(void) {
 | |
|     // If EEPROM config exists, load it
 | |
|     if (eeprom_is_valid()) {
 | |
|         fled_config fled_conf;
 | |
|         fled_conf.raw = eeprom_read_byte(EEPROM_FRONTLED_ADDR);
 | |
|         fled_mode = fled_conf.mode;
 | |
|         fled_val = fled_conf.val * FLED_VAL_STEP;
 | |
|     // Else, default config
 | |
|     } else {
 | |
|         fled_mode = FLED_RGB;
 | |
|         fled_val = 10 * FLED_VAL_STEP;
 | |
|         eeprom_update_conf();   // Store default config to EEPROM
 | |
|     }
 | |
|     
 | |
|     // Set default values for leds
 | |
|     setrgb(0, 0, 0, &fleds[0]);
 | |
|     setrgb(0, 0, 0, &fleds[1]);
 | |
|     
 | |
|     // Handle lighting for indicator mode
 | |
|     if (fled_mode == FLED_INDI) {
 | |
|         // Enable capslock led if enabled on host
 | |
|         if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK))
 | |
|             sethsv(FLED_CAPS_H, FLED_CAPS_S, fled_val, &fleds[0]);
 | |
|         
 | |
|         // Determine and set colour of layer LED according to current layer
 | |
|         // if hue = sat = 0, leave LED off
 | |
|         uint8_t layer = biton32(layer_state);
 | |
|         if (layer < lc_size && !(layer_colors[layer].hue == 0 && layer_colors[layer].hue == 0))
 | |
|             sethsv(layer_colors[layer].hue, layer_colors[layer].sat, fled_val, &fleds[1]);
 | |
|     }
 | |
| 
 | |
| 	matrix_init_user();
 | |
| }
 | |
| 
 | |
| void matrix_scan_kb(void) {
 | |
| 	// put your looping keyboard code here
 | |
| 	// runs every cycle (a lot)
 | |
| 
 | |
| 	matrix_scan_user();
 | |
| }
 | |
| 
 | |
| bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
 | |
|     // Handle custom keycodes for front LED operation
 | |
|     switch (keycode) {
 | |
|         case FLED_MOD: // Change between front LED operation modes (off, indicator, RGB)
 | |
|         if (record->event.pressed)
 | |
|             fled_mode_cycle();
 | |
|         break;
 | |
|         
 | |
|         case FLED_VAI: // Increase the brightness of the front LEDs by FLED_VAL_STEP
 | |
|         if (record->event.pressed)
 | |
|             fled_val_increase();
 | |
|         break;
 | |
|         
 | |
|         case FLED_VAD: // Decrease the brightness of the front LEDs by FLED_VAL_STEP
 | |
|         if (record->event.pressed)
 | |
|             fled_val_decrease();
 | |
|         break;
 | |
|         
 | |
|         default:
 | |
|         break; // Process all other keycodes normally
 | |
|       }
 | |
| 
 | |
| 	return process_record_user(keycode, record);
 | |
| }
 | |
| 
 | |
| void led_set_kb(uint8_t usb_led) {
 | |
|     // Set indicator LED appropriately, whether it is used or not
 | |
|     if (usb_led & (1 << USB_LED_CAPS_LOCK)) {
 | |
|         sethsv(FLED_CAPS_H, FLED_CAPS_S, fled_val, &fleds[0]);
 | |
|     } else {
 | |
|         setrgb(0, 0, 0, &fleds[0]);
 | |
|     }
 | |
| 
 | |
|     rgblight_set();
 | |
| 	led_set_user(usb_led);
 | |
| }
 | |
| 
 | |
| uint32_t layer_state_set_kb(uint32_t state) {
 | |
|     // Determine and set colour of layer LED according to current layer
 | |
|     // if hue = sat = 0, leave LED off
 | |
|     uint8_t layer = biton32(state);
 | |
|     
 | |
|     if (layer < lc_size && !(layer_colors[layer].hue == 0 && layer_colors[layer].hue == 0))
 | |
|         sethsv(layer_colors[layer].hue, layer_colors[layer].sat, fled_val, &fleds[1]);
 | |
|     else
 | |
|         setrgb(0, 0, 0, &fleds[1]);
 | |
|     
 | |
|     return state;
 | |
| }
 | |
| 
 | |
| // EEPROM Management
 | |
| 
 | |
| // Test if magic value is present at expected location
 | |
| bool eeprom_is_valid(void)
 | |
| {
 | |
| 	return (eeprom_read_word(EEPROM_MAGIC_ADDR) == EEPROM_MAGIC);
 | |
| }
 | |
| 
 | |
| // Set magic value at expected location
 | |
| void eeprom_set_valid(bool valid)
 | |
| {
 | |
| 	eeprom_update_word(EEPROM_MAGIC_ADDR, valid ? EEPROM_MAGIC : 0xFFFF);
 | |
| }
 | |
| 
 | |
| // Store current front led config in EEPROM
 | |
| void eeprom_update_conf(void)
 | |
| {
 | |
|     // Create storage struct and set values
 | |
|     fled_config conf;
 | |
|     conf.mode = fled_mode;
 | |
|     
 | |
|     // Small hack to ensure max value is stored correctly
 | |
|     if (fled_val == 255)
 | |
|         conf.val = 256 / FLED_VAL_STEP;
 | |
|     else
 | |
|         conf.val = fled_val / FLED_VAL_STEP;
 | |
|     
 | |
|     // Set magic value and store config
 | |
|     eeprom_set_valid(true);
 | |
| 	eeprom_update_byte(EEPROM_FRONTLED_ADDR, conf.raw);
 | |
| }
 | |
| 
 | |
| // Custom keycode functions
 | |
| 
 | |
| void fled_mode_cycle(void)
 | |
| {
 | |
|     // FLED -> FLED_RGB -> FLED_INDI
 | |
|     switch (fled_mode) {
 | |
|         case FLED_OFF:
 | |
|         fled_mode = FLED_RGB;
 | |
|         break;
 | |
|         
 | |
|         case FLED_RGB:
 | |
|         fled_mode = FLED_INDI;
 | |
|         break;
 | |
|         
 | |
|         case FLED_INDI:
 | |
|         fled_mode = FLED_OFF;
 | |
|         break;
 | |
|     }
 | |
|     
 | |
|     // Update stored config
 | |
|     eeprom_update_conf();
 | |
|     rgblight_set();
 | |
| }
 | |
| 
 | |
| void fled_val_increase(void)
 | |
| {
 | |
|     // Increase val by FLED_VAL_STEP, handling the upper edge case
 | |
|     if (fled_val + FLED_VAL_STEP > 255)
 | |
|         fled_val = 255;
 | |
|     else
 | |
|         fled_val += FLED_VAL_STEP;
 | |
|     
 | |
|     // Update stored config
 | |
|     eeprom_update_conf();
 | |
|     rgblight_set();
 | |
| }
 | |
| 
 | |
| void fled_val_decrease(void)
 | |
| {
 | |
|     // Decrease val by FLED_VAL_STEP, handling the lower edge case
 | |
|     if (fled_val - FLED_VAL_STEP > 255)
 | |
|         fled_val = 255;
 | |
|     else
 | |
|         fled_val -= FLED_VAL_STEP;
 | |
|     
 | |
|     // Update stored config
 | |
|     eeprom_update_conf();
 | |
|     rgblight_set();
 | |
| }
 |