Skip to content

Commit f19f8cd

Browse files
committed
Adds basic macro unit testing support
See Scan/TestIn/test.py for basic usage - Works in NKRO and 6KRO modes - Added convenience Python datastructures to help with comparisons - Added exit command for cli so it's possible to drop to the virtual cli during a test (and pause) - Added more callback pointer refresh functions (not sure why needed, but prevents segfaults) - Added initial code to control the timer systicks (will be used for timed macro evaluation)
1 parent 311fd87 commit f19f8cd

13 files changed

Lines changed: 414 additions & 55 deletions

File tree

Debug/cli/cli.c

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,11 @@
3333
// ----- Variables -----
3434

3535
// Basic command dictionary
36-
CLIDict_Entry( clear, "Clear the screen.");
36+
CLIDict_Entry( clear, "Clear the screen.");
3737
CLIDict_Entry( cliDebug, "Enables/Disables hex output of the most recent cli input." );
38+
#if defined(_host_)
39+
CLIDict_Entry( exit, "Host KLL Only - Exits cli." );
40+
#endif
3841
CLIDict_Entry( help, "You're looking at it :P" );
3942
CLIDict_Entry( led, "Enables/Disables indicator LED. Try a couple times just in case the LED is in an odd state.\r\n\t\t\033[33mWarning\033[0m: May adversely affect some modules..." );
4043
CLIDict_Entry( reload, "Signals microcontroller to reflash/reload." );
@@ -46,6 +49,9 @@ CLIDict_Entry( version, "Version information about this firmware." );
4649
CLIDict_Def( basicCLIDict, "General Commands" ) = {
4750
CLIDict_Item( clear ),
4851
CLIDict_Item( cliDebug ),
52+
#if defined(_host_)
53+
CLIDict_Item( exit ),
54+
#endif
4955
CLIDict_Item( help ),
5056
CLIDict_Item( led ),
5157
CLIDict_Item( reload ),
@@ -56,6 +62,10 @@ CLIDict_Def( basicCLIDict, "General Commands" ) = {
5662
{ 0, 0, 0 } // Null entry for dictionary end
5763
};
5864

65+
#if defined(_host_)
66+
int CLI_exit = 0; // When 1, cli signals library to exit (Host-side KLL only)
67+
#endif
68+
5969

6070

6171
// ----- Functions -----
@@ -90,10 +100,15 @@ inline void CLI_init()
90100

91101
// Hex debug mode is off by default
92102
CLIHexDebugMode = 0;
103+
104+
#if defined(_host_)
105+
// Make sure we're not exiting right away in Host-side KLL mode
106+
CLI_exit = 0;
107+
#endif
93108
}
94109

95110
// Query the serial input buffer for any new characters
96-
void CLI_process()
111+
int CLI_process()
97112
{
98113
// Current buffer position
99114
uint8_t prev_buf_pos = CLILineBufferCurrent;
@@ -120,7 +135,7 @@ void CLI_process()
120135
// Reset the prompt
121136
prompt();
122137

123-
return;
138+
return 0;
124139
}
125140

126141
// Place into line buffer
@@ -189,9 +204,18 @@ void CLI_process()
189204
print( NL );
190205
prompt();
191206

207+
// Check if we need to exit right away
208+
#if defined(_host_)
209+
if ( CLI_exit )
210+
{
211+
CLI_exit = 0;
212+
return 1;
213+
}
214+
#endif
215+
192216
// XXX There is a potential bug here when resetting the buffer (losing valid keypresses)
193217
// Doesn't look like it will happen *that* often, so not handling it for now -HaaTa
194-
return;
218+
return 0;
195219

196220
case 0x09: // Tab
197221
// Tab completion for the current command
@@ -201,7 +225,7 @@ void CLI_process()
201225

202226
// XXX There is a potential bug here when resetting the buffer (losing valid keypresses)
203227
// Doesn't look like it will happen *that* often, so not handling it for now -HaaTa
204-
return;
228+
return 0;
205229

206230
case 0x1B: // Esc / Escape codes
207231
// Check for other escape sequence
@@ -235,7 +259,7 @@ void CLI_process()
235259
CLI_retreiveHistory( CLIHistoryCurrent );
236260
}
237261
}
238-
return;
262+
return 0;
239263

240264
case 0x08:
241265
case 0x7F: // Backspace
@@ -267,6 +291,8 @@ void CLI_process()
267291
break;
268292
}
269293
}
294+
295+
return 0;
270296
}
271297

272298
// Takes a string, returns two pointers
@@ -484,6 +510,13 @@ void cliFunc_cliDebug( char* args )
484510
}
485511
}
486512

