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 <led.h>
|
||||||
#include <print.h>
|
#include <print.h>
|
||||||
|
|
||||||
|
// Interconnect module if compiled in
|
||||||
|
#if defined(ConnectEnabled_define)
|
||||||
|
#include <connect_scan.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// Local Includes
|
// Local Includes
|
||||||
#include "led_scan.h"
|
#include "led_scan.h"
|
||||||
|
|
||||||
@ -37,6 +42,10 @@
|
|||||||
|
|
||||||
#define LED_BufferLength 144
|
#define LED_BufferLength 144
|
||||||
|
|
||||||
|
// TODO Needs to be defined per keyboard
|
||||||
|
#define LED_TotalChannels 144
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----- Structs -----
|
// ----- Structs -----
|
||||||
|
|
||||||
@ -656,28 +665,15 @@ typedef struct LedControl {
|
|||||||
uint16_t index;
|
uint16_t index;
|
||||||
} LedControl;
|
} LedControl;
|
||||||
|
|
||||||
uint8_t LED_control_timer = 0;
|
|
||||||
void LED_control( LedControl *control )
|
void LED_control( LedControl *control )
|
||||||
{
|
{
|
||||||
// Only send if we've completed all other transactions
|
// Only send if we've completed all other transactions
|
||||||
|
/*
|
||||||
if ( I2C_TxBuffer.sequencePos > 0 )
|
if ( I2C_TxBuffer.sequencePos > 0 )
|
||||||
return;
|
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
|
// Configure based upon the given mode
|
||||||
// TODO Handle multiple issi chips per node
|
|
||||||
// TODO Perhaps do gamma adjustment?
|
// TODO Perhaps do gamma adjustment?
|
||||||
switch ( control->mode )
|
switch ( control->mode )
|
||||||
{
|
{
|
||||||
@ -696,7 +692,7 @@ void LED_control( LedControl *control )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case LedControlMode_brightness_decrease_all:
|
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
|
// Don't worry about rolling over, the cycle is quick
|
||||||
LED_pageBuffer.buffer[ channel ] -= control->amount;
|
LED_pageBuffer.buffer[ channel ] -= control->amount;
|
||||||
@ -704,7 +700,7 @@ void LED_control( LedControl *control )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case LedControlMode_brightness_increase_all:
|
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
|
// Don't worry about rolling over, the cycle is quick
|
||||||
LED_pageBuffer.buffer[ channel ] += control->amount;
|
LED_pageBuffer.buffer[ channel ] += control->amount;
|
||||||
@ -712,7 +708,7 @@ void LED_control( LedControl *control )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case LedControlMode_brightness_set_all:
|
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_pageBuffer.buffer[ channel ] = control->amount;
|
||||||
}
|
}
|
||||||
@ -726,6 +722,7 @@ void LED_control( LedControl *control )
|
|||||||
LED_sendPage( (uint8_t*)&LED_pageBuffer, sizeof( LED_Buffer ), 0 );
|
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 )
|
void LED_control_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
||||||
{
|
{
|
||||||
// Display capability name
|
// 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
|
if ( stateType == 0x00 && state == 0x03 ) // Not on release
|
||||||
return;
|
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
|
// Set the input structure
|
||||||
LedControl *control = (LedControl*)args;
|
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 );
|
LED_control( control );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,34 +42,6 @@
|
|||||||
|
|
||||||
// ----- Macros -----
|
// ----- 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
|
// Macro for popping from Tx ring buffer
|
||||||
#define uart_fillTxFifo( uartNum ) \
|
#define uart_fillTxFifo( uartNum ) \
|
||||||
{ \
|
{ \
|
||||||
@ -233,14 +205,41 @@ void Connect_addBytes( uint8_t *buffer, uint8_t count, uint8_t uart )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Choose the uart
|
// Invalid UART
|
||||||
switch ( uart )
|
if ( uart >= UART_Num_Interfaces )
|
||||||
{
|
{
|
||||||
uart_addTxBuffer( UART_Master );
|
erro_print("Invalid UART to send from...");
|
||||||
uart_addTxBuffer( UART_Slave );
|
return;
|
||||||
default:
|
}
|
||||||
erro_msg("Invalid UART to send from...");
|
|
||||||
break;
|
// 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 -
|
// - 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;
|
RemoteCapabilityCommand Connect_receive_RemoteCapabilityBuffer;
|
||||||
uint8_t Connect_receive_RemoteCapabilityArgs[Connect_receive_RemoteCapabilityMaxArgs];
|
uint8_t Connect_receive_RemoteCapabilityArgs[Connect_receive_RemoteCapabilityMaxArgs];
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user