aboutsummaryrefslogtreecommitdiff
path: root/tmk_core/common
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/common')
-rw-r--r--tmk_core/common/action.c18
-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/keycode.h14
-rw-r--r--tmk_core/common/matrix.h3
-rw-r--r--tmk_core/common/mousekey.c128
-rw-r--r--tmk_core/common/mousekey.h43
-rw-r--r--tmk_core/common/report.h5
-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
14 files changed, 394 insertions, 244 deletions
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index a7432bae5..a3830abbf 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();
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 b35620e7f..1250c45ae 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;
@@ -262,6 +277,7 @@ __attribute__((weak)) void housekeeping_task_user(void) {}
262 */ 277 */
263void keyboard_init(void) { 278void keyboard_init(void) {
264 timer_init(); 279 timer_init();
280 sync_timer_init();
265 matrix_init(); 281 matrix_init();
266#ifdef VIA_ENABLE 282#ifdef VIA_ENABLE
267 via_init(); 283 via_init();
@@ -339,15 +355,15 @@ void keyboard_task(void) {
339#ifdef QMK_KEYS_PER_SCAN 355#ifdef QMK_KEYS_PER_SCAN
340 uint8_t keys_processed = 0; 356 uint8_t keys_processed = 0;
341#endif 357#endif
358#ifdef ENCODER_ENABLE
359 bool encoders_changed = false;
360#endif
342 361
343 housekeeping_task_kb(); 362 housekeeping_task_kb();
344 housekeeping_task_user(); 363 housekeeping_task_user();
345 364
346#if defined(OLED_DRIVER_ENABLE) && !defined(OLED_DISABLE_TIMEOUT) 365 uint8_t matrix_changed = matrix_scan();
347 uint8_t ret = matrix_scan(); 366 if (matrix_changed) last_matrix_activity_trigger();
348#else
349 matrix_scan();
350#endif
351 367
352 if (should_process_keypress()) { 368 if (should_process_keypress()) {
353 for (uint8_t r = 0; r < MATRIX_ROWS; r++) { 369 for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
@@ -403,7 +419,8 @@ MATRIX_LOOP_END:
403#endif 419#endif
404 420
405#ifdef ENCODER_ENABLE 421#ifdef ENCODER_ENABLE
406 encoder_read(); 422 encoders_changed = encoder_read();
423 if (encoders_changed) last_encoder_activity_trigger();
407#endif 424#endif
408 425
409#ifdef QWIIC_ENABLE 426#ifdef QWIIC_ENABLE
@@ -413,8 +430,12 @@ MATRIX_LOOP_END:
413#ifdef OLED_DRIVER_ENABLE 430#ifdef OLED_DRIVER_ENABLE
414 oled_task(); 431 oled_task();
415# ifndef OLED_DISABLE_TIMEOUT 432# ifndef OLED_DISABLE_TIMEOUT
416 // Wake up oled if user is using those fabulous keys! 433 // Wake up oled if user is using those fabulous keys or spinning those encoders!
417 if (ret) oled_on(); 434# ifdef ENCODER_ENABLE
435 if (matrix_changed || encoders_changed) oled_on();
436# else
437 if (matrix_changed) oled_on();
438# endif
418# endif 439# endif
419#endif 440#endif
420 441
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/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..d8cf63f77 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)
@@ -209,16 +278,8 @@ void mousekey_on(uint8_t code) {
209 mouse_report.h = wheel_unit() * -1; 278 mouse_report.h = wheel_unit() * -1;
210 else if (code == KC_MS_WH_RIGHT) 279 else if (code == KC_MS_WH_RIGHT)
211 mouse_report.h = wheel_unit(); 280 mouse_report.h = wheel_unit();
212 else if (code == KC_MS_BTN1) 281 else if (IS_MOUSEKEY_BUTTON(code))
213 mouse_report.buttons |= MOUSE_BTN1; 282 mouse_report.buttons |= 1 << (code - KC_MS_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) 283 else if (code == KC_MS_ACCEL0)
223 mousekey_accel |= (1 << 0); 284 mousekey_accel |= (1 << 0);
224 else if (code == KC_MS_ACCEL1) 285 else if (code == KC_MS_ACCEL1)
@@ -244,23 +305,20 @@ void mousekey_off(uint8_t code) {
244 mouse_report.h = 0; 305 mouse_report.h = 0;
245 else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0) 306 else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0)
246 mouse_report.h = 0; 307 mouse_report.h = 0;
247 else if (code == KC_MS_BTN1) 308 else if (IS_MOUSEKEY_BUTTON(code))
248 mouse_report.buttons &= ~MOUSE_BTN1; 309 mouse_report.buttons &= ~(1 << (code - KC_MS_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) 310 else if (code == KC_MS_ACCEL0)
258 mousekey_accel &= ~(1 << 0); 311 mousekey_accel &= ~(1 << 0);
259 else if (code == KC_MS_ACCEL1) 312 else if (code == KC_MS_ACCEL1)
260 mousekey_accel &= ~(1 << 1); 313 mousekey_accel &= ~(1 << 1);
261 else if (code == KC_MS_ACCEL2) 314 else if (code == KC_MS_ACCEL2)
262 mousekey_accel &= ~(1 << 2); 315 mousekey_accel &= ~(1 << 2);
263 if (mouse_report.x == 0 && mouse_report.y == 0) mousekey_repeat = 0; 316 if (mouse_report.x == 0 && mouse_report.y == 0) {
317 mousekey_repeat = 0;
318# ifdef MK_KINETIC_SPEED
319 mouse_timer = 0;
320# endif /* #ifdef MK_KINETIC_SPEED */
321 }
264 if (mouse_report.v == 0 && mouse_report.h == 0) mousekey_wheel_repeat = 0; 322 if (mouse_report.v == 0 && mouse_report.h == 0) mousekey_wheel_repeat = 0;
265} 323}
266 324
@@ -349,16 +407,8 @@ void mousekey_on(uint8_t code) {
349 mouse_report.h = w_offset * -1; 407 mouse_report.h = w_offset * -1;
350 else if (code == KC_MS_WH_RIGHT) 408 else if (code == KC_MS_WH_RIGHT)
351 mouse_report.h = w_offset; 409 mouse_report.h = w_offset;
352 else if (code == KC_MS_BTN1) 410 else if (IS_MOUSEKEY_BUTTON(code))
353 mouse_report.buttons |= MOUSE_BTN1; 411 mouse_report.buttons |= 1 << (code - KC_MS_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) 412 else if (code == KC_MS_ACCEL0)
363 mk_speed = mkspd_0; 413 mk_speed = mkspd_0;
364 else if (code == KC_MS_ACCEL1) 414 else if (code == KC_MS_ACCEL1)
@@ -388,16 +438,8 @@ void mousekey_off(uint8_t code) {
388 mouse_report.h = 0; 438 mouse_report.h = 0;
389 else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0) 439 else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0)
390 mouse_report.h = 0; 440 mouse_report.h = 0;
391 else if (code == KC_MS_BTN1) 441 else if (IS_MOUSEKEY_BUTTON(code))
392 mouse_report.buttons &= ~MOUSE_BTN1; 442 mouse_report.buttons &= ~(1 << (code - KC_MS_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 443# ifdef MK_MOMENTARY_ACCEL
402 else if (code == KC_MS_ACCEL0) 444 else if (code == KC_MS_ACCEL0)
403 mk_speed = mkspd_DEFAULT; 445 mk_speed = mkspd_DEFAULT;
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/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/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) \