513+
#if defined(_host_)
514+
void cliFunc_exit( char* args )
515+
{
516+
CLI_exit = 1;
517+
}
518+
#endif
519+
487520
void cliFunc_help( char* args )
488521
{
489522
// Scan array of dictionaries and print every description
@@ -549,6 +582,9 @@ void cliFunc_tick( char* args )
549582
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_)
550583
extern volatile uint32_t systick_millis_count;
551584
uint32_t ms_count = systick_millis_count;
585+
#elif defined(_host_)
586+
extern volatile uint32_t systick_millis_count;
587+
uint32_t ms_count = systick_millis_count;
552588
#else
553589
// TODO
554590
uint32_t ms_count = 0;
@@ -560,6 +596,8 @@ void cliFunc_tick( char* args )
560596
print("13.889 ns");
561597
#elif F_CPU == 48000000
562598
print("20.833 ns");
599+
#elif defined(_host_)
600+
print("<USERDEFINED>");
563601
#else
564602
print("<UNSET>");
565603
#endif
@@ -569,6 +607,9 @@ void cliFunc_tick( char* args )
569607
print(":");
570608
#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_)
571609
printInt32( ARM_DWT_CYCCNT );
610+
#elif defined(_host_)
611+
extern volatile uint32_t ns_since_systick_count;
612+
printInt32( ns_since_systick_count );
572613
#endif
573614
print( NL );
574615
}

Debug/cli/cli.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ uint8_t CLIHexDebugMode;
107107
// ----- Functions and Corresponding Function Aliases -----
108108

109109
void CLI_init();
110-
void CLI_process();
110+
int CLI_process();
111111
void CLI_registerDictionary( const CLIDictItem *cmdDict, const char* dictName );
112112
void CLI_argumentIsolation( char* string, char** first, char** second );
113113

@@ -118,11 +118,9 @@ void CLI_saveHistory( char *buff );
118118
void CLI_retreiveHistory( int index );
119119

120120
// CLI Command Functions
121-
void cliFunc_arch ( char* args );
122-
void cliFunc_chip ( char* args );
123121
void cliFunc_clear ( char* args );
124122
void cliFunc_cliDebug( char* args );
125-
void cliFunc_device ( char* args );
123+
void cliFunc_exit ( char* args );
126124
void cliFunc_help ( char* args );
127125
void cliFunc_led ( char* args );
128126
void cliFunc_reload ( char* args );

Lib/CMake/host.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,12 @@ set( WARN "-Wall -ggdb3" )
7777
#| Clang Compiler
7878
if ( "${COMPILER}" MATCHES "clang" )
7979
# TODO
80-
set ( TUNING "-nostdlib -fdata-sections -ffunction-sections -fshort-wchar -fno-builtin" )
80+
set ( TUNING "-nostdlib -fshort-enums -fdata-sections -ffunction-sections -fshort-wchar -fno-builtin" )
8181

8282
#| GCC Compiler
8383
else()
8484
# TODO
85-
set( TUNING "-nostdlib -fdata-sections -ffunction-sections -fshort-wchar -fno-builtin -nostartfiles" )
85+
set( TUNING "-nostdlib -fshort-enums -fdata-sections -ffunction-sections -fshort-wchar -fno-builtin -nostartfiles" )
8686
endif()
8787

8888

Lib/host.py

Lines changed: 92 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@
3131

3232
from ctypes import CFUNCTYPE, c_int, c_char_p
3333

34-
import serial
35-
3634

3735

3836
### Decorators ###
@@ -64,6 +62,21 @@ def textFormatter_gettext( s ):
6462

6563
### Classes ###
6664

65+
class Data:
66+
'''
67+
Generic class used to hold data retrieved from libkiibohd callbacks
68+
'''
69+
def __init__( self ):
70+
self.usb_keyboard_data = None
71+
72+
def usb_keyboard( self ):
73+
'''
74+
Returns a tuple of USB Keyboard output
75+
'''
76+
if self.usb_keyboard_data is not None:
77+
return self.usb_keyboard_data.protocol, self.usb_keyboard_data.codes(), self.usb_keyboard_data.consumer_ctrl, self.usb_keyboard_data.system_ctrl
78+
return None
79+
6780
class Control:
6881
'''
6982
Handles general control of the libkiibohd host setup
@@ -100,6 +113,12 @@ def __init__( self, scan_module, output_module, libkiibohd_path ):
100113
output = importlib.util.module_from_spec( spec )
101114
spec.loader.exec_module( output )
102115

116+
# Container for any libkiibohd callback data storage
117+
global data
118+
self.data = Data()
119+
scan.data = self.data
120+
output.data = self.data
121+
103122
# Build command and callback dictionaries
104123
self.build_command_list()
105124
self.build_callback_list()
@@ -116,6 +135,7 @@ def __init__( self, scan_module, output_module, libkiibohd_path ):
116135
print( "{0} Could not open -> {1}".format( ERROR, libkiibohd_path ) )
117136
print( err )
118137
sys.exit( 1 )
138+
self.kiibohd = kiibohd
119139

120140
# Register Callback
121141
self.callback_setup()
@@ -146,7 +166,7 @@ def callback_setup( self ):
146166
'''
147167
self.CTYPE_callback = CFUNCTYPE( c_int, c_char_p, c_char_p )
148168
try:
149-
self.CTYPE_callback_ref = kiibohd.Host_register_callback( self.CTYPE_callback( callback ) )
169+
refresh_callback()
150170
except Exception as err:
151171
print( "{0} Could not register libkiibohd callback function".format( ERROR ) )
152172
print( err )
@@ -199,7 +219,7 @@ def process_args( self ):
199219
# Run test if requested, then exit
200220
if args.test:
201221
print("libkiibohd.so - Callback Test")
202-
val = kiibohd.Host_callback_test()
222+
val = self.kiibohd.Host_callback_test()
203223
print("Return Value:", val )
204224
sys.exit( 0 )
205225

