qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

wt_rgb_backlight.c (112215B)


      1 /* Copyright 2017 Jason Williams (Wilba)
      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 
     17 #if defined(RGB_BACKLIGHT_ZEAL60) || \
     18     defined(RGB_BACKLIGHT_ZEAL65) || \
     19     defined(RGB_BACKLIGHT_M60_A) || \
     20     defined(RGB_BACKLIGHT_M6_B) || \
     21     defined(RGB_BACKLIGHT_M10_C) || \
     22     defined(RGB_BACKLIGHT_KOYU) || \
     23     defined(RGB_BACKLIGHT_M65_B) || \
     24     defined(RGB_BACKLIGHT_M65_BX) || \
     25     defined(RGB_BACKLIGHT_HS60) || \
     26     defined(RGB_BACKLIGHT_NK65) || \
     27     defined(RGB_BACKLIGHT_NK87) || \
     28     defined(RGB_BACKLIGHT_KW_MEGA) || \
     29     defined(RGB_BACKLIGHT_NEBULA12) || \
     30     defined(RGB_BACKLIGHT_NEBULA68) || \
     31     defined(RGB_BACKLIGHT_U80_A) || \
     32     defined(RGB_BACKLIGHT_DAWN60) || \
     33     defined(RGB_BACKLIGHT_PORTICO) || \
     34 	defined(RGB_BACKLIGHT_PORTICO75) || \
     35     defined(RGB_BACKLIGHT_WT60_B) || \
     36     defined(RGB_BACKLIGHT_WT60_BX) || \
     37     defined(RGB_BACKLIGHT_WT60_C) || \
     38     defined(RGB_BACKLIGHT_M50_A)
     39 #else
     40 #error wt_rgb_backlight.c compiled without setting configuration symbol
     41 #endif
     42 
     43 #include "wt_rgb_backlight.h"
     44 #include "wt_rgb_backlight_api.h"
     45 #include "wt_rgb_backlight_keycodes.h"
     46 
     47 #include <stdlib.h>
     48 #include "quantum.h"
     49 #include "host.h"
     50 #include "util.h"
     51 
     52 #if !defined(RGB_BACKLIGHT_HS60) && !defined(RGB_BACKLIGHT_NK65) && !defined(RGB_BACKLIGHT_NK87) && !defined(RGB_BACKLIGHT_NEBULA68) && !defined(RGB_BACKLIGHT_NEBULA12) && !defined (RGB_BACKLIGHT_KW_MEGA)
     53 #include <avr/interrupt.h>
     54 #include "i2c_master.h"
     55 #else
     56 #include <ch.h>
     57 #include <hal.h>
     58 #include "i2c_master.h"
     59 #endif
     60 
     61 #if defined(RGB_BACKLIGHT_DAWN60)
     62 #include "ws2812.h"
     63 #endif
     64 
     65 #include "progmem.h"
     66 #include "quantum/color.h"
     67 #include "eeprom.h"
     68 
     69 #include "nvm_eeprom_eeconfig_internal.h" // expose EEPROM addresses, no appetite to move legacy/deprecated code to nvm
     70 #include "nvm_eeprom_via_internal.h" // expose EEPROM addresses, no appetite to move legacy/deprecated code to nvm
     71 #include "via.h" // uses EEPROM address, lighting value IDs
     72 #define RGB_BACKLIGHT_CONFIG_EEPROM_ADDR (VIA_EEPROM_CUSTOM_CONFIG_ADDR)
     73 
     74 #if VIA_EEPROM_CUSTOM_CONFIG_SIZE == 0
     75 #error VIA_EEPROM_CUSTOM_CONFIG_SIZE was not defined to store backlight_config struct
     76 #endif
     77 
     78 #if defined(RGB_BACKLIGHT_M6_B)
     79 #include "drivers/led/issi/is31fl3218.h"
     80 #define BACKLIGHT_LED_COUNT 6
     81 #elif defined(RGB_BACKLIGHT_HS60)
     82 #include "drivers/led/issi/is31fl3733.h"
     83 #define BACKLIGHT_LED_COUNT 64
     84 #elif defined(RGB_BACKLIGHT_NK65) || defined(RGB_BACKLIGHT_NEBULA68) || defined(RGB_BACKLIGHT_KW_MEGA)
     85 #include "drivers/led/issi/is31fl3733.h"
     86 #define BACKLIGHT_LED_COUNT 69
     87 #elif defined(RGB_BACKLIGHT_NK87)
     88 #include "drivers/led/issi/is31fl3733.h"
     89 #define BACKLIGHT_LED_COUNT 128
     90 #elif defined(RGB_BACKLIGHT_PORTICO75)
     91 #include "drivers/led/issi/is31fl3741.h"
     92 #define BACKLIGHT_LED_COUNT 98
     93 #else
     94 #include "drivers/led/issi/is31fl3731.h"
     95 #if defined(RGB_BACKLIGHT_U80_A)
     96 #define BACKLIGHT_LED_COUNT 108
     97 #elif defined(RGB_BACKLIGHT_DAWN60)
     98 #define BACKLIGHT_LED_COUNT 84  //64 + 20
     99 #elif defined(RGB_BACKLIGHT_PORTICO)
    100 #define BACKLIGHT_LED_COUNT 67  //36 + 31
    101 #elif defined(RGB_BACKLIGHT_NEBULA12)
    102 #define BACKLIGHT_LED_COUNT 16
    103 #elif defined(RGB_BACKLIGHT_M10_C)
    104 #define BACKLIGHT_LED_COUNT 12
    105 #else
    106 #define BACKLIGHT_LED_COUNT 72
    107 #endif
    108 #endif
    109 
    110 #define BACKLIGHT_EFFECT_MAX 10
    111 
    112 backlight_config g_config = {
    113     .use_split_backspace = RGB_BACKLIGHT_USE_SPLIT_BACKSPACE,
    114     .use_split_left_shift = RGB_BACKLIGHT_USE_SPLIT_LEFT_SHIFT,
    115     .use_split_right_shift = RGB_BACKLIGHT_USE_SPLIT_RIGHT_SHIFT,
    116     .use_7u_spacebar = RGB_BACKLIGHT_USE_7U_SPACEBAR,
    117     .use_iso_enter = RGB_BACKLIGHT_USE_ISO_ENTER,
    118     .disable_hhkb_blocker_leds = RGB_BACKLIGHT_DISABLE_HHKB_BLOCKER_LEDS,
    119     .disable_when_usb_suspended = RGB_BACKLIGHT_DISABLE_WHEN_USB_SUSPENDED,
    120     .disable_after_timeout = RGB_BACKLIGHT_DISABLE_AFTER_TIMEOUT,
    121     .brightness = RGB_BACKLIGHT_BRIGHTNESS,
    122     .effect = RGB_BACKLIGHT_EFFECT,
    123     .effect_speed = RGB_BACKLIGHT_EFFECT_SPEED,
    124     .color_1 = RGB_BACKLIGHT_COLOR_1,
    125     .color_2 = RGB_BACKLIGHT_COLOR_2,
    126     .caps_lock_indicator = RGB_BACKLIGHT_CAPS_LOCK_INDICATOR,
    127     .layer_1_indicator = RGB_BACKLIGHT_LAYER_1_INDICATOR,
    128     .layer_2_indicator = RGB_BACKLIGHT_LAYER_2_INDICATOR,
    129     .layer_3_indicator = RGB_BACKLIGHT_LAYER_3_INDICATOR,
    130     .alphas_mods = {
    131         RGB_BACKLIGHT_ALPHAS_MODS_ROW_0,
    132         RGB_BACKLIGHT_ALPHAS_MODS_ROW_1,
    133         RGB_BACKLIGHT_ALPHAS_MODS_ROW_2,
    134         RGB_BACKLIGHT_ALPHAS_MODS_ROW_3,
    135         RGB_BACKLIGHT_ALPHAS_MODS_ROW_4 },
    136 #if defined(RGB_BACKLIGHT_M6_B)
    137     .custom_color = { { 0, 255 }, { 43, 255 }, { 85, 255 }, { 128, 255 }, { 171, 255 }, { 213, 255 } }
    138 #elif defined(RGB_BACKLIGHT_M10_C)
    139     .custom_color = { { 0, 255 }, { 43, 255 }, { 85, 255 }, { 128, 255 }, { 171, 255 }, { 213, 255 }, { 0, 255 }, { 43, 255 }, { 85, 255 }, { 128, 255 } }
    140 #endif
    141 };
    142 
    143 bool g_suspend_state = false;
    144 
    145 // Global tick at 20 Hz
    146 uint32_t g_tick = 0;
    147 
    148 // Ticks since this key was last hit.
    149 uint8_t g_key_hit[BACKLIGHT_LED_COUNT];
    150 
    151 // Ticks since any key was last hit.
    152 uint32_t g_any_key_hit = 0;
    153 
    154 typedef struct Point {
    155     uint8_t x;
    156     uint8_t y;
    157 } Point;
    158 
    159 
    160 // index in range 0..71 (LA0..LA17, LB0..LB17, LC0..LC17, LD0..LD17)
    161 // point values in range x=0..224 y=0..64
    162 // origin is center of top-left key (i.e Esc)
    163 #if defined(RGB_BACKLIGHT_ZEAL65)
    164 const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
    165     // LA0..LA17
    166     {120,16}, {104,16}, {88,16}, {72,16}, {56,16}, {40,16}, {24,16}, {4,16}, {4,32},
    167     {128,0}, {112,0}, {96,0}, {80,0}, {64,0}, {48,0}, {32,0}, {16,0}, {0,0},
    168     // LB0..LB17
    169     {144,0}, {160,0}, {176,0}, {192,0}, {216,0}, {224,0}, {240,0}, {240,16}, {240,32},
    170     {136,16}, {152,16}, {168,16}, {184,16}, {200,16}, {220,16}, {240,48}, {240,64}, {224,64},
    171     // LC0..LC17
    172     {96,64}, {100,48}, {84,48}, {68,48}, {52,48}, {36,48}, {255,255}, {48,60}, {28,64},
    173     {108,32}, {92,32}, {76,32}, {60,32}, {44,32}, {28,32}, {20,44}, {10,48}, {4,64},
    174     // LD0..LD17
    175     {124,32}, {140,32}, {156,32}, {172,32}, {188,32}, {214,32}, {180,48}, {202,48}, {224,48},
    176     {116,48}, {132,48}, {148,48}, {164,48}, {255,255}, {144,60}, {164,64}, {188,64}, {208,64}
    177 };
    178 const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
    179     // LA0..LA17
    180     {64,128}, {75,132}, {84,145}, {91,164}, {97,187}, {102,213}, {105,242}, {109,255}, {128,243},
    181     {61,255}, {67,255}, {72,255}, {77,255}, {82,255}, {86,255}, {90,255}, {93,255}, {96,255},
    182     // LB0..LB17
    183     {56,255}, {51,255}, {46,255}, {42,255}, {37,255}, {35,255}, {32,255}, {19,255}, {0,255},
    184     {53,132}, {44,145}, {37,164}, {31,187}, {26,213}, {22,249}, {237,255}, {224,255}, {221,255},
    185     // LC0..LC17
    186     {184,255}, {179,135}, {170,149}, {163,169}, {157,193}, {153,220}, {255,255}, {167,255}, {165,255},
    187     {128,26}, {128,60}, {128,94}, {128,128}, {128,162}, {128,196}, {145,233}, {148,255}, {161,255},
    188     // LD0..LD17
    189     {0,9}, {0,43}, {0,77}, {0,111}, {0,145}, {0,201}, {224,181}, {230,217}, {235,255},
    190     {189,128}, {200,131}, {210,141}, {218,159}, {255,255}, {201,228}, {206,255}, {213,255}, {218,255}
    191 };
    192 #elif defined(RGB_BACKLIGHT_KOYU)
    193 const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
    194     // LA0..LA17
    195     {120,16}, {104,16}, {88,16}, {72,16}, {56,16}, {40,16}, {24,16}, {4,16}, {4,32},
    196     {128,0}, {112,0}, {96,0}, {80,0}, {64,0}, {48,0}, {32,0}, {16,0}, {0,0},
    197     // LB0..LB17
    198     {144,0}, {160,0}, {176,0}, {192,0}, {208,0}, {224,0}, {240,0}, {240,16}, {240,32},
    199     {136,16}, {152,16}, {168,16}, {184,16}, {200,16}, {220,16}, {240,48}, {240,64}, {224,64},
    200     // LC0..LC17
    201     {112,64}, {100,48}, {84,48}, {68,48}, {52,48}, {36,48}, {64,60}, {44,60}, {24,64},
    202     {108,32}, {92,32}, {76,32}, {60,32}, {44,32}, {28,32}, {255,255}, {10,48}, {4,64},
    203     // LD0..LD1762
    204 
    205     {124,32}, {140,32}, {156,32}, {172,32}, {188,32}, {214,32}, {180,48}, {202,48}, {224,48},
    206     {116,48}, {132,48}, {148,48}, {164,48}, {255,255}, {160,60}, {180,64}, {208,64}, {255,255}
    207 };
    208 const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
    209     // LA0..LA17
    210     {64,128}, {75,132}, {84,145}, {91,164}, {97,187}, {102,213}, {105,242}, {109,255}, {128,243},
    211     {61,255}, {67,255}, {72,255}, {77,255}, {82,255}, {86,255}, {90,255}, {93,255}, {96,255},
    212     // LB0..LB17
    213     {56,255}, {51,255}, {46,255}, {42,255}, {38,255}, {35,255}, {32,255}, {19,255}, {0,255},
    214     {53,132}, {44,145}, {37,164}, {31,187}, {26,213}, {22,249}, {237,255}, {224,255}, {221,255},
    215     // LC0..LC17
    216     {189,255}, {179,135}, {170,149}, {163,169}, {157,193}, {153,220}, {172,252}, {169,255}, {165,255},
    217     {128,26}, {128,60}, {128,94}, {128,128}, {128,162}, {128,196}, {255,255}, {148,255}, {161,255},
    218     // LD0..LD17
    219     {0,9}, {0,43}, {0,77}, {0,111}, {0,145}, {0,201}, {224,181}, {230,217}, {235,255},
    220     {189,128}, {200,131}, {210,141}, {218,159}, {255,255}, {207,238}, {211,255}, {218,255}, {255,255}
    221 };
    222 #elif defined(RGB_BACKLIGHT_M65_B) || defined(RGB_BACKLIGHT_M65_BX)
    223 const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
    224     // LA0..LA17
    225     {120,16}, {104,16}, {88,16}, {72,16}, {56,16}, {40,16}, {24,16}, {4,16}, {4,32},
    226     {128,0}, {112,0}, {96,0}, {80,0}, {64,0}, {48,0}, {32,0}, {16,0}, {0,0},
    227     // LB0..LB17
    228     {144,0}, {160,0}, {176,0}, {192,0}, {208,0}, {224,0}, {216,0}, {240,0}, {240,16},
    229     {136,16}, {152,16}, {168,16}, {184,16}, {200,16}, {220,16}, {240,32}, {240,48}, {240,64},
    230     // LC0..LC17
    231     {112,64}, {100,48}, {84,48}, {68,48}, {52,48}, {36,48}, {64,60}, {44,60}, {24,64},
    232     {108,32}, {92,32}, {76,32}, {60,32}, {44,32}, {28,32}, {255,255}, {10,48}, {4,64},
    233     // LD0..LD17
    234     {124,32}, {140,32}, {156,32}, {172,32}, {188,32}, {214,32}, {180,48}, {202,48}, {224,48},
    235     {116,48}, {132,48}, {148,48}, {164,48}, {255,255}, {160,60}, {180,64}, {208,64}, {224,64}
    236 };
    237 const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
    238     // LA0..LA17
    239     {64,128}, {75,132}, {84,145}, {91,164}, {97,187}, {102,213}, {105,242}, {109,255}, {128,243},
    240     {61,255}, {67,255}, {72,255}, {77,255}, {82,255}, {86,255}, {90,255}, {93,255}, {96,255},
    241     // LB0..LB17
    242     {56,255}, {51,255}, {46,255}, {42,255}, {38,255}, {35,255}, {37,255}, {32,255}, {19,255},
    243     {53,132}, {44,145}, {37,164}, {31,187}, {26,213}, {22,249}, {0,255}, {237,255}, {224,255},
    244     // LC0..LC17
    245     {189,255}, {179,135}, {170,149}, {163,169}, {157,193}, {153,220}, {172,252}, {169,255}, {165,255},
    246     {128,26}, {128,60}, {128,94}, {128,128}, {128,162}, {128,196}, {255,255}, {148,255}, {161,255},
    247     // LD0..LD17
    248     {0,9}, {0,43}, {0,77}, {0,111}, {0,145}, {0,201}, {224,181}, {230,217}, {235,255},
    249     {189,128}, {200,131}, {210,141}, {218,159}, {255,255}, {207,238}, {211,255}, {218,255}, {221,255}
    250 };
    251 #elif defined(RGB_BACKLIGHT_ZEAL60) || defined(RGB_BACKLIGHT_M60_A)
    252 const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
    253     // LA0..LA17
    254     {120,16}, {104,16}, {88,16}, {72,16}, {56,16}, {40,16}, {24,16}, {4,16}, {4,32},
    255     {128,0}, {112,0}, {96,0}, {80,0}, {64,0}, {48,0}, {32,0}, {16,0}, {0,0},
    256     // LB0..LB17
    257     {144,0}, {160,0}, {176,0}, {192,0}, {216,0}, {224,0}, {255,255}, {255,255}, {255,255},
    258     {136,16}, {152,16}, {168,16}, {184,16}, {200,16}, {220,16}, {255,255}, {255,255}, {255,255},
    259     // LC0..LC17
    260     {102,64}, {100,48}, {84,48}, {68,48}, {52,48}, {36,48}, {60,64}, {43,64}, {23,64},
    261     {108,32}, {92,32}, {76,32}, {60,32}, {44,32}, {28,32}, {20,48}, {2,48}, {3,64},
    262     // LD0..LD17
    263     {124,32}, {140,32}, {156,32}, {172,32}, {188,32}, {214,32}, {180,48}, {210,48}, {224,48},
    264     {116,48}, {132,48}, {148,48}, {164,48}, {144,64}, {161,64}, {181,64}, {201,64}, {221,64}
    265 };
    266 const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
    267     // LA0..LA17
    268     {58,129}, {70,129}, {80,139}, {89,157}, {96,181}, {101,208}, {105,238}, {109,255}, {128,247},
    269     {58,255}, {64,255}, {70,255}, {75,255}, {80,255}, {85,255}, {89,255}, {93,255}, {96,255},
    270     // LB0..LB17
    271     {53,255}, {48,255}, {43,255}, {39,255}, {34,255}, {32,255}, {255,255}, {255,255}, {255,255},
    272     {48,139}, {39,157}, {32,181}, {27,208}, {23,238}, {19,255}, {255,255}, {255,255}, {255,255},
    273     // LC0..LC17
    274     {188,255}, {183,131}, {173,143}, {165,163}, {159,188}, {154,216}, {172,252}, {170,255}, {165,255},
    275     {128,9}, {128,46}, {128,82}, {128,119}, {128,155}, {128,192}, {150,244}, {147,255}, {161,255},
    276     // LD0..LD17
    277     {0,27}, {0,64}, {0,101}, {0,137}, {0,174}, {255,233}, {228,201}, {235,255}, {237,255},
    278     {195,128}, {206,136}, {215,152}, {222,175}, {205,234}, {209,255}, {214,255}, {219,255}, {223,255}
    279 };
    280 #elif defined(RGB_BACKLIGHT_WT60_B) || defined(RGB_BACKLIGHT_WT60_BX) || defined(RGB_BACKLIGHT_WT60_C)
    281 const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
    282     // LA0..LA17
    283     {120,16}, {104,16}, {88,16}, {72,16}, {56,16}, {40,16}, {24,16}, {4,16}, {4,32},
    284     {128,0}, {112,0}, {96,0}, {80,0}, {64,0}, {48,0}, {32,0}, {16,0}, {0,0},
    285     // LB0..LB17
    286     {144,0}, {160,0}, {176,0}, {192,0}, {208,0}, {224,0}, {216,0}, {255,255}, {255,255},
    287     {136,16}, {152,16}, {168,16}, {184,16}, {200,16}, {220,16}, {255,255}, {255,255}, {255,255},
    288     // LC0..LC17
    289     {112,64}, {100,48}, {84,48}, {68,48}, {52,48}, {36,48}, {64,60}, {44,64}, {24,64},
    290     {108,32}, {92,32}, {76,32}, {60,32}, {44,32}, {28,32}, {255,255}, {10,48}, {4,64},
    291     // LD0..LD17
    292     {124,32}, {140,32}, {156,32}, {172,32}, {188,32}, {214,32}, {180,48}, {202,48}, {224,48},
    293     {116,48}, {132,48}, {148,48}, {164,48}, {255,255}, {160,60}, {180,64}, {200,64}, {220,64}
    294 };
    295 const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
    296     // LA0..LA17
    297     {58,129}, {70,129}, {80,139}, {89,157}, {96,181}, {101,208}, {105,238}, {109,255}, {128,247},
    298     {58,255}, {64,255}, {70,255}, {75,255}, {80,255}, {85,255}, {89,255}, {93,255}, {96,255},
    299     // LB0..LB17
    300     {53,255}, {48,255}, {43,255}, {39,255}, {35,255}, {32,255}, {34,255}, {255,255}, {255,255},
    301     {48,139}, {39,157}, {32,181}, {27,208}, {23,238}, {19,255}, {255,255}, {255,255}, {255,255},
    302     // LC0..LC17
    303     {192,255}, {183,131}, {173,143}, {165,163}, {159,188}, {154,216}, {173,248}, {170,255}, {165,255},
    304     {128,9}, {128,46}, {128,82}, {128,119}, {128,155}, {128,192}, {255,255}, {148,255}, {161,255},
    305     // LD0..LD17
    306     {0,27}, {0,64}, {0,101}, {0,137}, {0,174}, {0,233}, {228,201}, {235,242}, {237,255},
    307     {195,128}, {206,136}, {215,152}, {222,175}, {255,255}, {211,248}, {214,255}, {219,255}, {223,255}
    308 };
    309 #elif defined(RGB_BACKLIGHT_U80_A)
    310 const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
    311     // Thse are scaled by 14.5 per U
    312     // LA0..LA17
    313     {109,36}, {94,36}, {80,36}, {65,36}, {51,36}, {36,36}, {22,36}, {4,36}, {5,51},
    314     {116,22}, {102,22}, {87,22}, {73,22}, {58,22}, {44,22}, {29,22}, {15,22}, {0,22},
    315     // LB0..LB17
    316     {131,22}, {145,22}, {160,22}, {174,22}, {196,22}, {0,0}, {0,0}, {0,0}, {0,0},
    317     {123,36}, {138,36}, {152,36}, {167,36}, {181,36}, {199,36}, {0,0}, {0,0}, {0,0},
    318     // LC0..LC17
    319     {102,80}, {91,65}, {76,65}, {62,65}, {47,65}, {33,65}, {58,76}, {40,80}, {22,80},
    320     {98,51}, {83,51}, {69,51}, {54,51}, {40,51}, {25,51}, {0,0}, {9,65}, {4,80},
    321     // LD0..LD17
    322     {112,51}, {127,51}, {141,51}, {156,51}, {170,51}, {194,51}, {163,65}, {190,65}, {0,0},
    323     {105,65}, {120,65}, {134,65}, {149,65}, {0,0}, {145,76}, {163,80}, {181,80}, {199,80},
    324     // LE0..LE17
    325     {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0},
    326     {73,0}, {94,0}, {109,0}, {123,0}, {138,0}, {58,0}, {44,0}, {29,0}, {0,0},
    327     // LF0..LF17
    328     {160,0}, {174,0}, {189,0}, {203,0}, {225,0}, {239,0}, {254,0}, {254,22}, {254,36},
    329     {239,22}, {239,36}, {225,22}, {225,36}, {0,0}, {239,65}, {225,80}, {239,80}, {254,80}
    330 };
    331 const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
    332     // LA0..LA17
    333     {59,129}, {69,129}, {80,138}, {88,154}, {95,175}, {100,200}, {104,227}, {107,255}, {128,226},
    334     {59,255}, {64,255}, {69,255}, {75,255}, {80,255}, {84,255}, {88,255}, {91,255}, {95,255},
    335     // LB0..LB17
    336     {53,255}, {48,255}, {44,255}, {40,255}, {35,255}, {255,255}, {255,255}, {255,255}, {255,255},
    337     {48,138}, {40,154}, {33,175}, {28,200}, {24,227}, {21,255}, {255,255}, {255,255}, {255,255},
    338     // LC0..LC17
    339     {192,255}, {184,131}, {174,141}, {166,159}, {160,181}, {155,207}, {174,244}, {171,255}, {166,255},
    340     {128,9}, {128,43}, {128,77}, {128,111}, {128,145}, {128,179}, {255,255}, {150,252}, {162,255},
    341     // LD0..LD17
    342     {0,26}, {0,60}, {0,94}, {0,128}, {0,162}, {0,218}, {227,193}, {234,245}, {255,255},
    343     {195,128}, {205,135}, {214,149}, {221,169}, {255,255}, {210,244}, {213,255}, {218,255}, {222,255},
    344     // LE0..LE17
    345     {255,255}, {255,255}, {255,255}, {255,255}, {255,255}, {255,255}, {255,255}, {255,255}, {255,255},
    346     {70,255}, {66,255}, {62,255}, {59,255}, {56,255}, {73,255}, {76,255}, {79,255}, {84,255},
    347     // LF0..LF17
    348     {52,255}, {49,255}, {47,255}, {44,255}, {41,255}, {38,255}, {37,255}, {25,255}, {14,255},
    349     {27,255}, {15,255}, {29,255}, {17,255}, {255,255}, {241,255}, {227,255}, {229,255}, {231,255}
    350 };
    351 #elif defined(RGB_BACKLIGHT_HS60) && defined(HS60_ANSI)
    352 const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
    353     // LA1..LA47
    354     {0,0}, {4,16}, {6,32}, {10,48}, {16,0}, {24,16}, {28,32}, {36,48}, {32,0}, {40,16}, {44,32}, {52,48},
    355     {48,0}, {56,16}, {60,32}, {68,48}, {64,0}, {72,16}, {76,32}, {84,48}, {80,0}, {88,16}, {92,32}, {100,48},
    356     {96,0}, {104,16}, {108,32}, {116,48}, {112,0}, {120,16}, {124,32}, {132,48}, {128,0}, {136,16}, {140,32},
    357     {148,48}, {144,0}, {152,16}, {156,32}, {164,48}, {160,0}, {168,16}, {172,32}, {180,48}, {176,0}, {184, 16}, {188,32},
    358     {255,255},// LA48 does not exist, dummy
    359     // LA49..LA50
    360     {192,0}, {200,16},
    361     {255,255},// LA51 does not exit, dummy
    362     // LA52..LA60
    363     {210,48}, {216,0}, {220,16}, {214,32}, {222,64}, {2,64}, {22,64}, {42,64}, {102,64},
    364     {255,255},// LA61 does not exit, dummy
    365     {162,64}, {182,64}, {202,64}
    366 };
    367 const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
    368     // LA1..LA47
    369     {96,255}, {109,255}, {128,242}, {148,255}, {93,255}, {105,238}, {128,192}, {154,216}, {89,255}, {101,208}, {128,155}, {159,188},
    370     {85,255}, {96,181}, {128,119}, {165,163}, {81,255}, {89,157}, {128,82}, {173,143}, {75,255}, {81,139}, {128,46}, {183,131},
    371     {70,255}, {70,129}, {129,9}, {195,128}, {64,255}, {58,129}, {255,27}, {206,136}, {58,255}, {47,139}, {255,64}, {215,152},
    372     {53,255}, {39,157}, {255,101}, {222,175}, {47,255}, {32,181}, {255,137}, {228,201}, {43,255}, {27,208}, {255, 174},
    373     {255,255},// LA48 does not exist, dummy
    374     // LA49..LA50
    375     {39,255}, {23,238},
    376     {255,255},// LA51 does not exit, dummy
    377     // LA52..LA60
    378     {235,255}, {33,255}, {19,255}, {255,233}, {224,255}, {160,255}, {164,255}, {169,255}, {188,255},
    379     {255,255},// LA61 does not exit, dummy
    380     {209,255}, {215,255}, {220,255}
    381 };
    382 #elif defined(RGB_BACKLIGHT_HS60) && defined(HS60_HHKB)
    383 const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
    384     // LA1..LA60
    385     {0,0}, {4,16}, {6,32}, {10,48}, {16,0}, {24,16}, {28,32}, {36,48}, {32,0}, {40,16}, {44,32}, {52,48},
    386     {48,0}, {56,16}, {60,32}, {68,48}, {64,0}, {72,16}, {76,32}, {84,48}, {80,0}, {88,16}, {92,32}, {100,48},
    387     {96,0}, {104,16}, {108,32}, {116,48}, {112,0}, {120,16}, {124,32}, {132,48}, {128,0}, {136,16}, {140,32},
    388     {148,48}, {144,0}, {152,16}, {156,32}, {164,48}, {160,0}, {168,16}, {172,32}, {180,48}, {176,0}, {184, 16}, {188,32},
    389     {224,0}, {192,0}, {200,16}, {202,48}, {224,48}, {208,0}, {220,16}, {214,32}, {220,64}, {4,64}, {24,64}, {44,64}, {112,64},
    390     {255,255}, {255,255}, // LA61..LA62 does not exit, dummy
    391     // LA63..LA64
    392     {180,64}, {200,64}
    393 };
    394 const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
    395     // LA1..LA60
    396     {96,255}, {109,255}, {128,242}, {148,255}, {93,255}, {105,238}, {128,192}, {154,216}, {89,255}, {101,208}, {128,155}, {159,188},
    397     {85,255}, {96,181}, {128,119}, {165,163}, {81,255}, {89,157}, {128,82}, {173,143}, {75,255}, {81,139}, {128,46}, {183,131},
    398     {70,255}, {70,129}, {129,9}, {195,128}, {64,255}, {58,129}, {255,27}, {206,136}, {58,255}, {47,139}, {255,64}, {215,152},
    399     {53,255}, {39,157}, {255,101}, {222,175}, {47,255}, {32,181}, {255,137}, {228,201}, {43,255}, {27,208}, {255, 174}, {32,255},
    400     {39,255}, {23,238}, {233,242}, {237,255}, {35,255}, {19,255}, {255,233}, {223,255}, {161,255}, {165,255}, {170,255}, {192,255},
    401     {255,255}, {255,255}, // LA61..LA62 does not exit, dummy
    402     // LA63..LA64
    403     {214,255}, {219,255}
    404 };
    405 #elif defined(RGB_BACKLIGHT_HS60) //HS60_ISO
    406 const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
    407     // LA1..LA50
    408     {0,0}, {4,16}, {6,32}, {2,48}, {16,0}, {24,16}, {28,32}, {36,48}, {32,0}, {40,16}, {44,32}, {52,48}, {48,0},
    409     {56,16}, {60,32}, {68,48}, {64,0}, {72,16}, {76,32}, {84,48}, {80,0}, {88,16}, {92,32}, {100,48}, {96,0}, {104,16},
    410     {108,32}, {116,48}, {112,0}, {120,16}, {124,32}, {132,48}, {128,0}, {136,16}, {140,32}, {148,48}, {144,0}, {152,16},
    411     {156,32}, {164,48}, {160,0}, {168,16}, {172,32}, {180,48}, {176,0}, {184, 16}, {188,32}, {20,48}, {192,0}, {200,16},
    412     {255,255},// LA51 does not exit, dummy
    413     // LA52..LA60
    414     {210,48}, {216,0}, {220,16}, {222,24}, {222,64}, {2,64}, {22,64}, {42,64}, {102,64},
    415     {255,255},// LA61 does not exit, dummy
    416     {162,64}, {182,64}, {202,64}
    417 };
    418 const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
    419     // LA1..LA50
    420     {96,255}, {109,255}, {128,242}, {147,255}, {93,255}, {105,238}, {128,192}, {154,216}, {89,255}, {101,208}, {128,155}, {159,188}, {85,255},
    421     {96,181}, {128,119}, {165,163}, {81,255}, {89,157}, {128,82}, {173,143}, {75,255}, {81,139}, {128,46}, {183,131}, {70,255}, {70,129},
    422     {129,9}, {195,128}, {64,255}, {58,129}, {255,27}, {206,136}, {58,255}, {47,139}, {255,64}, {215,152}, {53,255}, {39,157}, {255,101},
    423     {222,175}, {47,255}, {32,181}, {255,137}, {228,201}, {43,255}, {27,208}, {255, 174}, {150,246}, {39,255}, {23,238},
    424     {255,255},// LA51 does not exit, dummy
    425     // LA52..LA60
    426     {235,255}, {33,255}, {19,255}, {10,255}, {224,255}, {160,255}, {164,255}, {169,255}, {188,255},
    427     {255,255},// LA61 does not exit, dummy
    428     {209,255}, {215,255}, {220,255}
    429 };
    430 #elif defined(RGB_BACKLIGHT_NK65) || defined(RGB_BACKLIGHT_KW_MEGA)
    431 const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
    432     // LA1..LA60
    433     {0,0}, {4,16}, {6,32}, {10,48}, {16,0}, {24,16}, {28,32}, {36,48}, {32,0}, {40,16}, {44,32}, {52,48},
    434     {48,0}, {56,16}, {60,32}, {68,48}, {64,0}, {72,16}, {76,32}, {84,48}, {80,0}, {88,16}, {92,32}, {100,48},
    435     {96,0}, {104,16}, {108,32}, {116,48}, {112,0}, {120,16}, {124,32}, {132,48}, {128,0}, {136,16}, {140,32},
    436     {148,48}, {144,0}, {152,16}, {156,32}, {164,48}, {160,0}, {168,16}, {172,32}, {180,48}, {176,0}, {184, 16}, {188,32},
    437     {160,64}, {192,0}, {200,16}, {210,48}, {224,48}, {216,0}, {220,16}, {214,32}, {224,64}, {2,64}, {22,64}, {42,64}, {102,64},
    438     {255,255},// LA61 does not exit, dummy
    439     //LA62..LB5
    440     {176,64}, {192,64}, {208,64}, {240,0}, {240,16}, {240,48}, {240,64}, {240,32}
    441 };
    442 const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
    443     // LA1..LA60
    444     {96,255}, {109,255}, {128,242}, {148,255}, {93,255}, {105,238}, {128,192}, {154,216}, {89,255}, {101,208}, {128,155}, {159,188},
    445     {85,255}, {96,181}, {128,119}, {165,163}, {81,255}, {89,157}, {128,82}, {173,143}, {75,255}, {81,139}, {128,46}, {183,131},
    446     {70,255}, {70,129}, {129,9}, {195,128}, {64,255}, {58,129}, {255,27}, {206,136}, {58,255}, {47,139}, {255,64}, {215,152},
    447     {53,255}, {39,157}, {255,101}, {222,175}, {47,255}, {32,181}, {255,137}, {228,201}, {43,255}, {27,208}, {255, 174},
    448     {208,255}, {39,255}, {23,238}, {235,255}, {235,255}, {33,255}, {19,255}, {255,233}, {224,255}, {160,255}, {164,255}, {169,255}, {188,255},
    449     {255,255},// LA61 does not exit, dummy
    450     //LA62..LB5
    451     {221,255}, {225,255}, {229,255}, {22,255}, {12,255}, {244,255}, {234,255}, {255,255}
    452 };
    453 #elif defined(RGB_BACKLIGHT_NK87)
    454 const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
    455     {0,19}, {4,33}, {6,48}, {9,63}, {15,19}, {22,33}, {26,48}, {33,63}, {30,19}, {37,33}, {41,48}, {48,63}, {44,19}, {52,33}, {56,48}, {63,63},
    456     {59,19}, {67,33}, {70,48}, {78,63}, {74,19}, {81,33}, {85,48}, {93,63}, {89,19}, {96,33}, {100,48}, {107,63}, {104,19}, {111,33}, {115,48},
    457     {122,63}, {118,19}, {126,33}, {130,48}, {137,63}, {133,19}, {141,33}, {144,48}, {152,63}, {148,19}, {155,33}, {159,48}, {167,63}, {163,19},
    458     {170,33}, {174,48}, {226,78}, {178,19}, {185,33}, {194,63}, {241,63}, {200,19}, {204,33}, {198,48}, {241,78}, {4,78}, {22,78}, {41,78}, {104,78},
    459     {255,255}, {167,78}, {185,78}, {204,78}, {0,0}, {255,255}, {255,255}, {255,255}, {19,0}, {255,255}, {255,255}, {255,255}, {33,0}, {255,255},
    460     {255,255}, {255,78}, {48,0}, {255,255}, {255,255}, {255,255}, {63,0}, {255,255}, {255,255}, {255,255}, {81,0}, {255,255}, {255,255}, {255,255},
    461     {96,0}, {255,255}, {255,255}, {255,255}, {111,0}, {255,255}, {255,255}, {255,255}, {126,0}, {255,255}, {255,255}, {255,255}, {144,0}, {255,255},
    462     {255,255}, {255,255}, {159,0}, {255,255}, {255,255}, {255,255}, {174,0}, {255,255}, {255,255}, {255,255}, {189,0}, {255,255}, {226,33}, {226,19},
    463     {207,0}, {255,255}, {241,33}, {241,19}, {226,0}, {255,255}, {255,33}, {255,19}, {241,0}, {255,255}, {255,255}, {255,0}
    464 };
    465 const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
    466     {104,255}, {120,242}, {141,246}, {157,255}, {101,255}, {119,208}, {143,210}, {162,255}, {99,251}, {118,180}, {145,183}, {165,248}, {95,230},
    467     {116,153}, {148,158}, {169,232}, {91,212}, {113,126}, {152,133}, {173,218}, {87,195}, {109,100}, {158,111}, {178,207}, {81,182}, {102,75},
    468     {167,92}, {184,200}, {75,172}, {89,55}, {179,79}, {190,196}, {68,167}, {67,45}, {194,75}, {196,197}, {61,166}, {43,52}, {208,82}, {201,201},
    469     {55,170}, {29,70}, {220,97}, {207,210}, {48,179}, {21,93}, {227,116}, {214,255}, {43,191}, {16,119}, {216,234}, {226,255}, {36,216}, {12,153},
    470     {235,155}, {216,255}, {166,255}, {169,255}, {172,255}, {186,255}, {255,255}, {201,255}, {206,255}, {210,255}, {91,255}, {255,255}, {255,255},
    471     {255,255}, {88,255}, {255,255}, {255,255}, {255,255}, {85,255}, {255,255}, {255,255}, {219,255}, {82,255}, {255,255}, {255,255}, {255,255},
    472     {79,255}, {255,255}, {255,255}, {255,255}, {75,255}, {255,255}, {255,255}, {255,255}, {72,255}, {255,255}, {255,255}, {255,255}, {68,255},
    473     {255,255}, {255,255}, {255,255}, {64,255}, {255,255}, {255,255}, {255,255}, {60,255}, {255,255}, {255,255}, {255,255}, {56,255}, {255,255},
    474     {255,255}, {255,255}, {53,255}, {255,255}, {255,255}, {255,255}, {50,255}, {255,255}, {10,194}, {29,251}, {46,255}, {255,255}, {8,222}, {27,255},
    475     {42,255}, {255,255}, {7,249}, {24,255}, {40,255}, {255,255}, {255,255}, {37,255}
    476 };
    477 #elif defined(RGB_BACKLIGHT_NEBULA12)
    478 const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
    479     // A1..A16
    480     {0,0}, {16,0}, {32,0}, {0,16}, {16,16}, {32,16}, {0,32}, {16,32},
    481     {255,255}, {255,255}, {255,255}, {255,255},
    482     {32,48}, {16,48}, {0,48}, {32,32}
    483 };
    484 const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
    485     // A1..A16
    486     {72,197}, {64,194}, {56,197}, {85,74}, {64,64}, {43,74}, {171,74}, {192,64},
    487     {255,255}, {255,255}, {255,255}, {255,255},
    488     {200,196}, {192,192}, {184,196}, {213,74}
    489 };
    490 #elif defined(RGB_BACKLIGHT_NEBULA68)
    491 const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
    492     // LA1..LA60
    493     {0,0}, {4,16}, {6,31}, {10,47}, {16,0}, {24,16}, {27,31}, {35,47}, {31,0}, {39,16}, {43,31}, {51,47},
    494     {47,0}, {55,16}, {59,31}, {67,47}, {63,0}, {71,16}, {75,31}, {82,47}, {79,0}, {86,16}, {90,31}, {98,47},
    495     {94,0}, {102,16}, {106,31}, {114,47}, {110,0}, {118,16}, {122,31}, {130,47}, {126,0}, {133,16}, {137,31},
    496     {145,47}, {141,0}, {149,16}, {153,31}, {161,47}, {157,0}, {165,16}, {169,31}, {177,47}, {173,0}, {181, 16}, {184,31},
    497     {159,63}, {188,0}, {196,16}, {206,47}, {220,47}, {212,0}, {216,16}, {210,31}, {220,63}, {2,63}, {22,63}, {41,63}, {100,63},
    498     {255,255},// LA61 does not exit, dummy
    499     //LA62..LB5
    500     {179,63}, {198,63}, {224,63}, {239,0}, {239,16}, {255,16}, {255,63}, {255,0}
    501 };
    502 const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
    503     // LA1..LA60
    504     {96,255}, {109,255}, {128,244}, {148,255}, {93,255}, {106,245}, {128,201}, {153,225}, {80,255}, {103,219}, {128,169}, {156,200},
    505     {87,255}, {99,194}, {128,138}, {161,177}, {83,255}, {94,171}, {128,106}, {167,157}, {79,255}, {87,152}, {128,75}, {174,141}, {74,255},
    506     {80,138}, {128,43}, {183,131}, {70,255}, {70,129}, {129,12}, {193,128}, {65,255}, {60,128}, {255,20}, {203,133}, {60,255},
    507     {51,135}, {255,51}, {212,145}, {55,255}, {42,148}, {255,83}, {219,162}, {50,255}, {36,166}, {255,114},
    508     {202,255}, {46,255}, {30,188}, {228,203}, {231,225}, {40,255}, {25,219}, {255,165}, {217,255}, {160,255}, {164,255}, {168,255}, {183,255},
    509     {255,255},// LA61 does not exit, dummy
    510     //LA62..LB5
    511     {207,255}, {213,255}, {218,255}, {35,255}, {21,255}, {19,255}, {224,255}, {32,255}
    512 };
    513 #elif defined(RGB_BACKLIGHT_M6_B)
    514 // M6-B is really simple:
    515 // 0 3 5
    516 // 1 2 4
    517 const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
    518     {0,0}, {0,16}, {16,16}, {16,0}, {32,16}, {32,0}
    519 };
    520 const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
    521     {160,255}, {96,255}, {77,255}, {179,255}, {51,255}, {205,255}
    522 };
    523 #elif defined(RGB_BACKLIGHT_M10_C)
    524 // M10-C is really simple:
    525 // 0     1     2
    526 // 3     4     5
    527 // 8     7     6
    528 //       11 10 9
    529 const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
    530     {0,0}, {16,0}, {32,0},
    531     {0,16}, {16,16}, {32,16},
    532     {32,32}, {16,32}, {0,32},
    533     {32,48}, {24,48}, {16,48}
    534 };
    535 const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
    536     {160,255}, {192,255}, {224,255},
    537     {128,255}, {0,0}, {0,255},
    538     {32,255}, {64,255}, {96,255},
    539     {45,255}, {54,255}, {64,255}
    540 };
    541 #elif defined(RGB_BACKLIGHT_DAWN60)
    542 const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
    543     // LA1..LA16
    544     {104, 16}, {88 , 16}, {72 , 16}, {56 , 16}, {40 , 16}, {24 , 16}, {4  , 16}, {6  , 32},
    545     {112,  0}, {96 ,  0}, {80 ,  0}, {64 ,  0}, {48 ,  0}, {32 ,  0}, {16 ,  0}, {0  ,  0},
    546 
    547     // LB1..LB16
    548     {128,  0}, {144,  0}, {160,  0}, {176,  0}, {192,  0}, {208,  0}, {224,  0}, {214, 32},
    549     {120, 16}, {136, 16}, {152, 16}, {168, 16}, {184, 16}, {200, 16}, {220, 16}, {224, 48},
    550 
    551     // LC1..LC16
    552     {100, 48}, {84 , 48}, {68 , 48}, {52 , 48}, {36 , 48}, {102, 64}, {42 , 64}, {22 , 64},
    553     {108, 32}, {92 , 32}, {76 , 32}, {60 , 32}, {44 , 32}, {28 , 32}, {10 , 48}, {2  , 64},
    554 
    555     // LD1..LD16
    556     {124, 32}, {140, 32}, {156, 32}, {172, 32}, {188, 32}, {180, 48}, {202, 48}, {224, 64},
    557     {116, 48}, {132, 48}, {148, 48}, {164, 48}, {160, 64},  {176, 64}, {192, 64}, {208, 64},
    558 
    559     //RGB UNDERGLOW
    560     {27 , 3}, {64 , 3}, {100, 3}, {137, 3}, {173, 3}, {209, 3}, {242, 4}, {255, 8}, {255,32}, {255,64},
    561     {241,64}, {212,64}, {173,64}, {137,64}, {100,64}, {63 ,64}, {28 ,64}, {0  ,64}, {0  ,32}, {0  , 8}, //20
    562 };
    563 
    564 const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
    565     //LA1..LA16
    566     {70,129}, {80,139}, {89,157}, {96,181}, {101,208}, {105,238}, {109,255}, {128,247},
    567     {64,255}, {70,255}, {75,255}, {80,255}, {85,255},  {89,255},  {93,255},  {96,255},
    568     //LB1..LB16
    569     {58,255}, {53,255}, {48,255}, {43,255}, {39,255},  {34,255}, {32,255}, {255,233},
    570     {58,129}, {48,139}, {39,157}, {32,181}, {27,208}, {23,238}, {19,255}, {237,255},
    571     //LC1..LC16
    572     {183,131}, {173,143}, {165,163}, {159,188}, {154,216}, {188,255}, {170,255}, {165,255},
    573     {128,9}, {128,46}, {128,82}, {128,119}, {128,155}, {128,192}, {147,255}, {161,255},
    574     //LD1..LD16
    575     {0,27}, {0,64}, {0,101}, {0,137}, {0,174}, {228,201}, {235,255}, {224,255},
    576     {195,128}, {206,136}, {215,152}, {222,175}, {208,255}, {213,255}, {217, 255}, {222,225},
    577 
    578     //UNDERGLOW, {A,D}
    579     //1 - 10
    580     {91,255}, {84,255}, {74,255}, {60,255}, {48,255}, {39,255}, {32,255}, {27,255}, {0,255}, {236,255},
    581     //11 - 20
    582     {234,255}, {222,255}, {213,255}, {197,255}, {180,255}, {167,255}, {152,255}, {147,255}, {128,255}, {101,255}
    583 };
    584 #elif defined(RGB_BACKLIGHT_PORTICO)
    585 const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
    586     {   0,   0 }, {  15,   0 }, {  30,   0 }, {  45,   0 }, {  60,   0 }, {  75,   0 }, {  90,   0 }, { 105,   0 }, { 120,   0 }, { 135,   0 }, { 150,   0 }, { 165,   0 }, { 180,   0 }, { 203,   0 }, { 224,   0 },
    587     {   4,  16 }, {  23,  16 }, {  38,  16 }, {  53,  16 }, {  68,  16 }, {  83,  16 }, {  98,  16 }, { 113,  16 }, { 128,  16 }, { 143,  16 }, { 158,  16 }, { 173,  16 }, { 188,  16 }, { 206,  16 }, { 224,  16 },
    588     {   6,  32 }, {  26,  32 }, {  41,  32 }, {  56,  32 }, {  71,  32 }, {  86,  32 }, { 101,  32 }, { 116,  32 }, { 131,  32 }, { 146,  32 }, { 161,  32 }, { 176,  32 },               { 201,  32 }, { 224,  32 },
    589     {   9,  48 },               {  34,  48 }, {  49,  48 }, {  64,  48 }, {  79,  48 }, {  94,  48 }, { 109,  48 }, { 124,  48 }, { 139,  48 }, { 154,  48 }, { 169,  48 }, { 189,  48 }, { 210,  48 }, { 224,  48 },
    590     {   2,  64 }, {  21,  64 }, {  39,  64 },                                           {  96,  64 },                                           { 152,  64 }, { 171,  64 }, { 195,  64 }, { 210,  64 }, { 224,  64 },
    591 };
    592 const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
    593     { 138, 240 }, { 140, 210 }, { 142, 181 }, { 145, 153 }, { 149, 126 }, { 156, 101 }, { 166,  80 }, { 182,  67 }, { 200,  68 }, { 216,  81 }, { 226, 102 }, { 232, 128 }, { 236, 155 }, { 240, 199 }, { 243, 240 }, //Done through here TM 052421 143PM
    594     { 133, 225 }, { 134, 186 }, { 136, 156 }, { 138, 126 }, { 141,  96 }, { 147,  68 }, { 161,  44 }, { 193,  33 }, { 222,  47 }, { 235,  72 }, { 240, 100 }, { 244, 130 }, { 246, 160 }, { 247, 196 }, { 248, 233 }, //Done through here TM 052421 235PM
    595     { 127, 218 }, { 127, 177 }, { 127, 146 }, { 127, 115 }, { 127,  84 }, { 127,  54 }, { 127,  23 }, {   0,   8 }, {   0,  39 }, {   0,  70 }, {   0, 101 }, {   0, 132 },               {   0, 183 }, {   0, 231 },
    596     { 121, 215 },               { 119, 164 }, { 117, 134 }, { 114, 104 }, { 109,  76 }, {  98,  50 }, {  71,  34 }, {  37,  41 }, {  22,  65 }, {  15,  93 }, {  11, 122 }, {   8, 162 }, {   7, 205 }, {   6, 233 },
    597     { 116, 236 }, { 113, 199 }, { 110, 164 },                                           {  82,  74 },                                           {  27, 106 }, {  20, 138 }, {  15, 183 }, {  13, 212 }, {  11, 240 }
    598 };
    599 #elif defined(RGB_BACKLIGHT_PORTICO75)
    600 const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
    601     {   0,   0 }, {  18,   0 }, {  33,   0 }, {  48,   0 }, {  62,   0 }, {  81,   0 }, {  96,   0 }, { 110,   0 }, { 125,   0 }, { 143,   0 }, { 158,   0 }, { 173,   0 }, { 187,   0 }, { 205,   0 }, { 224,   0 },
    602     {   0,  15 }, {  15,  15 }, {  29,  15 }, {  44,  15 }, {  59,  15 }, {  74,  15 }, {  88,  15 }, { 103,  15 }, { 118,  15 }, { 132,  15 }, { 147,  15 }, { 162,  15 }, { 176,  15 }, { 198,  15 }, { 224,  15 },
    603     {   4,  26 }, {  22,  26 }, {  37,  26 }, {  51,  26 }, {  66,  26 }, {  81,  26 }, {  96,  26 }, { 110,  26 }, { 125,  26 }, { 140,  26 }, { 154,  26 }, { 169,  26 }, { 183,  26 }, { 202,  26 }, { 224,  26 },
    604     {   5,  38 }, {  25,  38 }, {  40,  38 }, {  54,  38 }, {  69,  38 }, {  84,  38 }, {  98,  38 }, { 113,  38 }, { 128,  38 }, { 143,  38 }, { 157,  38 }, { 172,  38 }, { 197,  38 },
    605     {   9,  49 }, {  33,  49 }, {  48,  49 }, {  62,  49 }, {  77,  49 }, {  92,  49 }, { 107,  49 }, { 121,  49 }, { 136,  49 }, { 151,  49 }, { 165,  49 }, { 186,  49 }, { 209,  49 },
    606     {   2,  61 }, {  20,  61 }, {  39,  61 }, {  94,  61 }, { 151,  61 }, { 173,  61 }, { 195,  64 }, { 209,  64 }, { 224,  64 },
    607 	{   2,   0 }, {  46,   0 }, {  90,   0 }, { 134,   0 }, { 178,   0 }, { 222,   0 }, { 224,   2 }, { 224,  32 }, { 224,  62 }, {   2,  64 }, {  46,  64 }, {  90,  64 }, { 134,  64 }, { 178,  64 }, { 222,  64 }, {   0,   2 }, {   0,  32 }, {   0,  62 }
    608 };
    609 const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
    610     { 138, 240 }, { 140, 205 }, { 143, 176 }, { 146, 147 }, { 150, 122 }, { 159,  92 }, { 172,  74 }, { 188,  66 }, { 206,  71 }, { 222,  92 }, { 229, 115 }, { 234, 142 }, { 238, 168 }, { 241, 203 }, { 243, 240 },
    611     { 133, 233 }, { 134, 203 }, { 135, 175 }, { 137, 144 }, { 140, 115 }, { 144,  86 }, { 152,  61 }, { 171,  40 }, { 204,  37 }, { 226,  54 }, { 236,  80 }, { 241, 109 }, { 244, 136 }, { 246, 181 }, { 248, 233 },
    612     { 129, 223 }, { 130, 186 }, { 130, 155 }, { 131, 126 }, { 132,  96 }, { 135,  65 }, { 142,  35 }, { 177,  13 }, { 237,  30 }, { 245,  59 }, { 248,  87 }, { 250, 118 }, { 251, 147 }, { 251, 186 }, { 252, 231 },
    613     { 125, 221 }, { 124, 180 }, { 124, 149 }, { 123, 120 }, { 121,  89 }, { 118,  59 }, { 111,  31 }, {  57,  13 }, {  15,  35 }, {   8,  65 }, {   5,  94 }, {   4, 124 }, {   3, 176 },
    614     { 120, 215 }, { 118, 166 }, { 117, 136 }, { 114, 109 }, { 109,  80 }, {  99,  54 }, {  75,  37 }, {  44,  40 }, {  25,  61 }, {  17,  88 }, {  13, 115 }, {   9, 156 }, {   7, 203 },
    615     { 117, 234 }, { 115, 199 }, { 112, 162 }, {  86,  70 }, {  26, 100 }, {  18, 139 }, {  15, 183 }, {  13, 210 }, {  11, 240 },
    616     { 138, 236 }, { 145, 151 }, { 166,  80 }, { 215,  80 }, { 236, 151 }, { 243, 236 }, { 243, 239 }, {   0, 231 }, {  11, 239 }, { 116, 236 }, { 109, 151 }, { 88,  80 }, {  39,  80 }, {  18, 151 }, {  11, 236 }, { 138, 239 }, { 127, 231 }, { 116, 239 }
    617 };
    618 #elif defined(RGB_BACKLIGHT_M50_A)
    619 const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
    620     // LA0..LA17
    621     {255,255}, {104,16}, {88,16}, {72,16}, {56,16}, {40,16}, {24,16}, {255,255}, {255,255},
    622     {104,0}, {88,0}, {72,0}, {56,0}, {40,0}, {24,0}, {0,0}, {0,16}, {255,255},
    623     // LB0..LB17
    624     {255,255}, {120,0}, {136,0}, {152,0}, {168,0}, {184,0}, {200,0}, {255,255}, {255,255},
    625     {120,16}, {136,16}, {152,16}, {168,16}, {184,16}, {200,16}, {255,255}, {255,255}, {255,255},
    626     // LC0..LC17
    627     {255,255}, {112,48}, {88,48}, {72,48}, {56,48}, {40,48}, {24,48}, {0,48}, {255,255},
    628     {104,32}, {88,32}, {72,32}, {56,32}, {40,32}, {24,32}, {0,32}, {255,255}, {255,255},
    629     // LD0..LD17
    630     {255,255}, {120,32}, {136,32}, {152,32}, {168,32}, {184,32}, {200,32}, {255,255}, {255,255},
    631     {255,255}, {136,48}, {152,48}, {168,48}, {184,48}, {200,48}, {255,255}, {255,255}, {255,255}
    632 };
    633 const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
    634     // LA0..LA17
    635     {255,255}, {73,88}, {89,104}, {99,130}, {105,162}, {110,197}, {113,233}, {255,255}, {255,255},
    636     {67,255}, {73,255}, {79,255}, {84,255}, {89,255}, {93,255}, {98,255}, {116,255}, {255,255},
    637     // LB0..LB17
    638     {0,0},  {61,255}, {55,255}, {49,255}, {44,255}, {39,255}, {35,255}, {255,255}, {255,255},
    639     {55,88}, {39,104}, {29,130}, {23,162}, {18,197}, {15,233}, {255,255}, {255,255}, {255,255},
    640     // LC0..LC17
    641     {255,255}, {192,255}, {183,255}, {177,255}, {172,255}, {167,255}, {163,255}, {158,255}, {255,255},
    642     {183,88}, {167,104}, {157,130}, {151,162}, {146,197}, {143,233}, {140,255}, {255,255}, {255,255},
    643     // LD0..LD17
    644     {255,255}, {201,88}, {217,104}, {227,130}, {233,162}, {238,197}, {241,233}, {255,255}, {255,255},
    645     {255,255}, {201,255}, {207,255}, {212,255}, {217,255}, {221,255}, {255,255}, {255,255}, {255,255}
    646 };
    647 #endif
    648 
    649 // This may seem counter-intuitive, but it's quite flexible.
    650 // For each LED, get it's position to decide what color to make it.
    651 // This solves the issue of LEDs (and switches) not aligning to a grid,
    652 // or having a large "bitmap" and sampling them.
    653 void map_led_to_point( uint8_t index, Point *point )
    654 {
    655     // Slightly messy way to get Point structs out of progmem.
    656     uint8_t *addr = (uint8_t*)&g_map_led_to_point[index];
    657     point->x = pgm_read_byte(addr);
    658     point->y = pgm_read_byte(addr+1);
    659 
    660 #if defined(RGB_BACKLIGHT_M6_B) || defined(RGB_BACKLIGHT_M10_C) || defined(RGB_BACKLIGHT_HS60) || defined(RGB_BACKLIGHT_NK65) || defined(RGB_BACKLIGHT_PORTICO) || \
    661     defined(RGB_BACKLIGHT_PORTICO75) || defined(RGB_BACKLIGHT_NK87) || defined(RGB_BACKLIGHT_NEBULA68) || defined(RGB_BACKLIGHT_NEBULA12) || defined(RGB_BACKLIGHT_KW_MEGA)
    662     return;
    663 #endif
    664 
    665     switch (index)
    666     {
    667 #if !defined(RGB_BACKLIGHT_DAWN60)
    668         case 18+4: // LB4A
    669             if ( g_config.use_split_backspace )
    670                 point->x -= 8;
    671             break;
    672 #endif
    673 #if defined(RGB_BACKLIGHT_ZEAL60)
    674         case 18+14: // LB14A
    675             if ( g_config.use_iso_enter )
    676                 point->y += 8; // extremely pedantic
    677             break;
    678         case 54+5: // LD5A
    679             if ( !g_config.use_iso_enter )
    680                 point->x -= 10;
    681             break;
    682         case 36+16: // LC16A
    683             if ( !g_config.use_split_left_shift )
    684                 point->x += 8;
    685             break;
    686 #endif
    687 #if defined(RGB_BACKLIGHT_ZEAL60) || defined(RGB_BACKLIGHT_M60_A)
    688         case 36+0: // LC0A
    689             if ( g_config.use_7u_spacebar )
    690                 point->x += 10;
    691             break;
    692         case 36+6: // LC6A
    693             if ( g_config.use_7u_spacebar )
    694                 point->x += 4;
    695             break;
    696         case 54+7: // LD7A
    697             if ( !g_config.use_split_right_shift )
    698                 point->x -= 8;
    699             break;
    700 #endif
    701 #if defined(RGB_BACKLIGHT_DAWN60)
    702         case 15+6: // LB6A
    703             if ( !g_config.use_split_backspace )
    704                 point->x += 8;
    705             break;
    706         case 31+6: // LC6A
    707             if ( g_config.use_7u_spacebar )
    708                 point->x = 112;
    709             break;
    710         case 47+16: // LD16A
    711             if ( g_config.use_7u_spacebar )
    712                 point->x -= 8;
    713             break;
    714         case 47+6: // LD6A
    715             if ( g_config.use_split_right_shift )
    716                 point->x += 6;
    717             break;
    718         case 47+7: // LD7A
    719             if ( g_config.use_split_right_shift )
    720                 point->x += 6;
    721             break;
    722 #endif
    723     }
    724 }
    725 
    726 void map_led_to_point_polar( uint8_t index, Point *point )
    727 {
    728     // Slightly messy way to get Point structs out of progmem.
    729     uint8_t *addr = (uint8_t*)&g_map_led_to_point_polar[index];
    730     point->x = pgm_read_byte(addr);
    731     point->y = pgm_read_byte(addr+1);
    732 }
    733 
    734 //
    735 // Maps switch matrix coordinate (row,col) to LED index
    736 //
    737 
    738 
    739 #if defined(RGB_BACKLIGHT_ZEAL65)
    740 // Note: Left spacebar stab is at 4,2 (LC7)
    741 // Right spacebar stab is at 4,9 (D14)
    742 //
    743 // A17, A16, A15, A14, A13, A12, A11, A10,  A9,  B0,  B1,  B2,  B3,  B4,  B6
    744 //  A7,  A6,  A5,  A4,  A3,  A2,  A1,  A0,  B9, B10, B11, B12, B13, B14,  B7
    745 //  A8, C14, C13, C12, C11, C10,  C9,  D0,  D1,  D2,  D3,  D4,  D5,  B5,  B8
    746 // C16, C15,  C5,  C4,  C3,  C2,  C1,  D9, D10, D11, D12,  D6,  D7,  D8, B15
    747 // C17,  C8,  C7, ---, ---, ---, ---,  C0, ---, D14, D15, D16, D17, B17, B16
    748 const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
    749     {  0+17,  0+16,  0+15,  0+14,  0+13,  0+12,  0+11,  0+10,   0+9,  18+0,  18+1,  18+2,  18+3,  18+4,  18+6 },
    750     {   0+7,   0+6,   0+5,   0+4,   0+3,   0+2,   0+1,   0+0,  18+9, 18+10, 18+11, 18+12, 18+13, 18+14,  18+7 },
    751     {   0+8, 36+14, 36+13, 36+12, 36+11, 36+10,  36+9,  54+0,  54+1,  54+2,  54+3,  54+4,  54+5,  18+5,  18+8 },
    752     { 36+16, 36+15,  36+5,  36+4,  36+3,  36+2,  36+1,  54+9, 54+10, 54+11, 54+12,  54+6,  54+7,  54+8, 18+15 },
    753     { 36+17,  36+8,  36+7,   255,   255,   255,   255,  36+0,  255,  54+14, 54+15, 54+16, 54+17, 18+17, 18+16 }
    754 };
    755 #elif defined(RGB_BACKLIGHT_KOYU)
    756 // Note: Left spacebar stab is at 4,4 (LC6)
    757 // Right spacebar stab is at 4,10 (D14)
    758 //
    759 // A17, A16, A15, A14, A13, A12, A11, A10,  A9,  B0,  B1,  B2,  B3,  B4,  B6
    760 //  A7,  A6,  A5,  A4,  A3,  A2,  A1,  A0,  B9, B10, B11, B12, B13, B14,  B7
    761 //  A8, C14, C13, C12, C11, C10,  C9,  D0,  D1,  D2,  D3,  D4,  D5,  B5,  B8
    762 // C16, C15,  C5,  C4,  C3,  C2,  C1,  D9, D10, D11, D12,  D6,  D7,  D8, B15
    763 // C17,  C8,  C7,  C6, ---, ---, ---,  C0, ---, ---, D14, D15, D16, B17, B16
    764 const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
    765     {  0+17,  0+16,  0+15,  0+14,  0+13,  0+12,  0+11,  0+10,   0+9,  18+0,  18+1,  18+2,  18+3,  18+4,  18+6 },
    766     {   0+7,   0+6,   0+5,   0+4,   0+3,   0+2,   0+1,   0+0,  18+9, 18+10, 18+11, 18+12, 18+13, 18+14,  18+7 },
    767     {   0+8, 36+14, 36+13, 36+12, 36+11, 36+10,  36+9,  54+0,  54+1,  54+2,  54+3,  54+4,  54+5,  18+5,  18+8 },
    768     { 36+16, 36+15,  36+5,  36+4,  36+3,  36+2,  36+1,  54+9, 54+10, 54+11, 54+12,  54+6,  54+7,  54+8, 18+15 },
    769     { 36+17,  36+8,  36+7,  36+6,   255,   255,   255,  36+0,  255,    255, 54+14, 54+15, 54+16, 18+17, 18+16 }
    770 };
    771 #elif defined(RGB_BACKLIGHT_M65_B) || defined(RGB_BACKLIGHT_M65_BX)
    772 // Note: Left spacebar stab is at 4,4 (LC6)
    773 // Right spacebar stab is at 4,10 (D14)
    774 //                                                                  (B6)
    775 // A17, A16, A15, A14, A13, A12, A11, A10,  A9,  B0,  B1,  B2,  B3,  B4,  B7
    776 //  A7,  A6,  A5,  A4,  A3,  A2,  A1,  A0,  B9, B10, B11, B12, B13, B14,  B8
    777 //  A8, C14, C13, C12, C11, C10,  C9,  D0,  D1,  D2,  D3,  D4,  D5,  B5, B15
    778 // C16, C15,  C5,  C4,  C3,  C2,  C1,  D9, D10, D11, D12,  D6,  D7,  D8, B16
    779 // C17,  C8,  C7,  C6, ---, ---, ---,  C0, ---, ---, D14, D15, D16, D17, B17
    780 const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
    781     {  0+17,  0+16,  0+15,  0+14,  0+13,  0+12,  0+11,  0+10,   0+9,  18+0,  18+1,  18+2,  18+3,  18+4,  18+7 },
    782     {   0+7,   0+6,   0+5,   0+4,   0+3,   0+2,   0+1,   0+0,  18+9, 18+10, 18+11, 18+12, 18+13, 18+14,  18+8 },
    783     {   0+8, 36+14, 36+13, 36+12, 36+11, 36+10,  36+9,  54+0,  54+1,  54+2,  54+3,  54+4,  54+5,  18+5, 18+15 },
    784     { 36+16, 36+15,  36+5,  36+4,  36+3,  36+2,  36+1,  54+9, 54+10, 54+11, 54+12,  54+6,  54+7,  54+8, 18+16 },
    785     { 36+17,  36+8,  36+7,  36+6,   255,   255,   255,  36+0,  255,    255, 54+14, 54+15, 54+16, 54+17, 18+17 }
    786 };
    787 #elif defined(RGB_BACKLIGHT_ZEAL60) || defined(RGB_BACKLIGHT_M60_A)
    788 // Note: Left spacebar stab is at 4,3 (LC6)
    789 // Right spacebar stab is at 4,9 (LD13) or 4,10 (LD14)
    790 //
    791 // A17, A16, A15, A14, A13, A12, A11, A10,  A9,  B0,  B1,  B2,  B3,  B4,
    792 //  A7,  A6,  A5,  A4,  A3,  A2,  A1,  A0,  B9, B10, B11, B12, B13, B14,
    793 //  A8, C14, C13, C12, C11, C10,  C9,  D0,  D1,  D2,  D3,  D4,  D5,  B5,
    794 // C16, C15,  C5,  C4,  C3,  C2,  C1,  D9, D10, D11, D12,  D6,  D7,  D8,
    795 // C17,  C8,  C7,  C6, ---, ---, ---,  C0, ---, D13, D14, D15, D16, D17,
    796 const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
    797     {  0+17,  0+16,  0+15,  0+14,  0+13,  0+12,  0+11,  0+10,   0+9,  18+0,  18+1,  18+2,  18+3,  18+4 },
    798     {   0+7,   0+6,   0+5,   0+4,   0+3,   0+2,   0+1,   0+0,  18+9, 18+10, 18+11, 18+12, 18+13, 18+14 },
    799     {   0+8, 36+14, 36+13, 36+12, 36+11, 36+10,  36+9,  54+0,  54+1,  54+2,  54+3,  54+4,  54+5,  18+5 },
    800     { 36+16, 36+15,  36+5,  36+4,  36+3,  36+2,  36+1,  54+9, 54+10, 54+11, 54+12,  54+6,  54+7,  54+8 },
    801     { 36+17,  36+8,  36+7,  36+6,   255,   255,   255,  36+0,  255,  54+13, 54+14, 54+15, 54+16, 54+17 }
    802 };
    803 #elif defined(RGB_BACKLIGHT_WT60_B) || defined(RGB_BACKLIGHT_WT60_BX) || defined(RGB_BACKLIGHT_WT60_C)
    804 const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
    805     {  0+17,  0+16,  0+15,  0+14,  0+13,  0+12,  0+11,  0+10,   0+9,  18+0,  18+1,  18+2,  18+3,  18+4 },
    806     {   0+7,   0+6,   0+5,   0+4,   0+3,   0+2,   0+1,   0+0,  18+9, 18+10, 18+11, 18+12, 18+13, 18+14 },
    807     {   0+8, 36+14, 36+13, 36+12, 36+11, 36+10,  36+9,  54+0,  54+1,  54+2,  54+3,  54+4,  54+5,  18+5 },
    808     { 36+16,   255,  36+5,  36+4,  36+3,  36+2,  36+1,  54+9, 54+10, 54+11, 54+12,  54+6,  54+7,  54+8 },
    809     { 36+17,  36+8,  36+7,  36+6,   255,   255,   255,  36+0,  255,    255, 54+14, 54+15, 54+16, 54+17 }
    810 };
    811 #elif defined(RGB_BACKLIGHT_U80_A)
    812 // Note: Left spacebar stab is at 5,3 (LC6)
    813 // Right spacebar stab is at 5,10 (LD14)
    814 const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
    815     { 72+17, 72+16, 72+15, 72+14,  72+9, 72+10, 72+11, 72+12, 72+13,  90+0,  90+1,  90+2,  90+3,   255,  90+4,  90+5,  90+6 },
    816     {  0+17,  0+16,  0+15,  0+14,  0+13,  0+12,  0+11,  0+10,   0+9,  18+0,  18+1,  18+2,  18+3,  18+4, 90+11,  90+9,  90+7 },
    817     {   0+7,   0+6,   0+5,   0+4,   0+3,   0+2,   0+1,   0+0,  18+9, 18+10, 18+11, 18+12, 18+13, 18+14, 90+12, 90+10,  90+8 },
    818     {   0+8, 36+14, 36+13, 36+12, 36+11, 36+10,  36+9,  54+0,  54+1,  54+2,  54+3,  54+4,  54+5,   255,   255,   255,   255 },
    819     { 36+16,   255,  36+5,  36+4,  36+3,  36+2,  36+1,  54+9, 54+10, 54+11, 54+12,  54+6,  54+7,   255,   255, 90+14,   255 },
    820     { 36+17,  36+8,  36+7,  36+6,   255,   255,   255,  36+0,  255,    255, 54+14, 54+15, 54+16, 54+17, 90+15, 90+16, 90+17 }
    821 };
    822 #elif defined(RGB_BACKLIGHT_HS60) && defined(HS60_ANSI)
    823 //
    824 // LA1,  LA5,  LA9,  LA13, LA17, LA21, LA25, LA29, LA33, LA37, LA41, LA45, LA49, LA53,
    825 // LA2,  LA6,  LA10, LA14, LA18, LA22, LA26, LA30, LA34, LA38, LA42, LA46, LA50,  ---,
    826 // LA3,  LA7,  LA11, LA15, LA19, LA23, LA27, LA31, LA35, LA39, LA43, LA47, LA54, LA55,
    827 // LA4,  ---,   LA8, LA12, LA16, LA20, LA24, LA28, LA32, LA36, LA40, LA44,  ---, LA52,
    828 // LA57, LA58, LA59,  ---,  ---,  ---, LA60,  ---,  ---,  ---, LA62, LA63, LA64, LA56
    829 const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
    830     {  1-1,  5-1,  9-1, 13-1, 17-1, 21-1, 25-1, 29-1, 33-1, 37-1, 41-1, 45-1, 49-1, 53-1 },
    831     {  2-1,  6-1, 10-1, 14-1, 18-1, 22-1, 26-1, 30-1, 34-1, 38-1, 42-1, 46-1, 50-1,  255 },
    832     {  3-1,  7-1, 11-1, 15-1, 19-1, 23-1, 27-1, 31-1, 35-1, 39-1, 43-1, 47-1, 54-1, 55-1 },
    833     {  4-1,  255,  8-1, 12-1, 16-1, 20-1, 24-1, 28-1, 32-1, 36-1, 40-1, 44-1,  255, 52-1 },
    834     { 57-1, 58-1, 59-1,  255,  255,  255, 60-1,  255,  255,  255, 62-1, 63-1, 64-1, 56-1 }
    835 };
    836 #elif defined(RGB_BACKLIGHT_HS60) && defined(HS60_HHKB)
    837 //
    838 // LA1,  LA5,   LA9, LA13, LA17, LA21, LA25, LA29, LA33, LA37, LA41, LA45, LA49, LA53,
    839 // LA2,  LA6,  LA10, LA14, LA18, LA22, LA26, LA30, LA34, LA38, LA42, LA46, LA50, LA48,
    840 // LA3,  LA7,  LA11, LA15, LA19, LA23, LA27, LA31, LA35, LA39, LA43, LA47, LA54, LA55,
    841 // LA4,  ---,   LA8, LA12, LA16, LA20, LA24, LA28, LA32, LA36, LA40, LA44, LA51, LA52,
    842 // LA57, LA58, LA59,  ---,  ---,  ---, LA60,  ---,  ---,  ---,  ---, LA63, LA64, LA56
    843 const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
    844     {  1-1,  5-1,  9-1, 13-1, 17-1, 21-1, 25-1, 29-1, 33-1, 37-1, 41-1, 45-1, 49-1, 53-1 },
    845     {  2-1,  6-1, 10-1, 14-1, 18-1, 22-1, 26-1, 30-1, 34-1, 38-1, 42-1, 46-1, 50-1, 48-1 },
    846     {  3-1,  7-1, 11-1, 15-1, 19-1, 23-1, 27-1, 31-1, 35-1, 39-1, 43-1, 47-1, 54-1, 55-1 },
    847     {  4-1,  255,  8-1, 12-1, 16-1, 20-1, 24-1, 28-1, 32-1, 36-1, 40-1, 44-1, 51-1, 52-1 },
    848     { 57-1, 58-1, 59-1,  255,  255,  255, 60-1,  255,  255,  255,  255, 63-1, 64-1, 56-1 }
    849 };
    850 #elif defined(RGB_BACKLIGHT_HS60) //HS60_ISO
    851 //
    852 // LA1,  LA5,   LA9, LA13, LA17, LA21, LA25, LA29, LA33, LA37, LA41, LA45, LA49, LA53,
    853 // LA2,  LA6,  LA10, LA14, LA18, LA22, LA26, LA30, LA34, LA38, LA42, LA46, LA50,  ---,
    854 // LA3,  LA7,  LA11, LA15, LA19, LA23, LA27, LA31, LA35, LA39, LA43, LA47, LA54, LA55,
    855 // LA4,  LA48,  LA8, LA12, LA16, LA20, LA24, LA28, LA32, LA36, LA40, LA44,  ---, LA52,
    856 // LA57, LA58, LA59,  ---,  ---,  ---, LA60,  ---,  ---,  ---, LA62, LA63, LA64, LA56
    857 const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
    858     {  1-1,  5-1,  9-1, 13-1, 17-1, 21-1, 25-1, 29-1, 33-1, 37-1, 41-1, 45-1, 49-1, 53-1 },
    859     {  2-1,  6-1, 10-1, 14-1, 18-1, 22-1, 26-1, 30-1, 34-1, 38-1, 42-1, 46-1, 50-1,  255 },
    860     {  3-1,  7-1, 11-1, 15-1, 19-1, 23-1, 27-1, 31-1, 35-1, 39-1, 43-1, 47-1, 54-1, 55-1 },
    861     {  4-1, 48-1,  8-1, 12-1, 16-1, 20-1, 24-1, 28-1, 32-1, 36-1, 40-1, 44-1,  255, 52-1 },
    862     { 57-1, 58-1, 59-1,  255,  255,  255, 60-1,  255,  255,  255, 62-1, 63-1, 64-1, 56-1 }
    863 };
    864 #elif defined(RGB_BACKLIGHT_NK65) || defined(RGB_BACKLIGHT_NEBULA68) || defined(RGB_BACKLIGHT_KW_MEGA)
    865 //
    866 // LA1,  LA5,  LA9,  LA13, LA17, LA21, LA25, LA29, LA33, LA37, LA41, LA45, LA49, LA53, LB1,
    867 // LA2,  LA6,  LA10, LA14, LA18, LA22, LA26, LA30, LA34, LA38, LA42, LA46, LA50,  ---, LB2,
    868 // LA3,  LA7,  LA11, LA15, LA19, LA23, LA27, LA31, LA35, LA39, LA43, LA47, LA54, LA55, LB5,
    869 // LA4,  ---,   LA8, LA12, LA16, LA20, LA24, LA28, LA32, LA36, LA40, LA44, LA51, LA52, LB3,
    870 // LA57, LA58, LA59,  ---,  ---,  ---, LA60,  ---,  ---, LA48, LA62, LA63, LA64, LA56, LB4
    871 const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
    872     {  1-1,  5-1,  9-1, 13-1, 17-1, 21-1, 25-1, 29-1, 33-1, 37-1, 41-1, 45-1, 49-1, 53-1, 1+64-1 },
    873     {  2-1,  6-1, 10-1, 14-1, 18-1, 22-1, 26-1, 30-1, 34-1, 38-1, 42-1, 46-1, 50-1,  255, 2+64-1 },
    874     {  3-1,  7-1, 11-1, 15-1, 19-1, 23-1, 27-1, 31-1, 35-1, 39-1, 43-1, 47-1, 54-1, 55-1, 5+64-1 },
    875     {  4-1,  255,  8-1, 12-1, 16-1, 20-1, 24-1, 28-1, 32-1, 36-1, 40-1, 44-1, 51-1, 52-1, 3+64-1 },
    876     { 57-1, 58-1, 59-1,  255,  255,  255, 60-1,  255,  255, 48-1, 62-1, 63-1, 64-1, 56-1, 4+64-1 }
    877 };
    878 #elif defined(RGB_BACKLIGHT_NK87)
    879 //
    880 // LB1,  LB5,  LB9,  LB13, LB17, LB21, LB25, LB29, LB33, LB37, LB41, LB45, LB49, LB53, LB57, LB61, LB64,
    881 // LA1,  LA5,  LA9,  LA13, LA17, LA21, LA25, LA29, LA33, LA37, LA41, LA45, LA49, LA53, LB52, LB56, LB60,
    882 // LA2,  LA6,  LA10, LA14, LA18, LA22, LA26, LA30, LA34, LA38, LA42, LA46, LA50,  ---, LB51, LB55, LB59,
    883 // LA3,  LA7,  LA11, LA15, LA19, LA23, LA27, LA31, LA35, LA39, LA43, LA47, LA54, LA55,  ---,  ---,  ---,
    884 // LA4,  ---,   LA8, LA12, LA16, LA20, LA24, LA28, LA32, LA36, LA40, LA44, LA51,  ---,  ---, LA52,  ---,
    885 // LA57, LA58, LA59,  ---,  ---,  ---, LA60,  ---,  ---,  ---,  ---, LA62, LA63, LA64, LA48, LA56, LB12
    886 const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
    887     { 1+64-1, 5+64-1,  9+64-1, 13+64-1, 17+64-1, 21+64-1, 25+64-1, 29+64-1, 33+64-1, 37+64-1, 41+64-1, 45+64-1, 49+64-1, 53+64-1, 57+64-1, 61+64-1, 64+64-1 },
    888     {    1-1,    5-1,     9-1,    13-1,    17-1,    21-1,    25-1,    29-1,    33-1,    37-1,    41-1,    45-1,    49-1,    53-1, 52+64-1, 56+64-1, 60+64-1 },
    889     {    2-1,    6-1,    10-1,    14-1,    18-1,    22-1,    26-1,    30-1,    34-1,    38-1,    42-1,    46-1,    50-1,     255, 51+64-1, 55+64-1, 59+64-1 },
    890     {    3-1,    7-1,    11-1,    15-1,    19-1,    23-1,    27-1,    31-1,    35-1,    39-1,    43-1,    47-1,    54-1,    55-1,     255,     255,     255 },
    891     {    4-1,    255,     8-1,    12-1,    16-1,    20-1,    24-1,    28-1,    32-1,    36-1,    40-1,    44-1,    51-1,     255,     255,    52-1,     255 },
    892     {   57-1,   58-1,    59-1,     255,     255,     255,    60-1,     255,     255,     255,     255,    62-1,    63-1,    64-1,    48-1,    56-1, 12+64-1 }
    893 };
    894 #elif defined(RGB_BACKLIGHT_NEBULA12)
    895 //
    896 //  A1,   A2,   A3,
    897 //  A4,   A5,   A6,
    898 //  A7,   A8,  A16,
    899 // A15,  A14,  A13,
    900 const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
    901     {  1-1,  2-1,  3-1 },
    902     {  4-1,  5-1,  6-1 },
    903     {  7-1,  8-1, 16-1 },
    904     { 15-1, 14-1, 13-1 }
    905 };
    906 #elif defined(RGB_BACKLIGHT_M6_B)
    907 // M6-B is really simple:
    908 // 0 3 5
    909 // 1 2 4
    910 const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
    911     {     0,     3,     5,     1,     2,     4 }
    912 };
    913 #elif defined(RGB_BACKLIGHT_M10_C)
    914 // M10-C is really simple:
    915 // 0     1     2
    916 // 3     4     5
    917 // 8     7     6
    918 //      11 10 9
    919 const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
    920     { 0, 1, 2, 3, 4, 5, 8, 7, 6, 10 }
    921 };
    922 #elif defined(RGB_BACKLIGHT_DAWN60)
    923 //Dawn60
    924 // A16, A15, A14, A13, A12, A11, A10,  A9,  B1,  B2,  B3,  B4,  B5,  B6,
    925 //  A7,  A6,  A5,  A4,  A3,  A2,  A1,  B9, B10, B11, B12, B13, B14, B15,
    926 //  A8, C14, C13, C12, C11, C10,  C9,  D1,  D2,  D3,  D4,  D5,  B8,  B7,
    927 // C15,  C5,  C4,  C3,  C2,  C1,  D9, D10, D11, D12, ---,  D6,  D7, B16,
    928 // C16,  C8,  C7, ---, ---,  C6, ---, ---, ---, D13, D14, D15, D16,  D8,
    929 const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
    930     { -1+16, -1+15, -1+14, -1+13, -1+12, -1+11, -1+10, -1+9 , 15+1 , 15+2 , 15+3 , 15+4 , 15+5 , 15+6 },
    931     { -1+7 , -1+6 , -1+5 , -1+4 , -1+3 , -1+2 , -1 +1, 15+9 , 15+10, 15+11, 15+12, 15+13, 15+14, 15+15},
    932     { -1+8 , 31+14, 31+13, 31+12, 31+11, 31+10, 31+9 , 47+1 , 47+2 , 47+3 , 47+4 , 47+5 , 15+8 , 15+7 },
    933     { 31+15, 31+5 , 31+4 , 31+3 , 31+2 , 31+1 , 47+9 , 47+10, 47+11, 47+12, 255  ,47+6 , 47+7 , 15+16},
    934     { 31+16, 31+8 , 31+7 , 255  , 255  , 31+6 , 255  , 255  , 255  , 47+13, 47+14, 47+15, 47+16, 47+8 }
    935 };
    936 #elif defined(RGB_BACKLIGHT_PORTICO)
    937 const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
    938     {  0,      1,  2,      3,      4,      5,  6,      7,      8,      9, 10, 11, 12,     13, 14 },
    939     { 15,     16, 17,     18,     19,     20, 21,     22,     23,     24, 25, 26, 27,     28, 29 },
    940     { 30,     31, 32,     33,     34,     35, 36,     37,     38,     39, 40, 41, 42,    255, 43 },
    941     { 44,    255, 45,     46,     47,     48, 49,     50,     51,     52, 53, 54, 55,     56, 57 },
    942     { 58,     59, 60,    255,    255,    255, 61,    255,    255,    255, 62, 63, 64,     65, 66 }
    943 };
    944 #elif defined(RGB_BACKLIGHT_PORTICO75)
    945 const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
    946     {   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14 },
    947     {  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29 },
    948     {  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44 },
    949     {  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57, 255, 255 },
    950     {  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70, 255, 255 },
    951     {  71,  72,  73, 255, 255,  74, 255, 255, 255,  75,  76,  77,  78,  79, 255 }
    952 };
    953 #elif defined(RGB_BACKLIGHT_M50_A)
    954 // LA15, LA14, LA13, LA12, LA11, LA10,  LA9,  LB1,  LB2,  LB3,  LB4,  LB5,  LB6
    955 // LA16,  LA6,  LA5,  LA4,  LA3,  LA2,  LA1,  LB9, LB10, LB11, LB12, LB13, LB14
    956 // LC15, LC14, LC13, LC12, LC11, LC10,  LC9,  LD1,  LD2,  LD3,  LD4,  LD5,  LD6
    957 //  LC7,  LC6,  LC5,  LC4,  LC3,  LC2,  LC1, ----, LD10, LD11, LD12, LD13, LD14
    958 const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
    959     {  0+15,  0+14,  0+13,  0+12,  0+11,  0+10,   0+9,  18+1,  18+2,  18+3,  18+4,  18+5,  18+6 },
    960     {  0+16,   0+6,   0+5,   0+4,   0+3,   0+2,   0+1,  18+9, 18+10, 18+11, 18+12, 18+13, 18+14 },
    961     { 36+15, 36+14, 36+13, 36+12, 36+11, 36+10,  36+9,  54+1,  54+2,  54+3,  54+4,  54+5,  54+6 },
    962     {  36+7,  36+6,  36+5,  36+4,  36+3,  36+2,  36+1,   255, 54+10, 54+11, 54+12, 54+13, 54+14 },
    963 };
    964 #endif
    965 
    966 void map_row_column_to_led( uint8_t row, uint8_t column, uint8_t *led )
    967 {
    968     *led = 255;
    969     if ( row < MATRIX_ROWS && column < MATRIX_COLS )
    970     {
    971         *led = pgm_read_byte(&g_map_row_column_to_led[row][column]);
    972     }
    973 }
    974 
    975 void backlight_update_pwm_buffers(void)
    976 {
    977 #if defined(RGB_BACKLIGHT_M6_B)
    978     is31fl3218_update_pwm_buffers();
    979 #elif defined(RGB_BACKLIGHT_PORTICO75)
    980 	is31fl3741_update_pwm_buffers( 0 );
    981     is31fl3741_update_led_control_registers( 0 );
    982 #elif defined(RGB_BACKLIGHT_M10_C)
    983     is31fl3731_update_pwm_buffers( 0 );
    984     is31fl3731_update_led_control_registers( 0 );
    985 #elif defined(RGB_BACKLIGHT_HS60)
    986     is31fl3733_update_pwm_buffers( 0 );
    987     is31fl3733_update_led_control_registers(  0 );
    988 #elif defined(RGB_BACKLIGHT_NK65) || defined(RGB_BACKLIGHT_NEBULA68) || defined(RGB_BACKLIGHT_NK87) || defined(RGB_BACKLIGHT_KW_MEGA)
    989     is31fl3733_update_pwm_buffers( 0 );
    990     is31fl3733_update_pwm_buffers( 1 );
    991     is31fl3733_update_led_control_registers( 0 );
    992     is31fl3733_update_led_control_registers( 1 );
    993 #elif defined(RGB_BACKLIGHT_NEBULA12)
    994     is31fl3731_update_pwm_buffers( 0 );
    995     is31fl3731_update_led_control_registers( 0 );
    996 #elif defined(RGB_BACKLIGHT_U80_A)
    997     static uint8_t driver = 0;
    998     switch ( driver )
    999     {
   1000         case 0:
   1001             is31fl3731_update_pwm_buffers( 0 );
   1002             break;
   1003         case 1:
   1004             is31fl3731_update_pwm_buffers( 1 );
   1005             break;
   1006         case 2:
   1007             is31fl3731_update_pwm_buffers( 2 );
   1008             break;
   1009     }
   1010     if ( ++driver > 2 )
   1011     {
   1012         driver = 0;
   1013     }
   1014 #else
   1015 #if defined(RGB_BACKLIGHT_DAWN60)
   1016     ws2812_flush();
   1017 #endif
   1018     is31fl3731_update_pwm_buffers( 0 );
   1019     is31fl3731_update_pwm_buffers( 1 );
   1020     is31fl3731_update_led_control_registers( 0 );
   1021     is31fl3731_update_led_control_registers( 1 );
   1022 #endif
   1023 }
   1024 
   1025 void backlight_set_color( int index, uint8_t red, uint8_t green, uint8_t blue )
   1026 {
   1027 #if defined(RGB_BACKLIGHT_M6_B)
   1028     is31fl3218_set_color( index, red, green, blue );
   1029 #elif defined(RGB_BACKLIGHT_HS60) || defined(RGB_BACKLIGHT_NK65) || defined(RGB_BACKLIGHT_NEBULA68) || defined(RGB_BACKLIGHT_KW_MEGA)
   1030     is31fl3733_set_color( index, red, green, blue );
   1031 #elif defined (RGB_BACKLIGHT_PORTICO)
   1032     is31fl3731_set_color( index, red, green, blue );
   1033 #elif defined (RGB_BACKLIGHT_PORTICO75)
   1034     is31fl3741_set_color( index, red, green, blue );
   1035 #elif defined(RGB_BACKLIGHT_NK87)
   1036     // This is done to avoid indicator LEDs being set
   1037     if (( index != 63+64-1 ) && ( index != 48+64-1 )) {
   1038         is31fl3733_set_color( index, red, green, blue );
   1039     }
   1040 #elif defined(RGB_BACKLIGHT_DAWN60)
   1041     if( index < IS31FL3731_LED_COUNT ) {
   1042         is31fl3731_set_color( index, red, green, blue );
   1043     } else {
   1044         ws2812_set_color( index - IS31FL3731_LED_COUNT, red, green, blue );
   1045     }
   1046 #else
   1047     is31fl3731_set_color( index, red, green, blue );
   1048 #endif
   1049 }
   1050 
   1051 void backlight_set_color_all( uint8_t red, uint8_t green, uint8_t blue )
   1052 {
   1053 #if defined(RGB_BACKLIGHT_M6_B)
   1054     is31fl3218_set_color_all( red, green, blue );
   1055 #elif defined(RGB_BACKLIGHT_HS60) || defined(RGB_BACKLIGHT_NK65) || defined(RGB_BACKLIGHT_NEBULA68) || defined(RGB_BACKLIGHT_KW_MEGA)
   1056     // This is done to avoid indicator LEDs being set
   1057     for (int i = 0; i < BACKLIGHT_LED_COUNT; i++) {
   1058         is31fl3733_set_color(i, red, green, blue);
   1059     }
   1060 #elif defined (RGB_BACKLIGHT_PORTICO)
   1061     // This is done to avoid indicator LEDs being set
   1062     for (int i = 0; i < BACKLIGHT_LED_COUNT; i++) {
   1063         is31fl3731_set_color(i, red, green, blue);
   1064     }
   1065 #elif defined (RGB_BACKLIGHT_PORTICO75)
   1066     // This is done to avoid indicator LEDs being set
   1067     for (int i = 0; i < BACKLIGHT_LED_COUNT; i++) {
   1068         is31fl3741_set_color(i, red, green, blue);
   1069     }
   1070 #elif defined(RGB_BACKLIGHT_NK87)
   1071     // This is done to avoid indicator LEDs being set
   1072     for (int i = 0; i < BACKLIGHT_LED_COUNT; i++) {
   1073         if (( i != 63+64-1 ) && ( i != 48+64-1 )) {
   1074             is31fl3733_set_color(i, red, green, blue);
   1075         }
   1076     }
   1077 #elif defined(RGB_BACKLIGHT_DAWN60)
   1078     is31fl3731_set_color_all( red, green, blue );
   1079     ws2812_set_color_all( red, green, blue );
   1080 #else
   1081     is31fl3731_set_color_all( red, green, blue );
   1082 #endif
   1083 }
   1084 
   1085 void backlight_set_key_hit(uint8_t row, uint8_t column)
   1086 {
   1087     uint8_t led;
   1088     map_row_column_to_led(row,column,&led);
   1089     g_key_hit[led] = 0;
   1090 
   1091     g_any_key_hit = 0;
   1092 }
   1093 
   1094 #if !defined(RGB_BACKLIGHT_HS60) && !defined(RGB_BACKLIGHT_NK65) && !defined(RGB_BACKLIGHT_NEBULA68) && !defined(RGB_BACKLIGHT_NEBULA12) && !defined(RGB_BACKLIGHT_NK87) && !defined(RGB_BACKLIGHT_KW_MEGA)
   1095 // This is (F_CPU/1024) / 20 Hz
   1096 // = 15625 Hz / 20 Hz
   1097 // = 781
   1098 #define TIMER3_TOP 781
   1099 
   1100 void backlight_timer_init(void)
   1101 {
   1102     static uint8_t backlight_timer_is_init = 0;
   1103     if ( backlight_timer_is_init )
   1104     {
   1105         return;
   1106     }
   1107     backlight_timer_is_init = 1;
   1108 
   1109     // Timer 3 setup
   1110     TCCR3B = _BV(WGM32) |           // CTC mode OCR3A as TOP
   1111              _BV(CS32) | _BV(CS30); // prescale by /1024
   1112     // Set TOP value
   1113     uint8_t sreg = SREG;
   1114     cli();
   1115 
   1116     OCR3AH = (TIMER3_TOP >> 8) & 0xff;
   1117     OCR3AL = TIMER3_TOP & 0xff;
   1118     SREG = sreg;
   1119 }
   1120 
   1121 void backlight_timer_enable(void)
   1122 {
   1123     TIMSK3 |= _BV(OCIE3A);
   1124 }
   1125 
   1126 void backlight_timer_disable(void)
   1127 {
   1128     TIMSK3 &= ~_BV(OCIE3A);
   1129 }
   1130 
   1131 #elif defined(RGB_BACKLIGHT_NEBULA12) //STM32, use GPT with TIM3. Enable in halconf.h
   1132 static void gpt_backlight_timer_task(GPTDriver *gptp);
   1133 // Timer setup at 200Khz, callback at 10k ticks = 20Hz
   1134 static GPTConfig gpt3cfg1 = {
   1135     .frequency = 200000U,
   1136     .callback  = gpt_backlight_timer_task
   1137 };
   1138 
   1139 void backlight_timer_init(void)
   1140 {
   1141     gptStart(&GPTD3, &gpt3cfg1);
   1142 }
   1143 
   1144 void backlight_timer_enable(void)
   1145 {
   1146     gptStartContinuous(&GPTD3, 10000);
   1147 }
   1148 
   1149 void backlight_timer_disable(void)
   1150 {
   1151     gptStopTimer(&GPTD3);
   1152 }
   1153 
   1154 #else //STM32, use GPT with TIM4. Enable in halconf.h
   1155 static void gpt_backlight_timer_task(GPTDriver *gptp);
   1156 // Timer setup at 200Khz, callback at 10k ticks = 20Hz
   1157 static GPTConfig gpt4cfg1 = {
   1158     .frequency = 200000U,
   1159     .callback  = gpt_backlight_timer_task
   1160 };
   1161 
   1162 void backlight_timer_init(void)
   1163 {
   1164     gptStart(&GPTD4, &gpt4cfg1);
   1165 }
   1166 
   1167 void backlight_timer_enable(void)
   1168 {
   1169     gptStartContinuous(&GPTD4, 10000);
   1170 }
   1171 
   1172 void backlight_timer_disable(void)
   1173 {
   1174     gptStopTimer(&GPTD4);
   1175 }
   1176 #endif //!defined(RGB_BACKLIGHT_HS60) && !defined(RGB_BACKLIGHT_NK65) && !defined(RGB_BACKLIGHT_NEBULA68) && !defined(RGB_BACKLIGHT_NEBULA12) && !defined(RGB_BACKLIGHT_NK87) && !defined(RGB_BACKLIGHT_KW_MEGA)
   1177 
   1178 void backlight_set_suspend_state(bool state)
   1179 {
   1180     g_suspend_state = state;
   1181 }
   1182 
   1183 void backlight_effect_rgb_test(void)
   1184 {
   1185     // Mask out bits 4 and 5
   1186     // This 2-bit value will stay the same for 16 ticks.
   1187     switch ( (g_tick & 0x30) >> 4 )
   1188     {
   1189         case 0:
   1190         {
   1191             backlight_set_color_all( 255, 0, 0 );
   1192             break;
   1193         }
   1194         case 1:
   1195         {
   1196             backlight_set_color_all( 0, 255, 0 );
   1197             break;
   1198         }
   1199         case 2:
   1200         {
   1201             backlight_set_color_all( 0, 0, 255 );
   1202             break;
   1203         }
   1204         case 3:
   1205         {
   1206             backlight_set_color_all( 255, 255, 255 );
   1207             break;
   1208         }
   1209     }
   1210 }
   1211 
   1212 #if defined(RGB_DEBUGGING_ONLY)
   1213 // This tests the LEDs
   1214 // Note that it will change the LED control registers
   1215 // in the LED drivers, and leave them in an invalid
   1216 // state for other backlight effects.
   1217 // ONLY USE THIS FOR TESTING LEDS!
   1218 void backlight_effect_single_LED_test(void)
   1219 {
   1220     static uint8_t color = 0; // 0,1,2 for R,G,B
   1221     static uint8_t row = 0;
   1222     static uint8_t column = 0;
   1223 
   1224     static uint8_t tick = 0;
   1225     tick++;
   1226 
   1227     if ( tick > 2 )
   1228     {
   1229         tick = 0;
   1230         column++;
   1231     }
   1232     if ( column > 14 )
   1233     {
   1234         column = 0;
   1235         row++;
   1236     }
   1237     if ( row > 4 )
   1238     {
   1239         row = 0;
   1240         color++;
   1241     }
   1242     if ( color > 2 )
   1243     {
   1244         color = 0;
   1245     }
   1246 
   1247     uint8_t led;
   1248     map_row_column_to_led( row, column, &led );
   1249     backlight_set_color_all( 255, 255, 255 );
   1250     backlight_test_led( led, color==0, color==1, color==2 );
   1251 }
   1252 #endif // defined(RGB_DEBUGGING_ONLY)
   1253 
   1254 // All LEDs off
   1255 void backlight_effect_all_off(void)
   1256 {
   1257     backlight_set_color_all( 0, 0, 0 );
   1258 }
   1259 
   1260 // Solid color
   1261 void backlight_effect_solid_color(void)
   1262 {
   1263     hsv_t hsv = { .h = g_config.color_1.h, .s = g_config.color_1.s, .v = g_config.brightness };
   1264     rgb_t rgb = hsv_to_rgb( hsv );
   1265     backlight_set_color_all( rgb.r, rgb.g, rgb.b );
   1266 }
   1267 
   1268 // alphas = color1, mods = color2
   1269 void backlight_effect_alphas_mods(void)
   1270 {
   1271     rgb_t rgb1 = hsv_to_rgb( (hsv_t){ .h = g_config.color_1.h, .s = g_config.color_1.s, .v = g_config.brightness } );
   1272     rgb_t rgb2 = hsv_to_rgb( (hsv_t){ .h = g_config.color_2.h, .s = g_config.color_2.s, .v = g_config.brightness } );
   1273     bool is_alpha = false;
   1274     for ( int row = 0; row < MATRIX_ROWS; row++ )
   1275     {
   1276         for ( int column = 0; column < MATRIX_COLS; column++ )
   1277         {
   1278             uint8_t index;
   1279             map_row_column_to_led( row, column, &index );
   1280             if ( index < BACKLIGHT_LED_COUNT )
   1281             {
   1282 #if defined(RGB_BACKLIGHT_U80_A)
   1283                 if ( row == 0 )
   1284                 {
   1285                     is_alpha = ( column < 16 ) && (( 0b1110000111100001 & (1<<column) ) == 0);
   1286                 }
   1287                 else
   1288                 {
   1289                     is_alpha = ( column < 16 ) && (( g_config.alphas_mods[row-1] & (1<<column) ) == 0);
   1290                 }
   1291 #elif defined(RGB_BACKLIGHT_NK87)
   1292                 if ( row == 0 )
   1293                 {
   1294                     is_alpha = ( ( 0b11100000111100001 & (1<<column) ) == 0);
   1295                 }
   1296                 else
   1297                 {
   1298                     is_alpha = ( column < 16 ) && (( g_config.alphas_mods[row-1] & (1<<column) ) == 0);
   1299                 }
   1300 #elif defined(RGB_BACKLIGHT_PORTICO75)
   1301                 if ( row == 0 )
   1302                 {
   1303                     is_alpha = ( ( 0b11100000111100001 & (1<<column) ) == 0);
   1304                 }
   1305                 else
   1306                 {
   1307                     is_alpha = ( column < 16 ) && (( g_config.alphas_mods[row-1] & (1<<column) ) == 0);
   1308                 }
   1309 #else
   1310                 is_alpha = ( g_config.alphas_mods[row] & (1<<column) ) == 0;
   1311 #endif
   1312                 if ( is_alpha )
   1313                 {
   1314                     backlight_set_color( index, rgb1.r, rgb1.g, rgb1.b );
   1315                 }
   1316                 else
   1317                 {
   1318                     backlight_set_color( index, rgb2.r, rgb2.g, rgb2.b );
   1319                 }
   1320             }
   1321         }
   1322     }
   1323 #if defined(RGB_BACKLIGHT_DAWN60)
   1324     for (int i = 0; i < WS2812_LED_COUNT; i++) {
   1325         if ((RGB_UNDERGLOW_ALPHA_TOP_START <= i && i <= RGB_UNDERGLOW_ALPHA_TOP_END) ||
   1326             (RGB_UNDERGLOW_ALPHA_BOT_START <= i && i <= RGB_UNDERGLOW_ALPHA_BOT_END)) {
   1327             backlight_set_color(i + IS31FL3731_LED_COUNT, rgb1.r, rgb1.g, rgb1.b);
   1328         } else {
   1329             backlight_set_color(i + IS31FL3731_LED_COUNT, rgb2.r, rgb2.g, rgb2.b);
   1330         }
   1331     }
   1332 #endif
   1333 }
   1334 
   1335 void backlight_effect_gradient_up_down(void)
   1336 {
   1337     int16_t h1 = g_config.color_1.h;
   1338     int16_t h2 = g_config.color_2.h;
   1339     int16_t deltaH = h2 - h1;
   1340 
   1341     // Take the shortest path between hues
   1342     if ( deltaH > 127 )
   1343     {
   1344         deltaH -= 256;
   1345     }
   1346     else if ( deltaH < -127 )
   1347     {
   1348         deltaH += 256;
   1349     }
   1350     // Divide delta by 4, this gives the delta per row
   1351     deltaH /= 4;
   1352 
   1353     int16_t s1 = g_config.color_1.s;
   1354     int16_t s2 = g_config.color_2.s;
   1355     int16_t deltaS = ( s2 - s1 ) / 4;
   1356 
   1357     hsv_t hsv = { .h = 0, .s = 255, .v = g_config.brightness };
   1358     rgb_t rgb;
   1359     Point point;
   1360     for ( int i=0; i<BACKLIGHT_LED_COUNT; i++ )
   1361     {
   1362         map_led_to_point( i, &point );
   1363         // The y range will be 0..64, map this to 0..4
   1364         uint8_t y = (point.y>>4);
   1365         // Relies on hue being 8-bit and wrapping
   1366         hsv.h = g_config.color_1.h + ( deltaH * y );
   1367         hsv.s = g_config.color_1.s + ( deltaS * y );
   1368         rgb = hsv_to_rgb( hsv );
   1369 
   1370         backlight_set_color( i, rgb.r, rgb.g, rgb.b );
   1371     }
   1372 }
   1373 
   1374 void backlight_effect_raindrops(bool initialize)
   1375 {
   1376     int16_t h1 = g_config.color_1.h;
   1377     int16_t h2 = g_config.color_2.h;
   1378     int16_t deltaH = h2 - h1;
   1379     deltaH /= 4;
   1380 
   1381     // Take the shortest path between hues
   1382     if ( deltaH > 127 )
   1383     {
   1384         deltaH -= 256;
   1385     }
   1386     else if ( deltaH < -127 )
   1387     {
   1388         deltaH += 256;
   1389     }
   1390 
   1391     int16_t s1 = g_config.color_1.s;
   1392     int16_t s2 = g_config.color_2.s;
   1393     int16_t deltaS = ( s2 - s1 ) / 4;
   1394 
   1395     hsv_t hsv;
   1396     rgb_t rgb;
   1397 
   1398     // Change one LED every tick
   1399     uint8_t led_to_change = ( g_tick & 0x000 ) == 0 ? rand() % BACKLIGHT_LED_COUNT : 255;
   1400 
   1401     for ( int i=0; i<BACKLIGHT_LED_COUNT; i++ )
   1402     {
   1403         // If initialize, all get set to random colors
   1404         // If not, all but one will stay the same as before.
   1405         if ( initialize || i == led_to_change )
   1406         {
   1407             hsv.h = h1 + ( deltaH * ( rand() & 0x03 ) );
   1408             hsv.s = s1 + ( deltaS * ( rand() & 0x03 ) );
   1409             // Override brightness with global brightness control
   1410             hsv.v = g_config.brightness;
   1411 
   1412             rgb = hsv_to_rgb( hsv );
   1413             backlight_set_color( i, rgb.r, rgb.g, rgb.b );
   1414         }
   1415     }
   1416 }
   1417 
   1418 void backlight_effect_cycle_all(void)
   1419 {
   1420     uint8_t offset = ( g_tick << g_config.effect_speed ) & 0xFF;
   1421 
   1422     // Relies on hue being 8-bit and wrapping
   1423     for ( int i=0; i<BACKLIGHT_LED_COUNT; i++ )
   1424     {
   1425         uint16_t offset2 = g_key_hit[i]<<2;
   1426 #if !defined(RGB_BACKLIGHT_HS60) && !defined(RGB_BACKLIGHT_NK65) && !defined(RGB_BACKLIGHT_DAWN60) && !defined(RGB_BACKLIGHT_NEBULA68) && !defined(RGB_BACKLIGHT_NEBULA12) && !defined(RGB_BACKLIGHT_NK87) && !defined(RGB_BACKLIGHT_KW_MEGA)
   1427         // stabilizer LEDs use spacebar hits
   1428         if ( i == 36+6 || i == 54+13 || // LC6, LD13
   1429                 ( g_config.use_7u_spacebar && i == 54+14 ) ) // LD14
   1430         {
   1431             offset2 = g_key_hit[36+0]<<2;
   1432         }
   1433 #endif
   1434         offset2 = (offset2<=63) ? (63-offset2) : 0;
   1435 
   1436         hsv_t hsv = { .h = offset+offset2, .s = 255, .v = g_config.brightness };
   1437         rgb_t rgb = hsv_to_rgb( hsv );
   1438         backlight_set_color( i, rgb.r, rgb.g, rgb.b );
   1439     }
   1440 }
   1441 
   1442 void backlight_effect_cycle_left_right(void)
   1443 {
   1444     uint8_t offset = ( g_tick << g_config.effect_speed ) & 0xFF;
   1445     hsv_t hsv = { .h = 0, .s = 255, .v = g_config.brightness };
   1446     rgb_t rgb;
   1447     Point point;
   1448     for ( int i=0; i<BACKLIGHT_LED_COUNT; i++ )
   1449     {
   1450         uint16_t offset2 = g_key_hit[i]<<2;
   1451 #if !defined(RGB_BACKLIGHT_HS60) && !defined(RGB_BACKLIGHT_NK65) && !defined(RGB_BACKLIGHT_DAWN60) && !defined(RGB_BACKLIGHT_NEBULA68) && !defined(RGB_BACKLIGHT_NEBULA12) && !defined(RGB_BACKLIGHT_NK87) && !defined(RGB_BACKLIGHT_KW_MEGA)
   1452         // stabilizer LEDs use spacebar hits
   1453         if ( i == 36+6 || i == 54+13 || // LC6, LD13
   1454                 ( g_config.use_7u_spacebar && i == 54+14 ) ) // LD14
   1455         {
   1456             offset2 = g_key_hit[36+0]<<2;
   1457         }
   1458 #endif
   1459         offset2 = (offset2<=63) ? (63-offset2) : 0;
   1460 
   1461         map_led_to_point( i, &point );
   1462         // Relies on hue being 8-bit and wrapping
   1463         hsv.h = point.x + offset + offset2;
   1464         rgb = hsv_to_rgb( hsv );
   1465         backlight_set_color( i, rgb.r, rgb.g, rgb.b );
   1466     }
   1467 }
   1468 
   1469 void backlight_effect_cycle_up_down(void)
   1470 {
   1471     uint8_t offset = ( g_tick << g_config.effect_speed ) & 0xFF;
   1472     hsv_t hsv = { .h = 0, .s = 255, .v = g_config.brightness };
   1473     rgb_t rgb;
   1474     Point point;
   1475     for ( int i=0; i<BACKLIGHT_LED_COUNT; i++ )
   1476     {
   1477         uint16_t offset2 = g_key_hit[i]<<2;
   1478 #if !defined(RGB_BACKLIGHT_HS60) && !defined(RGB_BACKLIGHT_NK65) && !defined(RGB_BACKLIGHT_DAWN60) && !defined(RGB_BACKLIGHT_NEBULA68) && !defined(RGB_BACKLIGHT_NEBULA12) && !defined(RGB_BACKLIGHT_NK87) && !defined(RGB_BACKLIGHT_KW_MEGA)
   1479         // stabilizer LEDs use spacebar hits
   1480         if ( i == 36+6 || i == 54+13 || // LC6, LD13
   1481                 ( g_config.use_7u_spacebar && i == 54+14 ) ) // LD14
   1482         {
   1483             offset2 = g_key_hit[36+0]<<2;
   1484         }
   1485 #endif
   1486         offset2 = (offset2<=63) ? (63-offset2) : 0;
   1487 
   1488         map_led_to_point( i, &point );
   1489         // Relies on hue being 8-bit and wrapping
   1490         hsv.h = point.y + offset + offset2;
   1491         rgb = hsv_to_rgb( hsv );
   1492         backlight_set_color( i, rgb.r, rgb.g, rgb.b );
   1493     }
   1494 }
   1495 
   1496 void backlight_effect_jellybean_raindrops( bool initialize )
   1497 {
   1498     hsv_t hsv;
   1499     rgb_t rgb;
   1500 
   1501     // Change one LED every tick
   1502     uint8_t led_to_change = ( g_tick & 0x000 ) == 0 ? rand() % BACKLIGHT_LED_COUNT : 255;
   1503 
   1504     for ( int i=0; i<BACKLIGHT_LED_COUNT; i++ )
   1505     {
   1506         // If initialize, all get set to random colors
   1507         // If not, all but one will stay the same as before.
   1508         if ( initialize || i == led_to_change )
   1509         {
   1510             hsv.h = rand() & 0xFF;
   1511             hsv.s = rand() & 0xFF;
   1512             // Override brightness with global brightness control
   1513             hsv.v = g_config.brightness;;
   1514 
   1515             rgb = hsv_to_rgb( hsv );
   1516             backlight_set_color( i, rgb.r, rgb.g, rgb.b );
   1517         }
   1518     }
   1519 }
   1520 
   1521 void backlight_effect_cycle_radial1(void)
   1522 {
   1523     uint8_t offset = ( g_tick << g_config.effect_speed ) & 0xFF;
   1524     hsv_t hsv = { .h = 0, .s = 255, .v = g_config.brightness };
   1525     rgb_t rgb;
   1526     Point point;
   1527     for ( int i=0; i<BACKLIGHT_LED_COUNT; i++ )
   1528     {
   1529         map_led_to_point_polar( i, &point );
   1530         // Relies on hue being 8-bit and wrapping
   1531         hsv.h = point.x + offset;
   1532         hsv.s = point.y;
   1533         rgb = hsv_to_rgb( hsv );
   1534         backlight_set_color( i, rgb.r, rgb.g, rgb.b );
   1535     }
   1536 }
   1537 
   1538 void backlight_effect_cycle_radial2(void)
   1539 {
   1540     uint8_t offset = ( g_tick << g_config.effect_speed ) & 0xFF;
   1541 
   1542     hsv_t hsv = { .h = 0, .s = g_config.color_1.s, .v = g_config.brightness };
   1543     rgb_t rgb;
   1544     Point point;
   1545     for ( int i=0; i<BACKLIGHT_LED_COUNT; i++ )
   1546     {
   1547         map_led_to_point_polar( i, &point );
   1548         uint8_t offset2 = offset + point.x;
   1549         if ( offset2 & 0x80 )
   1550         {
   1551             offset2 = ~offset2;
   1552         }
   1553         offset2 = offset2 >> 2;
   1554         hsv.h = g_config.color_1.h + offset2;
   1555         hsv.s = 127 + ( point.y >> 1 );
   1556         rgb = hsv_to_rgb( hsv );
   1557         backlight_set_color( i, rgb.r, rgb.g, rgb.b );
   1558     }
   1559 }
   1560 
   1561 #if defined(RGB_BACKLIGHT_M6_B) || defined(RGB_BACKLIGHT_M10_C)
   1562 void backlight_effect_custom_colors(void)
   1563 {
   1564     rgb_t rgb;
   1565     for ( uint8_t i = 0; i < RGB_BACKLIGHT_CUSTOM_COLORS_COUNT; i++ )
   1566     {
   1567         hsv_t hsv = { .h = g_config.custom_color[i].h, .s = g_config.custom_color[i].s, .v = g_config.brightness };
   1568         rgb = hsv_to_rgb( hsv );
   1569         uint8_t led;
   1570         map_row_column_to_led( 0, i, &led );
   1571         backlight_set_color( led, rgb.r, rgb.g, rgb.b );
   1572 #if defined(RGB_BACKLIGHT_M10_C)
   1573         // Set stab LEDs with the same color
   1574         if ( led == 10 ) {
   1575             backlight_set_color( 9, rgb.r, rgb.g, rgb.b );
   1576             backlight_set_color( 11, rgb.r, rgb.g, rgb.b );
   1577         }
   1578 #endif
   1579     }
   1580 }
   1581 #endif
   1582 
   1583 void backlight_effect_indicators_set_colors( uint8_t index, HS color )
   1584 {
   1585     hsv_t hsv = { .h = color.h, .s = color.s, .v = g_config.brightness };
   1586     rgb_t rgb = hsv_to_rgb( hsv );
   1587     if ( index == 254 )
   1588     {
   1589         backlight_set_color_all( rgb.r, rgb.g, rgb.b );
   1590     }
   1591     else
   1592     {
   1593         backlight_set_color( index, rgb.r, rgb.g, rgb.b );
   1594 
   1595         // If the spacebar LED is the indicator,
   1596         // do the same for the spacebar stabilizers
   1597         if ( index == 36+0 ) // LC0
   1598         {
   1599 #if defined(RGB_BACKLIGHT_ZEAL65)
   1600             backlight_set_color( 36+7, rgb.r, rgb.g, rgb.b ); // LC7
   1601             backlight_set_color( 54+14, rgb.r, rgb.g, rgb.b ); // LD14
   1602 #elif defined(RGB_BACKLIGHT_KOYU) || defined(RGB_BACKLIGHT_M65_B) || defined(RGB_BACKLIGHT_M65_BX)
   1603             backlight_set_color( 36+6, rgb.r, rgb.g, rgb.b ); // LC6
   1604             backlight_set_color( 54+14, rgb.r, rgb.g, rgb.b ); // LD14
   1605 #elif defined(RGB_BACKLIGHT_ZEAL60) || defined(RGB_BACKLIGHT_M60_A)
   1606             backlight_set_color( 36+6, rgb.r, rgb.g, rgb.b ); // LC6
   1607             backlight_set_color( 54+13, rgb.r, rgb.g, rgb.b ); // LD13
   1608             if ( g_config.use_7u_spacebar )
   1609             {
   1610                 backlight_set_color( 54+14, rgb.r, rgb.g, rgb.b ); // LD14
   1611             }
   1612 #endif
   1613         }
   1614     }
   1615 }
   1616 
   1617 // This runs after another backlight effect and replaces
   1618 // colors already set
   1619 __attribute__ ((weak)) void backlight_effect_indicators(void)
   1620 {
   1621     if ( g_config.caps_lock_indicator.index != 255 && host_keyboard_led_state().caps_lock )
   1622     {
   1623         backlight_effect_indicators_set_colors( g_config.caps_lock_indicator.index, g_config.caps_lock_indicator.color );
   1624     }
   1625     // This if/else if structure allows higher layers to
   1626     // override lower ones. If we set layer 3's indicator
   1627     // to none, then it will NOT show layer 2 or layer 1
   1628     // indicators, even if those layers are on via the
   1629     // MO13/MO23 Fn combo magic.
   1630     //
   1631     // Basically we want to handle the case where layer 3 is
   1632     // still the backlight configuration layer and we don't
   1633     // want "all LEDs" indicators hiding the backlight effect,
   1634     // but still allow end users to do whatever they want.
   1635     if ( IS_LAYER_ON(3) )
   1636     {
   1637         if ( g_config.layer_3_indicator.index != 255 )
   1638         {
   1639             backlight_effect_indicators_set_colors( g_config.layer_3_indicator.index, g_config.layer_3_indicator.color );
   1640         }
   1641     }
   1642     else if ( IS_LAYER_ON(2) )
   1643     {
   1644         if ( g_config.layer_2_indicator.index != 255 )
   1645         {
   1646             backlight_effect_indicators_set_colors( g_config.layer_2_indicator.index, g_config.layer_2_indicator.color );
   1647         }
   1648     }
   1649     else if ( IS_LAYER_ON(1) )
   1650     {
   1651         if ( g_config.layer_1_indicator.index != 255 )
   1652         {
   1653             backlight_effect_indicators_set_colors( g_config.layer_1_indicator.index, g_config.layer_1_indicator.color );
   1654         }
   1655     }
   1656 }
   1657 
   1658 #if !defined(RGB_BACKLIGHT_HS60) && !defined(RGB_BACKLIGHT_NK65) && !defined(RGB_BACKLIGHT_NEBULA68) && !defined(RGB_BACKLIGHT_NEBULA12) && !defined(RGB_BACKLIGHT_NK87) && !defined(RGB_BACKLIGHT_KW_MEGA)
   1659 ISR(TIMER3_COMPA_vect)
   1660 #else //STM32 interrupt
   1661 static void gpt_backlight_timer_task(GPTDriver *gptp)
   1662 #endif
   1663 {
   1664     // delay 1 second before driving LEDs or doing anything else
   1665     static uint8_t startup_tick = 0;
   1666     if ( startup_tick < 20 )
   1667     {
   1668         startup_tick++;
   1669         return;
   1670     }
   1671 
   1672     g_tick++;
   1673 
   1674     if ( g_any_key_hit < 0xFFFFFFFF )
   1675     {
   1676         g_any_key_hit++;
   1677     }
   1678 
   1679     for ( int led = 0; led < BACKLIGHT_LED_COUNT; led++ )
   1680     {
   1681         if ( g_key_hit[led] < 255 )
   1682         {
   1683             g_key_hit[led]++;
   1684         }
   1685     }
   1686 
   1687     // Factory default magic value
   1688     if ( g_config.effect == 255 )
   1689     {
   1690         backlight_effect_rgb_test();
   1691         return;
   1692     }
   1693 
   1694     // Ideally we would also stop sending zeros to the LED driver PWM buffers
   1695     // while suspended and just do a software shutdown. This is a cheap hack for now.
   1696     bool suspend_backlight = ((g_suspend_state && g_config.disable_when_usb_suspended) ||
   1697             (g_config.disable_after_timeout > 0 && g_any_key_hit > g_config.disable_after_timeout * 60 * 20));
   1698     uint8_t effect = suspend_backlight ? 0 : g_config.effect;
   1699 
   1700     // Keep track of the effect used last time,
   1701     // detect change in effect, so each effect can
   1702     // have an optional initialization.
   1703     static uint8_t effect_last = 255;
   1704     bool initialize = effect != effect_last;
   1705     effect_last = effect;
   1706 
   1707     // this gets ticked at 20 Hz.
   1708     // each effect can opt to do calculations
   1709     // and/or request PWM buffer updates.
   1710     switch ( effect )
   1711     {
   1712         case 0:
   1713             backlight_effect_all_off();
   1714             break;
   1715         case 1:
   1716             backlight_effect_solid_color();
   1717             break;
   1718         case 2:
   1719 #if defined(RGB_BACKLIGHT_M6_B) || defined(RGB_BACKLIGHT_M10_C)
   1720             backlight_effect_custom_colors();
   1721 #else
   1722             backlight_effect_alphas_mods();
   1723 #endif
   1724             break;
   1725         case 3:
   1726             backlight_effect_gradient_up_down();
   1727             break;
   1728         case 4:
   1729             backlight_effect_raindrops( initialize );
   1730             break;
   1731         case 5:
   1732             backlight_effect_cycle_all();
   1733             break;
   1734         case 6:
   1735             backlight_effect_cycle_left_right();
   1736             break;
   1737         case 7:
   1738             backlight_effect_cycle_up_down();
   1739             break;
   1740         case 8:
   1741             backlight_effect_jellybean_raindrops( initialize );
   1742             break;
   1743         case 9:
   1744             backlight_effect_cycle_radial1();
   1745             break;
   1746         case 10:
   1747             backlight_effect_cycle_radial2();
   1748             break;
   1749         default:
   1750             backlight_effect_all_off();
   1751             break;
   1752     }
   1753 
   1754     if ( ! suspend_backlight )
   1755     {
   1756         backlight_effect_indicators();
   1757     }
   1758 }
   1759 
   1760 void backlight_set_indicator_index( uint8_t *index, uint8_t row, uint8_t column )
   1761 {
   1762     if ( row >= MATRIX_ROWS )
   1763     {
   1764         // Special value, 255=none, 254=all
   1765         *index = row;
   1766     }
   1767     else
   1768     {
   1769         map_row_column_to_led( row, column, index );
   1770     }
   1771 }
   1772 
   1773 void backlight_get_indicator_row_col( uint8_t index, uint8_t *row, uint8_t *column )
   1774 {
   1775     if ( index == 255 || index == 254 )
   1776     {
   1777         // Special value, 255=none, 254=all
   1778         *row = index;
   1779         *column = 0;
   1780         return;
   1781     }
   1782     for ( uint8_t r = 0; r < MATRIX_ROWS; r++ )
   1783     {
   1784         for ( uint8_t c = 0; c < MATRIX_COLS; c++ )
   1785         {
   1786             uint8_t i = 255;
   1787             map_row_column_to_led( r, c, &i );
   1788             if ( i == index )
   1789             {
   1790                 *row = r;
   1791                 *column = c;
   1792                 return;
   1793             }
   1794         }
   1795     }
   1796 }
   1797 
   1798 // Some helpers for setting/getting HSV
   1799 void _set_color( HS *color, uint8_t *data )
   1800 {
   1801     color->h = data[0];
   1802     color->s = data[1];
   1803 }
   1804 
   1805 void _get_color( HS *color, uint8_t *data )
   1806 {
   1807     data[0] = color->h;
   1808     data[1] = color->s;
   1809 }
   1810 
   1811 void backlight_config_set_value( uint8_t *data )
   1812 {
   1813     bool reinitialize = false;
   1814     uint8_t *value_id = &(data[0]);
   1815     uint8_t *value_data = &(data[1]);
   1816     switch ( *value_id )
   1817     {
   1818 #if defined (RGB_BACKLIGHT_ZEAL60) || defined(RGB_BACKLIGHT_ZEAL65)
   1819         case id_use_split_backspace:
   1820         {
   1821             g_config.use_split_backspace = (bool)*value_data;
   1822             reinitialize = true;
   1823             break;
   1824         }
   1825 #endif
   1826 #if defined (RGB_BACKLIGHT_ZEAL60)
   1827         case id_use_split_left_shift:
   1828         {
   1829             g_config.use_split_left_shift = (bool)*value_data;
   1830             reinitialize = true;
   1831             break;
   1832         }
   1833         case id_use_split_right_shift:
   1834         {
   1835             g_config.use_split_right_shift = (bool)*value_data;
   1836             reinitialize = true;
   1837             break;
   1838         }
   1839         case id_use_7u_spacebar:
   1840         {
   1841             g_config.use_7u_spacebar = (bool)*value_data;
   1842             reinitialize = true;
   1843             break;
   1844         }
   1845         case id_use_iso_enter:
   1846         {
   1847             g_config.use_iso_enter = (bool)*value_data;
   1848             reinitialize = true;
   1849             break;
   1850         }
   1851         case id_disable_hhkb_blocker_leds:
   1852         {
   1853             g_config.disable_hhkb_blocker_leds = (bool)*value_data;
   1854             reinitialize = true;
   1855             break;
   1856         }
   1857 #endif
   1858         case id_disable_when_usb_suspended:
   1859         {
   1860             g_config.disable_when_usb_suspended = (bool)*value_data;
   1861             break;
   1862         }
   1863         case id_disable_after_timeout:
   1864         {
   1865             g_config.disable_after_timeout = *value_data;
   1866             break;
   1867         }
   1868         case id_brightness:
   1869         {
   1870             g_config.brightness = *value_data;
   1871             break;
   1872         }
   1873         case id_effect:
   1874         {
   1875             g_config.effect = *value_data;
   1876             break;
   1877         }
   1878         case id_effect_speed:
   1879         {
   1880             g_config.effect_speed = *value_data;
   1881             break;
   1882         }
   1883         case id_color_1:
   1884         {
   1885             _set_color( &(g_config.color_1), value_data );
   1886             break;
   1887         }
   1888         case id_color_2:
   1889         {
   1890             _set_color( &(g_config.color_2), value_data );
   1891             break;
   1892         }
   1893         case id_caps_lock_indicator_color:
   1894         {
   1895             _set_color( &(g_config.caps_lock_indicator.color), value_data );
   1896             break;
   1897         }
   1898         case id_caps_lock_indicator_row_col:
   1899         {
   1900             backlight_set_indicator_index( &(g_config.caps_lock_indicator.index), value_data[0], value_data[1] );
   1901             break;
   1902         }
   1903         case id_layer_1_indicator_color:
   1904         {
   1905             _set_color( &(g_config.layer_1_indicator.color), value_data );
   1906             break;
   1907         }
   1908         case id_layer_1_indicator_row_col:
   1909         {
   1910             backlight_set_indicator_index( &(g_config.layer_1_indicator.index), value_data[0], value_data[1] );
   1911             break;
   1912         }
   1913         case id_layer_2_indicator_color:
   1914         {
   1915             _set_color( &(g_config.layer_2_indicator.color), value_data );
   1916             break;
   1917         }
   1918         case id_layer_2_indicator_row_col:
   1919         {
   1920             backlight_set_indicator_index( &(g_config.layer_2_indicator.index), value_data[0], value_data[1] );
   1921             break;
   1922         }
   1923         case id_layer_3_indicator_color:
   1924         {
   1925             _set_color( &(g_config.layer_3_indicator.color), value_data );
   1926             break;
   1927         }
   1928         case id_layer_3_indicator_row_col:
   1929         {
   1930             backlight_set_indicator_index( &(g_config.layer_3_indicator.index), value_data[0], value_data[1] );
   1931             break;
   1932         }
   1933         case id_alphas_mods:
   1934         {
   1935             for ( int i=0; i<5; i++ )
   1936             {
   1937                 g_config.alphas_mods[i] = ( *(value_data+i*2) << 8 ) | ( *(value_data+i*2+1) );
   1938             }
   1939         }
   1940 #if defined(RGB_BACKLIGHT_M6_B) || defined(RGB_BACKLIGHT_M10_C)
   1941         case id_custom_color:
   1942         {
   1943             uint8_t index = value_data[0];
   1944             if ( index >= 0 && index < RGB_BACKLIGHT_CUSTOM_COLORS_COUNT )
   1945             {
   1946                 _set_color( &(g_config.custom_color[index]), &(value_data[1]) );
   1947             }
   1948         }
   1949 #endif
   1950     }
   1951 
   1952     if ( reinitialize )
   1953     {
   1954         backlight_init_drivers();
   1955     }
   1956 }
   1957 
   1958 void backlight_config_get_value( uint8_t *data )
   1959 {
   1960     uint8_t *value_id = &(data[0]);
   1961     uint8_t *value_data = &(data[1]);
   1962     switch ( *value_id )
   1963     {
   1964         case id_use_split_backspace:
   1965         {
   1966             *value_data = ( g_config.use_split_backspace ? 1 : 0 );
   1967             break;
   1968         }
   1969         case id_use_split_left_shift:
   1970         {
   1971             *value_data = ( g_config.use_split_left_shift ? 1 : 0 );
   1972             break;
   1973         }
   1974         case id_use_split_right_shift:
   1975         {
   1976             *value_data = ( g_config.use_split_right_shift ? 1 : 0 );
   1977             break;
   1978         }
   1979         case id_use_7u_spacebar:
   1980         {
   1981             *value_data = ( g_config.use_7u_spacebar ? 1 : 0 );
   1982             break;
   1983         }
   1984         case id_use_iso_enter:
   1985         {
   1986             *value_data = ( g_config.use_iso_enter ? 1 : 0 );
   1987             break;
   1988         }
   1989         case id_disable_when_usb_suspended:
   1990         {
   1991             *value_data = ( g_config.disable_when_usb_suspended ? 1 : 0 );
   1992             break;
   1993         }
   1994         case id_disable_hhkb_blocker_leds:
   1995         {
   1996             *value_data = ( g_config.disable_hhkb_blocker_leds ? 1 : 0 );
   1997             break;
   1998         }
   1999         case id_disable_after_timeout:
   2000         {
   2001             *value_data = g_config.disable_after_timeout;
   2002             break;
   2003         }
   2004         case id_brightness:
   2005         {
   2006             *value_data = g_config.brightness;
   2007             break;
   2008         }
   2009         case id_effect:
   2010         {
   2011             *value_data = g_config.effect;
   2012             break;
   2013         }
   2014         case id_effect_speed:
   2015         {
   2016             *value_data = g_config.effect_speed;
   2017             break;
   2018         }
   2019         case id_color_1:
   2020         {
   2021             _get_color( &(g_config.color_1), value_data );
   2022             break;
   2023         }
   2024         case id_color_2:
   2025         {
   2026             _get_color( &(g_config.color_2), value_data );
   2027             break;
   2028         }
   2029         case id_caps_lock_indicator_color:
   2030         {
   2031             _get_color( &(g_config.caps_lock_indicator.color), value_data );
   2032             break;
   2033         }
   2034         case id_caps_lock_indicator_row_col:
   2035         {
   2036             backlight_get_indicator_row_col( g_config.caps_lock_indicator.index, &(value_data[0]), &(value_data[1]) );
   2037             break;
   2038         }
   2039         case id_layer_1_indicator_color:
   2040         {
   2041             _get_color( &(g_config.layer_1_indicator.color), value_data );
   2042             break;
   2043         }
   2044         case id_layer_1_indicator_row_col:
   2045         {
   2046             backlight_get_indicator_row_col( g_config.layer_1_indicator.index, &(value_data[0]), &(value_data[1]) );
   2047             break;
   2048         }
   2049         case id_layer_2_indicator_color:
   2050         {
   2051             _get_color( &(g_config.layer_2_indicator.color), value_data );
   2052             break;
   2053         }
   2054         case id_layer_2_indicator_row_col:
   2055         {
   2056             backlight_get_indicator_row_col( g_config.layer_2_indicator.index, &(value_data[0]), &(value_data[1]) );
   2057             break;
   2058         }
   2059         case id_layer_3_indicator_color:
   2060         {
   2061             _get_color( &(g_config.layer_3_indicator.color), value_data );
   2062             break;
   2063         }
   2064         case id_layer_3_indicator_row_col:
   2065         {
   2066             backlight_get_indicator_row_col( g_config.layer_3_indicator.index, &(value_data[0]), &(value_data[1]) );
   2067             break;
   2068         }
   2069         case id_alphas_mods:
   2070         {
   2071             for ( int i=0; i<5; i++ )
   2072             {
   2073                 *(value_data+i*2) = g_config.alphas_mods[i] >> 8;
   2074                 *(value_data+i*2+1) = g_config.alphas_mods[i] & 0xFF;
   2075             }
   2076         }
   2077 #if defined(RGB_BACKLIGHT_M6_B) || defined(RGB_BACKLIGHT_M10_C)
   2078         case id_custom_color:
   2079         {
   2080             uint8_t index = value_data[0];
   2081             if ( index >= 0 && index < RGB_BACKLIGHT_CUSTOM_COLORS_COUNT )
   2082             {
   2083                 _get_color( &(g_config.custom_color[index]), &(value_data[1]) );
   2084             }
   2085         }
   2086 #endif
   2087     }
   2088 }
   2089 
   2090 void backlight_config_set_alphas_mods( uint16_t *alphas_mods )
   2091 {
   2092     for ( int i=0; i<5; i++ )
   2093     {
   2094         g_config.alphas_mods[i] = alphas_mods[i];
   2095     }
   2096 
   2097     backlight_config_save();
   2098 }
   2099 
   2100 void backlight_config_load(void)
   2101 {
   2102     eeprom_read_block( &g_config, ((void*)RGB_BACKLIGHT_CONFIG_EEPROM_ADDR), sizeof(backlight_config) );
   2103 }
   2104 
   2105 void backlight_config_save(void)
   2106 {
   2107     eeprom_update_block( &g_config, ((void*)RGB_BACKLIGHT_CONFIG_EEPROM_ADDR), sizeof(backlight_config) );
   2108 }
   2109 
   2110 void backlight_init_drivers(void)
   2111 {
   2112     // Initialize I2C
   2113     i2c_init();
   2114 
   2115 #if defined(RGB_BACKLIGHT_M6_B)
   2116     is31fl3218_init();
   2117 
   2118     for ( int index = 0; index < IS31FL3218_LED_COUNT; index++ )
   2119     {
   2120         bool enabled = true;
   2121 
   2122         // This only caches it for later
   2123         is31fl3218_set_led_control_register( index, enabled, enabled, enabled );
   2124     }
   2125 
   2126     // This actually updates the LED drivers
   2127     is31fl3218_update_led_control_registers();
   2128 #elif defined(RGB_BACKLIGHT_HS60)
   2129     is31fl3733_init( 0 );
   2130 
   2131     for ( int index = 0; index < IS31FL3733_LED_COUNT; index++ )
   2132     {
   2133 #if defined(HS60_ANSI)
   2134         bool enabled = !( ( index == 48-1 ) || //LA48
   2135                           ( index == 51-1 ) || //LA51
   2136                           ( index == 61-1 ) ); //LA61
   2137 #elif defined(HS60_HHKB)
   2138         bool enabled = !( ( index == 61-1 ) || //LA61
   2139                           ( index == 62-1 ) ); //LA62
   2140 #else //HS60_ISO
   2141         bool enabled = !( ( index == 51-1 ) || //LA51
   2142                           ( index == 61-1 ) ); //LA61
   2143 #endif
   2144                 // This only caches it for later
   2145         is31fl3733_set_led_control_register( index, enabled, enabled, enabled );
   2146     }
   2147     // This actually updates the LED drivers
   2148     is31fl3733_update_led_control_registers( 0 );
   2149 #elif defined(RGB_BACKLIGHT_NK65)
   2150     is31fl3733_init( 0 );
   2151     is31fl3733_init( 1 );
   2152 
   2153     for ( int index = 0; index < IS31FL3733_LED_COUNT; index++ )
   2154     {
   2155         bool enabled = !( ( index == 61-1 )   || //LA61
   2156                           ( index > 6+64-1 ) ); //LB7-LB64
   2157         // This only caches it for later
   2158         is31fl3733_set_led_control_register( index, enabled, enabled, enabled );
   2159     }
   2160     is31fl3733_set_led_control_register( 7+64-1, 0, 1, 0 ); //Enable LB7 green enable for indicators
   2161     // This actually updates the LED drivers
   2162     is31fl3733_update_led_control_registers( 0 );
   2163     is31fl3733_update_led_control_registers( 1 );
   2164 #elif defined(RGB_BACKLIGHT_NK87)
   2165     is31fl3733_init( 0 );
   2166     is31fl3733_init( 1 );
   2167 
   2168     for ( int index = 0; index < IS31FL3733_LED_COUNT; index++ )
   2169     {
   2170         bool enabled = !( ( index == 61-1 )   || //LA61
   2171                           ( (index >= 2+64-1) && (index <= 4+64-1) ) ||
   2172                           ( (index >= 6+64-1) && (index <= 8+64-1) ) ||
   2173                           ( index == 10+64-1 ) || ( index == 11+64-1 ) ||
   2174                           ( (index >= 14+64-1) && (index <= 16+64-1) ) ||
   2175                           ( (index >= 18+64-1) && (index <= 20+64-1) ) ||
   2176                           ( (index >= 22+64-1) && (index <= 24+64-1) ) ||
   2177                           ( (index >= 26+64-1) && (index <= 28+64-1) ) ||
   2178                           ( (index >= 30+64-1) && (index <= 32+64-1) ) ||
   2179                           ( (index >= 34+64-1) && (index <= 36+64-1) ) ||
   2180                           ( (index >= 38+64-1) && (index <= 40+64-1) ) ||
   2181                           ( (index >= 42+64-1) && (index <= 44+64-1) ) ||
   2182                           ( (index >= 46+64-1) && (index <= 48+64-1) ) ||
   2183                           ( index == 50+64-1 )   ||
   2184                           ( index == 54+64-1 )   ||
   2185                           ( index == 58+64-1 )   ||
   2186                           ( index == 62+64-1 ) );
   2187         // This only caches it for later
   2188         is31fl3733_set_led_control_register( index, enabled, enabled, enabled );
   2189     }
   2190     is31fl3733_set_led_control_register( 48+64-1, 0, 0, 1 ); //Enable LB48 blue enable for indicators
   2191     // This actually updates the LED drivers
   2192     is31fl3733_update_led_control_registers( 0 );
   2193     is31fl3733_update_led_control_registers( 1 );
   2194 #elif defined(RGB_BACKLIGHT_NEBULA68)
   2195     is31fl3733_init( 0 );
   2196     is31fl3733_init( 1 );
   2197 
   2198     for ( int index = 0; index < IS31FL3733_LED_COUNT; index++ )
   2199     {
   2200         bool enabled = !( ( index == 61-1 )   || //LA61
   2201                           ( index > 5+64-1 ) ); //LB6-LB64
   2202         // This only caches it for later
   2203         is31fl3733_set_led_control_register( index, enabled, enabled, enabled );
   2204     }
   2205     // This actually updates the LED drivers
   2206     is31fl3733_update_led_control_registers( 0 );
   2207     is31fl3733_update_led_control_registers( 1 );
   2208 #elif defined(RGB_BACKLIGHT_PORTICO75)
   2209     is31fl3741_init( 0 );
   2210 	bool enabled = true;
   2211     for ( int index = 0; index < IS31FL3741_LED_COUNT; index++ )
   2212     {
   2213         is31fl3741_set_led_control_register( index, enabled, enabled, enabled );
   2214     }
   2215     // This actually updates the LED drivers
   2216     is31fl3741_update_led_control_registers( 0 );
   2217 #elif defined(RGB_BACKLIGHT_KW_MEGA)
   2218     is31fl3733_init( 0 );
   2219     is31fl3733_init( 1 );
   2220 
   2221     for ( int index = 0; index < IS31FL3733_LED_COUNT; index++ )
   2222     {
   2223         bool enabled = !( ( index == 61-1 )   || //LA61
   2224                           ( index > 6+64-1 ) ); //LB7-LB64
   2225         // This only caches it for later
   2226         is31fl3733_set_led_control_register( index, enabled, enabled, enabled );
   2227     }
   2228     // This actually updates the LED drivers
   2229     is31fl3733_update_led_control_registers( 0 );
   2230     is31fl3733_update_led_control_registers( 1 );
   2231 #else
   2232 #if defined(RGB_BACKLIGHT_DAWN60)
   2233     ws2812_init();
   2234 #endif
   2235     // Init the #1 driver
   2236     is31fl3731_init( 0 );
   2237     // Init the #2 driver (if used)
   2238 #if !defined(RGB_BACKLIGHT_NEBULA12) && !defined(RGB_BACKLIGHT_M10_C)
   2239     is31fl3731_init( 1 );
   2240 #endif
   2241     // Init the #3 driver (if used)
   2242 #if defined(RGB_BACKLIGHT_U80_A)
   2243     is31fl3731_init( 2 );
   2244 #endif
   2245 
   2246     // Experimental feature, not in configuration yet
   2247 #if defined(RGB_BACKLIGHT_ZEAL60)
   2248     bool disable_spacebar_stab_leds = false;
   2249 #endif
   2250 
   2251     for ( int index = 0; index < BACKLIGHT_LED_COUNT; index++ )
   2252     {
   2253         // OR the possible "disabled" cases together, then NOT the result to get the enabled state
   2254         // LC6 LD13 not present on Zeal65
   2255 #if defined(RGB_BACKLIGHT_ZEAL65)
   2256         bool enabled = !( ( index == 18+5 && !g_config.use_split_backspace ) || // LB5
   2257                           ( index == 36+6 ) || // LC6
   2258                           ( index == 54+13 ) ); // LD13
   2259 #elif defined(RGB_BACKLIGHT_KOYU)
   2260         bool enabled = !( ( index == 36+15 ) || // LC15
   2261                           ( index == 54+13 ) || // LD13
   2262                           ( index == 54+17 ) ); // LD17
   2263 #elif defined(RGB_BACKLIGHT_M65_B) || defined(RGB_BACKLIGHT_M65_BX)
   2264         bool enabled = !(
   2265         // LB6 not present on M65-B
   2266 #if defined(RGB_BACKLIGHT_M65_B)
   2267                           ( index == 18+6 ) || // LB6
   2268 #endif
   2269         // LC15 LD13 not present on M65-B, M65-BX
   2270                           ( index == 36+15 ) || // LC15
   2271                           ( index == 54+13 ) ); // LD13
   2272 #elif defined(RGB_BACKLIGHT_M60_A)
   2273         bool enabled = !(
   2274         // LB6 LB7 LB8 LB15 LB16 LB17 not present on M60-A
   2275                           ( index == 18+6 ) || // LB6
   2276                           ( index == 18+7 ) || // LB7
   2277                           ( index == 18+8 ) || // LB8
   2278                           ( index == 18+15 ) || // LB15
   2279                           ( index == 18+16 ) || // LB16
   2280                           ( index == 18+17 ) || // LB17
   2281         // HHKB blockers (LC17, LD17) and ISO extra keys (LC15,LD13) not present on M60-A
   2282                           ( index == 36+17 ) || // LC17
   2283                           ( index == 54+17 ) || // LD17
   2284                           ( index == 36+15 ) || // LC15
   2285                           ( index == 54+13 ) ); // LD13
   2286 #elif defined(RGB_BACKLIGHT_WT60_B) || defined(RGB_BACKLIGHT_WT60_BX) || defined(RGB_BACKLIGHT_WT60_C)
   2287         bool enabled = !(
   2288         // LB6 not present on WT60-B
   2289 #if defined(RGB_BACKLIGHT_WT60_B)
   2290                           ( index == 18+6 ) || // LB6
   2291 #endif
   2292         // LB7 LB8 LB15 LB16 LB17 LC15 LD13 not present on WT60-B, WT60-BX, WT60-C
   2293                           ( index == 18+7 ) || // LB7
   2294                           ( index == 18+8 ) || // LB8
   2295                           ( index == 18+15 ) || // LB15
   2296                           ( index == 18+16 ) || // LB16
   2297                           ( index == 18+17 ) || // LB17
   2298                           ( index == 36+15 ) || // LC15
   2299                           ( index == 54+13 ) ); // LD13
   2300 #elif defined(RGB_BACKLIGHT_ZEAL60)
   2301         // LB6 LB7 LB8 LB15 LB16 LB17 not present on Zeal60
   2302         bool enabled = !( ( index == 18+5 && !g_config.use_split_backspace ) || // LB5
   2303                           ( index == 36+15 && !g_config.use_split_left_shift ) || // LC15
   2304                           ( index == 54+8 && !g_config.use_split_right_shift ) || // LD8
   2305                           ( index == 54+13 && g_config.use_7u_spacebar ) || // LD13
   2306                           ( index == 36+17 && g_config.disable_hhkb_blocker_leds ) || // LC17
   2307                           ( index == 54+17 && g_config.disable_hhkb_blocker_leds ) ||  // LD17
   2308                           ( index == 18+6 ) || // LB6
   2309                           ( index == 18+7 ) || // LB7
   2310                           ( index == 18+8 ) || // LB8
   2311                           ( index == 18+15 ) || // LB15
   2312                           ( index == 18+16 ) || // LB16
   2313                           ( index == 18+17 ) || // LB17
   2314                           ( index == 36+6 && disable_spacebar_stab_leds ) ||  // LC6
   2315                           ( index == 54+13 && disable_spacebar_stab_leds ) ||  // LD13
   2316                           ( index == 54+14 && disable_spacebar_stab_leds && g_config.use_7u_spacebar ) ); // LD14
   2317 #elif defined(RGB_BACKLIGHT_U80_A)
   2318 // LB5, LB6, LB7, LB8, LB15, LB16, LB17, LC15, LD8, LD13, LE0-LE8, LF13
   2319         bool enabled = !(
   2320                           ( index == 18+5 ) || // LB5
   2321                           ( index == 18+6 ) || // LB6
   2322                           ( index == 18+7 ) || // LB7
   2323                           ( index == 18+8 ) || // LB8
   2324                           ( index == 18+15 ) || // LB15
   2325                           ( index == 18+16 ) || // LB16
   2326                           ( index == 18+16 ) || // LB17
   2327                           ( index == 36+15 ) || // LC15
   2328                           ( index == 54+8 ) || // LD8
   2329                           ( index == 54+13 ) ||  // LD13
   2330                           ( index >= 72+0 && index <= 72+8 ) ||  // LE0-LE8
   2331                           ( index == 90+13 ) ); // LF13
   2332 #elif defined(RGB_BACKLIGHT_DAWN60)
   2333         bool enabled = !( ( index == 15+7 && !g_config.use_split_backspace ) || //other backspace
   2334                           ( index == 47+13 && g_config.use_7u_spacebar ) ||     //LD13
   2335                           ( index == 47+15 && g_config.use_7u_spacebar ) );       //LD15
   2336 #elif defined(RGB_BACKLIGHT_NEBULA12)
   2337         bool enabled = !( ( index >= 9-1 && index <= 12-1 ) ); // A9-A12
   2338 #elif defined(RGB_BACKLIGHT_M50_A)
   2339         bool enabled = !(
   2340         // LA0, LA7, LA8, LA17
   2341                           ( index == 0+0 ) ||
   2342                           ( index == 0+7 ) ||
   2343                           ( index == 0+8 ) ||
   2344                           ( index == 0+17 ) ||
   2345 
   2346         // LB0, LB7, LB8, LB15, LB16, LB17,
   2347                           ( index == 18+0 ) ||
   2348                           ( index == 18+7 ) ||
   2349                           ( index == 18+8 ) ||
   2350                           ( index == 18+15 ) ||
   2351                           ( index == 18+16 ) ||
   2352                           ( index == 18+17 ) ||
   2353         // LC0, LC8, LC16, LC17
   2354                           ( index == 36+0 ) ||
   2355                           ( index == 36+8 ) ||
   2356                           ( index == 36+16 ) ||
   2357                           ( index == 36+17 ) ||
   2358         // LD0, LD7, LD8, LD9, LD15, LD16, LD17
   2359                           ( index == 54+0 ) ||
   2360                           ( index == 54+7 ) ||
   2361                           ( index == 54+8 ) ||
   2362                           ( index == 54+9 ) ||
   2363                           ( index == 54+15 ) ||
   2364                           ( index == 54+16 ) ||
   2365                           ( index == 54+17 ) );
   2366 #elif defined(RGB_BACKLIGHT_M10_C)
   2367         bool enabled = true;
   2368 #elif defined(RGB_BACKLIGHT_PORTICO)
   2369         bool enabled = true;
   2370 #endif
   2371         // This only caches it for later
   2372         is31fl3731_set_led_control_register( index, enabled, enabled, enabled );
   2373     }
   2374     // This actually updates the LED drivers
   2375     // TODO: refactor this to use DRIVER_COUNT
   2376     is31fl3731_update_led_control_registers(  0 );
   2377 #if !defined(RGB_BACKLIGHT_NEBULA12) && !defined(RGB_BACKLIGHT_M10_C)
   2378     is31fl3731_update_led_control_registers( 1 );
   2379 #endif
   2380 #if defined(RGB_BACKLIGHT_U80_A)
   2381     is31fl3731_update_led_control_registers( 2 );
   2382 #endif
   2383 #endif
   2384 
   2385     // TODO: put the 1 second startup delay here?
   2386 
   2387     // clear the key hits
   2388     for ( int led=0; led<BACKLIGHT_LED_COUNT; led++ )
   2389     {
   2390         g_key_hit[led] = 255;
   2391     }
   2392 }
   2393 
   2394 bool process_record_backlight(uint16_t keycode, keyrecord_t *record)
   2395 {
   2396     // Record keypresses for backlight effects
   2397     if ( record->event.pressed )
   2398     {
   2399         backlight_set_key_hit( record->event.key.row, record->event.key.col );
   2400     }
   2401 
   2402     switch(keycode)
   2403     {
   2404         case BR_INC:
   2405             if (record->event.pressed)
   2406             {
   2407                 backlight_brightness_increase();
   2408             }
   2409             return false;
   2410             break;
   2411         case BR_DEC:
   2412             if (record->event.pressed)
   2413             {
   2414                 backlight_brightness_decrease();
   2415             }
   2416             return false;
   2417             break;
   2418         case EF_INC:
   2419             if (record->event.pressed)
   2420             {
   2421                 backlight_effect_increase();
   2422             }
   2423             return false;
   2424             break;
   2425         case EF_DEC:
   2426             if (record->event.pressed)
   2427             {
   2428                 backlight_effect_decrease();
   2429             }
   2430             return false;
   2431             break;
   2432         case ES_INC:
   2433             if (record->event.pressed)
   2434             {
   2435                 backlight_effect_speed_increase();
   2436             }
   2437             return false;
   2438             break;
   2439         case ES_DEC:
   2440             if (record->event.pressed)
   2441             {
   2442                 backlight_effect_speed_decrease();
   2443             }
   2444             return false;
   2445             break;
   2446         case H1_INC:
   2447             if (record->event.pressed)
   2448             {
   2449                 backlight_color_1_hue_increase();
   2450             }
   2451             return false;
   2452             break;
   2453         case H1_DEC:
   2454             if (record->event.pressed)
   2455             {
   2456                 backlight_color_1_hue_decrease();
   2457             }
   2458             return false;
   2459             break;
   2460         case S1_INC:
   2461             if (record->event.pressed)
   2462             {
   2463                 backlight_color_1_sat_increase();
   2464             }
   2465             return false;
   2466             break;
   2467         case S1_DEC:
   2468             if (record->event.pressed)
   2469             {
   2470                 backlight_color_1_sat_decrease();
   2471                 break;
   2472             }
   2473             return false;
   2474             break;
   2475         case H2_INC:
   2476             if (record->event.pressed)
   2477             {
   2478                 backlight_color_2_hue_increase();
   2479             }
   2480             return false;
   2481             break;
   2482         case H2_DEC:
   2483             if (record->event.pressed)
   2484             {
   2485                 backlight_color_2_hue_decrease();
   2486             }
   2487             return false;
   2488             break;
   2489         case S2_INC:
   2490             if (record->event.pressed)
   2491             {
   2492                 backlight_color_2_sat_increase();
   2493             }
   2494             return false;
   2495             break;
   2496         case S2_DEC:
   2497             if (record->event.pressed)
   2498             {
   2499                 backlight_color_2_sat_decrease();
   2500                 break;
   2501             }
   2502             return false;
   2503             break;
   2504     }
   2505 
   2506     return true;
   2507 }
   2508 
   2509 // Deals with the messy details of incrementing an integer
   2510 uint8_t increment( uint8_t value, uint8_t step, uint8_t min, uint8_t max )
   2511 {
   2512     int16_t new_value = value;
   2513     new_value += step;
   2514     return MIN( MAX( new_value, min ), max );
   2515 }
   2516 
   2517 uint8_t decrement( uint8_t value, uint8_t step, uint8_t min, uint8_t max )
   2518 {
   2519     int16_t new_value = value;
   2520     new_value -= step;
   2521     return MIN( MAX( new_value, min ), max );
   2522 }
   2523 
   2524 void backlight_effect_increase(void)
   2525 {
   2526     g_config.effect = increment( g_config.effect, 1, 0, BACKLIGHT_EFFECT_MAX );
   2527     backlight_config_save();
   2528 }
   2529 
   2530 void backlight_effect_decrease(void)
   2531 {
   2532     g_config.effect = decrement( g_config.effect, 1, 0, BACKLIGHT_EFFECT_MAX );
   2533     backlight_config_save();
   2534 }
   2535 
   2536 void backlight_effect_speed_increase(void)
   2537 {
   2538     g_config.effect_speed = increment( g_config.effect_speed, 1, 0, 3 );
   2539     backlight_config_save();
   2540 }
   2541 
   2542 void backlight_effect_speed_decrease(void)
   2543 {
   2544     g_config.effect_speed = decrement( g_config.effect_speed, 1, 0, 3 );
   2545     backlight_config_save();
   2546 }
   2547 
   2548 void backlight_brightness_increase(void)
   2549 {
   2550     g_config.brightness = increment( g_config.brightness, 8, 0, 255 );
   2551     backlight_config_save();
   2552 }
   2553 
   2554 void backlight_brightness_decrease(void)
   2555 {
   2556     g_config.brightness = decrement( g_config.brightness, 8, 0, 255 );
   2557     backlight_config_save();
   2558 }
   2559 
   2560 void backlight_color_1_hue_increase(void)
   2561 {
   2562     g_config.color_1.h = increment( g_config.color_1.h, 8, 0, 255 );
   2563     backlight_config_save();
   2564 }
   2565 
   2566 void backlight_color_1_hue_decrease(void)
   2567 {
   2568     g_config.color_1.h = decrement( g_config.color_1.h, 8, 0, 255 );
   2569     backlight_config_save();
   2570 }
   2571 
   2572 void backlight_color_1_sat_increase(void)
   2573 {
   2574     g_config.color_1.s = increment( g_config.color_1.s, 8, 0, 255 );
   2575     backlight_config_save();
   2576 }
   2577 
   2578 void backlight_color_1_sat_decrease(void)
   2579 {
   2580     g_config.color_1.s = decrement( g_config.color_1.s, 8, 0, 255 );
   2581     backlight_config_save();
   2582 }
   2583 
   2584 void backlight_color_2_hue_increase(void)
   2585 {
   2586     g_config.color_2.h = increment( g_config.color_2.h, 8, 0, 255 );
   2587     backlight_config_save();
   2588 }
   2589 
   2590 void backlight_color_2_hue_decrease(void)
   2591 {
   2592     g_config.color_2.h = decrement( g_config.color_2.h, 8, 0, 255 );
   2593     backlight_config_save();
   2594 }
   2595 
   2596 void backlight_color_2_sat_increase(void)
   2597 {
   2598     g_config.color_2.s = increment( g_config.color_2.s, 8, 0, 255 );
   2599     backlight_config_save();
   2600 }
   2601 
   2602 void backlight_color_2_sat_decrease(void)
   2603 {
   2604     g_config.color_2.s = decrement( g_config.color_2.s, 8, 0, 255 );
   2605     backlight_config_save();
   2606 }
   2607 
   2608 #if defined(RGB_DEBUGGING_ONLY)
   2609 void backlight_test_led( uint8_t index, bool red, bool green, bool blue )
   2610 {
   2611     for ( int i=0; i<BACKLIGHT_LED_COUNT; i++ )
   2612     {
   2613         if ( i == index )
   2614         {
   2615             is31fl3731_set_led_control_register( i, red, green, blue );
   2616         }
   2617         else
   2618         {
   2619             is31fl3731_set_led_control_register( i, false, false, false );
   2620         }
   2621     }
   2622 }
   2623 
   2624 void backlight_debug_led( bool state )
   2625 {
   2626     if (state)
   2627     {
   2628         gpio_set_pin_output(E6);
   2629         gpio_write_pin_high(E6);
   2630     }
   2631     else
   2632     {
   2633         gpio_set_pin_input(E6);
   2634     }
   2635 }
   2636 #endif // defined(RGB_DEBUGGING_ONLY)
   2637 
   2638 void backlight_device_indication(uint8_t value)
   2639 {
   2640     static uint8_t current_effect = 0;
   2641     static uint8_t alternate_effect = 0;
   2642     if ( value == 0 ) {
   2643         current_effect = g_config.effect;
   2644         alternate_effect = g_config.effect > 0 ? 0 : 1;
   2645     }
   2646     g_config.effect = value % 2 == 0 ? alternate_effect : current_effect;
   2647 }