summaryrefslogtreecommitdiff
path: root/tmk_core
diff options
context:
space:
mode:
authorNick Brassel <nick@tzarc.org>2021-02-28 07:22:21 +1100
committerNick Brassel <nick@tzarc.org>2021-02-28 07:22:21 +1100
commit1a5f6b54aff179732e3f4f4eb79e47454f0a1eb5 (patch)
treeebf645f55cb0442899c894765b1af4344fb734db /tmk_core
parent804d5c1c5d59d9a12c1d793289ccbd59cb650ec2 (diff)
parent624359b725c9bfe8176cf72cdc2c8bbb7513949f (diff)
2021 February 27 Breaking Changes Update (#12040)
Diffstat (limited to 'tmk_core')
-rw-r--r--tmk_core/chibios.mk4
-rw-r--r--tmk_core/common.mk24
-rw-r--r--tmk_core/common/action.c99
-rw-r--r--tmk_core/common/action.h1
-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.c6
-rw-r--r--tmk_core/common/arm_atsam/printf.mk1
-rw-r--r--tmk_core/common/avr/_print.h33
-rw-r--r--tmk_core/common/avr/bootloader.c2
-rw-r--r--tmk_core/common/avr/pin_defs.h4
-rw-r--r--tmk_core/common/avr/printf.c20
-rw-r--r--tmk_core/common/avr/printf.mk2
-rw-r--r--tmk_core/common/avr/suspend.c4
-rw-r--r--tmk_core/common/chibios/suspend.c7
-rw-r--r--tmk_core/common/debug.c41
-rw-r--r--tmk_core/common/eeconfig.h2
-rw-r--r--tmk_core/common/keyboard.c103
-rw-r--r--tmk_core/common/keyboard.h9
-rw-r--r--tmk_core/common/keycode.h14
-rw-r--r--tmk_core/common/lib_printf.mk9
-rw-r--r--tmk_core/common/mousekey.c446
-rw-r--r--tmk_core/common/mousekey.h142
-rw-r--r--tmk_core/common/print.h301
-rw-r--r--tmk_core/common/printf.c27
-rw-r--r--tmk_core/common/progmem.h1
-rw-r--r--tmk_core/common/report.h14
-rw-r--r--tmk_core/common/sendchar.h2
-rw-r--r--tmk_core/common/suspend.h4
-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/wait.h79
-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.c4
-rw-r--r--tmk_core/protocol/arm_atsam/md_rgb_matrix.c86
-rw-r--r--tmk_core/protocol/arm_atsam/md_rgb_matrix_programs.c8
-rw-r--r--tmk_core/protocol/chibios/main.c3
-rw-r--r--tmk_core/protocol/chibios/usb_main.c95
-rw-r--r--tmk_core/protocol/chibios/usb_main.h11
-rw-r--r--tmk_core/protocol/lufa/lufa.c46
-rw-r--r--tmk_core/protocol/lufa/outputselect.h14
-rw-r--r--tmk_core/protocol/m0110.c8
-rw-r--r--tmk_core/protocol/ps2_mouse.c2
-rw-r--r--tmk_core/protocol/usb_descriptor.c12
-rw-r--r--tmk_core/protocol/vusb/main.c7
-rw-r--r--tmk_core/protocol/vusb/vusb.c10
50 files changed, 972 insertions, 1381 deletions
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 55af71ed6f..238b3c69fd 100644
--- a/tmk_core/common.mk
+++ b/tmk_core/common.mk
@@ -1,5 +1,3 @@
-PRINTF_PATH = $(LIB_PATH)/printf
-
COMMON_DIR = common
PLATFORM_COMMON_DIR = $(COMMON_DIR)/$(PLATFORM_KEY)
@@ -10,26 +8,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)/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
@@ -66,10 +58,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
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index a7432bae59..f53e3c7084 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,16 +76,6 @@ void action_exec(keyevent_t event) {
#endif
}
-#ifdef FAUXCLICKY_ENABLE
- if (IS_PRESSED(event)) {
- FAUXCLICKY_ACTION_PRESS;
- }
- if (IS_RELEASED(event)) {
- FAUXCLICKY_ACTION_RELEASE;
- }
- fauxclicky_check();
-#endif
-
#ifdef SWAP_HANDS_ENABLE
if (!IS_NOEVENT(event)) {
process_hand_swap(&event);
@@ -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,20 +888,25 @@ 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 register.
@@ -1017,6 +974,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 +985,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/print.c b/tmk_core/common/arm_atsam/_print.h
index 07aef0b0eb..a774f5d8d2 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) print(s)
+#define uprintln(s) println(s)
+#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..2cb59706a8 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,5 @@ void console_printf(char *fmt, ...) {
}
#endif // CONSOLE_ENABLE
+
+void print_set_sendchar(sendchar_func_t send) {} \ No newline at end of file
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/avr/_print.h b/tmk_core/common/avr/_print.h
new file mode 100644
index 0000000000..f9b79bdf85
--- /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) print(s)
+#define uprintln(s) println(s)
+#define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__) \ No newline at end of file
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/pin_defs.h b/tmk_core/common/avr/pin_defs.h
index dbfed21f48..23d948041d 100644
--- a/tmk_core/common/avr/pin_defs.h
+++ b/tmk_core/common/avr/pin_defs.h
@@ -29,7 +29,7 @@
# define PIND_ADDRESS 0x9
# define PINE_ADDRESS 0xC
# define PINF_ADDRESS 0xF
-#elif defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
+#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
@@ -125,4 +125,4 @@
# define F5 PINDEF(F, 5)
# define F6 PINDEF(F, 6)
# define F7 PINDEF(F, 7)
-#endif \ No newline at end of file
+#endif
diff --git a/tmk_core/common/avr/printf.c b/tmk_core/common/avr/printf.c
new file mode 100644
index 0000000000..9ad7a38693
--- /dev/null
+++ b/tmk_core/common/avr/printf.c
@@ -0,0 +1,20 @@
+/*
+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 "xprintf.h"
+#include "sendchar.h"
+
+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/suspend.c b/tmk_core/common/avr/suspend.c
index cb505ab329..47a82a2eec 100644
--- a/tmk_core/common/avr/suspend.c
+++ b/tmk_core/common/avr/suspend.c
@@ -148,8 +148,7 @@ void suspend_power_down(void) {
// Turn off audio
# ifdef AUDIO_ENABLE
- // This sometimes disables the start-up noise, so it's been disabled
- // stop_all_notes();
+ stop_all_notes();
# endif
// Turn off underglow
@@ -187,6 +186,7 @@ __attribute__((weak)) void suspend_wakeup_init_user(void) {}
* FIXME: needs doc
*/
__attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); }
+
/** \brief run immediately after wakeup
*
* FIXME: needs doc
diff --git a/tmk_core/common/chibios/suspend.c b/tmk_core/common/chibios/suspend.c
index 796056019f..49e20641fb 100644
--- a/tmk_core/common/chibios/suspend.c
+++ b/tmk_core/common/chibios/suspend.c
@@ -12,6 +12,10 @@
#include "led.h"
#include "wait.h"
+#ifdef AUDIO_ENABLE
+# include "audio.h"
+#endif /* AUDIO_ENABLE */
+
#ifdef BACKLIGHT_ENABLE
# include "backlight.h"
#endif
@@ -65,6 +69,9 @@ void suspend_power_down(void) {
#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
rgblight_suspend();
#endif
+#ifdef AUDIO_ENABLE
+ stop_all_notes();
+#endif /* AUDIO_ENABLE */
suspend_power_down_kb();
// on AVR, this enables the watchdog for 15ms (max), and goes to
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.h b/tmk_core/common/eeconfig.h
index c4f0483913..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)0xFEEC
+# 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/keyboard.c b/tmk_core/common/keyboard.c
index 7120cdacdf..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,6 +97,20 @@ 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;
@@ -217,6 +232,7 @@ void keyboard_setup(void) {
#ifndef NO_JTAG_DISABLE
disable_jtag();
#endif
+ print_set_sendchar(sendchar);
matrix_setup();
keyboard_pre_init_kb();
}
@@ -260,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();
@@ -296,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
@@ -317,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:
@@ -337,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;
}
}
}
@@ -394,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();
@@ -401,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
@@ -411,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 70e8f7e2c7..eaf74bac58 100644
--- a/tmk_core/common/keyboard.h
+++ b/tmk_core/common/keyboard.h
@@ -73,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..efad92b235 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
@@ -521,15 +524,18 @@ enum internal_special_keycodes {
enum mouse_keys {
/* Mouse Buttons */
- KC_MS_UP = 0xF0,
+ KC_MS_UP = 0xED,
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,
+ KC_MS_BTN6,
+ KC_MS_BTN7,
+ KC_MS_BTN8,
/* Mouse Wheel */
KC_MS_WH_UP,
@@ -540,5 +546,5 @@ enum mouse_keys {
/* Acceleration */
KC_MS_ACCEL0,
KC_MS_ACCEL1,
- KC_MS_ACCEL2
+ KC_MS_ACCEL2 // 0xFF
};
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/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/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/common/printf.c b/tmk_core/common/printf.c
new file mode 100644
index 0000000000..e8440e55ee
--- /dev/null
+++ b/tmk_core/common/printf.c
@@ -0,0 +1,27 @@
+/*
+Copyright 2011 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#include <stddef.h>
+#include "sendchar.h"
+
+// bind lib/printf to console interface - sendchar
+
+static int8_t null_sendchar_func(uint8_t c) { return 0; }
+static sendchar_func_t func = null_sendchar_func;
+
+void print_set_sendchar(sendchar_func_t send) { func = send; }
+
+void _putchar(char character) { func(character); }
diff --git a/tmk_core/common/progmem.h b/tmk_core/common/progmem.h
index 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..606a259643 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)
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 766df95aa1..9d17d984ed 100644
--- a/tmk_core/common/suspend.h
+++ b/tmk_core/common/suspend.h
@@ -12,3 +12,7 @@ void suspend_wakeup_init_user(void);
void suspend_wakeup_init_kb(void);
void suspend_power_down_user(void);
void suspend_power_down_kb(void);
+
+#ifndef USB_SUSPEND_WAKEUP_DELAY
+# define USB_SUSPEND_WAKEUP_DELAY 200
+#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/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/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..e4e79d3510 100644
--- a/tmk_core/protocol/arm_atsam/main_arm_atsam.c
+++ b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
@@ -305,10 +305,6 @@ 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 0ea7e38395..609ae047e6 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 "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,21 +296,21 @@ 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)) {
if (rgb_matrix_get_flags() & LED_FLAG_INDICATOR) {
led_buffer[i].r = 255 - led_buffer[i].r;
@@ -327,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
@@ -469,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 \ No newline at end of file
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..92b40b5b85 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 \ No newline at end of file
diff --git a/tmk_core/protocol/chibios/main.c b/tmk_core/protocol/chibios/main.c
index e07c181fc8..63e4c99d21 100644
--- a/tmk_core/protocol/chibios/main.c
+++ b/tmk_core/protocol/chibios/main.c
@@ -163,6 +163,7 @@ int main(void) {
keyboard_setup();
/* Init USB */
+ usb_event_queue_init();
init_usb_driver(&USB_DRIVER);
#ifdef MIDI_ENABLE
@@ -221,6 +222,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 ad489fb916..8adecfa719 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"
@@ -368,6 +369,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) {
@@ -402,9 +466,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.*/
@@ -425,12 +487,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:
@@ -651,6 +708,17 @@ void init_usb_driver(USBDriver *usbp) {
void restart_usb_driver(USBDriver *usbp) {
usbStop(usbp);
usbDisconnectBus(usbp);
+
+#if USB_SUSPEND_WAKEUP_DELAY > 0
+ // Some hubs, kvm switches, and monitors do
+ // weird things, with USB device state bouncing
+ // around wildly on wakeup, yielding race
+ // conditions that can corrupt the keyboard state.
+ //
+ // Pause for a while to let things settle...
+ wait_ms(USB_SUSPEND_WAKEUP_DELAY);
+#endif
+
usbStart(usbp, &usbcfg);
usbConnectBus(usbp);
}
@@ -806,7 +874,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 */
/* ---------------------------------------------------------
@@ -885,15 +953,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 623aa33ff5..f1908b3d07 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -435,7 +435,9 @@ void EVENT_USB_Device_Suspend() {
*/
void EVENT_USB_Device_WakeUp() {
print("[W]");
+#if defined(NO_USB_STARTUP_CHECK)
suspend_wakeup_init();
+#endif
#ifdef SLEEP_LED_ENABLE
sleep_led_disable();
@@ -669,9 +671,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
@@ -684,9 +684,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
@@ -727,9 +724,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);
@@ -744,9 +739,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
@@ -805,9 +797,7 @@ static void send_system(uint16_t data) {
static void send_consumer(uint16_t data) {
#ifdef EXTRAKEY_ENABLE
# 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_consumer_key(data);
# elif MODULE_RN42
@@ -821,9 +811,6 @@ static void send_consumer(uint16_t data) {
serial_send(bitmap & 0xFF);
serial_send((bitmap >> 8) & 0xFF);
# endif
- }
-
- if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
return;
}
# endif
@@ -1023,7 +1010,6 @@ static void setup_usb(void) {
// for Console_Task
USB_Device_EnableSOFEvents();
- print_set_sendchar(sendchar);
}
/** \brief Main
@@ -1073,12 +1059,26 @@ int main(void) {
print("Keyboard start.\n");
while (1) {
#if !defined(NO_USB_STARTUP_CHECK)
- while (USB_DeviceState == DEVICE_STATE_Suspended) {
+ if (USB_DeviceState == DEVICE_STATE_Suspended) {
print("[s]");
- suspend_power_down();
- if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
- USB_Device_SendRemoteWakeup();
+ while (USB_DeviceState == DEVICE_STATE_Suspended) {
+ suspend_power_down();
+ if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
+ USB_Device_SendRemoteWakeup();
+ clear_keyboard();
+
+# if USB_SUSPEND_WAKEUP_DELAY > 0
+ // Some hubs, kvm switches, and monitors do
+ // weird things, with USB device state bouncing
+ // around wildly on wakeup, yielding race
+ // conditions that can corrupt the keyboard state.
+ //
+ // Pause for a while to let things settle...
+ wait_ms(USB_SUSPEND_WAKEUP_DELAY);
+# endif
+ }
}
+ suspend_wakeup_init();
}
#endif
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/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/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c
index 7ea4b2e37c..ba7760f283 100644
--- a/tmk_core/protocol/usb_descriptor.c
+++ b/tmk_core/protocol/usb_descriptor.c
@@ -116,19 +116,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
@@ -356,7 +352,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = {
.Type = DTYPE_Device
},
.USBSpecification = VERSION_BCD(1, 1, 0),
-
+
#if VIRTSER_ENABLE
.Class = USB_CSCP_IADDeviceClass,
.SubClass = USB_CSCP_IADDeviceSubclass,
diff --git a/tmk_core/protocol/vusb/main.c b/tmk_core/protocol/vusb/main.c
index af64f4e561..4095979e93 100644
--- a/tmk_core/protocol/vusb/main.c
+++ b/tmk_core/protocol/vusb/main.c
@@ -95,12 +95,7 @@ static void vusb_wakeup(void) {
*
* FIXME: Needs doc
*/
-static void setup_usb(void) {
- initForUsbConnectivity();
-
- // for Console_Task
- print_set_sendchar(sendchar);
-}
+static void setup_usb(void) { initForUsbConnectivity(); }
/** \brief Main
*
diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c
index a422903ccf..9362fbde78 100644
--- a/tmk_core/protocol/vusb/vusb.c
+++ b/tmk_core/protocol/vusb/vusb.c
@@ -444,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)