3      Copyright (C) Dean Camera, 2012. 
   5   dean [at] fourwalledcubicle [dot] com 
  10   Copyright 2012  Dean Camera (dean [at] fourwalledcubicle [dot] com) 
  12   Permission to use, copy, modify, distribute, and sell this 
  13   software and its documentation for any purpose is hereby granted 
  14   without fee, provided that the above copyright notice appear in 
  15   all copies and that both that the copyright notice and this 
  16   permission notice and warranty disclaimer appear in supporting 
  17   documentation, and that the name of the author not be used in 
  18   advertising or publicity pertaining to distribution of the 
  19   software without specific, written prior permission. 
  21   The author disclaim all warranties with regard to this 
  22   software, including all implied warranties of merchantability 
  23   and fitness.  In no event shall the author be liable for any 
  24   special, indirect or consequential damages or any damages 
  25   whatsoever resulting from loss of use, data or profits, whether 
  26   in an action of contract, negligence or other tortious action, 
  27   arising out of or in connection with the use or performance of 
  31 #include "Descriptors.h" 
  33 const USB_Descriptor_Device_t PROGMEM DeviceDescriptor 
= 
  35         Header
:                 {Size
: sizeof(USB_Descriptor_Device_t
), Type
: DTYPE_Device
}, 
  37         USBSpecification
:       VERSION_BCD(01.10), 
  46         ReleaseNumber
:          VERSION_BCD(00.01), 
  48         ManufacturerStrIndex
:   0x01, 
  49         ProductStrIndex
:        0x02, 
  50         SerialNumStrIndex
:      0x03, 
  52         NumberOfConfigurations
: 1 
  55 const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor 
= 
  59                         Header
:                 {Size
: sizeof(USB_Descriptor_Configuration_Header_t
), Type
: DTYPE_Configuration
}, 
  61                         TotalConfigurationSize
: sizeof(USB_Descriptor_Configuration_t
), 
  64                         ConfigurationNumber
:    1, 
  65                         ConfigurationStrIndex
:  NO_DESCRIPTOR
, 
  67                         ConfigAttributes
:       (USB_CONFIG_ATTR_RESERVED 
| USB_CONFIG_ATTR_SELFPOWERED
), 
  69                         MaxPowerConsumption
:    USB_CONFIG_POWER_MA(100) 
  74                         Header
:                 {Size
: sizeof(USB_Descriptor_Interface_t
), Type
: DTYPE_Interface
}, 
  85                         InterfaceStrIndex
:      NO_DESCRIPTOR
 
  88         .SSHOW_DataInEndpoint 
= 
  90                         Header
:                 {Size
: sizeof(USB_Descriptor_Endpoint_t
), Type
: DTYPE_Endpoint
}, 
  92                         EndpointAddress
:        SIDESHOW_IN_EPADDR
, 
  93                         Attributes
:             EP_TYPE_BULK
, 
  94                         EndpointSize
:           SIDESHOW_IO_EPSIZE
, 
  95                         PollingIntervalMS
:      0x00 
  98         .SSHOW_DataOutEndpoint 
= 
 100                         Header
:                 {Size
: sizeof(USB_Descriptor_Endpoint_t
), Type
: DTYPE_Endpoint
}, 
 102                         EndpointAddress
:        SIDESHOW_OUT_EPADDR
, 
 103                         Attributes
:             EP_TYPE_BULK
, 
 104                         EndpointSize
:           SIDESHOW_IO_EPSIZE
, 
 105                         PollingIntervalMS
:      0x00 
 109 const USB_Descriptor_String_t PROGMEM LanguageString 
= 
 111         Header
:                 {Size
: USB_STRING_LEN(1), Type
: DTYPE_String
}, 
 113         UnicodeString
:          {LANGUAGE_ID_ENG
} 
 116 const USB_Descriptor_String_t PROGMEM ManufacturerString 
= 
 118         Header
:                 {Size
: USB_STRING_LEN(11), Type
: DTYPE_String
}, 
 120         UnicodeString
