Skip to content

Instantly share code, notes, and snippets.

@kylemisner
Forked from fdidron/ABOUT.md
Created March 7, 2019 00:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kylemisner/929ed5dc05622d4e557fd64b46a7e97f to your computer and use it in GitHub Desktop.
Save kylemisner/929ed5dc05622d4e557fd64b46a7e97f to your computer and use it in GitHub Desktop.
Ergodox-EZ Glow per layer / per key illumination

rules.mk

Contains all the directives required to activate QMK's rgb matrix features.

config.h

Sets a constant required to read the rgb matrix config from the EEPROM.

keymap.c

Custom keymap based on my layout. This is where the magic happens.

First let's declare a rgb_matrix_config variable of type rgb_config_t :

rgb_config_t rgb_matrix_config;

Then declare two maps which will serve two purposes, layercolors to illuminate all the leds of a layer with the same color, and ledcolors to illuminate individual keys on a layer.

const uint8_t PROGMEM layercolors[][2] = {
...
}

const uint8_t PROGMEM ledcolors[][DRIVER_LED_TOTAL][3] = {
...
}

All colors are described using the HSV format.

Note that the layercolor contains data for the hue and saturation only, since value (or brightness) will be overriden with the value from the eeprom to take into account the user's brightness settings.

Next step is to read the rgb_matrix config from the eeprom. We will use the enable boolean to turn off the leds if the user toggles them off, as well as use the val value to adjust the leds brightness based on user control:

void matrix_init_user(void) {
  rgb_matrix_config.raw = eeprom_read_dword(EECONFIG_RGB_MATRIX);
}

Then based on which layer is active, the led colors gets assigned:

void rgb_matrix_indicators_user(void) {
  uint32_t mode = rgblight_get_mode();
  // assign colors if the matrix is on and the current mode
  // is SOLID COLORS => No animations running
  if(rgb_matrix_config.enable == 1 && mode == 1) {
    uint8_t layer = biton32(layer_state);
    switch (layer) {
      case 0:
        set_layer_color(0);
        break;
      case 1:
        set_leds_color(1);
        break;
    }
  }
}

The set_layer_color function will set all the color of all the leds uniformally by merging the hue and saturation values from the layercolors map with the brightness value from the eeprom.

void set_layer_color( uint8_t layer ) {
  HSV hsv = { .h = pgm_read_byte(&layercolors[layer][0]), .s = pgm_read_byte(&layercolors[layer][1]), .v = rgb_matrix_config.val};
  RGB rgb = hsv_to_rgb( hsv );
  for (int i = 0; i < DRIVER_LED_TOTAL; i++) {
    rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );
  }
}

The set_leds_color function will set the leds color individually by merging the hue, saturation values from the ledcolors map with the brightness value from the eeprom. If the brightness of the key was set to 0 in the ledcolors map, it will override the brightness value from the eeprom allowing to have individal leds turned off.

