| /** |
| * \file |
| * |
| * \brief USB protocol definitions. |
| * |
| * This file contains the USB definitions and data structures provided by the |
| * USB 2.0 specification. |
| * |
| * Copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. |
| * |
| * \asf_license_start |
| * |
| * \page License |
| * |
| * Subject to your compliance with these terms, you may use Microchip |
| * software and any derivatives exclusively with Microchip products. |
| * It is your responsibility to comply with third party license terms applicable |
| * to your use of third party software (including open source software) that |
| * may accompany Microchip software. |
| * |
| * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, |
| * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, |
| * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, |
| * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE |
| * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL |
| * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE |
| * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE |
| * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT |
| * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY |
| * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, |
| * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. |
| * |
| * \asf_license_stop |
| */ |
| |
| #ifndef _USB_PROTOCOL_H_ |
| #define _USB_PROTOCOL_H_ |
| |
| #include "usb_includes.h" |
| |
| /** |
| * \ingroup usb_group |
| * \defgroup usb_protocol_group USB Protocol Definitions |
| * |
| * This module defines constants and data structures provided by the USB |
| * 2.0 specification. |
| * |
| * @{ |
| */ |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| #ifdef __CC_ARM |
| #pragma anon_unions |
| #endif |
| |
| /*! Value for field bcdUSB */ |
| #define USB_V2_0 (0x0200) /*!< USB Specification version 2.00 */ |
| #define USB_V2_1 (0x0201) /*!< USB Specification version 2.01 (support BOS) */ |
| |
| /*! \name Generic definitions (Class, subclass and protocol) |
| */ |
| /*! @{ */ |
| #define USB_CLASS_NO (0x00) |
| #define USB_SUBCLASS_NO (0x00) |
| #define USB_PROTOCOL_NO (0x00) |
| /*! @} */ |
| |
| /*! \name IAD (Interface Association Descriptor) constants */ |
| /*! @{ */ |
| #define USB_CLASS_IAD (0xEF) |
| #define USB_SUBCLASS_IAD (0x02) |
| #define USB_PROTOCOL_IAD (0x01) |
| /*! @} */ |
| |
| /** |
| * \brief USB request data transfer direction (bmRequestType) |
| */ |
| #define USB_REQT_DIR_OUT (0 << 7) /*!< Host to device */ |
| #define USB_REQT_DIR_H2D (0 << 7) /*!< Host to device */ |
| #define USB_REQT_DIR_IN (1 << 7) /*!< Device to host */ |
| #define USB_REQT_DIR_D2H (1 << 7) /*!< Device to host */ |
| #define USB_REQT_DIR_MASK (1 << 7) /*!< Mask */ |
| |
| /** |
| * \brief USB request types (bmRequestType) |
| */ |
| #define USB_REQT_TYPE_STANDARD (0 << 5) /*!< Standard request */ |
| #define USB_REQT_TYPE_CLASS (1 << 5) /*!< Class-specific request */ |
| #define USB_REQT_TYPE_VENDOR (2 << 5) /*!< Vendor-specific request */ |
| #define USB_REQT_TYPE_MASK (3 << 5) /*!< Mask */ |
| |
| /** |
| * \brief USB recipient codes (bmRequestType) |
| */ |
| #define USB_REQT_RECIP_DEVICE (0 << 0) /*!< Recipient device */ |
| #define USB_REQT_RECIP_INTERFACE (1 << 0) /*!< Recipient interface */ |
| #define USB_REQT_RECIP_ENDPOINT (2 << 0) /*!< Recipient endpoint */ |
| #define USB_REQT_RECIP_OTHER (3 << 0) /*!< Recipient other */ |
| #define USB_REQT_RECIP_MASK (0x1F) /*!< Mask */ |
| |
| /** |
| * \brief Standard USB control transfer stages. |
| */ |
| enum usb_ctrl_stage { USB_SETUP_STAGE = 0, USB_DATA_STAGE = 1, USB_STATUS_STAGE = 2 }; |
| |
| /** |
| * \brief Standard USB requests (bRequest) |
| */ |
| enum usb_req_code { |
| USB_REQ_GET_STATUS = 0, |
| USB_REQ_CLEAR_FTR = 1, |
| USB_REQ_SET_FTR = 3, |
| USB_REQ_SET_ADDRESS = 5, |
| USB_REQ_GET_DESC = 6, |
| USB_REQ_SET_DESC = 7, |
| USB_REQ_GET_CONFIG = 8, |
| USB_REQ_SET_CONFIG = 9, |
| USB_REQ_GET_INTERFACE = 10, |
| USB_REQ_SET_INTERFACE = 11, |
| USB_REQ_SYNCH_FRAME = 12, |
| USB_REQ_SET_SEL = 48, |
| USB_REQ_ISOCH_DELAY = 49 |
| }; |
| |
| /** |
| * \brief Standard USB device status flags |
| * |
| */ |
| enum usb_dev_status { |
| USB_DEV_STAT_BUS_POWERED = 0, |
| USB_DEV_STAT_SELF_POWERED = 1, |
| USB_DEV_STAT_REMOTEWAKEUP = 2, |
| USB_DEV_STAT_U1_ENABLE = 4, |
| USB_DEV_STAT_U2_ENABLE = 8, |
| USB_DEV_STAT_LTM_ENABLE = 16 |
| }; |
| |
| /** |
| * \brief Standard USB Interface status flags |
| * |
| */ |
| enum usb_interface_status { |
| USB_IFACE_STAT_RESERVED = 0, |
| USB_IFACE_STAT_REMOTEWAKE_CAP = 1, |
| USB_IFACE_STAT_REMOTEWAKE = 2 |
| }; |
| |
| /** |
| * \brief Standard USB endpoint status flags |
| * |
| */ |
| enum usb_endpoint_status { USB_EP_STAT_HALT = 1 }; |
| |
| /** |
| * \brief Standard USB device feature flags |
| * |
| * \note valid for SetFeature request. |
| */ |
| enum usb_device_feature { |
| USB_DEV_FTR_REMOTE_WAKEUP = 1, /*!< Remote wakeup enabled */ |
| USB_DEV_FTR_TEST_MODE = 2, /*!< USB test mode */ |
| USB_DEV_FTR_OTG_B_HNP_ENABLE = 3, |
| USB_DEV_FTR_OTG_A_HNP_SP = 4, |
| USB_DEV_FTR_OTG_A_ALT_HNP_SP = 5, |
| USB_DEV_FTR_U1_ENABLE = 48, |
| USB_DEV_FTR_U2_ENABLE = 49, |
| USB_DEV_FTR_LTM_ENABLE = 50 |
| }; |
| |
| /** |
| * \brief Test Mode possible on HS USB device |
| * |
| * \note valid for USB_DEV_FTR_TEST_MODE request. |
| */ |
| enum usb_device_hs_test_mode { |
| USB_DEV_TEST_MODE_J = 1, |
| USB_DEV_TEST_MODE_K = 2, |
| USB_DEV_TEST_MODE_SE0_NAK = 3, |
| USB_DEV_TEST_MODE_PACKET = 4, |
| USB_DEV_TEST_MODE_FORCE_ENABLE = 5 |
| }; |
| |
| /** |
| * \brief Standard Feature Selectors for Interface |
| */ |
| enum usb_iface_feature { USB_IFACE_FTR_FUNC_SUSP = 0 }; |
| |
| /** |
| * \brief Standard USB endpoint feature/status flags |
| */ |
| enum usb_endpoint_feature { USB_EP_FTR_HALT = 0 }; |
| |
| /** |
| * \brief Standard USB Test Mode Selectors |
| */ |
| enum usb_test_mode_selector { |
| USB_TEST_J = 0x01, |
| USB_TEST_K = 0x02, |
| USB_TEST_SE0_NAK = 0x03, |
| USB_TEST_PACKET = 0x04, |
| USB_TEST_FORCE_ENABLE = 0x05 |
| }; |
| |
| /** |
| * \brief Standard USB descriptor types |
| */ |
| enum usb_descriptor_type { |
| USB_DT_DEVICE = 1, |
| USB_DT_CONFIG = 2, |
| USB_DT_STRING = 3, |
| USB_DT_INTERFACE = 4, |
| USB_DT_ENDPOINT = 5, |
| USB_DT_DEVICE_QUALIFIER = 6, |
| USB_DT_OTHER_SPEED_CONFIG = 7, |
| USB_DT_INTERFACE_POWER = 8, |
| USB_DT_OTG = 9, |
| USB_DT_DEBUG = 10, |
| USB_DT_IAD = 11, |
| USB_DT_BOS = 15, |
| USB_DT_DEV_CAP = 16, |
| USB_DT_SS_EP_COMPANION = 48 |
| }; |
| |
| /** |
| * \brief Capability types |
| */ |
| enum usb_capability_type { |
| USB_CAPT_WIRELESS = 1, |
| USB_CAPT_2_0_EXT = 2, |
| USB_CAPT_SUPER_SPEED = 3, |
| USB_CAPT_CONTAINER_ID = 4 |
| }; |
| |
| /** |
| * \brief USB 2.0 Extension attributes |
| */ |
| enum usb_2_0_ext_attr { USB_2_0_EXT_LPM_SP = 1 }; |
| |
| /** |
| * \brief USB SuperSpeed Capability attributes |
| */ |
| enum usb_ss_cap_attr { USB_SS_LTM_SP }; |
| |
| /** |
| * \brief USB Speed Supports |
| */ |
| enum usb_speed_sp { |
| USB_SPEED_LOW_SP = 1, |
| USB_SPEED_LS_SP = 1, |
| USB_SPEED_FULL_SP = 2, |
| USB_SPEED_FS_SP = 2, |
| USB_SPEED_HIGH_SP = 4, |
| USB_SPEED_HS_SP = 4, |
| USB_SPEED_SUPER_SP = 8, |
| USB_SPEED_SS_SP = 8 |
| }; |
| |
| /** |
| * \brief Standard USB endpoint transfer types |
| */ |
| enum usb_ep_type { |
| USB_EP_TYPE_CONTROL = 0x00, |
| USB_EP_TYPE_ISOCHRONOUS = 0x01, |
| USB_EP_TYPE_BULK = 0x02, |
| USB_EP_TYPE_INTERRUPT = 0x03, |
| USB_EP_TYPE_MASK = 0x03u |
| }; |
| |
| /** |
| * \brief USB endpoint interrupt types |
| */ |
| enum usb_ep_int_type { USB_EP_INT_T_PERIODIC = 0x00u, USB_EP_INT_T_NOTIFICATION = 0x01u, USB_EP_INT_T_MASK = 0x03u }; |
| |
| /** |
| * \brief Standard USB endpoint synchronization types |
| */ |
| enum usb_ep_sync_type { |
| USB_EP_SYNC_T_NO = 0x00u, |
| USB_EP_SYNC_T_ASYNC = 0x02u, |
| USB_EP_SYNC_T_ADAPTIVE = 0x02u, |
| USB_EP_SYNC_T_SYNC = 0x03u, |
| USB_EP_SYNC_T_MASK = 0x03u |
| }; |
| |
| /** |
| * \brief Standard USB endpoint usage types |
| */ |
| enum usb_ep_usage_type { |
| USB_EP_USAGE_T_DATA = 0x00u, |
| USB_EP_USAGE_T_FEEDBACK = 0x01u, |
| USB_EP_USAGE_T_FEEDBACK_DATA = 0x02u, |
| USB_EP_USAGE_T_MASK = 0x03u |
| }; |
| |
| /** |
| * \brief Standard USB language IDs for string descriptors |
| */ |
| enum usb_langid { |
| USB_LANGID_EN_US = 0x0409 /*!< English (United States) */ |
| }; |
| |
| /** |
| * \brief Mask selecting the index part of an endpoint address |
| */ |
| #define USB_EP_ADDR_MASK 0x0f |
| /** |
| * \brief Endpoint transfer direction is IN |
| */ |
| #define USB_EP_DIR_IN 0x80 |
| /** |
| * \brief Endpoint transfer direction is OUT |
| */ |
| #define USB_EP_DIR_OUT 0x00 |
| |
| /** |
| * \brief Maximum length in bytes of a USB descriptor |
| * |
| * The maximum length of a USB descriptor is limited by the 8-bit |
| * bLength field. |
| */ |
| #define USB_DESC_LEN_MAX 255 |
| |
| /* |
| * 2-byte alignment requested for all USB structures. |
| */ |
| COMPILER_PACK_SET(1) |
| |
| /** |
| * \brief A USB Device SETUP request |
| * |
| * The data payload of SETUP packets always follows this structure. |
| */ |
| typedef struct usb_req { |
| uint8_t bmRequestType; |
| uint8_t bRequest; |
| union { |
| le16_t wValue; |
| struct { |
| uint8_t l; |
| uint8_t h; |
| } wValueBytes; |
| }; |
| union { |
| le16_t wIndex; |
| struct { |
| uint8_t l; |
| uint8_t h; |
| } wIndexBytes; |
| }; |
| union { |
| le16_t wLength; |
| struct { |
| uint8_t l; |
| uint8_t h; |
| } wLengthBytes; |
| }; |
| } usb_req_t; |
| |
| /** |
| * \brief Standard USB device descriptor structure |
| */ |
| typedef struct usb_dev_desc { |
| uint8_t bLength; |
| uint8_t bDescriptorType; |
| le16_t bcdUSB; |
| uint8_t bDeviceClass; |
| uint8_t bDeviceSubClass; |
| uint8_t bDeviceProtocol; |
| uint8_t bMaxPacketSize0; |
| le16_t idVendor; |
| le16_t idProduct; |
| le16_t bcdDevice; |
| uint8_t iManufacturer; |
| uint8_t iProduct; |
| uint8_t iSerialNumber; |
| uint8_t bNumConfigurations; |
| } usb_dev_desc_t; |
| |
| /** |
| * \brief Binary device Object Store (BOS) descriptor structure |
| */ |
| typedef struct usb_bos_desc { |
| uint8_t bLength; |
| uint8_t bDescriptorType; |
| le16_t wTotalLength; |
| uint8_t bNumDeviceCaps; |
| } usb_bos_desc_t; |
| |
| /** |
| * \brief Device Capability Descriptor structure |
| */ |
| typedef struct usb_cap_desc { |
| uint8_t bLength; |
| uint8_t bDescriptorType; |
| uint8_t bDevCapabilityType; |
| uint8_t Vars[1]; |
| } usb_cap_desc_t; |
| |
| /** |
| * \brief USB 2.0 Extension Descriptor structure |
| */ |
| typedef struct usb_2_0_ext { |
| uint8_t bLength; |
| uint8_t bDescriptorType; |
| uint8_t bDevCapabilityType; |
| uint32_t bmAttributes; |
| } usb_2_0_ext_t; |
| |
| /** |
| * \brief LPM Device Capabilities descriptor structure |
| */ |
| typedef struct usb_2_0_ext usb_lpm_cap_desc_t; |
| |
| /** |
| * \brief SuperSpeed USB Device Capability structure |
| */ |
| typedef struct usb_ss_cap_desc { |
| uint8_t bLength; |
| uint8_t bDescriptorType; |
| uint8_t bDevCapabilityType; |
| uint8_t bmAttributes; |
| le16_t wSpeedsSupported; |
| uint8_t bFunctionalitySupport; |
| uint8_t bU1DevExitLat; |
| uint8_t bU2DevExitLat; |
| } usb_ss_cap_desc_t; |
| |
| /** |
| * \brief USB Container ID Descriptor structure |
| */ |
| typedef struct usb_container_id_desc { |
| uint8_t bLength; |
| uint8_t bDescriptorType; |
| uint8_t bDevCapabilityType; |
| uint8_t bReserved; |
| uint8_t ContainerID[16]; |
| } usb_container_id_desc_t; |
| |
| /** |
| * \brief Standard USB device qualifier descriptor structure |
| * |
| * This descriptor contains information about the device when running at |
| * the "other" speed (i.e. if the device is currently operating at high |
| * speed, this descriptor can be used to determine what would change if |
| * the device was operating at full speed.) |
| */ |
| typedef struct usb_dev_qual_desc { |
| uint8_t bLength; |
| uint8_t bDescriptorType; |
| le16_t bcdUSB; |
| uint8_t bDeviceClass; |
| uint8_t bDeviceSubClass; |
| uint8_t bDeviceProtocol; |
| uint8_t bMaxPacketSize0; |
| uint8_t bNumConfigurations; |
| uint8_t bReserved; |
| } usb_dev_qual_desc_t; |
| |
| /** |
| * \brief Standard USB configuration descriptor structure |
| */ |
| typedef struct usb_config_desc { |
| uint8_t bLength; |
| uint8_t bDescriptorType; |
| le16_t wTotalLength; |
| uint8_t bNumInterfaces; |
| uint8_t bConfigurationValue; |
| uint8_t iConfiguration; |
| uint8_t bmAttributes; |
| uint8_t bMaxPower; |
| } usb_config_desc_t; |
| |
| #define USB_CONFIG_ATTR_MUST_SET (1 << 7) /*!< Must always be set */ |
| #define USB_CONFIG_ATTR_BUS_POWERED (0 << 6) /*!< Bus-powered */ |
| #define USB_CONFIG_ATTR_SELF_POWERED (1 << 6) /*!< Self-powered */ |
| #define USB_CONFIG_ATTR_REMOTE_WAKEUP (1 << 5) /*!< remote wakeup supported */ |
| |
| #define USB_CONFIG_MAX_POWER(ma) (((ma) + 1) / 2) /*!< Max power in mA */ |
| |
| /** |
| * \brief Standard USB association descriptor structure |
| */ |
| typedef struct usb_iad_desc { |
| uint8_t bLength; /*!< Size of this descriptor in bytes */ |
| uint8_t bDescriptorType; /*!< Interface descriptor type */ |
| uint8_t bFirstInterface; /*!< Number of interface */ |
| uint8_t bInterfaceCount; /*!< value to select alternate setting */ |
| uint8_t bFunctionClass; /*!< Class code assigned by the USB */ |
| uint8_t bFunctionSubClass; /*!< Sub-class code assigned by the USB */ |
| uint8_t bFunctionProtocol; /*!< Protocol code assigned by the USB */ |
| uint8_t iFunction; /*!< Index of string descriptor */ |
| } usb_iad_desc_t; |
| |
| /** |
| * \brief Standard USB interface descriptor structure |
| */ |
| typedef struct usb_iface_desc { |
| uint8_t bLength; |
| uint8_t bDescriptorType; |
| uint8_t bInterfaceNumber; |
| uint8_t bAlternateSetting; |
| uint8_t bNumEndpoints; |
| uint8_t bInterfaceClass; |
| uint8_t bInterfaceSubClass; |
| uint8_t bInterfaceProtocol; |
| uint8_t iInterface; |
| } usb_iface_desc_t; |
| |
| /** |
| * \brief Standard USB endpoint descriptor structure |
| */ |
| typedef struct usb_ep_desc { |
| uint8_t bLength; |
| uint8_t bDescriptorType; |
| uint8_t bEndpointAddress; |
| uint8_t bmAttributes; |
| le16_t wMaxPacketSize; |
| uint8_t bInterval; |
| } usb_ep_desc_t; |
| |
| /** |
| * \brief SuperSpeed Endpoint Companion descriptor structure |
| */ |
| typedef struct usb_ss_ep_comp_desc { |
| uint8_t bLength; |
| uint8_t bDescriptorType; |
| uint8_t bMaxBurst; |
| uint8_t bmAttributes; |
| le16_t wBytesPerInterval; |
| } usb_ss_ep_comp_desc_t; |
| |
| /** |
| * \brief LPM Token bmAttributes structure |
| */ |
| typedef struct usb_lpm_attributes { |
| uint8_t bLinkState : 4; |
| uint8_t HIRD : 4; |
| uint8_t bRemoteWake : 1; |
| uint8_t Reserved : 2; |
| } usb_lpm_attributes_t; |
| |
| /** |
| * \brief A standard USB string descriptor structure |
| */ |
| typedef struct usb_str_desc { |
| uint8_t bLength; |
| uint8_t bDescriptorType; |
| } usb_str_desc_t; |
| |
| typedef struct usb_str_langid_desc { |
| usb_str_desc_t desc; |
| le16_t string[1]; |
| } usb_str_langid_desc_t; |
| |
| COMPILER_PACK_RESET() |
| |
| /** \name Macros to build USB standard descriptors */ |
| /*@{*/ |
| |
| /** Build bytes for USB device descriptor. */ |
| #define USB_DEV_DESC_BYTES(bcdUSB, \ |
| bDeviceClass, \ |
| bDeviceSubClass, \ |
| bDeviceProtocol, \ |
| bMaxPacketSize0, \ |
| idVendor, \ |
| idProduct, \ |
| bcdDevice, \ |
| iManufacturer, \ |
| iProduct, \ |
| iSerialNumber, \ |
| bNumConfigurations) \ |
| 18, /* bLength */ \ |
| 0x01, /* bDescriptorType: DEVICE */ \ |
| LE_BYTE0(bcdUSB), LE_BYTE1(bcdUSB), bDeviceClass, bDeviceSubClass, bDeviceProtocol, bMaxPacketSize0, \ |
| LE_BYTE0(idVendor), LE_BYTE1(idVendor), LE_BYTE0(idProduct), LE_BYTE1(idProduct), LE_BYTE0(bcdDevice), \ |
| LE_BYTE1(bcdDevice), iManufacturer, iProduct, iSerialNumber, bNumConfigurations |
| |
| #define USB_DEV_QUAL_DESC_BYTES( \ |
| bcdUSB, bDeviceClass, bDeviceSubClass, bDeviceProtocol, bMaxPacketSize0, bNumConfigurations) \ |
| 10, /* bLength */ \ |
| USB_DT_DEVICE_QUALIFIER, /* bDescriptorType: DEVICE_QUALIFIER */ \ |
| LE_BYTE0(bcdUSB), LE_BYTE1(bcdUSB), bDeviceClass, bDeviceSubClass, bDeviceProtocol, bMaxPacketSize0, \ |
| bNumConfigurations, 0 |
| |
| #define USB_DEV_DESC_LEN 18 |
| |
| /** Build bytes for USB configuration descriptor. */ |
| #define USB_CONFIG_DESC_BYTES( \ |
| wTotalLength, bNumInterfaces, bConfigurationValue, iConfiguration, bmAttributes, bMaxPower) \ |
| 9, /* bLength */ \ |
| 0x02, /* bDescriptorType: CONFIGURATION */ \ |
| LE_BYTE0(wTotalLength), LE_BYTE1(wTotalLength), bNumInterfaces, bConfigurationValue, iConfiguration, \ |
| bmAttributes, bMaxPower |
| |
| #define USB_OTH_SPD_CFG_DESC_BYTES( \ |
| wTotalLength, bNumInterfaces, bConfigurationValue, iConfiguration, bmAttributes, bMaxPower) \ |
| 9, /* bLength */ \ |
| USB_DT_OTHER_SPEED_CONFIG, /* bDescriptorType: OTH_SPD_CONFIGURATION */ \ |
| LE_BYTE0(wTotalLength), LE_BYTE1(wTotalLength), bNumInterfaces, bConfigurationValue, iConfiguration, \ |
| bmAttributes, bMaxPower |
| |
| #define USB_CONFIG_DESC_LEN 9 |
| |
| /** Build bytes for USB IAD descriptor. */ |
| #define USB_IAD_DESC_BYTES( \ |
| bFirstInterface, bInterfaceCount, bFunctionClass, bFunctionSubClass, bFunctionProtocol, iFunction) \ |
| 8, /* bLength */ \ |
| USB_DT_IAD, /* bDescriptorType */ \ |
| bFirstInterface, bInterfaceCount, bFunctionClass, bFunctionSubClass, bFunctionProtocol, iFunction |
| |
| #define USB_IAD_DESC_LEN 8 |
| |
| /** Build bytes for USB interface descriptor. */ |
| #define USB_IFACE_DESC_BYTES(bInterfaceNumber, \ |
| bAlternateSetting, \ |
| bNumEndpoints, \ |
| bInterfaceClass, \ |
| bInterfaceSubClass, \ |
| bInterfaceProtocol, \ |
| iInterface) \ |
| 9, /* bLength */ \ |
| 0x04, /* bDescriptorType: INTERFACE */ \ |
| bInterfaceNumber, bAlternateSetting, bNumEndpoints, bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol, \ |
| iInterface |
| |
| #define USB_IFACE_DESC_LEN 9 |
| |
| /** Build bytes for USB endpoint descriptor. */ |
| #define USB_ENDP_DESC_BYTES(bEndpointAddress, bmAttributes, wMaxPacketSize, bInterval) \ |
| 7, /* bLength */ \ |
| 0x05, /* bDescriptorType: ENDPOINT */ \ |
| bEndpointAddress, bmAttributes, LE_BYTE0(wMaxPacketSize), LE_BYTE1(wMaxPacketSize), bInterval |
| |
| #define USB_ENDP_DESC_LEN 7 |
| |
| /*@}*/ |
| |
| /** \brief Get a word (calculate by little endian 16-bit data) |
| * \param[in] ptr Byte pointer to the address to get data |
| * \return a 16-bit word |
| */ |
| static inline uint16_t usb_get_u16(const uint8_t *ptr) |
| { |
| return (ptr[0] + (ptr[1] << 8)); |
| } |
| |
| /** \brief Get a double word (calculate by little endian 32-bit data) |
| * \param[in] ptr Byte pointer to the address to get data |
| * \return a 32-bit word |
| */ |
| static inline uint32_t usb_get_u32(const uint8_t *ptr) |
| { |
| return (ptr[0] + (ptr[1] << 8) + (ptr[2] << 16) + (ptr[3] << 24)); |
| } |
| |
| /** \brief Get descriptor length |
| * \param[in] desc Byte pointer to the descriptor start address |
| * \return descriptor length |
| */ |
| static inline uint8_t usb_desc_len(const uint8_t *desc) |
| { |
| return desc[0]; |
| } |
| |
| /** \brief Get descriptor type |
| * \param[in] desc Byte pointer to the descriptor start address |
| * \return descriptor type |
| */ |
| static inline uint8_t usb_desc_type(const uint8_t *desc) |
| { |
| return desc[1]; |
| } |
| |
| /** \brief Get next USB descriptor |
| * \param[in] desc Byte pointer to the descriptor start address |
| * \return Byte pointer to the next descriptor |
| */ |
| static inline uint8_t *usb_desc_next(uint8_t *desc) |
| { |
| return (desc + usb_desc_len(desc)); |
| } |
| |
| /** \brief Get idVendor of USB Device Descriptor |
| * \param[in] dev_desc Byte pointer to the descriptor start address |
| * \return 16-bit idVendor value |
| */ |
| static inline uint16_t usb_dev_desc_vid(const uint8_t *dev_desc) |
| { |
| return usb_get_u16(dev_desc + 8); |
| } |
| |
| /** \brief Get idProduct of USB Device Descriptor |
| * \param[in] dev_desc Byte pointer to the descriptor start address |
| * \return 16-bit idProduct value |
| */ |
| static inline uint16_t usb_dev_desc_pid(const uint8_t *dev_desc) |
| { |
| return usb_get_u16(dev_desc + 10); |
| } |
| |
| /** \brief Get wTotalLength of USB Configuration Descriptor |
| * \param[in] cfg_desc Byte pointer to the descriptor start address |
| * \return 16-bit total length of configuration list |
| */ |
| static inline uint16_t usb_cfg_desc_total_len(const uint8_t *cfg_desc) |
| { |
| return usb_get_u16(cfg_desc + 2); |
| } |
| |
| /** \brief Get Next USB Descriptor After the Configuration Descriptors list |
| * \param[in] cfg_desc Byte pointer to the descriptor start address |
| * \return Byte pointer to descriptor after configuration end |
| */ |
| static inline uint8_t *usb_cfg_desc_next(uint8_t *cfg_desc) |
| { |
| return (cfg_desc + usb_cfg_desc_total_len(cfg_desc)); |
| } |
| |
| /** \brief Find specific USB Descriptor by its type |
| * \param[in] desc Byte pointer to the descriptor start address |
| * \param[in] eof Byte pointer to the descriptor end address |
| * \param[in] type The descriptor type expected |
| * \return Pointer to the descriptor |
| * \retval NULL if not found |
| */ |
| uint8_t *usb_find_desc(uint8_t *desc, uint8_t *eof, uint8_t type); |
| |
| /** Get interface descriptor next to the specified one (by interface number) |
| * \param[in] desc Byte pointer to the descriptor start address |
| * \param[in] eof Byte pointer to the descriptor end address |
| * \param[in] iface_n The interface number to check |
| * \return Pointer to the descriptor |
| * \retval >= eof if not found |
| */ |
| uint8_t *usb_find_iface_after(uint8_t *desc, uint8_t *eof, uint8_t iface_n); |
| |
| /** Find endpoint descriptor, breaks if interface descriptor detected |
| * \param[in] desc Byte pointer to the descriptor start address |
| * \param[in] eof Byte pointer to the descriptor end address |
| * \return Pointer to the descriptor |
| * \retval NULL if not found |
| */ |
| uint8_t *usb_find_ep_desc(uint8_t *desc, uint8_t *eof); |
| |
| /** Find configuration descriptor by its configuration number |
| * \param[in] desc Byte pointer to the descriptor start address |
| * \param[in] eof Byte pointer to the descriptor end address |
| * \param[in] cfg_value The configure value expected |
| * \return Pointer to the descriptor |
| * \retval NULL if not found |
| */ |
| uint8_t *usb_find_cfg_desc(uint8_t *desc, uint8_t *eof, uint8_t cfg_value); |
| |
| /** Find other speed configuration descriptor by its configuration number |
| * \param[in] desc Byte pointer to the descriptor start address |
| * \param[in] eof Byte pointer to the descriptor end address |
| * \param[in] cfg_value The configure value expected |
| * \return Pointer to the descriptor |
| * \retval NULL if not found |
| */ |
| uint8_t *usb_find_othspdcfg_desc(uint8_t *desc, uint8_t *eof, uint8_t cfg_value); |
| |
| /** Find string descriptor by its index |
| * \param[in] desc Byte pointer to the descriptor start address |
| * \param[in] eof Byte pointer to the descriptor end address |
| * \param[in] str_index The string index expected |
| * \return Pointer to the descriptor |
| * \retval NULL if not found |
| */ |
| uint8_t *usb_find_str_desc(uint8_t *desc, uint8_t *eof, uint8_t str_index); |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| /*! @} */ |
| |
| #endif /* _USB_PROTOCOL_H_ */ |