@@ -210,8 +230,54 @@ def process( self ):
210230
Run main commands
211231
'''
212232
# Initialize kiibohd
213-
kiibohd.Host_init()
233+
print(">Host_init")
234+
self.kiibohd.Host_init()
235+
print("")
236+
237+
# Run cli if enabled
238+
self.virtual_serialport_process()
239+
240+
def loop( self, number_of_loops=1 ):
241+
'''
242+
Run Host-side KLL main processing loop N number of times
243+
244+
@param number_of_loops: Number of times to run main loop
245+
'''
246+
loop = 0
247+
while loop < number_of_loops:
248+
# Refresh callback interface
249+
refresh_callback()
250+
251+
print( ">Host_process ({0})".format( loop ) )
252+
self.kiibohd.Host_process()
253+
loop += 1
254+
255+
def cmd( self, command_name ):
256+
'''
257+
Run given command from Host-side KLL
214258
259+
Does a lookup of both Scan and Output module commands
260+
261+
@param command_name: String of command
262+
@return: Function
263+
'''
264+
# Refresh callback interface
265+
refresh_callback()
266+
267+
return self.command_dict[ command_name ]
268+
269+
def cli( self ):
270+
'''
271+
Setup and process cli commands
272+
Convenience function for test cases
273+
'''
274+
self.virtual_serialport_setup()
275+
self.virtual_serialport_process()
276+
277+
def virtual_serialport_process( self ):
278+
'''
279+
Process virtual serial port commands
280+
'''
215281
# Run cli loop if available
216282
while self.serial is not None:
217283
value = os.read( self.serial_master, 1 ).decode('utf-8')
@@ -223,7 +289,14 @@ def process( self ):
223289
sys.stdout.flush()
224290

225291
# Check if any cli commands need to be processed
226-
kiibohd.Host_cli_process()
292+
ret = self.kiibohd.Host_cli_process()
293+
294+
# If non-zero return, break out of processing loop
295+
if ret != 0:
296+
# Cleanup virtual serialport
297+
os.close( self.serial_master )
298+
os.close( self.serial_slave )
299+
break
227300

228301
def virtual_serialport_setup( self ):
229302
'''
@@ -256,6 +329,17 @@ def get_method_dict( obj ):
256329
return output
257330

258331

332+
def refresh_callback():
333+
'''
334+
XXX
335+
Refresh callback pointer
336+
For some reason, either garbage collection, or something else, the pointer becomes stale in certain situations
337+
Usually when calling different library functions
338+
This just refreshes the pointer (shouldn't be necessary, but it works...) -Jacob
339+
'''
340+
control.CTYPE_callback_ref = kiibohd.Host_register_callback( control.CTYPE_callback( callback ) )
341+
342+
259343
def callback( command, args ):
260344
'''
261345
libkiibohd callback function
@@ -268,12 +352,8 @@ def callback( command, args ):
268352
# Must convert byte string to utf-8 first
269353
ret = control.callback_dict[ command.decode('utf-8') ]( args.decode('utf-8') )
270354

271-
# XXX
272-
# Refresh callback pointer
273-
# For some reason, either garbage collection, or something else, the pointer becomes stale in certain situations
274-
# Usually when calling different library functions
275-
# This just refreshes the pointer (shouldn't be necessary, but it works...) -Jacob
276-
control.CTYPE_callback_ref = kiibohd.Host_register_callback( control.CTYPE_callback( callback ) )
355+
# Refresh callback interface
356+
refresh_callback()
277357

278358
# If returning None (default), change out to 1, C default
279359
return ret is None and 1 or ret

0 commit comments

Comments
 (0)