void set_leds_color( int layer) {
  for (int i = 0; i < DRIVER_LED_TOTAL; i++) {
    uint8_t val = pgm_read_byte(&ledcolors[layer][i][2]);
    // if the brightness of the led is set to 0 in the map,
    // the value is not overriden with global controls, allowing the led
    // to appear turned off
    HSV hsv = { .h = pgm_read_byte(&ledcolors[layer][i][0]), .s = pgm_read_byte(&ledcolors[layer][i][1]), .v = val == 0 ? 0 : rgb_matrix_config.val};
    RGB rgb = hsv_to_rgb( hsv );
    rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );
  }
}
#define EECONFIG_RGB_MATRIX (uint32_t *)16
#include "ergodox_ez.h"
#include "debug.h"
#include "action_layer.h"
#include "version.h"
#include "keymap_german.h"
#include "keymap_nordic.h"
rgb_config_t rgb_matrix_config;
enum custom_keycodes {
PLACEHOLDER = SAFE_RANGE, // can always be here
EPRM,
RGB_SLD,
HSV_153_77_255,
HSV_11_255_255
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT_ergodox(KC_EQUAL,KC_1,KC_2,KC_3,KC_4,KC_5,KC_TRANSPARENT,KC_DELETE,KC_Q,KC_W,KC_E,KC_R,KC_T,KC_TRANSPARENT,LT(1,KC_TAB),KC_A,KC_S,KC_D,KC_F,KC_G,OSM(MOD_LSFT),CTL_T(KC_Z),ALT_T(KC_X),KC_C,KC_V,KC_B,KC_TRANSPARENT,KC_GRAVE,KC_QUOTE,KC_TRANSPARENT,KC_LEFT,KC_RIGHT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,GUI_T(KC_SPACE),KC_ESCAPE,KC_TRANSPARENT,KC_TRANSPARENT,KC_6,KC_7,KC_8,KC_9,KC_0,KC_MINUS,KC_TRANSPARENT,KC_Y,KC_U,KC_I,KC_O,KC_P,KC_BSLASH,KC_H,KC_J,KC_K,KC_L,KC_SCOLON,LT(1,KC_QUOTE),KC_TRANSPARENT,KC_N,KC_M,KC_COMMA,ALT_T(KC_DOT),RCTL_T(KC_SLASH),OSM(MOD_RSFT),KC_DOWN,KC_UP,KC_LBRACKET,KC_RBRACKET,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_PGUP,KC_PGDOWN,KC_BSPACE,GUI_T(KC_ENTER)),
[1] = LAYOUT_ergodox(KC_TRANSPARENT,KC_F1,KC_F2,KC_F3,KC_F4,KC_F5,KC_TRANSPARENT,KC_TRANSPARENT,KC_EXLM,KC_AT,KC_LCBR,KC_RCBR,KC_PIPE,KC_TRANSPARENT,KC_TRANSPARENT,KC_HASH,KC_DLR,KC_LPRN,KC_RPRN,KC_AMPR,KC_TRANSPARENT,KC_PERC,KC_CIRC,KC_LBRACKET,KC_RBRACKET,KC_TILD,KC_TRANSPARENT,RESET,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,RGB_MOD,KC_TRANSPARENT,KC_TRANSPARENT,RGB_VAD,RGB_VAI,KC_TRANSPARENT,KC_TRANSPARENT,KC_F6,KC_F7,KC_F8,KC_F9,KC_F10,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_ASTR,KC_TRANSPARENT,KC_LEFT,KC_DOWN,KC_UP,KC_RIGHT,KC_PLUS,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_BSLASH,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_TRANSPARENT,KC_EQUAL,KC_TRANSPARENT,RGB_TOG,RGB_SLD,KC_TRANSPARENT,KC_TRANSPARENT,HSV_153_77_255,HSV_11_255_255),
};
const uint8_t PROGMEM layercolors[][2] = {
[0] = {200,155}
};
const uint8_t PROGMEM ledcolors[][DRIVER_LED_TOTAL][3] = {
[1] = {
{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {142,123,255}, {142,123,255}, {142,123,255}, {142,123,255}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}
}
};
const uint16_t PROGMEM fn_actions[] = {
[1] = ACTION_LAYER_TAP_TOGGLE(1)
};
void matrix_init_user(void) {
rgb_matrix_config.raw = eeprom_read_dword(EECONFIG_RGB_MATRIX);
}
void set_leds_color( int layer) {
for (int i = 0; i < DRIVER_LED_TOTAL; i++) {
uint8_t val = pgm_read_byte(&ledcolors[layer][i][2]);
// if the brightness of the led is set to 0 in the map,
   // the value is not overriden with global controls, allowing the led
   // to appear turned off
HSV hsv = { .h = pgm_read_byte(&ledcolors[layer][i][0]), .s = pgm_read_byte(&ledcolors[layer][i][1]), .v = val == 0 ? 0 : rgb_matrix_config.val};
RGB rgb = hsv_to_rgb( hsv );
rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );
}
}
void set_layer_color( uint8_t layer ) {
HSV hsv = { .h = pgm_read_byte(&layercolors[layer][0]), .s = pgm_read_byte(&layercolors[layer][1]), .v = rgb_matrix_config.val};
RGB rgb = hsv_to_rgb( hsv );
for (int i = 0; i < DRIVER_LED_TOTAL; i++) {
rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );
}
}
void rgb_matrix_indicators_user(void) {
uint32_t mode = rgblight_get_mode();
// assign colors if the matrix is on and the current mode
 // is SOLID COLORS => No animations running
if(rgb_matrix_config.enable == 1 && mode == 1) {
uint8_t layer = biton32(layer_state);
switch (layer) {
case 0:
set_layer_color(0);
break;
case 1:
set_leds_color(1);
break;
}
}
}
// leaving this in place for compatibilty with old keymaps cloned and re-compiled.
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
switch(id) {
case 0:
if (record->event.pressed) {
SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
}
break;
}
return MACRO_NONE;
};
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
// dynamically generate these.
case EPRM:
if (record->event.pressed) {
eeconfig_init();
}
return false;
break;
case RGB_SLD:
if (record->event.pressed) {
rgblight_mode(1);
}
return false;
break;
case HSV_153_77_255:
if (record->event.pressed) {
#ifdef RGB_MATRIX_ENABLE
rgblight_mode(1);
rgblight_sethsv(153,77,255);
#endif
}
return false;
break;
case HSV_11_255_255:
if (record->event.pressed) {
#ifdef RGB_MATRIX_ENABLE
rgblight_mode(1);
rgblight_sethsv(11,255,255);
#endif
}
return false;
break;
}
return true;
}
uint32_t layer_state_set_user(uint32_t state) {
uint8_t layer = biton32(state);
ergodox_board_led_off();
ergodox_right_led_1_off();
ergodox_right_led_2_off();
ergodox_right_led_3_off();
switch (layer) {
case 1:
ergodox_right_led_1_on();
break;
case 2:
ergodox_right_led_2_on();
break;
case 3:
ergodox_right_led_3_on();
break;
case 4:
ergodox_right_led_1_on();
ergodox_right_led_2_on();
break;
case 5:
ergodox_right_led_1_on();
ergodox_right_led_3_on();
break;
case 6:
ergodox_right_led_2_on();
ergodox_right_led_3_on();
break;
case 7:
ergodox_right_led_1_on();
ergodox_right_led_2_on();
ergodox_right_led_3_on();
break;
default:
break;
}
return state;
};
SRC = matrix.c
RGBLIGHT_ENABLE = no
RGB_MATRIX_ENABLE = yes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment