X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=Macro%2FPartialMap%2Fmacro.c;h=7161fbf9e495d92eb9ec5d6c42f50afae355555a;hb=51486bc4e16830c16c30f696b3a4f84c93a5baf8;hp=5f2cf77cea4b1abae6c01e2fc23ff73cf05a1939;hpb=2922fce0f72268b823226268ee9f64f165779621;p=kiibohd-controller.git diff --git a/Macro/PartialMap/macro.c b/Macro/PartialMap/macro.c index 5f2cf77..7161fbf 100644 --- a/Macro/PartialMap/macro.c +++ b/Macro/PartialMap/macro.c @@ -29,6 +29,11 @@ #include "usb_hid.h" #include // Generated using kll at compile time, in build directory +// Connect Includes +#if defined(ConnectEnabled_define) +#include +#endif + // Local Includes #include "macro.h" @@ -41,6 +46,7 @@ void cliFunc_capSelect ( char* args ); void cliFunc_keyHold ( char* args ); void cliFunc_keyPress ( char* args ); void cliFunc_keyRelease( char* args ); +void cliFunc_layerDebug( char* args ); void cliFunc_layerList ( char* args ); void cliFunc_layerState( char* args ); void cliFunc_macroDebug( char* args ); @@ -86,6 +92,7 @@ CLIDict_Entry( capSelect, "Triggers the specified capabilities. First two args CLIDict_Entry( keyHold, "Send key-hold events to the macro module. Duplicates have undefined behaviour." NL "\t\t\033[35mS10\033[0m Scancode 0x0A" ); CLIDict_Entry( keyPress, "Send key-press events to the macro module. Duplicates have undefined behaviour." NL "\t\t\033[35mS10\033[0m Scancode 0x0A" ); CLIDict_Entry( keyRelease, "Send key-release event to macro module. Duplicates have undefined behaviour." NL "\t\t\033[35mS10\033[0m Scancode 0x0A" ); +CLIDict_Entry( layerDebug, "Layer debug mode. Shows layer stack and any changes." ); CLIDict_Entry( layerList, "List available layers." ); CLIDict_Entry( layerState, "Modify specified indexed layer state ." NL "\t\t\033[35mL2\033[0m Indexed Layer 0x02" NL "\t\t0 Off, 1 Shift, 2 Latch, 4 Lock States" ); CLIDict_Entry( macroDebug, "Disables/Enables sending USB keycodes to the Output Module and prints U/K codes." ); @@ -100,6 +107,7 @@ CLIDict_Def( macroCLIDict, "Macro Module Commands" ) = { CLIDict_Item( keyHold ), CLIDict_Item( keyPress ), CLIDict_Item( keyRelease ), + CLIDict_Item( layerDebug ), CLIDict_Item( layerList ), CLIDict_Item( layerState ), CLIDict_Item( macroDebug ), @@ -111,6 +119,9 @@ CLIDict_Def( macroCLIDict, "Macro Module Commands" ) = { }; +// Layer debug flag - If set, displays any changes to layers and the full layer stack on change +uint8_t layerDebugMode = 0; + // Macro debug flag - If set, clears the USB Buffers after signalling processing completion uint8_t macroDebugMode = 0; @@ -145,6 +156,13 @@ uint16_t macroLayerIndexStackSize = 0; uint16_t macroResultMacroPendingList[ ResultMacroNum ] = { 0 }; uint16_t macroResultMacroPendingListSize = 0; +// Interconnect ScanCode Cache +#if defined(ConnectEnabled_define) +// TODO This can be shrunk by the size of the max node 0 ScanCode +TriggerGuide macroInterconnectCache[ MaxScanCode ]; +uint8_t macroInterconnectCacheSize = 0; +#endif + // ----- Capabilities ----- @@ -204,6 +222,30 @@ void Macro_layerState( uint8_t state, uint8_t stateType, uint16_t layer, uint8_t // Reduce LayerIndexStack size macroLayerIndexStackSize--; } + + // Layer Debug Mode + if ( layerDebugMode ) + { + dbug_msg("Layer "); + + // Iterate over each of the layers displaying the state as a hex value + for ( uint16_t index = 0; index < LayerNum; index++ ) + { + printHex_op( LayerState[ index ], 0 ); + } + + // Always show the default layer (it's always 0) + print(" 0"); + + // Iterate over the layer stack starting from the bottom of the stack + for ( uint16_t index = macroLayerIndexStackSize; index > 0; index-- ) + { + print(":"); + printHex_op( macroLayerIndexStack[ index - 1 ], 0 ); + } + + print( NL ); + } } // Modifies the specified Layer control byte @@ -332,7 +374,7 @@ nat_ptr_t *Macro_layerLookup( TriggerGuide *guide, uint8_t latch_expire ) } // If no trigger macro is defined at the given layer, fallthrough to the next layer - for ( uint16_t layerIndex = 0; layerIndex < macroLayerIndexStackSize; layerIndex++ ) + for ( uint16_t layerIndex = macroLayerIndexStackSize; layerIndex != 0xFFFF; layerIndex-- ) { // Lookup Layer const Layer *layer = &LayerIndex[ macroLayerIndexStack[ layerIndex ] ]; @@ -389,10 +431,82 @@ nat_ptr_t *Macro_layerLookup( TriggerGuide *guide, uint8_t latch_expire ) // Otherwise no defined Trigger Macro erro_msg("Scan Code has no defined Trigger Macro: "); printHex( scanCode ); + print( NL ); return 0; } +// Add an interconnect ScanCode +// These are handled differently (less information is sent, hold/off states must be assumed) +#if defined(ConnectEnabled_define) +inline void Macro_interconnectAdd( void *trigger_ptr ) +{ + TriggerGuide *trigger = (TriggerGuide*)trigger_ptr; + + // Error checking + uint8_t error = 0; + switch ( trigger->type ) + { + case 0x00: // Normal key + switch ( trigger->state ) + { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + break; + default: + erro_msg("Invalid key state - "); + error = 1; + break; + } + break; + + // Invalid TriggerGuide type + default: + erro_msg("Invalid type - "); + error = 1; + break; + } + + // Check if ScanCode is out of range + if ( trigger->scanCode > MaxScanCode ) + { + warn_msg("ScanCode is out of range/not defined - "); + error = 1; + } + + // Display TriggerGuide + if ( error ) + { + printHex( trigger->type ); + print(" "); + printHex( trigger->state ); + print(" "); + printHex( trigger->scanCode ); + print( NL ); + return; + } + + // Add trigger to the Interconnect Cache + // During each processing loop, a scancode may be re-added depending on it's state + for ( uint8_t c = 0; c < macroInterconnectCacheSize; c++ ) + { + // Check if the same ScanCode + if ( macroInterconnectCache[ c ].scanCode == trigger->scanCode ) + { + // Update the state + macroInterconnectCache[ c ].state = trigger->state; + return; + } + } + + // If not in the list, add it + macroInterconnectCache[ macroInterconnectCacheSize++ ] = *trigger; +} +#endif + + // Update the scancode key state // States: // * 0x00 - Off @@ -402,12 +516,35 @@ nat_ptr_t *Macro_layerLookup( TriggerGuide *guide, uint8_t latch_expire ) // * 0x04 - Unpressed (this is currently ignored) inline void Macro_keyState( uint8_t scanCode, uint8_t state ) { +#if defined(ConnectEnabled_define) + // Only compile in if a Connect node module is available + if ( !Connect_master ) + { + // ScanCodes are only added if there was a state change (on/off) + switch ( state ) + { + case 0x00: // Off + case 0x02: // Held + return; + } + } +#endif + // Only add to macro trigger list if one of three states switch ( state ) { case 0x01: // Pressed case 0x02: // Held case 0x03: // Released + // Check if ScanCode is out of range + if ( scanCode > MaxScanCode ) + { + warn_msg("ScanCode is out of range/not defined: "); + printHex( scanCode ); + print( NL ); + return; + } + macroTriggerListBuffer[ macroTriggerListBufferSize ].scanCode = scanCode; macroTriggerListBuffer[ macroTriggerListBufferSize ].state = state; macroTriggerListBuffer[ macroTriggerListBufferSize ].type = 0x00; // Normal key @@ -425,8 +562,18 @@ inline void Macro_keyState( uint8_t scanCode, uint8_t state ) inline void Macro_analogState( uint8_t scanCode, uint8_t state ) { // Only add to macro trigger list if non-off + // TODO Handle change for interconnect if ( state != 0x00 ) { + // Check if ScanCode is out of range + if ( scanCode > MaxScanCode ) + { + warn_msg("ScanCode is out of range/not defined: "); + printHex( scanCode ); + print( NL ); + return; + } + macroTriggerListBuffer[ macroTriggerListBufferSize ].scanCode = scanCode; macroTriggerListBuffer[ macroTriggerListBufferSize ].state = state; macroTriggerListBuffer[ macroTriggerListBufferSize ].type = 0x02; // Analog key @@ -442,8 +589,12 @@ inline void Macro_analogState( uint8_t scanCode, uint8_t state ) inline void Macro_ledState( uint8_t ledCode, uint8_t state ) { // Only add to macro trigger list if non-off + // TODO Handle change for interconnect if ( state != 0x00 ) { + // Check if LedCode is out of range + // TODO + macroTriggerListBuffer[ macroTriggerListBufferSize ].scanCode = ledCode; macroTriggerListBuffer[ macroTriggerListBufferSize ].state = state; macroTriggerListBuffer[ macroTriggerListBufferSize ].type = 0x01; // LED key @@ -862,6 +1013,10 @@ inline void Macro_updateTriggerMacroPendingList() // Lookup Trigger List nat_ptr_t *triggerList = Macro_layerLookup( ¯oTriggerListBuffer[ key ], latch_expire ); + // If there was an error during lookup, skip + if ( triggerList == 0 ) + continue; + // Number of Triggers in list nat_ptr_t triggerListSize = triggerList[0]; @@ -901,10 +1056,59 @@ inline void Macro_updateTriggerMacroPendingList() // Called once per USB buffer send inline void Macro_process() { +#if defined(ConnectEnabled_define) + // Only compile in if a Connect node module is available + // If this is a interconnect slave node, send all scancodes to master node + if ( !Connect_master ) + { + if ( macroTriggerListBufferSize > 0 ) + { + Connect_send_ScanCode( Connect_id, macroTriggerListBuffer, macroTriggerListBufferSize ); + macroTriggerListBufferSize = 0; + } + return; + } +#endif + // Only do one round of macro processing between Output Module timer sends if ( USBKeys_Sent != 0 ) return; +#if defined(ConnectEnabled_define) + // Check if there are any ScanCodes in the interconnect cache to process + if ( Connect_master && macroInterconnectCacheSize > 0 ) + { + // Iterate over all the cache ScanCodes + uint8_t currentInterconnectCacheSize = macroInterconnectCacheSize; + macroInterconnectCacheSize = 0; + for ( uint8_t c = 0; c < currentInterconnectCacheSize; c++ ) + { + // Add to the trigger list + macroTriggerListBuffer[ macroTriggerListBufferSize++ ] = macroInterconnectCache[ c ]; + + // TODO Handle other TriggerGuide types (e.g. analog) + switch ( macroInterconnectCache[ c ].type ) + { + // Normal (Press/Hold/Release) + case 0x00: + // Decide what to do based on the current state + switch ( macroInterconnectCache[ c ].state ) + { + // Re-add to interconnect cache in hold state + case 0x01: // Press + //case 0x02: // Hold // XXX Why does this not work? -HaaTa + macroInterconnectCache[ c ].state = 0x02; + macroInterconnectCache[ macroInterconnectCacheSize++ ] = macroInterconnectCache[ c ]; + break; + case 0x03: // Remove + break; + // Otherwise, do not re-add + } + } + } + } +#endif + // If the pause flag is set, only process if the step counter is non-zero if ( macroPauseMode ) { @@ -1194,6 +1398,16 @@ void cliFunc_keyRelease( char* args ) } } +void cliFunc_layerDebug( char *args ) +{ + // Toggle layer debug mode + layerDebugMode = layerDebugMode ? 0 : 1; + + print( NL ); + info_msg("Layer Debug Mode: "); + printInt8( layerDebugMode ); +} + void cliFunc_layerList( char* args ) { print( NL );