]> git.donarmstrong.com Git - tmk_firmware.git/blob - common/command.c
Add command console and mouseky parameters tweak.
[tmk_firmware.git] / common / command.c
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 #include <stdint.h>
18 #include <stdbool.h>
19 #include <util/delay.h>
20 #include "keycode.h"
21 #include "host.h"
22 #include "print.h"
23 #include "debug.h"
24 #include "util.h"
25 #include "timer.h"
26 #include "keyboard.h"
27 #include "bootloader.h"
28 #include "command.h"
29 #ifdef MOUSEKEY_ENABLE
30 #include "mousekey.h"
31 #endif
32
33 #ifdef HOST_PJRC
34 #   include "usb_keyboard.h"
35 #   ifdef EXTRAKEY_ENABLE
36 #       include "usb_extra.h"
37 #   endif
38 #endif
39
40 #ifdef HOST_VUSB
41 #   include "usbdrv.h"
42 #endif
43
44
45 static bool command_common(uint8_t code);
46 static void command_common_help(void);
47 static bool command_console(uint8_t code);
48 static void command_console_help(void);
49 static bool mousekey_console(uint8_t code);
50 static void mousekey_console_help(void);
51
52 static uint8_t kc2int(uint8_t code);
53 static void switch_layer(uint8_t layer);
54 static void clear_keyboard(void);
55
56
57 typedef enum { ONESHOT, CONSOLE, MOUSEKEY } cmdstate_t;
58 static cmdstate_t state = ONESHOT;
59
60
61 bool command_proc(uint8_t code)
62 {
63     switch (state) {
64         case ONESHOT:
65             if (!IS_COMMAND())
66                 return false;
67             return (command_extra(code) || command_common(code));
68         case CONSOLE:
69             command_console(code);
70             break;
71         case MOUSEKEY:
72             mousekey_console(code);
73             break;
74         default:
75             state = ONESHOT;
76             return false;
77     }
78     return true;
79 }
80
81 /* This allows to define extra commands. return false when not processed. */
82 bool command_extra(uint8_t code) __attribute__ ((weak));
83 bool command_extra(uint8_t code)
84 {
85     return false;
86 }
87
88
89 /***********************************************************
90  * Command common
91  ***********************************************************/
92 static void command_common_help(void)
93 {
94     print_enable = true;
95     print("\n\n----- Command Help -----\n");
96     print("c:   enter console mode\n");
97     print("d:   toggle debug enable\n");
98     print("x:   toggle matrix debug\n");
99     print("k:   toggle keyboard debug\n");
100     print("m:   toggle mouse debug\n");
101     print("p:   toggle print enable\n");
102     print("v:   print device version & info\n");
103     print("t:   print timer count\n");
104     print("s:   print status\n");
105 #ifdef NKRO_ENABLE
106     print("n:   toggle NKRO\n");
107 #endif
108     print("0/F10:       switch to Layer0 \n");
109     print("1/F1:        switch to Layer1 \n");
110     print("2/F2:        switch to Layer2 \n");
111     print("3/F3:        switch to Layer3 \n");
112     print("4/F4:        switch to Layer4 \n");
113     print("PScr:        power down/remote wake-up\n");
114     print("Paus:        jump to bootloader\n");
115 }
116
117 static bool command_common(uint8_t code)
118 {
119     switch (code) {
120         case KC_H:
121         case KC_SLASH: /* ? */
122             command_common_help();
123             break;
124         case KC_C:
125             print_enable = true;
126             debug_matrix   = false;
127             debug_keyboard = false;
128             debug_mouse    = false;
129             debug_enable   = false;
130             command_console_help();
131             print("\nEnter Console Mode\n");
132             print("C> ");
133             state = CONSOLE;
134             break;
135         case KC_PAUSE:
136             clear_keyboard();
137             print("\n\nJump to bootloader... ");
138             _delay_ms(1000);
139             bootloader_jump(); // not return
140             print("not supported.\n");
141             break;
142         case KC_D:
143             if (debug_enable) {
144                 print("\nDEBUG: disabled.\n");
145                 debug_matrix   = false;
146                 debug_keyboard = false;
147                 debug_mouse    = false;
148                 debug_enable   = false;
149             } else {
150                 print("\nDEBUG: enabled.\n");
151                 debug_matrix   = true;
152                 debug_keyboard = true;
153                 debug_mouse    = true;
154                 debug_enable   = true;
155             }
156             break;
157         case KC_X: // debug matrix toggle
158             debug_matrix = !debug_matrix;
159             if (debug_matrix) {
160                 print("\nDEBUG: matrix enabled.\n");
161                 debug_enable = true;
162             } else {
163                 print("\nDEBUG: matrix disabled.\n");
164             }
165             break;
166         case KC_K: // debug keyboard toggle
167             debug_keyboard = !debug_keyboard;
168             if (debug_keyboard) {
169                 print("\nDEBUG: keyboard enabled.\n");
170                 debug_enable = true;
171             } else {
172                 print("\nDEBUG: keyboard disabled.\n");
173             }
174             break;
175         case KC_M: // debug mouse toggle
176             debug_mouse = !debug_mouse;
177             if (debug_mouse) {
178                 print("\nDEBUG: mouse enabled.\n");
179                 debug_enable = true;
180             } else {
181                 print("\nDEBUG: mouse disabled.\n");
182             }
183             break;
184         case KC_V: // print version & information
185             print("\n\n----- Version -----\n");
186             print(STR(DESCRIPTION) "\n");
187             print(STR(MANUFACTURER) "(" STR(VENDOR_ID) ")/");
188             print(STR(PRODUCT) "(" STR(PRODUCT_ID) ") ");
189             print("VERSION: " STR(DEVICE_VER) "\n");
190             break;
191         case KC_T: // print timer
192             print("timer: "); phex16(timer_count>>16); phex16(timer_count); print("\n");
193             break;
194         case KC_P: // print toggle
195             if (print_enable) {
196                 print("print disabled.\n");
197                 print_enable = false;
198             } else {
199                 print_enable = true;
200                 print("print enabled.\n");
201             }
202             break;
203         case KC_S:
204             print("\n\n----- Status -----\n");
205             print("host_keyboard_leds:"); phex(host_keyboard_leds()); print("\n");
206 #ifdef HOST_PJRC
207             print("UDCON: "); phex(UDCON); print("\n");
208             print("UDIEN: "); phex(UDIEN); print("\n");
209             print("UDINT: "); phex(UDINT); print("\n");
210             print("usb_keyboard_leds:"); phex(usb_keyboard_leds); print("\n");
211             print("usb_keyboard_protocol: "); phex(usb_keyboard_protocol); print("\n");
212             print("usb_keyboard_idle_config:"); phex(usb_keyboard_idle_config); print("\n");
213             print("usb_keyboard_idle_count:"); phex(usb_keyboard_idle_count); print("\n");
214 #endif
215
216 #ifdef HOST_VUSB
217 #   if USB_COUNT_SOF
218             print("usbSofCount: "); phex(usbSofCount); print("\n");
219 #   endif
220 #endif
221             break;
222 #ifdef NKRO_ENABLE
223         case KC_N:
224             keyboard_nkro = !keyboard_nkro;
225             if (keyboard_nkro)
226                 print("NKRO: enabled\n");
227             else
228                 print("NKRO: disabled\n");
229             break;
230 #endif
231 #ifdef EXTRAKEY_ENABLE
232         case KC_PSCREEN:
233             // TODO: Power key should take this feature? otherwise any key during suspend.
234 #ifdef HOST_PJRC
235             if (suspend && remote_wakeup) {
236                 usb_remote_wakeup();
237             } else {
238                 host_system_send(SYSTEM_POWER_DOWN);
239                 host_system_send(0);
240                 _delay_ms(500);
241             }
242 #else
243             host_system_send(SYSTEM_POWER_DOWN);
244             host_system_send(0);
245             _delay_ms(500);
246 #endif
247             break;
248 #endif
249         case KC_0:
250         case KC_F10:
251             switch_layer(0);
252             break;
253         case KC_1:
254         case KC_F1:
255             switch_layer(1);
256             break;
257         case KC_2:
258         case KC_F2:
259             switch_layer(2);
260             break;
261         case KC_3:
262         case KC_F3:
263             switch_layer(3);
264             break;
265         case KC_4:
266         case KC_F4:
267             switch_layer(4);
268             break;
269         default:
270             print("?");
271             return false;
272     }
273     return true;
274 }
275
276
277 /***********************************************************
278  * Command console
279  ***********************************************************/
280 static void command_console_help(void)
281 {
282     print_enable = true;
283     print("\n\n----- Console Help -----\n");
284     print("ESC/q:       quit\n");
285 #ifdef MOUSEKEY_ENABLE
286     print("m:   mousekey\n");
287 #endif
288 }
289
290 static bool command_console(uint8_t code)
291 {
292     switch (code) {
293         case KC_H:
294         case KC_SLASH: /* ? */
295             command_console_help();
296             break;
297         case KC_Q:
298         case KC_ESC:
299             print("\nQuit Console Mode\n");
300             state = ONESHOT;
301             return false;
302 #ifdef MOUSEKEY_ENABLE
303         case KC_M:
304             mousekey_console_help();
305             print("\nEnter Mousekey Console\n");
306             print("M0>");
307             state = MOUSEKEY;
308             return true;
309 #endif
310         default:
311             print("?");
312             return false;
313     }
314     print("C> ");
315     return true;
316 }
317
318
319 #ifdef MOUSEKEY_ENABLE
320 /***********************************************************
321  * Mousekey console
322  ***********************************************************/
323 static uint8_t mousekey_param = 0;
324
325 static void mousekey_param_print(void)
326 {
327     print("\n\n----- Mousekey Parameters -----\n");
328     print("1: mk_delay(*10ms): "); pdec(mk_delay); print("\n");
329     print("2: mk_interval(ms): "); pdec(mk_interval); print("\n");
330     print("3: mk_max_speed: "); pdec(mk_max_speed); print("\n");
331     print("4: mk_time_to_max: "); pdec(mk_time_to_max); print("\n");
332     print("5: mk_wheel_max_speed: "); pdec(mk_wheel_max_speed); print("\n");
333     print("6: mk_wheel_time_to_max: "); pdec(mk_wheel_time_to_max); print("\n");
334 }
335
336 static void mousekey_param_inc(uint8_t param, uint8_t inc)
337 {
338     switch (param) {
339         case 1:
340             if (mk_delay + inc < UINT8_MAX)
341                 mk_delay += inc;
342             else
343                 mk_delay = UINT8_MAX;
344             print("mk_delay = "); pdec(mk_delay); print("\n");
345             break;
346         case 2:
347             if (mk_interval + inc < UINT8_MAX)
348                 mk_interval += inc;
349             else
350                 mk_interval = UINT8_MAX;
351             print("mk_interval = "); pdec(mk_interval); print("\n");
352             break;
353         case 3:
354             if (mk_max_speed + inc < UINT8_MAX)
355                 mk_max_speed += inc;
356             else
357                 mk_max_speed = UINT8_MAX;
358             print("mk_max_speed = "); pdec(mk_max_speed); print("\n");
359             break;
360         case 4:
361             if (mk_time_to_max + inc < UINT8_MAX)
362                 mk_time_to_max += inc;
363             else
364                 mk_time_to_max = UINT8_MAX;
365             print("mk_time_to_max = "); pdec(mk_time_to_max); print("\n");
366             break;
367         case 5:
368             if (mk_wheel_max_speed + inc < UINT8_MAX)
369                 mk_wheel_max_speed += inc;
370             else
371                 mk_wheel_max_speed = UINT8_MAX;
372             print("mk_wheel_max_speed = "); pdec(mk_wheel_max_speed); print("\n");
373             break;
374         case 6:
375             if (mk_wheel_time_to_max + inc < UINT8_MAX)
376                 mk_wheel_time_to_max += inc;
377             else
378                 mk_wheel_time_to_max = UINT8_MAX;
379             print("mk_wheel_time_to_max = "); pdec(mk_wheel_time_to_max); print("\n");
380             break;
381     }
382 }
383
384 static void mousekey_param_dec(uint8_t param, uint8_t dec)
385 {
386     switch (param) {
387         case 1:
388             if (mk_delay > dec)
389                 mk_delay -= dec;
390             else
391                 mk_delay = 0;
392             print("mk_delay = "); pdec(mk_delay); print("\n");
393             break;
394         case 2:
395             if (mk_interval > dec)
396                 mk_interval -= dec;
397             else
398                 mk_interval = 0;
399             print("mk_interval = "); pdec(mk_interval); print("\n");
400             break;
401         case 3:
402             if (mk_max_speed > dec)
403                 mk_max_speed -= dec;
404             else
405                 mk_max_speed = 0;
406             print("mk_max_speed = "); pdec(mk_max_speed); print("\n");
407             break;
408         case 4:
409             if (mk_time_to_max > dec)
410                 mk_time_to_max -= dec;
411             else
412                 mk_time_to_max = 0;
413             print("mk_time_to_max = "); pdec(mk_time_to_max); print("\n");
414             break;
415         case 5:
416             if (mk_wheel_max_speed > dec)
417                 mk_wheel_max_speed -= dec;
418             else
419                 mk_wheel_max_speed = 0;
420             print("mk_wheel_max_speed = "); pdec(mk_wheel_max_speed); print("\n");
421             break;
422         case 6:
423             if (mk_wheel_time_to_max > dec)
424                 mk_wheel_time_to_max -= dec;
425             else
426                 mk_wheel_time_to_max = 0;
427             print("mk_wheel_time_to_max = "); pdec(mk_wheel_time_to_max); print("\n");
428             break;
429     }
430 }
431
432 static void mousekey_console_help(void)
433 {
434     print("\n\n----- Mousekey Parameters Help -----\n");
435     print("ESC/q:       quit\n");
436     print("1:   select mk_delay(*10ms)\n");
437     print("2:   select mk_interval(ms)\n");
438     print("3:   select mk_max_speed\n");
439     print("4:   select mk_time_to_max\n");
440     print("5:   select mk_wheel_max_speed\n");
441     print("6:   select mk_wheel_time_to_max\n");
442     print("p:   print prameters\n");
443     print("d:   set default values\n");
444     print("up:  increase prameters(+1)\n");
445     print("down:        decrease prameters(-1)\n");
446     print("pgup:        increase prameters(+10)\n");
447     print("pgdown:      decrease prameters(-10)\n");
448     print("\nspeed = delta * max_speed * (repeat / time_to_max)\n");
449     print("where delta: cursor="); pdec(MOUSEKEY_MOVE_DELTA);
450     print(", wheel="); pdec(MOUSEKEY_WHEEL_DELTA); print("\n");
451     print("See http://en.wikipedia.org/wiki/Mouse_keys\n");
452 }
453
454 static bool mousekey_console(uint8_t code)
455 {
456     switch (code) {
457         case KC_H:
458         case KC_SLASH: /* ? */
459             mousekey_console_help();
460             break;
461         case KC_Q:
462         case KC_ESC:
463             mousekey_param = 0;
464             print("\nQuit Mousekey Console\n");
465             print("C> ");
466             state = CONSOLE;
467             return false;
468         case KC_P:
469             mousekey_param_print();
470             break;
471         case KC_1:
472         case KC_2:
473         case KC_3:
474         case KC_4:
475         case KC_5:
476         case KC_6:
477         case KC_7:
478         case KC_8:
479         case KC_9:
480         case KC_0:
481             mousekey_param = kc2int(code);
482             print("selected parameter: "); pdec(mousekey_param); print("\n");
483             break;
484         case KC_UP:
485             mousekey_param_inc(mousekey_param, 1);
486             break;
487         case KC_DOWN:
488             mousekey_param_dec(mousekey_param, 1);
489             break;
490         case KC_PGUP:
491             mousekey_param_inc(mousekey_param, 10);
492             break;
493         case KC_PGDN:
494             mousekey_param_dec(mousekey_param, 10);
495             break;
496         case KC_D:
497             mk_delay = MOUSEKEY_DELAY/10;
498             mk_interval = MOUSEKEY_INTERVAL;
499             mk_max_speed = MOUSEKEY_MAX_SPEED;
500             mk_time_to_max = MOUSEKEY_TIME_TO_MAX;
501             mk_wheel_max_speed = MOUSEKEY_WHEEL_MAX_SPEED;
502             mk_wheel_time_to_max = MOUSEKEY_WHEEL_TIME_TO_MAX;
503             print("set default values.\n");
504             break;
505         default:
506             print("?");
507             return false;
508     }
509     print("M"); pdec(mousekey_param); print("> ");
510     return true;
511 }
512 #endif
513
514
515 /***********************************************************
516  * Utilities
517  ***********************************************************/
518 static uint8_t kc2int(uint8_t code)
519 {
520     switch (code) {
521         case KC_1: return 1;
522         case KC_2: return 2;
523         case KC_3: return 3;
524         case KC_4: return 4;
525         case KC_5: return 5;
526         case KC_6: return 6;
527         case KC_7: return 7;
528         case KC_8: return 8;
529         case KC_9: return 9;
530         case KC_0: return 0;
531     }
532     return 0;
533 }
534
535 static void switch_layer(uint8_t layer)
536 {
537     print("current_layer: "); phex(current_layer); print("\n");
538     print("default_layer: "); phex(default_layer); print("\n");
539     current_layer = layer;
540     default_layer = layer;
541     print("switch to Layer: "); phex(layer); print("\n");
542 }
543
544 static void clear_keyboard(void)
545 {
546     host_clear_keys();
547     host_clear_mods();
548     host_send_keyboard_report();
549
550     host_system_send(0);
551     host_consumer_send(0);
552
553 #ifdef MOUSEKEY_ENABLE
554     mousekey_clear();
555     mousekey_send();
556 #endif
557 }