diff options
Diffstat (limited to 'tmk_core/common')
| -rw-r--r-- | tmk_core/common/action.c | 18 | ||||
| -rw-r--r-- | tmk_core/common/avr/bootloader.c | 10 | ||||
| -rw-r--r-- | tmk_core/common/keyboard.c | 37 | ||||
| -rw-r--r-- | tmk_core/common/keyboard.h | 9 | ||||
| -rw-r--r-- | tmk_core/common/keycode.h | 14 | ||||
| -rw-r--r-- | tmk_core/common/matrix.h | 3 | ||||
| -rw-r--r-- | tmk_core/common/mousekey.c | 128 | ||||
| -rw-r--r-- | tmk_core/common/mousekey.h | 43 | ||||
| -rw-r--r-- | tmk_core/common/report.h | 5 | ||||
| -rw-r--r-- | tmk_core/common/sync_timer.c | 58 | ||||
| -rw-r--r-- | tmk_core/common/sync_timer.h | 54 | ||||
| -rw-r--r-- | tmk_core/common/uart.c | 172 | ||||
| -rw-r--r-- | tmk_core/common/uart.h | 8 | ||||
| -rw-r--r-- | tmk_core/common/wait.h | 79 |
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 | */ |
| 80 | void 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 | ||
| 100 | static uint32_t last_input_modification_time = 0; | ||
| 101 | uint32_t last_input_activity_time(void) { return last_input_modification_time; } | ||
| 102 | uint32_t last_input_activity_elapsed(void) { return timer_elapsed32(last_input_modification_time); } | ||
| 103 | |||
| 104 | static uint32_t last_matrix_modification_time = 0; | ||
| 105 | uint32_t last_matrix_activity_time(void) { return last_matrix_modification_time; } | ||
| 106 | uint32_t last_matrix_activity_elapsed(void) { return timer_elapsed32(last_matrix_modification_time); } | ||
| 107 | void last_matrix_activity_trigger(void) { last_matrix_modification_time = last_input_modification_time = timer_read32(); } | ||
| 108 | |||
| 109 | static uint32_t last_encoder_modification_time = 0; | ||
| 110 | uint32_t last_encoder_activity_time(void) { return last_encoder_modification_time; } | ||
| 111 | uint32_t last_encoder_activity_elapsed(void) { return timer_elapsed32(last_encoder_modification_time); } | ||
| 112 | void 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) |
| 101 | static uint32_t matrix_timer = 0; | 116 | static uint32_t matrix_timer = 0; |
| @@ -262,6 +277,7 @@ __attribute__((weak)) void housekeeping_task_user(void) {} | |||
| 262 | */ | 277 | */ |
| 263 | void keyboard_init(void) { | 278 | void 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); | |||
| 73 | void housekeeping_task_kb(void); | 73 | void housekeeping_task_kb(void); |
| 74 | void housekeeping_task_user(void); | 74 | void housekeeping_task_user(void); |
| 75 | 75 | ||
| 76 | uint32_t last_input_activity_time(void); // Timestamp of the last matrix or encoder activity | ||
| 77 | uint32_t last_input_activity_elapsed(void); // Number of milliseconds since the last matrix or encoder activity | ||
| 78 | |||
| 79 | uint32_t last_matrix_activity_time(void); // Timestamp of the last matrix activity | ||
| 80 | uint32_t last_matrix_activity_elapsed(void); // Number of milliseconds since the last matrix activity | ||
| 81 | |||
| 82 | uint32_t last_encoder_activity_time(void); // Timestamp of the last encoder activity | ||
| 83 | uint32_t last_encoder_activity_elapsed(void); // Number of milliseconds since the last encoder activity | ||
| 84 | |||
| 76 | uint32_t get_matrix_scan_rate(void); | 85 | uint32_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 | ||
| 522 | enum mouse_keys { | 525 | enum 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 */ |
| 56 | void matrix_print(void); | 56 | void matrix_print(void); |
| 57 | /* delay between changing matrix pin state and reading values */ | 57 | /* delay between changing matrix pin state and reading values */ |
| 58 | void matrix_output_select_delay(void); | ||
| 59 | void matrix_output_unselect_delay(void); | ||
| 60 | /* only for backwards compatibility. delay between changing matrix pin state and reading values */ | ||
| 58 | void matrix_io_delay(void); | 61 | void 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); | |||
| 36 | static uint8_t mousekey_accel = 0; | 36 | static uint8_t mousekey_accel = 0; |
| 37 | static uint8_t mousekey_repeat = 0; | 37 | static uint8_t mousekey_repeat = 0; |
| 38 | static uint8_t mousekey_wheel_repeat = 0; | 38 | static uint8_t mousekey_wheel_repeat = 0; |
| 39 | #ifdef MK_KINETIC_SPEED | ||
| 40 | static 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; | |||
| 43 | static uint16_t last_timer_w = 0; | 46 | static 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 | */ | ||
| 125 | const uint16_t mk_accelerated_speed = MOUSEKEY_ACCELERATED_SPEED; | ||
| 126 | const uint16_t mk_base_speed = MOUSEKEY_BASE_SPEED; | ||
| 127 | const uint16_t mk_decelerated_speed = MOUSEKEY_DECELERATED_SPEED; | ||
| 128 | const uint16_t mk_initial_speed = MOUSEKEY_INITIAL_SPEED; | ||
| 129 | |||
| 130 | static 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 | |||
| 149 | float mk_wheel_interval = 1000.0f / MOUSEKEY_WHEEL_INITIAL_MOVEMENTS; | ||
| 150 | |||
| 151 | static 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 | ||
| 109 | static uint8_t move_unit(void) { | 171 | static 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 | ||
| 147 | void mousekey_task(void) { | 210 | void 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 | ||
| 195 | void mousekey_on(uint8_t code) { | 258 | void 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 | /* | ||
| 2 | Copyright (C) 2020 Ryan Caltabiano <https://github.com/XScorpion2> | ||
| 3 | |||
| 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
| 5 | this software and associated documentation files (the "Software"), to deal in | ||
| 6 | the Software without restriction, including without limitation the rights to | ||
| 7 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies | ||
| 8 | of the Software, and to permit persons to whom the Software is furnished to do | ||
| 9 | so, subject to the following conditions: | ||
| 10 | |||
| 11 | The above copyright notice and this permission notice shall be included in all | ||
| 12 | copies or substantial portions of the Software. | ||
| 13 | |||
| 14 | If you happen to meet one of the copyright holders in a bar you are obligated | ||
| 15 | to buy them one pint of beer. | ||
| 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 THE | ||
| 23 | SOFTWARE. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #include "sync_timer.h" | ||
| 27 | #include "keyboard.h" | ||
| 28 | |||
| 29 | #if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER) | ||
| 30 | volatile int32_t sync_timer_ms; | ||
| 31 | |||
| 32 | void sync_timer_init(void) { sync_timer_ms = 0; } | ||
| 33 | |||
| 34 | void sync_timer_update(uint32_t time) { | ||
| 35 | if (is_keyboard_master()) return; | ||
| 36 | sync_timer_ms = time - timer_read32(); | ||
| 37 | } | ||
| 38 | |||
| 39 | uint16_t sync_timer_read(void) { | ||
| 40 | if (is_keyboard_master()) return timer_read(); | ||
| 41 | return sync_timer_read32(); | ||
| 42 | } | ||
| 43 | |||
| 44 | uint32_t sync_timer_read32(void) { | ||
| 45 | if (is_keyboard_master()) return timer_read32(); | ||
| 46 | return sync_timer_ms + timer_read32(); | ||
| 47 | } | ||
| 48 | |||
| 49 | uint16_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 | |||
| 54 | uint32_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 | /* | ||
| 2 | Copyright (C) 2020 Ryan Caltabiano <https://github.com/XScorpion2> | ||
| 3 | |||
| 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
| 5 | this software and associated documentation files (the "Software"), to deal in | ||
| 6 | the Software without restriction, including without limitation the rights to | ||
| 7 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies | ||
| 8 | of the Software, and to permit persons to whom the Software is furnished to do | ||
| 9 | so, subject to the following conditions: | ||
| 10 | |||
| 11 | The above copyright notice and this permission notice shall be included in all | ||
| 12 | copies or substantial portions of the Software. | ||
| 13 | |||
| 14 | If you happen to meet one of the copyright holders in a bar you are obligated | ||
| 15 | to buy them one pint of beer. | ||
| 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 THE | ||
| 23 | SOFTWARE. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #pragma once | ||
| 27 | |||
| 28 | #include <stdint.h> | ||
| 29 | #include "timer.h" | ||
| 30 | |||
| 31 | #ifdef __cplusplus | ||
| 32 | extern "C" { | ||
| 33 | #endif | ||
| 34 | |||
| 35 | #if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER) | ||
| 36 | void sync_timer_init(void); | ||
| 37 | void sync_timer_update(uint32_t time); | ||
| 38 | uint16_t sync_timer_read(void); | ||
| 39 | uint32_t sync_timer_read32(void); | ||
| 40 | uint16_t sync_timer_elapsed(uint16_t last); | ||
| 41 | uint32_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 | |||
| 85 | static volatile uint8_t tx_buffer[TX_BUFFER_SIZE]; | ||
| 86 | static volatile uint8_t tx_buffer_head; | ||
| 87 | static volatile uint8_t tx_buffer_tail; | ||
| 88 | static volatile uint8_t rx_buffer[RX_BUFFER_SIZE]; | ||
| 89 | static volatile uint8_t rx_buffer_head; | ||
| 90 | static volatile uint8_t rx_buffer_tail; | ||
| 91 | |||
| 92 | // Initialize the UART | ||
| 93 | void 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 | ||
| 105 | void 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 | ||
| 122 | uint8_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. | ||
| 137 | uint8_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 | ||
| 147 | ISR(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 | ||
| 162 | ISR(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 | |||
| 5 | void uart_init(uint32_t baud); | ||
| 6 | void uart_putchar(uint8_t c); | ||
| 7 | uint8_t uart_getchar(void); | ||
| 8 | uint8_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 @@ | |||
| 6 | extern "C" { | 6 | extern "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) \ |
