/****************************************************************************//**
 * @file     descriptors.c
 * @version  V0.10
 * @brief    NuMicro series USBD descriptor file
 *
 * SPDX-License-Identifier: Apache-2.0
 * @copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
 ******************************************************************************/
/*!<Includes */
#include "NuMicro.h"
#include "usbd_audio.h"

/*
  *Speaker - Interface alternate 1
  +-----------+------------+----------------+------------------+
  | Alternate | Channel(s) | Bit Resolution | Sampling Rate(s) |
  +-----------+------------+----------------+------------------+
  |     1     |      2     |     16 bits    |   32kHz, 48kHz   |
  +-----------+------------+----------------+------------------+

  Note:
  1.If you want to add / remove sampling rate to certain alternate for Speaker interface,
    please modify Audio Streaming Format Type Descriptor (bLength, bSamFreqType, tSamFreq fields)
    and the Total Length field of Configuration Descriptor.
    For example,
      Add 48kHz to Speaker Interface alternate 1 (16 bit resolution) from Speaker descriptor with HID

      1.Modify Audio Streaming Format Type Descriptor for Speaker Interface alternate 1

         Audio Streaming Format Type Descriptor
         +--------------------+-------------------------------+-------------------------------+
         | *bLength           |        Original Value         |         Modified Value        |
         +--------------------+-------------------------------+-------------------------------+
         | bLength            |              0x0E             |         0x11(+3 Bytes)        |
         +--------------------+-------------------------------+-------------------------------+
         | bDescriptorType    |              0x24             |              0x24             |
         +--------------------+-------------------------------+-------------------------------+
         | bDescriptorSubType |              0x02             |              0x02             |
         +--------------------+-------------------------------+-------------------------------+
         | bFormatType        |              0x01             |              0x01             |
         +--------------------+-------------------------------+-------------------------------+
         | bNrChannels        |              0x02             |              0x02             |
         +--------------------+-------------------------------+-------------------------------+
         | bSubFrameSize      |              0x02             |              0x02             |
         +--------------------+-------------------------------+-------------------------------+
         | bBitResolution     |              0x10             |              0x10             |
         +--------------------+-------------------------------+-------------------------------+
         | *bSamFreqType      |              0x02             |       0x03(+1 Frequency)      |
         +--------------------+-------------------------------+-------------------------------+
         | *tSamFreq          |  AUDIO_RATE_48K & 0xFF        |  AUDIO_RATE_48K & 0xFF        |
         |                    | (AUDIO_RATE_48K >>  8) & 0xFF | (AUDIO_RATE_48K >>  8) & 0xFF | 
         |                    | (AUDIO_RATE_48K >> 16) & 0xFF | (AUDIO_RATE_48K >> 16) & 0xFF |
         |                    |  AUDIO_RATE_32K & 0xFF        |  AUDIO_RATE_32K & 0xFF        |
         |                    | (AUDIO_RATE_32K >>  8) & 0xFF | (AUDIO_RATE_32K >>  8) & 0xFF | 
         |                    | (AUDIO_RATE_32K >> 16) & 0xFF | (AUDIO_RATE_32K >> 16) & 0xFF |
         |                    |                               |  AUDIO_RATE_16K & 0xFF        |
         |                    |                               | (AUDIO_RATE_16K >>  8) & 0xFF | 
         |                    |                               | (AUDIO_RATE_16K >> 16) & 0xFF |
         +--------------------+-------------------------------+-------------------------------+


      2.Modify the Total Length field of Configuration Descriptor

         0x8A (Original Total Length) + 0x03(The increase Length of Audio Streaming Format Type Descriptor) = 0x8D

  2.If you want to change the support function of audio control, please modify the bmaControls field of
    Audio Control Feature Unit Descriptor for Speaker
      A bit set to 1 indicates that the mentioned Control is supported
         0:
         D0: Mute
         D1: Volume
         D2: Bass
         D3: Mid
         D4: Treble
         D5: Graphic Equalizer
         D6: Automatic Gain
         D7: Delay
         D8: Bass Boost
         D9: Loudness
         D10..(n*8-1): Reserved
  3.If you want to change the polling interal of HID Endpoint, please modify the bInterval field of Endpoint Descriptor for HID.
*/

