# HG changeset patch # User Jacob Alexander # Date 1445014921 25200 # Node ID a3825c7fc651d09e7241899f2305469bb1c82d7d # Parent fc2c2a1e961516b6c9ca9a143b1eca68ee3822aa 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 diff -r fc2c2a1e9615 -r a3825c7fc651 Scan/ISSILed/led_scan.c --- a/Scan/ISSILed/led_scan.c Thu Oct 15 00:16:36 2015 -0700 +++ b/Scan/ISSILed/led_scan.c Fri Oct 16 10:02:01 2015 -0700 @@ -25,6 +25,11 @@ #include #include +// Interconnect module if compiled in +#if defined(ConnectEnabled_define) +#include +#endif + // Local Includes #include "led_scan.h" @@ -37,6 +42,10 @@ #define LED_BufferLength 144 +// TODO Needs to be defined per keyboard +#define LED_TotalChannels 144 + + // ----- Structs ----- @@ -656,28 +665,15 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 ); } diff -r fc2c2a1e9615 -r a3825c7fc651 Scan/UARTConnect/connect_scan.c --- a/Scan/UARTConnect/connect_scan.c Thu Oct 15 00:16:36 2015 -0700 +++ b/Scan/UARTConnect/connect_scan.c Fri Oct 16 10:02:01 2015 -0700 @@ -42,34 +42,6 @@ // ----- 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 @@ return; } - // Choose the uart - switch ( uart ) + // Invalid UART + if ( uart >= UART_Num_Interfaces ) + { + 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 ) { - uart_addTxBuffer( UART_Master ); - uart_addTxBuffer( UART_Slave ); - default: - erro_msg("Invalid UART to send from..."); - break; + 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 @@ } // - 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];