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 : }; 45 0 : uint8_t bRequest; 46 0 : uint16_t wValue; 47 0 : uint16_t wIndex; 48 0 : uint16_t wLength; 49 : }; 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 : /** Bits used for GetStatus response defined in spec. Figure 9-4 */ 140 1 : #define USB_GET_STATUS_SELF_POWERED BIT(0) 141 0 : #define USB_GET_STATUS_REMOTE_WAKEUP BIT(1) 142 : 143 : /** Header of an USB descriptor */ 144 1 : struct usb_desc_header { 145 0 : uint8_t bLength; 146 0 : uint8_t bDescriptorType; 147 : } __packed; 148 : 149 : /** USB Standard Device Descriptor defined in spec. Table 9-8 */ 150 1 : struct usb_device_descriptor { 151 0 : uint8_t bLength; 152 0 : uint8_t bDescriptorType; 153 0 : uint16_t bcdUSB; 154 0 : uint8_t bDeviceClass; 155 0 : uint8_t bDeviceSubClass; 156 0 : uint8_t bDeviceProtocol; 157 0 : uint8_t bMaxPacketSize0; 158 0 : uint16_t idVendor; 159 0 : uint16_t idProduct; 160 0 : uint16_t bcdDevice; 161 0 : uint8_t iManufacturer; 162 0 : uint8_t iProduct; 163 0 : uint8_t iSerialNumber; 164 0 : uint8_t bNumConfigurations; 165 : } __packed; 166 : 167 : /** USB Device Qualifier Descriptor defined in spec. Table 9-9 */ 168 1 : struct usb_device_qualifier_descriptor { 169 0 : uint8_t bLength; 170 0 : uint8_t bDescriptorType; 171 0 : uint16_t bcdUSB; 172 0 : uint8_t bDeviceClass; 173 0 : uint8_t bDeviceSubClass; 174 0 : uint8_t bDeviceProtocol; 175 0 : uint8_t bMaxPacketSize0; 176 0 : uint8_t bNumConfigurations; 177 0 : uint8_t bReserved; 178 : } __packed; 179 : 180 : /** USB Standard Configuration Descriptor defined in spec. Table 9-10 */ 181 1 : struct usb_cfg_descriptor { 182 0 : uint8_t bLength; 183 0 : uint8_t bDescriptorType; 184 0 : uint16_t wTotalLength; 185 0 : uint8_t bNumInterfaces; 186 0 : uint8_t bConfigurationValue; 187 0 : uint8_t iConfiguration; 188 0 : uint8_t bmAttributes; 189 0 : uint8_t bMaxPower; 190 : } __packed; 191 : 192 : /** USB Standard Interface Descriptor defined in spec. Table 9-12 */ 193 1 : struct usb_if_descriptor { 194 0 : uint8_t bLength; 195 0 : uint8_t bDescriptorType; 196 0 : uint8_t bInterfaceNumber; 197 0 : uint8_t bAlternateSetting; 198 0 : uint8_t bNumEndpoints; 199 0 : uint8_t bInterfaceClass; 200 0 : uint8_t bInterfaceSubClass; 201 0 : uint8_t bInterfaceProtocol; 202 0 : uint8_t iInterface; 203 : } __packed; 204 : 205 0 : struct usb_ep_desc_bmattr { 206 : #ifdef CONFIG_LITTLE_ENDIAN 207 : uint8_t transfer : 2; 208 : uint8_t synch: 2; 209 : uint8_t usage: 2; 210 : uint8_t reserved: 2; 211 : #else 212 0 : uint8_t reserved: 2; 213 0 : uint8_t usage : 2; 214 0 : uint8_t synch : 2; 215 0 : uint8_t transfer : 2; 216 : #endif 217 : } __packed; 218 : 219 : /** USB Standard Endpoint Descriptor defined in spec. Table 9-13 */ 220 1 : struct usb_ep_descriptor { 221 0 : uint8_t bLength; 222 0 : uint8_t bDescriptorType; 223 0 : uint8_t bEndpointAddress; 224 : union { 225 0 : uint8_t bmAttributes; 226 0 : struct usb_ep_desc_bmattr Attributes; 227 0 : }; 228 0 : uint16_t wMaxPacketSize; 229 0 : uint8_t bInterval; 230 : } __packed; 231 : 232 : /** USB Unicode (UTF16LE) String Descriptor defined in spec. Table 9-15 */ 233 1 : struct usb_string_descriptor { 234 0 : uint8_t bLength; 235 0 : uint8_t bDescriptorType; 236 0 : uint16_t bString; 237 : } __packed; 238 : 239 : /** USB Association Descriptor defined in USB 3 spec. Table 9-16 */ 240 1 : struct usb_association_descriptor { 241 0 : uint8_t bLength; 242 0 : uint8_t bDescriptorType; 243 0 : uint8_t bFirstInterface; 244 0 : uint8_t bInterfaceCount; 245 0 : uint8_t bFunctionClass; 246 0 : uint8_t bFunctionSubClass; 247 0 : uint8_t bFunctionProtocol; 248 0 : uint8_t iFunction; 249 : } __packed; 250 : 251 : /** USB Standard Configuration Descriptor Characteristics from Table 9-10 */ 252 1 : #define USB_SCD_RESERVED BIT(7) 253 0 : #define USB_SCD_SELF_POWERED BIT(6) 254 0 : #define USB_SCD_REMOTE_WAKEUP BIT(5) 255 : 256 : /** USB Defined Base Class Codes from https://www.usb.org/defined-class-codes */ 257 1 : #define USB_BCC_AUDIO 0x01 258 0 : #define USB_BCC_CDC_CONTROL 0x02 259 0 : #define USB_BCC_HID 0x03 260 0 : #define USB_BCC_MASS_STORAGE 0x08 261 0 : #define USB_BCC_CDC_DATA 0x0A 262 0 : #define USB_BCC_VIDEO 0x0E 263 0 : #define USB_BCC_WIRELESS_CONTROLLER 0xE0 264 0 : #define USB_BCC_MISCELLANEOUS 0xEF 265 0 : #define USB_BCC_APPLICATION 0xFE 266 0 : #define USB_BCC_VENDOR 0xFF 267 : 268 : /** USB Specification Release Numbers (bcdUSB Descriptor field) */ 269 1 : #define USB_SRN_1_1 0x0110 270 0 : #define USB_SRN_2_0 0x0200 271 0 : #define USB_SRN_2_0_1 0x0201 272 0 : #define USB_SRN_2_1 0x0210 273 : 274 0 : #define USB_DEC_TO_BCD(dec) ((((dec) / 10) << 4) | ((dec) % 10)) 275 : 276 : /** USB Device release number (bcdDevice Descriptor field) */ 277 1 : #define USB_BCD_DRN (USB_DEC_TO_BCD(KERNEL_VERSION_MAJOR) << 8 | \ 278 : USB_DEC_TO_BCD(KERNEL_VERSION_MINOR)) 279 : 280 : /** Macro to obtain descriptor type from USB_SREQ_GET_DESCRIPTOR request */ 281 1 : #define USB_GET_DESCRIPTOR_TYPE(wValue) ((uint8_t)((wValue) >> 8)) 282 : 283 : /** Macro to obtain descriptor index from USB_SREQ_GET_DESCRIPTOR request */ 284 1 : #define USB_GET_DESCRIPTOR_INDEX(wValue) ((uint8_t)(wValue)) 285 : 286 : /** 287 : * USB Control Endpoints maximum packet size (MPS) 288 : * 289 : * This value may not be correct for devices operating at speeds other than 290 : * high speed. 291 : */ 292 1 : #define USB_CONTROL_EP_MPS 64U 293 : 294 : /** USB endpoint direction mask */ 295 1 : #define USB_EP_DIR_MASK (uint8_t)BIT(7) 296 : 297 : /** USB IN endpoint direction */ 298 1 : #define USB_EP_DIR_IN (uint8_t)BIT(7) 299 : 300 : /** USB OUT endpoint direction */ 301 1 : #define USB_EP_DIR_OUT 0U 302 : 303 : /* 304 : * REVISE: this should actually be (ep) & 0x0F, but is causes 305 : * many regressions in the current device support that are difficult 306 : * to handle. 307 : */ 308 : /** Get endpoint index (number) from endpoint address */ 309 1 : #define USB_EP_GET_IDX(ep) ((ep) & ~USB_EP_DIR_MASK) 310 : 311 : /** Get direction based on endpoint address */ 312 1 : #define USB_EP_GET_DIR(ep) ((ep) & USB_EP_DIR_MASK) 313 : 314 : /** Get endpoint address from endpoint index and direction */ 315 1 : #define USB_EP_GET_ADDR(idx, dir) ((idx) | ((dir) & USB_EP_DIR_MASK)) 316 : 317 : /** True if the endpoint is an IN endpoint */ 318 1 : #define USB_EP_DIR_IS_IN(ep) (USB_EP_GET_DIR(ep) == USB_EP_DIR_IN) 319 : 320 : /** True if the endpoint is an OUT endpoint */ 321 1 : #define USB_EP_DIR_IS_OUT(ep) (USB_EP_GET_DIR(ep) == USB_EP_DIR_OUT) 322 : 323 : /** USB Control Endpoints OUT address */ 324 1 : #define USB_CONTROL_EP_OUT (USB_EP_DIR_OUT | 0U) 325 : 326 : /** USB Control Endpoints IN address */ 327 1 : #define USB_CONTROL_EP_IN (USB_EP_DIR_IN | 0U) 328 : 329 : /** USB endpoint transfer type mask */ 330 1 : #define USB_EP_TRANSFER_TYPE_MASK 0x3U 331 : 332 : /** USB endpoint transfer type control */ 333 1 : #define USB_EP_TYPE_CONTROL 0U 334 : 335 : /** USB endpoint transfer type isochronous */ 336 1 : #define USB_EP_TYPE_ISO 1U 337 : 338 : /** USB endpoint transfer type bulk */ 339 1 : #define USB_EP_TYPE_BULK 2U 340 : 341 : /** USB endpoint transfer type interrupt */ 342 1 : #define USB_EP_TYPE_INTERRUPT 3U 343 : 344 : /** Calculate full speed interrupt endpoint bInterval from a value in microseconds */ 345 1 : #define USB_FS_INT_EP_INTERVAL(us) CLAMP(((us) / 1000U), 1U, 255U) 346 : 347 : /** Calculate high speed interrupt endpoint bInterval from a value in microseconds */ 348 1 : #define USB_HS_INT_EP_INTERVAL(us) CLAMP((ilog2((us) / 125U) + 1U), 1U, 16U) 349 : 350 : /** Calculate high speed isochronous endpoint bInterval from a value in microseconds */ 351 1 : #define USB_FS_ISO_EP_INTERVAL(us) CLAMP(((us) / 1000U), 1U, 16U) 352 : 353 : /** Calculate high speed isochronous endpoint bInterval from a value in microseconds */ 354 1 : #define USB_HS_ISO_EP_INTERVAL(us) CLAMP((ilog2((us) / 125U) + 1U), 1U, 16U) 355 : 356 : /** Get endpoint size field from Max Packet Size value */ 357 1 : #define USB_MPS_EP_SIZE(mps) ((mps) & BIT_MASK(11)) 358 : 359 : /** Get number of additional transactions per microframe from Max Packet Size value */ 360 1 : #define USB_MPS_ADDITIONAL_TRANSACTIONS(mps) (((mps) & 0x1800) >> 11) 361 : 362 : /** Calculate total payload length from Max Packet Size value */ 363 1 : #define USB_MPS_TO_TPL(mps) \ 364 : ((1 + USB_MPS_ADDITIONAL_TRANSACTIONS(mps)) * USB_MPS_EP_SIZE(mps)) 365 : 366 : /** Calculate Max Packet Size value from total payload length */ 367 1 : #define USB_TPL_TO_MPS(tpl) \ 368 : (((tpl) > 2048) ? ((2 << 11) | ((tpl) / 3)) : \ 369 : ((tpl) > 1024) ? ((1 << 11) | ((tpl) / 2)) : \ 370 : (tpl)) 371 : 372 : /** Round up total payload length to next valid value */ 373 1 : #define USB_TPL_ROUND_UP(tpl) \ 374 : (((tpl) > 2048) ? ROUND_UP(tpl, 3) : \ 375 : ((tpl) > 1024) ? ROUND_UP(tpl, 2) : \ 376 : (tpl)) 377 : 378 : /** Determine whether total payload length value is valid according to USB 2.0 */ 379 1 : #define USB_TPL_IS_VALID(tpl) \ 380 : (((tpl) > 3072) ? false : \ 381 : ((tpl) > 2048) ? ((tpl) % 3 == 0) : \ 382 : ((tpl) > 1024) ? ((tpl) % 2 == 0) : \ 383 : ((tpl) >= 0)) 384 : 385 : #ifdef __cplusplus 386 : } 387 : #endif 388 : 389 : #endif /* ZEPHYR_INCLUDE_USB_CH9_H_ */