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.c15
-rw-r--r--tmk_core/common/keyboard.h3
-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, 328 insertions, 17 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..aea09169f 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,10 @@ 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_matrix_modification_time = 0;
101uint32_t last_matrix_activity_time(void) { return last_matrix_modification_time; }
102uint32_t last_matrix_activity_elapsed(void) { return timer_elapsed32(last_matrix_modification_time); }
103
99// Only enable this if console is enabled to print to 104// Only enable this if console is enabled to print to
100#if defined(DEBUG_MATRIX_SCAN_RATE) && defined(CONSOLE_ENABLE) 105#if defined(DEBUG_MATRIX_SCAN_RATE) && defined(CONSOLE_ENABLE)
101static uint32_t matrix_timer = 0; 106static uint32_t matrix_timer = 0;
@@ -255,6 +260,7 @@ __attribute__((weak)) void housekeeping_task_user(void) {}
255 */ 260 */
256void keyboard_init(void) { 261void keyboard_init(void) {
257 timer_init(); 262 timer_init();
263 sync_timer_init();
258 matrix_init(); 264 matrix_init();
259#ifdef VIA_ENABLE 265#ifdef VIA_ENABLE
260 via_init(); 266 via_init();
@@ -336,11 +342,8 @@ void keyboard_task(void) {
336 housekeeping_task_kb(); 342 housekeeping_task_kb();
337 housekeeping_task_user(); 343 housekeeping_task_user();
338 344
339#if defined(OLED_DRIVER_ENABLE) && !defined(OLED_DISABLE_TIMEOUT) 345 uint8_t matrix_changed = matrix_scan();
340 uint8_t ret = matrix_scan(); 346 if (matrix_changed) last_matrix_modification_time = timer_read32();
341#else
342 matrix_scan();
343#endif
344 347
345 if (should_process_keypress()) { 348 if (should_process_keypress()) {
346 for (uint8_t r = 0; r < MATRIX_ROWS; r++) { 349 for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
@@ -407,7 +410,7 @@ MATRIX_LOOP_END:
407 oled_task(); 410 oled_task();
408# ifndef OLED_DISABLE_TIMEOUT 411# ifndef OLED_DISABLE_TIMEOUT
409 // Wake up oled if user is using those fabulous keys! 412 // Wake up oled if user is using those fabulous keys!
410 if (ret) oled_on(); 413 if (matrix_changed) oled_on();
411# endif 414# endif
412#endif 415#endif
413 416
diff --git a/tmk_core/common/keyboard.h b/tmk_core/common/keyboard.h
index d04e685cd..cc5b2e5e4 100644
--- a/tmk_core/common/keyboard.h
+++ b/tmk_core/common/keyboard.h
@@ -73,6 +73,9 @@ 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_matrix_activity_time(void); // Timestamp of the last matrix activity
77uint32_t last_matrix_activity_elapsed(void); // Number of milliseconds since the last matrix activity
78
76#ifdef __cplusplus 79#ifdef __cplusplus
77} 80}
78#endif 81#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) \