aboutsummaryrefslogtreecommitdiff
path: root/tmk_core
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core')
-rw-r--r--tmk_core/chibios.mk4
-rw-r--r--tmk_core/common.mk1
-rw-r--r--tmk_core/common/action.c18
-rw-r--r--tmk_core/common/avr/bootloader.c10
-rw-r--r--tmk_core/common/avr/suspend.c5
-rw-r--r--tmk_core/common/chibios/suspend.c7
-rw-r--r--tmk_core/common/keyboard.c37
-rw-r--r--tmk_core/common/keyboard.h9
-rw-r--r--tmk_core/common/keycode.h14
-rw-r--r--tmk_core/common/matrix.h3
-rw-r--r--tmk_core/common/mousekey.c128
-rw-r--r--tmk_core/common/mousekey.h43
-rw-r--r--tmk_core/common/report.h5
-rw-r--r--tmk_core/common/suspend.h4
-rw-r--r--tmk_core/common/sync_timer.c58
-rw-r--r--tmk_core/common/sync_timer.h54
-rw-r--r--tmk_core/common/uart.c172
-rw-r--r--tmk_core/common/uart.h8
-rw-r--r--tmk_core/common/wait.h79
-rw-r--r--tmk_core/protocol/adb.c256
-rw-r--r--tmk_core/protocol/adb.h58
-rw-r--r--tmk_core/protocol/arm_atsam/i2c_master.c3
-rw-r--r--tmk_core/protocol/arm_atsam/i2c_master.h4
-rw-r--r--tmk_core/protocol/arm_atsam/main_arm_atsam.c3
-rw-r--r--tmk_core/protocol/chibios/main.c3
-rw-r--r--tmk_core/protocol/chibios/usb_main.c86
-rw-r--r--tmk_core/protocol/chibios/usb_main.h11
-rw-r--r--tmk_core/protocol/lufa/lufa.c24
-rw-r--r--tmk_core/protocol/usb_descriptor.c12
-rw-r--r--tmk_core/protocol/vusb/vusb.c10
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
74endif 77endif
75 78
76ifeq ("$(wildcard $(BOARD_MK))","") 79ifeq ("$(wildcard $(BOARD_MK))","")
@@ -309,6 +312,7 @@ LDFLAGS += -mno-thumb-interwork -mthumb
309LDSYMBOLS =,--defsym=__process_stack_size__=$(USE_PROCESS_STACKSIZE) 312LDSYMBOLS =,--defsym=__process_stack_size__=$(USE_PROCESS_STACKSIZE)
310LDSYMBOLS :=$(LDSYMBOLS),--defsym=__main_stack_size__=$(USE_EXCEPTIONS_STACKSIZE) 313LDSYMBOLS :=$(LDSYMBOLS),--defsym=__main_stack_size__=$(USE_EXCEPTIONS_STACKSIZE)
311LDFLAGS += -Wl,--script=$(LDSCRIPT)$(LDSYMBOLS) 314LDFLAGS += -Wl,--script=$(LDSCRIPT)$(LDSYMBOLS)
315LDFLAGS += --specs=nano.specs
312 316
313OPT_DEFS += -DPROTOCOL_CHIBIOS 317OPT_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
23ifeq ($(PLATFORM),AVR) 24ifeq ($(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 */
80void bootloader_jump(void) { 80__attribute__((weak)) void bootloader_jump(void) {
81#if !defined(BOOTLOADER_SIZE) 81#if !defined(BOOTLOADER_SIZE)
82 uint8_t high_fuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS); 82 uint8_t high_fuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS);
83 83
@@ -237,13 +237,13 @@ void bootloader_jump(void) {
237 "bootloader_startup_loop%=: \n\t" 237 "bootloader_startup_loop%=: \n\t"
238 "rjmp bootloader_startup_loop%= \n\t" 238 "rjmp bootloader_startup_loop%= \n\t"
239 : 239 :
240 : [mcucsrio] "I"(_SFR_IO_ADDR(MCUCSR)), 240 : [ mcucsrio ] "I"(_SFR_IO_ADDR(MCUCSR)),
241# if (FLASHEND > 131071) 241# if (FLASHEND > 131071)
242 [ramendhi] "M"(((RAMEND - 2) >> 8) & 0xff), [ramendlo] "M"(((RAMEND - 2) >> 0) & 0xff), [bootaddrhi] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 16) & 0xff), 242 [ ramendhi ] "M"(((RAMEND - 2) >> 8) & 0xff), [ ramendlo ] "M"(((RAMEND - 2) >> 0) & 0xff), [ bootaddrhi ] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 16) & 0xff),
243# else 243# else
244 [ramendhi] "M"(((RAMEND - 1) >> 8) & 0xff), [ramendlo] "M"(((RAMEND - 1) >> 0) & 0xff), 244 [ ramendhi ] "M"(((RAMEND - 1) >> 8) & 0xff), [ ramendlo ] "M"(((RAMEND - 1) >> 0) & 0xff),
245# endif 245# endif
246 [bootaddrme] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 8) & 0xff), [bootaddrlo] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 0) & 0xff)); 246 [ bootaddrme ] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 8) & 0xff), [ bootaddrlo ] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 0) & 0xff));
247 247
248#else // Assume remaining boards are DFU, even if the flag isn't set 248#else // Assume remaining boards are DFU, even if the flag isn't set
249 249
diff --git a/tmk_core/common/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
100static uint32_t last_input_modification_time = 0;
101uint32_t last_input_activity_time(void) { return last_input_modification_time; }
102uint32_t last_input_activity_elapsed(void) { return timer_elapsed32(last_input_modification_time); }
103
104static uint32_t last_matrix_modification_time = 0;
105uint32_t last_matrix_activity_time(void) { return last_matrix_modification_time; }
106uint32_t last_matrix_activity_elapsed(void) { return timer_elapsed32(last_matrix_modification_time); }
107void last_matrix_activity_trigger(void) { last_matrix_modification_time = last_input_modification_time = timer_read32(); }
108
109static uint32_t last_encoder_modification_time = 0;
110uint32_t last_encoder_activity_time(void) { return last_encoder_modification_time; }
111uint32_t last_encoder_activity_elapsed(void) { return timer_elapsed32(last_encoder_modification_time); }
112void last_encoder_activity_trigger(void) { last_encoder_modification_time = last_input_modification_time = timer_read32(); }
113
99// Only enable this if console is enabled to print to 114// Only enable this if console is enabled to print to
100#if defined(DEBUG_MATRIX_SCAN_RATE) 115#if defined(DEBUG_MATRIX_SCAN_RATE)
101static uint32_t matrix_timer = 0; 116static uint32_t matrix_timer = 0;
@@ -260,6 +275,7 @@ __attribute__((weak)) void housekeeping_task_user(void) {}
260 */ 275 */
261void keyboard_init(void) { 276void 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);
73void housekeeping_task_kb(void); 73void housekeeping_task_kb(void);
74void housekeeping_task_user(void); 74void housekeeping_task_user(void);
75 75
76uint32_t last_input_activity_time(void); // Timestamp of the last matrix or encoder activity
77uint32_t last_input_activity_elapsed(void); // Number of milliseconds since the last matrix or encoder activity
78
79uint32_t last_matrix_activity_time(void); // Timestamp of the last matrix activity
80uint32_t last_matrix_activity_elapsed(void); // Number of milliseconds since the last matrix activity
81
82uint32_t last_encoder_activity_time(void); // Timestamp of the last encoder activity
83uint32_t last_encoder_activity_elapsed(void); // Number of milliseconds since the last encoder activity
84
76uint32_t get_matrix_scan_rate(void); 85uint32_t get_matrix_scan_rate(void);
77 86
78#ifdef __cplusplus 87#ifdef __cplusplus
diff --git a/tmk_core/common/keycode.h b/tmk_core/common/keycode.h
index d35e44d8d..efad92b23 100644
--- a/tmk_core/common/keycode.h
+++ b/tmk_core/common/keycode.h
@@ -39,7 +39,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
39 39
40#define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2) 40#define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2)
41#define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT) 41#define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT)
42#define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN5) 42#define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN8)
43#define IS_MOUSEKEY_WHEEL(code) (KC_MS_WH_UP <= (code) && (code) <= KC_MS_WH_RIGHT) 43#define IS_MOUSEKEY_WHEEL(code) (KC_MS_WH_UP <= (code) && (code) <= KC_MS_WH_RIGHT)
44#define IS_MOUSEKEY_ACCEL(code) (KC_MS_ACCEL0 <= (code) && (code) <= KC_MS_ACCEL2) 44#define IS_MOUSEKEY_ACCEL(code) (KC_MS_ACCEL0 <= (code) && (code) <= KC_MS_ACCEL2)
45 45
@@ -205,6 +205,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
205#define KC_BTN3 KC_MS_BTN3 205#define KC_BTN3 KC_MS_BTN3
206#define KC_BTN4 KC_MS_BTN4 206#define KC_BTN4 KC_MS_BTN4
207#define KC_BTN5 KC_MS_BTN5 207#define KC_BTN5 KC_MS_BTN5
208#define KC_BTN6 KC_MS_BTN6
209#define KC_BTN7 KC_MS_BTN7
210#define KC_BTN8 KC_MS_BTN8
208#define KC_WH_U KC_MS_WH_UP 211#define KC_WH_U KC_MS_WH_UP
209#define KC_WH_D KC_MS_WH_DOWN 212#define KC_WH_D KC_MS_WH_DOWN
210#define KC_WH_L KC_MS_WH_LEFT 213#define KC_WH_L KC_MS_WH_LEFT
@@ -521,15 +524,18 @@ enum internal_special_keycodes {
521 524
522enum mouse_keys { 525enum mouse_keys {
523 /* Mouse Buttons */ 526 /* Mouse Buttons */
524 KC_MS_UP = 0xF0, 527 KC_MS_UP = 0xED,
525 KC_MS_DOWN, 528 KC_MS_DOWN,
526 KC_MS_LEFT, 529 KC_MS_LEFT,
527 KC_MS_RIGHT, 530 KC_MS_RIGHT, // 0xF0
528 KC_MS_BTN1, 531 KC_MS_BTN1,
529 KC_MS_BTN2, 532 KC_MS_BTN2,
530 KC_MS_BTN3, 533 KC_MS_BTN3,
531 KC_MS_BTN4, 534 KC_MS_BTN4,
532 KC_MS_BTN5, 535 KC_MS_BTN5,
536 KC_MS_BTN6,
537 KC_MS_BTN7,
538 KC_MS_BTN8,
533 539
534 /* Mouse Wheel */ 540 /* Mouse Wheel */
535 KC_MS_WH_UP, 541 KC_MS_WH_UP,
@@ -540,5 +546,5 @@ enum mouse_keys {
540 /* Acceleration */ 546 /* Acceleration */
541 KC_MS_ACCEL0, 547 KC_MS_ACCEL0,
542 KC_MS_ACCEL1, 548 KC_MS_ACCEL1,
543 KC_MS_ACCEL2 549 KC_MS_ACCEL2 // 0xFF
544}; 550};
diff --git a/tmk_core/common/matrix.h b/tmk_core/common/matrix.h
index b570227a3..ce57010a4 100644
--- a/tmk_core/common/matrix.h
+++ b/tmk_core/common/matrix.h
@@ -55,6 +55,9 @@ matrix_row_t matrix_get_row(uint8_t row);
55/* print matrix for debug */ 55/* print matrix for debug */
56void matrix_print(void); 56void matrix_print(void);
57/* delay between changing matrix pin state and reading values */ 57/* delay between changing matrix pin state and reading values */
58void matrix_output_select_delay(void);
59void matrix_output_unselect_delay(void);
60/* only for backwards compatibility. delay between changing matrix pin state and reading values */
58void matrix_io_delay(void); 61void matrix_io_delay(void);
59 62
60/* power control */ 63/* power control */
diff --git a/tmk_core/common/mousekey.c b/tmk_core/common/mousekey.c
index ef18bcf1a..d8cf63f77 100644
--- a/tmk_core/common/mousekey.c
+++ b/tmk_core/common/mousekey.c
@@ -36,6 +36,9 @@ static void mousekey_debug(void);
36static uint8_t mousekey_accel = 0; 36static uint8_t mousekey_accel = 0;
37static uint8_t mousekey_repeat = 0; 37static uint8_t mousekey_repeat = 0;
38static uint8_t mousekey_wheel_repeat = 0; 38static uint8_t mousekey_wheel_repeat = 0;
39#ifdef MK_KINETIC_SPEED
40static uint16_t mouse_timer = 0;
41#endif
39 42
40#ifndef MK_3_SPEED 43#ifndef MK_3_SPEED
41 44
@@ -43,7 +46,7 @@ static uint16_t last_timer_c = 0;
43static uint16_t last_timer_w = 0; 46static uint16_t last_timer_w = 0;
44 47
45/* 48/*
46 * Mouse keys acceleration algorithm 49 * Mouse keys acceleration algorithm
47 * http://en.wikipedia.org/wiki/Mouse_keys 50 * http://en.wikipedia.org/wiki/Mouse_keys
48 * 51 *
49 * speed = delta * max_speed * (repeat / time_to_max)**((1000+curve)/1000) 52 * speed = delta * max_speed * (repeat / time_to_max)**((1000+curve)/1000)
@@ -105,6 +108,65 @@ static uint8_t wheel_unit(void) {
105} 108}
106 109
107# else /* #ifndef MK_COMBINED */ 110# else /* #ifndef MK_COMBINED */
111# ifndef MK_KINETIC_SPEED
112
113/*
114 * Kinetic movement acceleration algorithm
115 *
116 * current speed = I + A * T/50 + A * 0.5 * T^2 | maximum B
117 *
118 * T: time since the mouse movement started
119 * E: mouse events per second (set through MOUSEKEY_INTERVAL, UHK sends 250, the
120 * pro micro on my Signum 3.0 sends only 125!)
121 * I: initial speed at time 0
122 * A: acceleration
123 * B: base mouse travel speed
124 */
125const uint16_t mk_accelerated_speed = MOUSEKEY_ACCELERATED_SPEED;
126const uint16_t mk_base_speed = MOUSEKEY_BASE_SPEED;
127const uint16_t mk_decelerated_speed = MOUSEKEY_DECELERATED_SPEED;
128const uint16_t mk_initial_speed = MOUSEKEY_INITIAL_SPEED;
129
130static uint8_t move_unit(void) {
131 float speed = mk_initial_speed;
132
133 if (mousekey_accel & ((1 << 0) | (1 << 2))) {
134 speed = mousekey_accel & (1 << 2) ? mk_accelerated_speed : mk_decelerated_speed;
135 } else if (mousekey_repeat && mouse_timer) {
136 const float time_elapsed = timer_elapsed(mouse_timer) / 50;
137 speed = mk_initial_speed + MOUSEKEY_MOVE_DELTA * time_elapsed + MOUSEKEY_MOVE_DELTA * 0.5 * time_elapsed * time_elapsed;
138
139 speed = speed > mk_base_speed ? mk_base_speed : speed;
140 }
141
142 /* convert speed to USB mouse speed 1 to 127 */
143 speed = (uint8_t)(speed / (1000.0f / mk_interval));
144 speed = speed < 1 ? 1 : speed;
145
146 return speed > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : speed;
147}
148
149float mk_wheel_interval = 1000.0f / MOUSEKEY_WHEEL_INITIAL_MOVEMENTS;
150
151static uint8_t wheel_unit(void) {
152 float speed = MOUSEKEY_WHEEL_INITIAL_MOVEMENTS;
153
154 if (mousekey_accel & ((1 << 0) | (1 << 2))) {
155 speed = mousekey_accel & (1 << 2) ? MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS : MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS;
156 } else if (mousekey_repeat && mouse_timer) {
157 if (mk_wheel_interval != MOUSEKEY_WHEEL_BASE_MOVEMENTS) {
158 const float time_elapsed = timer_elapsed(mouse_timer) / 50;
159 speed = MOUSEKEY_WHEEL_INITIAL_MOVEMENTS + 1 * time_elapsed + 1 * 0.5 * time_elapsed * time_elapsed;
160 }
161 speed = speed > MOUSEKEY_WHEEL_BASE_MOVEMENTS ? MOUSEKEY_WHEEL_BASE_MOVEMENTS : speed;
162 }
163
164 mk_wheel_interval = 1000.0f / speed;
165
166 return 1;
167}
168
169# else /* #ifndef MK_KINETIC_SPEED */
108 170
109static uint8_t move_unit(void) { 171static uint8_t move_unit(void) {
110 uint16_t unit; 172 uint16_t unit;
@@ -142,7 +204,8 @@ static uint8_t wheel_unit(void) {
142 return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit)); 204 return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit));
143} 205}
144 206
145# endif /* #ifndef MK_COMBINED */ 207# endif /* #ifndef MK_KINETIC_SPEED */
208# endif /* #ifndef MK_COMBINED */
146 209
147void mousekey_task(void) { 210void mousekey_task(void) {
148 // report cursor and scroll movement independently 211 // report cursor and scroll movement independently
@@ -193,6 +256,12 @@ void mousekey_task(void) {
193} 256}
194 257
195void mousekey_on(uint8_t code) { 258void mousekey_on(uint8_t code) {
259# ifdef MK_KINETIC_SPEED
260 if (mouse_timer == 0) {
261 mouse_timer = timer_read();
262 }
263# endif /* #ifdef MK_KINETIC_SPEED */
264
196 if (code == KC_MS_UP) 265 if (code == KC_MS_UP)
197 mouse_report.y = move_unit() * -1; 266 mouse_report.y = move_unit() * -1;
198 else if (code == KC_MS_DOWN) 267 else if (code == KC_MS_DOWN)
@@ -209,16 +278,8 @@ void mousekey_on(uint8_t code) {
209 mouse_report.h = wheel_unit() * -1; 278 mouse_report.h = wheel_unit() * -1;
210 else if (code == KC_MS_WH_RIGHT) 279 else if (code == KC_MS_WH_RIGHT)
211 mouse_report.h = wheel_unit(); 280 mouse_report.h = wheel_unit();
212 else if (code == KC_MS_BTN1) 281 else if (IS_MOUSEKEY_BUTTON(code))
213 mouse_report.buttons |= MOUSE_BTN1; 282 mouse_report.buttons |= 1 << (code - KC_MS_BTN1);
214 else if (code == KC_MS_BTN2)
215 mouse_report.buttons |= MOUSE_BTN2;
216 else if (code == KC_MS_BTN3)
217 mouse_report.buttons |= MOUSE_BTN3;
218 else if (code == KC_MS_BTN4)
219 mouse_report.buttons |= MOUSE_BTN4;
220 else if (code == KC_MS_BTN5)
221 mouse_report.buttons |= MOUSE_BTN5;
222 else if (code == KC_MS_ACCEL0) 283 else if (code == KC_MS_ACCEL0)
223 mousekey_accel |= (1 << 0); 284 mousekey_accel |= (1 << 0);
224 else if (code == KC_MS_ACCEL1) 285 else if (code == KC_MS_ACCEL1)
@@ -244,23 +305,20 @@ void mousekey_off(uint8_t code) {
244 mouse_report.h = 0; 305 mouse_report.h = 0;
245 else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0) 306 else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0)
246 mouse_report.h = 0; 307 mouse_report.h = 0;
247 else if (code == KC_MS_BTN1) 308 else if (IS_MOUSEKEY_BUTTON(code))
248 mouse_report.buttons &= ~MOUSE_BTN1; 309 mouse_report.buttons &= ~(1 << (code - KC_MS_BTN1));
249 else if (code == KC_MS_BTN2)
250 mouse_report.buttons &= ~MOUSE_BTN2;
251 else if (code == KC_MS_BTN3)
252 mouse_report.buttons &= ~MOUSE_BTN3;
253 else if (code == KC_MS_BTN4)
254 mouse_report.buttons &= ~MOUSE_BTN4;
255 else if (code == KC_MS_BTN5)
256 mouse_report.buttons &= ~MOUSE_BTN5;
257 else if (code == KC_MS_ACCEL0) 310 else if (code == KC_MS_ACCEL0)
258 mousekey_accel &= ~(1 << 0); 311 mousekey_accel &= ~(1 << 0);
259 else if (code == KC_MS_ACCEL1) 312 else if (code == KC_MS_ACCEL1)
260 mousekey_accel &= ~(1 << 1); 313 mousekey_accel &= ~(1 << 1);
261 else if (code == KC_MS_ACCEL2) 314 else if (code == KC_MS_ACCEL2)
262 mousekey_accel &= ~(1 << 2); 315 mousekey_accel &= ~(1 << 2);
263 if (mouse_report.x == 0 && mouse_report.y == 0) mousekey_repeat = 0; 316 if (mouse_report.x == 0 && mouse_report.y == 0) {
317 mousekey_repeat = 0;
318# ifdef MK_KINETIC_SPEED
319 mouse_timer = 0;
320# endif /* #ifdef MK_KINETIC_SPEED */
321 }
264 if (mouse_report.v == 0 && mouse_report.h == 0) mousekey_wheel_repeat = 0; 322 if (mouse_report.v == 0 && mouse_report.h == 0) mousekey_wheel_repeat = 0;
265} 323}
266 324
@@ -349,16 +407,8 @@ void mousekey_on(uint8_t code) {
349 mouse_report.h = w_offset * -1; 407 mouse_report.h = w_offset * -1;
350 else if (code == KC_MS_WH_RIGHT) 408 else if (code == KC_MS_WH_RIGHT)
351 mouse_report.h = w_offset; 409 mouse_report.h = w_offset;
352 else if (code == KC_MS_BTN1) 410 else if (IS_MOUSEKEY_BUTTON(code))
353 mouse_report.buttons |= MOUSE_BTN1; 411 mouse_report.buttons |= 1 << (code - KC_MS_BTN1);
354 else if (code == KC_MS_BTN2)
355 mouse_report.buttons |= MOUSE_BTN2;
356 else if (code == KC_MS_BTN3)
357 mouse_report.buttons |= MOUSE_BTN3;
358 else if (code == KC_MS_BTN4)
359 mouse_report.buttons |= MOUSE_BTN4;
360 else if (code == KC_MS_BTN5)
361 mouse_report.buttons |= MOUSE_BTN5;
362 else if (code == KC_MS_ACCEL0) 412 else if (code == KC_MS_ACCEL0)
363 mk_speed = mkspd_0; 413 mk_speed = mkspd_0;
364 else if (code == KC_MS_ACCEL1) 414 else if (code == KC_MS_ACCEL1)
@@ -388,16 +438,8 @@ void mousekey_off(uint8_t code) {
388 mouse_report.h = 0; 438 mouse_report.h = 0;
389 else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0) 439 else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0)
390 mouse_report.h = 0; 440 mouse_report.h = 0;
391 else if (code == KC_MS_BTN1) 441 else if (IS_MOUSEKEY_BUTTON(code))
392 mouse_report.buttons &= ~MOUSE_BTN1; 442 mouse_report.buttons &= ~(1 << (code - KC_MS_BTN1));
393 else if (code == KC_MS_BTN2)
394 mouse_report.buttons &= ~MOUSE_BTN2;
395 else if (code == KC_MS_BTN3)
396 mouse_report.buttons &= ~MOUSE_BTN3;
397 else if (code == KC_MS_BTN4)
398 mouse_report.buttons &= ~MOUSE_BTN4;
399 else if (code == KC_MS_BTN5)
400 mouse_report.buttons &= ~MOUSE_BTN5;
401# ifdef MK_MOMENTARY_ACCEL 443# ifdef MK_MOMENTARY_ACCEL
402 else if (code == KC_MS_ACCEL0) 444 else if (code == KC_MS_ACCEL0)
403 mk_speed = mkspd_DEFAULT; 445 mk_speed = mkspd_DEFAULT;
diff --git a/tmk_core/common/mousekey.h b/tmk_core/common/mousekey.h
index 300d262f5..52b8fe10e 100644
--- a/tmk_core/common/mousekey.h
+++ b/tmk_core/common/mousekey.h
@@ -36,16 +36,28 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
36# endif 36# endif
37 37
38# ifndef MOUSEKEY_MOVE_DELTA 38# ifndef MOUSEKEY_MOVE_DELTA
39# define MOUSEKEY_MOVE_DELTA 5 39# ifndef MK_KINETIC_SPEED
40# define MOUSEKEY_MOVE_DELTA 5
41# else
42# define MOUSEKEY_MOVE_DELTA 25
43# endif
40# endif 44# endif
41# ifndef MOUSEKEY_WHEEL_DELTA 45# ifndef MOUSEKEY_WHEEL_DELTA
42# define MOUSEKEY_WHEEL_DELTA 1 46# define MOUSEKEY_WHEEL_DELTA 1
43# endif 47# endif
44# ifndef MOUSEKEY_DELAY 48# ifndef MOUSEKEY_DELAY
45# define MOUSEKEY_DELAY 300 49# ifndef MK_KINETIC_SPEED
50# define MOUSEKEY_DELAY 300
51# else
52# define MOUSEKEY_DELAY 8
53# endif
46# endif 54# endif
47# ifndef MOUSEKEY_INTERVAL 55# ifndef MOUSEKEY_INTERVAL
48# define MOUSEKEY_INTERVAL 50 56# ifndef MK_KINETIC_SPEED
57# define MOUSEKEY_INTERVAL 50
58# else
59# define MOUSEKEY_INTERVAL 8
60# endif
49# endif 61# endif
50# ifndef MOUSEKEY_MAX_SPEED 62# ifndef MOUSEKEY_MAX_SPEED
51# define MOUSEKEY_MAX_SPEED 10 63# define MOUSEKEY_MAX_SPEED 10
@@ -66,6 +78,31 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
66# define MOUSEKEY_WHEEL_TIME_TO_MAX 40 78# define MOUSEKEY_WHEEL_TIME_TO_MAX 40
67# endif 79# endif
68 80
81# ifndef MOUSEKEY_INITIAL_SPEED
82# define MOUSEKEY_INITIAL_SPEED 100
83# endif
84# ifndef MOUSEKEY_BASE_SPEED
85# define MOUSEKEY_BASE_SPEED 1000
86# endif
87# ifndef MOUSEKEY_DECELERATED_SPEED
88# define MOUSEKEY_DECELERATED_SPEED 400
89# endif
90# ifndef MOUSEKEY_ACCELERATED_SPEED
91# define MOUSEKEY_ACCELERATED_SPEED 3000
92# endif
93# ifndef MOUSEKEY_WHEEL_INITIAL_MOVEMENTS
94# define MOUSEKEY_WHEEL_INITIAL_MOVEMENTS 16
95# endif
96# ifndef MOUSEKEY_WHEEL_BASE_MOVEMENTS
97# define MOUSEKEY_WHEEL_BASE_MOVEMENTS 32
98# endif
99# ifndef MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS
100# define MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS 48
101# endif
102# ifndef MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS
103# define MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS 8
104# endif
105
69#else /* #ifndef MK_3_SPEED */ 106#else /* #ifndef MK_3_SPEED */
70 107
71# ifndef MK_C_OFFSET_UNMOD 108# ifndef MK_C_OFFSET_UNMOD
diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h
index 5d7c5b3b2..bcf5cab38 100644
--- a/tmk_core/common/report.h
+++ b/tmk_core/common/report.h
@@ -39,7 +39,10 @@ enum mouse_buttons {
39 MOUSE_BTN2 = (1 << 1), 39 MOUSE_BTN2 = (1 << 1),
40 MOUSE_BTN3 = (1 << 2), 40 MOUSE_BTN3 = (1 << 2),
41 MOUSE_BTN4 = (1 << 3), 41 MOUSE_BTN4 = (1 << 3),
42 MOUSE_BTN5 = (1 << 4) 42 MOUSE_BTN5 = (1 << 4),
43 MOUSE_BTN6 = (1 << 5),
44 MOUSE_BTN7 = (1 << 6),
45 MOUSE_BTN8 = (1 << 7)
43}; 46};
44 47
45/* Consumer Page (0x0C) 48/* Consumer Page (0x0C)
diff --git a/tmk_core/common/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);
12void suspend_wakeup_init_kb(void); 12void suspend_wakeup_init_kb(void);
13void suspend_power_down_user(void); 13void suspend_power_down_user(void);
14void suspend_power_down_kb(void); 14void 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/*
2Copyright (C) 2020 Ryan Caltabiano <https://github.com/XScorpion2>
3
4Permission is hereby granted, free of charge, to any person obtaining a copy of
5this software and associated documentation files (the "Software"), to deal in
6the Software without restriction, including without limitation the rights to
7use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8of the Software, and to permit persons to whom the Software is furnished to do
9so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in all
12copies or substantial portions of the Software.
13
14If you happen to meet one of the copyright holders in a bar you are obligated
15to buy them one pint of beer.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24*/
25
26#include "sync_timer.h"
27#include "keyboard.h"
28
29#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER)
30volatile int32_t sync_timer_ms;
31
32void sync_timer_init(void) { sync_timer_ms = 0; }
33
34void sync_timer_update(uint32_t time) {
35 if (is_keyboard_master()) return;
36 sync_timer_ms = time - timer_read32();
37}
38
39uint16_t sync_timer_read(void) {
40 if (is_keyboard_master()) return timer_read();
41 return sync_timer_read32();
42}
43
44uint32_t sync_timer_read32(void) {
45 if (is_keyboard_master()) return timer_read32();
46 return sync_timer_ms + timer_read32();
47}
48
49uint16_t sync_timer_elapsed(uint16_t last) {
50 if (is_keyboard_master()) return timer_elapsed(last);
51 return TIMER_DIFF_16(sync_timer_read(), last);
52}
53
54uint32_t sync_timer_elapsed32(uint32_t last) {
55 if (is_keyboard_master()) return timer_elapsed32(last);
56 return TIMER_DIFF_32(sync_timer_read32(), last);
57}
58#endif
diff --git a/tmk_core/common/sync_timer.h b/tmk_core/common/sync_timer.h
new file mode 100644
index 000000000..9ddef45bb
--- /dev/null
+++ b/tmk_core/common/sync_timer.h
@@ -0,0 +1,54 @@
1/*
2Copyright (C) 2020 Ryan Caltabiano <https://github.com/XScorpion2>
3
4Permission is hereby granted, free of charge, to any person obtaining a copy of
5this software and associated documentation files (the "Software"), to deal in
6the Software without restriction, including without limitation the rights to
7use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8of the Software, and to permit persons to whom the Software is furnished to do
9so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in all
12copies or substantial portions of the Software.
13
14If you happen to meet one of the copyright holders in a bar you are obligated
15to buy them one pint of beer.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24*/
25
26#pragma once
27
28#include <stdint.h>
29#include "timer.h"
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER)
36void sync_timer_init(void);
37void sync_timer_update(uint32_t time);
38uint16_t sync_timer_read(void);
39uint32_t sync_timer_read32(void);
40uint16_t sync_timer_elapsed(uint16_t last);
41uint32_t sync_timer_elapsed32(uint32_t last);
42#else
43# define sync_timer_init()
44# define sync_timer_clear()
45# define sync_timer_update(t)
46# define sync_timer_read() timer_read()
47# define sync_timer_read32() timer_read32()
48# define sync_timer_elapsed(t) timer_elapsed(t)
49# define sync_timer_elapsed32(t) timer_elapsed32(t)
50#endif
51
52#ifdef __cplusplus
53}
54#endif
diff --git a/tmk_core/common/uart.c b/tmk_core/common/uart.c
deleted file mode 100644
index 150e256c8..000000000
--- a/tmk_core/common/uart.c
+++ /dev/null
@@ -1,172 +0,0 @@
1// TODO: Teensy support(ATMega32u4/AT90USB128)
2// Fixed for Arduino Duemilanove ATmega168p by Jun Wako
3/* UART Example for Teensy USB Development Board
4 * http://www.pjrc.com/teensy/
5 * Copyright (c) 2009 PJRC.COM, LLC
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
25
26// Version 1.0: Initial Release
27// Version 1.1: Add support for Teensy 2.0, minor optimizations
28
29#include <avr/io.h>
30#include <avr/interrupt.h>
31
32#include "uart.h"
33
34#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
35# define UDRn UDR0
36# define UBRRnL UBRR0L
37# define UCSRnA UCSR0A
38# define UCSRnB UCSR0B
39# define UCSRnC UCSR0C
40# define U2Xn U2X0
41# define RXENn RXEN0
42# define TXENn TXEN0
43# define RXCIEn RXCIE0
44# define UCSZn1 UCSZ01
45# define UCSZn0 UCSZ00
46# define UDRIEn UDRIE0
47# define USARTn_UDRE_vect USART_UDRE_vect
48# define USARTn_RX_vect USART_RX_vect
49#elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega32U2__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
50# define UDRn UDR1
51# define UBRRnL UBRR1L
52# define UCSRnA UCSR1A
53# define UCSRnB UCSR1B
54# define UCSRnC UCSR1C
55# define U2Xn U2X1
56# define RXENn RXEN1
57# define TXENn TXEN1
58# define RXCIEn RXCIE1
59# define UCSZn1 UCSZ11
60# define UCSZn0 UCSZ10
61# define UDRIEn UDRIE1
62# define USARTn_UDRE_vect USART1_UDRE_vect
63# define USARTn_RX_vect USART1_RX_vect
64#elif defined(__AVR_ATmega32A__)
65# define UDRn UDR
66# define UBRRnL UBRRL
67# define UCSRnA UCSRA
68# define UCSRnB UCSRB
69# define UCSRnC UCSRC
70# define U2Xn U2X
71# define RXENn RXEN
72# define TXENn TXEN
73# define RXCIEn RXCIE
74# define UCSZn1 UCSZ1
75# define UCSZn0 UCSZ0
76# define UDRIEn UDRIE
77# define USARTn_UDRE_vect USART_UDRE_vect
78# define USARTn_RX_vect USART_RX_vect
79#endif
80
81// These buffers may be any size from 2 to 256 bytes.
82#define RX_BUFFER_SIZE 64
83#define TX_BUFFER_SIZE 256
84
85static volatile uint8_t tx_buffer[TX_BUFFER_SIZE];
86static volatile uint8_t tx_buffer_head;
87static volatile uint8_t tx_buffer_tail;
88static volatile uint8_t rx_buffer[RX_BUFFER_SIZE];
89static volatile uint8_t rx_buffer_head;
90static volatile uint8_t rx_buffer_tail;
91
92// Initialize the UART
93void uart_init(uint32_t baud) {
94 cli();
95 UBRRnL = (F_CPU / 4 / baud - 1) / 2;
96 UCSRnA = (1 << U2Xn);
97 UCSRnB = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn);
98 UCSRnC = (1 << UCSZn1) | (1 << UCSZn0);
99 tx_buffer_head = tx_buffer_tail = 0;
100 rx_buffer_head = rx_buffer_tail = 0;
101 sei();
102}
103
104// Transmit a byte
105void uart_putchar(uint8_t c) {
106 uint8_t i;
107
108 i = tx_buffer_head + 1;
109 if (i >= TX_BUFFER_SIZE) i = 0;
110 // return immediately to avoid deadlock when interrupt is disabled(called from ISR)
111 if (tx_buffer_tail == i && (SREG & (1 << SREG_I)) == 0) return;
112 while (tx_buffer_tail == i)
113 ; // wait until space in buffer
114 // cli();
115 tx_buffer[i] = c;
116 tx_buffer_head = i;
117 UCSRnB = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn) | (1 << UDRIEn);
118 // sei();
119}
120
121// Receive a byte
122uint8_t uart_getchar(void) {
123 uint8_t c, i;
124
125 while (rx_buffer_head == rx_buffer_tail)
126 ; // wait for character
127 i = rx_buffer_tail + 1;
128 if (i >= RX_BUFFER_SIZE) i = 0;
129 c = rx_buffer[i];
130 rx_buffer_tail = i;
131 return c;
132}
133
134// Return the number of bytes waiting in the receive buffer.
135// Call this before uart_getchar() to check if it will need
136// to wait for a byte to arrive.
137uint8_t uart_available(void) {
138 uint8_t head, tail;
139
140 head = rx_buffer_head;
141 tail = rx_buffer_tail;
142 if (head >= tail) return head - tail;
143 return RX_BUFFER_SIZE + head - tail;
144}
145
146// Transmit Interrupt
147ISR(USARTn_UDRE_vect) {
148 uint8_t i;
149
150 if (tx_buffer_head == tx_buffer_tail) {
151 // buffer is empty, disable transmit interrupt
152 UCSRnB = (1 << RXENn) | (1 << TXENn) | (1 << RXCIEn);
153 } else {
154 i = tx_buffer_tail + 1;
155 if (i >= TX_BUFFER_SIZE) i = 0;
156 UDRn = tx_buffer[i];
157 tx_buffer_tail = i;
158 }
159}
160
161// Receive Interrupt
162ISR(USARTn_RX_vect) {
163 uint8_t c, i;
164
165 c = UDRn;
166 i = rx_buffer_head + 1;
167 if (i >= RX_BUFFER_SIZE) i = 0;
168 if (i != rx_buffer_tail) {
169 rx_buffer[i] = c;
170 rx_buffer_head = i;
171 }
172}
diff --git a/tmk_core/common/uart.h b/tmk_core/common/uart.h
deleted file mode 100644
index ea247b17b..000000000
--- a/tmk_core/common/uart.h
+++ /dev/null
@@ -1,8 +0,0 @@
1#pragma once
2
3#include <stdint.h>
4
5void uart_init(uint32_t baud);
6void uart_putchar(uint8_t c);
7uint8_t uart_getchar(void);
8uint8_t uart_available(void);
diff --git a/tmk_core/common/wait.h b/tmk_core/common/wait.h
index 89128e9da..28224fe3a 100644
--- a/tmk_core/common/wait.h
+++ b/tmk_core/common/wait.h
@@ -6,10 +6,89 @@
6extern "C" { 6extern "C" {
7#endif 7#endif
8 8
9#if defined(__ARMEL__) || defined(__ARMEB__)
10# ifndef __OPTIMIZE__
11# pragma message "Compiler optimizations disabled; wait_cpuclock() won't work as designed"
12# endif
13
14# define wait_cpuclock(x) wait_cpuclock_allnop(x)
15
16# define CLOCK_DELAY_NOP8 "nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t"
17
18__attribute__((always_inline)) static inline void wait_cpuclock_allnop(unsigned int n) { /* n: 1..135 */
19 /* The argument n must be a constant expression.
20 * That way, compiler optimization will remove unnecessary code. */
21 if (n < 1) {
22 return;
23 }
24 if (n > 8) {
25 unsigned int n8 = n / 8;
26 n = n - n8 * 8;
27 switch (n8) {
28 case 16:
29 asm volatile(CLOCK_DELAY_NOP8::: "memory");
30 case 15:
31 asm volatile(CLOCK_DELAY_NOP8::: "memory");
32 case 14:
33 asm volatile(CLOCK_DELAY_NOP8::: "memory");
34 case 13:
35 asm volatile(CLOCK_DELAY_NOP8::: "memory");
36 case 12:
37 asm volatile(CLOCK_DELAY_NOP8::: "memory");
38 case 11:
39 asm volatile(CLOCK_DELAY_NOP8::: "memory");
40 case 10:
41 asm volatile(CLOCK_DELAY_NOP8::: "memory");
42 case 9:
43 asm volatile(CLOCK_DELAY_NOP8::: "memory");
44 case 8:
45 asm volatile(CLOCK_DELAY_NOP8::: "memory");
46 case 7:
47 asm volatile(CLOCK_DELAY_NOP8::: "memory");
48 case 6:
49 asm volatile(CLOCK_DELAY_NOP8::: "memory");
50 case 5:
51 asm volatile(CLOCK_DELAY_NOP8::: "memory");
52 case 4:
53 asm volatile(CLOCK_DELAY_NOP8::: "memory");
54 case 3:
55 asm volatile(CLOCK_DELAY_NOP8::: "memory");
56 case 2:
57 asm volatile(CLOCK_DELAY_NOP8::: "memory");
58 case 1:
59 asm volatile(CLOCK_DELAY_NOP8::: "memory");
60 case 0:
61 break;
62 }
63 }
64 switch (n) {
65 case 8:
66 asm volatile("nop" ::: "memory");
67 case 7:
68 asm volatile("nop" ::: "memory");
69 case 6:
70 asm volatile("nop" ::: "memory");
71 case 5:
72 asm volatile("nop" ::: "memory");
73 case 4:
74 asm volatile("nop" ::: "memory");
75 case 3:
76 asm volatile("nop" ::: "memory");
77 case 2:
78 asm volatile("nop" ::: "memory");
79 case 1:
80 asm volatile("nop" ::: "memory");
81 case 0:
82 break;
83 }
84}
85#endif
86
9#if defined(__AVR__) 87#if defined(__AVR__)
10# include <util/delay.h> 88# include <util/delay.h>
11# define wait_ms(ms) _delay_ms(ms) 89# define wait_ms(ms) _delay_ms(ms)
12# define wait_us(us) _delay_us(us) 90# define wait_us(us) _delay_us(us)
91# define wait_cpuclock(x) __builtin_avr_delay_cycles(x)
13#elif defined PROTOCOL_CHIBIOS 92#elif defined PROTOCOL_CHIBIOS
14# include <ch.h> 93# include <ch.h>
15# define wait_ms(ms) \ 94# define wait_ms(ms) \
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/*
2Copyright 2011 Jun WAKO <wakojun@gmail.com> 2Copyright 2011-19 Jun WAKO <wakojun@gmail.com>
3Copyright 2013 Shay Green <gblargg@gmail.com> 3Copyright 2013 Shay Green <gblargg@gmail.com>
4 4
5This software is licensed with a Modified BSD License. 5This 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);
59static inline void send_byte(uint8_t data); 60static inline void send_byte(uint8_t data);
60static inline uint16_t wait_data_lo(uint16_t us); 61static inline uint16_t wait_data_lo(uint16_t us);
61static inline uint16_t wait_data_hi(uint16_t us); 62static inline uint16_t wait_data_hi(uint16_t us);
62static inline uint16_t adb_host_dev_recv(uint8_t device);
63 63
64void adb_host_init(void) { 64void 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 84uint16_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
119enum { ADDR_KEYB = 0x20, ADDR_MOUSE = 0x30 };
120
121uint16_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
124void 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
126uint16_t adb_host_mouse_recv(void) { return adb_host_dev_recv(ADDR_MOUSE); } 91uint16_t adb_host_mouse_recv(void) { return adb_host_talk(ADB_ADDR_MOUSE, ADB_REG_0); }
127#endif 92#endif
128 93
129static 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; 95uint8_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
173error: 193error:
174 sei(); 194 sei();
175 return -n; 195 return n / 8;
176} 196}
177 197
178void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l) { 198uint16_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
206void 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
222void 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
227void 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
192void adb_host_kbd_led(uint8_t led) { 237void 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
483Address, 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
493ADB 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
526Keyboard 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
438END_OF_ADB 534END_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/*
2Copyright 2011 Jun WAKO <wakojun@gmail.com> 2Copyright 2011-19 Jun WAKO <wakojun@gmail.com>
3 3
4This software is licensed with a Modified BSD License. 4This software is licensed with a Modified BSD License.
5All of this is supposed to be Free Software, Open Source, DFSG-free, 5All 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
51void adb_host_init(void); 93void adb_host_init(void);
52bool adb_host_psw(void); 94bool adb_host_psw(void);
95uint16_t adb_host_talk(uint8_t addr, uint8_t reg);
96uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
97void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l);
98void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
99void adb_host_flush(uint8_t addr);
100void adb_host_kbd_led(uint8_t led);
53uint16_t adb_host_kbd_recv(void); 101uint16_t adb_host_kbd_recv(void);
54uint16_t adb_host_mouse_recv(void); 102uint16_t adb_host_mouse_recv(void);
55void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l); 103
56void adb_host_kbd_led(uint8_t led); 104// ADB Mouse
57void adb_mouse_task(void); 105void adb_mouse_task(void);
58void adb_mouse_init(void); 106void 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
31DmacDescriptor dmac_desc;
32DmacDescriptor dmac_desc_wb;
33
31static uint8_t i2c_led_q[I2C_Q_SIZE]; // I2C queue circular buffer 34static uint8_t i2c_led_q[I2C_Q_SIZE]; // I2C queue circular buffer
32static uint8_t i2c_led_q_s; // Start of circular buffer 35static uint8_t i2c_led_q_s; // Start of circular buffer
33static uint8_t i2c_led_q_e; // End of circular buffer 36static 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; 27extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc;
28__attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb; 28extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb;
29 29
30uint8_t I2C3733_Init_Control(void); 30uint8_t I2C3733_Init_Control(void);
31uint8_t I2C3733_Init_Drivers(void); 31uint8_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
373usbevent_t event_queue[USB_EVENT_QUEUE_SIZE];
374uint8_t event_queue_head;
375uint8_t event_queue_tail;
376
377void 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
384static 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
394static 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
403static inline void usb_event_suspend_handler(void) {
404#ifdef SLEEP_LED_ENABLE
405 sleep_led_enable();
406#endif /* SLEEP_LED_ENABLE */
407}
408
409static 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
418void 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? */
373static void usb_event_cb(USBDriver *usbp, usbevent_t event) { 437static 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) {
651void restart_usb_driver(USBDriver *usbp) { 708void 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);
38void restart_usb_driver(USBDriver *usbp); 38void restart_usb_driver(USBDriver *usbp);
39 39
40/* --------------- 40/* ---------------
41 * USB Event queue
42 * ---------------
43 */
44
45/* Initialisation of the FIFO */
46void usb_event_queue_init(void);
47
48/* Task to dequeue and execute any handlers for the USB events on the main thread */
49void 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 */
436void EVENT_USB_Device_WakeUp() { 436void 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)