1 /*
2 * Copyright (c) 2024, sakumisu
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include "usbd_core.h"
7 #include "usbd_adb.h"
8
9 /*!< endpoint address */
10 #define WINUSB_IN_EP 0x81
11 #define WINUSB_OUT_EP 0x02
12
13 #define USBD_VID 0xFFFF
14 #define USBD_PID 0xFFFF
15 #define USBD_MAX_POWER 100
16 #define USBD_LANGID_STRING 1033
17
18 /*!< config descriptor size */
19 #define USB_CONFIG_SIZE (9 + 9 + 7 + 7)
20
21 #ifdef CONFIG_USB_HS
22 #define WINUSB_MAX_MPS 512
23 #else
24 #define WINUSB_MAX_MPS 64
25 #endif
26
27 #define WCID_VENDOR_CODE 0x17
28 #define ADB_INTF_NUM 0
29
30 __ALIGN_BEGIN const uint8_t WCID_StringDescriptor_MSOS[18] __ALIGN_END = {
31 ///////////////////////////////////////
32 /// MS OS string descriptor
33 ///////////////////////////////////////
34 0x12, /* bLength */
35 USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
36 /* MSFT100 */
37 'M', 0x00, 'S', 0x00, 'F', 0x00, 'T', 0x00, /* wcChar_7 */
38 '1', 0x00, '0', 0x00, '0', 0x00, /* wcChar_7 */
39 WCID_VENDOR_CODE, /* bVendorCode */
40 0x00, /* bReserved */
41 };
42
43 __ALIGN_BEGIN const uint8_t WINUSB_WCIDDescriptor[40] __ALIGN_END = {
44 ///////////////////////////////////////
45 /// WCID descriptor
46 ///////////////////////////////////////
47 0x28, 0x00, 0x00, 0x00, /* dwLength */
48 0x00, 0x01, /* bcdVersion */
49 0x04, 0x00, /* wIndex */
50 0x01, /* bCount */
51 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_7 */
52
53 ///////////////////////////////////////
54 /// WCID function descriptor
55 ///////////////////////////////////////
56 ADB_INTF_NUM, /* bFirstInterfaceNumber */
57 0x01, /* bReserved */
58 /* Compatible ID */
59 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, /* cCID_8: WINUSB */
60 /* */
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* cSubCID_8 */
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_6 */
63 };
64
65 __ALIGN_BEGIN const uint8_t WINUSB_IF0_WCIDProperties[142] __ALIGN_END = {
66 ///////////////////////////////////////
67 /// WCID property descriptor
68 ///////////////////////////////////////
69 0x8e, 0x00, 0x00, 0x00, /* dwLength */
70 0x00, 0x01, /* bcdVersion */
71 0x05, 0x00, /* wIndex */
72 0x01, 0x00, /* wCount */
73
74 ///////////////////////////////////////
75 /// registry propter descriptor
76 ///////////////////////////////////////
77 0x84, 0x00, 0x00, 0x00, /* dwSize */
78 0x01, 0x00, 0x00, 0x00, /* dwPropertyDataType */
79 0x28, 0x00, /* wPropertyNameLength */
80 /* DeviceInterfaceGUID */
81 'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, /* wcName_20 */
82 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, /* wcName_20 */
83 't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, /* wcName_20 */
84 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, /* wcName_20 */
85 'U', 0x00, 'I', 0x00, 'D', 0x00, 0x00, 0x00, /* wcName_20 */
86 0x4e, 0x00, 0x00, 0x00, /* dwPropertyDataLength */
87 /* {1D4B2365-4749-48EA-B38A-7C6FDDDD7E26} */
88 '{', 0x00, '1', 0x00, 'D', 0x00, '4', 0x00, /* wcData_39 */
89 'B', 0x00, '2', 0x00, '3', 0x00, '6', 0x00, /* wcData_39 */
90 '5', 0x00, '-', 0x00, '4', 0x00, '7', 0x00, /* wcData_39 */
91 '4', 0x00, '9', 0x00, '-', 0x00, '4', 0x00, /* wcData_39 */
92 '8', 0x00, 'E', 0x00, 'A', 0x00, '-', 0x00, /* wcData_39 */
93 'B', 0x00, '3', 0x00, '8', 0x00, 'A', 0x00, /* wcData_39 */
94 '-', 0x00, '7', 0x00, 'C', 0x00, '6', 0x00, /* wcData_39 */
95 'F', 0x00, 'D', 0x00, 'D', 0x00, 'D', 0x00, /* wcData_39 */
96 'D', 0x00, '7', 0x00, 'E', 0x00, '2', 0x00, /* wcData_39 */
97 '6', 0x00, '}', 0x00, 0x00, 0x00, /* wcData_39 */
98 };
99
100 const uint8_t *WINUSB_IFx_WCIDProperties[] = {
101 WINUSB_IF0_WCIDProperties,
102 };
103
104 struct usb_msosv1_descriptor msosv1_desc = {
105 .string = WCID_StringDescriptor_MSOS,
106 .vendor_code = WCID_VENDOR_CODE,
107 .compat_id = WINUSB_WCIDDescriptor,
108 .comp_id_property = WINUSB_IFx_WCIDProperties,
109 };
110
111 #ifdef CONFIG_USBDEV_ADVANCE_DESC
112 static const uint8_t device_descriptor[] = {
113 USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0100, 0x01)
114 };
115
116 static const uint8_t config_descriptor[] = {
117 USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
118 ADB_DESCRIPTOR_INIT(ADB_INTF_NUM, WINUSB_IN_EP, WINUSB_OUT_EP, WINUSB_MAX_MPS)
119 };
120
121 static const uint8_t device_quality_descriptor[] = {
122 ///////////////////////////////////////
123 /// device qualifier descriptor
124 ///////////////////////////////////////
125 0x0a,
126 USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
127 0x00,
128 0x02,
129 0x00,
130 0x00,
131 0x00,
132 0x40,
133 0x00,
134 0x00,
135 };
136
137 static const char *string_descriptors[] = {
138 (const char[]){ 0x09, 0x04 }, /* Langid */
139 "CherryUSB", /* Manufacturer */
140 "CherryADB", /* Product */
141 "CherryADB2024", /* Serial Number */
142 };
143
device_descriptor_callback(uint8_t speed)144 static const uint8_t *device_descriptor_callback(uint8_t speed)
145 {
146 return device_descriptor;
147 }
148
config_descriptor_callback(uint8_t speed)149 static const uint8_t *config_descriptor_callback(uint8_t speed)
150 {
151 return config_descriptor;
152 }
153
device_quality_descriptor_callback(uint8_t speed)154 static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
155 {
156 return device_quality_descriptor;
157 }
158
string_descriptor_callback(uint8_t speed,uint8_t index)159 static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
160 {
161 if (index > 3) {
162 return NULL;
163 }
164 return string_descriptors[index];
165 }
166
167 const struct usb_descriptor adb_descriptor = {
168 .device_descriptor_callback = device_descriptor_callback,
169 .config_descriptor_callback = config_descriptor_callback,
170 .device_quality_descriptor_callback = device_quality_descriptor_callback,
171 .string_descriptor_callback = string_descriptor_callback,
172 .msosv1_descriptor = &msosv1_desc
173 };
174 #else
175 /*!< global descriptor */
176 static const uint8_t adb_descriptor[] = {
177 USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0100, 0x01),
178 USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
179 ADB_DESCRIPTOR_INIT(ADB_INTF_NUM, WINUSB_IN_EP, WINUSB_OUT_EP, WINUSB_MAX_MPS),
180 ///////////////////////////////////////
181 /// string0 descriptor
182 ///////////////////////////////////////
183 USB_LANGID_INIT(USBD_LANGID_STRING),
184 ///////////////////////////////////////
185 /// string1 descriptor
186 ///////////////////////////////////////
187 0x14, /* bLength */
188 USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
189 'C', 0x00, /* wcChar0 */
190 'h', 0x00, /* wcChar1 */
191 'e', 0x00, /* wcChar2 */
192 'r', 0x00, /* wcChar3 */
193 'r', 0x00, /* wcChar4 */
194 'y', 0x00, /* wcChar5 */
195 'U', 0x00, /* wcChar6 */
196 'S', 0x00, /* wcChar7 */
197 'B', 0x00, /* wcChar8 */
198 ///////////////////////////////////////
199 /// string2 descriptor
200 ///////////////////////////////////////
201 0x14, /* bLength */
202 USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
203 'C', 0x00, /* wcChar0 */
204 'h', 0x00, /* wcChar1 */
205 'e', 0x00, /* wcChar2 */
206 'r', 0x00, /* wcChar3 */
207 'r', 0x00, /* wcChar4 */
208 'y', 0x00, /* wcChar5 */
209 'A', 0x00, /* wcChar6 */
210 'D', 0x00, /* wcChar7 */
211 'B', 0x00, /* wcChar8 */
212 ///////////////////////////////////////
213 /// string3 descriptor
214 ///////////////////////////////////////
215 0x1C, /* bLength */
216 USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
217 'C', 0x00, /* wcChar0 */
218 'h', 0x00, /* wcChar1 */
219 'e', 0x00, /* wcChar2 */
220 'r', 0x00, /* wcChar3 */
221 'r', 0x00, /* wcChar4 */
222 'y', 0x00, /* wcChar5 */
223 'A', 0x00, /* wcChar6 */
224 'D', 0x00, /* wcChar7 */
225 'B', 0x00, /* wcChar8 */
226 '2', 0x00, /* wcChar9 */
227 '0', 0x00, /* wcChar10 */
228 '2', 0x00, /* wcChar11 */
229 '4', 0x00, /* wcChar12 */
230 #ifdef CONFIG_USB_HS
231 ///////////////////////////////////////
232 /// device qualifier descriptor
233 ///////////////////////////////////////
234 0x0a,
235 USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
236 0x00,
237 0x02,
238 0x00,
239 0x00,
240 0x00,
241 0x40,
242 0x00,
243 0x00,
244 #endif
245 0x00
246 };
247 #endif
248
usbd_event_handler(uint8_t busid,uint8_t event)249 static void usbd_event_handler(uint8_t busid, uint8_t event)
250 {
251 switch (event) {
252 case USBD_EVENT_RESET:
253 break;
254 case USBD_EVENT_CONNECTED:
255 break;
256 case USBD_EVENT_DISCONNECTED:
257 break;
258 case USBD_EVENT_RESUME:
259 break;
260 case USBD_EVENT_SUSPEND:
261 break;
262 case USBD_EVENT_CONFIGURED:
263
264 break;
265 case USBD_EVENT_SET_REMOTE_WAKEUP:
266 break;
267 case USBD_EVENT_CLR_REMOTE_WAKEUP:
268 break;
269
270 default:
271 break;
272 }
273 }
274
275 static struct usbd_interface intf0;
276
277 #ifdef RT_USING_MSH
278 extern void usbd_adb_shell_init(uint8_t in_ep, uint8_t out_ep);
279 #else
280 extern int shell_init(bool need_login);
281 #endif
cherryadb_init(uint8_t busid,uint32_t reg_base)282 void cherryadb_init(uint8_t busid, uint32_t reg_base)
283 {
284 #ifdef RT_USING_MSH
285 usbd_adb_shell_init(WINUSB_IN_EP, WINUSB_OUT_EP);
286 #else
287 /* default password is : 12345678 */
288 /* shell_init() must be called in-task */
289 if (0 != shell_init(false)) {
290 /* shell failed to be initialized */
291 printf("Failed to initialize shell\r\n");
292 for (;;) {
293 ;
294 }
295 }
296 #endif
297 #ifdef CONFIG_USBDEV_ADVANCE_DESC
298 usbd_desc_register(busid, &adb_descriptor);
299 #else
300 usbd_desc_register(busid, adb_descriptor);
301 #endif
302 #ifndef CONFIG_USBDEV_ADVANCE_DESC
303 usbd_msosv1_desc_register(busid, &msosv1_desc);
304 #endif
305 usbd_add_interface(busid, usbd_adb_init_intf(busid, &intf0, WINUSB_IN_EP, WINUSB_OUT_EP));
306 usbd_initialize(busid, reg_base, usbd_event_handler);
307 }
308