summaryrefslogtreecommitdiffstats
path: root/keyboards/mxss/mxss.c
diff options
context:
space:
mode:
authorMxBlu <mundekkat@hotmail.com>2018-07-08 12:33:36 +1000
committerDrashna Jaelre <drashna@live.com>2018-07-07 19:33:36 -0700
commite661f1559ebdf90c3bb806b6f5940c5363720738 (patch)
treed4104b21c10e6522d3c03339687354092de49e5e /keyboards/mxss/mxss.c
parentdf8b564518930969f6ee319edeee2fcb0d715db6 (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.c209
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();
+}