/*----------------------------------------------------------------------------*/
/*!<USB Device Descriptor */
uint8_t gu8DeviceDescriptor[] =
{
    LEN_DEVICE,         /* bLength */
    DESC_DEVICE,        /* bDescriptorType */
#ifdef SUPPORT_LPM
    0x01, 0x02,         /* bcdUSB => 0x0201 to support LPM */
#else
    0x10, 0x01,         /* bcdUSB */
#endif
    0x00,               /* bDeviceClass */
    0x00,               /* bDeviceSubClass */
    0x00,               /* bDeviceProtocol */
    EP0_MAX_PKT_SIZE,   /* bMaxPacketSize0 */
    /* idVendor */
    USBD_VID & 0x00FF,
    (USBD_VID & 0xFF00) >> 8,
    /* idProduct */
    USBD_PID & 0x00FF,
    (USBD_PID & 0xFF00) >> 8,
    0x00, 0x01,         /* bcdDevice */
    0x01,               /* iManufacture */
    0x02,               /* iProduct */
    0x03,               /* iSerialNumber - no serial */
    0x01                /* bNumConfigurations */
};

#ifdef __HID__
#ifdef __JOYSTICK__
uint8_t HID_DeviceReportDescriptor[] =
{
    0x05, 0x01,        /* Usage Page(Generic Desktop Controls) */
    0x09, 0x04,        /* Usage(Joystick) */
    0xA1, 0x01,        /* Collection(Application)  */
    0xA1, 0x02,        /* Collection(Logical)  */
    0x75, 0x08,        /* Report Size(0x8) */
    0x95, 0x05,        /* Report Count(0x5) */
    0x15, 0x00,        /* Logical Minimum(0x0) */
    0x26, 0xFF, 0x00,  /* Logical Maximum(0xFF) */
    0x35, 0x00,        /* Physical Minimum(0x0) */
    0x46, 0xFF, 0x00,  /* Physical Maximum(0xFF) */
    0x09, 0x30,        /* Usage(X) */
    0x09, 0x31,        /* Usage(Y) */
    0x09, 0x32,        /* Usage(Z) */
    0x09, 0x32,        /* Usage(Z) */
    0x09, 0x35,        /* Usage(Rz) */
    0x81, 0x02,        /* Input(Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Bit Field) */
    0x75, 0x04,        /* Report Size(0x4) */
    0x95, 0x01,        /* Report Count(0x1) */
    0x25, 0x07,        /* Logical Maximum(0x7) */
    0x46, 0x3B, 0x01,  /* Physical Maximum(0x13B) */
    0x65, 0x14,        /* Unit(0x14) */
    0x09, 0x39,        /* Usage(Hat switch) */
    0x81, 0x42,        /* Input(Data, Variable, Absolute, No Wrap, Linear, Preferred State, Null State, Bit Field) */
    0x65, 0x00,        /* Unit(0x0) */
    0x75, 0x01,        /* Report Size(0x1) */
    0x95, 0x0C,        /* Report Count(0xC) */  
    0x25, 0x01,        /* Logical Maximum(0x1) */
    0x45, 0x01,        /* Physical Maximum(0x1) */
    0x05, 0x09,        /* Usage Page(Button) */
    0x19, 0x01,        /* Usage Minimum(0x1) */
    0x29, 0x0C,        /* Usage Maximum(0xC) */
    0x81, 0x02,        /* Input(Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Bit Field) */  
    0x06, 0x00, 0xFF,  /* Usage Page(Undefined) */
    0x75, 0x01,        /* Report Size(0x1) */
    0x95, 0x08,        /* Report Count(0x8) */
    0x25, 0x01,        /* Logical Maximum(0x1) */
    0x45, 0x01,        /* Physical Maximum(0x1) */
    0x09, 0x01,        /* Usage(1) */
    0x81, 0x02,        /* Input(Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Bit Field) */
    0xC0,              /* End Collection */
    0xC0,              /* End Collection */
};

