From 06f16cbfe9342efee898f2d7116b9069ae5f17fb Mon Sep 17 00:00:00 2001 From: James Young <18669334+noroadsleft@users.noreply.github.com> Date: Sat, 29 Aug 2020 16:00:00 -0700 Subject: [PATCH 01/13] Branch point for 2020 November 28 Breaking Change Update readme.md --- readme.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/readme.md b/readme.md index 6092f209be1a..6321681a9249 100644 --- a/readme.md +++ b/readme.md @@ -7,6 +7,12 @@ [![GitHub contributors](https://img.shields.io/github/contributors/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/pulse/monthly) [![GitHub forks](https://img.shields.io/github/forks/qmk/qmk_firmware.svg?style=social&label=Fork)](https://github.com/qmk/qmk_firmware/) +# THIS IS THE DEVELOP BRANCH + +Warning- This is the `develop` branch of QMK Firmware. You may encounter broken code here. Please see [Breaking Changes](https://docs.qmk.fm/#/breaking_changes) for more information. + +# Original readme continues + This is a keyboard firmware based on the [tmk\_keyboard firmware](https://github.com/tmk/tmk_keyboard) with some useful features for Atmel AVR and ARM controllers, and more specifically, the [OLKB product line](https://olkb.com), the [ErgoDox EZ](https://ergodox-ez.com) keyboard, and the [Clueboard product line](https://clueboard.co). ## Documentation From 8f566901df10fb017fe8cafe9588e3374c6275af Mon Sep 17 00:00:00 2001 From: Sergey Vlasov Date: Tue, 1 Sep 2020 01:19:13 +0300 Subject: [PATCH 02/13] Remove matrix_col_t to allow MATRIX_ROWS > 32 (#10183) The matrix_col_t type was added in commit 0284431ad9 (part of #3449), but then the code which used that type was removed in #6140, and no other users were added since that time. The presence of that type, however, limits MATRIX_ROWS to 32, which probably does not matter for a real keyboard, but prevents doing things like making a firmware to test all existing pins on a board like Teensy++ 2.0 (which has 46 GPIOs). --- tmk_core/common/matrix.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tmk_core/common/matrix.h b/tmk_core/common/matrix.h index 78506059e6ac..31ec844302c8 100644 --- a/tmk_core/common/matrix.h +++ b/tmk_core/common/matrix.h @@ -30,16 +30,6 @@ typedef uint32_t matrix_row_t; # error "MATRIX_COLS: invalid value" #endif -#if (MATRIX_ROWS <= 8) -typedef uint8_t matrix_col_t; -#elif (MATRIX_ROWS <= 16) -typedef uint16_t matrix_col_t; -#elif (MATRIX_ROWS <= 32) -typedef uint32_t matrix_col_t; -#else -# error "MATRIX_ROWS: invalid value" -#endif - #define MATRIX_ROW_SHIFTER ((matrix_row_t)1) #define MATRIX_IS_ON(row, col) (matrix_get_row(row) && (1 << col)) From 343090769259230e2a1661d385789eaebd20919a Mon Sep 17 00:00:00 2001 From: Naoto Takai Date: Thu, 3 Sep 2020 01:18:21 +0900 Subject: [PATCH 03/13] Add support for soft serial to ATmega32U2 (#10204) * Add support for soft serial to ATmega32U2 * Update drivers/avr/serial.c * Update drivers/avr/serial.c * Update drivers/avr/serial.c * Fix comment * Update drivers/avr/serial.c --- common_features.mk | 6 ++++-- drivers/avr/serial.c | 10 +++++----- quantum/mcu_selection.mk | 3 +++ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/common_features.mk b/common_features.mk index ed6908f4b891..c0d97b0b28f6 100644 --- a/common_features.mk +++ b/common_features.mk @@ -428,8 +428,10 @@ ifeq ($(strip $(SPLIT_KEYBOARD)), yes) # Functions added via QUANTUM_LIB_SRC are only included in the final binary if they're called. # Unused functions are pruned away, which is why we can add multiple drivers here without bloat. ifeq ($(PLATFORM),AVR) - QUANTUM_LIB_SRC += i2c_master.c \ - i2c_slave.c + ifneq ($(NO_I2C),yes) + QUANTUM_LIB_SRC += i2c_master.c \ + i2c_slave.c + endif endif SERIAL_DRIVER ?= bitbang diff --git a/drivers/avr/serial.c b/drivers/avr/serial.c index c27cbfdd0a79..8d372d3b8b21 100644 --- a/drivers/avr/serial.c +++ b/drivers/avr/serial.c @@ -20,11 +20,11 @@ #ifdef SOFT_SERIAL_PIN -# ifdef __AVR_ATmega32U4__ -// if using ATmega32U4 I2C, can not use PD0 and PD1 in soft serial. +# if defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) +// if using ATmegaxxU4 I2C, can not use PD0 and PD1 in soft serial. # ifdef USE_AVR_I2C # if SOFT_SERIAL_PIN == D0 || SOFT_SERIAL_PIN == D1 -# error Using ATmega32U4 I2C, so can not use PD0, PD1 +# error Using ATmegaxxU4 I2C, so can not use PD0, PD1 # endif # endif @@ -52,7 +52,7 @@ # define EICRx_BIT (~(_BV(ISC30) | _BV(ISC31))) # define SERIAL_PIN_INTERRUPT INT3_vect # endif -# elif SOFT_SERIAL_PIN == E6 +# elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) && SOFT_SERIAL_PIN == E6 # define EIMSK_BIT _BV(INT6) # define EICRx_BIT (~(_BV(ISC60) | _BV(ISC61))) # define SERIAL_PIN_INTERRUPT INT6_vect @@ -61,7 +61,7 @@ # endif # else -# error serial.c now support ATmega32U4 only +# error serial.c currently only supports ATmegaxxU2 and ATmegaxxU4 # endif # define ALWAYS_INLINE __attribute__((always_inline)) diff --git a/quantum/mcu_selection.mk b/quantum/mcu_selection.mk index 33a0cabc84e5..25fd9d8edd3a 100644 --- a/quantum/mcu_selection.mk +++ b/quantum/mcu_selection.mk @@ -252,6 +252,9 @@ ifneq (,$(filter $(MCU),atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 a ifeq (,$(filter $(NO_INTERRUPT_CONTROL_ENDPOINT),yes)) OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT endif + ifneq (,$(filter $(MCU),atmega16u2 atmega32u2)) + NO_I2C = yes + endif endif ifneq (,$(filter $(MCU),atmega32a)) From d7e81917b4df38298d8845bb2a74a0d5b51aec7f Mon Sep 17 00:00:00 2001 From: jakobkg Date: Sun, 20 Sep 2020 03:13:45 +0200 Subject: [PATCH 04/13] Change MIDI velocity implementation to allow direct control of velocity value (#9940) * Initial changes to expose "real" MIDI velocity * Change MI_VELU and MI_VELD to fit new logic * Apply cleanups from fauxpark's review my bad on the errant whitespace and else {} placements * Slight changes to MI_VELD to match values when velocity is falling to when it is rising * Add keycode MI_VEL_0 * Update compute_velocity() to handle MI_VEL_0 * Store velocity as 7 bits to hard cap value at 127 --- quantum/process_keycode/process_midi.c | 25 ++++++++++++++++++------- quantum/process_keycode/process_midi.h | 2 +- quantum/quantum_keycodes.h | 3 ++- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/quantum/process_keycode/process_midi.c b/quantum/process_keycode/process_midi.c index b2fb902eb40e..4f97160f7d5d 100644 --- a/quantum/process_keycode/process_midi.c +++ b/quantum/process_keycode/process_midi.c @@ -41,12 +41,12 @@ static int8_t midi_modulation_step; static uint16_t midi_modulation_timer; midi_config_t midi_config; -inline uint8_t compute_velocity(uint8_t setting) { return (setting + 1) * (128 / (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN + 1)); } +inline uint8_t compute_velocity(uint8_t setting) { return setting * (128 / (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN)); } void midi_init(void) { midi_config.octave = MI_OCT_2 - MIDI_OCTAVE_MIN; midi_config.transpose = 0; - midi_config.velocity = (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN); + midi_config.velocity = 127; midi_config.channel = 0; midi_config.modulation_interval = 8; @@ -66,7 +66,7 @@ bool process_midi(uint16_t keycode, keyrecord_t *record) { case MIDI_TONE_MIN ... MIDI_TONE_MAX: { uint8_t channel = midi_config.channel; uint8_t tone = keycode - MIDI_TONE_MIN; - uint8_t velocity = compute_velocity(midi_config.velocity); + uint8_t velocity = midi_config.velocity; if (record->event.pressed) { uint8_t note = midi_compute_note(keycode); midi_send_noteon(&midi_device, channel, note, velocity); @@ -122,19 +122,30 @@ bool process_midi(uint16_t keycode, keyrecord_t *record) { return false; case MIDI_VELOCITY_MIN ... MIDI_VELOCITY_MAX: if (record->event.pressed) { - midi_config.velocity = keycode - MIDI_VELOCITY_MIN; + midi_config.velocity = compute_velocity(keycode - MIDI_VELOCITY_MIN); dprintf("midi velocity %d\n", midi_config.velocity); } return false; case MI_VELD: if (record->event.pressed && midi_config.velocity > 0) { - midi_config.velocity--; + if (midi_config.velocity == 127) { + midi_config.velocity -= 10; + } else if (midi_config.velocity > 12) { + midi_config.velocity -= 13; + } else { + midi_config.velocity = 0; + } + dprintf("midi velocity %d\n", midi_config.velocity); } return false; case MI_VELU: - if (record->event.pressed) { - midi_config.velocity++; + if (record->event.pressed && midi_config.velocity < 127) { + if (midi_config.velocity < 115) { + midi_config.velocity += 13; + } else { + midi_config.velocity = 127; + } dprintf("midi velocity %d\n", midi_config.velocity); } return false; diff --git a/quantum/process_keycode/process_midi.h b/quantum/process_keycode/process_midi.h index 0007b3ed255a..ef5661dd4d1c 100644 --- a/quantum/process_keycode/process_midi.h +++ b/quantum/process_keycode/process_midi.h @@ -35,7 +35,7 @@ typedef union { struct { uint8_t octave : 4; int8_t transpose : 4; - uint8_t velocity : 4; + uint8_t velocity : 7; uint8_t channel : 4; uint8_t modulation_interval : 4; }; diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index a0a7bc340f23..c1e31fc86744 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -343,7 +343,8 @@ enum quantum_keycodes { MI_TRNSU, // transpose up MIDI_VELOCITY_MIN, - MI_VEL_1 = MIDI_VELOCITY_MIN, + MI_VEL_0 = MIDI_VELOCITY_MIN, + MI_VEL_1, MI_VEL_2, MI_VEL_3, MI_VEL_4, From ce9741b81283e08df4cecd04a095f5cc5e39a642 Mon Sep 17 00:00:00 2001 From: Nick Brassel Date: Thu, 24 Sep 2020 12:46:43 +1000 Subject: [PATCH 05/13] Add ability to build a subset of all keyboards based on platform. --- Makefile | 17 ++++++++++++++++- build_keyboard.mk | 13 +++++++++++++ message.mk | 3 +++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c851e01e7314..6cad60f8769a 100644 --- a/Makefile +++ b/Makefile @@ -272,11 +272,24 @@ endef define PARSE_RULE RULE := $1 COMMANDS := + REQUIRE_PLATFORM_KEY := # If the rule starts with all, then continue the parsing from # PARSE_ALL_KEYBOARDS ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,all),true) KEYBOARD_RULE=all $$(eval $$(call PARSE_ALL_KEYBOARDS)) + else ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,avr),true) + KEYBOARD_RULE=all + REQUIRE_PLATFORM_KEY := avr + $$(eval $$(call PARSE_ALL_KEYBOARDS)) + else ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,chibios),true) + KEYBOARD_RULE=all + REQUIRE_PLATFORM_KEY := chibios + $$(eval $$(call PARSE_ALL_KEYBOARDS)) + else ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,arm_atsam),true) + KEYBOARD_RULE=all + REQUIRE_PLATFORM_KEY := arm_atsam + $$(eval $$(call PARSE_ALL_KEYBOARDS)) else ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,test),true) $$(eval $$(call PARSE_TEST)) # If the rule starts with the name of a known keyboard, then continue @@ -447,7 +460,7 @@ define PARSE_KEYMAP # Format it in bold KB_SP := $(BOLD)$$(KB_SP)$(NO_COLOR) # Specify the variables that we are passing forward to submake - MAKE_VARS := KEYBOARD=$$(CURRENT_KB) KEYMAP=$$(CURRENT_KM) + MAKE_VARS := KEYBOARD=$$(CURRENT_KB) KEYMAP=$$(CURRENT_KM) REQUIRE_PLATFORM_KEY=$$(REQUIRE_PLATFORM_KEY) # And the first part of the make command MAKE_CMD := $$(MAKE) -r -R -C $(ROOT_DIR) -f build_keyboard.mk $$(MAKE_TARGET) # The message to display @@ -466,6 +479,8 @@ define BUILD LOG=$$$$($$(MAKE_CMD) $$(MAKE_VARS) SILENT=true 2>&1) ; \ if [ $$$$? -gt 0 ]; \ then $$(PRINT_ERROR_PLAIN); \ + elif [ "$$$$LOG" = "skipped" ] ; \ + then $$(PRINT_SKIPPED_PLAIN); \ elif [ "$$$$LOG" != "" ] ; \ then $$(PRINT_WARNING_PLAIN); \ else \ diff --git a/build_keyboard.mk b/build_keyboard.mk index b4e1efd9ee40..e87dcb8f22c8 100644 --- a/build_keyboard.mk +++ b/build_keyboard.mk @@ -317,6 +317,13 @@ SRC += $(TMK_COMMON_SRC) OPT_DEFS += $(TMK_COMMON_DEFS) EXTRALDFLAGS += $(TMK_COMMON_LDFLAGS) +SKIP_COMPILE := no +ifneq ($(REQUIRE_PLATFORM_KEY),) + ifneq ($(REQUIRE_PLATFORM_KEY),$(PLATFORM_KEY)) + SKIP_COMPILE := yes + endif +endif + include $(TMK_PATH)/$(PLATFORM_KEY).mk ifneq ($(strip $(PROTOCOL)),) include $(TMK_PATH)/protocol/$(strip $(shell echo $(PROTOCOL) | tr '[:upper:]' '[:lower:]')).mk @@ -352,7 +359,13 @@ $(KEYBOARD_OUTPUT)_INC := $(PROJECT_INC) $(GFXINC) $(KEYBOARD_OUTPUT)_CONFIG := $(PROJECT_CONFIG) # Default target. +ifeq ($(SKIP_COMPILE),no) all: build check-size +else +all: + echo "skipped" >&2 +endif + build: elf cpfirmware check-size: build objs-size: build diff --git a/message.mk b/message.mk index be04fa9b8104..84b23c1ba871 100644 --- a/message.mk +++ b/message.mk @@ -5,6 +5,7 @@ ifeq ($(COLOR),true) OK_COLOR=\033[32;01m ERROR_COLOR=\033[31;01m WARN_COLOR=\033[33;01m + SKIPPED_COLOR=\033[36;01m BLUE=\033[0;34m BOLD=\033[1m endif @@ -20,6 +21,7 @@ ON_ERROR ?= exit 1 OK_STRING=$(OK_COLOR)[OK]$(NO_COLOR)\n ERROR_STRING=$(ERROR_COLOR)[ERRORS]$(NO_COLOR)\n WARN_STRING=$(WARN_COLOR)[WARNINGS]$(NO_COLOR)\n +SKIPPED_STRING=$(SKIPPED_COLOR)[SKIPPED]$(NO_COLOR)\n TAB_LOG = printf "\n%s\n\n" "$$LOG" | $(AWK) '{ sub(/^/," | "); print }' TAB_LOG_PLAIN = printf "%s\n" "$$LOG" @@ -29,6 +31,7 @@ PRINT_ERROR = ($(SILENT) ||printf " $(ERROR_STRING)" | $(AWK_STATUS)) && $(TAB_L PRINT_WARNING = ($(SILENT) || printf " $(WARN_STRING)" | $(AWK_STATUS)) && $(TAB_LOG) PRINT_ERROR_PLAIN = ($(SILENT) ||printf " $(ERROR_STRING)" | $(AWK_STATUS)) && $(TAB_LOG_PLAIN) && $(ON_ERROR) PRINT_WARNING_PLAIN = ($(SILENT) || printf " $(WARN_STRING)" | $(AWK_STATUS)) && $(TAB_LOG_PLAIN) +PRINT_SKIPPED_PLAIN = ($(SILENT) || printf " $(SKIPPED_STRING)" | $(AWK_STATUS)) PRINT_OK = $(SILENT) || printf " $(OK_STRING)" | $(AWK_STATUS) BUILD_CMD = LOG=$$($(CMD) 2>&1) ; if [ $$? -gt 0 ]; then $(PRINT_ERROR); elif [ "$$LOG" != "" ] ; then $(PRINT_WARNING); else $(PRINT_OK); fi; MAKE_MSG_FORMAT = $(AWK) '{ printf "%-118s", $$0;}' From 5b8ca900bba733f2f0af8649113c384400972d75 Mon Sep 17 00:00:00 2001 From: Nick Brassel Date: Sun, 27 Sep 2020 09:41:49 +1000 Subject: [PATCH 06/13] Make bootloader_jump weak for ChibiOS. (#10417) --- tmk_core/common/chibios/bootloader.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tmk_core/common/chibios/bootloader.c b/tmk_core/common/chibios/bootloader.c index 7b2cf5c435aa..f6d016ec9d13 100644 --- a/tmk_core/common/chibios/bootloader.c +++ b/tmk_core/common/chibios/bootloader.c @@ -32,7 +32,7 @@ extern uint32_t __ram0_end__; -void bootloader_jump(void) { +__attribute__((weak)) void bootloader_jump(void) { // For STM32 MCUs with dual-bank flash, and we're incapable of jumping to the bootloader. The first valid flash // bank is executed unconditionally after a reset, so it doesn't enter DFU unless BOOT0 is high. Instead, we do // it with hardware...in this case, we pull a GPIO high/low depending on the configuration, connects 3.3V to @@ -58,7 +58,7 @@ void enter_bootloader_mode_if_requested(void) {} // not needed at all, but if a extern uint32_t __ram0_end__; -void bootloader_jump(void) { +__attribute__((weak)) void bootloader_jump(void) { *MAGIC_ADDR = BOOTLOADER_MAGIC; // set magic flag => reset handler will jump into boot loader NVIC_SystemReset(); } @@ -85,8 +85,8 @@ void enter_bootloader_mode_if_requested(void) { # if defined(BOOTLOADER_KIIBOHD) /* Kiibohd Bootloader (MCHCK and Infinity KB) */ # define SCB_AIRCR_VECTKEY_WRITEMAGIC 0x05FA0000 -const uint8_t sys_reset_to_loader_magic[] = "\xff\x00\x7fRESET TO LOADER\x7f\x00\xff"; -void bootloader_jump(void) { +const uint8_t sys_reset_to_loader_magic[] = "\xff\x00\x7fRESET TO LOADER\x7f\x00\xff"; +__attribute__((weak)) void bootloader_jump(void) { __builtin_memcpy((void *)VBAT, (const void *)sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic)); // request reset SCB->AIRCR = SCB_AIRCR_VECTKEY_WRITEMAGIC | SCB_AIRCR_SYSRESETREQ_Msk; @@ -95,7 +95,7 @@ void bootloader_jump(void) { # else /* defined(BOOTLOADER_KIIBOHD) */ /* Default for Kinetis - expecting an ARM Teensy */ # include "wait.h" -void bootloader_jump(void) { +__attribute__((weak)) void bootloader_jump(void) { wait_ms(100); __BKPT(0); } From efbb842e8b1183d1296aaa532f09f47431b4d7c7 Mon Sep 17 00:00:00 2001 From: seb-pau <71823179+seb-pau@users.noreply.github.com> Date: Sat, 3 Oct 2020 20:19:07 +0200 Subject: [PATCH 07/13] Joystick 16-bit support (#10439) * Joystick 16-bit support * Add variable joystick axes resolution * Moved #define statements to .h files * Moved definitions to quantum/joystick.h Removed duplicate definitions from usb_descriptor.h and process_joysick.h Adjust process_joystick.c and usb_descriptor.c to use the pre-computed "JOYSTICK_RESOLUTION" value which contains the logical maximum value of a joystick axis * Cleaning up unnecessary code * Update docs/feature_joystick.md Co-authored-by: Ryan * Workaround to joystick.h not being included to report.h * Removed unnecessary newlines, updated report.h Changed JOYSTICK_AXES_RESOLUTION conditional in report.h Co-authored-by: Ryan --- docs/feature_joystick.md | 6 ++++++ quantum/joystick.h | 12 ++++++++++-- quantum/process_keycode/process_joystick.c | 8 ++++---- tmk_core/common/report.h | 6 +++++- tmk_core/protocol/usb_descriptor.c | 15 +++++++++++++-- 5 files changed, 38 insertions(+), 9 deletions(-) diff --git a/docs/feature_joystick.md b/docs/feature_joystick.md index be3c781f6cd4..12bbf5b35eff 100644 --- a/docs/feature_joystick.md +++ b/docs/feature_joystick.md @@ -141,6 +141,12 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { } ``` +### Axis Resolution + +By default, the resolution of each axis is 8 bit, giving a range of -127 to +127. If you need higher precision, you can increase it by defining eg. `JOYSTICK_AXES_RESOLUTION 12` in your `config.h`. The resolution must be between 8 and 16. + +Note that the supported AVR MCUs have a 10-bit ADC, and 12-bit for most STM32 MCUs. + ### Triggering Joystick Buttons Joystick buttons are normal Quantum keycodes, defined as `JS_BUTTON0` to `JS_BUTTON31`, depending on the number of buttons you have configured. diff --git a/quantum/joystick.h b/quantum/joystick.h index a95472b9fd44..87dbc24aff81 100644 --- a/quantum/joystick.h +++ b/quantum/joystick.h @@ -1,5 +1,9 @@ #pragma once +#include "quantum.h" + +#include + #ifndef JOYSTICK_BUTTON_COUNT # define JOYSTICK_BUTTON_COUNT 8 #endif @@ -8,9 +12,13 @@ # define JOYSTICK_AXES_COUNT 4 #endif -#include "quantum.h" +#ifndef JOYSTICK_AXES_RESOLUTION +# define JOYSTICK_AXES_RESOLUTION 8 +#elif JOYSTICK_AXES_RESOLUTION < 8 || JOYSTICK_AXES_RESOLUTION > 16 +# error JOYSTICK_AXES_RESOLUTION must be between 8 and 16 +#endif -#include +#define JOYSTICK_RESOLUTION ((1L << (JOYSTICK_AXES_RESOLUTION - 1)) - 1) // configure on input_pin of the joystick_axes array entry to JS_VIRTUAL_AXIS // to prevent it from being read from the ADC. This allows outputing forged axis value. diff --git a/quantum/process_keycode/process_joystick.c b/quantum/process_keycode/process_joystick.c index 5778a7434c1c..3ffaf42bf847 100644 --- a/quantum/process_keycode/process_joystick.c +++ b/quantum/process_keycode/process_joystick.c @@ -129,17 +129,17 @@ bool process_joystick_analogread_quantum() { // test the converted value against the lower range int32_t ref = joystick_axes[axis_index].mid_digit; int32_t range = joystick_axes[axis_index].min_digit; - int32_t ranged_val = ((axis_val - ref) * -127) / (range - ref); + int32_t ranged_val = ((axis_val - ref) * -JOYSTICK_RESOLUTION) / (range - ref); if (ranged_val > 0) { // the value is in the higher range range = joystick_axes[axis_index].max_digit; - ranged_val = ((axis_val - ref) * 127) / (range - ref); + ranged_val = ((axis_val - ref) * JOYSTICK_RESOLUTION) / (range - ref); } // clamp the result in the valid range - ranged_val = ranged_val < -127 ? -127 : ranged_val; - ranged_val = ranged_val > 127 ? 127 : ranged_val; + ranged_val = ranged_val < -JOYSTICK_RESOLUTION ? -JOYSTICK_RESOLUTION : ranged_val; + ranged_val = ranged_val > JOYSTICK_RESOLUTION ? JOYSTICK_RESOLUTION : ranged_val; if (ranged_val != joystick_status.axes[axis_index]) { joystick_status.axes[axis_index] = ranged_val; diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h index 1aa33c998d1e..2a0549ab8967 100644 --- a/tmk_core/common/report.h +++ b/tmk_core/common/report.h @@ -192,7 +192,11 @@ typedef struct { typedef struct { #if JOYSTICK_AXES_COUNT > 0 - int8_t axes[JOYSTICK_AXES_COUNT]; +# if JOYSTICK_AXES_RESOLUTION > 8 + int16_t axes[JOYSTICK_AXES_COUNT]; +# else + int8_t axes[JOYSTICK_AXES_COUNT]; +# endif #endif #if JOYSTICK_BUTTON_COUNT > 0 diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c index f5d32445de50..a0c0d4cdc80f 100644 --- a/tmk_core/protocol/usb_descriptor.c +++ b/tmk_core/protocol/usb_descriptor.c @@ -41,6 +41,10 @@ #include "usb_descriptor.h" #include "usb_descriptor_common.h" +#ifdef JOYSTICK_ENABLE +# include "joystick.h" +#endif + // clang-format off /* @@ -308,10 +312,17 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM JoystickReport[] = { HID_RI_USAGE(8, 0x35), // Rz # endif # if JOYSTICK_AXES_COUNT >= 1 - HID_RI_LOGICAL_MINIMUM(8, -127), - HID_RI_LOGICAL_MAXIMUM(8, 127), + # if JOYSTICK_AXES_RESOLUTION == 8 + HID_RI_LOGICAL_MINIMUM(8, -JOYSTICK_RESOLUTION), + HID_RI_LOGICAL_MAXIMUM(8, JOYSTICK_RESOLUTION), HID_RI_REPORT_COUNT(8, JOYSTICK_AXES_COUNT), HID_RI_REPORT_SIZE(8, 0x08), + # else + HID_RI_LOGICAL_MINIMUM(16, -JOYSTICK_RESOLUTION), + HID_RI_LOGICAL_MAXIMUM(16, JOYSTICK_RESOLUTION), + HID_RI_REPORT_COUNT(8, JOYSTICK_AXES_COUNT), + HID_RI_REPORT_SIZE(8, 0x10), + # endif HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), # endif From ebf53acebb382d4c2a0736e6a89df8728b3090c3 Mon Sep 17 00:00:00 2001 From: Ryan Date: Sun, 4 Oct 2020 06:00:21 +1100 Subject: [PATCH 08/13] Per-encoder resolutions (#10259) * Per-encoder resolutions * Resolutions for right hand --- docs/feature_encoders.md | 9 ++++++++- quantum/encoder.c | 24 ++++++++++++++++++++---- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/docs/feature_encoders.md b/docs/feature_encoders.md index 8f9ba1a80a79..e2cafdac48e8 100644 --- a/docs/feature_encoders.md +++ b/docs/feature_encoders.md @@ -32,13 +32,20 @@ Additionally, the resolution, which defines how many pulses the encoder register #define ENCODER_RESOLUTION 4 ``` +It can also be defined per-encoder, by instead defining: + +```c +#define ENCODER_RESOLUTIONS { 4, 2 } +``` + ## Split Keyboards -If you are using different pinouts for the encoders on each half of a split keyboard, you can define the pinout for the right half like this: +If you are using different pinouts for the encoders on each half of a split keyboard, you can define the pinout (and optionally, resolutions) for the right half like this: ```c #define ENCODERS_PAD_A_RIGHT { encoder1a, encoder2a } #define ENCODERS_PAD_B_RIGHT { encoder1b, encoder2b } +#define ENCODER_RESOLUTIONS_RIGHT { 2, 4 } ``` ## Callbacks diff --git a/quantum/encoder.c b/quantum/encoder.c index 81ec1bb376c8..7ca31afedc2f 100644 --- a/quantum/encoder.c +++ b/quantum/encoder.c @@ -23,7 +23,7 @@ // for memcpy #include -#ifndef ENCODER_RESOLUTION +#if !defined(ENCODER_RESOLUTIONS) && !defined(ENCODER_RESOLUTION) # define ENCODER_RESOLUTION 4 #endif @@ -34,6 +34,9 @@ #define NUMBER_OF_ENCODERS (sizeof(encoders_pad_a) / sizeof(pin_t)) static pin_t encoders_pad_a[] = ENCODERS_PAD_A; static pin_t encoders_pad_b[] = ENCODERS_PAD_B; +#ifdef ENCODER_RESOLUTIONS +static uint8_t encoder_resolutions[] = ENCODER_RESOLUTIONS; +#endif #ifndef ENCODER_DIRECTION_FLIP # define ENCODER_CLOCKWISE true @@ -65,9 +68,15 @@ void encoder_init(void) { if (!isLeftHand) { const pin_t encoders_pad_a_right[] = ENCODERS_PAD_A_RIGHT; const pin_t encoders_pad_b_right[] = ENCODERS_PAD_B_RIGHT; +# if defined(ENCODER_RESOLUTIONS_RIGHT) + const uint8_t encoder_resolutions_right[] = ENCODER_RESOLUTIONS_RIGHT; +# endif for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) { encoders_pad_a[i] = encoders_pad_a_right[i]; encoders_pad_b[i] = encoders_pad_b_right[i]; +# if defined(ENCODER_RESOLUTIONS_RIGHT) + encoder_resolutions[i] = encoder_resolutions_right[i]; +# endif } } #endif @@ -87,19 +96,26 @@ void encoder_init(void) { static void encoder_update(int8_t index, uint8_t state) { uint8_t i = index; + +#ifdef ENCODER_RESOLUTIONS + int8_t resolution = encoder_resolutions[i]; +#else + int8_t resolution = ENCODER_RESOLUTION; +#endif + #ifdef SPLIT_KEYBOARD index += thisHand; #endif encoder_pulses[i] += encoder_LUT[state & 0xF]; - if (encoder_pulses[i] >= ENCODER_RESOLUTION) { + if (encoder_pulses[i] >= resolution) { encoder_value[index]++; encoder_update_kb(index, ENCODER_COUNTER_CLOCKWISE); } - if (encoder_pulses[i] <= -ENCODER_RESOLUTION) { // direction is arbitrary here, but this clockwise + if (encoder_pulses[i] <= -resolution) { // direction is arbitrary here, but this clockwise encoder_value[index]--; encoder_update_kb(index, ENCODER_CLOCKWISE); } - encoder_pulses[i] %= ENCODER_RESOLUTION; + encoder_pulses[i] %= resolution; } void encoder_read(void) { From f755126e7450be6c9ca3c3e3bfae0f3421014cda Mon Sep 17 00:00:00 2001 From: Manna Harbour <51143715+manna-harbour@users.noreply.github.com> Date: Sun, 4 Oct 2020 06:12:20 +1100 Subject: [PATCH 09/13] Share button state from mousekey to pointing_device (#10179) * Branch point for 2020 November 28 Breaking Change Update readme.md * Share button state from mousekey to pointing_device Co-authored-by: Nick Brassel Co-authored-by: James Young <18669334+noroadsleft@users.noreply.github.com> Co-authored-by: Nick Brassel --- docs/feature_mouse_keys.md | 4 ++++ tmk_core/common/action.c | 49 +++++++++++++++++++++++++++++++------- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/docs/feature_mouse_keys.md b/docs/feature_mouse_keys.md index a6b46bc151f3..ffde13389242 100644 --- a/docs/feature_mouse_keys.md +++ b/docs/feature_mouse_keys.md @@ -140,3 +140,7 @@ To use constant speed mode, you must at least define `MK_COMBINED` in your keyma ```c #define MK_COMBINED ``` + +## Use with PS/2 Mouse and Pointing Device + +Mouse keys button state is shared with [PS/2 mouse](feature_ps2_mouse.md) and [pointing device](feature_pointing_device.md) so mouse keys button presses can be used for clicks and drags. diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c index ee9aa0df77db..f2560504a26d 100644 --- a/tmk_core/common/action.c +++ b/tmk_core/common/action.c @@ -37,6 +37,10 @@ along with this program. If not, see . # include "nodebug.h" #endif +#ifdef POINTING_DEVICE_ENABLE +# include "pointing_device.h" +#endif + int tp_buttons; #ifdef RETRO_TAPPING @@ -220,6 +224,19 @@ void process_record_handler(keyrecord_t *record) { process_action(record, action); } +#if defined(PS2_MOUSE_ENABLE) || defined(POINTING_DEVICE_ENABLE) +void register_button(bool pressed, enum mouse_buttons button) { + #ifdef PS2_MOUSE_ENABLE + tp_buttons = pressed ? tp_buttons | button : tp_buttons & ~button; + #endif + #ifdef POINTING_DEVICE_ENABLE + report_mouse_t currentReport = pointing_device_get_report(); + currentReport.buttons = pressed ? currentReport.buttons | button : currentReport.buttons & ~button; + pointing_device_set_report(currentReport); + #endif +} +#endif + /** \brief Take an action and processes it. * * FIXME: Needs documentation. @@ -404,15 +421,23 @@ void process_action(keyrecord_t *record, action_t action) { if (event.pressed) { mousekey_on(action.key.code); switch (action.key.code) { -# ifdef PS2_MOUSE_ENABLE +# if defined(PS2_MOUSE_ENABLE) || defined(POINTING_DEVICE_ENABLE) case KC_MS_BTN1: - tp_buttons |= (1 << 0); + register_button(true, MOUSE_BTN1); break; case KC_MS_BTN2: - tp_buttons |= (1 << 1); + register_button(true, MOUSE_BTN2); break; case KC_MS_BTN3: - tp_buttons |= (1 << 2); + register_button(true, MOUSE_BTN3); + break; +# endif +# ifdef POINTING_DEVICE_ENABLE + case KC_MS_BTN4: + register_button(true, MOUSE_BTN4); + break; + case KC_MS_BTN5: + register_button(true, MOUSE_BTN5); break; # endif default: @@ -422,15 +447,23 @@ void process_action(keyrecord_t *record, action_t action) { } else { mousekey_off(action.key.code); switch (action.key.code) { -# ifdef PS2_MOUSE_ENABLE +# if defined(PS2_MOUSE_ENABLE) || defined(POINTING_DEVICE_ENABLE) case KC_MS_BTN1: - tp_buttons &= ~(1 << 0); + register_button(false, MOUSE_BTN1); break; case KC_MS_BTN2: - tp_buttons &= ~(1 << 1); + register_button(false, MOUSE_BTN2); break; case KC_MS_BTN3: - tp_buttons &= ~(1 << 2); + register_button(false, MOUSE_BTN3); + break; +# endif +# ifdef POINTING_DEVICE_ENABLE + case KC_MS_BTN4: + register_button(false, MOUSE_BTN4); + break; + case KC_MS_BTN5: + register_button(false, MOUSE_BTN5); break; # endif default: From 633fe33b1b2d744ccb7699498a6d20742ab9c48e Mon Sep 17 00:00:00 2001 From: LSChyi Date: Sun, 4 Oct 2020 03:19:04 +0800 Subject: [PATCH 10/13] Add hotfix for chibios keyboards not wake (#10088) --- tmk_core/protocol/chibios/main.c | 1 + tmk_core/protocol/chibios/usb_main.c | 7 +++++++ tmk_core/protocol/chibios/usb_main.h | 3 +++ 3 files changed, 11 insertions(+) diff --git a/tmk_core/protocol/chibios/main.c b/tmk_core/protocol/chibios/main.c index a0d28f9afc08..0e577d551954 100644 --- a/tmk_core/protocol/chibios/main.c +++ b/tmk_core/protocol/chibios/main.c @@ -230,6 +230,7 @@ int main(void) { /* Remote wakeup */ if (suspend_wakeup_condition()) { usbWakeupHost(&USB_DRIVER); + restart_usb_driver(&USB_DRIVER); } } /* Woken up */ diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c index ae33e86a70de..59f6feb9519a 100644 --- a/tmk_core/protocol/chibios/usb_main.c +++ b/tmk_core/protocol/chibios/usb_main.c @@ -574,6 +574,13 @@ void init_usb_driver(USBDriver *usbp) { chVTObjectInit(&keyboard_idle_timer); } +void restart_usb_driver(USBDriver *usbp) { + usbStop(usbp); + usbDisconnectBus(usbp); + usbStart(usbp, &usbcfg); + usbConnectBus(usbp); +} + /* --------------------------------------------------------- * Keyboard functions * --------------------------------------------------------- diff --git a/tmk_core/protocol/chibios/usb_main.h b/tmk_core/protocol/chibios/usb_main.h index 94baf9b35e06..d8813f480134 100644 --- a/tmk_core/protocol/chibios/usb_main.h +++ b/tmk_core/protocol/chibios/usb_main.h @@ -35,6 +35,9 @@ /* Initialize the USB driver and bus */ void init_usb_driver(USBDriver *usbp); +/* Restart the USB driver and bus */ +void restart_usb_driver(USBDriver *usbp); + /* --------------- * Keyboard header * --------------- From 1d40f26368d888b3a77119783527918e95ccdd25 Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Sat, 3 Oct 2020 18:37:19 -0700 Subject: [PATCH 11/13] Add advanced/efficient RGB Matrix Indicators (#8564) * Add Advanced RGB Matrix effects Add a new option, so that we can better handle custom indicators * Switch to led min/max instead of params Because params has already been incremented and is wrong now * Add indicator color function for use with advanced indicator functions * Add docs and helper macros * Add comment for explanations * Fix macro variables * Fix typo * Run clang-format on rgb_matrix.h --- docs/feature_rgb_matrix.md | 8 ++++++++ quantum/rgb_matrix.c | 30 ++++++++++++++++++++++++++---- quantum/rgb_matrix.h | 9 +++++++++ 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/docs/feature_rgb_matrix.md b/docs/feature_rgb_matrix.md index a8fad59a191a..68821b7cecf7 100644 --- a/docs/feature_rgb_matrix.md +++ b/docs/feature_rgb_matrix.md @@ -482,6 +482,14 @@ void rgb_matrix_indicators_kb(void) { } ``` +In addition, there are the advanced indicator functions. These are aimed at those with heavily customized displays, where rendering every LED per cycle is expensive. Such as some of the "drashna" layouts. This includes a special macro to help make this easier to use: `RGB_MATRIX_INDICATOR_SET_COLOR(i, r, g, b)`. + +```c +void rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) { + RGB_MATRIX_INDICATOR_SET_COLOR(index, red, green, blue); +} +``` + ### Suspended state :id=suspended-state To use the suspend feature, make sure that `#define RGB_DISABLE_WHEN_USB_SUSPENDED true` is added to the `config.h` file. diff --git a/quantum/rgb_matrix.c b/quantum/rgb_matrix.c index 802c5afcee21..b7485f5d7bfe 100644 --- a/quantum/rgb_matrix.c +++ b/quantum/rgb_matrix.c @@ -401,6 +401,10 @@ void rgb_matrix_task(void) { break; case RENDERING: rgb_task_render(effect); + if (!suspend_backlight) { + rgb_matrix_indicators(); + rgb_matrix_indicators_advanced(&rgb_effect_params); + } break; case FLUSHING: rgb_task_flush(effect); @@ -409,10 +413,6 @@ void rgb_matrix_task(void) { rgb_task_sync(); break; } - - if (!suspend_backlight) { - rgb_matrix_indicators(); - } } void rgb_matrix_indicators(void) { @@ -424,6 +424,28 @@ __attribute__((weak)) void rgb_matrix_indicators_kb(void) {} __attribute__((weak)) void rgb_matrix_indicators_user(void) {} +void rgb_matrix_indicators_advanced(effect_params_t *params) { + /* special handling is needed for "params->iter", since it's already been incremented. + * Could move the invocations to rgb_task_render, but then it's missing a few checks + * and not sure which would be better. Otherwise, this should be called from + * rgb_task_render, right before the iter++ line. + */ +#if defined(RGB_MATRIX_LED_PROCESS_LIMIT) && RGB_MATRIX_LED_PROCESS_LIMIT > 0 && RGB_MATRIX_LED_PROCESS_LIMIT < DRIVER_LED_TOTAL + uint8_t min = RGB_MATRIX_LED_PROCESS_LIMIT * (params->iter - 1); + uint8_t max = min + RGB_MATRIX_LED_PROCESS_LIMIT; + if (max > DRIVER_LED_TOTAL) max = DRIVER_LED_TOTAL; +#else + uint8_t min = 0; + uint8_t max = DRIVER_LED_TOTAL; +#endif + rgb_matrix_indicators_advanced_kb(min, max); + rgb_matrix_indicators_advanced_user(min, max); +} + +__attribute__((weak)) void rgb_matrix_indicators_advanced_kb(uint8_t led_min, uint8_t led_max) {} + +__attribute__((weak)) void rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {} + void rgb_matrix_init(void) { rgb_matrix_driver.init(); diff --git a/quantum/rgb_matrix.h b/quantum/rgb_matrix.h index 733333349faa..771a1fcd35f6 100644 --- a/quantum/rgb_matrix.h +++ b/quantum/rgb_matrix.h @@ -57,6 +57,11 @@ uint8_t max = DRIVER_LED_TOTAL; #endif +#define RGB_MATRIX_INDICATOR_SET_COLOR(i, r, g, b) \ + if (i >= led_min && i <= led_max) { \ + rgb_matrix_set_color(i, r, g, b); \ + } + #define RGB_MATRIX_TEST_LED_FLAGS() \ if (!HAS_ANY_FLAGS(g_led_config.flags[i], params->flags)) continue @@ -103,6 +108,10 @@ void rgb_matrix_indicators(void); void rgb_matrix_indicators_kb(void); void rgb_matrix_indicators_user(void); +void rgb_matrix_indicators_advanced(effect_params_t *params); +void rgb_matrix_indicators_advanced_kb(uint8_t led_min, uint8_t led_max); +void rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max); + void rgb_matrix_init(void); void rgb_matrix_set_suspend_state(bool state); From 360ef75e5c15872b413c5059e6c489dadbddddbf Mon Sep 17 00:00:00 2001 From: Nick Brassel Date: Mon, 5 Oct 2020 10:40:10 +1100 Subject: [PATCH 12/13] Naming change. --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 6cad60f8769a..75b558db2c5e 100644 --- a/Makefile +++ b/Makefile @@ -278,15 +278,15 @@ define PARSE_RULE ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,all),true) KEYBOARD_RULE=all $$(eval $$(call PARSE_ALL_KEYBOARDS)) - else ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,avr),true) + else ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,all-avr),true) KEYBOARD_RULE=all REQUIRE_PLATFORM_KEY := avr $$(eval $$(call PARSE_ALL_KEYBOARDS)) - else ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,chibios),true) + else ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,all-chibios),true) KEYBOARD_RULE=all REQUIRE_PLATFORM_KEY := chibios $$(eval $$(call PARSE_ALL_KEYBOARDS)) - else ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,arm_atsam),true) + else ifeq ($$(call COMPARE_AND_REMOVE_FROM_RULE,all-arm_atsam),true) KEYBOARD_RULE=all REQUIRE_PLATFORM_KEY := arm_atsam $$(eval $$(call PARSE_ALL_KEYBOARDS)) From c3de342b4366f346871c450856c984d54f0a6b5c Mon Sep 17 00:00:00 2001 From: Manna Harbour <51143715+manna-harbour@users.noreply.github.com> Date: Fri, 31 Jul 2020 14:19:34 +1000 Subject: [PATCH 13/13] Add Retro Shift (Auto Shift for Tap Hold via Retro Tapping) --- docs/feature_auto_shift.md | 2 ++ docs/tap_hold.md | 20 ++++++++++++++++ tmk_core/common/action.c | 48 +++++++++++++++++++++++++++++++++++--- 3 files changed, 67 insertions(+), 3 deletions(-) diff --git a/docs/feature_auto_shift.md b/docs/feature_auto_shift.md index b21a7690d9e4..325a70cc4bbe 100644 --- a/docs/feature_auto_shift.md +++ b/docs/feature_auto_shift.md @@ -34,6 +34,8 @@ Yes, unfortunately. for a shifted version, but we did not. On the other hand, we may think we are tapping the keys, but really we have held it for a little longer than anticipated. +3. Auto Shift does not apply to Tap Hold keys. For automatic shifting of Tap Hold + keys see [Retro Shift](tap_hold.md#retro-shift). ## How Do I Enable Auto Shift? diff --git a/docs/tap_hold.md b/docs/tap_hold.md index 589ec3181609..e873ad0105de 100644 --- a/docs/tap_hold.md +++ b/docs/tap_hold.md @@ -179,6 +179,26 @@ Holding and releasing a dual function key without pressing another key will resu For instance, holding and releasing `LT(2, KC_SPACE)` without hitting another key will result in nothing happening. With this enabled, it will send `KC_SPACE` instead. +## Retro Shift + +Holding and releasing a Tap Hold key without pressing another key will result in only the hold. With Retro Shift enabled this action will also produce a shifted version of the tap keycode on release. + +This is a supplement to [Auto Shift](feature_auto_shift.md), which does not support Tap Hold. Auto Shift is not required to be enabled, but for consistency it should be enabled and configured with the Auto Shift timeout matching the tapping term. Retro Shift applies to the same tap keycodes as Auto Shift and uses the Auto Shift options `NO_AUTO_SHIFT_SPECIAL`, `NO_AUTO_SHIFT_NUMERIC`, `NO_AUTO_SHIFT_ALPHA`, and `AUTO_SHIFT_MODIFIERS` if defined. + +Retro Shift does not require [Retro Tapping](#retro-tapping) to be enabled, and if both are enabled Retro Tapping will only apply if the tap keycode is not matched by Retro Shift. + +To enable Retro Shift, add the following to your `config.h`: + +```c +#define RETRO_SHIFT +``` + +If `RETRO_SHIFT` is defined to a value, hold times greater than that value will not produce a tap on release. This enables modifiers to be held for combining with mouse clicks without generating taps on release. For example: + +```c +#define RETRO_SHIFT 500 +``` + ## Why do we include the key record for the per key functions? One thing that you may notice is that we include the key record for all of the "per key" functions, and may be wondering why we do that. diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c index f2560504a26d..4180422b47d3 100644 --- a/tmk_core/common/action.c +++ b/tmk_core/common/action.c @@ -43,10 +43,14 @@ along with this program. If not, see . int tp_buttons; -#ifdef RETRO_TAPPING +#if defined(RETRO_TAPPING) || defined(RETRO_SHIFT) int retro_tapping_counter = 0; #endif +#ifdef RETRO_SHIFT +# include "quantum.h" +#endif + #ifdef FAUXCLICKY_ENABLE # include #endif @@ -71,7 +75,7 @@ void action_exec(keyevent_t event) { dprint("EVENT: "); debug_event(event); dprintln(); -#ifdef RETRO_TAPPING +#if defined(RETRO_TAPPING) || defined(RETRO_SHIFT) retro_tapping_counter++; #endif } @@ -246,10 +250,16 @@ void process_action(keyrecord_t *record, action_t action) { #ifndef NO_ACTION_TAPPING uint8_t tap_count = record->tap.count; #endif +#ifdef RETRO_SHIFT + static uint16_t retro_shift_start_time; +#endif if (event.pressed) { // clear the potential weak mods left by previously pressed keys clear_weak_mods(); +#ifdef RETRO_SHIFT + retro_shift_start_time = event.time; +#endif } #ifndef NO_ACTION_ONESHOT @@ -725,7 +735,7 @@ void process_action(keyrecord_t *record, action_t action) { #endif #ifndef NO_ACTION_TAPPING -# ifdef RETRO_TAPPING +# if defined(RETRO_TAPPING) || defined(RETRO_SHIFT) if (!is_tap_action(action)) { retro_tapping_counter = 0; } else { @@ -739,7 +749,39 @@ void process_action(keyrecord_t *record, action_t action) { retro_tapping_counter = 0; } else { if (retro_tapping_counter == 2) { +# ifdef RETRO_SHIFT + if(!(RETRO_SHIFT + 0) || TIMER_DIFF_16(event.time, retro_shift_start_time) < (RETRO_SHIFT + 0)){ + + switch (action.layer_tap.code) { +# ifndef NO_AUTO_SHIFT_ALPHA + case KC_A ... KC_Z: +# endif +# ifndef NO_AUTO_SHIFT_NUMERIC + case KC_1 ... KC_0: +# endif +# ifndef NO_AUTO_SHIFT_SPECIAL + case KC_TAB: + case KC_MINUS ... KC_SLASH: + case KC_NONUS_BSLASH: +# endif +# ifndef AUTO_SHIFT_MODIFIERS + if (get_mods()) { + tap_code(action.layer_tap.code); + break; + } +# endif + tap_code16(LSFT(action.layer_tap.code)); + break; + default: +# ifdef RETRO_TAPPING + tap_code(action.layer_tap.code); +# endif + ; + } + } +# else tap_code(action.layer_tap.code); +# endif } retro_tapping_counter = 0; }