diff options
Diffstat (limited to 'tmk_core')
30 files changed, 764 insertions, 365 deletions
diff --git a/tmk_core/chibios.mk b/tmk_core/chibios.mk index e94e935eb..40595a1e3 100644 --- a/tmk_core/chibios.mk +++ b/tmk_core/chibios.mk | |||
| @@ -71,6 +71,9 @@ else ifneq ("$(wildcard $(TOP_DIR)/platforms/chibios/$(BOARD)/board/board.mk)"," | |||
| 71 | BOARD_PATH = $(TOP_DIR)/platforms/chibios/$(BOARD) | 71 | BOARD_PATH = $(TOP_DIR)/platforms/chibios/$(BOARD) |
| 72 | BOARD_MK += $(TOP_DIR)/platforms/chibios/$(BOARD)/board/board.mk | 72 | BOARD_MK += $(TOP_DIR)/platforms/chibios/$(BOARD)/board/board.mk |
| 73 | KEYBOARD_PATHS += $(BOARD_PATH)/configs | 73 | KEYBOARD_PATHS += $(BOARD_PATH)/configs |
| 74 | ifneq ("$(wildcard $(BOARD_PATH)/rules.mk)","") | ||
| 75 | include $(BOARD_PATH)/rules.mk | ||
| 76 | endif | ||
| 74 | endif | 77 | endif |
| 75 | 78 | ||
| 76 | ifeq ("$(wildcard $(BOARD_MK))","") | 79 | ifeq ("$(wildcard $(BOARD_MK))","") |
| @@ -309,6 +312,7 @@ LDFLAGS += -mno-thumb-interwork -mthumb | |||
| 309 | LDSYMBOLS =,--defsym=__process_stack_size__=$(USE_PROCESS_STACKSIZE) | 312 | LDSYMBOLS =,--defsym=__process_stack_size__=$(USE_PROCESS_STACKSIZE) |
| 310 | LDSYMBOLS :=$(LDSYMBOLS),--defsym=__main_stack_size__=$(USE_EXCEPTIONS_STACKSIZE) | 313 | LDSYMBOLS :=$(LDSYMBOLS),--defsym=__main_stack_size__=$(USE_EXCEPTIONS_STACKSIZE) |
| 311 | LDFLAGS += -Wl,--script=$(LDSCRIPT)$(LDSYMBOLS) | 314 | LDFLAGS += -Wl,--script=$(LDSCRIPT)$(LDSYMBOLS) |
| 315 | LDFLAGS += --specs=nano.specs | ||
| 312 | 316 | ||
| 313 | OPT_DEFS += -DPROTOCOL_CHIBIOS | 317 | OPT_DEFS += -DPROTOCOL_CHIBIOS |
| 314 | 318 | ||
diff --git a/tmk_core/common.mk b/tmk_core/common.mk index fdf2aa097..05839824c 100644 --- a/tmk_core/common.mk +++ b/tmk_core/common.mk | |||
| @@ -18,6 +18,7 @@ TMK_COMMON_SRC += $(COMMON_DIR)/host.c \ | |||
| 18 | $(COMMON_DIR)/report.c \ | 18 | $(COMMON_DIR)/report.c \ |
| 19 | $(PLATFORM_COMMON_DIR)/suspend.c \ | 19 | $(PLATFORM_COMMON_DIR)/suspend.c \ |
| 20 | $(PLATFORM_COMMON_DIR)/timer.c \ | 20 | $(PLATFORM_COMMON_DIR)/timer.c \ |
| 21 | $(COMMON_DIR)/sync_timer.c \ | ||
| 21 | $(PLATFORM_COMMON_DIR)/bootloader.c \ | 22 | $(PLATFORM_COMMON_DIR)/bootloader.c \ |
| 22 | 23 | ||
| 23 | ifeq ($(PLATFORM),AVR) | 24 | ifeq ($(PLATFORM),AVR) |
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/avr/suspend.c b/tmk_core/common/avr/suspend.c index 86c3df040..b784a0835 100644 --- a/tmk_core/common/avr/suspend.c +++ b/tmk_core/common/avr/suspend.c | |||
| @@ -97,13 +97,11 @@ static void power_down(uint8_t wdto) { | |||
| 97 | led_set(leds_off); | 97 | led_set(leds_off); |
| 98 | 98 | ||
| 99 | # ifdef AUDIO_ENABLE | 99 | # ifdef AUDIO_ENABLE |
| 100 | // This sometimes disables the start-up noise, so it's been disabled | 100 | stop_all_notes(); |
| 101 | // stop_all_notes(); | ||
| 102 | # endif /* AUDIO_ENABLE */ | 101 | # endif /* AUDIO_ENABLE */ |
| 103 | # if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) | 102 | # if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) |
| 104 | rgblight_suspend(); | 103 | rgblight_suspend(); |
| 105 | # endif | 104 | # endif |
| 106 | suspend_power_down_kb(); | ||
| 107 | 105 | ||
| 108 | // TODO: more power saving | 106 | // TODO: more power saving |
| 109 | // See PicoPower application note | 107 | // See PicoPower application note |
| @@ -157,6 +155,7 @@ __attribute__((weak)) void suspend_wakeup_init_user(void) {} | |||
| 157 | * FIXME: needs doc | 155 | * FIXME: needs doc |
| 158 | */ | 156 | */ |
| 159 | __attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); } | 157 | __attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); } |
| 158 | |||
| 160 | /** \brief run immediately after wakeup | 159 | /** \brief run immediately after wakeup |
| 161 | * | 160 | * |
| 162 | * FIXME: needs doc | 161 | * FIXME: needs doc |
diff --git a/tmk_core/common/chibios/suspend.c b/tmk_core/common/chibios/suspend.c index 796056019..49e20641f 100644 --- a/tmk_core/common/chibios/suspend.c +++ b/tmk_core/common/chibios/suspend.c | |||
| @@ -12,6 +12,10 @@ | |||
| 12 | #include "led.h" | 12 | #include "led.h" |
| 13 | #include "wait.h" | 13 | #include "wait.h" |
| 14 | 14 | ||
| 15 | #ifdef AUDIO_ENABLE | ||
| 16 | # include "audio.h" | ||
| 17 | #endif /* AUDIO_ENABLE */ | ||
| 18 | |||
| 15 | #ifdef BACKLIGHT_ENABLE | 19 | #ifdef BACKLIGHT_ENABLE |
| 16 | # include "backlight.h" | 20 | # include "backlight.h" |
| 17 | #endif | 21 | #endif |
| @@ -65,6 +69,9 @@ void suspend_power_down(void) { | |||
| 65 | #if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) | 69 | #if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) |
| 66 | rgblight_suspend(); | 70 | rgblight_suspend(); |
| 67 | #endif | 71 | #endif |
| 72 | #ifdef AUDIO_ENABLE | ||
| 73 | stop_all_notes(); | ||
| 74 | #endif /* AUDIO_ENABLE */ | ||
| 68 | 75 | ||
| 69 | suspend_power_down_kb(); | 76 | suspend_power_down_kb(); |
| 70 | // on AVR, this enables the watchdog for 15ms (max), and goes to | 77 | // on AVR, this enables the watchdog for 15ms (max), and goes to |
diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c index 7120cdacd..40989ca4c 100644 --- a/tmk_core/common/keyboard.c +++ b/tmk_core/common/keyboard.c | |||
| @@ -23,6 +23,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 23 | #include "led.h" | 23 | #include "led.h" |
| 24 | #include "keycode.h" | 24 | #include "keycode.h" |
| 25 | #include "timer.h" | 25 | #include "timer.h" |
| 26 | #include "sync_timer.h" | ||
| 26 | #include "print.h" | 27 | #include "print.h" |
| 27 | #include "debug.h" | 28 | #include "debug.h" |
| 28 | #include "command.h" | 29 | #include "command.h" |
| @@ -96,6 +97,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 96 | # include "dip_switch.h" | 97 | # include "dip_switch.h" |
| 97 | #endif | 98 | #endif |
| 98 | 99 | ||
| 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; |
| @@ -260,6 +275,7 @@ __attribute__((weak)) void housekeeping_task_user(void) {} | |||
| 260 | */ | 275 | */ |
| 261 | void keyboard_init(void) { | 276 | void keyboard_init(void) { |
| 262 | timer_init(); | 277 | timer_init(); |
| 278 | sync_timer_init(); | ||
| 263 | matrix_init(); | 279 | matrix_init(); |
| 264 | #ifdef VIA_ENABLE | 280 | #ifdef VIA_ENABLE |
| 265 | via_init(); | 281 | via_init(); |
| @@ -337,15 +353,15 @@ void keyboard_task(void) { | |||
| 337 | #ifdef QMK_KEYS_PER_SCAN | 353 | #ifdef QMK_KEYS_PER_SCAN |
| 338 | uint8_t keys_processed = 0; | 354 | uint8_t keys_processed = 0; |
| 339 | #endif | 355 | #endif |
| 356 | #ifdef ENCODER_ENABLE | ||
| 357 | bool encoders_changed = false; | ||
| 358 | #endif | ||
| 340 | 359 | ||
| 341 | housekeeping_task_kb(); | 360 | housekeeping_task_kb(); |
| 342 | housekeeping_task_user(); | 361 | housekeeping_task_user(); |
| 343 | 362 | ||
| 344 | #if defined(OLED_DRIVER_ENABLE) && !defined(OLED_DISABLE_TIMEOUT) | 363 | uint8_t matrix_changed = matrix_scan(); |
| 345 | uint8_t ret = matrix_scan(); | 364 | if (matrix_changed) last_matrix_activity_trigger(); |
| 346 | #else | ||
| 347 | matrix_scan(); | ||
| 348 | #endif | ||
| 349 | 365 | ||
| 350 | if (should_process_keypress()) { | 366 | if (should_process_keypress()) { |
| 351 | for (uint8_t r = 0; r < MATRIX_ROWS; r++) { | 367 | for (uint8_t r = 0; r < MATRIX_ROWS; r++) { |
| @@ -401,7 +417,8 @@ MATRIX_LOOP_END: | |||
| 401 | #endif | 417 | #endif |
| 402 | 418 | ||
| 403 | #ifdef ENCODER_ENABLE | 419 | #ifdef ENCODER_ENABLE |
| 404 | encoder_read(); | 420 | encoders_changed = encoder_read(); |
| 421 | if (encoders_changed) last_encoder_activity_trigger(); | ||
| 405 | #endif | 422 | #endif |
| 406 | 423 | ||
| 407 | #ifdef QWIIC_ENABLE | 424 | #ifdef QWIIC_ENABLE |
| @@ -411,8 +428,12 @@ MATRIX_LOOP_END: | |||
| 411 | #ifdef OLED_DRIVER_ENABLE | 428 | #ifdef OLED_DRIVER_ENABLE |
| 412 | oled_task(); | 429 | oled_task(); |
| 413 | # ifndef OLED_DISABLE_TIMEOUT | 430 | # ifndef OLED_DISABLE_TIMEOUT |
| 414 | // Wake up oled if user is using those fabulous keys! | 431 | // Wake up oled if user is using those fabulous keys or spinning those encoders! |
| 415 | if (ret) oled_on(); | 432 | # ifdef ENCODER_ENABLE |
| 433 | if (matrix_changed || encoders_changed) oled_on(); | ||
| 434 | # else | ||
| 435 | if (matrix_changed) oled_on(); | ||
| 436 | # endif | ||
| 416 | # endif | 437 | # endif |
| 417 | #endif | 438 | #endif |
| 418 | 439 | ||
diff --git a/tmk_core/common/keyboard.h b/tmk_core/common/keyboard.h index 70e8f7e2c..eaf74bac5 100644 --- a/tmk_core/common/keyboard.h +++ b/tmk_core/common/keyboard.h | |||
| @@ -73,6 +73,15 @@ void keyboard_post_init_user(void); | |||
| 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/suspend.h b/tmk_core/common/suspend.h index 766df95aa..9d17d984e 100644 --- a/tmk_core/common/suspend.h +++ b/tmk_core/common/suspend.h | |||
| @@ -12,3 +12,7 @@ void suspend_wakeup_init_user(void); | |||
| 12 | void suspend_wakeup_init_kb(void); | 12 | void suspend_wakeup_init_kb(void); |
| 13 | void suspend_power_down_user(void); | 13 | void suspend_power_down_user(void); |
| 14 | void suspend_power_down_kb(void); | 14 | void suspend_power_down_kb(void); |
| 15 | |||
| 16 | #ifndef USB_SUSPEND_WAKEUP_DELAY | ||
| 17 | # define USB_SUSPEND_WAKEUP_DELAY 200 | ||
| 18 | #endif | ||
diff --git a/tmk_core/common/sync_timer.c b/tmk_core/common/sync_timer.c new file mode 100644 index 000000000..de24b463b --- /dev/null +++ b/tmk_core/common/sync_timer.c | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | /* | ||
| 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) \ |
diff --git a/tmk_core/protocol/adb.c b/tmk_core/protocol/adb.c index a23c91961..367f1b09f 100644 --- a/tmk_core/protocol/adb.c +++ b/tmk_core/protocol/adb.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | Copyright 2011 Jun WAKO <wakojun@gmail.com> | 2 | Copyright 2011-19 Jun WAKO <wakojun@gmail.com> |
| 3 | Copyright 2013 Shay Green <gblargg@gmail.com> | 3 | Copyright 2013 Shay Green <gblargg@gmail.com> |
| 4 | 4 | ||
| 5 | This software is licensed with a Modified BSD License. | 5 | This software is licensed with a Modified BSD License. |
| @@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE. | |||
| 41 | #include <avr/io.h> | 41 | #include <avr/io.h> |
| 42 | #include <avr/interrupt.h> | 42 | #include <avr/interrupt.h> |
| 43 | #include "adb.h" | 43 | #include "adb.h" |
| 44 | #include "print.h" | ||
| 44 | 45 | ||
| 45 | // GCC doesn't inline functions normally | 46 | // GCC doesn't inline functions normally |
| 46 | #define data_lo() (ADB_DDR |= (1 << ADB_DATA_BIT)) | 47 | #define data_lo() (ADB_DDR |= (1 << ADB_DATA_BIT)) |
| @@ -59,7 +60,6 @@ static inline void place_bit1(void); | |||
| 59 | static inline void send_byte(uint8_t data); | 60 | static inline void send_byte(uint8_t data); |
| 60 | static inline uint16_t wait_data_lo(uint16_t us); | 61 | static inline uint16_t wait_data_lo(uint16_t us); |
| 61 | static inline uint16_t wait_data_hi(uint16_t us); | 62 | static inline uint16_t wait_data_hi(uint16_t us); |
| 62 | static inline uint16_t adb_host_dev_recv(uint8_t device); | ||
| 63 | 63 | ||
| 64 | void adb_host_init(void) { | 64 | void adb_host_init(void) { |
| 65 | ADB_PORT &= ~(1 << ADB_DATA_BIT); | 65 | ADB_PORT &= ~(1 << ADB_DATA_BIT); |
| @@ -81,119 +81,164 @@ bool adb_host_psw(void) { return psw_in(); } | |||
| 81 | * <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919> | 81 | * <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919> |
| 82 | * <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139> | 82 | * <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139> |
| 83 | */ | 83 | */ |
| 84 | 84 | uint16_t adb_host_kbd_recv(void) { return adb_host_talk(ADB_ADDR_KEYBOARD, ADB_REG_0); } | |
| 85 | // ADB Bit Cells | ||
| 86 | // | ||
| 87 | // bit cell time: 70-130us | ||
| 88 | // low part of bit0: 60-70% of bit cell | ||
| 89 | // low part of bit1: 30-40% of bit cell | ||
| 90 | // | ||
| 91 | // bit cell time 70us 130us | ||
| 92 | // -------------------------------------------- | ||
| 93 | // low part of bit0 42-49 78-91 | ||
| 94 | // high part of bit0 21-28 39-52 | ||
| 95 | // low part of bit1 21-28 39-52 | ||
| 96 | // high part of bit1 42-49 78-91 | ||
| 97 | // | ||
| 98 | // | ||
| 99 | // bit0: | ||
| 100 | // 70us bit cell: | ||
| 101 | // ____________~~~~~~ | ||
| 102 | // 42-49 21-28 | ||
| 103 | // | ||
| 104 | // 130us bit cell: | ||
| 105 | // ____________~~~~~~ | ||
| 106 | // 78-91 39-52 | ||
| 107 | // | ||
| 108 | // bit1: | ||
| 109 | // 70us bit cell: | ||
| 110 | // ______~~~~~~~~~~~~ | ||
| 111 | // 21-28 42-49 | ||
| 112 | // | ||
| 113 | // 130us bit cell: | ||
| 114 | // ______~~~~~~~~~~~~ | ||
| 115 | // 39-52 78-91 | ||
| 116 | // | ||
| 117 | // [from Apple IIgs Hardware Reference Second Edition] | ||
| 118 | |||
| 119 | enum { ADDR_KEYB = 0x20, ADDR_MOUSE = 0x30 }; | ||
| 120 | |||
| 121 | uint16_t adb_host_kbd_recv(void) { return adb_host_dev_recv(ADDR_KEYB); } | ||
| 122 | 85 | ||
| 123 | #ifdef ADB_MOUSE_ENABLE | 86 | #ifdef ADB_MOUSE_ENABLE |
| 124 | void adb_mouse_init(void) { return; } | 87 | __attribute__((weak)) void adb_mouse_init(void) { return; } |
| 88 | |||
| 89 | __attribute__((weak)) void adb_mouse_task(void) { return; } | ||
| 125 | 90 | ||
| 126 | uint16_t adb_host_mouse_recv(void) { return adb_host_dev_recv(ADDR_MOUSE); } | 91 | uint16_t adb_host_mouse_recv(void) { return adb_host_talk(ADB_ADDR_MOUSE, ADB_REG_0); } |
| 127 | #endif | 92 | #endif |
| 128 | 93 | ||
| 129 | static inline uint16_t adb_host_dev_recv(uint8_t device) { | 94 | // This sends Talk command to read data from register and returns length of the data. |
| 130 | uint16_t data = 0; | 95 | uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) { |
| 96 | for (int8_t i = 0; i < len; i++) buf[i] = 0; | ||
| 97 | |||
| 131 | cli(); | 98 | cli(); |
| 132 | attention(); | 99 | attention(); |
| 133 | send_byte(device | 0x0C); // Addr:Keyboard(0010)/Mouse(0011), Cmd:Talk(11), Register0(00) | 100 | send_byte((addr << 4) | ADB_CMD_TALK | reg); |
| 134 | place_bit0(); // Stopbit(0) | 101 | place_bit0(); // Stopbit(0) |
| 102 | // TODO: Service Request(Srq): | ||
| 103 | // Device holds low part of comannd stopbit for 140-260us | ||
| 104 | // | ||
| 105 | // Command: | ||
| 106 | // ......._ ______________________ ___ ............_ ------- | ||
| 107 | // | | | | | | | | ||
| 108 | // Command | | | | | Data bytes | | | ||
| 109 | // ........|___| | 140-260 |__| |_............|___| | ||
| 110 | // |stop0 | Tlt Stop-to-Start |start1| |stop0 | | ||
| 111 | // | ||
| 112 | // Command without data: | ||
| 113 | // ......._ __________________________ | ||
| 114 | // | | | ||
| 115 | // Command | | | ||
| 116 | // ........|___| | 140-260 | | ||
| 117 | // |stop0 | Tlt Stop-to-Start | | ||
| 118 | // | ||
| 119 | // Service Request: | ||
| 120 | // ......._ ______ ___ ............_ ------- | ||
| 121 | // | 140-260 | | | | | | | ||
| 122 | // Command | Service Request | | | | Data bytes | | | ||
| 123 | // ........|___________________| |__| |_............|___| | ||
| 124 | // |stop0 | |start1| |stop0 | | ||
| 125 | // ......._ __________ | ||
| 126 | // | 140-260 | | ||
| 127 | // Command | Service Request | | ||
| 128 | // ........|___________________| | ||
| 129 | // |stop0 | | ||
| 130 | // This can be happened? | ||
| 131 | // ......._ ______________________ ___ ............_ ----- | ||
| 132 | // | | | | | | 140-260 | | ||
| 133 | // Command | | | | | Data bytes | Service Request | | ||
| 134 | // ........|___| | 140-260 |__| |_............|_________________| | ||
| 135 | // |stop0 | Tlt Stop-to-Start |start1| |stop0 | | ||
| 136 | // | ||
| 137 | // "Service requests are issued by the devices during a very specific time at the | ||
| 138 | // end of the reception of the command packet. | ||
| 139 | // If a device in need of service issues a service request, it must do so within | ||
| 140 | // the 65 µs of the Stop Bit’s low time and maintain the line low for a total of 300 µs." | ||
| 141 | // | ||
| 142 | // "A device sends a Service Request signal by holding the bus low during the low | ||
| 143 | // portion of the stop bit of any command or data transaction. The device must lengthen | ||
| 144 | // the stop by a minimum of 140 J.lS beyond its normal duration, as shown in Figure 8-15." | ||
| 145 | // http://ww1.microchip.com/downloads/en/AppNotes/00591b.pdf | ||
| 135 | if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored | 146 | if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored |
| 147 | xprintf("R"); | ||
| 136 | sei(); | 148 | sei(); |
| 137 | return -30; // something wrong | 149 | return 0; |
| 138 | } | 150 | } |
| 139 | if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us) | 151 | if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us) |
| 140 | sei(); | 152 | sei(); |
| 141 | return 0; // No data to send | 153 | return 0; // No data from device(not error); |
| 154 | } | ||
| 155 | |||
| 156 | // start bit(1) | ||
| 157 | if (!wait_data_hi(40)) { | ||
| 158 | xprintf("S"); | ||
| 159 | sei(); | ||
| 160 | return 0; | ||
| 161 | } | ||
| 162 | if (!wait_data_lo(100)) { | ||
| 163 | xprintf("s"); | ||
| 164 | sei(); | ||
| 165 | return 0; | ||
| 142 | } | 166 | } |
| 143 | 167 | ||
| 144 | uint8_t n = 17; // start bit + 16 data bits | 168 | uint8_t n = 0; // bit count |
| 145 | do { | 169 | do { |
| 170 | // | ||
| 171 | // |<- bit_cell_max(130) ->| | ||
| 172 | // | |<- lo ->| | ||
| 173 | // | | |<-hi->| | ||
| 174 | // _______ | ||
| 175 | // | | | | ||
| 176 | // | 130-lo | lo-hi | | ||
| 177 | // |________| | | ||
| 178 | // | ||
| 146 | uint8_t lo = (uint8_t)wait_data_hi(130); | 179 | uint8_t lo = (uint8_t)wait_data_hi(130); |
| 147 | if (!lo) goto error; | 180 | if (!lo) goto error; // no more bit or after stop bit |
| 148 | 181 | ||
| 149 | uint8_t hi = (uint8_t)wait_data_lo(lo); | 182 | uint8_t hi = (uint8_t)wait_data_lo(lo); |
| 150 | if (!hi) goto error; | 183 | if (!hi) goto error; // stop bit extedned by Srq? |
| 151 | 184 | ||
| 152 | hi = lo - hi; | 185 | if (n / 8 >= len) continue; // can't store in buf |
| 153 | lo = 130 - lo; | ||
| 154 | 186 | ||
| 155 | data <<= 1; | 187 | buf[n / 8] <<= 1; |
| 156 | if (lo < hi) { | 188 | if ((130 - lo) < (lo - hi)) { |
| 157 | data |= 1; | 189 | buf[n / 8] |= 1; |
| 158 | } else if (n == 17) { | ||
| 159 | sei(); | ||
| 160 | return -20; | ||
| 161 | } | 190 | } |
| 162 | } while (--n); | 191 | } while (++n); |
| 163 | |||
| 164 | // Stop bit can't be checked normally since it could have service request lenghtening | ||
| 165 | // and its high state never goes low. | ||
| 166 | if (!wait_data_hi(351) || wait_data_lo(91)) { | ||
| 167 | sei(); | ||
| 168 | return -21; | ||
| 169 | } | ||
| 170 | sei(); | ||
| 171 | return data; | ||
| 172 | 192 | ||
| 173 | error: | 193 | error: |
| 174 | sei(); | 194 | sei(); |
| 175 | return -n; | 195 | return n / 8; |
| 176 | } | 196 | } |
| 177 | 197 | ||
| 178 | void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l) { | 198 | uint16_t adb_host_talk(uint8_t addr, uint8_t reg) { |
| 199 | uint8_t len; | ||
| 200 | uint8_t buf[8]; | ||
| 201 | len = adb_host_talk_buf(addr, reg, buf, 8); | ||
| 202 | if (len != 2) return 0; | ||
| 203 | return (buf[0] << 8 | buf[1]); | ||
| 204 | } | ||
| 205 | |||
| 206 | void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) { | ||
| 179 | cli(); | 207 | cli(); |
| 180 | attention(); | 208 | attention(); |
| 181 | send_byte(cmd); | 209 | send_byte((addr << 4) | ADB_CMD_LISTEN | reg); |
| 182 | place_bit0(); // Stopbit(0) | 210 | place_bit0(); // Stopbit(0) |
| 211 | // TODO: Service Request | ||
| 183 | _delay_us(200); // Tlt/Stop to Start | 212 | _delay_us(200); // Tlt/Stop to Start |
| 184 | place_bit1(); // Startbit(1) | 213 | place_bit1(); // Startbit(1) |
| 185 | send_byte(data_h); | 214 | for (int8_t i = 0; i < len; i++) { |
| 186 | send_byte(data_l); | 215 | send_byte(buf[i]); |
| 216 | // xprintf("%02X ", buf[i]); | ||
| 217 | } | ||
| 187 | place_bit0(); // Stopbit(0); | 218 | place_bit0(); // Stopbit(0); |
| 188 | sei(); | 219 | sei(); |
| 189 | } | 220 | } |
| 190 | 221 | ||
| 222 | void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l) { | ||
| 223 | uint8_t buf[2] = {data_h, data_l}; | ||
| 224 | adb_host_listen_buf(addr, reg, buf, 2); | ||
| 225 | } | ||
| 226 | |||
| 227 | void adb_host_flush(uint8_t addr) { | ||
| 228 | cli(); | ||
| 229 | attention(); | ||
| 230 | send_byte((addr << 4) | ADB_CMD_FLUSH); | ||
| 231 | place_bit0(); // Stopbit(0) | ||
| 232 | _delay_us(200); // Tlt/Stop to Start | ||
| 233 | sei(); | ||
| 234 | } | ||
| 235 | |||
| 191 | // send state of LEDs | 236 | // send state of LEDs |
| 192 | void adb_host_kbd_led(uint8_t led) { | 237 | void adb_host_kbd_led(uint8_t led) { |
| 193 | // Addr:Keyboard(0010), Cmd:Listen(10), Register2(10) | 238 | // Listen Register2 |
| 194 | // send upper byte (not used) | 239 | // upper byte: not used |
| 195 | // send lower byte (bit2: ScrollLock, bit1: CapsLock, bit0: | 240 | // lower byte: bit2=ScrollLock, bit1=CapsLock, bit0=NumLock |
| 196 | adb_host_listen(0x2A, 0, led & 0x07); | 241 | adb_host_listen(ADB_ADDR_KEYBOARD, ADB_REG_2, 0, led & 0x07); |
| 197 | } | 242 | } |
| 198 | 243 | ||
| 199 | #ifdef ADB_PSW_BIT | 244 | #ifdef ADB_PSW_BIT |
| @@ -327,7 +372,7 @@ Commands | |||
| 327 | 372 | ||
| 328 | bits commands | 373 | bits commands |
| 329 | ------------------------------------------------------ | 374 | ------------------------------------------------------ |
| 330 | - - - - 0 0 0 0 Send Request(reset all devices) | 375 | - - - - 0 0 0 0 Send Reset(reset all devices) |
| 331 | A A A A 0 0 0 1 Flush(reset a device) | 376 | A A A A 0 0 0 1 Flush(reset a device) |
| 332 | - - - - 0 0 1 0 Reserved | 377 | - - - - 0 0 1 0 Reserved |
| 333 | - - - - 0 0 1 1 Reserved | 378 | - - - - 0 0 1 1 Reserved |
| @@ -435,5 +480,56 @@ Keyboard LEDs & state of keys(Register2) | |||
| 435 | | +----------------------------- Delete | 480 | | +----------------------------- Delete |
| 436 | +------------------------------- Reserved | 481 | +------------------------------- Reserved |
| 437 | 482 | ||
| 483 | Address, Handler ID and bits(Register3) | ||
| 484 | 1514131211 . . 8 7 . . . . . . 0 | ||
| 485 | | | | | | | | | | | | | | | | | | ||
| 486 | | | | | | | | | +-+-+-+-+-+-+-+- Handler ID | ||
| 487 | | | | | +-+-+-+----------------- Address | ||
| 488 | | | | +------------------------- 0 | ||
| 489 | | | +--------------------------- Service request enable(1 = enabled) | ||
| 490 | | +----------------------------- Exceptional event(alwyas 1 if not used) | ||
| 491 | +------------------------------- 0 | ||
| 492 | |||
| 493 | ADB Bit Cells | ||
| 494 | bit cell time: 70-130us | ||
| 495 | low part of bit0: 60-70% of bit cell | ||
| 496 | low part of bit1: 30-40% of bit cell | ||
| 497 | |||
| 498 | bit cell time 70us 130us | ||
| 499 | -------------------------------------------- | ||
| 500 | low part of bit0 42-49 78-91 | ||
| 501 | high part of bit0 21-28 39-52 | ||
| 502 | low part of bit1 21-28 39-52 | ||
| 503 | high part of bit1 42-49 78-91 | ||
| 504 | |||
| 505 | |||
| 506 | bit0: | ||
| 507 | 70us bit cell: | ||
| 508 | ____________~~~~~~ | ||
| 509 | 42-49 21-28 | ||
| 510 | |||
| 511 | 130us bit cell: | ||
| 512 | ____________~~~~~~ | ||
| 513 | 78-91 39-52 | ||
| 514 | |||
| 515 | bit1: | ||
| 516 | 70us bit cell: | ||
| 517 | ______~~~~~~~~~~~~ | ||
| 518 | 21-28 42-49 | ||
| 519 | |||
| 520 | 130us bit cell: | ||
| 521 | ______~~~~~~~~~~~~ | ||
| 522 | 39-52 78-91 | ||
| 523 | |||
| 524 | [from Apple IIgs Hardware Reference Second Edition] | ||
| 525 | |||
| 526 | Keyboard Handle ID | ||
| 527 | Apple Standard Keyboard M0116: 0x01 | ||
| 528 | Apple Extended Keyboard M0115: 0x02 | ||
| 529 | Apple Extended Keyboard II M3501: 0x02 | ||
| 530 | Apple Adjustable Keybaord: 0x10 | ||
| 531 | |||
| 532 | http://lxr.free-electrons.com/source/drivers/macintosh/adbhid.c?v=4.4#L802 | ||
| 533 | |||
| 438 | END_OF_ADB | 534 | END_OF_ADB |
| 439 | */ | 535 | */ |
diff --git a/tmk_core/protocol/adb.h b/tmk_core/protocol/adb.h index 34cbcf769..fe8becc2d 100644 --- a/tmk_core/protocol/adb.h +++ b/tmk_core/protocol/adb.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | Copyright 2011 Jun WAKO <wakojun@gmail.com> | 2 | Copyright 2011-19 Jun WAKO <wakojun@gmail.com> |
| 3 | 3 | ||
| 4 | This software is licensed with a Modified BSD License. | 4 | This software is licensed with a Modified BSD License. |
| 5 | All of this is supposed to be Free Software, Open Source, DFSG-free, | 5 | All of this is supposed to be Free Software, Open Source, DFSG-free, |
| @@ -47,12 +47,60 @@ POSSIBILITY OF SUCH DAMAGE. | |||
| 47 | #define ADB_POWER 0x7F | 47 | #define ADB_POWER 0x7F |
| 48 | #define ADB_CAPS 0x39 | 48 | #define ADB_CAPS 0x39 |
| 49 | 49 | ||
| 50 | /* ADB commands */ | ||
| 51 | // Default Address | ||
| 52 | #define ADB_ADDR_0 0 | ||
| 53 | #define ADB_ADDR_DONGLE 1 | ||
| 54 | #define ADB_ADDR_KEYBOARD 2 | ||
| 55 | #define ADB_ADDR_MOUSE 3 | ||
| 56 | #define ADB_ADDR_TABLET 4 | ||
| 57 | #define ADB_ADDR_APPLIANCE 7 | ||
| 58 | #define ADB_ADDR_8 8 | ||
| 59 | #define ADB_ADDR_9 9 | ||
| 60 | #define ADB_ADDR_10 10 | ||
| 61 | #define ADB_ADDR_11 11 | ||
| 62 | #define ADB_ADDR_12 12 | ||
| 63 | #define ADB_ADDR_13 13 | ||
| 64 | #define ADB_ADDR_14 14 | ||
| 65 | #define ADB_ADDR_15 15 | ||
| 66 | // for temporary purpose, do not use for polling | ||
| 67 | #define ADB_ADDR_TMP 15 | ||
| 68 | #define ADB_ADDR_MOUSE_POLL 10 | ||
| 69 | // Command Type | ||
| 70 | #define ADB_CMD_RESET 0 | ||
| 71 | #define ADB_CMD_FLUSH 1 | ||
| 72 | #define ADB_CMD_LISTEN 8 | ||
| 73 | #define ADB_CMD_TALK 12 | ||
| 74 | // Register | ||
| 75 | #define ADB_REG_0 0 | ||
| 76 | #define ADB_REG_1 1 | ||
| 77 | #define ADB_REG_2 2 | ||
| 78 | #define ADB_REG_3 3 | ||
| 79 | |||
| 80 | /* ADB keyboard handler id */ | ||
| 81 | #define ADB_HANDLER_STD 0x01 /* IIGS, M0116 */ | ||
| 82 | #define ADB_HANDLER_AEK 0x02 /* M0115, M3501 */ | ||
| 83 | #define ADB_HANDLER_AEK_RMOD 0x03 /* M0115, M3501, alternate mode enableing right modifiers */ | ||
| 84 | #define ADB_HANDLER_STD_ISO 0x04 /* M0118, ISO swapping keys */ | ||
| 85 | #define ADB_HANDLER_AEK_ISO 0x05 /* M0115, M3501, ISO swapping keys */ | ||
| 86 | #define ADB_HANDLER_M1242_ANSI 0x10 /* Adjustable keyboard */ | ||
| 87 | #define ADB_HANDLER_CLASSIC1_MOUSE 0x01 | ||
| 88 | #define ADB_HANDLER_CLASSIC2_MOUSE 0x02 | ||
| 89 | #define ADB_HANDLER_EXTENDED_MOUSE 0x04 | ||
| 90 | #define ADB_HANDLER_TURBO_MOUSE 0x32 | ||
| 91 | |||
| 50 | // ADB host | 92 | // ADB host |
| 51 | void adb_host_init(void); | 93 | void adb_host_init(void); |
| 52 | bool adb_host_psw(void); | 94 | bool adb_host_psw(void); |
| 95 | uint16_t adb_host_talk(uint8_t addr, uint8_t reg); | ||
| 96 | uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len); | ||
| 97 | void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l); | ||
| 98 | void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len); | ||
| 99 | void adb_host_flush(uint8_t addr); | ||
| 100 | void adb_host_kbd_led(uint8_t led); | ||
| 53 | uint16_t adb_host_kbd_recv(void); | 101 | uint16_t adb_host_kbd_recv(void); |
| 54 | uint16_t adb_host_mouse_recv(void); | 102 | uint16_t adb_host_mouse_recv(void); |
| 55 | void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l); | 103 | |
| 56 | void adb_host_kbd_led(uint8_t led); | 104 | // ADB Mouse |
| 57 | void adb_mouse_task(void); | 105 | void adb_mouse_task(void); |
| 58 | void adb_mouse_init(void); | 106 | void adb_mouse_init(void); |
diff --git a/tmk_core/protocol/arm_atsam/i2c_master.c b/tmk_core/protocol/arm_atsam/i2c_master.c index d3319ab44..dda2f85b0 100644 --- a/tmk_core/protocol/arm_atsam/i2c_master.c +++ b/tmk_core/protocol/arm_atsam/i2c_master.c | |||
| @@ -28,6 +28,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 28 | 28 | ||
| 29 | # define I2C_LED_USE_DMA 1 // Set 1 to use background DMA transfers for leds, Set 0 to use inline software transfers | 29 | # define I2C_LED_USE_DMA 1 // Set 1 to use background DMA transfers for leds, Set 0 to use inline software transfers |
| 30 | 30 | ||
| 31 | DmacDescriptor dmac_desc; | ||
| 32 | DmacDescriptor dmac_desc_wb; | ||
| 33 | |||
| 31 | static uint8_t i2c_led_q[I2C_Q_SIZE]; // I2C queue circular buffer | 34 | static uint8_t i2c_led_q[I2C_Q_SIZE]; // I2C queue circular buffer |
| 32 | static uint8_t i2c_led_q_s; // Start of circular buffer | 35 | static uint8_t i2c_led_q_s; // Start of circular buffer |
| 33 | static uint8_t i2c_led_q_e; // End of circular buffer | 36 | static uint8_t i2c_led_q_e; // End of circular buffer |
diff --git a/tmk_core/protocol/arm_atsam/i2c_master.h b/tmk_core/protocol/arm_atsam/i2c_master.h index 44dbdfbff..68773f213 100644 --- a/tmk_core/protocol/arm_atsam/i2c_master.h +++ b/tmk_core/protocol/arm_atsam/i2c_master.h | |||
| @@ -24,8 +24,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 24 | # include "issi3733_driver.h" | 24 | # include "issi3733_driver.h" |
| 25 | # include "config.h" | 25 | # include "config.h" |
| 26 | 26 | ||
| 27 | __attribute__((__aligned__(16))) DmacDescriptor dmac_desc; | 27 | extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc; |
| 28 | __attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb; | 28 | extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb; |
| 29 | 29 | ||
| 30 | uint8_t I2C3733_Init_Control(void); | 30 | uint8_t I2C3733_Init_Control(void); |
| 31 | uint8_t I2C3733_Init_Drivers(void); | 31 | uint8_t I2C3733_Init_Drivers(void); |
diff --git a/tmk_core/protocol/arm_atsam/main_arm_atsam.c b/tmk_core/protocol/arm_atsam/main_arm_atsam.c index e10be52fb..a3d1f3449 100644 --- a/tmk_core/protocol/arm_atsam/main_arm_atsam.c +++ b/tmk_core/protocol/arm_atsam/main_arm_atsam.c | |||
| @@ -306,9 +306,6 @@ int main(void) { | |||
| 306 | } | 306 | } |
| 307 | #endif // CONSOLE_ENABLE | 307 | #endif // CONSOLE_ENABLE |
| 308 | 308 | ||
| 309 | // Run housekeeping | ||
| 310 | housekeeping_task_kb(); | ||
| 311 | housekeeping_task_user(); | ||
| 312 | } | 309 | } |
| 313 | 310 | ||
| 314 | return 1; | 311 | return 1; |
diff --git a/tmk_core/protocol/chibios/main.c b/tmk_core/protocol/chibios/main.c index e07c181fc..63e4c99d2 100644 --- a/tmk_core/protocol/chibios/main.c +++ b/tmk_core/protocol/chibios/main.c | |||
| @@ -163,6 +163,7 @@ int main(void) { | |||
| 163 | keyboard_setup(); | 163 | keyboard_setup(); |
| 164 | 164 | ||
| 165 | /* Init USB */ | 165 | /* Init USB */ |
| 166 | usb_event_queue_init(); | ||
| 166 | init_usb_driver(&USB_DRIVER); | 167 | init_usb_driver(&USB_DRIVER); |
| 167 | 168 | ||
| 168 | #ifdef MIDI_ENABLE | 169 | #ifdef MIDI_ENABLE |
| @@ -221,6 +222,8 @@ int main(void) { | |||
| 221 | 222 | ||
| 222 | /* Main loop */ | 223 | /* Main loop */ |
| 223 | while (true) { | 224 | while (true) { |
| 225 | usb_event_queue_task(); | ||
| 226 | |||
| 224 | #if !defined(NO_USB_STARTUP_CHECK) | 227 | #if !defined(NO_USB_STARTUP_CHECK) |
| 225 | if (USB_DRIVER.state == USB_SUSPENDED) { | 228 | if (USB_DRIVER.state == USB_SUSPENDED) { |
| 226 | print("[s]"); | 229 | print("[s]"); |
diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c index ad489fb91..13b1e34d2 100644 --- a/tmk_core/protocol/chibios/usb_main.c +++ b/tmk_core/protocol/chibios/usb_main.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | 27 | ||
| 28 | #include <ch.h> | 28 | #include <ch.h> |
| 29 | #include <hal.h> | 29 | #include <hal.h> |
| 30 | #include <string.h> | ||
| 30 | 31 | ||
| 31 | #include "usb_main.h" | 32 | #include "usb_main.h" |
| 32 | 33 | ||
| @@ -368,6 +369,69 @@ static usb_driver_configs_t drivers = { | |||
| 368 | * --------------------------------------------------------- | 369 | * --------------------------------------------------------- |
| 369 | */ | 370 | */ |
| 370 | 371 | ||
| 372 | #define USB_EVENT_QUEUE_SIZE 16 | ||
| 373 | usbevent_t event_queue[USB_EVENT_QUEUE_SIZE]; | ||
| 374 | uint8_t event_queue_head; | ||
| 375 | uint8_t event_queue_tail; | ||
| 376 | |||
| 377 | void usb_event_queue_init(void) { | ||
| 378 | // Initialise the event queue | ||
| 379 | memset(&event_queue, 0, sizeof(event_queue)); | ||
| 380 | event_queue_head = 0; | ||
| 381 | event_queue_tail = 0; | ||
| 382 | } | ||
| 383 | |||
| 384 | static inline bool usb_event_queue_enqueue(usbevent_t event) { | ||
| 385 | uint8_t next = (event_queue_head + 1) % USB_EVENT_QUEUE_SIZE; | ||
| 386 | if (next == event_queue_tail) { | ||
| 387 | return false; | ||
| 388 | } | ||
| 389 | event_queue[event_queue_head] = event; | ||
| 390 | event_queue_head = next; | ||
| 391 | return true; | ||
| 392 | } | ||
| 393 | |||
| 394 | static inline bool usb_event_queue_dequeue(usbevent_t *event) { | ||
| 395 | if (event_queue_head == event_queue_tail) { | ||
| 396 | return false; | ||
| 397 | } | ||
| 398 | *event = event_queue[event_queue_tail]; | ||
| 399 | event_queue_tail = (event_queue_tail + 1) % USB_EVENT_QUEUE_SIZE; | ||
| 400 | return true; | ||
| 401 | } | ||
| 402 | |||
| 403 | static inline void usb_event_suspend_handler(void) { | ||
| 404 | #ifdef SLEEP_LED_ENABLE | ||
| 405 | sleep_led_enable(); | ||
| 406 | #endif /* SLEEP_LED_ENABLE */ | ||
| 407 | } | ||
| 408 | |||
| 409 | static inline void usb_event_wakeup_handler(void) { | ||
| 410 | suspend_wakeup_init(); | ||
| 411 | #ifdef SLEEP_LED_ENABLE | ||
| 412 | sleep_led_disable(); | ||
| 413 | // NOTE: converters may not accept this | ||
| 414 | led_set(host_keyboard_leds()); | ||
| 415 | #endif /* SLEEP_LED_ENABLE */ | ||
| 416 | } | ||
| 417 | |||
| 418 | void usb_event_queue_task(void) { | ||
| 419 | usbevent_t event; | ||
| 420 | while (usb_event_queue_dequeue(&event)) { | ||
| 421 | switch (event) { | ||
| 422 | case USB_EVENT_SUSPEND: | ||
| 423 | usb_event_suspend_handler(); | ||
| 424 | break; | ||
| 425 | case USB_EVENT_WAKEUP: | ||
| 426 | usb_event_wakeup_handler(); | ||
| 427 | break; | ||
| 428 | default: | ||
| 429 | // Nothing to do, we don't handle it. | ||
| 430 | break; | ||
| 431 | } | ||
| 432 | } | ||
| 433 | } | ||
| 434 | |||
| 371 | /* Handles the USB driver global events | 435 | /* Handles the USB driver global events |
| 372 | * TODO: maybe disable some things when connection is lost? */ | 436 | * TODO: maybe disable some things when connection is lost? */ |
| 373 | static void usb_event_cb(USBDriver *usbp, usbevent_t event) { | 437 | static void usb_event_cb(USBDriver *usbp, usbevent_t event) { |
| @@ -402,9 +466,7 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) { | |||
| 402 | osalSysUnlockFromISR(); | 466 | osalSysUnlockFromISR(); |
| 403 | return; | 467 | return; |
| 404 | case USB_EVENT_SUSPEND: | 468 | case USB_EVENT_SUSPEND: |
| 405 | #ifdef SLEEP_LED_ENABLE | 469 | usb_event_queue_enqueue(USB_EVENT_SUSPEND); |
| 406 | sleep_led_enable(); | ||
| 407 | #endif /* SLEEP_LED_ENABLE */ | ||
| 408 | /* Falls into.*/ | 470 | /* Falls into.*/ |
| 409 | case USB_EVENT_UNCONFIGURED: | 471 | case USB_EVENT_UNCONFIGURED: |
| 410 | /* Falls into.*/ | 472 | /* Falls into.*/ |
| @@ -425,12 +487,7 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) { | |||
| 425 | qmkusbWakeupHookI(&drivers.array[i].driver); | 487 | qmkusbWakeupHookI(&drivers.array[i].driver); |
| 426 | chSysUnlockFromISR(); | 488 | chSysUnlockFromISR(); |
| 427 | } | 489 | } |
| 428 | suspend_wakeup_init(); | 490 | usb_event_queue_enqueue(USB_EVENT_WAKEUP); |
| 429 | #ifdef SLEEP_LED_ENABLE | ||
| 430 | sleep_led_disable(); | ||
| 431 | // NOTE: converters may not accept this | ||
| 432 | led_set(host_keyboard_leds()); | ||
| 433 | #endif /* SLEEP_LED_ENABLE */ | ||
| 434 | return; | 491 | return; |
| 435 | 492 | ||
| 436 | case USB_EVENT_STALLED: | 493 | case USB_EVENT_STALLED: |
| @@ -651,6 +708,17 @@ void init_usb_driver(USBDriver *usbp) { | |||
| 651 | void restart_usb_driver(USBDriver *usbp) { | 708 | void restart_usb_driver(USBDriver *usbp) { |
| 652 | usbStop(usbp); | 709 | usbStop(usbp); |
| 653 | usbDisconnectBus(usbp); | 710 | usbDisconnectBus(usbp); |
| 711 | |||
| 712 | #if USB_SUSPEND_WAKEUP_DELAY > 0 | ||
| 713 | // Some hubs, kvm switches, and monitors do | ||
| 714 | // weird things, with USB device state bouncing | ||
| 715 | // around wildly on wakeup, yielding race | ||
| 716 | // conditions that can corrupt the keyboard state. | ||
| 717 | // | ||
| 718 | // Pause for a while to let things settle... | ||
| 719 | wait_ms(USB_SUSPEND_WAKEUP_DELAY); | ||
| 720 | #endif | ||
| 721 | |||
| 654 | usbStart(usbp, &usbcfg); | 722 | usbStart(usbp, &usbcfg); |
| 655 | usbConnectBus(usbp); | 723 | usbConnectBus(usbp); |
| 656 | } | 724 | } |
diff --git a/tmk_core/protocol/chibios/usb_main.h b/tmk_core/protocol/chibios/usb_main.h index eaa08d8f7..fb33c8cd0 100644 --- a/tmk_core/protocol/chibios/usb_main.h +++ b/tmk_core/protocol/chibios/usb_main.h | |||
| @@ -38,6 +38,17 @@ void init_usb_driver(USBDriver *usbp); | |||
| 38 | void restart_usb_driver(USBDriver *usbp); | 38 | void restart_usb_driver(USBDriver *usbp); |
| 39 | 39 | ||
| 40 | /* --------------- | 40 | /* --------------- |
| 41 | * USB Event queue | ||
| 42 | * --------------- | ||
| 43 | */ | ||
| 44 | |||
| 45 | /* Initialisation of the FIFO */ | ||
| 46 | void usb_event_queue_init(void); | ||
| 47 | |||
| 48 | /* Task to dequeue and execute any handlers for the USB events on the main thread */ | ||
| 49 | void usb_event_queue_task(void); | ||
| 50 | |||
| 51 | /* --------------- | ||
| 41 | * Keyboard header | 52 | * Keyboard header |
| 42 | * --------------- | 53 | * --------------- |
| 43 | */ | 54 | */ |
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index 623aa33ff..74e48222d 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c | |||
| @@ -435,7 +435,9 @@ void EVENT_USB_Device_Suspend() { | |||
| 435 | */ | 435 | */ |
| 436 | void EVENT_USB_Device_WakeUp() { | 436 | void EVENT_USB_Device_WakeUp() { |
| 437 | print("[W]"); | 437 | print("[W]"); |
| 438 | #if defined(NO_USB_STARTUP_CHECK) | ||
| 438 | suspend_wakeup_init(); | 439 | suspend_wakeup_init(); |
| 440 | #endif | ||
| 439 | 441 | ||
| 440 | #ifdef SLEEP_LED_ENABLE | 442 | #ifdef SLEEP_LED_ENABLE |
| 441 | sleep_led_disable(); | 443 | sleep_led_disable(); |
| @@ -1073,12 +1075,26 @@ int main(void) { | |||
| 1073 | print("Keyboard start.\n"); | 1075 | print("Keyboard start.\n"); |
| 1074 | while (1) { | 1076 | while (1) { |
| 1075 | #if !defined(NO_USB_STARTUP_CHECK) | 1077 | #if !defined(NO_USB_STARTUP_CHECK) |
| 1076 | while (USB_DeviceState == DEVICE_STATE_Suspended) { | 1078 | if (USB_DeviceState == DEVICE_STATE_Suspended) { |
| 1077 | print("[s]"); | 1079 | print("[s]"); |
| 1078 | suspend_power_down(); | 1080 | while (USB_DeviceState == DEVICE_STATE_Suspended) { |
| 1079 | if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { | 1081 | suspend_power_down(); |
| 1080 | USB_Device_SendRemoteWakeup(); | 1082 | if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { |
| 1083 | USB_Device_SendRemoteWakeup(); | ||
| 1084 | clear_keyboard(); | ||
| 1085 | |||
| 1086 | # if USB_SUSPEND_WAKEUP_DELAY > 0 | ||
| 1087 | // Some hubs, kvm switches, and monitors do | ||
| 1088 | // weird things, with USB device state bouncing | ||
| 1089 | // around wildly on wakeup, yielding race | ||
| 1090 | // conditions that can corrupt the keyboard state. | ||
| 1091 | // | ||
| 1092 | // Pause for a while to let things settle... | ||
| 1093 | wait_ms(USB_SUSPEND_WAKEUP_DELAY); | ||
| 1094 | # endif | ||
| 1095 | } | ||
| 1081 | } | 1096 | } |
| 1097 | suspend_wakeup_init(); | ||
| 1082 | } | 1098 | } |
| 1083 | #endif | 1099 | #endif |
| 1084 | 1100 | ||
diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c index 7ea4b2e37..ba7760f28 100644 --- a/tmk_core/protocol/usb_descriptor.c +++ b/tmk_core/protocol/usb_descriptor.c | |||
| @@ -116,19 +116,15 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = { | |||
| 116 | # endif | 116 | # endif |
| 117 | HID_RI_USAGE(8, 0x01), // Pointer | 117 | HID_RI_USAGE(8, 0x01), // Pointer |
| 118 | HID_RI_COLLECTION(8, 0x00), // Physical | 118 | HID_RI_COLLECTION(8, 0x00), // Physical |
| 119 | // Buttons (5 bits) | 119 | // Buttons (8 bits) |
| 120 | HID_RI_USAGE_PAGE(8, 0x09), // Button | 120 | HID_RI_USAGE_PAGE(8, 0x09), // Button |
| 121 | HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1 | 121 | HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1 |
| 122 | HID_RI_USAGE_MAXIMUM(8, 0x05), // Button 5 | 122 | HID_RI_USAGE_MAXIMUM(8, 0x08), // Button 8 |
| 123 | HID_RI_LOGICAL_MINIMUM(8, 0x00), | 123 | HID_RI_LOGICAL_MINIMUM(8, 0x00), |
| 124 | HID_RI_LOGICAL_MAXIMUM(8, 0x01), | 124 | HID_RI_LOGICAL_MAXIMUM(8, 0x01), |
| 125 | HID_RI_REPORT_COUNT(8, 0x05), | 125 | HID_RI_REPORT_COUNT(8, 0x08), |
| 126 | HID_RI_REPORT_SIZE(8, 0x01), | 126 | HID_RI_REPORT_SIZE(8, 0x01), |
| 127 | HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), | 127 | HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), |
| 128 | // Button padding (3 bits) | ||
| 129 | HID_RI_REPORT_COUNT(8, 0x01), | ||
| 130 | HID_RI_REPORT_SIZE(8, 0x03), | ||
| 131 | HID_RI_INPUT(8, HID_IOF_CONSTANT), | ||
| 132 | 128 | ||
| 133 | // X/Y position (2 bytes) | 129 | // X/Y position (2 bytes) |
| 134 | HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop | 130 | HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop |
| @@ -356,7 +352,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = { | |||
| 356 | .Type = DTYPE_Device | 352 | .Type = DTYPE_Device |
| 357 | }, | 353 | }, |
| 358 | .USBSpecification = VERSION_BCD(1, 1, 0), | 354 | .USBSpecification = VERSION_BCD(1, 1, 0), |
| 359 | 355 | ||
| 360 | #if VIRTSER_ENABLE | 356 | #if VIRTSER_ENABLE |
| 361 | .Class = USB_CSCP_IADDeviceClass, | 357 | .Class = USB_CSCP_IADDeviceClass, |
| 362 | .SubClass = USB_CSCP_IADDeviceSubclass, | 358 | .SubClass = USB_CSCP_IADDeviceSubclass, |
diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c index a422903cc..9362fbde7 100644 --- a/tmk_core/protocol/vusb/vusb.c +++ b/tmk_core/protocol/vusb/vusb.c | |||
| @@ -444,19 +444,15 @@ const PROGMEM uchar shared_hid_report[] = { | |||
| 444 | 0x85, REPORT_ID_MOUSE, // Report ID | 444 | 0x85, REPORT_ID_MOUSE, // Report ID |
| 445 | 0x09, 0x01, // Usage (Pointer) | 445 | 0x09, 0x01, // Usage (Pointer) |
| 446 | 0xA1, 0x00, // Collection (Physical) | 446 | 0xA1, 0x00, // Collection (Physical) |
| 447 | // Buttons (5 bits) | 447 | // Buttons (8 bits) |
| 448 | 0x05, 0x09, // Usage Page (Button) | 448 | 0x05, 0x09, // Usage Page (Button) |
| 449 | 0x19, 0x01, // Usage Minimum (Button 1) | 449 | 0x19, 0x01, // Usage Minimum (Button 1) |
| 450 | 0x29, 0x05, // Usage Maximum (Button 5) | 450 | 0x29, 0x08, // Usage Maximum (Button 8) |
| 451 | 0x15, 0x00, // Logical Minimum (0) | 451 | 0x15, 0x00, // Logical Minimum (0) |
| 452 | 0x25, 0x01, // Logical Maximum (1) | 452 | 0x25, 0x01, // Logical Maximum (1) |
| 453 | 0x95, 0x05, // Report Count (5) | 453 | 0x95, 0x08, // Report Count (8) |
| 454 | 0x75, 0x01, // Report Size (1) | 454 | 0x75, 0x01, // Report Size (1) |
| 455 | 0x81, 0x02, // Input (Data, Variable, Absolute) | 455 | 0x81, 0x02, // Input (Data, Variable, Absolute) |
| 456 | // Button padding (3 bits) | ||
| 457 | 0x95, 0x01, // Report Count (1) | ||
| 458 | 0x75, 0x03, // Report Size (3) | ||
| 459 | 0x81, 0x03, // Input (Constant) | ||
| 460 | 456 | ||
| 461 | // X/Y position (2 bytes) | 457 | // X/Y position (2 bytes) |
| 462 | 0x05, 0x01, // Usage Page (Generic Desktop) | 458 | 0x05, 0x01, // Usage Page (Generic Desktop) |
