mxss.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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. #include QMK_KEYBOARD_H
  17. #include "tmk_core/common/eeprom.h"
  18. #include "tmk_core/common/action_layer.h"
  19. #include "rgblight.h"
  20. // Variables for controlling front LED application
  21. uint8_t fled_mode; // Mode for front LEDs
  22. uint8_t fled_val; // Brightness for front leds (0 - 255)
  23. LED_TYPE fleds[2]; // Front LED rgb values for indicator mode use
  24. // Predefined colors for layers
  25. // Format: {hue, saturation}
  26. // {0, 0} to turn off the LED
  27. // Add additional rows to handle more layers
  28. __attribute__ ((weak))
  29. const hs_set layer_colors[] = {
  30. [0] = {0, 0}, // Color for Layer 0
  31. [1] = {86, 255}, // Color for Layer 1
  32. [2] = {36, 255}, // Color for Layer 2
  33. [3] = {185, 255}, // Color for Layer 3
  34. };
  35. __attribute__ ((weak))
  36. const size_t lc_size = sizeof(layer_colors) / sizeof(uint16_t);
  37. void matrix_init_kb(void) {
  38. // If EEPROM config exists, load it
  39. if (eeprom_is_valid()) {
  40. fled_config fled_conf;
  41. fled_conf.raw = eeprom_read_byte(EEPROM_FRONTLED_ADDR);
  42. fled_mode = fled_conf.mode;
  43. fled_val = fled_conf.val * FLED_VAL_STEP;
  44. // Else, default config
  45. } else {
  46. fled_mode = FLED_RGB;
  47. fled_val = 10 * FLED_VAL_STEP;
  48. eeprom_update_conf(); // Store default config to EEPROM
  49. }
  50. // Set default values for leds
  51. setrgb(0, 0, 0, &fleds[0]);
  52. setrgb(0, 0, 0, &fleds[1]);
  53. // Handle lighting for indicator mode
  54. if (fled_mode == FLED_INDI) {
  55. // Enable capslock led if enabled on host
  56. if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK))
  57. sethsv(FLED_CAPS_H, FLED_CAPS_S, fled_val, &fleds[0]);
  58. // Determine and set colour of layer LED according to current layer
  59. // if hue = sat = 0, leave LED off
  60. uint8_t layer = biton32(layer_state);
  61. if (layer < lc_size && !(layer_colors[layer].hue == 0 && layer_colors[layer].hue == 0))
  62. sethsv(layer_colors[layer].hue, layer_colors[layer].sat, fled_val, &fleds[1]);
  63. }
  64. matrix_init_user();
  65. }
  66. void matrix_scan_kb(void) {
  67. // put your looping keyboard code here
  68. // runs every cycle (a lot)
  69. matrix_scan_user();
  70. }
  71. bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
  72. // Handle custom keycodes for front LED operation
  73. switch (keycode) {
  74. case FLED_MOD: // Change between front LED operation modes (off, indicator, RGB)
  75. if (record->event.pressed)
  76. fled_mode_cycle();
  77. break;
  78. case FLED_VAI: // Increase the brightness of the front LEDs by FLED_VAL_STEP
  79. if (record->event.pressed)
  80. fled_val_increase();
  81. break;
  82. case FLED_VAD: // Decrease the brightness of the front LEDs by FLED_VAL_STEP
  83. if (record->event.pressed)
  84. fled_val_decrease();
  85. break;
  86. default:
  87. break; // Process all other keycodes normally
  88. }
  89. return process_record_user(keycode, record);
  90. }
  91. void led_set_kb(uint8_t usb_led) {
  92. // Set indicator LED appropriately, whether it is used or not
  93. if (usb_led & (1 << USB_LED_CAPS_LOCK)) {
  94. sethsv(FLED_CAPS_H, FLED_CAPS_S, fled_val, &fleds[0]);
  95. } else {
  96. setrgb(0, 0, 0, &fleds[0]);
  97. }
  98. rgblight_set();
  99. led_set_user(usb_led);
  100. }
  101. uint32_t layer_state_set_kb(uint32_t state) {
  102. // Determine and set colour of layer LED according to current layer
  103. // if hue = sat = 0, leave LED off
  104. uint8_t layer = biton32(state);
  105. if (layer < lc_size && !(layer_colors[layer].hue == 0 && layer_colors[layer].hue == 0))
  106. sethsv(layer_colors[layer].hue, layer_colors[layer].sat, fled_val, &fleds[1]);
  107. else
  108. setrgb(0, 0, 0, &fleds[1]);
  109. return state;
  110. }
  111. // EEPROM Management
  112. // Test if magic value is present at expected location
  113. bool eeprom_is_valid(void)
  114. {
  115. return (eeprom_read_word(EEPROM_MAGIC_ADDR) == EEPROM_MAGIC);
  116. }
  117. // Set magic value at expected location
  118. void eeprom_set_valid(bool valid)
  119. {
  120. eeprom_update_word(EEPROM_MAGIC_ADDR, valid ? EEPROM_MAGIC : 0xFFFF);
  121. }
  122. // Store current front led config in EEPROM
  123. void eeprom_update_conf(void)
  124. {
  125. // Create storage struct and set values
  126. fled_config conf;
  127. conf.mode = fled_mode;
  128. // Small hack to ensure max value is stored correctly
  129. if (fled_val == 255)
  130. conf.val = 256 / FLED_VAL_STEP;
  131. else
  132. conf.val = fled_val / FLED_VAL_STEP;
  133. // Set magic value and store config
  134. eeprom_set_valid(true);
  135. eeprom_update_byte(EEPROM_FRONTLED_ADDR, conf.raw);
  136. }
  137. // Custom keycode functions
  138. void fled_mode_cycle(void)
  139. {
  140. // FLED -> FLED_RGB -> FLED_INDI
  141. switch (fled_mode) {
  142. case FLED_OFF:
  143. fled_mode = FLED_RGB;
  144. break;
  145. case FLED_RGB:
  146. fled_mode = FLED_INDI;
  147. break;
  148. case FLED_INDI:
  149. fled_mode = FLED_OFF;
  150. break;
  151. }
  152. // Update stored config
  153. eeprom_update_conf();
  154. rgblight_set();
  155. }
  156. void fled_val_increase(void)
  157. {
  158. // Increase val by FLED_VAL_STEP, handling the upper edge case
  159. if (fled_val + FLED_VAL_STEP > 255)
  160. fled_val = 255;
  161. else
  162. fled_val += FLED_VAL_STEP;
  163. // Update stored config
  164. eeprom_update_conf();
  165. rgblight_set();
  166. }
  167. void fled_val_decrease(void)
  168. {
  169. // Decrease val by FLED_VAL_STEP, handling the lower edge case
  170. if (fled_val - FLED_VAL_STEP > 255)
  171. fled_val = 255;
  172. else
  173. fled_val -= FLED_VAL_STEP;
  174. // Update stored config
  175. eeprom_update_conf();
  176. rgblight_set();
  177. }