1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
#include "usbdrv.h"
#include "usb_keycodes.h"
#include "keyboard.h"
#include "print.h"
static report_t report0;
static report_t report1;
static report_t *report = &report0;
static report_t *report_prev = &report1;
void report_send(void)
{
if (usbInterruptIsReady()){
usbSetInterrupt((void *)report, sizeof(*report));
}
}
report_t *report_get(void)
{
return report;
}
uint8_t report_mods(void)
{
return report->mods;
}
uint8_t *report_keys(void)
{
return report->keys;
}
bool report_has_key(void)
{
for (int i = 0; i < REPORT_KEYS; i++) {
if (report->keys[i])
return true;
}
return false;
}
void report_add_mod(uint8_t mod)
{
report->mods |= mod;
}
void report_add_key(uint8_t code)
{
int8_t i = 0;
int8_t empty = -1;
for (; i < REPORT_KEYS; i++) {
if (report_prev->keys[i] == code) {
report->keys[i] = code;
break;
}
if (empty == -1 && report_prev->keys[i] == KB_NO && report->keys[i] == KB_NO) {
empty = i;
}
}
if (i == REPORT_KEYS && empty != -1) {
report->keys[empty] = code;
}
}
void report_add_code(uint8_t code)
{
if (IS_MOD(code)) {
report_add_mod(code);
} else {
report_add_key(code);
}
}
void report_swap(void)
{
report_t *tmp = report_prev;
report_prev = report;
report = tmp;
}
void report_clear(void)
{
report->mods = 0;
for (int8_t i = 0; i < REPORT_KEYS; i++) {
report->keys[i] = 0;
}
}
static uchar idleRate; /* repeat rate for keyboards, never used for mice */
usbMsgLen_t usbFunctionSetup(uchar data[8])
{
usbRequest_t *rq = (void *)data;
print("Setup: ");
if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */
print("CLASS: ");
phex(rq->bRequest);
if(rq->bRequest == USBRQ_HID_GET_REPORT){
print("GET_REPORT");
/* we only have one report type, so don't look at wValue */
usbMsgPtr = (void *)report;
return sizeof(*report);
}else if(rq->bRequest == USBRQ_HID_GET_IDLE){
print("GET_IDLE: ");
phex(idleRate);
usbMsgPtr = &idleRate;
return 1;
}else if(rq->bRequest == USBRQ_HID_SET_IDLE){
idleRate = rq->wValue.bytes[1];
print("SET_IDLE: ");
phex(idleRate);
}
print("\n");
}else{
print("VENDOR\n");
/* no vendor specific requests implemented */
}
return 0; /* default for not implemented requests: return no data back to host */
}
PROGMEM char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = {
0x05, 0x01, // Usage Page (Generic Desktop),
0x09, 0x06, // Usage (Keyboard),
0xA1, 0x01, // Collection (Application),
0x75, 0x01, // Report Size (1),
0x95, 0x08, // Report Count (8),
0x05, 0x07, // Usage Page (Key Codes),
0x19, 0xE0, // Usage Minimum (224),
0x29, 0xE7, // Usage Maximum (231),
0x15, 0x00, // Logical Minimum (0),
0x25, 0x01, // Logical Maximum (1),
0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte
0x95, 0x01, // Report Count (1),
0x75, 0x08, // Report Size (8),
0x81, 0x03, // Input (Constant), ;Reserved byte
0x95, 0x05, // Report Count (5),
0x75, 0x01, // Report Size (1),
0x05, 0x08, // Usage Page (LEDs),
0x19, 0x01, // Usage Minimum (1),
0x29, 0x05, // Usage Maximum (5),
0x91, 0x02, // Output (Data, Variable, Absolute), ;LED report
0x95, 0x01, // Report Count (1),
0x75, 0x03, // Report Size (3),
0x91, 0x03, // Output (Constant), ;LED report padding
0x95, 0x06, // Report Count (6),
0x75, 0x08, // Report Size (8),
0x15, 0x00, // Logical Minimum (0),
0x25, 0xFF, // Logical Maximum(255),
0x05, 0x07, // Usage Page (Key Codes),
0x19, 0x00, // Usage Minimum (0),
0x29, 0xFF, // Usage Maximum (255),
0x81, 0x00, // Input (Data, Array),
0xc0 // End Collection
};
|