aboutsummaryrefslogtreecommitdiff
path: root/tmk_core/common
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/common')
-rw-r--r--tmk_core/common/avr/bootloader.c10
-rw-r--r--tmk_core/common/keyboard.c37
-rw-r--r--tmk_core/common/keyboard.h9
-rw-r--r--tmk_core/common/matrix.h3
-rw-r--r--tmk_core/common/mousekey.c80
-rw-r--r--tmk_core/common/mousekey.h43
-rw-r--r--tmk_core/common/sync_timer.c58
-rw-r--r--tmk_core/common/sync_timer.h54
-rw-r--r--tmk_core/common/wait.h79
9 files changed, 354 insertions, 19 deletions
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/keyboard.c b/tmk_core/common/keyboard.c
index 8c7bdc8b5..0ca454612 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) && defined(CONSOLE_ENABLE) 115#if defined(DEBUG_MATRIX_SCAN_RATE) && defined(CONSOLE_ENABLE)
101static uint32_t matrix_timer = 0; 116static uint32_t matrix_timer = 0;
@@ -255,6 +270,7 @@ __attribute__((weak)) void housekeeping_task_user(void) {}
255 */ 270 */
256void keyboard_init(void) { 271void keyboard_init(void) {
257 timer_init(); 272 timer_init();
273 sync_timer_init();
258 matrix_init(); 274 matrix_init();
259#ifdef VIA_ENABLE 275#ifdef VIA_ENABLE
260 via_init(); 276 via_init();
@@ -332,15 +348,15 @@ void keyboard_task(void) {
332#ifdef QMK_KEYS_PER_SCAN 348#ifdef QMK_KEYS_PER_SCAN
333 uint8_t keys_processed = 0; 349 uint8_t keys_processed = 0;
334#endif 350#endif
351#ifdef ENCODER_ENABLE
352 bool encoders_changed = false;
353#endif
335 354
336 housekeeping_task_kb(); 355 housekeeping_task_kb();
337 housekeeping_task_user(); 356 housekeeping_task_user();
338 357
339#if defined(OLED_DRIVER_ENABLE) && !defined(OLED_DISABLE_TIMEOUT) 358 uint8_t matrix_changed = matrix_scan();
340 uint8_t ret = matrix_scan(); 359 if (matrix_changed) last_matrix_activity_trigger();
341#else
342 matrix_scan();
343#endif
344 360
345 if (should_process_keypress()) { 361 if (should_process_keypress()) {
346 for (uint8_t r = 0; r < MATRIX_ROWS; r++) { 362 for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
@@ -396,7 +412,8 @@ MATRIX_LOOP_END:
396#endif 412#endif
397 413
398#ifdef ENCODER_ENABLE 414#ifdef ENCODER_ENABLE
399 encoder_read(); 415 encoders_changed = encoder_read();
416 if (encoders_changed) last_encoder_activity_trigger();
400#endif 417#endif
401 418
402#ifdef QWIIC_ENABLE 419#ifdef QWIIC_ENABLE
@@ -406,8 +423,12 @@ MATRIX_LOOP_END:
406#ifdef OLED_DRIVER_ENABLE 423#ifdef OLED_DRIVER_ENABLE
407 oled_task(); 424 oled_task();
408# ifndef OLED_DISABLE_TIMEOUT 425# ifndef OLED_DISABLE_TIMEOUT
409 // Wake up oled if user is using those fabulous keys! 426 // Wake up oled if user is using those fabulous keys or spinning those encoders!
410 if (ret) oled_on(); 427# ifdef ENCODER_ENABLE
428 if (matrix_changed || encoders_changed) oled_on();
429# else
430 if (matrix_changed) oled_on();
431# endif
411# endif 432# endif
412#endif 433#endif
413 434
diff --git a/tmk_core/common/keyboard.h b/tmk_core/common/keyboard.h
index d04e685cd..88b3896e9 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
76#ifdef __cplusplus 85#ifdef __cplusplus
77} 86}
78#endif 87#endif
diff --git a/tmk_core/common/matrix.h b/tmk_core/common/matrix.h
index b570227a3..ce57010a4 100644
--- a/tmk_core/common/matrix.h
+++ b/tmk_core/common/matrix.h
@@ -55,6 +55,9 @@ matrix_row_t matrix_get_row(uint8_t row);
55/* print matrix for debug */ 55/* print matrix for debug */
56void matrix_print(void); 56void matrix_print(void);
57/* delay between changing matrix pin state and reading values */ 57/* delay between changing matrix pin state and reading values */
58void matrix_output_select_delay(void);
59void matrix_output_unselect_delay(void);
60/* only for backwards compatibility. delay between changing matrix pin state and reading values */
58void matrix_io_delay(void); 61void matrix_io_delay(void);
59 62
60/* power control */ 63/* power control */
diff --git a/tmk_core/common/mousekey.c b/tmk_core/common/mousekey.c
index ef18bcf1a..6c9df6723 100644
--- a/tmk_core/common/mousekey.c
+++ b/tmk_core/common/mousekey.c
@@ -36,6 +36,9 @@ static void mousekey_debug(void);
36static uint8_t mousekey_accel = 0; 36static uint8_t mousekey_accel = 0;
37static uint8_t mousekey_repeat = 0; 37static uint8_t mousekey_repeat = 0;
38static uint8_t mousekey_wheel_repeat = 0; 38static uint8_t mousekey_wheel_repeat = 0;
39#ifdef MK_KINETIC_SPEED
40static uint16_t mouse_timer = 0;
41#endif
39 42
40#ifndef MK_3_SPEED 43#ifndef MK_3_SPEED
41 44
@@ -43,7 +46,7 @@ static uint16_t last_timer_c = 0;
43static uint16_t last_timer_w = 0; 46static uint16_t last_timer_w = 0;
44 47
45/* 48/*
46 * Mouse keys acceleration algorithm 49 * Mouse keys acceleration algorithm
47 * http://en.wikipedia.org/wiki/Mouse_keys 50 * http://en.wikipedia.org/wiki/Mouse_keys
48 * 51 *
49 * speed = delta * max_speed * (repeat / time_to_max)**((1000+curve)/1000) 52 * speed = delta * max_speed * (repeat / time_to_max)**((1000+curve)/1000)
@@ -105,6 +108,65 @@ static uint8_t wheel_unit(void) {
105} 108}
106 109
107# else /* #ifndef MK_COMBINED */ 110# else /* #ifndef MK_COMBINED */
111# ifndef MK_KINETIC_SPEED
112
113/*
114 * Kinetic movement acceleration algorithm
115 *
116 * current speed = I + A * T/50 + A * 0.5 * T^2 | maximum B
117 *
118 * T: time since the mouse movement started
119 * E: mouse events per second (set through MOUSEKEY_INTERVAL, UHK sends 250, the
120 * pro micro on my Signum 3.0 sends only 125!)
121 * I: initial speed at time 0
122 * A: acceleration
123 * B: base mouse travel speed
124 */
125const uint16_t mk_accelerated_speed = MOUSEKEY_ACCELERATED_SPEED;
126const uint16_t mk_base_speed = MOUSEKEY_BASE_SPEED;
127const uint16_t mk_decelerated_speed = MOUSEKEY_DECELERATED_SPEED;
128const uint16_t mk_initial_speed = MOUSEKEY_INITIAL_SPEED;
129
130static uint8_t move_unit(void) {
131 float speed = mk_initial_speed;
132
133 if (mousekey_accel & ((1 << 0) | (1 << 2))) {
134 speed = mousekey_accel & (1 << 2) ? mk_accelerated_speed : mk_decelerated_speed;
135 } else if (mousekey_repeat && mouse_timer) {
136 const float time_elapsed = timer_elapsed(mouse_timer) / 50;
137 speed = mk_initial_speed + MOUSEKEY_MOVE_DELTA * time_elapsed + MOUSEKEY_MOVE_DELTA * 0.5 * time_elapsed * time_elapsed;
138
139 speed = speed > mk_base_speed ? mk_base_speed : speed;
140 }
141
142 /* convert speed to USB mouse speed 1 to 127 */
143 speed = (uint8_t)(speed / (1000.0f / mk_interval));
144 speed = speed < 1 ? 1 : speed;
145
146 return speed > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : speed;
147}
148
149float mk_wheel_interval = 1000.0f / MOUSEKEY_WHEEL_INITIAL_MOVEMENTS;
150
151static uint8_t wheel_unit(void) {
152 float speed = MOUSEKEY_WHEEL_INITIAL_MOVEMENTS;
153
154 if (mousekey_accel & ((1 << 0) | (1 << 2))) {
155 speed = mousekey_accel & (1 << 2) ? MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS : MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS;
156 } else if (mousekey_repeat && mouse_timer) {
157 if (mk_wheel_interval != MOUSEKEY_WHEEL_BASE_MOVEMENTS) {
158 const float time_elapsed = timer_elapsed(mouse_timer) / 50;
159 speed = MOUSEKEY_WHEEL_INITIAL_MOVEMENTS + 1 * time_elapsed + 1 * 0.5 * time_elapsed * time_elapsed;
160 }
161 speed = speed > MOUSEKEY_WHEEL_BASE_MOVEMENTS ? MOUSEKEY_WHEEL_BASE_MOVEMENTS : speed;
162 }
163
164 mk_wheel_interval = 1000.0f / speed;
165
166 return 1;
167}
168
169# else /* #ifndef MK_KINETIC_SPEED */
108 170
109static uint8_t move_unit(void) { 171static uint8_t move_unit(void) {
110 uint16_t unit; 172 uint16_t unit;
@@ -142,7 +204,8 @@ static uint8_t wheel_unit(void) {
142 return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit)); 204 return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit));
143} 205}
144 206
145# endif /* #ifndef MK_COMBINED */ 207# endif /* #ifndef MK_KINETIC_SPEED */
208# endif /* #ifndef MK_COMBINED */
146 209
147void mousekey_task(void) { 210void mousekey_task(void) {
148 // report cursor and scroll movement independently 211 // report cursor and scroll movement independently
@@ -193,6 +256,12 @@ void mousekey_task(void) {
193} 256}
194 257
195void mousekey_on(uint8_t code) { 258void mousekey_on(uint8_t code) {
259# ifdef MK_KINETIC_SPEED
260 if (mouse_timer == 0) {
261 mouse_timer = timer_read();
262 }
263# endif /* #ifdef MK_KINETIC_SPEED */
264
196 if (code == KC_MS_UP) 265 if (code == KC_MS_UP)
197 mouse_report.y = move_unit() * -1; 266 mouse_report.y = move_unit() * -1;
198 else if (code == KC_MS_DOWN) 267 else if (code == KC_MS_DOWN)
@@ -260,7 +329,12 @@ void mousekey_off(uint8_t code) {
260 mousekey_accel &= ~(1 << 1); 329 mousekey_accel &= ~(1 << 1);
261 else if (code == KC_MS_ACCEL2) 330 else if (code == KC_MS_ACCEL2)
262 mousekey_accel &= ~(1 << 2); 331 mousekey_accel &= ~(1 << 2);
263 if (mouse_report.x == 0 && mouse_report.y == 0) mousekey_repeat = 0; 332 if (mouse_report.x == 0 && mouse_report.y == 0) {
333 mousekey_repeat = 0;
334# ifdef MK_KINETIC_SPEED
335 mouse_timer = 0;
336# endif /* #ifdef MK_KINETIC_SPEED */
337 }
264 if (mouse_report.v == 0 && mouse_report.h == 0) mousekey_wheel_repeat = 0; 338 if (mouse_report.v == 0 && mouse_report.h == 0) mousekey_wheel_repeat = 0;
265} 339}
266 340
diff --git a/tmk_core/common/mousekey.h b/tmk_core/common/mousekey.h
index 300d262f5..52b8fe10e 100644
--- a/tmk_core/common/mousekey.h
+++ b/tmk_core/common/mousekey.h
@@ -36,16 +36,28 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
36# endif 36# endif
37 37
38# ifndef MOUSEKEY_MOVE_DELTA 38# ifndef MOUSEKEY_MOVE_DELTA
39# define MOUSEKEY_MOVE_DELTA 5 39# ifndef MK_KINETIC_SPEED
40# define MOUSEKEY_MOVE_DELTA 5
41# else
42# define MOUSEKEY_MOVE_DELTA 25
43# endif
40# endif 44# endif
41# ifndef MOUSEKEY_WHEEL_DELTA 45# ifndef MOUSEKEY_WHEEL_DELTA
42# define MOUSEKEY_WHEEL_DELTA 1 46# define MOUSEKEY_WHEEL_DELTA 1
43# endif 47# endif
44# ifndef MOUSEKEY_DELAY 48# ifndef MOUSEKEY_DELAY
45# define MOUSEKEY_DELAY 300 49# ifndef MK_KINETIC_SPEED
50# define MOUSEKEY_DELAY 300
51# else
52# define MOUSEKEY_DELAY 8
53# endif
46# endif 54# endif
47# ifndef MOUSEKEY_INTERVAL 55# ifndef MOUSEKEY_INTERVAL
48# define MOUSEKEY_INTERVAL 50 56# ifndef MK_KINETIC_SPEED
57# define MOUSEKEY_INTERVAL 50
58# else
59# define MOUSEKEY_INTERVAL 8
60# endif
49# endif 61# endif
50# ifndef MOUSEKEY_MAX_SPEED 62# ifndef MOUSEKEY_MAX_SPEED
51# define MOUSEKEY_MAX_SPEED 10 63# define MOUSEKEY_MAX_SPEED 10
@@ -66,6 +78,31 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
66# define MOUSEKEY_WHEEL_TIME_TO_MAX 40 78# define MOUSEKEY_WHEEL_TIME_TO_MAX 40
67# endif 79# endif
68 80
81# ifndef MOUSEKEY_INITIAL_SPEED
82# define MOUSEKEY_INITIAL_SPEED 100
83# endif
84# ifndef MOUSEKEY_BASE_SPEED
85# define MOUSEKEY_BASE_SPEED 1000
86# endif
87# ifndef MOUSEKEY_DECELERATED_SPEED
88# define MOUSEKEY_DECELERATED_SPEED 400
89# endif
90# ifndef MOUSEKEY_ACCELERATED_SPEED
91# define MOUSEKEY_ACCELERATED_SPEED 3000
92# endif
93# ifndef MOUSEKEY_WHEEL_INITIAL_MOVEMENTS
94# define MOUSEKEY_WHEEL_INITIAL_MOVEMENTS 16
95# endif
96# ifndef MOUSEKEY_WHEEL_BASE_MOVEMENTS
97# define MOUSEKEY_WHEEL_BASE_MOVEMENTS 32
98# endif
99# ifndef MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS
100# define MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS 48
101# endif
102# ifndef MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS
103# define MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS 8
104# endif
105
69#else /* #ifndef MK_3_SPEED */ 106#else /* #ifndef MK_3_SPEED */
70 107
71# ifndef MK_C_OFFSET_UNMOD 108# ifndef MK_C_OFFSET_UNMOD
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/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) \