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