xref: /nrf52832-nimble/rt-thread/components/drivers/usb/usbdevice/core/usbdevice.c (revision 104654410c56c573564690304ae786df310c91fc)
1 /*
2  * File      : hid.c
3  * COPYRIGHT (C) 2008 - 2018, RT-Thread Development Team
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  *
7  * Change Logs:
8  * Date           Author       Notes
9  * 2012-10-02     Yi Qiu       first version
10  */
11 
12 #include <rtthread.h>
13 #include <rtdevice.h>
14 #include <rtservice.h>
15 
16 #ifdef RT_USING_USB_DEVICE
17 
18 #define USB_DEVICE_CONTROLLER_NAME      "usbd"
19 
20 #ifdef RT_USB_DEVICE_COMPOSITE
21 const static char* ustring[] =
22 {
23     "Language",
24     "RT-Thread Team.",
25     "RTT Composite Device",
26     "320219198301",
27     "Configuration",
28     "Interface",
29     USB_STRING_OS
30 };
31 
32 static struct udevice_descriptor compsit_desc =
33 {
34     USB_DESC_LENGTH_DEVICE,     //bLength;
35     USB_DESC_TYPE_DEVICE,       //type;
36     USB_BCD_VERSION,            //bcdUSB;
37     USB_CLASS_MISC,             //bDeviceClass;
38     0x02,                       //bDeviceSubClass;
39     0x01,                       //bDeviceProtocol;
40     0x40,                       //bMaxPacketSize0;
41     _VENDOR_ID,                 //idVendor;
42     _PRODUCT_ID,                //idProduct;
43     USB_BCD_DEVICE,             //bcdDevice;
44     USB_STRING_MANU_INDEX,      //iManufacturer;
45     USB_STRING_PRODUCT_INDEX,   //iProduct;
46     USB_STRING_SERIAL_INDEX,    //iSerialNumber;
47     USB_DYNAMIC,                //bNumConfigurations;
48 };
49 
50 //FS and HS needed
51 static struct usb_qualifier_descriptor dev_qualifier =
52 {
53     sizeof(dev_qualifier),          //bLength
54     USB_DESC_TYPE_DEVICEQUALIFIER,  //bDescriptorType
55     0x0200,                         //bcdUSB
56     USB_CLASS_MISC,                 //bDeviceClass
57     0x02,                           //bDeviceSubClass
58     0x01,                           //bDeviceProtocol
59     64,                             //bMaxPacketSize0
60     0x01,                           //bNumConfigurations
61     0,
62 };
63 #endif
64 
65 struct usb_os_comp_id_descriptor usb_comp_id_desc =
66 {
67     //head section
68     {
69         USB_DYNAMIC,
70         0x0100,
71         0x04,
72         USB_DYNAMIC,
73         {0x00,0x00,0x00,0x00,0x00,0x00,0x00},
74     },
75 };
76 static rt_list_t class_list;
rt_usbd_class_list_init(void)77 int rt_usbd_class_list_init(void)
78 {
79     rt_list_init(&class_list);
80     return 0;
81 }
82 INIT_BOARD_EXPORT(rt_usbd_class_list_init);
83 
rt_usbd_class_register(udclass_t udclass)84 rt_err_t rt_usbd_class_register(udclass_t udclass)
85 {
86 #ifndef RT_USB_DEVICE_COMPOSITE
87     if(!rt_list_isempty(&class_list))
88     {
89         rt_kprintf("[D/USBD] If you want to use usb composite device please define RT_USB_DEVICE_COMPOSITE\n");
90         return RT_ERROR;
91     }
92 #endif
93     rt_list_insert_before(&class_list,&udclass->list);
94     return RT_EOK;
95 }
96 
rt_usb_device_init(void)97 rt_err_t rt_usb_device_init(void)
98 {
99     rt_device_t udc;
100     udevice_t udevice;
101     uconfig_t cfg;
102     ufunction_t func;
103     rt_list_t *i;
104     udclass_t udclass;
105 
106     if(rt_list_isempty(&class_list))
107     {
108         rt_kprintf("[D/USBD] No class register on usb device\n");
109         return RT_ERROR;
110     }
111     /* create and startup usb device thread */
112     rt_usbd_core_init();
113 
114     /* create a device object */
115     udevice = rt_usbd_device_new();
116 
117     udc = rt_device_find(USB_DEVICE_CONTROLLER_NAME);
118     if(udc == RT_NULL)
119     {
120         rt_kprintf("can't find usb device controller %s\n", USB_DEVICE_CONTROLLER_NAME);
121         return -RT_ERROR;
122     }
123 
124     /* set usb controller driver to the device */
125     rt_usbd_device_set_controller(udevice, (udcd_t)udc);
126 
127     /* create a configuration object */
128     cfg = rt_usbd_config_new();
129 
130     rt_usbd_device_set_os_comp_id_desc(udevice, &usb_comp_id_desc);
131 
132     for(i = class_list.next; i!= &class_list; i = i->next)
133     {
134         /* get a class creater */
135         udclass = rt_list_entry(i, struct udclass, list);
136         /* create a function object */
137         func = udclass->rt_usbd_function_create(udevice);
138         /* add the function to the configuration */
139         rt_usbd_config_add_function(cfg, func);
140     }
141     /* set device descriptor to the device */
142 #ifdef RT_USB_DEVICE_COMPOSITE
143     rt_usbd_device_set_descriptor(udevice, &compsit_desc);
144     rt_usbd_device_set_string(udevice, ustring);
145     if(udevice->dcd->device_is_hs)
146     {
147         rt_usbd_device_set_qualifier(udevice, &dev_qualifier);
148     }
149 #else
150     rt_usbd_device_set_descriptor(udevice, func->dev_desc);
151 #endif
152 
153     /* add the configuration to the device */
154     rt_usbd_device_add_config(udevice, cfg);
155 
156     /* initialize usb device controller */
157     rt_device_init(udc);
158 
159     /* set default configuration to 1 */
160     rt_usbd_set_config(udevice, 1);
161 
162     return RT_EOK;
163 }
164 #endif
165