comparison Scan/ISSILed/led_scan.c @ 390:a3825c7fc651

Adding remote capability LED control - Works for all nodes in chain - Synchronized to 30 ms update rate (required for ISSI chip) * Interconnect cannot handle full update speed from Scan module * Though it should be able to handle quite a bit more than 30 ms updates
author Jacob Alexander <haata@kiibohd.com>
date Fri, 16 Oct 2015 10:02:01 -0700
parents 82ce1988fefe
children 23a1868b4ac2
comparison
equal deleted inserted replaced
389:fc2c2a1e9615 390:a3825c7fc651
23 #include <cli.h> 23 #include <cli.h>
24 #include <kll_defs.h> 24 #include <kll_defs.h>
25 #include <led.h> 25 #include <led.h>
26 #include <print.h> 26 #include <print.h>
27 27
28 // Interconnect module if compiled in
29 #if defined(ConnectEnabled_define)
30 #include <connect_scan.h>
31 #endif
32
28 // Local Includes 33 // Local Includes
29 #include "led_scan.h" 34 #include "led_scan.h"
30 35
31 36
32 37
34 39
35 #define I2C_TxBufferLength 300 40 #define I2C_TxBufferLength 300
36 #define I2C_RxBufferLength 8 41 #define I2C_RxBufferLength 8
37 42
38 #define LED_BufferLength 144 43 #define LED_BufferLength 144
44
45 // TODO Needs to be defined per keyboard
46 #define LED_TotalChannels 144
47
39 48
40 49
41 // ----- Structs ----- 50 // ----- Structs -----
42 51
43 typedef struct I2C_Buffer { 52 typedef struct I2C_Buffer {
654 LedControlMode mode; // XXX Make sure to adjust the .kll capability if this variable is larger than 8 bits 663 LedControlMode mode; // XXX Make sure to adjust the .kll capability if this variable is larger than 8 bits
655 uint8_t amount; 664 uint8_t amount;
656 uint16_t index; 665 uint16_t index;
657 } LedControl; 666 } LedControl;
658 667
659 uint8_t LED_control_timer = 0;
660 void LED_control( LedControl *control ) 668 void LED_control( LedControl *control )
661 { 669 {
662 // Only send if we've completed all other transactions 670 // Only send if we've completed all other transactions
671 /*
663 if ( I2C_TxBuffer.sequencePos > 0 ) 672 if ( I2C_TxBuffer.sequencePos > 0 )
664 return; 673 return;
665 674 */
666 // XXX
667 // ISSI Chip locks up if we spam updates too quickly (might be an I2C bug on this side too -HaaTa)
668 // Make sure we only send an update every 30 milliseconds at most
669 // It may be possible to optimize speed even further, but will likely require serious time with a logic analyzer
670
671 uint8_t currentTime = (uint8_t)systick_millis_count;
672 int8_t compare = (int8_t)(currentTime - LED_control_timer) & 0x7F;
673 if ( compare < 30 )
674 {
675 return;
676 }
677 LED_control_timer = currentTime;
678 675
679 // Configure based upon the given mode 676 // Configure based upon the given mode
680 // TODO Handle multiple issi chips per node
681 // TODO Perhaps do gamma adjustment? 677 // TODO Perhaps do gamma adjustment?
682 switch ( control->mode ) 678 switch ( control->mode )
683 { 679 {
684 case LedControlMode_brightness_decrease: 680 case LedControlMode_brightness_decrease:
685 // Don't worry about rolling over, the cycle is quick 681 // Don't worry about rolling over, the cycle is quick
694 case LedControlMode_brightness_set: 690 case LedControlMode_brightness_set:
695 LED_pageBuffer.buffer[ control->index ] = control->amount; 691 LED_pageBuffer.buffer[ control->index ] = control->amount;
696 break; 692 break;
697 693
698 case LedControlMode_brightness_decrease_all: 694 case LedControlMode_brightness_decrease_all:
699 for ( uint8_t channel = 0; channel < LED_BufferLength; channel++ ) 695 for ( uint8_t channel = 0; channel < LED_TotalChannels; channel++ )
700 { 696 {
701 // Don't worry about rolling over, the cycle is quick 697 // Don't worry about rolling over, the cycle is quick
702 LED_pageBuffer.buffer[ channel ] -= control->amount; 698 LED_pageBuffer.buffer[ channel ] -= control->amount;
703 } 699 }
704 break; 700 break;
705 701
706 case LedControlMode_brightness_increase_all: 702 case LedControlMode_brightness_increase_all:
707 for ( uint8_t channel = 0; channel < LED_BufferLength; channel++ ) 703 for ( uint8_t channel = 0; channel < LED_TotalChannels; channel++ )
708 { 704 {
709 // Don't worry about rolling over, the cycle is quick 705 // Don't worry about rolling over, the cycle is quick
710 LED_pageBuffer.buffer[ channel ] += control->amount; 706 LED_pageBuffer.buffer[ channel ] += control->amount;
711 } 707 }
712 break; 708 break;
713 709
714 case LedControlMode_brightness_set_all: 710 case LedControlMode_brightness_set_all:
715 for ( uint8_t channel = 0; channel < LED_BufferLength; channel++ ) 711 for ( uint8_t channel = 0; channel < LED_TotalChannels; channel++ )
716 { 712 {
717 LED_pageBuffer.buffer[ channel ] = control->amount; 713 LED_pageBuffer.buffer[ channel ] = control->amount;
718 } 714 }
719 break; 715 break;
720 } 716 }
724 LED_pageBuffer.i2c_addr = 0xE8; // Chip 1 720 LED_pageBuffer.i2c_addr = 0xE8; // Chip 1
725 LED_pageBuffer.reg_addr = 0x24; // Brightness section 721 LED_pageBuffer.reg_addr = 0x24; // Brightness section
726 LED_sendPage( (uint8_t*)&LED_pageBuffer, sizeof( LED_Buffer ), 0 ); 722 LED_sendPage( (uint8_t*)&LED_pageBuffer, sizeof( LED_Buffer ), 0 );
727 } 723 }
728 724
725 uint8_t LED_control_timer = 0;
729 void LED_control_capability( uint8_t state, uint8_t stateType, uint8_t *args ) 726 void LED_control_capability( uint8_t state, uint8_t stateType, uint8_t *args )
730 { 727 {
731 // Display capability name 728 // Display capability name
732 if ( stateType == 0xFF && state == 0xFF ) 729 if ( stateType == 0xFF && state == 0xFF )
733 { 730 {
738 // Only use capability on press 735 // Only use capability on press
739 // TODO Analog 736 // TODO Analog
740 if ( stateType == 0x00 && state == 0x03 ) // Not on release 737 if ( stateType == 0x00 && state == 0x03 ) // Not on release
741 return; 738 return;
742 739
740 // XXX
741 // ISSI Chip locks up if we spam updates too quickly (might be an I2C bug on this side too -HaaTa)
742 // Make sure we only send an update every 30 milliseconds at most
743 // It may be possible to optimize speed even further, but will likely require serious time with a logic analyzer
744
745 uint8_t currentTime = (uint8_t)systick_millis_count;
746 int8_t compare = (int8_t)(currentTime - LED_control_timer) & 0x7F;
747 if ( compare < 30 )
748 {
749 return;
750 }
751 LED_control_timer = currentTime;
752
743 // Set the input structure 753 // Set the input structure
744 LedControl *control = (LedControl*)args; 754 LedControl *control = (LedControl*)args;
745 755
746 // TODO broadcast to rest of interconnect nodes if necessary 756 // Interconnect broadcasting
757 #if defined(ConnectEnabled_define)
758 uint8_t send_packet = 0;
759 uint8_t ignore_node = 0;
760
761 // By default send to the *next* node, which will determine where to go next
762 extern uint8_t Connect_id; // connect_scan.c
763 uint8_t addr = Connect_id + 1;
764
765 switch ( control->mode )
766 {
767 // Calculate the led address to send
768 // If greater than the Total hannels
769 // Set address - Total channels
770 // Otherwise, ignore
771 case LedControlMode_brightness_decrease:
772 case LedControlMode_brightness_increase:
773 case LedControlMode_brightness_set:
774 // Ignore if led is on this node
775 if ( control->index < LED_TotalChannels )
776 break;
777
778 // Calculate new led index
779 control->index -= LED_TotalChannels;
780
781 ignore_node = 1;
782 send_packet = 1;
783 break;
784
785 // Broadcast to all nodes
786 // XXX Do not set broadcasting address
787 // Will send command twice
788 case LedControlMode_brightness_decrease_all:
789 case LedControlMode_brightness_increase_all:
790 case LedControlMode_brightness_set_all:
791 send_packet = 1;
792 break;
793 }
794
795 // Only send interconnect remote capability packet if necessary
796 if ( send_packet )
797 {
798 // generatedKeymap.h
799 extern const Capability CapabilitiesList[];
800
801 // Broadcast layerStackExact remote capability (0xFF is the broadcast id)
802 Connect_send_RemoteCapability(
803 addr,
804 LED_control_capability_index,
805 state,
806 stateType,
807 CapabilitiesList[ LED_control_capability_index ].argCount,
808 args
809 );
810 }
811
812 // If there is nothing to do on this node, ignore
813 if ( ignore_node )
814 return;
815 #endif
816
817 // Modify led state of this node
747 LED_control( control ); 818 LED_control( control );
748 } 819 }
749 820
750 821
751 822