1 /*
2 * Copyright (c) 2023 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include <zephyr/usb/usbd.h>
9 #include <zephyr/usb/usbh.h>
10
11 #include "usbh_ch9.h"
12 #include "usbh_device.h"
13
14 #include <zephyr/logging/log.h>
15 LOG_MODULE_REGISTER(usb_test, LOG_LEVEL_INF);
16
17 #define TEST_DEFAULT_INTERFACE 0
18 #define TEST_DEFAULT_ALTERNATE 1
19
20 USBD_CONFIGURATION_DEFINE(test_fs_config,
21 USB_SCD_SELF_POWERED | USB_SCD_REMOTE_WAKEUP,
22 200, NULL);
23
24 USBD_CONFIGURATION_DEFINE(test_hs_config,
25 USB_SCD_SELF_POWERED | USB_SCD_REMOTE_WAKEUP,
26 200, NULL);
27
28
29 USBD_DESC_LANG_DEFINE(test_lang);
30 USBD_DESC_STRING_DEFINE(test_mfg, "ZEPHYR", 1);
31 USBD_DESC_STRING_DEFINE(test_product, "Zephyr USB Test", 2);
32 USBD_DESC_STRING_DEFINE(test_sn, "0123456789ABCDEF", 3);
33
34 USBD_DEVICE_DEFINE(test_usbd,
35 DEVICE_DT_GET(DT_NODELABEL(zephyr_udc0)),
36 0x2fe3, 0xffff);
37
38 USBH_CONTROLLER_DEFINE(uhs_ctx, DEVICE_DT_GET(DT_NODELABEL(zephyr_uhc0)));
39
test_cmp_string_desc(struct net_buf * const buf,const int idx)40 static int test_cmp_string_desc(struct net_buf *const buf, const int idx)
41 {
42 static struct usbd_desc_node *desc_nd;
43 size_t len;
44
45 if (idx == test_mfg.str.idx) {
46 desc_nd = &test_mfg;
47 } else if (idx == test_product.str.idx) {
48 desc_nd = &test_product;
49 } else if (idx == test_sn.str.idx) {
50 desc_nd = &test_sn;
51 } else {
52 return -ENOTSUP;
53 }
54
55 if (net_buf_pull_u8(buf) != desc_nd->bLength) {
56 return -EINVAL;
57 }
58
59 if (net_buf_pull_u8(buf) != USB_DESC_STRING) {
60 return -EINVAL;
61 }
62
63 LOG_HEXDUMP_DBG(buf->data, buf->len, "");
64 len = MIN(buf->len / 2, desc_nd->bLength / 2);
65 for (size_t i = 0; i < len; i++) {
66 uint16_t a = net_buf_pull_le16(buf);
67 uint16_t b = ((uint8_t *)(desc_nd->ptr))[i];
68
69 if (a != b) {
70 LOG_INF("%c != %c", a, b);
71 return -EINVAL;
72 }
73 }
74
75 return 0;
76 }
77
ZTEST(device_next,test_get_desc_string)78 ZTEST(device_next, test_get_desc_string)
79 {
80 const uint8_t type = USB_DESC_STRING;
81 const uint16_t id = 0x0409;
82 static struct usb_device *udev;
83 struct net_buf *buf;
84 int err;
85
86 udev = usbh_device_get_any(&uhs_ctx);
87 zassert_not_null(udev, "No USB device available");
88
89 buf = usbh_xfer_buf_alloc(udev, UINT8_MAX);
90 zassert_not_null(udev, "Failed to allocate buffer");
91
92 err = k_mutex_lock(&udev->mutex, K_MSEC(200));
93 zassert_equal(err, 0, "Failed to lock device");
94
95 err = usbh_req_desc(udev, type, 1, id, UINT8_MAX, buf);
96 zassert_equal(err, 0, "Transfer status is an error");
97 err = test_cmp_string_desc(buf, 1);
98 zassert_equal(err, 0, "Descriptor comparison failed");
99
100 net_buf_reset(buf);
101 err = usbh_req_desc(udev, type, 2, id, UINT8_MAX, buf);
102 zassert_equal(err, 0, "Transfer status is an error");
103 err = test_cmp_string_desc(buf, 2);
104 zassert_equal(err, 0, "Descriptor comparison failed");
105
106 net_buf_reset(buf);
107 err = usbh_req_desc(udev, type, 3, id, UINT8_MAX, buf);
108 zassert_equal(err, 0, "Transfer status is an error");
109 err = test_cmp_string_desc(buf, 3);
110 zassert_equal(err, 0, "Descriptor comparison failed");
111
112 k_mutex_unlock(&udev->mutex);
113 usbh_xfer_buf_free(udev, buf);
114 }
115
ZTEST(device_next,test_vendor_control_in)116 ZTEST(device_next, test_vendor_control_in)
117 {
118 const uint8_t bmRequestType = (USB_REQTYPE_DIR_TO_HOST << 7) |
119 (USB_REQTYPE_TYPE_VENDOR << 5);
120 static struct usb_device *udev;
121 const uint8_t bRequest = 0x5c;
122 const uint16_t wLength = 64;
123 struct net_buf *buf;
124 int err;
125
126 if (!IS_ENABLED(CONFIG_UHC_VIRTUAL)) {
127 LOG_WRN("The test was skipped, controller is not supported.");
128 return;
129 }
130
131 udev = usbh_device_get_any(&uhs_ctx);
132 zassert_not_null(udev, "No USB device available");
133
134 buf = usbh_xfer_buf_alloc(udev, wLength);
135 zassert_not_null(udev, "Failed to allocate buffer");
136
137 err = k_mutex_lock(&udev->mutex, K_MSEC(200));
138 zassert_equal(err, 0, "Failed to lock device");
139
140 /* Perform regular vendor IN transfer */
141 for (uint32_t i = 0; i < CONFIG_UDC_BUF_COUNT; i++) {
142 net_buf_reset(buf);
143 err = usbh_req_setup(udev, bmRequestType, bRequest, 0, 0, wLength, buf);
144 zassert_equal(err, 0, "Transfer status is an error");
145 }
146
147 /* Perform vendor IN transfer but omit status stage*/
148 usbh_req_omit_status(true);
149 for (uint32_t i = 0; i < CONFIG_UDC_BUF_COUNT * 2; i++) {
150 net_buf_reset(buf);
151 err = usbh_req_setup(udev, bmRequestType, bRequest, 0, 0, wLength, buf);
152 zassert_equal(err, 0, "Transfer status is an error");
153 }
154
155 /* Perform vendor IN requests but omit data and status stage*/
156 for (uint32_t i = 0; i < CONFIG_UDC_BUF_COUNT * 2; i++) {
157 err = usbh_req_setup(udev, bmRequestType, bRequest, 0, 0, wLength, NULL);
158 zassert_equal(err, 0, "Transfer status is an error");
159 }
160
161 usbh_req_omit_status(false);
162
163 /* Perform regular vendor IN transfer again */
164 for (uint32_t i = 0; i < CONFIG_UDC_BUF_COUNT; i++) {
165 net_buf_reset(buf);
166 err = usbh_req_setup(udev, bmRequestType, bRequest, 0, 0, wLength, buf);
167 zassert_equal(err, 0, "Transfer status is an error");
168 }
169
170 k_mutex_unlock(&udev->mutex);
171 usbh_xfer_buf_free(udev, buf);
172 }
173
ZTEST(device_next,test_vendor_control_out)174 ZTEST(device_next, test_vendor_control_out)
175 {
176 const uint8_t bmRequestType = (USB_REQTYPE_DIR_TO_DEVICE << 7) |
177 (USB_REQTYPE_TYPE_VENDOR << 5);
178 const uint8_t bRequest = 0x5b;
179 static struct usb_device *udev;
180 const uint16_t wLength = 64;
181 struct net_buf *buf;
182 int err;
183
184 if (!IS_ENABLED(CONFIG_UHC_VIRTUAL)) {
185 LOG_WRN("The test was skipped, controller is not supported.");
186 return;
187 }
188
189 udev = usbh_device_get_any(&uhs_ctx);
190 zassert_not_null(udev, "No USB device available");
191
192 buf = usbh_xfer_buf_alloc(udev, wLength);
193 zassert_not_null(udev, "Failed to allocate buffer");
194
195 err = k_mutex_lock(&udev->mutex, K_MSEC(200));
196 zassert_equal(err, 0, "Failed to lock device");
197
198 /* Perform regular vendor OUT transfer */
199 for (uint32_t i = 0; i < CONFIG_UDC_BUF_COUNT; i++) {
200 net_buf_reset(buf);
201 for (uint32_t n = 0; n < wLength; n++) {
202 net_buf_add_u8(buf, n);
203 }
204
205 err = usbh_req_setup(udev, bmRequestType, bRequest, 0, 0, wLength, buf);
206 zassert_equal(err, 0, "Transfer status is an error");
207 }
208
209 /* Perform vendor OUT transfer but omit status stage*/
210 usbh_req_omit_status(true);
211 for (uint32_t i = 0; i < CONFIG_UDC_BUF_COUNT * 2; i++) {
212 net_buf_reset(buf);
213 for (uint32_t n = 0; n < wLength; n++) {
214 net_buf_add_u8(buf, n);
215 }
216
217 err = usbh_req_setup(udev, bmRequestType, bRequest, 0, 0, wLength, buf);
218 zassert_equal(err, 0, "Transfer status is an error");
219 }
220
221 /* Perform vendor OUT requests but omit data and status stage*/
222 for (uint32_t i = 0; i < CONFIG_UDC_BUF_COUNT * 2; i++) {
223 err = usbh_req_setup(udev, bmRequestType, bRequest, 0, 0, wLength, NULL);
224 zassert_equal(err, 0, "Transfer status is an error");
225 }
226
227 usbh_req_omit_status(false);
228
229 /* Perform regular vendor OUT transfer again */
230 for (uint32_t i = 0; i < CONFIG_UDC_BUF_COUNT; i++) {
231 net_buf_reset(buf);
232 for (uint32_t n = 0; n < wLength; n++) {
233 net_buf_add_u8(buf, n);
234 }
235
236 err = usbh_req_setup(udev, bmRequestType, bRequest, 0, 0, wLength, buf);
237 zassert_equal(err, 0, "Transfer status is an error");
238 }
239
240 k_mutex_unlock(&udev->mutex);
241 usbh_xfer_buf_free(udev, buf);
242 }
243
ZTEST(device_next,test_control_nodata)244 ZTEST(device_next, test_control_nodata)
245 {
246 const uint8_t bmRequestType = USB_REQTYPE_RECIPIENT_ENDPOINT;
247 const uint8_t bRequest = USB_SREQ_CLEAR_FEATURE;
248 const uint16_t wValue = USB_SFS_ENDPOINT_HALT;
249 const uint16_t wIndex = USB_CONTROL_EP_OUT;
250 static struct usb_device *udev;
251 int err;
252
253 if (!IS_ENABLED(CONFIG_UHC_VIRTUAL)) {
254 LOG_WRN("The test was skipped, controller is not supported.");
255 return;
256 }
257
258 udev = usbh_device_get_any(&uhs_ctx);
259 zassert_not_null(udev, "No USB device available");
260
261 err = k_mutex_lock(&udev->mutex, K_MSEC(200));
262 zassert_equal(err, 0, "Failed to lock device");
263
264 /* Perform regular control transfer */
265 for (uint32_t i = 0; i < CONFIG_UDC_BUF_COUNT; i++) {
266 err = usbh_req_setup(udev,
267 bmRequestType, bRequest, wValue, wIndex, 0,
268 NULL);
269 zassert_equal(err, 0, "Transfer status is an error");
270 }
271
272 /* Perform transfer but omit status stage*/
273 usbh_req_omit_status(true);
274 for (uint32_t i = 0; i < CONFIG_UDC_BUF_COUNT * 2; i++) {
275 err = usbh_req_setup(udev,
276 bmRequestType, bRequest, wValue, wIndex, 0,
277 NULL);
278 zassert_equal(err, 0, "Transfer status is an error");
279 }
280
281 usbh_req_omit_status(false);
282
283 /* Perform regular control transfer again */
284 for (uint32_t i = 0; i < CONFIG_UDC_BUF_COUNT; i++) {
285 err = usbh_req_setup(udev,
286 bmRequestType, bRequest, wValue, wIndex, 0,
287 NULL);
288 zassert_equal(err, 0, "Transfer status is an error");
289 }
290
291 k_mutex_unlock(&udev->mutex);
292 }
293
294 /* Get Configuration request test */
ZTEST(device_next,test_get_configuration)295 ZTEST(device_next, test_get_configuration)
296 {
297 struct usb_device *udev;
298 uint8_t cfg = 0;
299 int err;
300
301 udev = usbh_device_get_any(&uhs_ctx);
302 zassert_not_null(udev, "No USB device available");
303
304 err = k_mutex_lock(&udev->mutex, K_MSEC(200));
305 zassert_equal(err, 0, "Failed to lock device");
306
307 err = usbh_req_get_cfg(udev, &cfg);
308 k_mutex_unlock(&udev->mutex);
309
310 switch (udev->state) {
311 case USB_STATE_DEFAULT:
312 /* Not specified, expect protocol error */
313 zassert_equal(err, -EPIPE, "Transfer status is not a protocol error");
314 break;
315 case USB_STATE_ADDRESSED:
316 /* TODO: Expect zero value */
317 zassert_equal(err, 0, "Transfer status is an error");
318 zassert_equal(cfg, 0, "Device not in address state");
319 break;
320 case USB_STATE_CONFIGURED:
321 /* TODO: Expect non-zero valid configuration value */
322 zassert_equal(err, 0, "Transfer status is an error");
323 zassert_not_equal(cfg, 0, "Device not in configured state");
324 break;
325 default:
326 break;
327 }
328 }
329
330 /* Set Interface request test */
ZTEST(device_next,test_set_interface)331 ZTEST(device_next, test_set_interface)
332 {
333 struct usb_device *udev;
334 int err;
335
336 udev = usbh_device_get_any(&uhs_ctx);
337 zassert_not_null(udev, "No USB device available");
338
339 err = k_mutex_lock(&udev->mutex, K_MSEC(200));
340 zassert_equal(err, 0, "Failed to lock device");
341
342 err = usbh_req_set_alt(udev, TEST_DEFAULT_INTERFACE,
343 TEST_DEFAULT_ALTERNATE);
344 k_mutex_unlock(&udev->mutex);
345
346 switch (udev->state) {
347 case USB_STATE_DEFAULT:
348 /* Not specified, expect protocol error */
349 case USB_STATE_ADDRESSED:
350 /* Expect protocol error */
351 zassert_equal(err, -EPIPE, "Transfer status is not a protocol error");
352 break;
353 case USB_STATE_CONFIGURED:
354 /* TODO */
355 default:
356 break;
357 }
358 }
359
usb_test_enable(void)360 static void *usb_test_enable(void)
361 {
362 int err;
363
364 err = usbh_init(&uhs_ctx);
365 zassert_equal(err, 0, "Failed to initialize USB host");
366
367 err = usbh_enable(&uhs_ctx);
368 zassert_equal(err, 0, "Failed to enable USB host");
369
370 err = uhc_bus_reset(uhs_ctx.dev);
371 zassert_equal(err, 0, "Failed to signal bus reset");
372
373 err = uhc_bus_resume(uhs_ctx.dev);
374 zassert_equal(err, 0, "Failed to signal bus resume");
375
376 err = uhc_sof_enable(uhs_ctx.dev);
377 zassert_equal(err, 0, "Failed to enable SoF generator");
378
379 LOG_INF("Host controller enabled");
380
381 err = usbd_add_descriptor(&test_usbd, &test_lang);
382 zassert_equal(err, 0, "Failed to initialize descriptor (%d)", err);
383
384 err = usbd_add_descriptor(&test_usbd, &test_mfg);
385 zassert_equal(err, 0, "Failed to initialize descriptor (%d)", err);
386
387 err = usbd_add_descriptor(&test_usbd, &test_product);
388 zassert_equal(err, 0, "Failed to initialize descriptor (%d)", err);
389
390 err = usbd_add_descriptor(&test_usbd, &test_sn);
391 zassert_equal(err, 0, "Failed to initialize descriptor (%d)", err);
392
393 if (USBD_SUPPORTS_HIGH_SPEED &&
394 usbd_caps_speed(&test_usbd) == USBD_SPEED_HS) {
395 err = usbd_add_configuration(&test_usbd, USBD_SPEED_HS, &test_hs_config);
396 zassert_equal(err, 0, "Failed to add configuration (%d)", err);
397 }
398
399 err = usbd_add_configuration(&test_usbd, USBD_SPEED_FS, &test_fs_config);
400 zassert_equal(err, 0, "Failed to add configuration (%d)", err);
401
402 if (USBD_SUPPORTS_HIGH_SPEED &&
403 usbd_caps_speed(&test_usbd) == USBD_SPEED_HS) {
404 err = usbd_register_all_classes(&test_usbd, USBD_SPEED_HS, 1, NULL);
405 zassert_equal(err, 0, "Failed to unregister all instances(%d)", err);
406
407 err = usbd_unregister_all_classes(&test_usbd, USBD_SPEED_HS, 1);
408 zassert_equal(err, 0, "Failed to unregister all instances(%d)", err);
409
410 err = usbd_register_class(&test_usbd, "loopback_0", USBD_SPEED_HS, 1);
411 zassert_equal(err, 0, "Failed to register loopback_0 class (%d)", err);
412 }
413
414 err = usbd_register_all_classes(&test_usbd, USBD_SPEED_FS, 1, NULL);
415 zassert_equal(err, 0, "Failed to unregister all instances(%d)", err);
416
417 err = usbd_unregister_all_classes(&test_usbd, USBD_SPEED_FS, 1);
418 zassert_equal(err, 0, "Failed to unregister all instances(%d)", err);
419
420 err = usbd_register_class(&test_usbd, "loopback_0", USBD_SPEED_FS, 1);
421 zassert_equal(err, 0, "Failed to register loopback_0 class (%d)", err);
422
423 err = usbd_init(&test_usbd);
424 zassert_equal(err, 0, "Failed to initialize device support");
425
426 err = usbd_enable(&test_usbd);
427 zassert_equal(err, 0, "Failed to enable device support");
428
429 LOG_INF("Device support enabled");
430
431 /* Allow the host time to reset the device. */
432 k_msleep(200);
433
434 return NULL;
435 }
436
usb_test_shutdown(void * f)437 static void usb_test_shutdown(void *f)
438 {
439 int err;
440
441 err = usbd_disable(&test_usbd);
442 zassert_equal(err, 0, "Failed to enable device support");
443
444 err = usbd_shutdown(&test_usbd);
445 zassert_equal(err, 0, "Failed to shutdown device support");
446
447 LOG_INF("Device support disabled");
448
449 err = usbh_disable(&uhs_ctx);
450 zassert_equal(err, 0, "Failed to disable USB host");
451
452 LOG_INF("Host controller disabled");
453 }
454
455 ZTEST_SUITE(device_next, NULL, usb_test_enable, NULL, NULL, usb_test_shutdown);
456