#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 -----
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 )
{
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;
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;
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;
}
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
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 );
}
// ----- 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 ) \
{ \
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;
}
}
}
// - 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];