#elif defined __MEDIAKEY__
uint8_t HID_DeviceReportDescriptor[] =
{
    0x05, 0x0C,        /* Usage Page (Consumer) */
    0x09, 0x01,        /* Usage(Consumer Control) */
    0xA1, 0x01,        /* Collection(Application) */
    0x15, 0x00,        /* Logical Minimum(0x0) */
    0x25, 0x01,        /* Logical Maximum(0x1) */
    0x09, 0xE2,        /* Usage(Mute) */
    0x09, 0xE9,        /* Usage(Volume Increment) */
    0x09, 0xEA,        /* Usage(Volume Decrement) */
    0x75, 0x01,        /* Report Size(0x1) */
    0x95, 0x03,        /* Report Count(0x3) */
    0x81, 0x02,        /* Input(Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Bit Field) */
    0x75, 0x01,        /* Report Size(0x1) */
    0x95, 0x05,        /* Report Count(0x5) */
    0x81, 0x03,        /* Input(Constant, Variable, Absolute) */
    0x09, 0xB0,        /* Usage(Play) */
    0x09, 0xB7,        /* Usage(Stop) */
    0x09, 0xCD,        /* Usage(Play/Pause) */
    0x09, 0xB5,        /* Usage(Scan Next Track) */
    0x09, 0xB6,        /* Usage(Scan Previous Track) */
    0x09, 0xB2,        /* Usage(Record) */
    0x09, 0xB4,        /* Usage(Rewind) */
    0x09, 0xB3,        /* Usage(Fast Forward) */
    0x75, 0x01,        /* Report Size(0x1) */
    0x95, 0x08,        /* Report Count(0x8) */
    0x81, 0x02,        /* Input(Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Bit Field) */
    0x09, 0x00,        /* Usage(Undefined) */
    0x75, 0x08,        /* Report Size(0x8) */
    0x95, 0x06,        /* Report Count(0x6) */
    0x81, 0x02,        /* Input(Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Bit Field) */
    0x09, 0x00,        /* Usage(Undefined) */
    0x75, 0x08,        /* Report Size(0x8) */
    0x95, 0x08,        /* Report Count(0x8) */
    0x91, 0x00,        /* Output(Data, Array, Absolute, No Wrap, Linear, Preferred State, No Null Position, Non VolatileBit Field) */
    0xC0
};
#endif

#define HID_REPORT_DESC_SIZE \
    sizeof(HID_DeviceReportDescriptor) / sizeof(HID_DeviceReportDescriptor[0])
#define HID_REPORT_DESCRIPTOR_SIZE   HID_REPORT_DESC_SIZE
#endif

