700e.c (10766B)
1 /** 2 * @file 700e.c 3 * 4 Copyright 2022 astro 5 6 This program is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "quantum.h" 21 22 #ifdef RGBLIGHT_ENABLE 23 # include "i2c_master.h" 24 # include "drivers/led/issi/is31fl3731.h" 25 # include "ws2812.h" 26 27 enum { 28 SELF_TESTING, 29 CAPS_ALERT, 30 NORMAL, 31 }; 32 33 enum { 34 ST_STAGE_1, 35 ST_STAGE_2, 36 ST_STAGE_3, 37 }; 38 39 // alert state update interval 40 #define ALERT_INTERVAL 500 41 // self testing state update interval 42 #define ST_INTERVAL 100 43 // self testing start index 44 #define ST_DEFAULT_INDEX 15 45 // self testing stage delay 46 #define ST_STAGE_DELAY 10 47 // self testing stage cycle count 48 #define ST_STAGE_COUNT 4 49 // self testing stage end duration 50 #define ST_END_DURATION 10 51 52 // led index 53 #define ST_LEFT_BEGIN 0 54 #ifdef IS31FL3731_I2C_ADDRESS_2 55 #define ST_LEFT_SIZE 4 56 #else 57 #define ST_LEFT_SIZE 2 58 #endif 59 #define ST_LEFT_END (ST_LEFT_BEGIN+ST_LEFT_SIZE-1) 60 #ifdef IS31FL3731_I2C_ADDRESS_2 61 #define ST_RIGHT_BEGIN 60 62 #else 63 #define ST_RIGHT_BEGIN 30 64 #endif 65 #ifdef IS31FL3731_I2C_ADDRESS_2 66 #define ST_RIGHT_SIZE 4 67 #else 68 #define ST_RIGHT_SIZE 2 69 #endif 70 #define ST_RIGHT_END (ST_RIGHT_BEGIN+ST_RIGHT_SIZE-1) 71 72 73 typedef struct { 74 uint8_t state; 75 uint8_t testing; 76 bool alert; 77 uint8_t index; 78 uint8_t delay; 79 uint8_t count; 80 bool dir; 81 uint8_t duration; 82 uint16_t ticks; 83 } rgb_state_t; 84 85 static rgb_state_t rgb_state = { 86 .state = //NORMAL, 87 SELF_TESTING, 88 .testing = ST_STAGE_1, 89 .ticks = 0, 90 .alert = false, 91 .index = ST_DEFAULT_INDEX, 92 .delay = ST_STAGE_DELAY, 93 .count = ST_STAGE_COUNT, 94 .dir = true, 95 .duration = ST_END_DURATION, 96 }; 97 98 static void update_ticks(void) 99 { 100 rgb_state.ticks = timer_read(); 101 } 102 103 static void self_testing(void) 104 { 105 if (timer_elapsed(rgb_state.ticks) < ST_INTERVAL) return; 106 hsv_t hsv = rgblight_get_hsv(); 107 108 rgb_t led = hsv_to_rgb(hsv); 109 switch(rgb_state.testing) { 110 case ST_STAGE_1: 111 if (rgb_state.index !=0 ) { 112 is31fl3731_set_color_all(0, 0, 0); 113 } 114 115 if (rgb_state.index >= ST_LEFT_END) { 116 for (int i = rgb_state.index - 1; i < IS31FL3731_LED_COUNT - rgb_state.index + 1; i++) { 117 is31fl3731_set_color(i, led.r, led.g, led.b); 118 } 119 if (rgb_state.index == ST_LEFT_END) { 120 rgb_state.index = ST_LEFT_BEGIN; 121 } else { 122 rgb_state.index -= ST_LEFT_SIZE; 123 } 124 } else{ 125 if (rgb_state.delay > 0) { 126 rgb_state.delay--; 127 } else { 128 // move to stage 2 129 rgb_state.index = ST_LEFT_BEGIN+ST_LEFT_SIZE; 130 rgb_state.testing = ST_STAGE_2; 131 } 132 } 133 break; 134 case ST_STAGE_2: { 135 // clear all 136 is31fl3731_set_color_all(0, 0, 0); 137 int i = 0; 138 // light left and right 139 for (i = 0; i < ST_LEFT_SIZE; i++) { 140 is31fl3731_set_color(ST_LEFT_BEGIN+i, led.r, led.g, led.b); 141 } 142 for (i = 0; i < ST_RIGHT_SIZE; i++) { 143 is31fl3731_set_color(ST_RIGHT_BEGIN+i, led.r, led.g, led.b); 144 145 } 146 if (rgb_state.dir) { 147 // left to right 148 for (int i = rgb_state.index; i < rgb_state.index+ST_LEFT_SIZE+ST_RIGHT_SIZE; i++) { 149 is31fl3731_set_color(i, led.r, led.g, led.b); 150 } 151 rgb_state.index += ST_LEFT_SIZE+ST_RIGHT_SIZE; 152 if (rgb_state.index == ST_RIGHT_BEGIN) { 153 rgb_state.dir = !rgb_state.dir; 154 rgb_state.count--; 155 } 156 } else { 157 // right to left 158 for (int i = rgb_state.index - ST_RIGHT_SIZE; i < rgb_state.index; i++) { 159 is31fl3731_set_color(i, led.r, led.g, led.b); 160 } 161 rgb_state.index -= ST_LEFT_SIZE + ST_RIGHT_SIZE; 162 if (rgb_state.index == ST_LEFT_BEGIN+ST_LEFT_SIZE) { 163 rgb_state.dir = !rgb_state.dir; 164 rgb_state.count--; 165 } 166 } 167 168 if (rgb_state.count == 0) { 169 // move to stage 3 170 rgb_state.testing = ST_STAGE_3; 171 rgb_state.index = 0; 172 rgb_state.delay = ST_STAGE_DELAY; 173 rgb_state.duration = ST_END_DURATION; 174 } 175 } 176 break; 177 case ST_STAGE_3: 178 if (rgb_state.index != IS31FL3731_LED_COUNT/2) { 179 is31fl3731_set_color_all(0, 0, 0); 180 } 181 182 // light left and right 183 184 if (rgb_state.index == IS31FL3731_LED_COUNT/2) { 185 if (rgb_state.duration) { 186 rgb_state.duration--; 187 } else { 188 if (host_keyboard_led_state().caps_lock) { 189 rgb_state.state = CAPS_ALERT; 190 } else { 191 rgb_state.state = NORMAL; 192 rgblight_set(); 193 } 194 } 195 } else { 196 // left 197 for (int i = 0; i < rgb_state.index+1; i++) { 198 is31fl3731_set_color(i, led.r, led.g, led.b); 199 } 200 // right 201 for (int i = ST_RIGHT_END; i > ST_RIGHT_END - rgb_state.index - 1; i--) { 202 is31fl3731_set_color(i, led.r, led.g, led.b); 203 } 204 rgb_state.index ++; 205 } 206 break; 207 } 208 209 update_ticks(); 210 } 211 212 const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = { 213 /* Refer to IS31 manual for these locations 214 * driver 215 * | R location 216 * | | G location 217 * | | | B location 218 * | | | | */ 219 // left CA 220 {0, C1_1, C3_2, C4_2}, 221 {0, C1_2, C2_2, C4_3}, 222 {0, C1_3, C2_3, C3_3}, 223 {0, C1_4, C2_4, C3_4}, 224 {0, C1_5, C2_5, C3_5}, 225 {0, C1_6, C2_6, C3_6}, 226 {0, C1_7, C2_7, C3_7}, 227 {0, C1_8, C2_8, C3_8}, 228 229 {0, C9_1, C8_1, C7_1}, 230 {0, C9_2, C8_2, C7_2}, 231 {0, C9_3, C8_3, C7_3}, 232 {0, C9_4, C8_4, C7_4}, 233 {0, C9_5, C8_5, C7_5}, 234 {0, C9_6, C8_6, C7_6}, 235 {0, C9_7, C8_7, C6_6}, 236 {0, C9_8, C7_7, C6_7}, 237 // left CB 238 {0, C1_9, C3_10, C4_10}, 239 {0, C1_10, C2_10, C4_11}, 240 {0, C1_11, C2_11, C3_11}, 241 {0, C1_12, C2_12, C3_12}, 242 {0, C1_13, C2_13, C3_13}, 243 {0, C1_14, C2_14, C3_14}, 244 {0, C1_15, C2_15, C3_15}, 245 {0, C1_16, C2_16, C3_16}, 246 247 {0, C9_9, C8_9, C7_9}, 248 {0, C9_10, C8_10, C7_10}, 249 {0, C9_11, C8_11, C7_11}, 250 {0, C9_12, C8_12, C7_12}, 251 {0, C9_13, C8_13, C7_13}, 252 {0, C9_14, C8_14, C7_14}, 253 {0, C9_15, C8_15, C6_14}, 254 {0, C9_16, C7_15, C6_15}, 255 256 // right CA 257 {1, C1_1, C3_2, C4_2}, 258 {1, C1_2, C2_2, C4_3}, 259 {1, C1_3, C2_3, C3_3}, 260 {1, C1_4, C2_4, C3_4}, 261 {1, C1_5, C2_5, C3_5}, 262 {1, C1_6, C2_6, C3_6}, 263 {1, C1_7, C2_7, C3_7}, 264 {1, C1_8, C2_8, C3_8}, 265 266 {1, C9_1, C8_1, C7_1}, 267 {1, C9_2, C8_2, C7_2}, 268 {1, C9_3, C8_3, C7_3}, 269 {1, C9_4, C8_4, C7_4}, 270 {1, C9_5, C8_5, C7_5}, 271 {1, C9_6, C8_6, C7_6}, 272 {1, C9_7, C8_7, C6_6}, 273 {1, C9_8, C7_7, C6_7}, 274 // right CB 275 {1, C1_9, C3_10, C4_10}, 276 {1, C1_10, C2_10, C4_11}, 277 {1, C1_11, C2_11, C3_11}, 278 {1, C1_12, C2_12, C3_12}, 279 {1, C1_13, C2_13, C3_13}, 280 {1, C1_14, C2_14, C3_14}, 281 {1, C1_15, C2_15, C3_15}, 282 {1, C1_16, C2_16, C3_16}, 283 284 {1, C9_9, C8_9, C7_9}, 285 {1, C9_10, C8_10, C7_10}, 286 {1, C9_11, C8_11, C7_11}, 287 {1, C9_12, C8_12, C7_12}, 288 {1, C9_13, C8_13, C7_13}, 289 {1, C9_14, C8_14, C7_14}, 290 {1, C9_15, C8_15, C6_14}, 291 {1, C9_16, C7_15, C6_15}, 292 }; 293 294 void matrix_init_kb(void) 295 { 296 gpio_set_pin_output(LED_CAPS_LOCK_PIN); 297 gpio_write_pin_low(LED_CAPS_LOCK_PIN); 298 299 300 update_ticks(); 301 matrix_init_user(); 302 } 303 304 #define ALERM_LED_R 0xFF 305 #define ALERM_LED_G 0xA5 306 #define ALERM_LED_B 0x00 307 //golden 0xFF, 0xD9, 0x00 308 309 void housekeeping_task_kb(void) 310 { 311 if (rgb_state.state == SELF_TESTING) { 312 self_testing(); 313 } else if (rgb_state.state == CAPS_ALERT) { 314 if (rgb_state.alert) { 315 is31fl3731_set_color_all(ALERM_LED_R, ALERM_LED_G, ALERM_LED_B); 316 ws2812_set_color_all(ALERM_LED_G, ALERM_LED_R, ALERM_LED_B); 317 } else { 318 is31fl3731_set_color_all(0, 0, 0); 319 ws2812_set_color_all(0, 0, 0); 320 } 321 322 if (timer_elapsed(rgb_state.ticks) > ALERT_INTERVAL) { 323 rgb_state.alert = !rgb_state.alert; 324 update_ticks(); 325 } 326 } 327 328 is31fl3731_flush(); 329 ws2812_flush(); 330 } 331 332 void init_custom(void) { 333 is31fl3731_init_drivers(); 334 ws2812_init(); 335 } 336 337 void set_color_custom(int index, uint8_t red, uint8_t green, uint8_t blue) { 338 if (index < IS31FL3731_LED_COUNT) { 339 is31fl3731_set_color(index, red, green, blue); 340 } else if (index < IS31FL3731_LED_COUNT + WS2812_LED_COUNT) { 341 ws2812_set_color(index - IS31FL3731_LED_COUNT, green, red, blue); 342 } 343 } 344 345 void set_color_all_custom(uint8_t red, uint8_t green, uint8_t blue) { 346 for (int i = 0; i < RGBLIGHT_LED_COUNT; i++) { 347 set_color_custom(i, red, green, blue); 348 } 349 } 350 351 void flush_custom(void) { 352 if (rgb_state.state != NORMAL) return; 353 354 is31fl3731_flush(); 355 ws2812_flush(); 356 } 357 358 const rgblight_driver_t rgblight_driver = { 359 .init = init_custom, 360 .set_color = set_color_custom, 361 .set_color_all = set_color_all_custom, 362 .flush = flush_custom, 363 }; 364 365 bool led_update_kb(led_t led_state) 366 { 367 bool res = led_update_user(led_state); 368 if (res) { 369 gpio_write_pin(LED_CAPS_LOCK_PIN, led_state.caps_lock); 370 371 if (rgb_state.state != SELF_TESTING) { 372 if (led_state.caps_lock) { 373 rgb_state.state = CAPS_ALERT; 374 update_ticks(); 375 } else { 376 rgb_state.state = NORMAL; 377 rgblight_set(); 378 } 379 } 380 } 381 return res; 382 } 383 384 #endif