changeset 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 fc2c2a1e9615
children e85438377fe6
files Scan/ISSILed/led_scan.c Scan/UARTConnect/connect_scan.c
diffstat 2 files changed, 125 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- 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 <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"
 
@@ -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 );
 }
 
--- 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];