/*!<USB Configure Descriptor */
uint8_t gu8ConfigDescriptor[] =
{
    /* Configuration Descriptor */
    LEN_CONFIG,         /* bLength */
    DESC_CONFIG,        /* bDescriptorType */
#ifdef __HID__
#ifdef __FEEDBACK__
    0x93, 0x00,         /* wTotalLength */
#else
    0x8A, 0x00,         /* wTotalLength */
#endif
                        /*
                           Descriptor (Feedback) without HID           (0x7A)
                           Descriptor without HID                      (0x71)
                           HID Descriptor
                             Interface Descriptor                      (0x09)
                             HID Descriptor                            (0x09)
                             Endpoint Descriptor                       (0x07)

                           0x7A + (0x09 + 0x09 + 0x07) = 0x93 (with Feedback Endpoint)
                           0x71 + (0x09 + 0x09 + 0x07) = 0x8A
                        */
    0x03,               /* bNumInterfaces - Interface 0, Interface 1 (Speaker), Interface 2 (HID) */
#else
#ifdef __FEEDBACK__
    0x7A, 0x00,         /* wTotalLength */
#else
    0x71, 0x00,         /* wTotalLength */
#endif
    /*
       Configuration Descriptor                    (0x09)
       Interface Descriptor (Audio Class)          (0x09)
       Audio Control Interface Header Descriptor   (0x09)
       Speaker - Audio Control
         Audio Control Input Terminal Descriptor   (0x0C)
         Audio Control Feature Unit Descriptor     (0x0A)
         Audio Control Output Terminal Descriptor  (0x09)
       Speaker - Interface alternate 0
         Standard AS interface                     (0x09)
       Speaker - Interface alternate 1
         Standard AS interface                                         (0x09)
         Audio Streaming Class Specific Interface Descriptor           (0x07)
         Audio Streaming Format Type Descriptor                        (0x0E)*
         Endpoint Descriptor                                           (0x09)
         Audio Streaming Class Specific Audio Data Endpoint Descriptor (0x07)
         Feedback Endpoint Descriptor                                  (0x09)
         *Each Interface alternate Summary with Feedback Endpoint      (0x37)
         *Each Interface alternate Summary                             (0x2E)

       0x09 + 0x09 + 0x09 + (0x0C + 0x0A + 0x09) +
       0x09 + 0x37 = 0x7A  (with Feedback Endpoint)

       0x09 + 0x09 + 0x09 + (0x0C + 0x0A + 0x09) +
       0x09 + 0x2E = 0x71

    */
    0x02,               /* bNumInterfaces - Interface 0, Interface 1 (Speaker) */
#endif
    0x01,               /* bConfigurationValue */
    0x00,               /* iConfiguration */
    0x80,               /* bmAttributes */
    0x20,               /* Max power */

    /* Interface Descriptor (Audio Class) */
    0x09,               /* bLength */
    0x04,               /* bDescriptorType */
    0x00,               /* bInterfaceNumber */
    0x00,               /* bAlternateSetting */
    0x00,               /* bNumEndpoints */
    0x01,               /* bInterfaceClass:AUDIO */
    0x01,               /* bInterfaceSubClass:AUDIOCONTROL */
    0x00,               /* bInterfaceProtocol */
    0x00,               /* iInterface */

    /* Audio Control Interface Header Descriptor */
    0x09,               /* bLength */
    0x24,               /* bDescriptorType:CS_INTERFACE */
    0x01,               /* bDescriptorSubType:HEADER */
    0x00, 0x01,         /* bcdADC:1.0 */
    0x28, 0x00,         /* wTotalLength
                           Audio Control Interface Header Descriptor   (0x09)
                           Speaker - Audio Control
                             Audio Control Input Terminal Descriptor   (0x0C)
                             Audio Control Feature Unit Descriptor     (0x0A)
                             Audio Control Output Terminal Descriptor  (0x09)

                             0x09 + (0x0C + 0x0A + 0x09) = 0x28
                        */
    0x01,               /* bInCollection */
    0x01,               /* baInterfaceNr(1) - Speaker */

    /* Audio Control Input Terminal Descriptor - Speaker (Terminal ID 1) */
    0x0C,               /* bLength */
    0x24,               /* bDescriptorType:CS_INTERFACE */
    0x02,               /* bDescriptorSubType:INPUT_TERMINAL */
    0x01,               /* bTerminalID */
    0x01, 0x01,         /* wTerminalType: USB streaming */
    0x00,               /* bAssocTerminal */
    PLAY_CHANNELS,      /* bNrChannels : a number that specifies how many logical audio channels are present in the cluster */
    PLAY_CH_CFG, 0x00,  /* wChannelConfig: a bit field that indicates which spatial locations are present in the cluster.
                           The bit allocations are as follows:
                             D0: Left Front (L)
                             D1: Right Front (R)
                             D2: Center Front (C)
                             D3: Low Frequency Enhancement (LFE)
                             D4: Left Surround (LS)
                             D5: Right Surround (RS)
                             D6: Left of Center (LC)
                             D7: Right of Center (RC)
                             D8: Surround (S)
                             D9: Side Left (SL)
                             D10: Side Right (SR)
                             D11: Top (T)
                             D15..12: Reserved
                        */
    0x00,               /* iChannelNames */
    0x00,               /* iTerminal */

    /* Audio Control Feature Unit Descriptor - Speaker (UNIT ID 6 - Source ID 1) */
    0x0A,               /* bLength */
    0x24,               /* bDescriptorType */
    0x06,               /* bDescriptorSubType */
    PLAY_FEATURE_UNITID,/* bUnitID */
    0x01,               /* bSourceID */
    0x01,               /* bControlSize - Size, in bytes, of the bmControls field: n */
    0x01,               /* bmaControls(0) */
    /* A bit set to 1 indicates that the mentioned
       Control is supported for master channel
       0:
       D0: Mute
       D1: Volume
       D2: Bass
       D3: Mid
       D4: Treble
       D5: Graphic Equalizer
       D6: Automatic Gain
       D7: Delay
       D8: Bass Boost
       D9: Loudness
       D10..(n*8-1): Reserved
    */
    0x02,               /* bmaControls(1) - Left */
    /* A bit set to 1 indicates that the mentioned
       Control is supported for master channel
       0:
       D0: Mute
       D1: Volume
       D2: Bass
       D3: Mid
       D4: Treble
       D5: Graphic Equalizer
       D6: Automatic Gain
       D7: Delay
       D8: Bass Boost
       D9: Loudness
       D10..(n*8-1): Reserved
    */
    0x02,               /* bmaControls(2) - Right */
    /* A bit set to 1 indicates that the mentioned
       Control is supported for master channel
       0:
       D0: Mute
       D1: Volume
       D2: Bass
       D3: Mid
       D4: Treble
       D5: Graphic Equalizer
       D6: Automatic Gain
       D7: Delay
       D8: Bass Boost
       D9: Loudness
       D10..(n*8-1): Reserved
    */
    0x00,               /* iFeature */

    /* Audio Control Output Terminal Descriptor - Speaker (Terminal ID 3 - Source ID 6) */
    0x09,               /* bLength*/
    0x24,               /* bDescriptorType:CS_INTERFACE*/
    0x03,               /* bDescriptorSubType:OUTPUT_TERMINAL*/
    0x03,               /* bTerminalID*/
    0x01, 0x03,         /* wTerminalType: 0x0301 speaker*/
    0x00,               /* bAssocTerminal*/
    PLAY_FEATURE_UNITID,/* bSourceID*/
    0x00,               /* iTerminal*/

    /* Interface Descriptor - Interface 1, alternate 0 */
    0x09,               /* bLength */
    0x04,               /* bDescriptorType */
    0x01,               /* bInterfaceNumber */
    0x00,               /* bAlternateSetting */
    0x00,               /* bNumEndpoints */
    0x01,               /* bInterfaceClass:AUDIO */
    0x02,               /* bInterfaceSubClass:AUDIOSTREAMING */
    0x00,               /* bInterfaceProtocol */
    0x00,               /* iInterface */

    /* Interface Descriptor - Interface 1, alternate 1 */
    0x09,               /* bLength */
    0x04,               /* bDescriptorType */
    0x01,               /* bInterfaceNumber */
    0x01,               /* bAlternateSetting */
#ifdef __FEEDBACK__
    0x02,               /* bNumEndpoints : ISO OUT Endpoint for play & ISO IN Endpoint for Feedback */
#else
    0x01,               /* bNumEndpoints : ISO OUT Endpoint for play */
#endif
    0x01,               /* bInterfaceClass:AUDIO */
    0x02,               /* bInterfaceSubClass:AUDIOSTREAMING */
    0x00,               /* bInterfaceProtocol */
    0x00,               /* iInterface */

    /* Audio Streaming Class Specific Interface Descriptor (this interface's endpoint connect to Terminal ID 0x01 - Speaker) */
    0x07,               /* bLength */
    0x24,               /* bDescriptorType:CS_INTERFACE */
    0x01,               /* bDescriptorSubType:AS_GENERAL */
    0x01,               /* bTernimalLink (Speaker) */
    0x01,               /* bDelay */
    0x01,0x00,          /* wFormatTag:0x0001 PCM */

    /* Audio Streaming Format Type Descriptor */
    0x0E,               /* bLength */
    0x24,               /* bDescriptorType:CS_INTERFACE */
    0x02,               /* bDescriptorSubType:FORMAT_TYPE */
    0x01,               /* bFormatType:FORMAT_TYPE_I */
    /* Standard AS interface 1/2, alternate 1 */
    PLAY_CHANNELS,      /* bNrChannels    :  2 Channels */
    0x02,               /* bSubFrameSize  :  2 bytes per sample */
    0x10,               /* bBitResolution : 16 bits  per sample */
    0x02,               /* bSamFreqType :
                           0 Continuous sampling frequency
                           1 The number of discrete sampling frequencies */
    /* bSamFreqType  */
    (AUDIO_RATE_16K & 0xFF),
    ((AUDIO_RATE_16K >> 8) & 0xFF),
    ((AUDIO_RATE_16K >> 16) & 0xFF),

    (AUDIO_RATE_48K & 0xFF),
    ((AUDIO_RATE_48K >> 8) & 0xFF),
    ((AUDIO_RATE_48K >> 16) & 0xFF),


    /* Endpoint Descriptor (ISO OUT Audio Data Endpoint - alternate 1) */
    0x09,                             /* bLength */
    0x05,                             /* bDescriptorType */
    ISO_OUT_EP_NUM | EP_OUTPUT,       /* bEndpointAddress */
#ifdef __FEEDBACK__
    0x05,                             /* bmAttributes */
#else
    0x09,                             /* bmAttributes */
#endif
    (EP3_MAX_PKT_SIZE & 0xff),
    ((EP3_MAX_PKT_SIZE >> 8) & 0xff), /* wMaxPacketSize */
    0x01,                             /* bInterval */
    0x00,                             /* bRefresh */
#ifdef __FEEDBACK__
    ISO_IN_FB_EP_NUM | EP_INPUT,      /* bSynchAddress */
#else
    0x00,                             /* bSynchAddress */
#endif

    /* Audio Streaming Class Specific Audio Data Endpoint Descriptor */
    0x07,                             /* bLength */
    0x25,                             /* bDescriptorType:CS_ENDPOINT */
    0x01,                             /* bDescriptorSubType:EP_GENERAL */
    0x01,                             /* bmAttributes */
    0x02,                             /* bLockDelayUnits */
    0x00, 0x00,                       /* wLockDelay */

#ifdef __FEEDBACK__
    /* Feedback Endpoint */
    0x09,                             /* bLength */
    0x05,                             /* bDescriptorType */
    ISO_IN_FB_EP_NUM | EP_INPUT,      /* bEndpointAddress */
    0x11,                             /* bmAttributes */
    EP4_MAX_PKT_SIZE, 0x00,           /* wMaxPacketSize */
    0x01,                             /* bInterval */
    0x09,                             /* bRefresh */
    0x00,                             /* bSynchAddress */
#endif
#ifdef __HID__
    /* Interface Descriptor for HID */
    LEN_INTERFACE,      /* bLength */
    DESC_INTERFACE,     /* bDescriptorType */
    0x02,               /* bInterfaceNumber */
    0x00,               /* bAlternateSetting */
    0x01,               /* bNumEndpoints : Interrupt IN Endpoint */
    0x03,               /* bInterfaceClass */
    0x00,               /* bInterfaceSubClass */
    0x00,               /* bInterfaceProtocol */
    0x00,               /* iInterface */

    /* HID Descriptor */
    LEN_HID,            /* Size of this descriptor in UINT8s */
    DESC_HID,           /* HID descriptor type. */
    0x10, 0x01,         /* HID Class Spec. release number.*/
    0x00,               /* H/W target country. */
    0x01,               /* Number of HID class descriptors to follow. */
    DESC_HID_RPT,       /* Dscriptor type. */

    /* Total length of report descriptor */
    HID_REPORT_DESCRIPTOR_SIZE & 0x00FF,
    (HID_REPORT_DESCRIPTOR_SIZE & 0xFF00) >> 8,

    /* Endpoint Descriptor (Interrupt IN Endpoint) */
    LEN_ENDPOINT,                     /* bLength */
    DESC_ENDPOINT,                    /* bDescriptorType */
    (HID_IN_EP_NUM | EP_INPUT),       /* bEndpointAddress */
    EP_INT,                           /* bmAttributes */
    /* wMaxPacketSize */
    EP5_MAX_PKT_SIZE & 0x00FF,
    (EP5_MAX_PKT_SIZE & 0xFF00) >> 8,
    10                                /* bInterval */
#endif
};

