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
This commit is contained in:
parent
7e68e81f47
commit
a10afbcc6a
@ -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 @@ 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 );
|
||||
}
|
||||
|
||||
|
@ -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 @@ 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];
|
||||
|
||||
|
Reference in New Issue
Block a user