forked from mirrors/qmk_firmware
210 lines
6 KiB
C
210 lines
6 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]);
|
||
|
}
|
||
|
|
||
|
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();
|
||
|
}
|