LED Matrix: add led_matrix_types.h and implement g_led_config (#11741)

* LED Matrix: add led_matrix_types.h and implement g_led_config

* Set correct flags for non-"modifier" LEDs

* Clean up docs a little

* Add license headers for [led,rgb]_matrix_types.h
master
Ryan 2021-02-14 12:15:08 +11:00 committed by GitHub
parent de8caf708c
commit 7ce5ba645a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 301 additions and 298 deletions

View File

@ -10,9 +10,11 @@ If you want to use RGB LED's you should use the [RGB Matrix Subsystem](feature_r
There is basic support for addressable LED matrix lighting with the I2C IS31FL3731 RGB controller. To enable it, add this to your `rules.mk`: There is basic support for addressable LED matrix lighting with the I2C IS31FL3731 RGB controller. To enable it, add this to your `rules.mk`:
LED_MATRIX_ENABLE = yes ```make
LED_MATRIX_DRIVER = IS31FL3731 LED_MATRIX_ENABLE = yes
LED_MATRIX_DRIVER = IS31FL3731
```
You can use between 1 and 4 IS31FL3731 IC's. Do not specify `LED_DRIVER_ADDR_<N>` defines for IC's that are not present on your keyboard. You can define the following items in `config.h`: You can use between 1 and 4 IS31FL3731 IC's. Do not specify `LED_DRIVER_ADDR_<N>` defines for IC's that are not present on your keyboard. You can define the following items in `config.h`:
| Variable | Description | Default | | Variable | Description | Default |
@ -28,33 +30,38 @@ You can use between 1 and 4 IS31FL3731 IC's. Do not specify `LED_DRIVER_ADDR_<N>
Here is an example using 2 drivers. Here is an example using 2 drivers.
// This is a 7-bit address, that gets left-shifted and bit 0 ```c
// set to 0 for write, 1 for read (as per I2C protocol) // This is a 7-bit address, that gets left-shifted and bit 0
// The address will vary depending on your wiring: // set to 0 for write, 1 for read (as per I2C protocol)
// 0b1110100 AD <-> GND // The address will vary depending on your wiring:
// 0b1110111 AD <-> VCC // 0b1110100 AD <-> GND
// 0b1110101 AD <-> SCL // 0b1110111 AD <-> VCC
// 0b1110110 AD <-> SDA // 0b1110101 AD <-> SCL
#define LED_DRIVER_ADDR_1 0b1110100 // 0b1110110 AD <-> SDA
#define LED_DRIVER_ADDR_2 0b1110110 #define LED_DRIVER_ADDR_1 0b1110100
#define LED_DRIVER_ADDR_2 0b1110110
#define LED_DRIVER_COUNT 2 #define LED_DRIVER_COUNT 2
#define LED_DRIVER_1_LED_COUNT 25 #define LED_DRIVER_1_LED_COUNT 25
#define LED_DRIVER_2_LED_COUNT 24 #define LED_DRIVER_2_LED_COUNT 24
#define LED_DRIVER_LED_COUNT LED_DRIVER_1_LED_TOTAL + LED_DRIVER_2_LED_TOTAL #define LED_DRIVER_LED_COUNT LED_DRIVER_1_LED_TOTAL + LED_DRIVER_2_LED_TOTAL
```
Currently only 2 drivers are supported, but it would be trivial to support all 4 combinations. Currently only 2 drivers are supported, but it would be trivial to support all 4 combinations.
Define these arrays listing all the LEDs in your `<keyboard>.c`: Define these arrays listing all the LEDs in your `<keyboard>.c`:
const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { ```c
/* Refer to IS31 manual for these locations const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
* driver /* Refer to IS31 manual for these locations
* | LED address * driver
* | | */ * | LED address
{0, C3_3}, * | | */
.... { 0, C1_1 },
} { 0, C1_15 },
// ...
}
```
Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3731.pdf) and the header file `drivers/issi/is31fl3731-simple.h`. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3` ). Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3731.pdf) and the header file `drivers/issi/is31fl3731-simple.h`. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3` ).
@ -66,26 +73,28 @@ All LED matrix keycodes are currently shared with the [backlight system](feature
Currently no LED matrix effects have been created. Currently no LED matrix effects have been created.
## Custom layer effects ## Custom Layer Effects
Custom layer effects can be done by defining this in your `<keyboard>.c`: Custom layer effects can be done by defining this in your `<keyboard>.c`:
void led_matrix_indicators_kb(void) { ```c
led_matrix_set_index_value(index, value); void led_matrix_indicators_kb(void) {
} led_matrix_set_index_value(index, value);
}
```
A similar function works in the keymap as `led_matrix_indicators_user`. A similar function works in the keymap as `led_matrix_indicators_user`.
## Suspended state ## Suspended State
To use the suspend feature, add this to your `<keyboard>.c`: To use the suspend feature, add this to your `<keyboard>.c`:
void suspend_power_down_kb(void) ```c
{ void suspend_power_down_kb(void) {
led_matrix_set_suspend_state(true); led_matrix_set_suspend_state(true);
} }
void suspend_wakeup_init_kb(void) void suspend_wakeup_init_kb(void) {
{ led_matrix_set_suspend_state(false);
led_matrix_set_suspend_state(false); }
} ```

View File

@ -20,162 +20,109 @@
const is31_led g_is31_leds[LED_DRIVER_LED_COUNT] = { const is31_led g_is31_leds[LED_DRIVER_LED_COUNT] = {
/* Refer to IS31 manual for these locations /* Refer to IS31 manual for these locations
* driver * driver
* | LED address * | LED address
* | | */ * | | */
{0, C1_1}, // k00 KC_GESC { 0, C1_1 }, // k00 KC_GESC
{0, C1_2}, // k01 KC_1 { 0, C1_2 }, // k01 KC_1
{0, C1_3}, // k02 KC_2 { 0, C1_3 }, // k02 KC_2
{0, C1_4}, // k03 KC_3 { 0, C1_4 }, // k03 KC_3
{0, C1_5}, // k04 KC_4 { 0, C1_5 }, // k04 KC_4
{0, C1_6}, // k05 KC_5 { 0, C1_6 }, // k05 KC_5
{0, C1_7}, // k06 KC_6 { 0, C1_7 }, // k06 KC_6
{0, C1_8}, // k07 KC_7 { 0, C1_8 }, // k07 KC_7
{0, C1_9}, // k50 KC_8 { 0, C1_9 }, // k50 KC_8
{0, C1_10}, // k51 KC_9 { 0, C1_10 }, // k51 KC_9
{0, C1_11}, // k52 KC_0 { 0, C1_11 }, // k52 KC_0
{0, C1_12}, // k53 KC_MINS { 0, C1_12 }, // k53 KC_MINS
{0, C1_13}, // k54 KC_EQL { 0, C1_13 }, // k54 KC_EQL
{0, C1_14}, // k55 KC_BSPC { 0, C1_14 }, // k55 KC_BSPC
{0, C1_15}, // k57 KC_PGUP { 0, C1_15 }, // k57 KC_PGUP
{0, C2_1}, // k10 KC_TAB { 0, C2_1 }, // k10 KC_TAB
{0, C2_2}, // k11 KC_Q { 0, C2_2 }, // k11 KC_Q
{0, C2_3}, // k12 KC_W { 0, C2_3 }, // k12 KC_W
{0, C2_4}, // k13 KC_E { 0, C2_4 }, // k13 KC_E
{0, C2_5}, // k14 KC_R { 0, C2_5 }, // k14 KC_R
{0, C2_6}, // k15 KC_T { 0, C2_6 }, // k15 KC_T
{0, C2_7}, // k16 KC_Y { 0, C2_7 }, // k16 KC_Y
{0, C2_8}, // k17 KC_U { 0, C2_8 }, // k17 KC_U
{0, C2_9}, // k60 KC_I { 0, C2_9 }, // k60 KC_I
{0, C2_10}, // k61 KC_O { 0, C2_10 }, // k61 KC_O
{0, C2_11}, // k62 KC_P { 0, C2_11 }, // k62 KC_P
{0, C2_12}, // k63 KC_LBRC { 0, C2_12 }, // k63 KC_LBRC
{0, C2_13}, // k64 KC_RBRC { 0, C2_13 }, // k64 KC_RBRC
{0, C2_14}, // k65 KC_BSLS { 0, C2_14 }, // k65 KC_BSLS
{0, C2_15}, // k67 KC_PGDN { 0, C2_15 }, // k67 KC_PGDN
{0, C3_1}, // k20 KC_CAPS { 0, C3_1 }, // k20 KC_CAPS
{0, C3_2}, // k21 KC_A { 0, C3_2 }, // k21 KC_A
{0, C3_3}, // k22 KC_S { 0, C3_3 }, // k22 KC_S
{0, C3_4}, // k23 KC_D { 0, C3_4 }, // k23 KC_D
{0, C3_5}, // k24 KC_F { 0, C3_5 }, // k24 KC_F
{0, C3_6}, // k25 KC_G { 0, C3_6 }, // k25 KC_G
{0, C3_7}, // k26 KC_H { 0, C3_7 }, // k26 KC_H
{0, C3_8}, // k27 KC_J { 0, C3_8 }, // k27 KC_J
{0, C3_9}, // k70 KC_K { 0, C3_9 }, // k70 KC_K
{0, C3_10}, // k71 KC_L { 0, C3_10 }, // k71 KC_L
{0, C3_11}, // k72 KC_SCLN { 0, C3_11 }, // k72 KC_SCLN
{0, C3_12}, // k73 KC_QUOT { 0, C3_12 }, // k73 KC_QUOT
{0, C3_14}, // k75 KC_ENT { 0, C3_14 }, // k75 KC_ENT
{0, C4_1}, // k30 KC_LSFT { 0, C4_1 }, // k30 KC_LSFT
{0, C4_3}, // k32 KC_Z { 0, C4_3 }, // k32 KC_Z
{0, C4_4}, // k33 KC_X { 0, C4_4 }, // k33 KC_X
{0, C4_5}, // k34 KC_C { 0, C4_5 }, // k34 KC_C
{0, C4_6}, // k35 KC_V { 0, C4_6 }, // k35 KC_V
{0, C4_7}, // k36 KC_B { 0, C4_7 }, // k36 KC_B
{0, C4_8}, // k37 KC_N { 0, C4_8 }, // k37 KC_N
{0, C4_9}, // k80 KC_M { 0, C4_9 }, // k80 KC_M
{0, C4_10}, // k81 KC_COMM { 0, C4_10 }, // k81 KC_COMM
{0, C4_11}, // k82 KC_DOT { 0, C4_11 }, // k82 KC_DOT
{0, C4_12}, // k83 KC_SLSH { 0, C4_12 }, // k83 KC_SLSH
{0, C4_13}, // k85 KC_RSFT { 0, C4_13 }, // k85 KC_RSFT
{0, C4_14}, // k86 KC_UP { 0, C4_14 }, // k86 KC_UP
{0, C5_1}, // k40 KC_LCTL { 0, C5_1 }, // k40 KC_LCTL
{0, C5_2}, // k41 KC_LGUI { 0, C5_2 }, // k41 KC_LGUI
{0, C5_3}, // k42 KC_LALT { 0, C5_3 }, // k42 KC_LALT
{0, C5_4}, // Unassociated between LALT and SPACE_2.75 { 0, C5_4 }, // Unassociated between LALT and SPACE_2.75
{0, C5_5}, // k45 KC_SPC SPACE_2.75 { 0, C5_5 }, // k45 KC_SPC SPACE_2.75
{0, C5_6}, // k45 KC_SPC SPACE_6.75 { 0, C5_6 }, // k45 KC_SPC SPACE_6.75
{0, C5_7}, // k46 KC_SPC SPACE_2.25 { 0, C5_7 }, // k46 KC_SPC SPACE_2.25
{0, C5_8}, // Unassociated between SPACE_2.25 and SPACE_1.25 { 0, C5_8 }, // Unassociated between SPACE_2.25 and SPACE_1.25
{0, C5_9}, // k90 KC_RGUI { 0, C5_9 }, // k90 KC_RGUI
{0, C5_10}, // k92 KC_RALT { 0, C5_10 }, // k92 KC_RALT
{0, C5_11}, // k93 MO(_FL) { 0, C5_11 }, // k93 MO(_FL)
{0, C5_12}, // k94 KC_RCTL { 0, C5_12 }, // k94 KC_RCTL
{0, C5_13}, // k95 KC_LEFT { 0, C5_13 }, // k95 KC_LEFT
{0, C5_14}, // k96 KC_DOWN { 0, C5_14 }, // k96 KC_DOWN
{0, C5_15} // k97 KC_RGHT { 0, C5_15 } // k97 KC_RGHT
}; };
const led_matrix g_leds[LED_DRIVER_LED_COUNT] = { led_config_t g_led_config = {
{
/*{row | col << 4} // Key Matrix to LED Index
| LED_ROW_COL(row, col) { 0, 1, 2, 3, 4, 5, 6, 7 },
| | modifier { 15, 16, 17, 18, 19, 20, 21, 22 },
| | | */ { 30, 31, 32, 33, 34, 35, 36, 37 },
{{0|(1<<4)}, {0, 0}, 1}, // k00 KC_GESC { 43, NO_LED, 44, 45, 46, 47, 48, 49 },
{{0|(2<<4)}, {14.45, 0}, 0}, // k01 KC_1 { 56, 57, 58, NO_LED, NO_LED, 60, 61, NO_LED },
{{0|(3<<4)}, {28.9, 0}, 0}, // k02 KC_2 { 8, 9, 10, 11, 12, 13, NO_LED, 14 },
{{0|(4<<4)}, {43.35, 0}, 0}, // k03 KC_3 { 23, 24, 25, 26, 27, 28, NO_LED, 29 },
{{0|(5<<4)}, {57.8, 0}, 0}, // k04 KC_4 { 38, 39, 40, 41, NO_LED, 42, NO_LED, NO_LED },
{{0|(6<<4)}, {72.25, 0}, 0}, // k05 KC_5 { 50, 51, 52, 53, NO_LED, 54, 55, NO_LED },
{{0|(7<<4)}, {86.7, 0}, 0}, // k06 KC_6 { 64, NO_LED, 65, 66, 67, 68, 69, 70 }
{{0|(8<<4)}, {101.2, 0}, 0}, // k07 KC_7 }, {
{{0|(9<<4)}, {115.6, 0}, 0}, // k50 KC_8 // LED Index to Physical Position
{{0|(10<<4)}, {130, 0}, 0}, // k51 KC_9 { 0, 0 }, { 15, 0 }, { 29, 0 }, { 43, 0 }, { 58, 0 }, { 72, 0 }, { 87, 0 }, { 101, 0 }, { 116, 0 }, { 130, 0 }, { 145, 0 }, { 159, 0 }, { 173, 0 }, { 195, 0 }, { 224, 0 },
{{0|(11<<4)}, {144.5, 0}, 0}, // k52 KC_0 { 4, 16 }, { 22, 16 }, { 36, 16 }, { 51, 16 }, { 65, 16 }, { 80, 16 }, { 94, 16 }, { 108, 16 }, { 123, 16 }, { 137, 16 }, { 152, 16 }, { 166, 16 }, { 181, 16 }, { 199, 16 }, { 224, 16 },
{{0|(12<<4)}, {159, 0}, 0}, // k53 KC_MINS { 5, 32 }, { 25, 32 }, { 40, 32 }, { 54, 32 }, { 69, 32 }, { 83, 32 }, { 98, 32 }, { 112, 32 }, { 126, 32 }, { 141, 32 }, { 155, 32 }, { 170, 32 }, { 184, 32 },
{{0|(13<<4)}, {173.4, 0}, 0}, // k54 KC_EQL { 16, 48 }, { 33, 48 }, { 47, 48 }, { 61, 48 }, { 76, 48 }, { 90, 48 }, { 105, 48 }, { 119, 48 }, { 134, 48 }, { 148, 48 }, { 163, 48 }, { 188, 48 }, { 210, 48 },
{{0|(14<<4)}, {195.1, 0}, 1}, // k55 KC_BSPC { 9, 64 }, { 27, 64 }, { 45, 64 }, { 60, 64 }, { 74, 64 }, { 88, 64 }, { 103, 64 }, { 117, 64 }, { 136, 64 }, { 154, 64 }, { 168, 64 }, { 186, 64 }, { 195, 64 }, { 210, 64 }, { 224, 64 }
{{0|(15<<4)}, {224, 0}, 1}, // k57 KC_PGUP }, {
// LED Index to Flag
{{1|(0<<4)}, {3.6125, 16}, 1}, // k10 KC_TAB 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1,
{{1|(1<<4)}, {21.675, 16}, 0}, // k11 KC_Q 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1,
{{1|(2<<4)}, {36.125, 16}, 0}, // k12 KC_W 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1,
{{1|(3<<4)}, {50.575, 16}, 0}, // k13 KC_E 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1,
{{1|(4<<4)}, {65.025, 16}, 0}, // k14 KC_R 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
{{1|(5<<4)}, {79.475, 16}, 0}, // k15 KC_T }
{{1|(6<<4)}, {93.925, 16}, 0}, // k16 KC_Y
{{1|(7<<4)}, {108.375, 16}, 0}, // k17 KC_U
{{1|(8<<4)}, {122.825, 16}, 0}, // k60 KC_I
{{1|(9<<4)}, {137.275, 16}, 0}, // k61 KC_O
{{1|(10<<4)}, {151.725, 16}, 0}, // k62 KC_P
{{1|(11<<4)}, {166.175, 16}, 0}, // k63 KC_LBRC
{{1|(12<<4)}, {180.625, 16}, 0}, // k64 KC_RBRC
{{1|(13<<4)}, {198.6875, 16}, 1}, // k65 KC_BSLS
{{1|(14<<4)}, {224, 16}, 1}, // k67 KC_PGDN
{{2|(0<<4)}, {5.41875, 32}, 1}, // k20 KC_CAPS
{{2|(1<<4)}, {25.2875, 32}, 0}, // k21 KC_A
{{2|(2<<4)}, {39.7375, 32}, 0}, // k22 KC_S
{{2|(3<<4)}, {54.1875, 32}, 0}, // k23 KC_D
{{2|(4<<4)}, {68.6375, 32}, 0}, // k24 KC_F
{{2|(5<<4)}, {83.0875, 32}, 0}, // k25 KC_G
{{2|(6<<4)}, {97.5375, 32}, 0}, // k26 KC_H
{{2|(7<<4)}, {111.9875, 32}, 0}, // k27 KC_J
{{2|(8<<4)}, {126.4375, 32}, 0}, // k70 KC_K
{{2|(9<<4)}, {140.8875, 32}, 0}, // k71 KC_L
{{2|(10<<4)}, {155.3375, 32}, 0}, // k72 KC_SCLN
{{2|(11<<4)}, {169.7875, 32}, 0}, // k73 KC_QUOT
{{2|(12<<4)}, {184.2375, 32}, 1}, // k75 KC_ENT
{{3|(0<<4)}, {16.25625, 48}, 1}, // k30 KC_LSFT
{{3|(1<<4)}, {32.5125, 48}, 0}, // k32 KC_Z
{{3|(2<<4)}, {46.9625, 48}, 0}, // k33 KC_X
{{3|(3<<4)}, {61.4125, 48}, 0}, // k34 KC_C
{{3|(4<<4)}, {75.8625, 48}, 0}, // k35 KC_V
{{3|(5<<4)}, {90.3125, 48}, 0}, // k36 KC_B
{{3|(6<<4)}, {104.7625, 48}, 0}, // k37 KC_N
{{3|(7<<4)}, {119.2125, 48}, 0}, // k80 KC_M
{{3|(8<<4)}, {133.6625, 48}, 0}, // k81 KC_COMM
{{3|(9<<4)}, {148.1125, 48}, 0}, // k82 KC_DOT
{{3|(10<<4)}, {162.5625, 48}, 0}, // k83 KC_SLSH
{{3|(11<<4)}, {187.85, 48}, 1}, // k85 KC_RSFT
{{3|(12<<4)}, {209.525, 48}, 1}, // k86 KC_UP
{{4|(0<<4)}, {9.03125, 64}, 1}, // k40 KC_LCTL
{{4|(1<<4)}, {27.09375, 64}, 1}, // k41 KC_LGUI
{{4|(2<<4)}, {45.15625, 64}, 1}, // k42 KC_LALT
{{4|(3<<4)}, {59.45, 64}, 1}, // Unassociated between LALT and SPACE_2.75
{{4|(4<<4)}, {73.9, 64}, 1}, // k45 KC_SPC SPACE_2.75
{{4|(5<<4)}, {88.35, 64}, 1}, // k45 KC_SPC SPACE_6.25
{{4|(6<<4)}, {102.8, 64}, 1}, // k46 KC_SPC SPACE_2.25
{{4|(7<<4)}, {117.40625, 64}, 1}, // Unassociated between SPACE_2.25 and SPACE_2.75
{{4|(8<<4)}, {135.46875, 64}, 1}, // k90 KC_RGUI
{{4|(9<<4)}, {153.53125, 64}, 1}, // k92 KC_RALT
{{4|(10<<4)}, {167.98125, 64}, 1}, // k93 MO(_FL)
{{4|(11<<4)}, {186.04375, 64}, 1}, // k94 KC_RCTL
{{4|(12<<4)}, {195.075, 64}, 1}, // k95 KC_LEFT
{{4|(13<<4)}, {209.525, 64}, 1}, // k96 KC_DOWN
{{4|(14<<4)}, {224, 64}, 1} // k97 KC_RGHT
}; };
#endif #endif

View File

@ -27,7 +27,7 @@
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
led_config_t led_matrix_config; led_eeconfig_t led_matrix_eeconfig;
#ifndef MAX #ifndef MAX
# define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) # define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
@ -70,40 +70,32 @@ void eeconfig_update_led_matrix(uint32_t config_value) { eeprom_update_dword(EEC
void eeconfig_update_led_matrix_default(void) { void eeconfig_update_led_matrix_default(void) {
dprintf("eeconfig_update_led_matrix_default\n"); dprintf("eeconfig_update_led_matrix_default\n");
led_matrix_config.enable = 1; led_matrix_eeconfig.enable = 1;
led_matrix_config.mode = LED_MATRIX_UNIFORM_BRIGHTNESS; led_matrix_eeconfig.mode = LED_MATRIX_UNIFORM_BRIGHTNESS;
led_matrix_config.val = 128; led_matrix_eeconfig.val = 128;
led_matrix_config.speed = 0; led_matrix_eeconfig.speed = 0;
eeconfig_update_led_matrix(led_matrix_config.raw); eeconfig_update_led_matrix(led_matrix_eeconfig.raw);
} }
void eeconfig_debug_led_matrix(void) { void eeconfig_debug_led_matrix(void) {
dprintf("led_matrix_config eeprom\n"); dprintf("led_matrix_eeconfig eeprom\n");
dprintf("led_matrix_config.enable = %d\n", led_matrix_config.enable); dprintf("led_matrix_eeconfig.enable = %d\n", led_matrix_eeconfig.enable);
dprintf("led_matrix_config.mode = %d\n", led_matrix_config.mode); dprintf("led_matrix_eeconfig.mode = %d\n", led_matrix_eeconfig.mode);
dprintf("led_matrix_config.val = %d\n", led_matrix_config.val); dprintf("led_matrix_eeconfig.val = %d\n", led_matrix_eeconfig.val);
dprintf("led_matrix_config.speed = %d\n", led_matrix_config.speed); dprintf("led_matrix_eeconfig.speed = %d\n", led_matrix_eeconfig.speed);
} }
// Last led hit
#ifndef LED_HITS_TO_REMEMBER
# define LED_HITS_TO_REMEMBER 8
#endif
uint8_t g_last_led_hit[LED_HITS_TO_REMEMBER] = {255}; uint8_t g_last_led_hit[LED_HITS_TO_REMEMBER] = {255};
uint8_t g_last_led_count = 0; uint8_t g_last_led_count = 0;
void map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i, uint8_t *led_count) { uint8_t map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i) {
led_matrix led; uint8_t led_count = 0;
*led_count = 0; uint8_t led_index = g_led_config.matrix_co[row][column];
if (led_index != NO_LED) {
for (uint8_t i = 0; i < LED_DRIVER_LED_COUNT; i++) { led_i[led_count] = led_index;
// map_index_to_led(i, &led); led_count++;
led = g_leds[i];
if (row == led.matrix_co.row && column == led.matrix_co.col) {
led_i[*led_count] = i;
(*led_count)++;
}
} }
return led_count;
} }
void led_matrix_update_pwm_buffers(void) { led_matrix_driver.flush(); } void led_matrix_update_pwm_buffers(void) { led_matrix_driver.flush(); }
@ -114,8 +106,8 @@ void led_matrix_set_index_value_all(uint8_t value) { led_matrix_driver.set_value
bool process_led_matrix(uint16_t keycode, keyrecord_t *record) { bool process_led_matrix(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed) { if (record->event.pressed) {
uint8_t led[8], led_count; uint8_t led[8];
map_row_column_to_led(record->event.key.row, record->event.key.col, led, &led_count); uint8_t led_count = map_row_column_to_led(record->event.key.row, record->event.key.col, led);
if (led_count > 0) { if (led_count > 0) {
for (uint8_t i = LED_HITS_TO_REMEMBER; i > 1; i--) { for (uint8_t i = LED_HITS_TO_REMEMBER; i > 1; i--) {
g_last_led_hit[i - 1] = g_last_led_hit[i - 2]; g_last_led_hit[i - 1] = g_last_led_hit[i - 2];
@ -127,8 +119,8 @@ bool process_led_matrix(uint16_t keycode, keyrecord_t *record) {
g_any_key_hit = 0; g_any_key_hit = 0;
} else { } else {
#ifdef LED_MATRIX_KEYRELEASES #ifdef LED_MATRIX_KEYRELEASES
uint8_t led[8], led_count; uint8_t led[8];
map_row_column_to_led(record->event.key.row, record->event.key.col, led, &led_count); uint8_t led_count = map_row_column_to_led(record->event.key.row, record->event.key.col, led);
for (uint8_t i = 0; i < led_count; i++) g_key_hit[led[i]] = 255; for (uint8_t i = 0; i < led_count; i++) g_key_hit[led[i]] = 255;
g_any_key_hit = 255; g_any_key_hit = 255;
@ -143,12 +135,12 @@ void led_matrix_set_suspend_state(bool state) { g_suspend_state = state; }
void led_matrix_all_off(void) { led_matrix_set_index_value_all(0); } void led_matrix_all_off(void) { led_matrix_set_index_value_all(0); }
// Uniform brightness // Uniform brightness
void led_matrix_uniform_brightness(void) { led_matrix_set_index_value_all(LED_MATRIX_MAXIMUM_BRIGHTNESS / BACKLIGHT_LEVELS * led_matrix_config.val); } void led_matrix_uniform_brightness(void) { led_matrix_set_index_value_all(LED_MATRIX_MAXIMUM_BRIGHTNESS / BACKLIGHT_LEVELS * led_matrix_eeconfig.val); }
void led_matrix_custom(void) {} void led_matrix_custom(void) {}
void led_matrix_task(void) { void led_matrix_task(void) {
if (!led_matrix_config.enable) { if (!led_matrix_eeconfig.enable) {
led_matrix_all_off(); led_matrix_all_off();
led_matrix_indicators(); led_matrix_indicators();
return; return;
@ -170,7 +162,7 @@ void led_matrix_task(void) {
// Ideally we would also stop sending zeros to the LED driver PWM buffers // Ideally we would also stop sending zeros to the LED driver PWM buffers
// while suspended and just do a software shutdown. This is a cheap hack for now. // while suspended and just do a software shutdown. This is a cheap hack for now.
bool suspend_backlight = ((g_suspend_state && LED_DISABLE_WHEN_USB_SUSPENDED) || (LED_DISABLE_AFTER_TIMEOUT > 0 && g_any_key_hit > LED_DISABLE_AFTER_TIMEOUT * 60 * 20)); bool suspend_backlight = ((g_suspend_state && LED_DISABLE_WHEN_USB_SUSPENDED) || (LED_DISABLE_AFTER_TIMEOUT > 0 && g_any_key_hit > LED_DISABLE_AFTER_TIMEOUT * 60 * 20));
uint8_t effect = suspend_backlight ? 0 : led_matrix_config.mode; uint8_t effect = suspend_backlight ? 0 : led_matrix_eeconfig.mode;
// this gets ticked at 20 Hz. // this gets ticked at 20 Hz.
// each effect can opt to do calculations // each effect can opt to do calculations
@ -211,8 +203,8 @@ __attribute__((weak)) void led_matrix_indicators_user(void) {}
// else // else
// { // {
// // This needs updated to something like // // This needs updated to something like
// // uint8_t led[8], led_count; // // uint8_t led[8];
// // map_row_column_to_led(row,column,led,&led_count); // // uint8_t led_count = map_row_column_to_led(row, column, led);
// // for(uint8_t i = 0; i < led_count; i++) // // for(uint8_t i = 0; i < led_count; i++)
// map_row_column_to_led(row, column, index); // map_row_column_to_led(row, column, index);
// } // }
@ -235,12 +227,12 @@ void led_matrix_init(void) {
eeconfig_update_led_matrix_default(); eeconfig_update_led_matrix_default();
} }
led_matrix_config.raw = eeconfig_read_led_matrix(); led_matrix_eeconfig.raw = eeconfig_read_led_matrix();
if (!led_matrix_config.mode) { if (!led_matrix_eeconfig.mode) {
dprintf("led_matrix_init_drivers led_matrix_config.mode = 0. Write default values to EEPROM.\n"); dprintf("led_matrix_init_drivers led_matrix_eeconfig.mode = 0. Write default values to EEPROM.\n");
eeconfig_update_led_matrix_default(); eeconfig_update_led_matrix_default();
led_matrix_config.raw = eeconfig_read_led_matrix(); led_matrix_eeconfig.raw = eeconfig_read_led_matrix();
} }
eeconfig_debug_led_matrix(); // display current eeprom values eeconfig_debug_led_matrix(); // display current eeprom values
@ -270,8 +262,8 @@ static uint8_t decrement(uint8_t value, uint8_t step, uint8_t min, uint8_t max)
// } // }
// void backlight_set_key_value(uint8_t row, uint8_t column, uint8_t value) { // void backlight_set_key_value(uint8_t row, uint8_t column, uint8_t value) {
// uint8_t led[8], led_count; // uint8_t led[8];
// map_row_column_to_led(row,column,led,&led_count); // uint8_t led_count = map_row_column_to_led(row, column, led);
// for(uint8_t i = 0; i < led_count; i++) { // for(uint8_t i = 0; i < led_count; i++) {
// if (led[i] < LED_DRIVER_LED_COUNT) { // if (led[i] < LED_DRIVER_LED_COUNT) {
// void *address = backlight_get_custom_key_value_eeprom_address(led[i]); // void *address = backlight_get_custom_key_value_eeprom_address(led[i]);
@ -283,74 +275,74 @@ static uint8_t decrement(uint8_t value, uint8_t step, uint8_t min, uint8_t max)
uint32_t led_matrix_get_tick(void) { return g_tick; } uint32_t led_matrix_get_tick(void) { return g_tick; }
void led_matrix_toggle(void) { void led_matrix_toggle(void) {
led_matrix_config.enable ^= 1; led_matrix_eeconfig.enable ^= 1;
eeconfig_update_led_matrix(led_matrix_config.raw); eeconfig_update_led_matrix(led_matrix_eeconfig.raw);
} }
void led_matrix_enable(void) { void led_matrix_enable(void) {
led_matrix_config.enable = 1; led_matrix_eeconfig.enable = 1;
eeconfig_update_led_matrix(led_matrix_config.raw); eeconfig_update_led_matrix(led_matrix_eeconfig.raw);
} }
void led_matrix_enable_noeeprom(void) { led_matrix_config.enable = 1; } void led_matrix_enable_noeeprom(void) { led_matrix_eeconfig.enable = 1; }
void led_matrix_disable(void) { void led_matrix_disable(void) {
led_matrix_config.enable = 0; led_matrix_eeconfig.enable = 0;
eeconfig_update_led_matrix(led_matrix_config.raw); eeconfig_update_led_matrix(led_matrix_eeconfig.raw);
} }
void led_matrix_disable_noeeprom(void) { led_matrix_config.enable = 0; } void led_matrix_disable_noeeprom(void) { led_matrix_eeconfig.enable = 0; }
void led_matrix_step(void) { void led_matrix_step(void) {
led_matrix_config.mode++; led_matrix_eeconfig.mode++;
if (led_matrix_config.mode >= LED_MATRIX_EFFECT_MAX) { if (led_matrix_eeconfig.mode >= LED_MATRIX_EFFECT_MAX) {
led_matrix_config.mode = 1; led_matrix_eeconfig.mode = 1;
} }
eeconfig_update_led_matrix(led_matrix_config.raw); eeconfig_update_led_matrix(led_matrix_eeconfig.raw);
} }
void led_matrix_step_reverse(void) { void led_matrix_step_reverse(void) {
led_matrix_config.mode--; led_matrix_eeconfig.mode--;
if (led_matrix_config.mode < 1) { if (led_matrix_eeconfig.mode < 1) {
led_matrix_config.mode = LED_MATRIX_EFFECT_MAX - 1; led_matrix_eeconfig.mode = LED_MATRIX_EFFECT_MAX - 1;
} }
eeconfig_update_led_matrix(led_matrix_config.raw); eeconfig_update_led_matrix(led_matrix_eeconfig.raw);
} }
void led_matrix_increase_val(void) { void led_matrix_increase_val(void) {
led_matrix_config.val = increment(led_matrix_config.val, 8, 0, LED_MATRIX_MAXIMUM_BRIGHTNESS); led_matrix_eeconfig.val = increment(led_matrix_eeconfig.val, 8, 0, LED_MATRIX_MAXIMUM_BRIGHTNESS);
eeconfig_update_led_matrix(led_matrix_config.raw); eeconfig_update_led_matrix(led_matrix_eeconfig.raw);
} }
void led_matrix_decrease_val(void) { void led_matrix_decrease_val(void) {
led_matrix_config.val = decrement(led_matrix_config.val, 8, 0, LED_MATRIX_MAXIMUM_BRIGHTNESS); led_matrix_eeconfig.val = decrement(led_matrix_eeconfig.val, 8, 0, LED_MATRIX_MAXIMUM_BRIGHTNESS);
eeconfig_update_led_matrix(led_matrix_config.raw); eeconfig_update_led_matrix(led_matrix_eeconfig.raw);
} }
void led_matrix_increase_speed(void) { void led_matrix_increase_speed(void) {
led_matrix_config.speed = increment(led_matrix_config.speed, 1, 0, 3); led_matrix_eeconfig.speed = increment(led_matrix_eeconfig.speed, 1, 0, 3);
eeconfig_update_led_matrix(led_matrix_config.raw); // EECONFIG needs to be increased to support this eeconfig_update_led_matrix(led_matrix_eeconfig.raw); // EECONFIG needs to be increased to support this
} }
void led_matrix_decrease_speed(void) { void led_matrix_decrease_speed(void) {
led_matrix_config.speed = decrement(led_matrix_config.speed, 1, 0, 3); led_matrix_eeconfig.speed = decrement(led_matrix_eeconfig.speed, 1, 0, 3);
eeconfig_update_led_matrix(led_matrix_config.raw); // EECONFIG needs to be increased to support this eeconfig_update_led_matrix(led_matrix_eeconfig.raw); // EECONFIG needs to be increased to support this
} }
void led_matrix_mode(uint8_t mode, bool eeprom_write) { void led_matrix_mode(uint8_t mode, bool eeprom_write) {
led_matrix_config.mode = mode; led_matrix_eeconfig.mode = mode;
if (eeprom_write) { if (eeprom_write) {
eeconfig_update_led_matrix(led_matrix_config.raw); eeconfig_update_led_matrix(led_matrix_eeconfig.raw);
} }
} }
uint8_t led_matrix_get_mode(void) { return led_matrix_config.mode; } uint8_t led_matrix_get_mode(void) { return led_matrix_eeconfig.mode; }
void led_matrix_set_value_noeeprom(uint8_t val) { led_matrix_config.val = val; } void led_matrix_set_value_noeeprom(uint8_t val) { led_matrix_eeconfig.val = val; }
void led_matrix_set_value(uint8_t val) { void led_matrix_set_value(uint8_t val) {
led_matrix_set_value_noeeprom(val); led_matrix_set_value_noeeprom(val);
eeconfig_update_led_matrix(led_matrix_config.raw); eeconfig_update_led_matrix(led_matrix_eeconfig.raw);
} }
void backlight_set(uint8_t val) { led_matrix_set_value(val); } void backlight_set(uint8_t val) { led_matrix_set_value(val); }

View File

@ -19,46 +19,12 @@
#pragma once #pragma once
#include "led_matrix_types.h"
#ifndef BACKLIGHT_ENABLE #ifndef BACKLIGHT_ENABLE
# error You must define BACKLIGHT_ENABLE with LED_MATRIX_ENABLE # error You must define BACKLIGHT_ENABLE with LED_MATRIX_ENABLE
#endif #endif
typedef struct Point {
uint8_t x;
uint8_t y;
} __attribute__((packed)) Point;
typedef struct led_matrix {
union {
uint8_t raw;
struct {
uint8_t row : 4; // 16 max
uint8_t col : 4; // 16 max
};
} matrix_co;
Point point;
uint8_t modifier : 1;
} __attribute__((packed)) led_matrix;
extern const led_matrix g_leds[LED_DRIVER_LED_COUNT];
typedef struct {
uint8_t index;
uint8_t value;
} led_indicator;
typedef union {
uint32_t raw;
struct {
bool enable : 1;
uint8_t mode : 6;
uint8_t hue : 8; // Unused by led_matrix
uint8_t sat : 8; // Unused by led_matrix
uint8_t val : 8;
uint8_t speed : 8; // EECONFIG needs to be increased to support this
};
} led_config_t;
enum led_matrix_effects { enum led_matrix_effects {
LED_MATRIX_UNIFORM_BRIGHTNESS = 1, LED_MATRIX_UNIFORM_BRIGHTNESS = 1,
// All new effects go above this line // All new effects go above this line
@ -122,3 +88,7 @@ typedef struct {
} led_matrix_driver_t; } led_matrix_driver_t;
extern const led_matrix_driver_t led_matrix_driver; extern const led_matrix_driver_t led_matrix_driver;
extern led_eeconfig_t led_matrix_eeconfig;
extern led_config_t g_led_config;

View File

@ -0,0 +1,69 @@
/* Copyright 2021
*
* 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/>.
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#if defined(__GNUC__)
# define PACKED __attribute__((__packed__))
#else
# define PACKED
#endif
#if defined(_MSC_VER)
# pragma pack(push, 1)
#endif
// Last led hit
#ifndef LED_HITS_TO_REMEMBER
# define LED_HITS_TO_REMEMBER 8
#endif // LED_HITS_TO_REMEMBER
typedef struct PACKED {
uint8_t x;
uint8_t y;
} point_t;
#define LED_FLAG_ALL 0xFF
#define LED_FLAG_NONE 0x00
#define LED_FLAG_MODIFIER 0x01
#define LED_FLAG_KEYLIGHT 0x04
#define LED_FLAG_INDICATOR 0x08
#define NO_LED 255
typedef struct PACKED {
uint8_t matrix_co[MATRIX_ROWS][MATRIX_COLS];
point_t point[LED_DRIVER_LED_COUNT];
uint8_t flags[LED_DRIVER_LED_COUNT];
} led_config_t;
typedef union {
uint32_t raw;
struct PACKED {
uint8_t enable : 2;
uint8_t mode : 6;
uint16_t reserved;
uint8_t val;
uint8_t speed; // EECONFIG needs to be increased to support this
};
} led_eeconfig_t;
#if defined(_MSC_VER)
# pragma pack(pop)
#endif

View File

@ -1,3 +1,19 @@
/* Copyright 2021
*
* 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/>.
*/
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>