LCOV - code coverage report
Current view: top level - zephyr/usb - usb_ch9.h Coverage Total Hit
Test: new.info Lines: 30.3 % 188 57
Test Date: 2025-09-05 16:43:28

            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_ */
        

Generated by: LCOV version 2.0-1