]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/USBDevice/USBHID/USBHID.cpp
Merge commit '657d9f23fe47fb88cf221adb23095082f191ba6a'
[max/tmk_keyboard.git] / tmk_core / tool / mbed / mbed-sdk / libraries / USBDevice / USBHID / USBHID.cpp
1 /* Copyright (c) 2010-2011 mbed.org, MIT License
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
4 * and associated documentation files (the "Software"), to deal in the Software without
5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
7 * Software is furnished to do so, subject to the following conditions:
8 *
9 * The above copyright notice and this permission notice shall be included in all copies or
10 * substantial portions of the Software.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17 */
18
19 #include "stdint.h"
20 #include "USBHAL.h"
21 #include "USBHID.h"
22
23
24 USBHID::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)
25 {
26     output_length = output_report_length;
27     input_length = input_report_length;
28     if(connect) {
29         USBDevice::connect();
30     }
31 }
32
33
34 bool USBHID::send(HID_REPORT *report)
35 {
36     return write(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
37 }
38
39 bool USBHID::sendNB(HID_REPORT *report)
40 {
41     return writeNB(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
42 }
43
44
45 bool USBHID::read(HID_REPORT *report)
46 {
47     uint32_t bytesRead = 0;
48     bool result;
49     result = USBDevice::readEP(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
50     if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
51         return false;
52     report->length = bytesRead;
53     return result;
54 }
55
56
57 bool USBHID::readNB(HID_REPORT *report)
58 {
59     uint32_t bytesRead = 0;
60     bool result;
61     result = USBDevice::readEP_NB(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
62     // if readEP_NB did not succeed, does not issue a readStart
63     if (!result)
64         return false;
65     report->length = bytesRead;
66     if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
67         return false;
68     return result;
69 }
70
71
72 uint16_t USBHID::reportDescLength() {
73     reportDesc();
74     return reportLength;
75 }
76
77
78
79 //
80 //  Route callbacks from lower layers to class(es)
81 //
82
83
84 // Called in ISR context
85 // Called by USBDevice on Endpoint0 request
86 // This is used to handle extensions to standard requests
87 // and class specific requests
88 // Return true if class handles this request
89 bool USBHID::USBCallback_request() {
90     bool success = false;
91     CONTROL_TRANSFER * transfer = getTransferPtr();
92     uint8_t *hidDescriptor;
93
94     // Process additional standard requests
95
96     if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE))
97     {
98         switch (transfer->setup.bRequest)
99         {
100             case GET_DESCRIPTOR:
101                 switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
102                 {
103                     case REPORT_DESCRIPTOR:
104                         if ((reportDesc() != NULL) \
105                             && (reportDescLength() != 0))
106                         {
107                             transfer->remaining = reportDescLength();
108                             transfer->ptr = reportDesc();
109                             transfer->direction = DEVICE_TO_HOST;
110                             success = true;
111                         }
112                         break;
113                     case HID_DESCRIPTOR:
114                             // Find the HID descriptor, after the configuration descriptor
115                             hidDescriptor = findDescriptor(HID_DESCRIPTOR);
116                             if (hidDescriptor != NULL)
117                             {
118                                 transfer->remaining = HID_DESCRIPTOR_LENGTH;
119                                 transfer->ptr = hidDescriptor;
120                                 transfer->direction = DEVICE_TO_HOST;
121                                 success = true;
122                             }
123                             break;
124
125                     default:
126                         break;
127                 }
128                 break;
129             default:
130                 break;
131         }
132     }
133
134     // Process class-specific requests
135
136     if (transfer->setup.bmRequestType.Type == CLASS_TYPE)
137     {
138         switch (transfer->setup.bRequest)
139         {
140              case SET_REPORT:
141                 // First byte will be used for report ID
142                 outputReport.data[0] = transfer->setup.wValue & 0xff;
143                 outputReport.length = transfer->setup.wLength + 1;
144
145                 transfer->remaining = sizeof(outputReport.data) - 1;
146                 transfer->ptr = &outputReport.data[1];
147                 transfer->direction = HOST_TO_DEVICE;
148                 transfer->notify = true;
149                 success = true;
150             default:
151                 break;
152         }
153     }
154
155     return success;
156 }
157
158
159 #define DEFAULT_CONFIGURATION (1)
160
161
162 // Called in ISR context
163 // Set configuration. Return false if the
164 // configuration is not supported
165 bool USBHID::USBCallback_setConfiguration(uint8_t configuration) {
166     if (configuration != DEFAULT_CONFIGURATION) {
167         return false;
168     }
169
170     // Configure endpoints > 0
171     addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
172     addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
173
174     // We activate the endpoint to be able to recceive data
175     readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
176     return true;
177 }
178
179
180 uint8_t * USBHID::stringIinterfaceDesc() {
181     static uint8_t stringIinterfaceDescriptor[] = {
182         0x08,               //bLength
183         STRING_DESCRIPTOR,  //bDescriptorType 0x03
184         'H',0,'I',0,'D',0,  //bString iInterface - HID
185     };
186     return stringIinterfaceDescriptor;
187 }
188
189 uint8_t * USBHID::stringIproductDesc() {
190     static uint8_t stringIproductDescriptor[] = {
191         0x16,                                                       //bLength
192         STRING_DESCRIPTOR,                                          //bDescriptorType 0x03
193         'H',0,'I',0,'D',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 //bString iProduct - HID device
194     };
195     return stringIproductDescriptor;
196 }
197
198
199
200 uint8_t * USBHID::reportDesc() {
201     static uint8_t reportDescriptor[] = {
202         0x06, LSB(0xFFAB), MSB(0xFFAB),
203         0x0A, LSB(0x0200), MSB(0x0200),
204         0xA1, 0x01,         // Collection 0x01
205         0x75, 0x08,         // report size = 8 bits
206         0x15, 0x00,         // logical minimum = 0
207         0x26, 0xFF, 0x00,   // logical maximum = 255
208         0x95, input_length, // report count
209         0x09, 0x01,         // usage
210         0x81, 0x02,         // Input (array)
211         0x95, output_length,// report count
212         0x09, 0x02,         // usage
213         0x91, 0x02,         // Output (array)
214         0xC0                // end collection
215
216     };
217     reportLength = sizeof(reportDescriptor);
218     return reportDescriptor;
219 }
220
221 #define DEFAULT_CONFIGURATION (1)
222 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
223                                + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
224                                + (1 * HID_DESCRIPTOR_LENGTH) \
225                                + (2 * ENDPOINT_DESCRIPTOR_LENGTH))
226
227 uint8_t * USBHID::configurationDesc() {
228     static uint8_t configurationDescriptor[] = {
229         CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
230         CONFIGURATION_DESCRIPTOR,       // bDescriptorType
231         LSB(TOTAL_DESCRIPTOR_LENGTH),   // wTotalLength (LSB)
232         MSB(TOTAL_DESCRIPTOR_LENGTH),   // wTotalLength (MSB)
233         0x01,                           // bNumInterfaces
234         DEFAULT_CONFIGURATION,          // bConfigurationValue
235         0x00,                           // iConfiguration
236         C_RESERVED | C_SELF_POWERED,    // bmAttributes
237         C_POWER(0),                     // bMaxPower
238
239         INTERFACE_DESCRIPTOR_LENGTH,    // bLength
240         INTERFACE_DESCRIPTOR,           // bDescriptorType
241         0x00,                           // bInterfaceNumber
242         0x00,                           // bAlternateSetting
243         0x02,                           // bNumEndpoints
244         HID_CLASS,                      // bInterfaceClass
245         HID_SUBCLASS_NONE,              // bInterfaceSubClass
246         HID_PROTOCOL_NONE,              // bInterfaceProtocol
247         0x00,                           // iInterface
248
249         HID_DESCRIPTOR_LENGTH,          // bLength
250         HID_DESCRIPTOR,                 // bDescriptorType
251         LSB(HID_VERSION_1_11),          // bcdHID (LSB)
252         MSB(HID_VERSION_1_11),          // bcdHID (MSB)
253         0x00,                           // bCountryCode
254         0x01,                           // bNumDescriptors
255         REPORT_DESCRIPTOR,              // bDescriptorType
256         (uint8_t)(LSB(this->reportDescLength())),  // wDescriptorLength (LSB)
257         (uint8_t)(MSB(this->reportDescLength())),  // wDescriptorLength (MSB)
258
259         ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
260         ENDPOINT_DESCRIPTOR,            // bDescriptorType
261         PHY_TO_DESC(EPINT_IN),          // bEndpointAddress
262         E_INTERRUPT,                    // bmAttributes
263         LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
264         MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
265         1,                             // bInterval (milliseconds)
266
267         ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
268         ENDPOINT_DESCRIPTOR,            // bDescriptorType
269         PHY_TO_DESC(EPINT_OUT),          // bEndpointAddress
270         E_INTERRUPT,                    // bmAttributes
271         LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
272         MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
273         1,                             // bInterval (milliseconds)
274     };
275     return configurationDescriptor;
276 }