summaryrefslogtreecommitdiffstats
path: root/tmk_core/common
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/common')
-rw-r--r--tmk_core/common/action.c37
-rw-r--r--tmk_core/common/action.h5
-rw-r--r--tmk_core/common/action_layer.c12
-rw-r--r--tmk_core/common/action_layer.h29
-rw-r--r--tmk_core/common/action_tapping.c58
-rw-r--r--tmk_core/common/action_tapping.h1
-rw-r--r--tmk_core/common/action_util.c28
-rw-r--r--tmk_core/common/arm_atsam/_timer.h19
-rw-r--r--tmk_core/common/avr/_timer.h19
-rw-r--r--tmk_core/common/avr/gpio.h15
-rw-r--r--tmk_core/common/chibios/_timer.h19
-rw-r--r--tmk_core/common/chibios/bootloader.c5
-rw-r--r--tmk_core/common/chibios/gpio.h16
-rw-r--r--tmk_core/common/debug.c25
-rw-r--r--tmk_core/common/debug.h169
-rw-r--r--tmk_core/common/host.c14
-rw-r--r--tmk_core/common/keyboard.c24
-rw-r--r--tmk_core/common/lib_printf.mk9
-rw-r--r--tmk_core/common/nodebug.h26
-rw-r--r--tmk_core/common/print.h135
-rw-r--r--tmk_core/common/printf.c27
-rw-r--r--tmk_core/common/progmem.h2
-rw-r--r--tmk_core/common/sendchar.h33
-rw-r--r--tmk_core/common/sendchar_null.c19
-rw-r--r--tmk_core/common/sendchar_uart.c23
-rw-r--r--tmk_core/common/sync_timer.c2
-rw-r--r--tmk_core/common/sync_timer.h2
-rw-r--r--tmk_core/common/timer.h20
-rw-r--r--tmk_core/common/usb_util.c2
-rw-r--r--tmk_core/common/usb_util.h2
30 files changed, 297 insertions, 500 deletions
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index bd41d28b66..d19fd2a045 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -55,6 +55,8 @@ __attribute__((weak)) bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrec
__attribute__((weak)) bool get_retro_tapping(uint16_t keycode, keyrecord_t *record) { return false; }
#endif
+__attribute__((weak)) bool pre_process_record_quantum(keyrecord_t *record) { return true; }
+
#ifndef TAP_CODE_DELAY
# define TAP_CODE_DELAY 0
#endif
@@ -106,9 +108,13 @@ void action_exec(keyevent_t event) {
#endif
#ifndef NO_ACTION_TAPPING
- action_tapping_process(record);
+ if (IS_NOEVENT(record.event) || pre_process_record_quantum(&record)) {
+ action_tapping_process(record);
+ }
#else
- process_record(&record);
+ if (IS_NOEVENT(record.event) || pre_process_record_quantum(&record)) {
+ process_record(&record);
+ }
if (!IS_NOEVENT(record.event)) {
dprint("processed: ");
debug_record(record);
@@ -206,7 +212,16 @@ void process_record(keyrecord_t *record) {
}
void process_record_handler(keyrecord_t *record) {
+#ifdef COMBO_ENABLE
+ action_t action;
+ if (record->keycode) {
+ action = action_for_keycode(record->keycode);
+ } else {
+ action = store_or_get_action(record->event.pressed, record->event.key);
+ }
+#else
action_t action = store_or_get_action(record->event.pressed, record->event.key);
+#endif
dprint("ACTION: ");
debug_action(action);
#ifndef NO_ACTION_LAYER
@@ -994,6 +1009,24 @@ bool is_tap_key(keypos_t key) {
*
* FIXME: Needs documentation.
*/
+bool is_tap_record(keyrecord_t *record) {
+#ifdef COMBO_ENABLE
+ action_t action;
+ if (record->keycode) {
+ action = action_for_keycode(record->keycode);
+ } else {
+ action = layer_switch_get_action(record->event.key);
+ }
+#else
+ action_t action = layer_switch_get_action(record->event.key);
+#endif
+ return is_tap_action(action);
+}
+
+/** \brief Utilities for actions. (FIXME: Needs better description)
+ *
+ * FIXME: Needs documentation.
+ */
bool is_tap_action(action_t action) {
switch (action.kind.id) {
case ACT_LMODS_TAP:
diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h
index 8cb4722c6e..3d357b33b8 100644
--- a/tmk_core/common/action.h
+++ b/tmk_core/common/action.h
@@ -53,6 +53,9 @@ typedef struct {
#ifndef NO_ACTION_TAPPING
tap_t tap;
#endif
+#ifdef COMBO_ENABLE
+ uint16_t keycode;
+#endif
} keyrecord_t;
/* Execute action per keyevent */
@@ -60,6 +63,7 @@ void action_exec(keyevent_t event);
/* action for key */
action_t action_for_key(uint8_t layer, keypos_t key);
+action_t action_for_keycode(uint16_t keycode);
/* macro */
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt);
@@ -111,6 +115,7 @@ void clear_keyboard_but_mods(void);
void clear_keyboard_but_mods_and_keys(void);
void layer_switch(uint8_t new_layer);
bool is_tap_key(keypos_t key);
+bool is_tap_record(keyrecord_t *record);
bool is_tap_action(action_t action);
#ifndef NO_ACTION_TAPPING
diff --git a/tmk_core/common/action_layer.c b/tmk_core/common/action_layer.c
index af2d7d964b..ed1a4bd20d 100644
--- a/tmk_core/common/action_layer.c
+++ b/tmk_core/common/action_layer.c
@@ -131,32 +131,32 @@ bool layer_state_cmp(layer_state_t cmp_layer_state, uint8_t layer) {
if (!cmp_layer_state) {
return layer == 0;
}
- return (cmp_layer_state & (1UL << layer)) != 0;
+ return (cmp_layer_state & ((layer_state_t)1 << layer)) != 0;
}
/** \brief Layer move
*
* Turns on the given layer and turn off all other layers
*/
-void layer_move(uint8_t layer) { layer_state_set(1UL << layer); }
+void layer_move(uint8_t layer) { layer_state_set((layer_state_t)1 << layer); }
/** \brief Layer on
*
* Turns on given layer
*/
-void layer_on(uint8_t layer) { layer_state_set(layer_state | (1UL << layer)); }
+void layer_on(uint8_t layer) { layer_state_set(layer_state | ((layer_state_t)1 << layer)); }
/** \brief Layer off
*
* Turns off given layer
*/
-void layer_off(uint8_t layer) { layer_state_set(layer_state & ~(1UL << layer)); }
+void layer_off(uint8_t layer) { layer_state_set(layer_state & ~((layer_state_t)1 << layer)); }
/** \brief Layer invert
*
* Toggle the given layer (set it if it's unset, or unset it if it's set)
*/
-void layer_invert(uint8_t layer) { layer_state_set(layer_state ^ (1UL << layer)); }
+void layer_invert(uint8_t layer) { layer_state_set(layer_state ^ ((layer_state_t)1 << layer)); }
/** \brief Layer or
*
@@ -258,7 +258,7 @@ uint8_t layer_switch_get_layer(keypos_t key) {
layer_state_t layers = layer_state | default_layer_state;
/* check top layer first */
for (int8_t i = MAX_LAYER - 1; i >= 0; i--) {
- if (layers & (1UL << i)) {
+ if (layers & ((layer_state_t)1 << i)) {
action = action_for_key(i, key);
if (action.code != ACTION_TRANSPARENT) {
return i;
diff --git a/tmk_core/common/action_layer.h b/tmk_core/common/action_layer.h
index d72cd3e3a5..b87d096eed 100644
--- a/tmk_core/common/action_layer.h
+++ b/tmk_core/common/action_layer.h
@@ -21,6 +21,29 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "keyboard.h"
#include "action.h"
+#ifdef DYNAMIC_KEYMAP_ENABLE
+# ifndef DYNAMIC_KEYMAP_LAYER_COUNT
+# define DYNAMIC_KEYMAP_LAYER_COUNT 4
+# endif
+# if DYNAMIC_KEYMAP_LAYER_COUNT <= 8
+# ifndef LAYER_STATE_8BIT
+# define LAYER_STATE_8BIT
+# endif
+# elif DYNAMIC_KEYMAP_LAYER_COUNT <= 16
+# ifndef LAYER_STATE_16BIT
+# define LAYER_STATE_16BIT
+# endif
+# else
+# ifndef LAYER_STATE_32BIT
+# define LAYER_STATE_32BIT
+# endif
+# endif
+#endif
+
+#if !defined(LAYER_STATE_8BIT) && !defined(LAYER_STATE_16BIT) && !defined(LAYER_STATE_32BIT)
+# define LAYER_STATE_32BIT
+#endif
+
#if defined(LAYER_STATE_8BIT)
typedef uint8_t layer_state_t;
# define MAX_LAYER_BITS 3
@@ -35,13 +58,15 @@ typedef uint16_t layer_state_t;
# define MAX_LAYER 16
# endif
# define get_highest_layer(state) biton16(state)
-#else
+#elif defined(LAYER_STATE_32BIT)
typedef uint32_t layer_state_t;
# define MAX_LAYER_BITS 5
# ifndef MAX_LAYER
# define MAX_LAYER 32
# endif
# define get_highest_layer(state) biton32(state)
+#else
+# error Layer Mask size not specified. HOW?!
#endif
/*
@@ -92,7 +117,7 @@ layer_state_t layer_state_set_kb(layer_state_t state);
# define layer_state_set(layer)
# define layer_state_is(layer) (layer == 0)
-# define layer_state_cmp(state, layer) (state == 0 ? layer == 0 : (state & 1UL << layer) != 0)
+# define layer_state_cmp(state, layer) (state == 0 ? layer == 0 : (state & (layer_state_t)1 << layer) != 0)
# define layer_debug()
# define layer_clear()
diff --git a/tmk_core/common/action_tapping.c b/tmk_core/common/action_tapping.c
index 56044e096d..36839f9faf 100644
--- a/tmk_core/common/action_tapping.c
+++ b/tmk_core/common/action_tapping.c
@@ -18,11 +18,16 @@
# define IS_TAPPING_PRESSED() (IS_TAPPING() && tapping_key.event.pressed)
# define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed)
# define IS_TAPPING_KEY(k) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (k)))
+#ifndef COMBO_ENABLE
+# define IS_TAPPING_RECORD(r) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (r->event.key)))
+#else
+# define IS_TAPPING_RECORD(r) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (r->event.key)) && tapping_key.keycode == r->keycode)
+#endif
__attribute__((weak)) uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { return TAPPING_TERM; }
# ifdef TAPPING_TERM_PER_KEY
-# define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < get_tapping_term(get_event_keycode(tapping_key.event, false), &tapping_key))
+# define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < get_tapping_term(get_record_keycode(&tapping_key, false), &tapping_key))
# else
# define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < TAPPING_TERM)
# endif
@@ -35,6 +40,10 @@ __attribute__((weak)) bool get_tapping_force_hold(uint16_t keycode, keyrecord_t
__attribute__((weak)) bool get_permissive_hold(uint16_t keycode, keyrecord_t *record) { return false; }
# endif
+# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY
+__attribute__((weak)) bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) { return false; }
+# endif
+
static keyrecord_t tapping_key = {};
static keyrecord_t waiting_buffer[WAITING_BUFFER_SIZE] = {};
static uint8_t waiting_buffer_head = 0;
@@ -103,7 +112,7 @@ bool process_tapping(keyrecord_t *keyp) {
if (IS_TAPPING_PRESSED()) {
if (WITHIN_TAPPING_TERM(event)) {
if (tapping_key.tap.count == 0) {
- if (IS_TAPPING_KEY(event.key) && !event.pressed) {
+ if (IS_TAPPING_RECORD(keyp) && !event.pressed) {
// first tap!
debug("Tapping: First tap(0->1).\n");
tapping_key.tap.count = 1;
@@ -122,14 +131,14 @@ bool process_tapping(keyrecord_t *keyp) {
# if defined(TAPPING_TERM_PER_KEY) || (TAPPING_TERM >= 500) || defined(PERMISSIVE_HOLD) || defined(PERMISSIVE_HOLD_PER_KEY)
else if (((
# ifdef TAPPING_TERM_PER_KEY
- get_tapping_term(get_event_keycode(tapping_key.event, false), keyp)
+ get_tapping_term(get_record_keycode(&tapping_key, false), keyp)
# else
TAPPING_TERM
# endif
>= 500)
# ifdef PERMISSIVE_HOLD_PER_KEY
- || get_permissive_hold(get_event_keycode(tapping_key.event, false), keyp)
+ || get_permissive_hold(get_record_keycode(&tapping_key, false), keyp)
# elif defined(PERMISSIVE_HOLD)
|| true
# endif
@@ -170,6 +179,19 @@ bool process_tapping(keyrecord_t *keyp) {
// set interrupted flag when other key preesed during tapping
if (event.pressed) {
tapping_key.tap.interrupted = true;
+# if defined(HOLD_ON_OTHER_KEY_PRESS) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY)
+# if defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY)
+ if (get_hold_on_other_key_press(get_record_keycode(&tapping_key, false), keyp))
+# endif
+ {
+ debug("Tapping: End. No tap. Interfered by pressed key\n");
+ process_record(&tapping_key);
+ tapping_key = (keyrecord_t){};
+ debug_tapping_key();
+ // enqueue
+ return false;
+ }
+# endif
}
// enqueue
return false;
@@ -177,7 +199,7 @@ bool process_tapping(keyrecord_t *keyp) {
}
// tap_count > 0
else {
- if (IS_TAPPING_KEY(event.key) && !event.pressed) {
+ if (IS_TAPPING_RECORD(keyp) && !event.pressed) {
debug("Tapping: Tap release(");
debug_dec(tapping_key.tap.count);
debug(")\n");
@@ -186,11 +208,15 @@ bool process_tapping(keyrecord_t *keyp) {
tapping_key = *keyp;
debug_tapping_key();
return true;
- } else if (is_tap_key(event.key) && event.pressed) {
+ } else if (is_tap_record(keyp) && event.pressed) {
if (tapping_key.tap.count > 1) {
debug("Tapping: Start new tap with releasing last tap(>1).\n");
// unregister key
- process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false});
+ process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false,
+#ifdef COMBO_ENABLE
+ .keycode = tapping_key.keycode,
+#endif
+ });
} else {
debug("Tapping: Start while last tap(1).\n");
}
@@ -218,17 +244,21 @@ bool process_tapping(keyrecord_t *keyp) {
debug_tapping_key();
return false;
} else {
- if (IS_TAPPING_KEY(event.key) && !event.pressed) {
+ if (IS_TAPPING_RECORD(keyp) && !event.pressed) {
debug("Tapping: End. last timeout tap release(>0).");
keyp->tap = tapping_key.tap;
process_record(keyp);
tapping_key = (keyrecord_t){};
return true;
- } else if (is_tap_key(event.key) && event.pressed) {
+ } else if (is_tap_record(keyp) && event.pressed) {
if (tapping_key.tap.count > 1) {
debug("Tapping: Start new tap with releasing last timeout tap(>1).\n");
// unregister key
- process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false});
+ process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false,
+#ifdef COMBO_ENABLE
+ .keycode = tapping_key.keycode,
+#endif
+ });
} else {
debug("Tapping: Start while last timeout tap(1).\n");
}
@@ -248,12 +278,12 @@ bool process_tapping(keyrecord_t *keyp) {
} else if (IS_TAPPING_RELEASED()) {
if (WITHIN_TAPPING_TERM(event)) {
if (event.pressed) {
- if (IS_TAPPING_KEY(event.key)) {
+ if (IS_TAPPING_RECORD(keyp)) {
//# ifndef TAPPING_FORCE_HOLD
# if !defined(TAPPING_FORCE_HOLD) || defined(TAPPING_FORCE_HOLD_PER_KEY)
if (
# ifdef TAPPING_FORCE_HOLD_PER_KEY
- !get_tapping_force_hold(get_event_keycode(tapping_key.event, false), keyp) &&
+ !get_tapping_force_hold(get_record_keycode(&tapping_key, false), keyp) &&
# endif
!tapping_key.tap.interrupted && tapping_key.tap.count > 0) {
// sequential tap.
@@ -271,7 +301,7 @@ bool process_tapping(keyrecord_t *keyp) {
// FIX: start new tap again
tapping_key = *keyp;
return true;
- } else if (is_tap_key(event.key)) {
+ } else if (is_tap_record(keyp)) {
// Sequential tap can be interfered with other tap key.
debug("Tapping: Start with interfering other tap.\n");
tapping_key = *keyp;
@@ -303,7 +333,7 @@ bool process_tapping(keyrecord_t *keyp) {
}
// not tapping state
else {
- if (event.pressed && is_tap_key(event.key)) {
+ if (event.pressed && is_tap_record(keyp)) {
debug("Tapping: Start(Press tap key).\n");
tapping_key = *keyp;
process_record_tap_hint(&tapping_key);
diff --git a/tmk_core/common/action_tapping.h b/tmk_core/common/action_tapping.h
index 893ccb1ce1..7de8049c7f 100644
--- a/tmk_core/common/action_tapping.h
+++ b/tmk_core/common/action_tapping.h
@@ -30,6 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define WAITING_BUFFER_SIZE 8
#ifndef NO_ACTION_TAPPING
+uint16_t get_record_keycode(keyrecord_t *record, bool update_layer_cache);
uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache);
void action_tapping_process(keyrecord_t record);
diff --git a/tmk_core/common/action_util.c b/tmk_core/common/action_util.c
index a57c8bf66a..2b3c00cba0 100644
--- a/tmk_core/common/action_util.c
+++ b/tmk_core/common/action_util.c
@@ -27,6 +27,10 @@ extern keymap_config_t keymap_config;
static uint8_t real_mods = 0;
static uint8_t weak_mods = 0;
static uint8_t macro_mods = 0;
+#ifdef KEY_OVERRIDE_ENABLE
+static uint8_t weak_override_mods = 0;
+static uint8_t suppressed_mods = 0;
+#endif
#ifdef USB_6KRO_ENABLE
# define RO_ADD(a, b) ((a + b) % KEYBOARD_REPORT_KEYS)
@@ -229,6 +233,7 @@ void send_keyboard_report(void) {
keyboard_report->mods = real_mods;
keyboard_report->mods |= weak_mods;
keyboard_report->mods |= macro_mods;
+
#ifndef NO_ACTION_ONESHOT
if (oneshot_mods) {
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
@@ -244,6 +249,13 @@ void send_keyboard_report(void) {
}
#endif
+
+#ifdef KEY_OVERRIDE_ENABLE
+ // These need to be last to be able to properly control key overrides
+ keyboard_report->mods &= ~suppressed_mods;
+ keyboard_report->mods |= weak_override_mods;
+#endif
+
host_keyboard_send(keyboard_report);
}
@@ -299,6 +311,22 @@ void set_weak_mods(uint8_t mods) { weak_mods = mods; }
*/
void clear_weak_mods(void) { weak_mods = 0; }
+#ifdef KEY_OVERRIDE_ENABLE
+/** \brief set weak mods used by key overrides. DO not call this manually
+ */
+void set_weak_override_mods(uint8_t mods) { weak_override_mods = mods; }
+/** \brief clear weak mods used by key overrides. DO not call this manually
+ */
+void clear_weak_override_mods(void) { weak_override_mods = 0; }
+
+/** \brief set suppressed mods used by key overrides. DO not call this manually
+ */
+void set_suppressed_override_mods(uint8_t mods) { suppressed_mods = mods; }
+/** \brief clear suppressed mods used by key overrides. DO not call this manually
+ */
+void clear_suppressed_override_mods(void) { suppressed_mods = 0; }
+#endif
+
/* macro modifier */
/** \brief get macro mods
*
diff --git a/tmk_core/common/arm_atsam/_timer.h b/tmk_core/common/arm_atsam/_timer.h
new file mode 100644
index 0000000000..77402b612a
--- /dev/null
+++ b/tmk_core/common/arm_atsam/_timer.h
@@ -0,0 +1,19 @@
+/* Copyright 2021 Simon Arlott
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+// The platform is 32-bit, so prefer 32-bit timers to avoid overflow
+#define FAST_TIMER_T_SIZE 32
diff --git a/tmk_core/common/avr/_timer.h b/tmk_core/common/avr/_timer.h
new file mode 100644
index 0000000000..b81e0f68b7
--- /dev/null
+++ b/tmk_core/common/avr/_timer.h
@@ -0,0 +1,19 @@
+/* Copyright 2021 Simon Arlott
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+// The platform is 8-bit, so prefer 16-bit timers to reduce code size
+#define FAST_TIMER_T_SIZE 16
diff --git a/tmk_core/common/avr/gpio.h b/tmk_core/common/avr/gpio.h
index 231556c29c..e9be68491d 100644
--- a/tmk_core/common/avr/gpio.h
+++ b/tmk_core/common/avr/gpio.h
@@ -20,6 +20,8 @@
typedef uint8_t pin_t;
+/* Operation of GPIO by pin. */
+
#define setPinInput(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF))
#define setPinInputHigh(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) |= _BV((pin)&0xF))
#define setPinInputLow(pin) _Static_assert(0, "AVR processors cannot implement an input as pull low")
@@ -32,3 +34,16 @@ typedef uint8_t pin_t;
#define readPin(pin) ((bool)(PINx_ADDRESS(pin) & _BV((pin)&0xF)))
#define togglePin(pin) (PORTx_ADDRESS(pin) ^= _BV((pin)&0xF))
+
+/* Operation of GPIO by port. */
+
+typedef uint8_t port_data_t;
+
+#define readPort(port) PINx_ADDRESS(port)
+
+#define setPortBitInput(port, bit) (DDRx_ADDRESS(port) &= ~_BV((bit)&0xF), PORTx_ADDRESS(port) &= ~_BV((bit)&0xF))
+#define setPortBitInputHigh(port, bit) (DDRx_ADDRESS(port) &= ~_BV((bit)&0xF), PORTx_ADDRESS(port) |= _BV((bit)&0xF))
+#define setPortBitOutput(port, bit) (DDRx_ADDRESS(port) |= _BV((bit)&0xF))
+
+#define writePortBitLow(port, bit) (PORTx_ADDRESS(port) &= ~_BV((bit)&0xF))
+#define writePortBitHigh(port, bit) (PORTx_ADDRESS(port) |= _BV((bit)&0xF))
diff --git a/tmk_core/common/chibios/_timer.h b/tmk_core/common/chibios/_timer.h
new file mode 100644
index 0000000000..77402b612a
--- /dev/null
+++ b/tmk_core/common/chibios/_timer.h
@@ -0,0 +1,19 @@
+/* Copyright 2021 Simon Arlott
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+// The platform is 32-bit, so prefer 32-bit timers to avoid overflow
+#define FAST_TIMER_T_SIZE 32
diff --git a/tmk_core/common/chibios/bootloader.c b/tmk_core/common/chibios/bootloader.c
index 11f7abf432..f9514ee5f3 100644
--- a/tmk_core/common/chibios/bootloader.c
+++ b/tmk_core/common/chibios/bootloader.c
@@ -95,7 +95,7 @@ void enter_bootloader_mode_if_requested(void) {
}
}
-#elif defined(KL2x) || defined(K20x) || defined(MK66F18) // STM32_BOOTLOADER_DUAL_BANK // STM32_BOOTLOADER_ADDRESS
+#elif defined(KL2x) || defined(K20x) || defined(MK66F18) || defined(MIMXRT1062) // STM32_BOOTLOADER_DUAL_BANK // STM32_BOOTLOADER_ADDRESS
/* Kinetis */
# if defined(BOOTLOADER_KIIBOHD)
@@ -103,7 +103,8 @@ void enter_bootloader_mode_if_requested(void) {
# define SCB_AIRCR_VECTKEY_WRITEMAGIC 0x05FA0000
const uint8_t sys_reset_to_loader_magic[] = "\xff\x00\x7fRESET TO LOADER\x7f\x00\xff";
__attribute__((weak)) void bootloader_jump(void) {
- __builtin_memcpy((void *)VBAT, (const void *)sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic));
+ void *volatile vbat = (void *)VBAT;
+ __builtin_memcpy(vbat, (const void *)sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic));
// request reset
SCB->AIRCR = SCB_AIRCR_VECTKEY_WRITEMAGIC | SCB_AIRCR_SYSRESETREQ_Msk;
}
diff --git a/tmk_core/common/chibios/gpio.h b/tmk_core/common/chibios/gpio.h
index 5d0e142abc..4d057f1cab 100644
--- a/tmk_core/common/chibios/gpio.h
+++ b/tmk_core/common/chibios/gpio.h
@@ -20,6 +20,8 @@
typedef ioline_t pin_t;
+/* Operation of GPIO by pin. */
+
#define setPinInput(pin) palSetLineMode(pin, PAL_MODE_INPUT)
#define setPinInputHigh(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLUP)
#define setPinInputLow(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN)
@@ -32,3 +34,17 @@ typedef ioline_t pin_t;
#define readPin(pin) palReadLine(pin)
#define togglePin(pin) palToggleLine(pin)
+
+/* Operation of GPIO by port. */
+
+typedef uint16_t port_data_t;
+
+#define readPort(pin) palReadPort(PAL_PORT(pin))
+
+#define setPortBitInput(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_INPUT)
+#define setPortBitInputHigh(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_INPUT_PULLUP)
+#define setPortBitInputLow(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_INPUT_PULLDOWN)
+#define setPortBitOutput(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_OUTPUT_PUSHPULL)
+
+#define writePortBitLow(pin, bit) palClearLine(PAL_LINE(PAL_PORT(pin), bit))
+#define writePortBitHigh(pin, bit) palSetLine(PAL_LINE(PAL_PORT(pin), bit))
diff --git a/tmk_core/common/debug.c b/tmk_core/common/debug.c
deleted file mode 100644
index ea62deaa8c..0000000000
--- a/tmk_core/common/debug.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-Copyright 2011 Jun Wako <wakojun@gmail.com>
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-#include "debug.h"
-
-debug_config_t debug_config = {
- .enable = false, //
- .matrix = false, //
- .keyboard = false, //
- .mouse = false, //
- .reserved = 0 //
-};
diff --git a/tmk_core/common/debug.h b/tmk_core/common/debug.h
deleted file mode 100644
index 3d2e2315ef..0000000000
--- a/tmk_core/common/debug.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
-Copyright 2011 Jun Wako <wakojun@gmail.com>
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#pragma once
-
-#include <stdbool.h>
-#include "print.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Debug output control
- */
-typedef union {
- struct {
- bool enable : 1;
- bool matrix : 1;
- bool keyboard : 1;
- bool mouse : 1;
- uint8_t reserved : 4;
- };
- uint8_t raw;
-} debug_config_t;
-
-extern debug_config_t debug_config;
-
-#ifdef __cplusplus
-}
-#endif
-
-/* for backward compatibility */
-#define debug_enable (debug_config.enable)
-#define debug_matrix (debug_config.matrix)
-#define debug_keyboard (debug_config.keyboard)
-#define debug_mouse (debug_config.mouse)
-
-/*
- * Debug print utils
- */
-#ifndef NO_DEBUG
-
-# define dprint(s) \
- do { \
- if (debug_enable) print(s); \
- } while (0)
-# define dprintln(s) \
- do { \
- if (debug_enable) println(s); \
- } while (0)
-# define dprintf(fmt, ...) \
- do { \
- if (debug_enable) xprintf(fmt,