35f00b6c |
1 | /* Teensyduino Core Library |
2 | * http://www.pjrc.com/teensy/ |
3 | * Copyright (c) 2013 PJRC.COM, LLC. |
4 | * |
5 | * Permission is hereby granted, free of charge, to any person obtaining |
6 | * a copy of this software and associated documentation files (the |
7 | * "Software"), to deal in the Software without restriction, including |
8 | * without limitation the rights to use, copy, modify, merge, publish, |
9 | * distribute, sublicense, and/or sell copies of the Software, and to |
10 | * permit persons to whom the Software is furnished to do so, subject to |
11 | * the following conditions: |
12 | * |
13 | * 1. The above copyright notice and this permission notice shall be |
14 | * included in all copies or substantial portions of the Software. |
15 | * |
16 | * 2. If the Software is incorporated into a build system that allows |
17 | * selection among a list of target devices, then similar target |
18 | * devices manufactured by PJRC.COM must be included in the list of |
19 | * target devices and selectable in the same manner. |
20 | * |
21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
22 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
23 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
24 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
25 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
26 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
27 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
28 | * SOFTWARE. |
29 | */ |
30 | |
31 | #include "usb_desc.h" |
32 | #include "usb_names.h" |
33 | #include "mk20dx128.h" |
34 | #include "avr_functions.h" |
35 | |
36 | // USB Descriptors are binary data which the USB host reads to |
37 | // automatically detect a USB device's capabilities. The format |
38 | // and meaning of every field is documented in numerous USB |
39 | // standards. When working with USB descriptors, despite the |
40 | // complexity of the standards and poor writing quality in many |
41 | // of those documents, remember descriptors are nothing more |
42 | // than constant binary data that tells the USB host what the |
43 | // device can do. Computers will load drivers based on this data. |
44 | // Those drivers then communicate on the endpoints specified by |
45 | // the descriptors. |
46 | |
47 | // To configure a new combination of interfaces or make minor |
48 | // changes to existing configuration (eg, change the name or ID |
49 | // numbers), usually you would edit "usb_desc.h". This file |
50 | // is meant to be configured by the header, so generally it is |
51 | // only edited to add completely new USB interfaces or features. |
52 | |
53 | |
54 | |
55 | // ************************************************************** |
56 | // USB Device |
57 | // ************************************************************** |
58 | |
59 | #define LSB(n) ((n) & 255) |
60 | #define MSB(n) (((n) >> 8) & 255) |
61 | |
62 | // USB Device Descriptor. The USB host reads this first, to learn |
63 | // what type of device is connected. |
64 | static uint8_t device_descriptor[] = { |
65 | 18, // bLength |
66 | 1, // bDescriptorType |
67 | 0x00, 0x02, // bcdUSB |
68 | #ifdef DEVICE_CLASS |
69 | DEVICE_CLASS, // bDeviceClass |
70 | #else |
71 | 0, |
72 | #endif |
73 | #ifdef DEVICE_SUBCLASS |
74 | DEVICE_SUBCLASS, // bDeviceSubClass |
75 | #else |
76 | 0, |
77 | #endif |
78 | #ifdef DEVICE_PROTOCOL |
79 | DEVICE_PROTOCOL, // bDeviceProtocol |
80 | #else |
81 | 0, |
82 | #endif |
83 | EP0_SIZE, // bMaxPacketSize0 |
84 | LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor |
85 | LSB(PRODUCT_ID), MSB(PRODUCT_ID), // idProduct |
86 | 0x00, 0x01, // bcdDevice |
87 | 1, // iManufacturer |
88 | 2, // iProduct |
89 | 3, // iSerialNumber |
90 | 1 // bNumConfigurations |
91 | }; |
92 | |
93 | // These descriptors must NOT be "const", because the USB DMA |
94 | // has trouble accessing flash memory with enough bandwidth |
95 | // while the processor is executing from flash. |
96 | |
97 | |
98 | |
99 | // ************************************************************** |
100 | // HID Report Descriptors |
101 | // ************************************************************** |
102 | |
103 | // Each HID interface needs a special report descriptor that tells |
104 | // the meaning and format of the data. |
105 | |
106 | #ifdef KEYBOARD_INTERFACE |
107 | // Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60 |
108 | static uint8_t keyboard_report_desc[] = { |
109 | 0x05, 0x01, // Usage Page (Generic Desktop), |
110 | 0x09, 0x06, // Usage (Keyboard), |
111 | 0xA1, 0x01, // Collection (Application), |
112 | 0x75, 0x01, // Report Size (1), |
113 | 0x95, 0x08, // Report Count (8), |
114 | 0x05, 0x07, // Usage Page (Key Codes), |
115 | 0x19, 0xE0, // Usage Minimum (224), |
116 | 0x29, 0xE7, // Usage Maximum (231), |
117 | 0x15, 0x00, // Logical Minimum (0), |
118 | 0x25, 0x01, // Logical Maximum (1), |
119 | 0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte |
120 | 0x95, 0x08, // Report Count (8), |
121 | 0x75, 0x01, // Report Size (1), |
122 | 0x15, 0x00, // Logical Minimum (0), |
123 | 0x25, 0x01, // Logical Maximum (1), |
124 | 0x05, 0x0C, // Usage Page (Consumer), |
125 | 0x09, 0xE9, // Usage (Volume Increment), |
126 | 0x09, 0xEA, // Usage (Volume Decrement), |
127 | 0x09, 0xE2, // Usage (Mute), |
128 | 0x09, 0xCD, // Usage (Play/Pause), |
129 | 0x09, 0xB5, // Usage (Scan Next Track), |
130 | 0x09, 0xB6, // Usage (Scan Previous Track), |
131 | 0x09, 0xB7, // Usage (Stop), |
132 | 0x09, 0xB8, // Usage (Eject), |
133 | 0x81, 0x02, // Input (Data, Variable, Absolute), ;Media keys |
134 | 0x95, 0x05, // Report Count (5), |
135 | 0x75, 0x01, // Report Size (1), |
136 | 0x05, 0x08, // Usage Page (LEDs), |
137 | 0x19, 0x01, // Usage Minimum (1), |
138 | 0x29, 0x05, // Usage Maximum (5), |
139 | 0x91, 0x02, // Output (Data, Variable, Absolute), ;LED report |
140 | 0x95, 0x01, // Report Count (1), |
141 | 0x75, 0x03, // Report Size (3), |
142 | 0x91, 0x03, // Output (Constant), ;LED report padding |
143 | 0x95, 0x06, // Report Count (6), |
144 | 0x75, 0x08, // Report Size (8), |
145 | 0x15, 0x00, // Logical Minimum (0), |
146 | 0x25, 0x7F, // Logical Maximum(104), |
147 | 0x05, 0x07, // Usage Page (Key Codes), |
148 | 0x19, 0x00, // Usage Minimum (0), |
149 | 0x29, 0x7F, // Usage Maximum (104), |
150 | 0x81, 0x00, // Input (Data, Array), ;Normal keys |
151 | 0xc0 // End Collection |
152 | }; |
153 | #endif |
154 | |
155 | #ifdef MOUSE_INTERFACE |
156 | // Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension |
157 | static uint8_t mouse_report_desc[] = { |
158 | 0x05, 0x01, // Usage Page (Generic Desktop) |
159 | 0x09, 0x02, // Usage (Mouse) |
160 | 0xA1, 0x01, // Collection (Application) |
161 | 0x05, 0x09, // Usage Page (Button) |
162 | 0x19, 0x01, // Usage Minimum (Button #1) |
163 | 0x29, 0x03, // Usage Maximum (Button #3) |
164 | 0x15, 0x00, // Logical Minimum (0) |
165 | 0x25, 0x01, // Logical Maximum (1) |
166 | 0x95, 0x03, // Report Count (3) |
167 | 0x75, 0x01, // Report Size (1) |
168 | 0x81, 0x02, // Input (Data, Variable, Absolute) |
169 | 0x95, 0x01, // Report Count (1) |
170 | 0x75, 0x05, // Report Size (5) |
171 | 0x81, 0x03, // Input (Constant) |
172 | 0x05, 0x01, // Usage Page (Generic Desktop) |
173 | 0x09, 0x30, // Usage (X) |
174 | 0x09, 0x31, // Usage (Y) |
175 | 0x15, 0x00, // Logical Minimum (0) |
176 | 0x26, 0xFF, 0x7F, // Logical Maximum (32767) |
177 | 0x75, 0x10, // Report Size (16), |
178 | 0x95, 0x02, // Report Count (2), |
179 | 0x81, 0x02, // Input (Data, Variable, Absolute) |
180 | 0x09, 0x38, // Usage (Wheel) |
181 | 0x15, 0x81, // Logical Minimum (-127) |
182 | 0x25, 0x7F, // Logical Maximum (127) |
183 | 0x75, 0x08, // Report Size (8), |
184 | 0x95, 0x01, // Report Count (1), |
185 | 0x81, 0x06, // Input (Data, Variable, Relative) |
186 | 0xC0 // End Collection |
187 | }; |
188 | #endif |
189 | |
190 | #ifdef JOYSTICK_INTERFACE |
191 | static uint8_t joystick_report_desc[] = { |
192 | 0x05, 0x01, // Usage Page (Generic Desktop) |
193 | 0x09, 0x04, // Usage (Joystick) |
194 | 0xA1, 0x01, // Collection (Application) |
195 | 0x15, 0x00, // Logical Minimum (0) |
196 | 0x25, 0x01, // Logical Maximum (1) |
197 | 0x75, 0x01, // Report Size (1) |
198 | 0x95, 0x20, // Report Count (32) |
199 | 0x05, 0x09, // Usage Page (Button) |
200 | 0x19, 0x01, // Usage Minimum (Button #1) |
201 | 0x29, 0x20, // Usage Maximum (Button #32) |
202 | 0x81, 0x02, // Input (variable,absolute) |
203 | 0x15, 0x00, // Logical Minimum (0) |
204 | 0x25, 0x07, // Logical Maximum (7) |
205 | 0x35, 0x00, // Physical Minimum (0) |
206 | 0x46, 0x3B, 0x01, // Physical Maximum (315) |
207 | 0x75, 0x04, // Report Size (4) |
208 | 0x95, 0x01, // Report Count (1) |
209 | 0x65, 0x14, // Unit (20) |
210 | 0x05, 0x01, // Usage Page (Generic Desktop) |
211 | 0x09, 0x39, // Usage (Hat switch) |
212 | 0x81, 0x42, // Input (variable,absolute,null_state) |
213 | 0x05, 0x01, // Usage Page (Generic Desktop) |
214 | 0x09, 0x01, // Usage (Pointer) |
215 | 0xA1, 0x00, // Collection () |
216 | 0x15, 0x00, // Logical Minimum (0) |
217 | 0x26, 0xFF, 0x03, // Logical Maximum (1023) |
218 | 0x75, 0x0A, // Report Size (10) |
219 | 0x95, 0x04, // Report Count (4) |
220 | 0x09, 0x30, // Usage (X) |
221 | 0x09, 0x31, // Usage (Y) |
222 | 0x09, 0x32, // Usage (Z) |
223 | 0x09, 0x35, // Usage (Rz) |
224 | 0x81, 0x02, // Input (variable,absolute) |
225 | 0xC0, // End Collection |
226 | 0x15, 0x00, // Logical Minimum (0) |
227 | 0x26, 0xFF, 0x03, // Logical Maximum (1023) |
228 | 0x75, 0x0A, // Report Size (10) |
229 | 0x95, 0x02, // Report Count (2) |
230 | 0x09, 0x36, // Usage (Slider) |
231 | 0x09, 0x36, // Usage (Slider) |
232 | 0x81, 0x02, // Input (variable,absolute) |
233 | 0xC0 // End Collection |
234 | }; |
235 | #endif |
236 | |
237 | #ifdef SEREMU_INTERFACE |
238 | static uint8_t seremu_report_desc[] = { |
239 | 0x06, 0xC9, 0xFF, // Usage Page 0xFFC9 (vendor defined) |
240 | 0x09, 0x04, // Usage 0x04 |
241 | 0xA1, 0x5C, // Collection 0x5C |
242 | 0x75, 0x08, // report size = 8 bits (global) |
243 | 0x15, 0x00, // logical minimum = 0 (global) |
244 | 0x26, 0xFF, 0x00, // logical maximum = 255 (global) |
245 | 0x95, SEREMU_TX_SIZE, // report count (global) |
246 | 0x09, 0x75, // usage (local) |
247 | 0x81, 0x02, // Input |
248 | 0x95, SEREMU_RX_SIZE, // report count (global) |
249 | 0x09, 0x76, // usage (local) |
250 | 0x91, 0x02, // Output |
251 | 0x95, 0x04, // report count (global) |
252 | 0x09, 0x76, // usage (local) |
253 | 0xB1, 0x02, // Feature |
254 | 0xC0 // end collection |
255 | }; |
256 | #endif |
257 | |
258 | #ifdef RAWHID_INTERFACE |
259 | static uint8_t rawhid_report_desc[] = { |
260 | 0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE), |
261 | 0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE), |
262 | 0xA1, 0x01, // Collection 0x01 |
263 | 0x75, 0x08, // report size = 8 bits |
264 | 0x15, 0x00, // logical minimum = 0 |
265 | 0x26, 0xFF, 0x00, // logical maximum = 255 |
266 | 0x95, RAWHID_TX_SIZE, // report count |
267 | 0x09, 0x01, // usage |
268 | 0x81, 0x02, // Input (array) |
269 | 0x95, RAWHID_RX_SIZE, // report count |
270 | 0x09, 0x02, // usage |
271 | 0x91, 0x02, // Output (array) |
272 | 0xC0 // end collection |
273 | }; |
274 | #endif |
275 | |
276 | #ifdef FLIGHTSIM_INTERFACE |
277 | static uint8_t flightsim_report_desc[] = { |
278 | 0x06, 0x1C, 0xFF, // Usage page = 0xFF1C |
279 | 0x0A, 0x39, 0xA7, // Usage = 0xA739 |
280 | 0xA1, 0x01, // Collection 0x01 |
281 | 0x75, 0x08, // report size = 8 bits |
282 | 0x15, 0x00, // logical minimum = 0 |
283 | 0x26, 0xFF, 0x00, // logical maximum = 255 |
284 | 0x95, FLIGHTSIM_TX_SIZE, // report count |
285 | 0x09, 0x01, // usage |
286 | 0x81, 0x02, // Input (array) |
287 | 0x95, FLIGHTSIM_RX_SIZE, // report count |
288 | 0x09, 0x02, // usage |
289 | 0x91, 0x02, // Output (array) |
290 | 0xC0 // end collection |
291 | }; |
292 | #endif |
293 | |
294 | |
295 | |
296 | // ************************************************************** |
297 | // USB Configuration |
298 | // ************************************************************** |
299 | |
300 | // USB Configuration Descriptor. This huge descriptor tells all |
301 | // of the devices capbilities. |
302 | static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { |
303 | // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10 |
304 | 9, // bLength; |
305 | 2, // bDescriptorType; |
306 | LSB(CONFIG_DESC_SIZE), // wTotalLength |
307 | MSB(CONFIG_DESC_SIZE), |
308 | NUM_INTERFACE, // bNumInterfaces |
309 | 1, // bConfigurationValue |
310 | 0, // iConfiguration |
311 | 0xC0, // bmAttributes |
312 | 50, // bMaxPower |
313 | |
314 | #ifdef CDC_IAD_DESCRIPTOR |
315 | // interface association descriptor, USB ECN, Table 9-Z |
316 | 8, // bLength |
317 | 11, // bDescriptorType |
318 | CDC_STATUS_INTERFACE, // bFirstInterface |
319 | 2, // bInterfaceCount |
320 | 0x02, // bFunctionClass |
321 | 0x02, // bFunctionSubClass |
322 | 0x01, // bFunctionProtocol |
323 | 4, // iFunction |
324 | #endif |
325 | |
326 | #ifdef CDC_DATA_INTERFACE |
327 | // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 |
328 | 9, // bLength |
329 | 4, // bDescriptorType |
330 | CDC_STATUS_INTERFACE, // bInterfaceNumber |
331 | 0, // bAlternateSetting |
332 | 1, // bNumEndpoints |
333 | 0x02, // bInterfaceClass |
334 | 0x02, // bInterfaceSubClass |
335 | 0x01, // bInterfaceProtocol |
336 | 0, // iInterface |
337 | // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26 |
338 | 5, // bFunctionLength |
339 | 0x24, // bDescriptorType |
340 | 0x00, // bDescriptorSubtype |
341 | 0x10, 0x01, // bcdCDC |
342 | // Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27 |
343 | 5, // bFunctionLength |
344 | 0x24, // bDescriptorType |
345 | 0x01, // bDescriptorSubtype |
346 | 0x01, // bmCapabilities |
347 | 1, // bDataInterface |
348 | // Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28 |
349 | 4, // bFunctionLength |
350 | 0x24, // bDescriptorType |
351 | 0x02, // bDescriptorSubtype |
352 | 0x06, // bmCapabilities |
353 | // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33 |
354 | 5, // bFunctionLength |
355 | 0x24, // bDescriptorType |
356 | 0x06, // bDescriptorSubtype |
357 | CDC_STATUS_INTERFACE, // bMasterInterface |
358 | CDC_DATA_INTERFACE, // bSlaveInterface0 |
359 | // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 |
360 | 7, // bLength |
361 | 5, // bDescriptorType |
362 | CDC_ACM_ENDPOINT | 0x80, // bEndpointAddress |
363 | 0x03, // bmAttributes (0x03=intr) |
364 | CDC_ACM_SIZE, 0, // wMaxPacketSize |
365 | 64, // bInterval |
366 | // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 |
367 | 9, // bLength |
368 | 4, // bDescriptorType |
369 | CDC_DATA_INTERFACE, // bInterfaceNumber |
370 | 0, // bAlternateSetting |
371 | 2, // bNumEndpoints |
372 | 0x0A, // bInterfaceClass |
373 | 0x00, // bInterfaceSubClass |
374 | 0x00, // bInterfaceProtocol |
375 | 0, // iInterface |
376 | // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 |
377 | 7, // bLength |
378 | 5, // bDescriptorType |
379 | CDC_RX_ENDPOINT, // bEndpointAddress |
380 | 0x02, // bmAttributes (0x02=bulk) |
381 | CDC_RX_SIZE, 0, // wMaxPacketSize |
382 | 0, // bInterval |
383 | // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 |
384 | 7, // bLength |
385 | 5, // bDescriptorType |
386 | CDC_TX_ENDPOINT | 0x80, // bEndpointAddress |
387 | 0x02, // bmAttributes (0x02=bulk) |
388 | CDC_TX_SIZE, 0, // wMaxPacketSize |
389 | 0, // bInterval |
390 | #endif // CDC_DATA_INTERFACE |
391 | |
392 | #ifdef MIDI_INTERFACE |
393 | // Standard MS Interface Descriptor, |
394 | 9, // bLength |
395 | 4, // bDescriptorType |
396 | MIDI_INTERFACE, // bInterfaceNumber |
397 | 0, // bAlternateSetting |
398 | 2, // bNumEndpoints |
399 | 0x01, // bInterfaceClass (0x01 = Audio) |
400 | 0x03, // bInterfaceSubClass (0x03 = MIDI) |
401 | 0x00, // bInterfaceProtocol (unused for MIDI) |
402 | 0, // iInterface |
403 | // MIDI MS Interface Header, USB MIDI 6.1.2.1, page 21, Table 6-2 |
404 | 7, // bLength |
405 | 0x24, // bDescriptorType = CS_INTERFACE |
406 | 0x01, // bDescriptorSubtype = MS_HEADER |
407 | 0x00, 0x01, // bcdMSC = revision 01.00 |
408 | 0x41, 0x00, // wTotalLength |
409 | // MIDI IN Jack Descriptor, B.4.3, Table B-7 (embedded), page 40 |
410 | 6, // bLength |
411 | 0x24, // bDescriptorType = CS_INTERFACE |
412 | 0x02, // bDescriptorSubtype = MIDI_IN_JACK |
413 | 0x01, // bJackType = EMBEDDED |
414 | 1, // bJackID, ID = 1 |
415 | 0, // iJack |
416 | // MIDI IN Jack Descriptor, B.4.3, Table B-8 (external), page 40 |
417 | 6, // bLength |
418 | 0x24, // bDescriptorType = CS_INTERFACE |
419 | 0x02, // bDescriptorSubtype = MIDI_IN_JACK |
420 | 0x02, // bJackType = EXTERNAL |
421 | 2, // bJackID, ID = 2 |
422 | 0, // iJack |
423 | // MIDI OUT Jack Descriptor, B.4.4, Table B-9, page 41 |
424 | 9, |
425 | 0x24, // bDescriptorType = CS_INTERFACE |
426 | 0x03, // bDescriptorSubtype = MIDI_OUT_JACK |
427 | 0x01, // bJackType = EMBEDDED |
428 | 3, // bJackID, ID = 3 |
429 | 1, // bNrInputPins = 1 pin |
430 | 2, // BaSourceID(1) = 2 |
431 | 1, // BaSourcePin(1) = first pin |
432 | 0, // iJack |
433 | // MIDI OUT Jack Descriptor, B.4.4, Table B-10, page 41 |
434 | 9, |
435 | 0x24, // bDescriptorType = CS_INTERFACE |
436 | 0x03, // bDescriptorSubtype = MIDI_OUT_JACK |
437 | 0x02, // bJackType = EXTERNAL |
438 | 4, // bJackID, ID = 4 |
439 | 1, // bNrInputPins = 1 pin |
440 | 1, // BaSourceID(1) = 1 |
441 | 1, // BaSourcePin(1) = first pin |
442 | 0, // iJack |
443 | // Standard Bulk OUT Endpoint Descriptor, B.5.1, Table B-11, pae 42 |
444 | 9, // bLength |
445 | 5, // bDescriptorType = ENDPOINT |
446 | MIDI_RX_ENDPOINT, // bEndpointAddress |
447 | 0x02, // bmAttributes (0x02=bulk) |
448 | MIDI_RX_SIZE, 0, // wMaxPacketSize |
449 | 0, // bInterval |
450 | 0, // bRefresh |
451 | 0, // bSynchAddress |
452 | // Class-specific MS Bulk OUT Endpoint Descriptor, B.5.2, Table B-12, page 42 |
453 | 5, // bLength |
454 | 0x25, // bDescriptorSubtype = CS_ENDPOINT |
455 | 0x01, // bJackType = MS_GENERAL |
456 | 1, // bNumEmbMIDIJack = 1 jack |
457 | 1, // BaAssocJackID(1) = jack ID #1 |
458 | // Standard Bulk IN Endpoint Descriptor, B.5.1, Table B-11, pae 42 |
459 | 9, // bLength |
460 | 5, // bDescriptorType = ENDPOINT |
461 | MIDI_TX_ENDPOINT | 0x80, // bEndpointAddress |
462 | 0x02, // bmAttributes (0x02=bulk) |
463 | MIDI_TX_SIZE, 0, // wMaxPacketSize |
464 | 0, // bInterval |
465 | 0, // bRefresh |
466 | 0, // bSynchAddress |
467 | // Class-specific MS Bulk IN Endpoint Descriptor, B.5.2, Table B-12, page 42 |
468 | 5, // bLength |
469 | 0x25, // bDescriptorSubtype = CS_ENDPOINT |
470 | 0x01, // bJackType = MS_GENERAL |
471 | 1, // bNumEmbMIDIJack = 1 jack |
472 | 3, // BaAssocJackID(1) = jack ID #3 |
473 | #endif // MIDI_INTERFACE |
474 | |
475 | #ifdef KEYBOARD_INTERFACE |
476 | // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 |
477 | 9, // bLength |
478 | 4, // bDescriptorType |
479 | KEYBOARD_INTERFACE, // bInterfaceNumber |
480 | 0, // bAlternateSetting |
481 | 1, // bNumEndpoints |
482 | 0x03, // bInterfaceClass (0x03 = HID) |
483 | 0x01, // bInterfaceSubClass (0x01 = Boot) |
484 | 0x01, // bInterfaceProtocol (0x01 = Keyboard) |
485 | 0, // iInterface |
486 | // HID interface descriptor, HID 1.11 spec, section 6.2.1 |
487 | 9, // bLength |
488 | 0x21, // bDescriptorType |
489 | 0x11, 0x01, // bcdHID |
490 | 0, // bCountryCode |
491 | 1, // bNumDescriptors |
492 | 0x22, // bDescriptorType |
493 | LSB(sizeof(keyboard_report_desc)), // wDescriptorLength |
494 | MSB(sizeof(keyboard_report_desc)), |
495 | // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 |
496 | 7, // bLength |
497 | 5, // bDescriptorType |
498 | KEYBOARD_ENDPOINT | 0x80, // bEndpointAddress |
499 | 0x03, // bmAttributes (0x03=intr) |
500 | KEYBOARD_SIZE, 0, // wMaxPacketSize |
501 | KEYBOARD_INTERVAL, // bInterval |
502 | #endif // KEYBOARD_INTERFACE |
503 | |
504 | #ifdef MOUSE_INTERFACE |
505 | // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 |
506 | 9, // bLength |
507 | 4, // bDescriptorType |
508 | MOUSE_INTERFACE, // bInterfaceNumber |
509 | 0, // bAlternateSetting |
510 | 1, // bNumEndpoints |
511 | 0x03, // bInterfaceClass (0x03 = HID) |
512 | 0x00, // bInterfaceSubClass (0x01 = Boot) |
513 | 0x00, // bInterfaceProtocol (0x02 = Mouse) |
514 | 0, // iInterface |
515 | // HID interface descriptor, HID 1.11 spec, section 6.2.1 |
516 | 9, // bLength |
517 | 0x21, // bDescriptorType |
518 | 0x11, 0x01, // bcdHID |
519 | 0, // bCountryCode |
520 | 1, // bNumDescriptors |
521 | 0x22, // bDescriptorType |
522 | LSB(sizeof(mouse_report_desc)), // wDescriptorLength |
523 | MSB(sizeof(mouse_report_desc)), |
524 | // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 |
525 | 7, // bLength |
526 | 5, // bDescriptorType |
527 | MOUSE_ENDPOINT | 0x80, // bEndpointAddress |
528 | 0x03, // bmAttributes (0x03=intr) |
529 | MOUSE_SIZE, 0, // wMaxPacketSize |
530 | MOUSE_INTERVAL, // bInterval |
531 | #endif // MOUSE_INTERFACE |
532 | |
533 | #ifdef RAWHID_INTERFACE |
534 | // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 |
535 | 9, // bLength |
536 | 4, // bDescriptorType |
537 | RAWHID_INTERFACE, // bInterfaceNumber |
538 | 0, // bAlternateSetting |
539 | 2, // bNumEndpoints |
540 | 0x03, // bInterfaceClass (0x03 = HID) |
541 | 0x00, // bInterfaceSubClass |
542 | 0x00, // bInterfaceProtocol |
543 | 0, // iInterface |
544 | // HID interface descriptor, HID 1.11 spec, section 6.2.1 |
545 | 9, // bLength |
546 | 0x21, // bDescriptorType |
547 | 0x11, 0x01, // bcdHID |
548 | 0, // bCountryCode |
549 | 1, // bNumDescriptors |
550 | 0x22, // bDescriptorType |
551 | LSB(sizeof(rawhid_report_desc)), // wDescriptorLength |
552 | MSB(sizeof(rawhid_report_desc)), |
553 | // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 |
554 | 7, // bLength |
555 | 5, // bDescriptorType |
556 | RAWHID_TX_ENDPOINT | 0x80, // bEndpointAddress |
557 | 0x03, // bmAttributes (0x03=intr) |
558 | RAWHID_TX_SIZE, 0, // wMaxPacketSize |
559 | RAWHID_TX_INTERVAL, // bInterval |
560 | // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 |
561 | 7, // bLength |
562 | 5, // bDescriptorType |
563 | RAWHID_RX_ENDPOINT, // bEndpointAddress |
564 | 0x03, // bmAttributes (0x03=intr) |
565 | RAWHID_RX_SIZE, 0, // wMaxPacketSize |
566 | RAWHID_RX_INTERVAL, // bInterval |
567 | #endif // RAWHID_INTERFACE |
568 | |
569 | #ifdef FLIGHTSIM_INTERFACE |
570 | // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 |
571 | 9, // bLength |
572 | 4, // bDescriptorType |
573 | FLIGHTSIM_INTERFACE, // bInterfaceNumber |
574 | 0, // bAlternateSetting |
575 | 2, // bNumEndpoints |
576 | 0x03, // bInterfaceClass (0x03 = HID) |
577 | 0x00, // bInterfaceSubClass |
578 | 0x00, // bInterfaceProtocol |
579 | 0, // iInterface |
580 | // HID interface descriptor, HID 1.11 spec, section 6.2.1 |
581 | 9, // bLength |
582 | 0x21, // bDescriptorType |
583 | 0x11, 0x01, // bcdHID |
584 | 0, // bCountryCode |
585 | 1, // bNumDescriptors |
586 | 0x22, // bDescriptorType |
587 | LSB(sizeof(flightsim_report_desc)), // wDescriptorLength |
588 | MSB(sizeof(flightsim_report_desc)), |
589 | // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 |
590 | 7, // bLength |
591 | 5, // bDescriptorType |
592 | FLIGHTSIM_TX_ENDPOINT | 0x80, // bEndpointAddress |
593 | 0x03, // bmAttributes (0x03=intr) |
594 | FLIGHTSIM_TX_SIZE, 0, // wMaxPacketSize |
595 | FLIGHTSIM_TX_INTERVAL, // bInterval |
596 | // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 |
597 | 7, // bLength |
598 | 5, // bDescriptorType |
599 | FLIGHTSIM_RX_ENDPOINT, // bEndpointAddress |
600 | 0x03, // bmAttributes (0x03=intr) |
601 | FLIGHTSIM_RX_SIZE, 0, // wMaxPacketSize |
602 | FLIGHTSIM_RX_INTERVAL, // bInterval |
603 | #endif // FLIGHTSIM_INTERFACE |
604 | |
605 | #ifdef SEREMU_INTERFACE |
606 | // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 |
607 | 9, // bLength |
608 | 4, // bDescriptorType |
609 | SEREMU_INTERFACE, // bInterfaceNumber |
610 | 0, // bAlternateSetting |
611 | 2, // bNumEndpoints |
612 | 0x03, // bInterfaceClass (0x03 = HID) |
613 | 0x00, // bInterfaceSubClass |
614 | 0x00, // bInterfaceProtocol |
615 | 0, // iInterface |
616 | // HID interface descriptor, HID 1.11 spec, section 6.2.1 |
617 | 9, // bLength |
618 | 0x21, // bDescriptorType |
619 | 0x11, 0x01, // bcdHID |
620 | 0, // bCountryCode |
621 | 1, // bNumDescriptors |
622 | 0x22, // bDescriptorType |
623 | LSB(sizeof(seremu_report_desc)), // wDescriptorLength |
624 | MSB(sizeof(seremu_report_desc)), |
625 | // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 |
626 | 7, // bLength |
627 | 5, // bDescriptorType |
628 | SEREMU_TX_ENDPOINT | 0x80, // bEndpointAddress |
629 | 0x03, // bmAttributes (0x03=intr) |
630 | SEREMU_TX_SIZE, 0, // wMaxPacketSize |
631 | SEREMU_TX_INTERVAL, // bInterval |
632 | // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 |
633 | 7, // bLength |
634 | 5, // bDescriptorType |
635 | SEREMU_RX_ENDPOINT, // bEndpointAddress |
636 | 0x03, // bmAttributes (0x03=intr) |
637 | SEREMU_RX_SIZE, 0, // wMaxPacketSize |
638 | SEREMU_RX_INTERVAL, // bInterval |
639 | #endif // SEREMU_INTERFACE |
640 | |
641 | #ifdef JOYSTICK_INTERFACE |
642 | // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 |
643 | 9, // bLength |
644 | 4, // bDescriptorType |
645 | JOYSTICK_INTERFACE, // bInterfaceNumber |
646 | 0, // bAlternateSetting |
647 | 1, // bNumEndpoints |
648 | 0x03, // bInterfaceClass (0x03 = HID) |
649 | 0x00, // bInterfaceSubClass |
650 | 0x00, // bInterfaceProtocol |
651 | 0, // iInterface |
652 | // HID interface descriptor, HID 1.11 spec, section 6.2.1 |
653 | 9, // bLength |
654 | 0x21, // bDescriptorType |
655 | 0x11, 0x01, // bcdHID |
656 | 0, // bCountryCode |
657 | 1, // bNumDescriptors |
658 | 0x22, // bDescriptorType |
659 | LSB(sizeof(joystick_report_desc)), // wDescriptorLength |
660 | MSB(sizeof(joystick_report_desc)), |
661 | // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 |
662 | 7, // bLength |
663 | 5, // bDescriptorType |
664 | JOYSTICK_ENDPOINT | 0x80, // bEndpointAddress |
665 | 0x03, // bmAttributes (0x03=intr) |
666 | JOYSTICK_SIZE, 0, // wMaxPacketSize |
667 | JOYSTICK_INTERVAL, // bInterval |
668 | #endif // JOYSTICK_INTERFACE |
669 | |
670 | }; |
671 | |
672 | |
673 | // ************************************************************** |
674 | // String Descriptors |
675 | // ************************************************************** |
676 | |
677 | // The descriptors above can provide human readable strings, |
678 | // referenced by index numbers. These descriptors are the |
679 | // actual string data |
680 | |
681 | /* defined in usb_names.h |
682 | struct usb_string_descriptor_struct { |
683 | uint8_t bLength; |
684 | uint8_t bDescriptorType; |
685 | uint16_t wString[]; |
686 | }; |
687 | */ |
688 | |
689 | extern struct usb_string_descriptor_struct usb_string_manufacturer_name |
690 | __attribute__ ((weak, alias("usb_string_manufacturer_name_default"))); |
691 | extern struct usb_string_descriptor_struct usb_string_product_name |
692 | __attribute__ ((weak, alias("usb_string_product_name_default"))); |
693 | extern struct usb_string_descriptor_struct usb_string_serial_number |
694 | __attribute__ ((weak, alias("usb_string_serial_number_default"))); |
695 | |
696 | struct usb_string_descriptor_struct string0 = { |
697 | 4, |
698 | 3, |
699 | {0x0409} |
700 | }; |
701 | |
702 | struct usb_string_descriptor_struct usb_string_manufacturer_name_default = { |
703 | 2 + MANUFACTURER_NAME_LEN * 2, |
704 | 3, |
705 | MANUFACTURER_NAME |
706 | }; |
707 | struct usb_string_descriptor_struct usb_string_product_name_default = { |
708 | 2 + PRODUCT_NAME_LEN * 2, |
709 | 3, |
710 | PRODUCT_NAME |
711 | }; |
712 | struct usb_string_descriptor_struct usb_string_serial_number_default = { |
713 | 12, |
714 | 3, |
715 | {0,0,0,0,0,0,0,0,0,0} |
716 | }; |
717 | |
718 | void usb_init_serialnumber(void) |
719 | { |
720 | char buf[11]; |
721 | uint32_t i, num; |
722 | |
723 | __disable_irq(); |
724 | FTFL_FSTAT = FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL; |
725 | FTFL_FCCOB0 = 0x41; |
726 | FTFL_FCCOB1 = 15; |
727 | FTFL_FSTAT = FTFL_FSTAT_CCIF; |
728 | while (!(FTFL_FSTAT & FTFL_FSTAT_CCIF)) ; // wait |
729 | num = *(uint32_t *)&FTFL_FCCOB7; |
730 | __enable_irq(); |
731 | ultoa(num, buf, 10); |
732 | for (i=0; i<10; i++) { |
733 | char c = buf[i]; |
734 | if (!c) break; |
735 | usb_string_serial_number_default.wString[i] = c; |
736 | } |
737 | usb_string_serial_number_default.bLength = i * 2 + 2; |
738 | } |
739 | |
740 | |
741 | // ************************************************************** |
742 | // Descriptors List |
743 | // ************************************************************** |
744 | |
745 | // This table provides access to all the descriptor data above. |
746 | |
747 | const usb_descriptor_list_t usb_descriptor_list[] = { |
748 | //wValue, wIndex, address, length |
749 | {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)}, |
750 | {0x0200, 0x0000, config_descriptor, sizeof(config_descriptor)}, |
751 | #ifdef SEREMU_INTERFACE |
752 | {0x2200, SEREMU_INTERFACE, seremu_report_desc, sizeof(seremu_report_desc)}, |
753 | {0x2100, SEREMU_INTERFACE, config_descriptor+SEREMU_DESC_OFFSET, 9}, |
754 | #endif |
755 | #ifdef KEYBOARD_INTERFACE |
756 | {0x2200, KEYBOARD_INTERFACE, keyboard_report_desc, sizeof(keyboard_report_desc)}, |
757 | {0x2100, KEYBOARD_INTERFACE, config_descriptor+KEYBOARD_DESC_OFFSET, 9}, |
758 | #endif |
759 | #ifdef MOUSE_INTERFACE |
760 | {0x2200, MOUSE_INTERFACE, mouse_report_desc, sizeof(mouse_report_desc)}, |
761 | {0x2100, MOUSE_INTERFACE, config_descriptor+MOUSE_DESC_OFFSET, 9}, |
762 | #endif |
763 | #ifdef JOYSTICK_INTERFACE |
764 | {0x2200, JOYSTICK_INTERFACE, joystick_report_desc, sizeof(joystick_report_desc)}, |
765 | {0x2100, JOYSTICK_INTERFACE, config_descriptor+JOYSTICK_DESC_OFFSET, 9}, |
766 | #endif |
767 | #ifdef RAWHID_INTERFACE |
768 | {0x2200, RAWHID_INTERFACE, rawhid_report_desc, sizeof(rawhid_report_desc)}, |
769 | {0x2100, RAWHID_INTERFACE, config_descriptor+RAWHID_DESC_OFFSET, 9}, |
770 | #endif |
771 | #ifdef FLIGHTSIM_INTERFACE |
772 | {0x2200, FLIGHTSIM_INTERFACE, flightsim_report_desc, sizeof(flightsim_report_desc)}, |
773 | {0x2100, FLIGHTSIM_INTERFACE, config_descriptor+FLIGHTSIM_DESC_OFFSET, 9}, |
774 | #endif |
775 | {0x0300, 0x0000, (const uint8_t *)&string0, 0}, |
776 | {0x0301, 0x0409, (const uint8_t *)&usb_string_manufacturer_name, 0}, |
777 | {0x0302, 0x0409, (const uint8_t *)&usb_string_product_name, 0}, |
778 | {0x0303, 0x0409, (const uint8_t *)&usb_string_serial_number, 0}, |
779 | //{0x0301, 0x0409, (const uint8_t *)&string1, 0}, |
780 | //{0x0302, 0x0409, (const uint8_t *)&string2, 0}, |
781 | //{0x0303, 0x0409, (const uint8_t *)&string3, 0}, |
782 | {0, 0, NULL, 0} |
783 | }; |
784 | |
785 | |
786 | // ************************************************************** |
787 | // Endpoint Configuration |
788 | // ************************************************************** |
789 | |
790 | #if 0 |
791 | // 0x00 = not used |
792 | // 0x19 = Recieve only |
793 | // 0x15 = Transmit only |
794 | // 0x1D = Transmit & Recieve |
795 | // |
796 | const uint8_t usb_endpoint_config_table[NUM_ENDPOINTS] = |
797 | { |
798 | 0x00, 0x15, 0x19, 0x15, 0x00, 0x00, 0x00, 0x00, |
799 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
800 | }; |
801 | #endif |
802 | |
803 | |
804 | const uint8_t usb_endpoint_config_table[NUM_ENDPOINTS] = |
805 | { |
806 | #if (defined(ENDPOINT1_CONFIG) && NUM_ENDPOINTS >= 1) |
807 | ENDPOINT1_CONFIG, |
808 | #elif (NUM_ENDPOINTS >= 1) |
809 | ENDPOINT_UNUSED, |
810 | #endif |
811 | #if (defined(ENDPOINT2_CONFIG) && NUM_ENDPOINTS >= 2) |
812 | ENDPOINT2_CONFIG, |
813 | #elif (NUM_ENDPOINTS >= 2) |
814 | ENDPOINT_UNUSED, |
815 | #endif |
816 | #if (defined(ENDPOINT3_CONFIG) && NUM_ENDPOINTS >= 3) |
817 | ENDPOINT3_CONFIG, |
818 | #elif (NUM_ENDPOINTS >= 3) |
819 | ENDPOINT_UNUSED, |
820 | #endif |
821 | #if (defined(ENDPOINT4_CONFIG) && NUM_ENDPOINTS >= 4) |
822 | ENDPOINT4_CONFIG, |
823 | #elif (NUM_ENDPOINTS >= 4) |
824 | ENDPOINT_UNUSED, |
825 | #endif |
826 | #if (defined(ENDPOINT5_CONFIG) && NUM_ENDPOINTS >= 5) |
827 | ENDPOINT5_CONFIG, |
828 | #elif (NUM_ENDPOINTS >= 5) |
829 | ENDPOINT_UNUSED, |
830 | #endif |
831 | #if (defined(ENDPOINT6_CONFIG) && NUM_ENDPOINTS >= 6) |
832 | ENDPOINT6_CONFIG, |
833 | #elif (NUM_ENDPOINTS >= 6) |
834 | ENDPOINT_UNUSED, |
835 | #endif |
836 | #if (defined(ENDPOINT7_CONFIG) && NUM_ENDPOINTS >= 7) |
837 | ENDPOINT7_CONFIG, |
838 | #elif (NUM_ENDPOINTS >= 7) |
839 | ENDPOINT_UNUSED, |
840 | #endif |
841 | #if (defined(ENDPOINT8_CONFIG) && NUM_ENDPOINTS >= 8) |
842 | ENDPOINT8_CONFIG, |
843 | #elif (NUM_ENDPOINTS >= 8) |
844 | ENDPOINT_UNUSED, |
845 | #endif |
846 | #if (defined(ENDPOINT9_CONFIG) && NUM_ENDPOINTS >= 9) |
847 | ENDPOINT9_CONFIG, |
848 | #elif (NUM_ENDPOINTS >= 9) |
849 | ENDPOINT_UNUSED, |
850 | #endif |
851 | #if (defined(ENDPOINT10_CONFIG) && NUM_ENDPOINTS >= 10) |
852 | ENDPOINT10_CONFIG, |
853 | #elif (NUM_ENDPOINTS >= 10) |
854 | ENDPOINT_UNUSED, |
855 | #endif |
856 | #if (defined(ENDPOINT11_CONFIG) && NUM_ENDPOINTS >= 11) |
857 | ENDPOINT11_CONFIG, |
858 | #elif (NUM_ENDPOINTS >= 11) |
859 | ENDPOINT_UNUSED, |
860 | #endif |
861 | #if (defined(ENDPOINT12_CONFIG) && NUM_ENDPOINTS >= 12) |
862 | ENDPOINT12_CONFIG, |
863 | #elif (NUM_ENDPOINTS >= 12) |
864 | ENDPOINT_UNUSED, |
865 | #endif |
866 | #if (defined(ENDPOINT13_CONFIG) && NUM_ENDPOINTS >= 13) |
867 | ENDPOINT13_CONFIG, |
868 | #elif (NUM_ENDPOINTS >= 13) |
869 | ENDPOINT_UNUSED, |
870 | #endif |
871 | #if (defined(ENDPOINT14_CONFIG) && NUM_ENDPOINTS >= 14) |
872 | ENDPOINT14_CONFIG, |
873 | #elif (NUM_ENDPOINTS >= 14) |
874 | ENDPOINT_UNUSED, |
875 | #endif |
876 | #if (defined(ENDPOINT15_CONFIG) && NUM_ENDPOINTS >= 15) |
877 | ENDPOINT15_CONFIG, |
878 | #elif (NUM_ENDPOINTS >= 15) |
879 | ENDPOINT_UNUSED, |
880 | #endif |
881 | }; |
882 | |
883 | |
884 | |
885 | |