rgb_backlight.c 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596
  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. #if RGB_BACKLIGHT_ENABLED
  17. #if defined (RGB_BACKLIGHT_ZEAL60) || defined (RGB_BACKLIGHT_ZEAL65) || defined (RGB_BACKLIGHT_M60_A) || defined(RGB_BACKLIGHT_M6_B)
  18. #else
  19. #error None of the following was defined: RGB_BACKLIGHT_ZEAL60, RGB_BACKLIGHT_ZEAL65, RGB_BACKLIGHT_M60_A, RGB_BACKLIGHT_M6_B
  20. #endif
  21. #include "quantum.h"
  22. #include "rgb_backlight.h"
  23. #include "rgb_backlight_api.h"
  24. #include "rgb_backlight_keycodes.h"
  25. #include <avr/io.h>
  26. #include <util/delay.h>
  27. #include <avr/interrupt.h>
  28. #include "progmem.h"
  29. #include "quantum/color.h"
  30. #include "drivers/avr/i2c_master.h"
  31. #if defined (RGB_BACKLIGHT_M6_B)
  32. #include "drivers/issi/is31fl3218.h"
  33. #define BACKLIGHT_LED_COUNT 6
  34. #else
  35. #include "drivers/issi/is31fl3731.h"
  36. #define BACKLIGHT_LED_COUNT 72
  37. #endif
  38. #define BACKLIGHT_EFFECT_MAX 10
  39. backlight_config g_config = {
  40. .use_split_backspace = RGB_BACKLIGHT_USE_SPLIT_BACKSPACE,
  41. .use_split_left_shift = RGB_BACKLIGHT_USE_SPLIT_LEFT_SHIFT,
  42. .use_split_right_shift = RGB_BACKLIGHT_USE_SPLIT_RIGHT_SHIFT,
  43. .use_7u_spacebar = RGB_BACKLIGHT_USE_7U_SPACEBAR,
  44. .use_iso_enter = RGB_BACKLIGHT_USE_ISO_ENTER,
  45. .disable_hhkb_blocker_leds = RGB_BACKLIGHT_DISABLE_HHKB_BLOCKER_LEDS,
  46. .disable_when_usb_suspended = RGB_BACKLIGHT_DISABLE_WHEN_USB_SUSPENDED,
  47. .disable_after_timeout = RGB_BACKLIGHT_DISABLE_AFTER_TIMEOUT,
  48. .brightness = 255,
  49. .effect = RGB_BACKLIGHT_EFFECT,
  50. .effect_speed = 0,
  51. .color_1 = { .h = 0, .s = 255, .v = 255 },
  52. .color_2 = { .h = 127, .s = 255, .v = 255 },
  53. .caps_lock_indicator = { .color = { .h = 0, .s = 0, .v = 255 }, .index = 255 },
  54. .layer_1_indicator = { .color = { .h = 0, .s = 0, .v = 255 }, .index = 255 },
  55. .layer_2_indicator = { .color = { .h = 0, .s = 0, .v = 255 }, .index = 255 },
  56. .layer_3_indicator = { .color = { .h = 0, .s = 0, .v = 255 }, .index = 255 },
  57. .alphas_mods = {
  58. RGB_BACKLIGHT_ALPHAS_MODS_ROW_0,
  59. RGB_BACKLIGHT_ALPHAS_MODS_ROW_1,
  60. RGB_BACKLIGHT_ALPHAS_MODS_ROW_2,
  61. RGB_BACKLIGHT_ALPHAS_MODS_ROW_3,
  62. RGB_BACKLIGHT_ALPHAS_MODS_ROW_4 }
  63. };
  64. bool g_suspend_state = false;
  65. uint8_t g_indicator_state = 0;
  66. // Global tick at 20 Hz
  67. uint32_t g_tick = 0;
  68. // Ticks since this key was last hit.
  69. uint8_t g_key_hit[BACKLIGHT_LED_COUNT];
  70. // Ticks since any key was last hit.
  71. uint32_t g_any_key_hit = 0;
  72. #if !defined(RGB_BACKLIGHT_M6_B)
  73. // This is a 7-bit address, that gets left-shifted and bit 0
  74. // set to 0 for write, 1 for read (as per I2C protocol)
  75. #define ISSI_ADDR_1 0x74
  76. #define ISSI_ADDR_2 0x76
  77. const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
  78. /* Refer to IS31 manual for these locations
  79. * driver
  80. * | R location
  81. * | | G location
  82. * | | | B location
  83. * | | | | */
  84. {0, C2_1, C3_1, C4_1}, // LA0
  85. {0, C1_1, C3_2, C4_2}, // LA1
  86. {0, C1_2, C2_2, C4_3}, // LA2
  87. {0, C1_3, C2_3, C3_3}, // LA3
  88. {0, C1_4, C2_4, C3_4}, // LA4
  89. {0, C1_5, C2_5, C3_5}, // LA5
  90. {0, C1_6, C2_6, C3_6}, // LA6
  91. {0, C1_7, C2_7, C3_7}, // LA7
  92. {0, C1_8, C2_8, C3_8}, // LA8
  93. {0, C9_1, C8_1, C7_1}, // LA9
  94. {0, C9_2, C8_2, C7_2}, // LA10
  95. {0, C9_3, C8_3, C7_3}, // LA11
  96. {0, C9_4, C8_4, C7_4}, // LA12
  97. {0, C9_5, C8_5, C7_5}, // LA13
  98. {0, C9_6, C8_6, C7_6}, // LA14
  99. {0, C9_7, C8_7, C6_6}, // LA15
  100. {0, C9_8, C7_7, C6_7}, // LA16
  101. {0, C8_8, C7_8, C6_8}, // LA17
  102. {0, C2_9, C3_9, C4_9}, // LB0
  103. {0, C1_9, C3_10, C4_10}, // LB1
  104. {0, C1_10, C2_10, C4_11}, // LB2
  105. {0, C1_11, C2_11, C3_11}, // LB3
  106. {0, C1_12, C2_12, C3_12}, // LB4
  107. {0, C1_13, C2_13, C3_13}, // LB5
  108. {0, C1_14, C2_14, C3_14}, // LB6
  109. {0, C1_15, C2_15, C3_15}, // LB7
  110. {0, C1_16, C2_16, C3_16}, // LB8
  111. {0, C9_9, C8_9, C7_9}, // LB9
  112. {0, C9_10, C8_10, C7_10}, // LB10
  113. {0, C9_11, C8_11, C7_11}, // LB11
  114. {0, C9_12, C8_12, C7_12}, // LB12
  115. {0, C9_13, C8_13, C7_13}, // LB13
  116. {0, C9_14, C8_14, C7_14}, // LB14
  117. {0, C9_15, C8_15, C6_14}, // LB15
  118. {0, C9_16, C7_15, C6_15}, // LB16
  119. {0, C8_16, C7_16, C6_16}, // LB17
  120. {1, C2_1, C3_1, C4_1}, // LC0
  121. {1, C1_1, C3_2, C4_2}, // LC1
  122. {1, C1_2, C2_2, C4_3}, // LC2
  123. {1, C1_3, C2_3, C3_3}, // LC3
  124. {1, C1_4, C2_4, C3_4}, // LC4
  125. {1, C1_5, C2_5, C3_5}, // LC5
  126. {1, C1_6, C2_6, C3_6}, // LC6
  127. {1, C1_7, C2_7, C3_7}, // LC7
  128. {1, C1_8, C2_8, C3_8}, // LC8
  129. {1, C9_1, C8_1, C7_1}, // LC9
  130. {1, C9_2, C8_2, C7_2}, // LC10
  131. {1, C9_3, C8_3, C7_3}, // LC11
  132. {1, C9_4, C8_4, C7_4}, // LC12
  133. {1, C9_5, C8_5, C7_5}, // LC13
  134. {1, C9_6, C8_6, C7_6}, // LC14
  135. {1, C9_7, C8_7, C6_6}, // LC15
  136. {1, C9_8, C7_7, C6_7}, // LC16
  137. {1, C8_8, C7_8, C6_8}, // LC17
  138. {1, C2_9, C3_9, C4_9}, // LD0
  139. {1, C1_9, C3_10, C4_10}, // LD1
  140. {1, C1_10, C2_10, C4_11}, // LD2
  141. {1, C1_11, C2_11, C3_11}, // LD3
  142. {1, C1_12, C2_12, C3_12}, // LD4
  143. {1, C1_13, C2_13, C3_13}, // LD5
  144. {1, C1_14, C2_14, C3_14}, // LD6
  145. {1, C1_15, C2_15, C3_15}, // LD7
  146. {1, C1_16, C2_16, C3_16}, // LD8
  147. {1, C9_9, C8_9, C7_9}, // LD9
  148. {1, C9_10, C8_10, C7_10}, // LD10
  149. {1, C9_11, C8_11, C7_11}, // LD11
  150. {1, C9_12, C8_12, C7_12}, // LD12
  151. {1, C9_13, C8_13, C7_13}, // LD13
  152. {1, C9_14, C8_14, C7_14}, // LD14
  153. {1, C9_15, C8_15, C6_14}, // LD15
  154. {1, C9_16, C7_15, C6_15}, // LD16
  155. {1, C8_16, C7_16, C6_16}, // LD17
  156. };
  157. #endif // !defined(RGB_BACKLIGHT_M6_B)
  158. typedef struct Point {
  159. uint8_t x;
  160. uint8_t y;
  161. } Point;
  162. // index in range 0..71 (LA0..LA17, LB0..LB17, LC0..LC17, LD0..LD17)
  163. // point values in range x=0..224 y=0..64
  164. // origin is center of top-left key (i.e Esc)
  165. #if defined (RGB_BACKLIGHT_ZEAL65)
  166. const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
  167. // LA0..LA17
  168. {120,16}, {104,16}, {88,16}, {72,16}, {56,16}, {40,16}, {24,16}, {4,16}, {4,32},
  169. {128,0}, {112,0}, {96,0}, {80,0}, {64,0}, {48,0}, {32,0}, {16,0}, {0,0},
  170. // LB0..LB17
  171. {144,0}, {160,0}, {176,0}, {192,0}, {216,0}, {224,0}, {240,0}, {240,16}, {240,32},
  172. {136,16}, {152,16}, {168,16}, {184,16}, {200,16}, {220,16}, {240,48}, {240,64}, {224,64},
  173. // LC0..LC17
  174. {96,64}, {100,48}, {84,48}, {68,48}, {52,48}, {36,48}, {255,255}, {48,60}, {28,64},
  175. {108,32}, {92,32}, {76,32}, {60,32}, {44,32}, {28,32}, {20,44}, {10,48}, {4,64},
  176. // LD0..LD17
  177. {124,32}, {140,32}, {156,32}, {172,32}, {188,32}, {214,32}, {180,48}, {202,48}, {224,48},
  178. {116,48}, {132,48}, {148,48}, {164,48}, {255,255}, {144,60}, {164,64}, {188,64}, {208,64}
  179. };
  180. const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
  181. // LA0..LA17
  182. {64,128}, {75,132}, {84,145}, {91,164}, {97,187}, {102,213}, {105,242}, {109,255}, {128,247},
  183. {61,255}, {67,255}, {72,255}, {77,255}, {82,255}, {86,255}, {90,255}, {93,255}, {96,255},
  184. // LB0..LB17
  185. {56,255}, {51,255}, {46,255}, {42,255}, {37,255}, {35,255}, {32,255}, {19,255}, {0,255},
  186. {53,132}, {44,145}, {37,164}, {31,187}, {26,213}, {22,249}, {237,255}, {224,255}, {221,255},
  187. // LC0..LC17
  188. {184,255}, {179,135}, {170,149}, {163,169}, {157,193}, {153,220}, {255,255}, {167,255}, {165,255},
  189. {128,26}, {128,60}, {128,94}, {128,128}, {128,162}, {128,196}, {145,233}, {148,255}, {161,255},
  190. // LD0..LD17
  191. {0,9}, {0,43}, {0,77}, {0,111}, {0,145}, {255,201}, {224,181}, {230,217}, {235,255},
  192. {189,128}, {200,131}, {210,141}, {218,159}, {201,228}, {201,228}, {206,255}, {213,255}, {218,255}
  193. };
  194. #elif defined (RGB_BACKLIGHT_ZEAL60) || defined (RGB_BACKLIGHT_M60_A)
  195. const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
  196. // LA0..LA17
  197. {120,16}, {104,16}, {88,16}, {72,16}, {56,16}, {40,16}, {24,16}, {4,16}, {4,32},
  198. {128,0}, {112,0}, {96,0}, {80,0}, {64,0}, {48,0}, {32,0}, {16,0}, {0,0},
  199. // LB0..LB17
  200. {144,0}, {160,0}, {176,0}, {192,0}, {216,0}, {224,0}, {255,255}, {255,255}, {255,255},
  201. {136,16}, {152,16}, {168,16}, {184,16}, {200,16}, {220,16}, {255,255}, {255,255}, {255,255},
  202. // LC0..LC17
  203. {102,64}, {100,48}, {84,48}, {68,48}, {52,48}, {36,48}, {60,64}, {43,64}, {23,64},
  204. {108,32}, {92,32}, {76,32}, {60,32}, {44,32}, {28,32}, {20,48}, {2,48}, {3,64},
  205. // LD0..LD17
  206. {124,32}, {140,32}, {156,32}, {172,32}, {188,32}, {214,32}, {180,48}, {210,48}, {224,48},
  207. {116,48}, {132,48}, {148,48}, {164,48}, {144,64}, {161,64}, {181,64}, {201,64}, {221,64}
  208. };
  209. const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
  210. // LA0..LA17
  211. {58,129}, {70,129}, {80,139}, {89,157}, {96,181}, {101,208}, {105,238}, {109,255}, {128,247}, {58,255},
  212. {64,255}, {70,255}, {75,255}, {80,255}, {85,255}, {89,255}, {93,255}, {96,255},
  213. // LB0..LB17
  214. {53,255}, {48,255}, {43,255}, {39,255}, {34,255}, {32,255}, {255,255}, {255,255}, {255,255},
  215. {48,139}, {39,157}, {32,181}, {27,208}, {23,238}, {19,255}, {255,255}, {255,255}, {255,255},
  216. // LC0..LC17
  217. {188,255}, {183,131}, {173,143}, {165,163}, {159,188}, {154,216}, {172,252}, {170,255}, {165,255},
  218. {128,9}, {128,46}, {128,82}, {128,119}, {128,155}, {128,192}, {150,244}, {147,255}, {161,255},
  219. // LD0..LD17
  220. {0,27}, {0,64}, {0,101}, {0,137}, {0,174}, {255,233}, {228,201}, {235,255}, {237,255},
  221. {195,128}, {206,136}, {215,152}, {222,175}, {205,234}, {209,255}, {214,255}, {219,255}, {223,255}
  222. };
  223. #elif defined (RGB_BACKLIGHT_M6_B)
  224. // M6-B is really simple:
  225. // 0 3 5
  226. // 1 2 4
  227. const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
  228. {0,0}, {0,16}, {16,16}, {16,0}, {32,16}, {32,0}
  229. };
  230. const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
  231. {0,0}, {0,16}, {16,16}, {16,0}, {32,16}, {32,0}
  232. };
  233. #endif
  234. // This may seem counter-intuitive, but it's quite flexible.
  235. // For each LED, get it's position to decide what color to make it.
  236. // This solves the issue of LEDs (and switches) not aligning to a grid,
  237. // or having a large "bitmap" and sampling them.
  238. void map_led_to_point( uint8_t index, Point *point )
  239. {
  240. // Slightly messy way to get Point structs out of progmem.
  241. uint8_t *addr = (uint8_t*)&g_map_led_to_point[index];
  242. point->x = pgm_read_byte(addr);
  243. point->y = pgm_read_byte(addr+1);
  244. #if defined (RGB_BACKLIGHT_M6_B)
  245. return;
  246. #endif
  247. switch (index)
  248. {
  249. case 18+4: // LB4A
  250. if ( g_config.use_split_backspace )
  251. point->x -= 8;
  252. break;
  253. #if defined (RGB_BACKLIGHT_ZEAL60)
  254. case 18+14: // LB14A
  255. if ( g_config.use_iso_enter )
  256. point->y += 8; // extremely pedantic
  257. break;
  258. case 54+5: // LD5A
  259. if ( !g_config.use_iso_enter )
  260. point->x -= 10;
  261. break;
  262. case 36+16: // LC16A
  263. if ( !g_config.use_split_left_shift )
  264. point->x += 8;
  265. break;
  266. #endif
  267. #if defined (RGB_BACKLIGHT_ZEAL60) || defined (RGB_BACKLIGHT_M60_A)
  268. case 36+0: // LC0A
  269. if ( g_config.use_7u_spacebar )
  270. point->x += 10;
  271. break;
  272. case 36+6: // LC6A
  273. if ( g_config.use_7u_spacebar )
  274. point->x += 4;
  275. break;
  276. case 54+7: // LD7A
  277. if ( !g_config.use_split_right_shift )
  278. point->x -= 8;
  279. break;
  280. #endif
  281. }
  282. }
  283. void map_led_to_point_polar( uint8_t index, Point *point )
  284. {
  285. // Slightly messy way to get Point structs out of progmem.
  286. uint8_t *addr = (uint8_t*)&g_map_led_to_point_polar[index];
  287. point->x = pgm_read_byte(addr);
  288. point->y = pgm_read_byte(addr+1);
  289. }
  290. //
  291. // Maps switch matrix coordinate (row,col) to LED index
  292. //
  293. #if defined (RGB_BACKLIGHT_ZEAL65)
  294. // Note: Left spacebar stab is at 4,3 (LC7)
  295. // Right spacebar stab is at 4,9 (D14)
  296. //
  297. // A17, A16, A15, A14, A13, A12, A11, A10, A9, B0, B1, B2, B3, B4, B6
  298. // A7, A6, A5, A4, A3, A2, A1, A0, B9, B10, B11, B12, B13, B14, B7
  299. // A8, C14, C13, C12, C11, C10, C9, D0, D1, D2, D3, D4, D5, B5, B8
  300. // C16, C15, C5, C4, C3, C2, C1, D9, D10, D11, D12, D6, D7, D8, B15
  301. // C17, C8, C7, ---, ---, ---, ---, C0, ---, D14, D15, D16, D17, B17, B16
  302. const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
  303. { 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 },
  304. { 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 },
  305. { 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 },
  306. { 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 },
  307. { 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 }
  308. };
  309. #elif defined (RGB_BACKLIGHT_ZEAL60) || defined (RGB_BACKLIGHT_M60_A)
  310. // Note: Left spacebar stab is at 4,3 (LC6)
  311. // Right spacebar stab is at 4,9 (LD13) or 4,10 (LD14)
  312. //
  313. // A17, A16, A15, A14, A13, A12, A11, A10, A9, B0, B1, B2, B3, B4,
  314. // A7, A6, A5, A4, A3, A2, A1, A0, B9, B10, B11, B12, B13, B14,
  315. // A8, C14, C13, C12, C11, C10, C9, D0, D1, D2, D3, D4, D5, B5,
  316. // C16, C15, C5, C4, C3, C2, C1, D9, D10, D11, D12, D6, D7, D8,
  317. // C17, C8, C7, C6, ---, ---, ---, C0, ---, D13, D14, D15, D16, D17,
  318. const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
  319. { 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 },
  320. { 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 },
  321. { 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 },
  322. { 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 },
  323. { 36+17, 36+8, 36+7, 36+6, 255, 255, 255, 36+0, 255, 54+13, 54+14, 54+15, 54+16, 54+17 }
  324. };
  325. #elif defined (RGB_BACKLIGHT_M6_B)
  326. // M6-B is really simple:
  327. // 0 3 5
  328. // 1 2 4
  329. const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
  330. { 0, 3, 5, 1, 2, 4 }
  331. };
  332. #endif
  333. void map_row_column_to_led( uint8_t row, uint8_t column, uint8_t *led )
  334. {
  335. *led = 255;
  336. if ( row < MATRIX_ROWS && column < MATRIX_COLS )
  337. {
  338. *led = pgm_read_byte(&g_map_row_column_to_led[row][column]);
  339. }
  340. }
  341. void backlight_update_pwm_buffers(void)
  342. {
  343. #if defined (RGB_BACKLIGHT_M6_B)
  344. IS31FL3218_update_pwm_buffers();
  345. #else
  346. IS31FL3731_update_pwm_buffers( ISSI_ADDR_1, ISSI_ADDR_2 );
  347. IS31FL3731_update_led_control_registers( ISSI_ADDR_1, ISSI_ADDR_2 );
  348. #endif
  349. }
  350. void backlight_set_color( int index, uint8_t red, uint8_t green, uint8_t blue )
  351. {
  352. #if defined (RGB_BACKLIGHT_M6_B)
  353. IS31FL3218_set_color( index, red, green, blue );
  354. #else
  355. IS31FL3731_set_color( index, red, green, blue );
  356. #endif
  357. }
  358. void backlight_set_color_all( uint8_t red, uint8_t green, uint8_t blue )
  359. {
  360. #if defined (RGB_BACKLIGHT_M6_B)
  361. IS31FL3218_set_color_all( red, green, blue );
  362. #else
  363. IS31FL3731_set_color_all( red, green, blue );
  364. #endif
  365. }
  366. void backlight_set_key_hit(uint8_t row, uint8_t column)
  367. {
  368. uint8_t led;
  369. map_row_column_to_led(row,column,&led);
  370. g_key_hit[led] = 0;
  371. g_any_key_hit = 0;
  372. }
  373. // This is (F_CPU/1024) / 20 Hz
  374. // = 15625 Hz / 20 Hz
  375. // = 781
  376. #define TIMER3_TOP 781
  377. void backlight_timer_init(void)
  378. {
  379. static uint8_t backlight_timer_is_init = 0;
  380. if ( backlight_timer_is_init )
  381. {
  382. return;
  383. }
  384. backlight_timer_is_init = 1;
  385. // Timer 3 setup
  386. TCCR3B = _BV(WGM32) | // CTC mode OCR3A as TOP
  387. _BV(CS32) | _BV(CS30); // prescale by /1024
  388. // Set TOP value
  389. uint8_t sreg = SREG;
  390. cli();
  391. OCR3AH = (TIMER3_TOP >> 8) & 0xff;
  392. OCR3AL = TIMER3_TOP & 0xff;
  393. SREG = sreg;
  394. }
  395. void backlight_timer_enable(void)
  396. {
  397. TIMSK3 |= _BV(OCIE3A);
  398. }
  399. void backlight_timer_disable(void)
  400. {
  401. TIMSK3 &= ~_BV(OCIE3A);
  402. }
  403. void backlight_set_suspend_state(bool state)
  404. {
  405. g_suspend_state = state;
  406. }
  407. void backlight_set_indicator_state(uint8_t state)
  408. {
  409. g_indicator_state = state;
  410. }
  411. void backlight_effect_rgb_test(void)
  412. {
  413. // Mask out bits 4 and 5
  414. // This 2-bit value will stay the same for 16 ticks.
  415. switch ( (g_tick & 0x30) >> 4 )
  416. {
  417. case 0:
  418. {
  419. backlight_set_color_all( 255, 0, 0 );
  420. break;
  421. }
  422. case 1:
  423. {
  424. backlight_set_color_all( 0, 255, 0 );
  425. break;
  426. }
  427. case 2:
  428. {
  429. backlight_set_color_all( 0, 0, 255 );
  430. break;
  431. }
  432. case 3:
  433. {
  434. backlight_set_color_all( 255, 255, 255 );
  435. break;
  436. }
  437. }
  438. }
  439. #if defined(RGB_DEBUGGING_ONLY)
  440. // This tests the LEDs
  441. // Note that it will change the LED control registers
  442. // in the LED drivers, and leave them in an invalid
  443. // state for other backlight effects.
  444. // ONLY USE THIS FOR TESTING LEDS!
  445. void backlight_effect_single_LED_test(void)
  446. {
  447. static uint8_t color = 0; // 0,1,2 for R,G,B
  448. static uint8_t row = 0;
  449. static uint8_t column = 0;
  450. static uint8_t tick = 0;
  451. tick++;
  452. if ( tick > 2 )
  453. {
  454. tick = 0;
  455. column++;
  456. }
  457. if ( column > 14 )
  458. {
  459. column = 0;
  460. row++;
  461. }
  462. if ( row > 4 )
  463. {
  464. row = 0;
  465. color++;
  466. }
  467. if ( color > 2 )
  468. {
  469. color = 0;
  470. }
  471. uint8_t led;
  472. map_row_column_to_led( row, column, &led );
  473. backlight_set_color_all( 255, 255, 255 );
  474. backlight_test_led( led, color==0, color==1, color==2 );
  475. }
  476. #endif // defined(RGB_DEBUGGING_ONLY)
  477. // All LEDs off
  478. void backlight_effect_all_off(void)
  479. {
  480. backlight_set_color_all( 0, 0, 0 );
  481. }
  482. // Solid color
  483. void backlight_effect_solid_color(void)
  484. {
  485. HSV hsv = { .h = g_config.color_1.h, .s = g_config.color_1.s, .v = g_config.brightness };
  486. RGB rgb = hsv_to_rgb( hsv );
  487. backlight_set_color_all( rgb.r, rgb.g, rgb.b );
  488. }
  489. // alphas = color1, mods = color2
  490. void backlight_effect_alphas_mods(void)
  491. {
  492. RGB rgb1 = hsv_to_rgb( (HSV){ .h = g_config.color_1.h, .s = g_config.color_1.s, .v = g_config.brightness } );
  493. RGB rgb2 = hsv_to_rgb( (HSV){ .h = g_config.color_2.h, .s = g_config.color_2.s, .v = g_config.brightness } );
  494. for ( int row = 0; row < MATRIX_ROWS; row++ )
  495. {
  496. for ( int column = 0; column < MATRIX_COLS; column++ )
  497. {
  498. uint8_t index;
  499. map_row_column_to_led( row, column, &index );
  500. if ( index < BACKLIGHT_LED_COUNT )
  501. {
  502. if ( ( g_config.alphas_mods[row] & (1<<column) ) == 0 )
  503. {
  504. backlight_set_color( index, rgb1.r, rgb1.g, rgb1.b );
  505. }
  506. else
  507. {
  508. backlight_set_color( index, rgb2.r, rgb2.g, rgb2.b );
  509. }
  510. }
  511. }
  512. }
  513. }
  514. void backlight_effect_gradient_up_down(void)
  515. {
  516. int16_t h1 = g_config.color_1.h;
  517. int16_t h2 = g_config.color_2.h;
  518. int16_t deltaH = h2 - h1;
  519. // Take the shortest path between hues
  520. if ( deltaH > 127 )
  521. {
  522. deltaH -= 256;
  523. }
  524. else if ( deltaH < -127 )
  525. {
  526. deltaH += 256;
  527. }
  528. // Divide delta by 4, this gives the delta per row
  529. deltaH /= 4;
  530. int16_t s1 = g_config.color_1.s;
  531. int16_t s2 = g_config.color_2.s;
  532. int16_t deltaS = ( s2 - s1 ) / 4;
  533. HSV hsv = { .h = 0, .s = 255, .v = g_config.brightness };
  534. RGB rgb;
  535. Point point;
  536. for ( int i=0; i<BACKLIGHT_LED_COUNT; i++ )
  537. {
  538. map_led_to_point( i, &point );
  539. // The y range will be 0..64, map this to 0..4
  540. uint8_t y = (point.y>>4);
  541. // Relies on hue being 8-bit and wrapping
  542. hsv.h = g_config.color_1.h + ( deltaH * y );
  543. hsv.s = g_config.color_1.s + ( deltaS * y );
  544. rgb = hsv_to_rgb( hsv );
  545. backlight_set_color( i, rgb.r, rgb.g, rgb.b );
  546. }
  547. }
  548. void backlight_effect_raindrops(bool initialize)
  549. {
  550. int16_t h1 = g_config.color_1.h;
  551. int16_t h2 = g_config.color_2.h;
  552. int16_t deltaH = h2 - h1;
  553. deltaH /= 4;
  554. // Take the shortest path between hues
  555. if ( deltaH > 127 )
  556. {
  557. deltaH -= 256;
  558. }
  559. else if ( deltaH < -127 )
  560. {
  561. deltaH += 256;
  562. }
  563. int16_t s1 = g_config.color_1.s;
  564. int16_t s2 = g_config.color_2.s;
  565. int16_t deltaS = ( s2 - s1 ) / 4;
  566. HSV hsv;
  567. RGB rgb;
  568. // Change one LED every tick
  569. uint8_t led_to_change = ( g_tick & 0x000 ) == 0 ? rand() % BACKLIGHT_LED_COUNT : 255;
  570. for ( int i=0; i<BACKLIGHT_LED_COUNT; i++ )
  571. {
  572. // If initialize, all get set to random colors
  573. // If not, all but one will stay the same as before.
  574. if ( initialize || i == led_to_change )
  575. {
  576. hsv.h = h1 + ( deltaH * ( rand() & 0x03 ) );
  577. hsv.s = s1 + ( deltaS * ( rand() & 0x03 ) );
  578. // Override brightness with global brightness control
  579. hsv.v = g_config.brightness;;
  580. rgb = hsv_to_rgb( hsv );
  581. backlight_set_color( i, rgb.r, rgb.g, rgb.b );
  582. }
  583. }
  584. }
  585. void backlight_effect_cycle_all(void)
  586. {
  587. uint8_t offset = ( g_tick << g_config.effect_speed ) & 0xFF;
  588. // Relies on hue being 8-bit and wrapping
  589. for ( int i=0; i<BACKLIGHT_LED_COUNT; i++ )
  590. {
  591. uint16_t offset2 = g_key_hit[i]<<2;
  592. // stabilizer LEDs use spacebar hits
  593. if ( i == 36+6 || i == 54+13 || // LC6, LD13
  594. ( g_config.use_7u_spacebar && i == 54+14 ) ) // LD14
  595. {
  596. offset2 = g_key_hit[36+0]<<2;
  597. }
  598. offset2 = (offset2<=63) ? (63-offset2) : 0;
  599. HSV hsv = { .h = offset+offset2, .s = 255, .v = g_config.brightness };
  600. RGB rgb = hsv_to_rgb( hsv );
  601. backlight_set_color( i, rgb.r, rgb.g, rgb.b );
  602. }
  603. }
  604. void backlight_effect_cycle_left_right(void)
  605. {
  606. uint8_t offset = ( g_tick << g_config.effect_speed ) & 0xFF;
  607. HSV hsv = { .h = 0, .s = 255, .v = g_config.brightness };
  608. RGB rgb;
  609. Point point;
  610. for ( int i=0; i<BACKLIGHT_LED_COUNT; i++ )
  611. {
  612. uint16_t offset2 = g_key_hit[i]<<2;
  613. // stabilizer LEDs use spacebar hits
  614. if ( i == 36+6 || i == 54+13 || // LC6, LD13
  615. ( g_config.use_7u_spacebar && i == 54+14 ) ) // LD14
  616. {
  617. offset2 = g_key_hit[36+0]<<2;
  618. }
  619. offset2 = (offset2<=63) ? (63-offset2) : 0;
  620. map_led_to_point( i, &point );
  621. // Relies on hue being 8-bit and wrapping
  622. hsv.h = point.x + offset + offset2;
  623. rgb = hsv_to_rgb( hsv );
  624. backlight_set_color( i, rgb.r, rgb.g, rgb.b );
  625. }
  626. }
  627. void backlight_effect_cycle_up_down(void)
  628. {
  629. uint8_t offset = ( g_tick << g_config.effect_speed ) & 0xFF;
  630. HSV hsv = { .h = 0, .s = 255, .v = g_config.brightness };
  631. RGB rgb;
  632. Point point;
  633. for ( int i=0; i<BACKLIGHT_LED_COUNT; i++ )
  634. {
  635. uint16_t offset2 = g_key_hit[i]<<2;
  636. // stabilizer LEDs use spacebar hits
  637. if ( i == 36+6 || i == 54+13 || // LC6, LD13
  638. ( g_config.use_7u_spacebar && i == 54+14 ) ) // LD14
  639. {
  640. offset2 = g_key_hit[36+0]<<2;
  641. }
  642. offset2 = (offset2<=63) ? (63-offset2) : 0;
  643. map_led_to_point( i, &point );
  644. // Relies on hue being 8-bit and wrapping
  645. hsv.h = point.y + offset + offset2;
  646. rgb = hsv_to_rgb( hsv );
  647. backlight_set_color( i, rgb.r, rgb.g, rgb.b );
  648. }
  649. }
  650. void backlight_effect_jellybean_raindrops( bool initialize )
  651. {
  652. HSV hsv;
  653. RGB rgb;
  654. // Change one LED every tick
  655. uint8_t led_to_change = ( g_tick & 0x000 ) == 0 ? rand() % BACKLIGHT_LED_COUNT : 255;
  656. for ( int i=0; i<BACKLIGHT_LED_COUNT; i++ )
  657. {
  658. // If initialize, all get set to random colors
  659. // If not, all but one will stay the same as before.
  660. if ( initialize || i == led_to_change )
  661. {
  662. hsv.h = rand() & 0xFF;
  663. hsv.s = rand() & 0xFF;
  664. // Override brightness with global brightness control
  665. hsv.v = g_config.brightness;;
  666. rgb = hsv_to_rgb( hsv );
  667. backlight_set_color( i, rgb.r, rgb.g, rgb.b );
  668. }
  669. }
  670. }
  671. void backlight_effect_cycle_radial1(void)
  672. {
  673. uint8_t offset = ( g_tick << g_config.effect_speed ) & 0xFF;
  674. HSV hsv = { .h = 0, .s = 255, .v = g_config.brightness };
  675. RGB rgb;
  676. Point point;
  677. for ( int i=0; i<BACKLIGHT_LED_COUNT; i++ )
  678. {
  679. map_led_to_point_polar( i, &point );
  680. // Relies on hue being 8-bit and wrapping
  681. hsv.h = point.x + offset;
  682. hsv.s = point.y;
  683. rgb = hsv_to_rgb( hsv );
  684. backlight_set_color( i, rgb.r, rgb.g, rgb.b );
  685. }
  686. }
  687. void backlight_effect_cycle_radial2(void)
  688. {
  689. uint8_t offset = ( g_tick << g_config.effect_speed ) & 0xFF;
  690. HSV hsv = { .h = 0, .s = g_config.color_1.s, .v = g_config.brightness };
  691. RGB rgb;
  692. Point point;
  693. for ( int i=0; i<BACKLIGHT_LED_COUNT; i++ )
  694. {
  695. map_led_to_point_polar( i, &point );
  696. uint8_t offset2 = offset + point.x;
  697. if ( offset2 & 0x80 )
  698. {
  699. offset2 = ~offset2;
  700. }
  701. offset2 = offset2 >> 2;
  702. hsv.h = g_config.color_1.h + offset2;
  703. hsv.s = 127 + ( point.y >> 1 );
  704. rgb = hsv_to_rgb( hsv );
  705. backlight_set_color( i, rgb.r, rgb.g, rgb.b );
  706. }
  707. }
  708. void backlight_effect_indicators_set_colors( uint8_t index, HSV hsv )
  709. {
  710. RGB rgb = hsv_to_rgb( hsv );
  711. if ( index == 254 )
  712. {
  713. backlight_set_color_all( rgb.r, rgb.g, rgb.b );
  714. }
  715. else
  716. {
  717. backlight_set_color( index, rgb.r, rgb.g, rgb.b );
  718. // If the spacebar LED is the indicator,
  719. // do the same for the spacebar stabilizers
  720. if ( index == 36+0 ) // LC0
  721. {
  722. #if defined (RGB_BACKLIGHT_ZEAL65)
  723. backlight_set_color( 36+7, rgb.r, rgb.g, rgb.b ); // LC7
  724. backlight_set_color( 54+14, rgb.r, rgb.g, rgb.b ); // LD14
  725. #elif defined (RGB_BACKLIGHT_ZEAL60) || defined (RGB_BACKLIGHT_M60_A)
  726. backlight_set_color( 36+6, rgb.r, rgb.g, rgb.b ); // LC6
  727. backlight_set_color( 54+13, rgb.r, rgb.g, rgb.b ); // LD13
  728. if ( g_config.use_7u_spacebar )
  729. {
  730. backlight_set_color( 54+14, rgb.r, rgb.g, rgb.b ); // LD14
  731. }
  732. #endif
  733. }
  734. }
  735. }
  736. // This runs after another backlight effect and replaces
  737. // colors already set
  738. void backlight_effect_indicators(void)
  739. {
  740. if ( g_config.caps_lock_indicator.index != 255 &&
  741. ( g_indicator_state & (1<<USB_LED_CAPS_LOCK) ) )
  742. {
  743. backlight_effect_indicators_set_colors( g_config.caps_lock_indicator.index, g_config.caps_lock_indicator.color );
  744. }
  745. // This if/else if structure allows higher layers to
  746. // override lower ones. If we set layer 3's indicator
  747. // to none, then it will NOT show layer 2 or layer 1
  748. // indicators, even if those layers are on via the
  749. // MO13/MO23 Fn combo magic.
  750. //
  751. // Basically we want to handle the case where layer 3 is
  752. // still the backlight configuration layer and we don't
  753. // want "all LEDs" indicators hiding the backlight effect,
  754. // but still allow end users to do whatever they want.
  755. if ( IS_LAYER_ON(3) )
  756. {
  757. if ( g_config.layer_3_indicator.index != 255 )
  758. {
  759. backlight_effect_indicators_set_colors( g_config.layer_3_indicator.index, g_config.layer_3_indicator.color );
  760. }
  761. }
  762. else if ( IS_LAYER_ON(2) )
  763. {
  764. if ( g_config.layer_2_indicator.index != 255 )
  765. {
  766. backlight_effect_indicators_set_colors( g_config.layer_2_indicator.index, g_config.layer_2_indicator.color );
  767. }
  768. }
  769. else if ( IS_LAYER_ON(1) )
  770. {
  771. if ( g_config.layer_1_indicator.index != 255 )
  772. {
  773. backlight_effect_indicators_set_colors( g_config.layer_1_indicator.index, g_config.layer_1_indicator.color );
  774. }
  775. }
  776. }
  777. ISR(TIMER3_COMPA_vect)
  778. {
  779. // delay 1 second before driving LEDs or doing anything else
  780. static uint8_t startup_tick = 0;
  781. if ( startup_tick < 20 )
  782. {
  783. startup_tick++;
  784. return;
  785. }
  786. g_tick++;
  787. if ( g_any_key_hit < 0xFFFFFFFF )
  788. {
  789. g_any_key_hit++;
  790. }
  791. for ( int led = 0; led < BACKLIGHT_LED_COUNT; led++ )
  792. {
  793. if ( g_key_hit[led] < 255 )
  794. {
  795. g_key_hit[led]++;
  796. }
  797. }
  798. // Factory default magic value
  799. if ( g_config.effect == 255 )
  800. {
  801. backlight_effect_rgb_test();
  802. return;
  803. }
  804. // Ideally we would also stop sending zeros to the LED driver PWM buffers
  805. // while suspended and just do a software shutdown. This is a cheap hack for now.
  806. bool suspend_backlight = ((g_suspend_state && g_config.disable_when_usb_suspended) ||
  807. (g_config.disable_after_timeout > 0 && g_any_key_hit > g_config.disable_after_timeout * 60 * 20));
  808. uint8_t effect = suspend_backlight ? 0 : g_config.effect;
  809. // Keep track of the effect used last time,
  810. // detect change in effect, so each effect can
  811. // have an optional initialization.
  812. static uint8_t effect_last = 255;
  813. bool initialize = effect != effect_last;
  814. effect_last = effect;
  815. // this gets ticked at 20 Hz.
  816. // each effect can opt to do calculations
  817. // and/or request PWM buffer updates.
  818. switch ( effect )
  819. {
  820. case 0:
  821. backlight_effect_all_off();
  822. break;
  823. case 1:
  824. backlight_effect_solid_color();
  825. break;
  826. case 2:
  827. backlight_effect_alphas_mods();
  828. break;
  829. case 3:
  830. backlight_effect_gradient_up_down();
  831. break;
  832. case 4:
  833. backlight_effect_raindrops( initialize );
  834. break;
  835. case 5:
  836. backlight_effect_cycle_all();
  837. break;
  838. case 6:
  839. backlight_effect_cycle_left_right();
  840. break;
  841. case 7:
  842. backlight_effect_cycle_up_down();
  843. break;
  844. case 8:
  845. backlight_effect_jellybean_raindrops( initialize );
  846. break;
  847. case 9:
  848. backlight_effect_cycle_radial1();
  849. break;
  850. case 10:
  851. backlight_effect_cycle_radial2();
  852. break;
  853. default:
  854. backlight_effect_all_off();
  855. break;
  856. }
  857. if ( ! suspend_backlight )
  858. {
  859. #if !defined(RGB_BACKLIGHT_M6_B)
  860. backlight_effect_indicators();
  861. #endif
  862. }
  863. }
  864. void backlight_set_indicator_index( uint8_t *index, uint8_t row, uint8_t column )
  865. {
  866. if ( row >= MATRIX_ROWS )
  867. {
  868. // Special value, 255=none, 254=all
  869. *index = row;
  870. }
  871. else
  872. {
  873. map_row_column_to_led( row, column, index );
  874. }
  875. }
  876. void backlight_get_indicator_row_col( uint8_t index, uint8_t *row, uint8_t *column )
  877. {
  878. if ( index == 255 || index == 254 )
  879. {
  880. // Special value, 255=none, 254=all
  881. *row = index;
  882. *column = 0;
  883. return;
  884. }
  885. for ( uint8_t r = 0; r < MATRIX_ROWS; r++ )
  886. {
  887. for ( uint8_t c = 0; c < MATRIX_COLS; c++ )
  888. {
  889. uint8_t i = 255;
  890. map_row_column_to_led( r, c, &i );
  891. if ( i == index )
  892. {
  893. *row = r;
  894. *column = c;
  895. return;
  896. }
  897. }
  898. }
  899. }
  900. // Some helpers for setting/getting HSV
  901. void _set_color( HSV *color, uint8_t *data )
  902. {
  903. color->h = data[0];
  904. color->s = data[1];
  905. color->v = data[2];
  906. }
  907. void _get_color( HSV *color, uint8_t *data )
  908. {
  909. data[0] = color->h;
  910. data[1] = color->s;
  911. data[2] = color->v;
  912. }
  913. void backlight_config_set_value( uint8_t *data )
  914. {
  915. bool reinitialize = false;
  916. uint8_t *value_id = &(data[0]);
  917. uint8_t *value_data = &(data[1]);
  918. switch ( *value_id )
  919. {
  920. #if defined (RGB_BACKLIGHT_ZEAL60) || defined(RGB_BACKLIGHT_ZEAL65)
  921. case id_use_split_backspace:
  922. {
  923. g_config.use_split_backspace = (bool)*value_data;
  924. reinitialize = true;
  925. break;
  926. }
  927. #endif
  928. #if defined (RGB_BACKLIGHT_ZEAL60)
  929. case id_use_split_left_shift:
  930. {
  931. g_config.use_split_left_shift = (bool)*value_data;
  932. reinitialize = true;
  933. break;
  934. }
  935. case id_use_split_right_shift:
  936. {
  937. g_config.use_split_right_shift = (bool)*value_data;
  938. reinitialize = true;
  939. break;
  940. }
  941. case id_use_7u_spacebar:
  942. {
  943. g_config.use_7u_spacebar = (bool)*value_data;
  944. reinitialize = true;
  945. break;
  946. }
  947. case id_use_iso_enter:
  948. {
  949. g_config.use_iso_enter = (bool)*value_data;
  950. reinitialize = true;
  951. break;
  952. }
  953. case id_disable_hhkb_blocker_leds:
  954. {
  955. g_config.disable_hhkb_blocker_leds = (bool)*value_data;
  956. reinitialize = true;
  957. break;
  958. }
  959. #endif
  960. case id_disable_when_usb_suspended:
  961. {
  962. g_config.disable_when_usb_suspended = (bool)*value_data;
  963. break;
  964. }
  965. case id_disable_after_timeout:
  966. {
  967. g_config.disable_after_timeout = *value_data;
  968. break;
  969. }
  970. case id_brightness:
  971. {
  972. g_config.brightness = *value_data;
  973. break;
  974. }
  975. case id_effect:
  976. {
  977. g_config.effect = *value_data;
  978. break;
  979. }
  980. case id_effect_speed:
  981. {
  982. g_config.effect_speed = *value_data;
  983. break;
  984. }
  985. case id_color_1:
  986. {
  987. _set_color( &(g_config.color_1), value_data );
  988. break;
  989. }
  990. case id_color_2:
  991. {
  992. _set_color( &(g_config.color_2), value_data );
  993. break;
  994. }
  995. case id_caps_lock_indicator_color:
  996. {
  997. _set_color( &(g_config.caps_lock_indicator.color), value_data );
  998. break;
  999. }
  1000. case id_caps_lock_indicator_row_col:
  1001. {
  1002. backlight_set_indicator_index( &(g_config.caps_lock_indicator.index), value_data[0], value_data[1] );
  1003. break;
  1004. }
  1005. case id_layer_1_indicator_color:
  1006. {
  1007. _set_color( &(g_config.layer_1_indicator.color), value_data );
  1008. break;
  1009. }
  1010. case id_layer_1_indicator_row_col:
  1011. {
  1012. backlight_set_indicator_index( &(g_config.layer_1_indicator.index), value_data[0], value_data[1] );
  1013. break;
  1014. }
  1015. case id_layer_2_indicator_color:
  1016. {
  1017. _set_color( &(g_config.layer_2_indicator.color), value_data );
  1018. break;
  1019. }
  1020. case id_layer_2_indicator_row_col:
  1021. {
  1022. backlight_set_indicator_index( &(g_config.layer_2_indicator.index), value_data[0], value_data[1] );
  1023. break;
  1024. }
  1025. case id_layer_3_indicator_color:
  1026. {
  1027. _set_color( &(g_config.layer_3_indicator.color), value_data );
  1028. break;
  1029. }
  1030. case id_layer_3_indicator_row_col:
  1031. {
  1032. backlight_set_indicator_index( &(g_config.layer_3_indicator.index), value_data[0], value_data[1] );
  1033. break;
  1034. }
  1035. case id_alphas_mods:
  1036. {
  1037. for ( int i=0; i<5; i++ )
  1038. {
  1039. g_config.alphas_mods[i] = ( *(value_data+i*2) << 8 ) | ( *(value_data+i*2+1) );
  1040. }
  1041. }
  1042. }
  1043. if ( reinitialize )
  1044. {
  1045. backlight_init_drivers();
  1046. }
  1047. }
  1048. void backlight_config_get_value( uint8_t *data )
  1049. {
  1050. uint8_t *value_id = &(data[0]);
  1051. uint8_t *value_data = &(data[1]);
  1052. switch ( *value_id )
  1053. {
  1054. case id_use_split_backspace:
  1055. {
  1056. *value_data = ( g_config.use_split_backspace ? 1 : 0 );
  1057. break;
  1058. }
  1059. case id_use_split_left_shift:
  1060. {
  1061. *value_data = ( g_config.use_split_left_shift ? 1 : 0 );
  1062. break;
  1063. }
  1064. case id_use_split_right_shift:
  1065. {
  1066. *value_data = ( g_config.use_split_right_shift ? 1 : 0 );
  1067. break;
  1068. }
  1069. case id_use_7u_spacebar:
  1070. {
  1071. *value_data = ( g_config.use_7u_spacebar ? 1 : 0 );
  1072. break;
  1073. }
  1074. case id_use_iso_enter:
  1075. {
  1076. *value_data = ( g_config.use_iso_enter ? 1 : 0 );
  1077. break;
  1078. }
  1079. case id_disable_when_usb_suspended:
  1080. {
  1081. *value_data = ( g_config.disable_when_usb_suspended ? 1 : 0 );
  1082. break;
  1083. }
  1084. case id_disable_hhkb_blocker_leds:
  1085. {
  1086. *value_data = ( g_config.disable_hhkb_blocker_leds ? 1 : 0 );
  1087. break;
  1088. }
  1089. case id_disable_after_timeout:
  1090. {
  1091. *value_data = g_config.disable_after_timeout;
  1092. break;
  1093. }
  1094. case id_brightness:
  1095. {
  1096. *value_data = g_config.brightness;
  1097. break;
  1098. }
  1099. case id_effect:
  1100. {
  1101. *value_data = g_config.effect;
  1102. break;
  1103. }
  1104. case id_effect_speed:
  1105. {
  1106. *value_data = g_config.effect_speed;
  1107. break;
  1108. }
  1109. case id_color_1:
  1110. {
  1111. _get_color( &(g_config.color_1), value_data );
  1112. break;
  1113. }
  1114. case id_color_2:
  1115. {
  1116. _get_color( &(g_config.color_2), value_data );
  1117. break;
  1118. }
  1119. case id_caps_lock_indicator_color:
  1120. {
  1121. _get_color( &(g_config.caps_lock_indicator.color), value_data );
  1122. break;
  1123. }
  1124. case id_caps_lock_indicator_row_col:
  1125. {
  1126. backlight_get_indicator_row_col( g_config.caps_lock_indicator.index, &(value_data[0]), &(value_data[1]) );
  1127. break;
  1128. }
  1129. case id_layer_1_indicator_color:
  1130. {
  1131. _get_color( &(g_config.layer_1_indicator.color), value_data );
  1132. break;
  1133. }
  1134. case id_layer_1_indicator_row_col:
  1135. {
  1136. backlight_get_indicator_row_col( g_config.layer_1_indicator.index, &(value_data[0]), &(value_data[1]) );
  1137. break;
  1138. }
  1139. case id_layer_2_indicator_color:
  1140. {
  1141. _get_color( &(g_config.layer_2_indicator.color), value_data );
  1142. break;
  1143. }
  1144. case id_layer_2_indicator_row_col:
  1145. {
  1146. backlight_get_indicator_row_col( g_config.layer_2_indicator.index, &(value_data[0]), &(value_data[1]) );
  1147. break;
  1148. }
  1149. case id_layer_3_indicator_color:
  1150. {
  1151. _get_color( &(g_config.layer_3_indicator.color), value_data );
  1152. break;
  1153. }
  1154. case id_layer_3_indicator_row_col:
  1155. {
  1156. backlight_get_indicator_row_col( g_config.layer_3_indicator.index, &(value_data[0]), &(value_data[1]) );
  1157. break;
  1158. }
  1159. case id_alphas_mods:
  1160. {
  1161. for ( int i=0; i<5; i++ )
  1162. {
  1163. *(value_data+i*2) = g_config.alphas_mods[i] >> 8;
  1164. *(value_data+i*2+1) = g_config.alphas_mods[i] & 0xFF;
  1165. }
  1166. }
  1167. }
  1168. }
  1169. void backlight_config_set_alphas_mods( uint16_t *alphas_mods )
  1170. {
  1171. for ( int i=0; i<5; i++ )
  1172. {
  1173. g_config.alphas_mods[i] = alphas_mods[i];
  1174. }
  1175. backlight_config_save();
  1176. }
  1177. void backlight_config_load(void)
  1178. {
  1179. eeprom_read_block( &g_config, ((void*)RGB_BACKLIGHT_CONFIG_EEPROM_ADDR), sizeof(backlight_config) );
  1180. }
  1181. void backlight_config_save(void)
  1182. {
  1183. eeprom_update_block( &g_config, ((void*)RGB_BACKLIGHT_CONFIG_EEPROM_ADDR), sizeof(backlight_config) );
  1184. }
  1185. void backlight_init_drivers(void)
  1186. {
  1187. // Initialize I2C
  1188. i2c_init();
  1189. #if defined(RGB_BACKLIGHT_M6_B)
  1190. IS31FL3218_init();
  1191. #else
  1192. IS31FL3731_init( ISSI_ADDR_1 );
  1193. IS31FL3731_init( ISSI_ADDR_2 );
  1194. for ( int index = 0; index < BACKLIGHT_LED_COUNT; index++ )
  1195. {
  1196. // OR the possible "disabled" cases together, then NOT the result to get the enabled state
  1197. // LC6 LD13 not present on Zeal65
  1198. #if defined (RGB_BACKLIGHT_ZEAL65)
  1199. bool enabled = !( ( index == 18+5 && !g_config.use_split_backspace ) || // LB5
  1200. ( index == 36+6 ) || // LC6
  1201. ( index == 54+13 ) ); // LD13
  1202. #elif defined (RGB_BACKLIGHT_M60_A)
  1203. bool enabled = !(
  1204. // LB6 LB7 LB8 LB15 LB16 LB17 not present on M60-A
  1205. ( index == 18+6 ) || // LB6
  1206. ( index == 18+7 ) || // LB7
  1207. ( index == 18+8 ) || // LB8
  1208. ( index == 18+15 ) || // LB15
  1209. ( index == 18+16 ) || // LB16
  1210. ( index == 18+17 ) || // LB17
  1211. // HHKB blockers (LC17, LD17) and ISO extra keys (LC15,LD13) not present on M60-A
  1212. ( index == 36+17 ) || // LC17
  1213. ( index == 54+17 ) || // LD17
  1214. ( index == 36+15 ) || // LC15
  1215. ( index == 54+13 ) ); // LD13
  1216. #elif defined (RGB_BACKLIGHT_ZEAL60)
  1217. // LB6 LB7 LB8 LB15 LB16 LB17 not present on Zeal60
  1218. bool enabled = !( ( index == 18+5 && !g_config.use_split_backspace ) || // LB5
  1219. ( index == 36+15 && !g_config.use_split_left_shift ) || // LC15
  1220. ( index == 54+8 && !g_config.use_split_right_shift ) || // LD8
  1221. ( index == 54+13 && g_config.use_7u_spacebar ) || // LD13
  1222. ( index == 36+17 && g_config.disable_hhkb_blocker_leds ) || // LC17
  1223. ( index == 54+17 && g_config.disable_hhkb_blocker_leds ) || // LD17
  1224. ( index == 18+6 ) || // LB6
  1225. ( index == 18+7 ) || // LB7
  1226. ( index == 18+8 ) || // LB8
  1227. ( index == 18+15 ) || // LB15
  1228. ( index == 18+16 ) || // LB16
  1229. ( index == 18+17 ) ); // LB17
  1230. #endif
  1231. // This only caches it for later
  1232. IS31FL3731_set_led_control_register( index, enabled, enabled, enabled );
  1233. }
  1234. // This actually updates the LED drivers
  1235. IS31FL3731_update_led_control_registers( ISSI_ADDR_1, ISSI_ADDR_2 );
  1236. #endif // !defined(RGB_BACKLIGHT_M6_B)
  1237. // TODO: put the 1 second startup delay here?
  1238. // clear the key hits
  1239. for ( int led=0; led<BACKLIGHT_LED_COUNT; led++ )
  1240. {
  1241. g_key_hit[led] = 255;
  1242. }
  1243. }
  1244. bool process_record_backlight(uint16_t keycode, keyrecord_t *record)
  1245. {
  1246. // Record keypresses for backlight effects
  1247. if ( record->event.pressed )
  1248. {
  1249. backlight_set_key_hit( record->event.key.row, record->event.key.col );
  1250. }
  1251. switch(keycode)
  1252. {
  1253. case BR_INC:
  1254. if (record->event.pressed)
  1255. {
  1256. backlight_brightness_increase();
  1257. }
  1258. return false;
  1259. break;
  1260. case BR_DEC:
  1261. if (record->event.pressed)
  1262. {
  1263. backlight_brightness_decrease();
  1264. }
  1265. return false;
  1266. break;
  1267. case EF_INC:
  1268. if (record->event.pressed)
  1269. {
  1270. backlight_effect_increase();
  1271. }
  1272. return false;
  1273. break;
  1274. case EF_DEC:
  1275. if (record->event.pressed)
  1276. {
  1277. backlight_effect_decrease();
  1278. }
  1279. return false;
  1280. break;
  1281. case ES_INC:
  1282. if (record->event.pressed)
  1283. {
  1284. backlight_effect_speed_increase();
  1285. }
  1286. return false;
  1287. break;
  1288. case ES_DEC:
  1289. if (record->event.pressed)
  1290. {
  1291. backlight_effect_speed_decrease();
  1292. }
  1293. return false;
  1294. break;
  1295. case H1_INC:
  1296. if (record->event.pressed)
  1297. {
  1298. backlight_color_1_hue_increase();
  1299. }
  1300. return false;
  1301. break;
  1302. case H1_DEC:
  1303. if (record->event.pressed)
  1304. {
  1305. backlight_color_1_hue_decrease();
  1306. }
  1307. return false;
  1308. break;
  1309. case S1_INC:
  1310. if (record->event.pressed)
  1311. {
  1312. backlight_color_1_sat_increase();
  1313. }
  1314. return false;
  1315. break;
  1316. case S1_DEC:
  1317. if (record->event.pressed)
  1318. {
  1319. backlight_color_1_sat_decrease();
  1320. break;
  1321. }
  1322. return false;
  1323. break;
  1324. case H2_INC:
  1325. if (record->event.pressed)
  1326. {
  1327. backlight_color_2_hue_increase();
  1328. }
  1329. return false;
  1330. break;
  1331. case H2_DEC:
  1332. if (record->event.pressed)
  1333. {
  1334. backlight_color_2_hue_decrease();
  1335. }
  1336. return false;
  1337. break;
  1338. case S2_INC:
  1339. if (record->event.pressed)
  1340. {
  1341. backlight_color_2_sat_increase();
  1342. }
  1343. return false;
  1344. break;
  1345. case S2_DEC:
  1346. if (record->event.pressed)
  1347. {
  1348. backlight_color_2_sat_decrease();
  1349. break;
  1350. }
  1351. return false;
  1352. break;
  1353. }
  1354. return true;
  1355. }
  1356. // Deals with the messy details of incrementing an integer
  1357. uint8_t increment( uint8_t value, uint8_t step, uint8_t min, uint8_t max )
  1358. {
  1359. int16_t new_value = value;
  1360. new_value += step;
  1361. return MIN( MAX( new_value, min ), max );
  1362. }
  1363. uint8_t decrement( uint8_t value, uint8_t step, uint8_t min, uint8_t max )
  1364. {
  1365. int16_t new_value = value;
  1366. new_value -= step;
  1367. return MIN( MAX( new_value, min ), max );
  1368. }
  1369. void backlight_effect_increase(void)
  1370. {
  1371. g_config.effect = increment( g_config.effect, 1, 0, BACKLIGHT_EFFECT_MAX );
  1372. backlight_config_save();
  1373. }
  1374. void backlight_effect_decrease(void)
  1375. {
  1376. g_config.effect = decrement( g_config.effect, 1, 0, BACKLIGHT_EFFECT_MAX );
  1377. backlight_config_save();
  1378. }
  1379. void backlight_effect_speed_increase(void)
  1380. {
  1381. g_config.effect_speed = increment( g_config.effect_speed, 1, 0, 3 );
  1382. backlight_config_save();
  1383. }
  1384. void backlight_effect_speed_decrease(void)
  1385. {
  1386. g_config.effect_speed = decrement( g_config.effect_speed, 1, 0, 3 );
  1387. backlight_config_save();
  1388. }
  1389. void backlight_brightness_increase(void)
  1390. {
  1391. g_config.brightness = increment( g_config.brightness, 8, 0, 255 );
  1392. backlight_config_save();
  1393. }
  1394. void backlight_brightness_decrease(void)
  1395. {
  1396. g_config.brightness = decrement( g_config.brightness, 8, 0, 255 );
  1397. backlight_config_save();
  1398. }
  1399. void backlight_color_1_hue_increase(void)
  1400. {
  1401. g_config.color_1.h = increment( g_config.color_1.h, 8, 0, 255 );
  1402. backlight_config_save();
  1403. }
  1404. void backlight_color_1_hue_decrease(void)
  1405. {
  1406. g_config.color_1.h = decrement( g_config.color_1.h, 8, 0, 255 );
  1407. backlight_config_save();
  1408. }
  1409. void backlight_color_1_sat_increase(void)
  1410. {
  1411. g_config.color_1.s = increment( g_config.color_1.s, 8, 0, 255 );
  1412. backlight_config_save();
  1413. }
  1414. void backlight_color_1_sat_decrease(void)
  1415. {
  1416. g_config.color_1.s = decrement( g_config.color_1.s, 8, 0, 255 );
  1417. backlight_config_save();
  1418. }
  1419. void backlight_color_2_hue_increase(void)
  1420. {
  1421. g_config.color_2.h = increment( g_config.color_2.h, 8, 0, 255 );
  1422. backlight_config_save();
  1423. }
  1424. void backlight_color_2_hue_decrease(void)
  1425. {
  1426. g_config.color_2.h = decrement( g_config.color_2.h, 8, 0, 255 );
  1427. backlight_config_save();
  1428. }
  1429. void backlight_color_2_sat_increase(void)
  1430. {
  1431. g_config.color_2.s = increment( g_config.color_2.s, 8, 0, 255 );
  1432. backlight_config_save();
  1433. }
  1434. void backlight_color_2_sat_decrease(void)
  1435. {
  1436. g_config.color_2.s = decrement( g_config.color_2.s, 8, 0, 255 );
  1437. backlight_config_save();
  1438. }
  1439. #if defined(RGB_DEBUGGING_ONLY)
  1440. void backlight_test_led( uint8_t index, bool red, bool green, bool blue )
  1441. {
  1442. for ( int i=0; i<BACKLIGHT_LED_COUNT; i++ )
  1443. {
  1444. if ( i == index )
  1445. {
  1446. IS31FL3731_set_led_control_register( i, red, green, blue );
  1447. }
  1448. else
  1449. {
  1450. IS31FL3731_set_led_control_register( i, false, false, false );
  1451. }
  1452. }
  1453. }
  1454. #endif // defined(RGB_DEBUGGING_ONLY)
  1455. void backlight_debug_led( bool state )
  1456. {
  1457. if (state)
  1458. {
  1459. // Output high.
  1460. DDRE |= (1<<6);
  1461. PORTE |= (1<<6);
  1462. }
  1463. else
  1464. {
  1465. // Output low.
  1466. DDRE &= ~(1<<6);
  1467. PORTE &= ~(1<<6);
  1468. }
  1469. }
  1470. #endif // BACKLIGHT_ENABLED