/*
LUFA Library
Copyright ( C ) Dean Camera , 2009.
dean [ at ] fourwalledcubicle [ dot ] com
www . fourwalledcubicle . com
*/
/*
Copyright 2009 Dean Camera ( dean [ at ] fourwalledcubicle [ dot ] com )
Permission to use , copy , modify , and distribute this software
and its documentation for any purpose and without fee is hereby
granted , provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation , and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific , written prior permission .
The author disclaim all warranties with regard to this
software , including all implied warranties of merchantability
and fitness . In no event shall the author be liable for any
special , indirect or consequential damages or any damages
whatsoever resulting from loss of use , data or profits , whether
in an action of contract , negligence or other tortious action ,
arising out of or in connection with the use or performance of
this software .
*/
/** \file
*
* USB Device Descriptors , for library use when in USB device mode . Descriptors are special
* computer - readable structures which the host requests upon device enumeration , to determine
* the device ' s capabilities and functions .
*/
# include "Descriptors.h"
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
* device characteristics , including the supported USB version , control endpoint size and the
* number of device configurations . The descriptor is read out by the USB host when the enumeration
* process begins .
*/
USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
{
. Header = { . Size = sizeof ( USB_Descriptor_Device_t ) , . Type = DTYPE_Device } ,
. USBSpecification = VERSION_BCD ( 01.10 ) ,
. Class = 0xEF ,
. SubClass = 0x02 ,
. Protocol = 0x01 ,
. Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE ,
. VendorID = 0x03EB ,
. ProductID = 0x204E ,
. ReleaseNumber = 0x0000 ,
. ManufacturerStrIndex = 0x01 ,
. ProductStrIndex = 0x02 ,
. SerialNumStrIndex = USE_INTERNAL_SERIAL ,
. NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
} ;
/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
* of the device in one of its supported configurations , including information about any device interfaces
* and endpoints . The descriptor is read out by the USB host during the enumeration process when selecting
* a configuration so that the host may correctly communicate with the USB device .
*/
USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
{
. Config =
{
. Header = { . Size = sizeof ( USB_Descriptor_Configuration_Header_t ) , . Type = DTYPE_Configuration } ,
. TotalConfigurationSize = sizeof ( USB_Descriptor_Configuration_t ) ,
. TotalInterfaces = 4 ,
. ConfigurationNumber = 1 ,
. ConfigurationStrIndex = NO_DESCRIPTOR ,
. ConfigAttributes = ( USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELFPOWERED ) ,
. MaxPowerConsumption = USB_CONFIG_POWER_MA ( 100 )
} ,
. IAD1 =
{
. Header = { . Size = sizeof ( USB_Descriptor_Interface_Association_t ) , . Type = DTYPE_InterfaceAssociation } ,
. FirstInterfaceIndex = 0 ,
. TotalInterfaces = 2 ,
. Class = 0x02 ,
. SubClass = 0x02 ,
. Protocol = 0x01 ,
. IADStrIndex = NO_DESCRIPTOR
} ,
. CDC1_CCI_Interface =
{
. Header = { . Size = sizeof ( USB_Descriptor_Interface_t ) , . Type = DTYPE_Interface } ,
. InterfaceNumber = 0 ,
. AlternateSetting = 0 ,
. TotalEndpoints = 1 ,
. Class = 0x02 ,
. SubClass = 0x02 ,
. Protocol = 0x01 ,
. InterfaceStrIndex = NO_DESCRIPTOR
} ,
. CDC1_Functional_IntHeader =
{
. Header = { . Size = sizeof ( CDC_FUNCTIONAL_DESCRIPTOR ( 2 ) ) , . Type = 0x24 } ,
. SubType = 0x00 ,
. Data = { 0x01 , 0x10 }
} ,
. CDC1_Functional_CallManagement =
{
. Header = { . Size = sizeof ( CDC_FUNCTIONAL_DESCRIPTOR ( 2 ) ) , . Type = 0x24 } ,
. SubType = 0x01 ,
. Data = { 0x03 , 0x01 }
} ,
. CDC1_Functional_AbstractControlManagement =
{
. Header = { . Size = sizeof ( CDC_FUNCTIONAL_DESCRIPTOR ( 1 ) ) , . Type = 0x24 } ,
. SubType = 0x02 ,
. Data = { 0x06 }
} ,
. CDC1_Functional_Union =
{
. Header = { . Size = sizeof ( CDC_FUNCTIONAL_DESCRIPTOR ( 2 ) ) , . Type = 0x24 } ,
. SubType = 0x06 ,
. Data = { 0x00 , 0x01 }
} ,
. CDC1_ManagementEndpoint =
{
. Header = { . Size = sizeof ( USB_Descriptor_Endpoint_t ) , . Type = DTYPE_Endpoint } ,
. EndpointAddress = ( ENDPOINT_DESCRIPTOR_DIR_IN | CDC1_NOTIFICATION_EPNUM ) ,
. Attributes = ( EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA ) ,
. EndpointSize = CDC_NOTIFICATION_EPSIZE ,
. PollingIntervalMS = 0xFF
} ,
. CDC1_DCI_Interface =
{
. Header = { . Size = sizeof ( USB_Descriptor_Interface_t ) , . Type = DTYPE_Interface } ,
. InterfaceNumber = 1 ,
. AlternateSetting = 0 ,
. TotalEndpoints = 2 ,
. Class = 0x0A ,
. SubClass = 0x00 ,
. Protocol = 0x00 ,
. InterfaceStrIndex = NO_DESCRIPTOR
} ,
. CDC1_DataOutEndpoint =
{
. Header = { . Size = sizeof ( USB_Descriptor_Endpoint_t ) , . Type = DTYPE_Endpoint } ,
. EndpointAddress = ( ENDPOINT_DESCRIPTOR_DIR_OUT | CDC1_RX_EPNUM ) ,
. Attributes = ( EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA ) ,
. EndpointSize = CDC_TXRX_EPSIZE ,
. PollingIntervalMS = 0x00
} ,
. CDC1_DataInEndpoint =
{
. Header = { . Size = sizeof ( USB_Descriptor_Endpoint_t ) , . Type = DTYPE_Endpoint } ,
. EndpointAddress = ( ENDPOINT_DESCRIPTOR_DIR_IN | CDC1_TX_EPNUM ) ,
. Attributes = ( EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA ) ,
. EndpointSize = CDC_TXRX_EPSIZE ,
. PollingIntervalMS = 0x00
} ,
. IAD2 =
{
. Header = { . Size = sizeof ( USB_Descriptor_Interface_Association_t ) , . Type = DTYPE_InterfaceAssociation } ,
. FirstInterfaceIndex = 2 ,
. TotalInterfaces = 2 ,
. Class = 0x02 ,
. SubClass = 0x02 ,
. Protocol = 0x01 ,
. IADStrIndex = NO_DESCRIPTOR
} ,
. CDC2_CCI_Interface =
{
. Header = { . Size = sizeof ( USB_Descriptor_Interface_t ) , . Type = DTYPE_Interface } ,
. InterfaceNumber = 2 ,
. AlternateSetting = 0 ,
. TotalEndpoints = 1 ,
. Class = 0x02 ,
. SubClass = 0x02 ,
. Protocol = 0x01 ,
. InterfaceStrIndex = NO_DESCRIPTOR
} ,
. CDC2_Functional_IntHeader =
{
. Header = { . Size = sizeof ( CDC_FUNCTIONAL_DESCRIPTOR ( 2 ) ) , . Type = 0x24 } ,
. SubType = 0x00 ,
. Data = { 0x01 , 0x10 }
} ,
. CDC2_Functional_CallManagement =
{
. Header = { . Size = sizeof ( CDC_FUNCTIONAL_DESCRIPTOR ( 2 ) ) , . Type = 0x24 } ,
. SubType = 0x01 ,
. Data = { 0x03 , 0x03 }
} ,
. CDC2_Functional_AbstractControlManagement =
{
. Header = { . Size = sizeof ( CDC_FUNCTIONAL_DESCRIPTOR ( 1 ) ) , . Type = 0x24 } ,
. SubType = 0x02 ,
. Data = { 0x06 }
} ,
. CDC2_Functional_Union =
{
. Header = { . Size = sizeof ( CDC_FUNCTIONAL_DESCRIPTOR ( 2 ) ) , . Type = 0x24 } ,
. SubType = 0x06 ,
. Data = { 0x02 , 0x03 }
} ,
. CDC2_ManagementEndpoint =
{
. Header = { . Size = sizeof ( USB_Descriptor_Endpoint_t ) , . Type = DTYPE_Endpoint } ,
. EndpointAddress = ( ENDPOINT_DESCRIPTOR_DIR_IN | CDC2_NOTIFICATION_EPNUM ) ,
. Attributes = ( EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA ) ,
. EndpointSize = CDC_NOTIFICATION_EPSIZE ,
. PollingIntervalMS = 0xFF
} ,
. CDC2_DCI_Interface =
{
. Header = { . Size = sizeof ( USB_Descriptor_Interface_t ) , . Type = DTYPE_Interface } ,
. InterfaceNumber = 3 ,
. AlternateSetting = 0 ,
. TotalEndpoints = 2 ,
. Class = 0x0A ,
. SubClass = 0x00 ,
. Protocol = 0x00 ,
. InterfaceStrIndex = NO_DESCRIPTOR
} ,
. CDC2_DataOutEndpoint =
{
. Header = { . Size = sizeof ( USB_Descriptor_Endpoint_t ) , . Type = DTYPE_Endpoint } ,
. EndpointAddress = ( ENDPOINT_DESCRIPTOR_DIR_OUT | CDC2_RX_EPNUM ) ,
. Attributes = ( EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA ) ,
. EndpointSize = CDC_TXRX_EPSIZE ,
. PollingIntervalMS = 0x00
} ,
. CDC2_DataInEndpoint =
{
. Header = { . Size = sizeof ( USB_Descriptor_Endpoint_t ) , . Type = DTYPE_Endpoint } ,
. EndpointAddress = ( ENDPOINT_DESCRIPTOR_DIR_IN | CDC2_TX_EPNUM ) ,
. Attributes = ( EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA ) ,
. EndpointSize = CDC_TXRX_EPSIZE ,
. PollingIntervalMS = 0x00
}
} ;
/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
* the string descriptor with index 0 ( the first index ) . It is actually an array of 16 - bit integers , which indicate
* via the language ID table available at USB . org what languages the device supports for its string descriptors .
*/
USB_Descriptor_String_t PROGMEM LanguageString =
{
. Header = { . Size = USB_STRING_LEN ( 1 ) , . Type = DTYPE_String } ,
. UnicodeString = { LANGUAGE_ID_ENG }
} ;
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
* form , and is read out upon request by the host when the appropriate string ID is requested , listed in the Device
* Descriptor .
*/
USB_Descriptor_String_t PROGMEM ManufacturerString =
{
. Header = { . Size = USB_STRING_LEN ( 11 ) , . Type = DTYPE_String } ,
. UnicodeString = L " Dean Camera "
} ;
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
* and is read out upon request by the host when the appropriate string ID is requested , listed in the Device
* Descriptor .
*/
USB_Descriptor_String_t PROGMEM ProductString =
{
. Header = { . Size = USB_STRING_LEN ( 13 ) , . Type = DTYPE_String } ,
. UnicodeString = L " LUFA Dual CDC Demo "
} ;
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
* documentation ) by the application code so that the address and size of a requested descriptor can be given
* to the USB library . When the device receives a Get Descriptor request on the control endpoint , this function
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
* USB host .
*/
uint16_t CALLBACK_USB_GetDescriptor ( const uint16_t wValue , const uint8_t wIndex , void * * const DescriptorAddress )
{
const uint8_t DescriptorType = ( wValue > > 8 ) ;
const uint8_t DescriptorNumber = ( wValue & 0xFF ) ;
void * Address = NULL ;
uint16_t Size = NO_DESCRIPTOR ;
switch ( DescriptorType )
{
case DTYPE_Device :
Address = ( void * ) & DeviceDescriptor ;
Size = sizeof ( USB_Descriptor_Device_t ) ;
break ;
case DTYPE_Configuration :
Address = ( void * ) & ConfigurationDescriptor ;
Size = sizeof ( USB_Descriptor_Configuration_t ) ;
break ;
case DTYPE_String :
switch ( DescriptorNumber )
{
case 0x00 :
Address = ( void * ) & LanguageString ;
Size = pgm_read_byte ( & LanguageString . Header . Size ) ;
break ;
case 0x01 :
Address = ( void * ) & ManufacturerString ;
Size = pgm_read_byte ( & ManufacturerString . Header . Size ) ;
break ;
case 0x02 :
Address = ( void * ) & ProductString ;
Size = pgm_read_byte ( & ProductString . Header . Size ) ;
break ;
}
break ;
}
* DescriptorAddress = Address ;
return Size ;
}