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 
40 /* Get Configuration request test */
ZTEST(device_next,test_get_configuration)41 ZTEST(device_next, test_get_configuration)
42 {
43 	struct usb_device *udev;
44 	uint8_t cfg = 0;
45 	int err;
46 
47 	udev = usbh_device_get_any(&uhs_ctx);
48 	zassert_not_null(udev, "No USB device available");
49 
50 	err = k_mutex_lock(&udev->mutex, K_MSEC(200));
51 	zassert_equal(err, 0, "Failed to lock device");
52 
53 	err = usbh_req_get_cfg(udev, &cfg);
54 	k_mutex_unlock(&udev->mutex);
55 
56 	switch (udev->state) {
57 	case USB_STATE_DEFAULT:
58 		/* Not specified, expect protocol error */
59 		zassert_equal(err, -EPIPE, "Transfer status is not a protocol error");
60 		break;
61 	case USB_STATE_ADDRESSED:
62 		/* TODO: Expect zero value */
63 		zassert_equal(err, 0, "Transfer status is an error");
64 		zassert_equal(cfg, 0, "Device not in address state");
65 		break;
66 	case USB_STATE_CONFIGURED:
67 		/* TODO: Expect non-zero valid configuration value */
68 		zassert_equal(err, 0, "Transfer status is an error");
69 		zassert_not_equal(cfg, 0, "Device not in configured state");
70 		break;
71 	default:
72 		break;
73 	}
74 }
75 
76 /* Set Interface request test */
ZTEST(device_next,test_set_interface)77 ZTEST(device_next, test_set_interface)
78 {
79 	struct usb_device *udev;
80 	int err;
81 
82 	udev = usbh_device_get_any(&uhs_ctx);
83 	zassert_not_null(udev, "No USB device available");
84 
85 	err = k_mutex_lock(&udev->mutex, K_MSEC(200));
86 	zassert_equal(err, 0, "Failed to lock device");
87 
88 	err = usbh_req_set_alt(udev, TEST_DEFAULT_INTERFACE,
89 			       TEST_DEFAULT_ALTERNATE);
90 	k_mutex_unlock(&udev->mutex);
91 
92 	switch (udev->state) {
93 	case USB_STATE_DEFAULT:
94 		/* Not specified, expect protocol error */
95 	case USB_STATE_ADDRESSED:
96 		/* Expect protocol error */
97 		zassert_equal(err, -EPIPE, "Transfer status is not a protocol error");
98 		break;
99 	case USB_STATE_CONFIGURED:
100 		/* TODO */
101 	default:
102 		break;
103 	}
104 }
105 
usb_test_enable(void)106 static void *usb_test_enable(void)
107 {
108 	int err;
109 
110 	err = usbh_init(&uhs_ctx);
111 	zassert_equal(err, 0, "Failed to initialize USB host");
112 
113 	err = usbh_enable(&uhs_ctx);
114 	zassert_equal(err, 0, "Failed to enable USB host");
115 
116 	err = uhc_bus_reset(uhs_ctx.dev);
117 	zassert_equal(err, 0, "Failed to signal bus reset");
118 
119 	err = uhc_bus_resume(uhs_ctx.dev);
120 	zassert_equal(err, 0, "Failed to signal bus resume");
121 
122 	err = uhc_sof_enable(uhs_ctx.dev);
123 	zassert_equal(err, 0, "Failed to enable SoF generator");
124 
125 	LOG_INF("Host controller enabled");
126 
127 	err = usbd_add_descriptor(&test_usbd, &test_lang);
128 	zassert_equal(err, 0, "Failed to initialize descriptor (%d)", err);
129 
130 	err = usbd_add_descriptor(&test_usbd, &test_mfg);
131 	zassert_equal(err, 0, "Failed to initialize descriptor (%d)", err);
132 
133 	err = usbd_add_descriptor(&test_usbd, &test_product);
134 	zassert_equal(err, 0, "Failed to initialize descriptor (%d)", err);
135 
136 	err = usbd_add_descriptor(&test_usbd, &test_sn);
137 	zassert_equal(err, 0, "Failed to initialize descriptor (%d)", err);
138 
139 	if (usbd_caps_speed(&test_usbd) == USBD_SPEED_HS) {
140 		err = usbd_add_configuration(&test_usbd, USBD_SPEED_HS, &test_hs_config);
141 		zassert_equal(err, 0, "Failed to add configuration (%d)");
142 	}
143 
144 	err = usbd_add_configuration(&test_usbd, USBD_SPEED_FS, &test_fs_config);
145 	zassert_equal(err, 0, "Failed to add configuration (%d)");
146 
147 	if (usbd_caps_speed(&test_usbd) == USBD_SPEED_HS) {
148 		err = usbd_register_all_classes(&test_usbd, USBD_SPEED_HS, 1, NULL);
149 		zassert_equal(err, 0, "Failed to unregister all instances(%d)");
150 
151 		err = usbd_unregister_all_classes(&test_usbd, USBD_SPEED_HS, 1);
152 		zassert_equal(err, 0, "Failed to unregister all instances(%d)");
153 
154 		err = usbd_register_class(&test_usbd, "loopback_0", USBD_SPEED_HS, 1);
155 		zassert_equal(err, 0, "Failed to register loopback_0 class (%d)");
156 	}
157 
158 	err = usbd_register_all_classes(&test_usbd, USBD_SPEED_FS, 1, NULL);
159 	zassert_equal(err, 0, "Failed to unregister all instances(%d)");
160 
161 	err = usbd_unregister_all_classes(&test_usbd, USBD_SPEED_FS, 1);
162 	zassert_equal(err, 0, "Failed to unregister all instances(%d)");
163 
164 	err = usbd_register_class(&test_usbd, "loopback_0", USBD_SPEED_FS, 1);
165 	zassert_equal(err, 0, "Failed to register loopback_0 class (%d)");
166 
167 	err = usbd_init(&test_usbd);
168 	zassert_equal(err, 0, "Failed to initialize device support");
169 
170 	err = usbd_enable(&test_usbd);
171 	zassert_equal(err, 0, "Failed to enable device support");
172 
173 	LOG_INF("Device support enabled");
174 
175 	/* Allow the host time to reset the device. */
176 	k_msleep(200);
177 
178 	return NULL;
179 }
180 
usb_test_shutdown(void * f)181 static void usb_test_shutdown(void *f)
182 {
183 	int err;
184 
185 	err = usbd_disable(&test_usbd);
186 	zassert_equal(err, 0, "Failed to enable device support");
187 
188 	err = usbd_shutdown(&test_usbd);
189 	zassert_equal(err, 0, "Failed to shutdown device support");
190 
191 	LOG_INF("Device support disabled");
192 
193 	err = usbh_disable(&uhs_ctx);
194 	zassert_equal(err, 0, "Failed to disable USB host");
195 
196 	LOG_INF("Host controller disabled");
197 }
198 
199 ZTEST_SUITE(device_next, NULL, usb_test_enable, NULL, NULL, usb_test_shutdown);
200