app_usbd_descriptor.h 15.8 KB
Newer Older
X
xieyangrun 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
/**
 * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
 * 
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form, except as embedded into a Nordic
 *    Semiconductor ASA integrated circuit in a product or a software update for
 *    such product, must reproduce the above copyright notice, this list of
 *    conditions and the following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 * 
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 * 
 * 4. This software, with or without modification, must only be used with a
 *    Nordic Semiconductor ASA integrated circuit.
 * 
 * 5. Any software provided in binary form under this license must not be reverse
 *    engineered, decompiled, modified and/or disassembled.
 * 
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 */

#ifndef APP_USBD_DESCRIPTOR_H__
#define APP_USBD_DESCRIPTOR_H__

#ifdef __cplusplus
extern "C" {
#endif

#include "nrf.h"
#include "nrf_drv_usbd.h"
#include "app_usbd_langid.h"
#include "app_util_platform.h"

/* Compiler support for anonymous unions */
ANON_UNIONS_ENABLE

/**
 * @defgroup app_usbd_descriptor USB standard descriptors
 * @ingroup app_usbd
 *
 * @brief @tagAPI52840 Module with types definitions used for standard descriptors.
 * @{
 */

/**
 * @brief Helper macro for translating unsigned 24 bit value to 2 byte raw descriptor
 * */
#define APP_USBD_U16_TO_RAW_DSC(val) (uint8_t)(val),                    \
                                     (uint8_t)(((val) / (256)))

/**
 * @brief Helper macro for translating unsigned 24 bit value to 3 byte raw descriptor
 * */
#define APP_USBD_U24_TO_RAW_DSC(val) (uint8_t)(val),                    \
                                     (uint8_t)(((val) / (256))),        \
                                     (uint8_t)(((val) / (256 * 256)))

/**
 * @brief Helper macro for translating unsigned 32 bit value to 4 byte raw descriptor
 * */
#define APP_USBD_U32_TO_RAW_DSC(val) (uint8_t)(val),                    \
                                     (uint8_t)(((val) / (256))),        \
                                     (uint8_t)(((val) / (256 * 256)))   \
                                     (uint8_t)(((val) / (256 * 256 * 256)))
/**
 * @brief Descriptor types
 *
 * Descriptor types used in two situations:
 * - when processing @ref APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR SETUP request,
 *   the required descriptor type may be placed in wValue in HighByte.
 * - As a descriptor identifier itself inside descriptor stream.
 *
 * According to chapter 9.6 of USB 2.0 specification, following descriptors may
 * be requested directly by GetDescriptor method:
 * - @ref APP_USBD_DESCRIPTOR_DEVICE
 * - @ref APP_USBD_DESCRIPTOR_DEVICE_QUALIFIER (not used for FullSpeed only device)
 * - @ref APP_USBD_DESCRIPTOR_CONFIGURATION
 * - @ref APP_USBD_DESCRIPTOR_STRING
 */
typedef enum
{
    APP_USBD_DESCRIPTOR_DEVICE                    =  1, /**< Device descriptor. */
    APP_USBD_DESCRIPTOR_CONFIGURATION             =  2, /**<
                                                         * Specific configuration descriptor.
                                                         * Configuration descriptor is always followed by all the related interface
                                                         * and endpoints descriptors.
                                                         */
    APP_USBD_DESCRIPTOR_STRING                    =  3, /**< String descriptor. */
    APP_USBD_DESCRIPTOR_INTERFACE                 =  4, /**<
                                                         * Interface descriptor followed by all the related endpoints descriptors.
                                                         *
                                                         * @note It is returned together with @ref APP_USBD_DESCRIPTOR_CONFIGURATION.
                                                         *       Cannot be accessed by GetDescriptor or SetDescriptor
                                                         */
    APP_USBD_DESCRIPTOR_ENDPOINT                  =  5, /**<
                                                         * Endpoint descriptor.
                                                         *
                                                         * @note It is returned together with @ref APP_USBD_DESCRIPTOR_CONFIGURATION.
                                                         *       Cannot be accessed by GetDescriptor or SetDescriptor
                                                         */
    APP_USBD_DESCRIPTOR_DEVICE_QUALIFIER          =  6, /**< @note Not supported - used only in HighSpeed capable devices. */
    APP_USBD_DESCRIPTOR_OTHER_SPEED_CONFIGURATION =  7, /**< @note Not supported - our USB implementation supports only one speed. */
    APP_USBD_DESCRIPTOR_INTERFACE_POWER           =  8, /**< @note Not supported */
    APP_USBD_DESCRIPTOR_OTG                       =  9, /**< @note Not supported - Our USB have not OTG functionality */
    APP_USBD_DESCRIPTOR_DEBUG                     = 10, /**< Debug channel descriptor if available, can be only reached by GetDescriptor */
    APP_USBD_DESCRIPTOR_INTERFACE_ASSOCIATION     = 11  /**<
                                                         * Descriptor used to describe that two or more interfaces are associated to the same function.
                                                         *
                                                         * @note It is returned together with @ref APP_USBD_DESCRIPTOR_CONFIGURATION.
                                                         *       Cannot be accessed by GetDescriptor or SetDescriptor
                                                         */

} app_usbd_descriptor_t;

/* Make all descriptors packed */
#pragma pack(push, 1)

/**
 * @brief Common descriptor header
 *
 * The header that we can find on the beginning of all descriptors that contains
 * the descriptor length and type.
 */
typedef struct
{
    uint8_t  bLength;         //!< Size of the descriptor in bytes.
    uint8_t  bDescriptorType; //!< Should equal one of @ref app_usbd_descriptor_t.
                              /**  Class specific descriptors values are defined inside classes. */
} app_usbd_descriptor_header_t;

/**
 * @brief Device descriptor
 *
 * Descriptor used for the whole device
 */
typedef struct
{
    uint8_t  bLength;            //!< Size of the descriptor in bytes.
    uint8_t  bDescriptorType;    //!< Should equal to @ref APP_USBD_DESCRIPTOR_DEVICE.
    uint16_t bcdUSB;             //!< USB Specification Release Number in Binary-Coded Decimal
    uint8_t  bDeviceClass;       //!< Device class code.
                                 /**< If 0, each interface specifies its own class information.
                                  *   0xFF for vendor-specific.
                                  */
    uint8_t  bDeviceSubClass;    //!< Subclass code.
                                 /**< If bDevice Class is set to value other than 0xFF,
                                  *   all values here are reserved for assignment by USB-IF.
                                  */
    uint8_t  bDeviceProtocol;    //!< Subclass code.
                                 /**< If 0, no specific protocol is defined on device basis.
                                  *   Each interface may define its own protocol then.
                                  *   If set to 0xFF, vendor-specific protocol is used.
                                  */
    uint8_t  bMaxPacketSize0;    //!< Maximum packet size for endpoint zero.
    uint16_t idVendor;           //!< Vendor ID (Assigned by the USB-IF).
    uint16_t idProduct;          //!< Product ID (assigned by manufacturer).
    uint16_t bcdDevice;          //!< Device release number in binary-coded decimal.
    uint8_t  iManufacturer;      //!< Index of string descriptor in describing manufacturer.
    uint8_t  iProduct;           //!< Index of string descriptor in describing product.
    uint8_t  iSerialNumber;      //!< Index of string descriptor in describing the device's serial number.
    uint8_t  bNumConfigurations; //!< Number of possible configurations.
} app_usbd_descriptor_device_t;

/**
 * @brief Attributes masks
 *
 * Masks used for attributes in configuration.
 */
typedef enum
{
    /** This is reserved descriptor that has always to be set */
    APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_ALWAYS_SET_MASK    = 1U << 7,
    /** Attribute that informs that device is self powered */
    APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_SELF_POWERED_MASK  = 1U << 6,
    /** Attribute that informs that device has Remove Wakeup functionality */
    APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_REMOTE_WAKEUP_MASK = 1U << 5
} app_usbd_descriptor_configuration_attributes_t;

/**
 * @brief Configuration descriptor
 *
 * Descriptor used at the beginning of configuration response.
 */
typedef struct
{
    uint8_t  bLength;             //!< Size of the descriptor in bytes.
    uint8_t  bDescriptorType;     //!< Should equal to @ref APP_USBD_DESCRIPTOR_DEVICE.
    uint16_t wTotalLength;        //!< Total length of configuration data, including all descriptors returned after configuration itself.
    uint8_t  bNumInterfaces;      //!< Number of interfaces supportedf by this configuration
    uint8_t  bConfigurationValue; //!< Value to use as an argument to the SetConfiguration request.
    uint8_t  iConfiguration;      //!< Index of string descriptor describing this configuration.
    uint8_t  bmAttributes;        //!< Configuration characteristics.
    uint8_t  bMaxPower;           //!< Maximum power consumption. Expressed in 2&nbsp;mA units.
} app_usbd_descriptor_configuration_t;

/**
 * @brief Raw descriptor - String descriptor zero
 *
 * String descriptor sent only as a response for GetDescriptor.
 */
typedef struct
{
    uint8_t  bLength;         //!< Size of the descriptor in bytes.
    uint8_t  bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_STRING.
    uint16_t wLANGID[];       //!< The array of LANGID codes supported by the device.
} app_usbd_descriptor_string0_t;

/**
 * @brief Raw descriptor - Any normal string
 *
 * String descriptor sent only as a response for GetDescriptor.
 */
typedef struct
{
    uint8_t  bLength;         //!< Size of the descriptor in bytes.
    uint8_t  bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_STRING.
    uint16_t bString[];       //!< UNICODE encoded string.
} app_usbd_descriptor_string_t;


/**
 * @brief Interface descriptor
 *
 * Interface descriptor, returned as a part of configuration descriptor.
 */
typedef struct
{
    uint8_t bLength;            //!< Size of the descriptor in bytes.
    uint8_t bDescriptorType;    //!< Should equal to @ref APP_USBD_DESCRIPTOR_INTERFACE.
    uint8_t bInterfaceNumber;   //!< Number of this interface.
    uint8_t bAlternateSetting;  //!< Value used to select this alternate setting.
    uint8_t bNumEndpoints;      //!< Number of endpoints used by this interface.
    uint8_t bInterfaceClass;    //!< Class code (assigned by the USB-IF). 0xff for vendor specific.
    uint8_t bInterfaceSubClass; //!< Subclass code (assigned by the USB-IF).
    uint8_t bInterfaceProtocol; //!< Protocol code (assigned by the USB-IF). 0xff for vendor specific.
    uint8_t iInterface;         //!< Index of string descriptor describing this interface.
} app_usbd_descriptor_iface_t;

/** Offset of endpoint type attribute bits */
#define APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET 0
/** Mask of endpoint type attribute bits */
#define APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_MASK   BF_MASK(2, APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET)

/** Offset of endpoint synchronization type attribute bits */
#define APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET 2
/** Mask of endpoint synchronization type attribute bits */
#define APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_MASK   BF_MASK(2, APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET)

/** Offset of endpoint usage type attribute bits */
#define APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET 4
/** Mask of endpoint usage type attribute bits */
#define APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_MASK   BF_MASK(2, APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET)

/**
 * @brief Endpoint attributes mnemonics
 *
 * @sa APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_MASK
 * @sa APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_MASK
 * @sa APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_MASK
 */
typedef enum
{
    APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_CONTROL      = 0 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET,
    APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_ISOCHRONOUS  = 1 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET,
    APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK         = 2 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET,
    APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT    = 3 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET,

    APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_NONE         = 0 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET,
    APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_ASYNCHRONOUS = 1 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET,
    APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_ADAPTIVE     = 2 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET,
    APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_SYNCHRONOUS  = 3 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET,

    APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_DATA        = 0 << APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET,
    APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_FEEDBACK    = 1 << APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET,
    APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_IMPLICIT    = 2 << APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET
} app_usbd_descriptor_ep_attr_bitmap_t;

/**
 * @brief Endpoint descriptor
 *
 * Endpoint descriptor, returned as a part of configuration descriptor.
 */
typedef struct
{
    uint8_t  bLength;          //!< Size of the descriptor in bytes.
    uint8_t  bDescriptorType;  //!< Should equal to @ref APP_USBD_DESCRIPTOR_ENDPOINT.
    uint8_t  bEndpointAddress; //!< Endpoint address
    uint8_t  bmAttributes;     //!< Endpoint attributes
    uint16_t wMaxPacketSize;   //!< Maximum packet size this endpoint is capable of handling.
    uint8_t  bInterval;        //!< Interval for pooling endpoint for data transfers.
} app_usbd_descriptor_ep_t;

/**
 * @brief Interface association descriptor
 */
typedef struct
{
    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
} app_usbd_descriptor_iad_t;

#pragma pack(pop)
ANON_UNIONS_DISABLE

#ifdef __cplusplus
}
#endif

/** @} */
#endif /* APP_USBD_DESCRIPTOR_H__ */