rgb_backlight.c 39 KB

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