# HG changeset patch # User Rowan Decker # Date 1425871059 25200 # Node ID 4f47971c45c2f128b4a35c92bacee1682d977dc5 # Parent ab4515606277c6d193c63252f086ba4508378a29# Parent f158dfa0fa852d521b344755d31e54af4b2dba75 Merge remote-tracking branch 'upstream/master' diff -r ab4515606277 -r 4f47971c45c2 Debug/cli/cli.c --- a/Debug/cli/cli.c Sun Mar 08 18:40:01 2015 -0700 +++ b/Debug/cli/cli.c Sun Mar 08 20:17:39 2015 -0700 @@ -1,4 +1,4 @@ -/* Copyright (C) 2014 by Jacob Alexander +/* Copyright (C) 2014-2015 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -422,7 +422,7 @@ print( NL ); print( " \033[1mRevision:\033[0m " CLI_Revision NL ); print( " \033[1mBranch:\033[0m " CLI_Branch NL ); - print( " \033[1mTree Status:\033[0m " CLI_ModifiedStatus NL ); + print( " \033[1mTree Status:\033[0m " CLI_ModifiedStatus CLI_ModifiedFiles NL ); print( " \033[1mRepo Origin:\033[0m " CLI_RepoOrigin NL ); print( " \033[1mCommit Date:\033[0m " CLI_CommitDate NL ); print( " \033[1mCommit Author:\033[0m " CLI_CommitAuthor NL ); diff -r ab4515606277 -r 4f47971c45c2 Lib/CMake/FindDFUSuffix.cmake --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/CMake/FindDFUSuffix.cmake Sun Mar 08 20:17:39 2015 -0700 @@ -0,0 +1,40 @@ +# The module defines the following variables: +# DFU_SUFFIX_EXECUTABLE - path to ctags command line client +# DFU_SUFFIX_FOUND - true if the command line client was found +# DFU_SUFFIX_VERSION_STRING - the version of dfu-suffix found (since CMake 2.8.8) +# Example usage: +# find_package( DFUSuffix ) +# if( DFU_SUFFIX_FOUND ) +# message("ctags found: ${DFU_SUFFIX_EXECUTABLE}") +# endif() + +find_program ( DFU_SUFFIX_EXECUTABLE + NAMES dfu-suffix + DOC "dfu-suffix executable" +) +mark_as_advanced ( DFU_SUFFIX_EXECUTABLE ) + +if ( DFU_SUFFIX_EXECUTABLE ) + execute_process ( COMMAND ${DFU_SUFFIX_EXECUTABLE} --version + OUTPUT_VARIABLE dfu_suffix_version + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + if ( dfu_suffix_version MATCHES "^dfu-suffix \\(dfu-util\\)" ) + string ( REPLACE "\n" "" DFU_SUFFIX_VERSION_STRING ${dfu_suffix_version} ) + string ( REPLACE "dfu-suffix (dfu-util) " "" DFU_SUFFIX_VERSION_STRING ${DFU_SUFFIX_VERSION_STRING} ) + string ( REGEX REPLACE "Copyright .*$" "" DFU_SUFFIX_VERSION_STRING ${DFU_SUFFIX_VERSION_STRING} ) + endif () + unset ( dfu_suffix_version ) +endif () + +# Handle the QUIETLY and REQUIRED arguments and set DFU_SUFFIX_FOUND to TRUE if +# all listed variables are TRUE + +include ( FindPackageHandleStandardArgs ) +find_package_handle_standard_args ( DFU_SUFFIX + REQUIRED_VARS DFU_SUFFIX_EXECUTABLE + VERSION_VAR DFU_SUFFIX_VERSION_STRING +) + diff -r ab4515606277 -r 4f47971c45c2 Lib/CMake/build.cmake --- a/Lib/CMake/build.cmake Sun Mar 08 18:40:01 2015 -0700 +++ b/Lib/CMake/build.cmake Sun Mar 08 20:17:39 2015 -0700 @@ -1,6 +1,6 @@ ###| CMAKE Kiibohd Controller Source Configurator |### # -# Written by Jacob Alexander in 2011-2014 for the Kiibohd Controller +# Written by Jacob Alexander in 2011-2015 for the Kiibohd Controller # # Released into the Public Domain # @@ -46,12 +46,25 @@ #| Convert the .ELF into a .bin to load onto the McHCK +#| Then sign using dfu-suffix (requries dfu-util) if ( DEFINED DFU ) + # dfu-suffix is required to sign the dfu binary + find_package ( DFUSuffix ) + set( TARGET_BIN ${TARGET}.dfu.bin ) - add_custom_command( TARGET ${TARGET_ELF} POST_BUILD - COMMAND ${OBJ_COPY} ${BIN_FLAGS} ${TARGET_ELF} ${TARGET_BIN} - COMMENT "Creating dfu binary file: ${TARGET_BIN}" - ) + if ( DFU_SUFFIX_FOUND ) + add_custom_command( TARGET ${TARGET_ELF} POST_BUILD + COMMAND ${OBJ_COPY} ${BIN_FLAGS} ${TARGET_ELF} ${TARGET_BIN} + COMMAND ${DFU_SUFFIX_EXECUTABLE} --add ${TARGET_BIN} --vid ${BOOT_VENDOR_ID} --pid ${BOOT_PRODUCT_ID} 1> /dev/null + COMMENT "Create and sign dfu bin file: ${TARGET_BIN}" + ) + else () + message ( WARNING "DFU Binary has not been signed, requires dfu-suffix..." ) + add_custom_command( TARGET ${TARGET_ELF} POST_BUILD + COMMAND ${OBJ_COPY} ${BIN_FLAGS} ${TARGET_ELF} ${TARGET_BIN} + COMMENT "Creating dfu binary file: ${TARGET_BIN}" + ) + endif () endif () diff -r ab4515606277 -r 4f47971c45c2 Lib/CMake/kll.cmake --- a/Lib/CMake/kll.cmake Sun Mar 08 18:40:01 2015 -0700 +++ b/Lib/CMake/kll.cmake Sun Mar 08 20:17:39 2015 -0700 @@ -1,6 +1,6 @@ ###| CMAKE Kiibohd Controller KLL Configurator |### # -# Written by Jacob Alexander in 2014 for the Kiibohd Controller +# Written by Jacob Alexander in 2014-2015 for the Kiibohd Controller # # Released into the Public Domain # @@ -46,14 +46,10 @@ #| KLL_DEPENDS is used to build a dependency tree for kll.py, this way when files are changed, kll.py gets re-run -#| Search for capabilities.kll in each module directory -foreach ( DIR ${ScanModulePath} ${MacroModulePath} ${OutputModulePath} ${DebugModulePath} ) - # capabilities.kll exists, add to BaseMap - set ( filename "${PROJECT_SOURCE_DIR}/${DIR}/capabilities.kll" ) - if ( EXISTS ${filename} ) - set ( BaseMap_Args ${BaseMap_Args} ${filename} ) - set ( KLL_DEPENDS ${KLL_DEPENDS} ${filename} ) - endif () +#| Add each of the detected capabilities.kll +foreach ( filename ${ScanModule_KLL} ${MacroModule_KLL} ${OutputModule_KLL} ${DebugModule_KLL} ) + set ( BaseMap_Args ${BaseMap_Args} ${filename} ) + set ( KLL_DEPENDS ${KLL_DEPENDS} ${filename} ) endforeach () #| If set BaseMap cannot be found, use default map @@ -118,21 +114,25 @@ # #| KLL Options -set ( kll_backend -b kiibohd ) -set ( kll_template -t ${PROJECT_SOURCE_DIR}/kll/templates/kiibohdKeymap.h ) -set ( kll_outputname generatedKeymap.h ) -set ( kll_output -o ${kll_outputname} ) -set ( kll_define_output --defines-output kll_defs.h ) -set ( kll_define_template --defines-template ${PROJECT_SOURCE_DIR}/kll/templates/kiibohdDefs.h ) +set ( kll_backend --backend kiibohd ) +set ( kll_template --templates ${PROJECT_SOURCE_DIR}/kll/templates/kiibohdKeymap.h ${PROJECT_SOURCE_DIR}/kll/templates/kiibohdDefs.h ) +set ( kll_outputname generatedKeymap.h kll_defs.h ) +set ( kll_output --outputs ${kll_outputname} ) #| KLL Cmd -set ( kll_cmd ${PROJECT_SOURCE_DIR}/kll/kll.py ${BaseMap_Args} ${DefaultMap_Args} ${PartialMap_Args} ${kll_backend} ${kll_template} ${kll_output} ${kll_define_template} ${kll_define_output} ) +set ( kll_cmd ${PROJECT_SOURCE_DIR}/kll/kll.py ${BaseMap_Args} ${DefaultMap_Args} ${PartialMap_Args} ${kll_backend} ${kll_template} ${kll_output} ) add_custom_command ( OUTPUT ${kll_outputname} COMMAND ${kll_cmd} DEPENDS ${KLL_DEPENDS} COMMENT "Generating KLL Layout" ) +#| KLL Regen Convenience Target +add_custom_target ( kll_regen + COMMAND ${kll_cmd} + COMMENT "Re-generating KLL Layout" +) + #| Append generated file to required sources so it becomes a dependency in the main build set ( SRCS ${SRCS} ${kll_outputname} ) diff -r ab4515606277 -r 4f47971c45c2 Lib/CMake/modules.cmake --- a/Lib/CMake/modules.cmake Sun Mar 08 18:40:01 2015 -0700 +++ b/Lib/CMake/modules.cmake Sun Mar 08 20:17:39 2015 -0700 @@ -1,6 +1,6 @@ ###| CMAKE Kiibohd Controller Source Configurator |### # -# Written by Jacob Alexander in 2011-2014 for the Kiibohd Controller +# Written by Jacob Alexander in 2011-2015 for the Kiibohd Controller # # Released into the Public Domain # @@ -104,10 +104,8 @@ PathPrepend ( Module_SRCS ${ModulePath} ${Module_SRCS} ) # Check the current scope to see if a sub-module added some source files - set ( Module_SRCS ${${ModuleType}_SRCS} ${Module_SRCS} ) - # Append each of the sources to each type of module srcs list - set ( ${ModuleType}_SRCS ${Module_SRCS} ) + set ( ${ModuleType}_SRCS ${${ModuleType}_SRCS} ${Module_SRCS} ) # Add .h files add_definitions ( -I${ModuleFullPath} ) @@ -124,8 +122,17 @@ endif () endforeach () - # Finally, add the sources to the parent scope (i.e. return) + # Check for any capabilities.kll files in the Module + set ( kll_capabilities_file "${ModuleFullPath}/capabilities.kll" ) + if ( EXISTS ${kll_capabilities_file} ) + # Add the kll file and any submodule kll files to the running list + set ( ${ModuleType}Module_KLL ${${ModuleType}Module_KLL} ${kll_capabilities_file} ) + endif () + + + # Finally, add the sources and kll files to the parent scope (i.e. return) set ( ${ModuleType}_SRCS ${${ModuleType}_SRCS} PARENT_SCOPE ) + set ( ${ModuleType}Module_KLL ${${ModuleType}Module_KLL} PARENT_SCOPE ) endfunction () @@ -150,7 +157,7 @@ # #| Manufacturer name -set( MANUFACTURER "Kiibohd" ) +set ( MANUFACTURER "Kiibohd" ) #| Serial Number @@ -158,19 +165,29 @@ #| Modified #| Takes a bit of work to extract the "M " using CMake, and not using it if there are no modifications -execute_process( COMMAND ${GIT_EXECUTABLE} status -s -uno --porcelain +execute_process ( COMMAND ${GIT_EXECUTABLE} status -s -uno --porcelain WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} OUTPUT_VARIABLE Git_Modified_INFO ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ) -string( LENGTH "${Git_Modified_INFO}" Git_Modified_LENGTH ) -set( Git_Modified_Status "Clean" ) +string ( LENGTH "${Git_Modified_INFO}" Git_Modified_LENGTH ) +set ( Git_Modified_Status "Clean" ) if ( ${Git_Modified_LENGTH} GREATER 2 ) - string( SUBSTRING "${Git_Modified_INFO}" 1 2 Git_Modified_Flag_INFO ) - set( Git_Modified_Status "Dirty" ) + string ( SUBSTRING "${Git_Modified_INFO}" 1 2 Git_Modified_Flag_INFO ) + set ( Git_Modified_Status "Dirty" ) endif () +#| List of modified files +execute_process ( COMMAND ${GIT_EXECUTABLE} diff-index --name-only HEAD -- + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE Git_Modified_Files + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE +) +string ( REGEX REPLACE "\n" "\\\\r\\\\n\\\\t" Git_Modified_Files "${Git_Modified_Files}" ) +set ( Git_Modified_Files "\\r\\n\\t${Git_Modified_Files}" ) + #| Branch execute_process( COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} @@ -180,7 +197,7 @@ ) #| Date -execute_process( COMMAND ${GIT_EXECUTABLE} show -s --format=%ci +execute_process ( COMMAND ${GIT_EXECUTABLE} show -s --format=%ci WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} OUTPUT_VARIABLE Git_Date_INFO ERROR_QUIET @@ -188,7 +205,7 @@ ) #| Commit Author and Email -execute_process( COMMAND ${GIT_EXECUTABLE} show -s --format="%cn <%ce>" +execute_process ( COMMAND ${GIT_EXECUTABLE} show -s --format="%cn <%ce>" WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} OUTPUT_VARIABLE Git_Commit_Author ERROR_QUIET @@ -196,7 +213,7 @@ ) #| Commit Revision -execute_process( COMMAND ${GIT_EXECUTABLE} show -s --format=%H +execute_process ( COMMAND ${GIT_EXECUTABLE} show -s --format=%H WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} OUTPUT_VARIABLE Git_Commit_Revision ERROR_QUIET @@ -204,7 +221,7 @@ ) #| Origin URL -execute_process( COMMAND ${GIT_EXECUTABLE} config --get remote.origin.url +execute_process ( COMMAND ${GIT_EXECUTABLE} config --get remote.origin.url WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} OUTPUT_VARIABLE Git_Origin_URL ERROR_QUIET @@ -212,25 +229,25 @@ ) #| Build Date -execute_process( COMMAND "date" "+%Y-%m-%d %T %z" +execute_process ( COMMAND "date" "+%Y-%m-%d %T %z" OUTPUT_VARIABLE Build_Date ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ) #| Last Commit Date -set( GitLastCommitDate "${Git_Modified_Status} ${Git_Branch_INFO} - ${Git_Date_INFO}" ) +set ( GitLastCommitDate "${Git_Modified_Status} ${Git_Branch_INFO} - ${Git_Date_INFO}" ) #| Uses CMake variables to include as defines #| Primarily for USB configuration -configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/Lib/_buildvars.h buildvars.h ) +configure_file ( ${CMAKE_CURRENT_SOURCE_DIR}/Lib/_buildvars.h buildvars.h ) ### # Source Defines # -set( SRCS +set ( SRCS ${MAIN_SRCS} ${COMPILER_SRCS} ${Scan_SRCS} @@ -240,7 +257,7 @@ ) #| Directories to include by default -include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) +include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) @@ -248,20 +265,20 @@ # ctag Generation # -if( CTAGS_EXECUTABLE ) +if ( CTAGS_EXECUTABLE ) # Populate list of directories for ctags to parse # NOTE: Doesn't support dots in the folder names... - foreach( filename ${SRCS} ) - string( REGEX REPLACE "/[a-zA-Z0-9_-]+.c$" "" pathglob ${filename} ) - file( GLOB filenames "${pathglob}/*.c" ) - set( CTAG_PATHS ${CTAG_PATHS} ${filenames} ) - file( GLOB filenames "${pathglob}/*.h" ) - set( CTAG_PATHS ${CTAG_PATHS} ${filenames} ) - endforeach() + foreach ( filename ${SRCS} ) + string ( REGEX REPLACE "/[a-zA-Z0-9_-]+.c$" "" pathglob ${filename} ) + file ( GLOB filenames "${pathglob}/*.c" ) + set ( CTAG_PATHS ${CTAG_PATHS} ${filenames} ) + file ( GLOB filenames "${pathglob}/*.h" ) + set ( CTAG_PATHS ${CTAG_PATHS} ${filenames} ) + endforeach () # Generate the ctags - execute_process( COMMAND ctags ${CTAG_PATHS} + execute_process ( COMMAND ctags ${CTAG_PATHS} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} ) -endif() +endif () diff -r ab4515606277 -r 4f47971c45c2 Lib/_buildvars.h --- a/Lib/_buildvars.h Sun Mar 08 18:40:01 2015 -0700 +++ b/Lib/_buildvars.h Sun Mar 08 20:17:39 2015 -0700 @@ -1,4 +1,4 @@ -/* Copyright (C) 2013-2014 by Jacob Alexander +/* Copyright (C) 2013-2015 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,6 +38,7 @@ #define CLI_Revision "@Git_Commit_Revision@" #define CLI_Branch "@Git_Branch_INFO@" #define CLI_ModifiedStatus "@Git_Modified_Status@" +#define CLI_ModifiedFiles "@Git_Modified_Files@" #define CLI_RepoOrigin "@Git_Origin_URL@" #define CLI_CommitDate "@Git_Date_INFO@" #define CLI_CommitAuthor @Git_Commit_Author@ diff -r ab4515606277 -r 4f47971c45c2 LoadFile/load.dfu --- a/LoadFile/load.dfu Sun Mar 08 18:40:01 2015 -0700 +++ b/LoadFile/load.dfu Sun Mar 08 20:17:39 2015 -0700 @@ -49,7 +49,7 @@ if [[ "$SERIAL_PORT" != "" ]] && [[ -e "$SERIAL_PORT" ]]; then echo "NOTE: This may fail if the uC is in a bad state or does not support remote flashing" printf "reload\r" > $SERIAL_PORT - sleep 1 + sleep 2 fi # Load via dfu-util diff -r ab4515606277 -r 4f47971c45c2 Macro/PartialMap/macro.c --- a/Macro/PartialMap/macro.c Sun Mar 08 18:40:01 2015 -0700 +++ b/Macro/PartialMap/macro.c Sun Mar 08 20:17:39 2015 -0700 @@ -1,4 +1,4 @@ -/* Copyright (C) 2014 by Jacob Alexander +/* Copyright (C) 2014-2015 by Jacob Alexander * * 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 @@ -121,9 +121,11 @@ uint16_t macroStepCounter = 0; -// Key Trigger List Buffer +// 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 TriggerGuide macroTriggerListBuffer[ MaxScanCode ]; uint8_t macroTriggerListBufferSize = 0; +var_uint_t macroTriggerListLayerCache[ MaxScanCode ]; // Pending Trigger Macro Index List // * Any trigger macros that need processing from a previous macro processing loop @@ -311,8 +313,24 @@ // Looks up the trigger list for the given scan code (from the active layer) // NOTE: Calling function must handle the NULL pointer case -nat_ptr_t *Macro_layerLookup( uint8_t scanCode, uint8_t latch_expire ) +nat_ptr_t *Macro_layerLookup( TriggerGuide *guide, uint8_t latch_expire ) { + 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 ]; + + return map[ scanCode - layer->first ]; + } + // If no trigger macro is defined at the given layer, fallthrough to the next layer for ( uint16_t layerIndex = 0; layerIndex < macroLayerIndexStackSize; layerIndex++ ) { @@ -342,6 +360,9 @@ && scanCode >= layer->first && *map[ scanCode - layer->first ] != 0 ) { + // Set the layer cache + macroTriggerListLayerCache[ scanCode ] = macroLayerIndexStack[ layerIndex ]; + return map[ scanCode - layer->first ]; } } @@ -359,6 +380,9 @@ && scanCode >= layer->first && *map[ scanCode - layer->first ] != 0 ) { + // Set the layer cache to default map + macroTriggerListLayerCache[ scanCode ] = 0; + return map[ scanCode - layer->first ]; } @@ -836,7 +860,7 @@ uint8_t latch_expire = macroTriggerListBuffer[ key ].state == 0x03; // Lookup Trigger List - nat_ptr_t *triggerList = Macro_layerLookup( macroTriggerListBuffer[ key ].scanCode, latch_expire ); + nat_ptr_t *triggerList = Macro_layerLookup( ¯oTriggerListBuffer[ key ], latch_expire ); // Number of Triggers in list nat_ptr_t triggerListSize = triggerList[0]; diff -r ab4515606277 -r 4f47971c45c2 Macro/PartialMap/usb_hid.h --- a/Macro/PartialMap/usb_hid.h Sun Mar 08 18:40:01 2015 -0700 +++ b/Macro/PartialMap/usb_hid.h Sun Mar 08 20:17:39 2015 -0700 @@ -1,4 +1,4 @@ -/* Copyright (C) 2011-2014 by Jacob Alexander +/* Copyright (C) 2011-2015 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -113,7 +113,7 @@ #define KEY_UP 0x52 #define KEY_NUM_LOCK 0x53 #define KEYPAD_SLASH 0x54 -#define KEYPAD_ASTERIX 0x55 +#define KEYPAD_ASTERISK 0x55 #define KEYPAD_MINUS 0x56 #define KEYPAD_PLUS 0x57 #define KEYPAD_ENTER 0x58 diff -r ab4515606277 -r 4f47971c45c2 Output/pjrcUSB/arm/usb_dev.c --- a/Output/pjrcUSB/arm/usb_dev.c Sun Mar 08 18:40:01 2015 -0700 +++ b/Output/pjrcUSB/arm/usb_dev.c Sun Mar 08 20:17:39 2015 -0700 @@ -300,7 +300,7 @@ data = reply_buffer; break; case 0x0082: // GET_STATUS (endpoint) - if (setup.wIndex > NUM_ENDPOINTS) + if ( setup.wIndex > NUM_ENDPOINTS ) { // TODO: do we need to handle IN vs OUT here? endpoint0_stall(); @@ -313,17 +313,31 @@ data = reply_buffer; datalen = 2; break; - case 0x0102: // CLEAR_FEATURE (endpoint) + case 0x0100: // CLEAR_FEATURE (device) + case 0x0101: // CLEAR_FEATURE (interface) + // TODO: Currently ignoring, perhaps useful? -HaaTa + endpoint0_stall(); + return; + case 0x0102: // CLEAR_FEATURE (interface) i = setup.wIndex & 0x7F; if ( i > NUM_ENDPOINTS || setup.wValue != 0 ) { - // TODO: do we need to handle IN vs OUT here? endpoint0_stall(); return; } - (*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) &= ~0x02; + //(*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) &= ~0x02; // TODO: do we need to clear the data toggle here? - break; + //break; + + // FIXME: Clearing causes keyboard to freeze, likely an invalid clear + // XXX: Ignoring seems to work, though this may not be the ideal behaviour -HaaTa + endpoint0_stall(); + return; + case 0x0300: // SET_FEATURE (device) + case 0x0301: // SET_FEATURE (interface) + // TODO: Currently ignoring, perhaps useful? -HaaTa + endpoint0_stall(); + return; case 0x0302: // SET_FEATURE (endpoint) i = setup.wIndex & 0x7F; if ( i > NUM_ENDPOINTS || setup.wValue != 0 ) diff -r ab4515606277 -r 4f47971c45c2 Output/pjrcUSB/arm/usb_keyboard.c --- a/Output/pjrcUSB/arm/usb_keyboard.c Sun Mar 08 18:40:01 2015 -0700 +++ b/Output/pjrcUSB/arm/usb_keyboard.c Sun Mar 08 20:17:39 2015 -0700 @@ -1,7 +1,7 @@ /* Teensyduino Core Library * http://www.pjrc.com/teensy/ * Copyright (c) 2013 PJRC.COM, LLC. - * Modifications by Jacob Alexander 2013-2014 + * Modifications by Jacob Alexander 2013-2015 * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -120,6 +120,23 @@ { // Send boot keyboard interrupt packet(s) case 0: + // USB Boot Mode debug output + if ( Output_DebugMode ) + { + dbug_msg("Boot USB: "); + printHex_op( USBKeys_Modifiers, 2 ); + print(" "); + printHex( 0 ); + print(" "); + printHex_op( USBKeys_Keys[0], 2 ); + printHex_op( USBKeys_Keys[1], 2 ); + printHex_op( USBKeys_Keys[2], 2 ); + printHex_op( USBKeys_Keys[3], 2 ); + printHex_op( USBKeys_Keys[4], 2 ); + printHex_op( USBKeys_Keys[5], 2 ); + print( NL ); + } + // Boot Mode *tx_buf++ = USBKeys_Modifiers; *tx_buf++ = 0; @@ -133,9 +150,21 @@ // Send NKRO keyboard interrupts packet(s) case 1: + if ( Output_DebugMode ) + { + dbug_msg("NKRO USB: "); + } + // Check system control keys if ( USBKeys_Changed & USBKeyChangeState_System ) { + if ( Output_DebugMode ) + { + print("SysCtrl["); + printHex_op( USBKeys_SysCtrl, 2 ); + print( "] " NL ); + } + *tx_buf++ = 0x02; // ID *tx_buf = USBKeys_SysCtrl; tx_packet->len = 2; @@ -148,6 +177,13 @@ // Check consumer control keys if ( USBKeys_Changed & USBKeyChangeState_Consumer ) { + if ( Output_DebugMode ) + { + print("ConsCtrl["); + printHex_op( USBKeys_ConsCtrl, 2 ); + print( "] " NL ); + } + *tx_buf++ = 0x03; // ID *tx_buf++ = (uint8_t)(USBKeys_ConsCtrl & 0x00FF); *tx_buf = (uint8_t)(USBKeys_ConsCtrl >> 8); @@ -161,6 +197,24 @@ // Standard HID Keyboard if ( USBKeys_Changed ) { + // USB NKRO Debug output + if ( Output_DebugMode ) + { + printHex_op( USBKeys_Modifiers, 2 ); + print(" "); + for ( uint8_t c = 0; c < 6; c++ ) + printHex_op( USBKeys_Keys[ c ], 2 ); + print(" "); + for ( uint8_t c = 6; c < 20; c++ ) + printHex_op( USBKeys_Keys[ c ], 2 ); + print(" "); + printHex_op( USBKeys_Keys[20], 2 ); + print(" "); + for ( uint8_t c = 21; c < 27; c++ ) + printHex_op( USBKeys_Keys[ c ], 2 ); + print( NL ); + } + tx_packet->len = 0; // Modifiers diff -r ab4515606277 -r 4f47971c45c2 Output/pjrcUSB/output_com.c --- a/Output/pjrcUSB/output_com.c Sun Mar 08 18:40:01 2015 -0700 +++ b/Output/pjrcUSB/output_com.c Sun Mar 08 20:17:39 2015 -0700 @@ -61,6 +61,7 @@ // ----- Function Declarations ----- void cliFunc_kbdProtocol( char* args ); +void cliFunc_outputDebug( char* args ); void cliFunc_readLEDs ( char* args ); void cliFunc_sendKeys ( char* args ); void cliFunc_setKeys ( char* args ); @@ -72,6 +73,7 @@ // Output Module command dictionary CLIDict_Entry( kbdProtocol, "Keyboard Protocol Mode: 0 - Boot, 1 - OS/NKRO Mode" ); +CLIDict_Entry( outputDebug, "Toggle Output Debug mode." ); CLIDict_Entry( readLEDs, "Read LED byte:" NL "\t\t1 NumLck, 2 CapsLck, 4 ScrlLck, 16 Kana, etc." ); CLIDict_Entry( sendKeys, "Send the prepared list of USB codes and modifier byte." ); CLIDict_Entry( setKeys, "Prepare a space separated list of USB codes (decimal). Waits until \033[35msendKeys\033[0m." ); @@ -79,6 +81,7 @@ CLIDict_Def( outputCLIDict, "USB Module Commands" ) = { CLIDict_Item( kbdProtocol ), + CLIDict_Item( outputDebug ), CLIDict_Item( readLEDs ), CLIDict_Item( sendKeys ), CLIDict_Item( setKeys ), @@ -129,6 +132,11 @@ // 0 is often used to show that a USB cable is not plugged in (but has power) uint8_t Output_Available = 0; +// Debug control variable for Output modules +// 0 - Debug disabled (default) +// 1 - Debug enabled + uint8_t Output_DebugMode = 0; + // ----- Capabilities ----- @@ -211,7 +219,10 @@ // Only send keypresses if press or hold state if ( stateType == 0x00 && state == 0x03 ) // Release state + { + USBKeys_ConsCtrl = 0; return; + } // Set consumer control code USBKeys_ConsCtrl = *(uint16_t*)(&args[0]); @@ -242,7 +253,10 @@ // Only send keypresses if press or hold state if ( stateType == 0x00 && state == 0x03 ) // Release state + { + USBKeys_SysCtrl = 0; return; + } // Set system control code USBKeys_SysCtrl = args[0]; @@ -584,6 +598,24 @@ } +void cliFunc_outputDebug( char* args ) +{ + // Parse number from argument + // NOTE: Only first argument is used + char* arg1Ptr; + char* arg2Ptr; + CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr ); + + // Default to 1 if no argument is given + Output_DebugMode = 1; + + if ( arg1Ptr[0] != '\0' ) + { + Output_DebugMode = (uint16_t)numToInt( arg1Ptr ); + } +} + + void cliFunc_readLEDs( char* args ) { print( NL ); diff -r ab4515606277 -r 4f47971c45c2 Output/pjrcUSB/output_com.h --- a/Output/pjrcUSB/output_com.h Sun Mar 08 18:40:01 2015 -0700 +++ b/Output/pjrcUSB/output_com.h Sun Mar 08 20:17:39 2015 -0700 @@ -81,6 +81,8 @@ extern uint8_t Output_Available; // 0 - Output module not fully functional, 1 - Output module working +extern uint8_t Output_DebugMode; // 0 - Debug disabled, 1 - Debug enabled + // ----- Capabilities ----- diff -r ab4515606277 -r 4f47971c45c2 Output/usbMuxUart/capabilities.kll --- a/Output/usbMuxUart/capabilities.kll Sun Mar 08 18:40:01 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -Name = usbMuxUartCapabilities; -Version = 0.1; -Author = "HaaTa (Jacob Alexander) 2014"; -KLL = 0.3; - -# Modified Date -Date = 2014-09-28; - - -# Capabilties available to the usbMuxUart output module -consCtrlOut => Output_consCtrlSend_capability( consCode : 2 ); -sysCtrlOut => Output_sysCtrlSend_capability( sysCode : 1 ); -usbKeyOut => Output_usbCodeSend_capability( usbCode : 1 ); - diff -r ab4515606277 -r 4f47971c45c2 Output/usbMuxUart/output_com.c --- a/Output/usbMuxUart/output_com.c Sun Mar 08 18:40:01 2015 -0700 +++ b/Output/usbMuxUart/output_com.c Sun Mar 08 20:17:39 2015 -0700 @@ -33,10 +33,10 @@ // USB Includes #if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) #elif defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) -#include -#include -#include -#include +#include +#include +#include +#include #endif // Local Includes @@ -135,10 +135,69 @@ // 0 is often used to show that a USB cable is not plugged in (but has power) uint8_t Output_Available = 0; +// Debug control variable for Output modules +// 0 - Debug disabled (default) +// 1 - Debug enabled + uint8_t Output_DebugMode = 0; + // ----- Capabilities ----- +// Set Boot Keyboard Protocol +void Output_kbdProtocolBoot_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +{ + // Display capability name + if ( stateType == 0xFF && state == 0xFF ) + { + print("Output_kbdProtocolBoot()"); + return; + } + + // Only set if necessary + if ( USBKeys_Protocol == 0 ) + return; + + // TODO Analog inputs + // Only set on key press + if ( stateType != 0x01 ) + return; + + // Flush the key buffers + Output_flushBuffers(); + + // Set the keyboard protocol to Boot Mode + USBKeys_Protocol = 0; +} + + +// Set NKRO Keyboard Protocol +void Output_kbdProtocolNKRO_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +{ + // Display capability name + if ( stateType == 0xFF && state == 0xFF ) + { + print("Output_kbdProtocolNKRO()"); + return; + } + + // Only set if necessary + if ( USBKeys_Protocol == 1 ) + return; + + // TODO Analog inputs + // Only set on key press + if ( stateType != 0x01 ) + return; + + // Flush the key buffers + Output_flushBuffers(); + + // Set the keyboard protocol to NKRO Mode + USBKeys_Protocol = 1; +} + + // Sends a Consumer Control code to the USB Output buffer void Output_consCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args ) { @@ -374,6 +433,20 @@ // ----- Functions ----- +// Flush Key buffers +void Output_flushBuffers() +{ + // Zero out USBKeys_Keys array + for ( uint8_t c = 0; c < USB_NKRO_BITFIELD_SIZE_KEYS; c++ ) + USBKeys_Keys[ c ] = 0; + + // Zero out other key buffers + USBKeys_ConsCtrl = 0; + USBKeys_Modifiers = 0; + USBKeys_SysCtrl = 0; +} + + // USB Module Setup inline void Output_setup() { diff -r ab4515606277 -r 4f47971c45c2 Output/usbMuxUart/output_com.h --- a/Output/usbMuxUart/output_com.h Sun Mar 08 18:40:01 2015 -0700 +++ b/Output/usbMuxUart/output_com.h Sun Mar 08 20:17:39 2015 -0700 @@ -80,6 +80,8 @@ extern uint8_t Output_Available; // 0 - Output module not fully functional, 1 - Output module working +extern uint8_t Output_DebugMode; // 0 - Debug disabled, 1 - Debug enabled + // ----- Capabilities ----- @@ -88,6 +90,10 @@ void Output_sysCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args ); void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *args ); +// Configuration capabilities +void Output_kbdProtocolBoot_capability( uint8_t state, uint8_t stateType, uint8_t *args ); +void Output_kbdProtocolNKRO_capability( uint8_t state, uint8_t stateType, uint8_t *args ); + // ----- Functions ----- @@ -95,6 +101,8 @@ void Output_setup(); void Output_send(); +void Output_flushBuffers(); + void Output_firmwareReload(); void Output_softReset(); diff -r ab4515606277 -r 4f47971c45c2 Output/usbMuxUart/setup.cmake --- a/Output/usbMuxUart/setup.cmake Sun Mar 08 18:40:01 2015 -0700 +++ b/Output/usbMuxUart/setup.cmake Sun Mar 08 20:17:39 2015 -0700 @@ -23,6 +23,12 @@ output_com.c ) +# Remove duplicate output_com.c files from pjrcUSB and uartOut +list ( REMOVE_ITEM Output_SRCS + Output/pjrcUSB/output_com.c + Output/uartOut/output_com.c +) + ### # Compiler Family Compatibility diff -r ab4515606277 -r 4f47971c45c2 README.markdown --- a/README.markdown Sun Mar 08 18:40:01 2015 -0700 +++ b/README.markdown Sun Mar 08 20:17:39 2015 -0700 @@ -9,8 +9,9 @@ Linux is the ideal build environment (preferably recent'ish). In the near future I'll make available an Arch Linux VM for building/manufacturing tests. -Building on Mac should be ok for 99% of users with Macports (haven't tried -Brew). The dfu Bootloader will not build correctly with the old version of +Building on Mac should be ok for 99% of users with Macports or Homebrew. For +Homebrew, use `brew tap PX4/homebrew-px4` to get the arm-none-eabi-gcc installer. +The dfu Bootloader will not build correctly with the old version of arm-none-eabi-gcc that Macports currently has (4.7.3). This is due to a bug with lto (link time optimizations) which makes the resulting binary too big to fit on the chip (must be less than 4096 Bytes). @@ -58,7 +59,7 @@ - Arch Linux / Mac Ports - arm-none-eabi-gcc - - arm-none-eaby-binutils + - arm-none-eabi-binutils - Windows (https://launchpad.net/gcc-arm-embedded/+download) - gcc-arm-none-eabi (win32.zip) @@ -262,6 +263,112 @@ easier to just edit the file. e.g. `cmake -DScanModuleOverride=`. +Keymap Configuration +-------------------- + +This is where you define the layout for your keyboard. +Currently, the only way to define kebyoard layouts is using [KLL](https://www.overleaf.com/read/zzqbdwqjfwwf). + +KLL is built up of 3 different kinds of keymaps in total. +The BaseMap, DefaultMap and PartialMaps. + +For each type of keymap, it is possible to combine multiple .kll files together to create new ones using +the compiler. The order of the files matter, as the right-most file will overwrite any setting in the +previous files. + +> NOTE: Each keymap is done after the entire file is processed. This means that within the file the order +> of assignment doesa *not* matter (if you assign the same thing twice, then yes the most recent one +> takes priority). + + +BaseMap defines what the keyboard can do. This includes specific capabilities of the keyboard (such as USB), +the mapping of Scan Codes to USB Codes and any specific configurations for the keyboard. +In general, the BaseMap rarely needs to be changed. Usually only when adding a new keyboard to the firmware +does the Basemap need any modification. +The BaseMap is what both DefaultMap and PartialMaps are based upon. This allows for a common reference +when defining custom keymappings. + +> NOTE: Don't use defaultMap.kll to change your layouts. This will work, but they will not be portable. + + +The DefaultMap is the normal state of the keyboard, i.e. your default layer. +Using the BaseMap as a base, the DefaultMap is a modification of the BaseMap to what the keyboard should do. +Since the DefaultMap uses USB Code to USB Code translations, this means that keymaps used for one keyboard +will work with another keyboard. +For example, I use Colemak, so this means I only have to define Colemak once for every keyboard that supports +the kiibohd firmware. This is possible because every BaseMap defines the keyboard as a US ANSI like keyboard +layout. +The DefaultMap can also be thought of as Layer 0. + + +PartialMaps are optional keymaps that can be "stacked" on top of the DefaultMap. +They can be dynamically swapped out using the layer control capabilities: + +- layerLatch( `` ) +- layerLock( `` ) +- layerShift( `` ) + +layerShift is usually what you want as it works just like a standard shift key. +layerLock is similar to the CapsLock key. While layerLatch is a latch, where only the next key you press +will use that layer (e.g. stickykeys). + +A unique aspect of KLL layers is that it's a true stack of layers. +When a layer is activated, only the keys that are specified by the layer will change. +This means, if you define a layer that only sets `CapsLock -> LCtrl` and `LCtrl->Capslock` only those keys +will change when you active the layer. All the other keys will use the layer that is "underneath" to +lookup the keypress (usually the DefaultMap). + +This means that you can combine .kll files statically using the compiler or dynamically using the firmware. + +You can set the max number of layers by changing the `stateWordSize` define in one of your kll files. +By default it is set to 8 in Macro/PartialMap/capabilities.kll. This means you can have up to 256 layers +total (this includes the DefaultMap). +You can increase this number to either 16 or 32 (this will use more Flash and RAM btw) which will give you +2^16 and 2^32 possible layers respectively (65 535 and 4 294 967 295). + + +```cmake +### +# Keymap Configuration (do not include the .kll extension) +# + +#| Do not include the .kll extension +#| * BaseMap maps the native keyboard scan codes to USB Codes so the layout is compatible with all other layouts +#| * DefaultMap allows the default keymap to be modified from the BaseMap +#| * PartialMaps is a set of dynamically set layers (there is no limit, but too many may use up too much RAM...) +#| BaseMap generally does not need to be changed from "defaultMap" +#| +#| Syntax: +#| myMap +#| * defines a single .kll layout file, double-quotes are needed to distinguish between layers +#| "myMap specialLayer" +#| * defines myMap to be the main layout, then replace specialLayers on top of it +#| +#| - Only for PartialMaps - +#| "myMap specialLayer" "myMap colemak" dvorak +#| * As before, but also generates a second layer at index 2 and third at index 3 +#| +#| NOTE: Remember to add key(s) to enable each Partial Layer +#| NOTE2: Layers are always based up the BaseMap (which should be an ANSI-like mapping) +#| NOTE3: Compiler looks in kll/layouts and the build directory for layout files (precedence on build directory) + +##| Set the base keyboard .kll map, defaults to "defaultMap" if not found +##| Looks in Scan/ for the available BaseMaps +set( BaseMap "defaultMap" + CACHE STRING "KLL BaseMap/Scancode Keymapping" ) + +##| Layer additonal .kll maps on the BaseMap, layers are in order from 1st to nth +##| Can be set to "" +set( DefaultMap "md1Overlay stdFuncMap" + CACHE STRING "KLL DefaultMap" ) + +##| ParitalMaps available on top of the BaseMap. See above for syntax on specifying multiple layers vs. layering +##| Can be set to "" +set( PartialMaps "hhkbpro2" + CACHE STRING "KLL PartialMaps/Layer Definitions" ) +``` + + Linux Building -------------- diff -r ab4515606277 -r 4f47971c45c2 Scan/MatrixARM/capabilities.kll --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Scan/MatrixARM/capabilities.kll Sun Mar 08 20:17:39 2015 -0700 @@ -0,0 +1,34 @@ +Name = MatrixArmCapabilities; +Version = 0.1; +Author = "HaaTa (Jacob Alexander) 2015"; +KLL = 0.3a; + +# Modified Date +Date = 2015-02-28; + +# Defines available to the MatrixArm sub-module +# This debounce scheme uses a rolling counter for press/unpress on each key +# Each counter is incremented if pressed/unpressed and the opposite counter is divided by 2 +# Using the default division threshold (0xFFFF), there are approximately 13 cycles in a perfect cycle +# If debounce is actually necessary, this will increase (better switches will debounce faster) +# +# The maximum threshold is 0xFFFFFFFF, which will give around ~32 -> 36 cycles per perfect cycle +# Using a threshold higher than 0xFFFF will require 32 bit variables, and double the ram usage. +DebounceDivThreshold => DebounceDivThreshold_define; +DebounceDivThreshold = 0xFFFF; # Default debounce +#DebounceDivThreshold = 0xFFFFFFFF; # Max debounce + +# This defines how often the matrix is scanned +# By, default the key matrix is scanned once per macro processing loop +# For fast uCs and bouncy switches, this can be non-ideal +# 0 - Bit-shift of 0 +# 1 - Bit-shift of 1 (i.e. divide by 2) +# 2 - Bit-shift of 2 (i.e. divide by 4) +# 3 - Bit-shift of 3 (i.e. divide by 8) +# etc. +# Depending on the architecture, this is either a maximum of 16 or 32 +# Increasing this value will increase switch latency +DebounceThrottleDiv => DebounceThrottleDiv_define; +DebounceThrottleDiv = 0; # Default +#DebounceThrottleDiv = 2; # /4 divider + diff -r ab4515606277 -r 4f47971c45c2 Scan/MatrixARM/matrix_scan.c --- a/Scan/MatrixARM/matrix_scan.c Sun Mar 08 18:40:01 2015 -0700 +++ b/Scan/MatrixARM/matrix_scan.c Sun Mar 08 20:17:39 2015 -0700 @@ -1,4 +1,4 @@ -/* Copyright (C) 2014 by Jacob Alexander +/* Copyright (C) 2014-2015 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,6 +26,7 @@ // Project Includes #include +#include #include #include #include @@ -38,6 +39,14 @@ +// ----- Defines ----- + +#if ( DebounceThrottleDiv_define > 0 ) +nat_ptr_t Matrix_divCounter = 0; +#endif + + + // ----- Function Declarations ----- // CLI Functions @@ -191,7 +200,7 @@ Matrix_scanArray[ item ].prevState = KeyState_Off; Matrix_scanArray[ item ].curState = KeyState_Off; Matrix_scanArray[ item ].activeCount = 0; - Matrix_scanArray[ item ].inactiveCount = 0xFFFF; // Start at 'off' steady state + Matrix_scanArray[ item ].inactiveCount = DebounceDivThreshold_define; // Start at 'off' steady state } // Clear scan stats counters @@ -232,6 +241,15 @@ // NOTE: scanNum should be reset to 0 after a USB send (to reset all the counters) void Matrix_scan( uint16_t scanNum ) { +#if ( DebounceThrottleDiv_define > 0 ) + // Scan-rate throttling + // By scanning using a divider, the scan rate slowed down + // DebounceThrottleDiv_define == 1 means -> /2 or half scan rate + // This helps with bouncy switches on fast uCs + if ( !( Matrix_divCounter++ & (1 << ( DebounceThrottleDiv_define - 1 )) ) ) + return; +#endif + // Increment stats counters if ( scanNum > matrixMaxScans ) matrixMaxScans = scanNum; if ( scanNum == 0 ) @@ -275,14 +293,14 @@ if ( Matrix_pin( Matrix_rows[ sense ], Type_Sense ) ) { // Only update if not going to wrap around - if ( state->activeCount < 0xFFFF ) state->activeCount += 1; + if ( state->activeCount < DebounceDivThreshold_define ) state->activeCount += 1; state->inactiveCount >>= 1; } // Signal Not Detected else { // Only update if not going to wrap around - if ( state->inactiveCount < 0xFFFF ) state->inactiveCount += 1; + if ( state->inactiveCount < DebounceDivThreshold_define ) state->inactiveCount += 1; state->activeCount >>= 1; } diff -r ab4515606277 -r 4f47971c45c2 Scan/MatrixARM/matrix_scan.h --- a/Scan/MatrixARM/matrix_scan.h Sun Mar 08 18:40:01 2015 -0700 +++ b/Scan/MatrixARM/matrix_scan.h Sun Mar 08 20:17:39 2015 -0700 @@ -1,4 +1,4 @@ -/* Copyright (C) 2014 by Jacob Alexander +/* Copyright (C) 2014-2015 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,6 +24,23 @@ // ----- Includes ----- +// KLL Generated Defines +#include + + + +// ----- Defines ----- + +#if ( DebounceDivThreshold_define < 0xFF + 1 ) +#define DebounceCounter uint8_t +#elif ( DebounceDivThreshold_define < 0xFFFF + 1 ) +#define DebounceCounter uint16_t +#elif ( DebounceDivThreshold_define < 0xFFFFFFFF + 1 ) +#define DebounceCounter uint32_t +#else +#error "Debounce threshold is too high... 32 bit max. Check .kll defines." +#endif + // ----- Enums ----- @@ -110,10 +127,10 @@ // Debounce Element typedef struct KeyState { - KeyPosition prevState; - KeyPosition curState; - uint16_t activeCount; - uint16_t inactiveCount; + KeyPosition prevState; + KeyPosition curState; + DebounceCounter activeCount; + DebounceCounter inactiveCount; } KeyState;