aboutsummaryrefslogtreecommitdiff
path: root/pjrc/usb_keyboard.c
diff options
context:
space:
mode:
Diffstat (limited to 'pjrc/usb_keyboard.c')
-rw-r--r--pjrc/usb_keyboard.c183
1 files changed, 11 insertions, 172 deletions
diff --git a/pjrc/usb_keyboard.c b/pjrc/usb_keyboard.c
index 57e23d5fc..e29c5c9e9 100644
--- a/pjrc/usb_keyboard.c
+++ b/pjrc/usb_keyboard.c
@@ -5,14 +5,9 @@
5#include "print.h" 5#include "print.h"
6#include "debug.h" 6#include "debug.h"
7#include "util.h" 7#include "util.h"
8#include "host.h"
8 9
9 10
10// keyboard report.
11static usb_keyboard_report_t _report0 = { {0}, 0, false };
12static usb_keyboard_report_t _report1 = { {0}, 0, false };
13usb_keyboard_report_t *usb_keyboard_report = &_report0;
14usb_keyboard_report_t *usb_keyboard_report_prev = &_report1;
15
16// protocol setting from the host. We use exactly the same report 11// protocol setting from the host. We use exactly the same report
17// either way, so this variable only stores the setting since we 12// either way, so this variable only stores the setting since we
18// are required to be able to report which setting is in use. 13// are required to be able to report which setting is in use.
@@ -28,167 +23,42 @@ uint8_t usb_keyboard_idle_count=0;
28// 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana 23// 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana
29volatile uint8_t usb_keyboard_leds=0; 24volatile uint8_t usb_keyboard_leds=0;
30 25
31// enable USB NKRO
32bool usb_keyboard_nkro = false;
33 26
27static inline int8_t send_report(report_keyboard_t *report, uint8_t endpoint, uint8_t keys_start, uint8_t keys_end);
34 28
35int8_t usb_keyboard_send(void)
36{
37 return usb_keyboard_send_report(usb_keyboard_report);
38}
39 29
40static inline int8_t _send_report(usb_keyboard_report_t *report, uint8_t endpoint, uint8_t keys_start, uint8_t keys_end); 30int8_t usb_keyboard_send_report(report_keyboard_t *report)
41int8_t usb_keyboard_send_report(usb_keyboard_report_t *report)
42{ 31{
43 int8_t result = 0; 32 int8_t result = 0;
44 33
45#ifdef USB_NKRO_ENABLE 34#ifdef USB_NKRO_ENABLE
46 if (usb_keyboard_nkro) 35 if (keyboard_nkro)
47 result = _send_report(report, KBD2_ENDPOINT, 0, KBD2_REPORT_KEYS); 36 result = send_report(report, KBD2_ENDPOINT, 0, KBD2_REPORT_KEYS);
48 else 37 else
49#endif 38#endif
50 { 39 {
51 if (usb_keyboard_protocol) 40 if (usb_keyboard_protocol)
52 result = _send_report(report, KBD_ENDPOINT, 0, KBD_REPORT_KEYS); 41 result = send_report(report, KBD_ENDPOINT, 0, KBD_REPORT_KEYS);
53 else 42 else
54 result = _send_report(report, KBD_ENDPOINT, 0, 6); 43 result = send_report(report, KBD_ENDPOINT, 0, 6);
55 } 44 }
56 45
57 if (result) return result; 46 if (result) return result;
58 usb_keyboard_idle_count = 0; 47 usb_keyboard_idle_count = 0;
59 report->is_sent =true;
60 usb_keyboard_print_report(report); 48 usb_keyboard_print_report(report);
61 return 0; 49 return 0;
62} 50}
63 51
64void usb_keyboard_swap_report(void) { 52void usb_keyboard_print_report(report_keyboard_t *report)
65 usb_keyboard_report_t *tmp = usb_keyboard_report_prev;
66 usb_keyboard_report_prev = usb_keyboard_report;
67 usb_keyboard_report = tmp;
68}
69
70void usb_keyboard_clear_report(void) {
71 usb_keyboard_clear_keys();
72 usb_keyboard_clear_mods();
73 usb_keyboard_report->is_sent = false;
74}
75
76void usb_keyboard_clear_keys(void) {
77 for (int i = 0; i < KEYS_MAX; i++) usb_keyboard_report->keys[i] = 0;
78}
79
80void usb_keyboard_clear_mods(void)
81{
82 usb_keyboard_report->mods = 0;
83}
84
85void usb_keyboard_set_keys(uint8_t *keys)
86{
87 for (int i = 0; i < KEYS_MAX; i++)
88 usb_keyboard_report->keys[i] = keys[i];
89}
90
91void usb_keyboard_set_mods(uint8_t mods)
92{
93 usb_keyboard_report->mods = mods;
94}
95
96void usb_keyboard_add_code(uint8_t code)
97{
98 if (IS_MOD(code)) {
99 usb_keyboard_add_mod(code);
100 } else {
101 usb_keyboard_add_key(code);
102 }
103}
104
105static inline void _add_key_byte(uint8_t code);
106static inline void _add_key_bit(uint8_t code);
107void usb_keyboard_add_key(uint8_t code)
108{
109#ifdef USB_NKRO_ENABLE
110 if (usb_keyboard_nkro) {
111 _add_key_bit(code);
112 return;
113 }
114#endif
115 _add_key_byte(code);
116}
117
118void usb_keyboard_add_mod(uint8_t code)
119{
120 usb_keyboard_report->mods |= MOD_BIT(code);
121}
122
123void usb_keyboard_del_code(uint8_t code)
124{
125 if (IS_MOD(code)) {
126 usb_keyboard_del_mod(code);
127 } else {
128 usb_keyboard_del_key(code);
129 }
130}
131
132void usb_keyboard_del_key(uint8_t code)
133{
134#ifdef USB_NKRO_ENABLE
135 if ((code>>3) < KEYS_MAX) {
136 usb_keyboard_keys[code>>3] &= ~(1<<(code&7));
137 }
138#else
139 for (int i = 0; i < KEYS_MAX; i++) {
140 if (usb_keyboard_report->keys[i] == code) {
141 usb_keyboard_report->keys[i] = KB_NO;
142 return;
143 }
144 }
145#endif
146}
147
148void usb_keyboard_del_mod(uint8_t code)
149{
150 usb_keyboard_report->mods &= ~MOD_BIT(code);
151}
152
153bool usb_keyboard_is_sent(void)
154{
155 return usb_keyboard_report->is_sent;
156}
157
158bool usb_keyboard_has_key(void)
159{
160 uint8_t keys = 0;
161 for (int i = 0; i < KEYS_MAX; i++) keys |= usb_keyboard_report->keys[i];
162 return keys ? true : false;
163}
164
165bool usb_keyboard_has_mod(void)
166{
167 return usb_keyboard_report->mods ? true : false;
168}
169
170uint8_t usb_keyboard_get_key(void)
171{
172#ifdef USB_NKRO_ENABLE
173 if (usb_keyboard_nkro) {
174 uint8_t i = 0;
175 for (; i < KEYS_MAX && !usb_keyboard_keys[i]; i++);
176 return i<<3 | biton(usb_keyboard_keys[i]);
177 }
178#endif
179 return usb_keyboard_keys[0];
180}
181
182void usb_keyboard_print_report(usb_keyboard_report_t *report)
183{ 53{
184 if (!debug_keyboard) return; 54 if (!debug_keyboard) return;
185 print("keys: "); 55 print("keys: ");
186 for (int i = 0; i < KEYS_MAX; i++) { phex(report->keys[i]); print(" "); } 56 for (int i = 0; i < REPORT_KEYS; i++) { phex(report->keys[i]); print(" "); }
187 print(" mods: "); phex(report->mods); print("\n"); 57 print(" mods: "); phex(report->mods); print("\n");
188} 58}
189 59
190 60
191static inline int8_t _send_report(usb_keyboard_report_t *report, uint8_t endpoint, uint8_t keys_start, uint8_t keys_end) 61static inline int8_t send_report(report_keyboard_t *report, uint8_t endpoint, uint8_t keys_start, uint8_t keys_end)
192{ 62{
193 uint8_t intr_state, timeout; 63 uint8_t intr_state, timeout;
194 64
@@ -211,7 +81,7 @@ static inline int8_t _send_report(usb_keyboard_report_t *report, uint8_t endpoin
211 UENUM = endpoint; 81 UENUM = endpoint;
212 } 82 }
213 UEDATX = report->mods; 83 UEDATX = report->mods;
214 if (!usb_keyboard_nkro) 84 if (!keyboard_nkro)
215 UEDATX = 0; 85 UEDATX = 0;
216 for (uint8_t i = keys_start; i < keys_end; i++) { 86 for (uint8_t i = keys_start; i < keys_end; i++) {
217 UEDATX = report->keys[i]; 87 UEDATX = report->keys[i];
@@ -220,34 +90,3 @@ static inline int8_t _send_report(usb_keyboard_report_t *report, uint8_t endpoin
220 SREG = intr_state; 90 SREG = intr_state;
221 return 0; 91 return 0;
222} 92}
223
224static inline void _add_key_byte(uint8_t code)
225{
226 // TODO: fix ugly code
227 int8_t i = 0;
228 int8_t empty = -1;
229 for (; i < KEYS_MAX; i++) {
230 if (usb_keyboard_keys_prev[i] == code) {
231 usb_keyboard_keys[i] = code;
232 break;
233 }
234 if (empty == -1 &&
235 usb_keyboard_keys_prev[i] == 0 &&
236 usb_keyboard_keys[i] == 0) {
237 empty = i;
238 }
239 }
240 if (i == KEYS_MAX) {
241 if (empty != -1) {
242 usb_keyboard_keys[empty] = code;
243 }
244 }
245}
246
247static inline void _add_key_bit(uint8_t code)
248{
249 if ((code>>3) < KEYS_MAX) {
250 usb_keyboard_keys[code>>3] |= 1<<(code&7);
251 }
252}
253