Line data Source code
1 1 : /*
2 : * Copyright (c) 2020 PHYTEC Messtechnik GmbH
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : /**
8 : * @file
9 : * @brief USB Chapter 9 structures and definitions
10 : *
11 : * This file contains the USB Chapter 9 structures definitions
12 : * and follows, with few exceptions, the USB Specification 2.0.
13 : */
14 :
15 : #include <zephyr/version.h>
16 : #include <zephyr/sys/util.h>
17 : #include <zephyr/math/ilog2.h>
18 : #include <zephyr/usb/class/usb_hub.h>
19 :
20 : #ifndef ZEPHYR_INCLUDE_USB_CH9_H_
21 : #define ZEPHYR_INCLUDE_USB_CH9_H_
22 :
23 : #ifdef __cplusplus
24 : extern "C" {
25 : #endif
26 :
27 0 : struct usb_req_type_field {
28 : #ifdef CONFIG_LITTLE_ENDIAN
29 : uint8_t recipient : 5;
30 : uint8_t type : 2;
31 : uint8_t direction : 1;
32 : #else
33 0 : uint8_t direction : 1;
34 0 : uint8_t type : 2;
35 0 : uint8_t recipient : 5;
36 : #endif
37 : } __packed;
38 :
39 : /** USB Setup Data packet defined in spec. Table 9-2 */
40 1 : struct usb_setup_packet {
41 : union {
42 0 : uint8_t bmRequestType;
43 0 : struct usb_req_type_field RequestType;
44 0 : } __packed;
45 0 : uint8_t bRequest;
46 0 : uint16_t wValue;
47 0 : uint16_t wIndex;
48 0 : uint16_t wLength;
49 : } __packed;
50 :
51 : /** USB Setup packet RequestType Direction values (from Table 9-2) */
52 1 : #define USB_REQTYPE_DIR_TO_DEVICE 0
53 0 : #define USB_REQTYPE_DIR_TO_HOST 1
54 :
55 : /** USB Setup packet RequestType Type values (from Table 9-2) */
56 1 : #define USB_REQTYPE_TYPE_STANDARD 0
57 0 : #define USB_REQTYPE_TYPE_CLASS 1
58 0 : #define USB_REQTYPE_TYPE_VENDOR 2
59 0 : #define USB_REQTYPE_TYPE_RESERVED 3
60 :
61 : /** USB Setup packet RequestType Recipient values (from Table 9-2) */
62 1 : #define USB_REQTYPE_RECIPIENT_DEVICE 0
63 0 : #define USB_REQTYPE_RECIPIENT_INTERFACE 1
64 0 : #define USB_REQTYPE_RECIPIENT_ENDPOINT 2
65 0 : #define USB_REQTYPE_RECIPIENT_OTHER 3
66 :
67 : /** Get data transfer direction from bmRequestType */
68 1 : #define USB_REQTYPE_GET_DIR(bmRequestType) (((bmRequestType) >> 7) & 0x01U)
69 : /** Get request type from bmRequestType */
70 1 : #define USB_REQTYPE_GET_TYPE(bmRequestType) (((bmRequestType) >> 5) & 0x03U)
71 : /** Get request recipient from bmRequestType */
72 1 : #define USB_REQTYPE_GET_RECIPIENT(bmRequestType) ((bmRequestType) & 0x1FU)
73 :
74 : /**
75 : * @brief Check if request transfer direction is to host.
76 : *
77 : * @param setup Pointer to USB Setup packet
78 : * @return true If transfer direction is to host
79 : */
80 1 : static inline bool usb_reqtype_is_to_host(const struct usb_setup_packet *setup)
81 : {
82 : return setup->RequestType.direction == USB_REQTYPE_DIR_TO_HOST;
83 : }
84 :
85 : /**
86 : * @brief Check if request transfer direction is to device.
87 : *
88 : * @param setup Pointer to USB Setup packet
89 : * @return true If transfer direction is to device
90 : */
91 1 : static inline bool usb_reqtype_is_to_device(const struct usb_setup_packet *setup)
92 : {
93 : return setup->RequestType.direction == USB_REQTYPE_DIR_TO_DEVICE;
94 : }
95 :
96 : /** USB Standard Request Codes defined in spec. Table 9-4 */
97 1 : #define USB_SREQ_GET_STATUS 0x00
98 0 : #define USB_SREQ_CLEAR_FEATURE 0x01
99 0 : #define USB_SREQ_SET_FEATURE 0x03
100 0 : #define USB_SREQ_SET_ADDRESS 0x05
101 0 : #define USB_SREQ_GET_DESCRIPTOR 0x06
102 0 : #define USB_SREQ_SET_DESCRIPTOR 0x07
103 0 : #define USB_SREQ_GET_CONFIGURATION 0x08
104 0 : #define USB_SREQ_SET_CONFIGURATION 0x09
105 0 : #define USB_SREQ_GET_INTERFACE 0x0A
106 0 : #define USB_SREQ_SET_INTERFACE 0x0B
107 0 : #define USB_SREQ_SYNCH_FRAME 0x0C
108 :
109 : /** Descriptor Types defined in spec. Table 9-5 */
110 1 : #define USB_DESC_DEVICE 1
111 0 : #define USB_DESC_CONFIGURATION 2
112 0 : #define USB_DESC_STRING 3
113 0 : #define USB_DESC_INTERFACE 4
114 0 : #define USB_DESC_ENDPOINT 5
115 0 : #define USB_DESC_DEVICE_QUALIFIER 6
116 0 : #define USB_DESC_OTHER_SPEED 7
117 0 : #define USB_DESC_INTERFACE_POWER 8
118 : /** Additional Descriptor Types defined in USB 3 spec. Table 9-5 */
119 1 : #define USB_DESC_OTG 9
120 0 : #define USB_DESC_DEBUG 10
121 0 : #define USB_DESC_INTERFACE_ASSOC 11
122 0 : #define USB_DESC_BOS 15
123 0 : #define USB_DESC_DEVICE_CAPABILITY 16
124 :
125 : /** Class-Specific Descriptor Types as defined by
126 : * USB Common Class Specification
127 : */
128 1 : #define USB_DESC_CS_DEVICE 0x21
129 0 : #define USB_DESC_CS_CONFIGURATION 0x22
130 0 : #define USB_DESC_CS_STRING 0x23
131 0 : #define USB_DESC_CS_INTERFACE 0x24
132 0 : #define USB_DESC_CS_ENDPOINT 0x25
133 :
134 : /** USB Standard Feature Selectors defined in spec. Table 9-6 */
135 1 : #define USB_SFS_ENDPOINT_HALT 0x00
136 0 : #define USB_SFS_REMOTE_WAKEUP 0x01
137 0 : #define USB_SFS_TEST_MODE 0x02
138 :
139 : /** USB Test Mode Selectors defined in spec. Table 9-7 */
140 1 : #define USB_SFS_TEST_MODE_J 0x01
141 0 : #define USB_SFS_TEST_MODE_K 0x02
142 0 : #define USB_SFS_TEST_MODE_SE0_NAK 0x03
143 0 : #define USB_SFS_TEST_MODE_PACKET 0x04
144 0 : #define USB_SFS_TEST_MODE_FORCE_ENABLE 0x05
145 :
146 : /** Bits used for GetStatus response defined in spec. Figure 9-4 */
147 1 : #define USB_GET_STATUS_SELF_POWERED BIT(0)
148 0 : #define USB_GET_STATUS_REMOTE_WAKEUP BIT(1)
149 :
150 : /** Header of an USB descriptor */
151 1 : struct usb_desc_header {
152 0 : uint8_t bLength;
153 0 : uint8_t bDescriptorType;
154 : } __packed;
155 :
156 : /** USB Standard Device Descriptor defined in spec. Table 9-8 */
157 1 : struct usb_device_descriptor {
158 0 : uint8_t bLength;
159 0 : uint8_t bDescriptorType;
160 0 : uint16_t bcdUSB;
161 0 : uint8_t bDeviceClass;
162 0 : uint8_t bDeviceSubClass;
163 0 : uint8_t bDeviceProtocol;
164 0 : uint8_t bMaxPacketSize0;
165 0 : uint16_t idVendor;
166 0 : uint16_t idProduct;
167 0 : uint16_t bcdDevice;
168 0 : uint8_t iManufacturer;
169 0 : uint8_t iProduct;
170 0 : uint8_t iSerialNumber;
171 0 : uint8_t bNumConfigurations;
172 : } __packed;
173 :
174 : /** USB Device Qualifier Descriptor defined in spec. Table 9-9 */
175 1 : struct usb_device_qualifier_descriptor {
176 0 : uint8_t bLength;
177 0 : uint8_t bDescriptorType;
178 0 : uint16_t bcdUSB;
179 0 : uint8_t bDeviceClass;
180 0 : uint8_t bDeviceSubClass;
181 0 : uint8_t bDeviceProtocol;
182 0 : uint8_t bMaxPacketSize0;
183 0 : uint8_t bNumConfigurations;
184 0 : uint8_t bReserved;
185 : } __packed;
186 :
187 : /** USB Standard Configuration Descriptor defined in spec. Table 9-10 */
188 1 : struct usb_cfg_descriptor {
189 0 : uint8_t bLength;
190 0 : uint8_t bDescriptorType;
191 0 : uint16_t wTotalLength;
192 0 : uint8_t bNumInterfaces;
193 0 : uint8_t bConfigurationValue;
194 0 : uint8_t iConfiguration;
195 0 : uint8_t bmAttributes;
196 0 : uint8_t bMaxPower;
197 : } __packed;
198 :
199 : /** USB Standard Interface Descriptor defined in spec. Table 9-12 */
200 1 : struct usb_if_descriptor {
201 0 : uint8_t bLength;
202 0 : uint8_t bDescriptorType;
203 0 : uint8_t bInterfaceNumber;
204 0 : uint8_t bAlternateSetting;
205 0 : uint8_t bNumEndpoints;
206 0 : uint8_t bInterfaceClass;
207 0 : uint8_t bInterfaceSubClass;
208 0 : uint8_t bInterfaceProtocol;
209 0 : uint8_t iInterface;
210 : } __packed;
211 :
212 0 : struct usb_ep_desc_bmattr {
213 : #ifdef CONFIG_LITTLE_ENDIAN
214 : uint8_t transfer : 2;
215 : uint8_t synch: 2;
216 : uint8_t usage: 2;
217 : uint8_t reserved: 2;
218 : #else
219 0 : uint8_t reserved: 2;
220 0 : uint8_t usage : 2;
221 0 : uint8_t synch : 2;
222 0 : uint8_t transfer : 2;
223 : #endif
224 : } __packed;
225 :
226 : /** USB Standard Endpoint Descriptor defined in spec. Table 9-13 */
227 1 : struct usb_ep_descriptor {
228 0 : uint8_t bLength;
229 0 : uint8_t bDescriptorType;
230 0 : uint8_t bEndpointAddress;
231 : union {
232 0 : uint8_t bmAttributes;
233 0 : struct usb_ep_desc_bmattr Attributes;
234 0 : };
235 0 : uint16_t wMaxPacketSize;
236 0 : uint8_t bInterval;
237 : } __packed;
238 :
239 : /** USB Unicode (UTF16LE) String Descriptor defined in spec. Table 9-15 */
240 1 : struct usb_string_descriptor {
241 0 : uint8_t bLength;
242 0 : uint8_t bDescriptorType;
243 0 : uint16_t bString;
244 : } __packed;
245 :
246 : /** USB Association Descriptor defined in USB 3 spec. Table 9-16 */
247 1 : struct usb_association_descriptor {
248 0 : uint8_t bLength;
249 0 : uint8_t bDescriptorType;
250 0 : uint8_t bFirstInterface;
251 0 : uint8_t bInterfaceCount;
252 0 : uint8_t bFunctionClass;
253 0 : uint8_t bFunctionSubClass;
254 0 : uint8_t bFunctionProtocol;
255 0 : uint8_t iFunction;
256 : } __packed;
257 :
258 : /** USB Standard Configuration Descriptor Characteristics from Table 9-10 */
259 1 : #define USB_SCD_RESERVED BIT(7)
260 0 : #define USB_SCD_SELF_POWERED BIT(6)
261 0 : #define USB_SCD_REMOTE_WAKEUP BIT(5)
262 :
263 : /** USB Defined Base Class Codes from https://www.usb.org/defined-class-codes */
264 1 : #define USB_BCC_AUDIO 0x01
265 0 : #define USB_BCC_CDC_CONTROL 0x02
266 0 : #define USB_BCC_HID 0x03
267 0 : #define USB_BCC_MASS_STORAGE 0x08
268 0 : #define USB_BCC_CDC_DATA 0x0A
269 0 : #define USB_BCC_VIDEO 0x0E
270 0 : #define USB_BCC_WIRELESS_CONTROLLER 0xE0
271 0 : #define USB_BCC_MISCELLANEOUS 0xEF
272 0 : #define USB_BCC_APPLICATION 0xFE
273 0 : #define USB_BCC_VENDOR 0xFF
274 :
275 : /** USB Specification Release Numbers (bcdUSB Descriptor field) */
276 1 : #define USB_SRN_1_1 0x0110
277 0 : #define USB_SRN_2_0 0x0200
278 0 : #define USB_SRN_2_0_1 0x0201
279 0 : #define USB_SRN_2_1 0x0210
280 :
281 0 : #define USB_DEC_TO_BCD(dec) ((((dec) / 10) << 4) | ((dec) % 10))
282 :
283 : /** USB Device release number (bcdDevice Descriptor field) */
284 1 : #define USB_BCD_DRN (USB_DEC_TO_BCD(KERNEL_VERSION_MAJOR) << 8 | \
285 : USB_DEC_TO_BCD(KERNEL_VERSION_MINOR))
286 :
287 : /** Macro to obtain descriptor type from USB_SREQ_GET_DESCRIPTOR request */
288 1 : #define USB_GET_DESCRIPTOR_TYPE(wValue) ((uint8_t)((wValue) >> 8))
289 :
290 : /** Macro to obtain descriptor index from USB_SREQ_GET_DESCRIPTOR request */
291 1 : #define USB_GET_DESCRIPTOR_INDEX(wValue) ((uint8_t)(wValue))
292 :
293 : /**
294 : * USB Control Endpoints maximum packet size (MPS)
295 : *
296 : * This value may not be correct for devices operating at speeds other than
297 : * high speed.
298 : */
299 1 : #define USB_CONTROL_EP_MPS 64U
300 :
301 : /** USB endpoint direction mask */
302 1 : #define USB_EP_DIR_MASK (uint8_t)BIT(7)
303 :
304 : /** USB IN endpoint direction */
305 1 : #define USB_EP_DIR_IN (uint8_t)BIT(7)
306 :
307 : /** USB OUT endpoint direction */
308 1 : #define USB_EP_DIR_OUT 0U
309 :
310 : /*
311 : * REVISE: this should actually be (ep) & 0x0F, but is causes
312 : * many regressions in the current device support that are difficult
313 : * to handle.
314 : */
315 : /** Get endpoint index (number) from endpoint address */
316 1 : #define USB_EP_GET_IDX(ep) ((ep) & ~USB_EP_DIR_MASK)
317 :
318 : /** Get direction based on endpoint address */
319 1 : #define USB_EP_GET_DIR(ep) ((ep) & USB_EP_DIR_MASK)
320 :
321 : /** Get endpoint address from endpoint index and direction */
322 1 : #define USB_EP_GET_ADDR(idx, dir) ((idx) | ((dir) & USB_EP_DIR_MASK))
323 :
324 : /** True if the endpoint is an IN endpoint */
325 1 : #define USB_EP_DIR_IS_IN(ep) (USB_EP_GET_DIR(ep) == USB_EP_DIR_IN)
326 :
327 : /** True if the endpoint is an OUT endpoint */
328 1 : #define USB_EP_DIR_IS_OUT(ep) (USB_EP_GET_DIR(ep) == USB_EP_DIR_OUT)
329 :
330 : /** USB Control Endpoints OUT address */
331 1 : #define USB_CONTROL_EP_OUT (USB_EP_DIR_OUT | 0U)
332 :
333 : /** USB Control Endpoints IN address */
334 1 : #define USB_CONTROL_EP_IN (USB_EP_DIR_IN | 0U)
335 :
336 : /** USB endpoint transfer type mask */
337 1 : #define USB_EP_TRANSFER_TYPE_MASK 0x3U
338 :
339 : /** USB endpoint transfer type control */
340 1 : #define USB_EP_TYPE_CONTROL 0U
341 :
342 : /** USB endpoint transfer type isochronous */
343 1 : #define USB_EP_TYPE_ISO 1U
344 :
345 : /** USB endpoint transfer type bulk */
346 1 : #define USB_EP_TYPE_BULK 2U
347 :
348 : /** USB endpoint transfer type interrupt */
349 1 : #define USB_EP_TYPE_INTERRUPT 3U
350 :
351 : /** Calculate full speed interrupt endpoint bInterval from a value in microseconds */
352 1 : #define USB_FS_INT_EP_INTERVAL(us) CLAMP(((us) / 1000U), 1U, 255U)
353 :
354 : /** Calculate high speed interrupt endpoint bInterval from a value in microseconds */
355 1 : #define USB_HS_INT_EP_INTERVAL(us) CLAMP((ilog2((us) / 125U) + 1U), 1U, 16U)
356 :
357 : /** Calculate full speed isochronous endpoint bInterval from a value in microseconds */
358 1 : #define USB_FS_ISO_EP_INTERVAL(us) CLAMP((ilog2((us) / 1000U) + 1U), 1U, 16U)
359 :
360 : /** Calculate high speed isochronous endpoint bInterval from a value in microseconds */
361 1 : #define USB_HS_ISO_EP_INTERVAL(us) CLAMP((ilog2((us) / 125U) + 1U), 1U, 16U)
362 :
363 : /** Get endpoint size field from Max Packet Size value */
364 1 : #define USB_MPS_EP_SIZE(mps) ((mps) & BIT_MASK(11))
365 :
366 : /** Get number of additional transactions per microframe from Max Packet Size value */
367 1 : #define USB_MPS_ADDITIONAL_TRANSACTIONS(mps) (((mps) & 0x1800) >> 11)
368 :
369 : /** Calculate total payload length from Max Packet Size value */
370 1 : #define USB_MPS_TO_TPL(mps) \
371 : ((1 + USB_MPS_ADDITIONAL_TRANSACTIONS(mps)) * USB_MPS_EP_SIZE(mps))
372 :
373 : /** Calculate Max Packet Size value from total payload length */
374 1 : #define USB_TPL_TO_MPS(tpl) \
375 : (((tpl) > 2048) ? ((2 << 11) | ((tpl) / 3)) : \
376 : ((tpl) > 1024) ? ((1 << 11) | ((tpl) / 2)) : \
377 : (tpl))
378 :
379 : /** Round up total payload length to next valid value */
380 1 : #define USB_TPL_ROUND_UP(tpl) \
381 : (((tpl) > 2048) ? ROUND_UP(tpl, 3) : \
382 : ((tpl) > 1024) ? ROUND_UP(tpl, 2) : \
383 : (tpl))
384 :
385 : /** Determine whether total payload length value is valid according to USB 2.0 */
386 1 : #define USB_TPL_IS_VALID(tpl) \
387 : (((tpl) > 3072) ? false : \
388 : ((tpl) > 2048) ? ((tpl) % 3 == 0) : \
389 : ((tpl) > 1024) ? ((tpl) % 2 == 0) : \
390 : ((tpl) >= 0))
391 :
392 : #ifdef __cplusplus
393 : }
394 : #endif
395 :
396 : #endif /* ZEPHYR_INCLUDE_USB_CH9_H_ */
|