aboutsummaryrefslogtreecommitdiff
path: root/keyboards/infinity60/led_controller.c
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/infinity60/led_controller.c')
-rw-r--r--keyboards/infinity60/led_controller.c254
1 files changed, 175 insertions, 79 deletions
diff --git a/keyboards/infinity60/led_controller.c b/keyboards/infinity60/led_controller.c
index 4dc9b9234..59ca833b6 100644
--- a/keyboards/infinity60/led_controller.c
+++ b/keyboards/infinity60/led_controller.c
@@ -72,7 +72,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
72#define BREATHE_LED_ADDRESS CAPS_LOCK_LED_ADDRESS 72#define BREATHE_LED_ADDRESS CAPS_LOCK_LED_ADDRESS
73#endif 73#endif
74 74
75#define DEBUG_ENABLED 0 75#define DEBUG_ENABLED 1
76 76
77/* ================= 77/* =================
78 * ChibiOS I2C setup 78 * ChibiOS I2C setup
@@ -214,44 +214,58 @@ page_status = 0; //start frame 0 (all off/on)
214 //TODO: lighting key led on keypress 214 //TODO: lighting key led on keypress
215 break; 215 break;
216 216
217 //TODO: custom page that is written using keypresses
218 //TODO: BLINK_ON/OFF_LED 217 //TODO: BLINK_ON/OFF_LED
218 break;
219 219
220 case OFF_LED: 220 case OFF_LED:
221 //on/off/toggle single led, msg_led = row/col of led 221 //on/off/toggle single led, msg_led = row/col of led
222 xprintf("OFF_LED\n"); 222 xprintf("OFF_LED: %d\n", msg_led);
223 chThdSleepMilliseconds(10); 223 chThdSleepMilliseconds(10);
224 set_led_bit(7, control_register_word, msg_led, 0); 224 set_led_bit(7, control_register_word, msg_led, 0);
225 is31_write_data (7, control_register_word, 0x02); 225 is31_write_data (7, control_register_word, 0x02);
226 break; 226 break;
227
228 case ON_LED: 227 case ON_LED:
229 xprintf("ON_LED\n"); 228 xprintf("ON_LED: %d\n", msg_led);
230 chThdSleepMilliseconds(10); 229 chThdSleepMilliseconds(10);
231 set_led_bit(7, control_register_word, msg_led, 1); 230 set_led_bit(7, control_register_word, msg_led, 1);
232 is31_write_data (7, control_register_word, 0x02); 231 is31_write_data (7, control_register_word, 0x02);
233 break; 232 break;
234
235 case TOGGLE_LED: 233 case TOGGLE_LED:
236 xprintf("TOGGLE_LED\n"); 234 xprintf("TOGGLE_LED: %d\n", msg_led);
237 chThdSleepMilliseconds(10); 235 chThdSleepMilliseconds(10);
238 set_led_bit(7, control_register_word, msg_led, 2); 236 set_led_bit(7, control_register_word, msg_led, 2);
239 is31_write_data (7, control_register_word, 0x02); 237 is31_write_data (7, control_register_word, 0x02);
240 break; 238 break;
241 239
240 case BLINK_OFF_LED:
241 //on/off/toggle single led, msg_led = row/col of led
242 xprintf("BLINK_ON: %d\n", msg_led);
243 chThdSleepMilliseconds(10);
244 set_led_bit(7, control_register_word, msg_led, 4);
245 is31_write_data (7, control_register_word, 0x02);
246 break;
247 case BLINK_ON_LED:
248 xprintf("BLINK_OFF: %d\n", msg_led);
249 chThdSleepMilliseconds(10);
250 set_led_bit(7, control_register_word, msg_led, 5);
251 is31_write_data (7, control_register_word, 0x02);
252 break;
253 case BLINK_TOGGLE_LED:
254 xprintf("BLINK_TOGGLE: %d\n", msg_led);
255 chThdSleepMilliseconds(10);
256 set_led_bit(7, control_register_word, msg_led, 6);
257 is31_write_data (7, control_register_word, 0x02);
258
242 case TOGGLE_ALL: 259 case TOGGLE_ALL:
243 xprintf("TOGGLE_ALL\n"); 260 xprintf("TOGGLE_ALL: %d\n", msg_led);
244 chThdSleepMilliseconds(10); 261 chThdSleepMilliseconds(10);
245 //msg_led = unused 262 //msg_led = unused
246 is31_read_register(0, 0x00, &temp);//if first byte is on, then toggle frame 0 off 263 is31_read_register(0, 0x00, &temp);//if first byte is on, then toggle frame 0 off
247 led_control_reg[0] = 0; 264 led_control_reg[0] = 0;
265
248 if (temp==0 || page_status > 0) { 266 if (temp==0 || page_status > 0) {
249 xprintf("all leds on");
250 chThdSleepMilliseconds(10);
251 __builtin_memcpy(led_control_reg+1, all_on_leds_mask, 0x12); 267 __builtin_memcpy(led_control_reg+1, all_on_leds_mask, 0x12);
252 } else { 268 } else {
253 xprintf("all leds off");
254 chThdSleepMilliseconds(10);
255 __builtin_memset(led_control_reg+1, 0, 0x12); 269 __builtin_memset(led_control_reg+1, 0, 0x12);
256 } 270 }
257 is31_write_data(0, led_control_reg, 0x13); 271 is31_write_data(0, led_control_reg, 0x13);
@@ -292,15 +306,19 @@ page_status = 0; //start frame 0 (all off/on)
292 306
293 case DISPLAY_PAGE://show single layer indicator or full map of layer 307 case DISPLAY_PAGE://show single layer indicator or full map of layer
294 //msg_led = page to toggle on 308 //msg_led = page to toggle on
295 xprintf("DISPLAY_PAGE\n"); 309 xprintf("DISPLAY_PAGE");
296 chThdSleepMilliseconds(10); 310 chThdSleepMilliseconds(10);
297 if (page_status != msg_led) { 311 if (page_status != msg_led) {
312 xprintf(" - new page\n");
313 chThdSleepMilliseconds(10);
298 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, msg_led); 314 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, msg_led);
299 } 315 }
300 page_status = msg_led; 316 page_status = msg_led;
301 break; 317 break;
302 318
303 case RESET_PAGE: 319 case RESET_PAGE:
320 xprintf("RESET_PAGE\n");
321 chThdSleepMilliseconds(10);
304 //led_msg = page to reset 322 //led_msg = page to reset
305 led_control_reg[0] = 0; 323 led_control_reg[0] = 0;
306 __builtin_memset(led_control_reg+1, 0, 0x12); 324 __builtin_memset(led_control_reg+1, 0, 0x12);
@@ -317,19 +335,23 @@ page_status = 0; //start frame 0 (all off/on)
317 335
318 case TOGGLE_NUM_LOCK: 336 case TOGGLE_NUM_LOCK:
319 //msg_led = 0 or 1, off/on 337 //msg_led = 0 or 1, off/on
320 set_lock_leds(USB_LED_NUM_LOCK, msg_led); 338 xprintf("NUMLOCK: %d\n", msg_led);
339 chThdSleepMilliseconds(10);
340 set_lock_leds(NUM_LOCK_LED_ADDRESS, msg_led);
321 break; 341 break;
322 342
323 case TOGGLE_CAPS_LOCK: 343 case TOGGLE_CAPS_LOCK:
344 xprintf("CAPSLOCK: %d\n", msg_led);
345 chThdSleepMilliseconds(10);
324 //msg_led = 0 or 1, off/on 346 //msg_led = 0 or 1, off/on
325 set_lock_leds(USB_LED_CAPS_LOCK, msg_led); 347 set_lock_leds(CAPS_LOCK_LED_ADDRESS, msg_led);
326 break; 348 break;
327 349
328 //TODO: MODE_BREATH 350 //TODO: MODE_BREATH
329 case MODE_BREATH: 351 case MODE_BREATH:
330 break; 352 break;
331 case STEP_BRIGHTNESS: 353 case STEP_BRIGHTNESS:
332 xprintf("TOGGLE_BACKLIGHT\n"); 354 xprintf("STEP_BACKLIGHT\n");
333 chThdSleepMilliseconds(10); 355 chThdSleepMilliseconds(10);
334 //led_msg = step pwm up or down 356 //led_msg = step pwm up or down
335 switch (msg_led) { 357 switch (msg_led) {
@@ -394,27 +416,101 @@ page_status = 0; //start frame 0 (all off/on)
394 chThdSleepMilliseconds(10); 416 chThdSleepMilliseconds(10);
395 } 417 }
396#if DEBUG_ENABLED 418#if DEBUG_ENABLED
397 uint8_t j, page; 419 uint8_t j;
420 uint8_t pages[3]={0x00, 0x07};
398 //debugging code - print full led/blink/pwm registers on each frame 421 //debugging code - print full led/blink/pwm registers on each frame
399 xprintf("----layer state----: %X\n", layer_state); 422 xprintf("----layer state----: %X\n", layer_state);
400 for(i=0;i<8;i++) { 423 for(i=0;i<2;i++) {
401 xprintf("page: %d", i); 424 xprintf("page: %d\n", pages[i]);
402 chThdSleepMilliseconds(2);
403 for(j=0;j<0xB4;j++){
404 is31_read_register(i,j,&temp);
405 chThdSleepMilliseconds(2); 425 chThdSleepMilliseconds(2);
406 xprintf("%02X, ", temp); 426 for(j=0;j<0x24;j++){
407 if(j % 9 == 0){ 427 if(j > 0 && j % 9 == 0){
408 xprintf("\n"); 428 xprintf("\n");
409 if(j % 18 ==0){ 429 }
410 xprintf("register"); 430 switch (j) {
411 xprintf("\n"); 431 case 0:
412 } 432 xprintf("\n--on-off--\n");
433 chThdSleepMilliseconds(2);
434 break;
435 case 0x12:
436 xprintf("\n--blink--\n");
437 chThdSleepMilliseconds(2);
438 break;
413 } 439 }
414 chThdSleepMilliseconds(1); 440 is31_read_register(pages[i],j,&temp);
441 xprintf("%02X, ", temp);
442 chThdSleepMilliseconds(2);
415 } 443 }
444
445 xprintf("\n--pwm--\n");
446 chThdSleepMilliseconds(2);
447 for(j=0x24;j<0xB4;j++) {
448 is31_read_register(pages[i],j,&temp);
449 xprintf("%02X, ", temp);
450 chThdSleepMilliseconds(2);
451 if(j > 0x24 && (j-4) % 8 == 0){
416 xprintf("\n"); 452 xprintf("\n");
453 }
454 }
455 xprintf("\n");
456 }
457
458 //Function Register
459 xprintf("\n--FUNCTION--\n");
460 chThdSleepMilliseconds(2);
461 for(j=0;j<0x0D;j++) {
462 is31_read_register(0x0B,j,&temp);
463 switch(j) {
464 case 0:
465 xprintf("Config %02X", temp);
466 chThdSleepMilliseconds(2);
467 break;
468 case 1:
469 xprintf(" - Pict %02X\n", temp);
470 chThdSleepMilliseconds(2);
471 break;
472 case 2:
473 xprintf("Auto1 %02X", temp);
474 chThdSleepMilliseconds(2);
475 break;
476 case 3:
477 xprintf(" - Auto2 %02X\n", temp);
478 chThdSleepMilliseconds(2);
479 break;
480 case 5:
481 xprintf("Disp %02X", temp);
482 chThdSleepMilliseconds(2);
483 break;
484 case 6:
485 xprintf(" - Audio %02X\n", temp);
486 chThdSleepMilliseconds(2);
487 break;
488 case 7:
489 xprintf("Frame %02X", temp);
490 chThdSleepMilliseconds(2);
491 break;
492 case 8:
493 xprintf(" - Breath1 %02X\n", temp);
494 chThdSleepMilliseconds(2);
495 break;
496 case 9:
497 xprintf("Breath2 %02X - ", temp);
498 chThdSleepMilliseconds(2);
499 break;
500 case 10:
501 xprintf(" - Shut %02X\n", temp);
502 chThdSleepMilliseconds(2);
503 break;
504 case 11:
505 xprintf("AGC %02X", temp);
506 chThdSleepMilliseconds(2);
507 break;
508 case 12:
509 xprintf(" - ADC %02X\n", temp);
510 chThdSleepMilliseconds(2);
511 break;
417 } 512 }
513 }
418#endif 514#endif
419 } 515 }
420} 516}
@@ -425,22 +521,39 @@ page_status = 0; //start frame 0 (all off/on)
425 521
426void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint8_t action) { 522void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint8_t action) {
427 //returns 2 bytes led control register address and byte to write 523 //returns 2 bytes led control register address and byte to write
524 //0 - bit off, 1 - bit on, 2 - toggle bit
525
526 uint8_t control_reg_addr, column_bit, column_byte, temp, blink_on;
428 527
429 uint8_t control_reg_addr, column_bit, column_byte, temp;
430 //check for valid led address 528 //check for valid led address
431 if (led_addr < 0 || led_addr > 90 || led_addr % 10 > 8) { 529 if (led_addr < 0 || led_addr > 87 || led_addr % 10 > 8) {
432 xprintf("Invalid address: %d\n", led_addr); 530 xprintf("Invalid address: %d\n", led_addr);
433 return; 531 return;
434 } 532 }
435 533
534 xprintf("set_led_bit: %d\n", led_addr);
535 xprintf("action: %d\n", action);
536 chThdSleepMilliseconds(10);
537 //check blink bit
538 blink_on = action>>2;
539 action &= ~(1<<2); //strip blink bit
540
436 //first byte is led control register address 0x00 541 //first byte is led control register address 0x00
437 //msg_led tens column is pin#, ones column is bit position in 8-bit mask 542 //msg_led tens column is pin#, ones column is bit position in 8-bit mask
438 control_reg_addr = ((led_addr / 10) % 10 - 1 ) * 0x02;// A-register is every other byte 543 control_reg_addr = ((led_addr / 10) % 10 - 1 ) * 0x02;// A-register is every other byte
544 xprintf("pre-reg_addr: %X\n", control_reg_addr);
545 chThdSleepMilliseconds(10);
546 control_reg_addr += blink_on == 1 ? 0x12 : 0x00;//shift 12 bytes to blink register
547 xprintf("blink-reg_addr: %X\n", control_reg_addr);
548 chThdSleepMilliseconds(10);
549
439 column_bit = 1<<(led_addr % 10 - 1); 550 column_bit = 1<<(led_addr % 10 - 1);
440 551
441 is31_read_register(page, control_reg_addr, &temp);//maintain status of leds on this byte 552 is31_read_register(page, control_reg_addr, &temp);//maintain status of leds on this byte
442 column_byte = temp; 553 column_byte = temp;
443 554
555 xprintf("column_byte read: %X\n", column_byte);
556 chThdSleepMilliseconds(10);
444 switch(action) { 557 switch(action) {
445 case 0: 558 case 0:
446 column_byte &= ~column_bit; 559 column_byte &= ~column_bit;
@@ -452,72 +565,58 @@ void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint
452 column_byte ^= column_bit; 565 column_byte ^= column_bit;
453 break; 566 break;
454 } 567 }
568 xprintf("column_byte write: %X\n", column_byte);
569 chThdSleepMilliseconds(10);
455 570
456 //return word to be written in register 571 //return word to be written in register
457 led_control_reg[0] = control_reg_addr; 572 led_control_reg[0] = control_reg_addr;
458 led_control_reg[1] = column_byte; 573 led_control_reg[1] = column_byte;
459} 574}
460 575
461void set_lock_leds(uint8_t lock_type, uint8_t led_on) { 576void write_led_byte (uint8_t page, uint8_t row, uint8_t led_byte) {
462 uint8_t page, led_addr, start, temp; 577 uint8_t led_control_word[2] = {0};//register address and led on/off mask
463 uint8_t led_control_word[2] = {0};
464 //TODO: this function call could send led address vs lock_type.
465 //however, the switch/case allows for additional steps, like audio, depending on type
466 578
467 led_addr = 0; 579 led_control_word[0] = (row - 1 ) * 0x02;// A-register is every other byte
468 switch(lock_type) { 580 led_control_word[1] = led_byte;// A-register is every other byte
469 case USB_LED_NUM_LOCK: 581 is31_write_data(page, led_control_word, 0x13);
470 led_addr = NUM_LOCK_LED_ADDRESS;
471 break;
472 case USB_LED_CAPS_LOCK:
473 led_addr = CAPS_LOCK_LED_ADDRESS;
474 break;
475 #ifdef SCROLL_LOCK_LED_ADDRESS
476 case USB_LED_SCROLL_LOCK:
477 led_addr = SCROLL_LOCK_LED_ADDRESS;
478 break;
479 #endif
480 #ifdef COMPOSE_LED_ADDRESS
481 case USB_LED_COMPOSE:
482 led_addr = COMPOSE_LED_ADDRESS;
483 break;
484 #endif
485 #ifdef SCROLL_LOCK_LED_ADDRESS
486 case USB_LED_KANA:
487 led_addr = KANA_LED_ADDRESS;
488 break;
489 #endif
490 }
491
492 //ignore frame0 if all leds are on or if option set in led_controller.h
493 //TODO: blink of all leds are on, clear blink register if not
494 is31_read_register(0, 0x00, &temp);
495 led_addr += temp == 0 ? 0 : 0x12;//send bit to blink register instead
496 start = BACKLIGHT_OFF_LOCK_LED_OFF ? 1 : 0;
497
498 for(page=start; page<8; page++) {
499 set_led_bit(page,led_control_word,led_addr,led_on);
500 is31_write_data(page, led_control_word, 0x02);
501 }
502} 582}
503 583
504void write_led_page (uint8_t page, uint8_t *user_led_array, uint8_t led_count) { 584void write_led_page (uint8_t page, uint8_t *user_led_array, uint8_t led_count) {
505 uint8_t i; 585 uint8_t i;
506 uint8_t row, col; 586 uint8_t pin, col;
507 uint8_t led_control_register[0x13] = {0};//led control register start address + 0x12 bytes 587 uint8_t led_control_register[0x13] = {0};//led control register start address + 0x12 bytes
508 588
509 __builtin_memset(led_control_register,0,13); 589 __builtin_memset(led_control_register,0,13);
510 590
511 for(i=0;i<led_count;i++){ 591 for(i=0;i<led_count;i++){
512 row = ((user_led_array[i] / 10) % 10 - 1 ) * 2 + 1;// 1 byte shift for led register 0x00 address 592 pin = ((user_led_array[i] / 10) % 10 - 1 ) * 2 + 1;// 1 byte shift for led register 0x00 address
513 col = user_led_array[i] % 10 - 1; 593 col = user_led_array[i] % 10 - 1;
514 594
515 led_control_register[row] |= 1<<(col); 595 led_control_register[pin] |= 1<<(col);
516 } 596 }
517 597
518 is31_write_data(page, led_control_register, 0x13); 598 is31_write_data(page, led_control_register, 0x13);
519} 599}
520 600
601void set_lock_leds(uint8_t led_addr, uint8_t led_action) {
602 uint8_t page, temp;
603 uint8_t led_control_word[2] = {0};
604
605 //blink if all leds are on
606 //is31_read_register(0, 0x00, &temp);
607 //if (temp != 0x00) {
608 // set_led_bit(0,led_control_word,led_addr,(led_action | (1<<2))); //set blink bit
609 //} else {
610 // set_led_bit(0,led_control_word,led_addr,led_action);
611 //}
612 //is31_write_data(0, led_control_word, 0x02);
613
614 for(page=1; page<8; page++) {
615 set_led_bit(page,led_control_word,led_addr,led_action);
616 is31_write_data(page, led_control_word, 0x02);
617 }
618}
619
521/* ===================== 620/* =====================
522 * hook into user keymap 621 * hook into user keymap
523 * ===================== */ 622 * ===================== */
@@ -541,7 +640,8 @@ void led_controller_init(void) {
541 is31_init(); 640 is31_init();
542 641
543 //set Display Option Register so all pwm intensity is controlled from Frame 0 642 //set Display Option Register so all pwm intensity is controlled from Frame 0
544 is31_write_register(IS31_FUNCTIONREG, IS31_REG_DISPLAYOPT, IS31_REG_DISPLAYOPT_INTENSITY_SAME); 643 //enable blink and set blink period to 0.27s x rate
644 is31_write_register(IS31_FUNCTIONREG, IS31_REG_DISPLAYOPT, IS31_REG_DISPLAYOPT_INTENSITY_SAME + S31_REG_DISPLAYOPT_BLINK_ENABLE + 5);
545 645
546 /* set full pwm on Frame 1 */ 646 /* set full pwm on Frame 1 */
547 pwm_register_array[0] = 0; 647 pwm_register_array[0] = 0;
@@ -557,10 +657,6 @@ void led_controller_init(void) {
557 is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, (3<<4)|3); 657 is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, (3<<4)|3);
558 is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, IS31_REG_BREATHCTRL2_ENABLE|3); 658 is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, IS31_REG_BREATHCTRL2_ENABLE|3);
559 659
560 // clean up the lock LEDs
561 set_lock_leds(USB_LED_NUM_LOCK, 0);
562 set_lock_leds(USB_LED_CAPS_LOCK, 0);
563
564 /* more time consuming LED processing should be offloaded into 660 /* more time consuming LED processing should be offloaded into
565 * a thread, with asynchronous messaging. */ 661 * a thread, with asynchronous messaging. */
566 chMBObjectInit(&led_mailbox, led_mailbox_queue, LED_MAILBOX_NUM_MSGS); 662 chMBObjectInit(&led_mailbox, led_mailbox_queue, LED_MAILBOX_NUM_MSGS);