2016-05-09 01:50:28 +00:00
/* Copyright (C) 2014-2016 by Jacob Alexander
2014-04-06 18:49:27 +00:00
*
2014-06-23 03:45:56 +00:00
* This file is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
2014-04-06 18:49:27 +00:00
*
2014-06-23 03:45:56 +00:00
* This file is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
2014-04-06 18:49:27 +00:00
*
2014-06-23 03:45:56 +00:00
* You should have received a copy of the GNU General Public License
* along with this file . If not , see < http : //www.gnu.org/licenses/>.
2014-04-06 18:49:27 +00:00
*/
// ----- Includes -----
// Compiler Includes
# include <Lib/MacroLib.h>
// Project Includes
# include <cli.h>
# include <led.h>
# include <print.h>
# include <scan_loop.h>
// Keymaps
# include "usb_hid.h"
2014-09-14 22:51:36 +00:00
# include <generatedKeymap.h> // Generated using kll at compile time, in build directory
2014-04-06 18:49:27 +00:00
2015-08-09 07:20:41 +00:00
// Connect Includes
# if defined(ConnectEnabled_define)
# include <connect_scan.h>
# endif
2014-04-06 18:49:27 +00:00
// Local Includes
2016-05-09 01:50:28 +00:00
# include "trigger.h"
# include "result.h"
2014-04-06 18:49:27 +00:00
# include "macro.h"
// ----- Function Declarations -----
2014-07-25 05:22:35 +00:00
void cliFunc_capList ( char * args ) ;
void cliFunc_capSelect ( char * args ) ;
2014-08-15 17:42:12 +00:00
void cliFunc_keyHold ( char * args ) ;
2014-07-25 05:22:35 +00:00
void cliFunc_keyPress ( char * args ) ;
void cliFunc_keyRelease ( char * args ) ;
2015-06-20 03:14:37 +00:00
void cliFunc_layerDebug ( char * args ) ;
2014-07-25 05:22:35 +00:00
void cliFunc_layerList ( char * args ) ;
2014-07-26 19:20:59 +00:00
void cliFunc_layerState ( char * args ) ;
2014-07-25 05:22:35 +00:00
void cliFunc_macroDebug ( char * args ) ;
void cliFunc_macroList ( char * args ) ;
void cliFunc_macroProc ( char * args ) ;
void cliFunc_macroShow ( char * args ) ;
void cliFunc_macroStep ( char * args ) ;
2014-04-06 18:49:27 +00:00
// ----- Variables -----
2014-04-13 04:13:37 +00:00
// Macro Module command dictionary
2014-10-03 05:09:34 +00:00
CLIDict_Entry ( capList , " Prints an indexed list of all non USB keycode capabilities. " ) ;
CLIDict_Entry ( capSelect , " Triggers the specified capabilities. First two args are state and stateType. " NL " \t \t \033 [35mK11 \033 [0m Keyboard Capability 0x0B " ) ;
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 " ) ;
2015-06-20 03:14:37 +00:00
CLIDict_Entry ( layerDebug , " Layer debug mode. Shows layer stack and any changes. " ) ;
2014-10-03 05:09:34 +00:00
CLIDict_Entry ( layerList , " List available layers. " ) ;
CLIDict_Entry ( layerState , " Modify specified indexed layer state <layer> <state byte>. " NL " \t \t \033 [35mL2 \033 [0m Indexed Layer 0x02 " NL " \t \t 0 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. " ) ;
CLIDict_Entry ( macroList , " List the defined trigger and result macros. " ) ;
CLIDict_Entry ( macroProc , " Pause/Resume macro processing. " ) ;
CLIDict_Entry ( macroShow , " Show the macro corresponding to the given index. " NL " \t \t \033 [35mT16 \033 [0m Indexed Trigger Macro 0x10, \033 [35mR12 \033 [0m Indexed Result Macro 0x0C " ) ;
CLIDict_Entry ( macroStep , " Do N macro processing steps. Defaults to 1. " ) ;
CLIDict_Def ( macroCLIDict , " Macro Module Commands " ) = {
CLIDict_Item ( capList ) ,
CLIDict_Item ( capSelect ) ,
CLIDict_Item ( keyHold ) ,
CLIDict_Item ( keyPress ) ,
CLIDict_Item ( keyRelease ) ,
2015-06-20 03:14:37 +00:00
CLIDict_Item ( layerDebug ) ,
2014-10-03 05:09:34 +00:00
CLIDict_Item ( layerList ) ,
CLIDict_Item ( layerState ) ,
CLIDict_Item ( macroDebug ) ,
CLIDict_Item ( macroList ) ,
CLIDict_Item ( macroProc ) ,
CLIDict_Item ( macroShow ) ,
CLIDict_Item ( macroStep ) ,
2014-04-06 18:49:27 +00:00
{ 0 , 0 , 0 } // Null entry for dictionary end
} ;
2015-06-20 03:14:37 +00:00
// Layer debug flag - If set, displays any changes to layers and the full layer stack on change
uint8_t layerDebugMode = 0 ;
2014-04-06 20:12:31 +00:00
// Macro debug flag - If set, clears the USB Buffers after signalling processing completion
uint8_t macroDebugMode = 0 ;
2014-07-25 05:22:35 +00:00
// Macro pause flag - If set, the macro module pauses processing, unless unset, or the step counter is non-zero
uint8_t macroPauseMode = 0 ;
// Macro step counter - If non-zero, the step counter counts down every time the macro module does one processing loop
2014-09-11 18:17:17 +00:00
uint16_t macroStepCounter = 0 ;
2014-07-25 05:22:35 +00:00
2015-03-02 05:04:33 +00:00
// Key Trigger List Buffer and Layer Cache
// The layer cache is set on press only, hold and release events refer to the value set on press
2014-07-26 21:06:19 +00:00
TriggerGuide macroTriggerListBuffer [ MaxScanCode ] ;
2016-01-03 01:43:05 +00:00
var_uint_t macroTriggerListBufferSize = 0 ;
2015-03-02 05:04:33 +00:00
var_uint_t macroTriggerListLayerCache [ MaxScanCode ] ;
2014-06-23 03:45:56 +00:00
2014-07-26 21:06:19 +00:00
// Layer Index Stack
// * When modifying layer state and the state is non-0x0, the stack must be adjusted
2016-05-09 01:50:28 +00:00
index_uint_t macroLayerIndexStack [ LayerNum + 1 ] = { 0 } ;
index_uint_t macroLayerIndexStackSize = 0 ;
2014-07-26 21:06:19 +00:00
2016-05-09 01:50:28 +00:00
// TODO REMOVE when dependency no longer exists
extern index_uint_t macroResultMacroPendingList [ ] ;
extern index_uint_t macroResultMacroPendingListSize ;
extern index_uint_t macroTriggerMacroPendingList [ ] ;
extern index_uint_t macroTriggerMacroPendingListSize ;
2014-06-23 03:45:56 +00:00
2015-08-16 04:53:59 +00:00
// 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
2014-04-06 20:12:31 +00:00
2014-04-06 18:49:27 +00:00
2014-08-08 03:03:39 +00:00
// ----- Capabilities -----
2014-09-08 04:10:49 +00:00
// Sets the given layer with the specified layerState
void Macro_layerState ( uint8_t state , uint8_t stateType , uint16_t layer , uint8_t layerState )
2014-08-08 03:03:39 +00:00
{
2015-09-29 02:58:39 +00:00
// Ignore if layer does not exist or trying to manipulate layer 0/Default layer
if ( layer > = LayerNum | | layer = = 0 )
2014-10-15 17:39:39 +00:00
return ;
2014-08-08 03:03:39 +00:00
// Is layer in the LayerIndexStack?
uint8_t inLayerIndexStack = 0 ;
2014-09-11 18:17:17 +00:00
uint16_t stackItem = 0 ;
2014-08-08 03:03:39 +00:00
while ( stackItem < macroLayerIndexStackSize )
{
// Flag if layer is already in the LayerIndexStack
if ( macroLayerIndexStack [ stackItem ] = = layer )
{
inLayerIndexStack = 1 ;
break ;
}
// Increment to next item
stackItem + + ;
}
// Toggle Layer State Byte
2014-09-17 00:04:59 +00:00
if ( LayerState [ layer ] & layerState )
2014-08-08 03:03:39 +00:00
{
// Unset
2014-09-17 00:04:59 +00:00
LayerState [ layer ] & = ~ layerState ;
2014-08-08 03:03:39 +00:00
}
else
{
// Set
2014-09-17 00:04:59 +00:00
LayerState [ layer ] | = layerState ;
2014-08-08 03:03:39 +00:00
}
// If the layer was not in the LayerIndexStack add it
if ( ! inLayerIndexStack )
{
macroLayerIndexStack [ macroLayerIndexStackSize + + ] = layer ;
}
// If the layer is in the LayerIndexStack and the state is 0x00, remove
2014-09-17 00:04:59 +00:00
if ( LayerState [ layer ] = = 0x00 & & inLayerIndexStack )
2014-08-08 03:03:39 +00:00
{
// Remove the layer from the LayerIndexStack
// Using the already positioned stackItem variable from the loop above
while ( stackItem < macroLayerIndexStackSize )
{
macroLayerIndexStack [ stackItem ] = macroLayerIndexStack [ stackItem + 1 ] ;
stackItem + + ;
}
// Reduce LayerIndexStack size
macroLayerIndexStackSize - - ;
}
2015-06-20 03:14:37 +00:00
// Layer Debug Mode
if ( layerDebugMode )
{
dbug_msg ( " Layer " ) ;
// Iterate over each of the layers displaying the state as a hex value
2016-05-09 01:50:28 +00:00
for ( index_uint_t index = 0 ; index < LayerNum ; index + + )
2015-06-20 03:14:37 +00:00
{
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
2016-05-09 01:50:28 +00:00
for ( index_uint_t index = macroLayerIndexStackSize ; index > 0 ; index - - )
2015-06-20 03:14:37 +00:00
{
print ( " : " ) ;
2015-06-23 14:58:31 +00:00
printHex_op ( macroLayerIndexStack [ index - 1 ] , 0 ) ;
2015-06-20 03:14:37 +00:00
}
print ( NL ) ;
}
2014-08-08 03:03:39 +00:00
}
2014-09-08 04:10:49 +00:00
// Modifies the specified Layer control byte
// Argument #1: Layer Index -> uint16_t
// Argument #2: Layer State -> uint8_t
void Macro_layerState_capability ( uint8_t state , uint8_t stateType , uint8_t * args )
{
// Display capability name
if ( stateType = = 0xFF & & state = = 0xFF )
{
print ( " Macro_layerState(layerIndex,layerState) " ) ;
return ;
}
2014-09-11 03:53:30 +00:00
// Only use capability on press or release
// TODO Analog
// XXX This may cause issues, might be better to implement state table here to decide -HaaTa
if ( stateType = = 0x00 & & state = = 0x02 ) // Hold condition
return ;
2014-09-08 04:10:49 +00:00
// Get layer index from arguments
2014-09-11 18:17:17 +00:00
// Cast pointer to uint8_t to uint16_t then access that memory location
2014-09-08 04:10:49 +00:00
uint16_t layer = * ( uint16_t * ) ( & args [ 0 ] ) ;
// Get layer toggle byte
uint8_t layerState = args [ sizeof ( uint16_t ) ] ;
Macro_layerState ( state , stateType , layer , layerState ) ;
}
// Latches given layer
// Argument #1: Layer Index -> uint16_t
void Macro_layerLatch_capability ( uint8_t state , uint8_t stateType , uint8_t * args )
{
// Display capability name
if ( stateType = = 0xFF & & state = = 0xFF )
{
print ( " Macro_layerLatch(layerIndex) " ) ;
return ;
}
2014-09-11 03:53:30 +00:00
// Only use capability on press
// TODO Analog
2014-11-13 08:49:02 +00:00
if ( stateType = = 0x00 & & state ! = 0x03 ) // Only on release
2014-09-11 03:53:30 +00:00
return ;
2014-09-08 04:10:49 +00:00
// Get layer index from arguments
2014-09-11 18:17:17 +00:00
// Cast pointer to uint8_t to uint16_t then access that memory location
2014-09-08 04:10:49 +00:00
uint16_t layer = * ( uint16_t * ) ( & args [ 0 ] ) ;
Macro_layerState ( state , stateType , layer , 0x02 ) ;
}
// Locks given layer
// Argument #1: Layer Index -> uint16_t
void Macro_layerLock_capability ( uint8_t state , uint8_t stateType , uint8_t * args )
{
// Display capability name
if ( stateType = = 0xFF & & state = = 0xFF )
{
print ( " Macro_layerLock(layerIndex) " ) ;
return ;
}
2014-09-11 03:53:30 +00:00
// Only use capability on press
// TODO Analog
// XXX Could also be on release, but that's sorta dumb -HaaTa
if ( stateType = = 0x00 & & state ! = 0x01 ) // All normal key conditions except press
return ;
2014-09-08 04:10:49 +00:00
// Get layer index from arguments
2014-09-11 18:17:17 +00:00
// Cast pointer to uint8_t to uint16_t then access that memory location
2014-09-08 04:10:49 +00:00
uint16_t layer = * ( uint16_t * ) ( & args [ 0 ] ) ;
Macro_layerState ( state , stateType , layer , 0x04 ) ;
}
// Shifts given layer
// Argument #1: Layer Index -> uint16_t
void Macro_layerShift_capability ( uint8_t state , uint8_t stateType , uint8_t * args )
{
// Display capability name
if ( stateType = = 0xFF & & state = = 0xFF )
{
print ( " Macro_layerShift(layerIndex) " ) ;
return ;
}
2014-09-11 03:53:30 +00:00
// Only use capability on press or release
// TODO Analog
if ( stateType = = 0x00 & & ( state = = 0x00 | | state = = 0x02 ) ) // Only pass press or release conditions
return ;
2014-09-08 04:10:49 +00:00
// Get layer index from arguments
2014-09-11 18:17:17 +00:00
// Cast pointer to uint8_t to uint16_t then access that memory location
2014-09-08 04:10:49 +00:00
uint16_t layer = * ( uint16_t * ) ( & args [ 0 ] ) ;
Macro_layerState ( state , stateType , layer , 0x01 ) ;
}
2014-08-08 03:03:39 +00:00
2015-09-29 02:58:39 +00:00
// Rotate layer to next/previous
// Uses state variable to keep track of the current layer position
// Layers are still evaluated using the layer stack
uint16_t Macro_rotationLayer ;
void Macro_layerRotate_capability ( uint8_t state , uint8_t stateType , uint8_t * args )
{
// Display capability name
if ( stateType = = 0xFF & & state = = 0xFF )
{
print ( " Macro_layerRotate(previous) " ) ;
return ;
}
// Only use capability on press
// TODO Analog
// XXX Could also be on release, but that's sorta dumb -HaaTa
if ( stateType = = 0x00 & & state ! = 0x01 ) // All normal key conditions except press
return ;
// Unset previous rotation layer if not 0
if ( Macro_rotationLayer ! = 0 )
{
Macro_layerState ( state , stateType , Macro_rotationLayer , 0x04 ) ;
}
// Get direction of rotation, 0, next, non-zero previous
uint8_t direction = * args ;
// Next
if ( ! direction )
{
Macro_rotationLayer + + ;
// Invalid layer
if ( Macro_rotationLayer > = LayerNum )
Macro_rotationLayer = 0 ;
}
// Previous
else
{
Macro_rotationLayer - - ;
// Layer wrap
if ( Macro_rotationLayer > = LayerNum )
Macro_rotationLayer = LayerNum - 1 ;
}
// Toggle the computed layer rotation
Macro_layerState ( state , stateType , Macro_rotationLayer , 0x04 ) ;
}
2014-08-08 03:03:39 +00:00
2014-04-06 18:49:27 +00:00
// ----- Functions -----
2014-06-23 03:45:56 +00:00
// Looks up the trigger list for the given scan code (from the active layer)
2014-07-26 21:06:19 +00:00
// NOTE: Calling function must handle the NULL pointer case
2015-03-02 05:04:33 +00:00
nat_ptr_t * Macro_layerLookup ( TriggerGuide * guide , uint8_t latch_expire )
2014-06-14 18:00:29 +00:00
{
2015-03-02 05:04:33 +00:00
uint8_t scanCode = guide - > scanCode ;
// TODO Analog
// If a normal key, and not pressed, do a layer cache lookup
if ( guide - > type = = 0x00 & & guide - > state ! = 0x01 )
{
// Cached layer
var_uint_t cachedLayer = macroTriggerListLayerCache [ scanCode ] ;
// Lookup map, then layer
nat_ptr_t * * map = ( nat_ptr_t * * ) LayerIndex [ cachedLayer ] . triggerMap ;
const Layer * layer = & LayerIndex [ cachedLayer ] ;
2015-10-04 23:19:20 +00:00
// Cache trigger list before attempting to expire latch
nat_ptr_t * trigger_list = map [ scanCode - layer - > first ] ;
// Check if latch has been pressed for this layer
uint8_t latch = LayerState [ cachedLayer ] & 0x02 ;
if ( latch & & latch_expire )
{
Macro_layerState ( 0 , 0 , cachedLayer , 0x02 ) ;
# if defined(ConnectEnabled_define) && defined(LCDEnabled_define)
// Evaluate the layerStack capability if available (LCD + Interconnect)
extern void LCD_layerStack_capability ( uint8_t state , uint8_t stateType , uint8_t * args ) ;
LCD_layerStack_capability ( 0 , 0 , 0 ) ;
# endif
}
return trigger_list ;
2015-03-02 05:04:33 +00:00
}
2014-07-26 21:06:19 +00:00
// If no trigger macro is defined at the given layer, fallthrough to the next layer
2015-08-22 03:33:47 +00:00
for ( uint16_t layerIndex = macroLayerIndexStackSize ; layerIndex ! = 0xFFFF ; layerIndex - - )
2014-07-26 21:06:19 +00:00
{
2014-08-08 03:03:39 +00:00
// Lookup Layer
2014-09-17 00:04:59 +00:00
const Layer * layer = & LayerIndex [ macroLayerIndexStack [ layerIndex ] ] ;
2014-07-26 21:06:19 +00:00
2014-08-08 03:03:39 +00:00
// Check if latch has been pressed for this layer
// XXX Regardless of whether a key is found, the latch is removed on first lookup
2014-11-13 08:49:02 +00:00
uint8_t latch = LayerState [ macroLayerIndexStack [ layerIndex ] ] & 0x02 ;
if ( latch & & latch_expire )
2014-08-08 03:03:39 +00:00
{
2014-11-13 08:49:02 +00:00
Macro_layerState ( 0 , 0 , macroLayerIndexStack [ layerIndex ] , 0x02 ) ;
2014-08-08 03:03:39 +00:00
}
// Only use layer, if state is valid
// XOR each of the state bits
// If only two are enabled, do not use this state
2014-09-17 05:14:01 +00:00
if ( ( LayerState [ macroLayerIndexStack [ layerIndex ] ] & 0x01 ) ^ ( latch > > 1 ) ^ ( ( LayerState [ macroLayerIndexStack [ layerIndex ] ] & 0x04 ) > > 2 ) )
2014-08-08 03:03:39 +00:00
{
// Lookup layer
2014-09-11 17:54:50 +00:00
nat_ptr_t * * map = ( nat_ptr_t * * ) layer - > triggerMap ;
2014-08-08 03:03:39 +00:00
// Determine if layer has key defined
2014-09-17 00:04:59 +00:00
// Make sure scanCode is between layer first and last scancodes
if ( map ! = 0
2015-09-29 02:58:39 +00:00
& & scanCode < = layer - > last
& & scanCode > = layer - > first
& & * map [ scanCode - layer - > first ] ! = 0 )
2014-09-17 00:04:59 +00:00
{
2015-03-02 05:04:33 +00:00
// Set the layer cache
macroTriggerListLayerCache [ scanCode ] = macroLayerIndexStack [ layerIndex ] ;
2014-09-17 00:04:59 +00:00
return map [ scanCode - layer - > first ] ;
}
2014-08-08 03:03:39 +00:00
}
2014-07-26 21:06:19 +00:00
}
// Do lookup on default layer
2014-09-11 17:54:50 +00:00
nat_ptr_t * * map = ( nat_ptr_t * * ) LayerIndex [ 0 ] . triggerMap ;
2014-07-26 21:06:19 +00:00
2014-09-17 00:04:59 +00:00
// Lookup default layer
2014-09-17 05:14:01 +00:00
const Layer * layer = & LayerIndex [ 0 ] ;
2014-09-17 00:04:59 +00:00
// Make sure scanCode is between layer first and last scancodes
if ( map ! = 0
2015-09-29 02:58:39 +00:00
& & scanCode < = layer - > last
& & scanCode > = layer - > first
& & * map [ scanCode - layer - > first ] ! = 0 )
2014-07-26 21:06:19 +00:00
{
2015-03-02 05:04:33 +00:00
// Set the layer cache to default map
macroTriggerListLayerCache [ scanCode ] = 0 ;
2014-09-17 00:04:59 +00:00
return map [ scanCode - layer - > first ] ;
2014-07-26 21:06:19 +00:00
}
2014-09-17 00:04:59 +00:00
// Otherwise no defined Trigger Macro
erro_msg ( " Scan Code has no defined Trigger Macro: " ) ;
printHex ( scanCode ) ;
2015-08-16 04:53:59 +00:00
print ( NL ) ;
2014-09-17 00:04:59 +00:00
return 0 ;
2014-06-14 18:00:29 +00:00
}
2015-08-16 04:53:59 +00:00
// 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 )
2015-03-15 23:58:01 +00:00
{
2015-08-16 04:53:59 +00:00
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 :
2015-08-16 19:27:12 +00:00
erro_msg ( " Invalid key state - " ) ;
2015-08-16 04:53:59 +00:00
error = 1 ;
break ;
}
break ;
// Invalid TriggerGuide type
default :
2015-08-16 19:27:12 +00:00
erro_msg ( " Invalid type - " ) ;
2015-08-16 04:53:59 +00:00
error = 1 ;
break ;
}
2015-08-16 19:27:12 +00:00
// Check if ScanCode is out of range
2015-08-16 22:53:07 +00:00
if ( trigger - > scanCode > MaxScanCode )
2015-08-16 19:27:12 +00:00
{
warn_msg ( " ScanCode is out of range/not defined - " ) ;
error = 1 ;
}
2015-08-16 04:53:59 +00:00
// 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
2016-01-03 01:43:05 +00:00
for ( var_uint_t c = 0 ; c < macroInterconnectCacheSize ; c + + )
2015-08-16 04:53:59 +00:00
{
// 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 ;
2015-03-15 23:58:01 +00:00
}
2015-08-16 04:53:59 +00:00
# endif
2015-03-15 23:58:01 +00:00
2014-06-23 03:45:56 +00:00
// Update the scancode key state
// States:
2014-07-26 21:06:19 +00:00
// * 0x00 - Off
2014-06-23 03:45:56 +00:00
// * 0x01 - Pressed
// * 0x02 - Held
// * 0x03 - Released
// * 0x04 - Unpressed (this is currently ignored)
inline void Macro_keyState ( uint8_t scanCode , uint8_t state )
2014-06-14 18:00:29 +00:00
{
2015-08-16 04:53:59 +00:00
# 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
2014-06-23 03:45:56 +00:00
// Only add to macro trigger list if one of three states
switch ( state )
{
case 0x01 : // Pressed
case 0x02 : // Held
case 0x03 : // Released
2015-08-16 19:27:12 +00:00
// Check if ScanCode is out of range
if ( scanCode > MaxScanCode )
{
warn_msg ( " ScanCode is out of range/not defined: " ) ;
printHex ( scanCode ) ;
print ( NL ) ;
return ;
}
2014-07-26 21:06:19 +00:00
macroTriggerListBuffer [ macroTriggerListBufferSize ] . scanCode = scanCode ;
macroTriggerListBuffer [ macroTriggerListBufferSize ] . state = state ;
macroTriggerListBuffer [ macroTriggerListBufferSize ] . type = 0x00 ; // Normal key
macroTriggerListBufferSize + + ;
2014-06-23 03:45:56 +00:00
break ;
}
2014-06-14 18:00:29 +00:00
}
2014-06-23 03:45:56 +00:00
// Update the scancode analog state
// States:
2014-07-26 21:06:19 +00:00
// * 0x00 - Off
2014-06-23 03:45:56 +00:00
// * 0x01 - Released
// * 0x02-0xFF - Analog value (low to high)
inline void Macro_analogState ( uint8_t scanCode , uint8_t state )
{
2014-07-26 21:06:19 +00:00
// Only add to macro trigger list if non-off
2015-08-16 04:53:59 +00:00
// TODO Handle change for interconnect
2014-07-26 21:06:19 +00:00
if ( state ! = 0x00 )
{
2015-08-16 19:27:12 +00:00
// Check if ScanCode is out of range
if ( scanCode > MaxScanCode )
{
warn_msg ( " ScanCode is out of range/not defined: " ) ;
printHex ( scanCode ) ;
print ( NL ) ;
return ;
}
2014-07-26 21:06:19 +00:00
macroTriggerListBuffer [ macroTriggerListBufferSize ] . scanCode = scanCode ;
macroTriggerListBuffer [ macroTriggerListBufferSize ] . state = state ;
macroTriggerListBuffer [ macroTriggerListBufferSize ] . type = 0x02 ; // Analog key
macroTriggerListBufferSize + + ;
}
2014-06-23 03:45:56 +00:00
}
2014-06-14 18:00:29 +00:00
2014-06-23 03:45:56 +00:00
// Update led state
// States:
2014-07-26 21:06:19 +00:00
// * 0x00 - Off
2014-06-23 03:45:56 +00:00
// * 0x01 - On
inline void Macro_ledState ( uint8_t ledCode , uint8_t state )
{
2014-07-26 21:06:19 +00:00
// Only add to macro trigger list if non-off
2015-08-16 04:53:59 +00:00
// TODO Handle change for interconnect
2014-07-26 21:06:19 +00:00
if ( state ! = 0x00 )
{
2015-08-16 19:27:12 +00:00
// Check if LedCode is out of range
// TODO
2014-07-26 21:06:19 +00:00
macroTriggerListBuffer [ macroTriggerListBufferSize ] . scanCode = ledCode ;
macroTriggerListBuffer [ macroTriggerListBufferSize ] . state = state ;
macroTriggerListBuffer [ macroTriggerListBufferSize ] . type = 0x01 ; // LED key
macroTriggerListBufferSize + + ;
}
2014-06-23 03:45:56 +00:00
}
2014-06-14 18:00:29 +00:00
2014-08-05 18:33:55 +00:00
// Append result macro to pending list, checking for duplicates
// Do nothing if duplicate
2016-05-09 01:50:28 +00:00
void Macro_appendResultMacroToPendingList ( const TriggerMacro * triggerMacro )
2014-08-05 18:33:55 +00:00
{
2014-08-20 17:53:22 +00:00
// Lookup result macro index
2014-09-11 18:17:17 +00:00
var_uint_t resultMacroIndex = triggerMacro - > result ;
2014-08-20 17:53:22 +00:00
2014-08-05 18:33:55 +00:00
// Iterate through result macro pending list, making sure this macro hasn't been added yet
2014-09-11 18:17:17 +00:00
for ( var_uint_t macro = 0 ; macro < macroResultMacroPendingListSize ; macro + + )
2014-08-05 18:33:55 +00:00
{
// If duplicate found, do nothing
if ( macroResultMacroPendingList [ macro ] = = resultMacroIndex )
return ;
}
// No duplicates found, add to pending list
macroResultMacroPendingList [ macroResultMacroPendingListSize + + ] = resultMacroIndex ;
2014-08-20 17:53:22 +00:00
// Lookup scanCode of the last key in the last combo
2014-09-11 18:17:17 +00:00
var_uint_t pos = 0 ;
2014-08-20 17:53:22 +00:00
for ( uint8_t comboLength = triggerMacro - > guide [ 0 ] ; comboLength > 0 ; )
{
pos + = TriggerGuideSize * comboLength + 1 ;
comboLength = triggerMacro - > guide [ pos ] ;
}
uint8_t scanCode = ( ( TriggerGuide * ) & triggerMacro - > guide [ pos - TriggerGuideSize ] ) - > scanCode ;
// Lookup scanCode in buffer list for the current state and stateType
2016-01-03 01:43:05 +00:00
for ( var_uint_t keyIndex = 0 ; keyIndex < macroTriggerListBufferSize ; keyIndex + + )
2014-08-20 17:53:22 +00:00
{
if ( macroTriggerListBuffer [ keyIndex ] . scanCode = = scanCode )
{
2014-09-17 06:29:21 +00:00
ResultMacroRecordList [ resultMacroIndex ] . state = macroTriggerListBuffer [ keyIndex ] . state ;
ResultMacroRecordList [ resultMacroIndex ] . stateType = macroTriggerListBuffer [ keyIndex ] . type ;
2014-08-20 17:53:22 +00:00
}
}
// Reset the macro position
2014-09-17 06:29:21 +00:00
ResultMacroRecordList [ resultMacroIndex ] . pos = 0 ;
2014-08-05 18:33:55 +00:00
}
2014-07-28 06:15:41 +00:00
// Macro Procesing Loop
// Called once per USB buffer send
2014-04-06 18:49:27 +00:00
inline void Macro_process ( )
{
2015-08-09 07:20:41 +00:00
# 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 )
{
2015-08-16 04:53:59 +00:00
Connect_send_ScanCode ( Connect_id , macroTriggerListBuffer , macroTriggerListBufferSize ) ;
2015-08-09 07:20:41 +00:00
macroTriggerListBufferSize = 0 ;
}
return ;
}
# endif
2014-04-06 18:49:27 +00:00
// Only do one round of macro processing between Output Module timer sends
if ( USBKeys_Sent ! = 0 )
return ;
2015-08-16 04:53:59 +00:00
# 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
2014-07-25 05:22:35 +00:00
// If the pause flag is set, only process if the step counter is non-zero
2014-08-05 18:33:55 +00:00
if ( macroPauseMode )
2014-07-25 05:22:35 +00:00
{
2014-08-05 18:33:55 +00:00
if ( macroStepCounter = = 0 )
return ;
// Proceed, decrementing the step counter
2014-07-25 05:22:35 +00:00
macroStepCounter - - ;
2014-08-15 17:42:12 +00:00
dbug_print ( " Macro Step " ) ;
2014-07-25 05:22:35 +00:00
}
2016-05-09 01:50:28 +00:00
// Process Trigger Macros
Trigger_process ( ) ;
2014-06-23 03:45:56 +00:00
2016-05-09 01:50:28 +00:00
// Process result macros
Result_process ( ) ;
2014-08-06 19:18:06 +00:00
// Signal buffer that we've used it
Scan_finishedWithMacro ( macroTriggerListBufferSize ) ;
// Reset TriggerList buffer
macroTriggerListBufferSize = 0 ;
2014-04-06 20:12:31 +00:00
// If Macro debug mode is set, clear the USB Buffer
if ( macroDebugMode )
{
USBKeys_Modifiers = 0 ;
USBKeys_Sent = 0 ;
}
2014-04-06 18:49:27 +00:00
}
2014-07-28 06:15:41 +00:00
2014-04-06 18:49:27 +00:00
inline void Macro_setup ( )
{
// Register Macro CLI dictionary
CLI_registerDictionary ( macroCLIDict , macroCLIDictName ) ;
2014-04-06 20:12:31 +00:00
// Disable Macro debug mode
macroDebugMode = 0 ;
2014-06-23 03:45:56 +00:00
2014-07-25 05:22:35 +00:00
// Disable Macro pause flag
macroPauseMode = 0 ;
// Set Macro step counter to zero
macroStepCounter = 0 ;
2014-06-23 03:45:56 +00:00
// Make sure macro trigger buffer is empty
macroTriggerListBufferSize = 0 ;
2014-08-05 18:33:55 +00:00
2015-09-29 02:58:39 +00:00
// Set the current rotated layer to 0
Macro_rotationLayer = 0 ;
2016-05-09 01:50:28 +00:00
// Setup Triggers
Trigger_setup ( ) ;
2014-08-05 18:33:55 +00:00
2016-05-09 01:50:28 +00:00
// Setup Results
Result_setup ( ) ;
2014-04-06 18:49:27 +00:00
}
// ----- CLI Command Functions -----
void cliFunc_capList ( char * args )
{
2014-07-25 06:18:38 +00:00
print ( NL ) ;
2015-01-25 20:49:23 +00:00
info_msg ( " Capabilities List " ) ;
2014-08-15 17:42:12 +00:00
printHex ( CapabilitiesNum ) ;
2014-07-25 06:18:38 +00:00
// Iterate through all of the capabilities and display them
2014-09-11 18:17:17 +00:00
for ( var_uint_t cap = 0 ; cap < CapabilitiesNum ; cap + + )
2014-07-25 06:18:38 +00:00
{
print ( NL " \t " ) ;
printHex ( cap ) ;
print ( " - " ) ;
// Display/Lookup Capability Name (utilize debug mode of capability)
2014-07-25 17:53:33 +00:00
void ( * capability ) ( uint8_t , uint8_t , uint8_t * ) = ( void ( * ) ( uint8_t , uint8_t , uint8_t * ) ) ( CapabilitiesList [ cap ] . func ) ;
2014-07-25 06:18:38 +00:00
capability ( 0xFF , 0xFF , 0 ) ;
}
2014-04-06 18:49:27 +00:00
}
void cliFunc_capSelect ( char * args )
{
2014-04-06 20:12:31 +00:00
// Parse code from argument
2014-07-25 17:53:33 +00:00
char * curArgs ;
2014-04-06 20:12:31 +00:00
char * arg1Ptr ;
2014-07-25 17:53:33 +00:00
char * arg2Ptr = args ;
// Total number of args to scan (must do a lookup if a keyboard capability is selected)
2014-09-11 18:17:17 +00:00
var_uint_t totalArgs = 2 ; // Always at least two args
var_uint_t cap = 0 ;
2014-04-06 20:12:31 +00:00
2014-07-25 17:53:33 +00:00
// Arguments used for keyboard capability function
2014-09-11 18:17:17 +00:00
var_uint_t argSetCount = 0 ;
2014-07-25 17:53:33 +00:00
uint8_t * argSet = ( uint8_t * ) args ;
// Process all args
2014-09-11 18:17:17 +00:00
for ( var_uint_t c = 0 ; argSetCount < totalArgs ; c + + )
2014-04-06 20:12:31 +00:00
{
2014-07-25 17:53:33 +00:00
curArgs = arg2Ptr ;
CLI_argumentIsolation ( curArgs , & arg1Ptr , & arg2Ptr ) ;
2014-04-06 20:12:31 +00:00
2014-07-25 17:53:33 +00:00
// Stop processing args if no more are found
// Extra arguments are ignored
if ( * arg1Ptr = = ' \0 ' )
break ;
// For the first argument, choose the capability
if ( c = = 0 ) switch ( arg1Ptr [ 0 ] )
2014-04-06 20:12:31 +00:00
{
2014-07-25 17:53:33 +00:00
// Keyboard Capability
case ' K ' :
// Determine capability index
2014-08-16 19:07:25 +00:00
cap = numToInt ( & arg1Ptr [ 1 ] ) ;
2014-07-25 17:53:33 +00:00
// Lookup the number of args
totalArgs + = CapabilitiesList [ cap ] . argCount ;
continue ;
}
// Because allocating memory isn't doable, and the argument count is arbitrary
// The argument pointer is repurposed as the argument list (much smaller anyways)
2014-08-16 19:07:25 +00:00
argSet [ argSetCount + + ] = ( uint8_t ) numToInt ( arg1Ptr ) ;
2014-07-25 17:53:33 +00:00
// Once all the arguments are prepared, call the keyboard capability function
if ( argSetCount = = totalArgs )
{
// Indicate that the capability was called
print ( NL ) ;
info_msg ( " K " ) ;
printInt8 ( cap ) ;
print ( " - " ) ;
printHex ( argSet [ 0 ] ) ;
print ( " - " ) ;
printHex ( argSet [ 1 ] ) ;
print ( " - " ) ;
printHex ( argSet [ 2 ] ) ;
print ( " ... " NL ) ;
2015-10-12 05:07:11 +00:00
// Make sure this isn't the reload capability
// If it is, and the remote reflash define is not set, ignore
if ( flashModeEnabled_define = = 0 ) for ( uint32_t cap = 0 ; cap < CapabilitiesNum ; cap + + )
{
if ( CapabilitiesList [ cap ] . func = = ( const void * ) Output_flashMode_capability )
{
print ( NL ) ;
warn_print ( " flashModeEnabled not set, cancelling firmware reload... " ) ;
info_msg ( " Set flashModeEnabled to 1 in your kll configuration. " ) ;
return ;
}
}
2014-07-25 17:53:33 +00:00
void ( * capability ) ( uint8_t , uint8_t , uint8_t * ) = ( void ( * ) ( uint8_t , uint8_t , uint8_t * ) ) ( CapabilitiesList [ cap ] . func ) ;
capability ( argSet [ 0 ] , argSet [ 1 ] , & argSet [ 2 ] ) ;
2014-04-06 20:12:31 +00:00
}
}
2014-04-06 18:49:27 +00:00
}
2014-08-15 17:42:12 +00:00
void cliFunc_keyHold ( char * args )
{
// Parse codes from arguments
char * curArgs ;
char * arg1Ptr ;
char * arg2Ptr = args ;
// Process all args
for ( ; ; )
{
curArgs = arg2Ptr ;
CLI_argumentIsolation ( curArgs , & arg1Ptr , & arg2Ptr ) ;
// Stop processing args if no more are found
if ( * arg1Ptr = = ' \0 ' )
break ;
// Ignore non-Scancode numbers
switch ( arg1Ptr [ 0 ] )
{
// Scancode
case ' S ' :
2014-08-16 19:07:25 +00:00
Macro_keyState ( ( uint8_t ) numToInt ( & arg1Ptr [ 1 ] ) , 0x02 ) ; // Hold scancode
2014-08-15 17:42:12 +00:00
break ;
}
}
}
2014-07-25 05:22:35 +00:00
void cliFunc_keyPress ( char * args )
2014-04-06 18:49:27 +00:00
{
2014-07-25 05:22:35 +00:00
// Parse codes from arguments
char * curArgs ;
2014-04-06 20:12:31 +00:00
char * arg1Ptr ;
2014-07-25 05:22:35 +00:00
char * arg2Ptr = args ;
2014-04-06 20:12:31 +00:00
2014-07-25 05:22:35 +00:00
// Process all args
for ( ; ; )
2014-04-06 20:12:31 +00:00
{
2014-07-25 05:22:35 +00:00
curArgs = arg2Ptr ;
CLI_argumentIsolation ( curArgs , & arg1Ptr , & arg2Ptr ) ;
2014-04-06 20:12:31 +00:00
2014-07-25 05:22:35 +00:00
// Stop processing args if no more are found
if ( * arg1Ptr = = ' \0 ' )
break ;
// Ignore non-Scancode numbers
switch ( arg1Ptr [ 0 ] )
{
// Scancode
case ' S ' :
2014-08-16 19:07:25 +00:00
Macro_keyState ( ( uint8_t ) numToInt ( & arg1Ptr [ 1 ] ) , 0x01 ) ; // Press scancode
2014-07-25 05:22:35 +00:00
break ;
}
2014-04-06 20:12:31 +00:00
}
2014-04-06 18:49:27 +00:00
}
2014-07-25 05:22:35 +00:00
void cliFunc_keyRelease ( char * args )
2014-04-06 18:49:27 +00:00
{
2014-07-25 05:22:35 +00:00
// Parse codes from arguments
char * curArgs ;
2014-04-06 20:12:31 +00:00
char * arg1Ptr ;
2014-07-25 05:22:35 +00:00
char * arg2Ptr = args ;
2014-04-06 20:12:31 +00:00
2014-07-25 05:22:35 +00:00
// Process all args
for ( ; ; )
2014-04-06 20:12:31 +00:00
{
2014-07-25 05:22:35 +00:00
curArgs = arg2Ptr ;
CLI_argumentIsolation ( curArgs , & arg1Ptr , & arg2Ptr ) ;
// Stop processing args if no more are found
if ( * arg1Ptr = = ' \0 ' )
break ;
// Ignore non-Scancode numbers
switch ( arg1Ptr [ 0 ] )
{
// Scancode
case ' S ' :
2014-08-16 19:07:25 +00:00
Macro_keyState ( ( uint8_t ) numToInt ( & arg1Ptr [ 1 ] ) , 0x03 ) ; // Release scancode
2014-07-25 05:22:35 +00:00
break ;
}
2014-04-06 20:12:31 +00:00
}
2014-04-06 18:49:27 +00:00
}
2015-06-20 03:14:37 +00:00
void cliFunc_layerDebug ( char * args )
{
// Toggle layer debug mode
layerDebugMode = layerDebugMode ? 0 : 1 ;
print ( NL ) ;
info_msg ( " Layer Debug Mode: " ) ;
printInt8 ( layerDebugMode ) ;
}
2014-07-25 05:22:35 +00:00
void cliFunc_layerList ( char * args )
{
2014-07-26 19:20:59 +00:00
print ( NL ) ;
info_msg ( " Layer List " ) ;
// Iterate through all of the layers and display them
2014-09-11 18:17:17 +00:00
for ( uint16_t layer = 0 ; layer < LayerNum ; layer + + )
2014-07-26 19:20:59 +00:00
{
print ( NL " \t " ) ;
printHex ( layer ) ;
print ( " - " ) ;
// Display layer name
2014-08-15 17:42:12 +00:00
dPrint ( ( char * ) LayerIndex [ layer ] . name ) ;
2014-07-26 19:20:59 +00:00
// Default map
if ( layer = = 0 )
print ( " \033 [1m(default) \033 [0m " ) ;
// Layer State
print ( NL " \t \t Layer State: " ) ;
2014-09-17 00:04:59 +00:00
printHex ( LayerState [ layer ] ) ;
2014-07-26 19:20:59 +00:00
2014-09-17 00:04:59 +00:00
// First -> Last Indices
print ( " First -> Last Indices: " ) ;
printHex ( LayerIndex [ layer ] . first ) ;
print ( " -> " ) ;
printHex ( LayerIndex [ layer ] . last ) ;
2014-07-26 19:20:59 +00:00
}
2014-07-25 05:22:35 +00:00
}
2014-04-06 20:12:31 +00:00
2014-07-26 19:20:59 +00:00
void cliFunc_layerState ( char * args )
2014-07-25 05:22:35 +00:00
{
2014-07-26 19:20:59 +00:00
// Parse codes from arguments
char * curArgs ;
char * arg1Ptr ;
char * arg2Ptr = args ;
uint8_t arg1 = 0 ;
uint8_t arg2 = 0 ;
// Process first two args
for ( uint8_t c = 0 ; c < 2 ; c + + )
{
curArgs = arg2Ptr ;
CLI_argumentIsolation ( curArgs , & arg1Ptr , & arg2Ptr ) ;
// Stop processing args if no more are found
if ( * arg1Ptr = = ' \0 ' )
break ;
switch ( c )
{
// First argument (e.g. L1)
case 0 :
if ( arg1Ptr [ 0 ] ! = ' L ' )
return ;
2014-08-16 19:07:25 +00:00
arg1 = ( uint8_t ) numToInt ( & arg1Ptr [ 1 ] ) ;
2014-07-26 19:20:59 +00:00
break ;
// Second argument (e.g. 4)
case 1 :
2014-08-16 19:07:25 +00:00
arg2 = ( uint8_t ) numToInt ( arg1Ptr ) ;
2014-07-26 19:20:59 +00:00
// Display operation (to indicate that it worked)
print ( NL ) ;
info_msg ( " Setting Layer L " ) ;
printInt8 ( arg1 ) ;
print ( " to - " ) ;
printHex ( arg2 ) ;
// Set the layer state
2014-09-17 00:04:59 +00:00
LayerState [ arg1 ] = arg2 ;
2014-07-26 19:20:59 +00:00
break ;
}
}
2014-04-06 18:49:27 +00:00
}
void cliFunc_macroDebug ( char * args )
{
2014-04-06 20:12:31 +00:00
// Toggle macro debug mode
macroDebugMode = macroDebugMode ? 0 : 1 ;
print ( NL ) ;
info_msg ( " Macro Debug Mode: " ) ;
printInt8 ( macroDebugMode ) ;
2014-04-06 18:49:27 +00:00
}
2014-07-25 05:22:35 +00:00
void cliFunc_macroList ( char * args )
{
2014-08-15 17:42:12 +00:00
// Show pending key events
print ( NL ) ;
info_msg ( " Pending Key Events: " ) ;
printInt16 ( ( uint16_t ) macroTriggerListBufferSize ) ;
print ( " : " ) ;
2016-01-03 01:43:05 +00:00
for ( var_uint_t key = 0 ; key < macroTriggerListBufferSize ; key + + )
2014-08-15 17:42:12 +00:00
{
printHex ( macroTriggerListBuffer [ key ] . scanCode ) ;
print ( " " ) ;
}
// Show pending trigger macros
print ( NL ) ;
info_msg ( " Pending Trigger Macros: " ) ;
printInt16 ( ( uint16_t ) macroTriggerMacroPendingListSize ) ;
print ( " : " ) ;
2014-09-11 18:17:17 +00:00
for ( var_uint_t macro = 0 ; macro < macroTriggerMacroPendingListSize ; macro + + )
2014-08-15 17:42:12 +00:00
{
printHex ( macroTriggerMacroPendingList [ macro ] ) ;
print ( " " ) ;
}
// Show pending result macros
print ( NL ) ;
info_msg ( " Pending Result Macros: " ) ;
printInt16 ( ( uint16_t ) macroResultMacroPendingListSize ) ;
print ( " : " ) ;
2014-09-11 18:17:17 +00:00
for ( var_uint_t macro = 0 ; macro < macroResultMacroPendingListSize ; macro + + )
2014-08-15 17:42:12 +00:00
{
printHex ( macroResultMacroPendingList [ macro ] ) ;
print ( " " ) ;
}
2014-07-25 06:42:38 +00:00
// Show available trigger macro indices
print ( NL ) ;
info_msg ( " Trigger Macros Range: T0 -> T " ) ;
printInt16 ( ( uint16_t ) TriggerMacroNum - 1 ) ; // Hopefully large enough :P (can't assume 32-bit)
// Show available result macro indices
print ( NL ) ;
info_msg ( " Result Macros Range: R0 -> R " ) ;
printInt16 ( ( uint16_t ) ResultMacroNum - 1 ) ; // Hopefully large enough :P (can't assume 32-bit)
// Show Trigger to Result Macro Links
print ( NL ) ;
info_msg ( " Trigger : Result Macro Pairs " ) ;
2014-09-11 18:17:17 +00:00
for ( var_uint_t macro = 0 ; macro < TriggerMacroNum ; macro + + )
2014-07-25 06:42:38 +00:00
{
print ( NL ) ;
print ( " \t T " ) ;
printInt16 ( ( uint16_t ) macro ) ; // Hopefully large enough :P (can't assume 32-bit)
print ( " : R " ) ;
printInt16 ( ( uint16_t ) TriggerMacroList [ macro ] . result ) ; // Hopefully large enough :P (can't assume 32-bit)
}
2014-07-25 05:22:35 +00:00
}
void cliFunc_macroProc ( char * args )
{
// Toggle macro pause mode
macroPauseMode = macroPauseMode ? 0 : 1 ;
print ( NL ) ;
info_msg ( " Macro Processing Mode: " ) ;
printInt8 ( macroPauseMode ) ;
}
2014-09-11 18:17:17 +00:00
void macroDebugShowTrigger ( var_uint_t index )
2014-07-25 05:22:35 +00:00
{
// Only proceed if the macro exists
if ( index > = TriggerMacroNum )
return ;
// Trigger Macro Show
2014-09-17 06:29:21 +00:00
const TriggerMacro * macro = & TriggerMacroList [ index ] ;
TriggerMacroRecord * record = & TriggerMacroRecordList [ index ] ;
2014-07-25 05:22:35 +00:00
print ( NL ) ;
info_msg ( " Trigger Macro Index: " ) ;
printInt16 ( ( uint16_t ) index ) ; // Hopefully large enough :P (can't assume 32-bit)
print ( NL ) ;
// Read the comboLength for combo in the sequence (sequence of combos)
2014-09-11 18:17:17 +00:00
var_uint_t pos = 0 ;
2014-07-25 05:22:35 +00:00
uint8_t comboLength = macro - > guide [ pos ] ;
// Iterate through and interpret the guide
while ( comboLength ! = 0 )
{
// Initial position of the combo
2014-09-11 18:17:17 +00:00
var_uint_t comboPos = + + pos ;
2014-07-25 05:22:35 +00:00
// Iterate through the combo
while ( pos < comboLength * TriggerGuideSize + comboPos )
{
// Assign TriggerGuide element (key type, state and scancode)
TriggerGuide * guide = ( TriggerGuide * ) ( & macro - > guide [ pos ] ) ;
// Display guide information about trigger key
2014-07-26 21:06:19 +00:00
printHex ( guide - > scanCode ) ;
2014-07-25 05:22:35 +00:00
print ( " | " ) ;
printHex ( guide - > type ) ;
print ( " | " ) ;
printHex ( guide - > state ) ;
// Increment position
pos + = TriggerGuideSize ;
// Only show combo separator if there are combos left in the sequence element
if ( pos < comboLength * TriggerGuideSize + comboPos )
print ( " + " ) ;
}
// Read the next comboLength
comboLength = macro - > guide [ pos ] ;
// Only show sequence separator if there is another combo to process
if ( comboLength ! = 0 )
print ( " ; " ) ;
}
// Display current position
print ( NL " Position: " ) ;
2014-09-17 06:29:21 +00:00
printInt16 ( ( uint16_t ) record - > pos ) ; // Hopefully large enough :P (can't assume 32-bit)
2014-07-25 05:22:35 +00:00
// Display result macro index
print ( NL " Result Macro Index: " ) ;
printInt16 ( ( uint16_t ) macro - > result ) ; // Hopefully large enough :P (can't assume 32-bit)
2014-08-20 17:53:22 +00:00
// Display trigger macro state
print ( NL " Trigger Macro State: " ) ;
2014-09-17 06:29:21 +00:00
switch ( record - > state )
2014-08-20 17:53:22 +00:00
{
case TriggerMacro_Press : print ( " Press " ) ; break ;
case TriggerMacro_Release : print ( " Release " ) ; break ;
case TriggerMacro_Waiting : print ( " Waiting " ) ; break ;
}
2014-07-25 05:22:35 +00:00
}
2014-09-11 18:17:17 +00:00
void macroDebugShowResult ( var_uint_t index )
2014-07-25 05:22:35 +00:00
{
// Only proceed if the macro exists
if ( index > = ResultMacroNum )
return ;
// Trigger Macro Show
2014-09-17 06:29:21 +00:00
const ResultMacro * macro = & ResultMacroList [ index ] ;
ResultMacroRecord * record = & ResultMacroRecordList [ index ] ;
2014-07-25 05:22:35 +00:00
print ( NL ) ;
info_msg ( " Result Macro Index: " ) ;
printInt16 ( ( uint16_t ) index ) ; // Hopefully large enough :P (can't assume 32-bit)
print ( NL ) ;
// Read the comboLength for combo in the sequence (sequence of combos)
2014-09-11 18:17:17 +00:00
var_uint_t pos = 0 ;
2014-07-25 05:22:35 +00:00
uint8_t comboLength = macro - > guide [ pos + + ] ;
// Iterate through and interpret the guide
while ( comboLength ! = 0 )
{
// Function Counter, used to keep track of the combos processed
2014-09-11 18:17:17 +00:00
var_uint_t funcCount = 0 ;
2014-07-25 05:22:35 +00:00
// Iterate through the combo
while ( funcCount < comboLength )
{
// Assign TriggerGuide element (key type, state and scancode)
ResultGuide * guide = ( ResultGuide * ) ( & macro - > guide [ pos ] ) ;
2014-07-25 06:18:38 +00:00
// Display Function Index
printHex ( guide - > index ) ;
print ( " | " ) ;
2014-07-25 05:22:35 +00:00
// Display Function Ptr Address
2014-09-11 18:17:17 +00:00
printHex ( ( nat_ptr_t ) CapabilitiesList [ guide - > index ] . func ) ;
2014-07-25 05:22:35 +00:00
print ( " | " ) ;
// Display/Lookup Capability Name (utilize debug mode of capability)
2014-07-25 17:53:33 +00:00
void ( * capability ) ( uint8_t , uint8_t , uint8_t * ) = ( void ( * ) ( uint8_t , uint8_t , uint8_t * ) ) ( CapabilitiesList [ guide - > index ] . func ) ;
2014-07-25 05:22:35 +00:00
capability ( 0xFF , 0xFF , 0 ) ;
// Display Argument(s)
print ( " ( " ) ;
2014-09-11 18:17:17 +00:00
for ( var_uint_t arg = 0 ; arg < CapabilitiesList [ guide - > index ] . argCount ; arg + + )
2014-07-25 05:22:35 +00:00
{
2014-07-25 06:18:38 +00:00
// Arguments are only 8 bit values
printHex ( ( & guide - > args ) [ arg ] ) ;
2014-07-25 05:22:35 +00:00
// Only show arg separator if there are args left
2014-07-25 17:53:33 +00:00
if ( arg + 1 < CapabilitiesList [ guide - > index ] . argCount )
2014-07-25 05:22:35 +00:00
print ( " , " ) ;
}
print ( " ) " ) ;
// Increment position
pos + = ResultGuideSize ( guide ) ;
// Increment function count
funcCount + + ;
// Only show combo separator if there are combos left in the sequence element
if ( funcCount < comboLength )
print ( " + " ) ;
}
// Read the next comboLength
comboLength = macro - > guide [ pos + + ] ;
// Only show sequence separator if there is another combo to process
if ( comboLength ! = 0 )
print ( " ; " ) ;
}
// Display current position
print ( NL " Position: " ) ;
2014-09-17 06:29:21 +00:00
printInt16 ( ( uint16_t ) record - > pos ) ; // Hopefully large enough :P (can't assume 32-bit)
2014-07-25 05:22:35 +00:00
// Display final trigger state/type
print ( NL " Final Trigger State (State/Type): " ) ;
2014-09-17 06:29:21 +00:00
printHex ( record - > state ) ;
2014-07-25 05:22:35 +00:00
print ( " / " ) ;
2014-09-17 06:29:21 +00:00
printHex ( record - > stateType ) ;
2014-07-25 05:22:35 +00:00
}
void cliFunc_macroShow ( char * args )
{
// Parse codes from arguments
char * curArgs ;
char * arg1Ptr ;
char * arg2Ptr = args ;
// Process all args
for ( ; ; )
{
curArgs = arg2Ptr ;
CLI_argumentIsolation ( curArgs , & arg1Ptr , & arg2Ptr ) ;
// Stop processing args if no more are found
if ( * arg1Ptr = = ' \0 ' )
break ;
// Ignore invalid codes
switch ( arg1Ptr [ 0 ] )
{
// Indexed Trigger Macro
case ' T ' :
2014-08-16 19:07:25 +00:00
macroDebugShowTrigger ( numToInt ( & arg1Ptr [ 1 ] ) ) ;
2014-07-25 05:22:35 +00:00
break ;
// Indexed Result Macro
case ' R ' :
2014-08-16 19:07:25 +00:00
macroDebugShowResult ( numToInt ( & arg1Ptr [ 1 ] ) ) ;
2014-07-25 05:22:35 +00:00
break ;
}
}
}
void cliFunc_macroStep ( char * args )
{
// Parse number from argument
// NOTE: Only first argument is used
char * arg1Ptr ;
char * arg2Ptr ;
CLI_argumentIsolation ( args , & arg1Ptr , & arg2Ptr ) ;
2014-08-15 17:42:12 +00:00
// Default to 1, if no argument given
2014-09-11 18:17:17 +00:00
var_uint_t count = ( var_uint_t ) numToInt ( arg1Ptr ) ;
2014-08-15 17:42:12 +00:00
if ( count = = 0 )
count = 1 ;
2014-07-25 05:22:35 +00:00
// Set the macro step counter, negative int's are cast to uint
2014-08-15 17:42:12 +00:00
macroStepCounter = count ;
2014-07-25 05:22:35 +00:00
}