Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
2922fce0f7
@ -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 @@ void cliFunc_version( char* args )
|
||||
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 );
|
||||
|
40
Lib/CMake/FindDFUSuffix.cmake
Normal file
40
Lib/CMake/FindDFUSuffix.cmake
Normal file
@ -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
|
||||
)
|
||||
|
@ -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 @@ endif ()
|
||||
|
||||
|
||||
#| 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 ()
|
||||
|
||||
|
||||
|
@ -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 @@ endif () # kll/kll.py exists
|
||||
|
||||
#| 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 @@ endforeach ()
|
||||
#
|
||||
|
||||
#| 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} )
|
||||
|
||||
|
@ -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 @@ function ( AddModule ModuleType ModuleName )
|
||||
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 @@ function ( AddModule ModuleType ModuleName )
|
||||
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 @@ find_package ( Ctags ) # Optional
|
||||
#
|
||||
|
||||
#| Manufacturer name
|
||||
set( MANUFACTURER "Kiibohd" )
|
||||
set ( MANUFACTURER "Kiibohd" )
|
||||
|
||||
|
||||
#| Serial Number
|
||||
@ -158,19 +165,29 @@ set( MANUFACTURER "Kiibohd" )
|
||||
|
||||
#| 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 @@ execute_process( COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD
|
||||
)
|
||||
|
||||
#| 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 @@ execute_process( COMMAND ${GIT_EXECUTABLE} show -s --format=%ci
|
||||
)
|
||||
|
||||
#| 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 @@ execute_process( COMMAND ${GIT_EXECUTABLE} show -s --format="%cn <%ce>"
|
||||
)
|
||||
|
||||
#| 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 @@ execute_process( COMMAND ${GIT_EXECUTABLE} show -s --format=%H
|
||||
)
|
||||
|
||||
#| 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 @@ execute_process( COMMAND ${GIT_EXECUTABLE} config --get remote.origin.url
|
||||
)
|
||||
|
||||
#| 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 @@ set( SRCS
|
||||
)
|
||||
|
||||
#| 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 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} )
|
||||
# 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 ()
|
||||
|
||||
|
@ -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@
|
||||
|
@ -49,7 +49,7 @@ done
|
||||
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
|
||||
|
@ -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 @@ uint8_t macroPauseMode = 0;
|
||||
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 @@ void Macro_layerShift_capability( uint8_t state, uint8_t stateType, uint8_t *arg
|
||||
|
||||
// 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 @@ nat_ptr_t *Macro_layerLookup( uint8_t scanCode, uint8_t latch_expire )
|
||||
&& 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 @@ nat_ptr_t *Macro_layerLookup( uint8_t scanCode, uint8_t latch_expire )
|
||||
&& 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 @@ inline void Macro_updateTriggerMacroPendingList()
|
||||
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];
|
||||
|
@ -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
|
||||
|
@ -300,7 +300,7 @@ static void usb_setup()
|
||||
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 @@ static void usb_setup()
|
||||
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 )
|
||||
|
@ -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 @@ void usb_keyboard_send()
|
||||
{
|
||||
// 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 @@ void usb_keyboard_send()
|
||||
|
||||
// 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 @@ void usb_keyboard_send()
|
||||
// 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 @@ void usb_keyboard_send()
|
||||
// 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
|
||||
|
@ -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 @@ void cliFunc_setMod ( char* args );
|
||||
|
||||
// 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_Entry( setMod, "Set the modfier byte:" NL "\t\t1 LCtrl, 2 LShft, 4
|
||||
|
||||
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 @@ USBKeyChangeState USBKeys_Changed = USBKeyChangeState_None;
|
||||
// 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 @@ void Output_consCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *
|
||||
|
||||
// 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 @@ void Output_sysCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *a
|
||||
|
||||
// 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_kbdProtocol( char* args )
|
||||
}
|
||||
|
||||
|
||||
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 );
|
||||
|
@ -81,6 +81,8 @@ extern USBKeyChangeState USBKeys_Changed;
|
||||
|
||||
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 -----
|
||||
|
@ -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 );
|
||||
|
@ -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 <uartOut/arm/uart_serial.h>
|
||||
#include <pjrcUSB/arm/usb_dev.h>
|
||||
#include <pjrcUSB/arm/usb_keyboard.h>
|
||||
#include <pjrcUSB/arm/usb_serial.h>
|
||||
#include <arm/uart_serial.h>
|
||||
#include <arm/usb_dev.h>
|
||||
#include <arm/usb_keyboard.h>
|
||||
#include <arm/usb_serial.h>
|
||||
#endif
|
||||
|
||||
// Local Includes
|
||||
@ -135,10 +135,69 @@ USBKeyChangeState USBKeys_Changed = USBKeyChangeState_None;
|
||||
// 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 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a
|
||||
|
||||
// ----- 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()
|
||||
{
|
||||
|
@ -80,6 +80,8 @@ extern USBKeyChangeState USBKeys_Changed;
|
||||
|
||||
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_consCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *
|
||||
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_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a
|
||||
void Output_setup();
|
||||
void Output_send();
|
||||
|
||||
void Output_flushBuffers();
|
||||
|
||||
void Output_firmwareReload();
|
||||
void Output_softReset();
|
||||
|
||||
|
@ -23,6 +23,12 @@ set( Module_SRCS
|
||||
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
|
||||
|
113
README.markdown
113
README.markdown
@ -9,8 +9,9 @@ Teensy 3.0/3.1, McHCK).
|
||||
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 @@ ARM Specific (Teensy 3.0/3.1, Infinity Keyboard, McHCK)
|
||||
|
||||
- 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 @@ There are also CMake options for temporarily selecting modules. But it's
|
||||
easier to just edit the file. e.g. `cmake -DScanModuleOverride=<module name>`.
|
||||
|
||||
|
||||
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( `<layer number>` )
|
||||
- layerLock( `<layer number>` )
|
||||
- layerShift( `<layer number>` )
|
||||
|
||||
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/<Module Name> 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
|
||||
--------------
|
||||
|
||||
|
34
Scan/MatrixARM/capabilities.kll
Normal file
34
Scan/MatrixARM/capabilities.kll
Normal file
@ -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
|
||||
|
@ -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 <cli.h>
|
||||
#include <kll.h>
|
||||
#include <led.h>
|
||||
#include <print.h>
|
||||
#include <macro.h>
|
||||
@ -38,6 +39,14 @@
|
||||
|
||||
|
||||
|
||||
// ----- Defines -----
|
||||
|
||||
#if ( DebounceThrottleDiv_define > 0 )
|
||||
nat_ptr_t Matrix_divCounter = 0;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// ----- Function Declarations -----
|
||||
|
||||
// CLI Functions
|
||||
@ -191,7 +200,7 @@ void Matrix_setup()
|
||||
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 @@ void Matrix_keyPositionDebug( KeyPosition pos )
|
||||
// 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 @@ void Matrix_scan( uint16_t scanNum )
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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 <kll_defs.h>
|
||||
|
||||
|
||||
|
||||
// ----- 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 @@ typedef struct GPIO_Pin {
|
||||
|
||||
// Debounce Element
|
||||
typedef struct KeyState {
|
||||
KeyPosition prevState;
|
||||
KeyPosition curState;
|
||||
uint16_t activeCount;
|
||||
uint16_t inactiveCount;
|
||||
KeyPosition prevState;
|
||||
KeyPosition curState;
|
||||
DebounceCounter activeCount;
|
||||
DebounceCounter inactiveCount;
|
||||
} KeyState;
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user