You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							214 lines
						
					
					
						
							6.1 KiB
						
					
					
				
			
		
		
	
	
							214 lines
						
					
					
						
							6.1 KiB
						
					
					
				/* 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();
 | 
						|
}
 |