diff options
Diffstat (limited to 'tmk_core')
47 files changed, 534 insertions, 586 deletions
diff --git a/tmk_core/avr.mk b/tmk_core/avr.mk index 690154535b..d942e7ade5 100644 --- a/tmk_core/avr.mk +++ b/tmk_core/avr.mk @@ -237,6 +237,15 @@ endef bootloadHID: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware $(call EXEC_BOOTLOADHID) +HID_BOOTLOADER_CLI ?= hid_bootloader_cli + +define EXEC_HID_LUFA + $(HID_BOOTLOADER_CLI) -mmcu=$(MCU) -w -v $(BUILD_DIR)/$(TARGET).hex +endef + +hid_bootloader: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware + $(call EXEC_HID_LUFA) + # Convert hex to bin. bin: $(BUILD_DIR)/$(TARGET).hex $(OBJCOPY) -Iihex -Obinary $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin @@ -295,19 +304,26 @@ extcoff: $(BUILD_DIR)/$(TARGET).elf @$(SECHO) $(MSG_EXTENDED_COFF) $(BUILD_DIR)/$(TARGET).cof $(COFFCONVERT) -O coff-ext-avr $< $(BUILD_DIR)/$(TARGET).cof -bootloader: -ifneq ($(strip $(BOOTLOADER)), qmk-dfu) - $(error Please set BOOTLOADER = qmk-dfu first!) +ifeq ($(strip $(BOOTLOADER)), qmk-dfu) +QMK_BOOTLOADER_TYPE = DFU +else ifeq ($(strip $(BOOTLOADER)), qmk-hid) +QMK_BOOTLOADER_TYPE = HID endif - make -C lib/lufa/Bootloaders/DFU/ clean - $(QMK_BIN) generate-dfu-header --quiet --keyboard $(KEYBOARD) --output lib/lufa/Bootloaders/DFU/Keyboard.h - $(eval MAX_SIZE=$(shell n=`$(CC) -E -mmcu=$(MCU) $(CFLAGS) $(OPT_DEFS) tmk_core/common/avr/bootloader_size.c 2> /dev/null | sed -ne 's/\r//;/^#/n;/^AVR_SIZE:/,$${s/^AVR_SIZE: //;p;}'` && echo $$(($$n)) || echo 0)) + +bootloader: +ifeq ($(strip $(QMK_BOOTLOADER_TYPE)),) + $(error Please set BOOTLOADER to "qmk-dfu" or "qmk-hid" first!) +else + make -C lib/lufa/Bootloaders/$(QMK_BOOTLOADER_TYPE)/ clean + $(QMK_BIN) generate-dfu-header --quiet --keyboard $(KEYBOARD) --output lib/lufa/Bootloaders/$(QMK_BOOTLOADER_TYPE)/Keyboard.h + $(eval MAX_SIZE=$(shell n=`$(CC) -E -mmcu=$(MCU) -D__ASSEMBLER__ $(CFLAGS) $(OPT_DEFS) tmk_core/common/avr/bootloader_size.c 2> /dev/null | sed -ne 's/\r//;/^#/n;/^AVR_SIZE:/,$${s/^AVR_SIZE: //;p;}'` && echo $$(($$n)) || echo 0)) $(eval PROGRAM_SIZE_KB=$(shell n=`expr $(MAX_SIZE) / 1024` && echo $$(($$n)) || echo 0)) $(eval BOOT_SECTION_SIZE_KB=$(shell n=`expr $(BOOTLOADER_SIZE) / 1024` && echo $$(($$n)) || echo 0)) $(eval FLASH_SIZE_KB=$(shell n=`expr $(PROGRAM_SIZE_KB) + $(BOOT_SECTION_SIZE_KB)` && echo $$(($$n)) || echo 0)) - make -C lib/lufa/Bootloaders/DFU/ MCU=$(MCU) ARCH=$(ARCH) F_CPU=$(F_CPU) FLASH_SIZE_KB=$(FLASH_SIZE_KB) BOOT_SECTION_SIZE_KB=$(BOOT_SECTION_SIZE_KB) - printf "BootloaderDFU.hex copied to $(TARGET)_bootloader.hex\n" - cp lib/lufa/Bootloaders/DFU/BootloaderDFU.hex $(TARGET)_bootloader.hex + make -C lib/lufa/Bootloaders/$(QMK_BOOTLOADER_TYPE)/ MCU=$(MCU) ARCH=$(ARCH) F_CPU=$(F_CPU) FLASH_SIZE_KB=$(FLASH_SIZE_KB) BOOT_SECTION_SIZE_KB=$(BOOT_SECTION_SIZE_KB) + printf "Bootloader$(QMK_BOOTLOADER_TYPE).hex copied to $(TARGET)_bootloader.hex\n" + cp lib/lufa/Bootloaders/$(QMK_BOOTLOADER_TYPE)/Bootloader$(QMK_BOOTLOADER_TYPE).hex $(TARGET)_bootloader.hex +endif production: $(BUILD_DIR)/$(TARGET).hex bootloader cpfirmware @cat $(BUILD_DIR)/$(TARGET).hex | awk '/^:00000001FF/ == 0' > $(TARGET)_production.hex @@ -328,6 +344,8 @@ else ifeq ($(strip $(BOOTLOADER)), USBasp) $(call EXEC_USBASP) else ifeq ($(strip $(BOOTLOADER)), bootloadHID) $(call EXEC_BOOTLOADHID) +else ifeq ($(strip $(BOOTLOADER)), qmk-hid) + $(call EXEC_HID_LUFA) else $(PRINT_OK); $(SILENT) || printf "$(MSG_FLASH_BOOTLOADER)" endif diff --git a/tmk_core/chibios.mk b/tmk_core/chibios.mk index 97299b7d32..7eda360460 100644 --- a/tmk_core/chibios.mk +++ b/tmk_core/chibios.mk @@ -390,8 +390,10 @@ ifndef TEENSY_LOADER_CLI endif endif +TEENSY_LOADER_CLI_MCU ?= $(MCU_LDSCRIPT) + define EXEC_TEENSY - $(TEENSY_LOADER_CLI) -mmcu=$(MCU_LDSCRIPT) -w -v $(BUILD_DIR)/$(TARGET).hex + $(TEENSY_LOADER_CLI) -mmcu=$(TEENSY_LOADER_CLI_MCU) -w -v $(BUILD_DIR)/$(TARGET).hex endef teensy: $(BUILD_DIR)/$(TARGET).hex cpfirmware sizeafter @@ -408,6 +410,8 @@ else ifeq ($(strip $(BOOTLOADER)),kiibohd) $(call EXEC_DFU_UTIL) else ifeq ($(strip $(MCU_FAMILY)),KINETIS) $(call EXEC_TEENSY) +else ifeq ($(strip $(MCU_FAMILY)),MIMXRT1062) + $(call EXEC_TEENSY) else ifeq ($(strip $(MCU_FAMILY)),STM32) $(call EXEC_DFU_UTIL) else diff --git a/tmk_core/common.mk b/tmk_core/common.mk index 2f8f81126a..bd4142364c 100644 --- a/tmk_core/common.mk +++ b/tmk_core/common.mk @@ -8,22 +8,16 @@ TMK_COMMON_SRC += $(COMMON_DIR)/host.c \ $(COMMON_DIR)/action_macro.c \ $(COMMON_DIR)/action_layer.c \ $(COMMON_DIR)/action_util.c \ - $(COMMON_DIR)/debug.c \ - $(COMMON_DIR)/sendchar_null.c \ $(COMMON_DIR)/eeconfig.c \ $(COMMON_DIR)/report.c \ + $(COMMON_DIR)/sync_timer.c \ $(COMMON_DIR)/usb_util.c \ $(PLATFORM_COMMON_DIR)/suspend.c \ $(PLATFORM_COMMON_DIR)/timer.c \ - $(COMMON_DIR)/sync_timer.c \ $(PLATFORM_COMMON_DIR)/bootloader.c \ -# Use platform provided print - fall back to lib/printf -ifneq ("$(wildcard $(TMK_PATH)/$(PLATFORM_COMMON_DIR)/printf.mk)","") - include $(TMK_PATH)/$(PLATFORM_COMMON_DIR)/printf.mk -else - include $(TMK_PATH)/$(COMMON_DIR)/lib_printf.mk -endif +# Use platform provided print if it exists +-include $(TMK_PATH)/$(PLATFORM_COMMON_DIR)/printf.mk SHARED_EP_ENABLE = no MOUSE_SHARED_EP ?= yes @@ -55,6 +49,7 @@ endif ifeq ($(strip $(CONSOLE_ENABLE)), yes) TMK_COMMON_DEFS += -DCONSOLE_ENABLE else + # TODO: decouple this so other print backends can exist TMK_COMMON_DEFS += -DNO_PRINT TMK_COMMON_DEFS += -DNO_DEBUG endif diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c index bd41d28b66..d19fd2a045 100644 --- a/tmk_core/common/action.c +++ b/tmk_core/common/action.c @@ -55,6 +55,8 @@ __attribute__((weak)) bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrec __attribute__((weak)) bool get_retro_tapping(uint16_t keycode, keyrecord_t *record) { return false; } #endif +__attribute__((weak)) bool pre_process_record_quantum(keyrecord_t *record) { return true; } + #ifndef TAP_CODE_DELAY # define TAP_CODE_DELAY 0 #endif @@ -106,9 +108,13 @@ void action_exec(keyevent_t event) { #endif #ifndef NO_ACTION_TAPPING - action_tapping_process(record); + if (IS_NOEVENT(record.event) || pre_process_record_quantum(&record)) { + action_tapping_process(record); + } #else - process_record(&record); + if (IS_NOEVENT(record.event) || pre_process_record_quantum(&record)) { + process_record(&record); + } if (!IS_NOEVENT(record.event)) { dprint("processed: "); debug_record(record); @@ -206,7 +212,16 @@ void process_record(keyrecord_t *record) { } void process_record_handler(keyrecord_t *record) { +#ifdef COMBO_ENABLE + action_t action; + if (record->keycode) { + action = action_for_keycode(record->keycode); + } else { + action = store_or_get_action(record->event.pressed, record->event.key); + } +#else action_t action = store_or_get_action(record->event.pressed, record->event.key); +#endif dprint("ACTION: "); debug_action(action); #ifndef NO_ACTION_LAYER @@ -994,6 +1009,24 @@ bool is_tap_key(keypos_t key) { * * FIXME: Needs documentation. */ +bool is_tap_record(keyrecord_t *record) { +#ifdef COMBO_ENABLE + action_t action; + if (record->keycode) { + action = action_for_keycode(record->keycode); + } else { + action = layer_switch_get_action(record->event.key); + } +#else + action_t action = layer_switch_get_action(record->event.key); +#endif + return is_tap_action(action); +} + +/** \brief Utilities for actions. (FIXME: Needs better description) + * + * FIXME: Needs documentation. + */ bool is_tap_action(action_t action) { switch (action.kind.id) { case ACT_LMODS_TAP: diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h index 8cb4722c6e..3d357b33b8 100644 --- a/tmk_core/common/action.h +++ b/tmk_core/common/action.h @@ -53,6 +53,9 @@ typedef struct { #ifndef NO_ACTION_TAPPING tap_t tap; #endif +#ifdef COMBO_ENABLE + uint16_t keycode; +#endif } keyrecord_t; /* Execute action per keyevent */ @@ -60,6 +63,7 @@ void action_exec(keyevent_t event); /* action for key */ action_t action_for_key(uint8_t layer, keypos_t key); +action_t action_for_keycode(uint16_t keycode); /* macro */ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt); @@ -111,6 +115,7 @@ void clear_keyboard_but_mods(void); void clear_keyboard_but_mods_and_keys(void); void layer_switch(uint8_t new_layer); bool is_tap_key(keypos_t key); +bool is_tap_record(keyrecord_t *record); bool is_tap_action(action_t action); #ifndef NO_ACTION_TAPPING diff --git a/tmk_core/common/action_layer.c b/tmk_core/common/action_layer.c index af2d7d964b..ed1a4bd20d 100644 --- a/tmk_core/common/action_layer.c +++ b/tmk_core/common/action_layer.c @@ -131,32 +131,32 @@ bool layer_state_cmp(layer_state_t cmp_layer_state, uint8_t layer) { if (!cmp_layer_state) { return layer == 0; } - return (cmp_layer_state & (1UL << layer)) != 0; + return (cmp_layer_state & ((layer_state_t)1 << layer)) != 0; } /** \brief Layer move * * Turns on the given layer and turn off all other layers */ -void layer_move(uint8_t layer) { layer_state_set(1UL << layer); } +void layer_move(uint8_t layer) { layer_state_set((layer_state_t)1 << layer); } /** \brief Layer on * * Turns on given layer */ -void layer_on(uint8_t layer) { layer_state_set(layer_state | (1UL << layer)); } +void layer_on(uint8_t layer) { layer_state_set(layer_state | ((layer_state_t)1 << layer)); } /** \brief Layer off * * Turns off given layer */ -void layer_off(uint8_t layer) { layer_state_set(layer_state & ~(1UL << layer)); } +void layer_off(uint8_t layer) { layer_state_set(layer_state & ~((layer_state_t)1 << layer)); } /** \brief Layer invert * * Toggle the given layer (set it if it's unset, or unset it if it's set) */ -void layer_invert(uint8_t layer) { layer_state_set(layer_state ^ (1UL << layer)); } +void layer_invert(uint8_t layer) { layer_state_set(layer_state ^ ((layer_state_t)1 << layer)); } /** \brief Layer or * @@ -258,7 +258,7 @@ uint8_t layer_switch_get_layer(keypos_t key) { layer_state_t layers = layer_state | default_layer_state; /* check top layer first */ for (int8_t i = MAX_LAYER - 1; i >= 0; i--) { - if (layers & (1UL << i)) { + if (layers & ((layer_state_t)1 << i)) { action = action_for_key(i, key); if (action.code != ACTION_TRANSPARENT) { return i; diff --git a/tmk_core/common/action_layer.h b/tmk_core/common/action_layer.h index d72cd3e3a5..b87d096eed 100644 --- a/tmk_core/common/action_layer.h +++ b/tmk_core/common/action_layer.h @@ -21,6 +21,29 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include "keyboard.h" #include "action.h" +#ifdef DYNAMIC_KEYMAP_ENABLE +# ifndef DYNAMIC_KEYMAP_LAYER_COUNT +# define DYNAMIC_KEYMAP_LAYER_COUNT 4 +# endif +# if DYNAMIC_KEYMAP_LAYER_COUNT <= 8 +# ifndef LAYER_STATE_8BIT +# define LAYER_STATE_8BIT +# endif +# elif DYNAMIC_KEYMAP_LAYER_COUNT <= 16 +# ifndef LAYER_STATE_16BIT +# define LAYER_STATE_16BIT +# endif +# else +# ifndef LAYER_STATE_32BIT +# define LAYER_STATE_32BIT +# endif +# endif +#endif + +#if !defined(LAYER_STATE_8BIT) && !defined(LAYER_STATE_16BIT) && !defined(LAYER_STATE_32BIT) +# define LAYER_STATE_32BIT +#endif + #if defined(LAYER_STATE_8BIT) typedef uint8_t layer_state_t; # define MAX_LAYER_BITS 3 @@ -35,13 +58,15 @@ typedef uint16_t layer_state_t; # define MAX_LAYER 16 # endif # define get_highest_layer(state) biton16(state) -#else +#elif defined(LAYER_STATE_32BIT) typedef uint32_t layer_state_t; # define MAX_LAYER_BITS 5 # ifndef MAX_LAYER # define MAX_LAYER 32 # endif # define get_highest_layer(state) biton32(state) +#else +# error Layer Mask size not specified. HOW?! #endif /* @@ -92,7 +117,7 @@ layer_state_t layer_state_set_kb(layer_state_t state); # define layer_state_set(layer) # define layer_state_is(layer) (layer == 0) -# define layer_state_cmp(state, layer) (state == 0 ? layer == 0 : (state & 1UL << layer) != 0) +# define layer_state_cmp(state, layer) (state == 0 ? layer == 0 : (state & (layer_state_t)1 << layer) != 0) # define layer_debug() # define layer_clear() diff --git a/tmk_core/common/action_tapping.c b/tmk_core/common/action_tapping.c index 56044e096d..1701ae4717 100644 --- a/tmk_core/common/action_tapping.c +++ b/tmk_core/common/action_tapping.c @@ -18,11 +18,16 @@ # define IS_TAPPING_PRESSED() (IS_TAPPING() && tapping_key.event.pressed) # define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed) # define IS_TAPPING_KEY(k) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (k))) +#ifndef COMBO_ENABLE +# define IS_TAPPING_RECORD(r) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (r->event.key))) +#else +# define IS_TAPPING_RECORD(r) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (r->event.key)) && tapping_key.keycode == r->keycode) +#endif __attribute__((weak)) uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { return TAPPING_TERM; } # ifdef TAPPING_TERM_PER_KEY -# define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < get_tapping_term(get_event_keycode(tapping_key.event, false), &tapping_key)) +# define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < get_tapping_term(get_record_keycode(&tapping_key, false), &tapping_key)) # else # define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < TAPPING_TERM) # endif @@ -103,7 +108,7 @@ bool process_tapping(keyrecord_t *keyp) { if (IS_TAPPING_PRESSED()) { if (WITHIN_TAPPING_TERM(event)) { if (tapping_key.tap.count == 0) { - if (IS_TAPPING_KEY(event.key) && !event.pressed) { + if (IS_TAPPING_RECORD(keyp) && !event.pressed) { // first tap! debug("Tapping: First tap(0->1).\n"); tapping_key.tap.count = 1; @@ -122,14 +127,14 @@ bool process_tapping(keyrecord_t *keyp) { # if defined(TAPPING_TERM_PER_KEY) || (TAPPING_TERM >= 500) || defined(PERMISSIVE_HOLD) || defined(PERMISSIVE_HOLD_PER_KEY) else if ((( # ifdef TAPPING_TERM_PER_KEY - get_tapping_term(get_event_keycode(tapping_key.event, false), keyp) + get_tapping_term(get_record_keycode(&tapping_key, false), keyp) # else TAPPING_TERM # endif >= 500) # ifdef PERMISSIVE_HOLD_PER_KEY - || get_permissive_hold(get_event_keycode(tapping_key.event, false), keyp) + || get_permissive_hold(get_record_keycode(&tapping_key, false), keyp) # elif defined(PERMISSIVE_HOLD) || true # endif @@ -177,7 +182,7 @@ bool process_tapping(keyrecord_t *keyp) { } // tap_count > 0 else { - if (IS_TAPPING_KEY(event.key) && !event.pressed) { + if (IS_TAPPING_RECORD(keyp) && !event.pressed) { debug("Tapping: Tap release("); debug_dec(tapping_key.tap.count); debug(")\n"); @@ -186,11 +191,15 @@ bool process_tapping(keyrecord_t *keyp) { tapping_key = *keyp; debug_tapping_key(); return true; - } else if (is_tap_key(event.key) && event.pressed) { + } else if (is_tap_record(keyp) && event.pressed) { if (tapping_key.tap.count > 1) { debug("Tapping: Start new tap with releasing last tap(>1).\n"); // unregister key - process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false}); + process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false, +#ifdef COMBO_ENABLE + .keycode = tapping_key.keycode, +#endif + }); } else { debug("Tapping: Start while last tap(1).\n"); } @@ -218,17 +227,21 @@ bool process_tapping(keyrecord_t *keyp) { debug_tapping_key(); return false; } else { - if (IS_TAPPING_KEY(event.key) && !event.pressed) { + if (IS_TAPPING_RECORD(keyp) && !event.pressed) { debug("Tapping: End. last timeout tap release(>0)."); keyp->tap = tapping_key.tap; process_record(keyp); tapping_key = (keyrecord_t){}; return true; - } else if (is_tap_key(event.key) && event.pressed) { + } else if (is_tap_record(keyp) && event.pressed) { if (tapping_key.tap.count > 1) { debug("Tapping: Start new tap with releasing last timeout tap(>1).\n"); // unregister key - process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false}); + process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false, +#ifdef COMBO_ENABLE + .keycode = tapping_key.keycode, +#endif + }); } else { debug("Tapping: Start while last timeout tap(1).\n"); } @@ -248,12 +261,12 @@ bool process_tapping(keyrecord_t *keyp) { } else if (IS_TAPPING_RELEASED()) { if (WITHIN_TAPPING_TERM(event)) { if (event.pressed) { - if (IS_TAPPING_KEY(event.key)) { + if (IS_TAPPING_RECORD(keyp)) { //# ifndef TAPPING_FORCE_HOLD # if !defined(TAPPING_FORCE_HOLD) || defined(TAPPING_FORCE_HOLD_PER_KEY) if ( # ifdef TAPPING_FORCE_HOLD_PER_KEY - !get_tapping_force_hold(get_event_keycode(tapping_key.event, false), keyp) && + !get_tapping_force_hold(get_record_keycode(&tapping_key, false), keyp) && # endif !tapping_key.tap.interrupted && tapping_key.tap.count > 0) { // sequential tap. @@ -271,7 +284,7 @@ bool process_tapping(keyrecord_t *keyp) { // FIX: start new tap again tapping_key = *keyp; return true; - } else if (is_tap_key(event.key)) { + } else if (is_tap_record(keyp)) { // Sequential tap can be interfered with other tap key. debug("Tapping: Start with interfering other tap.\n"); tapping_key = *keyp; @@ -303,7 +316,7 @@ bool process_tapping(keyrecord_t *keyp) { } // not tapping state else { - if (event.pressed && is_tap_key(event.key)) { + if (event.pressed && is_tap_record(keyp)) { debug("Tapping: Start(Press tap key).\n"); tapping_key = *keyp; process_record_tap_hint(&tapping_key); diff --git a/tmk_core/common/action_tapping.h b/tmk_core/common/action_tapping.h index 893ccb1ce1..7de8049c7f 100644 --- a/tmk_core/common/action_tapping.h +++ b/tmk_core/common/action_tapping.h @@ -30,6 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #define WAITING_BUFFER_SIZE 8 #ifndef NO_ACTION_TAPPING +uint16_t get_record_keycode(keyrecord_t *record, bool update_layer_cache); uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache); void action_tapping_process(keyrecord_t record); diff --git a/tmk_core/common/action_util.c b/tmk_core/common/action_util.c index a57c8bf66a..2b3c00cba0 100644 --- a/tmk_core/common/action_util.c +++ b/tmk_core/common/action_util.c @@ -27,6 +27,10 @@ extern keymap_config_t keymap_config; static uint8_t real_mods = 0; static uint8_t weak_mods = 0; static uint8_t macro_mods = 0; +#ifdef KEY_OVERRIDE_ENABLE +static uint8_t weak_override_mods = 0; +static uint8_t suppressed_mods = 0; +#endif #ifdef USB_6KRO_ENABLE # define RO_ADD(a, b) ((a + b) % KEYBOARD_REPORT_KEYS) @@ -229,6 +233,7 @@ void send_keyboard_report(void) { keyboard_report->mods = real_mods; keyboard_report->mods |= weak_mods; keyboard_report->mods |= macro_mods; + #ifndef NO_ACTION_ONESHOT if (oneshot_mods) { # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) @@ -244,6 +249,13 @@ void send_keyboard_report(void) { } #endif + +#ifdef KEY_OVERRIDE_ENABLE + // These need to be last to be able to properly control key overrides + keyboard_report->mods &= ~suppressed_mods; + keyboard_report->mods |= weak_override_mods; +#endif + host_keyboard_send(keyboard_report); } @@ -299,6 +311,22 @@ void set_weak_mods(uint8_t mods) { weak_mods = mods; } */ void clear_weak_mods(void) { weak_mods = 0; } +#ifdef KEY_OVERRIDE_ENABLE +/** \brief set weak mods used by key overrides. DO not call this manually + */ +void set_weak_override_mods(uint8_t mods) { weak_override_mods = mods; } +/** \brief clear weak mods used by key overrides. DO not call this manually + */ +void clear_weak_override_mods(void) { weak_override_mods = 0; } + +/** \brief set suppressed mods used by key overrides. DO not call this manually + */ +void set_suppressed_override_mods(uint8_t mods) { suppressed_mods = mods; } +/** \brief clear suppressed mods used by key overrides. DO not call this manually + */ +void clear_suppressed_override_mods(void) { suppressed_mods = 0; } +#endif + /* macro modifier */ /** \brief get macro mods * diff --git a/tmk_core/common/arm_atsam/_timer.h b/tmk_core/common/arm_atsam/_timer.h new file mode 100644 index 0000000000..77402b612a --- /dev/null +++ b/tmk_core/common/arm_atsam/_timer.h @@ -0,0 +1,19 @@ +/* Copyright 2021 Simon Arlott + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#pragma once + +// The platform is 32-bit, so prefer 32-bit timers to avoid overflow +#define FAST_TIMER_T_SIZE 32 diff --git a/tmk_core/common/avr/_timer.h b/tmk_core/common/avr/_timer.h new file mode 100644 index 0000000000..b81e0f68b7 --- /dev/null +++ b/tmk_core/common/avr/_timer.h @@ -0,0 +1,19 @@ +/* Copyright 2021 Simon Arlott + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#pragma once + +// The platform is 8-bit, so prefer 16-bit timers to reduce code size +#define FAST_TIMER_T_SIZE 16 diff --git a/tmk_core/common/avr/gpio.h b/tmk_core/common/avr/gpio.h index 231556c29c..e9be68491d 100644 --- a/tmk_core/common/avr/gpio.h +++ b/tmk_core/common/avr/gpio.h @@ -20,6 +20,8 @@ typedef uint8_t pin_t; +/* Operation of GPIO by pin. */ + #define setPinInput(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF)) #define setPinInputHigh(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) |= _BV((pin)&0xF)) #define setPinInputLow(pin) _Static_assert(0, "AVR processors cannot implement an input as pull low") @@ -32,3 +34,16 @@ typedef uint8_t pin_t; #define readPin(pin) ((bool)(PINx_ADDRESS(pin) & _BV((pin)&0xF))) #define togglePin(pin) (PORTx_ADDRESS(pin) ^= _BV((pin)&0xF)) + +/* Operation of GPIO by port. */ + +typedef uint8_t port_data_t; + +#define readPort(port) PINx_ADDRESS(port) + +#define setPortBitInput(port, bit) (DDRx_ADDRESS(port) &= ~_BV((bit)&0xF), PORTx_ADDRESS(port) &= ~_BV((bit)&0xF)) +#define setPortBitInputHigh(port, bit) (DDRx_ADDRESS(port) &= ~_BV((bit)&0xF), PORTx_ADDRESS(port) |= _BV((bit)&0xF)) +#define setPortBitOutput(port, bit) (DDRx_ADDRESS(port) |= _BV((bit)&0xF)) + +#define writePortBitLow(port, bit) (PORTx_ADDRESS(port) &= ~_BV((bit)&0xF)) +#define writePortBitHigh(port, bit) (PORTx_ADDRESS(port) |= _BV((bit)&0xF)) diff --git a/tmk_core/common/chibios/_timer.h b/tmk_core/common/chibios/_timer.h new file mode 100644 index 0000000000..77402b612a --- /dev/null +++ b/tmk_core/common/chibios/_timer.h @@ -0,0 +1,19 @@ +/* Copyright 2021 Simon Arlott + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#pragma once + +// The platform is 32-bit, so prefer 32-bit timers to avoid overflow +#define FAST_TIMER_T_SIZE 32 diff --git a/tmk_core/common/chibios/bootloader.c b/tmk_core/common/chibios/bootloader.c index 11f7abf432..f9514ee5f3 100644 --- a/tmk_core/common/chibios/bootloader.c +++ b/tmk_core/common/chibios/bootloader.c @@ -95,7 +95,7 @@ void enter_bootloader_mode_if_requested(void) { } } -#elif defined(KL2x) || defined(K20x) || defined(MK66F18) // STM32_BOOTLOADER_DUAL_BANK // STM32_BOOTLOADER_ADDRESS +#elif defined(KL2x) || defined(K20x) || defined(MK66F18) || defined(MIMXRT1062) // STM32_BOOTLOADER_DUAL_BANK // STM32_BOOTLOADER_ADDRESS /* Kinetis */ # if defined(BOOTLOADER_KIIBOHD) @@ -103,7 +103,8 @@ void enter_bootloader_mode_if_requested(void) { # define SCB_AIRCR_VECTKEY_WRITEMAGIC 0x05FA0000 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)); + void *volatile vbat = (void *)VBAT; + __builtin_memcpy(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; } diff --git a/tmk_core/common/chibios/gpio.h b/tmk_core/common/chibios/gpio.h index 5d0e142abc..4d057f1cab 100644 --- a/tmk_core/common/chibios/gpio.h +++ b/tmk_core/common/chibios/gpio.h @@ -20,6 +20,8 @@ typedef ioline_t pin_t; +/* Operation of GPIO by pin. */ + #define setPinInput(pin) palSetLineMode(pin, PAL_MODE_INPUT) #define setPinInputHigh(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLUP) #define setPinInputLow(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN) @@ -32,3 +34,17 @@ typedef ioline_t pin_t; #define readPin(pin) palReadLine(pin) #define togglePin(pin) palToggleLine(pin) + +/* Operation of GPIO by port. */ + +typedef uint16_t port_data_t; + +#define readPort(pin) palReadPort(PAL_PORT(pin)) + +#define setPortBitInput(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_INPUT) +#define setPortBitInputHigh(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_INPUT_PULLUP) +#define setPortBitInputLow(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_INPUT_PULLDOWN) +#define setPortBitOutput(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_OUTPUT_PUSHPULL) + +#define writePortBitLow(pin, bit) palClearLine(PAL_LINE(PAL_PORT(pin), bit)) +#define writePortBitHigh(pin, bit) palSetLine(PAL_LINE(PAL_PORT(pin), bit)) diff --git a/tmk_core/common/debug.c b/tmk_core/common/debug.c deleted file mode 100644 index ea62deaa8c..0000000000 --- a/tmk_core/common/debug.c +++ /dev/null @@ -1,25 +0,0 @@ -/* -Copyright 2011 Jun Wako <wakojun@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ -#include "debug.h" - -debug_config_t debug_config = { - .enable = false, // - .matrix = false, // - .keyboard = false, // - .mouse = false, // - .reserved = 0 // -}; diff --git a/tmk_core/common/debug.h b/tmk_core/common/debug.h deleted file mode 100644 index 3d2e2315ef..0000000000 --- a/tmk_core/common/debug.h +++ /dev/null @@ -1,169 +0,0 @@ -/* -Copyright 2011 Jun Wako <wakojun@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#pragma once - -#include <stdbool.h> -#include "print.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Debug output control - */ -typedef union { - struct { - bool enable : 1; - bool matrix : 1; - bool keyboard : 1; - bool mouse : 1; - uint8_t reserved : 4; - }; - uint8_t raw; -} debug_config_t; - -extern debug_config_t debug_config; - -#ifdef __cplusplus -} -#endif - -/* for backward compatibility */ -#define debug_enable (debug_config.enable) -#define debug_matrix (debug_config.matrix) -#define debug_keyboard (debug_config.keyboard) -#define debug_mouse (debug_config.mouse) - -/* - * Debug print utils - */ -#ifndef NO_DEBUG - -# define dprint(s) \ - do { \ - if (debug_enable) print(s); \ - } while (0) -# define dprintln(s) \ - do { \ - if (debug_enable) println(s); \ - } while (0) -# define dprintf(fmt, ...) \ - do { \ - if (debug_enable) xprintf(fmt, ##__VA_ARGS__); \ - } while (0) -# define dmsg(s) dprintf("%s at %s: %S\n", __FILE__, __LINE__, PSTR(s)) - -/* Deprecated. DO NOT USE these anymore, use dprintf instead. */ -# define debug(s) \ - do { \ - if (debug_enable) print(s); \ - } while (0) -# define debugln(s) \ - do { \ - if (debug_enable) println(s); \ - } while (0) -# define debug_msg(s) \ - do { \ - if (debug_enable) { \ - print(__FILE__); \ - print(" at "); \ - print_dec(__LINE__); \ - print(" in "); \ - print(": "); \ - print(s); \ - } \ - } while (0) -# define debug_dec(data) \ - do { \ - if (debug_enable) print_dec(data); \ - } while (0) -# define debug_decs(data) \ - do { \ - if (debug_enable) print_decs(data); \ - } while (0) -# define debug_hex4(data) \ - do { \ - if (debug_enable) print_hex4(data); \ - } while (0) -# define debug_hex8(data) \ - do { \ - if (debug_enable) print_hex8(data); \ - } while (0) -# define debug_hex16(data) \ - do { \ - if (debug_enable) print_hex16(data); \ - } while (0) -# define debug_hex32(data) \ - do { \ - if (debug_enable) print_hex32(data); \ - } while (0) -# define debug_bin8(data) \ - do { \ - if (debug_enable) print_bin8(data); \ - } while (0) -# define debug_bin16(data) \ - do { \ - if (debug_enable) print_bin16(data); \ - } while (0) -# define debug_bin32(data) \ - do { \ - if (debug_enable) print_bin32(data); \ - } while (0) -# define debug_bin_reverse8(data) \ - do { \ - if (debug_enable) print_bin_reverse8(data); \ - } while (0) -# define debug_bin_reverse16(data) \ - do { \ - if (debug_enable) print_bin_reverse16(data); \ - } while (0) -# define debug_bin_reverse32(data) \ - do { \ - if (debug_enable) print_bin_reverse32(data); \ - } while (0) -# define debug_hex(data) debug_hex8(data) -# define debug_bin(data) debug_bin8(data) -# define debug_bin_reverse(data) debug_bin8(data) - -#else /* NO_DEBUG */ - -# define dprint(s) -# define dprintln(s) -# define dprintf(fmt, ...) -# define dmsg(s) -# define debug(s) -# define debugln(s) -# define debug_msg(s) -# define debug_dec(data) -# define debug_decs(data) -# define debug_hex4(data) -# define debug_hex8(data) -# define debug_hex16(data) -# define debug_hex32(data) -# define debug_bin8(data) -# define debug_bin16(data) -# define debug_bin32(data) -# define debug_bin_reverse8(data) -# define debug_bin_reverse16(data) -# define debug_bin_reverse32(data) -# define debug_hex(data) -# define debug_bin(data) -# define debug_bin_reverse(data) - -#endif /* NO_DEBUG */ diff --git a/tmk_core/common/host.c b/tmk_core/common/host.c index e7d92cfac6..a8b391e893 100644 --- a/tmk_core/common/host.c +++ b/tmk_core/common/host.c @@ -17,6 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include <stdint.h> //#include <avr/interrupt.h> +#include "keyboard.h" #include "keycode.h" #include "host.h" #include "util.h" @@ -35,15 +36,20 @@ void host_set_driver(host_driver_t *d) { driver = d; } host_driver_t *host_get_driver(void) { return driver; } +#ifdef SPLIT_KEYBOARD +uint8_t split_led_state = 0; +void set_split_host_keyboard_leds(uint8_t led_state) { split_led_state = led_state; } +#endif + uint8_t host_keyboard_leds(void) { +#ifdef SPLIT_KEYBOARD + if (!is_keyboard_master()) return split_led_state; +#endif if (!driver) return 0; return (*driver->keyboard_leds)(); } -led_t host_keyboard_led_state(void) { - if (!driver) return (led_t){0}; - return (led_t)((*driver->keyboard_leds)()); -} +led_t host_keyboard_led_state(void) { return (led_t)host_keyboard_leds(); } /* send report */ void host_keyboard_send(report_keyboard_t *report) { diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c index 3d6092e71c..28fa97bc8f 100644 --- a/tmk_core/common/keyboard.c +++ b/tmk_core/common/keyboard.c @@ -85,6 +85,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #ifdef OLED_DRIVER_ENABLE # include "oled_driver.h" #endif +#ifdef ST7565_ENABLE +# include "st7565.h" +#endif #ifdef VELOCIKEY_ENABLE # include "velocikey.h" #endif @@ -100,6 +103,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #ifdef EEPROM_DRIVER # include "eeprom_driver.h" #endif +#if defined(CRC_ENABLE) +# include "crc.h" +#endif static uint32_t last_input_modification_time = 0; uint32_t last_input_activity_time(void) { return last_input_modification_time; } @@ -297,6 +303,9 @@ void keyboard_init(void) { timer_init(); sync_timer_init(); matrix_init(); +#if defined(CRC_ENABLE) + crc_init(); +#endif #ifdef VIA_ENABLE via_init(); #endif @@ -306,6 +315,9 @@ void keyboard_init(void) { #ifdef OLED_DRIVER_ENABLE oled_init(OLED_ROTATION_0); #endif +#ifdef ST7565_ENABLE + st7565_init(DISPLAY_ROTATION_0); +#endif #ifdef PS2_MOUSE_ENABLE ps2_mouse_init(); #endif @@ -470,6 +482,18 @@ MATRIX_LOOP_END: # endif #endif +#ifdef ST7565_ENABLE + st7565_task(); +# ifndef ST7565_DISABLE_TIMEOUT + // Wake up display if user is using those fabulous keys or spinning those encoders! +# ifdef ENCODER_ENABLE + if (matrix_changed || encoders_changed) st7565_on(); +# else + if (matrix_changed) st7565_on(); +# endif +# endif +#endif + #ifdef MOUSEKEY_ENABLE // mousekey repeat & acceleration mousekey_task(); diff --git a/tmk_core/common/lib_printf.mk b/tmk_core/common/lib_printf.mk deleted file mode 100644 index 10d2d8468d..0000000000 --- a/tmk_core/common/lib_printf.mk +++ /dev/null @@ -1,9 +0,0 @@ -PRINTF_PATH = $(LIB_PATH)/printf - -TMK_COMMON_SRC += $(PRINTF_PATH)/printf.c -TMK_COMMON_SRC += $(COMMON_DIR)/printf.c -TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_FLOAT -TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_EXPONENTIAL -TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_LONG_LONG -TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_PTRDIFF_T -VPATH += $(PRINTF_PATH) diff --git a/tmk_core/common/nodebug.h b/tmk_core/common/nodebug.h deleted file mode 100644 index 0b176684bd..0000000000 --- a/tmk_core/common/nodebug.h +++ /dev/null @@ -1,26 +0,0 @@ -/* -Copyright 2013 Jun Wako <wakojun@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#pragma once - -#ifndef NO_DEBUG -# define NO_DEBUG -# include "debug.h" -# undef NO_DEBUG -#else -# include "debug.h" -#endif diff --git a/tmk_core/common/print.h b/tmk_core/common/print.h deleted file mode 100644 index 8c055f549e..0000000000 --- a/tmk_core/common/print.h +++ /dev/null @@ -1,135 +0,0 @@ -/* Copyright 2012 Jun Wako <wakojun@gmail.com> */ -/* Very basic print functions, intended to be used with usb_debug_only.c - * http://www.pjrc.com/teensy/ - * Copyright (c) 2008 PJRC.COM, LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#pragma once - -#include <stdint.h> -#include <stdbool.h> -#include "util.h" -#include "sendchar.h" -#include "progmem.h" - -void print_set_sendchar(sendchar_func_t func); - -#ifndef NO_PRINT -# if __has_include_next("_print.h") -# include_next "_print.h" /* Include the platforms print.h */ -# else -// Fall back to lib/printf -# include "printf.h" // lib/printf/printf.h - -// Create user & normal print defines -# define print(s) printf(s) -# define println(s) printf(s "\r\n") -# define xprintf printf -# define uprint(s) printf(s) -# define uprintln(s) printf(s "\r\n") -# define uprintf printf - -# endif /* __has_include_next("_print.h") */ -#else /* NO_PRINT */ -# undef xprintf -// Remove print defines -# define print(s) -# define println(s) -# define xprintf(fmt, ...) -# define uprintf(fmt, ...) -# define uprint(s) -# define uprintln(s) - -#endif /* NO_PRINT */ - -#ifdef USER_PRINT -// Remove normal print defines -# undef print -# undef println -# undef xprintf -# define print(s) -# define println(s) -# define xprintf(fmt, ...) -#endif - -#define print_dec(i) xprintf("%u", i) -#define print_decs(i) xprintf("%d", i) -/* hex */ -#define print_hex4(i) xprintf("%X", i) -#define print_hex8(i) xprintf("%02X", i) -#define print_hex16(i) xprintf("%04X", i) -#define print_hex32(i) xprintf("%08lX", i) -/* binary */ -#define print_bin4(i) xprintf("%04b", i) -#define print_bin8(i) xprintf("%08b", i) -#define print_bin16(i) xprintf("%016b", i) -#define print_bin32(i) xprintf("%032lb", i) -#define print_bin_reverse8(i) xprintf("%08b", bitrev(i)) -#define print_bin_reverse16(i) xprintf("%016b", bitrev16(i)) -#define print_bin_reverse32(i) xprintf("%032lb", bitrev32(i)) -/* print value utility */ -#define print_val_dec(v) xprintf(#v ": %u\n", v) -#define print_val_decs(v) xprintf(#v ": %d\n", v) -#define print_val_hex8(v) xprintf(#v ": %X\n", v) -#define print_val_hex16(v) xprintf(#v ": %02X\n", v) -#define print_val_hex32(v) xprintf(#v ": %04lX\n", v) -#define print_val_bin8(v) xprintf(#v ": %08b\n", v) -#define print_val_bin16(v) xprintf(#v ": %016b\n", v) -#define print_val_bin32(v) xprintf(#v ": %032lb\n", v) -#define print_val_bin_reverse8(v) xprintf(#v ": %08b\n", bitrev(v)) -#define print_val_bin_reverse16(v) xprintf(#v ": %016b\n", bitrev16(v)) -#define print_val_bin_reverse32(v) xprintf(#v ": %032lb\n", bitrev32(v)) - -// User print disables the normal print messages in the body of QMK/TMK code and -// is meant as a lightweight alternative to NOPRINT. Use it when you only want to do -// a spot of debugging but lack flash resources for allowing all of the codebase to -// print (and store their wasteful strings). -// -// !!! DO NOT USE USER PRINT CALLS IN THE BODY OF QMK/TMK !!! - -/* decimal */ -#define uprint_dec(i) uprintf("%u", i) -#define uprint_decs(i) uprintf("%d", i) -/* hex */ -#define uprint_hex4(i) uprintf("%X", i) -#define uprint_hex8(i) uprintf("%02X", i) -#define uprint_hex16(i) uprintf("%04X", i) -#define uprint_hex32(i) uprintf("%08lX", i) -/* binary */ -#define uprint_bin4(i) uprintf("%04b", i) -#define uprint_bin8(i) uprintf("%08b", i) -#define uprint_bin16(i) uprintf("%016b", i) -#define uprint_bin32(i) uprintf("%032lb", i) -#define uprint_bin_reverse8(i) uprintf("%08b", bitrev(i)) -#define uprint_bin_reverse16(i) uprintf("%016b", bitrev16(i)) -#define uprint_bin_reverse32(i) uprintf("%032lb", bitrev32(i)) -/* print value utility */ -#define uprint_val_dec(v) uprintf(#v ": %u\n", v) -#define uprint_val_decs(v) uprintf(#v ": %d\n", v) -#define uprint_val_hex8(v) uprintf(#v ": %X\n", v) -#define uprint_val_hex16(v) uprintf(#v ": %02X\n", v) -#define uprint_val_hex32(v) uprintf(#v ": %04lX\n", v) -#define uprint_val_bin8(v) uprintf(#v ": %08b\n", v) -#define uprint_val_bin16(v) uprintf(#v ": %016b\n", v) -#define uprint_val_bin32(v) uprintf(#v ": %032lb\n", v) -#define uprint_val_bin_reverse8(v) uprintf(#v ": %08b\n", bitrev(v)) -#define uprint_val_bin_reverse16(v) uprintf(#v ": %016b\n", bitrev16(v)) -#define uprint_val_bin_reverse32(v) uprintf(#v ": %032lb\n", bitrev32(v)) diff --git a/tmk_core/common/printf.c b/tmk_core/common/printf.c deleted file mode 100644 index e8440e55ee..0000000000 --- a/tmk_core/common/printf.c +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 2011 Jun Wako <wakojun@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ -#include <stddef.h> -#include "sendchar.h" - -// bind lib/printf to console interface - sendchar - -static int8_t null_sendchar_func(uint8_t c) { return 0; } -static sendchar_func_t func = null_sendchar_func; - -void print_set_sendchar(sendchar_func_t send) { func = send; } - -void _putchar(char character) { func(character); } diff --git a/tmk_core/common/progmem.h b/tmk_core/common/progmem.h index 4e4771e523..a70d8e299f 100644 --- a/tmk_core/common/progmem.h +++ b/tmk_core/common/progmem.h @@ -3,7 +3,9 @@ #if defined(__AVR__) # include <avr/pgmspace.h> #else +# include <string.h> # define PROGMEM +# define __flash # define PSTR(x) x # define PGM_P const char* # define memcpy_P(dest, src, n) memcpy(dest, src, n) diff --git a/tmk_core/common/sendchar.h b/tmk_core/common/sendchar.h deleted file mode 100644 index edcddaa6bb..0000000000 --- a/tmk_core/common/sendchar.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -Copyright 2011 Jun Wako <wakojun@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#pragma once - -#include <stdint.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef int8_t (*sendchar_func_t)(uint8_t c); - -/* transmit a character. return 0 on success, -1 on error. */ -int8_t sendchar(uint8_t c); - -#ifdef __cplusplus -} -#endif diff --git a/tmk_core/common/sendchar_null.c b/tmk_core/common/sendchar_null.c deleted file mode 100644 index fb67f70866..0000000000 --- a/tmk_core/common/sendchar_null.c +++ /dev/null @@ -1,19 +0,0 @@ -/* -Copyright 2011 Jun Wako <wakojun@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ -#include "sendchar.h" - -__attribute__((weak)) int8_t sendchar(uint8_t c) { return 0; } diff --git a/tmk_core/common/sendchar_uart.c b/tmk_core/common/sendchar_uart.c deleted file mode 100644 index 2fc48bafff..0000000000 --- a/tmk_core/common/sendchar_uart.c +++ /dev/null @@ -1,23 +0,0 @@ -/* -Copyright 2011 Jun Wako <wakojun@gmail.com> - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ -#include "uart.h" -#include "sendchar.h" - -int8_t sendchar(uint8_t c) { - uart_putchar(c); - return 0; -} diff --git a/tmk_core/common/sync_timer.c b/tmk_core/common/sync_timer.c index de24b463b6..68b92d8b43 100644 --- a/tmk_core/common/sync_timer.c +++ b/tmk_core/common/sync_timer.c @@ -26,7 +26,7 @@ SOFTWARE. #include "sync_timer.h" #include "keyboard.h" -#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER) +#if (defined(SPLIT_KEYBOARD) || defined(SERIAL_LINK_ENABLE)) && !defined(DISABLE_SYNC_TIMER) volatile int32_t sync_timer_ms; void sync_timer_init(void) { sync_timer_ms = 0; } diff --git a/tmk_core/common/sync_timer.h b/tmk_core/common/sync_timer.h index 9ddef45bb2..744e2b50d5 100644 --- a/tmk_core/common/sync_timer.h +++ b/tmk_core/common/sync_timer.h @@ -32,7 +32,7 @@ SOFTWARE. extern "C" { #endif -#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER) +#if (defined(SPLIT_KEYBOARD) || defined(SERIAL_LINK_ENABLE)) && !defined(DISABLE_SYNC_TIMER) void sync_timer_init(void); void sync_timer_update(uint32_t time); uint16_t sync_timer_read(void); diff --git a/tmk_core/common/timer.h b/tmk_core/common/timer.h index abddcea857..02e39e79e7 100644 --- a/tmk_core/common/timer.h +++ b/tmk_core/common/timer.h @@ -1,5 +1,6 @@ /* Copyright 2011 Jun Wako <wakojun@gmail.com> +Copyright 2021 Simon Arlott This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,6 +18,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #pragma once +#if __has_include_next("_timer.h") +# include_next "_timer.h" /* Include the platform's _timer.h */ +#endif + #include <stdint.h> #define TIMER_DIFF(a, b, max) ((max == UINT8_MAX) ? ((uint8_t)((a) - (b))) : ((max == UINT16_MAX) ? ((uint16_t)((a) - (b))) : ((max == UINT32_MAX) ? ((uint32_t)((a) - (b))) : ((a) >= (b) ? (a) - (b) : (max) + 1 - (b) + (a))))) @@ -42,6 +47,21 @@ uint32_t timer_elapsed32(uint32_t last); #define timer_expired(current, future) ((uint16_t)(current - future) < UINT16_MAX / 2) #define timer_expired32(current, future) ((uint32_t)(current - future) < UINT32_MAX / 2) +// Use an appropriate timer integer size based on architecture (16-bit will overflow sooner) +#if FAST_TIMER_T_SIZE < 32 +# define TIMER_DIFF_FAST(a, b) TIMER_DIFF_16(a, b) +# define timer_expired_fast(current, future) timer_expired(current, future) +typedef uint16_t fast_timer_t; +fast_timer_t inline timer_read_fast(void) { return timer_read(); } +fast_timer_t inline timer_elapsed_fast(fast_timer_t last) { return timer_elapsed(last); } +#else +# define TIMER_DIFF_FAST(a, b) TIMER_DIFF_32(a, b) +# define timer_expired_fast(current, future) timer_expired32(current, future) +typedef uint32_t fast_timer_t; +fast_timer_t inline timer_read_fast(void) { return timer_read32(); } +fast_timer_t inline timer_elapsed_fast(fast_timer_t last) { return timer_elapsed32(last); } +#endif + #ifdef __cplusplus } #endif diff --git a/tmk_core/common/usb_util.c b/tmk_core/common/usb_util.c index d4134a0446..dd1deeaa11 100644 --- a/tmk_core/common/usb_util.c +++ b/tmk_core/common/usb_util.c @@ -16,7 +16,7 @@ #include "quantum.h" #include "usb_util.h" -__attribute__((weak)) void usb_disable(void) {} +__attribute__((weak)) void usb_disconnect(void) {} __attribute__((weak)) bool usb_connected_state(void) { return true; } __attribute__((weak)) bool usb_vbus_state(void) { #ifdef USB_VBUS_PIN diff --git a/tmk_core/common/usb_util.h b/tmk_core/common/usb_util.h index 4ebedb1e71..13db9fbfbd 100644 --- a/tmk_core/common/usb_util.h +++ b/tmk_core/common/usb_util.h @@ -17,6 +17,6 @@ #include <stdbool.h> -void usb_disable(void); +void usb_disconnect(void); bool usb_connected_state(void); bool usb_vbus_state(void); diff --git a/tmk_core/protocol.mk b/tmk_core/protocol.mk index cc87e83478..b61f2f5463 100644 --- a/tmk_core/protocol.mk +++ b/tmk_core/protocol.mk @@ -14,13 +14,13 @@ endif ifeq ($(strip $(PS2_USE_INT)), yes) SRC += protocol/ps2_interrupt.c - SRC += protocol/ps2_io_avr.c + SRC += protocol/ps2_io_$(PLATFORM_KEY).c OPT_DEFS += -DPS2_USE_INT endif ifeq ($(strip $(PS2_USE_USART)), yes) SRC += protocol/ps2_usart.c - SRC += protocol/ps2_io_avr.c + SRC += protocol/ps2_io_$(PLATFORM_KEY).c OPT_DEFS += -DPS2_USE_USART endif diff --git a/tmk_core/protocol/arm_atsam/usb/udi_device_conf.h b/tmk_core/protocol/arm_atsam/usb/udi_device_conf.h index 9c9d94789d..1c0983115c 100644 --- a/tmk_core/protocol/arm_atsam/usb/udi_device_conf.h +++ b/tmk_core/protocol/arm_atsam/usb/udi_device_conf.h @@ -23,6 +23,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include "compiler.h" #include "usb_protocol_hid.h" +#ifndef USB_POLLING_INTERVAL_MS +# define USB_POLLING_INTERVAL_MS 10 +#endif + #ifdef VIRTSER_ENABLE // because CDC uses IAD (interface association descriptor // per USB Interface Association Descriptor Device Class Code and Use Model 7/23/2003 Rev 1.0) @@ -118,7 +122,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #define UDI_HID_KBD_EP_IN KEYBOARD_IN_EPNUM #define NEXT_IN_EPNUM_1 (KEYBOARD_IN_EPNUM + 1) #define UDI_HID_KBD_EP_SIZE KEYBOARD_EPSIZE -#define KBD_POLLING_INTERVAL 10 +#define KBD_POLLING_INTERVAL USB_POLLING_INTERVAL_MS #ifndef UDI_HID_KBD_STRING_ID # define UDI_HID_KBD_STRING_ID 0 #endif @@ -128,7 +132,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. # define NEXT_IN_EPNUM_2 (MOUSE_IN_EPNUM + 1) # define UDI_HID_MOU_EP_IN MOUSE_IN_EPNUM # define UDI_HID_MOU_EP_SIZE MOUSE_EPSIZE -# define MOU_POLLING_INTERVAL 10 +# define MOU_POLLING_INTERVAL USB_POLLING_INTERVAL_MS # ifndef UDI_HID_MOU_STRING_ID # define UDI_HID_MOU_STRING_ID 0 # endif @@ -141,7 +145,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. # define UDI_HID_EXK_EP_IN EXTRAKEY_IN_EPNUM # define NEXT_IN_EPNUM_3 (EXTRAKEY_IN_EPNUM + 1) # define UDI_HID_EXK_EP_SIZE EXTRAKEY_EPSIZE -# define EXTRAKEY_POLLING_INTERVAL 10 +# define EXTRAKEY_POLLING_INTERVAL USB_POLLING_INTERVAL_MS # ifndef UDI_HID_EXK_STRING_ID # define UDI_HID_EXK_STRING_ID 0 # endif diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c index d04302acae..e5edd74dcb 100644 --- a/tmk_core/protocol/chibios/usb_main.c +++ b/tmk_core/protocol/chibios/usb_main.c @@ -415,14 +415,18 @@ static inline void usb_event_wakeup_handler(void) { #endif /* SLEEP_LED_ENABLE */ } +bool last_suspend_state = false; + void usb_event_queue_task(void) { usbevent_t event; while (usb_event_queue_dequeue(&event)) { switch (event) { case USB_EVENT_SUSPEND: + last_suspend_state = true; usb_event_suspend_handler(); break; case USB_EVENT_WAKEUP: + last_suspend_state = false; usb_event_wakeup_handler(); break; default: @@ -464,6 +468,9 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) { qmkusbConfigureHookI(&drivers.array[i].driver); } osalSysUnlockFromISR(); + if (last_suspend_state) { + usb_event_queue_enqueue(USB_EVENT_WAKEUP); + } return; case USB_EVENT_SUSPEND: usb_event_queue_enqueue(USB_EVENT_SUSPEND); @@ -518,7 +525,7 @@ static uint16_t get_hword(uint8_t *p) { * Other Device Required Optional Optional Optional Optional Optional */ -static uint8_t set_report_buf[2] __attribute__((aligned(2))); +static uint8_t set_report_buf[2] __attribute__((aligned(4))); static void set_led_transfer_cb(USBDriver *usbp) { if (usbp->setup[6] == 2) { /* LSB(wLength) */ uint8_t report_id = set_report_buf[0]; @@ -705,7 +712,7 @@ void init_usb_driver(USBDriver *usbp) { chVTObjectInit(&keyboard_idle_timer); } -void restart_usb_driver(USBDriver *usbp) { +__attribute__((weak)) void restart_usb_driver(USBDriver *usbp) { usbStop(usbp); usbDisconnectBus(usbp); @@ -903,7 +910,8 @@ static void send_extra(uint8_t report_id, uint16_t data) { return; } - report_extra_t report = {.report_id = report_id, .usage = data}; + static report_extra_t report; + report = (report_extra_t){.report_id = report_id, .usage = data}; usbStartTransmitI(&USB_DRIVER, SHARED_IN_EPNUM, (uint8_t *)&report, sizeof(report_extra_t)); osalSysUnlock(); @@ -1051,45 +1059,44 @@ void virtser_task(void) { #ifdef JOYSTICK_ENABLE void send_joystick_packet(joystick_t *joystick) { - joystick_report_t rep = { + static joystick_report_t rep; + rep = (joystick_report_t) { # if JOYSTICK_AXES_COUNT > 0 .axes = - { - joystick->axes[0], + { joystick->axes[0], # if JOYSTICK_AXES_COUNT >= 2 - joystick->axes[1], + joystick->axes[1], # endif # if JOYSTICK_AXES_COUNT >= 3 - joystick->axes[2], + joystick->axes[2], # endif # if JOYSTICK_AXES_COUNT >= 4 - joystick->axes[3], + joystick->axes[3], # endif # if JOYSTICK_AXES_COUNT >= 5 - joystick->axes[4], + joystick->axes[4], # endif # if JOYSTICK_AXES_COUNT >= 6 - joystick->axes[5], + joystick->axes[5], # endif - }, + }, # endif // JOYSTICK_AXES_COUNT>0 # if JOYSTICK_BUTTON_COUNT > 0 - .buttons = - { - joystick->buttons[0], + .buttons = { + joystick->buttons[0], # if JOYSTICK_BUTTON_COUNT > 8 - joystick->buttons[1], + joystick->buttons[1], # endif # if JOYSTICK_BUTTON_COUNT > 16 - joystick->buttons[2], + joystick->buttons[2], # endif # if JOYSTICK_BUTTON_COUNT > 24 - joystick->buttons[3], + joystick->buttons[3], # endif - } + } # endif // JOYSTICK_BUTTON_COUNT>0 }; diff --git a/tmk_core/protocol/chibios/usb_util.c b/tmk_core/protocol/chibios/usb_util.c index 5945e8a8de..e32d6ebfa4 100644 --- a/tmk_core/protocol/chibios/usb_util.c +++ b/tmk_core/protocol/chibios/usb_util.c @@ -16,6 +16,6 @@ #include <hal.h> #include "usb_util.h" -void usb_disable(void) { usbStop(&USBD1); } +void usb_disconnect(void) { usbStop(&USBD1); } bool usb_connected_state(void) { return usbGetDriverStateI(&USBD1) == USB_ACTIVE; } diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index 63619fdb3b..4ac079e168 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -314,45 +314,44 @@ static void Console_Task(void) { void send_joystick_packet(joystick_t *joystick) { uint8_t timeout = 255; - joystick_report_t r = { + static joystick_report_t; + r = (joystick_report_t) { # if JOYSTICK_AXES_COUNT > 0 .axes = - { - joystick->axes[0], + { joystick->axes[0], # if JOYSTICK_AXES_COUNT >= 2 - joystick->axes[1], + joystick->axes[1], # endif # if JOYSTICK_AXES_COUNT >= 3 - joystick->axes[2], + joystick->axes[2], # endif # if JOYSTICK_AXES_COUNT >= 4 - joystick->axes[3], + joystick->axes[3], # endif # if JOYSTICK_AXES_COUNT >= 5 - joystick->axes[4], + joystick->axes[4], # endif # if JOYSTICK_AXES_COUNT >= 6 - joystick->axes[5], + joystick->axes[5], # endif - }, + }, # endif // JOYSTICK_AXES_COUNT>0 # if JOYSTICK_BUTTON_COUNT > 0 - .buttons = - { - joystick->buttons[0], + .buttons = { + joystick->buttons[0], # if JOYSTICK_BUTTON_COUNT > 8 - joystick->buttons[1], + joystick->buttons[1], # endif # if JOYSTICK_BUTTON_COUNT > 16 - joystick->buttons[2], + joystick->buttons[2], # endif # if JOYSTICK_BUTTON_COUNT > 24 - joystick->buttons[3], + joystick->buttons[3], # endif - } + } # endif // JOYSTICK_BUTTON_COUNT>0 }; @@ -768,7 +767,8 @@ static void send_extra(uint8_t report_id, uint16_t data) { if (USB_DeviceState != DEVICE_STATE_Configured) return; - report_extra_t r = {.report_id = report_id, .usage = data}; + static report_extra_t r; + r = (report_extra_t){.report_id = report_id, .usage = data}; Endpoint_SelectEndpoint(SHARED_IN_EPNUM); /* Check if write ready for a polling interval around 10ms */ diff --git a/tmk_core/protocol/lufa/usb_util.c b/tmk_core/protocol/lufa/usb_util.c index 9e943a21b9..9691eff1e4 100644 --- a/tmk_core/protocol/lufa/usb_util.c +++ b/tmk_core/protocol/lufa/usb_util.c @@ -17,7 +17,7 @@ #include "usb_util.h" #include "wait.h" -void usb_disable(void) { +void usb_disconnect(void) { USB_Disable(); USB_DeviceState = DEVICE_STATE_Unattached; } diff --git a/tmk_core/protocol/ps2_interrupt.c b/tmk_core/protocol/ps2_interrupt.c index 5afc8a82e4..780040d152 100644 --- a/tmk_core/protocol/ps2_interrupt.c +++ b/tmk_core/protocol/ps2_interrupt.c @@ -40,11 +40,19 @@ POSSIBILITY OF SUCH DAMAGE. */ #include <stdbool.h> -#include <avr/interrupt.h> -#include <util/delay.h> + +#if defined(__AVR__) +# include <avr/interrupt.h> +#elif defined(PROTOCOL_CHIBIOS) // TODO: or STM32 ? +// chibiOS headers +# include "ch.h" +# include "hal.h" +#endif + #include "ps2.h" #include "ps2_io.h" #include "print.h" +#include "wait.h" #define WAIT(stat, us, err) \ do { \ @@ -61,12 +69,30 @@ static inline void pbuf_enqueue(uint8_t data); static inline bool pbuf_has_data(void); static inline void pbuf_clear(void); +#if defined(PROTOCOL_CHIBIOS) +void ps2_interrupt_service_routine(void); +void palCallback(void *arg) { ps2_interrupt_service_routine(); } + +# define PS2_INT_INIT() \ + { palSetLineMode(PS2_CLOCK, PAL_MODE_INPUT); } \ + while (0) +# define PS2_INT_ON() \ + { \ + palEnableLineEvent(PS2_CLOCK, PAL_EVENT_MODE_FALLING_EDGE); \ + palSetLineCallback(PS2_CLOCK, palCallback, NULL); \ + } \ + while (0) +# define PS2_INT_OFF() \ + { palDisableLineEvent(PS2_CLOCK); } \ + while (0) +#endif // PROTOCOL_CHIBIOS + void ps2_host_init(void) { idle(); PS2_INT_INIT(); PS2_INT_ON(); // POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20) - //_delay_ms(2500); + // wait_ms(2500); } uint8_t ps2_host_send(uint8_t data) { @@ -77,7 +103,7 @@ uint8_t ps2_host_send(uint8_t data) { /* terminate a transmission if we have */ inhibit(); - _delay_us(100); // 100us [4]p.13, [5]p.50 + wait_us(100); // 100us [4]p.13, [5]p.50 /* 'Request to Send' and Start bit */ data_lo(); @@ -86,7 +112,6 @@ uint8_t ps2_host_send(uint8_t data) { /* Data bit[2-9] */ for (uint8_t i = 0; i < 8; i++) { - _delay_us(15); if (data & (1 << i)) { parity = !parity; data_hi(); @@ -98,7 +123,7 @@ uint8_t ps2_host_send(uint8_t data) { } /* Parity bit */ - _delay_us(15); + wait_us(15); if (parity) { data_hi(); } else { @@ -108,7 +133,7 @@ uint8_t ps2_host_send(uint8_t data) { WAIT(clock_lo, 50, 5); /* Stop bit */ - _delay_us(15); + wait_us(15); data_hi(); /* Ack */ @@ -132,7 +157,7 @@ uint8_t ps2_host_recv_response(void) { // Command may take 25ms/20ms at most([5]p.46, [3]p.21) uint8_t retry = 25; while (retry-- && !pbuf_has_data()) { - _delay_ms(1); + wait_ms(1); } return pbuf_dequeue(); } @@ -148,7 +173,7 @@ uint8_t ps2_host_recv(void) { } } -ISR(PS2_INT_VECT) { +void ps2_interrupt_service_routine(void) { static enum { INIT, START, @@ -218,6 +243,10 @@ RETURN: return; } +#if defined(__AVR__) +ISR(PS2_INT_VECT) { ps2_interrupt_service_routine(); } +#endif + /* send LED state to keyboard */ void ps2_host_set_led(uint8_t led) { ps2_host_send(0xED); @@ -232,8 +261,13 @@ static uint8_t pbuf[PBUF_SIZE]; static uint8_t pbuf_head = 0; static uint8_t pbuf_tail = 0; static inline void pbuf_enqueue(uint8_t data) { +#if defined(__AVR__) uint8_t sreg = SREG; cli(); +#elif defined(PROTOCOL_CHIBIOS) + chSysLockFromISR(); +#endif + uint8_t next = (pbuf_head + 1) % PBUF_SIZE; if (next != pbuf_tail) { pbuf[pbuf_head] = data; @@ -241,31 +275,66 @@ static inline void pbuf_enqueue(uint8_t data) { } else { print("pbuf: full\n"); } + +#if defined(__AVR__) SREG = sreg; +#elif defined(PROTOCOL_CHIBIOS) + chSysUnlockFromISR(); +#endif } static inline uint8_t pbuf_dequeue(void) { uint8_t val = 0; +#if defined(__AVR__) uint8_t sreg = SREG; cli(); +#elif defined(PROTOCOL_CHIBIOS) + chSysLock(); +#endif + if (pbuf_head != pbuf_tail) { val = pbuf[pbuf_tail]; pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE; } + +#if defined(__AVR__) SREG = sreg; +#elif defined(PROTOCOL_CHIBIOS) + chSysUnlock(); +#endif return val; } static inline bool pbuf_has_data(void) { +#if defined(__AVR__) uint8_t sreg = SREG; cli(); +#elif defined(PROTOCOL_CHIBIOS) + chSysLock(); +#endif + bool has_data = (pbuf_head != pbuf_tail); - SREG = sreg; + +#if defined(__AVR__) + SREG = sreg; +#elif defined(PROTOCOL_CHIBIOS) + chSysUnlock(); +#endif return has_data; } static inline void pbuf_clear(void) { +#if defined(__AVR__) uint8_t sreg = SREG; cli(); +#elif defined(PROTOCOL_CHIBIOS) + chSysLock(); +#endif + pbuf_head = pbuf_tail = 0; - SREG = sreg; + +#if defined(__AVR__) + SREG = sreg; +#elif defined(PROTOCOL_CHIBIOS) + chSysUnlock(); +#endif } diff --git a/tmk_core/protocol/ps2_io_chibios.c b/tmk_core/protocol/ps2_io_chibios.c new file mode 100644 index 0000000000..b672bd1f47 --- /dev/null +++ b/tmk_core/protocol/ps2_io_chibios.c @@ -0,0 +1,55 @@ +#include <stdbool.h> +#include "ps2_io.h" + +// chibiOS headers +#include "ch.h" +#include "hal.h" + +/* Check port settings for clock and data line */ +#if !(defined(PS2_CLOCK)) +# error "PS/2 clock setting is required in config.h" +#endif + +#if !(defined(PS2_DATA)) +# error "PS/2 data setting is required in config.h" +#endif + +/* + * Clock + */ +void clock_init(void) {} + +void clock_lo(void) { + palSetLineMode(PS2_CLOCK, PAL_MODE_OUTPUT_OPENDRAIN); + palWriteLine(PS2_CLOCK, PAL_LOW); +} + +void clock_hi(void) { + palSetLineMode(PS2_CLOCK, PAL_MODE_OUTPUT_OPENDRAIN); + palWriteLine(PS2_CLOCK, PAL_HIGH); +} + +bool clock_in(void) { + palSetLineMode(PS2_CLOCK, PAL_MODE_INPUT); + return palReadLine(PS2_CLOCK); +} + +/* + * Data + */ +void data_init(void) {} + +void data_lo(void) { + palSetLineMode(PS2_DATA, PAL_MODE_OUTPUT_OPENDRAIN); + palWriteLine(PS2_DATA, PAL_LOW); +} + +void data_hi(void) { + palSetLineMode(PS2_DATA, PAL_MODE_OUTPUT_OPENDRAIN); + palWriteLine(PS2_DATA, PAL_HIGH); +} + +bool data_in(void) { + palSetLineMode(PS2_DATA, PAL_MODE_INPUT); + return palReadLine(PS2_DATA); +} diff --git a/tmk_core/protocol/ps2_mouse.c b/tmk_core/protocol/ps2_mouse.c index 5415453a05..39251a6434 100644 --- a/tmk_core/protocol/ps2_mouse.c +++ b/tmk_core/protocol/ps2_mouse.c @@ -16,9 +16,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <stdbool.h> -#include <avr/io.h> -#include <util/delay.h> + +#if defined(__AVR__) +# include <avr/io.h> +#endif + #include "ps2_mouse.h" +#include "wait.h" #include "host.h" #include "timer.h" #include "print.h" @@ -42,7 +46,7 @@ static inline void ps2_mouse_scroll_button_task(report_mouse_t *mouse_report); void ps2_mouse_init(void) { ps2_host_init(); - _delay_ms(PS2_MOUSE_INIT_DELAY); // wait for powering up + wait_ms(PS2_MOUSE_INIT_DELAY); // wait for powering up PS2_MOUSE_SEND(PS2_MOUSE_RESET, "ps2_mouse_init: sending reset"); @@ -152,8 +156,15 @@ static inline void ps2_mouse_convert_report_to_hid(report_mouse_t *mouse_report) mouse_report->x = X_IS_NEG ? ((!X_IS_OVF && -127 <= mouse_report->x && mouse_report->x <= -1) ? mouse_report->x : -127) : ((!X_IS_OVF && 0 <= mouse_report->x && mouse_report->x <= 127) ? mouse_report->x : 127); mouse_report->y = Y_IS_NEG ? ((!Y_IS_OVF && -127 <= mouse_report->y && mouse_report->y <= -1) ? mouse_report->y : -127) : ((!Y_IS_OVF && 0 <= mouse_report->y && mouse_report->y <= 127) ? mouse_report->y : 127); +#ifdef PS2_MOUSE_INVERT_BUTTONS + // swap left & right buttons + uint8_t needs_left = mouse_report->buttons & PS2_MOUSE_BTN_RIGHT; + uint8_t needs_right = mouse_report->buttons & PS2_MOUSE_BTN_LEFT; + mouse_report->buttons = (mouse_report->buttons & ~(PS2_MOUSE_BTN_MASK)) | (needs_left ? PS2_MOUSE_BTN_LEFT : 0) | (needs_right ? PS2_MOUSE_BTN_RIGHT : 0); +#else // remove sign and overflow flags mouse_report->buttons &= PS2_MOUSE_BTN_MASK; +#endif #ifdef PS2_MOUSE_INVERT_X mouse_report->x = -mouse_report->x; @@ -210,7 +221,7 @@ static inline void ps2_mouse_enable_scrolling(void) { PS2_MOUSE_SEND(PS2_MOUSE_SET_SAMPLE_RATE, "Set sample rate"); PS2_MOUSE_SEND(80, "80"); PS2_MOUSE_SEND(PS2_MOUSE_GET_DEVICE_ID, "Finished enabling scroll wheel"); - _delay_ms(20); + wait_ms(20); } #define PRESS_SCROLL_BUTTONS mouse_report->buttons |= (PS2_MOUSE_SCROLL_BTN_MASK) @@ -252,7 +263,7 @@ static inline void ps2_mouse_scroll_button_task(report_mouse_t *mouse_report) { if (scroll_state == SCROLL_BTN && timer_elapsed(scroll_button_time) < PS2_MOUSE_SCROLL_BTN_SEND) { PRESS_SCROLL_BUTTONS; host_mouse_send(mouse_report); - _delay_ms(100); + wait_ms(100); RELEASE_SCROLL_BUTTONS; } #endif diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c index ba7760f283..7a4a790315 100644 --- a/tmk_core/protocol/usb_descriptor.c +++ b/tmk_core/protocol/usb_descriptor.c @@ -351,7 +351,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = { .Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device }, - .USBSpecification = VERSION_BCD(1, 1, 0), + .USBSpecification = VERSION_BCD(2, 0, 0), #if VIRTSER_ENABLE .Class = USB_CSCP_IADDeviceClass, @@ -953,10 +953,10 @@ const USB_Descriptor_String_t PROGMEM ProductString = { #if defined(SERIAL_NUMBER) const USB_Descriptor_String_t PROGMEM SerialNumberString = { .Header = { - .Size = USB_STRING_LEN(sizeof(STR(SERIAL_NUMBER)) - 1), // Subtract 1 for null terminator + .Size = USB_STRING_LEN(sizeof(SERIAL_NUMBER) - 1), // Subtract 1 for null terminator .Type = DTYPE_String }, - .UnicodeString = LSTR(SERIAL_NUMBER) + .UnicodeString = USBSTR(SERIAL_NUMBER) }; #endif diff --git a/tmk_core/protocol/usb_descriptor_common.h b/tmk_core/protocol/usb_descriptor_common.h index b1f602c82e..ce0cf09763 100644 --- a/tmk_core/protocol/usb_descriptor_common.h +++ b/tmk_core/protocol/usb_descriptor_common.h @@ -16,6 +16,10 @@ #pragma once +// Prefix string literal with L for descriptors +#define USBCONCAT(a, b) a##b +#define USBSTR(s) USBCONCAT(L, s) + ///////////////////// // RAW Usage page and ID configuration diff --git a/tmk_core/protocol/vusb/usb_util.c b/tmk_core/protocol/vusb/usb_util.c index 602854dbe6..4ee2d3188b 100644 --- a/tmk_core/protocol/vusb/usb_util.c +++ b/tmk_core/protocol/vusb/usb_util.c @@ -16,7 +16,7 @@ #include <usbdrv/usbdrv.h> #include "usb_util.h" -void usb_disable(void) { usbDeviceDisconnect(); } +void usb_disconnect(void) { usbDeviceDisconnect(); } bool usb_connected_state(void) { usbPoll(); diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c index 9362fbde78..98cebf6012 100644 --- a/tmk_core/protocol/vusb/vusb.c +++ b/tmk_core/protocol/vusb/vusb.c @@ -272,7 +272,8 @@ static void send_extra(uint8_t report_id, uint16_t data) { last_id = report_id; last_data = data; - report_extra_t report = {.report_id = report_id, .usage = data}; + static report_extra_t report; + report = (report_extra_t){.report_id = report_id, .usage = data}; if (usbInterruptIsReadyShared()) { usbSetInterruptShared((void *)&report, sizeof(report_extra_t)); } @@ -598,10 +599,10 @@ const PROGMEM usbStringDescriptor_t usbStringDescriptorProduct = { #if defined(SERIAL_NUMBER) const PROGMEM usbStringDescriptor_t usbStringDescriptorSerial = { .header = { - .bLength = USB_STRING_LEN(sizeof(STR(SERIAL_NUMBER)) - 1), + .bLength = USB_STRING_LEN(sizeof(SERIAL_NUMBER) - 1), .bDescriptorType = USBDESCR_STRING }, - .bString = LSTR(SERIAL_NUMBER) + .bString = USBSTR(SERIAL_NUMBER) }; #endif diff --git a/tmk_core/rules.mk b/tmk_core/rules.mk index fc2dc68be2..597f7aa827 100644 --- a/tmk_core/rules.mk +++ b/tmk_core/rules.mk @@ -458,7 +458,7 @@ ifeq ($(findstring avr-gcc,$(CC)),avr-gcc) SIZE_MARGIN = 1024 check-size: - $(eval MAX_SIZE=$(shell n=`$(CC) -E -mmcu=$(MCU) $(CFLAGS) $(OPT_DEFS) tmk_core/common/avr/bootloader_size.c 2> /dev/null | sed -ne 's/\r//;/^#/n;/^AVR_SIZE:/,$${s/^AVR_SIZE: //;p;}'` && echo $$(($$n)) || echo 0)) + $(eval MAX_SIZE=$(shell n=`$(CC) -E -mmcu=$(MCU) -D__ASSEMBLER__ $(CFLAGS) $(OPT_DEFS) tmk_core/common/avr/bootloader_size.c 2> /dev/null | sed -ne 's/\r//;/^#/n;/^AVR_SIZE:/,$${s/^AVR_SIZE: //;p;}'` && echo $$(($$n)) || echo 0)) $(eval CURRENT_SIZE=$(shell if [ -f $(BUILD_DIR)/$(TARGET).hex ]; then $(SIZE) --target=$(FORMAT) $(BUILD_DIR)/$(TARGET).hex | $(AWK) 'NR==2 {print $$4}'; else printf 0; fi)) $(eval FREE_SIZE=$(shell expr $(MAX_SIZE) - $(CURRENT_SIZE))) $(eval OVER_SIZE=$(shell expr $(CURRENT_SIZE) - $(MAX_SIZE))) |