]> git.donarmstrong.com Git - kiibohd-controller.git/commitdiff
Adding remote capability LED control
authorJacob Alexander <haata@kiibohd.com>
Fri, 16 Oct 2015 17:02:01 +0000 (10:02 -0700)
committerJacob Alexander <haata@kiibohd.com>
Fri, 16 Oct 2015 17:02:01 +0000 (10:02 -0700)
- 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

Scan/ISSILed/led_scan.c
Scan/UARTConnect/connect_scan.c

index 549fc0d27cb211178d1b950f3caeedfc1e7df3d1..8a92b768c67122b4b3e69b5dd037cb550a1f48d7 100644 (file)
 #include <led.h>
 #include <print.h>
 
+// Interconnect module if compiled in
+#if defined(ConnectEnabled_define)
+#include <connect_scan.h>
+#endif
+
 // Local Includes
 #include "led_scan.h"
 
 
 #define LED_BufferLength 144
 
+// TODO Needs to be defined per keyboard
+#define LED_TotalChannels 144
+
+
 
 // ----- Structs -----
 
@@ -656,28 +665,15 @@ typedef struct LedControl {
        uint16_t       index;
 } LedControl;
 
-uint8_t LED_control_timer = 0;
 void LED_control( LedControl *control )
 {
        // Only send if we've completed all other transactions
+       /*
        if ( I2C_TxBuffer.sequencePos > 0 )
                return;
-
-       // XXX
-       // ISSI Chip locks up if we spam updates too quickly (might be an I2C bug on this side too -HaaTa)
-       // Make sure we only send an update every 30 milliseconds at most
-       // It may be possible to optimize speed even further, but will likely require serious time with a logic analyzer
-
-       uint8_t currentTime = (uint8_t)systick_millis_count;
-       int8_t compare = (int8_t)(currentTime - LED_control_timer) & 0x7F;
-       if ( compare < 30 )
-       {
-               return;
-       }
-       LED_control_timer = currentTime;
+       */
 
        // Configure based upon the given mode
-       // TODO Handle multiple issi chips per node
        // TODO Perhaps do gamma adjustment?
        switch ( control->mode )
        {
@@ -696,7 +692,7 @@ void LED_control( LedControl *control )
                break;
 
        case LedControlMode_brightness_decrease_all:
-               for ( uint8_t channel = 0; channel < LED_BufferLength; channel++ )
+               for ( uint8_t channel = 0; channel < LED_TotalChannels; channel++ )
                {
                        // Don't worry about rolling over, the cycle is quick
                        LED_pageBuffer.buffer[ channel ] -= control->amount;
@@ -704,7 +700,7 @@ void LED_control( LedControl *control )
                break;
 
        case LedControlMode_brightness_increase_all:
-               for ( uint8_t channel = 0; channel < LED_BufferLength; channel++ )
+               for ( uint8_t channel = 0; channel < LED_TotalChannels; channel++ )
                {
                        // Don't worry about rolling over, the cycle is quick
                        LED_pageBuffer.buffer[ channel ] += control->amount;
@@ -712,7 +708,7 @@ void LED_control( LedControl *control )
                break;
 
        case LedControlMode_brightness_set_all:
-               for ( uint8_t channel = 0; channel < LED_BufferLength; channel++ )
+               for ( uint8_t channel = 0; channel < LED_TotalChannels; channel++ )
                {
                        LED_pageBuffer.buffer[ channel ] = control->amount;
                }
@@ -726,6 +722,7 @@ void LED_control( LedControl *control )
        LED_sendPage( (uint8_t*)&LED_pageBuffer, sizeof( LED_Buffer ), 0 );
 }
 
+uint8_t LED_control_timer = 0;
 void LED_control_capability( uint8_t state, uint8_t stateType, uint8_t *args )
 {
        // Display capability name
@@ -740,10 +737,84 @@ void LED_control_capability( uint8_t state, uint8_t stateType, uint8_t *args )
        if ( stateType == 0x00 && state == 0x03 ) // Not on release
                return;
 
+       // XXX
+       // ISSI Chip locks up if we spam updates too quickly (might be an I2C bug on this side too -HaaTa)
+       // Make sure we only send an update every 30 milliseconds at most
+       // It may be possible to optimize speed even further, but will likely require serious time with a logic analyzer
+
+       uint8_t currentTime = (uint8_t)systick_millis_count;
+       int8_t compare = (int8_t)(currentTime - LED_control_timer) & 0x7F;
+       if ( compare < 30 )
+       {
+               return;
+       }
+       LED_control_timer = currentTime;
+
        // Set the input structure
        LedControl *control = (LedControl*)args;
 
-       // TODO broadcast to rest of interconnect nodes if necessary
+       // Interconnect broadcasting
+#if defined(ConnectEnabled_define)
+       uint8_t send_packet = 0;
+       uint8_t ignore_node = 0;
+
+       // By default send to the *next* node, which will determine where to go next
+       extern uint8_t Connect_id; // connect_scan.c
+       uint8_t addr = Connect_id + 1;
+
+       switch ( control->mode )
+       {
+       // Calculate the led address to send
+       // If greater than the Total hannels
+       // Set address - Total channels
+       // Otherwise, ignore
+       case LedControlMode_brightness_decrease:
+       case LedControlMode_brightness_increase:
+       case LedControlMode_brightness_set:
+               // Ignore if led is on this node
+               if ( control->index < LED_TotalChannels )
+                       break;
+
+               // Calculate new led index
+               control->index -= LED_TotalChannels;
+
+               ignore_node = 1;
+               send_packet = 1;
+               break;
+
+       // Broadcast to all nodes
+       // XXX Do not set broadcasting address
+       //     Will send command twice
+       case LedControlMode_brightness_decrease_all:
+       case LedControlMode_brightness_increase_all:
+       case LedControlMode_brightness_set_all:
+               send_packet = 1;
+               break;
+       }
+
+       // Only send interconnect remote capability packet if necessary
+       if ( send_packet )
+       {
+               // generatedKeymap.h
+               extern const Capability CapabilitiesList[];
+
+               // Broadcast layerStackExact remote capability (0xFF is the broadcast id)
+               Connect_send_RemoteCapability(
+                       addr,
+                       LED_control_capability_index,
+                       state,
+                       stateType,
+                       CapabilitiesList[ LED_control_capability_index ].argCount,
+                       args
+               );
+       }
+
+       // If there is nothing to do on this node, ignore
+       if ( ignore_node )
+               return;
+#endif
+
+       // Modify led state of this node
        LED_control( control );
 }
 
index 2b223e17dba5a3efffaca1a9fee12bd0d20b022b..1d08777cbda8d5f268c8196ce7ddeee17fc20653 100644 (file)
 
 // ----- Macros -----
 
-// Macro for adding to each uart Tx ring buffer
-#define uart_addTxBuffer( uartNum ) \
-case uartNum: \
-       /* Delay UART copy until there's some space left */ \
-       while ( uart_tx_buf[ uartNum ].items + count > UART_Buffer_Size ) \
-       { \
-               warn_msg("Too much data to send on UART0, waiting..."); \
-               delay( 1 ); \
-       } \
-       /* Append data to ring buffer */ \
-       for ( uint8_t c = 0; c < count; c++ ) \
-       { \
-               if ( Connect_debug ) \
-               { \
-                       printHex( buffer[ c ] ); \
-                       print( " +" #uartNum NL ); \
-               } \
-               uart_tx_buf[ uartNum ].buffer[ uart_tx_buf[ uartNum ].tail++ ] = buffer[ c ]; \
-               uart_tx_buf[ uartNum ].items++; \
-               if ( uart_tx_buf[ uartNum ].tail >= UART_Buffer_Size ) \
-                       uart_tx_buf[ uartNum ].tail = 0; \
-               if ( uart_tx_buf[ uartNum ].head == uart_tx_buf[ uartNum ].tail ) \
-                       uart_tx_buf[ uartNum ].head++; \
-               if ( uart_tx_buf[ uartNum ].head >= UART_Buffer_Size ) \
-                       uart_tx_buf[ uartNum ].head = 0; \
-       } \
-       break
-
 // Macro for popping from Tx ring buffer
 #define uart_fillTxFifo( uartNum ) \
 { \
@@ -233,14 +205,41 @@ void Connect_addBytes( uint8_t *buffer, uint8_t count, uint8_t uart )
                return;
        }
 
-       // Choose the uart
-       switch ( uart )
+       // Invalid UART
+       if ( uart >= UART_Num_Interfaces )
        {
-       uart_addTxBuffer( UART_Master );
-       uart_addTxBuffer( UART_Slave );
-       default:
-               erro_msg("Invalid UART to send from...");
-               break;
+               erro_print("Invalid UART to send from...");
+               return;
+       }
+
+       // Delay UART copy until there's some space left
+       while ( uart_tx_buf[ uart ].items + count > UART_Buffer_Size )
+       {
+               warn_msg("Too much data to send on UART");
+               printInt8( uart );
+               print( ", waiting..." NL );
+               delay( 1 );
+       }
+
+       // Append data to ring buffer
+       for ( uint8_t c = 0; c < count; c++ )
+       {
+               if ( Connect_debug )
+               {
+                       printHex( buffer[ c ] );
+                       print(" +");
+                       printInt8( uart );
+                       print( NL );
+               }
+
+               uart_tx_buf[ uart ].buffer[ uart_tx_buf[ uart ].tail++ ] = buffer[ c ];
+               uart_tx_buf[ uart ].items++;
+               if ( uart_tx_buf[ uart ].tail >= UART_Buffer_Size )
+                       uart_tx_buf[ uart ].tail = 0;
+               if ( uart_tx_buf[ uart ].head == uart_tx_buf[ uart ].tail )
+                       uart_tx_buf[ uart ].head++;
+               if ( uart_tx_buf[ uart ].head >= UART_Buffer_Size )
+                       uart_tx_buf[ uart ].head = 0;
        }
 }
 
@@ -718,7 +717,7 @@ uint8_t Connect_receive_Animation( uint8_t byte, uint16_t *pending_bytes, uint8_
 }
 
 // - Remote Capability Variables -
-#define Connect_receive_RemoteCapabilityMaxArgs 5 // XXX Calculate the max using kll
+#define Connect_receive_RemoteCapabilityMaxArgs 25 // XXX Calculate the max using kll
 RemoteCapabilityCommand Connect_receive_RemoteCapabilityBuffer;
 uint8_t Connect_receive_RemoteCapabilityArgs[Connect_receive_RemoteCapabilityMaxArgs];