aboutsummaryrefslogtreecommitdiff
path: root/tmk_core/common
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/common')
-rw-r--r--tmk_core/common/action.c26
-rw-r--r--tmk_core/common/avr/bootloader.c10
-rw-r--r--tmk_core/common/avr/suspend.c5
-rw-r--r--tmk_core/common/chibios/suspend.c7
-rw-r--r--tmk_core/common/keyboard.c37
-rw-r--r--tmk_core/common/keyboard.h9
-rw-r--r--tmk_core/common/keycode.h14
-rw-r--r--tmk_core/common/mousekey.c446
-rw-r--r--tmk_core/common/mousekey.h142
-rw-r--r--tmk_core/common/print.h10
-rw-r--r--tmk_core/common/report.h5
-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
17 files changed, 283 insertions, 803 deletions
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index a7432bae5..ef01a7177 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -443,6 +443,15 @@ void process_action(keyrecord_t *record, action_t action) {
443 case KC_MS_BTN5: 443 case KC_MS_BTN5:
444 register_button(true, MOUSE_BTN5); 444 register_button(true, MOUSE_BTN5);
445 break; 445 break;
446 case KC_MS_BTN6:
447 register_button(true, MOUSE_BTN6);
448 break;
449 case KC_MS_BTN7:
450 register_button(true, MOUSE_BTN7);
451 break;
452 case KC_MS_BTN8:
453 register_button(true, MOUSE_BTN8);
454 break;
446# endif 455# endif
447 default: 456 default:
448 mousekey_send(); 457 mousekey_send();
@@ -469,6 +478,15 @@ void process_action(keyrecord_t *record, action_t action) {
469 case KC_MS_BTN5: 478 case KC_MS_BTN5:
470 register_button(false, MOUSE_BTN5); 479 register_button(false, MOUSE_BTN5);
471 break; 480 break;
481 case KC_MS_BTN6:
482 register_button(false, MOUSE_BTN6);
483 break;
484 case KC_MS_BTN7:
485 register_button(false, MOUSE_BTN7);
486 break;
487 case KC_MS_BTN8:
488 register_button(false, MOUSE_BTN8);
489 break;
472# endif 490# endif
473 default: 491 default:
474 mousekey_send(); 492 mousekey_send();
@@ -1017,6 +1035,10 @@ void clear_keyboard_but_mods(void) {
1017 * FIXME: Needs documentation. 1035 * FIXME: Needs documentation.
1018 */ 1036 */
1019void clear_keyboard_but_mods_and_keys() { 1037void clear_keyboard_but_mods_and_keys() {
1038#ifdef EXTRAKEY_ENABLE
1039 host_system_send(0);
1040 host_consumer_send(0);
1041#endif
1020 clear_weak_mods(); 1042 clear_weak_mods();
1021 clear_macro_mods(); 1043 clear_macro_mods();
1022 send_keyboard_report(); 1044 send_keyboard_report();
@@ -1024,10 +1046,6 @@ void clear_keyboard_but_mods_and_keys() {
1024 mousekey_clear(); 1046 mousekey_clear();
1025 mousekey_send(); 1047 mousekey_send();
1026#endif 1048#endif
1027#ifdef EXTRAKEY_ENABLE
1028 host_system_send(0);
1029 host_consumer_send(0);
1030#endif
1031} 1049}
1032 1050
1033/** \brief Utilities for actions. (FIXME: Needs better description) 1051/** \brief Utilities for actions. (FIXME: Needs better description)
diff --git a/tmk_core/common/avr/bootloader.c b/tmk_core/common/avr/bootloader.c
index a1db55da9..4e3a27022 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;")));
77 * 77 *
78 * FIXME: needs doc 78 * FIXME: needs doc
79 */ 79 */
80void bootloader_jump(void) { 80__attribute__((weak)) void bootloader_jump(void) {
81#if !defined(BOOTLOADER_SIZE) 81#if !defined(BOOTLOADER_SIZE)
82 uint8_t high_fuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS); 82 uint8_t high_fuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS);
83 83
@@ -237,13 +237,13 @@ void bootloader_jump(void) {
237 "bootloader_startup_loop%=: \n\t" 237 "bootloader_startup_loop%=: \n\t"
238 "rjmp bootloader_startup_loop%= \n\t" 238 "rjmp bootloader_startup_loop%= \n\t"
239 : 239 :
240 : [mcucsrio] "I"(_SFR_IO_ADDR(MCUCSR)), 240 : [ mcucsrio ] "I"(_SFR_IO_ADDR(MCUCSR)),
241# if (FLASHEND > 131071) 241# if (FLASHEND > 131071)
242 [ramendhi] "M"(((RAMEND - 2) >> 8) & 0xff), [ramendlo] "M"(((RAMEND - 2) >> 0) & 0xff), [bootaddrhi] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 16) & 0xff), 242 [ ramendhi ] "M"(((RAMEND - 2) >> 8) & 0xff), [ ramendlo ] "M"(((RAMEND - 2) >> 0) & 0xff), [ bootaddrhi ] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 16) & 0xff),
243# else 243# else
244 [ramendhi] "M"(((RAMEND - 1) >> 8) & 0xff), [ramendlo] "M"(((RAMEND - 1) >> 0) & 0xff), 244 [ ramendhi ] "M"(((RAMEND - 1) >> 8) & 0xff), [ ramendlo ] "M"(((RAMEND - 1) >> 0) & 0xff),
245# endif 245# endif
246 [bootaddrme] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 8) & 0xff), [bootaddrlo] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 0) & 0xff)); 246 [ bootaddrme ] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 8) & 0xff), [ bootaddrlo ] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 0) & 0xff));
247 247
248#else // Assume remaining boards are DFU, even if the flag isn't set 248#else // Assume remaining boards are DFU, even if the flag isn't set
249 249
diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c
index 86c3df040..b784a0835 100644
--- a/tmk_core/common/avr/suspend.c
+++ b/tmk_core/common/avr/suspend.c
@@ -97,13 +97,11 @@ static void power_down(uint8_t wdto) {
97 led_set(leds_off); 97 led_set(leds_off);
98 98
99# ifdef AUDIO_ENABLE 99# ifdef AUDIO_ENABLE
100 // This sometimes disables the start-up noise, so it's been disabled 100 stop_all_notes();
101 // stop_all_notes();
102# endif /* AUDIO_ENABLE */ 101# endif /* AUDIO_ENABLE */
103# if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) 102# if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
104 rgblight_suspend(); 103 rgblight_suspend();
105# endif 104# endif
106 suspend_power_down_kb();
107 105
108 // TODO: more power saving 106 // TODO: more power saving
109 // See PicoPower application note 107 // See PicoPower application note
@@ -157,6 +155,7 @@ __attribute__((weak)) void suspend_wakeup_init_user(void) {}
157 * FIXME: needs doc 155 * FIXME: needs doc
158 */ 156 */
159__attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); } 157__attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); }
158
160/** \brief run immediately after wakeup 159/** \brief run immediately after wakeup
161 * 160 *
162 * FIXME: needs doc 161 * FIXME: needs doc
diff --git a/tmk_core/common/chibios/suspend.c b/tmk_core/common/chibios/suspend.c
index 796056019..49e20641f 100644
--- a/tmk_core/common/chibios/suspend.c
+++ b/tmk_core/common/chibios/suspend.c
@@ -12,6 +12,10 @@
12#include "led.h" 12#include "led.h"
13#include "wait.h" 13#include "wait.h"
14 14
15#ifdef AUDIO_ENABLE
16# include "audio.h"
17#endif /* AUDIO_ENABLE */
18
15#ifdef BACKLIGHT_ENABLE 19#ifdef BACKLIGHT_ENABLE
16# include "backlight.h" 20# include "backlight.h"
17#endif 21#endif
@@ -65,6 +69,9 @@ void suspend_power_down(void) {
65#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) 69#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
66 rgblight_suspend(); 70 rgblight_suspend();
67#endif 71#endif
72#ifdef AUDIO_ENABLE
73 stop_all_notes();
74#endif /* AUDIO_ENABLE */
68 75
69 suspend_power_down_kb(); 76 suspend_power_down_kb();
70 // on AVR, this enables the watchdog for 15ms (max), and goes to 77 // on AVR, this enables the watchdog for 15ms (max), and goes to
diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c
index 7120cdacd..40989ca4c 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/>.
23#include "led.h" 23#include "led.h"
24#include "keycode.h" 24#include "keycode.h"
25#include "timer.h" 25#include "timer.h"
26#include "sync_timer.h"
26#include "print.h" 27#include "print.h"
27#include "debug.h" 28#include "debug.h"
28#include "command.h" 29#include "command.h"
@@ -96,6 +97,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
96# include "dip_switch.h" 97# include "dip_switch.h"
97#endif 98#endif
98 99
100static uint32_t last_input_modification_time = 0;
101uint32_t last_input_activity_time(void) { return last_input_modification_time; }
102uint32_t last_input_activity_elapsed(void) { return timer_elapsed32(last_input_modification_time); }
103
104static uint32_t last_matrix_modification_time = 0;
105uint32_t last_matrix_activity_time(void) { return last_matrix_modification_time; }
106uint32_t last_matrix_activity_elapsed(void) { return timer_elapsed32(last_matrix_modification_time); }
107void last_matrix_activity_trigger(void) { last_matrix_modification_time = last_input_modification_time = timer_read32(); }
108
109static uint32_t last_encoder_modification_time = 0;
110uint32_t last_encoder_activity_time(void) { return last_encoder_modification_time; }
111uint32_t last_encoder_activity_elapsed(void) { return timer_elapsed32(last_encoder_modification_time); }
112void last_encoder_activity_trigger(void) { last_encoder_modification_time = last_input_modification_time = timer_read32(); }
113
99// Only enable this if console is enabled to print to 114// Only enable this if console is enabled to print to
100#if defined(DEBUG_MATRIX_SCAN_RATE) 115#if defined(DEBUG_MATRIX_SCAN_RATE)
101static uint32_t matrix_timer = 0; 116static uint32_t matrix_timer = 0;
@@ -260,6 +275,7 @@ __attribute__((weak)) void housekeeping_task_user(void) {}
260 */ 275 */
261void keyboard_init(void) { 276void keyboard_init(void) {
262 timer_init(); 277 timer_init();
278 sync_timer_init();
263 matrix_init(); 279 matrix_init();
264#ifdef VIA_ENABLE 280#ifdef VIA_ENABLE
265 via_init(); 281 via_init();
@@ -337,15 +353,15 @@ void keyboard_task(void) {
337#ifdef QMK_KEYS_PER_SCAN 353#ifdef QMK_KEYS_PER_SCAN
338 uint8_t keys_processed = 0; 354 uint8_t keys_processed = 0;
339#endif 355#endif
356#ifdef ENCODER_ENABLE
357 bool encoders_changed = false;
358#endif
340 359
341 housekeeping_task_kb(); 360 housekeeping_task_kb();
342 housekeeping_task_user(); 361 housekeeping_task_user();
343 362
344#if defined(OLED_DRIVER_ENABLE) && !defined(OLED_DISABLE_TIMEOUT) 363 uint8_t matrix_changed = matrix_scan();
345 uint8_t ret = matrix_scan(); 364 if (matrix_changed) last_matrix_activity_trigger();
346#else
347 matrix_scan();
348#endif
349 365
350 if (should_process_keypress()) { 366 if (should_process_keypress()) {
351 for (uint8_t r = 0; r < MATRIX_ROWS; r++) { 367 for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
@@ -401,7 +417,8 @@ MATRIX_LOOP_END:
401#endif 417#endif
402 418
403#ifdef ENCODER_ENABLE 419#ifdef ENCODER_ENABLE
404 encoder_read(); 420 encoders_changed = encoder_read();
421 if (encoders_changed) last_encoder_activity_trigger();
405#endif 422#endif
406 423
407#ifdef QWIIC_ENABLE 424#ifdef QWIIC_ENABLE
@@ -411,8 +428,12 @@ MATRIX_LOOP_END:
411#ifdef OLED_DRIVER_ENABLE 428#ifdef OLED_DRIVER_ENABLE
412 oled_task(); 429 oled_task();
413# ifndef OLED_DISABLE_TIMEOUT 430# ifndef OLED_DISABLE_TIMEOUT
414 // Wake up oled if user is using those fabulous keys! 431 // Wake up oled if user is using those fabulous keys or spinning those encoders!
415 if (ret) oled_on(); 432# ifdef ENCODER_ENABLE
433 if (matrix_changed || encoders_changed) oled_on();
434# else
435 if (matrix_changed) oled_on();
436# endif
416# endif 437# endif
417#endif 438#endif
418 439
diff --git a/tmk_core/common/keyboard.h b/tmk_core/common/keyboard.h
index 70e8f7e2c..eaf74bac5 100644
--- a/tmk_core/common/keyboard.h
+++ b/tmk_core/common/keyboard.h
@@ -73,6 +73,15 @@ void keyboard_post_init_user(void);
73void housekeeping_task_kb(void); 73void housekeeping_task_kb(void);
74void housekeeping_task_user(void); 74void housekeeping_task_user(void);
75 75
76uint32_t last_input_activity_time(void); // Timestamp of the last matrix or encoder activity
77uint32_t last_input_activity_elapsed(void); // Number of milliseconds since the last matrix or encoder activity
78
79uint32_t last_matrix_activity_time(void); // Timestamp of the last matrix activity
80uint32_t last_matrix_activity_elapsed(void); // Number of milliseconds since the last matrix activity
81
82uint32_t last_encoder_activity_time(void); // Timestamp of the last encoder activity
83uint32_t last_encoder_activity_elapsed(void); // Number of milliseconds since the last encoder activity
84
76uint32_t get_matrix_scan_rate(void); 85uint32_t get_matrix_scan_rate(void);
77 86
78#ifdef __cplusplus 87#ifdef __cplusplus
diff --git a/tmk_core/common/keycode.h b/tmk_core/common/keycode.h
index d35e44d8d..efad92b23 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/>.
39 39
40#define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2) 40#define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2)
41#define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT) 41#define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT)
42#define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN5) 42#define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN8)
43#define IS_MOUSEKEY_WHEEL(code) (KC_MS_WH_UP <= (code) && (code) <= KC_MS_WH_RIGHT) 43#define IS_MOUSEKEY_WHEEL(code) (KC_MS_WH_UP <= (code) && (code) <= KC_MS_WH_RIGHT)
44#define IS_MOUSEKEY_ACCEL(code) (KC_MS_ACCEL0 <= (code) && (code) <= KC_MS_ACCEL2) 44#define IS_MOUSEKEY_ACCEL(code) (KC_MS_ACCEL0 <= (code) && (code) <= KC_MS_ACCEL2)
45 45
@@ -205,6 +205,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
205#define KC_BTN3 KC_MS_BTN3 205#define KC_BTN3 KC_MS_BTN3
206#define KC_BTN4 KC_MS_BTN4 206#define KC_BTN4 KC_MS_BTN4
207#define KC_BTN5 KC_MS_BTN5 207#define KC_BTN5 KC_MS_BTN5
208#define KC_BTN6 KC_MS_BTN6
209#define KC_BTN7 KC_MS_BTN7
210#define KC_BTN8 KC_MS_BTN8
208#define KC_WH_U KC_MS_WH_UP 211#define KC_WH_U KC_MS_WH_UP
209#define KC_WH_D KC_MS_WH_DOWN 212#define KC_WH_D KC_MS_WH_DOWN
210#define KC_WH_L KC_MS_WH_LEFT 213#define KC_WH_L KC_MS_WH_LEFT
@@ -521,15 +524,18 @@ enum internal_special_keycodes {
521 524
522enum mouse_keys { 525enum mouse_keys {
523 /* Mouse Buttons */ 526 /* Mouse Buttons */
524 KC_MS_UP = 0xF0, 527 KC_MS_UP = 0xED,
525 KC_MS_DOWN, 528 KC_MS_DOWN,
526 KC_MS_LEFT, 529 KC_MS_LEFT,
527 KC_MS_RIGHT, 530 KC_MS_RIGHT, // 0xF0
528 KC_MS_BTN1, 531 KC_MS_BTN1,
529 KC_MS_BTN2, 532 KC_MS_BTN2,
530 KC_MS_BTN3, 533 KC_MS_BTN3,
531 KC_MS_BTN4, 534 KC_MS_BTN4,
532 KC_MS_BTN5, 535 KC_MS_BTN5,
536 KC_MS_BTN6,
537 KC_MS_BTN7,
538 KC_MS_BTN8,
533 539
534 /* Mouse Wheel */ 540 /* Mouse Wheel */
535 KC_MS_WH_UP, 541 KC_MS_WH_UP,
@@ -540,5 +546,5 @@ enum mouse_keys {
540 /* Acceleration */ 546 /* Acceleration */
541 KC_MS_ACCEL0, 547 KC_MS_ACCEL0,
542 KC_MS_ACCEL1, 548 KC_MS_ACCEL1,
543 KC_MS_ACCEL2 549 KC_MS_ACCEL2 // 0xFF
544}; 550};
diff --git a/tmk_core/common/mousekey.c b/tmk_core/common/mousekey.c
deleted file mode 100644
index ef18bcf1a..000000000
--- a/tmk_core/common/mousekey.c
+++ /dev/null
@@ -1,446 +0,0 @@
1/*
2 * Copyright 2011 Jun Wako <wakojun@gmail.com>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include <stdint.h>
19#include "keycode.h"
20#include "host.h"
21#include "timer.h"
22#include "print.h"
23#include "debug.h"
24#include "mousekey.h"
25
26inline int8_t times_inv_sqrt2(int8_t x) {
27 // 181/256 is pretty close to 1/sqrt(2)
28 // 0.70703125 0.707106781
29 // 1 too small for x=99 and x=198
30 // This ends up being a mult and discard lower 8 bits
31 return (x * 181) >> 8;
32}
33
34static report_mouse_t mouse_report = {0};
35static void mousekey_debug(void);
36static uint8_t mousekey_accel = 0;
37static uint8_t mousekey_repeat = 0;
38static uint8_t mousekey_wheel_repeat = 0;
39
40#ifndef MK_3_SPEED
41
42static uint16_t last_timer_c = 0;
43static uint16_t last_timer_w = 0;
44
45/*
46 * Mouse keys acceleration algorithm
47 * http://en.wikipedia.org/wiki/Mouse_keys
48 *
49 * speed = delta * max_speed * (repeat / time_to_max)**((1000+curve)/1000)
50 */
51/* milliseconds between the initial key press and first repeated motion event (0-2550) */
52uint8_t mk_delay = MOUSEKEY_DELAY / 10;
53/* milliseconds between repeated motion events (0-255) */
54uint8_t mk_interval = MOUSEKEY_INTERVAL;
55/* steady speed (in action_delta units) applied each event (0-255) */
56uint8_t mk_max_speed = MOUSEKEY_MAX_SPEED;
57/* number of events (count) accelerating to steady speed (0-255) */
58uint8_t mk_time_to_max = MOUSEKEY_TIME_TO_MAX;
59/* ramp used to reach maximum pointer speed (NOT SUPPORTED) */
60// int8_t mk_curve = 0;
61/* wheel params */
62/* milliseconds between the initial key press and first repeated motion event (0-2550) */
63uint8_t mk_wheel_delay = MOUSEKEY_WHEEL_DELAY / 10;
64/* milliseconds between repeated motion events (0-255) */
65uint8_t mk_wheel_interval = MOUSEKEY_WHEEL_INTERVAL;
66uint8_t mk_wheel_max_speed = MOUSEKEY_WHEEL_MAX_SPEED;
67uint8_t mk_wheel_time_to_max = MOUSEKEY_WHEEL_TIME_TO_MAX;
68
69# ifndef MK_COMBINED
70
71static uint8_t move_unit(void) {
72 uint16_t unit;
73 if (mousekey_accel & (1 << 0)) {
74 unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed) / 4;
75 } else if (mousekey_accel & (1 << 1)) {
76 unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed) / 2;
77 } else if (mousekey_accel & (1 << 2)) {
78 unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed);
79 } else if (mousekey_repeat == 0) {
80 unit = MOUSEKEY_MOVE_DELTA;
81 } else if (mousekey_repeat >= mk_time_to_max) {
82 unit = MOUSEKEY_MOVE_DELTA * mk_max_speed;
83 } else {
84 unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed * mousekey_repeat) / mk_time_to_max;
85 }
86 return (unit > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : (unit == 0 ? 1 : unit));
87}
88
89static uint8_t wheel_unit(void) {
90 uint16_t unit;
91 if (mousekey_accel & (1 << 0)) {
92 unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed) / 4;
93 } else if (mousekey_accel & (1 << 1)) {
94 unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed) / 2;
95 } else if (mousekey_accel & (1 << 2)) {
96 unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed);
97 } else if (mousekey_wheel_repeat == 0) {
98 unit = MOUSEKEY_WHEEL_DELTA;
99 } else if (mousekey_wheel_repeat >= mk_wheel_time_to_max) {
100 unit = MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed;
101 } else {
102 unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed * mousekey_wheel_repeat) / mk_wheel_time_to_max;
103 }
104 return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit));
105}
106
107# else /* #ifndef MK_COMBINED */
108
109static uint8_t move_unit(void) {
110 uint16_t unit;
111 if (mousekey_accel & (1 << 0)) {
112 unit = 1;
113 } else if (mousekey_accel & (1 << 1)) {
114 unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed) / 2;
115 } else if (mousekey_accel & (1 << 2)) {
116 unit = MOUSEKEY_MOVE_MAX;
117 } else if (mousekey_repeat == 0) {
118 unit = MOUSEKEY_MOVE_DELTA;
119 } else if (mousekey_repeat >= mk_time_to_max) {
120 unit = MOUSEKEY_MOVE_DELTA * mk_max_speed;
121 } else {
122 unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed * mousekey_repeat) / mk_time_to_max;
123 }
124 return (unit > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : (unit == 0 ? 1 : unit));
125}
126
127static uint8_t wheel_unit(void) {
128 uint16_t unit;
129 if (mousekey_accel & (1 << 0)) {
130 unit = 1;
131 } else if (mousekey_accel & (1 << 1)) {
132 unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed) / 2;
133 } else if (mousekey_accel & (1 << 2)) {
134 unit = MOUSEKEY_WHEEL_MAX;
135 } else if (mousekey_repeat == 0) {
136 unit = MOUSEKEY_WHEEL_DELTA;
137 } else if (mousekey_repeat >= mk_wheel_time_to_max) {
138 unit = MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed;
139 } else {
140 unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed * mousekey_repeat) / mk_wheel_time_to_max;
141 }
142 return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit));
143}
144
145# endif /* #ifndef MK_COMBINED */
146
147void mousekey_task(void) {
148 // report cursor and scroll movement independently
149 report_mouse_t const tmpmr = mouse_report;
150
151 mouse_report.x = 0;
152 mouse_report.y = 0;
153 mouse_report.v = 0;
154 mouse_report.h = 0;
155
156 if ((tmpmr.x || tmpmr.y) && timer_elapsed(last_timer_c) > (mousekey_repeat ? mk_interval : mk_delay * 10)) {
157 if (mousekey_repeat != UINT8_MAX) mousekey_repeat++;
158 if (tmpmr.x != 0) mouse_report.x = move_unit() * ((tmpmr.x > 0) ? 1 : -1);
159 if (tmpmr.y != 0) mouse_report.y = move_unit() * ((tmpmr.y > 0) ? 1 : -1);
160
161 /* diagonal move [1/sqrt(2)] */
162 if (mouse_report.x && mouse_report.y) {
163 mouse_report.x = times_inv_sqrt2(mouse_report.x);
164 if (mouse_report.x == 0) {
165 mouse_report.x = 1;
166 }
167 mouse_report.y = times_inv_sqrt2(mouse_report.y);
168 if (mouse_report.y == 0) {
169 mouse_report.y = 1;
170 }
171 }
172 }
173 if ((tmpmr.v || tmpmr.h) && timer_elapsed(last_timer_w) > (mousekey_wheel_repeat ? mk_wheel_interval : mk_wheel_delay * 10)) {
174 if (mousekey_wheel_repeat != UINT8_MAX) mousekey_wheel_repeat++;
175 if (tmpmr.v != 0) mouse_report.v = wheel_unit() * ((tmpmr.v > 0) ? 1 : -1);
176 if (tmpmr.h != 0) mouse_report.h = wheel_unit() * ((tmpmr.h > 0) ? 1 : -1);
177
178 /* diagonal move [1/sqrt(2)] */
179 if (mouse_report.v && mouse_report.h) {
180 mouse_report.v = times_inv_sqrt2(mouse_report.v);
181 if (mouse_report.v == 0) {
182 mouse_report.v = 1;
183 }
184 mouse_report.h = times_inv_sqrt2(mouse_report.h);
185 if (mouse_report.h == 0) {
186 mouse_report.h = 1;
187 }
188 }
189 }
190
191 if (mouse_report.x || mouse_report.y || mouse_report.v || mouse_report.h) mousekey_send();
192 mouse_report = tmpmr;
193}
194
195void mousekey_on(uint8_t code) {
196 if (code == KC_MS_UP)
197 mouse_report.y = move_unit() * -1;
198 else if (code == KC_MS_DOWN)
199 mouse_report.y = move_unit();
200 else if (code == KC_MS_LEFT)
201 mouse_report.x = move_unit() * -1;
202 else if (code == KC_MS_RIGHT)
203 mouse_report.x = move_unit();
204 else if (code == KC_MS_WH_UP)
205 mouse_report.v = wheel_unit();
206 else if (code == KC_MS_WH_DOWN)
207 mouse_report.v = wheel_unit() * -1;
208 else if (code == KC_MS_WH_LEFT)
209 mouse_report.h = wheel_unit() * -1;
210 else if (code == KC_MS_WH_RIGHT)
211 mouse_report.h = wheel_unit();
212 else if (code == KC_MS_BTN1)
213 mouse_report.buttons |= MOUSE_BTN1;
214 else if (code == KC_MS_BTN2)
215 mouse_report.buttons |= MOUSE_BTN2;
216 else if (code == KC_MS_BTN3)
217 mouse_report.buttons |= MOUSE_BTN3;
218 else if (code == KC_MS_BTN4)
219 mouse_report.buttons |= MOUSE_BTN4;
220 else if (code == KC_MS_BTN5)
221 mouse_report.buttons |= MOUSE_BTN5;
222 else if (code == KC_MS_ACCEL0)
223 mousekey_accel |= (1 << 0);
224 else if (code == KC_MS_ACCEL1)
225 mousekey_accel |= (1 << 1);
226 else if (code == KC_MS_ACCEL2)
227 mousekey_accel |= (1 << 2);
228}
229
230void mousekey_off(uint8_t code) {
231 if (code == KC_MS_UP && mouse_report.y < 0)
232 mouse_report.y = 0;
233 else if (code == KC_MS_DOWN && mouse_report.y > 0)
234 mouse_report.y = 0;
235 else if (code == KC_MS_LEFT && mouse_report.x < 0)
236 mouse_report.x = 0;
237 else if (code == KC_MS_RIGHT && mouse_report.x > 0)
238 mouse_report.x = 0;
239 else if (code == KC_MS_WH_UP && mouse_report.v > 0)
240 mouse_report.v = 0;
241 else if (code == KC_MS_WH_DOWN && mouse_report.v < 0)
242 mouse_report.v = 0;
243 else if (code == KC_MS_WH_LEFT && mouse_report.h < 0)
244 mouse_report.h = 0;
245 else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0)
246 mouse_report.h = 0;
247 else if (code == KC_MS_BTN1)
248 mouse_report.buttons &= ~MOUSE_BTN1;
249 else if (code == KC_MS_BTN2)
250 mouse_report.buttons &= ~MOUSE_BTN2;
251 else if (code == KC_MS_BTN3)
252 mouse_report.buttons &= ~MOUSE_BTN3;
253 else if (code == KC_MS_BTN4)
254 mouse_report.buttons &= ~MOUSE_BTN4;
255 else if (code == KC_MS_BTN5)
256 mouse_report.buttons &= ~MOUSE_BTN5;
257 else if (code == KC_MS_ACCEL0)
258 mousekey_accel &= ~(1 << 0);
259 else if (code == KC_MS_ACCEL1)
260 mousekey_accel &= ~(1 << 1);
261 else if (code == KC_MS_ACCEL2)
262 mousekey_accel &= ~(1 << 2);
263 if (mouse_report.x == 0 && mouse_report.y == 0) mousekey_repeat = 0;
264 if (mouse_report.v == 0 && mouse_report.h == 0) mousekey_wheel_repeat = 0;
265}
266
267#else /* #ifndef MK_3_SPEED */
268
269enum { mkspd_unmod, mkspd_0, mkspd_1, mkspd_2, mkspd_COUNT };
270# ifndef MK_MOMENTARY_ACCEL
271static uint8_t mk_speed = mkspd_1;
272# else
273static uint8_t mk_speed = mkspd_unmod;
274static uint8_t mkspd_DEFAULT = mkspd_unmod;
275# endif
276static uint16_t last_timer_c = 0;
277static uint16_t last_timer_w = 0;
278uint16_t c_offsets[mkspd_COUNT] = {MK_C_OFFSET_UNMOD, MK_C_OFFSET_0, MK_C_OFFSET_1, MK_C_OFFSET_2};
279uint16_t c_intervals[mkspd_COUNT] = {MK_C_INTERVAL_UNMOD, MK_C_INTERVAL_0, MK_C_INTERVAL_1, MK_C_INTERVAL_2};
280uint16_t w_offsets[mkspd_COUNT] = {MK_W_OFFSET_UNMOD, MK_W_OFFSET_0, MK_W_OFFSET_1, MK_W_OFFSET_2};
281uint16_t w_intervals[mkspd_COUNT] = {MK_W_INTERVAL_UNMOD, MK_W_INTERVAL_0, MK_W_INTERVAL_1, MK_W_INTERVAL_2};
282
283void mousekey_task(void) {
284 // report cursor and scroll movement independently
285 report_mouse_t const tmpmr = mouse_report;
286 mouse_report.x = 0;
287 mouse_report.y = 0;
288 mouse_report.v = 0;
289 mouse_report.h = 0;
290
291 if ((tmpmr.x || tmpmr.y) && timer_elapsed(last_timer_c) > c_intervals[mk_speed]) {
292 mouse_report.x = tmpmr.x;
293 mouse_report.y = tmpmr.y;
294 }
295 if ((tmpmr.h || tmpmr.v) && timer_elapsed(last_timer_w) > w_intervals[mk_speed]) {
296 mouse_report.v = tmpmr.v;
297 mouse_report.h = tmpmr.h;
298 }
299
300 if (mouse_report.x || mouse_report.y || mouse_report.v || mouse_report.h) mousekey_send();
301 mouse_report = tmpmr;
302}
303
304void adjust_speed(void) {
305 uint16_t const c_offset = c_offsets[mk_speed];
306 uint16_t const w_offset = w_offsets[mk_speed];
307 if (mouse_report.x > 0) mouse_report.x = c_offset;
308 if (mouse_report.x < 0) mouse_report.x = c_offset * -1;
309 if (mouse_report.y > 0) mouse_report.y = c_offset;
310 if (mouse_report.y < 0) mouse_report.y = c_offset * -1;
311 if (mouse_report.h > 0) mouse_report.h = w_offset;
312 if (mouse_report.h < 0) mouse_report.h = w_offset * -1;
313 if (mouse_report.v > 0) mouse_report.v = w_offset;
314 if (mouse_report.v < 0) mouse_report.v = w_offset * -1;
315 // adjust for diagonals
316 if (mouse_report.x && mouse_report.y) {
317 mouse_report.x = times_inv_sqrt2(mouse_report.x);
318 if (mouse_report.x == 0) {
319 mouse_report.x = 1;
320 }
321 mouse_report.y = times_inv_sqrt2(mouse_report.y);
322 if (mouse_report.y == 0) {
323 mouse_report.y = 1;
324 }
325 }
326 if (mouse_report.h && mouse_report.v) {
327 mouse_report.h = times_inv_sqrt2(mouse_report.h);
328 mouse_report.v = times_inv_sqrt2(mouse_report.v);
329 }
330}
331
332void mousekey_on(uint8_t code) {
333 uint16_t const c_offset = c_offsets[mk_speed];
334 uint16_t const w_offset = w_offsets[mk_speed];
335 uint8_t const old_speed = mk_speed;
336 if (code == KC_MS_UP)
337 mouse_report.y = c_offset * -1;
338 else if (code == KC_MS_DOWN)
339 mouse_report.y = c_offset;
340 else if (code == KC_MS_LEFT)
341 mouse_report.x = c_offset * -1;
342 else if (code == KC_MS_RIGHT)
343 mouse_report.x = c_offset;
344 else if (code == KC_MS_WH_UP)
345 mouse_report.v = w_offset;
346 else if (code == KC_MS_WH_DOWN)
347 mouse_report.v = w_offset * -1;
348 else if (code == KC_MS_WH_LEFT)
349 mouse_report.h = w_offset * -1;
350 else if (code == KC_MS_WH_RIGHT)
351 mouse_report.h = w_offset;
352 else if (code == KC_MS_BTN1)
353 mouse_report.buttons |= MOUSE_BTN1;
354 else if (code == KC_MS_BTN2)
355 mouse_report.buttons |= MOUSE_BTN2;
356 else if (code == KC_MS_BTN3)
357 mouse_report.buttons |= MOUSE_BTN3;
358 else if (code == KC_MS_BTN4)
359 mouse_report.buttons |= MOUSE_BTN4;
360 else if (code == KC_MS_BTN5)
361 mouse_report.buttons |= MOUSE_BTN5;
362 else if (code == KC_MS_ACCEL0)
363 mk_speed = mkspd_0;
364 else if (code == KC_MS_ACCEL1)
365 mk_speed = mkspd_1;
366 else if (code == KC_MS_ACCEL2)
367 mk_speed = mkspd_2;
368 if (mk_speed != old_speed) adjust_speed();
369}
370
371void mousekey_off(uint8_t code) {
372# ifdef MK_MOMENTARY_ACCEL
373 uint8_t const old_speed = mk_speed;
374# endif
375 if (code == KC_MS_UP && mouse_report.y < 0)
376 mouse_report.y = 0;
377 else if (code == KC_MS_DOWN && mouse_report.y > 0)
378 mouse_report.y = 0;
379 else if (code == KC_MS_LEFT && mouse_report.x < 0)
380 mouse_report.x = 0;
381 else if (code == KC_MS_RIGHT && mouse_report.x > 0)
382 mouse_report.x = 0;
383 else if (code == KC_MS_WH_UP && mouse_report.v > 0)
384 mouse_report.v = 0;
385 else if (code == KC_MS_WH_DOWN && mouse_report.v < 0)
386 mouse_report.v = 0;
387 else if (code == KC_MS_WH_LEFT && mouse_report.h < 0)
388 mouse_report.h = 0;
389 else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0)
390 mouse_report.h = 0;
391 else if (code == KC_MS_BTN1)
392 mouse_report.buttons &= ~MOUSE_BTN1;
393 else if (code == KC_MS_BTN2)
394 mouse_report.buttons &= ~MOUSE_BTN2;
395 else if (code == KC_MS_BTN3)
396 mouse_report.buttons &= ~MOUSE_BTN3;
397 else if (code == KC_MS_BTN4)
398 mouse_report.buttons &= ~MOUSE_BTN4;
399 else if (code == KC_MS_BTN5)
400 mouse_report.buttons &= ~MOUSE_BTN5;
401# ifdef MK_MOMENTARY_ACCEL
402 else if (code == KC_MS_ACCEL0)
403 mk_speed = mkspd_DEFAULT;
404 else if (code == KC_MS_ACCEL1)
405 mk_speed = mkspd_DEFAULT;
406 else if (code == KC_MS_ACCEL2)
407 mk_speed = mkspd_DEFAULT;
408 if (mk_speed != old_speed) adjust_speed();
409# endif
410}
411
412#endif /* #ifndef MK_3_SPEED */
413
414void mousekey_send(void) {
415 mousekey_debug();
416 uint16_t time = timer_read();
417 if (mouse_report.x || mouse_report.y) last_timer_c = time;
418 if (mouse_report.v || mouse_report.h) last_timer_w = time;
419 host_mouse_send(&mouse_report);
420}
421
422void mousekey_clear(void) {
423 mouse_report = (report_mouse_t){};
424 mousekey_repeat = 0;
425 mousekey_wheel_repeat = 0;
426 mousekey_accel = 0;
427}
428
429static void mousekey_debug(void) {
430 if (!debug_mouse) return;
431 print("mousekey [btn|x y v h](rep/acl): [");
432 phex(mouse_report.buttons);
433 print("|");
434 print_decs(mouse_report.x);
435 print(" ");
436 print_decs(mouse_report.y);
437 print(" ");
438 print_decs(mouse_report.v);
439 print(" ");
440 print_decs(mouse_report.h);
441 print("](");
442 print_dec(mousekey_repeat);
443 print("/");
444 print_dec(mousekey_accel);
445 print(")\n");
446}
diff --git a/tmk_core/common/mousekey.h b/tmk_core/common/mousekey.h
deleted file mode 100644
index 300d262f5..000000000
--- a/tmk_core/common/mousekey.h
+++ /dev/null
@@ -1,142 +0,0 @@
1/*
2Copyright 2011 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20#include <stdbool.h>
21#include "host.h"
22
23#ifndef MK_3_SPEED
24
25/* max value on report descriptor */
26# ifndef MOUSEKEY_MOVE_MAX
27# define MOUSEKEY_MOVE_MAX 127
28# elif MOUSEKEY_MOVE_MAX > 127
29# error MOUSEKEY_MOVE_MAX needs to be smaller than 127
30# endif
31
32# ifndef MOUSEKEY_WHEEL_MAX
33# define MOUSEKEY_WHEEL_MAX 127
34# elif MOUSEKEY_WHEEL_MAX > 127
35# error MOUSEKEY_WHEEL_MAX needs to be smaller than 127
36# endif
37
38# ifndef MOUSEKEY_MOVE_DELTA
39# define MOUSEKEY_MOVE_DELTA 5
40# endif
41# ifndef MOUSEKEY_WHEEL_DELTA
42# define MOUSEKEY_WHEEL_DELTA 1
43# endif
44# ifndef MOUSEKEY_DELAY
45# define MOUSEKEY_DELAY 300
46# endif
47# ifndef MOUSEKEY_INTERVAL
48# define MOUSEKEY_INTERVAL 50
49# endif
50# ifndef MOUSEKEY_MAX_SPEED
51# define MOUSEKEY_MAX_SPEED 10
52# endif
53# ifndef MOUSEKEY_TIME_TO_MAX
54# define MOUSEKEY_TIME_TO_MAX 20
55# endif
56# ifndef MOUSEKEY_WHEEL_DELAY
57# define MOUSEKEY_WHEEL_DELAY 300
58# endif
59# ifndef MOUSEKEY_WHEEL_INTERVAL
60# define MOUSEKEY_WHEEL_INTERVAL 100
61# endif
62# ifndef MOUSEKEY_WHEEL_MAX_SPEED
63# define MOUSEKEY_WHEEL_MAX_SPEED 8
64# endif
65# ifndef MOUSEKEY_WHEEL_TIME_TO_MAX
66# define MOUSEKEY_WHEEL_TIME_TO_MAX 40
67# endif
68
69#else /* #ifndef MK_3_SPEED */
70
71# ifndef MK_C_OFFSET_UNMOD
72# define MK_C_OFFSET_UNMOD 16
73# endif
74# ifndef MK_C_INTERVAL_UNMOD
75# define MK_C_INTERVAL_UNMOD 16
76# endif
77# ifndef MK_C_OFFSET_0
78# define MK_C_OFFSET_0 1
79# endif
80# ifndef MK_C_INTERVAL_0
81# define MK_C_INTERVAL_0 32
82# endif
83# ifndef MK_C_OFFSET_1
84# define MK_C_OFFSET_1 4
85# endif
86# ifndef MK_C_INTERVAL_1
87# define MK_C_INTERVAL_1 16
88# endif
89# ifndef MK_C_OFFSET_2
90# define MK_C_OFFSET_2 32
91# endif
92# ifndef MK_C_INTERVAL_2
93# define MK_C_INTERVAL_2 16
94# endif
95
96# ifndef MK_W_OFFSET_UNMOD
97# define MK_W_OFFSET_UNMOD 1
98# endif
99# ifndef MK_W_INTERVAL_UNMOD
100# define MK_W_INTERVAL_UNMOD 40
101# endif
102# ifndef MK_W_OFFSET_0
103# define MK_W_OFFSET_0 1
104# endif
105# ifndef MK_W_INTERVAL_0
106# define MK_W_INTERVAL_0 360
107# endif
108# ifndef MK_W_OFFSET_1
109# define MK_W_OFFSET_1 1
110# endif
111# ifndef MK_W_INTERVAL_1
112# define MK_W_INTERVAL_1 120
113# endif
114# ifndef MK_W_OFFSET_2
115# define MK_W_OFFSET_2 1
116# endif
117# ifndef MK_W_INTERVAL_2
118# define MK_W_INTERVAL_2 20
119# endif
120
121#endif /* #ifndef MK_3_SPEED */
122
123#ifdef __cplusplus
124extern "C" {
125#endif
126
127extern uint8_t mk_delay;
128extern uint8_t mk_interval;
129extern uint8_t mk_max_speed;
130extern uint8_t mk_time_to_max;
131extern uint8_t mk_wheel_max_speed;
132extern uint8_t mk_wheel_time_to_max;
133
134void mousekey_task(void);
135void mousekey_on(uint8_t code);
136void mousekey_off(uint8_t code);
137void mousekey_clear(void);
138void mousekey_send(void);
139
140#ifdef __cplusplus
141}
142#endif
diff --git a/tmk_core/common/print.h b/tmk_core/common/print.h
index 647a5aa05..35fcad0f4 100644
--- a/tmk_core/common/print.h
+++ b/tmk_core/common/print.h
@@ -258,13 +258,3 @@ extern "C"
258# define print_val_bin_reverse32(v) 258# define print_val_bin_reverse32(v)
259 259
260#endif /* NO_PRINT */ 260#endif /* NO_PRINT */
261
262/* Backward compatiblitly for old name */
263#define pdec(data) print_dec(data)
264#define pdec16(data) print_dec(data)
265#define phex(data) print_hex8(data)
266#define phex16(data) print_hex16(data)
267#define pbin(data) print_bin8(data)
268#define pbin16(data) print_bin16(data)
269#define pbin_reverse(data) print_bin_reverse8(data)
270#define pbin_reverse16(data) print_bin_reverse16(data)
diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h
index 5d7c5b3b2..bcf5cab38 100644
--- a/tmk_core/common/report.h
+++ b/tmk_core/common/report.h
@@ -39,7 +39,10 @@ enum mouse_buttons {
39 MOUSE_BTN2 = (1 << 1), 39 MOUSE_BTN2 = (1 << 1),
40 MOUSE_BTN3 = (1 << 2), 40 MOUSE_BTN3 = (1 << 2),
41 MOUSE_BTN4 = (1 << 3), 41 MOUSE_BTN4 = (1 << 3),
42 MOUSE_BTN5 = (1 << 4) 42 MOUSE_BTN5 = (1 << 4),
43 MOUSE_BTN6 = (1 << 5),
44 MOUSE_BTN7 = (1 << 6),
45 MOUSE_BTN8 = (1 << 7)
43}; 46};
44 47
45/* Consumer Page (0x0C) 48/* Consumer Page (0x0C)
diff --git a/tmk_core/common/suspend.h b/tmk_core/common/suspend.h
index 766df95aa..9d17d984e 100644
--- a/tmk_core/common/suspend.h
+++ b/tmk_core/common/suspend.h
@@ -12,3 +12,7 @@ void suspend_wakeup_init_user(void);
12void suspend_wakeup_init_kb(void); 12void suspend_wakeup_init_kb(void);
13void suspend_power_down_user(void); 13void suspend_power_down_user(void);
14void suspend_power_down_kb(void); 14void suspend_power_down_kb(void);
15
16#ifndef USB_SUSPEND_WAKEUP_DELAY
17# define USB_SUSPEND_WAKEUP_DELAY 200
18#endif
diff --git a/tmk_core/common/sync_timer.c b/tmk_core/common/sync_timer.c
new file mode 100644
index 000000000..de24b463b
--- /dev/null
+++ b/tmk_core/common/sync_timer.c
@@ -0,0 +1,58 @@
1/*
2Copyright (C) 2020 Ryan Caltabiano <https://github.com/XScorpion2>
3
4Permission is hereby granted, free of charge, to any person obtaining a copy of
5this software and associated documentation files (the "Software"), to deal in
6the Software without restriction, including without limitation the rights to
7use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8of the Software, and to permit persons to whom the Software is furnished to do
9so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in all
12copies or substantial portions of the Software.
13
14If you happen to meet one of the copyright holders in a bar you are obligated
15to buy them one pint of beer.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24*/
25
26#include "sync_timer.h"
27#include "keyboard.h"
28
29#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER)
30volatile int32_t sync_timer_ms;
31
32void sync_timer_init(void) { sync_timer_ms = 0; }
33
34void sync_timer_update(uint32_t time) {
35 if (is_keyboard_master()) return;
36 sync_timer_ms = time - timer_read32();
37}
38
39uint16_t sync_timer_read(void) {
40 if (is_keyboard_master()) return timer_read();
41 return sync_timer_read32();
42}
43
44uint32_t sync_timer_read32(void) {
45 if (is_keyboard_master()) return timer_read32();
46 return sync_timer_ms + timer_read32();
47}
48
49uint16_t sync_timer_elapsed(uint16_t last) {
50 if (is_keyboard_master()) return timer_elapsed(last);
51 return TIMER_DIFF_16(sync_timer_read(), last);
52}
53
54uint32_t sync_timer_elapsed32(uint32_t last) {
55 if (is_keyboard_master()) return timer_elapsed32(last);
56 return TIMER_DIFF_32(sync_timer_read32(), last);
57}
58#endif
diff --git a/tmk_core/common/sync_timer.h b/tmk_core/common/sync_timer.h
new file mode 100644
index 000000000..9ddef45bb
--- /dev/null
+++ b/tmk_core/common/sync_timer.h
@@ -0,0 +1,54 @@
1/*
2Copyright (C) 2020 Ryan Caltabiano <https://github.com/XScorpion2>
3
4Permission is hereby granted, free of charge, to any person obtaining a copy of
5this software and associated documentation files (the "Software"), to deal in
6the Software without restriction, including without limitation the rights to
7use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8of the Software, and to permit persons to whom the Software is furnished to do
9so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in all
12copies or substantial portions of the Software.
13
14If you happen to meet one of the copyright holders in a bar you are obligated
15to buy them one pint of beer.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24*/
25
26#pragma once
27
28#include <stdint.h>
29#include "timer.h"
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER)
36void sync_timer_init(void);
37void sync_timer_update(uint32_t time);
38uint16_t sync_timer_read(void);
39uint32_t sync_timer_read32(void);
40uint16_t sync_timer_elapsed(uint16_t last);
41uint32_t sync_timer_elapsed32(uint32_t last);
42#else
43# define sync_timer_init()
44# define sync_timer_clear()
45# define sync_timer_update(t)
46# define sync_timer_read() timer_read()
47# define sync_timer_read32() timer_read32()
48# define sync_timer_elapsed(t) timer_elapsed(t)
49# define sync_timer_elapsed32(t) timer_elapsed32(t)
50#endif
51
52#ifdef __cplusplus
53}
54#endif
diff --git a/tmk_core/common/uart.c b/tmk_core/common/uart.c
deleted file mode 100644
index 150e256c8..000000000
--- a/tmk_core/common/uart.c
+++ /dev/null
@@ -1,172 +0,0 @@
1// TODO: Teensy support(ATMega32u4/AT90USB128)
2// Fixed for Arduino Duemilanove ATmega168p by Jun Wako
3/* UART Example for Teensy USB Development Board
4 * http://www.pjrc.com/teensy/
5 * Copyright (c) 2009 PJRC.COM, LLC
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
25
26// Version 1.0: Initial Release
27// Version 1.1: Add support for Teensy 2.0, minor optimizations
28
29#include <avr/io.h>
30#include <avr/interrupt.h>
31
32#include "uart.h"
33
34#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
35# define UDRn UDR0
36# define UBRRnL UBRR0L
37# define UCSRnA UCSR0A
38# define UCSRnB UCSR0B
39# define UCSRnC UCSR0C
40# define U2Xn U2X0
41# define RXENn RXEN0
42# define TXENn TXEN0
43# define RXCIEn RXCIE0
44# define UCSZn1 UCSZ01
45# define UCSZn0 UCSZ00
46# define UDRIEn UDRIE0
47# define USARTn_UDRE_vect USART_UDRE_vect
48# define USARTn_RX_vect USART_RX_vect
49#elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega32U2__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
50# define UDRn UDR1
51# define UBRRnL UBRR1L
52# define UCSRnA UCSR1A
53# define UCSRnB UCSR1B
54# define UCSRnC UCSR1C
55# define U2Xn U2X1
56# define RXENn RXEN1
57# define TXENn TXEN1
58# define RXCIEn RXCIE1
59# define UCSZn1 UCSZ11
60# define UCSZn0 UCSZ10
61# define UDRIEn UDRIE1
62# define USARTn_UDRE_vect USART1_UDRE_vect
63# define USARTn_RX_vect USART1_RX_vect
64#elif defined(__AVR_ATmega32A__)
65# define UDRn UDR
66# define UBRRnL UBRRL
67# define UCSRnA UCSRA
68# define UCSRnB UCSRB
69# define UCSRnC UCSRC
70# define U2Xn U2X
71# define RXENn RXEN
72# define TXENn TXEN
73# define RXCIEn RXCIE
74# define UCSZn1 UCSZ1
75# define UCSZn0 UCSZ0
76# define UDRIEn UDRIE
77# define USARTn_UDRE_vect USART_UDRE_vect
78# define USARTn_RX_vect USART_RX_vect
79#endif
80
81// These buffers may be any size from 2 to 256 bytes.
82#define RX_BUFFER_SIZE 64
83#define TX_BUFFER_SIZE 256
84
85static volatile uint8_t tx_buffer[TX_BUFFER_SIZE];
86static volatile uint8_t tx_buffer_head;
87static volatile uint8_t tx_buffer_tail;
88static volatile uint8_t rx_buffer[RX_BUFFER_SIZE];
89static volatile uint8_t rx_buffer_head;
90static volatile uint8_t rx_buffer_tail;
91
92// Initialize the UART
93void uart_init(uint32_t baud) {
94 cli();
95 UBRRnL = (F_CPU / 4 / baud - 1) / 2;
96 UCSRnA = (1 << U2Xn);
97 UCSRnB = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn);
98 UCSRnC = (1 << UCSZn1) | (1 << UCSZn0);
99 tx_buffer_head = tx_buffer_tail = 0;
100 rx_buffer_head = rx_buffer_tail = 0;
101 sei();
102}
103
104// Transmit a byte
105void uart_putchar(uint8_t c) {
106 uint8_t i;
107
108 i = tx_buffer_head + 1;
109 if (i >= TX_BUFFER_SIZE) i = 0;
110 // return immediately to avoid deadlock when interrupt is disabled(called from ISR)
111 if (tx_buffer_tail == i && (SREG & (1 << SREG_I)) == 0) return;
112 while (tx_buffer_tail == i)
113 ; // wait until space in buffer
114 // cli();
115 tx_buffer[i] = c;
116 tx_buffer_head = i;
117 UCSRnB = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn) | (1 << UDRIEn);
118 // sei();
119}
120
121// Receive a byte
122uint8_t uart_getchar(void) {
123 uint8_t c, i;
124
125 while (rx_buffer_head == rx_buffer_tail)
126 ; // wait for character
127 i = rx_buffer_tail + 1;
128 if (i >= RX_BUFFER_SIZE) i = 0;
129 c = rx_buffer[i];
130 rx_buffer_tail = i;
131 return c;
132}
133
134// Return the number of bytes waiting in the receive buffer.
135// Call this before uart_getchar() to check if it will need
136// to wait for a byte to arrive.
137uint8_t uart_available(void) {
138 uint8_t head, tail;
139
140 head = rx_buffer_head;
141 tail = rx_buffer_tail;
142 if (head >= tail) return head - tail;
143 return RX_BUFFER_SIZE + head - tail;
144}
145
146// Transmit Interrupt
147ISR(USARTn_UDRE_vect) {
148 uint8_t i;
149
150 if (tx_buffer_head == tx_buffer_tail) {
151 // buffer is empty, disable transmit interrupt
152 UCSRnB = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn);
153 } else {
154 i = tx_buffer_tail + 1;
155 if (i >= TX_BUFFER_SIZE) i = 0;
156 UDRn = tx_buffer[i];
157 tx_buffer_tail = i;
158 }
159}
160
161// Receive Interrupt
162ISR(USARTn_RX_vect) {
163 uint8_t c, i;
164
165 c = UDRn;
166 i = rx_buffer_head + 1;
167 if (i >= RX_BUFFER_SIZE) i = 0;
168 if (i != rx_buffer_tail) {
169 rx_buffer[i] = c;
170 rx_buffer_head = i;
171 }
172}
diff --git a/tmk_core/common/uart.h b/tmk_core/common/uart.h
deleted file mode 100644
index ea247b17b..000000000
--- a/tmk_core/common/uart.h
+++ /dev/null
@@ -1,8 +0,0 @@
1#pragma once
2
3#include <stdint.h>
4
5void uart_init(uint32_t baud);
6void uart_putchar(uint8_t c);
7uint8_t uart_getchar(void);
8uint8_t uart_available(void);
diff --git a/tmk_core/common/wait.h b/tmk_core/common/wait.h
index 89128e9da..28224fe3a 100644
--- a/tmk_core/common/wait.h
+++ b/tmk_core/common/wait.h
@@ -6,10 +6,89 @@
6extern "C" { 6extern "C" {
7#endif 7#endif
8 8
9#if defined(__ARMEL__) || defined(__ARMEB__)
10# ifndef __OPTIMIZE__
11# pragma message "Compiler optimizations disabled; wait_cpuclock() won't work as designed"
12# endif
13
14# define wait_cpuclock(x) wait_cpuclock_allnop(x)
15
16# 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"
17
18__attribute__((always_inline)) static inline void wait_cpuclock_allnop(unsigned int n) { /* n: 1..135 */
19 /* The argument n must be a constant expression.
20 * That way, compiler optimization will remove unnecessary code. */
21 if (n < 1) {
22 return;
23 }
24 if (n > 8) {
25 unsigned int n8 = n / 8;
26 n = n - n8 * 8;
27 switch (n8) {
28 case 16:
29 asm volatile(CLOCK_DELAY_NOP8::: "memory");
30 case 15:
31 asm volatile(CLOCK_DELAY_NOP8::: "memory");
32 case 14:
33 asm volatile(CLOCK_DELAY_NOP8::: "memory");
34 case 13:
35 asm volatile(CLOCK_DELAY_NOP8::: "memory");
36 case 12:
37 asm volatile(CLOCK_DELAY_NOP8::: "memory");
38 case 11:
39 asm volatile(CLOCK_DELAY_NOP8::: "memory");
40 case 10:
41 asm volatile(CLOCK_DELAY_NOP8::: "memory");
42 case 9:
43 asm volatile(CLOCK_DELAY_NOP8::: "memory");
44 case 8:
45 asm volatile(CLOCK_DELAY_NOP8::: "memory");
46 case 7:
47 asm volatile(CLOCK_DELAY_NOP8::: "memory");
48 case 6:
49 asm volatile(CLOCK_DELAY_NOP8::: "memory");
50 case 5:
51 asm volatile(CLOCK_DELAY_NOP8::: "memory");
52 case 4:
53 asm volatile(CLOCK_DELAY_NOP8::: "memory");
54 case 3:
55 asm volatile(CLOCK_DELAY_NOP8::: "memory");
56 case 2:
57 asm volatile(CLOCK_DELAY_NOP8::: "memory");
58 case 1:
59 asm volatile(CLOCK_DELAY_NOP8::: "memory");
60 case 0:
61 break;
62 }
63 }
64 switch (n) {
65 case 8:
66 asm volatile("nop" ::: "memory");
67 case 7:
68 asm volatile("nop" ::: "memory");
69 case 6:
70 asm volatile("nop" ::: "memory");
71 case 5:
72 asm volatile("nop" ::: "memory");
73 case 4:
74 asm volatile("nop" ::: "memory");
75 case 3:
76 asm volatile("nop" ::: "memory");
77 case 2:
78 asm volatile("nop" ::: "memory");
79 case 1:
80 asm volatile("nop" ::: "memory");
81 case 0:
82 break;
83 }
84}
85#endif
86
9#if defined(__AVR__) 87#if defined(__AVR__)
10# include <util/delay.h> 88# include <util/delay.h>
11# define wait_ms(ms) _delay_ms(ms) 89# define wait_ms(ms) _delay_ms(ms)
12# define wait_us(us) _delay_us(us) 90# define wait_us(us) _delay_us(us)
91# define wait_cpuclock(x) __builtin_avr_delay_cycles(x)
13#elif defined PROTOCOL_CHIBIOS 92#elif defined PROTOCOL_CHIBIOS
14# include <ch.h> 93# include <ch.h>
15# define wait_ms(ms) \ 94# define wait_ms(ms) \