re-enabling serial
[clinton/Smoothieware.git] / gcc4mbed / samples / MSTest / USBDevice / USBHID / USBHID.cpp
CommitLineData
cd011f58
AW
1// USBHID.c\r
2// Human Interface Device (HID) class\r
3// Copyright (c) 2011 ARM Limited. All rights reserved.\r
4\r
5#include "stdint.h"\r
6#include "USBBusInterface.h"\r
7#include "USBHID.h"\r
8\r
9\r
10USBHID::USBHID(uint8_t output_report_length, uint8_t input_report_length, uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect): USBDevice(vendor_id, product_id, product_release)\r
11{\r
12 output_length = output_report_length;\r
13 input_length = input_report_length;\r
14 if(connect) {\r
15 USBDevice::connect();\r
16 }\r
17}\r
18\r
19\r
20bool USBHID::send(HID_REPORT *report)\r
21{\r
22 return write(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);\r
23}\r
24\r
25bool USBHID::sendNB(HID_REPORT *report)\r
26{\r
27 return writeNB(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);\r
28}\r
29\r
30\r
31bool USBHID::read(HID_REPORT *report)\r
32{\r
33 uint16_t bytesRead = 0;\r
34 bool result;\r
35 result = USBDevice::readEP(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);\r
36 if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))\r
37 return false;\r
38 report->length = bytesRead;\r
39 return result;\r
40}\r
41\r
42\r
43bool USBHID::readNB(HID_REPORT *report)\r
44{\r
45 uint16_t bytesRead = 0;\r
46 bool result;\r
47 result = USBDevice::readEP_NB(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);\r
48 report->length = bytesRead;\r
49 if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))\r
50 return false;\r
51 return result;\r
52}\r
53\r
54\r
55uint16_t USBHID::reportDescLength() {\r
56 reportDesc();\r
57 return reportLength;\r
58}\r
59\r
60\r
61\r
62//\r
63// Route callbacks from lower layers to class(es)\r
64//\r
65\r
66\r
67// Called in ISR context\r
68// Called by USBDevice on Endpoint0 request\r
69// This is used to handle extensions to standard requests\r
70// and class specific requests\r
71// Return true if class handles this request\r
72bool USBHID::USBCallback_request() {\r
73 bool success = false;\r
74 CONTROL_TRANSFER * transfer = getTransferPtr();\r
75 uint8_t *hidDescriptor;\r
76\r
77 // Process additional standard requests\r
78\r
79 if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE))\r
80 {\r
81 switch (transfer->setup.bRequest)\r
82 {\r
83 case GET_DESCRIPTOR:\r
84 switch (DESCRIPTOR_TYPE(transfer->setup.wValue))\r
85 {\r
86 case REPORT_DESCRIPTOR:\r
87 if ((reportDesc() != NULL) \\r
88 && (reportDescLength() != 0))\r
89 {\r
90 transfer->remaining = reportDescLength();\r
91 transfer->ptr = reportDesc();\r
92 transfer->direction = DEVICE_TO_HOST;\r
93 success = true;\r
94 }\r
95 break;\r
96 case HID_DESCRIPTOR:\r
97 // Find the HID descriptor, after the configuration descriptor\r
98 hidDescriptor = findDescriptor(HID_DESCRIPTOR);\r
99 if (hidDescriptor != NULL)\r
100 {\r
101 transfer->remaining = HID_DESCRIPTOR_LENGTH;\r
102 transfer->ptr = hidDescriptor;\r
103 transfer->direction = DEVICE_TO_HOST;\r
104 success = true;\r
105 }\r
106 break;\r
107 \r
108 default:\r
109 break;\r
110 }\r
111 break;\r
112 default:\r
113 break;\r
114 }\r
115 }\r
116\r
117 // Process class-specific requests\r
118\r
119 if (transfer->setup.bmRequestType.Type == CLASS_TYPE)\r
120 {\r
121 switch (transfer->setup.bRequest)\r
122 {\r
123 case SET_REPORT:\r
124 // First byte will be used for report ID\r
125 outputReport.data[0] = transfer->setup.wValue & 0xff;\r
126 outputReport.length = transfer->setup.wLength + 1;\r
127\r
128 transfer->remaining = sizeof(outputReport.data) - 1;\r
129 transfer->ptr = &outputReport.data[1];\r
130 transfer->direction = HOST_TO_DEVICE;\r
131 transfer->notify = true;\r
132 success = true;\r
133 default:\r
134 break;\r
135 }\r
136 }\r
137\r
138 return success;\r
139}\r
140\r
141\r
142#define DEFAULT_CONFIGURATION (1)\r
143\r
144\r
145// Called in ISR context\r
146// Set configuration. Return false if the\r
147// configuration is not supported\r
148bool USBHID::USBCallback_setConfiguration(uint8_t configuration) {\r
149 if (configuration != DEFAULT_CONFIGURATION) {\r
150 return false;\r
151 }\r
152\r
153 // Configure endpoints > 0\r
154 addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);\r
155 addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);\r
156\r
157 // We activate the endpoint to be able to recceive data\r
158 readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);\r
159 return true;\r
160}\r
161\r
162\r
163uint8_t * USBHID::stringIinterfaceDesc() {\r
164 static uint8_t stringIinterfaceDescriptor[] = {\r
165 0x08, //bLength\r
166 STRING_DESCRIPTOR, //bDescriptorType 0x03\r
167 'H',0,'I',0,'D',0, //bString iInterface - HID\r
168 };\r
169 return stringIinterfaceDescriptor;\r
170}\r
171\r
172uint8_t * USBHID::stringIproductDesc() {\r
173 static uint8_t stringIproductDescriptor[] = {\r
174 0x16, //bLength\r
175 STRING_DESCRIPTOR, //bDescriptorType 0x03\r
176 'H',0,'I',0,'D',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 //bString iProduct - HID device\r
177 };\r
178 return stringIproductDescriptor;\r
179}\r
180\r
181\r
182\r
183uint8_t * USBHID::reportDesc() {\r
184 static uint8_t reportDescriptor[] = {\r
185 0x06, LSB(0xFFAB), MSB(0xFFAB),\r
186 0x0A, LSB(0x0200), MSB(0x0200),\r
187 0xA1, 0x01, // Collection 0x01\r
188 0x75, 0x08, // report size = 8 bits\r
189 0x15, 0x00, // logical minimum = 0\r
190 0x26, 0xFF, 0x00, // logical maximum = 255\r
191 0x95, input_length, // report count\r
192 0x09, 0x01, // usage\r
193 0x81, 0x02, // Input (array)\r
194 0x95, output_length, // report count\r
195 0x09, 0x02, // usage\r
196 0x91, 0x02, // Output (array)\r
197 0xC0 // end collection\r
198\r
199 };\r
200 reportLength = sizeof(reportDescriptor);\r
201 return reportDescriptor;\r
202}\r
203\r
204#define DEFAULT_CONFIGURATION (1)\r
205#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \\r
206 + (1 * INTERFACE_DESCRIPTOR_LENGTH) \\r
207 + (1 * HID_DESCRIPTOR_LENGTH) \\r
208 + (2 * ENDPOINT_DESCRIPTOR_LENGTH))\r
209\r
210uint8_t * USBHID::configurationDesc() {\r
211 static uint8_t configurationDescriptor[] = {\r
212 CONFIGURATION_DESCRIPTOR_LENGTH,// bLength\r
213 CONFIGURATION_DESCRIPTOR, // bDescriptorType\r
214 LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB)\r
215 MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB)\r
216 0x01, // bNumInterfaces\r
217 DEFAULT_CONFIGURATION, // bConfigurationValue\r
218 0x00, // iConfiguration\r
219 C_RESERVED | C_SELF_POWERED, // bmAttributes\r
220 C_POWER(0), // bMaxPower\r
221\r
222 INTERFACE_DESCRIPTOR_LENGTH, // bLength\r
223 INTERFACE_DESCRIPTOR, // bDescriptorType\r
224 0x00, // bInterfaceNumber\r
225 0x00, // bAlternateSetting\r
226 0x02, // bNumEndpoints\r
227 HID_CLASS, // bInterfaceClass\r
228 HID_SUBCLASS_NONE, // bInterfaceSubClass\r
229 HID_PROTOCOL_NONE, // bInterfaceProtocol\r
230 0x00, // iInterface\r
231\r
232 HID_DESCRIPTOR_LENGTH, // bLength\r
233 HID_DESCRIPTOR, // bDescriptorType\r
234 LSB(HID_VERSION_1_11), // bcdHID (LSB)\r
235 MSB(HID_VERSION_1_11), // bcdHID (MSB)\r
236 0x00, // bCountryCode\r
237 0x01, // bNumDescriptors\r
238 REPORT_DESCRIPTOR, // bDescriptorType\r
239 LSB(this->reportDescLength()), // wDescriptorLength (LSB)\r
240 MSB(this->reportDescLength()), // wDescriptorLength (MSB)\r
241\r
242 ENDPOINT_DESCRIPTOR_LENGTH, // bLength\r
243 ENDPOINT_DESCRIPTOR, // bDescriptorType\r
244 PHY_TO_DESC(EPINT_IN), // bEndpointAddress\r
245 E_INTERRUPT, // bmAttributes\r
246 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)\r
247 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)\r
248 1, // bInterval (milliseconds)\r
249\r
250 ENDPOINT_DESCRIPTOR_LENGTH, // bLength\r
251 ENDPOINT_DESCRIPTOR, // bDescriptorType\r
252 PHY_TO_DESC(EPINT_OUT), // bEndpointAddress\r
253 E_INTERRUPT, // bmAttributes\r
254 LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)\r
255 MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)\r
256 1, // bInterval (milliseconds)\r
257 };\r
258 return configurationDescriptor;\r
259}\r