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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -422,7 +422,7 @@ void cliFunc_version( char* args )
|
|||||||
print( NL );
|
print( NL );
|
||||||
print( " \033[1mRevision:\033[0m " CLI_Revision NL );
|
print( " \033[1mRevision:\033[0m " CLI_Revision NL );
|
||||||
print( " \033[1mBranch:\033[0m " CLI_Branch 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[1mRepo Origin:\033[0m " CLI_RepoOrigin NL );
|
||||||
print( " \033[1mCommit Date:\033[0m " CLI_CommitDate NL );
|
print( " \033[1mCommit Date:\033[0m " CLI_CommitDate NL );
|
||||||
print( " \033[1mCommit Author:\033[0m " CLI_CommitAuthor 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 |###
|
###| 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
|
# Released into the Public Domain
|
||||||
#
|
#
|
||||||
@ -46,13 +46,26 @@ endif ()
|
|||||||
|
|
||||||
|
|
||||||
#| Convert the .ELF into a .bin to load onto the McHCK
|
#| Convert the .ELF into a .bin to load onto the McHCK
|
||||||
|
#| Then sign using dfu-suffix (requries dfu-util)
|
||||||
if ( DEFINED DFU )
|
if ( DEFINED DFU )
|
||||||
|
# dfu-suffix is required to sign the dfu binary
|
||||||
|
find_package ( DFUSuffix )
|
||||||
|
|
||||||
set( TARGET_BIN ${TARGET}.dfu.bin )
|
set( TARGET_BIN ${TARGET}.dfu.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
|
add_custom_command( TARGET ${TARGET_ELF} POST_BUILD
|
||||||
COMMAND ${OBJ_COPY} ${BIN_FLAGS} ${TARGET_ELF} ${TARGET_BIN}
|
COMMAND ${OBJ_COPY} ${BIN_FLAGS} ${TARGET_ELF} ${TARGET_BIN}
|
||||||
COMMENT "Creating dfu binary file: ${TARGET_BIN}"
|
COMMENT "Creating dfu binary file: ${TARGET_BIN}"
|
||||||
)
|
)
|
||||||
endif ()
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
|
||||||
#| Convert the .ELF into a .HEX to load onto the Teensy
|
#| Convert the .ELF into a .HEX to load onto the Teensy
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
###| CMAKE Kiibohd Controller KLL Configurator |###
|
###| 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
|
# 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
|
#| 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
|
#| Add each of the detected capabilities.kll
|
||||||
foreach ( DIR ${ScanModulePath} ${MacroModulePath} ${OutputModulePath} ${DebugModulePath} )
|
foreach ( filename ${ScanModule_KLL} ${MacroModule_KLL} ${OutputModule_KLL} ${DebugModule_KLL} )
|
||||||
# capabilities.kll exists, add to BaseMap
|
|
||||||
set ( filename "${PROJECT_SOURCE_DIR}/${DIR}/capabilities.kll" )
|
|
||||||
if ( EXISTS ${filename} )
|
|
||||||
set ( BaseMap_Args ${BaseMap_Args} ${filename} )
|
set ( BaseMap_Args ${BaseMap_Args} ${filename} )
|
||||||
set ( KLL_DEPENDS ${KLL_DEPENDS} ${filename} )
|
set ( KLL_DEPENDS ${KLL_DEPENDS} ${filename} )
|
||||||
endif ()
|
|
||||||
endforeach ()
|
endforeach ()
|
||||||
|
|
||||||
#| If set BaseMap cannot be found, use default map
|
#| If set BaseMap cannot be found, use default map
|
||||||
@ -118,21 +114,25 @@ endforeach ()
|
|||||||
#
|
#
|
||||||
|
|
||||||
#| KLL Options
|
#| KLL Options
|
||||||
set ( kll_backend -b kiibohd )
|
set ( kll_backend --backend kiibohd )
|
||||||
set ( kll_template -t ${PROJECT_SOURCE_DIR}/kll/templates/kiibohdKeymap.h )
|
set ( kll_template --templates ${PROJECT_SOURCE_DIR}/kll/templates/kiibohdKeymap.h ${PROJECT_SOURCE_DIR}/kll/templates/kiibohdDefs.h )
|
||||||
set ( kll_outputname generatedKeymap.h )
|
set ( kll_outputname generatedKeymap.h kll_defs.h )
|
||||||
set ( kll_output -o ${kll_outputname} )
|
set ( kll_output --outputs ${kll_outputname} )
|
||||||
set ( kll_define_output --defines-output kll_defs.h )
|
|
||||||
set ( kll_define_template --defines-template ${PROJECT_SOURCE_DIR}/kll/templates/kiibohdDefs.h )
|
|
||||||
|
|
||||||
#| KLL Cmd
|
#| 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}
|
add_custom_command ( OUTPUT ${kll_outputname}
|
||||||
COMMAND ${kll_cmd}
|
COMMAND ${kll_cmd}
|
||||||
DEPENDS ${KLL_DEPENDS}
|
DEPENDS ${KLL_DEPENDS}
|
||||||
COMMENT "Generating KLL Layout"
|
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
|
#| Append generated file to required sources so it becomes a dependency in the main build
|
||||||
set ( SRCS ${SRCS} ${kll_outputname} )
|
set ( SRCS ${SRCS} ${kll_outputname} )
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
###| CMAKE Kiibohd Controller Source Configurator |###
|
###| 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
|
# Released into the Public Domain
|
||||||
#
|
#
|
||||||
@ -104,10 +104,8 @@ function ( AddModule ModuleType ModuleName )
|
|||||||
PathPrepend ( Module_SRCS ${ModulePath} ${Module_SRCS} )
|
PathPrepend ( Module_SRCS ${ModulePath} ${Module_SRCS} )
|
||||||
|
|
||||||
# Check the current scope to see if a sub-module added some source files
|
# 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
|
# 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 .h files
|
||||||
add_definitions ( -I${ModuleFullPath} )
|
add_definitions ( -I${ModuleFullPath} )
|
||||||
@ -124,8 +122,17 @@ function ( AddModule ModuleType ModuleName )
|
|||||||
endif ()
|
endif ()
|
||||||
endforeach ()
|
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}_SRCS ${${ModuleType}_SRCS} PARENT_SCOPE )
|
||||||
|
set ( ${ModuleType}Module_KLL ${${ModuleType}Module_KLL} PARENT_SCOPE )
|
||||||
endfunction ()
|
endfunction ()
|
||||||
|
|
||||||
|
|
||||||
@ -171,6 +178,16 @@ if ( ${Git_Modified_LENGTH} GREATER 2 )
|
|||||||
set ( Git_Modified_Status "Dirty" )
|
set ( Git_Modified_Status "Dirty" )
|
||||||
endif ()
|
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
|
#| Branch
|
||||||
execute_process( COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD
|
execute_process( COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD
|
||||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||||
|
@ -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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -38,6 +38,7 @@
|
|||||||
#define CLI_Revision "@Git_Commit_Revision@"
|
#define CLI_Revision "@Git_Commit_Revision@"
|
||||||
#define CLI_Branch "@Git_Branch_INFO@"
|
#define CLI_Branch "@Git_Branch_INFO@"
|
||||||
#define CLI_ModifiedStatus "@Git_Modified_Status@"
|
#define CLI_ModifiedStatus "@Git_Modified_Status@"
|
||||||
|
#define CLI_ModifiedFiles "@Git_Modified_Files@"
|
||||||
#define CLI_RepoOrigin "@Git_Origin_URL@"
|
#define CLI_RepoOrigin "@Git_Origin_URL@"
|
||||||
#define CLI_CommitDate "@Git_Date_INFO@"
|
#define CLI_CommitDate "@Git_Date_INFO@"
|
||||||
#define CLI_CommitAuthor @Git_Commit_Author@
|
#define CLI_CommitAuthor @Git_Commit_Author@
|
||||||
|
@ -49,7 +49,7 @@ done
|
|||||||
if [[ "$SERIAL_PORT" != "" ]] && [[ -e "$SERIAL_PORT" ]]; then
|
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"
|
echo "NOTE: This may fail if the uC is in a bad state or does not support remote flashing"
|
||||||
printf "reload\r" > $SERIAL_PORT
|
printf "reload\r" > $SERIAL_PORT
|
||||||
sleep 1
|
sleep 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Load via dfu-util
|
# 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
|
* 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
|
* 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;
|
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 ];
|
TriggerGuide macroTriggerListBuffer[ MaxScanCode ];
|
||||||
uint8_t macroTriggerListBufferSize = 0;
|
uint8_t macroTriggerListBufferSize = 0;
|
||||||
|
var_uint_t macroTriggerListLayerCache[ MaxScanCode ];
|
||||||
|
|
||||||
// Pending Trigger Macro Index List
|
// Pending Trigger Macro Index List
|
||||||
// * Any trigger macros that need processing from a previous macro processing loop
|
// * 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)
|
// Looks up the trigger list for the given scan code (from the active layer)
|
||||||
// NOTE: Calling function must handle the NULL pointer case
|
// 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
|
// If no trigger macro is defined at the given layer, fallthrough to the next layer
|
||||||
for ( uint16_t layerIndex = 0; layerIndex < macroLayerIndexStackSize; layerIndex++ )
|
for ( uint16_t layerIndex = 0; layerIndex < macroLayerIndexStackSize; layerIndex++ )
|
||||||
{
|
{
|
||||||
@ -342,6 +360,9 @@ nat_ptr_t *Macro_layerLookup( uint8_t scanCode, uint8_t latch_expire )
|
|||||||
&& scanCode >= layer->first
|
&& scanCode >= layer->first
|
||||||
&& *map[ scanCode - layer->first ] != 0 )
|
&& *map[ scanCode - layer->first ] != 0 )
|
||||||
{
|
{
|
||||||
|
// Set the layer cache
|
||||||
|
macroTriggerListLayerCache[ scanCode ] = macroLayerIndexStack[ layerIndex ];
|
||||||
|
|
||||||
return map[ scanCode - layer->first ];
|
return map[ scanCode - layer->first ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -359,6 +380,9 @@ nat_ptr_t *Macro_layerLookup( uint8_t scanCode, uint8_t latch_expire )
|
|||||||
&& scanCode >= layer->first
|
&& scanCode >= layer->first
|
||||||
&& *map[ scanCode - layer->first ] != 0 )
|
&& *map[ scanCode - layer->first ] != 0 )
|
||||||
{
|
{
|
||||||
|
// Set the layer cache to default map
|
||||||
|
macroTriggerListLayerCache[ scanCode ] = 0;
|
||||||
|
|
||||||
return map[ scanCode - layer->first ];
|
return map[ scanCode - layer->first ];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -836,7 +860,7 @@ inline void Macro_updateTriggerMacroPendingList()
|
|||||||
uint8_t latch_expire = macroTriggerListBuffer[ key ].state == 0x03;
|
uint8_t latch_expire = macroTriggerListBuffer[ key ].state == 0x03;
|
||||||
|
|
||||||
// Lookup Trigger List
|
// 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
|
// Number of Triggers in list
|
||||||
nat_ptr_t triggerListSize = triggerList[0];
|
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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -113,7 +113,7 @@
|
|||||||
#define KEY_UP 0x52
|
#define KEY_UP 0x52
|
||||||
#define KEY_NUM_LOCK 0x53
|
#define KEY_NUM_LOCK 0x53
|
||||||
#define KEYPAD_SLASH 0x54
|
#define KEYPAD_SLASH 0x54
|
||||||
#define KEYPAD_ASTERIX 0x55
|
#define KEYPAD_ASTERISK 0x55
|
||||||
#define KEYPAD_MINUS 0x56
|
#define KEYPAD_MINUS 0x56
|
||||||
#define KEYPAD_PLUS 0x57
|
#define KEYPAD_PLUS 0x57
|
||||||
#define KEYPAD_ENTER 0x58
|
#define KEYPAD_ENTER 0x58
|
||||||
|
@ -313,17 +313,31 @@ static void usb_setup()
|
|||||||
data = reply_buffer;
|
data = reply_buffer;
|
||||||
datalen = 2;
|
datalen = 2;
|
||||||
break;
|
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;
|
i = setup.wIndex & 0x7F;
|
||||||
if ( i > NUM_ENDPOINTS || setup.wValue != 0 )
|
if ( i > NUM_ENDPOINTS || setup.wValue != 0 )
|
||||||
{
|
{
|
||||||
// TODO: do we need to handle IN vs OUT here?
|
|
||||||
endpoint0_stall();
|
endpoint0_stall();
|
||||||
return;
|
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?
|
// 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)
|
case 0x0302: // SET_FEATURE (endpoint)
|
||||||
i = setup.wIndex & 0x7F;
|
i = setup.wIndex & 0x7F;
|
||||||
if ( i > NUM_ENDPOINTS || setup.wValue != 0 )
|
if ( i > NUM_ENDPOINTS || setup.wValue != 0 )
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* Teensyduino Core Library
|
/* Teensyduino Core Library
|
||||||
* http://www.pjrc.com/teensy/
|
* http://www.pjrc.com/teensy/
|
||||||
* Copyright (c) 2013 PJRC.COM, LLC.
|
* 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
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
@ -120,6 +120,23 @@ void usb_keyboard_send()
|
|||||||
{
|
{
|
||||||
// Send boot keyboard interrupt packet(s)
|
// Send boot keyboard interrupt packet(s)
|
||||||
case 0:
|
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
|
// Boot Mode
|
||||||
*tx_buf++ = USBKeys_Modifiers;
|
*tx_buf++ = USBKeys_Modifiers;
|
||||||
*tx_buf++ = 0;
|
*tx_buf++ = 0;
|
||||||
@ -133,9 +150,21 @@ void usb_keyboard_send()
|
|||||||
|
|
||||||
// Send NKRO keyboard interrupts packet(s)
|
// Send NKRO keyboard interrupts packet(s)
|
||||||
case 1:
|
case 1:
|
||||||
|
if ( Output_DebugMode )
|
||||||
|
{
|
||||||
|
dbug_msg("NKRO USB: ");
|
||||||
|
}
|
||||||
|
|
||||||
// Check system control keys
|
// Check system control keys
|
||||||
if ( USBKeys_Changed & USBKeyChangeState_System )
|
if ( USBKeys_Changed & USBKeyChangeState_System )
|
||||||
{
|
{
|
||||||
|
if ( Output_DebugMode )
|
||||||
|
{
|
||||||
|
print("SysCtrl[");
|
||||||
|
printHex_op( USBKeys_SysCtrl, 2 );
|
||||||
|
print( "] " NL );
|
||||||
|
}
|
||||||
|
|
||||||
*tx_buf++ = 0x02; // ID
|
*tx_buf++ = 0x02; // ID
|
||||||
*tx_buf = USBKeys_SysCtrl;
|
*tx_buf = USBKeys_SysCtrl;
|
||||||
tx_packet->len = 2;
|
tx_packet->len = 2;
|
||||||
@ -148,6 +177,13 @@ void usb_keyboard_send()
|
|||||||
// Check consumer control keys
|
// Check consumer control keys
|
||||||
if ( USBKeys_Changed & USBKeyChangeState_Consumer )
|
if ( USBKeys_Changed & USBKeyChangeState_Consumer )
|
||||||
{
|
{
|
||||||
|
if ( Output_DebugMode )
|
||||||
|
{
|
||||||
|
print("ConsCtrl[");
|
||||||
|
printHex_op( USBKeys_ConsCtrl, 2 );
|
||||||
|
print( "] " NL );
|
||||||
|
}
|
||||||
|
|
||||||
*tx_buf++ = 0x03; // ID
|
*tx_buf++ = 0x03; // ID
|
||||||
*tx_buf++ = (uint8_t)(USBKeys_ConsCtrl & 0x00FF);
|
*tx_buf++ = (uint8_t)(USBKeys_ConsCtrl & 0x00FF);
|
||||||
*tx_buf = (uint8_t)(USBKeys_ConsCtrl >> 8);
|
*tx_buf = (uint8_t)(USBKeys_ConsCtrl >> 8);
|
||||||
@ -161,6 +197,24 @@ void usb_keyboard_send()
|
|||||||
// Standard HID Keyboard
|
// Standard HID Keyboard
|
||||||
if ( USBKeys_Changed )
|
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;
|
tx_packet->len = 0;
|
||||||
|
|
||||||
// Modifiers
|
// Modifiers
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
// ----- Function Declarations -----
|
// ----- Function Declarations -----
|
||||||
|
|
||||||
void cliFunc_kbdProtocol( char* args );
|
void cliFunc_kbdProtocol( char* args );
|
||||||
|
void cliFunc_outputDebug( char* args );
|
||||||
void cliFunc_readLEDs ( char* args );
|
void cliFunc_readLEDs ( char* args );
|
||||||
void cliFunc_sendKeys ( char* args );
|
void cliFunc_sendKeys ( char* args );
|
||||||
void cliFunc_setKeys ( char* args );
|
void cliFunc_setKeys ( char* args );
|
||||||
@ -72,6 +73,7 @@ void cliFunc_setMod ( char* args );
|
|||||||
|
|
||||||
// Output Module command dictionary
|
// Output Module command dictionary
|
||||||
CLIDict_Entry( kbdProtocol, "Keyboard Protocol Mode: 0 - Boot, 1 - OS/NKRO Mode" );
|
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( 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( 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." );
|
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_Def( outputCLIDict, "USB Module Commands" ) = {
|
||||||
CLIDict_Item( kbdProtocol ),
|
CLIDict_Item( kbdProtocol ),
|
||||||
|
CLIDict_Item( outputDebug ),
|
||||||
CLIDict_Item( readLEDs ),
|
CLIDict_Item( readLEDs ),
|
||||||
CLIDict_Item( sendKeys ),
|
CLIDict_Item( sendKeys ),
|
||||||
CLIDict_Item( setKeys ),
|
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)
|
// 0 is often used to show that a USB cable is not plugged in (but has power)
|
||||||
uint8_t Output_Available = 0;
|
uint8_t Output_Available = 0;
|
||||||
|
|
||||||
|
// Debug control variable for Output modules
|
||||||
|
// 0 - Debug disabled (default)
|
||||||
|
// 1 - Debug enabled
|
||||||
|
uint8_t Output_DebugMode = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----- Capabilities -----
|
// ----- 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
|
// Only send keypresses if press or hold state
|
||||||
if ( stateType == 0x00 && state == 0x03 ) // Release state
|
if ( stateType == 0x00 && state == 0x03 ) // Release state
|
||||||
|
{
|
||||||
|
USBKeys_ConsCtrl = 0;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Set consumer control code
|
// Set consumer control code
|
||||||
USBKeys_ConsCtrl = *(uint16_t*)(&args[0]);
|
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
|
// Only send keypresses if press or hold state
|
||||||
if ( stateType == 0x00 && state == 0x03 ) // Release state
|
if ( stateType == 0x00 && state == 0x03 ) // Release state
|
||||||
|
{
|
||||||
|
USBKeys_SysCtrl = 0;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Set system control code
|
// Set system control code
|
||||||
USBKeys_SysCtrl = args[0];
|
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 )
|
void cliFunc_readLEDs( char* args )
|
||||||
{
|
{
|
||||||
print( NL );
|
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_Available; // 0 - Output module not fully functional, 1 - Output module working
|
||||||
|
|
||||||
|
extern uint8_t Output_DebugMode; // 0 - Debug disabled, 1 - Debug enabled
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----- Capabilities -----
|
// ----- 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
|
// USB Includes
|
||||||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_)
|
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_)
|
||||||
#elif defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_)
|
#elif defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_)
|
||||||
#include <uartOut/arm/uart_serial.h>
|
#include <arm/uart_serial.h>
|
||||||
#include <pjrcUSB/arm/usb_dev.h>
|
#include <arm/usb_dev.h>
|
||||||
#include <pjrcUSB/arm/usb_keyboard.h>
|
#include <arm/usb_keyboard.h>
|
||||||
#include <pjrcUSB/arm/usb_serial.h>
|
#include <arm/usb_serial.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Local Includes
|
// 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)
|
// 0 is often used to show that a USB cable is not plugged in (but has power)
|
||||||
uint8_t Output_Available = 0;
|
uint8_t Output_Available = 0;
|
||||||
|
|
||||||
|
// Debug control variable for Output modules
|
||||||
|
// 0 - Debug disabled (default)
|
||||||
|
// 1 - Debug enabled
|
||||||
|
uint8_t Output_DebugMode = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----- Capabilities -----
|
// ----- 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
|
// Sends a Consumer Control code to the USB Output buffer
|
||||||
void Output_consCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
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 -----
|
// ----- 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
|
// USB Module Setup
|
||||||
inline void Output_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_Available; // 0 - Output module not fully functional, 1 - Output module working
|
||||||
|
|
||||||
|
extern uint8_t Output_DebugMode; // 0 - Debug disabled, 1 - Debug enabled
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----- Capabilities -----
|
// ----- 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_sysCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args );
|
||||||
void Output_usbCodeSend_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 -----
|
// ----- Functions -----
|
||||||
@ -95,6 +101,8 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a
|
|||||||
void Output_setup();
|
void Output_setup();
|
||||||
void Output_send();
|
void Output_send();
|
||||||
|
|
||||||
|
void Output_flushBuffers();
|
||||||
|
|
||||||
void Output_firmwareReload();
|
void Output_firmwareReload();
|
||||||
void Output_softReset();
|
void Output_softReset();
|
||||||
|
|
||||||
|
@ -23,6 +23,12 @@ set( Module_SRCS
|
|||||||
output_com.c
|
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
|
# 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
|
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.
|
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
|
Building on Mac should be ok for 99% of users with Macports or Homebrew. For
|
||||||
Brew). The dfu Bootloader will not build correctly with the old version of
|
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
|
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
|
with lto (link time optimizations) which makes the resulting binary too big to
|
||||||
fit on the chip (must be less than 4096 Bytes).
|
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
|
- Arch Linux / Mac Ports
|
||||||
- arm-none-eabi-gcc
|
- arm-none-eabi-gcc
|
||||||
- arm-none-eaby-binutils
|
- arm-none-eabi-binutils
|
||||||
|
|
||||||
- Windows (https://launchpad.net/gcc-arm-embedded/+download)
|
- Windows (https://launchpad.net/gcc-arm-embedded/+download)
|
||||||
- gcc-arm-none-eabi (win32.zip)
|
- 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>`.
|
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
|
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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
// Project Includes
|
// Project Includes
|
||||||
#include <cli.h>
|
#include <cli.h>
|
||||||
|
#include <kll.h>
|
||||||
#include <led.h>
|
#include <led.h>
|
||||||
#include <print.h>
|
#include <print.h>
|
||||||
#include <macro.h>
|
#include <macro.h>
|
||||||
@ -38,6 +39,14 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----- Defines -----
|
||||||
|
|
||||||
|
#if ( DebounceThrottleDiv_define > 0 )
|
||||||
|
nat_ptr_t Matrix_divCounter = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----- Function Declarations -----
|
// ----- Function Declarations -----
|
||||||
|
|
||||||
// CLI Functions
|
// CLI Functions
|
||||||
@ -191,7 +200,7 @@ void Matrix_setup()
|
|||||||
Matrix_scanArray[ item ].prevState = KeyState_Off;
|
Matrix_scanArray[ item ].prevState = KeyState_Off;
|
||||||
Matrix_scanArray[ item ].curState = KeyState_Off;
|
Matrix_scanArray[ item ].curState = KeyState_Off;
|
||||||
Matrix_scanArray[ item ].activeCount = 0;
|
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
|
// 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)
|
// NOTE: scanNum should be reset to 0 after a USB send (to reset all the counters)
|
||||||
void Matrix_scan( uint16_t scanNum )
|
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
|
// Increment stats counters
|
||||||
if ( scanNum > matrixMaxScans ) matrixMaxScans = scanNum;
|
if ( scanNum > matrixMaxScans ) matrixMaxScans = scanNum;
|
||||||
if ( scanNum == 0 )
|
if ( scanNum == 0 )
|
||||||
@ -275,14 +293,14 @@ void Matrix_scan( uint16_t scanNum )
|
|||||||
if ( Matrix_pin( Matrix_rows[ sense ], Type_Sense ) )
|
if ( Matrix_pin( Matrix_rows[ sense ], Type_Sense ) )
|
||||||
{
|
{
|
||||||
// Only update if not going to wrap around
|
// 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;
|
state->inactiveCount >>= 1;
|
||||||
}
|
}
|
||||||
// Signal Not Detected
|
// Signal Not Detected
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Only update if not going to wrap around
|
// 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;
|
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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -24,6 +24,23 @@
|
|||||||
|
|
||||||
// ----- Includes -----
|
// ----- 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 -----
|
// ----- Enums -----
|
||||||
@ -112,8 +129,8 @@ typedef struct GPIO_Pin {
|
|||||||
typedef struct KeyState {
|
typedef struct KeyState {
|
||||||
KeyPosition prevState;
|
KeyPosition prevState;
|
||||||
KeyPosition curState;
|
KeyPosition curState;
|
||||||
uint16_t activeCount;
|
DebounceCounter activeCount;
|
||||||
uint16_t inactiveCount;
|
DebounceCounter inactiveCount;
|
||||||
} KeyState;
|
} KeyState;
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user