LCOV - code coverage report
Current view: top level - zephyr/usb - usb_ch9.h Hit Total Coverage
Test: new.info Lines: 56 183 30.6 %
Date: 2024-12-22 00:14:23

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

Generated by: LCOV version 1.14