diff options
Diffstat (limited to 'tmk_core')
47 files changed, 551 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..36839f9faf 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 @@ -35,6 +40,10 @@ __attribute__((weak)) bool get_tapping_force_hold(uint16_t keycode, keyrecord_t  __attribute__((weak)) bool get_permissive_hold(uint16_t keycode, keyrecord_t *record) { return false; }  #    endif +#    ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY +__attribute__((weak)) bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) { return false; } +#    endif +  static keyrecord_t tapping_key                         = {};  static keyrecord_t waiting_buffer[WAITING_BUFFER_SIZE] = {};  static uint8_t     waiting_buffer_head                 = 0; @@ -103,7 +112,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 +131,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 @@ -170,6 +179,19 @@ bool process_tapping(keyrecord_t *keyp) {                      // set interrupted flag when other key preesed during tapping                      if (event.pressed) {                          tapping_key.tap.interrupted = true; +#    if defined(HOLD_ON_OTHER_KEY_PRESS) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY) +#        if defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY) +                        if (get_hold_on_other_key_press(get_record_keycode(&tapping_key, false), keyp)) +#        endif +                        { +                            debug("Tapping: End. No tap. Interfered by pressed key\n"); +                            process_record(&tapping_key); +                            tapping_key = (keyrecord_t){}; +                            debug_tapping_key(); +                            // enqueue +                            return false; +                        } +#    endif                      }                      // enqueue                      return false; @@ -177,7 +199,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 +208,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 +244,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 +278,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 +301,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 +333,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))) | 
