]> git.donarmstrong.com Git - tmk_firmware.git/blob - keyboard.c
ADD: V-USB Circuit in README
[tmk_firmware.git] / keyboard.c
1 #include "keyboard.h"
2 #include "host.h"
3 #include "layer.h"
4 #include "matrix.h"
5 #include "led.h"
6 #include "usb_keycodes.h"
7 #include "timer.h"
8 #include "print.h"
9 #include "debug.h"
10 #include "command.h"
11 #ifdef MOUSEKEY_ENABLE
12 #include "mousekey.h"
13 #endif
14 /* TODO: shoud make new API */
15 #ifdef USB_EXTRA_ENABLE
16 #include "usb_extra.h"
17 #include <util/delay.h>
18 #endif
19
20
21 static uint8_t last_leds = 0;
22
23
24 void keyboard_init(void)
25 {
26     timer_init();
27     matrix_init();
28 #ifdef PS2_MOUSE_ENABLE
29     ps2_mouse_init();
30 #endif
31 }
32
33 void keyboard_proc(void)
34 {
35     uint8_t fn_bits = 0;
36
37     matrix_scan();
38
39     if (matrix_is_modified()) {
40         if (debug_matrix) matrix_print();
41 #ifdef DEBUG_LED
42         // LED flash for debug
43         DEBUG_LED_CONFIG;
44         DEBUG_LED_ON;
45 #endif
46     }
47
48     if (matrix_has_ghost()) {
49         // should send error?
50         debug("matrix has ghost!!\n");
51         return;
52     }
53
54     host_swap_keyboard_report();
55     host_clear_keyboard_report();
56     for (int row = 0; row < matrix_rows(); row++) {
57         for (int col = 0; col < matrix_cols(); col++) {
58             if (!matrix_is_on(row, col)) continue;
59
60             uint8_t code = layer_get_keycode(row, col);
61             if (code == KB_NO) {
62                 // do nothing
63             } else if (IS_MOD(code)) {
64                 host_add_mod_bit(MOD_BIT(code));
65             } else if (IS_FN(code)) {
66                 fn_bits |= FN_BIT(code);
67             }
68 #ifdef USB_EXTRA_ENABLE
69             // audio control & system control
70             else if (code == KB_MUTE) {
71                 usb_extra_audio_send(AUDIO_MUTE);
72                 usb_extra_audio_send(0);
73                 _delay_ms(500);
74             } else if (code == KB_VOLU) {
75                 usb_extra_audio_send(AUDIO_VOL_UP);
76                 usb_extra_audio_send(0);
77                 _delay_ms(200);
78             } else if (code == KB_VOLD) {
79                 usb_extra_audio_send(AUDIO_VOL_DOWN);
80                 usb_extra_audio_send(0);
81                 _delay_ms(200);
82             } else if (code == KB_PWR) {
83                 if (suspend && remote_wakeup) {
84                     usb_remote_wakeup();
85                 } else {
86                     usb_extra_system_send(SYSTEM_POWER_DOWN);
87                 }
88                 _delay_ms(1000);
89             }
90 #endif
91             else if (IS_KEY(code)) {
92                 host_add_key(code);
93             }
94 #ifdef MOUSEKEY_ENABLE
95             else if (IS_MOUSEKEY(code)) {
96                 mousekey_decode(code);
97             }
98 #endif
99             else {
100                 debug("ignore keycode: "); debug_hex(code); debug("\n");
101             }
102         }
103     }
104
105     layer_switching(fn_bits);
106
107     if (command_proc()) {
108         return;
109     }
110
111     // TODO: should send only when changed from last report
112     if (matrix_is_modified()) {
113         host_send_keyboard_report();
114 #ifdef DEBUG_LED
115         // LED flash for debug
116         DEBUG_LED_CONFIG;
117         DEBUG_LED_OFF;
118 #endif
119     }
120
121 #ifdef MOUSEKEY_ENABLE
122     mousekey_send();
123 #endif
124
125 #ifdef PS2_MOUSE_ENABLE
126     // TODO: should comform new API
127     if (ps2_mouse_read() == 0)
128         ps2_mouse_usb_send();
129 #endif
130
131     if (last_leds != host_keyboard_leds()) {
132         keyboard_set_leds(host_keyboard_leds());
133         last_leds = host_keyboard_leds();
134     }
135 }
136
137 void keyboard_set_leds(uint8_t leds)
138 {
139     led_set(leds);
140 }