Mercurial > louis > kiibohd-controller
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 |