aboutsummaryrefslogtreecommitdiff
path: root/pjrc
diff options
context:
space:
mode:
Diffstat (limited to 'pjrc')
-rw-r--r--pjrc/host.c135
-rwxr-xr-xpjrc/usb.c8
-rw-r--r--pjrc/usb.h21
-rw-r--r--pjrc/usb_keyboard.c183
-rw-r--r--pjrc/usb_keyboard.h68
5 files changed, 172 insertions, 243 deletions
diff --git a/pjrc/host.c b/pjrc/host.c
new file mode 100644
index 000000000..7247288bd
--- /dev/null
+++ b/pjrc/host.c
@@ -0,0 +1,135 @@
1#include <stdint.h>
2#include "usb_keycodes.h"
3#include "usb_keyboard.h"
4#include "usb_mouse.h"
5#include "debug.h"
6#include "host.h"
7
8
9#ifdef USB_NKRO_ENABLE
10bool keyboard_nkro = false;
11#endif
12
13static report_keyboard_t report0;
14static report_keyboard_t report1;
15report_keyboard_t *keyboard_report = &report0;
16report_keyboard_t *keyboard_report_prev = &report1;
17
18static inline void add_key_byte(uint8_t code);
19static inline void add_key_bit(uint8_t code);
20
21
22uint8_t host_keyboard_leds(void)
23{
24 return usb_keyboard_leds;
25}
26
27/* keyboard report operations */
28void host_add_key(uint8_t key)
29{
30#ifdef USB_NKRO_ENABLE
31 if (keyboard_nkro) {
32 add_key_bit(key);
33 return;
34 }
35#endif
36 add_key_byte(key);
37}
38
39void host_add_mod_bit(uint8_t mod)
40{
41 keyboard_report->mods |= mod;
42}
43
44void host_set_mods(uint8_t mods)
45{
46 keyboard_report->mods = mods;
47}
48
49void host_add_code(uint8_t code)
50{
51 if (IS_MOD(code)) {
52 host_add_mod_bit(MOD_BIT(code));
53 } else {
54 host_add_key(code);
55 }
56}
57
58void host_swap_keyboard_report(void)
59{
60 report_keyboard_t *tmp = keyboard_report_prev;
61 keyboard_report_prev = keyboard_report;
62 keyboard_report = tmp;
63}
64
65void host_clear_keyboard_report(void)
66{
67 keyboard_report->mods = 0;
68 for (int8_t i = 0; i < REPORT_KEYS; i++) {
69 keyboard_report->keys[i] = 0;
70 }
71}
72
73uint8_t host_has_anykey(void)
74{
75 uint8_t cnt = 0;
76 for (int i = 0; i < REPORT_KEYS; i++) {
77 if (keyboard_report->keys[i])
78 cnt++;
79 }
80 return cnt;
81}
82
83uint8_t *host_get_keys(void)
84{
85 return keyboard_report->keys;
86}
87
88uint8_t host_get_mods(void)
89{
90 return keyboard_report->mods;
91}
92
93
94void host_send_keyboard_report(void)
95{
96 usb_keyboard_send_report(keyboard_report);
97}
98
99void host_mouse_send(report_mouse_t *report)
100{
101 usb_mouse_send(report->x, report->y, report->v, report->h, report->buttons);
102}
103
104
105static inline void add_key_byte(uint8_t code)
106{
107 // TODO: fix ugly code
108 int8_t i = 0;
109 int8_t empty = -1;
110 for (; i < REPORT_KEYS; i++) {
111 if (keyboard_report_prev->keys[i] == code) {
112 keyboard_report->keys[i] = code;
113 break;
114 }
115 if (empty == -1 &&
116 keyboard_report_prev->keys[i] == 0 &&
117 keyboard_report->keys[i] == 0) {
118 empty = i;
119 }
120 }
121 if (i == REPORT_KEYS) {
122 if (empty != -1) {
123 keyboard_report->keys[empty] = code;
124 }
125 }
126}
127
128static inline void add_key_bit(uint8_t code)
129{
130 if ((code>>3) < REPORT_KEYS) {
131 keyboard_report->keys[code>>3] |= 1<<(code&7);
132 } else {
133 debug("add_key_bit: can't add: "); phex(code); debug("\n");
134 }
135}
diff --git a/pjrc/usb.c b/pjrc/usb.c
index 845b00bea..9fd30dee3 100755
--- a/pjrc/usb.c
+++ b/pjrc/usb.c
@@ -687,10 +687,10 @@ ISR(USB_GEN_vect)
687 usb_keyboard_idle_count++; 687 usb_keyboard_idle_count++;
688 if (usb_keyboard_idle_count == usb_keyboard_idle_config) { 688 if (usb_keyboard_idle_count == usb_keyboard_idle_config) {
689 usb_keyboard_idle_count = 0; 689 usb_keyboard_idle_count = 0;
690 UEDATX = usb_keyboard_mods; 690 UEDATX = keyboard_report->mods;
691 UEDATX = 0; 691 UEDATX = 0;
692 for (i=0; i<6; i++) { 692 for (i=0; i<6; i++) {
693 UEDATX = usb_keyboard_keys[i]; 693 UEDATX = keyboard_report->keys[i];
694 } 694 }
695 UEINTX = 0x3A; 695 UEINTX = 0x3A;
696 } 696 }
@@ -873,10 +873,10 @@ ISR(USB_COM_vect)
873 if (bmRequestType == 0xA1) { 873 if (bmRequestType == 0xA1) {
874 if (bRequest == HID_GET_REPORT) { 874 if (bRequest == HID_GET_REPORT) {
875 usb_wait_in_ready(); 875 usb_wait_in_ready();
876 UEDATX = usb_keyboard_mods; 876 UEDATX = keyboard_report->mods;
877 UEDATX = 0; 877 UEDATX = 0;
878 for (i=0; i<6; i++) { 878 for (i=0; i<6; i++) {
879 UEDATX = usb_keyboard_keys[i]; 879 UEDATX = keyboard_report->keys[i];
880 } 880 }
881 usb_send_in(); 881 usb_send_in();
882 return; 882 return;
diff --git a/pjrc/usb.h b/pjrc/usb.h
index ee72a1e39..4f0fd8f1e 100644
--- a/pjrc/usb.h
+++ b/pjrc/usb.h
@@ -14,8 +14,6 @@ uint8_t usb_configured(void); // is the USB port configured
14void usb_remote_wakeup(void); 14void usb_remote_wakeup(void);
15 15
16 16
17
18
19#define EP_TYPE_CONTROL 0x00 17#define EP_TYPE_CONTROL 0x00
20#define EP_TYPE_BULK_IN 0x81 18#define EP_TYPE_BULK_IN 0x81
21#define EP_TYPE_BULK_OUT 0x80 19#define EP_TYPE_BULK_OUT 0x80
@@ -88,4 +86,23 @@ void usb_remote_wakeup(void);
88#define ENDPOINT_HALT 0 86#define ENDPOINT_HALT 0
89#define TEST_MODE 2 87#define TEST_MODE 2
90 88
89
90/*------------------------------------------------------------------*
91 * Keyboard descriptor setting
92 *------------------------------------------------------------------*/
93#define KBD_INTERFACE 0
94#define KBD_ENDPOINT 1
95#define KBD_SIZE 8
96#define KBD_BUFFER EP_DOUBLE_BUFFER
97#define KBD_REPORT_KEYS (KBD_SIZE - 2)
98
99// secondary keyboard
100#ifdef USB_NKRO_ENABLE
101#define KBD2_INTERFACE 4
102#define KBD2_ENDPOINT 5
103#define KBD2_SIZE 16
104#define KBD2_BUFFER EP_DOUBLE_BUFFER
105#define KBD2_REPORT_KEYS (KBD2_SIZE - 1)
106#endif
107
91#endif 108#endif
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
diff --git a/pjrc/usb_keyboard.h b/pjrc/usb_keyboard.h
index 53de4336d..22287a056 100644
--- a/pjrc/usb_keyboard.h
+++ b/pjrc/usb_keyboard.h
@@ -4,78 +4,16 @@
4#include <stdint.h> 4#include <stdint.h>
5#include <stdbool.h> 5#include <stdbool.h>
6#include "usb.h" 6#include "usb.h"
7#include "host.h"
7 8
8 9
9#define KBD_INTERFACE 0
10#define KBD_ENDPOINT 1
11#define KBD_SIZE 8
12#define KBD_BUFFER EP_DOUBLE_BUFFER
13#define KBD_REPORT_KEYS (KBD_SIZE - 2)
14
15// secondary keyboard
16#ifdef USB_NKRO_ENABLE
17#define KBD2_INTERFACE 4
18#define KBD2_ENDPOINT 5
19#define KBD2_SIZE 16
20#define KBD2_BUFFER EP_DOUBLE_BUFFER
21#define KBD2_REPORT_KEYS (KBD2_SIZE - 1)
22#endif
23
24#if defined(KBD2_REPORT_KEYS) && KBD2_REPORT_KEYS > KBD_REPORT_KEYS
25#define KEYS_MAX KBD2_REPORT_KEYS
26#else
27#define KEYS_MAX KBD_REPORT_KEYS
28#endif
29
30
31typedef struct report {
32 uint8_t keys[KEYS_MAX];
33 uint8_t mods;
34 bool is_sent;
35} usb_keyboard_report_t;
36
37
38#define usb_keyboard_keys usb_keyboard_report->keys
39#define usb_keyboard_mods usb_keyboard_report->mods
40#define usb_keyboard_keys_prev usb_keyboard_report_prev->keys
41#define usb_keyboard_mods_prev usb_keyboard_report_prev->mods
42
43
44extern usb_keyboard_report_t *usb_keyboard_report;
45extern usb_keyboard_report_t *usb_keyboard_report_prev;
46extern uint8_t usb_keyboard_protocol; 10extern uint8_t usb_keyboard_protocol;
47extern uint8_t usb_keyboard_idle_config; 11extern uint8_t usb_keyboard_idle_config;
48extern uint8_t usb_keyboard_idle_count; 12extern uint8_t usb_keyboard_idle_count;
49extern volatile uint8_t usb_keyboard_leds; 13extern volatile uint8_t usb_keyboard_leds;
50extern bool usb_keyboard_nkro;
51
52
53int8_t usb_keyboard_send(void);
54int8_t usb_keyboard_send_report(usb_keyboard_report_t *report);
55
56void usb_keyboard_swap_report(void);
57
58void usb_keyboard_clear_report(void);
59void usb_keyboard_clear_keys(void);
60void usb_keyboard_clear_mods(void);
61
62void usb_keyboard_set_keys(uint8_t *keys);
63void usb_keyboard_set_mods(uint8_t mods);
64
65void usb_keyboard_add_code(uint8_t code);
66void usb_keyboard_add_key(uint8_t code);
67void usb_keyboard_add_mod(uint8_t code);
68
69void usb_keyboard_del_code(uint8_t code);
70void usb_keyboard_del_key(uint8_t code);
71void usb_keyboard_del_mod(uint8_t code);
72
73bool usb_keyboard_is_sent(void);
74bool usb_keyboard_has_key(void);
75bool usb_keyboard_has_mod(void);
76 14
77uint8_t usb_keyboard_get_key(void);
78 15
79void usb_keyboard_print_report(usb_keyboard_report_t *report); 16int8_t usb_keyboard_send_report(report_keyboard_t *report);
17void usb_keyboard_print_report(report_keyboard_t *report);
80 18
81#endif 19#endif