From a423cb90be21ffd4025e0a004ad3d4de1c67dba1 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Mon, 16 Feb 2015 13:27:42 -0800 Subject: [PATCH 01/17] Adding convenience build target for testing out kll compiler changes. --- Lib/CMake/kll.cmake | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Lib/CMake/kll.cmake b/Lib/CMake/kll.cmake index 71df3b7..fe28a09 100644 --- a/Lib/CMake/kll.cmake +++ b/Lib/CMake/kll.cmake @@ -133,6 +133,12 @@ add_custom_command ( OUTPUT ${kll_outputname} COMMENT "Generating KLL Layout" ) +#| KLL Regen Convenience Target +add_custom_target ( kll_regen + COMMAND ${kll_cmd} + COMMENT "Re-generating KLL Layout" +) + #| Append generated file to required sources so it becomes a dependency in the main build set ( SRCS ${SRCS} ${kll_outputname} ) From 7a7b73ca4a798dbb1a28f647ad77b41310de31bd Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Fri, 20 Feb 2015 21:01:33 -0800 Subject: [PATCH 02/17] Internally fixing typo (ASTERIX to ASTERISK (Requires a kll update to work correctly) --- Macro/PartialMap/usb_hid.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Macro/PartialMap/usb_hid.h b/Macro/PartialMap/usb_hid.h index ce097ba..f2dba32 100644 --- a/Macro/PartialMap/usb_hid.h +++ b/Macro/PartialMap/usb_hid.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2011-2014 by Jacob Alexander +/* Copyright (C) 2011-2015 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -113,7 +113,7 @@ #define KEY_UP 0x52 #define KEY_NUM_LOCK 0x53 #define KEYPAD_SLASH 0x54 -#define KEYPAD_ASTERIX 0x55 +#define KEYPAD_ASTERISK 0x55 #define KEYPAD_MINUS 0x56 #define KEYPAD_PLUS 0x57 #define KEYPAD_ENTER 0x58 From 987550568f0ee8a21fb4d91d33585954fd3a3ab0 Mon Sep 17 00:00:00 2001 From: aclowes Date: Sat, 21 Feb 2015 15:45:12 -0500 Subject: [PATCH 03/17] Add instructions for using Homebrew --- README.markdown | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.markdown b/README.markdown index 8907cb4..2823893 100644 --- a/README.markdown +++ b/README.markdown @@ -9,8 +9,9 @@ Teensy 3.0/3.1, McHCK). Linux is the ideal build environment (preferably recent'ish). In the near future I'll make available an Arch Linux VM for building/manufacturing tests. -Building on Mac should be ok for 99% of users with Macports (haven't tried -Brew). The dfu Bootloader will not build correctly with the old version of +Building on Mac should be ok for 99% of users with Macports or Homebrew. For +Homebrew, use `brew tap PX4/homebrew-px4` to get the arm-none-eabi-gcc installer. +The dfu Bootloader will not build correctly with the old version of arm-none-eabi-gcc that Macports currently has (4.7.3). This is due to a bug with lto (link time optimizations) which makes the resulting binary too big to fit on the chip (must be less than 4096 Bytes). From 7597fea053ba64b04e1d5ebcb67462ee1c6f8218 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sat, 21 Feb 2015 13:06:28 -0800 Subject: [PATCH 04/17] Adding outputDebug command - Displays all of the bytes sent via USB - Different display mode for NKRO and Boot modes --- Output/pjrcUSB/arm/usb_keyboard.c | 56 ++++++++++++++++++++++++++++++- Output/pjrcUSB/output_com.c | 26 ++++++++++++++ Output/pjrcUSB/output_com.h | 2 ++ 3 files changed, 83 insertions(+), 1 deletion(-) diff --git a/Output/pjrcUSB/arm/usb_keyboard.c b/Output/pjrcUSB/arm/usb_keyboard.c index 24c60bf..42d71bc 100644 --- a/Output/pjrcUSB/arm/usb_keyboard.c +++ b/Output/pjrcUSB/arm/usb_keyboard.c @@ -1,7 +1,7 @@ /* Teensyduino Core Library * http://www.pjrc.com/teensy/ * Copyright (c) 2013 PJRC.COM, LLC. - * Modifications by Jacob Alexander 2013-2014 + * Modifications by Jacob Alexander 2013-2015 * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -120,6 +120,23 @@ void usb_keyboard_send() { // Send boot keyboard interrupt packet(s) case 0: + // USB Boot Mode debug output + if ( Output_DebugMode ) + { + dbug_msg("Boot USB: "); + printHex_op( USBKeys_Modifiers, 2 ); + print(" "); + printHex( 0 ); + print(" "); + printHex_op( USBKeys_Keys[0], 2 ); + printHex_op( USBKeys_Keys[1], 2 ); + printHex_op( USBKeys_Keys[2], 2 ); + printHex_op( USBKeys_Keys[3], 2 ); + printHex_op( USBKeys_Keys[4], 2 ); + printHex_op( USBKeys_Keys[5], 2 ); + print( NL ); + } + // Boot Mode *tx_buf++ = USBKeys_Modifiers; *tx_buf++ = 0; @@ -133,9 +150,21 @@ void usb_keyboard_send() // Send NKRO keyboard interrupts packet(s) case 1: + if ( Output_DebugMode ) + { + dbug_msg("NKRO USB: "); + } + // Check system control keys if ( USBKeys_Changed & USBKeyChangeState_System ) { + if ( Output_DebugMode ) + { + print("SysCtrl["); + printHex_op( USBKeys_SysCtrl, 2 ); + print("] "); + } + *tx_buf++ = 0x02; // ID *tx_buf = USBKeys_SysCtrl; tx_packet->len = 2; @@ -148,6 +177,13 @@ void usb_keyboard_send() // Check consumer control keys if ( USBKeys_Changed & USBKeyChangeState_Consumer ) { + if ( Output_DebugMode ) + { + print("ConsCtrl["); + printHex_op( USBKeys_ConsCtrl, 2 ); + print("] "); + } + *tx_buf++ = 0x03; // ID *tx_buf++ = (uint8_t)(USBKeys_ConsCtrl & 0x00FF); *tx_buf = (uint8_t)(USBKeys_ConsCtrl >> 8); @@ -161,6 +197,24 @@ void usb_keyboard_send() // Standard HID Keyboard if ( USBKeys_Changed ) { + // USB NKRO Debug output + if ( Output_DebugMode ) + { + printHex_op( USBKeys_Modifiers, 2 ); + print(" "); + for ( uint8_t c = 0; c < 6; c++ ) + printHex_op( USBKeys_Keys[ c ], 2 ); + print(" "); + for ( uint8_t c = 6; c < 20; c++ ) + printHex_op( USBKeys_Keys[ c ], 2 ); + print(" "); + printHex_op( USBKeys_Keys[20], 2 ); + print(" "); + for ( uint8_t c = 21; c < 27; c++ ) + printHex_op( USBKeys_Keys[ c ], 2 ); + print( NL ); + } + tx_packet->len = 0; // Modifiers diff --git a/Output/pjrcUSB/output_com.c b/Output/pjrcUSB/output_com.c index 1651222..f5111e0 100644 --- a/Output/pjrcUSB/output_com.c +++ b/Output/pjrcUSB/output_com.c @@ -61,6 +61,7 @@ // ----- Function Declarations ----- void cliFunc_kbdProtocol( char* args ); +void cliFunc_outputDebug( char* args ); void cliFunc_readLEDs ( char* args ); void cliFunc_sendKeys ( char* args ); void cliFunc_setKeys ( char* args ); @@ -72,6 +73,7 @@ void cliFunc_setMod ( char* args ); // Output Module command dictionary CLIDict_Entry( kbdProtocol, "Keyboard Protocol Mode: 0 - Boot, 1 - OS/NKRO Mode" ); +CLIDict_Entry( outputDebug, "Toggle Output Debug mode." ); CLIDict_Entry( readLEDs, "Read LED byte:" NL "\t\t1 NumLck, 2 CapsLck, 4 ScrlLck, 16 Kana, etc." ); CLIDict_Entry( sendKeys, "Send the prepared list of USB codes and modifier byte." ); CLIDict_Entry( setKeys, "Prepare a space separated list of USB codes (decimal). Waits until \033[35msendKeys\033[0m." ); @@ -79,6 +81,7 @@ CLIDict_Entry( setMod, "Set the modfier byte:" NL "\t\t1 LCtrl, 2 LShft, 4 CLIDict_Def( outputCLIDict, "USB Module Commands" ) = { CLIDict_Item( kbdProtocol ), + CLIDict_Item( outputDebug ), CLIDict_Item( readLEDs ), CLIDict_Item( sendKeys ), CLIDict_Item( setKeys ), @@ -129,6 +132,11 @@ USBKeyChangeState USBKeys_Changed = USBKeyChangeState_None; // 0 is often used to show that a USB cable is not plugged in (but has power) uint8_t Output_Available = 0; +// Debug control variable for Output modules +// 0 - Debug disabled (default) +// 1 - Debug enabled + uint8_t Output_DebugMode = 0; + // ----- Capabilities ----- @@ -584,6 +592,24 @@ void cliFunc_kbdProtocol( char* args ) } +void cliFunc_outputDebug( char* args ) +{ + // Parse number from argument + // NOTE: Only first argument is used + char* arg1Ptr; + char* arg2Ptr; + CLI_argumentIsolation( args, &arg1Ptr, &arg2Ptr ); + + // Default to 1 if no argument is given + Output_DebugMode = 1; + + if ( arg1Ptr[0] != '\0' ) + { + Output_DebugMode = (uint16_t)numToInt( arg1Ptr ); + } +} + + void cliFunc_readLEDs( char* args ) { print( NL ); diff --git a/Output/pjrcUSB/output_com.h b/Output/pjrcUSB/output_com.h index 22b3871..aeddc09 100644 --- a/Output/pjrcUSB/output_com.h +++ b/Output/pjrcUSB/output_com.h @@ -81,6 +81,8 @@ extern USBKeyChangeState USBKeys_Changed; extern uint8_t Output_Available; // 0 - Output module not fully functional, 1 - Output module working +extern uint8_t Output_DebugMode; // 0 - Debug disabled, 1 - Debug enabled + // ----- Capabilities ----- From d4300009ceb0cdb0d891e2e3f6584300b3ad6433 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sat, 21 Feb 2015 23:21:59 -0800 Subject: [PATCH 05/17] Updating kll invocation arguments for readability. - Removing old cli arguments --- Lib/CMake/kll.cmake | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/Lib/CMake/kll.cmake b/Lib/CMake/kll.cmake index fe28a09..09ec0d1 100644 --- a/Lib/CMake/kll.cmake +++ b/Lib/CMake/kll.cmake @@ -118,15 +118,13 @@ endforeach () # #| KLL Options -set ( kll_backend -b kiibohd ) -set ( kll_template -t ${PROJECT_SOURCE_DIR}/kll/templates/kiibohdKeymap.h ) -set ( kll_outputname generatedKeymap.h ) -set ( kll_output -o ${kll_outputname} ) -set ( kll_define_output --defines-output kll_defs.h ) -set ( kll_define_template --defines-template ${PROJECT_SOURCE_DIR}/kll/templates/kiibohdDefs.h ) +set ( kll_backend --backend kiibohd ) +set ( kll_template --templates ${PROJECT_SOURCE_DIR}/kll/templates/kiibohdKeymap.h ${PROJECT_SOURCE_DIR}/kll/templates/kiibohdDefs.h ) +set ( kll_outputname generatedKeymap.h kll_defs.h ) +set ( kll_output --outputs ${kll_outputname} ) #| KLL Cmd -set ( kll_cmd ${PROJECT_SOURCE_DIR}/kll/kll.py ${BaseMap_Args} ${DefaultMap_Args} ${PartialMap_Args} ${kll_backend} ${kll_template} ${kll_output} ${kll_define_template} ${kll_define_output} ) +set ( kll_cmd ${PROJECT_SOURCE_DIR}/kll/kll.py ${BaseMap_Args} ${DefaultMap_Args} ${PartialMap_Args} ${kll_backend} ${kll_template} ${kll_output} ) add_custom_command ( OUTPUT ${kll_outputname} COMMAND ${kll_cmd} DEPENDS ${KLL_DEPENDS} From a3b80b0f2ac852a8940072bc4161261f20fa84fe Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sun, 22 Feb 2015 14:14:55 -0800 Subject: [PATCH 06/17] Adding keymap configuration section to the README. --- README.markdown | 108 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 2823893..566d17f 100644 --- a/README.markdown +++ b/README.markdown @@ -9,7 +9,7 @@ Teensy 3.0/3.1, McHCK). Linux is the ideal build environment (preferably recent'ish). In the near future I'll make available an Arch Linux VM for building/manufacturing tests. -Building on Mac should be ok for 99% of users with Macports or Homebrew. For +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 @@ -263,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=`. +Keymap Configuration +-------------------- + +This is where you define the layout for your keyboard. +Currently, the only way to define kebyoard layouts is using [KLL](https://www.overleaf.com/read/zzqbdwqjfwwf). + +KLL is built up of 3 different kinds of keymaps in total. +The BaseMap, DefaultMap and PartialMaps. + +For each type of keymap, it is possible to combine multiple .kll files together to create new ones using +the compiler. The order of the files matter, as the right-most file will overwrite any setting in the +previous files. + +> NOTE: Each keymap is done after the entire file is processed. This means that within the file the order +> of assignment doesa *not* matter (if you assign the same thing twice, then yes the most recent one +> takes priority). + + +BaseMap defines what the keyboard can do. This includes specific capabilities of the keyboard (such as USB), +the mapping of Scan Codes to USB Codes and any specific configurations for the keyboard. +In general, the BaseMap rarely needs to be changed. Usually only when adding a new keyboard to the firmware +does the Basemap need any modification. +The BaseMap is what both DefaultMap and PartialMaps are based upon. This allows for a common reference +when defining custom keymappings. + +> NOTE: Don't use defaultMap.kll to change your layouts. This will work, but they will not be portable. + + +The DefaultMap is the normal state of the keyboard, i.e. your default layer. +Using the BaseMap as a base, the DefaultMap is a modification of the BaseMap to what the keyboard should do. +Since the DefaultMap uses USB Code to USB Code translations, this means that keymaps used for one keyboard +will work with another keyboard. +For example, I use Colemak, so this means I only have to define Colemak once for every keyboard that supports +the kiibohd firmware. This is possible because every BaseMap defines the keyboard as a US ANSI like keyboard +layout. +The DefaultMap can also be thought of as Layer 0. + + +PartialMaps are optional keymaps that can be "stacked" on top of the DefaultMap. +They can be dynamically swapped out using the layer control capabilities: + +- layerLatch( `` ) +- layerLock( `` ) +- layerShift( `` ) + +layerShift is usually what you want as it works just like a standard shift key. +layerLock is similar to the CapsLock key. While layerLatch is a latch, where only the next key you press +will use that layer (e.g. stickykeys). + +A unique aspect of KLL layers is that it's a true stack of layers. +When a layer is activated, only the keys that are specified by the layer will change. +This means, if you define a layer that only sets `CapsLock -> LCtrl` and `LCtrl->Capslock` only those keys +will change when you active the layer. All the other keys will use the layer that is "underneath" to +lookup the keypress (usually the DefaultMap). + +This means that you can combine .kll files statically using the compiler or dynamically using the firmware. + +You can set the max number of layers by changing the `stateWordSize` define in one of your kll files. +By default it is set to 8 in Macro/PartialMap/capabilities.kll. This means you can have up to 256 layers +total (this includes the DefaultMap). +You can increase this number to either 16 or 32 (this will use more Flash and RAM btw) which will give you +2^16 and 2^32 possible layers respectively (65 535 and 4 294 967 295). + + +```cmake +### +# Keymap Configuration (do not include the .kll extension) +# + +#| Do not include the .kll extension +#| * BaseMap maps the native keyboard scan codes to USB Codes so the layout is compatible with all other layouts +#| * DefaultMap allows the default keymap to be modified from the BaseMap +#| * PartialMaps is a set of dynamically set layers (there is no limit, but too many may use up too much RAM...) +#| BaseMap generally does not need to be changed from "defaultMap" +#| +#| Syntax: +#| myMap +#| * defines a single .kll layout file, double-quotes are needed to distinguish between layers +#| "myMap specialLayer" +#| * defines myMap to be the main layout, then replace specialLayers on top of it +#| +#| - Only for PartialMaps - +#| "myMap specialLayer" "myMap colemak" dvorak +#| * As before, but also generates a second layer at index 2 and third at index 3 +#| +#| NOTE: Remember to add key(s) to enable each Partial Layer +#| NOTE2: Layers are always based up the BaseMap (which should be an ANSI-like mapping) +#| NOTE3: Compiler looks in kll/layouts and the build directory for layout files (precedence on build directory) + +##| Set the base keyboard .kll map, defaults to "defaultMap" if not found +##| Looks in Scan/ for the available BaseMaps +set( BaseMap "defaultMap" + CACHE STRING "KLL BaseMap/Scancode Keymapping" ) + +##| Layer additonal .kll maps on the BaseMap, layers are in order from 1st to nth +##| Can be set to "" +set( DefaultMap "md1Overlay stdFuncMap" + CACHE STRING "KLL DefaultMap" ) + +##| ParitalMaps available on top of the BaseMap. See above for syntax on specifying multiple layers vs. layering +##| Can be set to "" +set( PartialMaps "hhkbpro2" + CACHE STRING "KLL PartialMaps/Layer Definitions" ) +``` + + Linux Building -------------- From 595319c511e0a852219f8b174a259145f581e1b5 Mon Sep 17 00:00:00 2001 From: Victor Luft Date: Mon, 23 Feb 2015 18:27:33 -0800 Subject: [PATCH 07/17] clear buffers on Consumer/System Control release fixes #15 --- Output/pjrcUSB/output_com.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Output/pjrcUSB/output_com.c b/Output/pjrcUSB/output_com.c index f5111e0..eb25b83 100644 --- a/Output/pjrcUSB/output_com.c +++ b/Output/pjrcUSB/output_com.c @@ -219,7 +219,10 @@ void Output_consCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t * // Only send keypresses if press or hold state if ( stateType == 0x00 && state == 0x03 ) // Release state + { + USBKeys_ConsCtrl = 0; return; + } // Set consumer control code USBKeys_ConsCtrl = *(uint16_t*)(&args[0]); @@ -250,7 +253,10 @@ void Output_sysCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *a // Only send keypresses if press or hold state if ( stateType == 0x00 && state == 0x03 ) // Release state + { + USBKeys_SysCtrl = 0; return; + } // Set system control code USBKeys_SysCtrl = args[0]; From 0ec5e6d9c2d4e280d84c7ec39aee8c0fdca74225 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Mon, 23 Feb 2015 22:25:46 -0800 Subject: [PATCH 08/17] Adding missing NL's for Cons and Sys Control debug --- Output/pjrcUSB/arm/usb_keyboard.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Output/pjrcUSB/arm/usb_keyboard.c b/Output/pjrcUSB/arm/usb_keyboard.c index 42d71bc..b425073 100644 --- a/Output/pjrcUSB/arm/usb_keyboard.c +++ b/Output/pjrcUSB/arm/usb_keyboard.c @@ -162,7 +162,7 @@ void usb_keyboard_send() { print("SysCtrl["); printHex_op( USBKeys_SysCtrl, 2 ); - print("] "); + print( "] " NL ); } *tx_buf++ = 0x02; // ID @@ -181,7 +181,7 @@ void usb_keyboard_send() { print("ConsCtrl["); printHex_op( USBKeys_ConsCtrl, 2 ); - print("] "); + print( "] " NL ); } *tx_buf++ = 0x03; // ID From a9c5898ba5fcb06f11ff97c4fe1fbafb836ebd87 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sat, 28 Feb 2015 22:13:17 -0800 Subject: [PATCH 09/17] Adding configurable DebounceDivThreshold Can be specified from any .kll file DebounceDivThreshold = 0xFFFFFFFF Sets to max debounce, default is 0xFFFF. The 0xFFFFFFFF is about a 2x longer debounce The max requires more ram (as it uses 32 bit variables instead of 16). Added support for submodule capabilities files. --- Lib/CMake/kll.cmake | 14 +++++--------- Lib/CMake/modules.cmake | 17 ++++++++++++----- Scan/MatrixARM/capabilities.kll | 20 ++++++++++++++++++++ Scan/MatrixARM/matrix_scan.c | 8 ++++---- Scan/MatrixARM/matrix_scan.h | 27 ++++++++++++++++++++++----- 5 files changed, 63 insertions(+), 23 deletions(-) create mode 100644 Scan/MatrixARM/capabilities.kll diff --git a/Lib/CMake/kll.cmake b/Lib/CMake/kll.cmake index 09ec0d1..5d007d2 100644 --- a/Lib/CMake/kll.cmake +++ b/Lib/CMake/kll.cmake @@ -1,6 +1,6 @@ ###| CMAKE Kiibohd Controller KLL Configurator |### # -# Written by Jacob Alexander in 2014 for the Kiibohd Controller +# Written by Jacob Alexander in 2014-2015 for the Kiibohd Controller # # Released into the Public Domain # @@ -46,14 +46,10 @@ endif () # kll/kll.py exists #| KLL_DEPENDS is used to build a dependency tree for kll.py, this way when files are changed, kll.py gets re-run -#| Search for capabilities.kll in each module directory -foreach ( DIR ${ScanModulePath} ${MacroModulePath} ${OutputModulePath} ${DebugModulePath} ) - # capabilities.kll exists, add to BaseMap - set ( filename "${PROJECT_SOURCE_DIR}/${DIR}/capabilities.kll" ) - if ( EXISTS ${filename} ) - set ( BaseMap_Args ${BaseMap_Args} ${filename} ) - set ( KLL_DEPENDS ${KLL_DEPENDS} ${filename} ) - endif () +#| Add each of the detected capabilities.kll +foreach ( filename ${ScanModule_KLL} ${MacroModule_KLL} ${OutputModule_KLL} ${DebugModule_KLL} ) + set ( BaseMap_Args ${BaseMap_Args} ${filename} ) + set ( KLL_DEPENDS ${KLL_DEPENDS} ${filename} ) endforeach () #| If set BaseMap cannot be found, use default map diff --git a/Lib/CMake/modules.cmake b/Lib/CMake/modules.cmake index 02ecbe8..e251aa1 100644 --- a/Lib/CMake/modules.cmake +++ b/Lib/CMake/modules.cmake @@ -1,6 +1,6 @@ ###| CMAKE Kiibohd Controller Source Configurator |### # -# Written by Jacob Alexander in 2011-2014 for the Kiibohd Controller +# Written by Jacob Alexander in 2011-2015 for the Kiibohd Controller # # Released into the Public Domain # @@ -104,10 +104,8 @@ function ( AddModule ModuleType ModuleName ) PathPrepend ( Module_SRCS ${ModulePath} ${Module_SRCS} ) # Check the current scope to see if a sub-module added some source files - set ( Module_SRCS ${${ModuleType}_SRCS} ${Module_SRCS} ) - # Append each of the sources to each type of module srcs list - set ( ${ModuleType}_SRCS ${Module_SRCS} ) + set ( ${ModuleType}_SRCS ${${ModuleType}_SRCS} ${Module_SRCS} ) # Add .h files add_definitions ( -I${ModuleFullPath} ) @@ -124,8 +122,17 @@ function ( AddModule ModuleType ModuleName ) endif () endforeach () - # Finally, add the sources to the parent scope (i.e. return) + # Check for any capabilities.kll files in the Module + set ( kll_capabilities_file "${ModuleFullPath}/capabilities.kll" ) + if ( EXISTS ${kll_capabilities_file} ) + # Add the kll file and any submodule kll files to the running list + set ( ${ModuleType}Module_KLL ${${ModuleType}Module_KLL} ${kll_capabilities_file} ) + endif () + + + # Finally, add the sources and kll files to the parent scope (i.e. return) set ( ${ModuleType}_SRCS ${${ModuleType}_SRCS} PARENT_SCOPE ) + set ( ${ModuleType}Module_KLL ${${ModuleType}Module_KLL} PARENT_SCOPE ) endfunction () diff --git a/Scan/MatrixARM/capabilities.kll b/Scan/MatrixARM/capabilities.kll new file mode 100644 index 0000000..319b81d --- /dev/null +++ b/Scan/MatrixARM/capabilities.kll @@ -0,0 +1,20 @@ +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 + diff --git a/Scan/MatrixARM/matrix_scan.c b/Scan/MatrixARM/matrix_scan.c index b336efe..eaea368 100644 --- a/Scan/MatrixARM/matrix_scan.c +++ b/Scan/MatrixARM/matrix_scan.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2014 by Jacob Alexander +/* Copyright (C) 2014-2015 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -191,7 +191,7 @@ void Matrix_setup() Matrix_scanArray[ item ].prevState = KeyState_Off; Matrix_scanArray[ item ].curState = KeyState_Off; Matrix_scanArray[ item ].activeCount = 0; - Matrix_scanArray[ item ].inactiveCount = 0xFFFF; // Start at 'off' steady state + Matrix_scanArray[ item ].inactiveCount = DebounceDivThreshold_define; // Start at 'off' steady state } // Clear scan stats counters @@ -275,14 +275,14 @@ void Matrix_scan( uint16_t scanNum ) if ( Matrix_pin( Matrix_rows[ sense ], Type_Sense ) ) { // Only update if not going to wrap around - if ( state->activeCount < 0xFFFF ) state->activeCount += 1; + if ( state->activeCount < DebounceDivThreshold_define ) state->activeCount += 1; state->inactiveCount >>= 1; } // Signal Not Detected else { // Only update if not going to wrap around - if ( state->inactiveCount < 0xFFFF ) state->inactiveCount += 1; + if ( state->inactiveCount < DebounceDivThreshold_define ) state->inactiveCount += 1; state->activeCount >>= 1; } diff --git a/Scan/MatrixARM/matrix_scan.h b/Scan/MatrixARM/matrix_scan.h index 487abef..13839a1 100644 --- a/Scan/MatrixARM/matrix_scan.h +++ b/Scan/MatrixARM/matrix_scan.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2014 by Jacob Alexander +/* Copyright (C) 2014-2015 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,6 +24,23 @@ // ----- Includes ----- +// KLL Generated Defines +#include + + + +// ----- Defines ----- + +#if ( DebounceDivThreshold_define < 0xFF + 1 ) +#define DebounceCounter uint8_t +#elif ( DebounceDivThreshold_define < 0xFFFF + 1 ) +#define DebounceCounter uint16_t +#elif ( DebounceDivThreshold_define < 0xFFFFFFFF + 1 ) +#define DebounceCounter uint32_t +#else +#error "Debounce threshold is too high... 32 bit max. Check .kll defines." +#endif + // ----- Enums ----- @@ -110,10 +127,10 @@ typedef struct GPIO_Pin { // Debounce Element typedef struct KeyState { - KeyPosition prevState; - KeyPosition curState; - uint16_t activeCount; - uint16_t inactiveCount; + KeyPosition prevState; + KeyPosition curState; + DebounceCounter activeCount; + DebounceCounter inactiveCount; } KeyState; From bf3b06aa22867c839f9937895040ae99194844dc Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sat, 28 Feb 2015 23:50:13 -0800 Subject: [PATCH 10/17] Adding list of modified files to the cli version command. --- Debug/cli/cli.c | 4 +-- Lib/CMake/modules.cmake | 60 ++++++++++++++++++++++++----------------- Lib/_buildvars.h | 3 ++- 3 files changed, 39 insertions(+), 28 deletions(-) diff --git a/Debug/cli/cli.c b/Debug/cli/cli.c index 570c621..e910469 100644 --- a/Debug/cli/cli.c +++ b/Debug/cli/cli.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2014 by Jacob Alexander +/* Copyright (C) 2014-2015 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -422,7 +422,7 @@ void cliFunc_version( char* args ) print( NL ); print( " \033[1mRevision:\033[0m " CLI_Revision NL ); print( " \033[1mBranch:\033[0m " CLI_Branch NL ); - print( " \033[1mTree Status:\033[0m " CLI_ModifiedStatus NL ); + print( " \033[1mTree Status:\033[0m " CLI_ModifiedStatus CLI_ModifiedFiles NL ); print( " \033[1mRepo Origin:\033[0m " CLI_RepoOrigin NL ); print( " \033[1mCommit Date:\033[0m " CLI_CommitDate NL ); print( " \033[1mCommit Author:\033[0m " CLI_CommitAuthor NL ); diff --git a/Lib/CMake/modules.cmake b/Lib/CMake/modules.cmake index e251aa1..0951d4d 100644 --- a/Lib/CMake/modules.cmake +++ b/Lib/CMake/modules.cmake @@ -157,7 +157,7 @@ find_package ( Ctags ) # Optional # #| Manufacturer name -set( MANUFACTURER "Kiibohd" ) +set ( MANUFACTURER "Kiibohd" ) #| Serial Number @@ -165,19 +165,29 @@ set( MANUFACTURER "Kiibohd" ) #| Modified #| Takes a bit of work to extract the "M " using CMake, and not using it if there are no modifications -execute_process( COMMAND ${GIT_EXECUTABLE} status -s -uno --porcelain +execute_process ( COMMAND ${GIT_EXECUTABLE} status -s -uno --porcelain WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} OUTPUT_VARIABLE Git_Modified_INFO ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ) -string( LENGTH "${Git_Modified_INFO}" Git_Modified_LENGTH ) -set( Git_Modified_Status "Clean" ) +string ( LENGTH "${Git_Modified_INFO}" Git_Modified_LENGTH ) +set ( Git_Modified_Status "Clean" ) if ( ${Git_Modified_LENGTH} GREATER 2 ) - string( SUBSTRING "${Git_Modified_INFO}" 1 2 Git_Modified_Flag_INFO ) - set( Git_Modified_Status "Dirty" ) + string ( SUBSTRING "${Git_Modified_INFO}" 1 2 Git_Modified_Flag_INFO ) + set ( Git_Modified_Status "Dirty" ) endif () +#| List of modified files +execute_process ( COMMAND ${GIT_EXECUTABLE} diff-index --name-only HEAD -- + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE Git_Modified_Files + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE +) +string ( REGEX REPLACE "\n" "\\\\r\\\\n\\\\t" Git_Modified_Files "${Git_Modified_Files}" ) +set ( Git_Modified_Files "\\r\\n\\t${Git_Modified_Files}" ) + #| Branch execute_process( COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} @@ -187,7 +197,7 @@ execute_process( COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD ) #| Date -execute_process( COMMAND ${GIT_EXECUTABLE} show -s --format=%ci +execute_process ( COMMAND ${GIT_EXECUTABLE} show -s --format=%ci WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} OUTPUT_VARIABLE Git_Date_INFO ERROR_QUIET @@ -195,7 +205,7 @@ execute_process( COMMAND ${GIT_EXECUTABLE} show -s --format=%ci ) #| Commit Author and Email -execute_process( COMMAND ${GIT_EXECUTABLE} show -s --format="%cn <%ce>" +execute_process ( COMMAND ${GIT_EXECUTABLE} show -s --format="%cn <%ce>" WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} OUTPUT_VARIABLE Git_Commit_Author ERROR_QUIET @@ -203,7 +213,7 @@ execute_process( COMMAND ${GIT_EXECUTABLE} show -s --format="%cn <%ce>" ) #| Commit Revision -execute_process( COMMAND ${GIT_EXECUTABLE} show -s --format=%H +execute_process ( COMMAND ${GIT_EXECUTABLE} show -s --format=%H WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} OUTPUT_VARIABLE Git_Commit_Revision ERROR_QUIET @@ -211,7 +221,7 @@ execute_process( COMMAND ${GIT_EXECUTABLE} show -s --format=%H ) #| Origin URL -execute_process( COMMAND ${GIT_EXECUTABLE} config --get remote.origin.url +execute_process ( COMMAND ${GIT_EXECUTABLE} config --get remote.origin.url WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} OUTPUT_VARIABLE Git_Origin_URL ERROR_QUIET @@ -219,25 +229,25 @@ execute_process( COMMAND ${GIT_EXECUTABLE} config --get remote.origin.url ) #| Build Date -execute_process( COMMAND "date" "+%Y-%m-%d %T %z" +execute_process ( COMMAND "date" "+%Y-%m-%d %T %z" OUTPUT_VARIABLE Build_Date ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ) #| Last Commit Date -set( GitLastCommitDate "${Git_Modified_Status} ${Git_Branch_INFO} - ${Git_Date_INFO}" ) +set ( GitLastCommitDate "${Git_Modified_Status} ${Git_Branch_INFO} - ${Git_Date_INFO}" ) #| Uses CMake variables to include as defines #| Primarily for USB configuration -configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/Lib/_buildvars.h buildvars.h ) +configure_file ( ${CMAKE_CURRENT_SOURCE_DIR}/Lib/_buildvars.h buildvars.h ) ### # Source Defines # -set( SRCS +set ( SRCS ${MAIN_SRCS} ${COMPILER_SRCS} ${Scan_SRCS} @@ -247,7 +257,7 @@ set( SRCS ) #| Directories to include by default -include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) +include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) @@ -255,20 +265,20 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) # ctag Generation # -if( CTAGS_EXECUTABLE ) +if ( CTAGS_EXECUTABLE ) # Populate list of directories for ctags to parse # NOTE: Doesn't support dots in the folder names... - foreach( filename ${SRCS} ) - string( REGEX REPLACE "/[a-zA-Z0-9_-]+.c$" "" pathglob ${filename} ) - file( GLOB filenames "${pathglob}/*.c" ) - set( CTAG_PATHS ${CTAG_PATHS} ${filenames} ) - file( GLOB filenames "${pathglob}/*.h" ) - set( CTAG_PATHS ${CTAG_PATHS} ${filenames} ) - endforeach() + foreach ( filename ${SRCS} ) + string ( REGEX REPLACE "/[a-zA-Z0-9_-]+.c$" "" pathglob ${filename} ) + file ( GLOB filenames "${pathglob}/*.c" ) + set ( CTAG_PATHS ${CTAG_PATHS} ${filenames} ) + file ( GLOB filenames "${pathglob}/*.h" ) + set ( CTAG_PATHS ${CTAG_PATHS} ${filenames} ) + endforeach () # Generate the ctags - execute_process( COMMAND ctags ${CTAG_PATHS} + execute_process ( COMMAND ctags ${CTAG_PATHS} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} ) -endif() +endif () diff --git a/Lib/_buildvars.h b/Lib/_buildvars.h index 2a2f502..f07a6ae 100644 --- a/Lib/_buildvars.h +++ b/Lib/_buildvars.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2013-2014 by Jacob Alexander +/* Copyright (C) 2013-2015 by Jacob Alexander * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,6 +38,7 @@ #define CLI_Revision "@Git_Commit_Revision@" #define CLI_Branch "@Git_Branch_INFO@" #define CLI_ModifiedStatus "@Git_Modified_Status@" +#define CLI_ModifiedFiles "@Git_Modified_Files@" #define CLI_RepoOrigin "@Git_Origin_URL@" #define CLI_CommitDate "@Git_Date_INFO@" #define CLI_CommitAuthor @Git_Commit_Author@ From 3c1b5790e31986a20609be6b1ae3b42745f2792f Mon Sep 17 00:00:00 2001 From: Andrei Thorp Date: Sun, 1 Mar 2015 00:07:35 -0800 Subject: [PATCH 11/17] README package name correction Signed-off-by: Andrei Thorp --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 566d17f..a24d03d 100644 --- a/README.markdown +++ b/README.markdown @@ -59,7 +59,7 @@ ARM Specific (Teensy 3.0/3.1, Infinity Keyboard, McHCK) - Arch Linux / Mac Ports - arm-none-eabi-gcc - - arm-none-eaby-binutils + - arm-none-eabi-binutils - Windows (https://launchpad.net/gcc-arm-embedded/+download) - gcc-arm-none-eabi (win32.zip) From f07e9342ddebebc1ca78033e86f132dbf1f89cd7 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sun, 1 Mar 2015 21:04:33 -0800 Subject: [PATCH 12/17] Fixing releasing Function key and holding layered key - Pressed key will remain on the same layer until released regardless of the layer changes that happen in the meantime --- LoadFile/load.dfu | 2 +- Macro/PartialMap/macro.c | 32 ++++++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/LoadFile/load.dfu b/LoadFile/load.dfu index 7f55c2c..d99c5e6 100755 --- a/LoadFile/load.dfu +++ b/LoadFile/load.dfu @@ -49,7 +49,7 @@ done if [[ "$SERIAL_PORT" != "" ]] && [[ -e "$SERIAL_PORT" ]]; then echo "NOTE: This may fail if the uC is in a bad state or does not support remote flashing" printf "reload\r" > $SERIAL_PORT - sleep 1 + sleep 2 fi # Load via dfu-util diff --git a/Macro/PartialMap/macro.c b/Macro/PartialMap/macro.c index 0be5c77..5f2cf77 100644 --- a/Macro/PartialMap/macro.c +++ b/Macro/PartialMap/macro.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2014 by Jacob Alexander +/* Copyright (C) 2014-2015 by Jacob Alexander * * This file is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -121,9 +121,11 @@ uint8_t macroPauseMode = 0; uint16_t macroStepCounter = 0; -// Key Trigger List Buffer +// Key Trigger List Buffer and Layer Cache +// The layer cache is set on press only, hold and release events refer to the value set on press TriggerGuide macroTriggerListBuffer[ MaxScanCode ]; uint8_t macroTriggerListBufferSize = 0; +var_uint_t macroTriggerListLayerCache[ MaxScanCode ]; // Pending Trigger Macro Index List // * Any trigger macros that need processing from a previous macro processing loop @@ -311,8 +313,24 @@ void Macro_layerShift_capability( uint8_t state, uint8_t stateType, uint8_t *arg // Looks up the trigger list for the given scan code (from the active layer) // NOTE: Calling function must handle the NULL pointer case -nat_ptr_t *Macro_layerLookup( uint8_t scanCode, uint8_t latch_expire ) +nat_ptr_t *Macro_layerLookup( TriggerGuide *guide, uint8_t latch_expire ) { + uint8_t scanCode = guide->scanCode; + + // TODO Analog + // If a normal key, and not pressed, do a layer cache lookup + if ( guide->type == 0x00 && guide->state != 0x01 ) + { + // Cached layer + var_uint_t cachedLayer = macroTriggerListLayerCache[ scanCode ]; + + // Lookup map, then layer + nat_ptr_t **map = (nat_ptr_t**)LayerIndex[ cachedLayer ].triggerMap; + const Layer *layer = &LayerIndex[ cachedLayer ]; + + return map[ scanCode - layer->first ]; + } + // If no trigger macro is defined at the given layer, fallthrough to the next layer for ( uint16_t layerIndex = 0; layerIndex < macroLayerIndexStackSize; layerIndex++ ) { @@ -342,6 +360,9 @@ nat_ptr_t *Macro_layerLookup( uint8_t scanCode, uint8_t latch_expire ) && scanCode >= layer->first && *map[ scanCode - layer->first ] != 0 ) { + // Set the layer cache + macroTriggerListLayerCache[ scanCode ] = macroLayerIndexStack[ layerIndex ]; + return map[ scanCode - layer->first ]; } } @@ -359,6 +380,9 @@ nat_ptr_t *Macro_layerLookup( uint8_t scanCode, uint8_t latch_expire ) && scanCode >= layer->first && *map[ scanCode - layer->first ] != 0 ) { + // Set the layer cache to default map + macroTriggerListLayerCache[ scanCode ] = 0; + return map[ scanCode - layer->first ]; } @@ -836,7 +860,7 @@ inline void Macro_updateTriggerMacroPendingList() uint8_t latch_expire = macroTriggerListBuffer[ key ].state == 0x03; // Lookup Trigger List - nat_ptr_t *triggerList = Macro_layerLookup( macroTriggerListBuffer[ key ].scanCode, latch_expire ); + nat_ptr_t *triggerList = Macro_layerLookup( ¯oTriggerListBuffer[ key ], latch_expire ); // Number of Triggers in list nat_ptr_t triggerListSize = triggerList[0]; From a959011faa6cd49c7c2db430902f224a9a24094a Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Mon, 2 Mar 2015 01:58:53 -0800 Subject: [PATCH 13/17] Adding dfu-suffix signing support to build system - If dfu-suffix is not found, a warning is given and the binary is not signed - Unsigned binaries are still ok with the latest version of dfu-util --- Lib/CMake/FindDFUSuffix.cmake | 40 +++++++++++++++++++++++++++++++++++ Lib/CMake/build.cmake | 23 +++++++++++++++----- 2 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 Lib/CMake/FindDFUSuffix.cmake diff --git a/Lib/CMake/FindDFUSuffix.cmake b/Lib/CMake/FindDFUSuffix.cmake new file mode 100644 index 0000000..9aaa8f2 --- /dev/null +++ b/Lib/CMake/FindDFUSuffix.cmake @@ -0,0 +1,40 @@ +# The module defines the following variables: +# DFU_SUFFIX_EXECUTABLE - path to ctags command line client +# DFU_SUFFIX_FOUND - true if the command line client was found +# DFU_SUFFIX_VERSION_STRING - the version of dfu-suffix found (since CMake 2.8.8) +# Example usage: +# find_package( DFUSuffix ) +# if( DFU_SUFFIX_FOUND ) +# message("ctags found: ${DFU_SUFFIX_EXECUTABLE}") +# endif() + +find_program ( DFU_SUFFIX_EXECUTABLE + NAMES dfu-suffix + DOC "dfu-suffix executable" +) +mark_as_advanced ( DFU_SUFFIX_EXECUTABLE ) + +if ( DFU_SUFFIX_EXECUTABLE ) + execute_process ( COMMAND ${DFU_SUFFIX_EXECUTABLE} --version + OUTPUT_VARIABLE dfu_suffix_version + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + if ( dfu_suffix_version MATCHES "^dfu-suffix \\(dfu-util\\)" ) + string ( REPLACE "\n" "" DFU_SUFFIX_VERSION_STRING ${dfu_suffix_version} ) + string ( REPLACE "dfu-suffix (dfu-util) " "" DFU_SUFFIX_VERSION_STRING ${DFU_SUFFIX_VERSION_STRING} ) + string ( REGEX REPLACE "Copyright .*$" "" DFU_SUFFIX_VERSION_STRING ${DFU_SUFFIX_VERSION_STRING} ) + endif () + unset ( dfu_suffix_version ) +endif () + +# Handle the QUIETLY and REQUIRED arguments and set DFU_SUFFIX_FOUND to TRUE if +# all listed variables are TRUE + +include ( FindPackageHandleStandardArgs ) +find_package_handle_standard_args ( DFU_SUFFIX + REQUIRED_VARS DFU_SUFFIX_EXECUTABLE + VERSION_VAR DFU_SUFFIX_VERSION_STRING +) + diff --git a/Lib/CMake/build.cmake b/Lib/CMake/build.cmake index 676e557..b3209bf 100644 --- a/Lib/CMake/build.cmake +++ b/Lib/CMake/build.cmake @@ -1,6 +1,6 @@ ###| CMAKE Kiibohd Controller Source Configurator |### # -# Written by Jacob Alexander in 2011-2014 for the Kiibohd Controller +# Written by Jacob Alexander in 2011-2015 for the Kiibohd Controller # # Released into the Public Domain # @@ -46,12 +46,25 @@ endif () #| Convert the .ELF into a .bin to load onto the McHCK +#| Then sign using dfu-suffix (requries dfu-util) if ( DEFINED DFU ) + # dfu-suffix is required to sign the dfu binary + find_package ( DFUSuffix ) + set( TARGET_BIN ${TARGET}.dfu.bin ) - add_custom_command( TARGET ${TARGET_ELF} POST_BUILD - COMMAND ${OBJ_COPY} ${BIN_FLAGS} ${TARGET_ELF} ${TARGET_BIN} - COMMENT "Creating dfu binary file: ${TARGET_BIN}" - ) + if ( DFU_SUFFIX_FOUND ) + add_custom_command( TARGET ${TARGET_ELF} POST_BUILD + COMMAND ${OBJ_COPY} ${BIN_FLAGS} ${TARGET_ELF} ${TARGET_BIN} + COMMAND ${DFU_SUFFIX_EXECUTABLE} --add ${TARGET_BIN} --vid ${BOOT_VENDOR_ID} --pid ${BOOT_PRODUCT_ID} 1> /dev/null + COMMENT "Create and sign dfu bin file: ${TARGET_BIN}" + ) + else () + message ( WARNING "DFU Binary has not been signed, requires dfu-suffix..." ) + add_custom_command( TARGET ${TARGET_ELF} POST_BUILD + COMMAND ${OBJ_COPY} ${BIN_FLAGS} ${TARGET_ELF} ${TARGET_BIN} + COMMENT "Creating dfu binary file: ${TARGET_BIN}" + ) + endif () endif () From ae6daa0e5c070b6c5fe2616ca009b48887ef0edb Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Fri, 6 Mar 2015 22:18:15 -0800 Subject: [PATCH 14/17] Adding DebounceThrottleDiv define to slow down the debounce rate. By default: DebounceThrottleDiv = 0; This is the default infinity behaviour right now (may be changed in the future). Increasing DebounceThrottleDiv will increase the scan rate divider. DebounceThrottleDiv = 1; # Scans half as much DebounceThrottleDiv = 2; # Scans a quarter as much DebounceThrottleDiv = 3; # Scans an eigth as much etc. For ARM based uCs (like the Infinity) the maximum divider is 32. --- Scan/MatrixARM/capabilities.kll | 14 ++++++++++++++ Scan/MatrixARM/matrix_scan.c | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/Scan/MatrixARM/capabilities.kll b/Scan/MatrixARM/capabilities.kll index 319b81d..8221ec8 100644 --- a/Scan/MatrixARM/capabilities.kll +++ b/Scan/MatrixARM/capabilities.kll @@ -18,3 +18,17 @@ DebounceDivThreshold => DebounceDivThreshold_define; DebounceDivThreshold = 0xFFFF; # Default debounce #DebounceDivThreshold = 0xFFFFFFFF; # Max debounce +# This defines how often the matrix is scanned +# By, default the key matrix is scanned once per macro processing loop +# For fast uCs and bouncy switches, this can be non-ideal +# 0 - Bit-shift of 0 +# 1 - Bit-shift of 1 (i.e. divide by 2) +# 2 - Bit-shift of 2 (i.e. divide by 4) +# 3 - Bit-shift of 3 (i.e. divide by 8) +# etc. +# Depending on the architecture, this is either a maximum of 16 or 32 +# Increasing this value will increase switch latency +DebounceThrottleDiv => DebounceThrottleDiv_define; +DebounceThrottleDiv = 0; # Default +#DebounceThrottleDiv = 2; # /4 divider + diff --git a/Scan/MatrixARM/matrix_scan.c b/Scan/MatrixARM/matrix_scan.c index eaea368..85f8205 100644 --- a/Scan/MatrixARM/matrix_scan.c +++ b/Scan/MatrixARM/matrix_scan.c @@ -26,6 +26,7 @@ // Project Includes #include +#include #include #include #include @@ -38,6 +39,14 @@ +// ----- Defines ----- + +#if ( DebounceThrottleDiv_define > 0 ) +nat_ptr_t Matrix_divCounter = 0; +#endif + + + // ----- Function Declarations ----- // CLI Functions @@ -232,6 +241,15 @@ void Matrix_keyPositionDebug( KeyPosition pos ) // NOTE: scanNum should be reset to 0 after a USB send (to reset all the counters) void Matrix_scan( uint16_t scanNum ) { +#if ( DebounceThrottleDiv_define > 0 ) + // Scan-rate throttling + // By scanning using a divider, the scan rate slowed down + // DebounceThrottleDiv_define == 1 means -> /2 or half scan rate + // This helps with bouncy switches on fast uCs + if ( !( Matrix_divCounter++ & (1 << ( DebounceThrottleDiv_define - 1 )) ) ) + return; +#endif + // Increment stats counters if ( scanNum > matrixMaxScans ) matrixMaxScans = scanNum; if ( scanNum == 0 ) From 733201d39bf1cb4b6be424310db019a4381f6bae Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Fri, 6 Mar 2015 23:37:09 -0800 Subject: [PATCH 15/17] Fixing compiler errors for usbMuxUart Output module - Removing (currently) redundant usbMuxUart capabilities.kll file - Issues were due to the recent AddModule cmake function addition --- Output/usbMuxUart/capabilities.kll | 14 ------ Output/usbMuxUart/output_com.c | 81 ++++++++++++++++++++++++++++-- Output/usbMuxUart/output_com.h | 8 +++ Output/usbMuxUart/setup.cmake | 6 +++ 4 files changed, 91 insertions(+), 18 deletions(-) delete mode 100644 Output/usbMuxUart/capabilities.kll diff --git a/Output/usbMuxUart/capabilities.kll b/Output/usbMuxUart/capabilities.kll deleted file mode 100644 index 8cfdc03..0000000 --- a/Output/usbMuxUart/capabilities.kll +++ /dev/null @@ -1,14 +0,0 @@ -Name = usbMuxUartCapabilities; -Version = 0.1; -Author = "HaaTa (Jacob Alexander) 2014"; -KLL = 0.3; - -# Modified Date -Date = 2014-09-28; - - -# Capabilties available to the usbMuxUart output module -consCtrlOut => Output_consCtrlSend_capability( consCode : 2 ); -sysCtrlOut => Output_sysCtrlSend_capability( sysCode : 1 ); -usbKeyOut => Output_usbCodeSend_capability( usbCode : 1 ); - diff --git a/Output/usbMuxUart/output_com.c b/Output/usbMuxUart/output_com.c index 5c883e7..d33d7e0 100644 --- a/Output/usbMuxUart/output_com.c +++ b/Output/usbMuxUart/output_com.c @@ -33,10 +33,10 @@ // USB Includes #if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) #elif defined(_mk20dx128_) || defined(_mk20dx128vlf5_) || defined(_mk20dx256_) || defined(_mk20dx256vlh7_) -#include -#include -#include -#include +#include +#include +#include +#include #endif // Local Includes @@ -135,10 +135,69 @@ USBKeyChangeState USBKeys_Changed = USBKeyChangeState_None; // 0 is often used to show that a USB cable is not plugged in (but has power) uint8_t Output_Available = 0; +// Debug control variable for Output modules +// 0 - Debug disabled (default) +// 1 - Debug enabled + uint8_t Output_DebugMode = 0; + // ----- Capabilities ----- +// Set Boot Keyboard Protocol +void Output_kbdProtocolBoot_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +{ + // Display capability name + if ( stateType == 0xFF && state == 0xFF ) + { + print("Output_kbdProtocolBoot()"); + return; + } + + // Only set if necessary + if ( USBKeys_Protocol == 0 ) + return; + + // TODO Analog inputs + // Only set on key press + if ( stateType != 0x01 ) + return; + + // Flush the key buffers + Output_flushBuffers(); + + // Set the keyboard protocol to Boot Mode + USBKeys_Protocol = 0; +} + + +// Set NKRO Keyboard Protocol +void Output_kbdProtocolNKRO_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +{ + // Display capability name + if ( stateType == 0xFF && state == 0xFF ) + { + print("Output_kbdProtocolNKRO()"); + return; + } + + // Only set if necessary + if ( USBKeys_Protocol == 1 ) + return; + + // TODO Analog inputs + // Only set on key press + if ( stateType != 0x01 ) + return; + + // Flush the key buffers + Output_flushBuffers(); + + // Set the keyboard protocol to NKRO Mode + USBKeys_Protocol = 1; +} + + // Sends a Consumer Control code to the USB Output buffer void Output_consCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args ) { @@ -374,6 +433,20 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a // ----- Functions ----- +// Flush Key buffers +void Output_flushBuffers() +{ + // Zero out USBKeys_Keys array + for ( uint8_t c = 0; c < USB_NKRO_BITFIELD_SIZE_KEYS; c++ ) + USBKeys_Keys[ c ] = 0; + + // Zero out other key buffers + USBKeys_ConsCtrl = 0; + USBKeys_Modifiers = 0; + USBKeys_SysCtrl = 0; +} + + // USB Module Setup inline void Output_setup() { diff --git a/Output/usbMuxUart/output_com.h b/Output/usbMuxUart/output_com.h index b041ea7..e73fd09 100644 --- a/Output/usbMuxUart/output_com.h +++ b/Output/usbMuxUart/output_com.h @@ -80,6 +80,8 @@ extern USBKeyChangeState USBKeys_Changed; extern uint8_t Output_Available; // 0 - Output module not fully functional, 1 - Output module working +extern uint8_t Output_DebugMode; // 0 - Debug disabled, 1 - Debug enabled + // ----- Capabilities ----- @@ -88,6 +90,10 @@ void Output_consCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t * void Output_sysCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args ); void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *args ); +// Configuration capabilities +void Output_kbdProtocolBoot_capability( uint8_t state, uint8_t stateType, uint8_t *args ); +void Output_kbdProtocolNKRO_capability( uint8_t state, uint8_t stateType, uint8_t *args ); + // ----- Functions ----- @@ -95,6 +101,8 @@ void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *a void Output_setup(); void Output_send(); +void Output_flushBuffers(); + void Output_firmwareReload(); void Output_softReset(); diff --git a/Output/usbMuxUart/setup.cmake b/Output/usbMuxUart/setup.cmake index 32dfecc..bd07893 100644 --- a/Output/usbMuxUart/setup.cmake +++ b/Output/usbMuxUart/setup.cmake @@ -23,6 +23,12 @@ set( Module_SRCS output_com.c ) +# Remove duplicate output_com.c files from pjrcUSB and uartOut +list ( REMOVE_ITEM Output_SRCS + Output/pjrcUSB/output_com.c + Output/uartOut/output_com.c +) + ### # Compiler Family Compatibility From b2dfd63d4b4ecbde73a7a33e0c0353d85ed50250 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sat, 7 Mar 2015 00:34:14 -0800 Subject: [PATCH 16/17] Fixing Mac OSX freeze on wake-up bug - CLEAR_FEATURE unset is currently causing the keyboarod to freeze - Though not ideal, it seems harmless to ignore this USB Control Packet - Tested working on a Mac Mini (Yosemite) --- Output/pjrcUSB/arm/usb_dev.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Output/pjrcUSB/arm/usb_dev.c b/Output/pjrcUSB/arm/usb_dev.c index c4c60b8..18e51b6 100644 --- a/Output/pjrcUSB/arm/usb_dev.c +++ b/Output/pjrcUSB/arm/usb_dev.c @@ -317,13 +317,17 @@ static void usb_setup() i = setup.wIndex & 0x7F; if ( i > NUM_ENDPOINTS || setup.wValue != 0 ) { - // TODO: do we need to handle IN vs OUT here? endpoint0_stall(); return; } - (*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) &= ~0x02; + //(*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) &= ~0x02; // TODO: do we need to clear the data toggle here? - break; + //break; + + // FIXME: Clearing causes keyboard to freeze, likely an invalid clear + // XXX: Ignoring seems to work, though this may not be the ideal behaviour -HaaTa + endpoint0_stall(); + return; case 0x0302: // SET_FEATURE (endpoint) i = setup.wIndex & 0x7F; if ( i > NUM_ENDPOINTS || setup.wValue != 0 ) From 55346314b8195d5f33f46c4bd07741544b82cbf4 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sat, 7 Mar 2015 00:50:42 -0800 Subject: [PATCH 17/17] Adding additional case statements for SET_FEATURE and CLEAR_FEATURE - Ignoring (which is done by default) - Device, Interface and Endpoint variants --- Output/pjrcUSB/arm/usb_dev.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Output/pjrcUSB/arm/usb_dev.c b/Output/pjrcUSB/arm/usb_dev.c index 18e51b6..138d2c2 100644 --- a/Output/pjrcUSB/arm/usb_dev.c +++ b/Output/pjrcUSB/arm/usb_dev.c @@ -300,7 +300,7 @@ static void usb_setup() data = reply_buffer; break; case 0x0082: // GET_STATUS (endpoint) - if (setup.wIndex > NUM_ENDPOINTS) + if ( setup.wIndex > NUM_ENDPOINTS ) { // TODO: do we need to handle IN vs OUT here? endpoint0_stall(); @@ -313,7 +313,12 @@ static void usb_setup() data = reply_buffer; datalen = 2; break; - case 0x0102: // CLEAR_FEATURE (endpoint) + case 0x0100: // CLEAR_FEATURE (device) + case 0x0101: // CLEAR_FEATURE (interface) + // TODO: Currently ignoring, perhaps useful? -HaaTa + endpoint0_stall(); + return; + case 0x0102: // CLEAR_FEATURE (interface) i = setup.wIndex & 0x7F; if ( i > NUM_ENDPOINTS || setup.wValue != 0 ) { @@ -328,6 +333,11 @@ static void usb_setup() // XXX: Ignoring seems to work, though this may not be the ideal behaviour -HaaTa endpoint0_stall(); return; + case 0x0300: // SET_FEATURE (device) + case 0x0301: // SET_FEATURE (interface) + // TODO: Currently ignoring, perhaps useful? -HaaTa + endpoint0_stall(); + return; case 0x0302: // SET_FEATURE (endpoint) i = setup.wIndex & 0x7F; if ( i > NUM_ENDPOINTS || setup.wValue != 0 )