Parcourir la source

Merge remote-tracking branch 'upstream/master'

bringup
Rowan Decker il y a 9 ans
Parent
révision
2922fce0f7

+ 2
- 2
Debug/cli/cli.c Voir le fichier

/* 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
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
- 0
Lib/CMake/FindDFUSuffix.cmake Voir le fichier

# 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
)


+ 18
- 5
Lib/CMake/build.cmake Voir le fichier

###| 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
# #




#| 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 )
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 () endif ()





+ 16
- 16
Lib/CMake/kll.cmake Voir le fichier

###| 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
# #


#| 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
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 () endforeach ()


#| If set BaseMap cannot be found, use default map #| If set BaseMap cannot be found, use default map
# #


#| KLL Options #| 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 #| 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} )



+ 47
- 30
Lib/CMake/modules.cmake Voir le fichier

###| 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
# #
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} )
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 ()




# #


#| Manufacturer name #| Manufacturer name
set( MANUFACTURER "Kiibohd" )
set ( MANUFACTURER "Kiibohd" )




#| Serial Number #| Serial Number


#| Modified #| Modified
#| Takes a bit of work to extract the "M " using CMake, and not using it if there are no modifications #| 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} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_VARIABLE Git_Modified_INFO OUTPUT_VARIABLE Git_Modified_INFO
ERROR_QUIET ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE 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 ) 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 () 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}
) )


#| Date #| Date
execute_process( COMMAND ${GIT_EXECUTABLE} show -s --format=%ci
execute_process ( COMMAND ${GIT_EXECUTABLE} show -s --format=%ci
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_VARIABLE Git_Date_INFO OUTPUT_VARIABLE Git_Date_INFO
ERROR_QUIET ERROR_QUIET
) )


#| Commit Author and Email #| 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} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_VARIABLE Git_Commit_Author OUTPUT_VARIABLE Git_Commit_Author
ERROR_QUIET ERROR_QUIET
) )


#| Commit Revision #| 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} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_VARIABLE Git_Commit_Revision OUTPUT_VARIABLE Git_Commit_Revision
ERROR_QUIET ERROR_QUIET
) )


#| Origin URL #| 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} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_VARIABLE Git_Origin_URL OUTPUT_VARIABLE Git_Origin_URL
ERROR_QUIET ERROR_QUIET
) )


#| Build Date #| Build Date
execute_process( COMMAND "date" "+%Y-%m-%d %T %z"
execute_process ( COMMAND "date" "+%Y-%m-%d %T %z"
OUTPUT_VARIABLE Build_Date OUTPUT_VARIABLE Build_Date
ERROR_QUIET ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_STRIP_TRAILING_WHITESPACE
) )


#| Last Commit Date #| 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 #| Uses CMake variables to include as defines
#| Primarily for USB configuration #| 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 # Source Defines
# #
set( SRCS
set ( SRCS
${MAIN_SRCS} ${MAIN_SRCS}
${COMPILER_SRCS} ${COMPILER_SRCS}
${Scan_SRCS} ${Scan_SRCS}
) )


#| Directories to include by default #| 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} )






# ctag Generation # ctag Generation
# #


if( CTAGS_EXECUTABLE )
if ( CTAGS_EXECUTABLE )
# Populate list of directories for ctags to parse # Populate list of directories for ctags to parse
# NOTE: Doesn't support dots in the folder names... # 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 # Generate the ctags
execute_process( COMMAND ctags ${CTAG_PATHS}
execute_process ( COMMAND ctags ${CTAG_PATHS}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
) )
endif()
endif ()



+ 2
- 1
Lib/_buildvars.h Voir le fichier

/* 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
#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@

+ 1
- 1
LoadFile/load.dfu Voir le fichier

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

+ 28
- 4
Macro/PartialMap/macro.c Voir le fichier

/* 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
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


// 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++ )
{ {
&& 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 ];
} }
} }
&& 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 ];
} }


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( &macroTriggerListBuffer[ 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];

+ 2
- 2
Macro/PartialMap/usb_hid.h Voir le fichier

/* 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
#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

+ 19
- 5
Output/pjrcUSB/arm/usb_dev.c Voir le fichier

data = reply_buffer; data = reply_buffer;
break; break;
case 0x0082: // GET_STATUS (endpoint) 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? // TODO: do we need to handle IN vs OUT here?
endpoint0_stall(); endpoint0_stall();
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 )

+ 55
- 1
Output/pjrcUSB/arm/usb_keyboard.c Voir le fichier

/* 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
{ {
// 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;


// 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;
// 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);
// 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

+ 32
- 0
Output/pjrcUSB/output_com.c Voir le fichier

// ----- 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 );


// 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." );


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 ),
// 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 -----


// 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]);


// 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];
} }




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 );

+ 2
- 0
Output/pjrcUSB/output_com.h Voir le fichier



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 -----

+ 0
- 14
Output/usbMuxUart/capabilities.kll Voir le fichier

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 );


+ 77
- 4
Output/usbMuxUart/output_com.c Voir le fichier

// 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 <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 #endif


// Local Includes // Local Includes
// 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 )
{ {


// ----- 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()
{ {

+ 8
- 0
Output/usbMuxUart/output_com.h Voir le fichier



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 -----
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 -----
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();



+ 6
- 0
Output/usbMuxUart/setup.cmake Voir le fichier

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

+ 110
- 3
README.markdown Voir le fichier

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
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 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).


- 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)
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
- 0
Scan/MatrixARM/capabilities.kll Voir le fichier

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


+ 22
- 4
Scan/MatrixARM/matrix_scan.c Voir le fichier

/* 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


// 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>






// ----- Defines -----

#if ( DebounceThrottleDiv_define > 0 )
nat_ptr_t Matrix_divCounter = 0;
#endif



// ----- Function Declarations ----- // ----- Function Declarations -----


// CLI Functions // CLI Functions
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
// 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 )
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;
} }



+ 22
- 5
Scan/MatrixARM/matrix_scan.h Voir le fichier

/* 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


// ----- 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 -----


// Debounce Element // Debounce Element
typedef struct KeyState { typedef struct KeyState {
KeyPosition prevState;
KeyPosition curState;
uint16_t activeCount;
uint16_t inactiveCount;
KeyPosition prevState;
KeyPosition curState;
DebounceCounter activeCount;
DebounceCounter inactiveCount;
} KeyState; } KeyState;