diff options
author | tmk <nobody@nowhere> | 2012-10-06 02:23:12 +0900 |
---|---|---|
committer | tmk <nobody@nowhere> | 2012-10-17 15:55:37 +0900 |
commit | 4ae979f6ef8dbf9e1d1f35be15322ad6d02e2958 (patch) | |
tree | 9f5132005c27ef04ae793b77d4699cb285479466 | |
parent | 93e33fb8f694c9685accd72ed0458a2cf3d3f04a (diff) | |
download | qmk_firmware-4ae979f6ef8dbf9e1d1f35be15322ad6d02e2958.tar.gz qmk_firmware-4ae979f6ef8dbf9e1d1f35be15322ad6d02e2958.zip |
Initial version of new code for layer switch is added.
-rw-r--r-- | common.mk | 1 | ||||
-rw-r--r-- | common/command.c | 2 | ||||
-rw-r--r-- | common/host.c | 22 | ||||
-rw-r--r-- | common/host.h | 4 | ||||
-rwxr-xr-x[-rw-r--r--] | common/keyboard.c | 543 | ||||
-rwxr-xr-x[-rw-r--r--] | common/keyboard.h | 28 | ||||
-rw-r--r-- | common/layer.c | 207 | ||||
-rw-r--r-- | common/layer.h | 32 | ||||
-rw-r--r-- | common/matrix.h | 21 | ||||
-rw-r--r-- | common/mousekey.c | 120 | ||||
-rw-r--r-- | common/mousekey.h | 7 | ||||
-rw-r--r-- | common/timer.c | 1 | ||||
-rw-r--r-- | common/usb_keycodes.h | 5 | ||||
-rw-r--r-- | common/util.c | 16 | ||||
-rw-r--r-- | common/util.h | 4 | ||||
-rw-r--r-- | keyboard/hhkb/config.h | 2 | ||||
-rw-r--r-- | keyboard/hhkb/keymap.c | 8 | ||||
-rw-r--r-- | keyboard/hhkb/matrix.c | 50 | ||||
-rw-r--r-- | protocol/lufa/lufa.c | 2 |
19 files changed, 586 insertions, 489 deletions
@@ -2,7 +2,6 @@ COMMON_DIR = common | |||
2 | SRC += $(COMMON_DIR)/host.c \ | 2 | SRC += $(COMMON_DIR)/host.c \ |
3 | $(COMMON_DIR)/keyboard.c \ | 3 | $(COMMON_DIR)/keyboard.c \ |
4 | $(COMMON_DIR)/command.c \ | 4 | $(COMMON_DIR)/command.c \ |
5 | $(COMMON_DIR)/layer.c \ | ||
6 | $(COMMON_DIR)/timer.c \ | 5 | $(COMMON_DIR)/timer.c \ |
7 | $(COMMON_DIR)/print.c \ | 6 | $(COMMON_DIR)/print.c \ |
8 | $(COMMON_DIR)/debug.c \ | 7 | $(COMMON_DIR)/debug.c \ |
diff --git a/common/command.c b/common/command.c index 13d37242d..0020d8a17 100644 --- a/common/command.c +++ b/common/command.c | |||
@@ -23,7 +23,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
23 | #include "debug.h" | 23 | #include "debug.h" |
24 | #include "util.h" | 24 | #include "util.h" |
25 | #include "timer.h" | 25 | #include "timer.h" |
26 | #include "layer.h" | 26 | #include "keyboard.h" |
27 | #include "matrix.h" | 27 | #include "matrix.h" |
28 | #include "bootloader.h" | 28 | #include "bootloader.h" |
29 | #include "command.h" | 29 | #include "command.h" |
diff --git a/common/host.c b/common/host.c index 8dd2abbee..fddd5b662 100644 --- a/common/host.c +++ b/common/host.c | |||
@@ -56,6 +56,19 @@ uint8_t host_keyboard_leds(void) | |||
56 | return (*driver->keyboard_leds)(); | 56 | return (*driver->keyboard_leds)(); |
57 | } | 57 | } |
58 | 58 | ||
59 | /* new interface */ | ||
60 | void host_register_key(uint8_t key) | ||
61 | { | ||
62 | host_add_key(key); | ||
63 | host_send_keyboard_report(); | ||
64 | } | ||
65 | |||
66 | void host_unregister_key(uint8_t key) | ||
67 | { | ||
68 | host_del_key(key); | ||
69 | host_send_keyboard_report(); | ||
70 | } | ||
71 | |||
59 | /* keyboard report operations */ | 72 | /* keyboard report operations */ |
60 | void host_add_key(uint8_t key) | 73 | void host_add_key(uint8_t key) |
61 | { | 74 | { |
@@ -158,6 +171,14 @@ void host_send_keyboard_report(void) | |||
158 | { | 171 | { |
159 | if (!driver) return; | 172 | if (!driver) return; |
160 | (*driver->send_keyboard)(keyboard_report); | 173 | (*driver->send_keyboard)(keyboard_report); |
174 | |||
175 | if (debug_keyboard) { | ||
176 | print("keys: "); | ||
177 | for (int i = 0; i < REPORT_KEYS; i++) { | ||
178 | phex(keyboard_report->keys[i]); print(" "); | ||
179 | } | ||
180 | print(" mods: "); phex(keyboard_report->mods); print("\n"); | ||
181 | } | ||
161 | } | 182 | } |
162 | 183 | ||
163 | void host_mouse_send(report_mouse_t *report) | 184 | void host_mouse_send(report_mouse_t *report) |
@@ -216,7 +237,6 @@ static inline void del_key_byte(uint8_t code) | |||
216 | for (; i < REPORT_KEYS; i++) { | 237 | for (; i < REPORT_KEYS; i++) { |
217 | if (keyboard_report->keys[i] == code) { | 238 | if (keyboard_report->keys[i] == code) { |
218 | keyboard_report->keys[i] = 0; | 239 | keyboard_report->keys[i] = 0; |
219 | break; | ||
220 | } | 240 | } |
221 | } | 241 | } |
222 | } | 242 | } |
diff --git a/common/host.h b/common/host.h index 26bf3c362..84a6c2477 100644 --- a/common/host.h +++ b/common/host.h | |||
@@ -39,6 +39,10 @@ void host_set_driver(host_driver_t *driver); | |||
39 | host_driver_t *host_get_driver(void); | 39 | host_driver_t *host_get_driver(void); |
40 | uint8_t host_keyboard_leds(void); | 40 | uint8_t host_keyboard_leds(void); |
41 | 41 | ||
42 | /* new interface */ | ||
43 | void host_register_key(uint8_t key); | ||
44 | void host_unregister_key(uint8_t key); | ||
45 | |||
42 | /* keyboard report operations */ | 46 | /* keyboard report operations */ |
43 | void host_add_key(uint8_t key); | 47 | void host_add_key(uint8_t key); |
44 | void host_del_key(uint8_t key); | 48 | void host_del_key(uint8_t key); |
diff --git a/common/keyboard.c b/common/keyboard.c index 25f32eb02..9f0c27670 100644..100755 --- a/common/keyboard.c +++ b/common/keyboard.c | |||
@@ -15,15 +15,16 @@ You should have received a copy of the GNU General Public License | |||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | */ | 16 | */ |
17 | #include "keyboard.h" | 17 | #include "keyboard.h" |
18 | #include "host.h" | ||
19 | #include "layer.h" | ||
20 | #include "matrix.h" | 18 | #include "matrix.h" |
19 | #include "keymap.h" | ||
20 | #include "host.h" | ||
21 | #include "led.h" | 21 | #include "led.h" |
22 | #include "usb_keycodes.h" | 22 | #include "usb_keycodes.h" |
23 | #include "timer.h" | 23 | #include "timer.h" |
24 | #include "print.h" | 24 | #include "print.h" |
25 | #include "debug.h" | 25 | #include "debug.h" |
26 | #include "command.h" | 26 | #include "command.h" |
27 | #include "util.h" | ||
27 | #ifdef MOUSEKEY_ENABLE | 28 | #ifdef MOUSEKEY_ENABLE |
28 | #include "mousekey.h" | 29 | #include "mousekey.h" |
29 | #endif | 30 | #endif |
@@ -32,162 +33,444 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
32 | #endif | 33 | #endif |
33 | 34 | ||
34 | 35 | ||
35 | static uint8_t last_leds = 0; | 36 | #define LAYER_DELAY 250 |
36 | 37 | ||
38 | typedef enum keykind { | ||
39 | NONE, | ||
40 | FN_DOWN, FN_UP, | ||
41 | FNK_DOWN, FNK_UP, | ||
42 | KEY_DOWN, KEY_UP, | ||
43 | MOD_DOWN, MOD_UP, | ||
44 | MOUSEKEY_DOWN, MOUSEKEY_UP, | ||
45 | DELAY | ||
46 | } keykind_t; | ||
37 | 47 | ||
38 | void keyboard_init(void) | 48 | typedef enum { IDLE, DELAYING, WAITING, PRESSING } kbdstate_t; |
49 | |||
50 | |||
51 | uint8_t current_layer = 0; | ||
52 | uint8_t default_layer = 0; | ||
53 | |||
54 | /* keyboard internal states */ | ||
55 | static kbdstate_t kbdstate = IDLE; | ||
56 | static uint8_t fn_state_bits = 0; | ||
57 | static keyrecord_t delayed_fn; | ||
58 | static keyrecord_t waiting_key; | ||
59 | |||
60 | |||
61 | static const char *state_str(kbdstate_t state) | ||
39 | { | 62 | { |
40 | timer_init(); | 63 | if (state == IDLE) return PSTR("IDLE"); |
41 | matrix_init(); | 64 | if (state == DELAYING) return PSTR("DELAYING"); |
42 | #ifdef PS2_MOUSE_ENABLE | 65 | if (state == WAITING) return PSTR("WAITING"); |
43 | ps2_mouse_init(); | 66 | if (state == PRESSING) return PSTR("PRESSING"); |
44 | #endif | 67 | return PSTR("UNKNOWN"); |
45 | } | 68 | } |
46 | 69 | ||
47 | void keyboard_proc(void) | 70 | static inline keykind_t get_keykind(uint8_t code, bool pressed) |
48 | { | 71 | { |
49 | uint8_t fn_bits = 0; | 72 | if IS_KEY(code) return (pressed ? KEY_DOWN : KEY_UP); |
50 | #ifdef EXTRAKEY_ENABLE | 73 | if IS_MOD(code) return (pressed ? MOD_DOWN : MOD_UP); |
51 | uint16_t consumer_code = 0; | 74 | if IS_FN(code) { |
52 | uint16_t system_code = 0; | 75 | if (keymap_fn_keycode(FN_INDEX(code))) |
53 | #endif | 76 | return (pressed ? FNK_DOWN : FNK_UP); |
54 | 77 | else | |
55 | matrix_scan(); | 78 | return (pressed ? FN_DOWN : FN_UP); |
79 | } | ||
80 | if IS_MOUSEKEY(code) return (pressed ? MOUSEKEY_DOWN : MOUSEKEY_UP); | ||
81 | return NONE; | ||
82 | } | ||
56 | 83 | ||
57 | if (matrix_is_modified()) { | 84 | static void layer_switch_on(uint8_t code) |
58 | if (debug_matrix) matrix_print(); | 85 | { |
59 | #ifdef DEBUG_LED | 86 | if (!IS_FN(code)) return; |
60 | // LED flash for debug | 87 | fn_state_bits |= FN_BIT(code); |
61 | DEBUG_LED_CONFIG; | 88 | if (current_layer != keymap_fn_layer(FN_INDEX(code))) { |
62 | DEBUG_LED_ON; | 89 | //TODO: clear all key execpt Mod key |
63 | #endif | 90 | debug("Layer Switch(on): "); debug_hex(current_layer); |
91 | current_layer = keymap_fn_layer(FN_INDEX(code)); | ||
92 | debug(" -> "); debug_hex(current_layer); debug("\n"); | ||
64 | } | 93 | } |
94 | } | ||
65 | 95 | ||
66 | if (matrix_has_ghost()) { | 96 | static void layer_switch_off(uint8_t code) |
67 | // should send error? | 97 | { |
68 | debug("matrix has ghost!!\n"); | 98 | if (!IS_FN(code)) return; |
69 | return; | 99 | fn_state_bits &= ~FN_BIT(code); |
100 | if (current_layer != keymap_fn_layer(biton(fn_state_bits))) { | ||
101 | //TODO: clear all key execpt Mod key | ||
102 | debug("Layer Switch(off): "); debug_hex(current_layer); | ||
103 | current_layer = keymap_fn_layer(biton(fn_state_bits)); | ||
104 | debug(" -> "); debug_hex(current_layer); debug("\n"); | ||
70 | } | 105 | } |
106 | } | ||
71 | 107 | ||
72 | host_swap_keyboard_report(); | 108 | static inline uint8_t get_keycode(key_t key) |
73 | host_clear_keyboard_report(); | 109 | { |
74 | for (int row = 0; row < matrix_rows(); row++) { | 110 | return keymap_get_keycode(current_layer, key.row, key.col); |
75 | for (int col = 0; col < matrix_cols(); col++) { | 111 | } |
76 | if (!matrix_is_on(row, col)) continue; | 112 | |
77 | 113 | // whether any key except modifier is down or not | |
78 | uint8_t code = layer_get_keycode(row, col); | 114 | static inline bool is_anykey_down(void) |
79 | if (code == KB_NO) { | 115 | { |
80 | // do nothing | 116 | for (int r = 0; r < MATRIX_ROWS; r++) { |
81 | } else if (IS_MOD(code)) { | 117 | matrix_row_t matrix_row = matrix_get_row(r); |
82 | host_add_mod_bit(MOD_BIT(code)); | 118 | for (int c = 0; c < MATRIX_COLS; c++) { |
83 | } else if (IS_FN(code)) { | 119 | if (matrix_row && (1<<c)) { |
84 | fn_bits |= FN_BIT(code); | 120 | if (IS_KEY(get_keycode((key_t){ .row = r, .col = c }))) { |
85 | } | 121 | return true; |
86 | // TODO: use table or something | ||
87 | #ifdef EXTRAKEY_ENABLE | ||
88 | // System Control | ||
89 | else if (code == KB_SYSTEM_POWER) { | ||
90 | #ifdef HOST_PJRC | ||
91 | if (suspend && remote_wakeup) { | ||
92 | usb_remote_wakeup(); | ||
93 | } | 122 | } |
94 | #endif | ||
95 | system_code = SYSTEM_POWER_DOWN; | ||
96 | } else if (code == KB_SYSTEM_SLEEP) { | ||
97 | system_code = SYSTEM_SLEEP; | ||
98 | } else if (code == KB_SYSTEM_WAKE) { | ||
99 | system_code = SYSTEM_WAKE_UP; | ||
100 | } | ||
101 | // Consumer Page | ||
102 | else if (code == KB_AUDIO_MUTE) { | ||
103 | consumer_code = AUDIO_MUTE; | ||
104 | } else if (code == KB_AUDIO_VOL_UP) { | ||
105 | consumer_code = AUDIO_VOL_UP; | ||
106 | } else if (code == KB_AUDIO_VOL_DOWN) { | ||
107 | consumer_code = AUDIO_VOL_DOWN; | ||
108 | } | 123 | } |
109 | else if (code == KB_MEDIA_NEXT_TRACK) { | 124 | } |
110 | consumer_code = TRANSPORT_NEXT_TRACK; | 125 | } |
111 | } else if (code == KB_MEDIA_PREV_TRACK) { | 126 | return false; |
112 | consumer_code = TRANSPORT_PREV_TRACK; | 127 | } |
113 | } else if (code == KB_MEDIA_STOP) { | 128 | |
114 | consumer_code = TRANSPORT_STOP; | 129 | static void register_code(uint8_t code) |
115 | } else if (code == KB_MEDIA_PLAY_PAUSE) { | 130 | { |
116 | consumer_code = TRANSPORT_PLAY_PAUSE; | 131 | if IS_KEY(code) { |
117 | } else if (code == KB_MEDIA_SELECT) { | 132 | host_add_key(code); |
118 | consumer_code = AL_CC_CONFIG; | 133 | host_send_keyboard_report(); |
119 | } | 134 | } |
120 | else if (code == KB_MAIL) { | 135 | else if IS_MOD(code) { |
121 | consumer_code = AL_EMAIL; | 136 | host_add_mod_bit(MOD_BIT(code)); |
122 | } else if (code == KB_CALCULATOR) { | 137 | host_send_keyboard_report(); |
123 | consumer_code = AL_CALCULATOR; | 138 | } |
124 | } else if (code == KB_MY_COMPUTER) { | 139 | else if IS_MOUSEKEY(code) { |
125 | consumer_code = AL_LOCAL_BROWSER; | 140 | mousekey_on(code); |
126 | } | 141 | mousekey_send(); |
127 | else if (code == KB_WWW_SEARCH) { | 142 | } |
128 | consumer_code = AC_SEARCH; | 143 | } |
129 | } else if (code == KB_WWW_HOME) { | 144 | |
130 | consumer_code = AC_HOME; | 145 | static void unregister_code(uint8_t code) |
131 | } else if (code == KB_WWW_BACK) { | 146 | { |
132 | consumer_code = AC_BACK; | 147 | if IS_KEY(code) { |
133 | } else if (code == KB_WWW_FORWARD) { | 148 | host_del_key(code); |
134 | consumer_code = AC_FORWARD; | 149 | host_send_keyboard_report(); |
135 | } else if (code == KB_WWW_STOP) { | 150 | } |
136 | consumer_code = AC_STOP; | 151 | else if IS_MOD(code) { |
137 | } else if (code == KB_WWW_REFRESH) { | 152 | host_del_mod_bit(MOD_BIT(code)); |
138 | consumer_code = AC_REFRESH; | 153 | host_send_keyboard_report(); |
139 | } else if (code == KB_WWW_FAVORITES) { | 154 | } |
140 | consumer_code = AC_BOOKMARKS; | 155 | else if IS_MOUSEKEY(code) { |
156 | mousekey_off(code); | ||
157 | mousekey_send(); | ||
158 | } | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * | ||
163 | * Event/State|IDLE DELAYING[f] WAITING[f,k] PRESSING | ||
164 | * -----------+------------------------------------------------------------------ | ||
165 | * Fn Down |IDLE(L+) WAITING(Sk) WAITING(Sk) - | ||
166 | * Up |IDLE(L-) IDLE(L-) IDLE(L-) IDLE(L-) | ||
167 | * Fnk Down |DELAYING(Sf) WAITING(Sk) WAINTING(Sk) PRESSING(Rf) | ||
168 | * Up |IDLE(L-) IDLE(Rf,Uf) IDLE(Rf,Ps,Uf)*3 PRESSING(Uf) | ||
169 | * Key Down |PRESSING(Rk) WAITING(Sk) WAITING(Sk) PRESSING(Rk) | ||
170 | * Up |IDLE(Uk) DELAYING(Uk) IDLE(L+,Ps,Uk) IDLE(Uk)*4 | ||
171 | * Delay |- IDLE(L+) IDLE(L+,Ps) - | ||
172 | * | | ||
173 | * No key Down|IDLE(Ld) IDLE(Ld) IDLE(Ld) IDLE(Ld) | ||
174 | * | ||
175 | * *2: register Fnk if any key is pressing | ||
176 | * *3: when Fnk == Stored Fnk, if not ignore. | ||
177 | * *4: when no registered key any more | ||
178 | * | ||
179 | * States: | ||
180 | * IDLE: | ||
181 | * DELAYING: delay layer switch after pressing Fn with alt keycode | ||
182 | * WAITING: key is pressed during DELAYING | ||
183 | * | ||
184 | * Events: | ||
185 | * Fn: Fn key without alternative keycode | ||
186 | * Fnk: Fn key with alternative keycode | ||
187 | * -: ignore | ||
188 | * | ||
189 | * Actions: | ||
190 | * Rk: register key | ||
191 | * Uk: unregister key | ||
192 | * Rf: register stored Fn(alt keycode) | ||
193 | * Uf: unregister stored Fn(alt keycode) | ||
194 | * Rs: register stored key | ||
195 | * Us: unregister stored key | ||
196 | * Sk: store key | ||
197 | * Sf: store Fn | ||
198 | * Ps: play stored key(Interpret stored key and transit state) | ||
199 | * L+: Switch to new layer(*retain* Modifiers only) | ||
200 | * L-: Switch back to last layer(*clear* stored key/Fn, *unregister* all Modifier/key) | ||
201 | * Ld: Switch back to default layer(*clear* stored key/Fn, *unregister* all Modifier/key) | ||
202 | */ | ||
203 | #define NEXT(state) do { \ | ||
204 | debug("NEXT: "); print_P(state_str(kbdstate)); \ | ||
205 | kbdstate = state; \ | ||
206 | debug(" -> "); print_P(state_str(kbdstate)); debug("\n"); \ | ||
207 | } while (0) | ||
208 | |||
209 | static inline void process_key(keyevent_t event) | ||
210 | { | ||
211 | |||
212 | /* TODO: ring buffer | ||
213 | static keyrecord_t waiting_keys[5]; | ||
214 | static uint8_t waiting_keys_head = 0; | ||
215 | static uint8_t waiting_keys_tail = 0; | ||
216 | */ | ||
217 | |||
218 | uint8_t code = get_keycode(event.key); | ||
219 | keykind_t kind = get_keykind(code, event.pressed); | ||
220 | |||
221 | uint8_t tmp_mods; | ||
222 | |||
223 | //debug("kbdstate: "); debug_hex(kbdstate); | ||
224 | debug("state: "); print_P(state_str(kbdstate)); | ||
225 | debug(" kind: "); debug_hex(kind); | ||
226 | debug(" code: "); debug_hex(code); | ||
227 | if (event.pressed) { debug("d"); } else { debug("u"); } | ||
228 | debug("\n"); | ||
229 | switch (kbdstate) { | ||
230 | case IDLE: | ||
231 | switch (kind) { | ||
232 | case FN_DOWN: | ||
233 | layer_switch_on(code); | ||
234 | break; | ||
235 | case FN_UP: | ||
236 | layer_switch_off(code); | ||
237 | break; | ||
238 | case FNK_DOWN: | ||
239 | // store event | ||
240 | delayed_fn = (keyrecord_t) { .event = event, .code = code, .mods = keyboard_report->mods, .time = timer_read() }; | ||
241 | NEXT(DELAYING); | ||
242 | break; | ||
243 | case FNK_UP: | ||
244 | layer_switch_off(code); | ||
245 | break; | ||
246 | case KEY_DOWN: | ||
247 | case MOUSEKEY_DOWN: | ||
248 | register_code(code); | ||
249 | NEXT(PRESSING); | ||
250 | break; | ||
251 | case MOD_DOWN: | ||
252 | register_code(code); | ||
253 | break; | ||
254 | case KEY_UP: | ||
255 | case MOUSEKEY_UP: | ||
256 | case MOD_UP: | ||
257 | unregister_code(code); | ||
258 | break; | ||
259 | default: | ||
260 | break; | ||
141 | } | 261 | } |
142 | #endif | 262 | break; |
143 | else if (IS_KEY(code)) { | 263 | case PRESSING: |
144 | host_add_key(code); | 264 | switch (kind) { |
265 | case FN_DOWN: | ||
266 | // ignored when any key is pressed | ||
267 | break; | ||
268 | case FN_UP: | ||
269 | layer_switch_off(code); | ||
270 | NEXT(IDLE); | ||
271 | break; | ||
272 | case FNK_DOWN: | ||
273 | register_code(keymap_fn_keycode(FN_INDEX(code))); | ||
274 | break; | ||
275 | case FNK_UP: | ||
276 | unregister_code(keymap_fn_keycode(FN_INDEX(code))); | ||
277 | break; | ||
278 | case KEY_DOWN: | ||
279 | case MOD_DOWN: | ||
280 | case MOUSEKEY_DOWN: | ||
281 | register_code(code); | ||
282 | break; | ||
283 | case KEY_UP: | ||
284 | case MOD_UP: | ||
285 | case MOUSEKEY_UP: | ||
286 | unregister_code(code); | ||
287 | // no key registered? mousekey, mediakey, systemkey | ||
288 | if (!host_has_anykey()) | ||
289 | NEXT(IDLE); | ||
290 | break; | ||
291 | default: | ||
292 | break; | ||
145 | } | 293 | } |
146 | #ifdef MOUSEKEY_ENABLE | 294 | break; |
147 | else if (IS_MOUSEKEY(code)) { | 295 | case DELAYING: |
148 | mousekey_decode(code); | 296 | switch (kind) { |
297 | case FN_DOWN: | ||
298 | case FNK_DOWN: | ||
299 | case KEY_DOWN: | ||
300 | case MOUSEKEY_DOWN: | ||
301 | waiting_key = (keyrecord_t) { .event = event, .code = code, .mods = keyboard_report->mods, .time = timer_read() }; | ||
302 | NEXT(WAITING); | ||
303 | break; | ||
304 | case MOD_DOWN: | ||
305 | register_code(code); | ||
306 | break; | ||
307 | case FN_UP: | ||
308 | layer_switch_off(code); | ||
309 | NEXT(IDLE); | ||
310 | break; | ||
311 | case FNK_UP: | ||
312 | if (code == delayed_fn.code) { | ||
313 | // type Fn with alt keycode | ||
314 | // restore the mod status at the time of pressing Fn key | ||
315 | tmp_mods = keyboard_report->mods; | ||
316 | host_set_mods(delayed_fn.mods); | ||
317 | register_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code))); | ||
318 | unregister_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code))); | ||
319 | host_set_mods(tmp_mods); | ||
320 | NEXT(IDLE); | ||
321 | } else { | ||
322 | layer_switch_off(code); | ||
323 | NEXT(IDLE); | ||
324 | } | ||
325 | break; | ||
326 | case KEY_UP: | ||
327 | case MOUSEKEY_UP: | ||
328 | unregister_code(code); | ||
329 | NEXT(IDLE); | ||
330 | break; | ||
331 | case MOD_UP: | ||
332 | unregister_code(code); | ||
333 | break; | ||
334 | default: | ||
335 | break; | ||
149 | } | 336 | } |
150 | #endif | 337 | break; |
151 | else { | 338 | case WAITING: |
152 | debug("ignore keycode: "); debug_hex(code); debug("\n"); | 339 | switch (kind) { |
340 | case FN_DOWN: | ||
341 | case FNK_DOWN: | ||
342 | case KEY_DOWN: | ||
343 | case MOUSEKEY_DOWN: | ||
344 | tmp_mods = keyboard_report->mods; | ||
345 | host_set_mods(delayed_fn.mods); | ||
346 | register_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code))); | ||
347 | host_set_mods(waiting_key.mods); | ||
348 | register_code(waiting_key.code); | ||
349 | host_set_mods(tmp_mods); | ||
350 | register_code(code); | ||
351 | NEXT(IDLE); | ||
352 | break; | ||
353 | case MOD_DOWN: | ||
354 | register_code(code); | ||
355 | break; | ||
356 | case FN_UP: | ||
357 | layer_switch_off(code); | ||
358 | NEXT(IDLE); | ||
359 | break; | ||
360 | case FNK_UP: | ||
361 | if (code == delayed_fn.code) { | ||
362 | // alt down, key down, alt up | ||
363 | tmp_mods = keyboard_report->mods; | ||
364 | host_set_mods(delayed_fn.mods); | ||
365 | register_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code))); | ||
366 | host_set_mods(waiting_key.mods); | ||
367 | register_code(waiting_key.code); | ||
368 | unregister_code(keymap_fn_keycode(FN_INDEX(delayed_fn.code))); | ||
369 | host_set_mods(tmp_mods); | ||
370 | NEXT(IDLE); | ||
371 | } else { | ||
372 | layer_switch_off(code); | ||
373 | NEXT(IDLE); | ||
374 | } | ||
375 | break; | ||
376 | case KEY_UP: | ||
377 | case MOUSEKEY_UP: | ||
378 | if (code == waiting_key.code) { | ||
379 | layer_switch_on(delayed_fn.code); | ||
380 | NEXT(IDLE); | ||
381 | // process waiting_key | ||
382 | tmp_mods = keyboard_report->mods; | ||
383 | host_set_mods(waiting_key.mods); | ||
384 | process_key(waiting_key.event); | ||
385 | host_set_mods(tmp_mods); | ||
386 | process_key(event); | ||
387 | } else { | ||
388 | unregister_code(code); | ||
389 | } | ||
390 | break; | ||
391 | case MOD_UP: | ||
392 | unregister_code(code); | ||
393 | break; | ||
394 | default: | ||
395 | break; | ||
153 | } | 396 | } |
154 | } | 397 | break; |
155 | } | 398 | } |
156 | 399 | ||
157 | layer_switching(fn_bits); | 400 | // TODO: FAIL SAFE: unregister all keys when no key down |
401 | } | ||
402 | |||
403 | void keyboard_init(void) | ||
404 | { | ||
405 | debug_keyboard = true; | ||
406 | |||
407 | timer_init(); | ||
408 | matrix_init(); | ||
409 | #ifdef PS2_MOUSE_ENABLE | ||
410 | ps2_mouse_init(); | ||
411 | #endif | ||
412 | } | ||
413 | |||
414 | void keyboard_task(void) | ||
415 | { | ||
416 | static matrix_row_t matrix_prev[MATRIX_ROWS]; | ||
417 | matrix_row_t matrix_row = 0; | ||
418 | matrix_row_t matrix_change = 0; | ||
158 | 419 | ||
420 | matrix_scan(); | ||
159 | if (command_proc()) { | 421 | if (command_proc()) { |
422 | debug("COMMAND\n"); | ||
423 | // TODO: clear all keys | ||
424 | host_clear_keyboard_report(); | ||
425 | host_send_keyboard_report(); | ||
160 | return; | 426 | return; |
161 | } | 427 | } |
428 | for (int r = 0; r < MATRIX_ROWS; r++) { | ||
429 | matrix_row = matrix_get_row(r); | ||
430 | matrix_change = matrix_row ^ matrix_prev[r]; | ||
431 | if (matrix_change) { | ||
432 | // TODO: print once per scan | ||
433 | if (debug_matrix) matrix_print(); | ||
162 | 434 | ||
163 | // TODO: should send only when changed from last report | 435 | for (int c = 0; c < MATRIX_COLS; c++) { |
164 | if (matrix_is_modified()) { | 436 | if (matrix_change & (1<<c)) { |
165 | host_send_keyboard_report(); | 437 | process_key((keyevent_t){ |
166 | #ifdef EXTRAKEY_ENABLE | 438 | .key = (key_t){ .row = r, .col = c }, |
167 | host_consumer_send(consumer_code); | 439 | .pressed = (matrix_row & (1<<c)) |
168 | host_system_send(system_code); | 440 | }); |
169 | #endif | 441 | // record a processed key |
170 | #ifdef DEBUG_LED | 442 | matrix_prev[r] ^= (1<<c); |
171 | // LED flash for debug | 443 | // process a key per task call |
172 | DEBUG_LED_CONFIG; | 444 | goto MATRIX_LOOP_END; |
173 | DEBUG_LED_OFF; | 445 | } |
174 | #endif | 446 | } |
447 | } | ||
175 | } | 448 | } |
449 | MATRIX_LOOP_END: | ||
450 | // TODO: FAIL SAFE: clear all key if no key down | ||
176 | 451 | ||
177 | #ifdef MOUSEKEY_ENABLE | 452 | // layer switch when delay term elapses |
178 | mousekey_send(); | 453 | if (kbdstate == DELAYING || kbdstate == WAITING) { |
179 | #endif | 454 | if (timer_elapsed(delayed_fn.time) > LAYER_DELAY) { |
455 | if (kbdstate == DELAYING) { | ||
456 | layer_switch_on(delayed_fn.code); | ||
457 | NEXT(IDLE); | ||
458 | } | ||
459 | if (kbdstate == WAITING) { | ||
460 | layer_switch_on(delayed_fn.code); | ||
461 | NEXT(IDLE); | ||
462 | uint8_t tmp_mods = keyboard_report->mods; | ||
463 | host_set_mods(waiting_key.mods); | ||
464 | process_key(waiting_key.event); | ||
465 | host_set_mods(tmp_mods); | ||
466 | } | ||
467 | } | ||
468 | } | ||
180 | 469 | ||
181 | #ifdef PS2_MOUSE_ENABLE | 470 | // mousekey repeat & acceleration |
182 | // TODO: should comform new API | 471 | mousekey_task(); |
183 | if (ps2_mouse_read() == 0) | ||
184 | ps2_mouse_usb_send(); | ||
185 | #endif | ||
186 | 472 | ||
187 | if (last_leds != host_keyboard_leds()) { | 473 | return; |
188 | keyboard_set_leds(host_keyboard_leds()); | ||
189 | last_leds = host_keyboard_leds(); | ||
190 | } | ||
191 | } | 474 | } |
192 | 475 | ||
193 | void keyboard_set_leds(uint8_t leds) | 476 | void keyboard_set_leds(uint8_t leds) |
diff --git a/common/keyboard.h b/common/keyboard.h index 51bf67379..2353805e1 100644..100755 --- a/common/keyboard.h +++ b/common/keyboard.h | |||
@@ -18,15 +18,41 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
18 | #ifndef KEYBOARD_H | 18 | #ifndef KEYBOARD_H |
19 | #define KEYBOARD_H | 19 | #define KEYBOARD_H |
20 | 20 | ||
21 | #include <stdbool.h> | ||
21 | #include <stdint.h> | 22 | #include <stdint.h> |
22 | 23 | ||
23 | 24 | ||
24 | #ifdef __cplusplus | 25 | #ifdef __cplusplus |
25 | extern "C" { | 26 | extern "C" { |
26 | #endif | 27 | #endif |
28 | |||
29 | typedef struct { | ||
30 | uint8_t row; | ||
31 | uint8_t col; | ||
32 | } key_t; | ||
33 | |||
34 | typedef struct { | ||
35 | key_t key; | ||
36 | bool pressed; | ||
37 | } keyevent_t; | ||
38 | |||
39 | typedef struct { | ||
40 | keyevent_t event; | ||
41 | uint8_t code; | ||
42 | uint8_t mods; | ||
43 | uint16_t time; | ||
44 | } keyrecord_t; | ||
45 | |||
46 | #define KEYEQ(keya, keyb) (keya.row == keyb.row && keya.col == keyb.col) | ||
47 | |||
48 | |||
49 | extern uint8_t current_layer; | ||
50 | extern uint8_t default_layer; | ||
51 | |||
27 | void keyboard_init(void); | 52 | void keyboard_init(void); |
28 | void keyboard_proc(void); | 53 | void keyboard_task(void); |
29 | void keyboard_set_leds(uint8_t leds); | 54 | void keyboard_set_leds(uint8_t leds); |
55 | |||
30 | #ifdef __cplusplus | 56 | #ifdef __cplusplus |
31 | } | 57 | } |
32 | #endif | 58 | #endif |
diff --git a/common/layer.c b/common/layer.c deleted file mode 100644 index 0854eede0..000000000 --- a/common/layer.c +++ /dev/null | |||
@@ -1,207 +0,0 @@ | |||
1 | /* | ||
2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | ||
3 | |||
4 | This program is free software: you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation, either version 2 of the License, or | ||
7 | (at your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | #include "keymap.h" | ||
19 | #include "host.h" | ||
20 | #include "debug.h" | ||
21 | #include "timer.h" | ||
22 | #include "usb_keycodes.h" | ||
23 | #include "layer.h" | ||
24 | |||
25 | |||
26 | /* | ||
27 | * Parameters: | ||
28 | * SWITCH_DELAY |=======| | ||
29 | * SEND_FN_TERM |================| | ||
30 | * | ||
31 | * Fn key processing cases: | ||
32 | * 1. release Fn after SEND_FN_TERM. | ||
33 | * Layer sw ___________|~~~~~~~~~~~|___ | ||
34 | * Fn press ___|~~~~~~~~~~~~~~~~~~~|___ | ||
35 | * Fn send ___________________________ | ||
36 | * | ||
37 | * 2. release Fn during SEND_FN_TERM.(not layer used) | ||
38 | * Layer sw ___________|~~~~~~|________ | ||
39 | * Fn press ___|~~~~~~~~~~~~~~|________ | ||
40 | * Fn key send __________________|~|______ | ||
41 | * other key press ___________________________ | ||
42 | * other key send ___________________________ | ||
43 | * | ||
44 | * 3. release Fn during SEND_FN_TERM.(layer used) | ||
45 | * Layer sw ___________|~~~~~~|________ | ||
46 | * Fn press ___|~~~~~~~~~~~~~~|________ | ||
47 | * Fn key send ___________________________ | ||
48 | * Fn send ___________________________ | ||
49 | * other key press _____________|~~|__________ | ||
50 | * other key send _____________|~~|__________ | ||
51 | * | ||
52 | * 4. press other key during SWITCH_DELAY. | ||
53 | * Layer sw ___________________________ | ||
54 | * Fn key press ___|~~~~~~~~~|_____________ | ||
55 | * Fn key send ______|~~~~~~|_____________ | ||
56 | * other key press ______|~~~|________________ | ||
57 | * other key send _______|~~|________________ | ||
58 | * | ||
59 | * 5. press Fn while press other key. | ||
60 | * Layer sw ___________________________ | ||
61 | * Fn key press ___|~~~~~~~~~|_____________ | ||
62 | * Fn key send ___|~~~~~~~~~|_____________ | ||
63 | * other key press ~~~~~~~|___________________ | ||
64 | * other key send ~~~~~~~|___________________ | ||
65 | * | ||
66 | * 6. press Fn twice quickly and keep holding down.(repeat) | ||
67 | * Layer sw ___________________________ | ||
68 | * Fn key press ___|~|____|~~~~~~~~~~~~~~~~ | ||
69 | * Fn key send _____|~|__|~~~~~~~~~~~~~~~~ | ||
70 | */ | ||
71 | |||
72 | // LAYER_SWITCH_DELAY: prevent from moving to new layer | ||
73 | #ifndef LAYER_SWITCH_DELAY | ||
74 | # define LAYER_SWITCH_DELAY 150 | ||
75 | #endif | ||
76 | |||
77 | // LAYER_SEND_FN_TERM: send keycode if release key in this term | ||
78 | #ifndef LAYER_SEND_FN_TERM | ||
79 | # define LAYER_SEND_FN_TERM 500 | ||
80 | #endif | ||
81 | |||
82 | |||
83 | uint8_t default_layer = 0; | ||
84 | uint8_t current_layer = 0; | ||
85 | |||
86 | static bool layer_used = false; | ||
87 | static uint8_t new_layer(uint8_t fn_bits); | ||
88 | |||
89 | |||
90 | uint8_t layer_get_keycode(uint8_t row, uint8_t col) | ||
91 | { | ||
92 | uint8_t code = keymap_get_keycode(current_layer, row, col); | ||
93 | // normal key or mouse key | ||
94 | if ((IS_KEY(code) || IS_MOUSEKEY(code))) { | ||
95 | layer_used = true; | ||
96 | } | ||
97 | return code; | ||
98 | } | ||
99 | |||
100 | // bit substract b from a | ||
101 | #define BIT_SUBST(a, b) (a&(a^b)) | ||
102 | void layer_switching(uint8_t fn_bits) | ||
103 | { | ||
104 | // layer switching | ||
105 | static uint8_t last_fn = 0; | ||
106 | static uint8_t last_mods = 0; | ||
107 | static uint16_t last_timer = 0; | ||
108 | static uint8_t sent_fn = 0; | ||
109 | |||
110 | if (fn_bits == last_fn) { // Fn state is not changed | ||
111 | if (fn_bits == 0) { | ||
112 | // do nothing | ||
113 | } else { | ||
114 | if (!keymap_fn_keycode(BIT_SUBST(fn_bits, sent_fn)) || | ||
115 | timer_elapsed(last_timer) > LAYER_SWITCH_DELAY) { | ||
116 | uint8_t _layer_to_switch = new_layer(BIT_SUBST(fn_bits, sent_fn)); | ||
117 | if (current_layer != _layer_to_switch) { // not switch layer yet | ||
118 | debug("Fn case: 1,2,3(LAYER_SWITCH_DELAY passed)\n"); | ||
119 | debug("Switch Layer: "); debug_hex(current_layer); | ||
120 | current_layer = _layer_to_switch; | ||
121 | layer_used = false; | ||
122 | debug(" -> "); debug_hex(current_layer); debug("\n"); | ||
123 | } | ||
124 | } else { | ||
125 | if (host_has_anykey()) { // other keys is pressed | ||
126 | uint8_t _fn_to_send = BIT_SUBST(fn_bits, sent_fn); | ||
127 | if (_fn_to_send) { | ||
128 | debug("Fn case: 4(press other key during SWITCH_DELAY.)\n"); | ||
129 | // send only Fn key first | ||
130 | uint8_t tmp_mods = keyboard_report->mods; | ||
131 | host_add_code(keymap_fn_keycode(_fn_to_send)); | ||
132 | host_set_mods(last_mods); | ||
133 | host_send_keyboard_report(); | ||
134 | host_set_mods(tmp_mods); | ||
135 | host_del_code(keymap_fn_keycode(_fn_to_send)); | ||
136 | sent_fn |= _fn_to_send; | ||
137 | } | ||
138 | } | ||
139 | } | ||
140 | // add Fn keys to send | ||
141 | //host_add_code(keymap_fn_keycode(fn_bits&sent_fn)); // TODO: do all Fn keys | ||
142 | } | ||
143 | } else { // Fn state is changed(edge) | ||
144 | uint8_t fn_changed = 0; | ||
145 | |||
146 | debug("fn_bits: "); debug_bin(fn_bits); debug("\n"); | ||
147 | debug("sent_fn: "); debug_bin(sent_fn); debug("\n"); | ||
148 | debug("last_fn: "); debug_bin(last_fn); debug("\n"); | ||
149 | debug("last_mods: "); debug_hex(last_mods); debug("\n"); | ||
150 | debug("last_timer: "); debug_hex16(last_timer); debug("\n"); | ||
151 | debug("timer_count: "); debug_hex16(timer_count); debug("\n"); | ||
152 | |||
153 | // pressed Fn | ||
154 | if ((fn_changed = BIT_SUBST(fn_bits, last_fn))) { | ||
155 | debug("fn_changed: "); debug_bin(fn_changed); debug("\n"); | ||
156 | if (host_has_anykey()) { | ||
157 | debug("Fn case: 5(pressed Fn with other key)\n"); | ||
158 | sent_fn |= fn_changed; | ||
159 | } else if (fn_changed & sent_fn) { // pressed same Fn in a row | ||
160 | if (timer_elapsed(last_timer) > LAYER_SEND_FN_TERM) { | ||
161 | debug("Fn case: 6(not repeat)\n"); | ||
162 | // time passed: not repeate | ||
163 | sent_fn &= ~fn_changed; | ||
164 | } else { | ||
165 | debug("Fn case: 6(repeat)\n"); | ||
166 | } | ||
167 | } | ||
168 | } | ||
169 | // released Fn | ||
170 | if ((fn_changed = BIT_SUBST(last_fn, fn_bits))) { | ||
171 | debug("fn_changed: "); debug_bin(fn_changed); debug("\n"); | ||
172 | if (timer_elapsed(last_timer) < LAYER_SEND_FN_TERM) { | ||
173 | if (!layer_used && BIT_SUBST(fn_changed, sent_fn)) { | ||
174 | debug("Fn case: 2(send Fn one shot: released Fn during LAYER_SEND_FN_TERM)\n"); | ||
175 | // send only Fn key first | ||
176 | uint8_t tmp_mods = keyboard_report->mods; | ||
177 | host_add_code(keymap_fn_keycode(fn_changed)); | ||
178 | host_set_mods(last_mods); | ||
179 | host_send_keyboard_report(); | ||
180 | host_set_mods(tmp_mods); | ||
181 | host_del_code(keymap_fn_keycode(fn_changed)); | ||
182 | sent_fn |= fn_changed; | ||
183 | } | ||
184 | } | ||
185 | debug("Switch Layer(released Fn): "); debug_hex(current_layer); | ||
186 | current_layer = new_layer(BIT_SUBST(fn_bits, sent_fn)); | ||
187 | debug(" -> "); debug_hex(current_layer); debug("\n"); | ||
188 | } | ||
189 | |||
190 | layer_used = false; | ||
191 | last_fn = fn_bits; | ||
192 | last_mods = keyboard_report->mods; | ||
193 | last_timer = timer_read(); | ||
194 | } | ||
195 | // send Fn keys | ||
196 | for (uint8_t i = 0; i < 8; i++) { | ||
197 | if ((sent_fn & fn_bits) & (1<<i)) { | ||
198 | host_add_code(keymap_fn_keycode(1<<i)); | ||
199 | } | ||
200 | } | ||
201 | } | ||
202 | |||
203 | inline | ||
204 | static uint8_t new_layer(uint8_t fn_bits) | ||
205 | { | ||
206 | return (fn_bits ? keymap_fn_layer(fn_bits) : default_layer); | ||
207 | } | ||
diff --git a/common/layer.h b/common/layer.h deleted file mode 100644 index d9e8cebb8..000000000 --- a/common/layer.h +++ /dev/null | |||
@@ -1,32 +0,0 @@ | |||
1 | /* | ||
2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | ||
3 | |||
4 | This program is free software: you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation, either version 2 of the License, or | ||
7 | (at your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | #ifndef LAYER_H | ||
19 | #define LAYER_H 1 | ||
20 | |||
21 | #include <stdint.h> | ||
22 | |||
23 | extern uint8_t default_layer; | ||
24 | extern uint8_t current_layer; | ||
25 | |||
26 | /* return keycode for switch */ | ||
27 | uint8_t layer_get_keycode(uint8_t row, uint8_t col); | ||
28 | |||
29 | /* process layer switching */ | ||
30 | void layer_switching(uint8_t fn_bits); | ||
31 | |||
32 | #endif | ||
diff --git a/common/matrix.h b/common/matrix.h index c4b2cab51..b3332d5ff 100644 --- a/common/matrix.h +++ b/common/matrix.h | |||
@@ -18,8 +18,23 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
18 | #ifndef MATRIX_H | 18 | #ifndef MATRIX_H |
19 | #define MATRIX_H | 19 | #define MATRIX_H |
20 | 20 | ||
21 | #include <stdint.h> | ||
21 | #include <stdbool.h> | 22 | #include <stdbool.h> |
22 | 23 | ||
24 | |||
25 | #if (MATRIX_COLS <= 8) | ||
26 | typedef uint8_t matrix_row_t; | ||
27 | #elif (MATRIX_COLS <= 16) | ||
28 | typedef uint16_t matrix_row_t; | ||
29 | #elif (MATRIX_COLS <= 32) | ||
30 | typedef uint32_t matrix_row_t; | ||
31 | #else | ||
32 | #error "MATRIX_COLS: invalid value" | ||
33 | #endif | ||
34 | |||
35 | #define MATRIX_IS_ON(row, col) (matrix_get_row(row) && (1<<col)) | ||
36 | |||
37 | |||
23 | /* number of matrix rows */ | 38 | /* number of matrix rows */ |
24 | uint8_t matrix_rows(void); | 39 | uint8_t matrix_rows(void); |
25 | /* number of matrix columns */ | 40 | /* number of matrix columns */ |
@@ -35,11 +50,7 @@ bool matrix_has_ghost(void); | |||
35 | /* whether a swtich is on */ | 50 | /* whether a swtich is on */ |
36 | bool matrix_is_on(uint8_t row, uint8_t col); | 51 | bool matrix_is_on(uint8_t row, uint8_t col); |
37 | /* matrix state on row */ | 52 | /* matrix state on row */ |
38 | #if (MATRIX_COLS <= 8) | 53 | matrix_row_t matrix_get_row(uint8_t row); |
39 | uint8_t matrix_get_row(uint8_t row); | ||
40 | #else | ||
41 | uint16_t matrix_get_row(uint8_t row); | ||
42 | #endif | ||
43 | /* count keys pressed */ | 54 | /* count keys pressed */ |
44 | uint8_t matrix_key_count(void); | 55 | uint8_t matrix_key_count(void); |
45 | /* print matrix for debug */ | 56 | /* print matrix for debug */ |
diff --git a/common/mousekey.c b/common/mousekey.c index 1d35355b4..7f8e860aa 100644 --- a/common/mousekey.c +++ b/common/mousekey.c | |||
@@ -26,7 +26,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
26 | 26 | ||
27 | 27 | ||
28 | static report_mouse_t report; | 28 | static report_mouse_t report; |
29 | static report_mouse_t report_prev; | ||
30 | 29 | ||
31 | static uint8_t mousekey_repeat = 0; | 30 | static uint8_t mousekey_repeat = 0; |
32 | 31 | ||
@@ -38,84 +37,111 @@ static void mousekey_debug(void); | |||
38 | * see wikipedia http://en.wikipedia.org/wiki/Mouse_keys | 37 | * see wikipedia http://en.wikipedia.org/wiki/Mouse_keys |
39 | */ | 38 | */ |
40 | #ifndef MOUSEKEY_DELAY_TIME | 39 | #ifndef MOUSEKEY_DELAY_TIME |
41 | # define MOUSEKEY_DELAY_TIME 255 | 40 | # define MOUSEKEY_DELAY_TIME 20 |
42 | #endif | 41 | #endif |
43 | 42 | ||
43 | #define MOUSEKEY_MOVE_INIT 5 | ||
44 | #define MOUSEKEY_WHEEL_INIT 1 | ||
45 | #define MOUSEKEY_MOVE_ACCEL 5 | ||
46 | #define MOUSEKEY_WHEEL_ACCEL 1 | ||
47 | |||
48 | static uint16_t last_timer = 0; | ||
49 | |||
44 | // acceleration parameters | 50 | // acceleration parameters |
45 | uint8_t mousekey_move_unit = 2; | 51 | //uint8_t mousekey_move_unit = 2; |
46 | uint8_t mousekey_resolution = 5; | 52 | //uint8_t mousekey_resolution = 5; |
47 | 53 | ||
48 | 54 | ||
49 | static inline uint8_t move_unit(void) | 55 | static inline uint8_t move_unit(void) |
50 | { | 56 | { |
51 | uint16_t unit = 5 + mousekey_repeat*2; | 57 | uint16_t unit = 5 + mousekey_repeat*4; |
52 | return (unit > 63 ? 63 : unit); | 58 | return (unit > 63 ? 63 : unit); |
53 | } | 59 | } |
54 | 60 | ||
55 | void mousekey_decode(uint8_t code) | 61 | void mousekey_task(void) |
56 | { | ||
57 | if (code == KB_MS_UP) report.y = -move_unit(); | ||
58 | else if (code == KB_MS_DOWN) report.y = move_unit(); | ||
59 | else if (code == KB_MS_LEFT) report.x = -move_unit(); | ||
60 | else if (code == KB_MS_RIGHT) report.x = move_unit(); | ||
61 | else if (code == KB_MS_BTN1) report.buttons |= MOUSE_BTN1; | ||
62 | else if (code == KB_MS_BTN2) report.buttons |= MOUSE_BTN2; | ||
63 | else if (code == KB_MS_BTN3) report.buttons |= MOUSE_BTN3; | ||
64 | else if (code == KB_MS_BTN4) report.buttons |= MOUSE_BTN4; | ||
65 | else if (code == KB_MS_BTN5) report.buttons |= MOUSE_BTN5; | ||
66 | else if (code == KB_MS_WH_UP) report.v += move_unit()/4; | ||
67 | else if (code == KB_MS_WH_DOWN) report.v -= move_unit()/4; | ||
68 | else if (code == KB_MS_WH_LEFT) report.h -= move_unit()/4; | ||
69 | else if (code == KB_MS_WH_RIGHT)report.h += move_unit()/4; | ||
70 | } | ||
71 | |||
72 | bool mousekey_changed(void) | ||
73 | { | ||
74 | return (report.buttons != report_prev.buttons || | ||
75 | report.x || report.y || report.v || report.h); | ||
76 | } | ||
77 | |||
78 | void mousekey_send(void) | ||
79 | { | 62 | { |
80 | static uint16_t last_timer = 0; | 63 | if (timer_elapsed(last_timer) < MOUSEKEY_DELAY_TIME) |
81 | |||
82 | if (!mousekey_changed()) { | ||
83 | mousekey_repeat = 0; | ||
84 | mousekey_clear_report(); | ||
85 | return; | 64 | return; |
86 | } | ||
87 | 65 | ||
88 | // send immediately when buttun state is changed | 66 | if (report.x == 0 && report.y == 0 && report.v == 0 && report.h == 0) |
89 | if (report.buttons == report_prev.buttons) { | 67 | return; |
90 | if (timer_elapsed(last_timer) < 100) { | ||
91 | mousekey_clear_report(); | ||
92 | return; | ||
93 | } | ||
94 | } | ||
95 | 68 | ||
96 | if (mousekey_repeat != 0xFF) { | 69 | if (mousekey_repeat != UINT8_MAX) |
97 | mousekey_repeat++; | 70 | mousekey_repeat++; |
98 | } | 71 | |
72 | |||
73 | if (report.x > 0) report.x = move_unit(); | ||
74 | if (report.x < 0) report.x = move_unit() * -1; | ||
75 | if (report.y > 0) report.y = move_unit(); | ||
76 | if (report.y < 0) report.y = move_unit() * -1; | ||
99 | 77 | ||
100 | if (report.x && report.y) { | 78 | if (report.x && report.y) { |
101 | report.x *= 0.7; | 79 | report.x *= 0.7; |
102 | report.y *= 0.7; | 80 | report.y *= 0.7; |
103 | } | 81 | } |
104 | 82 | ||
83 | if (report.v > 0) report.v = move_unit(); | ||
84 | if (report.v < 0) report.v = move_unit() * -1; | ||
85 | if (report.h > 0) report.h = move_unit(); | ||
86 | if (report.h < 0) report.h = move_unit() * -1; | ||
87 | |||
88 | mousekey_send(); | ||
89 | } | ||
90 | |||
91 | void mousekey_on(uint8_t code) | ||
92 | { | ||
93 | if (code == KB_MS_UP) report.y = MOUSEKEY_MOVE_INIT * -1; | ||
94 | else if (code == KB_MS_DOWN) report.y = MOUSEKEY_MOVE_INIT; | ||
95 | else if (code == KB_MS_LEFT) report.x = MOUSEKEY_MOVE_INIT * -1; | ||
96 | else if (code == KB_MS_RIGHT) report.x = MOUSEKEY_MOVE_INIT; | ||
97 | else if (code == KB_MS_WH_UP) report.v = MOUSEKEY_WHEEL_INIT; | ||
98 | else if (code == KB_MS_WH_DOWN) report.v = MOUSEKEY_WHEEL_INIT * -1; | ||
99 | else if (code == KB_MS_WH_LEFT) report.h = MOUSEKEY_WHEEL_INIT * -1; | ||
100 | else if (code == KB_MS_WH_RIGHT) report.h = MOUSEKEY_WHEEL_INIT; | ||
101 | else if (code == KB_MS_BTN1) report.buttons |= MOUSE_BTN1; | ||
102 | else if (code == KB_MS_BTN2) report.buttons |= MOUSE_BTN2; | ||
103 | else if (code == KB_MS_BTN3) report.buttons |= MOUSE_BTN3; | ||
104 | else if (code == KB_MS_BTN4) report.buttons |= MOUSE_BTN4; | ||
105 | else if (code == KB_MS_BTN5) report.buttons |= MOUSE_BTN5; | ||
106 | } | ||
107 | |||
108 | void mousekey_off(uint8_t code) | ||
109 | { | ||
110 | if (code == KB_MS_UP && report.y < 0) report.y = 0; | ||
111 | else if (code == KB_MS_DOWN && report.y > 0) report.y = 0; | ||
112 | else if (code == KB_MS_LEFT && report.x < 0) report.x = 0; | ||
113 | else if (code == KB_MS_RIGHT && report.x > 0) report.x = 0; | ||
114 | else if (code == KB_MS_WH_UP && report.v > 0) report.v = 0; | ||
115 | else if (code == KB_MS_WH_DOWN && report.v < 0) report.v = 0; | ||
116 | else if (code == KB_MS_WH_LEFT && report.h < 0) report.h = 0; | ||
117 | else if (code == KB_MS_WH_RIGHT && report.h > 0) report.h = 0; | ||
118 | else if (code == KB_MS_BTN1) report.buttons &= ~MOUSE_BTN1; | ||
119 | else if (code == KB_MS_BTN2) report.buttons &= ~MOUSE_BTN2; | ||
120 | else if (code == KB_MS_BTN3) report.buttons &= ~MOUSE_BTN3; | ||
121 | else if (code == KB_MS_BTN4) report.buttons &= ~MOUSE_BTN4; | ||
122 | else if (code == KB_MS_BTN5) report.buttons &= ~MOUSE_BTN5; | ||
123 | |||
124 | if (report.x == 0 && report.y == 0 && report.v == 0 && report.h == 0) | ||
125 | mousekey_repeat = 0; | ||
126 | } | ||
127 | |||
128 | void mousekey_send(void) | ||
129 | { | ||
105 | mousekey_debug(); | 130 | mousekey_debug(); |
106 | host_mouse_send(&report); | 131 | host_mouse_send(&report); |
107 | report_prev = report; | ||
108 | last_timer = timer_read(); | 132 | last_timer = timer_read(); |
109 | mousekey_clear_report(); | ||
110 | } | 133 | } |
111 | 134 | ||
112 | void mousekey_clear_report(void) | 135 | void mousekey_clear(void) |
113 | { | 136 | { |
137 | report = (report_mouse_t){}; | ||
138 | /* | ||
114 | report.buttons = 0; | 139 | report.buttons = 0; |
115 | report.x = 0; | 140 | report.x = 0; |
116 | report.y = 0; | 141 | report.y = 0; |
117 | report.v = 0; | 142 | report.v = 0; |
118 | report.h = 0; | 143 | report.h = 0; |
144 | */ | ||
119 | } | 145 | } |
120 | 146 | ||
121 | static void mousekey_debug(void) | 147 | static void mousekey_debug(void) |
diff --git a/common/mousekey.h b/common/mousekey.h index c2c24e9fa..3006c4634 100644 --- a/common/mousekey.h +++ b/common/mousekey.h | |||
@@ -21,9 +21,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
21 | #include <stdbool.h> | 21 | #include <stdbool.h> |
22 | #include "host.h" | 22 | #include "host.h" |
23 | 23 | ||
24 | void mousekey_decode(uint8_t code); | 24 | void mousekey_task(void); |
25 | bool mousekey_changed(void); | 25 | void mousekey_on(uint8_t code); |
26 | void mousekey_off(uint8_t code); | ||
27 | void mousekey_clear(void); | ||
26 | void mousekey_send(void); | 28 | void mousekey_send(void); |
27 | void mousekey_clear_report(void); | ||
28 | 29 | ||
29 | #endif | 30 | #endif |
diff --git a/common/timer.c b/common/timer.c index 8b8d37e8b..e0dec6cef 100644 --- a/common/timer.c +++ b/common/timer.c | |||
@@ -22,6 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
22 | 22 | ||
23 | 23 | ||
24 | // counter resolution 1ms | 24 | // counter resolution 1ms |
25 | // NOTE: union { uint32_t timer32; struct { uint16_t dummy; uint16_t timer16; }} | ||
25 | volatile uint32_t timer_count = 0; | 26 | volatile uint32_t timer_count = 0; |
26 | 27 | ||
27 | void timer_init(void) | 28 | void timer_init(void) |
diff --git a/common/usb_keycodes.h b/common/usb_keycodes.h index 04b398fa2..61d6bf002 100644 --- a/common/usb_keycodes.h +++ b/common/usb_keycodes.h | |||
@@ -33,8 +33,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
33 | #define IS_MOUSEKEY_BUTTON(code) (KB_MS_BTN1 <= (code) && (code) <= KB_MS_BTN5) | 33 | #define IS_MOUSEKEY_BUTTON(code) (KB_MS_BTN1 <= (code) && (code) <= KB_MS_BTN5) |
34 | #define IS_MOUSEKEY_WHEEL(code) (KB_MS_WH_UP <= (code) && (code) <= KB_MS_WH_RIGHT) | 34 | #define IS_MOUSEKEY_WHEEL(code) (KB_MS_WH_UP <= (code) && (code) <= KB_MS_WH_RIGHT) |
35 | 35 | ||
36 | #define MOD_BIT(code) (1<<((code) & 0x07)) | 36 | #define MOD_BIT(code) (1<<((code) & 0x07)) |
37 | #define FN_BIT(code) (1<<((code) - KB_FN0)) | 37 | #define FN_BIT(code) (1<<((code) - KB_FN0)) |
38 | #define FN_INDEX(code) ((code) - KB_FN0) | ||
38 | 39 | ||
39 | 40 | ||
40 | /* Short names */ | 41 | /* Short names */ |
diff --git a/common/util.c b/common/util.c index 36afdd447..644301fe8 100644 --- a/common/util.c +++ b/common/util.c | |||
@@ -17,19 +17,23 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
17 | 17 | ||
18 | #include "util.h" | 18 | #include "util.h" |
19 | 19 | ||
20 | // bit population | 20 | // bit population - return number of on-bit |
21 | int bitpop(uint8_t bits) | 21 | uint8_t bitpop(uint8_t bits) |
22 | { | 22 | { |
23 | int c; | 23 | uint8_t c; |
24 | for (c = 0; bits; c++) | 24 | for (c = 0; bits; c++) |
25 | bits &= bits -1; | 25 | bits &= bits -1; |
26 | return c; | 26 | return c; |
27 | /* | ||
28 | const uint8_t bit_count[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; | ||
29 | return bit_count[bits>>4] + bit_count[bits&0x0F] | ||
30 | */ | ||
27 | } | 31 | } |
28 | 32 | ||
29 | // most significant on-bit | 33 | // most significant on-bit - return highest location of on-bit |
30 | int biton(uint8_t bits) | 34 | uint8_t biton(uint8_t bits) |
31 | { | 35 | { |
32 | int n = 0; | 36 | uint8_t n = 0; |
33 | if (bits >> 4) { bits >>= 4; n += 4;} | 37 | if (bits >> 4) { bits >>= 4; n += 4;} |
34 | if (bits >> 2) { bits >>= 2; n += 2;} | 38 | if (bits >> 2) { bits >>= 2; n += 2;} |
35 | if (bits >> 1) { bits >>= 1; n += 1;} | 39 | if (bits >> 1) { bits >>= 1; n += 1;} |
diff --git a/common/util.h b/common/util.h index 66bccbfa5..87636c971 100644 --- a/common/util.h +++ b/common/util.h | |||
@@ -28,7 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
28 | #define XSTR(s) #s | 28 | #define XSTR(s) #s |
29 | 29 | ||
30 | 30 | ||
31 | int bitpop(uint8_t bits); | 31 | uint8_t bitpop(uint8_t bits); |
32 | int biton(uint8_t bits); | 32 | uint8_t biton(uint8_t bits); |
33 | 33 | ||
34 | #endif | 34 | #endif |
diff --git a/keyboard/hhkb/config.h b/keyboard/hhkb/config.h index bf946ac01..17a449406 100644 --- a/keyboard/hhkb/config.h +++ b/keyboard/hhkb/config.h | |||
@@ -35,8 +35,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
35 | /* matrix size */ | 35 | /* matrix size */ |
36 | #define MATRIX_ROWS 8 | 36 | #define MATRIX_ROWS 8 |
37 | #define MATRIX_COLS 8 | 37 | #define MATRIX_COLS 8 |
38 | /* define if matrix has ghost */ | ||
39 | //#define MATRIX_HAS_GHOST | ||
40 | 38 | ||
41 | 39 | ||
42 | /* key combination for command */ | 40 | /* key combination for command */ |
diff --git a/keyboard/hhkb/keymap.c b/keyboard/hhkb/keymap.c index f05962aed..43f777c56 100644 --- a/keyboard/hhkb/keymap.c +++ b/keyboard/hhkb/keymap.c | |||
@@ -210,12 +210,12 @@ uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col) | |||
210 | return KEYCODE(layer, row, col); | 210 | return KEYCODE(layer, row, col); |
211 | } | 211 | } |
212 | 212 | ||
213 | uint8_t keymap_fn_layer(uint8_t fn_bits) | 213 | uint8_t keymap_fn_layer(uint8_t index) |
214 | { | 214 | { |
215 | return pgm_read_byte(&fn_layer[biton(fn_bits)]); | 215 | return pgm_read_byte(&fn_layer[index]); |
216 | } | 216 | } |
217 | 217 | ||
218 | uint8_t keymap_fn_keycode(uint8_t fn_bits) | 218 | uint8_t keymap_fn_keycode(uint8_t index) |
219 | { | 219 | { |
220 | return pgm_read_byte(&fn_keycode[(biton(fn_bits))]); | 220 | return pgm_read_byte(&fn_keycode[index]); |
221 | } | 221 | } |
diff --git a/keyboard/hhkb/matrix.c b/keyboard/hhkb/matrix.c index 79d2d9873..3bd6e73b3 100644 --- a/keyboard/hhkb/matrix.c +++ b/keyboard/hhkb/matrix.c | |||
@@ -43,22 +43,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
43 | 43 | ||
44 | 44 | ||
45 | // matrix state buffer(1:on, 0:off) | 45 | // matrix state buffer(1:on, 0:off) |
46 | #if (MATRIX_COLS <= 8) | 46 | static matrix_row_t *matrix; |
47 | static uint8_t *matrix; | 47 | static matrix_row_t *matrix_prev; |
48 | static uint8_t *matrix_prev; | 48 | static matrix_row_t _matrix0[MATRIX_ROWS]; |
49 | static uint8_t _matrix0[MATRIX_ROWS]; | 49 | static matrix_row_t _matrix1[MATRIX_ROWS]; |
50 | static uint8_t _matrix1[MATRIX_ROWS]; | ||
51 | #else | ||
52 | static uint16_t *matrix; | ||
53 | static uint16_t *matrix_prev; | ||
54 | static uint16_t _matrix0[MATRIX_ROWS]; | ||
55 | static uint16_t _matrix1[MATRIX_ROWS]; | ||
56 | #endif | ||
57 | |||
58 | // HHKB has no ghost and no bounce. | ||
59 | #ifdef MATRIX_HAS_GHOST | ||
60 | static bool matrix_has_ghost_in_row(uint8_t row); | ||
61 | #endif | ||
62 | 50 | ||
63 | 51 | ||
64 | // Matrix I/O ports | 52 | // Matrix I/O ports |
@@ -192,6 +180,8 @@ uint8_t matrix_scan(void) | |||
192 | } | 180 | } |
193 | 181 | ||
194 | // Ignore if this code region execution time elapses more than 20us. | 182 | // Ignore if this code region execution time elapses more than 20us. |
183 | // MEMO: 20[us] * (TIMER_RAW_FREQ / 1000000)[count per us] | ||
184 | // MEMO: then change above using this rule: a/(b/c) = a*1/(b/c) = a*(c/b) | ||
195 | if (TIMER_DIFF_RAW(TIMER_RAW, last) > 20/(1000000/TIMER_RAW_FREQ)) { | 185 | if (TIMER_DIFF_RAW(TIMER_RAW, last) > 20/(1000000/TIMER_RAW_FREQ)) { |
196 | matrix[row] = matrix_prev[row]; | 186 | matrix[row] = matrix_prev[row]; |
197 | } | 187 | } |
@@ -219,12 +209,6 @@ bool matrix_is_modified(void) | |||
219 | inline | 209 | inline |
220 | bool matrix_has_ghost(void) | 210 | bool matrix_has_ghost(void) |
221 | { | 211 | { |
222 | #ifdef MATRIX_HAS_GHOST | ||
223 | for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | ||
224 | if (matrix_has_ghost_in_row(i)) | ||
225 | return true; | ||
226 | } | ||
227 | #endif | ||
228 | return false; | 212 | return false; |
229 | } | 213 | } |
230 | 214 | ||
@@ -258,11 +242,6 @@ void matrix_print(void) | |||
258 | #else | 242 | #else |
259 | pbin_reverse16(matrix_get_row(row)); | 243 | pbin_reverse16(matrix_get_row(row)); |
260 | #endif | 244 | #endif |
261 | #ifdef MATRIX_HAS_GHOST | ||
262 | if (matrix_has_ghost_in_row(row)) { | ||
263 | print(" <ghost"); | ||
264 | } | ||
265 | #endif | ||
266 | print("\n"); | 245 | print("\n"); |
267 | } | 246 | } |
268 | } | 247 | } |
@@ -279,20 +258,3 @@ uint8_t matrix_key_count(void) | |||
279 | } | 258 | } |
280 | return count; | 259 | return count; |
281 | } | 260 | } |
282 | |||
283 | #ifdef MATRIX_HAS_GHOST | ||
284 | inline | ||
285 | static bool matrix_has_ghost_in_row(uint8_t row) | ||
286 | { | ||
287 | // no ghost exists in case less than 2 keys on | ||
288 | if (((matrix[row] - 1) & matrix[row]) == 0) | ||
289 | return false; | ||
290 | |||
291 | // ghost exists in case same state as other row | ||
292 | for (uint8_t i=0; i < MATRIX_ROWS; i++) { | ||
293 | if (i != row && (matrix[i] & matrix[row]) == matrix[row]) | ||
294 | return true; | ||
295 | } | ||
296 | return false; | ||
297 | } | ||
298 | #endif | ||
diff --git a/protocol/lufa/lufa.c b/protocol/lufa/lufa.c index ff3413227..bff1f5e8b 100644 --- a/protocol/lufa/lufa.c +++ b/protocol/lufa/lufa.c | |||
@@ -475,7 +475,7 @@ int main(void) | |||
475 | keyboard_init(); | 475 | keyboard_init(); |
476 | host_set_driver(&lufa_driver); | 476 | host_set_driver(&lufa_driver); |
477 | while (1) { | 477 | while (1) { |
478 | keyboard_proc(); | 478 | keyboard_task(); |
479 | 479 | ||
480 | #if !defined(INTERRUPT_CONTROL_ENDPOINT) | 480 | #if !defined(INTERRUPT_CONTROL_ENDPOINT) |
481 | USB_USBTask(); | 481 | USB_USBTask(); |