/*!<USB BOS Descriptor */
uint8_t gu8BosDescriptor[] = {
    LEN_BOS,                         /* bLength         */
    DESC_BOS,                        /* bDescriptorType */
    ((LEN_BOS + LEN_BOSCAP) & 0xFF), /* wTotalLength    */
    ((LEN_BOS + LEN_BOSCAP) >> 8),   /* wTotalLength    */
    0x01,                            /* bNumDevcieCaps  */
    LEN_BOSCAP,                      /* bLength         */
    DESC_CAPABILITY,                 /* bDescriptorType */
    CAP_USB20_EXT,                   /* bDevCapabilityType, 0x02 is USB 2.0 Extension */
    0x06, 0x04, 0x00, 0x00  /* bmAttributs, 32 bits     */
    /* bit 0 : Reserved. Must 0.                                         */
    /* bit 1 : 1 to support LPM.                                         */
    /* bit 2 : 1 to support BSL & Alternat HIRD                          */
    /* bit 3 : 1 to recommend Baseline BESL                              */
    /* bit 4 : 1 to recommand Deep BESL                                  */
    /* bit 11:8 : Recommend Baseline BESL value. Ignore by bit3 is zero. */
    /* bit 15:12 : Recommend Deep BESL value. Ignore by bit4 is zero.    */
    /* bit 31:16 : Reserved. Must 0.                                     */
};


