aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios-contrib/demos/STM32/RT-STM32F407-DISCOVERY-TinyUSB-CDC-MSC/usb_descriptors.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chibios-contrib/demos/STM32/RT-STM32F407-DISCOVERY-TinyUSB-CDC-MSC/usb_descriptors.c')
-rw-r--r--lib/chibios-contrib/demos/STM32/RT-STM32F407-DISCOVERY-TinyUSB-CDC-MSC/usb_descriptors.c211
1 files changed, 211 insertions, 0 deletions
diff --git a/lib/chibios-contrib/demos/STM32/RT-STM32F407-DISCOVERY-TinyUSB-CDC-MSC/usb_descriptors.c b/lib/chibios-contrib/demos/STM32/RT-STM32F407-DISCOVERY-TinyUSB-CDC-MSC/usb_descriptors.c
new file mode 100644
index 000000000..75b5ce7bb
--- /dev/null
+++ b/lib/chibios-contrib/demos/STM32/RT-STM32F407-DISCOVERY-TinyUSB-CDC-MSC/usb_descriptors.c
@@ -0,0 +1,211 @@
1/*
2 * The MIT License (MIT)
3 *
4 * Copyright (c) 2019 Ha Thach (tinyusb.org)
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 *
24 */
25
26#include "tusb.h"
27
28/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug.
29 * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC.
30 *
31 * Auto ProductID layout's Bitmap:
32 * [MSB] HID | MSC | CDC [LSB]
33 */
34#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) )
35#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \
36 _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) )
37
38//--------------------------------------------------------------------+
39// Device Descriptors
40//--------------------------------------------------------------------+
41tusb_desc_device_t const desc_device =
42{
43 .bLength = sizeof(tusb_desc_device_t),
44 .bDescriptorType = TUSB_DESC_DEVICE,
45 .bcdUSB = 0x0200,
46
47 // Use Interface Association Descriptor (IAD) for CDC
48 // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1)
49 .bDeviceClass = TUSB_CLASS_MISC,
50 .bDeviceSubClass = MISC_SUBCLASS_COMMON,
51 .bDeviceProtocol = MISC_PROTOCOL_IAD,
52
53 .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
54
55 .idVendor = 0xCafe,
56 .idProduct = USB_PID,
57 .bcdDevice = 0x0100,
58
59 .iManufacturer = 0x01,
60 .iProduct = 0x02,
61 .iSerialNumber = 0x03,
62
63 .bNumConfigurations = 0x01
64};
65
66// Invoked when received GET DEVICE DESCRIPTOR
67// Application return pointer to descriptor
68uint8_t const * tud_descriptor_device_cb(void)
69{
70 return (uint8_t const *) &desc_device;
71}
72
73//--------------------------------------------------------------------+
74// Configuration Descriptor
75//--------------------------------------------------------------------+
76
77enum
78{
79 ITF_NUM_CDC = 0,
80 ITF_NUM_CDC_DATA,
81 ITF_NUM_MSC,
82 ITF_NUM_TOTAL
83};
84
85#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_MSC_DESC_LEN)
86
87#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX
88 // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number
89 // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In, 5 Bulk etc ...
90 #define EPNUM_CDC_NOTIF 0x81
91 #define EPNUM_CDC_OUT 0x02
92 #define EPNUM_CDC_IN 0x82
93
94 #define EPNUM_MSC_OUT 0x05
95 #define EPNUM_MSC_IN 0x85
96
97#elif CFG_TUSB_MCU == OPT_MCU_SAMG
98 // SAMG doesn't support a same endpoint number with different direction IN and OUT
99 // e.g EP1 OUT & EP1 IN cannot exist together
100 #define EPNUM_CDC_NOTIF 0x81
101 #define EPNUM_CDC_OUT 0x02
102 #define EPNUM_CDC_IN 0x83
103
104 #define EPNUM_MSC_OUT 0x04
105 #define EPNUM_MSC_IN 0x85
106
107#else
108 #define EPNUM_CDC_NOTIF 0x81
109 #define EPNUM_CDC_OUT 0x02
110 #define EPNUM_CDC_IN 0x82
111
112 #define EPNUM_MSC_OUT 0x03
113 #define EPNUM_MSC_IN 0x83
114
115#endif
116
117uint8_t const desc_fs_configuration[] =
118{
119 // Config number, interface count, string index, total length, attribute, power in mA
120 TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
121
122 // Interface number, string index, EP notification address and size, EP data address (out, in) and size.
123 TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64),
124
125 // Interface number, string index, EP Out & EP In address, EP size
126 TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, 64),
127};
128
129#if TUD_OPT_HIGH_SPEED
130uint8_t const desc_hs_configuration[] =
131{
132 // Config number, interface count, string index, total length, attribute, power in mA
133 TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
134
135 // Interface number, string index, EP notification address and size, EP data address (out, in) and size.
136 TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512),
137
138 // Interface number, string index, EP Out & EP In address, EP size
139 TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, 512),
140};
141#endif
142
143// Invoked when received GET CONFIGURATION DESCRIPTOR
144// Application return pointer to descriptor
145// Descriptor contents must exist long enough for transfer to complete
146uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
147{
148 (void) index; // for multiple configurations
149
150#if TUD_OPT_HIGH_SPEED
151 // Although we are highspeed, host may be fullspeed.
152 return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration;
153#else
154 return desc_fs_configuration;
155#endif
156}
157
158//--------------------------------------------------------------------+
159// String Descriptors
160//--------------------------------------------------------------------+
161
162// array of pointer to string descriptors
163char const* string_desc_arr [] =
164{
165 (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
166 "TinyUSB", // 1: Manufacturer
167 "TinyUSB Device", // 2: Product
168 "123456", // 3: Serials, should use chip ID
169 "TinyUSB CDC", // 4: CDC Interface
170 "TinyUSB MSC", // 5: MSC Interface
171};
172
173static uint16_t _desc_str[32];
174
175// Invoked when received GET STRING DESCRIPTOR request
176// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
177uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
178{
179 (void) langid;
180
181 uint8_t chr_count;
182
183 if ( index == 0)
184 {
185 memcpy(&_desc_str[1], string_desc_arr[0], 2);
186 chr_count = 1;
187 }else
188 {
189 // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors.
190 // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors
191
192 if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL;
193
194 const char* str = string_desc_arr[index];
195
196 // Cap at max char
197 chr_count = strlen(str);
198 if ( chr_count > 31 ) chr_count = 31;
199
200 // Convert ASCII string into UTF-16
201 for(uint8_t i=0; i<chr_count; i++)
202 {
203 _desc_str[1+i] = str[i];
204 }
205 }
206
207 // first byte is length (including header), second byte is string type
208 _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2);
209
210 return _desc_str;
211}