summaryrefslogtreecommitdiff
path: root/tmk_core
diff options
context:
space:
mode:
authorDrashna Jael're <drashna@live.com>2021-06-29 12:23:03 -0700
committerDrashna Jael're <drashna@live.com>2021-06-29 12:24:07 -0700
commitacf2c323e2927f6007b17ded577cf49fd86fec6c (patch)
tree8334dc5c71e6ab9bf33c76143eac7bb0e60159b0 /tmk_core
parentec7a7beeed3046e9144d4c4ce0ef3b2c4f9e4341 (diff)
parentf55e39e8a2246f6f96fd5d4a84a866e2615cde7b (diff)
Merge upstream QMK Firmware at '0.12.52~1'
Diffstat (limited to 'tmk_core')
-rw-r--r--tmk_core/avr.mk72
-rw-r--r--tmk_core/chibios.mk4
-rw-r--r--tmk_core/common.mk38
-rw-r--r--tmk_core/common/action.c108
-rw-r--r--tmk_core/common/action.h1
-rw-r--r--tmk_core/common/action_tapping.c15
-rw-r--r--tmk_core/common/arm_atsam/_print.h (renamed from tmk_core/common/print.c)33
-rw-r--r--tmk_core/common/arm_atsam/printf.c9
-rw-r--r--tmk_core/common/arm_atsam/printf.mk1
-rw-r--r--tmk_core/common/arm_atsam/suspend.c3
-rw-r--r--tmk_core/common/atomic_util.h32
-rw-r--r--tmk_core/common/avr/_print.h33
-rw-r--r--tmk_core/common/avr/atomic_util.h22
-rw-r--r--tmk_core/common/avr/bootloader.c2
-rw-r--r--tmk_core/common/avr/gpio.h34
-rw-r--r--tmk_core/common/avr/pin_defs.h128
-rw-r--r--tmk_core/common/avr/printf.c (renamed from tmk_core/common/util.h)33
-rw-r--r--tmk_core/common/avr/printf.mk2
-rw-r--r--tmk_core/common/avr/sleep_led.c2
-rw-r--r--tmk_core/common/avr/suspend.c92
-rw-r--r--tmk_core/common/avr/suspend_avr.h25
-rw-r--r--tmk_core/common/chibios/atomic_util.h37
-rw-r--r--tmk_core/common/chibios/eeprom_teensy.c2
-rw-r--r--tmk_core/common/chibios/gpio.h34
-rw-r--r--tmk_core/common/chibios/pin_defs.h242
-rw-r--r--tmk_core/common/command.c787
-rw-r--r--tmk_core/common/command.h163
-rw-r--r--tmk_core/common/debug.c41
-rw-r--r--tmk_core/common/eeconfig.c12
-rw-r--r--tmk_core/common/eeconfig.h2
-rw-r--r--tmk_core/common/gpio.h22
-rw-r--r--tmk_core/common/host.c2
-rw-r--r--tmk_core/common/keyboard.c122
-rw-r--r--tmk_core/common/keyboard.h11
-rw-r--r--tmk_core/common/keycode.h24
-rw-r--r--tmk_core/common/led.h54
-rw-r--r--tmk_core/common/lib_printf.mk9
-rw-r--r--tmk_core/common/matrix.h76
-rw-r--r--tmk_core/common/mousekey.c446
-rw-r--r--tmk_core/common/mousekey.h142
-rw-r--r--tmk_core/common/pin_defs.h23
-rw-r--r--tmk_core/common/print.h301
-rw-r--r--tmk_core/common/printf.c (renamed from tmk_core/protocol/usb_hid/test/config.h)19
-rw-r--r--tmk_core/common/progmem.h1
-rw-r--r--tmk_core/common/report.h37
-rw-r--r--tmk_core/common/sendchar.h2
-rw-r--r--tmk_core/common/suspend.h2
-rw-r--r--tmk_core/common/sync_timer.c58
-rw-r--r--tmk_core/common/sync_timer.h54
-rw-r--r--tmk_core/common/uart.c172
-rw-r--r--tmk_core/common/uart.h8
-rw-r--r--tmk_core/common/util.c123
-rw-r--r--tmk_core/common/wait.h79
-rwxr-xr-xtmk_core/make_dfu_header.sh14
-rw-r--r--tmk_core/protocol/adb.c256
-rw-r--r--tmk_core/protocol/adb.h58
-rw-r--r--tmk_core/protocol/arm_atsam/i2c_master.c3
-rw-r--r--tmk_core/protocol/arm_atsam/i2c_master.h4
-rw-r--r--tmk_core/protocol/arm_atsam/main_arm_atsam.c6
-rw-r--r--tmk_core/protocol/arm_atsam/md_rgb_matrix.c94
-rw-r--r--tmk_core/protocol/arm_atsam/md_rgb_matrix_programs.c8
-rw-r--r--tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c42
-rw-r--r--tmk_core/protocol/arm_atsam/usb/usb_protocol_hid.h7
-rw-r--r--tmk_core/protocol/chibios/main.c3
-rw-r--r--tmk_core/protocol/chibios/usb_main.c117
-rw-r--r--tmk_core/protocol/chibios/usb_main.h11
-rw-r--r--tmk_core/protocol/lufa/lufa.c35
-rw-r--r--tmk_core/protocol/lufa/outputselect.h14
-rw-r--r--tmk_core/protocol/m0110.c8
-rw-r--r--tmk_core/protocol/midi/qmk_midi.c2
-rw-r--r--tmk_core/protocol/ps2_mouse.c2
-rw-r--r--tmk_core/protocol/serial.h2
-rw-r--r--tmk_core/protocol/serial_uart.c25
-rw-r--r--tmk_core/protocol/usb_descriptor.c17
-rw-r--r--tmk_core/protocol/usb_descriptor.h3
-rw-r--r--tmk_core/protocol/usb_hid/test/Makefile126
-rw-r--r--tmk_core/protocol/usb_hid/test/test.cpp92
-rw-r--r--tmk_core/protocol/vusb/main.c66
-rw-r--r--tmk_core/protocol/vusb/usbconfig.h356
-rw-r--r--tmk_core/protocol/vusb/vusb.c22
-rw-r--r--tmk_core/protocol/vusb/vusb.h3
-rw-r--r--tmk_core/protocol/xt.h41
-rw-r--r--tmk_core/protocol/xt_interrupt.c13
-rw-r--r--tmk_core/readme.md1
-rw-r--r--tmk_core/ring_buffer.h45
-rw-r--r--tmk_core/rules.mk5
86 files changed, 2187 insertions, 3110 deletions
diff --git a/tmk_core/avr.mk b/tmk_core/avr.mk
index dcdb6a449a..2bc7cc9553 100644
--- a/tmk_core/avr.mk
+++ b/tmk_core/avr.mk
@@ -154,38 +154,45 @@ dfu-split-left: $(BUILD_DIR)/$(TARGET).hex cpfirmware check-size
dfu-split-right: $(BUILD_DIR)/$(TARGET).hex cpfirmware check-size
$(call EXEC_DFU,eeprom-righthand.eep)
+AVRDUDE_PROGRAMMER ?= avrdude
+
define EXEC_AVRDUDE
- USB= ;\
- if $(GREP) -q -s Microsoft /proc/version; then \
- echo 'ERROR: AVR flashing cannot be automated within the Windows Subsystem for Linux (WSL) currently. Instead, take the .hex file generated and flash it using QMK Toolbox, AVRDUDE, AVRDUDESS, or XLoader.'; \
- else \
- printf "Detecting USB port, reset your controller now."; \
- TMP1=`mktemp`; \
- TMP2=`mktemp`; \
- ls /dev/tty* > $$TMP1; \
- while [ -z $$USB ]; do \
- sleep 0.5; \
- printf "."; \
- ls /dev/tty* > $$TMP2; \
- USB=`comm -13 $$TMP1 $$TMP2 | $(GREP) -o '/dev/tty.*'`; \
- mv $$TMP2 $$TMP1; \
- done; \
- rm $$TMP1; \
- echo ""; \
- echo "Device $$USB has appeared; assuming it is the controller."; \
- if $(GREP) -q -s 'MINGW\|MSYS' /proc/version; then \
- USB=`echo "$$USB" | perl -pne 's/\/dev\/ttyS(\d+)/COM.($$1+1)/e'`; \
- echo "Remapped MSYS2 USB port to $$USB"; \
- sleep 1; \
+ list_devices() { \
+ if $(GREP) -q -s icrosoft /proc/version; then \
+ wmic.exe path Win32_SerialPort get DeviceID 2>/dev/null | LANG=C perl -pne 's/COM(\d+)/COM.($$1-1)/e' | sed 's!COM!/dev/ttyS!' | xargs echo -n | sort; \
+ elif [ "`uname`" = "FreeBSD" ]; then \
+ ls /dev/tty* | grep -v '\.lock$$' | grep -v '\.init$$'; \
else \
- printf "Waiting for $$USB to become writable."; \
- while [ ! -w "$$USB" ]; do sleep 0.5; printf "."; done; echo ""; \
+ ls /dev/tty*; \
fi; \
- if [ -z "$(1)" ]; then \
- avrdude -p $(MCU) -c avr109 -P $$USB -U flash:w:$(BUILD_DIR)/$(TARGET).hex; \
- else \
- avrdude -p $(MCU) -c avr109 -P $$USB -U flash:w:$(BUILD_DIR)/$(TARGET).hex -U eeprom:w:$(QUANTUM_PATH)/split_common/$(1); \
- fi \
+ }; \
+ USB= ;\
+ printf "Detecting USB port, reset your controller now."; \
+ TMP1=`mktemp`; \
+ TMP2=`mktemp`; \
+ list_devices > $$TMP1; \
+ while [ -z "$$USB" ]; do \
+ sleep 0.5; \
+ printf "."; \
+ list_devices > $$TMP2; \
+ USB=`comm -13 $$TMP1 $$TMP2 | $(GREP) -o '/dev/tty.*'`; \
+ mv $$TMP2 $$TMP1; \
+ done; \
+ rm $$TMP1; \
+ echo ""; \
+ echo "Device $$USB has appeared; assuming it is the controller."; \
+ if $(GREP) -q -s 'MINGW\|MSYS\|icrosoft' /proc/version; then \
+ USB=`echo "$$USB" | LANG=C perl -pne 's/\/dev\/ttyS(\d+)/COM.($$1+1)/e'`; \
+ echo "Remapped USB port to $$USB"; \
+ sleep 1; \
+ else \
+ printf "Waiting for $$USB to become writable."; \
+ while [ ! -w "$$USB" ]; do sleep 0.5; printf "."; done; echo ""; \
+ fi; \
+ if [ -z "$(1)" ]; then \
+ $(AVRDUDE_PROGRAMMER) -p $(MCU) -c avr109 -P $$USB -U flash:w:$(BUILD_DIR)/$(TARGET).hex; \
+ else \
+ $(AVRDUDE_PROGRAMMER) -p $(MCU) -c avr109 -P $$USB -U flash:w:$(BUILD_DIR)/$(TARGET).hex -U eeprom:w:$(QUANTUM_PATH)/split_common/$(1); \
fi
endef
@@ -204,7 +211,7 @@ avrdude-split-right: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware
$(call EXEC_AVRDUDE,eeprom-righthand.eep)
define EXEC_USBASP
- avrdude -p $(MCU) -c usbasp -U flash:w:$(BUILD_DIR)/$(TARGET).hex
+ $(AVRDUDE_PROGRAMMER) -p $(AVRDUDE_MCU) -c usbasp -U flash:w:$(BUILD_DIR)/$(TARGET).hex
endef
usbasp: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware
@@ -283,8 +290,11 @@ extcoff: $(BUILD_DIR)/$(TARGET).elf
$(COFFCONVERT) -O coff-ext-avr $< $(BUILD_DIR)/$(TARGET).cof
bootloader:
+ifneq ($(strip $(BOOTLOADER)), qmk-dfu)
+ $(error Please set BOOTLOADER = qmk-dfu first!)
+endif
make -C lib/lufa/Bootloaders/DFU/ clean
- $(TMK_DIR)/make_dfu_header.sh $(ALL_CONFIGS)
+ bin/qmk 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))
$(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))
diff --git a/tmk_core/chibios.mk b/tmk_core/chibios.mk
index e94e935ebb..40595a1e3b 100644
--- a/tmk_core/chibios.mk
+++ b/tmk_core/chibios.mk
@@ -71,6 +71,9 @@ else ifneq ("$(wildcard $(TOP_DIR)/platforms/chibios/$(BOARD)/board/board.mk)","
BOARD_PATH = $(TOP_DIR)/platforms/chibios/$(BOARD)
BOARD_MK += $(TOP_DIR)/platforms/chibios/$(BOARD)/board/board.mk
KEYBOARD_PATHS += $(BOARD_PATH)/configs
+ ifneq ("$(wildcard $(BOARD_PATH)/rules.mk)","")
+ include $(BOARD_PATH)/rules.mk
+ endif
endif
ifeq ("$(wildcard $(BOARD_MK))","")
@@ -309,6 +312,7 @@ LDFLAGS += -mno-thumb-interwork -mthumb
LDSYMBOLS =,--defsym=__process_stack_size__=$(USE_PROCESS_STACKSIZE)
LDSYMBOLS :=$(LDSYMBOLS),--defsym=__main_stack_size__=$(USE_EXCEPTIONS_STACKSIZE)
LDFLAGS += -Wl,--script=$(LDSCRIPT)$(LDSYMBOLS)
+LDFLAGS += --specs=nano.specs
OPT_DEFS += -DPROTOCOL_CHIBIOS
diff --git a/tmk_core/common.mk b/tmk_core/common.mk
index 5ead3c090f..bcc44a63e6 100644
--- a/tmk_core/common.mk
+++ b/tmk_core/common.mk
@@ -10,27 +10,20 @@ TMK_COMMON_SRC += $(COMMON_DIR)/host.c \
$(COMMON_DIR)/action_macro.c \
$(COMMON_DIR)/action_layer.c \
$(COMMON_DIR)/action_util.c \
- $(COMMON_DIR)/print.c \
$(COMMON_DIR)/debug.c \
$(COMMON_DIR)/sendchar_null.c \
- $(COMMON_DIR)/util.c \
$(COMMON_DIR)/eeconfig.c \
$(COMMON_DIR)/report.c \
$(PLATFORM_COMMON_DIR)/suspend.c \
$(PLATFORM_COMMON_DIR)/timer.c \
+ $(COMMON_DIR)/sync_timer.c \
$(PLATFORM_COMMON_DIR)/bootloader.c \
-ifeq ($(PLATFORM),AVR)
- TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/xprintf.S
-else ifeq ($(PLATFORM),CHIBIOS)
- TMK_COMMON_SRC += $(PRINTF_PATH)/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)
-else ifeq ($(PLATFORM),ARM_ATSAM)
- TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/printf.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
# Option modules
@@ -67,10 +60,6 @@ ifeq ($(strip $(KEYBOARD_SHARED_EP)), yes)
endif
ifeq ($(strip $(MOUSEKEY_ENABLE)), yes)
- TMK_COMMON_SRC += $(COMMON_DIR)/mousekey.c
- TMK_COMMON_DEFS += -DMOUSEKEY_ENABLE
- TMK_COMMON_DEFS += -DMOUSE_ENABLE
-
ifeq ($(strip $(MOUSE_SHARED_EP)), yes)
TMK_COMMON_DEFS += -DMOUSE_SHARED_EP
SHARED_EP_ENABLE = yes
@@ -98,17 +87,16 @@ else
TMK_COMMON_DEFS += -DNO_DEBUG
endif
-ifeq ($(strip $(COMMAND_ENABLE)), yes)
- TMK_COMMON_SRC += $(COMMON_DIR)/command.c
- TMK_COMMON_DEFS += -DCOMMAND_ENABLE
-endif
-
ifeq ($(strip $(NKRO_ENABLE)), yes)
- ifneq ($(PROTOCOL),VUSB)
+ ifeq ($(PROTOCOL), VUSB)
+ $(info NKRO is not currently supported on V-USB, and has been disabled.)
+ else ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
+ $(info NKRO is not currently supported with Bluetooth, and has been disabled.)
+ else ifneq ($(BLUETOOTH),)
+ $(info NKRO is not currently supported with Bluetooth, and has been disabled.)
+ else
TMK_COMMON_DEFS += -DNKRO_ENABLE
SHARED_EP_ENABLE = yes
- else
- $(info NKRO is not currently supported on V-USB, and has been disabled.)
endif
endif
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index b87b9e7282..055bd91de0 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -47,10 +47,6 @@ int tp_buttons;
int retro_tapping_counter = 0;
#endif
-#ifdef FAUXCLICKY_ENABLE
-# include "fauxclicky.h"
-#endif
-
#ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY
__attribute__((weak)) bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { return false; }
#endif
@@ -80,15 +76,10 @@ void action_exec(keyevent_t event) {
#endif
}
-#ifdef FAUXCLICKY_ENABLE
- if (IS_PRESSED(event)) {
- FAUXCLICKY_ACTION_PRESS;
- }
- if (IS_RELEASED(event)) {
- FAUXCLICKY_ACTION_RELEASE;
+ if (event.pressed) {
+ // clear the potential weak mods left by previously pressed keys
+ clear_weak_mods();
}
- fauxclicky_check();
-#endif
#ifdef SWAP_HANDS_ENABLE
if (!IS_NOEVENT(event)) {
@@ -251,11 +242,6 @@ void process_action(keyrecord_t *record, action_t action) {
uint8_t tap_count = record->tap.count;
#endif
- if (event.pressed) {
- // clear the potential weak mods left by previously pressed keys
- clear_weak_mods();
- }
-
#ifndef NO_ACTION_ONESHOT
bool do_release_oneshot = false;
// notice we only clear the one shot layer if the pressed key is not a modifier.
@@ -424,56 +410,22 @@ void process_action(keyrecord_t *record, action_t action) {
case ACT_MOUSEKEY:
if (event.pressed) {
mousekey_on(action.key.code);
- switch (action.key.code) {
-# if defined(PS2_MOUSE_ENABLE) || defined(POINTING_DEVICE_ENABLE)
- case KC_MS_BTN1:
- register_button(true, MOUSE_BTN1);
- break;
- case KC_MS_BTN2:
- register_button(true, MOUSE_BTN2);
- break;
- case KC_MS_BTN3:
- register_button(true, MOUSE_BTN3);
- break;
-# endif
-# ifdef POINTING_DEVICE_ENABLE
- case KC_MS_BTN4:
- register_button(true, MOUSE_BTN4);
- break;
- case KC_MS_BTN5:
- register_button(true, MOUSE_BTN5);
- break;
-# endif
- default:
- mousekey_send();
- break;
- }
} else {
mousekey_off(action.key.code);
- switch (action.key.code) {
+ }
+ switch (action.key.code) {
# if defined(PS2_MOUSE_ENABLE) || defined(POINTING_DEVICE_ENABLE)
- case KC_MS_BTN1:
- register_button(false, MOUSE_BTN1);
- break;
- case KC_MS_BTN2:
- register_button(false, MOUSE_BTN2);
- break;
- case KC_MS_BTN3:
- register_button(false, MOUSE_BTN3);
- break;
-# endif
-# ifdef POINTING_DEVICE_ENABLE
- case KC_MS_BTN4:
- register_button(false, MOUSE_BTN4);
- break;
- case KC_MS_BTN5:
- register_button(false, MOUSE_BTN5);
- break;
+# ifdef POINTING_DEVICE_ENABLE
+ case KC_MS_BTN1 ... KC_MS_BTN8:
+# else
+ case KC_MS_BTN1 ... KC_MS_BTN3:
+# endif
+ register_button(event.pressed, MOUSE_BTN_MASK(action.key.code - KC_MS_BTN1));
+ break;
# endif
- default:
- mousekey_send();
- break;
- }
+ default:
+ mousekey_send();
+ break;
}
break;
#endif
@@ -936,23 +888,28 @@ void unregister_code(uint8_t code) {
#endif
}
-/** \brief Utilities for actions. (FIXME: Needs better description)
+/** \brief Tap a keycode with a delay.
*
- * FIXME: Needs documentation.
+ * \param code The basic keycode to tap.
+ * \param delay The amount of time in milliseconds to leave the keycode registered, before unregistering it.
*/
-void tap_code(uint8_t code) {
+void tap_code_delay(uint8_t code, uint16_t delay) {
register_code(code);
- if (code == KC_CAPS) {
- wait_ms(TAP_HOLD_CAPS_DELAY);
- } else {
- wait_ms(TAP_CODE_DELAY);
+ for (uint16_t i = delay; i > 0; i--) {
+ wait_ms(1);
}
unregister_code(code);
}
+/** \brief Tap a keycode with the default delay.
+ *
+ * \param code The basic keycode to tap. If `code` is `KC_CAPS`, the delay will be `TAP_HOLD_CAPS_DELAY`, otherwise `TAP_CODE_DELAY`, if defined.
+ */
+void tap_code(uint8_t code) { tap_code_delay(code, code == KC_CAPS ? TAP_HOLD_CAPS_DELAY : TAP_CODE_DELAY); }
+
/** \brief Adds the given physically pressed modifiers and sends a keyboard report immediately.
*
- * \param mods A bitfield of modifiers to unregister.
+ * \param mods A bitfield of modifiers to register.
*/
void register_mods(uint8_t mods) {
if (mods) {
@@ -972,6 +929,7 @@ void unregister_mods(uint8_t mods) {
}
}
+
/** \brief Adds the given weak modifiers and sends a keyboard report immediately.
*
* \param mods A bitfield of modifiers to register.
@@ -1017,6 +975,10 @@ void clear_keyboard_but_mods(void) {
* FIXME: Needs documentation.
*/
void clear_keyboard_but_mods_and_keys() {
+#ifdef EXTRAKEY_ENABLE
+ host_system_send(0);
+ host_consumer_send(0);
+#endif
clear_weak_mods();
clear_macro_mods();
send_keyboard_report();
@@ -1024,10 +986,6 @@ void clear_keyboard_but_mods_and_keys() {
mousekey_clear();
mousekey_send();
#endif
-#ifdef EXTRAKEY_ENABLE
- host_system_send(0);
- host_consumer_send(0);
-#endif
}
/** \brief Utilities for actions. (FIXME: Needs better description)
diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h
index 81cd54369c..9a991de1c2 100644
--- a/tmk_core/common/action.h
+++ b/tmk_core/common/action.h
@@ -100,6 +100,7 @@ void process_action(keyrecord_t *record, action_t action);
void register_code(uint8_t code);
void unregister_code(uint8_t code);
void tap_code(uint8_t code);
+void tap_code_delay(uint8_t code, uint16_t delay);
void register_mods(uint8_t mods);
void unregister_mods(uint8_t mods);
void register_weak_mods(uint8_t mods);
diff --git a/tmk_core/common/action_tapping.c b/tmk_core/common/action_tapping.c
index fe545c79a0..56044e096d 100644
--- a/tmk_core/common/action_tapping.c
+++ b/tmk_core/common/action_tapping.c
@@ -120,14 +120,21 @@ bool process_tapping(keyrecord_t *keyp) {
* useful for long TAPPING_TERM but may prevent fast typing.
*/
# if defined(TAPPING_TERM_PER_KEY) || (TAPPING_TERM >= 500) || defined(PERMISSIVE_HOLD) || defined(PERMISSIVE_HOLD_PER_KEY)
- else if (
+ else if (((
# ifdef TAPPING_TERM_PER_KEY
- (get_tapping_term(get_event_keycode(tapping_key.event, false), keyp) >= 500) &&
+ get_tapping_term(get_event_keycode(tapping_key.event, 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_event_keycode(tapping_key.event, false), keyp)
+# elif defined(PERMISSIVE_HOLD)
+ || true
# endif
- IS_RELEASED(event) && waiting_buffer_typed(event)) {
+ ) &&
+ IS_RELEASED(event) && waiting_buffer_typed(event)) {
debug("Tapping: End. No tap. Interfered by typing key\n");
process_record(&tapping_key);
tapping_key = (keyrecord_t){};
diff --git a/tmk_core/common/print.c b/tmk_core/common/arm_atsam/_print.h
index 07aef0b0eb..04320ee38b 100644
--- a/tmk_core/common/print.c
+++ b/tmk_core/common/arm_atsam/_print.h
@@ -1,4 +1,4 @@
-/* Copyright 2012,2013 Jun Wako <wakojun@gmail.com> */
+/* 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
@@ -21,27 +21,14 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#pragma once
-#include <stdint.h>
-#include "print.h"
+#include "arm_atsam/printf.h"
-#ifndef NO_PRINT
-
-# if defined(__AVR__)
-
-# define sendchar(c) xputc(c)
-
-void print_set_sendchar(int8_t (*sendchar_func)(uint8_t)) { xdev_out(sendchar_func); }
-
-# elif defined(PROTOCOL_CHIBIOS) /* __AVR__ */
-
-// don't need anything extra
-
-# elif defined(__arm__) /* __AVR__ */
-
-// TODO
-// void print_set_sendchar(int8_t (*sendchar_func)(uint8_t)) { }
-
-# endif /* __AVR__ */
-
-#endif
+// Create user & normal print defines
+#define xprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
+#define print(s) __xprintf(s)
+#define println(s) __xprintf(s "\r\n")
+#define uprint(s) __xprintf(s)
+#define uprintln(s) __xprintf(s "\r\n")
+#define uprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
diff --git a/tmk_core/common/arm_atsam/printf.c b/tmk_core/common/arm_atsam/printf.c
index cd7cdb52e6..6f7e8d343f 100644
--- a/tmk_core/common/arm_atsam/printf.c
+++ b/tmk_core/common/arm_atsam/printf.c
@@ -15,11 +15,13 @@ 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 "printf.h"
+#include "sendchar.h"
+
#ifdef CONSOLE_ENABLE
# include "samd51j18a.h"
# include "arm_atsam_protocol.h"
-# include "printf.h"
# include <string.h>
# include <stdarg.h>
@@ -66,3 +68,8 @@ void console_printf(char *fmt, ...) {
}
#endif // CONSOLE_ENABLE
+<<<<<<< HEAD
+=======
+
+void print_set_sendchar(sendchar_func_t send) {}
+>>>>>>> 0.12.52~1
diff --git a/tmk_core/common/arm_atsam/printf.mk b/tmk_core/common/arm_atsam/printf.mk
new file mode 100644
index 0000000000..f70e02731f
--- /dev/null
+++ b/tmk_core/common/arm_atsam/printf.mk
@@ -0,0 +1 @@
+TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/printf.c
diff --git a/tmk_core/common/arm_atsam/suspend.c b/tmk_core/common/arm_atsam/suspend.c
index 6a36740658..e51426128d 100644
--- a/tmk_core/common/arm_atsam/suspend.c
+++ b/tmk_core/common/arm_atsam/suspend.c
@@ -7,7 +7,8 @@
*
* FIXME: needs doc
*/
-void suspend_idle(uint8_t time) { /* Note: Not used anywhere currently */ }
+void suspend_idle(uint8_t time) { /* Note: Not used anywhere currently */
+}
/** \brief Run user level Power down
*
diff --git a/tmk_core/common/atomic_util.h b/tmk_core/common/atomic_util.h
new file mode 100644
index 0000000000..2c95302a13
--- /dev/null
+++ b/tmk_core/common/atomic_util.h
@@ -0,0 +1,32 @@
+/* Copyright 2021 QMK
+ *
+ * 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 3 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
+
+// Macro to help make GPIO and other controls atomic.
+
+#ifndef IGNORE_ATOMIC_BLOCK
+# if __has_include_next("atomic_util.h")
+# include_next "atomic_util.h" /* Include the platforms atomic.h */
+# else
+# define ATOMIC_BLOCK _Static_assert(0, "ATOMIC_BLOCK not implemented")
+# define ATOMIC_BLOCK_RESTORESTATE _Static_assert(0, "ATOMIC_BLOCK_RESTORESTATE not implemented")
+# define ATOMIC_BLOCK_FORCEON _Static_assert(0, "ATOMIC_BLOCK_FORCEON not implemented")
+# endif
+#else /* do nothing atomic macro */
+# define ATOMIC_BLOCK for (uint8_t __ToDo = 1; __ToDo; __ToDo = 0)
+# define ATOMIC_BLOCK_RESTORESTATE ATOMIC_BLOCK
+# define ATOMIC_BLOCK_FORCEON ATOMIC_BLOCK
+#endif
diff --git a/tmk_core/common/avr/_print.h b/tmk_core/common/avr/_print.h
new file mode 100644
index 0000000000..5c1fdd26d8
--- /dev/null
+++ b/tmk_core/common/avr/_print.h
@@ -0,0 +1,33 @@
+/* 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 "avr/xprintf.h"
+
+// Create user & normal print defines
+#define print(s) xputs(PSTR(s))
+#define println(s) xputs(PSTR(s "\r\n"))
+#define uprint(s) xputs(PSTR(s))
+#define uprintln(s) xputs(PSTR(s "\r\n"))
+#define uprintf(fmt, ...) __xprintf(PSTR(fmt), ##__VA_ARGS__) \ No newline at end of file
diff --git a/tmk_core/common/avr/atomic_util.h b/tmk_core/common/avr/atomic_util.h
new file mode 100644
index 0000000000..7c5d2e7dcc
--- /dev/null
+++ b/tmk_core/common/avr/atomic_util.h
@@ -0,0 +1,22 @@
+/* Copyright 2021 QMK
+ *
+ * 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 3 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
+
+/* atomic macro for AVR */
+#include <util/atomic.h>
+
+#define ATOMIC_BLOCK_RESTORESTATE ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
+#define ATOMIC_BLOCK_FORCEON ATOMIC_BLOCK(ATOMIC_FORCEON)
diff --git a/tmk_core/common/avr/bootloader.c b/tmk_core/common/avr/bootloader.c
index a1db55da93..c0272903b8 100644
--- a/tmk_core/common/avr/bootloader.c
+++ b/tmk_core/common/avr/bootloader.c
@@ -77,7 +77,7 @@ uint32_t reset_key __attribute__((section(".noinit,\"aw\",@nobits;")));
*
* FIXME: needs doc
*/
-void bootloader_jump(void) {
+__attribute__((weak)) void bootloader_jump(void) {
#if !defined(BOOTLOADER_SIZE)
uint8_t high_fuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS);
diff --git a/tmk_core/common/avr/gpio.h b/tmk_core/common/avr/gpio.h
new file mode 100644
index 0000000000..231556c29c
--- /dev/null
+++ b/tmk_core/common/avr/gpio.h
@@ -0,0 +1,34 @@
+/* Copyright 2021 QMK
+ *
+ * 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 3 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 <avr/io.h>
+#include "pin_defs.h"
+
+typedef uint8_t pin_t;
+
+#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")
+#define setPinOutput(pin) (DDRx_ADDRESS(pin) |= _BV((pin)&0xF))
+
+#define writePinHigh(pin) (PORTx_ADDRESS(pin) |= _BV((pin)&0xF))
+#define writePinLow(pin) (PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF))
+#define writePin(pin, level) ((level) ? writePinHigh(pin) : writePinLow(pin))
+
+#define readPin(pin) ((bool)(PINx_ADDRESS(pin) & _BV((pin)&0xF)))
+
+#define togglePin(pin) (PORTx_ADDRESS(pin) ^= _BV((pin)&0xF))
diff --git a/tmk_core/common/avr/pin_defs.h b/tmk_core/common/avr/pin_defs.h
new file mode 100644
index 0000000000..23d948041d
--- /dev/null
+++ b/tmk_core/common/avr/pin_defs.h
@@ -0,0 +1,128 @@
+/* Copyright 2021 QMK
+ *
+ * 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 3 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 <avr/io.h>
+
+#define PORT_SHIFTER 4 // this may be 4 for all AVR chips
+
+// If you want to add more to this list, reference the PINx definitions in these header
+// files: https://github.com/vancegroup-mirrors/avr-libc/tree/master/avr-libc/include/avr
+
+#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__)
+# define ADDRESS_BASE 0x00
+# define PINB_ADDRESS 0x3
+# define PINC_ADDRESS 0x6
+# define PIND_ADDRESS 0x9
+# define PINE_ADDRESS 0xC
+# define PINF_ADDRESS 0xF
+#elif defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
+# define ADDRESS_BASE 0x00
+# define PINB_ADDRESS 0x3
+# define PINC_ADDRESS 0x6
+# define PIND_ADDRESS 0x9
+#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
+# define ADDRESS_BASE 0x00
+# define PINA_ADDRESS 0x0
+# define PINB_ADDRESS 0x3
+# define PINC_ADDRESS 0x6
+# define PIND_ADDRESS 0x9
+# define PINE_ADDRESS 0xC
+# define PINF_ADDRESS 0xF
+#elif defined(__AVR_ATmega32A__)
+# define ADDRESS_BASE 0x10
+# define PIND_ADDRESS 0x0
+# define PINC_ADDRESS 0x3
+# define PINB_ADDRESS 0x6
+# define PINA_ADDRESS 0x9
+#elif defined(__AVR_ATtiny85__)
+# define ADDRESS_BASE 0x10
+# define PINB_ADDRESS 0x6
+#else
+# error "Pins are not defined"
+#endif
+
+#define PINDEF(port, pin) ((PIN##port##_ADDRESS << PORT_SHIFTER) | pin)
+
+#define _PIN_ADDRESS(p, offset) _SFR_IO8(ADDRESS_BASE + ((p) >> PORT_SHIFTER) + (offset))
+// Port X Input Pins Address
+#define PINx_ADDRESS(p) _PIN_ADDRESS(p, 0)
+// Port X Data Direction Register, 0:input 1:output
+#define DDRx_ADDRESS(p) _PIN_ADDRESS(p, 1)
+// Port X Data Register
+#define PORTx_ADDRESS(p) _PIN_ADDRESS(p, 2)
+
+/* I/O pins */
+#ifdef PORTA
+# define A0 PINDEF(A, 0)
+# define A1 PINDEF(A, 1)
+# define A2 PINDEF(A, 2)
+# define A3 PINDEF(A, 3)
+# define A4 PINDEF(A, 4)
+# define A5 PINDEF(A, 5)
+# define A6 PINDEF(A, 6)
+# define A7 PINDEF(A, 7)
+#endif
+#ifdef PORTB
+# define B0 PINDEF(B, 0)
+# define B1 PINDEF(B, 1)
+# define B2 PINDEF(B, 2)
+# define B3 PINDEF(B, 3)
+# define B4 PINDEF(B, 4)
+# define B5 PINDEF(B, 5)
+# define B6 PINDEF(B, 6)
+# define B7 PINDEF(B, 7)
+#endif
+#ifdef PORTC
+# define C0 PINDEF(C, 0)
+# define C1 PINDEF(C, 1)
+# define C2 PINDEF(C, 2)
+# define C3 PINDEF(C, 3)
+# define C4 PINDEF(C, 4)
+# define C5 PINDEF(C, 5)
+# define C6 PINDEF(C, 6)
+# define C7 PINDEF(C, 7)
+#endif
+#ifdef PORTD
+# define D0 PINDEF(D, 0)
+# define D1 PINDEF(D, 1)
+# define D2 PINDEF(D, 2)
+# define D3 PINDEF(D, 3)
+# define D4 PINDEF(D, 4)
+# define D5 PINDEF(D, 5)
+# define D6 PINDEF(D, 6)
+# define D7 PINDEF(D, 7)
+#endif
+#ifdef PORTE
+# define E0 PINDEF(E, 0)
+# define E1 PINDEF(E, 1)
+# define E2 PINDEF(E, 2)
+# define E3 PINDEF(E, 3)
+# define E4 PINDEF(E, 4)
+# define E5 PINDEF(E, 5)
+# define E6 PINDEF(E, 6)
+# define E7 PINDEF(E, 7)
+#endif
+#ifdef PORTF
+# define F0 PINDEF(F, 0)
+# define F1 PINDEF(F, 1)
+# define F2 PINDEF(F, 2)
+# define F3 PINDEF(F, 3)
+# define F4 PINDEF(F, 4)
+# define F5 PINDEF(F, 5)
+# define F6 PINDEF(F, 6)
+# define F7 PINDEF(F, 7)
+#endif
diff --git a/tmk_core/common/util.h b/tmk_core/common/avr/printf.c
index db57f268c3..9ad7a38693 100644
--- a/tmk_core/common/util.h
+++ b/tmk_core/common/avr/printf.c
@@ -14,34 +14,7 @@ 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 "xprintf.h"
+#include "sendchar.h"
-#pragma once
-
-#include <stdint.h>
-
-// convert to L string
-#define LSTR(s) XLSTR(s)
-#define XLSTR(s) L## #s
-// convert to string
-#define STR(s) XSTR(s)
-#define XSTR(s) #s
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-uint8_t bitpop(uint8_t bits);
-uint8_t bitpop16(uint16_t bits);
-uint8_t bitpop32(uint32_t bits);
-
-uint8_t biton(uint8_t bits);
-uint8_t biton16(uint16_t bits);
-uint8_t biton32(uint32_t bits);
-
-uint8_t bitrev(uint8_t bits);
-uint16_t bitrev16(uint16_t bits);
-uint32_t bitrev32(uint32_t bits);
-
-#ifdef __cplusplus
-}
-#endif
+void print_set_sendchar(sendchar_func_t func) { xdev_out(func); }
diff --git a/tmk_core/common/avr/printf.mk b/tmk_core/common/avr/printf.mk
new file mode 100644
index 0000000000..060ad88c57
--- /dev/null
+++ b/tmk_core/common/avr/printf.mk
@@ -0,0 +1,2 @@
+TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/xprintf.S
+TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/printf.c
diff --git a/tmk_core/common/avr/sleep_led.c b/tmk_core/common/avr/sleep_led.c
index 63dcc2afd9..9a3b52abe5 100644
--- a/tmk_core/common/avr/sleep_led.c
+++ b/tmk_core/common/avr/sleep_led.c
@@ -90,7 +90,7 @@ void sleep_led_toggle(void) {
*
* (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle
*
- * http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63
+ * https://www.wolframalpha.com/input/?i=sin%28x%2F64*pi%29**8+*+255%2C+x%3D0+to+63
* (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i }
*/
static const uint8_t breathing_table[64] PROGMEM = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10, 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252, 255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23, 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c
index b784a0835d..47a82a2eec 100644
--- a/tmk_core/common/avr/suspend.c
+++ b/tmk_core/common/avr/suspend.c
@@ -4,7 +4,6 @@
#include <avr/interrupt.h>
#include "matrix.h"
#include "action.h"
-#include "suspend_avr.h"
#include "suspend.h"
#include "timer.h"
#include "led.h"
@@ -13,6 +12,9 @@
#ifdef PROTOCOL_LUFA
# include "lufa.h"
#endif
+#ifdef PROTOCOL_VUSB
+# include "vusb.h"
+#endif
#ifdef BACKLIGHT_ENABLE
# include "backlight.h"
@@ -52,7 +54,25 @@ __attribute__((weak)) void suspend_power_down_user(void) {}
*/
__attribute__((weak)) void suspend_power_down_kb(void) { suspend_power_down_user(); }
-#ifndef NO_SUSPEND_POWER_DOWN
+#if !defined(NO_SUSPEND_POWER_DOWN) && defined(WDT_vect)
+
+// clang-format off
+#define wdt_intr_enable(value) \
+__asm__ __volatile__ ( \
+ "in __tmp_reg__,__SREG__" "\n\t" \
+ "cli" "\n\t" \
+ "wdr" "\n\t" \
+ "sts %0,%1" "\n\t" \
+ "out __SREG__,__tmp_reg__" "\n\t" \
+ "sts %0,%2" "\n\t" \
+ : /* no outputs */ \
+ : "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
+ "r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \
+ "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | _BV(WDIE) | (value & 0x07))) \
+ : "r0" \
+)
+// clang-format on
+
/** \brief Power down MCU with watchdog timer
*
* wdto: watchdog timer timeout defined in <avr/wdt.h>
@@ -74,35 +94,11 @@ static uint8_t wdt_timeout = 0;
* FIXME: needs doc
*/
static void power_down(uint8_t wdto) {
-# ifdef PROTOCOL_LUFA
- if (USB_DeviceState == DEVICE_STATE_Configured) return;
-# endif
wdt_timeout = wdto;
// Watchdog Interrupt Mode
wdt_intr_enable(wdto);
-# ifdef BACKLIGHT_ENABLE
- backlight_set(0);
-# endif
-
- // Turn off LED indicators
- uint8_t leds_off = 0;
-# if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE)
- if (is_backlight_enabled()) {
- // Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off
- leds_off |= (1 << USB_LED_CAPS_LOCK);
- }
-# endif
- led_set(leds_off);
-
-# ifdef AUDIO_ENABLE
- stop_all_notes();
-# endif /* AUDIO_ENABLE */
-# if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
- rgblight_suspend();
-# endif
-
// TODO: more power saving
// See PicoPower application note
// - I/O port input with pullup
@@ -125,10 +121,45 @@ static void power_down(uint8_t wdto) {
* FIXME: needs doc
*/
void suspend_power_down(void) {
+#ifdef PROTOCOL_LUFA
+ if (USB_DeviceState == DEVICE_STATE_Configured) return;
+#endif
+#ifdef PROTOCOL_VUSB
+ if (!vusb_suspended) return;
+#endif
+
suspend_power_down_kb();
#ifndef NO_SUSPEND_POWER_DOWN
+ // Turn off backlight
+# ifdef BACKLIGHT_ENABLE
+ backlight_set(0);
+# endif
+
+ // Turn off LED indicators
+ uint8_t leds_off = 0;
+# if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE)
+ if (is_backlight_enabled()) {
+ // Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off
+ leds_off |= (1 << USB_LED_CAPS_LOCK);
+ }
+# endif
+ led_set(leds_off);
+
+ // Turn off audio
+# ifdef AUDIO_ENABLE
+ stop_all_notes();
+# endif
+
+ // Turn off underglow
+# if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
+ rgblight_suspend();
+# endif
+
+ // Enter sleep state if possible (ie, the MCU has a watchdog timeout interrupt)
+# if defined(WDT_vect)
power_down(WDTO_15MS);
+# endif
#endif
}
@@ -163,17 +194,24 @@ __attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_us
void suspend_wakeup_init(void) {
// clear keyboard state
clear_keyboard();
+
+ // Turn on backlight
#ifdef BACKLIGHT_ENABLE
backlight_init();
#endif
+
+ // Restore LED indicators
led_set(host_keyboard_leds());
+
+ // Wake up underglow
#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
rgblight_wakeup();
#endif
+
suspend_wakeup_init_kb();
}
-#ifndef NO_SUSPEND_POWER_DOWN
+#if !defined(NO_SUSPEND_POWER_DOWN) && defined(WDT_vect)
/* watchdog timeout */
ISR(WDT_vect) {
// compensate timer for sleep
diff --git a/tmk_core/common/avr/suspend_avr.h b/tmk_core/common/avr/suspend_avr.h
deleted file mode 100644
index 6df048f3bb..0000000000
--- a/tmk_core/common/avr/suspend_avr.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#pragma once
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <avr/sleep.h>
-#include <avr/wdt.h>
-#include <avr/interrupt.h>
-
-// clang-format off
-#define wdt_intr_enable(value) \
-__asm__ __volatile__ ( \
- "in __tmp_reg__,__SREG__" "\n\t" \
- "cli" "\n\t" \
- "wdr" "\n\t" \
- "sts %0,%1" "\n\t" \
- "out __SREG__,__tmp_reg__" "\n\t" \
- "sts %0,%2" "\n\t" \
- : /* no outputs */ \
- : "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
- "r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \
- "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \
- _BV(WDIE) | (value & 0x07)) ) \
- : "r0" \
-)
-// clang-format on
diff --git a/tmk_core/common/chibios/atomic_util.h b/tmk_core/common/chibios/atomic_util.h
new file mode 100644
index 0000000000..8975045153
--- /dev/null
+++ b/tmk_core/common/chibios/atomic_util.h
@@ -0,0 +1,37 @@
+/* Copyright 2021 QMK
+ *
+ * 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 3 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 <ch.h>
+
+static __inline__ uint8_t __interrupt_disable__(void) {
+ chSysLock();
+
+ return 1;
+}
+
+static __inline__ void __interrupt_enable__(const uint8_t *__s) {
+ chSysUnlock();
+
+ __asm__ volatile("" ::: "memory");
+ (void)__s;
+}
+
+#define ATOMIC_BLOCK(type) for (type, __ToDo = __interrupt_disable__(); __ToDo; __ToDo = 0)
+#define ATOMIC_FORCEON uint8_t sreg_save __attribute__((__cleanup__(__interrupt_enable__))) = 0
+
+#define ATOMIC_BLOCK_RESTORESTATE _Static_assert(0, "ATOMIC_BLOCK_RESTORESTATE not implemented")
+#define ATOMIC_BLOCK_FORCEON ATOMIC_BLOCK(ATOMIC_FORCEON)
diff --git a/tmk_core/common/chibios/eeprom_teensy.c b/tmk_core/common/chibios/eeprom_teensy.c
index e135e19a21..4aaf665269 100644
--- a/tmk_core/common/chibios/eeprom_teensy.c
+++ b/tmk_core/common/chibios/eeprom_teensy.c
@@ -363,7 +363,7 @@ void eeprom_initialize(void) {
return;
}
} while (p < (uint16_t *)SYMVAL(__eeprom_workarea_end__));
- flashend = (uint32_t)((uint16_t *)SYMVAL(__eeprom_workarea_end__) - 1);
+ flashend = (uint32_t)(p - 1);
}
uint8_t eeprom_read_byte(const uint8_t *addr) {
diff --git a/tmk_core/common/chibios/gpio.h b/tmk_core/common/chibios/gpio.h
new file mode 100644
index 0000000000..5d0e142abc
--- /dev/null
+++ b/tmk_core/common/chibios/gpio.h
@@ -0,0 +1,34 @@
+/* Copyright 2021 QMK
+ *
+ * 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 3 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 <hal.h>
+#include "pin_defs.h"
+
+typedef ioline_t pin_t;
+
+#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)
+#define setPinOutput(pin) palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)
+
+#define writePinHigh(pin) palSetLine(pin)
+#define writePinLow(pin) palClearLine(pin)
+#define writePin(pin, level) ((level) ? (writePinHigh(pin)) : (writePinLow(pin)))
+
+#define readPin(pin) palReadLine(pin)
+
+#define togglePin(pin) palToggleLine(pin)
diff --git a/tmk_core/common/chibios/pin_defs.h b/tmk_core/common/chibios/pin_defs.h
new file mode 100644
index 0000000000..86bc1076e8
--- /dev/null
+++ b/tmk_core/common/chibios/pin_defs.h
@@ -0,0 +1,242 @@
+/* Copyright 2021 QMK
+ *
+ * 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 3 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
+
+// Defines mapping for Proton C replacement
+#ifdef CONVERT_TO_PROTON_C
+// Left side (front)
+# define D3 PAL_LINE(GPIOA, 9)
+# define D2 PAL_LINE(GPIOA, 10)
+// GND
+// GND
+# define D1 PAL_LINE(GPIOB, 7)
+# define D0 PAL_LINE(GPIOB, 6)
+# define D4 PAL_LINE(GPIOB, 5)
+# define C6 PAL_LINE(GPIOB, 4)
+# define D7 PAL_LINE(GPIOB, 3)
+# define E6 PAL_LINE(GPIOB, 2)
+# define B4 PAL_LINE(GPIOB, 1)
+# define B5 PAL_LINE(GPIOB, 0)
+
+// Right side (front)
+// RAW
+// GND
+// RESET
+// VCC
+# define F4 PAL_LINE(GPIOA, 2)
+# define F5 PAL_LINE(GPIOA, 1)
+# define F6 PAL_LINE(GPIOA, 0)
+# define F7 PAL_LINE(GPIOB, 8)
+# define B1 PAL_LINE(GPIOB, 13)
+# define B3 PAL_LINE(GPIOB, 14)
+# define B2 PAL_LINE(GPIOB, 15)
+# define B6 PAL_LINE(GPIOB, 9)
+
+// LEDs (only D5/C13 uses an actual LED)
+# ifdef CONVERT_TO_PROTON_C_RXLED
+# define D5 PAL_LINE(GPIOC, 14)
+# define B0 PAL_LINE(GPIOC, 13)
+# else
+# define D5 PAL_LINE(GPIOC, 13)
+# define B0 PAL_LINE(GPIOC, 14)
+# endif
+#else
+# define A0 PAL_LINE(GPIOA, 0)
+# define A1 PAL_LINE(GPIOA, 1)
+# define A2 PAL_LINE(GPIOA, 2)
+# define A3 PAL_LINE(GPIOA, 3)
+# define A4 PAL_LINE(GPIOA, 4)
+# define A5 PAL_LINE(GPIOA, 5)
+# define A6 PAL_LINE(GPIOA, 6)
+# define A7 PAL_LINE(GPIOA, 7)
+# define A8 PAL_LINE(GPIOA, 8)
+# define A9 PAL_LINE(GPIOA, 9)
+# define A10 PAL_LINE(GPIOA, 10)
+# define A11 PAL_LINE(GPIOA, 11)
+# define A12 PAL_LINE(GPIOA, 12)
+# define A13 PAL_LINE(GPIOA, 13)
+# define A14 PAL_LINE(GPIOA, 14)
+# define A15 PAL_LINE(GPIOA, 15)
+# define B0 PAL_LINE(GPIOB, 0)
+# define B1 PAL_LINE(GPIOB, 1)
+# define B2 PAL_LINE(GPIOB, 2)
+# define B3 PAL_LINE(GPIOB, 3)
+# define B4 PAL_LINE(GPIOB, 4)
+# define B5 PAL_LINE(GPIOB, 5)
+# define B6 PAL_LINE(GPIOB, 6)
+# define B7 PAL_LINE(GPIOB, 7)
+# define B8 PAL_LINE(GPIOB, 8)
+# define B9 PAL_LINE(GPIOB, 9)
+# define B10 PAL_LINE(GPIOB, 10)
+# define B11 PAL_LINE(GPIOB, 11)
+# define B12 PAL_LINE(GPIOB, 12)
+# define B13 PAL_LINE(GPIOB, 13)
+# define B14 PAL_LINE(GPIOB, 14)
+# define B15 PAL_LINE(GPIOB, 15)
+# define B16 PAL_LINE(GPIOB, 16)
+# define B17 PAL_LINE(GPIOB, 17)
+# define B18 PAL_LINE(GPIOB, 18)
+# define B19 PAL_LINE(GPIOB, 19)
+# define C0 PAL_LINE(GPIOC, 0)
+# define C1 PAL_LINE(GPIOC, 1)
+# define C2 PAL_LINE(GPIOC, 2)
+# define C3 PAL_LINE(GPIOC, 3)
+# define C4 PAL_LINE(GPIOC, 4)
+# define C5 PAL_LINE(GPIOC, 5)
+# define C6 PAL_LINE(GPIOC, 6)
+# define C7 PAL_LINE(GPIOC, 7)
+# define C8 PAL_LINE(GPIOC, 8)
+# define C9 PAL_LINE(GPIOC, 9)
+# define C10 PAL_LINE(GPIOC, 10)
+# define C11 PAL_LINE(GPIOC, 11)
+# define C12 PAL_LINE(GPIOC, 12)
+# define C13 PAL_LINE(GPIOC, 13)
+# define C14 PAL_LINE(GPIOC, 14)
+# define C15 PAL_LINE(GPIOC, 15)
+# define D0 PAL_LINE(GPIOD, 0)
+# define D1 PAL_LINE(GPIOD, 1)
+# define D2 PAL_LINE(GPIOD, 2)
+# define D3 PAL_LINE(GPIOD, 3)
+# define D4 PAL_LINE(GPIOD, 4)
+# define D5 PAL_LINE(GPIOD, 5)
+# define D6 PAL_LINE(GPIOD, 6)
+# define D7 PAL_LINE(GPIOD, 7)
+# define D8 PAL_LINE(GPIOD, 8)
+# define D9 PAL_LINE(GPIOD, 9)
+# define D10 PAL_LINE(GPIOD, 10)
+# define D11 PAL_LINE(GPIOD, 11)
+# define D12 PAL_LINE(GPIOD, 12)
+# define D13 PAL_LINE(GPIOD, 13)
+# define D14 PAL_LINE(GPIOD, 14)
+# define D15 PAL_LINE(GPIOD, 15)
+# define E0 PAL_LINE(GPIOE, 0)
+# define E1 PAL_LINE(GPIOE, 1)
+# define E2 PAL_LINE(GPIOE, 2)
+# define E3 PAL_LINE(GPIOE, 3)
+# define E4 PAL_LINE(GPIOE, 4)
+# define E5 PAL_LINE(GPIOE, 5)
+# define E6 PAL_LINE(GPIOE, 6)
+# define E7 PAL_LINE(GPIOE, 7)
+# define E8 PAL_LINE(GPIOE, 8)
+# define E9 PAL_LINE(GPIOE, 9)
+# define E10 PAL_LINE(GPIOE, 10)
+# define E11 PAL_LINE(GPIOE, 11)
+# define E12 PAL_LINE(GPIOE, 12)
+# define E13 PAL_LINE(GPIOE, 13)
+# define E14 PAL_LINE(GPIOE, 14)
+# define E15 PAL_LINE(GPIOE, 15)
+# define F0 PAL_LINE(GPIOF, 0)
+# define F1 PAL_LINE(GPIOF, 1)
+# define F2 PAL_LINE(GPIOF, 2)
+# define F3 PAL_LINE(GPIOF, 3)
+# define F4 PAL_LINE(GPIOF, 4)
+# define F5 PAL_LINE(GPIOF, 5)
+# define F6 PAL_LINE(GPIOF, 6)
+# define F7 PAL_LINE(GPIOF, 7)
+# define F8 PAL_LINE(GPIOF, 8)
+# define F9 PAL_LINE(GPIOF, 9)
+# define F10 PAL_LINE(GPIOF, 10)
+# define F11 PAL_LINE(GPIOF, 11)
+# define F12 PAL_LINE(GPIOF, 12)
+# define F13 PAL_LINE(GPIOF, 13)
+# define F14 PAL_LINE(GPIOF, 14)
+# define F15 PAL_LINE(GPIOF, 15)
+# define G0 PAL_LINE(GPIOG, 0)
+# define G1 PAL_LINE(GPIOG, 1)
+# define G2 PAL_LINE(GPIOG, 2)
+# define G3 PAL_LINE(GPIOG, 3)
+# define G4 PAL_LINE(GPIOG, 4)
+# define G5 PAL_LINE(GPIOG, 5)
+# define G6 PAL_LINE(GPIOG, 6)
+# define G7 PAL_LINE(GPIOG, 7)
+# define G8 PAL_LINE(GPIOG, 8)
+# define G9 PAL_LINE(GPIOG, 9)
+# define G10 PAL_LINE(GPIOG, 10)
+# define G11 PAL_LINE(GPIOG, 11)
+# define G12 PAL_LINE(GPIOG, 12)
+# define G13 PAL_LINE(GPIOG, 13)
+# define G14 PAL_LINE(GPIOG, 14)
+# define G15 PAL_LINE(GPIOG, 15)
+# define H0 PAL_LINE(GPIOH, 0)
+# define H1 PAL_LINE(GPIOH, 1)
+# define H2 PAL_LINE(GPIOH, 2)
+# define H3 PAL_LINE(GPIOH, 3)
+# define H4 PAL_LINE(GPIOH, 4)
+# define H5 PAL_LINE(GPIOH, 5)
+# define H6 PAL_LINE(GPIOH, 6)
+# define H7 PAL_LINE(GPIOH, 7)
+# define H8 PAL_LINE(GPIOH, 8)
+# define H9 PAL_LINE(GPIOH, 9)
+# define H10 PAL_LINE(GPIOH, 10)
+# define H11 PAL_LINE(GPIOH, 11)
+# define H12 PAL_LINE(GPIOH, 12)
+# define H13 PAL_LINE(GPIOH, 13)
+# define H14 PAL_LINE(GPIOH, 14)
+# define H15 PAL_LINE(GPIOH, 15)
+# define I0 PAL_LINE(GPIOI, 0)
+# define I1 PAL_LINE(GPIOI, 1)
+# define I2 PAL_LINE(GPIOI, 2)
+# define I3 PAL_LINE(GPIOI, 3)
+# define I4 PAL_LINE(GPIOI, 4)
+# define I5 PAL_LINE(GPIOI, 5)
+# define I6 PAL_LINE(GPIOI, 6)
+# define I7 PAL_LINE(GPIOI, 7)
+# define I8 PAL_LINE(GPIOI, 8)
+# define I9 PAL_LINE(GPIOI, 9)
+# define I10 PAL_LINE(GPIOI, 10)
+# define I11 PAL_LINE(GPIOI, 11)
+# define I12 PAL_LINE(GPIOI, 12)
+# define I13 PAL_LINE(GPIOI, 13)
+# define I14 PAL_LINE(GPIOI, 14)
+# define I15 PAL_LINE(GPIOI, 15)
+# define J0 PAL_LINE(GPIOJ, 0)
+# define J1 PAL_LINE(GPIOJ, 1)
+# define J2 PAL_LINE(GPIOJ, 2)
+# define J3 PAL_LINE(GPIOJ, 3)
+# define J4 PAL_LINE(GPIOJ, 4)
+# define J5 PAL_LINE(GPIOJ, 5)
+# define J6 PAL_LINE(GPIOJ, 6)
+# define J7 PAL_LINE(GPIOJ, 7)
+# define J8 PAL_LINE(GPIOJ, 8)
+# define J9 PAL_LINE(GPIOJ, 9)
+# define J10 PAL_LINE(GPIOJ, 10)
+# define J11 PAL_LINE(GPIOJ, 11)
+# define J12 PAL_LINE(GPIOJ, 12)
+# define J13 PAL_LINE(GPIOJ, 13)
+# define J14 PAL_LINE(GPIOJ, 14)
+# define J15 PAL_LINE(GPIOJ, 15)
+// Keyboards can `#define KEYBOARD_REQUIRES_GPIOK` if they need to access GPIO-K pins. These conflict with a whole
+// bunch of layout definitions, so it's intentionally left out unless absolutely required -- in that case, the
+// keyboard designer should use a different symbol when defining their layout macros.
+# ifdef KEYBOARD_REQUIRES_GPIOK
+# define K0 PAL_LINE(GPIOK, 0)
+# define K1 PAL_LINE(GPIOK, 1)
+# define K2 PAL_LINE(GPIOK, 2)
+# define K3 PAL_LINE(GPIOK, 3)
+# define K4 PAL_LINE(GPIOK, 4)
+# define K5 PAL_LINE(GPIOK, 5)
+# define K6 PAL_LINE(GPIOK, 6)
+# define K7 PAL_LINE(GPIOK, 7)
+# define K8 PAL_LINE(GPIOK, 8)
+# define K9 PAL_LINE(GPIOK, 9)
+# define K10 PAL_LINE(GPIOK, 10)
+# define K11 PAL_LINE(GPIOK, 11)
+# define K12 PAL_LINE(GPIOK, 12)
+# define K13 PAL_LINE(GPIOK, 13)
+# define K14 PAL_LINE(GPIOK, 14)
+# define K15 PAL_LINE(GPIOK, 15)
+# endif
+#endif
diff --git a/tmk_core/common/command.c b/tmk_core/common/command.c
deleted file mode 100644
index fb34ebb462..0000000000
--- a/tmk_core/common/command.c
+++ /dev/null
@@ -1,787 +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 <stdint.h>
-#include <stdbool.h>
-#include "wait.h"
-#include "keycode.h"
-#include "host.h"
-#include "keymap.h"
-#include "print.h"
-#include "debug.h"
-#include "util.h"
-#include "timer.h"
-#include "keyboard.h"
-#include "bootloader.h"
-#include "action_layer.h"
-#include "action_util.h"
-#include "eeconfig.h"
-#include "sleep_led.h"
-#include "led.h"
-#include "command.h"
-#include "quantum.h"
-#include "version.h"
-
-#ifdef BACKLIGHT_ENABLE
-# include "backlight.h"
-#endif
-
-#if defined(MOUSEKEY_ENABLE) && !defined(MK_3_SPEED)
-# include "mousekey.h"
-#endif
-
-#ifdef AUDIO_ENABLE
-# include "audio.h"
-#endif /* AUDIO_ENABLE */
-
-static bool command_common(uint8_t code);
-static void command_common_help(void);
-static void print_version(void);
-static void print_status(void);
-static bool command_console(uint8_t code);
-static void command_console_help(void);
-#if defined(MOUSEKEY_ENABLE) && !defined(MK_3_SPEED)
-static bool mousekey_console(uint8_t code);
-static void mousekey_console_help(void);
-#endif
-
-static void switch_default_layer(uint8_t layer);
-
-command_state_t command_state = ONESHOT;
-
-bool command_proc(uint8_t code) {
- switch (command_state) {
- case ONESHOT:
- if (!IS_COMMAND()) return false;
- return (command_extra(code) || command_common(code));
- break;
- case CONSOLE:
- if (IS_COMMAND())
- return (command_extra(code) || command_common(code));
- else
- return (command_console_extra(code) || command_console(code));
- break;
-#if defined(MOUSEKEY_ENABLE) && !defined(MK_3_SPEED)
- case MOUSEKEY:
- mousekey_console(code);
- break;
-#endif
- default:
- command_state = ONESHOT;
- return false;
- }
- return true;
-}
-
-/* TODO: Refactoring is needed. */
-/* This allows to define extra commands. return false when not processed. */
-bool command_extra(uint8_t code) __attribute__((weak));
-bool command_extra(uint8_t code) {
- (void)code;
- return false;
-}
-
-bool command_console_extra(uint8_t code) __attribute__((weak));
-bool command_console_extra(uint8_t code) {
- (void)code;
- return false;
-}
-
-/***********************************************************
- * Command common
- ***********************************************************/
-static void command_common_help(void) {
- print("\n\t- Magic -\n" STR(MAGIC_KEY_DEBUG) ": Debug Message Toggle\n" STR(MAGIC_KEY_DEBUG_MATRIX) ": Matrix Debug Mode Toggle - Show keypresses in matrix grid\n" STR(MAGIC_KEY_DEBUG_KBD) ": Keyboard Debug Toggle - Show keypress report\n" STR(MAGIC_KEY_DEBUG_MOUSE) ": Debug Mouse Toggle\n" STR(MAGIC_KEY_VERSION) ": Version\n" STR(MAGIC_KEY_STATUS) ": Status\n" STR(MAGIC_KEY_CONSOLE) ": Activate Console Mode\n"
-
-#if MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
- STR(MAGIC_KEY_LAYER0) ": Switch to Layer 0\n" STR(MAGIC_KEY_LAYER1) ": Switch to Layer 1\n" STR(MAGIC_KEY_LAYER2) ": Switch to Layer 2\n" STR(MAGIC_KEY_LAYER3) ": Switch to Layer 3\n" STR(MAGIC_KEY_LAYER4) ": Switch to Layer 4\n" STR(MAGIC_KEY_LAYER5) ": Switch to Layer 5\n" STR(MAGIC_KEY_LAYER6) ": Switch to Layer 6\n" STR(MAGIC_KEY_LAYER7) ": Switch to Layer 7\n" STR(MAGIC_KEY_LAYER8) ": Switch to Layer 8\n" STR(MAGIC_KEY_LAYER9) ": Switch to Layer 9\n"
-#endif
-
-#if MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
- "F1-F10: Switch to Layer 0-9 (F10 = L0)\n"
-#endif
-
-#if MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
- "0-9: Switch to Layer 0-9\n"
-#endif
-
- STR(MAGIC_KEY_LAYER0_ALT) ": Switch to Layer 0 (alternate)\n"
-
- STR(MAGIC_KEY_BOOTLOADER) ": Jump to Bootloader\n" STR(MAGIC_KEY_BOOTLOADER_ALT) ": Jump to Bootloader (alternate)\n"
-
-#ifdef KEYBOARD_LOCK_ENABLE
- STR(MAGIC_KEY_LOCK) ": Lock Keyboard\n"
-#endif
-
- STR(MAGIC_KEY_EEPROM) ": Print EEPROM Settings\n" STR(MAGIC_KEY_EEPROM_CLEAR) ": Clear EEPROM\n"
-
-#ifdef NKRO_ENABLE
- STR(MAGIC_KEY_NKRO) ": NKRO Toggle\n"
-#endif
-
-#ifdef SLEEP_LED_ENABLE
- STR(MAGIC_KEY_SLEEP_LED) ": Sleep LED Test\n"
-#endif
- );
-}
-
-static void print_version(void) {
- // print version & information
- print("\n\t- Version -\n");
- print("DESC: " STR(DESCRIPTION) "\n");
- print("VID: " STR(VENDOR_ID) "(" STR(MANUFACTURER) ") "
- "PID: " STR(PRODUCT_ID) "(" STR(PRODUCT) ") "
- "VER: " STR(DEVICE_VER) "\n");
- print("BUILD: (" __DATE__ ")\n");
-#ifndef SKIP_VERSION
-# ifdef PROTOCOL_CHIBIOS
- print("CHIBIOS: " STR(CHIBIOS_VERSION) ", CONTRIB: " STR(CHIBIOS_CONTRIB_VERSION) "\n");
-# endif
-#endif
-
- /* build options */
- print("OPTIONS:"
-
-#ifdef PROTOCOL_LUFA
- " LUFA"
-#endif
-#ifdef PROTOCOL_VUSB
- " VUSB"
-#endif
-#ifdef BOOTMAGIC_ENABLE
- " BOOTMAGIC"
-#endif
-#ifdef MOUSEKEY_ENABLE
- " MOUSEKEY"
-#endif
-#ifdef EXTRAKEY_ENABLE
- " EXTRAKEY"
-#endif
-#ifdef CONSOLE_ENABLE
- " CONSOLE"
-#endif
-#ifdef COMMAND_ENABLE
- " COMMAND"
-#endif
-#ifdef NKRO_ENABLE
- " NKRO"
-#endif
-#ifdef LTO_ENABLE
- " LTO"
-#endif
-
- " " STR(BOOTLOADER_SIZE) "\n");
-
- print("GCC: " STR(__GNUC__) "." STR(__GNUC_MINOR__) "." STR(__GNUC_PATCHLEVEL__)
-#if defined(__AVR__)
- " AVR-LIBC: " __AVR_LIBC_VERSION_STRING__ " AVR_ARCH: avr" STR(__AVR_ARCH__)
-#endif
- "\n");
-
- return;
-}
-
-static void print_status(void) {
- print("\n\t- Status -\n");
-
- print_val_hex8(host_keyboard_leds());
-#ifndef PROTOCOL_VUSB
- // these aren't set on the V-USB protocol, so we just ignore them for now
- print_val_hex8(keyboard_protocol);
- print_val_hex8(keyboard_idle);
-#endif
-#ifdef NKRO_ENABLE
- print_val_hex8(keymap_config.nkro);
-#endif
- print_val_hex32(timer_read32());
- return;
-}
-
-static void print_eeconfig(void) {
-// Print these variables if NO_PRINT or USER_PRINT are not defined.
-#if !defined(NO_PRINT) && !defined(USER_PRINT)
-
- print("default_layer: ");
- print_dec(eeconfig_read_default_layer());
- print("\n");
-
- debug_config_t dc;
- dc.raw = eeconfig_read_debug();
- print("debug_config.raw: ");
- print_hex8(dc.raw);
- print("\n");
- print(".enable: ");
- print_dec(dc.enable);
- print("\n");
- print(".matrix: ");
- print_dec(dc.matrix);
- print("\n");
- print(".keyboard: ");
- print_dec(dc.keyboard);
- print("\n");
- print(".mouse: ");
- print_dec(dc.mouse);
- print("\n");
-
- keymap_config_t kc;
- kc.raw = eeconfig_read_keymap();
- print("keymap_config.raw: ");
- print_hex8(kc.raw);
- print("\n");
- print(".swap_control_capslock: ");
- print_dec(kc.swap_control_capslock);
- print("\n");
- print(".capslock_to_control: ");
- print_dec(kc.capslock_to_control);
- print("\n");
- print(".swap_lctl_lgui: ");
- print_dec(kc.swap_lctl_lgui);
- print("\n");
- print(".swap_rctl_rgui: ");
- print_dec(kc.swap_rctl_rgui);
- print("\n");
- print(".swap_lalt_lgui: ");
- print_dec(kc.swap_lalt_lgui);
- print("\n");
- print(".swap_ralt_rgui: ");
- print_dec(kc.swap_ralt_rgui);
- print("\n");
- print(".no_gui: ");
- print_dec(kc.no_gui);
- print("\n");
- print(".swap_grave_esc: ");
- print_dec(kc.swap_grave_esc);
- print("\n");
- print(".swap_backslash_backspace: ");
- print_dec(kc.swap_backslash_backspace);
- print("\n");
- print(".nkro: ");
- print_dec(kc.nkro);
- print("\n");
-
-# ifdef BACKLIGHT_ENABLE
- backlight_config_t bc;
- bc.raw = eeconfig_read_backlight();
- print("backlight_config.raw: ");
- print_hex8(bc.raw);
- print("\n");
- print(".enable: ");
- print_dec(bc.enable);
- print("\n");
- print(".level: ");
- print_dec(bc.level);
- print("\n");
-# endif /* BACKLIGHT_ENABLE */
-
-#endif /* !NO_PRINT */
-}
-
-static bool command_common(uint8_t code) {
-#ifdef KEYBOARD_LOCK_ENABLE
- static host_driver_t *host_driver = 0;
-#endif
-
- switch (code) {
-#ifdef SLEEP_LED_ENABLE
-
- // test breathing sleep LED
- case MAGIC_KC(MAGIC_KEY_SLEEP_LED):
- print("Sleep LED Test\n");
- sleep_led_toggle();
- led_set(host_keyboard_leds());
- break;
-#endif
-
- // print stored eeprom config
- case MAGIC_KC(MAGIC_KEY_EEPROM):
- print("eeconfig:\n");
- print_eeconfig();
- break;
-
- // clear eeprom
- case MAGIC_KC(MAGIC_KEY_EEPROM_CLEAR):
- print("Clearing EEPROM\n");
- eeconfig_init();
- break;
-
-#ifdef KEYBOARD_LOCK_ENABLE
-
- // lock/unlock keyboard
- case MAGIC_KC(MAGIC_KEY_LOCK):
- if (host_get_driver()) {
- host_driver = host_get_driver();
- clear_keyboard();
- host_set_driver(0);
- print("Locked.\n");
- } else {
- host_set_driver(host_driver);
- print("Unlocked.\n");
- }
- break;
-#endif
-
- // print help
- case MAGIC_KC(MAGIC_KEY_HELP):
- case MAGIC_KC(MAGIC_KEY_HELP_ALT):
- command_common_help();
- break;
-
- // activate console
- case MAGIC_KC(MAGIC_KEY_CONSOLE):
- debug_matrix = false;
- debug_keyboard = false;
- debug_mouse = false;
- debug_enable = false;
- command_console_help();
- print("C> ");
- command_state = CONSOLE;
- break;
-
- // jump to bootloader
- case MAGIC_KC(MAGIC_KEY_BOOTLOADER):
- case MAGIC_KC(MAGIC_KEY_BOOTLOADER_ALT):
- print("\n\nJumping to bootloader... ");
- reset_keyboard();
- break;
-
- // debug toggle
- case MAGIC_KC(MAGIC_KEY_DEBUG):
- debug_enable = !debug_enable;
- if (debug_enable) {
- print("\ndebug: on\n");
- } else {
- print("\ndebug: off\n");
- debug_matrix = false;
- debug_keyboard = false;
- debug_mouse = false;
- }
- break;
-
- // debug matrix toggle
- case MAGIC_KC(MAGIC_KEY_DEBUG_MATRIX):
- debug_matrix = !debug_matrix;
- if (debug_matrix) {
- print("\nmatrix: on\n");
- debug_enable = true;
- } else {
- print("\nmatrix: off\n");
- }
- break;
-
- // debug keyboard toggle
- case MAGIC_KC(MAGIC_KEY_DEBUG_KBD):
- debug_keyboard = !debug_keyboard;
- if (debug_keyboard) {
- print("\nkeyboard: on\n");
- debug_enable = true;
- } else {
- print("\nkeyboard: off\n");
- }
- break;
-
- // debug mouse toggle
- case MAGIC_KC(MAGIC_KEY_DEBUG_MOUSE):
- debug_mouse = !debug_mouse;
- if (debug_mouse) {
- print("\nmouse: on\n");
- debug_enable = true;
- } else {
- print("\nmouse: off\n");
- }
- break;
-
- // print version
- case MAGIC_KC(MAGIC_KEY_VERSION):
- print_version();
- break;
-
- // print status
- case MAGIC_KC(MAGIC_KEY_STATUS):
- print_status();
- break;
-
-#ifdef NKRO_ENABLE
-
- // NKRO toggle
- case MAGIC_KC(MAGIC_KEY_NKRO):
- clear_keyboard(); // clear to prevent stuck keys
- keymap_config.nkro = !keymap_config.nkro;
- if (keymap_config.nkro) {
- print("NKRO: on\n");
- } else {
- print("NKRO: off\n");
- }
- break;
-#endif
-
- // switch layers
-
- case MAGIC_KC(MAGIC_KEY_LAYER0_ALT):
- switch_default_layer(0);
- break;
-
-#if MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
-
- case MAGIC_KC(MAGIC_KEY_LAYER0):
- switch_default_layer(0);
- break;
-
- case MAGIC_KC(MAGIC_KEY_LAYER1):
- switch_default_layer(1);
- break;
-
- case MAGIC_KC(MAGIC_KEY_LAYER2):
- switch_default_layer(2);
- break;
-
- case MAGIC_KC(MAGIC_KEY_LAYER3):
- switch_default_layer(3);
- break;
-
- case MAGIC_KC(MAGIC_KEY_LAYER4):
- switch_default_layer(4);
- break;
-
- case MAGIC_KC(MAGIC_KEY_LAYER5):
- switch_default_layer(5);
- break;
-
- case MAGIC_KC(MAGIC_KEY_LAYER6):
- switch_default_layer(6);
- break;
-
- case MAGIC_KC(MAGIC_KEY_LAYER7):
- switch_default_layer(7);
- break;
-
- case MAGIC_KC(MAGIC_KEY_LAYER8):
- switch_default_layer(8);
- break;
-
- case MAGIC_KC(MAGIC_KEY_LAYER9):
- switch_default_layer(9);
- break;
-#endif
-
-#if MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
-
- case KC_F1 ... KC_F9:
- switch_default_layer((code - KC_F1) + 1);
- break;
- case KC_F10:
- switch_default_layer(0);
- break;
-#endif
-
-#if MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
-
- case KC_1 ... KC_9:
- switch_default_layer((code - KC_1) + 1);
- break;
- case KC_0:
- switch_default_layer(0);
- break;
-#endif
-
- default:
- print("?");
- return false;
- }
- return true;
-}
-
-/***********************************************************
- * Command console
- ***********************************************************/
-static void command_console_help(void) {
- print("\n\t- Console -\n"
- "ESC/q: quit\n"
-#ifdef MOUSEKEY_ENABLE
- "m: mousekey\n"
-#endif
- );
-}
-
-static bool command_console(uint8_t code) {
- switch (code) {
- case KC_H:
- case KC_SLASH: /* ? */
- command_console_help();
- break;
- case KC_Q:
- case KC_ESC:
- command_state = ONESHOT;
- return false;
-#if defined(MOUSEKEY_ENABLE) && !defined(MK_3_SPEED)
- case KC_M:
- mousekey_console_help();
- print("M> ");
- command_state = MOUSEKEY;
- return true;
-#endif
- default:
- print("?");
- return false;
- }
- print("C> ");
- return true;
-}
-
-#if defined(MOUSEKEY_ENABLE) && !defined(MK_3_SPEED)
-/***********************************************************
- * Mousekey console
- ***********************************************************/
-static uint8_t mousekey_param = 0;
-
-static void mousekey_param_print(void) {
-// Print these variables if NO_PRINT or USER_PRINT are not defined.
-# if !defined(NO_PRINT) && !defined(USER_PRINT)
- print("\n\t- Values -\n");
- print("1: delay(*10ms): ");
- pdec(mk_delay);
- print("\n");
- print("2: interval(ms): ");
- pdec(mk_interval);
- print("\n");
- print("3: max_speed: ");
- pdec(mk_max_speed);
- print("\n");
- print("4: time_to_max: ");
- pdec(mk_time_to_max);
- print("\n");
- print("5: wheel_max_speed: ");
- pdec(mk_wheel_max_speed);
- print("\n");
- print("6: wheel_time_to_max: ");
- pdec(mk_wheel_time_to_max);
- print("\n");
-# endif /* !NO_PRINT */
-}
-
-//#define PRINT_SET_VAL(v) print(#v " = "); print_dec(v); print("\n");
-# define PRINT_SET_VAL(v) xprintf(# v " = %d\n", (v))
-static void mousekey_param_inc(uint8_t param, uint8_t inc) {
- switch (param) {
- case 1:
- if (mk_delay + inc < UINT8_MAX)
- mk_delay += inc;
- else
- mk_delay = UINT8_MAX;
- PRINT_SET_VAL(mk_delay);
- break;
- case 2:
- if (mk_interval + inc < UINT8_MAX)
- mk_interval += inc;
- else
- mk_interval = UINT8_MAX;
- PRINT_SET_VAL(mk_interval);
- break;
- case 3:
- if (mk_max_speed + inc < UINT8_MAX)
- mk_max_speed += inc;
- else
- mk_max_speed = UINT8_MAX;
- PRINT_SET_VAL(mk_max_speed);
- break;
- case 4:
- if (mk_time_to_max + inc < UINT8_MAX)
- mk_time_to_max += inc;
- else
- mk_time_to_max = UINT8_MAX;
- PRINT_SET_VAL(mk_time_to_max);
- break;
- case 5:
- if (mk_wheel_max_speed + inc < UINT8_MAX)
- mk_wheel_max_speed += inc;
- else
- mk_wheel_max_speed = UINT8_MAX;
- PRINT_SET_VAL(mk_wheel_max_speed);
- break;
- case 6:
- if (mk_wheel_time_to_max + inc < UINT8_MAX)
- mk_wheel_time_to_max += inc;
- else
- mk_wheel_time_to_max = UINT8_MAX;
- PRINT_SET_VAL(mk_wheel_time_to_max);
- break;
- }
-}
-
-static void mousekey_param_dec(uint8_t param, uint8_t dec) {
- switch (param) {
- case 1:
- if (mk_delay > dec)
- mk_delay -= dec;
- else
- mk_delay = 0;
- PRINT_SET_VAL(mk_delay);
- break;
- case 2:
- if (mk_interval > dec)
- mk_interval -= dec;
- else
- mk_interval = 0;
- PRINT_SET_VAL(mk_interval);
- break;
- case 3:
- if (mk_max_speed > dec)
- mk_max_speed -= dec;
- else
- mk_max_speed = 0;
- PRINT_SET_VAL(mk_max_speed);
- break;
- case 4:
- if (mk_time_to_max > dec)
- mk_time_to_max -= dec;
- else
- mk_time_to_max = 0;
- PRINT_SET_VAL(mk_time_to_max);
- break;
- case 5:
- if (mk_wheel_max_speed > dec)
- mk_wheel_max_speed -= dec;
- else
- mk_wheel_max_speed = 0;
- PRINT_SET_VAL(mk_wheel_max_speed);
- break;
- case 6:
- if (mk_wheel_time_to_max > dec)
- mk_wheel_time_to_max -= dec;
- else
- mk_wheel_time_to_max = 0;
- PRINT_SET_VAL(mk_wheel_time_to_max);
- break;
- }
-}
-
-static void mousekey_console_help(void) {
- print("\n\t- Mousekey -\n"
- "ESC/q: quit\n"
- "1: delay(*10ms)\n"
- "2: interval(ms)\n"
- "3: max_speed\n"
- "4: time_to_max\n"
- "5: wheel_max_speed\n"
- "6: wheel_time_to_max\n"
- "\n"
- "p: print values\n"
- "d: set defaults\n"
- "up: +1\n"
- "down: -1\n"
- "pgup: +10\n"
- "pgdown: -10\n"
- "\n"
- "speed = delta * max_speed * (repeat / time_to_max)\n");
- xprintf("where delta: cursor=%d, wheel=%d\n"
- "See http://en.wikipedia.org/wiki/Mouse_keys\n",
- MOUSEKEY_MOVE_DELTA, MOUSEKEY_WHEEL_DELTA);
-}
-
-static bool mousekey_console(uint8_t code) {
- switch (code) {
- case KC_H:
- case KC_SLASH: /* ? */
- mousekey_console_help();
- break;
- case KC_Q:
- case KC_ESC:
- if (mousekey_param) {
- mousekey_param = 0;
- } else {
- print("C> ");
- command_state = CONSOLE;
- return false;
- }
- break;
- case KC_P:
- mousekey_param_print();
- break;
- case KC_1:
- case KC_2:
- case KC_3:
- case KC_4:
- case KC_5:
- case KC_6:
- mousekey_param = numkey2num(code);
- break;
- case KC_UP:
- mousekey_param_inc(mousekey_param, 1);
- break;
- case KC_DOWN:
- mousekey_param_dec(mousekey_param, 1);
- break;
- case KC_PGUP:
- mousekey_param_inc(mousekey_param, 10);
- break;
- case KC_PGDN:
- mousekey_param_dec(mousekey_param, 10);
- break;
- case KC_D:
- mk_delay = MOUSEKEY_DELAY / 10;
- mk_interval = MOUSEKEY_INTERVAL;
- mk_max_speed = MOUSEKEY_MAX_SPEED;
- mk_time_to_max = MOUSEKEY_TIME_TO_MAX;
- mk_wheel_max_speed = MOUSEKEY_WHEEL_MAX_SPEED;
- mk_wheel_time_to_max = MOUSEKEY_WHEEL_TIME_TO_MAX;
- print("set default\n");
- break;
- default:
- print("?");
- return false;
- }
- if (mousekey_param) {
- xprintf("M%d> ", mousekey_param);
- } else {
- print("M>");
- }
- return true;
-}
-#endif
-
-/***********************************************************
- * Utilities
- ***********************************************************/
-uint8_t numkey2num(uint8_t code) {
- switch (code) {
- case KC_1:
- return 1;
- case KC_2:
- return 2;
- case KC_3:
- return 3;
- case KC_4:
- return 4;
- case KC_5:
- return 5;
- case KC_6:
- return 6;
- case KC_7:
- return 7;
- case KC_8:
- return 8;
- case KC_9:
- return 9;
- case KC_0:
- return 0;
- }
- return 0;
-}
-
-static void switch_default_layer(uint8_t layer) {
- xprintf("L%d\n", layer);
- default_layer_set(1UL << layer);
- clear_keyboard();
-}
diff --git a/tmk_core/common/command.h b/tmk_core/common/command.h
deleted file mode 100644
index 4f77be085c..0000000000
--- a/tmk_core/common/command.h
+++ /dev/null
@@ -1,163 +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
-
-/* FIXME: Add doxygen comments for the behavioral defines in here. */
-
-/* TODO: Refactoring */
-typedef enum { ONESHOT, CONSOLE, MOUSEKEY } command_state_t;
-extern command_state_t command_state;
-
-/* This allows to extend commands. Return false when command is not processed. */
-bool command_extra(uint8_t code);
-bool command_console_extra(uint8_t code);
-
-#ifdef COMMAND_ENABLE
-uint8_t numkey2num(uint8_t code);
-bool command_proc(uint8_t code);
-#else
-# define command_proc(code) false
-#endif
-
-#ifndef IS_COMMAND
-# define IS_COMMAND() (get_mods() == MOD_MASK_SHIFT)
-#endif
-
-#ifndef MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
-# define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true
-#endif
-
-#ifndef MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
-# define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true
-#endif
-
-#ifndef MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
-# define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
-#endif
-
-#ifndef MAGIC_KEY_HELP
-# define MAGIC_KEY_HELP H
-#endif
-
-#ifndef MAGIC_KEY_HELP_ALT
-# define MAGIC_KEY_HELP_ALT SLASH
-#endif
-
-#ifndef MAGIC_KEY_DEBUG
-# define MAGIC_KEY_DEBUG D
-#endif
-
-#ifndef MAGIC_KEY_DEBUG_MATRIX
-# define MAGIC_KEY_DEBUG_MATRIX X
-#endif
-
-#ifndef MAGIC_KEY_DEBUG_KBD
-# define MAGIC_KEY_DEBUG_KBD K
-#endif
-
-#ifndef MAGIC_KEY_DEBUG_MOUSE
-# define MAGIC_KEY_DEBUG_MOUSE M
-#endif
-
-#ifndef MAGIC_KEY_VERSION
-# define MAGIC_KEY_VERSION V
-#endif
-
-#ifndef MAGIC_KEY_STATUS
-# define MAGIC_KEY_STATUS S
-#endif
-
-#ifndef MAGIC_KEY_CONSOLE
-# define MAGIC_KEY_CONSOLE C
-#endif
-
-#ifndef MAGIC_KEY_LAYER0
-# define MAGIC_KEY_LAYER0 0
-#endif
-
-#ifndef MAGIC_KEY_LAYER0_ALT
-# define MAGIC_KEY_LAYER0_ALT GRAVE
-#endif
-
-#ifndef MAGIC_KEY_LAYER1
-# define MAGIC_KEY_LAYER1 1
-#endif
-
-#ifndef MAGIC_KEY_LAYER2
-# define MAGIC_KEY_LAYER2 2
-#endif
-
-#ifndef MAGIC_KEY_LAYER3
-# define MAGIC_KEY_LAYER3 3
-#endif
-
-#ifndef MAGIC_KEY_LAYER4
-# define MAGIC_KEY_LAYER4 4
-#endif
-
-#ifndef MAGIC_KEY_LAYER5
-# define MAGIC_KEY_LAYER5 5
-#endif
-
-#ifndef MAGIC_KEY_LAYER6
-# define MAGIC_KEY_LAYER6 6
-#endif
-
-#ifndef MAGIC_KEY_LAYER7
-# define MAGIC_KEY_LAYER7 7
-#endif
-
-#ifndef MAGIC_KEY_LAYER8
-# define MAGIC_KEY_LAYER8 8
-#endif
-
-#ifndef MAGIC_KEY_LAYER9
-# define MAGIC_KEY_LAYER9 9
-#endif
-
-#ifndef MAGIC_KEY_BOOTLOADER
-# define MAGIC_KEY_BOOTLOADER B
-#endif
-
-#ifndef MAGIC_KEY_BOOTLOADER_ALT
-# define MAGIC_KEY_BOOTLOADER_ALT ESC
-#endif
-
-#ifndef MAGIC_KEY_LOCK
-# define MAGIC_KEY_LOCK CAPS
-#endif
-
-#ifndef MAGIC_KEY_EEPROM
-# define MAGIC_KEY_EEPROM E
-#endif
-
-#ifndef MAGIC_KEY_EEPROM_CLEAR
-# define MAGIC_KEY_EEPROM_CLEAR BSPACE
-#endif
-
-#ifndef MAGIC_KEY_NKRO
-# define MAGIC_KEY_NKRO N
-#endif
-
-#ifndef MAGIC_KEY_SLEEP_LED
-# define MAGIC_KEY_SLEEP_LED Z
-
-#endif
-
-#define XMAGIC_KC(key) KC_##key
-#define MAGIC_KC(key) XMAGIC_KC(key)
diff --git a/tmk_core/common/debug.c b/tmk_core/common/debug.c
index bea96dfc14..ea62deaa8c 100644
--- a/tmk_core/common/debug.c
+++ b/tmk_core/common/debug.c
@@ -1,24 +1,25 @@
-#include <stdbool.h>
-#include "debug.h"
+/*
+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.
-#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+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 = {
-/* GCC Bug 10676 - Using unnamed fields in initializers
- * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10676 */
-#if GCC_VERSION >= 40600
- .enable = false,
- .matrix = false,
- .keyboard = false,
- .mouse = false,
- .reserved = 0
-#else
- {
- false, // .enable
- false, // .matrix
- false, // .keyboard
- false, // .mouse
- 0 // .reserved
- }
-#endif
+ .enable = false, //
+ .matrix = false, //
+ .keyboard = false, //
+ .mouse = false, //
+ .reserved = 0 //
};
diff --git a/tmk_core/common/eeconfig.c b/tmk_core/common/eeconfig.c
index 9bdf926a5a..60b2dcb7e7 100644
--- a/tmk_core/common/eeconfig.c
+++ b/tmk_core/common/eeconfig.c
@@ -6,6 +6,7 @@
#ifdef ORYX_ENABLE
# include "oryx.h"
#endif
+
#ifdef STM32_EEPROM_ENABLE
# include <hal.h>
# include "eeprom_stm32.h"
@@ -60,19 +61,18 @@ void eeconfig_init_quantum(void) {
eeprom_update_byte(EECONFIG_VELOCIKEY, 0);
eeprom_update_dword(EECONFIG_RGB_MATRIX, 0);
eeprom_update_byte(EECONFIG_RGB_MATRIX_SPEED, 0);
-
+#ifdef ORYX_ENABLE
+ eeconfig_init_oryx();
+#endif
// TODO: Remove once ARM has a way to configure EECONFIG_HANDEDNESS
// within the emulated eeprom via dfu-util or another tool
#if defined INIT_EE_HANDS_LEFT
- #pragma message "Faking EE_HANDS for left hand"
+# pragma message "Faking EE_HANDS for left hand"
eeprom_update_byte(EECONFIG_HANDEDNESS, 1);
#elif defined INIT_EE_HANDS_RIGHT
- #pragma message "Faking EE_HANDS for right hand"
+# pragma message "Faking EE_HANDS for right hand"
eeprom_update_byte(EECONFIG_HANDEDNESS, 0);
#endif
-#ifdef ORYX_ENABLE
- eeconfig_init_oryx();
-#endif
#if defined(HAPTIC_ENABLE)
haptic_reset();
diff --git a/tmk_core/common/eeconfig.h b/tmk_core/common/eeconfig.h
index 95e9523662..86b9e6f99b 100644
--- a/tmk_core/common/eeconfig.h
+++ b/tmk_core/common/eeconfig.h
@@ -21,7 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdbool.h>
#ifndef EECONFIG_MAGIC_NUMBER
-# define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEEF
+# define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEEB // When changing, decrement this value to avoid future re-init issues
#endif
#define EECONFIG_MAGIC_NUMBER_OFF (uint16_t)0xFFFF
diff --git a/tmk_core/common/gpio.h b/tmk_core/common/gpio.h
new file mode 100644
index 0000000000..b47f6f8e43
--- /dev/null
+++ b/tmk_core/common/gpio.h
@@ -0,0 +1,22 @@
+/* Copyright 2021 QMK
+ *
+ * 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 3 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 "pin_defs.h"
+
+#if __has_include_next("gpio.h")
+# include_next "gpio.h" /* Include the platforms gpio.h */
+#endif \ No newline at end of file
diff --git a/tmk_core/common/host.c b/tmk_core/common/host.c
index 713b0d9456..e7d92cfac6 100644
--- a/tmk_core/common/host.c
+++ b/tmk_core/common/host.c
@@ -41,7 +41,7 @@ uint8_t host_keyboard_leds(void) {
}
led_t host_keyboard_led_state(void) {
- if (!driver) return (led_t) {0};
+ if (!driver) return (led_t){0};
return (led_t)((*driver->keyboard_leds)());
}
diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c
index 0932a1d21b..ce3255c069 100644
--- a/tmk_core/common/keyboard.c
+++ b/tmk_core/common/keyboard.c
@@ -23,6 +23,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "led.h"
#include "keycode.h"
#include "timer.h"
+#include "sync_timer.h"
#include "print.h"
#include "debug.h"
#include "command.h"
@@ -53,15 +54,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifdef RGBLIGHT_ENABLE
# include "rgblight.h"
#endif
+#ifdef RGB_MATRIX_ENABLE
+# include "rgb_matrix.h"
+#endif
#ifdef ENCODER_ENABLE
# include "encoder.h"
#endif
#ifdef STENO_ENABLE
# include "process_steno.h"
#endif
-#ifdef FAUXCLICKY_ENABLE
-# include "fauxclicky.h"
-#endif
#ifdef SERIAL_LINK_ENABLE
# include "serial_link/system/serial_link.h"
#endif
@@ -96,10 +97,24 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# include "dip_switch.h"
#endif
+static uint32_t last_input_modification_time = 0;
+uint32_t last_input_activity_time(void) { return last_input_modification_time; }
+uint32_t last_input_activity_elapsed(void) { return timer_elapsed32(last_input_modification_time); }
+
+static uint32_t last_matrix_modification_time = 0;
+uint32_t last_matrix_activity_time(void) { return last_matrix_modification_time; }
+uint32_t last_matrix_activity_elapsed(void) { return timer_elapsed32(last_matrix_modification_time); }
+void last_matrix_activity_trigger(void) { last_matrix_modification_time = last_input_modification_time = timer_read32(); }
+
+static uint32_t last_encoder_modification_time = 0;
+uint32_t last_encoder_activity_time(void) { return last_encoder_modification_time; }
+uint32_t last_encoder_activity_elapsed(void) { return timer_elapsed32(last_encoder_modification_time); }
+void last_encoder_activity_trigger(void) { last_encoder_modification_time = last_input_modification_time = timer_read32(); }
+
// Only enable this if console is enabled to print to
#if defined(DEBUG_MATRIX_SCAN_RATE)
-static uint32_t matrix_timer = 0;
-static uint32_t matrix_scan_count = 0;
+static uint32_t matrix_timer = 0;
+static uint32_t matrix_scan_count = 0;
static uint32_t last_matrix_scan_count = 0;
void matrix_scan_perf_task(void) {
@@ -108,17 +123,15 @@ void matrix_scan_perf_task(void) {
uint32_t timer_now = timer_read32();
if (TIMER_DIFF_32(timer_now, matrix_timer) > 1000) {
# if defined(CONSOLE_ENABLE)
- dprintf("matrix scan frequency: %d\n", matrix_scan_count);
+ dprintf("matrix scan frequency: %lu\n", matrix_scan_count);
# endif
last_matrix_scan_count = matrix_scan_count;
- matrix_timer = timer_now;
- matrix_scan_count = 0;
+ matrix_timer = timer_now;
+ matrix_scan_count = 0;
}
}
-uint32_t get_matrix_scan_rate(void) {
- return last_matrix_scan_count;
-}
+uint32_t get_matrix_scan_rate(void) { return last_matrix_scan_count; }
#else
# define matrix_scan_perf_task()
#endif
@@ -173,6 +186,9 @@ void disable_jtag(void) {
#if (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
MCUCR |= _BV(JTD);
MCUCR |= _BV(JTD);
+#elif defined(__AVR_ATmega32A__)
+ MCUCSR |= _BV(JTD);
+ MCUCSR |= _BV(JTD);
#endif
}
@@ -213,7 +229,10 @@ __attribute__((weak)) void keyboard_post_init_kb(void) { keyboard_post_init_user
* FIXME: needs doc
*/
void keyboard_setup(void) {
+#ifndef NO_JTAG_DISABLE
disable_jtag();
+#endif
+ print_set_sendchar(sendchar);
matrix_setup();
keyboard_pre_init_kb();
}
@@ -257,6 +276,7 @@ __attribute__((weak)) void housekeeping_task_user(void) {}
*/
void keyboard_init(void) {
timer_init();
+ sync_timer_init();
matrix_init();
#ifdef VIA_ENABLE
via_init();
@@ -293,9 +313,6 @@ void keyboard_init(void) {
#ifdef STENO_ENABLE
steno_init();
#endif
-#ifdef FAUXCLICKY_ENABLE
- fauxclicky_init();
-#endif
#ifdef POINTING_DEVICE_ENABLE
pointing_device_init();
#endif
@@ -314,6 +331,17 @@ void keyboard_init(void) {
keyboard_post_init_kb(); /* Always keep this last */
}
+/** \brief key_event_task
+ *
+ * This function is responsible for calling into other systems when they need to respond to electrical switch press events.
+ * This is differnet than keycode events as no layer processing, or filtering occurs.
+ */
+void switch_events(uint8_t row, uint8_t col, bool pressed) {
+#if defined(RGB_MATRIX_ENABLE)
+ process_rgb_matrix(row, col, pressed);
+#endif
+}
+
/** \brief Keyboard task: Do keyboard routine jobs
*
* Do routine keyboard jobs:
@@ -334,42 +362,45 @@ void keyboard_task(void) {
#ifdef QMK_KEYS_PER_SCAN
uint8_t keys_processed = 0;
#endif
+#ifdef ENCODER_ENABLE
+ bool encoders_changed = false;
+#endif
housekeeping_task_kb();
housekeeping_task_user();
-#if defined(OLED_DRIVER_ENABLE) && !defined(OLED_DISABLE_TIMEOUT)
- uint8_t ret = matrix_scan();
-#else
- matrix_scan();
-#endif
+ uint8_t matrix_changed = matrix_scan();
+ if (matrix_changed) last_matrix_activity_trigger();
- if (should_process_keypress()) {
- for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
- matrix_row = matrix_get_row(r);
- matrix_change = matrix_row ^ matrix_prev[r];
- if (matrix_change) {
+ for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
+ matrix_row = matrix_get_row(r);
+ matrix_change = matrix_row ^ matrix_prev[r];
+ if (matrix_change) {
#ifdef MATRIX_HAS_GHOST
- if (has_ghost_in_row(r, matrix_row)) {
- continue;
- }
+ if (has_ghost_in_row(r, matrix_row)) {
+ continue;
+ }
#endif
- if (debug_matrix) matrix_print();
- matrix_row_t col_mask = 1;
- for (uint8_t c = 0; c < MATRIX_COLS; c++, col_mask <<= 1) {
- if (matrix_change & col_mask) {
+ if (debug_matrix) matrix_print();
+ matrix_row_t col_mask = 1;
+ for (uint8_t c = 0; c < MATRIX_COLS; c++, col_mask <<= 1) {
+ if (matrix_change & col_mask) {
+ if (should_process_keypress()) {
action_exec((keyevent_t){
.key = (keypos_t){.row = r, .col = c}, .pressed = (matrix_row & col_mask), .time = (timer_read() | 1) /* time should not be 0 */
});
- // record a processed key
- matrix_prev[r] ^= col_mask;
+ }
+ // record a processed key
+ matrix_prev[r] ^= col_mask;
+
+ switch_events(r, c, (matrix_row & col_mask));
+
#ifdef QMK_KEYS_PER_SCAN
- // only jump out if we have processed "enough" keys.
- if (++keys_processed >= QMK_KEYS_PER_SCAN)
+ // only jump out if we have processed "enough" keys.
+ if (++keys_processed >= QMK_KEYS_PER_SCAN)
#endif
- // process a key per task call
- goto MATRIX_LOOP_END;
- }
+ // process a key per task call
+ goto MATRIX_LOOP_END;
}
}
}
@@ -391,6 +422,10 @@ MATRIX_LOOP_END:
rgblight_task();
#endif
+#ifdef RGB_MATRIX_ENABLE
+ rgb_matrix_task();
+#endif
+
#if defined(BACKLIGHT_ENABLE)
# if defined(BACKLIGHT_PIN) || defined(BACKLIGHT_PINS)
backlight_task();
@@ -398,7 +433,8 @@ MATRIX_LOOP_END:
#endif
#ifdef ENCODER_ENABLE
- encoder_read();
+ encoders_changed = encoder_read();
+ if (encoders_changed) last_encoder_activity_trigger();
#endif
#ifdef QWIIC_ENABLE
@@ -408,8 +444,12 @@ MATRIX_LOOP_END:
#ifdef OLED_DRIVER_ENABLE
oled_task();
# ifndef OLED_DISABLE_TIMEOUT
- // Wake up oled if user is using those fabulous keys!
- if (ret) oled_on();
+ // Wake up oled if user is using those fabulous keys or spinning those encoders!
+# ifdef ENCODER_ENABLE
+ if (matrix_changed || encoders_changed) oled_on();
+# else
+ if (matrix_changed) oled_on();
+# endif
# endif
#endif
diff --git a/tmk_core/common/keyboard.h b/tmk_core/common/keyboard.h
index f330854fba..eaf74bac58 100644
--- a/tmk_core/common/keyboard.h
+++ b/tmk_core/common/keyboard.h
@@ -52,8 +52,6 @@ static inline bool IS_RELEASED(keyevent_t event) { return (!IS_NOEVENT(event) &&
#define TICK \
(keyevent_t) { .key = (keypos_t){.row = 255, .col = 255}, .pressed = false, .time = (timer_read() | 1) }
-void disable_jtag(void);
-
/* it runs once at early stage of startup before keyboard_init. */
void keyboard_setup(void);
/* it runs once after initializing host side protocol, debug and MCU peripherals. */
@@ -75,6 +73,15 @@ void keyboard_post_init_user(void);
void housekeeping_task_kb(void);
void housekeeping_task_user(void);
+uint32_t last_input_activity_time(void); // Timestamp of the last matrix or encoder activity
+uint32_t last_input_activity_elapsed(void); // Number of milliseconds since the last matrix or encoder activity
+
+uint32_t last_matrix_activity_time(void); // Timestamp of the last matrix activity
+uint32_t last_matrix_activity_elapsed(void); // Number of milliseconds since the last matrix activity
+
+uint32_t last_encoder_activity_time(void); // Timestamp of the last encoder activity
+uint32_t last_encoder_activity_elapsed(void); // Number of milliseconds since the last encoder activity
+
uint32_t get_matrix_scan_rate(void);
#ifdef __cplusplus
diff --git a/tmk_core/common/keycode.h b/tmk_core/common/keycode.h
index d35e44d8dc..8facabd818 100644
--- a/tmk_core/common/keycode.h
+++ b/tmk_core/common/keycode.h
@@ -39,7 +39,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2)
#define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT)
-#define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN5)
+#define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN8)
#define IS_MOUSEKEY_WHEEL(code) (KC_MS_WH_UP <= (code) && (code) <= KC_MS_WH_RIGHT)
#define IS_MOUSEKEY_ACCEL(code) (KC_MS_ACCEL0 <= (code) && (code) <= KC_MS_ACCEL2)
@@ -205,6 +205,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define KC_BTN3 KC_MS_BTN3
#define KC_BTN4 KC_MS_BTN4
#define KC_BTN5 KC_MS_BTN5
+#define KC_BTN6 KC_MS_BTN6
+#define KC_BTN7 KC_MS_BTN7
+#define KC_BTN8 KC_MS_BTN8
#define KC_WH_U KC_MS_WH_UP
#define KC_WH_D KC_MS_WH_DOWN
#define KC_WH_L KC_MS_WH_LEFT
@@ -520,16 +523,29 @@ enum internal_special_keycodes {
};
enum mouse_keys {
- /* Mouse Buttons */
+/* Mouse Buttons */
+#ifdef VIA_ENABLE
KC_MS_UP = 0xF0,
+#else
+ KC_MS_UP = 0xED,
+#endif
KC_MS_DOWN,
KC_MS_LEFT,
- KC_MS_RIGHT,
+ KC_MS_RIGHT, // 0xF0
KC_MS_BTN1,
KC_MS_BTN2,
KC_MS_BTN3,
KC_MS_BTN4,
KC_MS_BTN5,
+#ifdef VIA_ENABLE
+ KC_MS_BTN6 = KC_MS_BTN5,
+ KC_MS_BTN7 = KC_MS_BTN5,
+ KC_MS_BTN8 = KC_MS_BTN5,
+#else
+ KC_MS_BTN6,
+ KC_MS_BTN7,
+ KC_MS_BTN8,
+#endif
/* Mouse Wheel */
KC_MS_WH_UP,
@@ -540,5 +556,5 @@ enum mouse_keys {
/* Acceleration */
KC_MS_ACCEL0,
KC_MS_ACCEL1,
- KC_MS_ACCEL2
+ KC_MS_ACCEL2 // 0xFF
};
diff --git a/tmk_core/common/led.h b/tmk_core/common/led.h
deleted file mode 100644
index f9b2229c36..0000000000
--- a/tmk_core/common/led.h
+++ /dev/null
@@ -1,54 +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>
-#include <stdbool.h>
-
-/* FIXME: Add doxygen comments here. */
-
-/* keyboard LEDs */
-#define USB_LED_NUM_LOCK 0
-#define USB_LED_CAPS_LOCK 1
-#define USB_LED_SCROLL_LOCK 2
-#define USB_LED_COMPOSE 3
-#define USB_LED_KANA 4
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef union {
- uint8_t raw;
- struct {
- bool num_lock : 1;
- bool caps_lock : 1;
- bool scroll_lock : 1;
- bool compose : 1;
- bool kana : 1;
- uint8_t reserved : 3;
- };
-} led_t;
-
-void led_set(uint8_t usb_led);
-
-void led_init_ports(void);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/tmk_core/common/lib_printf.mk b/tmk_core/common/lib_printf.mk
new file mode 100644
index 0000000000..10d2d8468d
--- /dev/null
+++ b/tmk_core/common/lib_printf.mk
@@ -0,0 +1,9 @@
+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/matrix.h b/tmk_core/common/matrix.h
deleted file mode 100644
index b570227a31..0000000000
--- a/tmk_core/common/matrix.h
+++ /dev/null
@@ -1,76 +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>
-#include <stdbool.h>
-
-#if (MATRIX_COLS <= 8)
-typedef uint8_t matrix_row_t;
-#elif (MATRIX_COLS <= 16)
-typedef uint16_t matrix_row_t;
-#elif (MATRIX_COLS <= 32)
-typedef uint32_t matrix_row_t;
-#else
-# error "MATRIX_COLS: invalid value"
-#endif
-
-#define MATRIX_ROW_SHIFTER ((matrix_row_t)1)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* number of matrix rows */
-uint8_t matrix_rows(void);
-/* number of matrix columns */
-uint8_t matrix_cols(void);
-/* should be called at early stage of startup before matrix_init.(optional) */
-void matrix_setup(void);
-/* intialize matrix for scaning. */
-void matrix_init(void);
-/* scan all key states on matrix */
-uint8_t matrix_scan(void);
-/* whether modified from previous scan. used after matrix_scan. */
-bool matrix_is_modified(void) __attribute__((deprecated));
-/* whether a switch is on */
-bool matrix_is_on(uint8_t row, uint8_t col);
-/* matrix state on row */
-matrix_row_t matrix_get_row(uint8_t row);
-/* print matrix for debug */
-void matrix_print(void);
-/* delay between changing matrix pin state and reading values */
-void matrix_io_delay(void);
-
-/* power control */
-void matrix_power_up(void);
-void matrix_power_down(void);
-
-/* executes code for Quantum */
-void matrix_init_quantum(void);
-void matrix_scan_quantum(void);
-
-void matrix_init_kb(void);
-void matrix_scan_kb(void);
-
-void matrix_init_user(void);
-void matrix_scan_user(void);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/tmk_core/common/mousekey.c b/tmk_core/common/mousekey.c
deleted file mode 100644
index ef18bcf1a8..0000000000
--- a/tmk_core/common/mousekey.c
+++ /dev/null
@@ -1,446 +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 <stdint.h>
-#include "keycode.h"
-#include "host.h"
-#include "timer.h"
-#include "print.h"
-#include "debug.h"
-#include "mousekey.h"
-
-inline int8_t times_inv_sqrt2(int8_t x) {
- // 181/256 is pretty close to 1/sqrt(2)
- // 0.70703125 0.707106781
- // 1 too small for x=99 and x=198
- // This ends up being a mult and discard lower 8 bits
- return (x * 181) >> 8;
-}
-
-static report_mouse_t mouse_report = {0};
-static void mousekey_debug(void);
-static uint8_t mousekey_accel = 0;
-static uint8_t mousekey_repeat = 0;
-static uint8_t mousekey_wheel_repeat = 0;
-
-#ifndef MK_3_SPEED
-
-static uint16_t last_timer_c = 0;
-static uint16_t last_timer_w = 0;
-
-/*
- * Mouse keys acceleration algorithm
- * http://en.wikipedia.org/wiki/Mouse_keys
- *
- * speed = delta * max_speed * (repeat / time_to_max)**((1000+curve)/1000)
- */
-/* milliseconds between the initial key press and first repeated motion event (0-2550) */
-uint8_t mk_delay = MOUSEKEY_DELAY / 10;
-/* milliseconds between repeated motion events (0-255) */
-uint8_t mk_interval = MOUSEKEY_INTERVAL;
-/* steady speed (in action_delta units) applied each event (0-255) */
-uint8_t mk_max_speed = MOUSEKEY_MAX_SPEED;
-/* number of events (count) accelerating to steady speed (0-255) */
-uint8_t mk_time_to_max = MOUSEKEY_TIME_TO_MAX;
-/* ramp used to reach maximum pointer speed (NOT SUPPORTED) */
-// int8_t mk_curve = 0;
-/* wheel params */
-/* milliseconds between the initial key press and first repeated motion event (0-2550) */
-uint8_t mk_wheel_delay = MOUSEKEY_WHEEL_DELAY / 10;
-/* milliseconds between repeated motion events (0-255) */
-uint8_t mk_wheel_interval = MOUSEKEY_WHEEL_INTERVAL;
-uint8_t mk_wheel_max_speed = MOUSEKEY_WHEEL_MAX_SPEED;
-uint8_t mk_wheel_time_to_max = MOUSEKEY_WHEEL_TIME_TO_MAX;
-
-# ifndef MK_COMBINED
-
-static uint8_t move_unit(void) {
- uint16_t unit;
- if (mousekey_accel & (1 << 0)) {
- unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed) / 4;
- } else if (mousekey_accel & (1 << 1)) {
- unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed) / 2;
- } else if (mousekey_accel & (1 << 2)) {
- unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed);
- } else if (mousekey_repeat == 0) {
- unit = MOUSEKEY_MOVE_DELTA;
- } else if (mousekey_repeat >= mk_time_to_max) {
- unit = MOUSEKEY_MOVE_DELTA * mk_max_speed;
- } else {
- unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed * mousekey_repeat) / mk_time_to_max;
- }
- return (unit > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : (unit == 0 ? 1 : unit));
-}
-
-static uint8_t wheel_unit(void) {
- uint16_t unit;
- if (mousekey_accel & (1 << 0)) {
- unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed) / 4;
- } else if (mousekey_accel & (1 << 1)) {
- unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed) / 2;
- } else if (mousekey_accel & (1 << 2)) {
- unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed);
- } else if (mousekey_wheel_repeat == 0) {
- unit = MOUSEKEY_WHEEL_DELTA;
- } else if (mousekey_wheel_repeat >= mk_wheel_time_to_max) {
- unit = MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed;
- } else {
- unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed * mousekey_wheel_repeat) / mk_wheel_time_to_max;
- }
- return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit));
-}
-
-# else /* #ifndef MK_COMBINED */
-
-static uint8_t move_unit(void) {
- uint16_t unit;
- if (mousekey_accel & (1 << 0)) {
- unit = 1;
- } else if (mousekey_accel & (1 << 1)) {
- unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed) / 2;
- } else if (mousekey_accel & (1 << 2)) {
- unit = MOUSEKEY_MOVE_MAX;
- } else if (mousekey_repeat == 0) {
- unit = MOUSEKEY_MOVE_DELTA;
- } else if (mousekey_repeat >= mk_time_to_max) {
- unit = MOUSEKEY_MOVE_DELTA * mk_max_speed;
- } else {
- unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed * mousekey_repeat) / mk_time_to_max;
- }
- return (unit > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : (unit == 0 ? 1 : unit));
-}
-
-static uint8_t wheel_unit(void) {
- uint16_t unit;
- if (mousekey_accel & (1 << 0)) {
- unit = 1;
- } else if (mousekey_accel & (1 << 1)) {
- unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed) / 2;
- } else if (mousekey_accel & (1 << 2)) {
- unit = MOUSEKEY_WHEEL_MAX;
- } else if (mousekey_repeat == 0) {
- unit = MOUSEKEY_WHEEL_DELTA;
- } else if (mousekey_repeat >= mk_wheel_time_to_max) {
- unit = MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed;
- } else {
- unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed * mousekey_repeat) / mk_wheel_time_to_max;
- }
- return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit));
-}
-
-# endif /* #ifndef MK_COMBINED */
-
-void mousekey_task(void) {
- // report cursor and scroll movement independently
- report_mouse_t const tmpmr = mouse_report;
-
- mouse_report.x = 0;
- mouse_report.y = 0;
- mouse_report.v = 0;
- mouse_report.h = 0;
-
- if ((tmpmr.x || tmpmr.y) && timer_elapsed(last_timer_c) > (mousekey_repeat ? mk_interval : mk_delay * 10)) {
- if (mousekey_repeat != UINT8_MAX) mousekey_repeat++;
- if (tmpmr.x != 0) mouse_report.x = move_unit() * ((tmpmr.x > 0) ? 1 : -1);
- if (tmpmr.y != 0) mouse_report.y = move_unit() * ((tmpmr.y > 0) ? 1 : -1);
-
- /* diagonal move [1/sqrt(2)] */
- if (mouse_report.x && mouse_report.y) {
- mouse_report.x = times_inv_sqrt2(mouse_report.x);
- if (mouse_report.x == 0) {
- mouse_report.x = 1;
- }
- mouse_report.y = times_inv_sqrt2(mouse_report.y);
- if (mouse_report.y == 0) {
- mouse_report.y = 1;
- }
- }
- }
- if ((tmpmr.v || tmpmr.h) && timer_elapsed(last_timer_w) > (mousekey_wheel_repeat ? mk_wheel_interval : mk_wheel_delay * 10)) {
- if (mousekey_wheel_repeat != UINT8_MAX) mousekey_wheel_repeat++;
- if (tmpmr.v != 0) mouse_report.v = wheel_unit() * ((tmpmr.v > 0) ? 1 : -1);
- if (tmpmr.h != 0) mouse_report.h = wheel_unit() * ((tmpmr.h > 0) ? 1 : -1);
-
- /* diagonal move [1/sqrt(2)] */
- if (mouse_report.v && mouse_report.h) {
- mouse_report.v = times_inv_sqrt2(mouse_report.v);
- if (mouse_report.v == 0) {
- mouse_report.v = 1;
- }
- mouse_report.h = times_inv_sqrt2(mouse_report.h);
- if (mouse_report.h == 0) {
- mouse_report.h = 1;
- }
- }
- }
-
- if (mouse_report.x || mouse_report.y || mouse_report.v || mouse_report.h) mousekey_send();
- mouse_report = tmpmr;
-}
-
-void mousekey_on(uint8_t code) {
- if (code == KC_MS_UP)
- mouse_report.y = move_unit() * -1;
- else if (code == KC_MS_DOWN)
- mouse_report.y = move_unit();
- else if (code == KC_MS_LEFT)
- mouse_report.x = move_unit() * -1;
- else if (code == KC_MS_RIGHT)
- mouse_report.x = move_unit();
- else if (code == KC_MS_WH_UP)
- mouse_report.v = wheel_unit();
- else if (code == KC_MS_WH_DOWN)
- mouse_report.v = wheel_unit() * -1;
- else if (code == KC_MS_WH_LEFT)
- mouse_report.h = wheel_unit() * -1;
- else if (code == KC_MS_WH_RIGHT)
- mouse_report.h = wheel_unit();
- else if (code == KC_MS_BTN1)
- mouse_report.buttons |= MOUSE_BTN1;
- else if (code == KC_MS_BTN2)
- mouse_report.buttons |= MOUSE_BTN2;
- else if (code == KC_MS_BTN3)
- mouse_report.buttons |= MOUSE_BTN3;
- else if (code == KC_MS_BTN4)
- mouse_report.buttons |= MOUSE_BTN4;
- else if (code == KC_MS_BTN5)
- mouse_report.buttons |= MOUSE_BTN5;
- else if (code == KC_MS_ACCEL0)
- mousekey_accel |= (1 << 0);
- else if (code == KC_MS_ACCEL1)
- mousekey_accel |= (1 << 1);
- else if (code == KC_MS_ACCEL2)
- mousekey_accel |= (1 << 2);
-}
-
-void mousekey_off(uint8_t code) {
- if (code == KC_MS_UP && mouse_report.y < 0)
- mouse_report.y = 0;
- else if (code == KC_MS_DOWN && mouse_report.y > 0)
- mouse_report.y = 0;
- else if (code == KC_MS_LEFT && mouse_report.x < 0)
- mouse_report.x = 0;
- else if (code == KC_MS_RIGHT && mouse_report.x > 0)
- mouse_report.x = 0;
- else if (code == KC_MS_WH_UP && mouse_report.v > 0)
- mouse_report.v = 0;
- else if (code == KC_MS_WH_DOWN && mouse_report.v < 0)
- mouse_report.v = 0;
- else if (code == KC_MS_WH_LEFT && mouse_report.h < 0)
- mouse_report.h = 0;
- else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0)
- mouse_report.h = 0;
- else if (code == KC_MS_BTN1)
- mouse_report.buttons &= ~MOUSE_BTN1;
- else if (code == KC_MS_BTN2)
- mouse_report.buttons &= ~MOUSE_BTN2;
- else if (code == KC_MS_BTN3)
- mouse_report.buttons &= ~MOUSE_BTN3;
- else if (code == KC_MS_BTN4)
- mouse_report.buttons &= ~MOUSE_BTN4;
- else if (code == KC_MS_BTN5)
- mouse_report.buttons &= ~MOUSE_BTN5;
- else if (code == KC_MS_ACCEL0)
- mousekey_accel &= ~(1 << 0);
- else if (code == KC_MS_ACCEL1)
- mousekey_accel &= ~(1 << 1);
- else if (code == KC_MS_ACCEL2)
- mousekey_accel &= ~(1 << 2);
- if (mouse_report.x == 0 && mouse_report.y == 0) mousekey_repeat = 0;
- if (mouse_report.v == 0 && mouse_report.h == 0) mousekey_wheel_repeat = 0;
-}
-
-#else /* #ifndef MK_3_SPEED */
-
-enum { mkspd_unmod, mkspd_0, mkspd_1, mkspd_2, mkspd_COUNT };
-# ifndef MK_MOMENTARY_ACCEL
-static uint8_t mk_speed = mkspd_1;
-# else
-static uint8_t mk_speed = mkspd_unmod;
-static uint8_t mkspd_DEFAULT = mkspd_unmod;
-# endif
-static uint16_t last_timer_c = 0;
-static uint16_t last_timer_w = 0;
-uint16_t c_offsets[mkspd_COUNT] = {MK_C_OFFSET_UNMOD, MK_C_OFFSET_0, MK_C_OFFSET_1, MK_C_OFFSET_2};
-uint16_t c_intervals[mkspd_COUNT] = {MK_C_INTERVAL_UNMOD, MK_C_INTERVAL_0, MK_C_INTERVAL_1, MK_C_INTERVAL_2};
-uint16_t w_offsets[mkspd_COUNT] = {MK_W_OFFSET_UNMOD, MK_W_OFFSET_0, MK_W_OFFSET_1, MK_W_OFFSET_2};
-uint16_t w_intervals[mkspd_COUNT] = {MK_W_INTERVAL_UNMOD, MK_W_INTERVAL_0, MK_W_INTERVAL_1, MK_W_INTERVAL_2};
-
-void mousekey_task(void) {
- // report cursor and scroll movement independently
- report_mouse_t const tmpmr = mouse_report;
- mouse_report.x = 0;
- mouse_report.y = 0;
- mouse_report.v = 0;
- mouse_report.h = 0;
-
- if ((tmpmr.x || tmpmr.y) && timer_elapsed(last_timer_c) > c_intervals[mk_speed]) {
- mouse_report.x = tmpmr.x;
- mouse_report.y = tmpmr.y;
- }
- if ((tmpmr.h || tmpmr.v) && timer_elapsed(last_timer_w) > w_intervals[mk_speed]) {
- mouse_report.v = tmpmr.v;
- mouse_report.h = tmpmr.h;
- }
-
- if (mouse_report.x || mouse_report.y || mouse_report.v || mouse_report.h) mousekey_send();
- mouse_report = tmpmr;
-}
-
-void adjust_speed(void) {
- uint16_t const c_offset = c_offsets[mk_speed];
- uint16_t const w_offset = w_offsets[mk_speed];
- if (mouse_report.x > 0) mouse_report.x = c_offset;
- if (mouse_report.x < 0) mouse_report.x = c_offset * -1;
- if (mouse_report.y > 0) mouse_report.y = c_offset;
- if (mouse_report.y < 0) mouse_report.y = c_offset * -1;
- if (mouse_report.h > 0) mouse_report.h = w_offset;
- if (mouse_report.h < 0) mouse_report.h = w_offset * -1;
- if (mouse_report.v > 0) mouse_report.v = w_offset;
- if (mouse_report.v < 0) mouse_report.v = w_offset * -1;
- // adjust for diagonals
- if (mouse_report.x && mouse_report.y) {
- mouse_report.x = times_inv_sqrt2(mouse_report.x);
- if (mouse_report.x == 0) {
- mouse_report.x = 1;
- }
- mouse_report.y = times_inv_sqrt2(mouse_report.y);
- if (mouse_report.y == 0) {
- mouse_report.y = 1;
- }
- }
- if (mouse_report.h && mouse_report.v) {
- mouse_report.h = times_inv_sqrt2(mouse_report.h);
- mouse_report.v = times_inv_sqrt2(mouse_report.v);
- }
-}
-
-void mousekey_on(uint8_t code) {
- uint16_t const c_offset = c_offsets[mk_speed];
- uint16_t const w_offset = w_offsets[mk_speed];
- uint8_t const old_speed = mk_speed;
- if (code == KC_MS_UP)
- mouse_report.y = c_offset * -1;
- else if (code == KC_MS_DOWN)
- mouse_report.y = c_offset;
- else if (code == KC_MS_LEFT)
- mouse_report.x = c_offset * -1;
- else if (code == KC_MS_RIGHT)
- mouse_report.x = c_offset;
- else if (code == KC_MS_WH_UP)
- mouse_report.v = w_offset;
- else if (code == KC_MS_WH_DOWN)
- mouse_report.v = w_offset * -1;
- else if (code == KC_MS_WH_LEFT)
- mouse_report.h = w_offset * -1;
- else if (code == KC_MS_WH_RIGHT)
- mouse_report.h = w_offset;
- else if (code == KC_MS_BTN1)
- mouse_report.buttons |= MOUSE_BTN1;
- else if (code == KC_MS_BTN2)
- mouse_report.buttons |= MOUSE_BTN2;
- else if (code == KC_MS_BTN3)
- mouse_report.buttons |= MOUSE_BTN3;
- else if (code == KC_MS_BTN4)
- mouse_report.buttons |= MOUSE_BTN4;
- else if (code == KC_MS_BTN5)
- mouse_report.buttons |= MOUSE_BTN5;
- else if (code == KC_MS_ACCEL0)
- mk_speed = mkspd_0;
- else if (code == KC_MS_ACCEL1)
- mk_speed = mkspd_1;
- else if (code == KC_MS_ACCEL2)
- mk_speed = mkspd_2;
- if (mk_speed != old_speed) adjust_speed();
-}
-
-void mousekey_off(uint8_t code) {
-# ifdef MK_MOMENTARY_ACCEL
- uint8_t const old_speed = mk_speed;
-# endif
- if (code == KC_MS_UP && mouse_report.y < 0)
- mouse_report.y = 0;
- else if (code == KC_MS_DOWN && mouse_report.y > 0)
- mouse_report.y = 0;
- else if (code == KC_MS_LEFT && mouse_report.x < 0)
- mouse_report.x = 0;
- else if (code == KC_MS_RIGHT && mouse_report.x > 0)
- mouse_report.x = 0;
- else if (code == KC_MS_WH_UP && mouse_report.v > 0)
- mouse_report.v = 0;
- else if (code == KC_MS_WH_DOWN && mouse_report.v < 0)
- mouse_report.v = 0;
- else if (code == KC_MS_WH_LEFT && mouse_report.h < 0)
- mouse_report.h = 0;
- else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0)
- mouse_report.h = 0;
- else if (code == KC_MS_BTN1)
- mouse_report.buttons &= ~MOUSE_BTN1;
- else if (code == KC_MS_BTN2)
- mouse_report.buttons &= ~MOUSE_BTN2;
- else if (code == KC_MS_BTN3)
- mouse_report.buttons &= ~MOUSE_BTN3;
- else if (code == KC_MS_BTN4)
- mouse_report.buttons &= ~MOUSE_BTN4;
- else if (code == KC_MS_BTN5)
- mouse_report.buttons &= ~MOUSE_BTN5;
-# ifdef MK_MOMENTARY_ACCEL
- else if (code == KC_MS_ACCEL0)
- mk_speed = mkspd_DEFAULT;
- else if (code == KC_MS_ACCEL1)
- mk_speed = mkspd_DEFAULT;
- else if (code == KC_MS_ACCEL2)
- mk_speed = mkspd_DEFAULT;
- if (mk_speed != old_speed) adjust_speed();
-# endif
-}
-
-#endif /* #ifndef MK_3_SPEED */
-
-void mousekey_send(void) {
- mousekey_debug();
- uint16_t time = timer_read();
- if (mouse_report.x || mouse_report.y) last_timer_c = time;
- if (mouse_report.v || mouse_report.h) last_timer_w = time;
- host_mouse_send(&mouse_report);
-}
-
-void mousekey_clear(void) {
- mouse_report = (report_mouse_t){};
- mousekey_repeat = 0;
- mousekey_wheel_repeat = 0;
- mousekey_accel = 0;
-}
-
-static void mousekey_debug(void) {
- if (!debug_mouse) return;
- print("mousekey [btn|x y v h](rep/acl): [");
- phex(mouse_report.buttons);
- print("|");
- print_decs(mouse_report.x);
- print(" ");
- print_decs(mouse_report.y);
- print(" ");
- print_decs(mouse_report.v);
- print(" ");
- print_decs(mouse_report.h);
- print("](");
- print_dec(mousekey_repeat);
- print("/");
- print_dec(mousekey_accel);
- print(")\n");
-}
diff --git a/tmk_core/common/mousekey.h b/tmk_core/common/mousekey.h
deleted file mode 100644
index 300d262f5d..0000000000
--- a/tmk_core/common/mousekey.h
+++ /dev/null
@@ -1,142 +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 "host.h"
-
-#ifndef MK_3_SPEED
-
-/* max value on report descriptor */
-# ifndef MOUSEKEY_MOVE_MAX
-# define MOUSEKEY_MOVE_MAX 127
-# elif MOUSEKEY_MOVE_MAX > 127
-# error MOUSEKEY_MOVE_MAX needs to be smaller than 127
-# endif
-
-# ifndef MOUSEKEY_WHEEL_MAX
-# define MOUSEKEY_WHEEL_MAX 127
-# elif MOUSEKEY_WHEEL_MAX > 127
-# error MOUSEKEY_WHEEL_MAX needs to be smaller than 127
-# endif
-
-# ifndef MOUSEKEY_MOVE_DELTA
-# define MOUSEKEY_MOVE_DELTA 5
-# endif
-# ifndef MOUSEKEY_WHEEL_DELTA
-# define MOUSEKEY_WHEEL_DELTA 1
-# endif
-# ifndef MOUSEKEY_DELAY
-# define MOUSEKEY_DELAY 300
-# endif
-# ifndef MOUSEKEY_INTERVAL
-# define MOUSEKEY_INTERVAL 50
-# endif
-# ifndef MOUSEKEY_MAX_SPEED
-# define MOUSEKEY_MAX_SPEED 10
-# endif
-# ifndef MOUSEKEY_TIME_TO_MAX
-# define MOUSEKEY_TIME_TO_MAX 20
-# endif
-# ifndef MOUSEKEY_WHEEL_DELAY
-# define MOUSEKEY_WHEEL_DELAY 300
-# endif
-# ifndef MOUSEKEY_WHEEL_INTERVAL
-# define MOUSEKEY_WHEEL_INTERVAL 100
-# endif
-# ifndef MOUSEKEY_WHEEL_MAX_SPEED
-# define MOUSEKEY_WHEEL_MAX_SPEED 8
-# endif
-# ifndef MOUSEKEY_WHEEL_TIME_TO_MAX
-# define MOUSEKEY_WHEEL_TIME_TO_MAX 40
-# endif
-
-#else /* #ifndef MK_3_SPEED */
-
-# ifndef MK_C_OFFSET_UNMOD
-# define MK_C_OFFSET_UNMOD 16
-# endif
-# ifndef MK_C_INTERVAL_UNMOD
-# define MK_C_INTERVAL_UNMOD 16
-# endif
-# ifndef MK_C_OFFSET_0
-# define MK_C_OFFSET_0 1
-# endif
-# ifndef MK_C_INTERVAL_0
-# define MK_C_INTERVAL_0 32
-# endif
-# ifndef MK_C_OFFSET_1
-# define MK_C_OFFSET_1 4
-# endif
-# ifndef MK_C_INTERVAL_1
-# define MK_C_INTERVAL_1 16
-# endif
-# ifndef MK_C_OFFSET_2
-# define MK_C_OFFSET_2 32
-# endif
-# ifndef MK_C_INTERVAL_2
-# define MK_C_INTERVAL_2 16
-# endif
-
-# ifndef MK_W_OFFSET_UNMOD
-# define MK_W_OFFSET_UNMOD 1
-# endif
-# ifndef MK_W_INTERVAL_UNMOD
-# define MK_W_INTERVAL_UNMOD 40
-# endif
-# ifndef MK_W_OFFSET_0
-# define MK_W_OFFSET_0 1
-# endif
-# ifndef MK_W_INTERVAL_0
-# define MK_W_INTERVAL_0 360
-# endif
-# ifndef MK_W_OFFSET_1
-# define MK_W_OFFSET_1 1
-# endif
-# ifndef MK_W_INTERVAL_1
-# define MK_W_INTERVAL_1 120
-# endif
-# ifndef MK_W_OFFSET_2
-# define MK_W_OFFSET_2 1
-# endif
-# ifndef MK_W_INTERVAL_2
-# define MK_W_INTERVAL_2 20
-# endif
-
-#endif /* #ifndef MK_3_SPEED */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern uint8_t mk_delay;
-extern uint8_t mk_interval;
-extern uint8_t mk_max_speed;
-extern uint8_t mk_time_to_max;
-extern uint8_t mk_wheel_max_speed;
-extern uint8_t mk_wheel_time_to_max;
-
-void mousekey_task(void);
-void mousekey_on(uint8_t code);
-void mousekey_off(uint8_t code);
-void mousekey_clear(void);
-void mousekey_send(void);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/tmk_core/common/pin_defs.h b/tmk_core/common/pin_defs.h
new file mode 100644
index 0000000000..ea730138f2
--- /dev/null
+++ b/tmk_core/common/pin_defs.h
@@ -0,0 +1,23 @@
+/* Copyright 2021 QMK
+ *
+ * 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 3 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
+
+// useful for direct pin mapping
+#define NO_PIN (pin_t)(~0)
+
+#if __has_include_next("pin_defs.h")
+# include_next "pin_defs.h" /* Include the platforms pin_defs.h */
+#endif
diff --git a/tmk_core/common/print.h b/tmk_core/common/print.h
index 647a5aa053..48f91e6342 100644
--- a/tmk_core/common/print.h
+++ b/tmk_core/common/print.h
@@ -27,104 +27,76 @@
#include <stdint.h>
#include <stdbool.h>
#include "util.h"
+#include "sendchar.h"
+#include "progmem.h"
-#if defined(PROTOCOL_CHIBIOS) || defined(PROTOCOL_ARM_ATSAM)
-# define PSTR(x) x
-#endif
+void print_set_sendchar(sendchar_func_t func);
#ifndef NO_PRINT
-
-# if defined(__AVR__) /* __AVR__ */
-
-# include "avr/xprintf.h"
-
-# ifdef USER_PRINT /* USER_PRINT */
-
-// Remove normal print defines
-# define print(s)
-# define println(s)
-# undef xprintf
-# define xprintf(fmt, ...)
-
-// Create user print defines
-# define uprint(s) xputs(PSTR(s))
-# define uprintln(s) xputs(PSTR(s "\r\n"))
-# define uprintf(fmt, ...) __xprintf(PSTR(fmt), ##__VA_ARGS__)
-
-# else /* NORMAL PRINT */
-
-// Create user & normal print defines
-# define print(s) xputs(PSTR(s))
-# define println(s) xputs(PSTR(s "\r\n"))
-# define uprint(s) print(s)
-# define uprintln(s) println(s)
-# define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
-
-# endif /* USER_PRINT / NORMAL PRINT */
-
-# ifdef __cplusplus
-extern "C"
-# endif
-
- /* function pointer of sendchar to be used by print utility */
- void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t));
-
-# elif defined(PROTOCOL_CHIBIOS) /* PROTOCOL_CHIBIOS */
-
+# 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
-# ifdef USER_PRINT /* USER_PRINT */
-
-// Remove normal print defines
-# define print(s)
-# define println(s)
-# define xprintf(fmt, ...)
-
-// Create user print defines
-# define uprint(s) printf(s)
-# define uprintln(s) printf(s "\r\n")
-# define uprintf printf
-
-# else /* NORMAL PRINT */
// 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
+# 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 /* USER_PRINT / NORMAL PRINT */
-
-# elif defined(PROTOCOL_ARM_ATSAM) /* PROTOCOL_ARM_ATSAM */
-
-# include "arm_atsam/printf.h"
+# endif /* __AVR__ / PROTOCOL_CHIBIOS / PROTOCOL_ARM_ATSAM */
+#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)
-# ifdef USER_PRINT /* USER_PRINT */
+#endif /* NO_PRINT */
+#ifdef USER_PRINT
// Remove normal print defines
-# define print(s)
-# define println(s)
-# define xprintf(fmt, ...)
-
-// Create user print defines
-# define uprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
-# define uprint(s) xprintf(s)
-# define uprintln(s) xprintf(s "\r\n")
-
-# else /* NORMAL PRINT */
-
-// Create user & normal print defines
-# define xprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
-# define print(s) xprintf(s)
-# define println(s) xprintf(s "\r\n")
-# define uprint(s) print(s)
-# define uprintln(s) println(s)
-# define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
-
-# endif /* USER_PRINT / NORMAL PRINT */
+# undef print
+# undef println
+# undef xprintf
+# define print(s)
+# define println(s)
+# define xprintf(fmt, ...)
+#endif
-# endif /* __AVR__ / PROTOCOL_CHIBIOS / PROTOCOL_ARM_ATSAM */
+#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
@@ -132,139 +104,32 @@ extern "C"
// print (and store their wasteful strings).
//
// !!! DO NOT USE USER PRINT CALLS IN THE BODY OF QMK/TMK !!!
-//
-# ifdef USER_PRINT
-
-// Disable normal print
-# define print_dec(data)
-# define print_decs(data)
-# define print_hex4(data)
-# define print_hex8(data)
-# define print_hex16(data)
-# define print_hex32(data)
-# define print_bin4(data)
-# define print_bin8(data)
-# define print_bin16(data)
-# define print_bin32(data)
-# define print_bin_reverse8(data)
-# define print_bin_reverse16(data)
-# define print_bin_reverse32(data)
-# define print_val_dec(v)
-# define print_val_decs(v)
-# define print_val_hex8(v)
-# define print_val_hex16(v)
-# define print_val_hex32(v)
-# define print_val_bin8(v)
-# define print_val_bin16(v)
-# define print_val_bin32(v)
-# define print_val_bin_reverse8(v)
-# define print_val_bin_reverse16(v)
-# define print_val_bin_reverse32(v)
-
-# else /* NORMAL_PRINT */
-
-// Enable normal print
-/* decimal */
-# 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))
-
-# endif /* USER_PRINT / NORMAL_PRINT */
-
-// User Print
/* decimal */
-# define uprint_dec(i) uprintf("%u", i)
-# define uprint_decs(i) uprintf("%d", i)
+#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)
+#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))
+#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))
-
-#else /* NO_PRINT */
-
-# define xprintf(fmt, ...)
-# define print(s)
-# define println(s)
-# define print_set_sendchar(func)
-# define print_dec(data)
-# define print_decs(data)
-# define print_hex4(data)
-# define print_hex8(data)
-# define print_hex16(data)
-# define print_hex32(data)
-# define print_bin4(data)
-# define print_bin8(data)
-# define print_bin16(data)
-# define print_bin32(data)
-# define print_bin_reverse8(data)
-# define print_bin_reverse16(data)
-# define print_bin_reverse32(data)
-# define print_val_dec(v)
-# define print_val_decs(v)
-# define print_val_hex8(v)
-# define print_val_hex16(v)
-# define print_val_hex32(v)
-# define print_val_bin8(v)
-# define print_val_bin16(v)
-# define print_val_bin32(v)
-# define print_val_bin_reverse8(v)
-# define print_val_bin_reverse16(v)
-# define print_val_bin_reverse32(v)
-
-#endif /* NO_PRINT */
-
-/* Backward compatiblitly for old name */
-#define pdec(data) print_dec(data)
-#define pdec16(data) print_dec(data)
-#define phex(data) print_hex8(data)
-#define phex16(data) print_hex16(data)
-#define pbin(data) print_bin8(data)
-#define pbin16(data) print_bin16(data)
-#define pbin_reverse(data) print_bin_reverse8(data)
-#define pbin_reverse16(data) print_bin_reverse16(data)
+#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/protocol/usb_hid/test/config.h b/tmk_core/common/printf.c
index 71a6814fd1..e8440e55ee 100644
--- a/tmk_core/protocol/usb_hid/test/config.h
+++ b/tmk_core/common/printf.c
@@ -1,5 +1,5 @@
/*
-Copyright 2012 Jun Wako <wakojun@gmail.com>
+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
@@ -14,17 +14,14 @@ 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"
-#pragma once
+// bind lib/printf to console interface - sendchar
-#define VENDOR_ID 0xFEED
-#define PRODUCT_ID 0xCAFE
-#define DEVICE_VER 0x0814
-#define MANUFACTURER t.m.k.
-#define PRODUCT USB to USB keyboard converter
+static int8_t null_sendchar_func(uint8_t c) { return 0; }
+static sendchar_func_t func = null_sendchar_func;
-#define DESCRIPTION Product from t.m.k. keyboard firmware project
+void print_set_sendchar(sendchar_func_t send) { func = send; }
-/* matrix size */
-#define MATRIX_ROWS 32
-#define MATRIX_COLS 8
+void _putchar(char character) { func(character); }
diff --git a/tmk_core/common/progmem.h b/tmk_core/common/progmem.h
index c8863d3ad2..4e4771e523 100644
--- a/tmk_core/common/progmem.h
+++ b/tmk_core/common/progmem.h
@@ -4,6 +4,7 @@
# include <avr/pgmspace.h>
#else
# define PROGMEM
+# define PSTR(x) x
# define PGM_P const char*
# define memcpy_P(dest, src, n) memcpy(dest, src, n)
# define pgm_read_byte(address_short) *((uint8_t*)(address_short))
diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h
index 5d7c5b3b28..db6370657d 100644
--- a/tmk_core/common/report.h
+++ b/tmk_core/common/report.h
@@ -34,12 +34,16 @@ enum hid_report_ids {
};
/* Mouse buttons */
+#define MOUSE_BTN_MASK(n) (1 << (n))
enum mouse_buttons {
- MOUSE_BTN1 = (1 << 0),
- MOUSE_BTN2 = (1 << 1),
- MOUSE_BTN3 = (1 << 2),
- MOUSE_BTN4 = (1 << 3),
- MOUSE_BTN5 = (1 << 4)
+ MOUSE_BTN1 = MOUSE_BTN_MASK(0),
+ MOUSE_BTN2 = MOUSE_BTN_MASK(1),
+ MOUSE_BTN3 = MOUSE_BTN_MASK(2),
+ MOUSE_BTN4 = MOUSE_BTN_MASK(3),
+ MOUSE_BTN5 = MOUSE_BTN_MASK(4),
+ MOUSE_BTN6 = MOUSE_BTN_MASK(5),
+ MOUSE_BTN7 = MOUSE_BTN_MASK(6),
+ MOUSE_BTN8 = MOUSE_BTN_MASK(7)
};
/* Consumer Page (0x0C)
@@ -76,7 +80,21 @@ enum consumer_usages {
AL_ASSISTANT = 0x1CB,
AL_KEYBOARD_LAYOUT = 0x1AE,
// 15.16 Generic GUI Application Controls
+ AC_NEW = 0x201,
+ AC_OPEN = 0x202,
+ AC_CLOSE = 0x203,
+ AC_EXIT = 0x204,
+ AC_MAXIMIZE = 0x205,
AC_MINIMIZE = 0x206,
+ AC_SAVE = 0x207,
+ AC_PRINT = 0x208,
+ AC_PROPERTIES = 0x209,
+ AC_UNDO = 0x21A,
+ AC_COPY = 0x21B,
+ AC_CUT = 0x21C,
+ AC_PASTE = 0x21D,
+ AC_SELECT_ALL = 0x21E,
+ AC_FIND = 0x21F,
AC_SEARCH = 0x221,
AC_HOME = 0x223,
AC_BACK = 0x224,
@@ -92,9 +110,12 @@ enum consumer_usages {
*/
enum desktop_usages {
// 4.5.1 System Controls - Power Controls
- SYSTEM_POWER_DOWN = 0x81,
- SYSTEM_SLEEP = 0x82,
- SYSTEM_WAKE_UP = 0x83
+ SYSTEM_POWER_DOWN = 0x81,
+ SYSTEM_SLEEP = 0x82,
+ SYSTEM_WAKE_UP = 0x83,
+ SYSTEM_RESTART = 0x8F,
+ // 4.10 System Display Controls
+ SYSTEM_DISPLAY_TOGGLE_INT_EXT = 0xB5
};
// clang-format on
diff --git a/tmk_core/common/sendchar.h b/tmk_core/common/sendchar.h
index b150dd464e..edcddaa6bb 100644
--- a/tmk_core/common/sendchar.h
+++ b/tmk_core/common/sendchar.h
@@ -23,6 +23,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
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);
diff --git a/tmk_core/common/suspend.h b/tmk_core/common/suspend.h
index 9d17d984ed..95845e4b63 100644
--- a/tmk_core/common/suspend.h
+++ b/tmk_core/common/suspend.h
@@ -14,5 +14,5 @@ void suspend_power_down_user(void);
void suspend_power_down_kb(void);
#ifndef USB_SUSPEND_WAKEUP_DELAY
-# define USB_SUSPEND_WAKEUP_DELAY 200
+# define USB_SUSPEND_WAKEUP_DELAY 0
#endif
diff --git a/tmk_core/common/sync_timer.c b/tmk_core/common/sync_timer.c
new file mode 100644
index 0000000000..de24b463b6
--- /dev/null
+++ b/tmk_core/common/sync_timer.c
@@ -0,0 +1,58 @@
+/*
+Copyright (C) 2020 Ryan Caltabiano <https://github.com/XScorpion2>
+
+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.
+
+If you happen to meet one of the copyright holders in a bar you are obligated
+to buy them one pint of beer.
+
+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.
+*/
+
+#include "sync_timer.h"
+#include "keyboard.h"
+
+#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER)
+volatile int32_t sync_timer_ms;
+
+void sync_timer_init(void) { sync_timer_ms = 0; }
+
+void sync_timer_update(uint32_t time) {
+ if (is_keyboard_master()) return;
+ sync_timer_ms = time - timer_read32();
+}
+
+uint16_t sync_timer_read(void) {
+ if (is_keyboard_master()) return timer_read();
+ return sync_timer_read32();
+}
+
+uint32_t sync_timer_read32(void) {
+ if (is_keyboard_master()) return timer_read32();
+ return sync_timer_ms + timer_read32();
+}
+
+uint16_t sync_timer_elapsed(uint16_t last) {
+ if (is_keyboard_master()) return timer_elapsed(last);
+ return TIMER_DIFF_16(sync_timer_read(), last);
+}
+
+uint32_t sync_timer_elapsed32(uint32_t last) {
+ if (is_keyboard_master()) return timer_elapsed32(last);
+ return TIMER_DIFF_32(sync_timer_read32(), last);
+}
+#endif
diff --git a/tmk_core/common/sync_timer.h b/tmk_core/common/sync_timer.h
new file mode 100644
index 0000000000..9ddef45bb2
--- /dev/null
+++ b/tmk_core/common/sync_timer.h
@@ -0,0 +1,54 @@
+/*
+Copyright (C) 2020 Ryan Caltabiano <https://github.com/XScorpion2>
+
+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.
+
+If you happen to meet one of the copyright holders in a bar you are obligated
+to buy them one pint of beer.
+
+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 "timer.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER)
+void sync_timer_init(void);
+void sync_timer_update(uint32_t time);
+uint16_t sync_timer_read(void);
+uint32_t sync_timer_read32(void);
+uint16_t sync_timer_elapsed(uint16_t last);
+uint32_t sync_timer_elapsed32(uint32_t last);
+#else
+# define sync_timer_init()
+# define sync_timer_clear()
+# define sync_timer_update(t)
+# define sync_timer_read() timer_read()
+# define sync_timer_read32() timer_read32()
+# define sync_timer_elapsed(t) timer_elapsed(t)
+# define sync_timer_elapsed32(t) timer_elapsed32(t)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tmk_core/common/uart.c b/tmk_core/common/uart.c
deleted file mode 100644
index 150e256c8f..0000000000
--- a/tmk_core/common/uart.c
+++ /dev/null
@@ -1,172 +0,0 @@
-// TODO: Teensy support(ATMega32u4/AT90USB128)
-// Fixed for Arduino Duemilanove ATmega168p by Jun Wako
-/* UART Example for Teensy USB Development Board
- * http://www.pjrc.com/teensy/
- * Copyright (c) 2009 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.
- */
-
-// Version 1.0: Initial Release
-// Version 1.1: Add support for Teensy 2.0, minor optimizations
-
-#include <avr/io.h>
-#include <avr/interrupt.h>
-
-#include "uart.h"
-
-#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
-# define UDRn UDR0
-# define UBRRnL UBRR0L
-# define UCSRnA UCSR0A
-# define UCSRnB UCSR0B
-# define UCSRnC UCSR0C
-# define U2Xn U2X0
-# define RXENn RXEN0
-# define TXENn TXEN0
-# define RXCIEn RXCIE0
-# define UCSZn1 UCSZ01
-# define UCSZn0 UCSZ00
-# define UDRIEn UDRIE0
-# define USARTn_UDRE_vect USART_UDRE_vect
-# define USARTn_RX_vect USART_RX_vect
-#elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega32U2__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
-# define UDRn UDR1
-# define UBRRnL UBRR1L
-# define UCSRnA UCSR1A
-# define UCSRnB UCSR1B
-# define UCSRnC UCSR1C
-# define U2Xn U2X1
-# define RXENn RXEN1
-# define TXENn TXEN1
-# define RXCIEn RXCIE1
-# define UCSZn1 UCSZ11
-# define UCSZn0 UCSZ10
-# define UDRIEn UDRIE1
-# define USARTn_UDRE_vect USART1_UDRE_vect
-# define USARTn_RX_vect USART1_RX_vect
-#elif defined(__AVR_ATmega32A__)
-# define UDRn UDR
-# define UBRRnL UBRRL
-# define UCSRnA UCSRA
-# define UCSRnB UCSRB
-# define UCSRnC UCSRC
-# define U2Xn U2X
-# define RXENn RXEN
-# define TXENn TXEN
-# define RXCIEn RXCIE
-# define UCSZn1 UCSZ1
-# define UCSZn0 UCSZ0
-# define UDRIEn UDRIE
-# define USARTn_UDRE_vect USART_UDRE_vect
-# define USARTn_RX_vect USART_RX_vect
-#endif
-
-// These buffers may be any size from 2 to 256 bytes.
-#define RX_BUFFER_SIZE 64
-#define TX_BUFFER_SIZE 256
-
-static volatile uint8_t tx_buffer[TX_BUFFER_SIZE];
-static volatile uint8_t tx_buffer_head;
-static volatile uint8_t tx_buffer_tail;
-static volatile uint8_t rx_buffer[RX_BUFFER_SIZE];
-static volatile uint8_t rx_buffer_head;
-static volatile uint8_t rx_buffer_tail;
-
-// Initialize the UART
-void uart_init(uint32_t baud) {
- cli();
- UBRRnL = (F_CPU / 4 / baud - 1) / 2;
- UCSRnA = (1 << U2Xn);
- UCSRnB = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn);
- UCSRnC = (1 << UCSZn1) | (1 << UCSZn0);
- tx_buffer_head = tx_buffer_tail = 0;
- rx_buffer_head = rx_buffer_tail = 0;
- sei();
-}
-
-// Transmit a byte
-void uart_putchar(uint8_t c) {
- uint8_t i;
-
- i = tx_buffer_head + 1;
- if (i >= TX_BUFFER_SIZE) i = 0;
- // return immediately to avoid deadlock when interrupt is disabled(called from ISR)
- if (tx_buffer_tail == i && (SREG & (1 << SREG_I)) == 0) return;
- while (tx_buffer_tail == i)
- ; // wait until space in buffer
- // cli();
- tx_buffer[i] = c;
- tx_buffer_head = i;
- UCSRnB = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn) | (1 << UDRIEn);
- // sei();
-}
-
-// Receive a byte
-uint8_t uart_getchar(void) {
- uint8_t c, i;
-
- while (rx_buffer_head == rx_buffer_tail)
- ; // wait for character
- i = rx_buffer_tail + 1;
- if (i >= RX_BUFFER_SIZE) i = 0;
- c = rx_buffer[i];
- rx_buffer_tail = i;
- return c;
-}
-
-// Return the number of bytes waiting in the receive buffer.
-// Call this before uart_getchar() to check if it will need
-// to wait for a byte to arrive.
-uint8_t uart_available(void) {
- uint8_t head, tail;
-
- head = rx_buffer_head;
- tail = rx_buffer_tail;
- if (head >= tail) return head - tail;
- return RX_BUFFER_SIZE + head - tail;
-}
-
-// Transmit Interrupt
-ISR(USARTn_UDRE_vect) {
- uint8_t i;
-
- if (tx_buffer_head == tx_buffer_tail) {
- // buffer is empty, disable transmit interrupt
- UCSRnB = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn);
- } else {
- i = tx_buffer_tail + 1;
- if (i >= TX_BUFFER_SIZE) i = 0;
- UDRn = tx_buffer[i];
- tx_buffer_tail = i;
- }
-}
-
-// Receive Interrupt
-ISR(USARTn_RX_vect) {
- uint8_t c, i;
-
- c = UDRn;
- i = rx_buffer_head + 1;
- if (i >= RX_BUFFER_SIZE) i = 0;
- if (i != rx_buffer_tail) {
- rx_buffer[i] = c;
- rx_buffer_head = i;
- }
-}
diff --git a/tmk_core/common/uart.h b/tmk_core/common/uart.h
deleted file mode 100644
index ea247b17b8..0000000000
--- a/tmk_core/common/uart.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#pragma once
-
-#include <stdint.h>
-
-void uart_init(uint32_t baud);
-void uart_putchar(uint8_t c);
-uint8_t uart_getchar(void);
-uint8_t uart_available(void);
diff --git a/tmk_core/common/util.c b/tmk_core/common/util.c
deleted file mode 100644
index 861cca0054..0000000000
--- a/tmk_core/common/util.c
+++ /dev/null
@@ -1,123 +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 "util.h"
-
-// bit population - return number of on-bit
-__attribute__((noinline)) uint8_t bitpop(uint8_t bits) {
- uint8_t c;
- for (c = 0; bits; c++) bits &= bits - 1;
- return c;
- /*
- const uint8_t bit_count[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
- return bit_count[bits>>4] + bit_count[bits&0x0F]
- */
-}
-
-uint8_t bitpop16(uint16_t bits) {
- uint8_t c;
- for (c = 0; bits; c++) bits &= bits - 1;
- return c;
-}
-
-uint8_t bitpop32(uint32_t bits) {
- uint8_t c;
- for (c = 0; bits; c++) bits &= bits - 1;
- return c;
-}
-
-// most significant on-bit - return highest location of on-bit
-// NOTE: return 0 when bit0 is on or all bits are off
-__attribute__((noinline)) uint8_t biton(uint8_t bits) {
- uint8_t n = 0;
- if (bits >> 4) {
- bits >>= 4;
- n += 4;
- }
- if (bits >> 2) {
- bits >>= 2;
- n += 2;
- }
- if (bits >> 1) {
- bits >>= 1;
- n += 1;
- }
- return n;
-}
-
-uint8_t biton16(uint16_t bits) {
- uint8_t n = 0;
- if (bits >> 8) {
- bits >>= 8;
- n += 8;
- }
- if (bits >> 4) {
- bits >>= 4;
- n += 4;
- }
- if (bits >> 2) {
- bits >>= 2;
- n += 2;
- }
- if (bits >> 1) {
- bits >>= 1;
- n += 1;
- }
- return n;
-}
-
-uint8_t biton32(uint32_t bits) {
- uint8_t n = 0;
- if (bits >> 16) {
- bits >>= 16;
- n += 16;
- }
- if (bits >> 8) {
- bits >>= 8;
- n += 8;
- }
- if (bits >> 4) {
- bits >>= 4;
- n += 4;
- }
- if (bits >> 2) {
- bits >>= 2;
- n += 2;
- }
- if (bits >> 1) {
- bits >>= 1;
- n += 1;
- }
- return n;
-}
-
-__attribute__((noinline)) uint8_t bitrev(uint8_t bits) {
- bits = (bits & 0x0f) << 4 | (bits & 0xf0) >> 4;
- bits = (bits & 0b00110011) << 2 | (bits & 0b11001100) >> 2;
- bits = (bits & 0b01010101) << 1 | (bits & 0b10101010) >> 1;
- return bits;
-}
-
-uint16_t bitrev16(uint16_t bits) {
- bits = bitrev(bits & 0x00ff) << 8 | bitrev((bits & 0xff00) >> 8);
- return bits;
-}
-
-uint32_t bitrev32(uint32_t bits) {
- bits = (uint32_t)bitrev16(bits & 0x0000ffff) << 16 | bitrev16((bits & 0xffff0000) >> 16);
- return bits;
-}
diff --git a/tmk_core/common/wait.h b/tmk_core/common/wait.h
index 89128e9daf..28224fe3aa 100644
--- a/tmk_core/common/wait.h
+++ b/tmk_core/common/wait.h
@@ -6,10 +6,89 @@
extern "C" {
#endif
+#if defined(__ARMEL__) || defined(__ARMEB__)
+# ifndef __OPTIMIZE__
+# pragma message "Compiler optimizations disabled; wait_cpuclock() won't work as designed"
+# endif
+
+# define wait_cpuclock(x) wait_cpuclock_allnop(x)
+
+# define CLOCK_DELAY_NOP8 "nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t"
+
+__attribute__((always_inline)) static inline void wait_cpuclock_allnop(unsigned int n) { /* n: 1..135 */
+ /* The argument n must be a constant expression.
+ * That way, compiler optimization will remove unnecessary code. */
+ if (n < 1) {
+ return;
+ }
+ if (n > 8) {
+ unsigned int n8 = n / 8;
+ n = n - n8 * 8;
+ switch (n8) {
+ case 16:
+ asm volatile(CLOCK_DELAY_NOP8::: "memory");
+ case 15:
+ asm volatile(CLOCK_DELAY_NOP8::: "memory");
+ case 14:
+ asm volatile(CLOCK_DELAY_NOP8::: "memory");
+ case 13:
+ asm volatile(CLOCK_DELAY_NOP8::: "memory");
+ case 12:
+ asm volatile(CLOCK_DELAY_NOP8::: "memory");
+ case 11:
+ asm volatile(CLOCK_DELAY_NOP8::: "memory");
+ case 10:
+ asm volatile(CLOCK_DELAY_NOP8::: "memory");
+ case 9:
+ asm volatile(CLOCK_DELAY_NOP8::: "memory");
+ case 8:
+ asm volatile(CLOCK_DELAY_NOP8::: "memory");
+ case 7:
+ asm volatile(CLOCK_DELAY_NOP8::: "memory");
+ case 6:
+ asm volatile(CLOCK_DELAY_NOP8::: "memory");
+ case 5:
+ asm volatile(CLOCK_DELAY_NOP8::: "memory");
+ case 4:
+ asm volatile(CLOCK_DELAY_NOP8::: "memory");
+ case 3:
+ asm volatile(CLOCK_DELAY_NOP8::: "memory");
+ case 2:
+ asm volatile(CLOCK_DELAY_NOP8::: "memory");
+ case 1:
+ asm volatile(CLOCK_DELAY_NOP8::: "memory");
+ case 0:
+ break;
+ }
+ }
+ switch (n) {
+ case 8:
+ asm volatile("nop" ::: "memory");
+ case 7:
+ asm volatile("nop" ::: "memory");
+ case 6:
+ asm volatile("nop" ::: "memory");
+ case 5:
+ asm volatile("nop" ::: "memory");
+ case 4:
+ asm volatile("nop" ::: "memory");
+ case 3:
+ asm volatile("nop" ::: "memory");
+ case 2:
+ asm volatile("nop" ::: "memory");
+ case 1:
+ asm volatile("nop" ::: "memory");
+ case 0:
+ break;
+ }
+}
+#endif
+
#if defined(__AVR__)
# include <util/delay.h>
# define wait_ms(ms) _delay_ms(ms)
# define wait_us(us) _delay_us(us)
+# define wait_cpuclock(x) __builtin_avr_delay_cycles(x)
#elif defined PROTOCOL_CHIBIOS
# include <ch.h>
# define wait_ms(ms) \
diff --git a/tmk_core/make_dfu_header.sh b/tmk_core/make_dfu_header.sh
deleted file mode 100755
index 7e2283dd70..0000000000
--- a/tmk_core/make_dfu_header.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-ALL_CONFIGS=$*
-GREP="grep"
-
-cat <<- EOF > lib/lufa/Bootloaders/DFU/Keyboard.h
-#pragma once
-
-$($GREP "MANUFACTURER[ \t]" $ALL_CONFIGS -h | tail -1)
-$($GREP "PRODUCT[ \t]" $ALL_CONFIGS -h | tail -1 | tr -d '\r') Bootloader
-$($GREP "QMK_ESC_OUTPUT[ \t]" $ALL_CONFIGS -h | tail -1)
-$($GREP "QMK_ESC_INPUT[ \t]" $ALL_CONFIGS -h | tail -1)
-$($GREP "QMK_LED[ \t]" $ALL_CONFIGS -h | tail -1)
-$($GREP "QMK_SPEAKER[ \t]" $ALL_CONFIGS -h | tail -1)
-EOF
diff --git a/tmk_core/protocol/adb.c b/tmk_core/protocol/adb.c
index a23c919619..367f1b09fa 100644
--- a/tmk_core/protocol/adb.c
+++ b/tmk_core/protocol/adb.c
@@ -1,5 +1,5 @@
/*
-Copyright 2011 Jun WAKO <wakojun@gmail.com>
+Copyright 2011-19 Jun WAKO <wakojun@gmail.com>
Copyright 2013 Shay Green <gblargg@gmail.com>
This software is licensed with a Modified BSD License.
@@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <avr/io.h>
#include <avr/interrupt.h>
#include "adb.h"
+#include "print.h"
// GCC doesn't inline functions normally
#define data_lo() (ADB_DDR |= (1 << ADB_DATA_BIT))
@@ -59,7 +60,6 @@ static inline void place_bit1(void);
static inline void send_byte(uint8_t data);
static inline uint16_t wait_data_lo(uint16_t us);
static inline uint16_t wait_data_hi(uint16_t us);
-static inline uint16_t adb_host_dev_recv(uint8_t device);
void adb_host_init(void) {
ADB_PORT &= ~(1 << ADB_DATA_BIT);
@@ -81,119 +81,164 @@ bool adb_host_psw(void) { return psw_in(); }
* <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919>
* <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139>
*/
-
-// ADB Bit Cells
-//
-// bit cell time: 70-130us
-// low part of bit0: 60-70% of bit cell
-// low part of bit1: 30-40% of bit cell
-//
-// bit cell time 70us 130us
-// --------------------------------------------
-// low part of bit0 42-49 78-91
-// high part of bit0 21-28 39-52
-// low part of bit1 21-28 39-52
-// high part of bit1 42-49 78-91
-//
-//
-// bit0:
-// 70us bit cell:
-// ____________~~~~~~
-// 42-49 21-28
-//
-// 130us bit cell:
-// ____________~~~~~~
-// 78-91 39-52
-//
-// bit1:
-// 70us bit cell:
-// ______~~~~~~~~~~~~
-// 21-28 42-49
-//
-// 130us bit cell:
-// ______~~~~~~~~~~~~
-// 39-52 78-91
-//
-// [from Apple IIgs Hardware Reference Second Edition]
-
-enum { ADDR_KEYB = 0x20, ADDR_MOUSE = 0x30 };
-
-uint16_t adb_host_kbd_recv(void) { return adb_host_dev_recv(ADDR_KEYB); }
+uint16_t adb_host_kbd_recv(void) { return adb_host_talk(ADB_ADDR_KEYBOARD, ADB_REG_0); }
#ifdef ADB_MOUSE_ENABLE
-void adb_mouse_init(void) { return; }
+__attribute__((weak)) void adb_mouse_init(void) { return; }
+
+__attribute__((weak)) void adb_mouse_task(void) { return; }
-uint16_t adb_host_mouse_recv(void) { return adb_host_dev_recv(ADDR_MOUSE); }
+uint16_t adb_host_mouse_recv(void) { return adb_host_talk(ADB_ADDR_MOUSE, ADB_REG_0); }
#endif
-static inline uint16_t adb_host_dev_recv(uint8_t device) {
- uint16_t data = 0;
+// This sends Talk command to read data from register and returns length of the data.
+uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) {
+ for (int8_t i = 0; i < len; i++) buf[i] = 0;
+
cli();
attention();
- send_byte(device | 0x0C); // Addr:Keyboard(0010)/Mouse(0011), Cmd:Talk(11), Register0(00)
- place_bit0(); // Stopbit(0)
+ send_byte((addr << 4) | ADB_CMD_TALK | reg);
+ place_bit0(); // Stopbit(0)
+ // TODO: Service Request(Srq):
+ // Device holds low part of comannd stopbit for 140-260us
+ //
+ // Command:
+ // ......._ ______________________ ___ ............_ -------
+ // | | | | | | |
+ // Command | | | | | Data bytes | |
+ // ........|___| | 140-260 |__| |_............|___|
+ // |stop0 | Tlt Stop-to-Start |start1| |stop0 |
+ //
+ // Command without data:
+ // ......._ __________________________
+ // | |
+ // Command | |
+ // ........|___| | 140-260 |
+ // |stop0 | Tlt Stop-to-Start |
+ //
+ // Service Request:
+ // ......._ ______ ___ ............_ -------
+ // | 140-260 | | | | | |
+ // Command | Service Request | | | | Data bytes | |
+ // ........|___________________| |__| |_............|___|
+ // |stop0 | |start1| |stop0 |
+ // ......._ __________
+ // | 140-260 |
+ // Command | Service Request |
+ // ........|___________________|
+ // |stop0 |
+ // This can be happened?
+ // ......._ ______________________ ___ ............_ -----
+ // | | | | | | 140-260 |
+ // Command | | | | | Data bytes | Service Request |
+ // ........|___| | 140-260 |__| |_............|_________________|
+ // |stop0 | Tlt Stop-to-Start |start1| |stop0 |
+ //
+ // "Service requests are issued by the devices during a very specific time at the
+ // end of the reception of the command packet.
+ // If a device in need of service issues a service request, it must do so within
+ // the 65 µs of the Stop Bit’s low time and maintain the line low for a total of 300 µs."
+ //
+ // "A device sends a Service Request signal by holding the bus low during the low
+ // portion of the stop bit of any command or data transaction. The device must lengthen
+ // the stop by a minimum of 140 J.lS beyond its normal duration, as shown in Figure 8-15."
+ // http://ww1.microchip.com/downloads/en/AppNotes/00591b.pdf
if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored
+ xprintf("R");
sei();
- return -30; // something wrong
+ return 0;
}
if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us)
sei();
- return 0; // No data to send
+ return 0; // No data from device(not error);
+ }
+
+ // start bit(1)
+ if (!wait_data_hi(40)) {
+ xprintf("S");
+ sei();
+ return 0;
+ }
+ if (!wait_data_lo(100)) {
+ xprintf("s");
+ sei();
+ return 0;
}
- uint8_t n = 17; // start bit + 16 data bits
+ uint8_t n = 0; // bit count
do {
+ //
+ // |<- bit_cell_max(130) ->|
+ // | |<- lo ->|
+ // | | |<-hi->|
+ // _______
+ // | | |
+ // | 130-lo | lo-hi |
+ // |________| |
+ //
uint8_t lo = (uint8_t)wait_data_hi(130);
- if (!lo) goto error;
+ if (!lo) goto error; // no more bit or after stop bit
uint8_t hi = (uint8_t)wait_data_lo(lo);
- if (!hi) goto error;
+ if (!hi) goto error; // stop bit extedned by Srq?
- hi = lo - hi;
- lo = 130 - lo;
+ if (n / 8 >= len) continue; // can't store in buf
- data <<= 1;
- if (lo < hi) {
- data |= 1;
- } else if (n == 17) {
- sei();
- return -20;
+ buf[n / 8] <<= 1;
+ if ((130 - lo) < (lo - hi)) {
+ buf[n / 8] |= 1;
}
- } while (--n);
-
- // Stop bit can't be checked normally since it could have service request lenghtening
- // and its high state never goes low.
- if (!wait_data_hi(351) || wait_data_lo(91)) {
- sei();
- return -21;
- }
- sei();
- return data;
+ } while (++n);
error:
sei();
- return -n;
+ return n / 8;
}
-void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l) {
+uint16_t adb_host_talk(uint8_t addr, uint8_t reg) {
+ uint8_t len;
+ uint8_t buf[8];
+ len = adb_host_talk_buf(addr, reg, buf, 8);
+ if (len != 2) return 0;
+ return (buf[0] << 8 | buf[1]);
+}
+
+void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) {
cli();
attention();
- send_byte(cmd);
- place_bit0(); // Stopbit(0)
+ send_byte((addr << 4) | ADB_CMD_LISTEN | reg);
+ place_bit0(); // Stopbit(0)
+ // TODO: Service Request
_delay_us(200); // Tlt/Stop to Start
place_bit1(); // Startbit(1)
- send_byte(data_h);
- send_byte(data_l);
+ for (int8_t i = 0; i < len; i++) {
+ send_byte(buf[i]);
+ // xprintf("%02X ", buf[i]);
+ }
place_bit0(); // Stopbit(0);
sei();
}
+void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l) {
+ uint8_t buf[2] = {data_h, data_l};
+ adb_host_listen_buf(addr, reg, buf, 2);
+}
+
+void adb_host_flush(uint8_t addr) {
+ cli();
+ attention();
+ send_byte((addr << 4) | ADB_CMD_FLUSH);
+ place_bit0(); // Stopbit(0)
+ _delay_us(200); // Tlt/Stop to Start
+ sei();
+}
+
// send state of LEDs
void adb_host_kbd_led(uint8_t led) {
- // Addr:Keyboard(0010), Cmd:Listen(10), Register2(10)
- // send upper byte (not used)
- // send lower byte (bit2: ScrollLock, bit1: CapsLock, bit0:
- adb_host_listen(0x2A, 0, led & 0x07);
+ // Listen Register2
+ // upper byte: not used
+ // lower byte: bit2=ScrollLock, bit1=CapsLock, bit0=NumLock
+ adb_host_listen(ADB_ADDR_KEYBOARD, ADB_REG_2, 0, led & 0x07);
}
#ifdef ADB_PSW_BIT
@@ -327,7 +372,7 @@ Commands
bits commands
------------------------------------------------------
- - - - - 0 0 0 0 Send Request(reset all devices)
+ - - - - 0 0 0 0 Send Reset(reset all devices)
A A A A 0 0 0 1 Flush(reset a device)
- - - - 0 0 1 0 Reserved
- - - - 0 0 1 1 Reserved
@@ -435,5 +480,56 @@ Keyboard LEDs & state of keys(Register2)
| +----------------------------- Delete
+------------------------------- Reserved
+Address, Handler ID and bits(Register3)
+ 1514131211 . . 8 7 . . . . . . 0
+ | | | | | | | | | | | | | | | |
+ | | | | | | | | +-+-+-+-+-+-+-+- Handler ID
+ | | | | +-+-+-+----------------- Address
+ | | | +------------------------- 0
+ | | +--------------------------- Service request enable(1 = enabled)
+ | +----------------------------- Exceptional event(alwyas 1 if not used)
+ +------------------------------- 0
+
+ADB Bit Cells
+ bit cell time: 70-130us
+ low part of bit0: 60-70% of bit cell
+ low part of bit1: 30-40% of bit cell
+
+ bit cell time 70us 130us
+ --------------------------------------------
+ low part of bit0 42-49 78-91
+ high part of bit0 21-28 39-52
+ low part of bit1 21-28 39-52
+ high part of bit1 42-49 78-91
+
+
+ bit0:
+ 70us bit cell:
+ ____________~~~~~~
+ 42-49 21-28
+
+ 130us bit cell:
+ ____________~~~~~~
+ 78-91 39-52
+
+ bit1:
+ 70us bit cell:
+ ______~~~~~~~~~~~~
+ 21-28 42-49
+
+ 130us bit cell:
+ ______~~~~~~~~~~~~
+ 39-52 78-91
+
+ [from Apple IIgs Hardware Reference Second Edition]
+
+Keyboard Handle ID
+ Apple Standard Keyboard M0116: 0x01
+ Apple Extended Keyboard M0115: 0x02
+ Apple Extended Keyboard II M3501: 0x02
+ Apple Adjustable Keybaord: 0x10
+
+ http://lxr.free-electrons.com/source/drivers/macintosh/adbhid.c?v=4.4#L802
+
END_OF_ADB
*/
diff --git a/tmk_core/protocol/adb.h b/tmk_core/protocol/adb.h
index 34cbcf7691..fe8becc2d5 100644
--- a/tmk_core/protocol/adb.h
+++ b/tmk_core/protocol/adb.h
@@ -1,5 +1,5 @@
/*
-Copyright 2011 Jun WAKO <wakojun@gmail.com>
+Copyright 2011-19 Jun WAKO <wakojun@gmail.com>
This software is licensed with a Modified BSD License.
All of this is supposed to be Free Software, Open Source, DFSG-free,
@@ -47,12 +47,60 @@ POSSIBILITY OF SUCH DAMAGE.
#define ADB_POWER 0x7F
#define ADB_CAPS 0x39
+/* ADB commands */
+// Default Address
+#define ADB_ADDR_0 0
+#define ADB_ADDR_DONGLE 1
+#define ADB_ADDR_KEYBOARD 2
+#define ADB_ADDR_MOUSE 3
+#define ADB_ADDR_TABLET 4
+#define ADB_ADDR_APPLIANCE 7
+#define ADB_ADDR_8 8
+#define ADB_ADDR_9 9
+#define ADB_ADDR_10 10
+#define ADB_ADDR_11 11
+#define ADB_ADDR_12 12
+#define ADB_ADDR_13 13
+#define ADB_ADDR_14 14
+#define ADB_ADDR_15 15
+// for temporary purpose, do not use for polling
+#define ADB_ADDR_TMP 15
+#define ADB_ADDR_MOUSE_POLL 10
+// Command Type
+#define ADB_CMD_RESET 0
+#define ADB_CMD_FLUSH 1
+#define ADB_CMD_LISTEN 8
+#define ADB_CMD_TALK 12
+// Register
+#define ADB_REG_0 0
+#define ADB_REG_1 1
+#define ADB_REG_2 2
+#define ADB_REG_3 3
+
+/* ADB keyboard handler id */
+#define ADB_HANDLER_STD 0x01 /* IIGS, M0116 */
+#define ADB_HANDLER_AEK 0x02 /* M0115, M3501 */
+#define ADB_HANDLER_AEK_RMOD 0x03 /* M0115, M3501, alternate mode enableing right modifiers */
+#define ADB_HANDLER_STD_ISO 0x04 /* M0118, ISO swapping keys */
+#define ADB_HANDLER_AEK_ISO 0x05 /* M0115, M3501, ISO swapping keys */
+#define ADB_HANDLER_M1242_ANSI 0x10 /* Adjustable keyboard */
+#define ADB_HANDLER_CLASSIC1_MOUSE 0x01
+#define ADB_HANDLER_CLASSIC2_MOUSE 0x02
+#define ADB_HANDLER_EXTENDED_MOUSE 0x04
+#define ADB_HANDLER_TURBO_MOUSE 0x32
+
// ADB host
void adb_host_init(void);
bool adb_host_psw(void);
+uint16_t adb_host_talk(uint8_t addr, uint8_t reg);
+uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
+void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l);
+void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
+void adb_host_flush(uint8_t addr);
+void adb_host_kbd_led(uint8_t led);
uint16_t adb_host_kbd_recv(void);
uint16_t adb_host_mouse_recv(void);
-void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l);
-void adb_host_kbd_led(uint8_t led);
-void adb_mouse_task(void);
-void adb_mouse_init(void);
+
+// ADB Mouse
+void adb_mouse_task(void);
+void adb_mouse_init(void);
diff --git a/tmk_core/protocol/arm_atsam/i2c_master.c b/tmk_core/protocol/arm_atsam/i2c_master.c
index d3319ab447..dda2f85b00 100644
--- a/tmk_core/protocol/arm_atsam/i2c_master.c
+++ b/tmk_core/protocol/arm_atsam/i2c_master.c
@@ -28,6 +28,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# define I2C_LED_USE_DMA 1 // Set 1 to use background DMA transfers for leds, Set 0 to use inline software transfers
+DmacDescriptor dmac_desc;
+DmacDescriptor dmac_desc_wb;
+
static uint8_t i2c_led_q[I2C_Q_SIZE]; // I2C queue circular buffer
static uint8_t i2c_led_q_s; // Start of circular buffer
static uint8_t i2c_led_q_e; // End of circular buffer
diff --git a/tmk_core/protocol/arm_atsam/i2c_master.h b/tmk_core/protocol/arm_atsam/i2c_master.h
index 44dbdfbffa..68773f213f 100644
--- a/tmk_core/protocol/arm_atsam/i2c_master.h
+++ b/tmk_core/protocol/arm_atsam/i2c_master.h
@@ -24,8 +24,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# include "issi3733_driver.h"
# include "config.h"
-__attribute__((__aligned__(16))) DmacDescriptor dmac_desc;
-__attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb;
+extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc;
+extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb;
uint8_t I2C3733_Init_Control(void);
uint8_t I2C3733_Init_Drivers(void);
diff --git a/tmk_core/protocol/arm_atsam/main_arm_atsam.c b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
index e10be52fb8..ab5e9a9852 100644
--- a/tmk_core/protocol/arm_atsam/main_arm_atsam.c
+++ b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
@@ -305,11 +305,5 @@ int main(void) {
// dprintf("5v=%u 5vu=%u dlow=%u dhi=%u gca=%u gcd=%u\r\n", v_5v, v_5v_avg, v_5v_avg - V5_LOW, v_5v_avg - V5_HIGH, gcr_actual, gcr_desired);
}
#endif // CONSOLE_ENABLE
-
- // Run housekeeping
- housekeeping_task_kb();
- housekeeping_task_user();
- }
-
return 1;
}
diff --git a/tmk_core/protocol/arm_atsam/md_rgb_matrix.c b/tmk_core/protocol/arm_atsam/md_rgb_matrix.c
index b337df7627..2b0805dc86 100644
--- a/tmk_core/protocol/arm_atsam/md_rgb_matrix.c
+++ b/tmk_core/protocol/arm_atsam/md_rgb_matrix.c
@@ -15,16 +15,17 @@ 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 "arm_atsam_protocol.h"
-#include "tmk_core/common/led.h"
-#include "rgb_matrix.h"
-#include <string.h>
-#include <math.h>
-
-#ifdef USE_MASSDROP_CONFIGURATOR
+#ifdef RGB_MATRIX_ENABLE
+# include "arm_atsam_protocol.h"
+# include "led.h"
+# include "rgb_matrix.h"
+# include <string.h>
+# include <math.h>
+
+# ifdef USE_MASSDROP_CONFIGURATOR
__attribute__((weak)) led_instruction_t led_instructions[] = {{.end = 1}};
static void md_rgb_matrix_config_override(int i);
-#endif // USE_MASSDROP_CONFIGURATOR
+# endif // USE_MASSDROP_CONFIGURATOR
void SERCOM1_0_Handler(void) {
if (SERCOM1->I2CM.INTFLAG.bit.ERROR) {
@@ -58,17 +59,17 @@ RGB led_buffer[ISSI3733_LED_COUNT];
uint8_t gcr_desired;
uint8_t gcr_actual;
uint8_t gcr_actual_last;
-#ifdef USE_MASSDROP_CONFIGURATOR
+# ifdef USE_MASSDROP_CONFIGURATOR
uint8_t gcr_breathe;
float breathe_mult;
float pomod;
-#endif
+# endif
-#define ACT_GCR_NONE 0
-#define ACT_GCR_INC 1
-#define ACT_GCR_DEC 2
+# define ACT_GCR_NONE 0
+# define ACT_GCR_INC 1
+# define ACT_GCR_DEC 2
-#define LED_GCR_STEP_AUTO 2
+# define LED_GCR_STEP_AUTO 2
static uint8_t gcr_min_counter;
static uint8_t v_5v_cat_hit;
@@ -78,11 +79,11 @@ void gcr_compute(void) {
uint8_t action = ACT_GCR_NONE;
uint8_t gcr_use = gcr_desired;
-#ifdef USE_MASSDROP_CONFIGURATOR
+# ifdef USE_MASSDROP_CONFIGURATOR
if (led_animation_breathing) {
gcr_use = gcr_breathe;
}
-#endif
+# endif
// If the 5v takes a catastrophic hit, disable the LED drivers briefly, assert auto gcr mode, min gcr and let the auto take over
if (v_5v < V5_CAT) {
@@ -150,7 +151,7 @@ void gcr_compute(void) {
gcr_actual -= LED_GCR_STEP_AUTO;
gcr_min_counter = 0;
-#ifdef USE_MASSDROP_CONFIGURATOR
+# ifdef USE_MASSDROP_CONFIGURATOR
// If breathe mode is active, the top end can fluctuate if the host can not supply enough current
// So set the breathe GCR to where it becomes stable
if (led_animation_breathing == 1) {
@@ -159,7 +160,7 @@ void gcr_compute(void) {
// and the same would happen maybe one or two more times. Therefore I'm favoring
// powering through one full breathe and letting gcr settle completely
}
-#endif
+# endif
}
}
}
@@ -196,25 +197,25 @@ void md_rgb_matrix_prepare(void) {
}
}
-void led_set_one(int i, uint8_t r, uint8_t g, uint8_t b) {
+static void led_set_one(int i, uint8_t r, uint8_t g, uint8_t b) {
if (i < ISSI3733_LED_COUNT) {
-#ifdef USE_MASSDROP_CONFIGURATOR
+# ifdef USE_MASSDROP_CONFIGURATOR
md_rgb_matrix_config_override(i);
-#else
+# else
led_buffer[i].r = r;
led_buffer[i].g = g;
led_buffer[i].b = b;
-#endif
+# endif
}
}
-void led_set_all(uint8_t r, uint8_t g, uint8_t b) {
+static void led_set_all(uint8_t r, uint8_t g, uint8_t b) {
for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) {
led_set_one(i, r, g, b);
}
}
-void init(void) {
+static void init(void) {
DBGC(DC_LED_MATRIX_INIT_BEGIN);
issi3733_prepare_arrays();
@@ -227,16 +228,16 @@ void init(void) {
DBGC(DC_LED_MATRIX_INIT_COMPLETE);
}
-void flush(void) {
-#ifdef USE_MASSDROP_CONFIGURATOR
+static void flush(void) {
+# ifdef USE_MASSDROP_CONFIGURATOR
if (!led_enabled) {
return;
} // Prevent calculations and I2C traffic if LED drivers are not enabled
-#else
+# else
if (!sr_exp_data.bit.SDB_N) {
return;
} // Prevent calculations and I2C traffic if LED drivers are not enabled
-#endif
+# endif
// Wait for previous transfer to complete
while (i2c_led_q_running) {
@@ -249,7 +250,7 @@ void flush(void) {
*led_map[i].rgb.b = led_buffer[i].b;
}
-#ifdef USE_MASSDROP_CONFIGURATOR
+# ifdef USE_MASSDROP_CONFIGURATOR
breathe_mult = 1;
if (led_animation_breathing) {
@@ -275,7 +276,7 @@ void flush(void) {
pomod = (uint32_t)pomod % 10000;
pomod /= 100.0f;
-#endif // USE_MASSDROP_CONFIGURATOR
+# endif // USE_MASSDROP_CONFIGURATOR
uint8_t drvid;
@@ -295,25 +296,27 @@ void md_rgb_matrix_indicators(void) {
if (kbled && rgb_matrix_config.enable) {
for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) {
if (
-#if USB_LED_NUM_LOCK_SCANCODE != 255
+# if USB_LED_NUM_LOCK_SCANCODE != 255
(led_map[i].scan == USB_LED_NUM_LOCK_SCANCODE && (kbled & (1 << USB_LED_NUM_LOCK))) ||
-#endif // NUM LOCK
-#if USB_LED_CAPS_LOCK_SCANCODE != 255
+# endif // NUM LOCK
+# if USB_LED_CAPS_LOCK_SCANCODE != 255
(led_map[i].scan == USB_LED_CAPS_LOCK_SCANCODE && (kbled & (1 << USB_LED_CAPS_LOCK))) ||
-#endif // CAPS LOCK
-#if USB_LED_SCROLL_LOCK_SCANCODE != 255
+# endif // CAPS LOCK
+# if USB_LED_SCROLL_LOCK_SCANCODE != 255
(led_map[i].scan == USB_LED_SCROLL_LOCK_SCANCODE && (kbled & (1 << USB_LED_SCROLL_LOCK))) ||
-#endif // SCROLL LOCK
-#if USB_LED_COMPOSE_SCANCODE != 255
+# endif // SCROLL LOCK
+# if USB_LED_COMPOSE_SCANCODE != 255
(led_map[i].scan == USB_LED_COMPOSE_SCANCODE && (kbled & (1 << USB_LED_COMPOSE))) ||
-#endif // COMPOSE
-#if USB_LED_KANA_SCANCODE != 255
+# endif // COMPOSE
+# if USB_LED_KANA_SCANCODE != 255
(led_map[i].scan == USB_LED_KANA_SCANCODE && (kbled & (1 << USB_LED_KANA))) ||
-#endif // KANA
+# endif // KANA
(0)) {
- led_buffer[i].r = 255 - led_buffer[i].r;
- led_buffer[i].g = 255 - led_buffer[i].g;
- led_buffer[i].b = 255 - led_buffer[i].b;
+ if (rgb_matrix_get_flags() & LED_FLAG_INDICATOR) {
+ led_buffer[i].r = 255 - led_buffer[i].r;
+ led_buffer[i].g = 255 - led_buffer[i].g;
+ led_buffer[i].b = 255 - led_buffer[i].b;
+ }
}
}
}
@@ -325,7 +328,7 @@ const rgb_matrix_driver_t rgb_matrix_driver = {.init = init, .flush = flush, .se
= Legacy Lighting Support =
==============================================================================*/
-#ifdef USE_MASSDROP_CONFIGURATOR
+# ifdef USE_MASSDROP_CONFIGURATOR
// Ported from Massdrop QMK GitHub Repo
// TODO?: wire these up to keymap.c
@@ -467,4 +470,5 @@ static void md_rgb_matrix_config_override(int i) {
led_buffer[i].b = (uint8_t)bo;
}
-#endif // USE_MASSDROP_CONFIGURATOR
+# endif // USE_MASSDROP_CONFIGURATOR
+#endif // RGB_MATRIX_ENABLE
diff --git a/tmk_core/protocol/arm_atsam/md_rgb_matrix_programs.c b/tmk_core/protocol/arm_atsam/md_rgb_matrix_programs.c
index b43008cc5b..fce225a6c4 100644
--- a/tmk_core/protocol/arm_atsam/md_rgb_matrix_programs.c
+++ b/tmk_core/protocol/arm_atsam/md_rgb_matrix_programs.c
@@ -15,9 +15,10 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifdef USE_MASSDROP_CONFIGURATOR
+#ifdef RGB_MATRIX_ENABLE
+# ifdef USE_MASSDROP_CONFIGURATOR
-# include "md_rgb_matrix.h"
+# include "md_rgb_matrix.h"
// Teal <-> Salmon
led_setup_t leds_teal_salmon[] = {
@@ -96,4 +97,5 @@ void *led_setups[] = {leds_rainbow_s, leds_rainbow_ns, leds_teal_salmon, leds_ye
const uint8_t led_setups_count = sizeof(led_setups) / sizeof(led_setups[0]);
-#endif
+# endif // USE_MASSDROP_CONFIGURATOR
+#endif // RGB_MATRIX_ENABLE
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c b/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c
index e3fa65574e..9ea4addcfc 100644
--- a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c
+++ b/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c
@@ -374,39 +374,33 @@ static uint8_t udi_hid_exk_report_trans[UDI_HID_EXK_REPORT_SIZE];
COMPILER_WORD_ALIGNED
UDC_DESC_STORAGE udi_hid_exk_report_desc_t udi_hid_exk_report_desc = {{
+ // clang-format off
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x80, // Usage (System Control)
0xA1, 0x01, // Collection (Application)
0x85, REPORT_ID_SYSTEM, // Report ID
- 0x1A, 0x81,
- 0x00, // Usage Minimum (81) (System Power Down)
- 0x2A, 0x83,
- 0x00, // Usage Maximum (83) (System Wake Up)
- 0x16, 0x01,
- 0x00, // Logical Minimum (1)
- 0x26, 0x03,
- 0x00, // Logical Maximum (3)
- 0x95, 0x01, // Report Count (1)
- 0x75, 0x10, // Report Size (16)
- 0x81, 0x00, // Input (Data, Array, Absolute)
- 0xC0, // End Collection
+ 0x19, 0x01, // Usage Minimum (Pointer)
+ 0x2A, 0xB7, 0x00, // Usage Maximum (System Display LCD Autoscale)
+ 0x15, 0x01, // Logical Minimum
+ 0x26, 0xB7, 0x00, // Logical Maximum
+ 0x95, 0x01, // Report Count (1)
+ 0x75, 0x10, // Report Size (16)
+ 0x81, 0x00, // Input (Data, Array, Absolute)
+ 0xC0, // End Collection
0x05, 0x0C, // Usage Page (Consumer)
0x09, 0x01, // Usage (Consumer Control)
0xA1, 0x01, // Collection (Application)
0x85, REPORT_ID_CONSUMER, // Report ID
- 0x1A, 0x01,
- 0x00, // Usage Minimum (Consumer Control)
- 0x2A, 0x9C,
- 0x02, // Usage Maximum (AC Distribute Vertically)
- 0x16, 0x01,
- 0x00, // Logical Minimum
- 0x26, 0x9C,
- 0x02, // Logical Maximum
- 0x95, 0x01, // Report Count (1)
- 0x75, 0x10, // Report Size (16)
- 0x81, 0x00, // Input (Data, Array, Absolute)
- 0xC0 // End Collection
+ 0x19, 0x01, // Usage Minimum (Consumer Control)
+ 0x2A, 0xA0, 0x02, // Usage Maximum (AC Desktop Show All Applications)
+ 0x15, 0x01, // Logical Minimum
+ 0x26, 0xA0, 0x02, // Logical Maximum
+ 0x95, 0x01, // Report Count (1)
+ 0x75, 0x10, // Report Size (16)
+ 0x81, 0x00, // Input (Data, Array, Absolute)
+ 0xC0 // End Collection
+ //clang-format on
}};
static bool udi_hid_exk_setreport(void);
diff --git a/tmk_core/protocol/arm_atsam/usb/usb_protocol_hid.h b/tmk_core/protocol/arm_atsam/usb/usb_protocol_hid.h
index 2f8a39bdd8..fb97f63cef 100644
--- a/tmk_core/protocol/arm_atsam/usb/usb_protocol_hid.h
+++ b/tmk_core/protocol/arm_atsam/usb/usb_protocol_hid.h
@@ -186,9 +186,10 @@ COMPILER_PACK_RESET()
#define USB_HID_COUNTRY_UK 32 // UK
#define USB_HID_COUNTRY_US 33 // US
#define USB_HID_COUNTRY_YUGOSLAVIA 34 // Yugoslavia
-#define USB_HID_COUNTRY_TURKISH_F 35 // Turkish-F
- //! @}
- //! @}
+#define USB_HID_COUNTRY_TURKISH_F \
+ 35 // Turkish-F
+ //! @}
+ //! @}
//! @}
//! \name HID KEYS values
diff --git a/tmk_core/protocol/chibios/main.c b/tmk_core/protocol/chibios/main.c
index 5c27a8c6a0..6cd88be577 100644
--- a/tmk_core/protocol/chibios/main.c
+++ b/tmk_core/protocol/chibios/main.c
@@ -167,6 +167,7 @@ int main(void) {
keyboard_setup();
/* Init USB */
+ usb_event_queue_init();
init_usb_driver(&USB_DRIVER);
#ifdef MIDI_ENABLE
@@ -225,6 +226,8 @@ int main(void) {
/* Main loop */
while (true) {
+ usb_event_queue_task();
+
#if !defined(NO_USB_STARTUP_CHECK)
if (USB_DRIVER.state == USB_SUSPENDED) {
print("[s]");
diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c
index 67ae8520fd..990dc1b91c 100644
--- a/tmk_core/protocol/chibios/usb_main.c
+++ b/tmk_core/protocol/chibios/usb_main.c
@@ -27,6 +27,7 @@
#include <ch.h>
#include <hal.h>
+#include <string.h>
#include "usb_main.h"
@@ -50,6 +51,7 @@ extern keymap_config_t keymap_config;
#ifdef WEBUSB_ENABLE
# include "webusb.h"
#endif
+
#ifdef JOYSTICK_ENABLE
# include "joystick.h"
#endif
@@ -168,6 +170,7 @@ static const USBEndpointConfig shared_ep_config = {
};
#endif
+
#ifdef WEBUSB_ENABLE
/** Microsoft OS 2.0 Descriptor. This is used by Windows to select the USB driver for the device.
*
@@ -397,6 +400,69 @@ static usb_driver_configs_t drivers = {
* ---------------------------------------------------------
*/
+#define USB_EVENT_QUEUE_SIZE 16
+usbevent_t event_queue[USB_EVENT_QUEUE_SIZE];
+uint8_t event_queue_head;
+uint8_t event_queue_tail;
+
+void usb_event_queue_init(void) {
+ // Initialise the event queue
+ memset(&event_queue, 0, sizeof(event_queue));
+ event_queue_head = 0;
+ event_queue_tail = 0;
+}
+
+static inline bool usb_event_queue_enqueue(usbevent_t event) {
+ uint8_t next = (event_queue_head + 1) % USB_EVENT_QUEUE_SIZE;
+ if (next == event_queue_tail) {
+ return false;
+ }
+ event_queue[event_queue_head] = event;
+ event_queue_head = next;
+ return true;
+}
+
+static inline bool usb_event_queue_dequeue(usbevent_t *event) {
+ if (event_queue_head == event_queue_tail) {
+ return false;
+ }
+ *event = event_queue[event_queue_tail];
+ event_queue_tail = (event_queue_tail + 1) % USB_EVENT_QUEUE_SIZE;
+ return true;
+}
+
+static inline void usb_event_suspend_handler(void) {
+#ifdef SLEEP_LED_ENABLE
+ sleep_led_enable();
+#endif /* SLEEP_LED_ENABLE */
+}
+
+static inline void usb_event_wakeup_handler(void) {
+ suspend_wakeup_init();
+#ifdef SLEEP_LED_ENABLE
+ sleep_led_disable();
+ // NOTE: converters may not accept this
+ led_set(host_keyboard_leds());
+#endif /* SLEEP_LED_ENABLE */
+}
+
+void usb_event_queue_task(void) {
+ usbevent_t event;
+ while (usb_event_queue_dequeue(&event)) {
+ switch (event) {
+ case USB_EVENT_SUSPEND:
+ usb_event_suspend_handler();
+ break;
+ case USB_EVENT_WAKEUP:
+ usb_event_wakeup_handler();
+ break;
+ default:
+ // Nothing to do, we don't handle it.
+ break;
+ }
+ }
+}
+
/* Handles the USB driver global events
* TODO: maybe disable some things when connection is lost? */
static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
@@ -431,9 +497,7 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
osalSysUnlockFromISR();
return;
case USB_EVENT_SUSPEND:
-#ifdef SLEEP_LED_ENABLE
- sleep_led_enable();
-#endif /* SLEEP_LED_ENABLE */
+ usb_event_queue_enqueue(USB_EVENT_SUSPEND);
/* Falls into.*/
case USB_EVENT_UNCONFIGURED:
/* Falls into.*/
@@ -454,12 +518,7 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
qmkusbWakeupHookI(&drivers.array[i].driver);
chSysUnlockFromISR();
}
- suspend_wakeup_init();
-#ifdef SLEEP_LED_ENABLE
- sleep_led_disable();
- // NOTE: converters may not accept this
- led_set(host_keyboard_leds());
-#endif /* SLEEP_LED_ENABLE */
+ usb_event_queue_enqueue(USB_EVENT_WAKEUP);
return;
case USB_EVENT_STALLED:
@@ -575,7 +634,7 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
if (!keymap_config.nkro && keyboard_idle) {
#else /* NKRO_ENABLE */
if (keyboard_idle) {
-#endif /* NKRO_ENABLE */
+#endif /* NKRO_ENABLE */
/* arm the idle timer if boot protocol & idle */
osalSysLockFromISR();
chVTSetI(&keyboard_idle_timer, 4 * TIME_MS2I(keyboard_idle), keyboard_idle_timer_cb, (void *)usbp);
@@ -867,7 +926,7 @@ void send_mouse(report_mouse_t *report) {
}
#else /* MOUSE_ENABLE */
-void send_mouse(report_mouse_t *report) { (void)report; }
+void send_mouse(report_mouse_t *report) { (void)report; }
#endif /* MOUSE_ENABLE */
/* ---------------------------------------------------------
@@ -923,9 +982,32 @@ void send_consumer(uint16_t data) {
#ifdef CONSOLE_ENABLE
int8_t sendchar(uint8_t c) {
- // The previous implmentation had timeouts, but I think it's better to just slow down
- // and make sure that everything is transferred, rather than dropping stuff
- return chnWrite(&drivers.console_driver.driver, &c, 1);
+ static bool timed_out = false;
+ /* The `timed_out` state is an approximation of the ideal `is_listener_disconnected?` state.
+ *
+ * When a 5ms timeout write has timed out, hid_listen is most likely not running, or not
+ * listening to this keyboard, so we go into the timed_out state. In this state we assume
+ * that hid_listen is most likely not gonna be connected to us any time soon, so it would
+ * be wasteful to write follow-up characters with a 5ms timeout, it would all add up and
+ * unncecessarily slow down the firmware. However instead of just dropping the characters,
+ * we write them with a TIME_IMMEDIATE timeout, which is a zero timeout,
+ * and this will succeed only if hid_listen gets connected again. When a write with
+ * TIME_IMMEDIATE timeout succeeds, we know that hid_listen is listening to us again, and
+ * we can go back to the timed_out = false state, and following writes will be executed
+ * with a 5ms timeout. The reason we don't just send all characters with the TIME_IMMEDIATE
+ * timeout is that this could cause bytes to be lost even if hid_listen is running, if there
+ * is a lot of data being sent over the console.
+ *
+ * This logic will work correctly as long as hid_listen is able to receive at least 200
+ * bytes per second. On a heavily overloaded machine that's so overloaded that it's
+ * unusable, and constantly swapping, hid_listen might have trouble receiving 200 bytes per
+ * second, so some bytes might be lost on the console.
+ */
+
+ const sysinterval_t timeout = timed_out ? TIME_IMMEDIATE : TIME_MS2I(5);
+ const size_t result = chnWriteTimeout(&drivers.console_driver.driver, &c, 1, timeout);
+ timed_out = (result == 0);
+ return result;
}
// Just a dummy function for now, this could be exposed as a weak function
@@ -946,15 +1028,8 @@ void console_task(void) {
} while (size > 0);
}
-#else /* CONSOLE_ENABLE */
-int8_t sendchar(uint8_t c) {
- (void)c;
- return 0;
-}
#endif /* CONSOLE_ENABLE */
-void _putchar(char character) { sendchar(character); }
-
#ifdef RAW_ENABLE
void raw_hid_send(uint8_t *data, uint8_t length) {
// TODO: implement variable size packet
diff --git a/tmk_core/protocol/chibios/usb_main.h b/tmk_core/protocol/chibios/usb_main.h
index eaa08d8f79..fb33c8cd0f 100644
--- a/tmk_core/protocol/chibios/usb_main.h
+++ b/tmk_core/protocol/chibios/usb_main.h
@@ -38,6 +38,17 @@ void init_usb_driver(USBDriver *usbp);
void restart_usb_driver(USBDriver *usbp);
/* ---------------
+ * USB Event queue
+ * ---------------
+ */
+
+/* Initialisation of the FIFO */
+void usb_event_queue_init(void);
+
+/* Task to dequeue and execute any handlers for the USB events on the main thread */
+void usb_event_queue_task(void);
+
+/* ---------------
* Keyboard header
* ---------------
*/
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index 1d019d1695..b1af36d113 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -782,9 +782,7 @@ static void send_keyboard(report_keyboard_t *report) {
uint8_t timeout = 255;
#ifdef BLUETOOTH_ENABLE
- uint8_t where = where_to_send();
-
- if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
+ if (where_to_send() == OUTPUT_BLUETOOTH) {
# ifdef MODULE_ADAFRUIT_BLE
adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys));
# elif MODULE_RN42
@@ -797,9 +795,6 @@ static void send_keyboard(report_keyboard_t *report) {
serial_send(report->keys[i]);
}
# endif
- }
-
- if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
return;
}
#endif
@@ -840,9 +835,7 @@ static void send_mouse(report_mouse_t *report) {
uint8_t timeout = 255;
# ifdef BLUETOOTH_ENABLE
- uint8_t where = where_to_send();
-
- if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
+ if (where_to_send() == OUTPUT_BLUETOOTH) {
# ifdef MODULE_ADAFRUIT_BLE
// FIXME: mouse buttons
adafruit_ble_send_mouse_move(report->x, report->y, report->v, report->h, report->buttons);
@@ -857,9 +850,6 @@ static void send_mouse(report_mouse_t *report) {
serial_send(report->h); // should try sending the wheel h here
serial_send(0x00);
# endif
- }
-
- if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
return;
}
# endif
@@ -918,9 +908,13 @@ static void send_system(uint16_t data) {
static void send_consumer(uint16_t data) {
#ifdef EXTRAKEY_ENABLE
# ifdef BLUETOOTH_ENABLE
+<<<<<<< HEAD
uint8_t where = where_to_send();
if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
+=======
+ if (where_to_send() == OUTPUT_BLUETOOTH) {
+>>>>>>> 0.12.52~1
# ifdef MODULE_ADAFRUIT_BLE
adafruit_ble_send_consumer_key(data);
# elif MODULE_RN42
@@ -934,9 +928,12 @@ static void send_consumer(uint16_t data) {
serial_send(bitmap & 0xFF);
serial_send((bitmap >> 8) & 0xFF);
# endif
+<<<<<<< HEAD
}
if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
+=======
+>>>>>>> 0.12.52~1
return;
}
# endif
@@ -955,9 +952,14 @@ static void send_consumer(uint16_t data) {
* FIXME: Needs doc
*/
int8_t sendchar(uint8_t c) {
+<<<<<<< HEAD
// Not wait once timeouted.
+=======
+ // Do not wait if the previous write has timed_out.
+>>>>>>> 0.12.52~1
// Because sendchar() is called so many times, waiting each call causes big lag.
- static bool timeouted = false;
+ // The `timed_out` state is an approximation of the ideal `is_listener_disconnected?` state.
+ static bool timed_out = false;
// prevents Console_Task() from running during sendchar() runs.
// or char will be lost. These two function is mutually exclusive.
@@ -971,11 +973,11 @@ int8_t sendchar(uint8_t c) {
goto ERROR_EXIT;
}
- if (timeouted && !Endpoint_IsReadWriteAllowed()) {
+ if (timed_out && !Endpoint_IsReadWriteAllowed()) {
goto ERROR_EXIT;
}
- timeouted = false;
+ timed_out = false;
uint8_t timeout = SEND_TIMEOUT;
while (!Endpoint_IsReadWriteAllowed()) {
@@ -986,7 +988,7 @@ int8_t sendchar(uint8_t c) {
goto ERROR_EXIT;
}
if (!(timeout--)) {
- timeouted = true;
+ timed_out = true;
goto ERROR_EXIT;
}
_delay_ms(1);
@@ -1136,7 +1138,6 @@ static void setup_usb(void) {
// for Console_Task
USB_Device_EnableSOFEvents();
- print_set_sendchar(sendchar);
}
/** \brief Main
diff --git a/tmk_core/protocol/lufa/outputselect.h b/tmk_core/protocol/lufa/outputselect.h
index 7f7ed00b95..c4548e1122 100644
--- a/tmk_core/protocol/lufa/outputselect.h
+++ b/tmk_core/protocol/lufa/outputselect.h
@@ -21,21 +21,11 @@ enum outputs {
OUTPUT_NONE,
OUTPUT_USB,
- OUTPUT_BLUETOOTH,
-
- // backward compatibility
- OUTPUT_USB_AND_BT
+ OUTPUT_BLUETOOTH
};
-/**
- * backward compatibility for BLUETOOTH_ENABLE, send to BT and USB by default
- */
#ifndef OUTPUT_DEFAULT
-# ifdef BLUETOOTH_ENABLE
-# define OUTPUT_DEFAULT OUTPUT_USB_AND_BT
-# else
-# define OUTPUT_DEFAULT OUTPUT_AUTO
-# endif
+# define OUTPUT_DEFAULT OUTPUT_AUTO
#endif
void set_output(uint8_t output);
diff --git a/tmk_core/protocol/m0110.c b/tmk_core/protocol/m0110.c
index b02a6933d2..64f2fa50ab 100644
--- a/tmk_core/protocol/m0110.c
+++ b/tmk_core/protocol/m0110.c
@@ -95,11 +95,11 @@ void m0110_init(void) {
uint8_t data;
m0110_send(M0110_MODEL);
data = m0110_recv();
- print("m0110_init model: "); phex(data); print("\n");
+ print("m0110_init model: "); print_hex8(data); print("\n");
m0110_send(M0110_TEST);
data = m0110_recv();
- print("m0110_init test: "); phex(data); print("\n");
+ print("m0110_init test: "); print_hex8(data); print("\n");
*/
}
@@ -122,7 +122,7 @@ uint8_t m0110_send(uint8_t data) {
return 1;
ERROR:
print("m0110_send err: ");
- phex(m0110_error);
+ print_hex8(m0110_error);
print("\n");
_delay_ms(500);
idle();
@@ -146,7 +146,7 @@ uint8_t m0110_recv(void) {
return data;
ERROR:
print("m0110_recv err: ");
- phex(m0110_error);
+ print_hex8(m0110_error);
print("\n");
_delay_ms(500);
idle();
diff --git a/tmk_core/protocol/midi/qmk_midi.c b/tmk_core/protocol/midi/qmk_midi.c
index 6f6aced725..c18dbf9930 100644
--- a/tmk_core/protocol/midi/qmk_midi.c
+++ b/tmk_core/protocol/midi/qmk_midi.c
@@ -5,7 +5,7 @@
#include "usb_descriptor.h"
#include "process_midi.h"
#if API_SYSEX_ENABLE
-# include "api.h"
+# include "api_sysex.h"
#endif
/*******************************************************************************
diff --git a/tmk_core/protocol/ps2_mouse.c b/tmk_core/protocol/ps2_mouse.c
index 8df465026b..5415453a05 100644
--- a/tmk_core/protocol/ps2_mouse.c
+++ b/tmk_core/protocol/ps2_mouse.c
@@ -190,7 +190,7 @@ static inline void ps2_mouse_clear_report(report_mouse_t *mouse_report) {
static inline void ps2_mouse_print_report(report_mouse_t *mouse_report) {
if (!debug_mouse) return;
print("ps2_mouse: [");
- phex(mouse_report->buttons);
+ print_hex8(mouse_report->buttons);
print("|");
print_hex8((uint8_t)mouse_report->x);
print(" ");
diff --git a/tmk_core/protocol/serial.h b/tmk_core/protocol/serial.h
index b70d117d7c..0204b84a92 100644
--- a/tmk_core/protocol/serial.h
+++ b/tmk_core/protocol/serial.h
@@ -37,6 +37,8 @@ POSSIBILITY OF SUCH DAMAGE.
#pragma once
+#define SERIAL_UART_DATA UDR1
+
/* host role */
void serial_init(void);
uint8_t serial_recv(void);
diff --git a/tmk_core/protocol/serial_uart.c b/tmk_core/protocol/serial_uart.c
index a15124193a..d5b5657095 100644
--- a/tmk_core/protocol/serial_uart.c
+++ b/tmk_core/protocol/serial_uart.c
@@ -40,6 +40,22 @@ POSSIBILITY OF SUCH DAMAGE.
#include <avr/interrupt.h>
#include "serial.h"
+#ifndef SERIAL_UART_BAUD
+# define SERIAL_UART_BAUD 9600
+#endif
+
+#define SERIAL_UART_UBRR (F_CPU / (16UL * SERIAL_UART_BAUD) - 1)
+#define SERIAL_UART_TXD_READY (UCSR1A & _BV(UDRE1))
+#define SERIAL_UART_RXD_VECT USART1_RX_vect
+
+#ifndef SERIAL_UART_INIT_CUSTOM
+# define SERIAL_UART_INIT_CUSTOM \
+ /* enable TX */ \
+ UCSR1B = _BV(TXEN1); \
+ /* 8-bit data */ \
+ UCSR1C = _BV(UCSZ11) | _BV(UCSZ10);
+#endif
+
#if defined(SERIAL_UART_RTS_LO) && defined(SERIAL_UART_RTS_HI)
// Buffer state
// Empty: RBUF_SPACE == RBUF_SIZE(head==tail)
@@ -61,7 +77,14 @@ POSSIBILITY OF SUCH DAMAGE.
# define rbuf_check_rts_hi()
#endif
-void serial_init(void) { SERIAL_UART_INIT(); }
+void serial_init(void) {
+ do {
+ // Set baud rate
+ UBRR1L = SERIAL_UART_UBRR;
+ UBRR1L = SERIAL_UART_UBRR >> 8;
+ SERIAL_UART_INIT_CUSTOM;
+ } while (0);
+}
// RX ring buffer
#define RBUF_SIZE 256
diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c
index 4a5edb1907..9277554856 100644
--- a/tmk_core/protocol/usb_descriptor.c
+++ b/tmk_core/protocol/usb_descriptor.c
@@ -40,7 +40,7 @@
#include "report.h"
#include "usb_descriptor.h"
#ifdef WEBUSB_ENABLE
-#include "webusb_descriptor.h"
+# include "webusb_descriptor.h"
#endif
#include "usb_descriptor_common.h"
@@ -119,19 +119,15 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
# endif
HID_RI_USAGE(8, 0x01), // Pointer
HID_RI_COLLECTION(8, 0x00), // Physical
- // Buttons (5 bits)
+ // Buttons (8 bits)
HID_RI_USAGE_PAGE(8, 0x09), // Button
HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1
- HID_RI_USAGE_MAXIMUM(8, 0x05), // Button 5
+ HID_RI_USAGE_MAXIMUM(8, 0x08), // Button 8
HID_RI_LOGICAL_MINIMUM(8, 0x00),
HID_RI_LOGICAL_MAXIMUM(8, 0x01),
- HID_RI_REPORT_COUNT(8, 0x05),
+ HID_RI_REPORT_COUNT(8, 0x08),
HID_RI_REPORT_SIZE(8, 0x01),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
- // Button padding (3 bits)
- HID_RI_REPORT_COUNT(8, 0x01),
- HID_RI_REPORT_SIZE(8, 0x03),
- HID_RI_INPUT(8, HID_IOF_CONSTANT),
// X/Y position (2 bytes)
HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
@@ -288,8 +284,8 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] = {
#ifdef WEBUSB_ENABLE
const USB_Descriptor_BOS_t PROGMEM BOSDescriptor = BOS_DESCRIPTOR(
- (MS_OS_20_PLATFORM_DESCRIPTOR(MS_OS_20_VENDOR_CODE, MS_OS_20_DESCRIPTOR_SET_TOTAL_LENGTH))
- (WEBUSB_PLATFORM_DESCRIPTOR(WEBUSB_VENDOR_CODE, WEBUSB_LANDING_PAGE_INDEX))
+ (MS_OS_20_PLATFORM_DESCRIPTOR(MS_OS_20_VENDOR_CODE, MS_OS_20_DESCRIPTOR_SET_TOTAL_LENGTH))
+ (WEBUSB_PLATFORM_DESCRIPTOR(WEBUSB_VENDOR_CODE, WEBUSB_LANDING_PAGE_INDEX))
);
#endif
#ifdef JOYSTICK_ENABLE
@@ -369,6 +365,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = {
#else
.USBSpecification = VERSION_BCD(1, 1, 0),
#endif
+
#if VIRTSER_ENABLE
.Class = USB_CSCP_IADDeviceClass,
.SubClass = USB_CSCP_IADDeviceSubclass,
diff --git a/tmk_core/protocol/usb_descriptor.h b/tmk_core/protocol/usb_descriptor.h
index e4d5435110..2ea4861f36 100644
--- a/tmk_core/protocol/usb_descriptor.h
+++ b/tmk_core/protocol/usb_descriptor.h
@@ -49,7 +49,7 @@
# include <hal.h>
#endif
#ifdef WEBUSB_ENABLE
-#include "webusb_descriptor.h"
+# include "webusb_descriptor.h"
#endif
/*
@@ -271,6 +271,7 @@ enum usb_endpoints {
# define WEBUSB_IN_EPADDR (ENDPOINT_DIR_IN | WEBUSB_IN_EPNUM)
# define WEBUSB_OUT_EPADDR (ENDPOINT_DIR_OUT | WEBUSB_OUT_EPNUM)
#endif
+
#ifdef JOYSTICK_ENABLE
JOYSTICK_IN_EPNUM = NEXT_EPNUM,
# if STM32_USB_USE_OTG1
diff --git a/tmk_core/protocol/usb_hid/test/Makefile b/tmk_core/protocol/usb_hid/test/Makefile
deleted file mode 100644
index 83bf2aed67..0000000000
--- a/tmk_core/protocol/usb_hid/test/Makefile
+++ /dev/null
@@ -1,126 +0,0 @@
-#----------------------------------------------------------------------------
-# On command line:
-#
-# make all = Make software.
-#
-# make clean = Clean out built project files.
-#
-# make coff = Convert ELF to AVR COFF.
-#
-# make extcoff = Convert ELF to AVR Extended COFF.
-#
-# make program = Download the hex file to the device.
-# Please customize your programmer settings(PROGRAM_CMD)
-#
-# make teensy = Download the hex file to the device, using teensy_loader_cli.
-# (must have teensy_loader_cli installed).
-#
-# make dfu = Download the hex file to the device, using dfu-programmer (must
-# have dfu-programmer installed).
-#
-# make flip = Download the hex file to the device, using Atmel FLIP (must
-# have Atmel FLIP installed).
-#
-# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
-# (must have dfu-programmer installed).
-#
-# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
-# (must have Atmel FLIP installed).
-#
-# make debug = Start either simulavr or avarice as specified for debugging,
-# with avr-gdb or avr-insight as the front end for debugging.
-#
-# make filename.s = Just compile filename.c into the assembler code only.
-#
-# make filename.i = Create a preprocessed source file for use in submitting
-# bug reports to the GCC project.
-#
-# To rebuild project do "make clean" then "make all".
-#----------------------------------------------------------------------------
-
-# Target file name (without extension).
-TARGET = usb_hid_test
-
-TMK_DIR = ../../..
-
-# Directory keyboard dependent files exist
-TARGET_DIR = .
-
-# MCU name
-MCU = atmega32u4
-
-
-# Processor frequency.
-# This will define a symbol, F_CPU, in all source code files equal to the
-# processor frequency in Hz. You can then use this symbol in your source code to
-# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
-# automatically to create a 32-bit value in your source code.
-#
-# This will be an integer division of F_USB below, as it is sourced by
-# F_USB after it has run through any CPU prescalers. Note that this value
-# does not *change* the processor frequency - it should merely be updated to
-# reflect the processor speed set externally so that the code can use accurate
-# software delays.
-F_CPU = 16000000
-
-
-
-#
-# LUFA specific
-#
-# Target architecture (see library "Board Types" documentation).
-ARCH = AVR8
-# Input clock frequency.
-# This will define a symbol, F_USB, in all source code files equal to the
-# input clock frequency (before any prescaling is performed) in Hz. This value may
-# differ from F_CPU if prescaling is used on the latter, and is required as the
-# raw input clock is fed directly to the PLL sections of the AVR for high speed
-# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
-# at the end, this will be done automatically to create a 32-bit value in your
-# source code.
-#
-# If no clock division is performed on the input clock inside the AVR (via the
-# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
-F_USB = $(F_CPU)
-# Interrupt driven control endpoint task
-OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
-
-
-
-# Build Options
-# comment out to disable the options.
-#
-# Console for debug
-OPT_DEFS += -DCONSOLE_ENABLE
-
-# Boot Section Size in bytes
-# Teensy halfKay 512
-# Atmel DFU loader 4096
-# LUFA bootloader 4096
-#OPT_DEFS += -DBOOT_SIZE=4096
-
-
-
-SRC = test.cpp
-SRC += common/debug.c
-SRC += common/print.c
-
-CONFIG_H = config.h
-
-
-
-# Search Path
-VPATH += $(TARGET_DIR)
-VPATH += $(TMK_DIR)
-VPATH += $(TMK_DIR)/common
-
-
-
-# program Leonardo
-PROGRAM_CMD = avrdude -p$(MCU) -cavr109 -P$(DEV) -b57600 -Uflash:w:$(TARGET).hex
-
-
-
-include $(TMK_DIR)/protocol/usb_hid.mk
-include $(TMK_DIR)/protocol/lufa.mk
-include $(TMK_DIR)/rules.mk
diff --git a/tmk_core/protocol/usb_hid/test/test.cpp b/tmk_core/protocol/usb_hid/test/test.cpp
deleted file mode 100644
index 4958f0c619..0000000000
--- a/tmk_core/protocol/usb_hid/test/test.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-#include <avr/io.h>
-#include <avr/wdt.h>
-#include <avr/power.h>
-#include <util/delay.h>
-#include <Arduino.h>
-
-// USB HID host
-#include "Usb.h"
-#include "hid.h"
-#include "hidboot.h"
-#include "parser.h"
-
-// LUFA
-#include "lufa.h"
-
-#include "debug.h"
-
-#include "leonardo_led.h"
-
-
-static USB usb_host;
-static HIDBoot<HID_PROTOCOL_KEYBOARD> kbd(&usb_host);
-static KBDReportParser kbd_parser;
-
-static void LUFA_setup(void)
-{
- /* Disable watchdog if enabled by bootloader/fuses */
- MCUSR &= ~(1 << WDRF);
- wdt_disable();
-
- /* Disable clock division */
- clock_prescale_set(clock_div_1);
-
- // Leonardo needs. Without this USB device is not recognized.
- USB_Disable();
-
- USB_Init();
-
- // for Console_Task
- USB_Device_EnableSOFEvents();
-}
-
-static void HID_setup()
-{
- // Arduino Timer startup: wiring.c
- init();
-
- if (usb_host.Init() == -1) {
- debug("HID init: failed\n");
- LED_TX_OFF;
- }
-
- _delay_ms(200);
-
- kbd.SetReportParser(0, (HIDReportParser*)&kbd_parser);
-}
-
-int main(void)
-{
- // LED for debug
- LED_TX_INIT;
- LED_TX_ON;
-
- print_enable = true;
- debug_enable = true;
- debug_matrix = true;
- debug_keyboard = true;
- debug_mouse = true;
-
- LUFA_setup();
- sei();
-
- // wait for startup of sendchar routine
- while (USB_DeviceState != DEVICE_STATE_Configured) ;
- if (debug_enable) {
- _delay_ms(1000);
- }
-
- HID_setup();
-
- debug("init: done\n");
- for (;;) {
- usb_host.Task();
-
-#if !defined(INTERRUPT_CONTROL_ENDPOINT)
- // LUFA Task for control request
- USB_USBTask();
-#endif
- }
-
- return 0;
-}
diff --git a/tmk_core/protocol/vusb/main.c b/tmk_core/protocol/vusb/main.c
index 2e8bb2fbbc..53926a7493 100644
--- a/tmk_core/protocol/vusb/main.c
+++ b/tmk_core/protocol/vusb/main.c
@@ -53,10 +53,10 @@ static void initForUsbConnectivity(void) {
usbDeviceConnect();
}
-static void usb_remote_wakeup(void) {
+static void vusb_send_remote_wakeup(void) {
cli();
- int8_t ddr_orig = USBDDR;
+ uint8_t ddr_orig = USBDDR;
USBOUT |= (1 << USBMINUS);
USBDDR = ddr_orig | USBMASK;
USBOUT ^= USBMASK;
@@ -70,16 +70,34 @@ static void usb_remote_wakeup(void) {
sei();
}
+bool vusb_suspended = false;
+
+static void vusb_suspend(void) {
+ vusb_suspended = true;
+
+#ifdef SLEEP_LED_ENABLE
+ sleep_led_enable();
+#endif
+
+ suspend_power_down();
+}
+
+#if USB_COUNT_SOF
+static void vusb_wakeup(void) {
+ vusb_suspended = false;
+ suspend_wakeup_init();
+
+# ifdef SLEEP_LED_ENABLE
+ sleep_led_disable();
+# endif
+}
+#endif
+
/** \brief Setup USB
*
* FIXME: Needs doc
*/
-static void setup_usb(void) {
- initForUsbConnectivity();
-
- // for Console_Task
- print_set_sendchar(sendchar);
-}
+static void setup_usb(void) { initForUsbConnectivity(); }
/** \brief Main
*
@@ -87,9 +105,8 @@ static void setup_usb(void) {
*/
int main(void) __attribute__((weak));
int main(void) {
- bool suspended = false;
#if USB_COUNT_SOF
- uint16_t last_timer = timer_read();
+ uint16_t sof_timer = timer_read();
#endif
#ifdef CLKPR
@@ -112,23 +129,24 @@ int main(void) {
while (1) {
#if USB_COUNT_SOF
if (usbSofCount != 0) {
- suspended = false;
usbSofCount = 0;
- last_timer = timer_read();
-# ifdef SLEEP_LED_ENABLE
- sleep_led_disable();
-# endif
+ sof_timer = timer_read();
+ if (vusb_suspended) {
+ vusb_wakeup();
+ }
} else {
// Suspend when no SOF in 3ms-10ms(7.1.7.4 Suspending of USB1.1)
- if (timer_elapsed(last_timer) > 5) {
- suspended = true;
-# ifdef SLEEP_LED_ENABLE
- sleep_led_enable();
-# endif
+ if (!vusb_suspended && timer_elapsed(sof_timer) > 5) {
+ vusb_suspend();
}
}
#endif
- if (!suspended) {
+ if (vusb_suspended) {
+ vusb_suspend();
+ if (suspend_wakeup_condition()) {
+ vusb_send_remote_wakeup();
+ }
+ } else {
usbPoll();
// TODO: configuration process is inconsistent. it sometime fails.
@@ -145,6 +163,7 @@ int main(void) {
raw_hid_task();
}
#endif
+
#ifdef CONSOLE_ENABLE
usbPoll();
@@ -154,10 +173,7 @@ int main(void) {
#endif
// Run housekeeping
- housekeeping_task_kb();
- housekeeping_task_user();
- } else if (suspend_wakeup_condition()) {
- usb_remote_wakeup();
+ housekeeping_task();
}
}
}
diff --git a/tmk_core/protocol/vusb/usbconfig.h b/tmk_core/protocol/vusb/usbconfig.h
new file mode 100644
index 0000000000..041f7bd095
--- /dev/null
+++ b/tmk_core/protocol/vusb/usbconfig.h
@@ -0,0 +1,356 @@
+/* Name: usbconfig.h
+ * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
+ * Author: Christian Starkjohann
+ * Creation Date: 2005-04-01
+ * Tabsize: 4
+ * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * This Revision: $Id: usbconfig-prototype.h 785 2010-05-30 17:57:07Z cs $
+ */
+
+#pragma once
+
+// clang-format off
+
+/*
+General Description:
+This file is an example configuration (with inline documentation) for the USB
+driver. It configures V-USB for USB D+ connected to Port D bit 2 (which is
+also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may
+wire the lines to any other port, as long as D+ is also wired to INT0 (or any
+other hardware interrupt, as long as it is the highest level interrupt, see
+section at the end of this file).
+*/
+
+/* ---------------------------- Hardware Config ---------------------------- */
+
+#ifndef USB_CFG_IOPORTNAME
+#define USB_CFG_IOPORTNAME D
+#endif
+/* This is the port where the USB bus is connected. When you configure it to
+ * "B", the registers PORTB, PINB and DDRB will be used.
+ */
+#ifndef USB_CFG_DMINUS_BIT
+#define USB_CFG_DMINUS_BIT 3
+#endif
+/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected.
+ * This may be any bit in the port.
+ */
+#ifndef USB_CFG_DPLUS_BIT
+#define USB_CFG_DPLUS_BIT 2
+#endif
+/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected.
+ * This may be any bit in the port. Please note that D+ must also be connected
+ * to interrupt pin INT0! [You can also use other interrupts, see section
+ * "Optional MCU Description" below, or you can connect D- to the interrupt, as
+ * it is required if you use the USB_COUNT_SOF feature. If you use D- for the
+ * interrupt, the USB interrupt will also be triggered at Start-Of-Frame
+ * markers every millisecond.]
+ */
+#define USB_CFG_CHECK_CRC 0
+/* Define this to 1 if you want that the driver checks integrity of incoming
+ * data packets (CRC checks). CRC checks cost quite a bit of code size and are
+ * currently only available for 18 MHz crystal clock. You must choose
+ * USB_CFG_CLOCK_KHZ = 18000 if you enable this option.
+ */
+
+/* ----------------------- Optional Hardware Config ------------------------ */
+
+/* #define USB_CFG_PULLUP_IOPORTNAME D */
+/* If you connect the 1.5k pullup resistor from D- to a port pin instead of
+ * V+, you can connect and disconnect the device from firmware by calling
+ * the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h).
+ * This constant defines the port on which the pullup resistor is connected.
+ */
+/* #define USB_CFG_PULLUP_BIT 4 */
+/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined
+ * above) where the 1.5k pullup resistor is connected. See description
+ * above for details.
+ */
+
+/* --------------------------- Functional Range ---------------------------- */
+
+#define USB_CFG_HAVE_INTRIN_ENDPOINT 1
+/* Define this to 1 if you want to compile a version with two endpoints: The
+ * default control endpoint 0 and an interrupt-in endpoint (any other endpoint
+ * number).
+ */
+#define USB_CFG_HAVE_INTRIN_ENDPOINT3 1
+/* Define this to 1 if you want to compile a version with three endpoints: The
+ * default control endpoint 0, an interrupt-in endpoint 3 (or the number
+ * configured below) and a catch-all default interrupt-in endpoint as above.
+ * You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature.
+ */
+#define USB_CFG_EP3_NUMBER 3
+/* If the so-called endpoint 3 is used, it can now be configured to any other
+ * endpoint number (except 0) with this macro. Default if undefined is 3.
+ */
+#define USB_CFG_HAVE_INTRIN_ENDPOINT4 1
+/* Define this to 1 if you want to compile a version with three endpoints: The
+ * default control endpoint 0, an interrupt-in endpoint 4 (or the number
+ * configured below) and a catch-all default interrupt-in endpoint as above.
+ * You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature.
+ */
+#define USB_CFG_EP4_NUMBER 4
+/* If the so-called endpoint 4 is used, it can now be configured to any other
+ * endpoint number (except 0) with this macro. Default if undefined is 4.
+ */
+/* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */
+/* The above macro defines the startup condition for data toggling on the
+ * interrupt/bulk endpoints 1, 3 and 4. Defaults to USBPID_DATA1.
+ * Since the token is toggled BEFORE sending any data, the first packet is
+ * sent with the oposite value of this configuration!
+ */
+#define USB_CFG_IMPLEMENT_HALT 0
+/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature
+ * for endpoint 1 (interrupt endpoint). Although you may not need this feature,
+ * it is required by the standard. We have made it a config option because it
+ * bloats the code considerably.
+ */
+#define USB_CFG_SUPPRESS_INTR_CODE 0
+/* Define this to 1 if you want to declare interrupt-in endpoints, but don't
+ * want to send any data over them. If this macro is defined to 1, functions
+ * usbSetInterrupt(), usbSetInterrupt3() and usbSetInterrupt4() are omitted.
+ * This is useful if you need the interrupt-in endpoints in order to comply
+ * to an interface (e.g. HID), but never want to send any data. This option
+ * saves a couple of bytes in flash memory and the transmit buffers in RAM.
+ */
+#define USB_CFG_IS_SELF_POWERED 0
+/* Define this to 1 if the device has its own power supply. Set it to 0 if the
+ * device is powered from the USB bus.
+ */
+#define USB_CFG_IMPLEMENT_FN_WRITE 1
+/* Set this to 1 if you want usbFunctionWrite() to be called for control-out
+ * transfers. Set it to 0 if you don't need it and want to save a couple of
+ * bytes.
+ */
+#define USB_CFG_IMPLEMENT_FN_READ 0
+/* Set this to 1 if you need to send control replies which are generated
+ * "on the fly" when usbFunctionRead() is called. If you only want to send
+ * data from a static buffer, set it to 0 and return the data from
+ * usbFunctionSetup(). This saves a couple of bytes.
+ */
+#define USB_CFG_IMPLEMENT_FN_WRITEOUT 1
+/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints.
+ * You must implement the function usbFunctionWriteOut() which receives all
+ * interrupt/bulk data sent to any endpoint other than 0. The endpoint number
+ * can be found in 'usbRxToken'.
+ */
+#define USB_CFG_HAVE_FLOWCONTROL 0
+/* Define this to 1 if you want flowcontrol over USB data. See the definition
+ * of the macros usbDisableAllRequests() and usbEnableAllRequests() in
+ * usbdrv.h.
+ */
+#define USB_CFG_DRIVER_FLASH_PAGE 0
+/* If the device has more than 64 kBytes of flash, define this to the 64 k page
+ * where the driver's constants (descriptors) are located. Or in other words:
+ * Define this to 1 for boot loaders on the ATMega128.
+ */
+#define USB_CFG_LONG_TRANSFERS 0
+/* Define this to 1 if you want to send/receive blocks of more than 254 bytes
+ * in a single control-in or control-out transfer. Note that the capability
+ * for long transfers increases the driver size.
+ */
+/* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */
+/* This macro is a hook if you want to do unconventional things. If it is
+ * defined, it's inserted at the beginning of received message processing.
+ * If you eat the received message and don't want default processing to
+ * proceed, do a return after doing your things. One possible application
+ * (besides debugging) is to flash a status LED on each packet.
+ */
+/* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */
+/* This macro is a hook if you need to know when an USB RESET occurs. It has
+ * one parameter which distinguishes between the start of RESET state and its
+ * end.
+ */
+/* #define USB_SET_ADDRESS_HOOK() hadAddressAssigned(); */
+/* This macro (if defined) is executed when a USB SET_ADDRESS request was
+ * received.
+ */
+#ifndef USB_COUNT_SOF
+#define USB_COUNT_SOF 1
+#endif
+/* define this macro to 1 if you need the global variable "usbSofCount" which
+ * counts SOF packets. This feature requires that the hardware interrupt is
+ * connected to D- instead of D+.
+ */
+/* #ifdef __ASSEMBLER__
+ * macro myAssemblerMacro
+ * in YL, TCNT0
+ * sts timer0Snapshot, YL
+ * endm
+ * #endif
+ * #define USB_SOF_HOOK myAssemblerMacro
+ * This macro (if defined) is executed in the assembler module when a
+ * Start Of Frame condition is detected. It is recommended to define it to
+ * the name of an assembler macro which is defined here as well so that more
+ * than one assembler instruction can be used. The macro may use the register
+ * YL and modify SREG. If it lasts longer than a couple of cycles, USB messages
+ * immediately after an SOF pulse may be lost and must be retried by the host.
+ * What can you do with this hook? Since the SOF signal occurs exactly every
+ * 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in
+ * designs running on the internal RC oscillator.
+ * Please note that Start Of Frame detection works only if D- is wired to the
+ * interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES!
+ */
+#define USB_CFG_CHECK_DATA_TOGGLING 0
+/* define this macro to 1 if you want to filter out duplicate data packets
+ * sent by the host. Duplicates occur only as a consequence of communication
+ * errors, when the host does not receive an ACK. Please note that you need to
+ * implement the filtering yourself in usbFunctionWriteOut() and
+ * usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable
+ * for each control- and out-endpoint to check for duplicate packets.
+ */
+#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
+/* define this macro to 1 if you want the function usbMeasureFrameLength()
+ * compiled in. This function can be used to calibrate the AVR's RC oscillator.
+ */
+#define USB_USE_FAST_CRC 0
+/* The assembler module has two implementations for the CRC algorithm. One is
+ * faster, the other is smaller. This CRC routine is only used for transmitted
+ * messages where timing is not critical. The faster routine needs 31 cycles
+ * per byte while the smaller one needs 61 to 69 cycles. The faster routine
+ * may be worth the 32 bytes bigger code size if you transmit lots of data and
+ * run the AVR close to its limit.
+ */
+
+/* -------------------------- Device Description --------------------------- */
+
+#define USB_CFG_VENDOR_ID
+/* USB vendor ID for the device, low byte first. If you have registered your
+ * own Vendor ID, define it here. Otherwise you may use one of obdev's free
+ * shared VID/PID pairs. Be sure to read USB-IDs-for-free.txt for rules!
+ * *** IMPORTANT NOTE ***
+ * This template uses obdev's shared VID/PID pair for Vendor Class devices
+ * with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
+ * the implications!
+ */
+#define USB_CFG_DEVICE_ID
+/* This is the ID of the product, low byte first. It is interpreted in the
+ * scope of the vendor ID. If you have registered your own VID with usb.org
+ * or if you have licensed a PID from somebody else, define it here. Otherwise
+ * you may use one of obdev's free shared VID/PID pairs. See the file
+ * USB-IDs-for-free.txt for details!
+ * *** IMPORTANT NOTE ***
+ * This template uses obdev's shared VID/PID pair for Vendor Class devices
+ * with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
+ * the implications!
+ */
+#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 0
+/* Define this to the length of the HID report descriptor, if you implement
+ * an HID device. Otherwise don't define it or define it to 0.
+ * If you use this define, you must add a PROGMEM character array named
+ * "usbHidReportDescriptor" to your code which contains the report descriptor.
+ * Don't forget to keep the array and this define in sync!
+ */
+
+/* #define USB_PUBLIC static */
+/* Use the define above if you #include usbdrv.c instead of linking against it.
+ * This technique saves a couple of bytes in flash memory.
+ */
+
+/* ------------------- Fine Control over USB Descriptors ------------------- */
+/* If you don't want to use the driver's default USB descriptors, you can
+ * provide our own. These can be provided as (1) fixed length static data in
+ * flash memory, (2) fixed length static data in RAM or (3) dynamically at
+ * runtime in the function usbFunctionDescriptor(). See usbdrv.h for more
+ * information about this function.
+ * Descriptor handling is configured through the descriptor's properties. If
+ * no properties are defined or if they are 0, the default descriptor is used.
+ * Possible properties are:
+ * + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched
+ * at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is
+ * used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if
+ * you want RAM pointers.
+ * + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found
+ * in static memory is in RAM, not in flash memory.
+ * + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash),
+ * the driver must know the descriptor's length. The descriptor itself is
+ * found at the address of a well known identifier (see below).
+ * List of static descriptor names (must be declared PROGMEM if in flash):
+ * char usbDescriptorDevice[];
+ * char usbDescriptorConfiguration[];
+ * char usbDescriptorHidReport[];
+ * char usbDescriptorString0[];
+ * int usbDescriptorStringVendor[];
+ * int usbDescriptorStringDevice[];
+ * int usbDescriptorStringSerialNumber[];
+ * Other descriptors can't be provided statically, they must be provided
+ * dynamically at runtime.
+ *
+ * Descriptor properties are or-ed or added together, e.g.:
+ * #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18))
+ *
+ * The following descriptors are defined:
+ * USB_CFG_DESCR_PROPS_DEVICE
+ * USB_CFG_DESCR_PROPS_CONFIGURATION
+ * USB_CFG_DESCR_PROPS_STRINGS
+ * USB_CFG_DESCR_PROPS_STRING_0
+ * USB_CFG_DESCR_PROPS_STRING_VENDOR
+ * USB_CFG_DESCR_PROPS_STRING_PRODUCT
+ * USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER
+ * USB_CFG_DESCR_PROPS_HID
+ * USB_CFG_DESCR_PROPS_HID_REPORT
+ * USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver)
+ *
+ * Note about string descriptors: String descriptors are not just strings, they
+ * are Unicode strings prefixed with a 2 byte header. Example:
+ * int serialNumberDescriptor[] = {
+ * USB_STRING_DESCRIPTOR_HEADER(6),
+ * 'S', 'e', 'r', 'i', 'a', 'l'
+ * };
+ */
+
+#define USB_CFG_DESCR_PROPS_DEVICE USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_CONFIGURATION USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_STRINGS USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_STRING_0 USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_STRING_VENDOR USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_STRING_PRODUCT USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_HID USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_HID_REPORT USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_UNKNOWN 0
+
+#define usbMsgPtr_t unsigned short
+/* If usbMsgPtr_t is not defined, it defaults to 'uchar *'. We define it to
+ * a scalar type here because gcc generates slightly shorter code for scalar
+ * arithmetics than for pointer arithmetics. Remove this define for backward
+ * type compatibility or define it to an 8 bit type if you use data in RAM only
+ * and all RAM is below 256 bytes (tiny memory model in IAR CC).
+ */
+
+/* ----------------------- Optional MCU Description ------------------------ */
+
+/* The following configurations have working defaults in usbdrv.h. You
+ * usually don't need to set them explicitly. Only if you want to run
+ * the driver on a device which is not yet supported or with a compiler
+ * which is not fully supported (such as IAR C) or if you use a differnt
+ * interrupt than INT0, you may have to define some of these.
+ */
+/* #define USB_INTR_CFG MCUCR */
+/* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) */
+/* #define USB_INTR_CFG_CLR 0 */
+/* #define USB_INTR_ENABLE GIMSK */
+/* #define USB_INTR_ENABLE_BIT INT0 */
+/* #define USB_INTR_PENDING GIFR */
+/* #define USB_INTR_PENDING_BIT INTF0 */
+/* #define USB_INTR_VECTOR INT0_vect */
+
+/* Set INT1 for D- falling edge to count SOF */
+/* #define USB_INTR_CFG EICRA */
+#ifndef USB_INTR_CFG_SET
+#define USB_INTR_CFG_SET ((1 << ISC11) | (0 << ISC10))
+#endif
+/* #define USB_INTR_CFG_CLR 0 */
+/* #define USB_INTR_ENABLE EIMSK */
+#ifndef USB_INTR_ENABLE_BIT
+#define USB_INTR_ENABLE_BIT INT1
+#endif
+/* #define USB_INTR_PENDING EIFR */
+#ifndef USB_INTR_PENDING_BIT
+#define USB_INTR_PENDING_BIT INTF1
+#endif
+#ifndef USB_INTR_VECTOR
+#define USB_INTR_VECTOR INT1_vect
+#endif
diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c
index 4a13ca5847..9362fbde78 100644
--- a/tmk_core/protocol/vusb/vusb.c
+++ b/tmk_core/protocol/vusb/vusb.c
@@ -296,7 +296,7 @@ static void send_consumer(uint16_t data) {
*------------------------------------------------------------------*/
static struct {
uint16_t len;
- enum { NONE, BOOTLOADER, SET_LED } kind;
+ enum { NONE, SET_LED } kind;
} last_req;
usbMsgLen_t usbFunctionSetup(uchar data[8]) {
@@ -323,11 +323,6 @@ usbMsgLen_t usbFunctionSetup(uchar data[8]) {
dprint("SET_LED:");
last_req.kind = SET_LED;
last_req.len = rq->wLength.word;
-#ifdef BOOTLOADER_SIZE
- } else if (rq->wValue.word == 0x0301) {
- last_req.kind = BOOTLOADER;
- last_req.len = rq->wLength.word;
-#endif
}
return USB_NO_MSG; // to get data in usbFunctionWrite
} else {
@@ -352,11 +347,6 @@ uchar usbFunctionWrite(uchar *data, uchar len) {
last_req.len = 0;
return 1;
break;
- case BOOTLOADER:
- usbDeviceDisconnect();
- bootloader_jump();
- return 1;
- break;
case NONE:
default:
return -1;
@@ -454,19 +444,15 @@ const PROGMEM uchar shared_hid_report[] = {
0x85, REPORT_ID_MOUSE, // Report ID
0x09, 0x01, // Usage (Pointer)
0xA1, 0x00, // Collection (Physical)
- // Buttons (5 bits)
+ // Buttons (8 bits)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (Button 1)
- 0x29, 0x05, // Usage Maximum (Button 5)
+ 0x29, 0x08, // Usage Maximum (Button 8)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
- 0x95, 0x05, // Report Count (5)
+ 0x95, 0x08, // Report Count (8)
0x75, 0x01, // Report Size (1)
0x81, 0x02, // Input (Data, Variable, Absolute)
- // Button padding (3 bits)
- 0x95, 0x01, // Report Count (1)
- 0x75, 0x03, // Report Size (3)
- 0x81, 0x03, // Input (Constant)
// X/Y position (2 bytes)
0x05, 0x01, // Usage Page (Generic Desktop)
diff --git a/tmk_core/protocol/vusb/vusb.h b/tmk_core/protocol/vusb/vusb.h
index b4c73aabae..b1ecc98f37 100644
--- a/tmk_core/protocol/vusb/vusb.h
+++ b/tmk_core/protocol/vusb/vusb.h
@@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#pragma once
#include "host_driver.h"
+#include <usbdrv/usbdrv.h>
typedef struct usbDescriptorHeader {
uchar bLength;
@@ -119,5 +120,7 @@ typedef struct usbConfigurationDescriptor {
#define USB_STRING_LEN(s) (sizeof(usbDescriptorHeader_t) + ((s) << 1))
+extern bool vusb_suspended;
+
host_driver_t *vusb_driver(void);
void vusb_transfer_keyboard(void);
diff --git a/tmk_core/protocol/xt.h b/tmk_core/protocol/xt.h
index 6dc5f19d00..538ff0e459 100644
--- a/tmk_core/protocol/xt.h
+++ b/tmk_core/protocol/xt.h
@@ -38,33 +38,36 @@ POSSIBILITY OF SUCH DAMAGE.
#pragma once
-#define XT_DATA_IN() \
- do { \
- XT_DATA_DDR &= ~(1 << XT_DATA_BIT); \
- XT_DATA_PORT |= (1 << XT_DATA_BIT); \
+#include "quantum.h"
+
+#define XT_DATA_IN() \
+ do { \
+ setPinInput(XT_DATA_PIN); \
+ writePinHigh(XT_DATA_PIN); \
} while (0)
-#define XT_DATA_READ() (XT_DATA_PIN & (1 << XT_DATA_BIT))
+#define XT_DATA_READ() readPin(XT_DATA_PIN)
-#define XT_DATA_LO() \
- do { \
- XT_DATA_PORT &= ~(1 << XT_DATA_BIT); \
- XT_DATA_DDR |= (1 << XT_DATA_BIT); \
+#define XT_DATA_LO() \
+ do { \
+ writePinLow(XT_DATA_PIN); \
+ setPinOutput(XT_DATA_PIN); \
} while (0)
-#define XT_CLOCK_IN() \
- do { \
- XT_CLOCK_DDR &= ~(1 << XT_CLOCK_BIT); \
- XT_CLOCK_PORT |= (1 << XT_CLOCK_BIT); \
+#define XT_CLOCK_IN() \
+ do { \
+ setPinInput(XT_CLOCK_PIN); \
+ writePinHigh(XT_CLOCK_PIN); \
} while (0)
-#define XT_CLOCK_READ() (XT_CLOCK_PIN & (1 << XT_CLOCK_BIT))
+#define XT_CLOCK_READ() readPin(XT_CLOCK_PIN)
-#define XT_CLOCK_LO() \
- do { \
- XT_CLOCK_PORT &= ~(1 << XT_CLOCK_BIT); \
- XT_CLOCK_DDR |= (1 << XT_CLOCK_BIT); \
+#define XT_CLOCK_LO() \
+ do { \
+ writePinLow(XT_CLOCK_PIN); \
+ setPinOutput(XT_CLOCK_PIN); \
} while (0)
-void xt_host_init(void);
+void xt_host_init(void);
+
uint8_t xt_host_recv(void);
diff --git a/tmk_core/protocol/xt_interrupt.c b/tmk_core/protocol/xt_interrupt.c
index 51e52243fd..ba9d71848f 100644
--- a/tmk_core/protocol/xt_interrupt.c
+++ b/tmk_core/protocol/xt_interrupt.c
@@ -38,7 +38,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include <stdbool.h>
#include <avr/interrupt.h>
-#include <util/delay.h>
#include "xt.h"
#include "wait.h"
#include "debug.h"
@@ -60,7 +59,7 @@ void xt_host_init(void) {
/* soft reset: pull clock line down for 20ms */
XT_DATA_LO();
XT_CLOCK_LO();
- _delay_ms(20);
+ wait_ms(20);
/* input mode with pullup */
XT_CLOCK_IN();
@@ -120,9 +119,10 @@ ISR(XT_INT_VECT) {
* Ring buffer to store scan codes from keyboard
*------------------------------------------------------------------*/
#define PBUF_SIZE 32
-static uint8_t pbuf[PBUF_SIZE];
-static uint8_t pbuf_head = 0;
-static uint8_t pbuf_tail = 0;
+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) {
uint8_t sreg = SREG;
cli();
@@ -135,6 +135,7 @@ static inline void pbuf_enqueue(uint8_t data) {
}
SREG = sreg;
}
+
static inline uint8_t pbuf_dequeue(void) {
uint8_t val = 0;
@@ -148,6 +149,7 @@ static inline uint8_t pbuf_dequeue(void) {
return val;
}
+
static inline bool pbuf_has_data(void) {
uint8_t sreg = SREG;
cli();
@@ -155,6 +157,7 @@ static inline bool pbuf_has_data(void) {
SREG = sreg;
return has_data;
}
+
static inline void pbuf_clear(void) {
uint8_t sreg = SREG;
cli();
diff --git a/tmk_core/readme.md b/tmk_core/readme.md
index 69a4f75e06..a754cfee42 100644
--- a/tmk_core/readme.md
+++ b/tmk_core/readme.md
@@ -67,7 +67,6 @@ Start Your Own Project
#define PRODUCT_ID 0xBEEF
#define MANUFACTURER t.m.k.
#define PRODUCT Macway mod
- #define DESCRIPTION t.m.k. keyboard firmware for Macway mod
#### 2. Keyboard matrix configuration
#define MATRIX_ROWS 8
diff --git a/tmk_core/ring_buffer.h b/tmk_core/ring_buffer.h
deleted file mode 100644
index 8f887c8f74..0000000000
--- a/tmk_core/ring_buffer.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#pragma once
-
-/*--------------------------------------------------------------------
- * Ring buffer to store scan codes from keyboard
- *------------------------------------------------------------------*/
-#ifndef RBUF_SIZE
-# define RBUF_SIZE 32
-#endif
-#include <util/atomic.h>
-#include <stdint.h>
-#include <stdbool.h>
-static uint8_t rbuf[RBUF_SIZE];
-static uint8_t rbuf_head = 0;
-static uint8_t rbuf_tail = 0;
-static inline bool rbuf_enqueue(uint8_t data) {
- bool ret = false;
- ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
- uint8_t next = (rbuf_head + 1) % RBUF_SIZE;
- if (next != rbuf_tail) {
- rbuf[rbuf_head] = data;
- rbuf_head = next;
- ret = true;
- }
- }
- return ret;
-}
-static inline uint8_t rbuf_dequeue(void) {
- uint8_t val = 0;
- ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
- if (rbuf_head != rbuf_tail) {
- val = rbuf[rbuf_tail];
- rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
- }
- }
-
- return val;
-}
-static inline bool rbuf_has_data(void) {
- bool has_data;
- ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { has_data = (rbuf_head != rbuf_tail); }
- return has_data;
-}
-static inline void rbuf_clear(void) {
- ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { rbuf_head = rbuf_tail = 0; }
-}
diff --git a/tmk_core/rules.mk b/tmk_core/rules.mk
index f5f758943e..bbcfc1e4d1 100644
--- a/tmk_core/rules.mk
+++ b/tmk_core/rules.mk
@@ -108,6 +108,10 @@ endif
CFLAGS += -Wa,-adhlns=$(@:%.o=%.lst)
CFLAGS += $(CSTANDARD)
+# This fixes lots of keyboards linking errors but SHOULDN'T BE A FINAL SOLUTION
+# Fixing of multiple variable definitions must be made.
+CFLAGS += -fcommon
+
#---------------- Compiler Options C++ ----------------
# -g*: generate debugging information
# -O*: optimization level
@@ -124,6 +128,7 @@ CXXFLAGS += -O$(OPT)
CXXFLAGS += -w
CXXFLAGS += -Wall
CXXFLAGS += -Wundef
+
ifneq ($(strip $(ALLOW_WARNINGS)), yes)
CXXFLAGS += -Werror
endif