// Send a remote capability command using capability index // This may not be what's expected (especially if the firmware is not the same on each node) // To broadcast to all slave nodes, set id to 255 instead of a specific id void Connect_send_RemoteCapability( uint8_t id, uint8_t capabilityIndex, uint8_t state, uint8_t stateType, uint8_t numArgs, uint8_t *args ) { // Prepare header uint8_t header[] = { 0x16, 0x01, RemoteCapability, id, capabilityIndex, state, stateType, numArgs }; // Ignore current id if ( id == Connect_id ) return; // Send towards slave node if ( id > Connect_id ) { // Lock slave bound Tx uart_lockTx( UART_Slave ); // Send header Connect_addBytes( header, sizeof( header ), UART_Slave ); // Send arguments Connect_addBytes( args, numArgs, UART_Slave ); // Unlock Tx uart_unlockTx( UART_Slave ); } // Send towards master node if ( id < Connect_id || id == 255 ) { // Lock slave bound Tx uart_lockTx( UART_Master ); // Send header Connect_addBytes( header, sizeof( header ), UART_Master ); // Send arguments Connect_addBytes( args, numArgs, UART_Master ); // Unlock Tx uart_unlockTx( UART_Master ); } }
// id is the currently assigned id to the slave void Connect_send_IdReport( uint8_t id ) { // Lock master bound Tx uart_lockTx( UART_Master ); // Prepare header uint8_t header[] = { 0x16, 0x01, IdReport, id }; // Send header Connect_addBytes( header, sizeof( header ), UART_Master ); // Unlock Tx uart_unlockTx( UART_Master ); }
// id is the value the next slave should enumerate as void Connect_send_IdEnumeration( uint8_t id ) { // Lock slave bound Tx uart_lockTx( UART_Slave ); // Prepare header uint8_t header[] = { 0x16, 0x01, IdEnumeration, id }; // Send header Connect_addBytes( header, sizeof( header ), UART_Slave ); // Unlock Tx uart_unlockTx( UART_Slave ); }
void Connect_send_CurrentEvent( uint16_t current ) { // Lock master bound Tx uart_lockTx( UART_Slave ); // Prepare header uint8_t header[] = { 0x16, 0x01, CurrentEvent, current & 0xFF, (current >> 8) & 0xFF }; // Send header Connect_addBytes( header, sizeof( header ), UART_Slave ); // Unlock Tx uart_unlockTx( UART_Slave ); }
void Connect_send_IdRequest() { // Lock master bound Tx uart_lockTx( UART_Master ); // Prepare header uint8_t header[] = { Command_SYN, SOH, IdRequest }; // Send header Connect_addBytes( header, sizeof( header ), UART_Master ); // Unlock Tx uart_unlockTx( UART_Master ); }
// id is the currently assigned id to the slave // paramList is an array of [param, value]'s (8 bit values) // numParams is the number of params to parse from the array void Connect_send_Animation( uint8_t id, uint8_t *paramList, uint8_t numParams ) { // Lock slave bound Tx uart_lockTx( UART_Slave ); // Prepare header uint8_t header[] = { 0x16, 0x01, Animation, id, numParams }; // Send header Connect_addBytes( header, sizeof( header ), UART_Slave ); // Send each of the scan codes Connect_addBytes( paramList, numParams, UART_Slave ); // Unlock Tx uart_unlockTx( UART_Slave ); }
// id is the currently assigned id to the slave // scanCodeStateList is an array of [scancode, state]'s (8 bit values) // numScanCodes is the number of scan codes to parse from array void Connect_send_ScanCode( uint8_t id, TriggerGuide *scanCodeStateList, uint8_t numScanCodes ) { // Lock master bound Tx uart_lockTx( UART_Master ); // Prepare header uint8_t header[] = { 0x16, 0x01, ScanCode, id, numScanCodes }; // Send header Connect_addBytes( header, sizeof( header ), UART_Master ); // Send each of the scan codes Connect_addBytes( (uint8_t*)scanCodeStateList, numScanCodes * TriggerGuideSize, UART_Master ); // Unlock Tx uart_unlockTx( UART_Master ); }
uint8_t Connect_receive_RemoteCapability( uint8_t byte, uint16_t *pending_bytes, uint8_t uart_num ) { // Check which byte in the packet we are at switch ( (*pending_bytes)-- ) { // Byte count always starts at 0xFFFF case 0xFFFF: // Device Id Connect_receive_RemoteCapabilityBuffer.id = byte; break; case 0xFFFE: // Capability Index Connect_receive_RemoteCapabilityBuffer.capabilityIndex = byte; break; case 0xFFFD: // State Connect_receive_RemoteCapabilityBuffer.state = byte; break; case 0xFFFC: // StateType Connect_receive_RemoteCapabilityBuffer.stateType = byte; break; case 0xFFFB: // Number of args Connect_receive_RemoteCapabilityBuffer.numArgs = byte; *pending_bytes = byte; break; default: // Args (# defined by previous byte) Connect_receive_RemoteCapabilityArgs[ Connect_receive_RemoteCapabilityBuffer.numArgs - *pending_bytes + 1 ] = byte; // If entire packet has been fully received if ( *pending_bytes == 0 ) { // Determine if this is the node to run the capability on // Conditions: Matches or broadcast (0xFF) if ( Connect_receive_RemoteCapabilityBuffer.id == 0xFF || Connect_receive_RemoteCapabilityBuffer.id == Connect_id ) { extern const Capability CapabilitiesList[]; // See generatedKeymap.h void (*capability)(uint8_t, uint8_t, uint8_t*) = (void(*)(uint8_t, uint8_t, uint8_t*))( CapabilitiesList[ Connect_receive_RemoteCapabilityBuffer.capabilityIndex ].func ); capability( Connect_receive_RemoteCapabilityBuffer.state, Connect_receive_RemoteCapabilityBuffer.stateType, &Connect_receive_RemoteCapabilityArgs[2] ); } // If this is not the correct node, keep sending it in the same direction (doesn't matter if more nodes exist) // or if this is a broadcast if ( Connect_receive_RemoteCapabilityBuffer.id == 0xFF || Connect_receive_RemoteCapabilityBuffer.id != Connect_id ) { // Prepare outgoing packet Connect_receive_RemoteCapabilityBuffer.command = RemoteCapability; // Send to the other UART (not the one receiving the packet from uint8_t uart_direction = uart_num == UART_Master ? UART_Slave : UART_Master; // Lock Tx UART switch ( uart_direction ) { case UART_Master: uart_lockTx( UART_Master ); break; case UART_Slave: uart_lockTx( UART_Slave ); break; } // Send header uint8_t header[] = { 0x16, 0x01 }; Connect_addBytes( header, sizeof( header ), uart_direction ); // Send Remote Capability and arguments Connect_addBytes( (uint8_t*)&Connect_receive_RemoteCapabilityBuffer, sizeof( RemoteCapabilityCommand ), uart_direction ); Connect_addBytes( Connect_receive_RemoteCapabilityArgs, Connect_receive_RemoteCapabilityBuffer.numArgs, uart_direction ); // Unlock Tx UART switch ( uart_direction ) { case UART_Master: uart_unlockTx( UART_Master ); break; case UART_Slave: uart_unlockTx( UART_Slave ); break; } } } break; } // Check whether the scan codes have finished sending return *pending_bytes == 0 ? 1 : 0; }
uint8_t Connect_receive_ScanCode( uint8_t byte, uint16_t *pending_bytes, uint8_t uart_num ) { // Check the directionality if ( uart_num == UART_Master ) { erro_print("Invalid ScanCode direction..."); } // Master node, trigger scan codes if ( Connect_master ) switch ( (*pending_bytes)-- ) { // Byte count always starts at 0xFFFF case 0xFFFF: // Device Id Connect_receive_ScanCodeDeviceId = byte; break; case 0xFFFE: // Number of TriggerGuides in bytes (byte * 3) *pending_bytes = byte * sizeof( TriggerGuide ); Connect_receive_ScanCodeBufferPos = 0; break; default: // Set the specific TriggerGuide entry ((uint8_t*)&Connect_receive_ScanCodeBuffer)[ Connect_receive_ScanCodeBufferPos++ ] = byte; // Reset the BufferPos if higher than sizeof TriggerGuide // And send the TriggerGuide to the Macro Module if ( Connect_receive_ScanCodeBufferPos >= sizeof( TriggerGuide ) ) { Connect_receive_ScanCodeBufferPos = 0; // Adjust ScanCode offset if ( Connect_receive_ScanCodeDeviceId > 0 ) { // Check if this node is too large if ( Connect_receive_ScanCodeDeviceId >= InterconnectNodeMax ) { warn_msg("Not enough interconnect layout nodes configured: "); printHex( Connect_receive_ScanCodeDeviceId ); print( NL ); break; } // This variable is in generatedKeymaps.h extern uint8_t InterconnectOffsetList[]; Connect_receive_ScanCodeBuffer.scanCode = Connect_receive_ScanCodeBuffer.scanCode + InterconnectOffsetList[ Connect_receive_ScanCodeDeviceId - 1 ]; } // ScanCode receive debug if ( Connect_debug ) { dbug_msg(""); printHex( Connect_receive_ScanCodeBuffer.type ); print(" "); printHex( Connect_receive_ScanCodeBuffer.state ); print(" "); printHex( Connect_receive_ScanCodeBuffer.scanCode ); print( NL ); } // Send ScanCode to macro module Macro_interconnectAdd( &Connect_receive_ScanCodeBuffer ); } break; } // Propagate ScanCode packet // XXX It would be safer to buffer the scancodes first, before transmitting the packet -Jacob // The current method is the more efficient/aggressive, but could cause issues if there were errors during transmission else switch ( (*pending_bytes)-- ) { // Byte count always starts at 0xFFFF case 0xFFFF: // Device Id { Connect_receive_ScanCodeDeviceId = byte; // Lock the master Tx buffer uart_lockTx( UART_Master ); // Send header + Id byte uint8_t header[] = { 0x16, 0x01, ScanCode, byte }; Connect_addBytes( header, sizeof( header ), UART_Master ); break; } case 0xFFFE: // Number of TriggerGuides in bytes *pending_bytes = byte * sizeof( TriggerGuide ); Connect_receive_ScanCodeBufferPos = 0; // Pass through byte Connect_addBytes( &byte, 1, UART_Master ); break; default: // Pass through byte Connect_addBytes( &byte, 1, UART_Master ); // Unlock Tx Buffer after sending last byte if ( *pending_bytes == 0 ) uart_unlockTx( UART_Master ); break; } // Check whether the scan codes have finished sending return *pending_bytes == 0 ? 1 : 0; }