]> git.gir.st - tmk_keyboard.git/blob - common/host.c
Initial version of new code for layer switch is added.
[tmk_keyboard.git] / common / host.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
18 #include <stdint.h>
19 #include <avr/interrupt.h>
20 #include "usb_keycodes.h"
21 #include "host.h"
22 #include "util.h"
23 #include "debug.h"
24
25
26 #ifdef NKRO_ENABLE
27 bool keyboard_nkro = false;
28 #endif
29
30 static host_driver_t *driver;
31 static report_keyboard_t report0;
32 static report_keyboard_t report1;
33 report_keyboard_t *keyboard_report = &report0;
34 report_keyboard_t *keyboard_report_prev = &report1;
35
36
37 static inline void add_key_byte(uint8_t code);
38 static inline void del_key_byte(uint8_t code);
39 static inline void add_key_bit(uint8_t code);
40 static inline void del_key_bit(uint8_t code);
41
42
43 void host_set_driver(host_driver_t *d)
44 {
45 driver = d;
46 }
47
48 host_driver_t *host_get_driver(void)
49 {
50 return driver;
51 }
52
53 uint8_t host_keyboard_leds(void)
54 {
55 if (!driver) return 0;
56 return (*driver->keyboard_leds)();
57 }
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
72 /* keyboard report operations */
73 void host_add_key(uint8_t key)
74 {
75 #ifdef NKRO_ENABLE
76 if (keyboard_nkro) {
77 add_key_bit(key);
78 return;
79 }
80 #endif
81 add_key_byte(key);
82 }
83
84 void host_del_key(uint8_t key)
85 {
86 #ifdef NKRO_ENABLE
87 if (keyboard_nkro) {
88 del_key_bit(key);
89 return;
90 }
91 #endif
92 del_key_byte(key);
93 }
94
95 void host_add_mod_bit(uint8_t mod)
96 {
97 keyboard_report->mods |= mod;
98 }
99
100 void host_del_mod_bit(uint8_t mod)
101 {
102 keyboard_report->mods &= ~mod;
103 }
104
105 void host_set_mods(uint8_t mods)
106 {
107 keyboard_report->mods = mods;
108 }
109
110 void host_add_code(uint8_t code)
111 {
112 if (IS_MOD(code)) {
113 host_add_mod_bit(MOD_BIT(code));
114 } else {
115 host_add_key(code);
116 }
117 }
118
119 void host_del_code(uint8_t code)
120 {
121 if (IS_MOD(code)) {
122 host_del_mod_bit(MOD_BIT(code));
123 } else {
124 host_del_key(code);
125 }
126 }
127
128 void host_swap_keyboard_report(void)
129 {
130 uint8_t sreg = SREG;
131 cli();
132 report_keyboard_t *tmp = keyboard_report_prev;
133 keyboard_report_prev = keyboard_report;
134 keyboard_report = tmp;
135 SREG = sreg;
136 }
137
138 void host_clear_keyboard_report(void)
139 {
140 keyboard_report->mods = 0;
141 for (int8_t i = 0; i < REPORT_KEYS; i++) {
142 keyboard_report->keys[i] = 0;
143 }
144 }
145
146 uint8_t host_has_anykey(void)
147 {
148 uint8_t cnt = 0;
149 for (int i = 0; i < REPORT_KEYS; i++) {
150 if (keyboard_report->keys[i])
151 cnt++;
152 }
153 return cnt;
154 }
155
156 uint8_t host_get_first_key(void)
157 {
158 #ifdef NKRO_ENABLE
159 if (keyboard_nkro) {
160 uint8_t i = 0;
161 for (; i < REPORT_KEYS && !keyboard_report->keys[i]; i++)
162 ;
163 return i<<3 | biton(keyboard_report->keys[i]);
164 }
165 #endif
166 return keyboard_report->keys[0];
167 }
168
169
170 void host_send_keyboard_report(void)
171 {
172 if (!driver) return;
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 }
182 }
183
184 void host_mouse_send(report_mouse_t *report)
185 {
186 if (!driver) return;
187 (*driver->send_mouse)(report);
188 }
189
190 void host_system_send(uint16_t data)
191 {
192 static uint16_t last_data = 0;
193 if (data == last_data) return;
194 last_data = data;
195
196 if (!driver) return;
197 (*driver->send_system)(data);
198 }
199
200 void host_consumer_send(uint16_t data)
201 {
202 static uint16_t last_data = 0;
203 if (data == last_data) return;
204 last_data = data;
205
206 if (!driver) return;
207 (*driver->send_consumer)(data);
208 }
209
210
211 static inline void add_key_byte(uint8_t code)
212 {
213 // TODO: fix ugly code
214 int8_t i = 0;
215 int8_t empty = -1;
216 for (; i < REPORT_KEYS; i++) {
217 if (keyboard_report_prev->keys[i] == code) {
218 keyboard_report->keys[i] = code;
219 break;
220 }
221 if (empty == -1 &&
222 keyboard_report_prev->keys[i] == 0 &&
223 keyboard_report->keys[i] == 0) {
224 empty = i;
225 }
226 }
227 if (i == REPORT_KEYS) {
228 if (empty != -1) {
229 keyboard_report->keys[empty] = code;
230 }
231 }
232 }
233
234 static inline void del_key_byte(uint8_t code)
235 {
236 int i = 0;
237 for (; i < REPORT_KEYS; i++) {
238 if (keyboard_report->keys[i] == code) {
239 keyboard_report->keys[i] = 0;
240 }
241 }
242 }
243
244 static inline void add_key_bit(uint8_t code)
245 {
246 if ((code>>3) < REPORT_KEYS) {
247 keyboard_report->keys[code>>3] |= 1<<(code&7);
248 } else {
249 debug("add_key_bit: can't add: "); phex(code); debug("\n");
250 }
251 }
252
253 static inline void del_key_bit(uint8_t code)
254 {
255 if ((code>>3) < REPORT_KEYS) {
256 keyboard_report->keys[code>>3] &= ~(1<<(code&7));
257 } else {
258 debug("del_key_bit: can't del: "); phex(code); debug("\n");
259 }
260 }
Imprint / Impressum