]> git.donarmstrong.com Git - tmk_firmware.git/blob - protocol/mbed/HIDKeyboard.cpp
Merge branch 'merge_rn42'
[tmk_firmware.git] / protocol / mbed / HIDKeyboard.cpp
1 #include <stdint.h>
2 #include "USBHID.h"
3 #include "USBHID_Types.h"
4 #include "USBDescriptor.h"
5 #include "HIDKeyboard.h"
6
7 #define DEFAULT_CONFIGURATION (1)
8
9
10 HIDKeyboard::HIDKeyboard(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release)
11 {
12     USBDevice::connect();
13 }
14
15 bool HIDKeyboard::sendReport(report_keyboard_t report) {
16     USBDevice::write(EP1IN, report.raw, sizeof(report), MAX_PACKET_SIZE_EP1);
17     return true;
18 }
19
20 uint8_t HIDKeyboard::leds() {
21     return led_state;
22 }
23
24 bool HIDKeyboard::USBCallback_setConfiguration(uint8_t configuration) {
25     if (configuration != DEFAULT_CONFIGURATION) {
26         return false;
27     }
28
29     // Configure endpoints > 0
30     addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
31     //addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
32
33     // We activate the endpoint to be able to recceive data
34     //readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
35     return true;
36 }
37
38
39 uint8_t * HIDKeyboard::stringImanufacturerDesc() {
40     static uint8_t stringImanufacturerDescriptor[] = {
41         0x18,                                            /*bLength*/
42         STRING_DESCRIPTOR,                               /*bDescriptorType 0x03*/
43         't',0,'m',0,'k',0,'-',0,'k',0,'b',0,'d',0,'.',0,'c',0,'o',0,'m',0   /*bString iManufacturer*/
44     };
45     return stringImanufacturerDescriptor;
46 }
47
48 uint8_t * HIDKeyboard::stringIproductDesc() {
49     static uint8_t stringIproductDescriptor[] = {
50         0x0a,                                                       /*bLength*/
51         STRING_DESCRIPTOR,                                          /*bDescriptorType 0x03*/
52         'm',0,'b',0,'e',0,'d',0                                     /*bString iProduct*/
53     };
54     return stringIproductDescriptor;
55 }
56
57 uint8_t * HIDKeyboard::stringIserialDesc() {
58     static uint8_t stringIserialDescriptor[] = {
59         0x04,                                                           /*bLength*/
60         STRING_DESCRIPTOR,                                              /*bDescriptorType 0x03*/
61         '0',0                                                           /*bString iSerial*/
62     };
63     return stringIserialDescriptor;
64 }
65
66 uint8_t * HIDKeyboard::reportDesc() {
67     static uint8_t reportDescriptor[] = {
68         USAGE_PAGE(1), 0x01,                    // Generic Desktop
69         USAGE(1), 0x06,                         // Keyboard
70         COLLECTION(1), 0x01,                    // Application
71
72         USAGE_PAGE(1), 0x07,                    // Key Codes
73         USAGE_MINIMUM(1), 0xE0,
74         USAGE_MAXIMUM(1), 0xE7,
75         LOGICAL_MINIMUM(1), 0x00,
76         LOGICAL_MAXIMUM(1), 0x01,
77         REPORT_SIZE(1), 0x01,
78         REPORT_COUNT(1), 0x08,
79         INPUT(1), 0x02,                         // Data, Variable, Absolute
80
81         REPORT_COUNT(1), 0x01,
82         REPORT_SIZE(1), 0x08,
83         INPUT(1), 0x01,                         // Constant
84
85         REPORT_COUNT(1), 0x05,
86         REPORT_SIZE(1), 0x01,
87         USAGE_PAGE(1), 0x08,                    // LEDs
88         USAGE_MINIMUM(1), 0x01,
89         USAGE_MAXIMUM(1), 0x05,
90         OUTPUT(1), 0x02,                        // Data, Variable, Absolute
91
92         REPORT_COUNT(1), 0x01,
93         REPORT_SIZE(1), 0x03,
94         OUTPUT(1), 0x01,                        // Constant
95
96
97         REPORT_COUNT(1), 0x06,
98         REPORT_SIZE(1), 0x08,
99         LOGICAL_MINIMUM(1), 0x00,
100         LOGICAL_MAXIMUM(1), 0xFF,
101         USAGE_PAGE(1), 0x07,                    // Key Codes
102         USAGE_MINIMUM(1), 0x00,
103         USAGE_MAXIMUM(1), 0xFF,
104         INPUT(1), 0x00,                         // Data, Array
105         END_COLLECTION(0),
106     };
107     reportLength = sizeof(reportDescriptor);
108     return reportDescriptor;
109 }
110
111 uint16_t HIDKeyboard::reportDescLength() {
112     reportDesc();
113     return reportLength;
114 }
115
116 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
117                                + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
118                                + (1 * HID_DESCRIPTOR_LENGTH) \
119                                + (1 * ENDPOINT_DESCRIPTOR_LENGTH))
120 uint8_t * HIDKeyboard::configurationDesc() {
121     static uint8_t configurationDescriptor[] = {
122         CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
123         CONFIGURATION_DESCRIPTOR,       // bDescriptorType
124         LSB(TOTAL_DESCRIPTOR_LENGTH),   // wTotalLength (LSB)
125         MSB(TOTAL_DESCRIPTOR_LENGTH),   // wTotalLength (MSB)
126         0x01,                           // bNumInterfaces
127         DEFAULT_CONFIGURATION,          // bConfigurationValue
128         0x00,                           // iConfiguration
129         C_RESERVED | C_REMOTE_WAKEUP,   // bmAttributes
130         C_POWER(100),                   // bMaxPowerHello World from Mbed
131
132         INTERFACE_DESCRIPTOR_LENGTH,    // bLength
133         INTERFACE_DESCRIPTOR,           // bDescriptorType
134         0x00,                           // bInterfaceNumber
135         0x00,                           // bAlternateSetting
136         0x01,                           // bNumEndpoints
137         HID_CLASS,                      // bInterfaceClass
138         1,                              // bInterfaceSubClass (boot)
139         1,                              // bInterfaceProtocol (keyboard)
140         0x00,                           // iInterface
141
142         HID_DESCRIPTOR_LENGTH,          // bLength
143         HID_DESCRIPTOR,                 // bDescriptorType
144         LSB(HID_VERSION_1_11),          // bcdHID (LSB)
145         MSB(HID_VERSION_1_11),          // bcdHID (MSB)
146         0x00,                           // bCountryCode
147         0x01,                           // bNumDescriptors
148         REPORT_DESCRIPTOR,              // bDescriptorType
149         (uint8_t)(LSB(reportDescLength())),  // wDescriptorLength (LSB)
150         (uint8_t)(MSB(reportDescLength())),  // wDescriptorLength (MSB)
151
152         ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
153         ENDPOINT_DESCRIPTOR,            // bDescriptorType
154         PHY_TO_DESC(EP1IN),             // bEndpointAddress
155         E_INTERRUPT,                    // bmAttributes
156         LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
157         MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
158         1,                           // bInterval (milliseconds)
159     };
160     return configurationDescriptor;
161 }
162
163 #if 0
164 uint8_t * HIDKeyboard::deviceDesc() {
165     static uint8_t deviceDescriptor[] = {
166         DEVICE_DESCRIPTOR_LENGTH,       /* bLength */
167         DEVICE_DESCRIPTOR,              /* bDescriptorType */
168         LSB(USB_VERSION_2_0),           /* bcdUSB (LSB) */
169         MSB(USB_VERSION_2_0),           /* bcdUSB (MSB) */
170         0x00,                           /* bDeviceClass */
171         0x00,                           /* bDeviceSubClass */
172         0x00,                           /* bDeviceprotocol */
173         MAX_PACKET_SIZE_EP0,            /* bMaxPacketSize0 */
174         (uint8_t)(LSB(0xfeed)),                 /* idVendor (LSB) */
175         (uint8_t)(MSB(0xfeed)),                 /* idVendor (MSB) */
176         (uint8_t)(LSB(0x1bed)),                /* idProduct (LSB) */
177         (uint8_t)(MSB(0x1bed)),                /* idProduct (MSB) */
178         (uint8_t)(LSB(0x0002)),           /* bcdDevice (LSB) */
179         (uint8_t)(MSB(0x0002)),           /* bcdDevice (MSB) */
180         0,    /* iManufacturer */
181         0,         /* iProduct */
182         0,          /* iSerialNumber */
183         0x01                            /* bNumConfigurations */
184     };
185     return deviceDescriptor;
186 }
187 #endif
188
189 bool HIDKeyboard::USBCallback_request() {
190     bool success = false;
191     CONTROL_TRANSFER * transfer = getTransferPtr();
192     uint8_t *hidDescriptor;
193
194     // Process additional standard requests
195
196     if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE))
197     {
198         switch (transfer->setup.bRequest)
199         {
200             case GET_DESCRIPTOR:
201                 switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
202                 {
203                     case REPORT_DESCRIPTOR:
204                         if ((reportDesc() != NULL) \
205                             && (reportDescLength() != 0))
206                         {
207                             transfer->remaining = reportDescLength();
208                             transfer->ptr = reportDesc();
209                             transfer->direction = DEVICE_TO_HOST;
210                             success = true;
211                         }
212                         break;
213                     case HID_DESCRIPTOR:
214                             // Find the HID descriptor, after the configuration descriptor
215                             hidDescriptor = findDescriptor(HID_DESCRIPTOR);
216                             if (hidDescriptor != NULL)
217                             {
218                                 transfer->remaining = HID_DESCRIPTOR_LENGTH;
219                                 transfer->ptr = hidDescriptor;
220                                 transfer->direction = DEVICE_TO_HOST;
221                                 success = true;
222                             }
223                             break;
224                      
225                     default:
226                         break;
227                 }
228                 break;
229             default:
230                 break;
231         }
232     }
233
234     // Process class-specific requests
235     if (transfer->setup.bmRequestType.Type == CLASS_TYPE)
236     {
237         switch (transfer->setup.bRequest) {
238             case SET_REPORT:
239                 // LED indicator
240                 // TODO: check Interface and Report length?
241                 // if (transfer->setup.wIndex == INTERFACE_KEYBOAD) { }
242                 // if (transfer->setup.wLength == 1)
243
244                 transfer->remaining = 1;
245                 //transfer->ptr = ?? what ptr should be set when OUT(not used?)
246                 transfer->direction = HOST_TO_DEVICE;
247                 transfer->notify = true;    /* notify with USBCallback_requestCompleted */
248                 success = true;
249             default:
250                 break;
251         }
252     }
253
254     return success;
255 }
256
257 void HIDKeyboard::USBCallback_requestCompleted(uint8_t * buf, uint32_t length)
258 {
259     if (length > 0) {
260         CONTROL_TRANSFER *transfer = getTransferPtr();
261         if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
262             switch (transfer->setup.bRequest) {
263                 case SET_REPORT:
264                     led_state = buf[0];
265                     break;
266                 default:
267                     break;
268             }
269         }
270     }
271 }