1 /* ----------------------------------------------------------------------------
2 * Copyright (c) Huawei Technologies Co., Ltd. 2016-2019. All rights reserved.
3 * Description: LiteOS USB Driver Virtual Serial Port Descriptor
4 * Author: huangjieliang
5 * Create: 2016-07-06
6 * Redistribution and use in source and binary forms, with or without modification,
7 * are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
14 * to endorse or promote products derived from this software without specific prior written
15 * permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 * --------------------------------------------------------------------------- */
28 /* ----------------------------------------------------------------------------
29 * Notice of Export Control Law
30 * ===============================================
31 * Huawei LiteOS may be subject to applicable export control laws and regulations, which might
32 * include those applicable to Huawei LiteOS of U.S. and the country in which you are located.
33 * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such
34 * applicable export control laws and regulations.
35 * --------------------------------------------------------------------------- */
36
37 #include "gadget/cdcacm.h"
38
39 #ifdef __cplusplus
40 #if __cplusplus
41 extern "C" {
42 #endif /* __cplusplus */
43 #endif /* __cplusplus */
44
45 static const struct usb_device_descriptor g_cdcacm_device_desc =
46 {
47 .bLength = sizeof(struct usb_device_descriptor),
48 .bDescriptorType = UDESC_DEVICE,
49 HSETW(.bcdUSB, UD_BCD_USB), /* usb version */
50 .bDeviceClass = UDCLASS_COMM, /* 0x02 */
51 .bDeviceSubClass = 0,
52 .bDeviceProtocol = 0,
53 .bMaxPacketSize = UD_USB_MPS,
54 HSETW(.idVendor, DEVICE_VENDOR_ID), /* vendor 0x0525 */
55 HSETW(.idProduct, DEVICE_PRODUCT_ID), /* product 0xa4a7 */
56 HSETW(.bcdDevice, DEVICE_VERSION), /* device version */
57 .iManufacturer = 1,
58 .iProduct = 2,
59 .iSerialNumber = 0,
60 .bNumConfigurations = 1,
61 };
62
63 struct cdcacm_hs_function_descriptor g_cdcacm_hs_func_desc =
64 {
65 {
66 .bLength = sizeof(struct usb_interface_assoc_descriptor),
67 .bDescriptorType = UDESC_IFACE_ASSOC,
68 .bInterfaceCount = 2,
69 .bFunctionClass = 2, /* UFCLASS_CDC */
70 .bFunctionSubClass = 2,
71 .bFunctionProtocol = 1,
72
73 /* Dynamic configuration when composite driver. 0x0c */
74
75 .iFunction = 7,
76 },
77 {
78 .bLength = sizeof(struct usb_interface_descriptor),
79 .bDescriptorType = UDESC_INTERFACE,
80 .bAlternateSetting = 0,
81 .bNumEndpoints = 0x1,
82 .bInterfaceClass = UICLASS_CDC,
83 .bInterfaceSubClass = UISUBCLASS_ABSTRACT_CONTROL_MODEL,
84 .bInterfaceProtocol = UIPROTO_CDC_AT,
85
86 /* Dynamic configuration when composite driver. 0x0a */
87
88 .iInterface = 5
89 },
90 {
91 .bLength = sizeof(struct usb_cdc_header_descriptor),
92 .bDescriptorType = UDESC_CS_INTERFACE,
93 .bDescriptorSubtype = UDESCSUB_CDC_HEADER,
94 HSETW(.bcdCDC, 0x0110)
95 },
96 {
97 .bLength = sizeof(struct usb_cdc_cm_descriptor),
98 .bDescriptorType = UDESC_CS_INTERFACE,
99 .bDescriptorSubtype = UDESCSUB_CDC_CM, /* call Management */
100 .bmCapabilities = 0x0,
101 },
102 {
103 .bLength = sizeof(struct usb_cdc_acm_descriptor),
104 .bDescriptorType = UDESC_CS_INTERFACE,
105 .bDescriptorSubType = UDESCSUB_CDC_ACM, /* Abstract Control Model */
106 .bmCapabilities = USB_CDC_ACM_HAS_LINE
107 },
108 {
109 .bLength = sizeof(struct usb_cdc_union_desc),
110 .bDescriptorType = UDESC_CS_INTERFACE,
111 .bDescriptorSubType = UDESCSUB_CDC_UNION,
112 },
113 {
114 .bLength = sizeof(struct usb_endpoint_descriptor),
115 .bDescriptorType = UDESC_ENDPOINT,
116 .bEndpointAddress = UE_DIR_IN,
117 .bmAttributes = UE_INTERRUPT,
118 HSETW(.wMaxPacketSize, 0x000a),
119 .bInterval = 9
120 },
121 #ifdef DWC3_USB_SERIAL
122 {
123 .bLength = 6,
124 .bDescriptorType = 0x30,
125 .bMaxBurst = 0,
126 .bmAttributes = 0,
127 .wBytesPerInterval = {0}
128 },
129 #endif
130 {
131 .bLength = sizeof(struct usb_interface_descriptor),
132 .bDescriptorType = UDESC_INTERFACE,
133 .bAlternateSetting = 0,
134 .bNumEndpoints = 0x2,
135 .bInterfaceClass = UICLASS_CDC_DATA,
136 .bInterfaceSubClass = UISUBCLASS_DATA,
137 .bInterfaceProtocol = 0x0,
138
139 /* Dynamic configuration when composite driver. 0x0b */
140
141 .iInterface = 6
142 },
143 {
144 .bLength = sizeof(struct usb_endpoint_descriptor),
145 .bDescriptorType = UDESC_ENDPOINT,
146 .bEndpointAddress = UE_DIR_IN,
147 .bmAttributes = UE_BULK,
148 HSETW(.wMaxPacketSize, MAX_PACKET_SIZE),
149 .bInterval = 0
150 },
151 #ifdef DWC3_USB_SERIAL
152 {
153 .bLength = 6,
154 .bDescriptorType = 0x30,
155 .bMaxBurst = 0,
156 .bmAttributes = 0,
157 .wBytesPerInterval = {0}
158 },
159 #endif
160 {
161 .bLength = sizeof(struct usb_endpoint_descriptor),
162 .bDescriptorType = UDESC_ENDPOINT,
163 .bEndpointAddress = UE_DIR_OUT,
164 .bmAttributes = UE_BULK,
165 HSETW(.wMaxPacketSize, MAX_PACKET_SIZE),
166 .bInterval = 0
167 },
168 #ifdef DWC3_USB_SERIAL
169 {
170 .bLength = 6,
171 .bDescriptorType = 0x30,
172 .bMaxBurst = 0,
173 .bmAttributes = 0,
174 .wBytesPerInterval = {0}
175 },
176 #endif
177 };
178
179 /* config contain func */
180
181 static const struct usb_config_descriptor g_cdcacm_hs_config_desc =
182 {
183 .bLength = USB_CONFIG_DESC_SIZE,
184 .bDescriptorType = UDESC_CONFIG,
185 HSETW(.wTotalLength, USB_CONFIG_DESC_SIZE + sizeof(g_cdcacm_hs_func_desc)),
186 .bNumInterface = 2,
187 .bConfigurationValue = 2,
188 .iConfiguration = 4,
189 .bmAttributes = UC_SELF_POWERED | UC_BUS_POWERED, /* 0xc0 */
190 .bMaxPower = 1 /* max power */
191 };
192
193 #define DT_STRING_ID_LEN 4
194 static const char g_dt_string_id[DT_STRING_ID_LEN] =
195 {
196 DT_STRING_ID_LEN,
197 UDESC_STRING,
198 0x09, 0x04
199 };
200
201 #ifdef DWC3_USB_SERIAL
202 #define DT_STRING_VID_LEN 94
203 #else
204 #define DT_STRING_VID_LEN 16
205 #endif
206 static const char g_dt_string_vid[DT_STRING_VID_LEN] =
207 {
208 DT_STRING_VID_LEN,
209 UDESC_STRING,
210 #ifndef DWC3_USB_SERIAL
211 'D',0,'W',0,'C',0,'-',0,'O',0,'T',0,'G',0
212 #else
213 0x4c, 0, 0x69, 0, 0x6e, 0, 0x75, 0, 0x78, 0, 0x20, 0, 0x33, 0, 0x2e, 0, 0x31, 0, 0x38, 0,
214 0x2e, 0, 0x31, 0, 0x33, 0, 0x2d, 0, 0x67, 0, 0x64, 0, 0x37, 0, 0x32, 0, 0x32, 0, 0x36, 0,
215 0x65, 0, 0x37, 0, 0x2d, 0, 0x64, 0, 0x69, 0, 0x72, 0, 0x74, 0, 0x79, 0, 0x20, 0, 0x77, 0,
216 0x69, 0, 0x74, 0, 0x68, 0, 0x20, 0, 0x64, 0, 0x77, 0, 0x63, 0, 0x5f, 0, 0x75, 0, 0x73, 0,
217 0x62, 0, 0x33, 0, 0x5f, 0, 0x70, 0, 0x63, 0, 0x64, 0
218 #endif
219 };
220
221 #define DT_STRING_PID_LEN 38
222 static const char g_dt_string_pid[DT_STRING_PID_LEN] =
223 {
224 DT_STRING_PID_LEN,
225 UDESC_STRING,
226 'G',0,'a',0,'d',0,'g',0,'e',0,'t',0,' ',0,
227 'S',0,'e',0,'r',0,'i',0,'a',0,'l',0,' ',0,
228 'v',0,'2',0,'.',0,'4',0
229 };
230
231 #define DT_STRING_SERIAL_LEN 18
232 static const char g_dt_string_serial[DT_STRING_SERIAL_LEN] =
233 {
234 DT_STRING_SERIAL_LEN,
235 UDESC_STRING,
236 '2',0,'0',0,'1',0,'5',0,'0',0,'7',0,'3',0,'0',0
237 };
238
239 #define DT_STRING_4_LEN 30
240 static const char g_dt_string_4[DT_STRING_4_LEN] =
241 {
242 DT_STRING_4_LEN,
243 UDESC_STRING,
244 0x43, 0, 0x44, 0, 0x43, 0, 0x20, 0, 0x41, 0, 0x43, 0, 0x4d, 0,
245 0x20, 0, 0x63, 0, 0x6f, 0, 0x6e, 0, 0x66, 0, 0x69, 0, 0x67, 0
246 };
247
248 #define DT_STRING_5_LEN 66
249 static const char g_dt_string_5[DT_STRING_5_LEN] =
250 {
251 DT_STRING_5_LEN,
252 UDESC_STRING,
253 0x43, 0, 0x44, 0, 0x43, 0, 0x20, 0, 0x41, 0, 0x62, 0, 0x73, 0, 0x74, 0, 0x72, 0, 0x61, 0,
254 0x63, 0, 0x74, 0, 0x20, 0, 0x43, 0, 0x6f, 0, 0x6e, 0, 0x74, 0, 0x72, 0, 0x6f, 0, 0x6c, 0,
255 0x20, 0, 0x4d, 0, 0x6f, 0, 0x64, 0, 0x65, 0, 0x6c, 0, 0x20, 0, 0x28, 0, 0x41, 0, 0x43, 0,
256 0x4d, 0, 0x29, 0
257 };
258
259 #define DT_STRING_6_LEN 26
260 static const char g_dt_string_6[DT_STRING_6_LEN] =
261 {
262 DT_STRING_6_LEN,
263 UDESC_STRING,
264 0x43, 0, 0x44, 0, 0x43, 0, 0x20, 0, 0x41, 0,
265 0x43, 0, 0x4d, 0, 0x20, 0, 0x44, 0, 0x61, 0, 0x74, 0, 0x61, 0
266 };
267
268 #define DT_STRING_7_LEN 22
269 static const char g_dt_string_7[DT_STRING_7_LEN] =
270 {
271 DT_STRING_7_LEN,
272 UDESC_STRING,
273 0x43, 0, 0x44, 0, 0x43, 0, 0x20, 0, 0x53, 0, 0x65, 0,
274 0x72, 0, 0x69, 0, 0x61, 0, 0x6c, 0
275 };
276
277 #define FSERIAL_DSTR_IDX 9
278 static struct usbd_string g_cdcacm_device_strings[FSERIAL_DSTR_IDX] =
279 {
280 { 0, g_dt_string_id },
281 { 1, g_dt_string_vid },
282 { 2, g_dt_string_pid },
283 { 3, g_dt_string_serial },
284 { 4, g_dt_string_4 },
285 { 5, g_dt_string_5 },
286 { 6, g_dt_string_6 },
287 { 7, g_dt_string_7 },
288 USBD_DEVICE_STRINGS_END
289 };
290
291 /* ***************************************************************************
292 * Name: cdcacm_mkdevdesc
293 *
294 * Description:
295 * Construct the device descriptor
296 *
297 * ***************************************************************************
298 */
299
cdcacm_mkdevdesc(uint8_t * buf)300 void cdcacm_mkdevdesc(uint8_t *buf)
301 {
302 errno_t ret;
303
304 ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, &g_cdcacm_device_desc, sizeof(g_cdcacm_device_desc));
305 if (ret != EOK)
306 {
307 usb_err("memcpy_s fail!, ret:%d\n", ret);
308 return;
309 }
310 }
311
312 /* ***************************************************************************
313 * Name: cdcacm_mkcfgdesc
314 *
315 * Description:
316 * Construct the configuration descriptor
317 *
318 * ***************************************************************************
319 */
320
cdcacm_mkcfgdesc(uint8_t * buf,struct usbdev_devinfo_s * devinfo)321 int16_t cdcacm_mkcfgdesc(uint8_t *buf, struct usbdev_devinfo_s *devinfo)
322 {
323 int16_t total_len = 0;
324 int16_t len = USB_CONFIG_DESC_SIZE;
325 errno_t ret;
326
327 g_cdcacm_hs_func_desc.ifcad.bFirstInterface = (uint8_t)devinfo->ifnobase;
328 g_cdcacm_hs_func_desc.ifcd.bInterfaceNumber = (uint8_t)devinfo->ifnobase;
329 g_cdcacm_hs_func_desc.cdc_union_desc.bMasterInterface0 = (uint8_t)devinfo->ifnobase;
330 g_cdcacm_hs_func_desc.ifdd.bInterfaceNumber = (uint8_t)devinfo->ifnobase + 1;
331 g_cdcacm_hs_func_desc.cdc_union_desc.bSlaveInterface0 = (uint8_t)devinfo->ifnobase + 1;
332 g_cdcacm_hs_func_desc.cdc_call_desc.bDataInterface = (uint8_t)devinfo->ifnobase + 1;
333
334 /* Copy Serial device configure descriptor. */
335
336 ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, (const void *)&g_cdcacm_hs_config_desc, (uint32_t)len);
337 if (ret != EOK)
338 {
339 usb_err("memcpy_s fail, ret:%d\n", ret);
340 return -1;
341 }
342 total_len += len;
343
344 /* Copy Serial device function descriptor. */
345
346 buf += USB_CONFIG_DESC_SIZE;
347 len = sizeof(g_cdcacm_hs_func_desc);
348 ret = memcpy_s(buf, (USB_COMP_EP0_BUFSIZ - total_len), (const void *)&g_cdcacm_hs_func_desc, (uint32_t)len);
349 if (ret != EOK)
350 {
351 usb_err("memcpy_s fail, ret:%d\n", ret);
352 return -1;
353 }
354 total_len += len;
355
356 return total_len;
357 }
358
359 /****************************************************************************
360 * Name: cdcacm_mkstrdesc
361 *
362 * Description:
363 * Construct a string descriptor
364 *
365 ****************************************************************************/
366
cdcacm_mkstrdesc(uint8_t id,uint8_t * buf)367 int cdcacm_mkstrdesc(uint8_t id, uint8_t *buf)
368 {
369 errno_t ret;
370 const char *str;
371 int i;
372
373 for (i = 0; g_cdcacm_device_strings[i].s != NULL; i++)
374 {
375 str = g_cdcacm_device_strings[i].s;
376 if (g_cdcacm_device_strings[i].id == id)
377 {
378 ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, (const void *)str, (uint32_t)str[0]);
379 if (ret != EOK)
380 {
381 usb_err("memcpy_s failed, ret = %d\n", ret);
382 return -1;
383 }
384 return str[0];
385 }
386 }
387
388 usb_err("Can not find the id = %u of string\n", id);
389 return -1;
390 }
391
392 #ifdef __cplusplus
393 #if __cplusplus
394 }
395 #endif /* __cplusplus */
396 #endif /* __cplusplus */