aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common.mk10
-rw-r--r--common/action.c151
-rw-r--r--common/action.h6
-rw-r--r--common/action_code.h14
-rw-r--r--common/action_oneshot.c21
-rw-r--r--common/action_oneshot.h52
-rw-r--r--common/action_tapping.c39
-rw-r--r--common/action_util.c213
-rw-r--r--common/action_util.h56
-rw-r--r--common/bootloader.c7
-rw-r--r--common/bootmagic.c4
-rw-r--r--common/bootmagic.h40
-rw-r--r--common/command.c47
-rw-r--r--common/host.c150
-rw-r--r--common/host.h17
-rw-r--r--common/keyboard.c3
-rw-r--r--common/keyboard.h19
-rw-r--r--common/keymap.c3
-rw-r--r--common/suspend.c3
-rw-r--r--converter/adb_usb/Makefile108
-rw-r--r--converter/adb_usb/Makefile.blargg (renamed from converter/adb_usb/Makefile.lufa)4
-rw-r--r--converter/adb_usb/Makefile.pjrc63
-rw-r--r--converter/adb_usb/adb_blargg.c216
-rw-r--r--converter/adb_usb/adb_blargg.h38
-rw-r--r--converter/adb_usb/config.h6
-rw-r--r--converter/adb_usb/led.c5
-rw-r--r--converter/adb_usb/matrix.c12
-rw-r--r--converter/m0110_usb/Makefile3
-rw-r--r--converter/m0110_usb/README.md128
-rw-r--r--converter/m0110_usb/config.h12
-rw-r--r--converter/m0110_usb/doc/m0110.jpgbin49360 -> 0 bytes
-rw-r--r--converter/m0110_usb/doc/teensy.jpgbin50081 -> 0 bytes
-rw-r--r--converter/m0110_usb/keymap.c139
-rw-r--r--converter/news_usb/config_pjrc.h6
-rw-r--r--converter/ps2_usb/config.h6
-rw-r--r--doc/keymap.md21
-rw-r--r--keyboard/IIgs/config.h6
-rw-r--r--keyboard/hhkb/Makefile18
-rw-r--r--keyboard/hhkb/config.h3
-rw-r--r--keyboard/hhkb/config_iwrap.h5
-rw-r--r--keyboard/hhkb/config_vusb.h6
-rw-r--r--keyboard/hhkb/keymap.c19
-rw-r--r--ldscript_keymap_avr5.x268
-rw-r--r--protocol/adb.c217
-rw-r--r--protocol/lufa/lufa.c9
-rw-r--r--protocol/m0110.c50
-rw-r--r--protocol/pjrc/main.c3
-rw-r--r--protocol/pjrc/usb.c1
48 files changed, 1516 insertions, 711 deletions
diff --git a/common.mk b/common.mk
index 47d5c852f..5b70db949 100644
--- a/common.mk
+++ b/common.mk
@@ -3,9 +3,9 @@ SRC += $(COMMON_DIR)/host.c \
3 $(COMMON_DIR)/keyboard.c \ 3 $(COMMON_DIR)/keyboard.c \
4 $(COMMON_DIR)/action.c \ 4 $(COMMON_DIR)/action.c \
5 $(COMMON_DIR)/action_tapping.c \ 5 $(COMMON_DIR)/action_tapping.c \
6 $(COMMON_DIR)/action_oneshot.c \
7 $(COMMON_DIR)/action_macro.c \ 6 $(COMMON_DIR)/action_macro.c \
8 $(COMMON_DIR)/action_layer.c \ 7 $(COMMON_DIR)/action_layer.c \
8 $(COMMON_DIR)/action_util.c \
9 $(COMMON_DIR)/keymap.c \ 9 $(COMMON_DIR)/keymap.c \
10 $(COMMON_DIR)/timer.c \ 10 $(COMMON_DIR)/timer.c \
11 $(COMMON_DIR)/print.c \ 11 $(COMMON_DIR)/print.c \
@@ -68,6 +68,14 @@ ifdef BACKLIGHT_ENABLE
68 OPT_DEFS += -DBACKLIGHT_ENABLE 68 OPT_DEFS += -DBACKLIGHT_ENABLE
69endif 69endif
70 70
71ifdef KEYMAP_SECTION_ENABLE
72 OPT_DEFS += -DKEYMAP_SECTION_ENABLE
73 EXTRALDFLAGS = -Wl,-L$(TOP_DIR),-Tldscript_keymap_avr5.x
74endif
75
76# Version string
77OPT_DEFS += -DVERSION=$(shell (git describe --always --dirty || echo 'unknown') 2> /dev/null)
78
71 79
72# Search Path 80# Search Path
73VPATH += $(TOP_DIR)/common 81VPATH += $(TOP_DIR)/common
diff --git a/common/action.c b/common/action.c
index 59c6f252d..f7ae85b94 100644
--- a/common/action.c
+++ b/common/action.c
@@ -23,8 +23,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
23#include "backlight.h" 23#include "backlight.h"
24#include "action_layer.h" 24#include "action_layer.h"
25#include "action_tapping.h" 25#include "action_tapping.h"
26#include "action_oneshot.h"
27#include "action_macro.h" 26#include "action_macro.h"
27#include "action_util.h"
28#include "action.h" 28#include "action.h"
29 29
30#ifdef DEBUG_ACTION 30#ifdef DEBUG_ACTION
@@ -79,15 +79,15 @@ void process_action(keyrecord_t *record)
79 action.key.mods<<4; 79 action.key.mods<<4;
80 if (event.pressed) { 80 if (event.pressed) {
81 if (mods) { 81 if (mods) {
82 host_add_mods(mods); 82 add_weak_mods(mods);
83 host_send_keyboard_report(); 83 send_keyboard_report();
84 } 84 }
85 register_code(action.key.code); 85 register_code(action.key.code);
86 } else { 86 } else {
87 unregister_code(action.key.code); 87 unregister_code(action.key.code);
88 if (mods) { 88 if (mods) {
89 host_del_mods(mods); 89 del_weak_mods(mods);
90 host_send_keyboard_report(); 90 send_keyboard_report();
91 } 91 }
92 } 92 }
93 } 93 }
@@ -100,43 +100,30 @@ void process_action(keyrecord_t *record)
100 action.key.mods<<4; 100 action.key.mods<<4;
101 switch (action.layer_tap.code) { 101 switch (action.layer_tap.code) {
102 #ifndef NO_ACTION_ONESHOT 102 #ifndef NO_ACTION_ONESHOT
103 case 0x00: 103 case MODS_ONESHOT:
104 // Oneshot modifier 104 // Oneshot modifier
105 if (event.pressed) { 105 if (event.pressed) {
106 if (tap_count == 0) { 106 if (tap_count == 0) {
107 dprint("MODS_TAP: Oneshot: add_mods\n"); 107 register_mods(mods);
108 add_mods(mods);
109 } 108 }
110 else if (tap_count == 1) { 109 else if (tap_count == 1) {
111 dprint("MODS_TAP: Oneshot: start\n"); 110 dprint("MODS_TAP: Oneshot: start\n");
112 oneshot_start(mods); 111 set_oneshot_mods(mods);
113 }
114 else if (tap_count == TAPPING_TOGGLE) {
115 dprint("MODS_TAP: Oneshot: toggle\n");
116 oneshot_toggle();
117 } 112 }
118 else { 113 else {
119 dprint("MODS_TAP: Oneshot: cancel&add_mods\n"); 114 register_mods(mods);
120 // double tap cancels oneshot and works as normal modifier.
121 oneshot_cancel();
122 add_mods(mods);
123 } 115 }
124 } else { 116 } else {
125 if (tap_count == 0) { 117 if (tap_count == 0) {
126 dprint("MODS_TAP: Oneshot: cancel/del_mods\n"); 118 clear_oneshot_mods();
127 // cancel oneshot on hold 119 unregister_mods(mods);
128 oneshot_cancel();
129 del_mods(mods);
130 } 120 }
131 else if (tap_count == 1) { 121 else if (tap_count == 1) {
132 dprint("MODS_TAP: Oneshot: del_mods\n"); 122 // Retain Oneshot mods
133 // retain Oneshot
134 del_mods(mods);
135 } 123 }
136 else { 124 else {
137 dprint("MODS_TAP: Oneshot: del_mods\n"); 125 clear_oneshot_mods();
138 // cancel Mods 126 unregister_mods(mods);
139 del_mods(mods);
140 } 127 }
141 } 128 }
142 break; 129 break;
@@ -148,14 +135,14 @@ void process_action(keyrecord_t *record)
148 dprint("MODS_TAP: Tap: Cancel: add_mods\n"); 135 dprint("MODS_TAP: Tap: Cancel: add_mods\n");
149 // ad hoc: set 0 to cancel tap 136 // ad hoc: set 0 to cancel tap
150 record->tap.count = 0; 137 record->tap.count = 0;
151 add_mods(mods); 138 register_mods(mods);
152 } else { 139 } else {
153 dprint("MODS_TAP: Tap: register_code\n"); 140 dprint("MODS_TAP: Tap: register_code\n");
154 register_code(action.key.code); 141 register_code(action.key.code);
155 } 142 }
156 } else { 143 } else {
157 dprint("MODS_TAP: No tap: add_mods\n"); 144 dprint("MODS_TAP: No tap: add_mods\n");
158 add_mods(mods); 145 register_mods(mods);
159 } 146 }
160 } else { 147 } else {
161 if (tap_count > 0) { 148 if (tap_count > 0) {
@@ -163,7 +150,7 @@ void process_action(keyrecord_t *record)
163 unregister_code(action.key.code); 150 unregister_code(action.key.code);
164 } else { 151 } else {
165 dprint("MODS_TAP: No tap: add_mods\n"); 152 dprint("MODS_TAP: No tap: add_mods\n");
166 del_mods(mods); 153 unregister_mods(mods);
167 } 154 }
168 } 155 }
169 break; 156 break;
@@ -343,30 +330,30 @@ void register_code(uint8_t code)
343 // Resync: ignore if caps lock already is on 330 // Resync: ignore if caps lock already is on
344 if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) return; 331 if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) return;
345#endif 332#endif
346 host_add_key(KC_CAPSLOCK); 333 add_key(KC_CAPSLOCK);
347 host_send_keyboard_report(); 334 send_keyboard_report();
348 host_del_key(KC_CAPSLOCK); 335 del_key(KC_CAPSLOCK);
349 host_send_keyboard_report(); 336 send_keyboard_report();
350 } 337 }
351 338
352 else if (KC_LOCKING_NUM == code) { 339 else if (KC_LOCKING_NUM == code) {
353#ifdef LOCKING_RESYNC_ENABLE 340#ifdef LOCKING_RESYNC_ENABLE
354 if (host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) return; 341 if (host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) return;
355#endif 342#endif
356 host_add_key(KC_NUMLOCK); 343 add_key(KC_NUMLOCK);
357 host_send_keyboard_report(); 344 send_keyboard_report();
358 host_del_key(KC_NUMLOCK); 345 del_key(KC_NUMLOCK);
359 host_send_keyboard_report(); 346 send_keyboard_report();
360 } 347 }
361 348
362 else if (KC_LOCKING_SCROLL == code) { 349 else if (KC_LOCKING_SCROLL == code) {
363#ifdef LOCKING_RESYNC_ENABLE 350#ifdef LOCKING_RESYNC_ENABLE
364 if (host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK)) return; 351 if (host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK)) return;
365#endif 352#endif
366 host_add_key(KC_SCROLLLOCK); 353 add_key(KC_SCROLLLOCK);
367 host_send_keyboard_report(); 354 send_keyboard_report();
368 host_del_key(KC_SCROLLLOCK); 355 del_key(KC_SCROLLLOCK);
369 host_send_keyboard_report(); 356 send_keyboard_report();
370 } 357 }
371#endif 358#endif
372 359
@@ -375,25 +362,28 @@ void register_code(uint8_t code)
375 if (command_proc(code)) return; 362 if (command_proc(code)) return;
376 363
377#ifndef NO_ACTION_ONESHOT 364#ifndef NO_ACTION_ONESHOT
365/* TODO: remove
378 if (oneshot_state.mods && !oneshot_state.disabled) { 366 if (oneshot_state.mods && !oneshot_state.disabled) {
379 uint8_t tmp_mods = host_get_mods(); 367 uint8_t tmp_mods = get_mods();
380 host_add_mods(oneshot_state.mods); 368 add_mods(oneshot_state.mods);
381 369
382 host_add_key(code); 370 add_key(code);
383 host_send_keyboard_report(); 371 send_keyboard_report();
384 372
385 host_set_mods(tmp_mods); 373 set_mods(tmp_mods);
374 send_keyboard_report();
386 oneshot_cancel(); 375 oneshot_cancel();
387 } else 376 } else
377*/
388#endif 378#endif
389 { 379 {
390 host_add_key(code); 380 add_key(code);
391 host_send_keyboard_report(); 381 send_keyboard_report();
392 } 382 }
393 } 383 }
394 else if IS_MOD(code) { 384 else if IS_MOD(code) {
395 host_add_mods(MOD_BIT(code)); 385 add_mods(MOD_BIT(code));
396 host_send_keyboard_report(); 386 send_keyboard_report();
397 } 387 }
398 else if IS_SYSTEM(code) { 388 else if IS_SYSTEM(code) {
399 host_system_send(KEYCODE2SYSTEM(code)); 389 host_system_send(KEYCODE2SYSTEM(code));
@@ -415,40 +405,40 @@ void unregister_code(uint8_t code)
415 // Resync: ignore if caps lock already is off 405 // Resync: ignore if caps lock already is off
416 if (!(host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK))) return; 406 if (!(host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK))) return;
417#endif 407#endif
418 host_add_key(KC_CAPSLOCK); 408 add_key(KC_CAPSLOCK);
419 host_send_keyboard_report(); 409 send_keyboard_report();
420 host_del_key(KC_CAPSLOCK); 410 del_key(KC_CAPSLOCK);
421 host_send_keyboard_report(); 411 send_keyboard_report();
422 } 412 }
423 413
424 else if (KC_LOCKING_NUM == code) { 414 else if (KC_LOCKING_NUM == code) {
425#ifdef LOCKING_RESYNC_ENABLE 415#ifdef LOCKING_RESYNC_ENABLE
426 if (!(host_keyboard_leds() & (1<<USB_LED_NUM_LOCK))) return; 416 if (!(host_keyboard_leds() & (1<<USB_LED_NUM_LOCK))) return;
427#endif 417#endif
428 host_add_key(KC_NUMLOCK); 418 add_key(KC_NUMLOCK);
429 host_send_keyboard_report(); 419 send_keyboard_report();
430 host_del_key(KC_NUMLOCK); 420 del_key(KC_NUMLOCK);
431 host_send_keyboard_report(); 421 send_keyboard_report();
432 } 422 }
433 423
434 else if (KC_LOCKING_SCROLL == code) { 424 else if (KC_LOCKING_SCROLL == code) {
435#ifdef LOCKING_RESYNC_ENABLE 425#ifdef LOCKING_RESYNC_ENABLE
436 if (!(host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK))) return; 426 if (!(host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK))) return;
437#endif 427#endif
438 host_add_key(KC_SCROLLLOCK); 428 add_key(KC_SCROLLLOCK);
439 host_send_keyboard_report(); 429 send_keyboard_report();
440 host_del_key(KC_SCROLLLOCK); 430 del_key(KC_SCROLLLOCK);
441 host_send_keyboard_report(); 431 send_keyboard_report();
442 } 432 }
443#endif 433#endif
444 434
445 else if IS_KEY(code) { 435 else if IS_KEY(code) {
446 host_del_key(code); 436 del_key(code);
447 host_send_keyboard_report(); 437 send_keyboard_report();
448 } 438 }
449 else if IS_MOD(code) { 439 else if IS_MOD(code) {
450 host_del_mods(MOD_BIT(code)); 440 del_mods(MOD_BIT(code));
451 host_send_keyboard_report(); 441 send_keyboard_report();
452 } 442 }
453 else if IS_SYSTEM(code) { 443 else if IS_SYSTEM(code) {
454 host_system_send(0); 444 host_system_send(0);
@@ -458,38 +448,33 @@ void unregister_code(uint8_t code)
458 } 448 }
459} 449}
460 450
461void add_mods(uint8_t mods) 451void register_mods(uint8_t mods)
462{ 452{
463 if (mods) { 453 if (mods) {
464 host_add_mods(mods); 454 add_mods(mods);
465 host_send_keyboard_report(); 455 send_keyboard_report();
466 } 456 }
467} 457}
468 458
469void del_mods(uint8_t mods) 459void unregister_mods(uint8_t mods)
470{ 460{
471 if (mods) { 461 if (mods) {
472 host_del_mods(mods); 462 del_mods(mods);
473 host_send_keyboard_report(); 463 send_keyboard_report();
474 } 464 }
475} 465}
476 466
477void set_mods(uint8_t mods)
478{
479 host_set_mods(mods);
480 host_send_keyboard_report();
481}
482
483void clear_keyboard(void) 467void clear_keyboard(void)
484{ 468{
485 host_clear_mods(); 469 clear_mods();
486 clear_keyboard_but_mods(); 470 clear_keyboard_but_mods();
487} 471}
488 472
489void clear_keyboard_but_mods(void) 473void clear_keyboard_but_mods(void)
490{ 474{
491 host_clear_keys(); 475 clear_weak_mods();
492 host_send_keyboard_report(); 476 clear_keys();
477 send_keyboard_report();
493#ifdef MOUSEKEY_ENABLE 478#ifdef MOUSEKEY_ENABLE
494 mousekey_clear(); 479 mousekey_clear();
495 mousekey_send(); 480 mousekey_send();
@@ -502,7 +487,7 @@ void clear_keyboard_but_mods(void)
502 487
503bool sending_anykey(void) 488bool sending_anykey(void)
504{ 489{
505 return (host_has_anykey() || host_mouse_in_use() || 490 return (has_anykey() || host_mouse_in_use() ||
506 host_last_sysytem_report() || host_last_consumer_report()); 491 host_last_sysytem_report() || host_last_consumer_report());
507} 492}
508 493
diff --git a/common/action.h b/common/action.h
index 8f1f5b798..d57f4a86f 100644
--- a/common/action.h
+++ b/common/action.h
@@ -59,9 +59,9 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt);
59void process_action(keyrecord_t *record); 59void process_action(keyrecord_t *record);
60void register_code(uint8_t code); 60void register_code(uint8_t code);
61void unregister_code(uint8_t code); 61void unregister_code(uint8_t code);
62void add_mods(uint8_t mods); 62void register_mods(uint8_t mods);
63void del_mods(uint8_t mods); 63void unregister_mods(uint8_t mods);
64void set_mods(uint8_t mods); 64//void set_mods(uint8_t mods);
65void clear_keyboard(void); 65void clear_keyboard(void);
66void clear_keyboard_but_mods(void); 66void clear_keyboard_but_mods(void);
67bool sending_anykey(void); 67bool sending_anykey(void);
diff --git a/common/action_code.h b/common/action_code.h
index 45e974a66..c153838f2 100644
--- a/common/action_code.h
+++ b/common/action_code.h
@@ -29,13 +29,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
29 * 000r|0000|0000 0001 Transparent code 29 * 000r|0000|0000 0001 Transparent code
30 * 000r|0000| keycode Key 30 * 000r|0000| keycode Key
31 * 000r|mods|0000 0000 Modifiers 31 * 000r|mods|0000 0000 Modifiers
32 * 000r|mods| keycode Key and Modifiers 32 * 000r|mods| keycode Modifiers+Key(Modified key)
33 * r: Left/Right flag(Left:0, Right:1) 33 * r: Left/Right flag(Left:0, Right:1)
34 * 34 *
35 * ACT_MODS_TAP(001r): 35 * ACT_MODS_TAP(001r):
36 * 001r|mods|0000 0000 Modifiers with OneShot 36 * 001r|mods|0000 0000 Modifiers with OneShot
37 * 001r|mods|0000 00xx (reserved) 37 * 001r|mods|0000 00xx (reserved)
38 * 001r|mods| keycode Modifiers with Tap Key 38 * 001r|mods| keycode Modifiers with Tap Key(Dual role)
39 * 39 *
40 * 40 *
41 * Other Keys(01xx) 41 * Other Keys(01xx)
@@ -69,7 +69,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
69 * 1001|oopp|BBBB BBBB 8-bit Bitwise Operation??? 69 * 1001|oopp|BBBB BBBB 8-bit Bitwise Operation???
70 * 70 *
71 * ACT_LAYER_TAP(101x): 71 * ACT_LAYER_TAP(101x):
72 * 101E|LLLL| keycode Invert with tap key 72 * 101E|LLLL| keycode On/Off with tap key
73 * 101E|LLLL|1110 xxxx Reserved(0xE0-EF) 73 * 101E|LLLL|1110 xxxx Reserved(0xE0-EF)
74 * 101E|LLLL|1111 0000 Invert with tap toggle(0xF0) 74 * 101E|LLLL|1111 0000 Invert with tap toggle(0xF0)
75 * 101E|LLLL|1111 0001 On/Off 75 * 101E|LLLL|1111 0001 On/Off
@@ -207,10 +207,10 @@ enum mods_codes {
207 MODS_ONESHOT = 0x00, 207 MODS_ONESHOT = 0x00,
208}; 208};
209#define ACTION_KEY(key) ACTION(ACT_MODS, (key)) 209#define ACTION_KEY(key) ACTION(ACT_MODS, (key))
210#define ACTION_MODS(mods) ACTION(ACT_MODS, (mods)<<8 | 0) 210#define ACTION_MODS(mods) ACTION(ACT_MODS, (mods&0x1f)<<8 | 0)
211#define ACTION_MODS_KEY(mods, key) ACTION(ACT_MODS, (mods)<<8 | (key)) 211#define ACTION_MODS_KEY(mods, key) ACTION(ACT_MODS, (mods&0x1f)<<8 | (key))
212#define ACTION_MODS_TAP_KEY(mods, key) ACTION(ACT_MODS_TAP, (mods)<<8 | (key)) 212#define ACTION_MODS_TAP_KEY(mods, key) ACTION(ACT_MODS_TAP, (mods&0x1f)<<8 | (key))
213#define ACTION_MODS_ONESHOT(mods) ACTION(ACT_MODS_TAP, (mods)<<8 | MODS_ONESHOT) 213#define ACTION_MODS_ONESHOT(mods) ACTION(ACT_MODS_TAP, (mods&0x1f)<<8 | MODS_ONESHOT)
214 214
215 215
216/* 216/*
diff --git a/common/action_oneshot.c b/common/action_oneshot.c
deleted file mode 100644
index d34f44b5a..000000000
--- a/common/action_oneshot.c
+++ /dev/null
@@ -1,21 +0,0 @@
1#include "action_oneshot.h"
2
3
4#ifndef NO_ACTION_ONESHOT
5oneshot_state_t oneshot_state;
6
7void oneshot_start(uint8_t mods)
8{
9 oneshot_state.mods = mods;
10}
11
12void oneshot_cancel(void)
13{
14 oneshot_state.mods = 0;
15}
16
17void oneshot_toggle(void)
18{
19 oneshot_state.disabled = !oneshot_state.disabled;
20}
21#endif
diff --git a/common/action_oneshot.h b/common/action_oneshot.h
deleted file mode 100644
index 36ef9e9bc..000000000
--- a/common/action_oneshot.h
+++ /dev/null
@@ -1,52 +0,0 @@
1/*
2Copyright 2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17#ifndef ACTION_ONESHOT_H
18#define ACTION_ONESHOT_H
19
20#include <stdint.h>
21#include <stdbool.h>
22
23#ifdef NO_ACTION_TAPPING
24 #define NO_ACTION_ONESHOT
25#endif
26
27#ifndef NO_ACTION_ONESHOT
28/* Oneshot modifier
29 *
30 * Problem: Want to capitalize like 'The' but the result tends to be 'THe'.
31 * Solution: Oneshot modifier have its effect on only one key coming next.
32 * Tap Shift, then type 't', 'h' and 'e'. Not need to hold Shift key.
33 *
34 * Hold: works as normal modifier.
35 * Tap: one shot modifier.
36 * 2 Tap: cancel one shot modifier.
37 * 5-Tap: toggles enable/disable oneshot feature.
38 */
39typedef struct {
40 uint8_t mods;
41 bool disabled;
42} oneshot_state_t;
43
44
45oneshot_state_t oneshot_state;
46
47void oneshot_start(uint8_t mods);
48void oneshot_cancel(void);
49void oneshot_toggle(void);
50#endif
51
52#endif
diff --git a/common/action_tapping.c b/common/action_tapping.c
index a6292535e..826c23309 100644
--- a/common/action_tapping.c
+++ b/common/action_tapping.c
@@ -1,7 +1,9 @@
1#include <stdint.h> 1#include <stdint.h>
2#include <stdbool.h> 2#include <stdbool.h>
3#include "action.h" 3#include "action.h"
4#include "action_layer.h"
4#include "action_tapping.h" 5#include "action_tapping.h"
6#include "keycode.h"
5#include "timer.h" 7#include "timer.h"
6 8
7#ifdef DEBUG_ACTION 9#ifdef DEBUG_ACTION
@@ -27,9 +29,7 @@ static uint8_t waiting_buffer_tail = 0;
27static bool process_tapping(keyrecord_t *record); 29static bool process_tapping(keyrecord_t *record);
28static bool waiting_buffer_enq(keyrecord_t record); 30static bool waiting_buffer_enq(keyrecord_t record);
29static void waiting_buffer_clear(void); 31static void waiting_buffer_clear(void);
30#if TAPPING_TERM >= 500
31static bool waiting_buffer_typed(keyevent_t event); 32static bool waiting_buffer_typed(keyevent_t event);
32#endif
33static bool waiting_buffer_has_anykey_pressed(void); 33static bool waiting_buffer_has_anykey_pressed(void);
34static void waiting_buffer_scan_tap(void); 34static void waiting_buffer_scan_tap(void);
35static void debug_tapping_key(void); 35static void debug_tapping_key(void);
@@ -97,18 +97,43 @@ bool process_tapping(keyrecord_t *keyp)
97 return false; 97 return false;
98 } 98 }
99#if TAPPING_TERM >= 500 99#if TAPPING_TERM >= 500
100 /* This can settle mod/fn state fast but may prevent from typing fast. */ 100 /* Process a key typed within TAPPING_TERM
101 else if (!event.pressed && waiting_buffer_typed(event)) { 101 * This can register the key before settlement of tapping,
102 // other key typed. not tap. 102 * useful for long TAPPING_TERM but may prevent fast typing.
103 */
104 else if (IS_RELEASED(event) && waiting_buffer_typed(event)) {
103 debug("Tapping: End. No tap. Interfered by typing key\n"); 105 debug("Tapping: End. No tap. Interfered by typing key\n");
104 process_action(&tapping_key); 106 process_action(&tapping_key);
105 tapping_key = (keyrecord_t){}; 107 tapping_key = (keyrecord_t){};
106 debug_tapping_key(); 108 debug_tapping_key();
107
108 // enqueue 109 // enqueue
109 return false; 110 return false;
110 } 111 }
111#endif 112#endif
113 /* Process release event of a key pressed before tapping starts
114 * Without this unexpected repeating will occur with having fast repeating setting
115 * https://github.com/tmk/tmk_keyboard/issues/60
116 */
117 else if (IS_RELEASED(event) && !waiting_buffer_typed(event)) {
118 // Modifier should be retained till end of this tapping.
119 action_t action = layer_switch_get_action(event.key);
120 switch (action.kind.id) {
121 case ACT_LMODS:
122 case ACT_RMODS:
123 if (action.key.mods && !action.key.code) return false;
124 if (IS_MOD(action.key.code)) return false;
125 break;
126 case ACT_LMODS_TAP:
127 case ACT_RMODS_TAP:
128 if (action.key.mods && keyp->tap.count == 0) return false;
129 if (IS_MOD(action.key.code)) return false;
130 break;
131 }
132 // Release of key should be process immediately.
133 debug("Tapping: release event of a key pressed before tapping\n");
134 process_action(keyp);
135 return true;
136 }
112 else { 137 else {
113 // set interrupted flag when other key preesed during tapping 138 // set interrupted flag when other key preesed during tapping
114 if (event.pressed) { 139 if (event.pressed) {
@@ -289,7 +314,6 @@ void waiting_buffer_clear(void)
289 waiting_buffer_tail = 0; 314 waiting_buffer_tail = 0;
290} 315}
291 316
292#if TAPPING_TERM >= 500
293bool waiting_buffer_typed(keyevent_t event) 317bool waiting_buffer_typed(keyevent_t event)
294{ 318{
295 for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) { 319 for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
@@ -299,7 +323,6 @@ bool waiting_buffer_typed(keyevent_t event)
299 } 323 }
300 return false; 324 return false;
301} 325}
302#endif
303 326
304bool waiting_buffer_has_anykey_pressed(void) 327bool waiting_buffer_has_anykey_pressed(void)
305{ 328{
diff --git a/common/action_util.c b/common/action_util.c
new file mode 100644
index 000000000..99a3adaab
--- /dev/null
+++ b/common/action_util.c
@@ -0,0 +1,213 @@
1/*
2Copyright 2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17#include "host.h"
18#include "report.h"
19#include "debug.h"
20#include "action_util.h"
21#include "timer.h"
22
23static inline void add_key_byte(uint8_t code);
24static inline void del_key_byte(uint8_t code);
25#ifdef NKRO_ENABLE
26static inline void add_key_bit(uint8_t code);
27static inline void del_key_bit(uint8_t code);
28#endif
29
30static uint8_t real_mods = 0;
31static uint8_t weak_mods = 0;
32
33
34// TODO: pointer variable is not needed
35//report_keyboard_t keyboard_report = {};
36report_keyboard_t *keyboard_report = &(report_keyboard_t){};
37
38#ifndef NO_ACTION_ONESHOT
39static int8_t oneshot_mods = 0;
40#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
41static int16_t oneshot_time = 0;
42#endif
43#endif
44
45
46void send_keyboard_report(void) {
47 keyboard_report->mods = real_mods;
48 keyboard_report->mods |= weak_mods;
49#ifndef NO_ACTION_ONESHOT
50 if (oneshot_mods) {
51#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
52 if (TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT) {
53 dprintf("Oneshot: timeout\n");
54 clear_oneshot_mods();
55 }
56#endif
57 keyboard_report->mods |= oneshot_mods;
58 if (has_anykey()) {
59 clear_oneshot_mods();
60 }
61 }
62#endif
63 host_keyboard_send(keyboard_report);
64}
65
66/* key */
67void add_key(uint8_t key)
68{
69#ifdef NKRO_ENABLE
70 if (keyboard_nkro) {
71 add_key_bit(key);
72 return;
73 }
74#endif
75 add_key_byte(key);
76}
77
78void del_key(uint8_t key)
79{
80#ifdef NKRO_ENABLE
81 if (keyboard_nkro) {
82 del_key_bit(key);
83 return;
84 }
85#endif
86 del_key_byte(key);
87}
88
89void clear_keys(void)
90{
91 // not clear mods
92 for (int8_t i = 1; i < REPORT_SIZE; i++) {
93 keyboard_report->raw[i] = 0;
94 }
95}
96
97
98/* modifier */
99uint8_t get_mods(void) { return real_mods; }
100void add_mods(uint8_t mods) { real_mods |= mods; }
101void del_mods(uint8_t mods) { real_mods &= ~mods; }
102void set_mods(uint8_t mods) { real_mods = mods; }
103void clear_mods(void) { real_mods = 0; }
104
105/* weak modifier */
106uint8_t get_weak_mods(void) { return weak_mods; }
107void add_weak_mods(uint8_t mods) { weak_mods |= mods; }
108void del_weak_mods(uint8_t mods) { weak_mods &= ~mods; }
109void set_weak_mods(uint8_t mods) { weak_mods = mods; }
110void clear_weak_mods(void) { weak_mods = 0; }
111
112/* Oneshot modifier */
113#ifndef NO_ACTION_ONESHOT
114void set_oneshot_mods(uint8_t mods)
115{
116 oneshot_mods = mods;
117#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
118 oneshot_time = timer_read();
119#endif
120}
121void clear_oneshot_mods(void)
122{
123 oneshot_mods = 0;
124#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
125 oneshot_time = 0;
126#endif
127}
128#endif
129
130
131
132
133/*
134 * inspect keyboard state
135 */
136uint8_t has_anykey(void)
137{
138 uint8_t cnt = 0;
139 for (uint8_t i = 1; i < REPORT_SIZE; i++) {
140 if (keyboard_report->raw[i])
141 cnt++;
142 }
143 return cnt;
144}
145
146uint8_t has_anymod(void)
147{
148 return bitpop(real_mods);
149}
150
151uint8_t get_first_key(void)
152{
153#ifdef NKRO_ENABLE
154 if (keyboard_nkro) {
155 uint8_t i = 0;
156 for (; i < REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
157 ;
158 return i<<3 | biton(keyboard_report->nkro.bits[i]);
159 }
160#endif
161 return keyboard_report->keys[0];
162}
163
164
165
166/* local functions */
167static inline void add_key_byte(uint8_t code)
168{
169 int8_t i = 0;
170 int8_t empty = -1;
171 for (; i < REPORT_KEYS; i++) {
172 if (keyboard_report->keys[i] == code) {
173 break;
174 }
175 if (empty == -1 && keyboard_report->keys[i] == 0) {
176 empty = i;
177 }
178 }
179 if (i == REPORT_KEYS) {
180 if (empty != -1) {
181 keyboard_report->keys[empty] = code;
182 }
183 }
184}
185
186static inline void del_key_byte(uint8_t code)
187{
188 for (uint8_t i = 0; i < REPORT_KEYS; i++) {
189 if (keyboard_report->keys[i] == code) {
190 keyboard_report->keys[i] = 0;
191 }
192 }
193}
194
195#ifdef NKRO_ENABLE
196static inline void add_key_bit(uint8_t code)
197{
198 if ((code>>3) < REPORT_BITS) {
199 keyboard_report->nkro.bits[code>>3] |= 1<<(code&7);
200 } else {
201 dprintf("add_key_bit: can't add: %02X\n", code);
202 }
203}
204
205static inline void del_key_bit(uint8_t code)
206{
207 if ((code>>3) < REPORT_BITS) {
208 keyboard_report->nkro.bits[code>>3] &= ~(1<<(code&7));
209 } else {
210 dprintf("del_key_bit: can't del: %02X\n", code);
211 }
212}
213#endif
diff --git a/common/action_util.h b/common/action_util.h
new file mode 100644
index 000000000..939bc2b66
--- /dev/null
+++ b/common/action_util.h
@@ -0,0 +1,56 @@
1/*
2Copyright 2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17#ifndef ACTION_UTIL_H
18#define ACTION_UTIL_H
19
20#include <stdint.h>
21
22extern report_keyboard_t *keyboard_report;
23
24void send_keyboard_report(void);
25
26/* key */
27void add_key(uint8_t key);
28void del_key(uint8_t key);
29void clear_keys(void);
30
31/* modifier */
32uint8_t get_mods(void);
33void add_mods(uint8_t mods);
34void del_mods(uint8_t mods);
35void set_mods(uint8_t mods);
36void clear_mods(void);
37
38/* weak modifier */
39uint8_t get_weak_mods(void);
40void add_weak_mods(uint8_t mods);
41void del_weak_mods(uint8_t mods);
42void set_weak_mods(uint8_t mods);
43void clear_weak_mods(void);
44
45/* oneshot modifier */
46void set_oneshot_mods(uint8_t mods);
47void clear_oneshot_mods(void);
48void oneshot_toggle(void);
49void oneshot_enable(void);
50void oneshot_disable(void);
51
52/* inspect */
53uint8_t has_anykey(void);
54uint8_t has_anymod(void);
55uint8_t get_first_key(void);
56#endif
diff --git a/common/bootloader.c b/common/bootloader.c
index 43a7e47ce..cda295b18 100644
--- a/common/bootloader.c
+++ b/common/bootloader.c
@@ -71,7 +71,8 @@ void bootloader_jump_after_watchdog_reset(void)
71 MCUSR &= ~(1<<WDRF); 71 MCUSR &= ~(1<<WDRF);
72 wdt_disable(); 72 wdt_disable();
73 73
74 ((void (*)(void))BOOTLOADER_START)(); 74 // This is compled into 'icall', address should be in word unit, not byte.
75 ((void (*)(void))(BOOTLOADER_START/2))();
75 } 76 }
76} 77}
77 78
@@ -141,7 +142,7 @@ void bootloader_jump(void) {
141 ADCSRA = 0; TWCR = 0; UCSR0B = 0; 142 ADCSRA = 0; TWCR = 0; UCSR0B = 0;
142#endif 143#endif
143 144
144 // start Bootloader 145 // This is compled into 'icall', address should be in word unit, not byte.
145 ((void (*)(void))BOOTLOADER_START)(); 146 ((void (*)(void))(BOOTLOADER_START/2))();
146} 147}
147#endif 148#endif
diff --git a/common/bootmagic.c b/common/bootmagic.c
index 410dc6836..036d49044 100644
--- a/common/bootmagic.c
+++ b/common/bootmagic.c
@@ -18,8 +18,10 @@ void bootmagic(void)
18 } 18 }
19 19
20 /* do scans in case of bounce */ 20 /* do scans in case of bounce */
21 print("boogmagic scan: ... ");
21 uint8_t scan = 100; 22 uint8_t scan = 100;
22 while (scan--) { matrix_scan(); _delay_ms(10); } 23 while (scan--) { matrix_scan(); _delay_ms(10); }
24 print("done.\n");
23 25
24 /* bootmagic skip */ 26 /* bootmagic skip */
25 if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SKIP)) { 27 if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SKIP)) {
@@ -53,7 +55,7 @@ void bootmagic(void)
53 55
54 /* keymap config */ 56 /* keymap config */
55 keymap_config.raw = eeconfig_read_keymap(); 57 keymap_config.raw = eeconfig_read_keymap();
56 if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_CONTROL_CPASLOCK)) { 58 if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK)) {
57 keymap_config.swap_control_capslock = !keymap_config.swap_control_capslock; 59 keymap_config.swap_control_capslock = !keymap_config.swap_control_capslock;
58 } 60 }
59 if (bootmagic_scan_keycode(BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL)) { 61 if (bootmagic_scan_keycode(BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL)) {
diff --git a/common/bootmagic.h b/common/bootmagic.h
index 2d14b3e76..7c1922397 100644
--- a/common/bootmagic.h
+++ b/common/bootmagic.h
@@ -23,34 +23,72 @@
23#endif 23#endif
24 24
25/* debug enable */ 25/* debug enable */
26#ifndef BOOTMAGIC_KEY_DEBUG_ENABLE
26#define BOOTMAGIC_KEY_DEBUG_ENABLE KC_D 27#define BOOTMAGIC_KEY_DEBUG_ENABLE KC_D
28#endif
29#ifndef BOOTMAGIC_KEY_DEBUG_MATRIX
27#define BOOTMAGIC_KEY_DEBUG_MATRIX KC_X 30#define BOOTMAGIC_KEY_DEBUG_MATRIX KC_X
31#endif
32#ifndef BOOTMAGIC_KEY_DEBUG_KEYBOARD
28#define BOOTMAGIC_KEY_DEBUG_KEYBOARD KC_K 33#define BOOTMAGIC_KEY_DEBUG_KEYBOARD KC_K
34#endif
35#ifndef BOOTMAGIC_KEY_DEBUG_MOUSE
29#define BOOTMAGIC_KEY_DEBUG_MOUSE KC_M 36#define BOOTMAGIC_KEY_DEBUG_MOUSE KC_M
37#endif
30 38
31/* 39/*
32 * keymap config 40 * keymap config
33 */ 41 */
34#define BOOTMAGIC_KEY_SWAP_CONTROL_CPASLOCK KC_LCTRL 42#ifndef BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK
43#define BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK KC_LCTRL
44#endif
45#ifndef BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL
35#define BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL KC_CAPSLOCK 46#define BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL KC_CAPSLOCK
47#endif
48#ifndef BOOTMAGIC_KEY_SWAP_LALT_LGUI
36#define BOOTMAGIC_KEY_SWAP_LALT_LGUI KC_LALT 49#define BOOTMAGIC_KEY_SWAP_LALT_LGUI KC_LALT
50#endif
51#ifndef BOOTMAGIC_KEY_SWAP_RALT_RGUI
37#define BOOTMAGIC_KEY_SWAP_RALT_RGUI KC_RALT 52#define BOOTMAGIC_KEY_SWAP_RALT_RGUI KC_RALT
53#endif
54#ifndef BOOTMAGIC_KEY_NO_GUI
38#define BOOTMAGIC_KEY_NO_GUI KC_LGUI 55#define BOOTMAGIC_KEY_NO_GUI KC_LGUI
56#endif
57#ifndef BOOTMAGIC_KEY_SWAP_GRAVE_ESC
39#define BOOTMAGIC_KEY_SWAP_GRAVE_ESC KC_GRAVE 58#define BOOTMAGIC_KEY_SWAP_GRAVE_ESC KC_GRAVE
59#endif
60#ifndef BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE
40#define BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE KC_BSLASH 61#define BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE KC_BSLASH
62#endif
41 63
42 64
43/* 65/*
44 * change default layer 66 * change default layer
45 */ 67 */
68#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_0
46#define BOOTMAGIC_KEY_DEFAULT_LAYER_0 KC_0 69#define BOOTMAGIC_KEY_DEFAULT_LAYER_0 KC_0
70#endif
71#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_1
47#define BOOTMAGIC_KEY_DEFAULT_LAYER_1 KC_1 72#define BOOTMAGIC_KEY_DEFAULT_LAYER_1 KC_1
73#endif
74#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_2
48#define BOOTMAGIC_KEY_DEFAULT_LAYER_2 KC_2 75#define BOOTMAGIC_KEY_DEFAULT_LAYER_2 KC_2
76#endif
77#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_3
49#define BOOTMAGIC_KEY_DEFAULT_LAYER_3 KC_3 78#define BOOTMAGIC_KEY_DEFAULT_LAYER_3 KC_3
79#endif
80#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_4
50#define BOOTMAGIC_KEY_DEFAULT_LAYER_4 KC_4 81#define BOOTMAGIC_KEY_DEFAULT_LAYER_4 KC_4
82#endif
83#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_5
51#define BOOTMAGIC_KEY_DEFAULT_LAYER_5 KC_5 84#define BOOTMAGIC_KEY_DEFAULT_LAYER_5 KC_5
85#endif
86#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_6
52#define BOOTMAGIC_KEY_DEFAULT_LAYER_6 KC_6 87#define BOOTMAGIC_KEY_DEFAULT_LAYER_6 KC_6
88#endif
89#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_7
53#define BOOTMAGIC_KEY_DEFAULT_LAYER_7 KC_7 90#define BOOTMAGIC_KEY_DEFAULT_LAYER_7 KC_7
91#endif
54 92
55 93
56void bootmagic(void); 94void bootmagic(void);
diff --git a/common/command.c b/common/command.c
index 4649e00ab..f6f276951 100644
--- a/common/command.c
+++ b/common/command.c
@@ -27,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
27#include "keyboard.h" 27#include "keyboard.h"
28#include "bootloader.h" 28#include "bootloader.h"
29#include "action_layer.h" 29#include "action_layer.h"
30#include "action_util.h"
30#include "eeconfig.h" 31#include "eeconfig.h"
31#include "sleep_led.h" 32#include "sleep_led.h"
32#include "led.h" 33#include "led.h"
@@ -251,10 +252,48 @@ static bool command_common(uint8_t code)
251 break; 252 break;
252 case KC_V: // print version & information 253 case KC_V: // print version & information
253 print("\n\n----- Version -----\n"); 254 print("\n\n----- Version -----\n");
254 print(STR(DESCRIPTION) "\n"); 255 print("DESC: " STR(DESCRIPTION) "\n");
255 print(STR(MANUFACTURER) "(" STR(VENDOR_ID) ")/"); 256 print("VID: " STR(VENDOR_ID) "(" STR(MANUFACTURER) ") "
256 print(STR(PRODUCT) "(" STR(PRODUCT_ID) ") "); 257 "PID: " STR(PRODUCT_ID) "(" STR(PRODUCT) ") "
257 print("VERSION: " STR(DEVICE_VER) "\n"); 258 "VER: " STR(DEVICE_VER) "\n");
259 print("BUILD: " STR(VERSION) " (" __TIME__ " " __DATE__ ")\n");
260 /* build options */
261 print("OPTIONS:"
262#ifdef PROTOCOL_PJRC
263 " PJRC"
264#endif
265#ifdef PROTOCOL_LUFA
266 " LUFA"
267#endif
268#ifdef PROTOCOL_VUSB
269 " VUSB"
270#endif
271#ifdef BOOTMAGIC_ENABLE
272 " BOOTMAGIC"
273#endif
274#ifdef MOUSEKEY_ENABLE
275 " MOUSEKEY"
276#endif
277#ifdef EXTRAKEY_ENABLE
278 " EXTRAKEY"
279#endif
280#ifdef CONSOLE_ENABLE
281 " CONSOLE"
282#endif
283#ifdef COMMAND_ENABLE
284 " COMMAND"
285#endif
286#ifdef NKRO_ENABLE
287 " NKRO"
288#endif
289#ifdef KEYMAP_SECTION_ENABLE
290 " KEYMAP_SECTION"
291#endif
292 " " STR(BOOTLOADER_SIZE) "\n");
293
294 print("GCC: " STR(__GNUC__) "." STR(__GNUC_MINOR__) "." STR(__GNUC_PATCHLEVEL__)
295 " AVR-LIBC: " __AVR_LIBC_VERSION_STRING__
296 " AVR_ARCH: avr" STR(__AVR_ARCH__) "\n");
258 break; 297 break;
259 case KC_T: // print timer 298 case KC_T: // print timer
260 print_val_hex32(timer_count); 299 print_val_hex32(timer_count);
diff --git a/common/host.c b/common/host.c
index 569451652..0703dba01 100644
--- a/common/host.c
+++ b/common/host.c
@@ -27,7 +27,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
27bool keyboard_nkro = false; 27bool keyboard_nkro = false;
28#endif 28#endif
29 29
30report_keyboard_t *keyboard_report = &(report_keyboard_t){};
31report_mouse_t mouse_report = {}; 30report_mouse_t mouse_report = {};
32 31
33 32
@@ -35,13 +34,6 @@ static host_driver_t *driver;
35static uint16_t last_system_report = 0; 34static uint16_t last_system_report = 0;
36static uint16_t last_consumer_report = 0; 35static uint16_t last_consumer_report = 0;
37 36
38static inline void add_key_byte(uint8_t code);
39static inline void del_key_byte(uint8_t code);
40#ifdef NKRO_ENABLE
41static inline void add_key_bit(uint8_t code);
42static inline void del_key_bit(uint8_t code);
43#endif
44
45 37
46void host_set_driver(host_driver_t *d) 38void host_set_driver(host_driver_t *d)
47{ 39{
@@ -67,7 +59,7 @@ void host_keyboard_send(report_keyboard_t *report)
67 if (debug_keyboard) { 59 if (debug_keyboard) {
68 dprint("keyboard_report: "); 60 dprint("keyboard_report: ");
69 for (uint8_t i = 0; i < REPORT_SIZE; i++) { 61 for (uint8_t i = 0; i < REPORT_SIZE; i++) {
70 dprintf("%02X ", keyboard_report->raw[i]); 62 dprintf("%02X ", report->raw[i]);
71 } 63 }
72 dprint("\n"); 64 dprint("\n");
73 } 65 }
@@ -97,98 +89,6 @@ void host_consumer_send(uint16_t report)
97 (*driver->send_consumer)(report); 89 (*driver->send_consumer)(report);
98} 90}
99 91
100
101
102/* keyboard report utils */
103void host_add_key(uint8_t key)
104{
105#ifdef NKRO_ENABLE
106 if (keyboard_nkro) {
107 add_key_bit(key);
108 return;
109 }
110#endif
111 add_key_byte(key);
112}
113
114void host_del_key(uint8_t key)
115{
116#ifdef NKRO_ENABLE
117 if (keyboard_nkro) {
118 del_key_bit(key);
119 return;
120 }
121#endif
122 del_key_byte(key);
123}
124
125void host_clear_keys(void)
126{
127 // not clea mods
128 for (int8_t i = 1; i < REPORT_SIZE; i++) {
129 keyboard_report->raw[i] = 0;
130 }
131}
132
133uint8_t host_get_mods(void)
134{
135 return keyboard_report->mods;
136}
137
138void host_add_mods(uint8_t mods)
139{
140 keyboard_report->mods |= mods;
141}
142
143void host_del_mods(uint8_t mods)
144{
145 keyboard_report->mods &= ~mods;
146}
147
148void host_set_mods(uint8_t mods)
149{
150 keyboard_report->mods = mods;
151}
152
153void host_clear_mods(void)
154{
155 keyboard_report->mods = 0;
156}
157
158uint8_t host_has_anykey(void)
159{
160 uint8_t cnt = 0;
161 for (uint8_t i = 1; i < REPORT_SIZE; i++) {
162 if (keyboard_report->raw[i])
163 cnt++;
164 }
165 return cnt;
166}
167
168uint8_t host_has_anymod(void)
169{
170 return bitpop(keyboard_report->mods);
171}
172
173uint8_t host_get_first_key(void)
174{
175#ifdef NKRO_ENABLE
176 if (keyboard_nkro) {
177 uint8_t i = 0;
178 for (; i < REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
179 ;
180 return i<<3 | biton(keyboard_report->nkro.bits[i]);
181 }
182#endif
183 return keyboard_report->keys[0];
184}
185
186void host_send_keyboard_report(void)
187{
188 if (!driver) return;
189 host_keyboard_send(keyboard_report);
190}
191
192uint8_t host_mouse_in_use(void) 92uint8_t host_mouse_in_use(void)
193{ 93{
194 return (mouse_report.buttons | mouse_report.x | mouse_report.y | mouse_report.v | mouse_report.h); 94 return (mouse_report.buttons | mouse_report.x | mouse_report.y | mouse_report.v | mouse_report.h);
@@ -203,51 +103,3 @@ uint16_t host_last_consumer_report(void)
203{ 103{
204 return last_consumer_report; 104 return last_consumer_report;
205} 105}
206
207static inline void add_key_byte(uint8_t code)
208{
209 int8_t i = 0;
210 int8_t empty = -1;
211 for (; i < REPORT_KEYS; i++) {
212 if (keyboard_report->keys[i] == code) {
213 break;
214 }
215 if (empty == -1 && keyboard_report->keys[i] == 0) {
216 empty = i;
217 }
218 }
219 if (i == REPORT_KEYS) {
220 if (empty != -1) {
221 keyboard_report->keys[empty] = code;
222 }
223 }
224}
225
226static inline void del_key_byte(uint8_t code)
227{
228 for (uint8_t i = 0; i < REPORT_KEYS; i++) {
229 if (keyboard_report->keys[i] == code) {
230 keyboard_report->keys[i] = 0;
231 }
232 }
233}
234
235#ifdef NKRO_ENABLE
236static inline void add_key_bit(uint8_t code)
237{
238 if ((code>>3) < REPORT_BITS) {
239 keyboard_report->nkro.bits[code>>3] |= 1<<(code&7);
240 } else {
241 dprintf("add_key_bit: can't add: %02X\n", code);
242 }
243}
244
245static inline void del_key_bit(uint8_t code)
246{
247 if ((code>>3) < REPORT_BITS) {
248 keyboard_report->nkro.bits[code>>3] &= ~(1<<(code&7));
249 } else {
250 dprintf("del_key_bit: can't del: %02X\n", code);
251 }
252}
253#endif
diff --git a/common/host.h b/common/host.h
index 7c4f06601..c1a0fbac4 100644
--- a/common/host.h
+++ b/common/host.h
@@ -33,7 +33,6 @@ extern bool keyboard_nkro;
33#endif 33#endif
34 34
35/* report */ 35/* report */
36extern report_keyboard_t *keyboard_report;
37extern report_mouse_t mouse_report; 36extern report_mouse_t mouse_report;
38 37
39 38
@@ -48,22 +47,6 @@ void host_mouse_send(report_mouse_t *report);
48void host_system_send(uint16_t data); 47void host_system_send(uint16_t data);
49void host_consumer_send(uint16_t data); 48void host_consumer_send(uint16_t data);
50 49
51/* keyboard report utils */
52void host_add_key(uint8_t key);
53void host_del_key(uint8_t key);
54void host_clear_keys(void);
55
56uint8_t host_get_mods(void);
57void host_add_mods(uint8_t mods);
58void host_del_mods(uint8_t mods);
59void host_set_mods(uint8_t mods);
60void host_clear_mods(void);
61
62uint8_t host_has_anykey(void);
63uint8_t host_has_anymod(void);
64uint8_t host_get_first_key(void);
65void host_send_keyboard_report(void);
66
67/* mouse report utils */ 50/* mouse report utils */
68uint8_t host_mouse_in_use(void); 51uint8_t host_mouse_in_use(void);
69 52
diff --git a/common/keyboard.c b/common/keyboard.c
index d1821a099..601e3abe1 100644
--- a/common/keyboard.c
+++ b/common/keyboard.c
@@ -54,9 +54,6 @@ static bool has_ghost_in_row(uint8_t row)
54 54
55void keyboard_init(void) 55void keyboard_init(void)
56{ 56{
57 // TODO: configuration of sendchar impl
58 print_set_sendchar(sendchar);
59
60 timer_init(); 57 timer_init();
61 matrix_init(); 58 matrix_init();
62#ifdef PS2_MOUSE_ENABLE 59#ifdef PS2_MOUSE_ENABLE
diff --git a/common/keyboard.h b/common/keyboard.h
index 78cb24034..d1a922420 100644
--- a/common/keyboard.h
+++ b/common/keyboard.h
@@ -42,16 +42,15 @@ typedef struct {
42/* equivalent test of key_t */ 42/* equivalent test of key_t */
43#define KEYEQ(keya, keyb) ((keya).row == (keyb).row && (keya).col == (keyb).col) 43#define KEYEQ(keya, keyb) ((keya).row == (keyb).row && (keya).col == (keyb).col)
44 44
45/* (time == 0) means no event and assumes matrix has no 255 line. */ 45/* Rules for No Event:
46#define IS_NOEVENT(event) ((event).time == 0 || ((event).key.row == 255 && (event).key.col == 255)) 46 * 1) (time == 0) to handle (keyevent_t){} as empty event
47 47 * 2) Matrix(255, 255) to make TICK event available
48#define NOEVENT (keyevent_t){ \ 48 */
49 .key = (key_t){ .row = 255, .col = 255 }, \ 49static inline bool IS_NOEVENT(keyevent_t event) { return event.time == 0 || (event.key.row == 255 && event.key.col == 255); }
50 .pressed = false, \ 50static inline bool IS_PRESSED(keyevent_t event) { return (!IS_NOEVENT(event) && event.pressed); }
51 .time = 0 \ 51static inline bool IS_RELEASED(keyevent_t event) { return (!IS_NOEVENT(event) && !event.pressed); }
52} 52
53 53/* Tick event */
54/* tick event */
55#define TICK (keyevent_t){ \ 54#define TICK (keyevent_t){ \
56 .key = (key_t){ .row = 255, .col = 255 }, \ 55 .key = (key_t){ .row = 255, .col = 255 }, \
57 .pressed = false, \ 56 .pressed = false, \
diff --git a/common/keymap.c b/common/keymap.c
index cf4711bf6..bfb8ffac1 100644
--- a/common/keymap.c
+++ b/common/keymap.c
@@ -36,10 +36,11 @@ action_t action_for_key(uint8_t layer, key_t key)
36 return keymap_fn_to_action(keycode); 36 return keymap_fn_to_action(keycode);
37#ifdef BOOTMAGIC_ENABLE 37#ifdef BOOTMAGIC_ENABLE
38 case KC_CAPSLOCK: 38 case KC_CAPSLOCK:
39 case KC_LOCKING_CAPS:
39 if (keymap_config.swap_control_capslock || keymap_config.capslock_to_control) { 40 if (keymap_config.swap_control_capslock || keymap_config.capslock_to_control) {
40 return keycode_to_action(KC_LCTL); 41 return keycode_to_action(KC_LCTL);
41 } 42 }
42 return keycode_to_action(KC_CAPS); 43 return keycode_to_action(keycode);
43 case KC_LCTL: 44 case KC_LCTL:
44 if (keymap_config.swap_control_capslock) { 45 if (keymap_config.swap_control_capslock) {
45 return keycode_to_action(KC_CAPSLOCK); 46 return keycode_to_action(KC_CAPSLOCK);
diff --git a/common/suspend.c b/common/suspend.c
index 146b96d5c..5b378892f 100644
--- a/common/suspend.c
+++ b/common/suspend.c
@@ -51,8 +51,7 @@ bool suspend_wakeup_condition(void)
51// run immediately after wakeup 51// run immediately after wakeup
52void suspend_wakeup_init(void) 52void suspend_wakeup_init(void)
53{ 53{
54 // clear matrix and keyboard state 54 // clear keyboard state
55 matrix_init();
56 clear_keyboard(); 55 clear_keyboard();
57#ifdef BACKLIGHT_ENABLE 56#ifdef BACKLIGHT_ENABLE
58 backlight_init(); 57 backlight_init();
diff --git a/converter/adb_usb/Makefile b/converter/adb_usb/Makefile
index 09f30180a..372ef6c09 100644
--- a/converter/adb_usb/Makefile
+++ b/converter/adb_usb/Makefile
@@ -1,5 +1,45 @@
1#----------------------------------------------------------------------------
2# On command line:
3#
4# make all = Make software.
5#
6# make clean = Clean out built project files.
7#
8# make coff = Convert ELF to AVR COFF.
9#
10# make extcoff = Convert ELF to AVR Extended COFF.
11#
12# make program = Download the hex file to the device.
13# Please customize your programmer settings(PROGRAM_CMD)
14#
15# make teensy = Download the hex file to the device, using teensy_loader_cli.
16# (must have teensy_loader_cli installed).
17#
18# make dfu = Download the hex file to the device, using dfu-programmer (must
19# have dfu-programmer installed).
20#
21# make flip = Download the hex file to the device, using Atmel FLIP (must
22# have Atmel FLIP installed).
23#
24# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
25# (must have dfu-programmer installed).
26#
27# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
28# (must have Atmel FLIP installed).
29#
30# make debug = Start either simulavr or avarice as specified for debugging,
31# with avr-gdb or avr-insight as the front end for debugging.
32#
33# make filename.s = Just compile filename.c into the assembler code only.
34#
35# make filename.i = Create a preprocessed source file for use in submitting
36# bug reports to the GCC project.
37#
38# To rebuild project do "make clean" then "make all".
39#----------------------------------------------------------------------------
40
1# Target file name (without extension). 41# Target file name (without extension).
2TARGET = adb_usb 42TARGET = adb_usb_lufa
3 43
4# Directory common source filess exist 44# Directory common source filess exist
5TOP_DIR = ../.. 45TOP_DIR = ../..
@@ -7,7 +47,7 @@ TOP_DIR = ../..
7# Directory keyboard dependent files exist 47# Directory keyboard dependent files exist
8TARGET_DIR = . 48TARGET_DIR = .
9 49
10# keyboard dependent files 50# project specific files
11SRC = keymap.c \ 51SRC = keymap.c \
12 matrix.c \ 52 matrix.c \
13 led.c \ 53 led.c \
@@ -16,22 +56,47 @@ SRC = keymap.c \
16CONFIG_H = config.h 56CONFIG_H = config.h
17 57
18 58
19# MCU name, you MUST set this to match the board you are using 59# MCU name
20# type "make clean" after changing this, so all files will be rebuilt 60#MCU = at90usb1287
21#MCU = at90usb162 # Teensy 1.0 61MCU = atmega32u4
22MCU = atmega32u4 # Teensy 2.0
23#MCU = at90usb646 # Teensy++ 1.0
24#MCU = at90usb1286 # Teensy++ 2.0
25
26 62
27# Processor frequency. 63# Processor frequency.
28# Normally the first thing your program should do is set the clock prescaler, 64# This will define a symbol, F_CPU, in all source code files equal to the
29# so your program will run at the correct speed. You should also set this 65# processor frequency in Hz. You can then use this symbol in your source code to
30# variable to same clock speed. The _delay_ms() macro uses this, and many 66# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
31# examples use this variable to calculate timings. Do not add a "UL" here. 67# automatically to create a 32-bit value in your source code.
68#
69# This will be an integer division of F_USB below, as it is sourced by
70# F_USB after it has run through any CPU prescalers. Note that this value
71# does not *change* the processor frequency - it should merely be updated to
72# reflect the processor speed set externally so that the code can use accurate
73# software delays.
32F_CPU = 16000000 74F_CPU = 16000000
33 75
34 76
77#
78# LUFA specific
79#
80# Target architecture (see library "Board Types" documentation).
81ARCH = AVR8
82
83# Input clock frequency.
84# This will define a symbol, F_USB, in all source code files equal to the
85# input clock frequency (before any prescaling is performed) in Hz. This value may
86# differ from F_CPU if prescaling is used on the latter, and is required as the
87# raw input clock is fed directly to the PLL sections of the AVR for high speed
88# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
89# at the end, this will be done automatically to create a 32-bit value in your
90# source code.
91#
92# If no clock division is performed on the input clock inside the AVR (via the
93# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
94F_USB = $(F_CPU)
95
96# Interrupt driven control endpoint task(+60)
97#OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
98
99
35# Boot Section Size in *bytes* 100# Boot Section Size in *bytes*
36# Teensy halfKay 512 101# Teensy halfKay 512
37# Teensy++ halfKay 1024 102# Teensy++ halfKay 1024
@@ -44,20 +109,23 @@ OPT_DEFS += -DBOOTLOADER_SIZE=4096
44# Build Options 109# Build Options
45# comment out to disable the options. 110# comment out to disable the options.
46# 111#
47#BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000) 112BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
48#MOUSEKEY_ENABLE = yes # Mouse keys(+5000) 113MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
49#EXTRAKEY_ENABLE = yes # Audio control and System control(+600) 114EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
50#CONSOLE_ENABLE = yes # Console for debug 115CONSOLE_ENABLE = yes # Console for debug(+400)
51#COMMAND_ENABLE = yes # Commands for debug and configuration 116COMMAND_ENABLE = yes # Commands for debug and configuration
52#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend 117#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
53#NKRO_ENABLE = yes # USB Nkey Rollover(+500) 118#NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA
119
54 120
121# Optimize size but this may cause error "relocation truncated to fit"
122#EXTRALDFLAGS = -Wl,--relax
55 123
56# Search Path 124# Search Path
57VPATH += $(TARGET_DIR) 125VPATH += $(TARGET_DIR)
58VPATH += $(TOP_DIR) 126VPATH += $(TOP_DIR)
59 127
60include $(TOP_DIR)/protocol/pjrc.mk 128include $(TOP_DIR)/protocol/lufa.mk
61include $(TOP_DIR)/protocol.mk 129include $(TOP_DIR)/protocol.mk
62include $(TOP_DIR)/common.mk 130include $(TOP_DIR)/common.mk
63include $(TOP_DIR)/rules.mk 131include $(TOP_DIR)/rules.mk
diff --git a/converter/adb_usb/Makefile.lufa b/converter/adb_usb/Makefile.blargg
index 372ef6c09..edce82d69 100644
--- a/converter/adb_usb/Makefile.lufa
+++ b/converter/adb_usb/Makefile.blargg
@@ -39,7 +39,7 @@
39#---------------------------------------------------------------------------- 39#----------------------------------------------------------------------------
40 40
41# Target file name (without extension). 41# Target file name (without extension).
42TARGET = adb_usb_lufa 42TARGET = adb_usb_blargg
43 43
44# Directory common source filess exist 44# Directory common source filess exist
45TOP_DIR = ../.. 45TOP_DIR = ../..
@@ -51,7 +51,7 @@ TARGET_DIR = .
51SRC = keymap.c \ 51SRC = keymap.c \
52 matrix.c \ 52 matrix.c \
53 led.c \ 53 led.c \
54 adb.c 54 adb_blargg.c
55 55
56CONFIG_H = config.h 56CONFIG_H = config.h
57 57
diff --git a/converter/adb_usb/Makefile.pjrc b/converter/adb_usb/Makefile.pjrc
new file mode 100644
index 000000000..c3a5d8f55
--- /dev/null
+++ b/converter/adb_usb/Makefile.pjrc
@@ -0,0 +1,63 @@
1# Target file name (without extension).
2TARGET = adb_usb_pjrc
3
4# Directory common source filess exist
5TOP_DIR = ../..
6
7# Directory keyboard dependent files exist
8TARGET_DIR = .
9
10# keyboard dependent files
11SRC = keymap.c \
12 matrix.c \
13 led.c \
14 adb.c
15
16CONFIG_H = config.h
17
18
19# MCU name, you MUST set this to match the board you are using
20# type "make clean" after changing this, so all files will be rebuilt
21#MCU = at90usb162 # Teensy 1.0
22MCU = atmega32u4 # Teensy 2.0
23#MCU = at90usb646 # Teensy++ 1.0
24#MCU = at90usb1286 # Teensy++ 2.0
25
26
27# Processor frequency.
28# Normally the first thing your program should do is set the clock prescaler,
29# so your program will run at the correct speed. You should also set this
30# variable to same clock speed. The _delay_ms() macro uses this, and many
31# examples use this variable to calculate timings. Do not add a "UL" here.
32F_CPU = 16000000
33
34
35# Boot Section Size in *bytes*
36# Teensy halfKay 512
37# Teensy++ halfKay 1024
38# Atmel DFU loader 4096
39# LUFA bootloader 4096
40# USBaspLoader 2048
41OPT_DEFS += -DBOOTLOADER_SIZE=4096
42
43
44# Build Options
45# comment out to disable the options.
46#
47BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
48MOUSEKEY_ENABLE = yes # Mouse keys(+5000)
49EXTRAKEY_ENABLE = yes # Audio control and System control(+600)
50CONSOLE_ENABLE = yes # Console for debug
51COMMAND_ENABLE = yes # Commands for debug and configuration
52#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
53#NKRO_ENABLE = yes # USB Nkey Rollover(+500)
54
55
56# Search Path
57VPATH += $(TARGET_DIR)
58VPATH += $(TOP_DIR)
59
60include $(TOP_DIR)/protocol/pjrc.mk
61include $(TOP_DIR)/protocol.mk
62include $(TOP_DIR)/common.mk
63include $(TOP_DIR)/rules.mk
diff --git a/converter/adb_usb/adb_blargg.c b/converter/adb_usb/adb_blargg.c
new file mode 100644
index 000000000..963758c53
--- /dev/null
+++ b/converter/adb_usb/adb_blargg.c
@@ -0,0 +1,216 @@
1// Bit-banged implementation without any use of interrupts.
2// Data pin must have external 1K pull-up resistor.
3// Operates data pin as open-collector output.
4
5#include "adb_blargg.h"
6
7#ifdef HAVE_CONFIG_H
8 #include "config.h"
9#endif
10
11#include <avr/io.h>
12#include <avr/interrupt.h>
13#include <util/delay.h>
14
15// Copyright 2011 Jun WAKO <wakojun@gmail.com>
16// Copyright 2013 Shay Green <gblargg@gmail.com>
17// See bottom of file for license
18
19typedef uint8_t byte;
20
21// Make loop iteration take us total, including cyc overhead of loop logic
22#define delay_loop_usec( us, cyc ) \
23 __builtin_avr_delay_cycles( (unsigned long) (F_CPU / 1e6 * (us) + 0.5) - (cyc) )
24
25#if !defined(ADB_PORT) || \
26 !defined(ADB_PIN) || \
27 !defined(ADB_DDR) || \
28 !defined(ADB_DATA_BIT)
29 #error
30#endif
31
32enum { data_mask = 1<<ADB_DATA_BIT };
33
34enum { adb_cmd_read = 0x2C };
35enum { adb_cmd_write = 0x28 };
36
37// gcc is very unreliable for inlining, so use macros
38#define data_lo() (ADB_DDR |= data_mask)
39#define data_hi() (ADB_DDR &= ~data_mask)
40#define data_in() (ADB_PIN & data_mask)
41
42static void place_bit( byte bit )
43{
44 // 100 us bit cell time
45 data_lo();
46 _delay_us( 35 );
47
48 // Difference between a 0 and 1 bit is just this 30us portion in the middle
49 if ( bit )
50 data_hi();
51 _delay_us( 30 );
52
53 data_hi();
54 _delay_us( 35 );
55}
56
57static void place_bit0( void ) { place_bit( 0 ); }
58static void place_bit1( void ) { place_bit( 1 ); }
59
60static void send_byte( byte data )
61{
62 for ( byte n = 8; n; n-- )
63 {
64 place_bit( data & 0x80 );
65 data <<= 1;
66 }
67}
68
69static void command( byte cmd )
70{
71 data_lo();
72 _delay_us( 800 );
73 place_bit1();
74 send_byte( cmd );
75 place_bit0();
76}
77
78void adb_host_init( void )
79{
80 // Always keep port output 0, then just toggle DDR to be GND or leave it floating (high).
81 ADB_DDR &= ~data_mask;
82 ADB_PORT &= ~data_mask;
83
84 #ifdef ADB_PSW_BIT
85 // Weak pull-up
86 ADB_PORT |= (1<<ADB_PSW_BIT);
87 ADB_DDR &= ~(1<<ADB_PSW_BIT);
88 #endif
89}
90
91bool adb_host_psw( void )
92{
93 #ifdef ADB_PSW_BIT
94 return (ADB_PIN & (1<<ADB_PSW_BIT)) != 0;
95 #else
96 return true;
97 #endif
98}
99
100// Waits while data == val, or until us timeout expires. Returns remaining time,
101// zero if timed out.
102static byte while_data( byte us, byte data )
103{
104 while ( data_in() == data )
105 {
106 delay_loop_usec( 1 /* us period */, 7 /* cycles loop overhead */ );
107 if ( !--us )
108 break;
109 }
110 return us;
111}
112
113static byte while_lo( byte us ) { return while_data( us, 0 ); }
114static byte while_hi( byte us ) { return while_data( us, data_mask ); }
115
116static uint16_t adb_host_talk( byte cmd )
117{
118 command( cmd );
119 _delay_us( 5 );
120 if ( !while_hi( 260 - 5 ) ) // avg 160
121 return adb_host_nothing;
122
123 // Receive start bit and 16 data bits.
124 // Doing them all in loop allows consistent error checking
125 uint16_t data = 0;
126 byte n = 17;
127 do
128 {
129 data <<= 1;
130 enum { timeout = 130 }; // maximum bit cell time
131
132 byte lo = while_lo( timeout );
133 if ( !lo )
134 goto error; // timeout
135
136 byte hi = while_hi( lo );
137 if ( !hi )
138 goto error; // timeout
139
140 if ( timeout-lo < lo-hi )
141 data |= 1;
142 else if ( n == 17 )
143 goto error; // start bit is wrong
144 }
145 while ( --n );
146
147 // duration must be split in two due to 255 limit
148 if ( !while_lo( 255 ) && !while_lo( 351 - 255 ) )
149 goto error;
150
151 if ( while_hi( 91 ) )
152 goto error;
153
154 return data;
155
156error:
157 return adb_host_error;
158}
159
160uint16_t adb_host_kbd_recv( void )
161{
162 return adb_host_talk( adb_cmd_read + 0 );
163}
164
165uint16_t adb_host_kbd_modifiers( void )
166{
167 return adb_host_talk( adb_cmd_read + 2 );
168}
169
170void adb_host_listen( byte cmd, byte data_h, byte data_l )
171{
172 command( cmd );
173 _delay_us( 200 );
174
175 place_bit1();
176 send_byte( data_h );
177 send_byte( data_l );
178 place_bit0();
179}
180
181void adb_host_kbd_led( byte led )
182{
183 adb_host_listen( adb_cmd_write + 2, 0, led & 0x07 );
184}
185
186/* This software is licensed with a Modified BSD License.
187All of this is supposed to be Free Software, Open Source, DFSG-free,
188GPL-compatible, and OK to use in both free and proprietary applications.
189Additions and corrections to this file are welcome.
190
191Redistribution and use in source and binary forms, with or without
192modification, are permitted provided that the following conditions are met:
193
194* Redistributions of source code must retain the above copyright
195 notice, this list of conditions and the following disclaimer.
196
197* Redistributions in binary form must reproduce the above copyright
198 notice, this list of conditions and the following disclaimer in
199 the documentation and/or other materials provided with the
200 distribution.
201
202* Neither the name of the copyright holders nor the names of
203 contributors may be used to endorse or promote products derived
204 from this software without specific prior written permission.
205
206THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
207AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
208IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
209ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
210LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
211CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
212SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
213INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
214CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
215ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
216POSSIBILITY OF SUCH DAMAGE. */
diff --git a/converter/adb_usb/adb_blargg.h b/converter/adb_usb/adb_blargg.h
new file mode 100644
index 000000000..2542cb549
--- /dev/null
+++ b/converter/adb_usb/adb_blargg.h
@@ -0,0 +1,38 @@
1// Basic support for ADB keyboard
2
3#ifndef ADB_BLARGG_H
4#define ADB_BLARGG_H
5
6#include <stdint.h>
7#include <stdbool.h>
8
9// Sets up ADB bus. Doesn't send anything to keyboard.
10void adb_host_init( void );
11
12// Receives key press event from keyboard.
13// 0xKKFF: one key changed state
14// 0xKKKK: two keys changed state
15enum { adb_host_nothing = 0 }; // no keys changed state
16enum { adb_host_error = 0xFFFE }; // receive error
17uint16_t adb_host_kbd_recv( void );
18
19// Current state of keyboard modifiers and a few other keys
20// Returns adb_host_nothing if keyboard didn't respond.
21// Returns adb_host_error if error receiving.
22uint16_t adb_host_kbd_modifiers( void );
23
24// Sends command and two bytes of data to keyboard
25void adb_host_listen( uint8_t cmd, uint8_t data_h, uint8_t data_l );
26
27// Sets keyboard LEDs. Note that bits are inverted here, so 1 means off, 0 means on.
28void adb_host_kbd_led( uint8_t led );
29
30// State of power switch (false = pressed), or true if unsupported
31bool adb_host_psw( void );
32
33
34// Legacy support
35#define ADB_POWER 0x7F
36#define ADB_CAPS 0x39
37
38#endif
diff --git a/converter/adb_usb/config.h b/converter/adb_usb/config.h
index 4ce27bbfe..5ce5c2215 100644
--- a/converter/adb_usb/config.h
+++ b/converter/adb_usb/config.h
@@ -44,12 +44,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
44#define USE_LEGACY_KEYMAP 44#define USE_LEGACY_KEYMAP
45 45
46 46
47/* mouse keys */
48#ifdef MOUSEKEY_ENABLE
49# define MOUSEKEY_DELAY_TIME 192
50#endif
51
52
53/* ADB port setting */ 47/* ADB port setting */
54#define ADB_PORT PORTD 48#define ADB_PORT PORTD
55#define ADB_PIN PIND 49#define ADB_PIN PIND
diff --git a/converter/adb_usb/led.c b/converter/adb_usb/led.c
index 0e162f379..1e7911f94 100644
--- a/converter/adb_usb/led.c
+++ b/converter/adb_usb/led.c
@@ -15,12 +15,15 @@ You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>. 15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/ 16*/
17 17
18#include "stdint.h" 18#include <stdint.h>
19#include <util/delay.h>
19#include "adb.h" 20#include "adb.h"
20#include "led.h" 21#include "led.h"
21 22
22 23
23void led_set(uint8_t usb_led) 24void led_set(uint8_t usb_led)
24{ 25{
26 // need a wait to send command without miss
27 _delay_ms(100);
25 adb_host_kbd_led(~usb_led); 28 adb_host_kbd_led(~usb_led);
26} 29}
diff --git a/converter/adb_usb/matrix.c b/converter/adb_usb/matrix.c
index a616d10e4..54be2b0f5 100644
--- a/converter/adb_usb/matrix.c
+++ b/converter/adb_usb/matrix.c
@@ -67,6 +67,13 @@ uint8_t matrix_cols(void)
67void matrix_init(void) 67void matrix_init(void)
68{ 68{
69 adb_host_init(); 69 adb_host_init();
70 // wait for keyboard to boot up and receive command
71 _delay_ms(1000);
72 // Enable keyboard left/right modifier distinction
73 // Addr:Keyboard(0010), Cmd:Listen(10), Register3(11)
74 // upper byte: reserved bits 0000, device address 0010
75 // lower byte: device handler 00000011
76 adb_host_listen(0x2B,0x02,0x03);
70 77
71 // initialize matrix state: all keys off 78 // initialize matrix state: all keys off
72 for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00; 79 for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
@@ -85,6 +92,7 @@ uint8_t matrix_scan(void)
85 uint8_t key0, key1; 92 uint8_t key0, key1;
86 93
87 is_modified = false; 94 is_modified = false;
95 _delay_ms(12); // delay for preventing overload of poor ADB keyboard controller
88 codes = adb_host_kbd_recv(); 96 codes = adb_host_kbd_recv();
89 key0 = codes>>8; 97 key0 = codes>>8;
90 key1 = codes&0xFF; 98 key1 = codes&0xFF;
@@ -100,9 +108,7 @@ uint8_t matrix_scan(void)
100 } else if (codes == 0xFFFF) { // power key release 108 } else if (codes == 0xFFFF) { // power key release
101 register_key(0xFF); 109 register_key(0xFF);
102 } else if (key0 == 0xFF) { // error 110 } else if (key0 == 0xFF) { // error
103 if (debug_matrix) print("adb_host_kbd_recv: ERROR(matrix cleared.)\n"); 111 xprintf("adb_host_kbd_recv: ERROR(%02X)\n", codes);
104 // clear matrix to unregister all keys
105 for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
106 return key1; 112 return key1;
107 } else { 113 } else {
108 register_key(key0); 114 register_key(key0);
diff --git a/converter/m0110_usb/Makefile b/converter/m0110_usb/Makefile
index 66eae880f..7791527e4 100644
--- a/converter/m0110_usb/Makefile
+++ b/converter/m0110_usb/Makefile
@@ -71,13 +71,14 @@ OPT_DEFS += -DBOOTLOADER_SIZE=4096
71# Build Options 71# Build Options
72# *Comment out* to disable the options. 72# *Comment out* to disable the options.
73# 73#
74#BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000) 74BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
75MOUSEKEY_ENABLE = yes # Mouse keys(+4700) 75MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
76EXTRAKEY_ENABLE = yes # Audio control and System control(+450) 76EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
77CONSOLE_ENABLE = yes # Console for debug(+400) 77CONSOLE_ENABLE = yes # Console for debug(+400)
78COMMAND_ENABLE = yes # Commands for debug and configuration 78COMMAND_ENABLE = yes # Commands for debug and configuration
79#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend 79#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
80#NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA 80#NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA
81KEYMAP_SECTION_ENABLE = yes # fixed address keymap for keymap editor
81 82
82 83
83 84
diff --git a/converter/m0110_usb/README.md b/converter/m0110_usb/README.md
index bd8bef9f2..b3fb8f7e9 100644
--- a/converter/m0110_usb/README.md
+++ b/converter/m0110_usb/README.md
@@ -1,10 +1,12 @@
1M0110/M0110A to USB keyboard converter 1M0110/M0110A to USB keyboard converter
2====================================== 2======================================
3This firmware converts the protocol of Apple Macintosh keyboard M0110/M0110A into USB. 3This firmware converts the protocol of Apple Macintosh keyboard **M0110**, **M0110A** and **M0120** into USB. Target of this project is USB AVR controller **ATmega32U4**. Using this converter you can revive these retro keyboards with modern computer.
4Target board of this project is [PJRC Teensy](http://www.pjrc.com/teensy/), though, 4
5you can use other board with USB AVR like `ATmega32U4` and `AT90USB`. 5Pics of **M0110 + M0120** and **M0110A**.
6
7![M0110+M0120](http://i.imgur.com/dyvXb2Tm.jpg)
8![M0110A](http://i.imgur.com/HuHOEoHm.jpg)
6 9
7![M0110](https://raw.github.com/tmk/tmk_keyboard/master/converter/m0110_usb/doc/m0110.jpg)
8 10
9- M0110A support was contributed by [skagon@github](https://github.com/skagon). 11- M0110A support was contributed by [skagon@github](https://github.com/skagon).
10- M0120 also is supported. keys(+ * / and ,) on M0120 are recognized as cursor keys. 12- M0120 also is supported. keys(+ * / and ,) on M0120 are recognized as cursor keys.
@@ -13,49 +15,42 @@ you can use other board with USB AVR like `ATmega32U4` and `AT90USB`.
13 15
14Update 16Update
15------ 17------
16- 2013/08 Change port for signals PF to PD 18- 2013/08: Change port for signals `PF` to `PD`
19- 2013/09: Change port again, it uses inversely `PD0` for data and `PD1` for clock line now.
17 20
18 21
19 22
20Connection 23Building Hardware
21---------- 24-----------------
22You need 4P4C plug and cable to connect Teensy or other AVR dev board into the keyboard. 25You need **4P4C** cable and **ATMega32U4** board like PJRC [Teensy]. Port of the MCU `PD1` is assigned to `CLOCK` line and `PD0` to `DATA` by default, you can change pin configuration with editing `config.h`.
23Teensy port `PD0` is assigned for `CLOCK` line and `PD1` for `DATA` by default,
24you can change pin configuration with editing *config.h*.
25 26
26You can find 4P4C plugs on telephone handset cable. Note that it is *crossover* connection 27[![M0110 Converter](http://i.imgur.com/4G2ZOegm.jpg)](http://i.imgur.com/4G2ZOeg.jpg)
27while Macintosh keyboard cable is *straight*.
28 28
29[![Conection](https://raw.github.com/tmk/tmk_keyboard/master/converter/m0110_usb/doc/teensy.jpg)] 29### 4P4C phone handset cable
30Note that original cable used with Mac is **straight** while phone handset cable is **crossover**.
30 31
31In this pic: 32<http://en.wikipedia.org/wiki/Modular_connector#4P4C>
32 33
331. `GND`(Black) 34Close-up pic of handset cable. You can see one end of plug has reverse color codes against the other. Click to enlarge.
342. `CLOCK`(Red) 35[![4P4C cable](http://i.imgur.com/3S9P1mYm.jpg?1)](http://i.imgur.com/3S9P1mY.jpg?1)
353. `DATA`(Green)
364. `+5V`(Yellow)
37 36
38Note that wire colors may vary in your cable. 37[Teensy]: http://www.pjrc.com/teensy/
39 38
40 39
41### Pinout 40### Socket Pinout
42- <http://pinouts.ru/Inputs/MacKeyboard_pinout.shtml> 41- <http://pinouts.ru/Inputs/MacKeyboard_pinout.shtml>
43- <http://en.wikipedia.org/wiki/Modular_connector#4P4C>
44 42
45![Jack fig](http://www.kbdbabel.org/conn/kbd_connector_macplus.png) 43![Jack fig](http://www.kbdbabel.org/conn/kbd_connector_macplus.png)
46 44
47 45
48### Pull-up Registor 46### Pull-up Registor
49You may need pull-up registors on signal lines(`CLOCK`, `DATA`) in particular 47You may need pull-up registors on signal lines(`CLOCK`, `DATA`) in particular when you have long or coiled cable. **1k-10k Ohm** will be OK for this purpose. In that case the converter may not read signal from keyboard correctly without pull-up resistors.
50when you have long or coiled cable. 1k-10k Ohm will be OK for this purpose.
51In some cases MCU can't read signal from keyboard correctly without pull-up resistors.
52 48
53 49
54 50
55Building Frimware 51Building Frimware
56----------------- 52-----------------
57To compile firmware you need AVR GCC. You can use [WinAVR](http://winavr.sourceforge.net/) on Windows. 53To compile firmware you need AVR GCC. You can edit *Makefile* and *config.h* to change compile options and pin configuration.
58You can edit *Makefile* and *config.h* to change compile options and pin configuration.
59 54
60 $ git clone git://github.com/tmk/tmk_keyboard.git (or download source) 55 $ git clone git://github.com/tmk/tmk_keyboard.git (or download source)
61 $ cd m0110_usb 56 $ cd m0110_usb
@@ -71,64 +66,69 @@ Keymap
71You can change keymaps by editing *keymap.c*. 66You can change keymaps by editing *keymap.c*.
72 67
73### M0110 & M0120 68### M0110 & M0120
74#### *Default* 69#### *Default Layer*
75 ,---------------------------------------------------------. ,---------------. 70 ,---------------------------------------------------------. ,---------------.
76 | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |Ctl| -|Lft|Rgt| 71 | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |Clr| -|Lft|Rgt|
77 |---------------------------------------------------------| |---------------| 72 |---------------------------------------------------------| |---------------|
78 |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| | 7| 8| 9| Up| 73 |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| | 7| 8| 9| Up|
79 |---------------------------------------------------------| |---------------| 74 |---------------------------------------------------------| |---------------|
80 |Fn0 | A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| Dn| 75 |Caps | A| S| D| F| G| H| J| K| L| ;| '|Enter | | 4| 5| 6| Dn|
81 |---------------------------------------------------------| |---------------| 76 |---------------------------------------------------------| |---------------|
82 |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shift | | 1| 2| 3| | 77 |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shift | | 1| 2| 3| |
83 `---------------------------------------------------------' |-----------|Ent| 78 `---------------------------------------------------------' |-----------|Ent|
84 |Ctl|Alt | Space |Gui |Ctl| | 0| .| | 79 |Ctl|Gui | Space |Alt |Ctl| | 0| .| |
85 `-----------------------------------------------' `---------------' 80 `-----------------------------------------------' `---------------'
86#### *HHKB/WASD Layer(WASD/IJKL)* 81
87 ,---------------------------------------------------------. ,---------------. 82- `Space` and `Enter` also work as `Fn` layer switch key when holding down.
88 |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delet| |Nlk| -|Lft|Rgt| 83
89 |---------------------------------------------------------| |---------------| 84#### *Function Layer(WASD/HHKB)*
90 |Caps |Hom| Up|PgU| | | |PgU| Up|Hom|Psc|Slk|Pau|Ins| | 7| 8| 9| Up| 85 ,---------------------------------------------------------. ,---------------.
91 |---------------------------------------------------------| |---------------| 86 |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delet| |Nlk| -|Lft|Rgt|
92 |Fn0 |Lef|Dow|Rig| | | |Lef|Dow|Rig| | |Return| | 4| 5| 6| Dn| 87 |---------------------------------------------------------| |---------------|
93 |---------------------------------------------------------| |---------------| 88 |Caps |Hom| Up|PgU| | | | |Psc|Slk|Pau|Up |Ins| \| | 7| 8| 9| Up|
94 |Shift |End| |PgD| | | |PgD| |End| |Shift | | 1| 2| 3| | 89 |---------------------------------------------------------| |---------------|
95 `---------------------------------------------------------' |-----------|Ent| 90 |Caps |Lef|Dow|Rig| | | | |Hom|PgU|Lef|Rig|Enter | | 4| 5| 6| Dn|
96 |Ctl|Alt | Space |Gui |Ctl| | 0| .| | 91 |---------------------------------------------------------| |---------------|
97 `-----------------------------------------------' `---------------' 92 |Shift |End| |PgD| | | | |End|PgD|Dow|Shift | | 1| 2| 3| |
93 `---------------------------------------------------------' |-----------|Ent|
94 |Ctl|Gui | Space |Alt |Ctl| | 0| .| |
95 `-----------------------------------------------' `---------------'
96
98 97
99### M0110A 98### M0110A
100#### *Default* 99#### *Default Layer*
101 ,---------------------------------------------------------. ,---------------. 100 ,---------------------------------------------------------. ,---------------.
102 | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |Ctl| =| /| *| 101 | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |Clr| =| /| *|
103 |---------------------------------------------------------| |---------------| 102 |---------------------------------------------------------| |---------------|
104 |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -| 103 |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -|
105 |-----------------------------------------------------' | |---------------| 104 |-----------------------------------------------------' | |---------------|
106 |Fn0 | A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +| 105 |Caps | A| S| D| F| G| H| J| K| L| ;| '|Enter | | 4| 5| 6| +|
107 |---------------------------------------------------------| |---------------| 106 |---------------------------------------------------------| |---------------|
108 |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft| Up| | 1| 2| 3| | 107 |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft| Up| | 1| 2| 3| |
109 |---------------------------------------------------------| |-----------|Ent| 108 |---------------------------------------------------------| |-----------|Ent|
110 |Alt |Gui | Space | \|Lft|Rgt| Dn| | 0| .| | 109 |Ctrl |Gui | Space | \|Lft|Rgt|Dwn| | 0| .| |
111 `---------------------------------------------------------' `---------------' 110 `---------------------------------------------------------' `---------------'
112#### *Cursor Layer(WASD/IJKL)* 111
112- `Space` and `Enter` also work as `Fn` layer switch key when holding down.
113- `Backslash(\)` also works as `Alt` when holding down.
114
115#### *Function Layer(WASD/HHKB)*
113 ,---------------------------------------------------------. ,---------------. 116 ,---------------------------------------------------------. ,---------------.
114 |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delet| |Nlk| =| /| *| 117 |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delet| |Nlk| =| /| *|
115 |---------------------------------------------------------| |---------------| 118 |---------------------------------------------------------| |---------------|
116 |Caps |Hom| Up|PgU| | | |PgU| Up|Hom|Psc|Slk|Pau| | | 7| 8| 9| -| 119 |Caps |Hom| Up|PgU| | | | |Psc|Slk|Pau|Up |Ins| | | 7| 8| 9| -|
117 |-----------------------------------------------------' | |---------------| 120 |-----------------------------------------------------' | |---------------|
118 |Fn0 |Lef|Dow|Rig| | | |Lef|Dow|Rig| | |Return| | 4| 5| 6| +| 121 |Caps |Lef|Dow|Rig| | | | |Hom|PgU|Lef|Rig|Enter | | 4| 5| 6| +|
119 |---------------------------------------------------------| |---------------| 122 |---------------------------------------------------------| |---------------|
120 |Shift |End| |PgD| | | |PgD| |End| |Shif|PgU| | 1| 2| 3| | 123 |Shift |End| |PgD| | | | |End|PgD|Dow|Shif|PgU| | 1| 2| 3| |
121 |---------------------------------------------------------| |-----------|Ent| 124 |---------------------------------------------------------| |-----------|Ent|
122 |Alt |Gui | Space |Ins|Hom|End|PgD| | 0| .| | 125 |Ctrl |Gui | Space | \|Hom|End|PgD| | 0| .| |
123 `---------------------------------------------------------' `---------------' 126 `---------------------------------------------------------' `---------------'
124 127
125 128
126 129
127Debug 130Debug
128----- 131-----
129You can use [PJRC HID listen](http://www.pjrc.com/teensy/hid_listen.html) to see debug output. 132You can use [PJRC HID listen](http://www.pjrc.com/teensy/hid_listen.html) to see debug output. The converter has some functions for debug, press `<Command>+H` simultaneously to get help.
130
131The converter has some functions for debug, press `<magickey>+H` simultaneously to get help.
132These function is totally undocumented, tentative, inconsistent and buggy.
133 133
134magickey: Shift+Option+Command(Shift+Alt+Gui or Shift+Alt+Control) 134- Command: `Shift+Option+Command`(`Shift+Alt+Gui` or `Shift+Alt+Control`)
diff --git a/converter/m0110_usb/config.h b/converter/m0110_usb/config.h
index 2f63a3a49..801bc4ebf 100644
--- a/converter/m0110_usb/config.h
+++ b/converter/m0110_usb/config.h
@@ -32,10 +32,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
32#define MATRIX_COLS 8 32#define MATRIX_COLS 8
33 33
34 34
35/* legacy keymap support */
36#define USE_LEGACY_KEYMAP
37
38
39/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ 35/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
40#define LOCKING_SUPPORT_ENABLE 36#define LOCKING_SUPPORT_ENABLE
41/* Locking resynchronize hack */ 37/* Locking resynchronize hack */
@@ -48,15 +44,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
48 keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_LALT) | MOD_BIT(KC_LCTL)) \ 44 keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_LALT) | MOD_BIT(KC_LCTL)) \
49) 45)
50 46
47/* boot magic key */
48#define BOOTMAGIC_KEY_SALT KC_FN0
49#define BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL KC_LCAP
50
51 51
52/* ports */ 52/* ports */
53#define M0110_CLOCK_PORT PORTD 53#define M0110_CLOCK_PORT PORTD
54#define M0110_CLOCK_PIN PIND 54#define M0110_CLOCK_PIN PIND
55#define M0110_CLOCK_DDR DDRD 55#define M0110_CLOCK_DDR DDRD
56#define M0110_CLOCK_BIT 0 56#define M0110_CLOCK_BIT 1
57#define M0110_DATA_PORT PORTD 57#define M0110_DATA_PORT PORTD
58#define M0110_DATA_PIN PIND 58#define M0110_DATA_PIN PIND
59#define M0110_DATA_DDR DDRD 59#define M0110_DATA_DDR DDRD
60#define M0110_DATA_BIT 1 60#define M0110_DATA_BIT 0
61 61
62#endif 62#endif
diff --git a/converter/m0110_usb/doc/m0110.jpg b/converter/m0110_usb/doc/m0110.jpg
deleted file mode 100644
index ef9a123ab..000000000
--- a/converter/m0110_usb/doc/m0110.jpg
+++ /dev/null
Binary files differ
diff --git a/converter/m0110_usb/doc/teensy.jpg b/converter/m0110_usb/doc/teensy.jpg
deleted file mode 100644
index 96e93e7e2..000000000
--- a/converter/m0110_usb/doc/teensy.jpg
+++ /dev/null
Binary files differ
diff --git a/converter/m0110_usb/keymap.c b/converter/m0110_usb/keymap.c
index 7a3bc3585..031c881b7 100644
--- a/converter/m0110_usb/keymap.c
+++ b/converter/m0110_usb/keymap.c
@@ -44,7 +44,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
44 * |---------------------------------------------------------| |---------------| 44 * |---------------------------------------------------------| |---------------|
45 * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -| 45 * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -|
46 * |-----------------------------------------------------' | |---------------| 46 * |-----------------------------------------------------' | |---------------|
47 * |Caps | A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +| 47 * |Caps | A| S| D| F| G| H| J| K| L| ;| '|Enter | | 4| 5| 6| +|
48 * |---------------------------------------------------------| |---------------| 48 * |---------------------------------------------------------| |---------------|
49 * |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| | 49 * |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| |
50 * |---------------------------------------------------------' |-----------|Ent| 50 * |---------------------------------------------------------' |-----------|Ent|
@@ -57,7 +57,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
57 * |---------------------------------------------------------| |---------------| 57 * |---------------------------------------------------------| |---------------|
58 * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| | 7| 8| 9| /| 58 * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| | 7| 8| 9| /|
59 * |---------------------------------------------------------| |---------------| 59 * |---------------------------------------------------------| |---------------|
60 * |Caps | A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| ,| 60 * |Caps | A| S| D| F| G| H| J| K| L| ;| '|Enter | | 4| 5| 6| ,|
61 * |---------------------------------------------------------| |---------------| 61 * |---------------------------------------------------------| |---------------|
62 * |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shift | | 1| 2| 3| | 62 * |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shift | | 1| 2| 3| |
63 * `---------------------------------------------------------' |-----------|Ent| 63 * `---------------------------------------------------------' |-----------|Ent|
@@ -77,7 +77,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
77 * |---------------------------------------------------------| |---------------| 77 * |---------------------------------------------------------| |---------------|
78 * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -| 78 * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -|
79 * |-----------------------------------------------------' | |---------------| 79 * |-----------------------------------------------------' | |---------------|
80 * |Caps | A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +| 80 * |Caps | A| S| D| F| G| H| J| K| L| ;| '|Enter | | 4| 5| 6| +|
81 * |---------------------------------------------------------| |---------------| 81 * |---------------------------------------------------------| |---------------|
82 * |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| | 82 * |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| |
83 * |---------------------------------------------------------| |-----------|Ent| 83 * |---------------------------------------------------------| |-----------|Ent|
@@ -108,89 +108,116 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
108 { KC_##K68, KC_NO, KC_NO, KC_NO, KC_NO, KC_##K6D, KC_NO, KC_NO }, \ 108 { KC_##K68, KC_NO, KC_NO, KC_NO, KC_NO, KC_##K6D, KC_NO, KC_NO }, \
109} 109}
110 110
111#define KEYCODE(layer, row, col) (pgm_read_byte(&keymaps[(layer)][(row)][(col)])) 111#ifdef KEYMAP_SECTION_ENABLE
112 112const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS] __attribute__ ((section (".keymap.keymaps"))) = {
113 113#else
114// Assign Fn key(0-7) to a layer to which switch with the Fn key pressed. 114static const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
115static const uint8_t PROGMEM fn_layer[] = { 115#endif
116 1, // Fn0
117 0, // Fn1
118 0, // Fn2
119 0, // Fn3
120 0, // Fn4
121 0, // Fn5
122 0, // Fn6
123 0 // Fn7
124};
125
126// Assign Fn key(0-7) to a keycode sent when release Fn key without use of the layer.
127// See layer.c for details.
128static const uint8_t PROGMEM fn_keycode[] = {
129 KC_NO, // Fn0
130 KC_NO, // Fn1
131 KC_NO, // Fn2
132 KC_NO, // Fn3
133 KC_NO, // Fn4
134 KC_NO, // Fn5
135 KC_NO, // Fn6
136 KC_NO // Fn7
137};
138
139static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
140 /* Default: 116 /* Default:
141 * ,---------------------------------------------------------. ,---------------. 117 * ,---------------------------------------------------------. ,---------------.
142 * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |Ctl| =| /| *| 118 * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |Clr| =| /| *|
143 * |---------------------------------------------------------| |---------------| 119 * |---------------------------------------------------------| |---------------|
144 * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -| 120 * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -|
145 * |-----------------------------------------------------' | |---------------| 121 * |-----------------------------------------------------' | |---------------|
146 * |Fn0 | A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +| 122 * |Caps | A| S| D| F| G| H| J| K| L| ;| '|Enter | | 4| 5| 6| +|
147 * |---------------------------------------------------------| |---------------| 123 * |---------------------------------------------------------| |---------------|
148 * |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| | 124 * |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| |
149 * |---------------------------------------------------------| |-----------|Ent| 125 * |---------------------------------------------------------| |-----------|Ent|
150 * |Ctl |Alt | Space |Gui| \|Lft|Rgt|Dn | | 0| .| | 126 * |Ctl |Gui | Space |Alt| \|Lft|Rgt|Dn | | 0| .| |
151 * `---------------------------------------------------------' `---------------' 127 * `---------------------------------------------------------' `---------------'
152 */ 128 */
153 KEYMAP( 129 [0] = KEYMAP(
154 GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, LCTL,EQL, PSLS,PAST, 130 GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, CLR, EQL, PSLS,PAST,
155 TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, P7, P8, P9, PMNS, 131 TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, P7, P8, P9, PMNS,
156 FN0, A, S, D, F, G, H, J, K, L, SCLN,QUOT, ENT, P4, P5, P6, PPLS, 132 LCAP,A, S, D, F, G, H, J, K, L, SCLN,QUOT, FN15, P4, P5, P6, PPLS,
157 LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH, UP, P1, P2, P3, PENT, 133 LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH, UP, P1, P2, P3, PENT,
158 LCTL,LALT, SPC, LGUI,BSLS,LEFT,RGHT,DOWN, P0, PDOT 134 LCTL,LGUI, FN16, LALT,FN31,LEFT,RGHT,DOWN, P0, PDOT
159 ), 135 ),
160 /* Cursor Layer(WASD, IJKL) 136 /* Cursor Layer(WASD, IJKL)
161 * ,---------------------------------------------------------. ,---------------. 137 * ,---------------------------------------------------------. ,---------------.
162 * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delet| |Nlk| =| /| *| 138 * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delet| |Nlk| =| /| *|
163 * |---------------------------------------------------------| |---------------| 139 * |---------------------------------------------------------| |---------------|
164 * |Caps |Hom| Up|PgU| | | |PgU| Up|Hom|Psc|Slk|Pau| | | 7| 8| 9| -| 140 * |Caps |Hom| Up|PgU| | | | |Psc|Slk|Pau|Up |Ins| | | 7| 8| 9| -|
165 * |-----------------------------------------------------' | |---------------| 141 * |-----------------------------------------------------' | |---------------|
166 * |Fn0 |Lef|Dow|Rig| | | |Lef|Dow|Rig| | |Return| | 4| 5| 6| +| 142 * |Caps |Lef|Dow|Rig| | | | |Hom|PgU|Lef|Rig|Enter | | 4| 5| 6| +|
167 * |---------------------------------------------------------| |---------------| 143 * |---------------------------------------------------------| |---------------|
168 * |Shift |End| |PgD| | | |PgD| |End| |Shif|PgU| | 1| 2| 3| | 144 * |Shift |End| |PgD| | | | |End|PgD|Dow|Shif|PgU| | 1| 2| 3| |
169 * |---------------------------------------------------------| |-----------|Ent| 145 * |---------------------------------------------------------| |-----------|Ent|
170 * |Ctl |Alt | Space |Gui |Ins|Hom|End|PgD| | 0| .| | 146 * |Ctl |Gui | Space |Alt | \|Hom|End|PgD| | 0| .| |
171 * `---------------------------------------------------------' `---------------' 147 * `---------------------------------------------------------' `---------------'
172 */ 148 */
173 KEYMAP( 149 [3] = KEYMAP(
150 ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, NLCK,EQL, PSLS,PAST,
151 CAPS,HOME,UP, PGUP,NO, NO, NO, NO, PSCR,SLCK,PAUS,UP, INS, P7, P8, P9, PMNS,
152 LCAP,LEFT,DOWN,RGHT,NO, NO, NO, NO, HOME,PGUP,LEFT,RGHT, FN15, P4, P5, P6, PPLS,
153 LSFT,END, NO, PGDN,NO, NO, NO, NO, END, PGDN,DOWN, PGUP, P1, P2, P3, PENT,
154 LCTL,LGUI, FN16, LALT,FN31,HOME,END, PGDN, P0, PDOT
155 ),
156 [4] = KEYMAP(
174 ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, NLCK,EQL, PSLS,PAST, 157 ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, NLCK,EQL, PSLS,PAST,
175 CAPS,HOME,UP, PGUP,NO, NO, NO, PGUP,UP, HOME,PSCR,SLCK,PAUS, P7, P8, P9, PMNS, 158 CAPS,HOME,UP, PGUP,NO, NO, NO, NO, PSCR,SLCK,PAUS,UP, INS, P7, P8, P9, PMNS,
176 FN0, LEFT,DOWN,RGHT,NO, NO, NO, LEFT,DOWN,RGHT,NO, NO, ENT, P4, P5, P6, PPLS, 159 LCAP,LEFT,DOWN,RGHT,NO, NO, NO, NO, HOME,PGUP,LEFT,RGHT, FN15, P4, P5, P6, PPLS,
177 LSFT,END, NO, PGDN,NO, NO, NO, PGDN,NO, END, NO, PGUP, P1, P2, P3, PENT, 160 LSFT,END, NO, PGDN,NO, NO, NO, NO, END, PGDN,DOWN, PGUP, P1, P2, P3, PENT,
178 LCTL,LALT, SPC, LGUI,INS, HOME,END, PGDN, P0, PDOT 161 LCTL,LGUI, FN16, LALT,FN31,HOME,END, PGDN, P0, PDOT
179 ), 162 ),
163 [7] = {},
164};
165
166
167/*
168 * Fn action definition
169 */
170#ifdef KEYMAP_SECTION_ENABLE
171const uint16_t fn_actions[] __attribute__ ((section (".keymap.fn_actions"))) = {
172#else
173static const uint16_t fn_actions[] PROGMEM = {
174#endif
175 [0] = ACTION_LAYER_MOMENTARY(1),
176 [1] = ACTION_LAYER_MOMENTARY(2),
177 [2] = ACTION_LAYER_MOMENTARY(3),
178 [3] = ACTION_LAYER_MOMENTARY(4),
179 [4] = ACTION_LAYER_MOMENTARY(5),
180 [5] = ACTION_LAYER_MOMENTARY(6),
181 [6] = ACTION_LAYER_MOMENTARY(7),
182 [7] = ACTION_LAYER_TOGGLE(1),
183 [8] = ACTION_LAYER_TOGGLE(2),
184 [9] = ACTION_LAYER_TOGGLE(3),
185 [10] = ACTION_LAYER_TAP_TOGGLE(1),
186 [11] = ACTION_LAYER_TAP_TOGGLE(2),
187 [12] = ACTION_LAYER_TAP_TOGGLE(3),
188 [13] = ACTION_LAYER_TAP_KEY(1, KC_F),
189 [14] = ACTION_LAYER_TAP_KEY(2, KC_J),
190 [15] = ACTION_LAYER_TAP_KEY(3, KC_ENTER),
191 [16] = ACTION_LAYER_TAP_KEY(4, KC_SPACE),
192 [17] = ACTION_LAYER_TAP_KEY(5, KC_SCOLON),
193 [18] = ACTION_LAYER_TAP_KEY(6, KC_QUOTE),
194 [19] = ACTION_LAYER_TAP_KEY(7, KC_SLASH),
195 [20] = ACTION_MODS_TAP_KEY(MOD_LSFT, KC_SPACE),
196 [21] = ACTION_MODS_TAP_KEY(MOD_LCTL, KC_SPACE),
197 [22] = ACTION_MODS_TAP_KEY(MOD_RCTL, KC_QUOTE),
198 [23] = ACTION_MODS_TAP_KEY(MOD_RCTL, KC_ENTER),
199 [24] = ACTION_MODS_TAP_KEY(MOD_LCTL, KC_ESC),
200 [25] = ACTION_MODS_TAP_KEY(MOD_LCTL, KC_BSPACE),
201 [26] = ACTION_MODS_ONESHOT(MOD_LCTL),
202 [27] = ACTION_MODS_TAP_KEY(MOD_LSFT, KC_ESC),
203 [28] = ACTION_MODS_TAP_KEY(MOD_LSFT, KC_BSPACE),
204 [29] = ACTION_MODS_ONESHOT(MOD_LSFT),
205 [30] = ACTION_MODS_TAP_KEY(MOD_RSFT, KC_GRAVE),
206 [31] = ACTION_MODS_TAP_KEY(MOD_RALT, KC_BSLASH),
180}; 207};
181 208
182 209
183uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col)
184{
185 return KEYCODE(layer, row, col);
186}
187 210
188uint8_t keymap_fn_layer(uint8_t index) 211/* translates key to keycode */
212uint8_t keymap_key_to_keycode(uint8_t layer, key_t key)
189{ 213{
190 return pgm_read_byte(&fn_layer[index]); 214 return pgm_read_byte(&keymaps[(layer)][(key.row)][(key.col)]);
191} 215}
192 216
193uint8_t keymap_fn_keycode(uint8_t index) 217/* translates Fn index to action */
218action_t keymap_fn_to_action(uint8_t keycode)
194{ 219{
195 return pgm_read_byte(&fn_keycode[index]); 220 action_t action;
221 action.code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]);
222 return action;
196} 223}
diff --git a/converter/news_usb/config_pjrc.h b/converter/news_usb/config_pjrc.h
index 92751d1ee..adce014c9 100644
--- a/converter/news_usb/config_pjrc.h
+++ b/converter/news_usb/config_pjrc.h
@@ -42,12 +42,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
42) 42)
43 43
44 44
45/* mouse keys */
46#ifdef MOUSEKEY_ENABLE
47# define MOUSEKEY_DELAY_TIME 255
48#endif
49
50
51/* Asynchronous USART 45/* Asynchronous USART
52 * 8-data bit, non parity, 1-stop bit, no flow control 46 * 8-data bit, non parity, 1-stop bit, no flow control
53 */ 47 */
diff --git a/converter/ps2_usb/config.h b/converter/ps2_usb/config.h
index 4a2d1fc47..51cd271d7 100644
--- a/converter/ps2_usb/config.h
+++ b/converter/ps2_usb/config.h
@@ -39,10 +39,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
39) 39)
40 40
41 41
42/* mouse keys */ 42/* legacy keymap support */
43#ifdef MOUSEKEY_ENABLE 43#define USE_LEGACY_KEYMAP
44# define MOUSEKEY_DELAY_TIME 255
45#endif
46 44
47 45
48#ifdef PS2_USE_USART 46#ifdef PS2_USE_USART
diff --git a/doc/keymap.md b/doc/keymap.md
index e4728b507..11e80a9c3 100644
--- a/doc/keymap.md
+++ b/doc/keymap.md
@@ -227,7 +227,7 @@ You can define these actions on *'A'* key and *'left shift'* modifier with:
227 ACTION_KEY(KC_A) 227 ACTION_KEY(KC_A)
228 ACTION_KEY(KC_LSFT) 228 ACTION_KEY(KC_LSFT)
229 229
230#### 2.1.2 Key with modifiers 230#### 2.1.2 Modified key
231This action is comprised of strokes of modifiers and a key. `Macro` action is needed if you want more complex key strokes. 231This action is comprised of strokes of modifiers and a key. `Macro` action is needed if you want more complex key strokes.
232 232
233Say you want to assign a key to `Shift + 1` to get charactor *'!'* or `Alt + Tab` to switch application windows. 233Say you want to assign a key to `Shift + 1` to get charactor *'!'* or `Alt + Tab` to switch application windows.
@@ -244,7 +244,7 @@ Registers multiple modifiers with pressing a key. To specify multiple modifiers
244 244
245 ACTION_MODS(MOD_ALT | MOD_LSFT) 245 ACTION_MODS(MOD_ALT | MOD_LSFT)
246 246
247#### 2.1.3 Modifier with tap key 247#### 2.1.3 Modifier with Tap key([Dual role][dual_role])
248Works as a modifier key while holding, but registers a key on tap(press and release quickly). 248Works as a modifier key while holding, but registers a key on tap(press and release quickly).
249 249
250 250
@@ -497,7 +497,7 @@ Number of taps can be configured with `TAPPING_TOGGLE` in `config.h`, `5` by def
497Tapping is to press and release a key quickly. Tapping speed is determined with setting of `TAPPING_TERM`, which can be defined in `config.h`, 200ms by default. 497Tapping is to press and release a key quickly. Tapping speed is determined with setting of `TAPPING_TERM`, which can be defined in `config.h`, 200ms by default.
498 498
499### 4.1 Tap Key 499### 4.1 Tap Key
500This is a feature to assign normal key action and modifier including layer switching to just same one physical key. This is a kind of [Dual role modifier][dual_role]. It works as modifier when holding the key but registers normal key when tapping. 500This is a feature to assign normal key action and modifier including layer switching to just same one physical key. This is a kind of [Dual role key][dual_role]. It works as modifier when holding the key but registers normal key when tapping.
501 501
502Modifier with tap key: 502Modifier with tap key:
503 503
@@ -507,7 +507,7 @@ Layer switching with tap key:
507 507
508 ACTION_LAYER_TAP_KEY(2, KC_SCLN) 508 ACTION_LAYER_TAP_KEY(2, KC_SCLN)
509 509
510[dual_role]: http://en.wikipedia.org/wiki/Modifier_key#Dual-role_modifier_keys 510[dual_role]: http://en.wikipedia.org/wiki/Modifier_key#Dual-role_keys
511 511
512 512
513### 4.2 Tap Toggle 513### 4.2 Tap Toggle
@@ -516,13 +516,14 @@ This is a feature to assign both toggle layer and momentary switch layer action
516 ACTION_LAYER_TAP_TOGGLE(1) 516 ACTION_LAYER_TAP_TOGGLE(1)
517 517
518 518
519### 4.3 One Shot Modifier 519### 4.3 Oneshot Modifier
520This adds oneshot feature to modifier key. 'One Shot Modifier' is one time modifier which has effect only on following just one key. 520This runs onetime effect swhich modify only on just one following key. It works as normal modifier key when holding down while oneshot modifier when tapping.
521It works as normal modifier key when holding but oneshot modifier when tapping.
522 521
523 ACTION_MODS_ONESHOT(MOD_LSFT) 522 ACTION_MODS_ONESHOT(MOD_LSFT)
524 523
525Say you want to type 'The', you have to push and hold Shift before type 't' then release Shift before type 'h' and 'e' or you'll get 'THe'. With One Shot Modifier you can tap Shift then type 't', 'h' and 'e' normally, you don't need to holding Shift key properly here. 524Say you want to type 'The', you have to push and hold Shift key before type 't' then release it before type 'h' and 'e', otherwise you'll get 'THe' or 'the' unintentionally. With Oneshot Modifier you can tap Shift then type 't', 'h' and 'e' normally, you don't need to holding Shift key properly here. This mean you can realease Shift before 't' is pressed down.
525
526Oneshot effect is cancel unless following key is pressed down within `ONESHOT_TIMEOUT` of `config.h`. No timeout when it is `0` or not defined.
526 527
527 528
528 529
@@ -571,5 +572,5 @@ Top layer has higher precedence than lower layers.
571is to press and release a key quickly. 572is to press and release a key quickly.
572### Fn key 573### Fn key
573is key which executes a special action like layer switching, mouse key, macro or etc. 574is key which executes a special action like layer switching, mouse key, macro or etc.
574### dual role modifier 575### dual role key
575<http://en.wikipedia.org/wiki/Modifier_key#Dual-role_modifier_keys> 576<http://en.wikipedia.org/wiki/Modifier_key#Dual-role_keys>
diff --git a/keyboard/IIgs/config.h b/keyboard/IIgs/config.h
index 0039cb48b..bc8bf75f9 100644
--- a/keyboard/IIgs/config.h
+++ b/keyboard/IIgs/config.h
@@ -56,10 +56,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
56#define LAYER_SEND_FN_TERM 300 56#define LAYER_SEND_FN_TERM 300
57 57
58 58
59/* mouse keys */ 59/* legacy keymap support */
60#ifdef MOUSEKEY_ENABLE 60#define USE_LEGACY_KEYMAP
61# define MOUSEKEY_DELAY_TIME 192
62#endif
63 61
64 62
65#endif 63#endif
diff --git a/keyboard/hhkb/Makefile b/keyboard/hhkb/Makefile
index 1ef0a0187..94078702c 100644
--- a/keyboard/hhkb/Makefile
+++ b/keyboard/hhkb/Makefile
@@ -111,12 +111,13 @@ OPT_DEFS += -DBOOTLOADER_SIZE=4096
111# Build Options 111# Build Options
112# comment out to disable the options. 112# comment out to disable the options.
113# 113#
114BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration 114BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration
115MOUSEKEY_ENABLE = yes # Mouse keys 115MOUSEKEY_ENABLE = yes # Mouse keys
116EXTRAKEY_ENABLE = yes # Audio control and System control 116EXTRAKEY_ENABLE = yes # Audio control and System control
117CONSOLE_ENABLE = yes # Console for debug 117CONSOLE_ENABLE = yes # Console for debug
118COMMAND_ENABLE = yes # Commands for debug and configuration 118COMMAND_ENABLE = yes # Commands for debug and configuration
119NKRO_ENABLE = yes # USB Nkey Rollover 119NKRO_ENABLE = yes # USB Nkey Rollover
120KEYMAP_SECTION_ENABLE = yes # fixed address keymap for keymap editor
120 121
121 122
122# Search Path 123# Search Path
@@ -127,5 +128,8 @@ include $(TOP_DIR)/protocol/lufa.mk
127include $(TOP_DIR)/common.mk 128include $(TOP_DIR)/common.mk
128include $(TOP_DIR)/rules.mk 129include $(TOP_DIR)/rules.mk
129 130
130debug-on: EXTRAFLAGS += -DDEBUG 131debug-on: EXTRAFLAGS += -DDEBUG -DDEBUG_ACTION
131debug-on: all 132debug-on: all
133
134debug-off: EXTRAFLAGS += -DNO_DEBUG -DNO_PRINT
135debug-off: all
diff --git a/keyboard/hhkb/config.h b/keyboard/hhkb/config.h
index 83a911bea..a8f76ae6b 100644
--- a/keyboard/hhkb/config.h
+++ b/keyboard/hhkb/config.h
@@ -40,7 +40,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
40#define TAPPING_TERM 300 40#define TAPPING_TERM 300
41/* tap count needed for toggling a feature */ 41/* tap count needed for toggling a feature */
42#define TAPPING_TOGGLE 5 42#define TAPPING_TOGGLE 5
43 43/* Oneshot timeout(ms) */
44#define ONESHOT_TIMEOUT 300
44 45
45/* Boot Magic salt key: Space */ 46/* Boot Magic salt key: Space */
46#define BOOTMAGIC_KEY_SALT KC_FN6 47#define BOOTMAGIC_KEY_SALT KC_FN6
diff --git a/keyboard/hhkb/config_iwrap.h b/keyboard/hhkb/config_iwrap.h
index 80a608882..747c75513 100644
--- a/keyboard/hhkb/config_iwrap.h
+++ b/keyboard/hhkb/config_iwrap.h
@@ -34,11 +34,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
34/* key combination for command */ 34/* key combination for command */
35#define IS_COMMAND() (keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) 35#define IS_COMMAND() (keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)))
36 36
37/* mouse keys */
38#ifdef MOUSEKEY_ENABLE
39# define MOUSEKEY_DELAY_TIME 255
40#endif
41
42/* pins for Software UART */ 37/* pins for Software UART */
43#define SUART_IN_PIN PINC 38#define SUART_IN_PIN PINC
44#define SUART_IN_BIT 5 39#define SUART_IN_BIT 5
diff --git a/keyboard/hhkb/config_vusb.h b/keyboard/hhkb/config_vusb.h
index 37d3e4f22..44f7acd6c 100644
--- a/keyboard/hhkb/config_vusb.h
+++ b/keyboard/hhkb/config_vusb.h
@@ -35,10 +35,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
35/* key combination for command */ 35/* key combination for command */
36#define IS_COMMAND() (keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) 36#define IS_COMMAND() (keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)))
37 37
38/* mouse keys */
39#ifdef MOUSEKEY_ENABLE
40# define MOUSEKEY_DELAY_TIME 100
41#endif
42
43
44#endif 38#endif
diff --git a/keyboard/hhkb/keymap.c b/keyboard/hhkb/keymap.c
index faa62dd7e..f2c6caf48 100644
--- a/keyboard/hhkb/keymap.c
+++ b/keyboard/hhkb/keymap.c
@@ -48,8 +48,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
48 { KC_##K70, KC_##K71, KC_##K72, KC_##K73, KC_##K74, KC_##K75, KC_##K76, KC_NO } \ 48 { KC_##K70, KC_##K71, KC_##K72, KC_##K73, KC_##K74, KC_##K75, KC_##K76, KC_NO } \
49} 49}
50 50
51 51#ifdef KEYMAP_SECTION_ENABLE
52static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { 52const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS] __attribute__ ((section (".keymap.keymaps"))) = {
53#else
54static const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
55#endif
53 /* Layer 0: Default Layer 56 /* Layer 0: Default Layer
54 * ,-----------------------------------------------------------. 57 * ,-----------------------------------------------------------.
55 * |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \| `| 58 * |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \| `|
@@ -186,7 +189,11 @@ enum macro_id {
186/* 189/*
187 * Fn action definition 190 * Fn action definition
188 */ 191 */
189static const uint16_t PROGMEM fn_actions[] = { 192#ifdef KEYMAP_SECTION_ENABLE
193const uint16_t fn_actions[] __attribute__ ((section (".keymap.fn_actions"))) = {
194#else
195static const uint16_t fn_actions[] PROGMEM = {
196#endif
190 [0] = ACTION_DEFAULT_LAYER_SET(0), // Default layer(not used) 197 [0] = ACTION_DEFAULT_LAYER_SET(0), // Default layer(not used)
191 [1] = ACTION_LAYER_TAP_TOGGLE(1), // HHKB layer(toggle with 5 taps) 198 [1] = ACTION_LAYER_TAP_TOGGLE(1), // HHKB layer(toggle with 5 taps)
192 [2] = ACTION_LAYER_TAP_KEY(2, KC_SLASH), // Cursor layer with Slash* 199 [2] = ACTION_LAYER_TAP_KEY(2, KC_SLASH), // Cursor layer with Slash*
@@ -310,10 +317,6 @@ uint8_t keymap_key_to_keycode(uint8_t layer, key_t key)
310action_t keymap_fn_to_action(uint8_t keycode) 317action_t keymap_fn_to_action(uint8_t keycode)
311{ 318{
312 action_t action; 319 action_t action;
313 if (FN_INDEX(keycode) < sizeof(fn_actions) / sizeof(fn_actions[0])) { 320 action.code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]);
314 action.code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]);
315 } else {
316 action.code = ACTION_NO;
317 }
318 return action; 321 return action;
319} 322}
diff --git a/ldscript_keymap_avr5.x b/ldscript_keymap_avr5.x
new file mode 100644
index 000000000..c09693e51
--- /dev/null
+++ b/ldscript_keymap_avr5.x
@@ -0,0 +1,268 @@
1/*
2 * linker script for configurable keymap
3 *
4 * This adds keymap section which places keymap at fixed address and
5 * is based on binutils-avr ldscripts(/usr/lib/ldscripts/avr5.x).
6 */
7OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
8OUTPUT_ARCH(avr:5)
9MEMORY
10{
11 /* With keymap section
12 *
13 * Flash Map of ATMega32U4(32KB)
14 * +------------+ 0x0000
15 * | .vectors |
16 * | .progmem |
17 * | .init0-9 | > text region
18 * | .text |
19 * | .fini9-0 |
20 * | |
21 * |------------| _etext
22 * | .data |
23 * | .bss | > data region
24 * | .noinit |
25 * | |
26 * |------------| 0x6800
27 * | .keymap | > keymap region(2KB)
28 * |------------| 0x7000
29 * | bootloader | 4KB
30 * +------------+ 0x7FFF
31 */
32 text (rx) : ORIGIN = 0, LENGTH = 128K
33 keymap (rw!x) : ORIGIN = 0x6800, LENGTH = 2K
34 data (rw!x) : ORIGIN = 0x800060, LENGTH = 0xffa0
35 eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 64K
36 fuse (rw!x) : ORIGIN = 0x820000, LENGTH = 1K
37 lock (rw!x) : ORIGIN = 0x830000, LENGTH = 1K
38 signature (rw!x) : ORIGIN = 0x840000, LENGTH = 1K
39}
40SECTIONS
41{
42 /* Read-only sections, merged into text segment: */
43 .hash : { *(.hash) }
44 .dynsym : { *(.dynsym) }
45 .dynstr : { *(.dynstr) }
46 .gnu.version : { *(.gnu.version) }
47 .gnu.version_d : { *(.gnu.version_d) }
48 .gnu.version_r : { *(.gnu.version_r) }
49 .rel.init : { *(.rel.init) }
50 .rela.init : { *(.rela.init) }
51 .rel.text :
52 {
53 *(.rel.text)
54 *(.rel.text.*)
55 *(.rel.gnu.linkonce.t*)
56 }
57 .rela.text :
58 {
59 *(.rela.text)
60 *(.rela.text.*)
61 *(.rela.gnu.linkonce.t*)
62 }
63 .rel.fini : { *(.rel.fini) }
64 .rela.fini : { *(.rela.fini) }
65 .rel.rodata :
66 {
67 *(.rel.rodata)
68 *(.rel.rodata.*)
69 *(.rel.gnu.linkonce.r*)
70 }
71 .rela.rodata :
72 {
73 *(.rela.rodata)
74 *(.rela.rodata.*)
75 *(.rela.gnu.linkonce.r*)
76 }
77 .rel.data :
78 {
79 *(.rel.data)
80 *(.rel.data.*)
81 *(.rel.gnu.linkonce.d*)
82 }
83 .rela.data :
84 {
85 *(.rela.data)
86 *(.rela.data.*)
87 *(.rela.gnu.linkonce.d*)
88 }
89 .rel.ctors : { *(.rel.ctors) }
90 .rela.ctors : { *(.rela.ctors) }
91 .rel.dtors : { *(.rel.dtors) }
92 .rela.dtors : { *(.rela.dtors) }
93 .rel.got : { *(.rel.got) }
94 .rela.got : { *(.rela.got) }
95 .rel.bss : { *(.rel.bss) }
96 .rela.bss : { *(.rela.bss) }
97 .rel.plt : { *(.rel.plt) }
98 .rela.plt : { *(.rela.plt) }
99 /* Internal text space or external memory. */
100 .text :
101 {
102 *(.vectors)
103 KEEP(*(.vectors))
104 /* For data that needs to reside in the lower 64k of progmem. */
105 *(.progmem.gcc*)
106 *(.progmem*)
107 . = ALIGN(2);
108 __trampolines_start = . ;
109 /* The jump trampolines for the 16-bit limited relocs will reside here. */
110 *(.trampolines)
111 *(.trampolines*)
112 __trampolines_end = . ;
113 /* For future tablejump instruction arrays for 3 byte pc devices.
114 We don't relax jump/call instructions within these sections. */
115 *(.jumptables)
116 *(.jumptables*)
117 /* For code that needs to reside in the lower 128k progmem. */
118 *(.lowtext)
119 *(.lowtext*)
120 __ctors_start = . ;
121 *(.ctors)
122 __ctors_end = . ;
123 __dtors_start = . ;
124 *(.dtors)
125 __dtors_end = . ;
126 KEEP(SORT(*)(.ctors))
127 KEEP(SORT(*)(.dtors))
128 /* From this point on, we don't bother about wether the insns are
129 below or above the 16 bits boundary. */
130 *(.init0) /* Start here after reset. */
131 KEEP (*(.init0))
132 *(.init1)
133 KEEP (*(.init1))
134 *(.init2) /* Clear __zero_reg__, set up stack pointer. */
135 KEEP (*(.init2))
136 *(.init3)
137 KEEP (*(.init3))
138 *(.init4) /* Initialize data and BSS. */
139 KEEP (*(.init4))
140 *(.init5)
141 KEEP (*(.init5))
142 *(.init6) /* C++ constructors. */
143 KEEP (*(.init6))
144 *(.init7)
145 KEEP (*(.init7))
146 *(.init8)
147 KEEP (*(.init8))
148 *(.init9) /* Call main(). */
149 KEEP (*(.init9))
150 *(.text)
151 . = ALIGN(2);
152 *(.text.*)
153 . = ALIGN(2);
154 *(.fini9) /* _exit() starts here. */
155 KEEP (*(.fini9))
156 *(.fini8)
157 KEEP (*(.fini8))
158 *(.fini7)
159 KEEP (*(.fini7))
160 *(.fini6) /* C++ destructors. */
161 KEEP (*(.fini6))
162 *(.fini5)
163 KEEP (*(.fini5))
164 *(.fini4)
165 KEEP (*(.fini4))
166 *(.fini3)
167 KEEP (*(.fini3))
168 *(.fini2)
169 KEEP (*(.fini2))
170 *(.fini1)
171 KEEP (*(.fini1))
172 *(.fini0) /* Infinite loop after program termination. */
173 KEEP (*(.fini0))
174 _etext = . ;
175 } > text
176 .data : AT (ADDR (.text) + SIZEOF (.text))
177 {
178 PROVIDE (__data_start = .) ;
179 *(.data)
180 *(.data*)
181 *(.rodata) /* We need to include .rodata here if gcc is used */
182 *(.rodata*) /* with -fdata-sections. */
183 *(.gnu.linkonce.d*)
184 . = ALIGN(2);
185 _edata = . ;
186 PROVIDE (__data_end = .) ;
187 } > data
188 .bss : AT (ADDR (.bss))
189 {
190 PROVIDE (__bss_start = .) ;
191 *(.bss)
192 *(.bss*)
193 *(COMMON)
194 PROVIDE (__bss_end = .) ;
195 } > data
196 __data_load_start = LOADADDR(.data);
197 __data_load_end = __data_load_start + SIZEOF(.data);
198 /* Global data not cleared after reset. */
199 .noinit :
200 {
201 PROVIDE (__noinit_start = .) ;
202 *(.noinit*)
203 PROVIDE (__noinit_end = .) ;
204 _end = . ;
205 PROVIDE (__heap_start = .) ;
206 } > data
207 /* keymap region is located at end of flash
208 * .fn_actions Fn actions definitions
209 * .keymaps Mapping layers
210 */
211 .keymap :
212 {
213 PROVIDE(__keymap_start = .) ;
214 *(.keymap.fn_actions) /* 32*actions = 64bytes */
215 . = ALIGN(0x40);
216 *(.keymap.keymaps) /* rest of .keymap section */
217 *(.keymap*)
218 /* . = ALIGN(0x800); */ /* keymap section takes 2KB- */
219 } > keymap = 0x00 /* zero fill */
220 .eeprom :
221 {
222 *(.eeprom*)
223 __eeprom_end = . ;
224 } > eeprom
225 .fuse :
226 {
227 KEEP(*(.fuse))
228 KEEP(*(.lfuse))
229 KEEP(*(.hfuse))
230 KEEP(*(.efuse))
231 } > fuse
232 .lock :
233 {
234 KEEP(*(.lock*))
235 } > lock
236 .signature :
237 {
238 KEEP(*(.signature*))
239 } > signature
240 /* Stabs debugging sections. */
241 .stab 0 : { *(.stab) }
242 .stabstr 0 : { *(.stabstr) }
243 .stab.excl 0 : { *(.stab.excl) }
244 .stab.exclstr 0 : { *(.stab.exclstr) }
245 .stab.index 0 : { *(.stab.index) }
246 .stab.indexstr 0 : { *(.stab.indexstr) }
247 .comment 0 : { *(.comment) }
248 /* DWARF debug sections.
249 Symbols in the DWARF debugging sections are relative to the beginning
250 of the section so we begin them at 0. */
251 /* DWARF 1 */
252 .debug 0 : { *(.debug) }
253 .line 0 : { *(.line) }
254 /* GNU DWARF 1 extensions */
255 .debug_srcinfo 0 : { *(.debug_srcinfo) }
256 .debug_sfnames 0 : { *(.debug_sfnames) }
257 /* DWARF 1.1 and DWARF 2 */
258 .debug_aranges 0 : { *(.debug_aranges) }
259 .debug_pubnames 0 : { *(.debug_pubnames) }
260 /* DWARF 2 */
261 .debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) }
262 .debug_abbrev 0 : { *(.debug_abbrev) }
263 .debug_line 0 : { *(.debug_line) }
264 .debug_frame 0 : { *(.debug_frame) }
265 .debug_str 0 : { *(.debug_str) }
266 .debug_loc 0 : { *(.debug_loc) }
267 .debug_macinfo 0 : { *(.debug_macinfo) }
268}
diff --git a/protocol/adb.c b/protocol/adb.c
index 2baad3234..750f4b965 100644
--- a/protocol/adb.c
+++ b/protocol/adb.c
@@ -1,5 +1,6 @@
1/* 1/*
2Copyright 2011 Jun WAKO <wakojun@gmail.com> 2Copyright 2011 Jun WAKO <wakojun@gmail.com>
3Copyright 2013 Shay Green <gblargg@gmail.com>
3 4
4This software is licensed with a Modified BSD License. 5This software is licensed with a Modified BSD License.
5All of this is supposed to be Free Software, Open Source, DFSG-free, 6All of this is supposed to be Free Software, Open Source, DFSG-free,
@@ -40,11 +41,14 @@ POSSIBILITY OF SUCH DAMAGE.
40#include <avr/io.h> 41#include <avr/io.h>
41#include <avr/interrupt.h> 42#include <avr/interrupt.h>
42#include "adb.h" 43#include "adb.h"
44#include "debug.h"
43 45
44 46
45static inline void data_lo(void); 47// GCC doesn't inline functions normally
46static inline void data_hi(void); 48#define data_lo() (ADB_DDR |= (1<<ADB_DATA_BIT))
47static inline bool data_in(void); 49#define data_hi() (ADB_DDR &= ~(1<<ADB_DATA_BIT))
50#define data_in() (ADB_PIN & (1<<ADB_DATA_BIT))
51
48#ifdef ADB_PSW_BIT 52#ifdef ADB_PSW_BIT
49static inline void psw_lo(void); 53static inline void psw_lo(void);
50static inline void psw_hi(void); 54static inline void psw_hi(void);
@@ -55,24 +59,17 @@ static inline void attention(void);
55static inline void place_bit0(void); 59static inline void place_bit0(void);
56static inline void place_bit1(void); 60static inline void place_bit1(void);
57static inline void send_byte(uint8_t data); 61static inline void send_byte(uint8_t data);
58static inline bool read_bit(void); 62static inline uint16_t wait_data_lo(uint16_t us);
59static inline uint8_t read_byte(void); 63static inline uint16_t wait_data_hi(uint16_t us);
60static inline uint8_t wait_data_lo(uint16_t us);
61static inline uint8_t wait_data_hi(uint8_t us);
62 64
63 65
64void adb_host_init(void) 66void adb_host_init(void)
65{ 67{
68 ADB_PORT &= ~(1<<ADB_DATA_BIT);
66 data_hi(); 69 data_hi();
67#ifdef ADB_PSW_BIT 70#ifdef ADB_PSW_BIT
68 psw_hi(); 71 psw_hi();
69#endif 72#endif
70
71 // Enable keyboard left/right modifier distinction
72 // Addr:Keyboard(0010), Cmd:Listen(10), Register3(11)
73 // upper byte: reserved bits 0000, device address 0010
74 // lower byte: device handler 00000011
75 adb_host_listen(0x2B,0x02,0x03);
76} 73}
77 74
78#ifdef ADB_PSW_BIT 75#ifdef ADB_PSW_BIT
@@ -82,6 +79,49 @@ bool adb_host_psw(void)
82} 79}
83#endif 80#endif
84 81
82/*
83 * Don't call this in a row without the delay, otherwise it makes some of poor controllers
84 * overloaded and misses strokes. Recommended interval is 12ms.
85 *
86 * Thanks a lot, blargg!
87 * <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919>
88 * <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139>
89 */
90
91// ADB Bit Cells
92//
93// bit cell time: 70-130us
94// low part of bit0: 60-70% of bit cell
95// low part of bit1: 30-40% of bit cell
96//
97// bit cell time 70us 130us
98// --------------------------------------------
99// low part of bit0 42-49 78-91
100// high part of bit0 21-28 39-52
101// low part of bit1 21-28 39-52
102// high part of bit1 42-49 78-91
103//
104//
105// bit0:
106// 70us bit cell:
107// ____________~~~~~~
108// 42-49 21-28
109//
110// 130us bit cell:
111// ____________~~~~~~
112// 78-91 39-52
113//
114// bit1:
115// 70us bit cell:
116// ______~~~~~~~~~~~~
117// 21-28 42-49
118//
119// 130us bit cell:
120// ______~~~~~~~~~~~~
121// 39-52 78-91
122//
123// [from Apple IIgs Hardware Reference Second Edition]
124
85uint16_t adb_host_kbd_recv(void) 125uint16_t adb_host_kbd_recv(void)
86{ 126{
87 uint16_t data = 0; 127 uint16_t data = 0;
@@ -91,22 +131,50 @@ uint16_t adb_host_kbd_recv(void)
91 if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us) 131 if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us)
92 return 0; // No data to send 132 return 0; // No data to send
93 } 133 }
94 if (!read_bit()) { // Startbit(1) 134
95 // Service Request
96 return -2;
97 }
98
99 // ad hoc fix: without block inerrupt read wrong bit occasionally and get keys stuck 135 // ad hoc fix: without block inerrupt read wrong bit occasionally and get keys stuck
100 cli(); 136 // TODO: is this needed anymore with improved timing?
101 data = read_byte(); 137 //cli();
102 data = (data<<8) | read_byte(); 138 uint8_t n = 17; // start bit + 16 data bits
103 uint8_t stop = read_bit(); // Stopbit(0) 139 do {
104 sei(); 140 uint8_t lo = (uint8_t) wait_data_hi(130);
141 if (!lo)
142 goto error;
143
144 uint8_t hi = (uint8_t) wait_data_lo(lo);
145 if (!hi)
146 goto error;
147
148 hi = lo - hi;
149 lo = 130 - lo;
150
151 data <<= 1;
152 if (lo < hi) {
153 data |= 1;
154 }
155 else if (n == 17) {
156 // Service Request
157 dprintf("Startbit ERROR\n");
158 sei();
159 return -2;
160 }
161 }
162 while ( --n );
105 163
106 if (stop) { 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 dprintf("Stopbit ERROR\n");
168 sei();
107 return -3; 169 return -3;
108 } 170 }
171 sei();
109 return data; 172 return data;
173
174error:
175 dprintf("Bit ERROR\n");
176 sei();
177 return -4;
110} 178}
111 179
112void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l) 180void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l)
@@ -131,23 +199,6 @@ void adb_host_kbd_led(uint8_t led)
131} 199}
132 200
133 201
134static inline void data_lo()
135{
136 ADB_DDR |= (1<<ADB_DATA_BIT);
137 ADB_PORT &= ~(1<<ADB_DATA_BIT);
138}
139static inline void data_hi()
140{
141 ADB_PORT |= (1<<ADB_DATA_BIT);
142 ADB_DDR &= ~(1<<ADB_DATA_BIT);
143}
144static inline bool data_in()
145{
146 ADB_PORT |= (1<<ADB_DATA_BIT);
147 ADB_DDR &= ~(1<<ADB_DATA_BIT);
148 return ADB_PIN&(1<<ADB_DATA_BIT);
149}
150
151#ifdef ADB_PSW_BIT 202#ifdef ADB_PSW_BIT
152static inline void psw_lo() 203static inline void psw_lo()
153{ 204{
@@ -170,7 +221,7 @@ static inline bool psw_in()
170static inline void attention(void) 221static inline void attention(void)
171{ 222{
172 data_lo(); 223 data_lo();
173 _delay_us(700); 224 _delay_us(800-35); // bit1 holds lo for 35 more
174 place_bit1(); 225 place_bit1();
175} 226}
176 227
@@ -200,81 +251,27 @@ static inline void send_byte(uint8_t data)
200 } 251 }
201} 252}
202 253
203static inline bool read_bit(void) 254// These are carefully coded to take 6 cycles of overhead.
204{ 255// inline asm approach became too convoluted
205 // ADB Bit Cells 256static inline uint16_t wait_data_lo(uint16_t us)
206 //
207 // bit cell time: 70-130us
208 // low part of bit0: 60-70% of bit cell
209 // low part of bit1: 30-40% of bit cell
210 //
211 // bit cell time 70us 130us
212 // --------------------------------------------
213 // low part of bit0 42-49 78-91
214 // high part of bit0 21-28 39-52
215 // low part of bit1 21-28 39-52
216 // high part of bit1 42-49 78-91
217 //
218 //
219 // bit0:
220 // 70us bit cell:
221 // ____________~~~~~~
222 // 42-49 21-28
223 //
224 // 130us bit cell:
225 // ____________~~~~~~
226 // 78-91 39-52
227 //
228 // bit1:
229 // 70us bit cell:
230 // ______~~~~~~~~~~~~
231 // 21-28 42-49
232 //
233 // 130us bit cell:
234 // ______~~~~~~~~~~~~
235 // 39-52 78-91
236 //
237 // read:
238 // ________|~~~~~~~~~
239 // 55us
240 // Read data line after 55us. If data line is low/high then bit is 0/1.
241 // This method might not work at <90us bit cell time.
242 //
243 // [from Apple IIgs Hardware Reference Second Edition]
244 bool bit;
245 wait_data_lo(75); // wait the start of bit cell at least 130ms(55+0+75)
246 _delay_us(55);
247 bit = data_in();
248 wait_data_hi(36); // wait high part of bit cell at least 91ms(55+36)
249 return bit;
250}
251
252static inline uint8_t read_byte(void)
253{
254 uint8_t data = 0;
255 for (int i = 0; i < 8; i++) {
256 data <<= 1;
257 if (read_bit())
258 data = data | 1;
259 }
260 return data;
261}
262
263static inline uint8_t wait_data_lo(uint16_t us)
264{ 257{
265 while (data_in() && us) { 258 do {
266 _delay_us(1); 259 if ( !data_in() )
267 us--; 260 break;
261 _delay_us(1 - (6 * 1000000.0 / F_CPU));
268 } 262 }
263 while ( --us );
269 return us; 264 return us;
270} 265}
271 266
272static inline uint8_t wait_data_hi(uint8_t us) 267static inline uint16_t wait_data_hi(uint16_t us)
273{ 268{
274 while (!data_in() && us) { 269 do {
275 _delay_us(1); 270 if ( data_in() )
276 us--; 271 break;
272 _delay_us(1 - (6 * 1000000.0 / F_CPU));
277 } 273 }
274 while ( --us );
278 return us; 275 return us;
279} 276}
280 277
diff --git a/protocol/lufa/lufa.c b/protocol/lufa/lufa.c
index c1617cd05..a230d5ba2 100644
--- a/protocol/lufa/lufa.c
+++ b/protocol/lufa/lufa.c
@@ -531,19 +531,26 @@ static void SetupHardware(void)
531 531
532 // for Console_Task 532 // for Console_Task
533 USB_Device_EnableSOFEvents(); 533 USB_Device_EnableSOFEvents();
534 print_set_sendchar(sendchar);
534} 535}
535 536
536int main(void) __attribute__ ((weak)); 537int main(void) __attribute__ ((weak));
537int main(void) 538int main(void)
538{ 539{
539 SetupHardware(); 540 SetupHardware();
541 sei();
542#if defined(INTERRUPT_CONTROL_ENDPOINT)
543 while (USB_DeviceState != DEVICE_STATE_Configured) ;
544#endif
545 print("USB configured.\n");
546
540 keyboard_init(); 547 keyboard_init();
541 host_set_driver(&lufa_driver); 548 host_set_driver(&lufa_driver);
542#ifdef SLEEP_LED_ENABLE 549#ifdef SLEEP_LED_ENABLE
543 sleep_led_init(); 550 sleep_led_init();
544#endif 551#endif
545 sei();
546 552
553 print("Keyboard start.\n");
547 while (1) { 554 while (1) {
548 while (USB_DeviceState == DEVICE_STATE_Suspended) { 555 while (USB_DeviceState == DEVICE_STATE_Suspended) {
549 suspend_power_down(); 556 suspend_power_down();
diff --git a/protocol/m0110.c b/protocol/m0110.c
index 8bf7cfe4f..924ec316b 100644
--- a/protocol/m0110.c
+++ b/protocol/m0110.c
@@ -91,10 +91,11 @@ uint8_t m0110_error = 0;
91 91
92void m0110_init(void) 92void m0110_init(void)
93{ 93{
94 uint8_t data;
95 idle(); 94 idle();
96 _delay_ms(1000); 95 _delay_ms(1000);
97 96
97/* Not needed to initialize in fact.
98 uint8_t data;
98 m0110_send(M0110_MODEL); 99 m0110_send(M0110_MODEL);
99 data = m0110_recv(); 100 data = m0110_recv();
100 print("m0110_init model: "); phex(data); print("\n"); 101 print("m0110_init model: "); phex(data); print("\n");
@@ -102,6 +103,7 @@ void m0110_init(void)
102 m0110_send(M0110_TEST); 103 m0110_send(M0110_TEST);
103 data = m0110_recv(); 104 data = m0110_recv();
104 print("m0110_init test: "); phex(data); print("\n"); 105 print("m0110_init test: "); phex(data); print("\n");
106*/
105} 107}
106 108
107uint8_t m0110_send(uint8_t data) 109uint8_t m0110_send(uint8_t data)
@@ -503,29 +505,29 @@ Scan Code
503 m0110_recv_key() function returns following scan codes instead of raw key events. 505 m0110_recv_key() function returns following scan codes instead of raw key events.
504 Scan codes are 1 byte long and MSB(bit7) is set when key is released. 506 Scan codes are 1 byte long and MSB(bit7) is set when key is released.
505 507
506 M0110 508 M0110 M0120
507 ,---------------------------------------------------------. 509 ,---------------------------------------------------------. ,---------------.
508 | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| 510 | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |Clr| -|Lft|Rgt|
509 |---------------------------------------------------------| 511 |---------------------------------------------------------| |---------------|
510 |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| 512 |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| | 7| 8| 9|Up |
511 |---------------------------------------------------------| 513 |---------------------------------------------------------| |---------------|
512 |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| 514 |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6|Dn |
513 |---------------------------------------------------------| 515 |---------------------------------------------------------| |---------------|
514 |Shift | Z| X| C| V| B| N| M| ,| ,| /| | 516 |Shift | Z| X| C| V| B| N| M| ,| ,| /| | | 1| 2| 3| |
515 `---------------------------------------------------------' 517 `---------------------------------------------------------' |-----------|Ent|
516 |Opt|Mac | Space |Enter|Opt| 518 |Opt|Mac | Space |Enter|Opt| | 0| .| |
517 `------------------------------------------------' 519 `------------------------------------------------' `---------------'
518 ,---------------------------------------------------------. 520 ,---------------------------------------------------------. ,---------------.
519 | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33| 521 | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33| | 47| 4E| 46| 42|
520 |---------------------------------------------------------| 522 |---------------------------------------------------------| |---------------|
521 | 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| 2A| 523 | 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| 2A| | 59| 5B| 5C| 4D|
522 |---------------------------------------------------------| 524 |---------------------------------------------------------| |---------------|
523 | 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24| 525 | 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24| | 56| 57| 58| 48|
524 |---------------------------------------------------------| 526 |---------------------------------------------------------| |---------------|
525 | 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 38| 527 | 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 38| | 53| 54| 55| |
526 `---------------------------------------------------------' 528 `---------------------------------------------------------' |-----------| 4C|
527 | 3A| 37| 31 | 34| 3A| 529 | 3A| 37| 31 | 34| 3A| | 52| 41| |
528 `------------------------------------------------' 530 `------------------------------------------------' `---------------'
529 531
530 M0110A 532 M0110A
531 ,---------------------------------------------------------. ,---------------. 533 ,---------------------------------------------------------. ,---------------.
diff --git a/protocol/pjrc/main.c b/protocol/pjrc/main.c
index 5f15dbf89..1ef87f865 100644
--- a/protocol/pjrc/main.c
+++ b/protocol/pjrc/main.c
@@ -30,6 +30,7 @@
30#include "matrix.h" 30#include "matrix.h"
31#include "print.h" 31#include "print.h"
32#include "debug.h" 32#include "debug.h"
33#include "sendchar.h"
33#include "util.h" 34#include "util.h"
34#include "suspend.h" 35#include "suspend.h"
35#include "host.h" 36#include "host.h"
@@ -50,6 +51,8 @@ int main(void)
50 usb_init(); 51 usb_init();
51 while (!usb_configured()) /* wait */ ; 52 while (!usb_configured()) /* wait */ ;
52 53
54 print_set_sendchar(sendchar);
55
53 keyboard_init(); 56 keyboard_init();
54 host_set_driver(pjrc_driver()); 57 host_set_driver(pjrc_driver());
55#ifdef SLEEP_LED_ENABLE 58#ifdef SLEEP_LED_ENABLE
diff --git a/protocol/pjrc/usb.c b/protocol/pjrc/usb.c
index 902f9f7f7..84c99972f 100644
--- a/protocol/pjrc/usb.c
+++ b/protocol/pjrc/usb.c
@@ -38,6 +38,7 @@
38#include "sleep_led.h" 38#include "sleep_led.h"
39#endif 39#endif
40#include "suspend.h" 40#include "suspend.h"
41#include "action_util.h"
41 42
42 43
43/************************************************************************** 44/**************************************************************************