/*!<USB Language String Descriptor */
uint8_t gu8StringLang[4] =
{
    4,              /* bLength */
    DESC_STRING,    /* bDescriptorType */
    0x09, 0x04
};

/*!<USB Vendor String Descriptor */
uint8_t gu8VendorStringDesc[] =
{
    16,
    DESC_STRING,
    'N', 0, 'u', 0, 'v', 0, 'o', 0, 't', 0, 'o', 0, 'n', 0
};

/*!<USB Product String Descriptor */
uint8_t gu8ProductStringDesc[] =
{
#ifdef __HID__
    54,
    DESC_STRING,
    'U', 0, 'A', 0, 'C', 0, ' ', 0, '1', 0, '.', 0, '0', 0, ' ', 0,
    'S', 0, 'p', 0, 'e', 0, 'a', 0, 'k', 0, 'e', 0, 'r', 0,
    ' ', 0, '&', 0,
#ifdef __JOYSTICK__
    ' ', 0, 'J', 0, 'o', 0, 'y', 0, 's', 0, 't', 0, 'i', 0, 'c', 0, 'k', 0,
#elif defined __MEDIAKEY__
    ' ', 0, 'M', 0, 'e', 0, 'd', 0, 'i', 0, 'a', 0, 'k', 0, 'e', 0, 'y', 0,
#else
    ' ', 0, 'P', 0, 'h', 0, 'o', 0, 'n', 0, 'e', 0, 'k', 0, 'e', 0, 'y', 0,
#endif
#else
    32,
    DESC_STRING,
    'U', 0, 'A', 0, 'C', 0, ' ', 0, '1', 0, '.', 0, '0', 0, ' ', 0,
    'S', 0, 'p', 0, 'e', 0, 'a', 0, 'k', 0, 'e', 0, 'r', 0
#endif
};
/*!<USB Serial String Descriptor */
uint8_t gu8StringSerial[26] =
{
    26,             /* bLength */
    DESC_STRING,    /* bDescriptorType */
    'A', 0, '0', 0, '2', 0, '0', 0, '0', 0, '8', 0, '0', 0, '4', 0, '0', 0, '1', 0, '1', 0, '4', 0
};

uint8_t *gpu8UsbString[4] =
{
    gu8StringLang,
    gu8VendorStringDesc,
    gu8ProductStringDesc,
    gu8StringSerial
};

uint8_t *gu8UsbHidReport[4] =
{
    0,
    0,
#ifdef __HID__
    HID_DeviceReportDescriptor,
#else
    0,
#endif
    0
};

uint32_t gu32UsbHidReportLen[4] =
{
    0,
    0,
#ifdef __HID__
    sizeof(HID_DeviceReportDescriptor),
#else
    0,
#endif
    0
};
uint32_t gu32ConfigHidDescIdx[3] =
{
    0,
    0,
    (sizeof(gu8ConfigDescriptor) - LEN_HID - LEN_ENDPOINT),
};
const S_USBD_INFO_T gsInfo = {
    gu8DeviceDescriptor,
    gu8ConfigDescriptor,
    gpu8UsbString,
    gu8UsbHidReport,
    0,
    gu32UsbHidReportLen,
    gu32ConfigHidDescIdx,
};

