summaryrefslogtreecommitdiff
path: root/tmk_core
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core')
-rw-r--r--tmk_core/common.mk23
-rw-r--r--tmk_core/common/action_util.c58
-rw-r--r--tmk_core/common/action_util.h5
-rw-r--r--tmk_core/common/arm_atsam/_wait.h22
-rw-r--r--tmk_core/common/avr/_wait.h29
-rw-r--r--tmk_core/common/avr/suspend.c4
-rw-r--r--tmk_core/common/bootmagic.c163
-rw-r--r--tmk_core/common/bootmagic.h102
-rw-r--r--tmk_core/common/bootmagic_lite.c49
-rw-r--r--tmk_core/common/chibios/_wait.h55
-rw-r--r--tmk_core/common/chibios/bootloader.c2
-rw-r--r--tmk_core/common/chibios/chibios_config.h7
-rw-r--r--tmk_core/common/chibios/sleep_led.c88
-rw-r--r--tmk_core/common/chibios/suspend.c8
-rw-r--r--tmk_core/common/chibios/wait.c89
-rw-r--r--tmk_core/common/eeconfig.c2
-rw-r--r--tmk_core/common/eeconfig.h14
-rw-r--r--tmk_core/common/keyboard.c16
-rw-r--r--tmk_core/common/magic.c39
-rw-r--r--tmk_core/common/magic.h3
-rw-r--r--tmk_core/common/test/_wait.h22
-rw-r--r--tmk_core/common/usb_util.c29
-rw-r--r--tmk_core/common/usb_util.h22
-rw-r--r--tmk_core/common/wait.h125
-rw-r--r--tmk_core/protocol.mk4
-rw-r--r--tmk_core/protocol/chibios.mk1
-rw-r--r--tmk_core/protocol/chibios/usb_util.c21
-rw-r--r--tmk_core/protocol/lufa.mk1
-rw-r--r--tmk_core/protocol/lufa/usb_util.c34
-rw-r--r--tmk_core/protocol/vusb.mk1
-rw-r--r--tmk_core/protocol/vusb/usb_util.c24
31 files changed, 496 insertions, 566 deletions
diff --git a/tmk_core/common.mk b/tmk_core/common.mk
index 238b3c69fd..2f8f81126a 100644
--- a/tmk_core/common.mk
+++ b/tmk_core/common.mk
@@ -12,6 +12,7 @@ TMK_COMMON_SRC += $(COMMON_DIR)/host.c \
$(COMMON_DIR)/sendchar_null.c \
$(COMMON_DIR)/eeconfig.c \
$(COMMON_DIR)/report.c \
+ $(COMMON_DIR)/usb_util.c \
$(PLATFORM_COMMON_DIR)/suspend.c \
$(PLATFORM_COMMON_DIR)/timer.c \
$(COMMON_DIR)/sync_timer.c \
@@ -24,28 +25,6 @@ else
include $(TMK_PATH)/$(COMMON_DIR)/lib_printf.mk
endif
-# Option modules
-BOOTMAGIC_ENABLE ?= no
-VALID_MAGIC_TYPES := yes full lite
-ifneq ($(strip $(BOOTMAGIC_ENABLE)), no)
- ifeq ($(filter $(BOOTMAGIC_ENABLE),$(VALID_MAGIC_TYPES)),)
- $(error BOOTMAGIC_ENABLE="$(BOOTMAGIC_ENABLE)" is not a valid type of magic)
- endif
- ifeq ($(strip $(BOOTMAGIC_ENABLE)), lite)
- TMK_COMMON_DEFS += -DBOOTMAGIC_LITE
- TMK_COMMON_SRC += $(COMMON_DIR)/bootmagic_lite.c
-
- TMK_COMMON_DEFS += -DMAGIC_ENABLE
- TMK_COMMON_SRC += $(COMMON_DIR)/magic.c
- else
- TMK_COMMON_DEFS += -DBOOTMAGIC_ENABLE
- TMK_COMMON_SRC += $(COMMON_DIR)/bootmagic.c
- endif
-else
- TMK_COMMON_DEFS += -DMAGIC_ENABLE
- TMK_COMMON_SRC += $(COMMON_DIR)/magic.c
-endif
-
SHARED_EP_ENABLE = no
MOUSE_SHARED_EP ?= yes
ifeq ($(strip $(KEYBOARD_SHARED_EP)), yes)
diff --git a/tmk_core/common/action_util.c b/tmk_core/common/action_util.c
index 000503b082..a57c8bf66a 100644
--- a/tmk_core/common/action_util.c
+++ b/tmk_core/common/action_util.c
@@ -147,12 +147,16 @@ void clear_oneshot_swaphands(void) {
* FIXME: needs doc
*/
void set_oneshot_layer(uint8_t layer, uint8_t state) {
- oneshot_layer_data = layer << 3 | state;
- layer_on(layer);
+ if (!keymap_config.oneshot_disable) {
+ oneshot_layer_data = layer << 3 | state;
+ layer_on(layer);
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
- oneshot_layer_time = timer_read();
+ oneshot_layer_time = timer_read();
# endif
- oneshot_layer_changed_kb(get_oneshot_layer());
+ oneshot_layer_changed_kb(get_oneshot_layer());
+ } else {
+ layer_on(layer);
+ }
}
/** \brief Reset oneshot layer
*
@@ -172,7 +176,7 @@ void reset_oneshot_layer(void) {
void clear_oneshot_layer_state(oneshot_fullfillment_t state) {
uint8_t start_state = oneshot_layer_data;
oneshot_layer_data &= ~state;
- if (!get_oneshot_layer_state() && start_state != oneshot_layer_data) {
+ if ((!get_oneshot_layer_state() && start_state != oneshot_layer_data) || keymap_config.oneshot_disable) {
layer_off(get_oneshot_layer());
reset_oneshot_layer();
}
@@ -182,6 +186,39 @@ void clear_oneshot_layer_state(oneshot_fullfillment_t state) {
* FIXME: needs doc
*/
bool is_oneshot_layer_active(void) { return get_oneshot_layer_state(); }
+
+/** \brief set oneshot
+ *
+ * FIXME: needs doc
+ */
+void oneshot_set(bool active) {
+ if (keymap_config.oneshot_disable != active) {
+ keymap_config.oneshot_disable = active;
+ eeconfig_update_keymap(keymap_config.raw);
+ dprintf("Oneshot: active: %d\n", active);
+ }
+}
+
+/** \brief toggle oneshot
+ *
+ * FIXME: needs doc
+ */
+void oneshot_toggle(void) { oneshot_set(!keymap_config.oneshot_disable); }
+
+/** \brief enable oneshot
+ *
+ * FIXME: needs doc
+ */
+void oneshot_enable(void) { oneshot_set(true); }
+
+/** \brief disable oneshot
+ *
+ * FIXME: needs doc
+ */
+void oneshot_disable(void) { oneshot_set(false); }
+
+bool is_oneshot_enabled(void) { return keymap_config.oneshot_disable; }
+
#endif
/** \brief Send keyboard report
@@ -321,14 +358,17 @@ void del_oneshot_mods(uint8_t mods) {
* FIXME: needs doc
*/
void set_oneshot_mods(uint8_t mods) {
- if (oneshot_mods != mods) {
+ if (!keymap_config.oneshot_disable) {
+ if (oneshot_mods != mods) {
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
- oneshot_time = timer_read();
+ oneshot_time = timer_read();
# endif
- oneshot_mods = mods;
- oneshot_mods_changed_kb(mods);
+ oneshot_mods = mods;
+ oneshot_mods_changed_kb(mods);
+ }
}
}
+
/** \brief clear oneshot mods
*
* FIXME: needs doc
diff --git a/tmk_core/common/action_util.h b/tmk_core/common/action_util.h
index ff29f79b09..f2b3897ae5 100644
--- a/tmk_core/common/action_util.h
+++ b/tmk_core/common/action_util.h
@@ -85,6 +85,11 @@ void oneshot_mods_changed_kb(uint8_t mods);
void oneshot_layer_changed_user(uint8_t layer);
void oneshot_layer_changed_kb(uint8_t layer);
+void oneshot_toggle(void);
+void oneshot_enable(void);
+void oneshot_disable(void);
+bool is_oneshot_enabled(void);
+
/* inspect */
uint8_t has_anymod(void);
diff --git a/tmk_core/common/arm_atsam/_wait.h b/tmk_core/common/arm_atsam/_wait.h
new file mode 100644
index 0000000000..41b686b56c
--- /dev/null
+++ b/tmk_core/common/arm_atsam/_wait.h
@@ -0,0 +1,22 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include "clks.h"
+
+#define wait_ms(ms) CLK_delay_ms(ms)
+#define wait_us(us) CLK_delay_us(us)
+#define waitInputPinDelay()
diff --git a/tmk_core/common/avr/_wait.h b/tmk_core/common/avr/_wait.h
new file mode 100644
index 0000000000..56eb316faf
--- /dev/null
+++ b/tmk_core/common/avr/_wait.h
@@ -0,0 +1,29 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include <util/delay.h>
+
+#define wait_ms(ms) _delay_ms(ms)
+#define wait_us(us) _delay_us(us)
+
+/* The AVR series GPIOs have a one clock read delay for changes in the digital input signal.
+ * But here's more margin to make it two clocks. */
+#ifndef GPIO_INPUT_PIN_DELAY
+# define GPIO_INPUT_PIN_DELAY 2
+#endif
+
+#define waitInputPinDelay() __builtin_avr_delay_cycles(GPIO_INPUT_PIN_DELAY)
diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c
index 47a82a2eec..d52c8ac410 100644
--- a/tmk_core/common/avr/suspend.c
+++ b/tmk_core/common/avr/suspend.c
@@ -28,6 +28,10 @@
# include "rgblight.h"
#endif
+#ifdef RGB_MATRIX_ENABLE
+# include "rgb_matrix.h"
+#endif
+
/** \brief Suspend idle
*
* FIXME: needs doc
diff --git a/tmk_core/common/bootmagic.c b/tmk_core/common/bootmagic.c
deleted file mode 100644
index c1b3adf94d..0000000000
--- a/tmk_core/common/bootmagic.c
+++ /dev/null
@@ -1,163 +0,0 @@
-#include <stdint.h>
-#include <stdbool.h>
-#include "wait.h"
-#include "matrix.h"
-#include "bootloader.h"
-#include "debug.h"
-#include "keymap.h"
-#include "host.h"
-#include "action_layer.h"
-#include "eeconfig.h"
-#include "bootmagic.h"
-
-keymap_config_t keymap_config;
-
-/** \brief Bootmagic
- *
- * FIXME: needs doc
- */
-void bootmagic(void) {
- /* check signature */
- if (!eeconfig_is_enabled()) {
- eeconfig_init();
- }
-
- /* do scans in case of bounce */
- print("bootmagic scan: ... ");
- uint8_t scan = 100;
- while (scan--) {
- matrix_scan();
- wait_ms(10);
- }
- print("done.\n");
-
- /* bootmagic skip */
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SKIP)) {
- return;
- }
-
- /* eeconfig clear */
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_EEPROM_CLEAR)) {
- eeconfig_init();
- }
-
- /* bootloader */
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_BOOTLOADER)) {
- bootloader_jump();
- }
-
- /* debug enable */
- debug_config.raw = eeconfig_read_debug();
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_ENABLE)) {
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_MATRIX)) {
- debug_config.matrix = !debug_config.matrix;
- } else if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_KEYBOARD)) {
- debug_config.keyboard = !debug_config.keyboard;
- } else if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_MOUSE)) {
- debug_config.mouse = !debug_config.mouse;
- } else {
- debug_config.enable = !debug_config.enable;
- }
- }
- eeconfig_update_debug(debug_config.raw);
-
- /* keymap config */
- keymap_config.raw = eeconfig_read_keymap();
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK)) {
- keymap_config.swap_control_capslock = !keymap_config.swap_control_capslock;
- }
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL)) {
- keymap_config.capslock_to_control = !keymap_config.capslock_to_control;
- }
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_LALT_LGUI)) {
- keymap_config.swap_lalt_lgui = !keymap_config.swap_lalt_lgui;
- }
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_RALT_RGUI)) {
- keymap_config.swap_ralt_rgui = !keymap_config.swap_ralt_rgui;
- }
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_NO_GUI)) {
- keymap_config.no_gui = !keymap_config.no_gui;
- }
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_GRAVE_ESC)) {
- keymap_config.swap_grave_esc = !keymap_config.swap_grave_esc;
- }
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE)) {
- keymap_config.swap_backslash_backspace = !keymap_config.swap_backslash_backspace;
- }
- if (bootmagic_scan_keycode(BOOTMAGIC_HOST_NKRO)) {
- keymap_config.nkro = !keymap_config.nkro;
- }
- eeconfig_update_keymap(keymap_config.raw);
-
- /* default layer */
- uint8_t default_layer = 0;
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_0)) {
- default_layer |= (1 << 0);
- }
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_1)) {
- default_layer |= (1 << 1);
- }
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_2)) {
- default_layer |= (1 << 2);
- }
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_3)) {
- default_layer |= (1 << 3);
- }
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_4)) {
- default_layer |= (1 << 4);
- }
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_5)) {
- default_layer |= (1 << 5);
- }
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_6)) {
- default_layer |= (1 << 6);
- }
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_7)) {
- default_layer |= (1 << 7);
- }
- if (default_layer) {
- eeconfig_update_default_layer(default_layer);
- default_layer_set((layer_state_t)default_layer);
- } else {
- default_layer = eeconfig_read_default_layer();
- default_layer_set((layer_state_t)default_layer);
- }
- /* Also initialize layer state to trigger callback functions for layer_state */
- layer_state_set_kb((layer_state_t)layer_state);
-
- /* EE_HANDS handedness */
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_EE_HANDS_LEFT)) {
- eeconfig_update_handedness(true);
- }
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_EE_HANDS_RIGHT)) {
- eeconfig_update_handedness(false);
- }
-}
-
-/** \brief Scan Keycode
- *
- * FIXME: needs doc
- */
-static bool scan_keycode(uint8_t keycode) {
- for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
- matrix_row_t matrix_row = matrix_get_row(r);
- for (uint8_t c = 0; c < MATRIX_COLS; c++) {
- if (matrix_row & ((matrix_row_t)1 << c)) {
- if (keycode == keymap_key_to_keycode(0, (keypos_t){.row = r, .col = c})) {
- return true;
- }
- }
- }
- }
- return false;
-}
-
-/** \brief Bootmagic Scan Keycode
- *
- * FIXME: needs doc
- */
-bool bootmagic_scan_keycode(uint8_t keycode) {
- if (!scan_keycode(BOOTMAGIC_KEY_SALT)) return false;
-
- return scan_keycode(keycode);
-}
diff --git a/tmk_core/common/bootmagic.h b/tmk_core/common/bootmagic.h
deleted file mode 100644
index 8209d0194f..0000000000
--- a/tmk_core/common/bootmagic.h
+++ /dev/null
@@ -1,102 +0,0 @@
-#pragma once
-
-/* FIXME: Add special doxygen comments for defines here. */
-
-/* bootmagic salt key */
-#ifndef BOOTMAGIC_KEY_SALT
-# define BOOTMAGIC_KEY_SALT KC_SPACE
-#endif
-
-/* skip bootmagic and eeconfig */
-#ifndef BOOTMAGIC_KEY_SKIP
-# define BOOTMAGIC_KEY_SKIP KC_ESC
-#endif
-
-/* eeprom clear */
-#ifndef BOOTMAGIC_KEY_EEPROM_CLEAR
-# define BOOTMAGIC_KEY_EEPROM_CLEAR KC_BSPACE
-#endif
-
-/* kick up bootloader */
-#ifndef BOOTMAGIC_KEY_BOOTLOADER
-# define BOOTMAGIC_KEY_BOOTLOADER KC_B
-#endif
-
-/* debug enable */
-#ifndef BOOTMAGIC_KEY_DEBUG_ENABLE
-# define BOOTMAGIC_KEY_DEBUG_ENABLE KC_D
-#endif
-#ifndef BOOTMAGIC_KEY_DEBUG_MATRIX
-# define BOOTMAGIC_KEY_DEBUG_MATRIX KC_X
-#endif
-#ifndef BOOTMAGIC_KEY_DEBUG_KEYBOARD
-# define BOOTMAGIC_KEY_DEBUG_KEYBOARD KC_K
-#endif
-#ifndef BOOTMAGIC_KEY_DEBUG_MOUSE
-# define BOOTMAGIC_KEY_DEBUG_MOUSE KC_M
-#endif
-#ifndef BOOTMAGIC_KEY_EE_HANDS_LEFT
-# define BOOTMAGIC_KEY_EE_HANDS_LEFT KC_L
-#endif
-#ifndef BOOTMAGIC_KEY_EE_HANDS_RIGHT
-# define BOOTMAGIC_KEY_EE_HANDS_RIGHT KC_R
-#endif
-
-/*
- * keymap config
- */
-#ifndef BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK
-# define BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK KC_LCTRL
-#endif
-#ifndef BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL
-# define BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL KC_CAPSLOCK
-#endif
-#ifndef BOOTMAGIC_KEY_SWAP_LALT_LGUI
-# define BOOTMAGIC_KEY_SWAP_LALT_LGUI KC_LALT
-#endif
-#ifndef BOOTMAGIC_KEY_SWAP_RALT_RGUI
-# define BOOTMAGIC_KEY_SWAP_RALT_RGUI KC_RALT
-#endif
-#ifndef BOOTMAGIC_KEY_NO_GUI
-# define BOOTMAGIC_KEY_NO_GUI KC_LGUI
-#endif
-#ifndef BOOTMAGIC_KEY_SWAP_GRAVE_ESC
-# define BOOTMAGIC_KEY_SWAP_GRAVE_ESC KC_GRAVE
-#endif
-#ifndef BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE
-# define BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE KC_BSLASH
-#endif
-#ifndef BOOTMAGIC_HOST_NKRO
-# define BOOTMAGIC_HOST_NKRO KC_N
-#endif
-
-/*
- * change default layer
- */
-#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_0
-# define BOOTMAGIC_KEY_DEFAULT_LAYER_0 KC_0
-#endif
-#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_1
-# define BOOTMAGIC_KEY_DEFAULT_LAYER_1 KC_1
-#endif
-#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_2
-# define BOOTMAGIC_KEY_DEFAULT_LAYER_2 KC_2
-#endif
-#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_3
-# define BOOTMAGIC_KEY_DEFAULT_LAYER_3 KC_3
-#endif
-#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_4
-# define BOOTMAGIC_KEY_DEFAULT_LAYER_4 KC_4
-#endif
-#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_5
-# define BOOTMAGIC_KEY_DEFAULT_LAYER_5 KC_5
-#endif
-#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_6
-# define BOOTMAGIC_KEY_DEFAULT_LAYER_6 KC_6
-#endif
-#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_7
-# define BOOTMAGIC_KEY_DEFAULT_LAYER_7 KC_7
-#endif
-
-void bootmagic(void);
-bool bootmagic_scan_keycode(uint8_t keycode);
diff --git a/tmk_core/common/bootmagic_lite.c b/tmk_core/common/bootmagic_lite.c
deleted file mode 100644
index cbf756a175..0000000000
--- a/tmk_core/common/bootmagic_lite.c
+++ /dev/null
@@ -1,49 +0,0 @@
-#include "quantum.h"
-
-/** \brief Reset eeprom
- *
- * ...just incase someone wants to only change the eeprom behaviour
- */
-__attribute__((weak)) void bootmagic_lite_reset_eeprom(void) {
-#if defined(VIA_ENABLE)
- via_eeprom_reset();
-#else
- eeconfig_disable();
-#endif
-}
-
-/** \brief The lite version of TMK's bootmagic based on Wilba.
- *
- * 100% less potential for accidentally making the keyboard do stupid things.
- */
-__attribute__((weak)) void bootmagic_lite(void) {
- // We need multiple scans because debouncing can't be turned off.
- matrix_scan();
-#if defined(DEBOUNCE) && DEBOUNCE > 0
- wait_ms(DEBOUNCE * 2);
-#else
- wait_ms(30);
-#endif
- matrix_scan();
-
- // If the configured key (commonly Esc) is held down on power up,
- // reset the EEPROM valid state and jump to bootloader.
- // This isn't very generalized, but we need something that doesn't
- // rely on user's keymaps in firmware or EEPROM.
- uint8_t row = BOOTMAGIC_LITE_ROW;
- uint8_t col = BOOTMAGIC_LITE_COLUMN;
-
-#if defined(SPLIT_KEYBOARD) && defined(BOOTMAGIC_LITE_ROW_RIGHT) && defined(BOOTMAGIC_LITE_COLUMN_RIGHT)
- if (!is_keyboard_left()) {
- row = BOOTMAGIC_LITE_ROW_RIGHT;
- col = BOOTMAGIC_LITE_COLUMN_RIGHT;
- }
-#endif
-
- if (matrix_get_row(row) & (1 << col)) {
- bootmagic_lite_reset_eeprom();
-
- // Jump to bootloader.
- bootloader_jump();
- }
-}
diff --git a/tmk_core/common/chibios/_wait.h b/tmk_core/common/chibios/_wait.h
new file mode 100644
index 0000000000..5bface53e1
--- /dev/null
+++ b/tmk_core/common/chibios/_wait.h
@@ -0,0 +1,55 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include <ch.h>
+
+/* chThdSleepX of zero maps to infinite - so we map to a tiny delay to still yield */
+#define wait_ms(ms) \
+ do { \
+ if (ms != 0) { \
+ chThdSleepMilliseconds(ms); \
+ } else { \
+ chThdSleepMicroseconds(1); \
+ } \
+ } while (0)
+#define wait_us(us) \
+ do { \
+ if (us != 0) { \
+ chThdSleepMicroseconds(us); \
+ } else { \
+ chThdSleepMicroseconds(1); \
+ } \
+ } while (0)
+
+/* For GPIOs on ARM-based MCUs, the input pins are sampled by the clock of the bus
+ * to which the GPIO is connected.
+ * The connected buses differ depending on the various series of MCUs.
+ * And since the instruction execution clock of the CPU and the bus clock of GPIO are different,
+ * there is a delay of several clocks to read the change of the input signal.
+ *
+ * Define this delay with the GPIO_INPUT_PIN_DELAY macro.
+ * If the GPIO_INPUT_PIN_DELAY macro is not defined, the following default values will be used.
+ * (A fairly large value of 0.25 microseconds is set.)
+ */
+
+#include "wait.c"
+
+#ifndef GPIO_INPUT_PIN_DELAY
+# define GPIO_INPUT_PIN_DELAY (STM32_SYSCLK / 1000000L / 4)
+#endif
+
+#define waitInputPinDelay() wait_cpuclock(GPIO_INPUT_PIN_DELAY)
diff --git a/tmk_core/common/chibios/bootloader.c b/tmk_core/common/chibios/bootloader.c
index 6cabcc4b81..4a175a6283 100644
--- a/tmk_core/common/chibios/bootloader.c
+++ b/tmk_core/common/chibios/bootloader.c
@@ -79,7 +79,7 @@ void enter_bootloader_mode_if_requested(void) {
}
}
-#elif defined(KL2x) || defined(K20x) // STM32_BOOTLOADER_DUAL_BANK // STM32_BOOTLOADER_ADDRESS
+#elif defined(KL2x) || defined(K20x) || defined(MK66F18) // STM32_BOOTLOADER_DUAL_BANK // STM32_BOOTLOADER_ADDRESS
/* Kinetis */
# if defined(BOOTLOADER_KIIBOHD)
diff --git a/tmk_core/common/chibios/chibios_config.h b/tmk_core/common/chibios/chibios_config.h
index b4d96465d1..1d8ace4955 100644
--- a/tmk_core/common/chibios/chibios_config.h
+++ b/tmk_core/common/chibios/chibios_config.h
@@ -15,6 +15,8 @@
*/
#pragma once
+#define SPLIT_USB_DETECT // Force this on for now
+
#if defined(STM32F1XX)
# define USE_GPIOV1
#endif
@@ -28,4 +30,9 @@
# define USE_I2CV1
# define USE_I2CV1_CONTRIB // for some reason a bunch of ChibiOS-Contrib boards only have clock_speed
# define USE_GPIOV1
+# define STM32_SYSCLK KINETIS_SYSCLK_FREQUENCY
+#endif
+
+#if defined(MK66F18)
+# define STM32_SYSCLK KINETIS_SYSCLK_FREQUENCY
#endif
diff --git a/tmk_core/common/chibios/sleep_led.c b/tmk_core/common/chibios/sleep_led.c
index 5595eec0e5..477056a454 100644
--- a/tmk_core/common/chibios/sleep_led.c
+++ b/tmk_core/common/chibios/sleep_led.c
@@ -9,21 +9,13 @@
* Use LP timer on Kinetises, TIM14 on STM32F0.
*/
-#if defined(KL2x) || defined(K20x)
-
-/* Use Low Power Timer (LPTMR) */
-# define TIMER_INTERRUPT_VECTOR KINETIS_LPTMR0_IRQ_VECTOR
-# define RESET_COUNTER LPTMR0->CSR |= LPTMRx_CSR_TCF
-
-#elif defined(STM32F0XX)
-
-/* Use TIM14 manually */
-# define TIMER_INTERRUPT_VECTOR STM32_TIM14_HANDLER
-# define RESET_COUNTER STM32_TIM14->SR &= ~STM32_TIM_SR_UIF
-
+#ifndef SLEEP_LED_GPT_DRIVER
+# if defined(STM32F0XX)
+# define SLEEP_LED_GPT_DRIVER GPTD14
+# endif
#endif
-#if defined(KL2x) || defined(K20x) || defined(STM32F0XX) /* common parts for timers/interrupts */
+#if defined(KL2x) || defined(K20x) || defined(SLEEP_LED_GPT_DRIVER) /* common parts for timers/interrupts */
/* Breathing Sleep LED brighness(PWM On period) table
* (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle
@@ -33,10 +25,7 @@
*/
static const uint8_t breathing_table[64] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10, 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252, 255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23, 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-/* interrupt handler */
-OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) {
- OSAL_IRQ_PROLOGUE();
-
+void sleep_led_timer_callback(void) {
/* Software PWM
* timer:1111 1111 1111 1111
* \_____/\/ \_______/____ count(0-255)
@@ -64,17 +53,16 @@ OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) {
if (timer.pwm.count == breathing_table[timer.pwm.index]) {
led_set(0);
}
-
- /* Reset the counter */
- RESET_COUNTER;
-
- OSAL_IRQ_EPILOGUE();
}
#endif /* common parts for known platforms */
#if defined(KL2x) || defined(K20x) /* platform selection: familiar Kinetis chips */
+/* Use Low Power Timer (LPTMR) */
+# define TIMER_INTERRUPT_VECTOR KINETIS_LPTMR0_IRQ_VECTOR
+# define RESET_COUNTER LPTMR0->CSR |= LPTMRx_CSR_TCF
+
/* LPTMR clock options */
# define LPTMR_CLOCK_MCGIRCLK 0 /* 4MHz clock */
# define LPTMR_CLOCK_LPO 1 /* 1kHz clock */
@@ -86,6 +74,18 @@ OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) {
# define SIM_SCGC5_LPTMR SIM_SCGC5_LPTIMER
# endif
+/* interrupt handler */
+OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) {
+ OSAL_IRQ_PROLOGUE();
+
+ sleep_led_timer_callback();
+
+ /* Reset the counter */
+ RESET_COUNTER;
+
+ OSAL_IRQ_EPILOGUE();
+}
+
/* Initialise the timer */
void sleep_led_init(void) {
/* Make sure the clock to the LPTMR is enabled */
@@ -159,45 +159,23 @@ void sleep_led_toggle(void) {
LPTMR0->CSR ^= LPTMRx_CSR_TEN;
}
-#elif defined(STM32F0XX) /* platform selection: STM32F0XX */
-
-/* Initialise the timer */
-void sleep_led_init(void) {
- /* enable clock */
- rccEnableTIM14(FALSE); /* low power enable = FALSE */
- rccResetTIM14();
-
- /* prescale */
- /* Assuming 48MHz internal clock */
- /* getting cca 65484 irqs/sec */
- STM32_TIM14->PSC = 733;
+#elif defined(SLEEP_LED_GPT_DRIVER)
- /* auto-reload */
- /* 0 => interrupt every time */
- STM32_TIM14->ARR = 3;
+static void gptTimerCallback(GPTDriver *gptp) {
+ (void)gptp;
+ sleep_led_timer_callback();
+}
- /* enable counter update event interrupt */
- STM32_TIM14->DIER |= STM32_TIM_DIER_UIE;
+static const GPTConfig gptcfg = {1000000, gptTimerCallback, 0, 0};
- /* register interrupt vector */
- nvicEnableVector(STM32_TIM14_NUMBER, 2); /* vector, priority */
-}
+/* Initialise the timer */
+void sleep_led_init(void) { gptStart(&SLEEP_LED_GPT_DRIVER, &gptcfg); }
-void sleep_led_enable(void) {
- /* Enable the timer */
- STM32_TIM14->CR1 = STM32_TIM_CR1_CEN | STM32_TIM_CR1_URS;
- /* URS => update event only on overflow; setting UG bit disabled */
-}
+void sleep_led_enable(void) { gptStartContinuous(&SLEEP_LED_GPT_DRIVER, gptcfg.frequency / 0xFFFF); }
-void sleep_led_disable(void) {
- /* Disable the timer */
- STM32_TIM14->CR1 = 0;
-}
+void sleep_led_disable(void) { gptStopTimer(&SLEEP_LED_GPT_DRIVER); }
-void sleep_led_toggle(void) {
- /* Toggle the timer */
- STM32_TIM14->CR1 ^= STM32_TIM_CR1_CEN;
-}
+void sleep_led_toggle(void) { (SLEEP_LED_GPT_DRIVER.state == GPT_READY) ? sleep_led_enable() : sleep_led_disable(); }
#else /* platform selection: not on familiar chips */
diff --git a/tmk_core/common/chibios/suspend.c b/tmk_core/common/chibios/suspend.c
index 49e20641fb..17f024caba 100644
--- a/tmk_core/common/chibios/suspend.c
+++ b/tmk_core/common/chibios/suspend.c
@@ -24,6 +24,10 @@
# include "rgblight.h"
#endif
+#ifdef RGB_MATRIX_ENABLE
+# include "rgb_matrix.h"
+#endif
+
/** \brief suspend idle
*
* FIXME: needs doc
@@ -53,6 +57,10 @@ void suspend_power_down(void) {
backlight_set(0);
#endif
+#ifdef RGB_MATRIX_ENABLE
+ rgb_matrix_task();
+#endif
+
// Turn off LED indicators
uint8_t leds_off = 0;
#if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE)
diff --git a/tmk_core/common/chibios/wait.c b/tmk_core/common/chibios/wait.c
new file mode 100644
index 0000000000..c6270fd95e
--- /dev/null
+++ b/tmk_core/common/chibios/wait.c
@@ -0,0 +1,89 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __OPTIMIZE__
+# pragma message "Compiler optimizations disabled; wait_cpuclock() won't work as designed"
+#endif
+
+#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(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;
+ }
+} \ No newline at end of file
diff --git a/tmk_core/common/eeconfig.c b/tmk_core/common/eeconfig.c
index 5e3ebe6ee6..92a5092176 100644
--- a/tmk_core/common/eeconfig.c
+++ b/tmk_core/common/eeconfig.c
@@ -57,7 +57,7 @@ void eeconfig_init_quantum(void) {
eeprom_update_dword(EECONFIG_HAPTIC, 0);
eeprom_update_byte(EECONFIG_VELOCIKEY, 0);
eeprom_update_dword(EECONFIG_RGB_MATRIX, 0);
- eeprom_update_byte(EECONFIG_RGB_MATRIX_SPEED, 0);
+ eeprom_update_word(EECONFIG_RGB_MATRIX_EXTENDED, 0);
// TODO: Remove once ARM has a way to configure EECONFIG_HANDEDNESS
// within the emulated eeprom via dfu-util or another tool
diff --git a/tmk_core/common/eeconfig.h b/tmk_core/common/eeconfig.h
index 86b9e6f99b..9e18fd4e15 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)0xFEEB // When changing, decrement this value to avoid future re-init issues
+# define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEEA // When changing, decrement this value to avoid future re-init issues
#endif
#define EECONFIG_MAGIC_NUMBER_OFF (uint16_t)0xFFFF
@@ -43,12 +43,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define EECONFIG_VELOCIKEY (uint8_t *)23
#define EECONFIG_HAPTIC (uint32_t *)24
+
+// Mutually exclusive
+#define EECONFIG_LED_MATRIX (uint32_t *)28
#define EECONFIG_RGB_MATRIX (uint32_t *)28
-#define EECONFIG_RGB_MATRIX_SPEED (uint8_t *)32
+// Speed & Flags
+#define EECONFIG_LED_MATRIX_EXTENDED (uint16_t *)32
+#define EECONFIG_RGB_MATRIX_EXTENDED (uint16_t *)32
+
// TODO: Combine these into a single word and single block of EEPROM
-#define EECONFIG_KEYMAP_UPPER_BYTE (uint8_t *)33
+#define EECONFIG_KEYMAP_UPPER_BYTE (uint8_t *)34
// Size of EEPROM being used, other code can refer to this for available EEPROM
-#define EECONFIG_SIZE 34
+#define EECONFIG_SIZE 35
/* debug bit */
#define EECONFIG_DEBUG_ENABLE (1 << 0)
#define EECONFIG_DEBUG_MATRIX (1 << 1)
diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c
index ce3255c069..e473806b21 100644
--- a/tmk_core/common/keyboard.c
+++ b/tmk_core/common/keyboard.c
@@ -34,11 +34,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifdef BACKLIGHT_ENABLE
# include "backlight.h"
#endif
-#ifdef BOOTMAGIC_ENABLE
-# include "bootmagic.h"
-#else
-# include "magic.h"
-#endif
#ifdef MOUSEKEY_ENABLE
# include "mousekey.h"
#endif
@@ -54,6 +49,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifdef RGBLIGHT_ENABLE
# include "rgblight.h"
#endif
+#ifdef LED_MATRIX_ENABLE
+# include "led_matrix.h"
+#endif
#ifdef RGB_MATRIX_ENABLE
# include "rgb_matrix.h"
#endif
@@ -296,11 +294,6 @@ void keyboard_init(void) {
#ifdef ADB_MOUSE_ENABLE
adb_mouse_init();
#endif
-#ifdef BOOTMAGIC_ENABLE
- bootmagic();
-#else
- magic();
-#endif
#ifdef BACKLIGHT_ENABLE
backlight_init();
#endif
@@ -422,6 +415,9 @@ MATRIX_LOOP_END:
rgblight_task();
#endif
+#ifdef LED_MATRIX_ENABLE
+ led_matrix_task();
+#endif
#ifdef RGB_MATRIX_ENABLE
rgb_matrix_task();
#endif
diff --git a/tmk_core/common/magic.c b/tmk_core/common/magic.c
deleted file mode 100644
index e14994164e..0000000000
--- a/tmk_core/common/magic.c
+++ /dev/null
@@ -1,39 +0,0 @@
-#include <stdint.h>
-#include <stdbool.h>
-#if defined(__AVR__)
-# include <util/delay.h>
-#endif
-#include "matrix.h"
-#include "bootloader.h"
-#include "debug.h"
-#include "keymap.h"
-#include "host.h"
-#include "action_layer.h"
-#include "eeconfig.h"
-#include "magic.h"
-
-keymap_config_t keymap_config;
-
-/** \brief Magic
- *
- * FIXME: Needs doc
- */
-void magic(void) {
- /* check signature */
- if (!eeconfig_is_enabled()) {
- eeconfig_init();
- }
-
- /* debug enable */
- debug_config.raw = eeconfig_read_debug();
-
- /* keymap config */
- keymap_config.raw = eeconfig_read_keymap();
-
- uint8_t default_layer = 0;
- default_layer = eeconfig_read_default_layer();
- default_layer_set((layer_state_t)default_layer);
-
- /* Also initialize layer state to trigger callback functions for layer_state */
- layer_state_set_kb((layer_state_t)layer_state);
-}
diff --git a/tmk_core/common/magic.h b/tmk_core/common/magic.h
deleted file mode 100644
index a6552c04dc..0000000000
--- a/tmk_core/common/magic.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-void magic(void);
diff --git a/tmk_core/common/test/_wait.h b/tmk_core/common/test/_wait.h
new file mode 100644
index 0000000000..4e22f593b7
--- /dev/null
+++ b/tmk_core/common/test/_wait.h
@@ -0,0 +1,22 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include <inttypes.h>
+
+void wait_ms(uint32_t ms);
+#define wait_us(us) wait_ms(us / 1000)
+#define waitInputPinDelay()
diff --git a/tmk_core/common/usb_util.c b/tmk_core/common/usb_util.c
new file mode 100644
index 0000000000..e4c50fcb10
--- /dev/null
+++ b/tmk_core/common/usb_util.c
@@ -0,0 +1,29 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "usb_util.h"
+#include "wait.h"
+
+__attribute__((weak)) void usb_disable(void) {}
+__attribute__((weak)) bool usb_connected_state(void) { return true; }
+__attribute__((weak)) bool usb_vbus_state(void) {
+#ifdef USB_VBUS_PIN
+ setPinInput(USB_VBUS_PIN);
+ wait_us(5);
+ return readPin(USB_VBUS_PIN);
+#else
+ return true;
+#endif
+}
diff --git a/tmk_core/common/usb_util.h b/tmk_core/common/usb_util.h
new file mode 100644
index 0000000000..4ebedb1e71
--- /dev/null
+++ b/tmk_core/common/usb_util.h
@@ -0,0 +1,22 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include <stdbool.h>
+
+void usb_disable(void);
+bool usb_connected_state(void);
+bool usb_vbus_state(void);
diff --git a/tmk_core/common/wait.h b/tmk_core/common/wait.h
index 28224fe3aa..cf7180fb07 100644
--- a/tmk_core/common/wait.h
+++ b/tmk_core/common/wait.h
@@ -1,3 +1,18 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
#pragma once
#include <inttypes.h>
@@ -6,114 +21,8 @@
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) \
- do { \
- if (ms != 0) { \
- chThdSleepMilliseconds(ms); \
- } else { \
- chThdSleepMicroseconds(1); \
- } \
- } while (0)
-# define wait_us(us) \
- do { \
- if (us != 0) { \
- chThdSleepMicroseconds(us); \
- } else { \
- chThdSleepMicroseconds(1); \
- } \
- } while (0)
-#elif defined PROTOCOL_ARM_ATSAM
-# include "clks.h"
-# define wait_ms(ms) CLK_delay_ms(ms)
-# define wait_us(us) CLK_delay_us(us)
-#else // Unit tests
-void wait_ms(uint32_t ms);
-# define wait_us(us) wait_ms(us / 1000)
+#if __has_include_next("_wait.h")
+# include_next "_wait.h" /* Include the platforms _wait.h */
#endif
#ifdef __cplusplus
diff --git a/tmk_core/protocol.mk b/tmk_core/protocol.mk
index 0c41642b9b..cc87e83478 100644
--- a/tmk_core/protocol.mk
+++ b/tmk_core/protocol.mk
@@ -54,5 +54,9 @@ ifeq ($(strip $(XT_ENABLE)), yes)
OPT_DEFS += -DXT_ENABLE
endif
+ifeq ($(strip $(USB_HID_ENABLE)), yes)
+ include $(TMK_DIR)/protocol/usb_hid.mk
+endif
+
# Search Path
VPATH += $(TMK_DIR)/protocol
diff --git a/tmk_core/protocol/chibios.mk b/tmk_core/protocol/chibios.mk
index 80554abb32..d01697835b 100644
--- a/tmk_core/protocol/chibios.mk
+++ b/tmk_core/protocol/chibios.mk
@@ -6,6 +6,7 @@ SRC += $(CHIBIOS_DIR)/usb_main.c
SRC += $(CHIBIOS_DIR)/main.c
SRC += usb_descriptor.c
SRC += $(CHIBIOS_DIR)/usb_driver.c
+SRC += $(CHIBIOS_DIR)/usb_util.c
SRC += $(LIBSRC)
VPATH += $(TMK_PATH)/$(PROTOCOL_DIR)
diff --git a/tmk_core/protocol/chibios/usb_util.c b/tmk_core/protocol/chibios/usb_util.c
new file mode 100644
index 0000000000..5945e8a8de
--- /dev/null
+++ b/tmk_core/protocol/chibios/usb_util.c
@@ -0,0 +1,21 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <hal.h>
+#include "usb_util.h"
+
+void usb_disable(void) { usbStop(&USBD1); }
+
+bool usb_connected_state(void) { return usbGetDriverStateI(&USBD1) == USB_ACTIVE; }
diff --git a/tmk_core/protocol/lufa.mk b/tmk_core/protocol/lufa.mk
index 1cc1fa04e5..9d9fb728b1 100644
--- a/tmk_core/protocol/lufa.mk
+++ b/tmk_core/protocol/lufa.mk
@@ -44,6 +44,7 @@ ifeq ($(strip $(VIRTSER_ENABLE)), yes)
endif
SRC += $(LUFA_SRC)
+SRC += $(LUFA_DIR)/usb_util.c
# Search Path
VPATH += $(TMK_PATH)/$(LUFA_DIR)
diff --git a/tmk_core/protocol/lufa/usb_util.c b/tmk_core/protocol/lufa/usb_util.c
new file mode 100644
index 0000000000..9e943a21b9
--- /dev/null
+++ b/tmk_core/protocol/lufa/usb_util.c
@@ -0,0 +1,34 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <LUFA/Drivers/USB/USB.h>
+#include "usb_util.h"
+#include "wait.h"
+
+void usb_disable(void) {
+ USB_Disable();
+ USB_DeviceState = DEVICE_STATE_Unattached;
+}
+
+bool usb_connected_state(void) { return USB_Device_IsAddressSet(); }
+
+#if defined(OTGPADE)
+bool usb_vbus_state(void) {
+ USB_OTGPAD_On(); // enables VBUS pad
+ wait_us(5);
+
+ return USB_VBUS_GetStatus(); // checks state of VBUS
+}
+#endif
diff --git a/tmk_core/protocol/vusb.mk b/tmk_core/protocol/vusb.mk
index 1de6003089..e4d013b38d 100644
--- a/tmk_core/protocol/vusb.mk
+++ b/tmk_core/protocol/vusb.mk
@@ -5,6 +5,7 @@ VUSB_PATH = $(LIB_PATH)/vusb
SRC += $(VUSB_DIR)/main.c \
$(VUSB_DIR)/vusb.c \
+ $(VUSB_DIR)/usb_util.c \
$(VUSB_PATH)/usbdrv/usbdrv.c \
$(VUSB_PATH)/usbdrv/usbdrvasm.S \
$(VUSB_PATH)/usbdrv/oddebug.c
diff --git a/tmk_core/protocol/vusb/usb_util.c b/tmk_core/protocol/vusb/usb_util.c
new file mode 100644
index 0000000000..602854dbe6
--- /dev/null
+++ b/tmk_core/protocol/vusb/usb_util.c
@@ -0,0 +1,24 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <usbdrv/usbdrv.h>
+#include "usb_util.h"
+
+void usb_disable(void) { usbDeviceDisconnect(); }
+
+bool usb_connected_state(void) {
+ usbPoll();
+ return usbConfiguration;
+}