diff options
author | MxBlu <mundekkat@hotmail.com> | 2018-07-08 12:33:36 +1000 |
---|---|---|
committer | Drashna Jaelre <drashna@live.com> | 2018-07-07 19:33:36 -0700 |
commit | e661f1559ebdf90c3bb806b6f5940c5363720738 (patch) | |
tree | d4104b21c10e6522d3c03339687354092de49e5e /keyboards/mxss/mxss.c | |
parent | df8b564518930969f6ee319edeee2fcb0d715db6 (diff) |
Add MxSS keyboard (#3335)
* 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
Diffstat (limited to 'keyboards/mxss/mxss.c')
-rw-r--r-- | keyboards/mxss/mxss.c | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/keyboards/mxss/mxss.c b/keyboards/mxss/mxss.c new file mode 100644 index 0000000000..b16348c7bd --- /dev/null +++ b/keyboards/mxss/mxss.c @@ -0,0 +1,209 @@ +/* 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]); + } + + 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(); +} + +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(); +} + +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(); +} |