:          L
"Dean Camera" 
 123 const USB_Descriptor_String_t PROGMEM ProductString 
= 
 125         Header
:                 {Size
: USB_STRING_LEN(22), Type
: DTYPE_String
}, 
 127         UnicodeString
:          L
"LUFA Sideshow Demo" 
 130 const USB_Descriptor_String_t PROGMEM SerialNumberString 
= 
 132         Header
:                 {Size
: USB_STRING_LEN(12), Type
: DTYPE_String
}, 
 134         UnicodeString
:          L
"000000000000" 
 137 const USB_OSDescriptor_t PROGMEM OSDescriptorString 
= 
 139         Header
:                 {Size
: sizeof(USB_OSDescriptor_t
), Type
: DTYPE_String
}, 
 141         Signature
:              L
"MSFT100", 
 142         VendorCode
:             REQ_GetOSFeatureDescriptor
 
 145 const USB_OSCompatibleIDDescriptor_t PROGMEM DevCompatIDs 
= 
 147         TotalLength
:            sizeof(USB_OSCompatibleIDDescriptor_t
), 
 149         Index
:                  EXTENDED_COMPAT_ID_DESCRIPTOR
, 
 152         SideshowCompatID
:       {FirstInterfaceNumber
: 0x00, 
 153                                  CompatibleID
: "SIDESHW", 
 154                                  SubCompatibleID
: "UNIV1"} 
 157 uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue
, 
 158                                     const uint8_t wIndex
, 
 159                                     const void** const DescriptorAddress
) 
 161         const uint8_t  DescriptorType   
= (wValue 
>> 8); 
 162         const uint8_t  DescriptorNumber 
= (wValue 
& 0xFF); 
 164         const void* Address 
= NULL
; 
 165         uint16_t    Size    
= NO_DESCRIPTOR
; 
 167         switch (DescriptorType
) 
 170                         Address 
= &DeviceDescriptor
; 
 171                         Size    
= sizeof(USB_Descriptor_Device_t
); 
 173                 case DTYPE_Configuration
: 
 174                         Address 
= &ConfigurationDescriptor
; 
 175                         Size    
= sizeof(USB_Descriptor_Configuration_t
); 
 178                         switch (DescriptorNumber
) 
 181                                         Address 
= &LanguageString
; 
 182                                         Size    
= pgm_read_byte(&LanguageString
.Header
.Size
); 
 185                                         Address 
= &ManufacturerString
; 
 186                                         Size    
= pgm_read_byte(&ManufacturerString
.Header
.Size
); 
 189                                         Address 
= &ProductString
; 
 190                                         Size    
= pgm_read_byte(&ProductString
.Header
.Size
); 
 193                                         Address 
= &SerialNumberString
; 
 194                                         Size    
= pgm_read_byte(&SerialNumberString
.Header
.Size
); 
 197                                         /* A Microsoft-proprietary extension. String address 0xEE is used by Windows for 
 198                                            "OS Descriptors", which in this case allows us to indicate that our device is 
 199                                            Sideshow compatible regardless of VID/PID values. */ 
 200                                         Address 
= &OSDescriptorString
; 
 201                                         Size    
= pgm_read_byte(&OSDescriptorString
.Header
.Size
); 
 208         *DescriptorAddress 
= Address
; 
 212 uint16_t USB_GetOSFeatureDescriptor(const uint16_t wValue
, 
 213                                     const uint8_t wIndex
, 
 214                                     const void** const DescriptorAddress
) 
 216         const void* Address 
= NULL
; 
 217         uint16_t    Size    
= NO_DESCRIPTOR
; 
 219         /* Check if a device level OS feature descriptor is being requested */ 
 220         if (wValue 
== 0x0000) 
 222                 /* Only the Extended Device Compatibility descriptor is supported */ 
 223                 if (wIndex 
== EXTENDED_COMPAT_ID_DESCRIPTOR
) 
 225                         Address 
= &DevCompatIDs
; 
 226                         Size    
= sizeof(USB_OSCompatibleIDDescriptor_t
); 
 230         *DescriptorAddress 
= Address
;