• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */