|
/*******************************************************************************
|
|
Copyright 2016 Microchip Technology Inc. (www.microchip.com)
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
To request to license the code under the MLA license (www.microchip.com/mla_license),
|
|
please contact mla_licensing@microchip.com
|
|
*******************************************************************************/
|
|
|
|
/********************************************************************
|
|
-usb_descriptors.c-
|
|
-------------------------------------------------------------------
|
|
Filling in the descriptor values in the usb_descriptors.c file:
|
|
-------------------------------------------------------------------
|
|
|
|
[Device Descriptors]
|
|
The device descriptor is defined as a USB_DEVICE_DESCRIPTOR type.
|
|
This type is defined in usb_ch9.h Each entry into this structure
|
|
needs to be the correct length for the data type of the entry.
|
|
|
|
[Configuration Descriptors]
|
|
The configuration descriptor was changed in v2.x from a structure
|
|
to a uint8_t array. Given that the configuration is now a byte array
|
|
each byte of multi-byte fields must be listed individually. This
|
|
means that for fields like the total size of the configuration where
|
|
the field is a 16-bit value "64,0," is the correct entry for a
|
|
configuration that is only 64 bytes long and not "64," which is one
|
|
too few bytes.
|
|
|
|
The configuration attribute must always have the _DEFAULT
|
|
definition at the minimum. Additional options can be ORed
|
|
to the _DEFAULT attribute. Available options are _SELF and _RWU.
|
|
These definitions are defined in the usb_device.h file. The
|
|
_SELF tells the USB host that this device is self-powered. The
|
|
_RWU tells the USB host that this device supports Remote Wakeup.
|
|
|
|
[Endpoint Descriptors]
|
|
Like the configuration descriptor, the endpoint descriptors were
|
|
changed in v2.x of the stack from a structure to a uint8_t array. As
|
|
endpoint descriptors also has a field that are multi-byte entities,
|
|
please be sure to specify both bytes of the field. For example, for
|
|
the endpoint size an endpoint that is 64 bytes needs to have the size
|
|
defined as "64,0," instead of "64,"
|
|
|
|
Take the following example:
|
|
// Endpoint Descriptor //
|
|
0x07, //the size of this descriptor //
|
|
USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
|
|
_EP02_IN, //EndpointAddress
|
|
_INT, //Attributes
|
|
0x08,0x00, //size (note: 2 bytes)
|
|
0x02, //Interval
|
|
|
|
The first two parameters are self-explanatory. They specify the
|
|
length of this endpoint descriptor (7) and the descriptor type.
|
|
The next parameter identifies the endpoint, the definitions are
|
|
defined in usb_device.h and has the following naming
|
|
convention:
|
|
_EP<##>_<dir>
|
|
where ## is the endpoint number and dir is the direction of
|
|
transfer. The dir has the value of either 'OUT' or 'IN'.
|
|
The next parameter identifies the type of the endpoint. Available
|
|
options are _BULK, _INT, _ISO, and _CTRL. The _CTRL is not
|
|
typically used because the default control transfer endpoint is
|
|
not defined in the USB descriptors. When _ISO option is used,
|
|
addition options can be ORed to _ISO. Example:
|
|
_ISO|_AD|_FE
|
|
This describes the endpoint as an isochronous pipe with adaptive
|
|
and feedback attributes. See usb_device.h and the USB
|
|
specification for details. The next parameter defines the size of
|
|
the endpoint. The last parameter in the polling interval.
|
|
|
|
-------------------------------------------------------------------
|
|
Adding a USB String
|
|
-------------------------------------------------------------------
|
|
A string descriptor array should have the following format:
|
|
|
|
rom struct{byte bLength;byte bDscType;word string[size];}sdxxx={
|
|
sizeof(sdxxx),DSC_STR,<text>};
|
|
|
|
The above structure provides a means for the C compiler to
|
|
calculate the length of string descriptor sdxxx, where xxx is the
|
|
index number. The first two bytes of the descriptor are descriptor
|
|
length and type. The rest <text> are string texts which must be
|
|
in the unicode format. The unicode format is achieved by declaring
|
|
each character as a word type. The whole text string is declared
|
|
as a word array with the number of characters equals to <size>.
|
|
<size> has to be manually counted and entered into the array
|
|
declaration. Let's study this through an example:
|
|
if the string is "USB" , then the string descriptor should be:
|
|
(Using index 02)
|
|
rom struct{byte bLength;byte bDscType;word string[3];}sd002={
|
|
sizeof(sd002),DSC_STR,'U','S','B'};
|
|
|
|
A USB project may have multiple strings and the firmware supports
|
|
the management of multiple strings through a look-up table.
|
|
The look-up table is defined as:
|
|
rom const unsigned char *rom USB_SD_Ptr[]={&sd000,&sd001,&sd002};
|
|
|
|
The above declaration has 3 strings, sd000, sd001, and sd002.
|
|
Strings can be removed or added. sd000 is a specialized string
|
|
descriptor. It defines the language code, usually this is
|
|
US English (0x0409). The index of the string must match the index
|
|
position of the USB_SD_Ptr array, &sd000 must be in position
|
|
USB_SD_Ptr[0], &sd001 must be in position USB_SD_Ptr[1] and so on.
|
|
The look-up table USB_SD_Ptr is used by the get string handler
|
|
function.
|
|
|
|
-------------------------------------------------------------------
|
|
|
|
The look-up table scheme also applies to the configuration
|
|
descriptor. A USB device may have multiple configuration
|
|
descriptors, i.e. CFG01, CFG02, etc. To add a configuration
|
|
descriptor, user must implement a structure similar to CFG01.
|
|
The next step is to add the configuration descriptor name, i.e.
|
|
cfg01, cfg02,.., to the look-up table USB_CD_Ptr. USB_CD_Ptr[0]
|
|
is a dummy place holder since configuration 0 is the un-configured
|
|
state according to the definition in the USB specification.
|
|
|
|
********************************************************************/
|
|
|
|
/*********************************************************************
|
|
* Descriptor specific type definitions are defined in:
|
|
* usb_device.h
|
|
*
|
|
* Configuration options are defined in:
|
|
* usb_config.h
|
|
********************************************************************/
|
|
|
|
/** INCLUDES *******************************************************/
|
|
#include "usb.h"
|
|
#include "usb_device_hid.h"
|
|
|
|
/** CONSTANTS ******************************************************/
|
|
#if defined(COMPILER_MPLAB_C18)
|
|
#pragma romdata
|
|
#endif
|
|
|
|
/* Device Descriptor */
|
|
const USB_DEVICE_DESCRIPTOR device_dsc=
|
|
{
|
|
0x12, //from 0x18 // Size of this descriptor in bytes
|
|
USB_DESCRIPTOR_DEVICE, // DEVICE descriptor type
|
|
0x0200, // USB Spec Release Number in BCD format
|
|
0x00, // Class Code
|
|
0x00, // Subclass code
|
|
0x00, // Protocol code
|
|
USB_EP0_BUFF_SIZE, // Max packet size for EP0, see usb_config.h
|
|
0x04D8, // Vendor ID, see usb_config.h
|
|
0x0000, //from 0x005E // Product ID, see usb_config.h
|
|
0x0100, //from 0x0001 // Device release number in BCD format
|
|
0x01, // Manufacturer string index
|
|
0x02, // Product string index
|
|
0x00, // Device serial number string index
|
|
0x01 // Number of possible configurations
|
|
};
|
|
|
|
/* Configuration 1 Descriptor */
|
|
const uint8_t configDescriptor1[]={
|
|
/* Configuration Descriptor */
|
|
0x09,//sizeof(USB_CFG_DSC), // Size of this descriptor in bytes
|
|
USB_DESCRIPTOR_CONFIGURATION, // CONFIGURATION descriptor type
|
|
/*DESC_CONFIG_WORD(0x0022), // Total length of data for this cfg
|
|
1, // Number of interfaces in this cfg
|
|
1, // Index value of this configuration
|
|
0, // Configuration string index
|
|
_DEFAULT | _SELF, // Attributes, see usb_device.h
|
|
50, // Max power consumption (2X mA)
|
|
*/
|
|
/* Interface Descriptor */
|
|
//added
|
|
41,0, // 41 Bytes size: of the conf descriptor
|
|
1, //number of interfaces in this conf
|
|
0x01, //Index value of this conf
|
|
0x00, //Conf string index
|
|
_DEFAULT | _SELF,
|
|
50, //max power consumption (2X mA)
|
|
// end added
|
|
0x09,//sizeof(USB_INTF_DSC), // Size of this descriptor in bytes
|
|
USB_DESCRIPTOR_INTERFACE, // INTERFACE descriptor type
|
|
0, // Interface Number
|
|
0, // Alternate Setting Number
|
|
2, //from 1 // Number of endpoints in this intf
|
|
|
|
HID_INTF, // Class code
|
|
0x00, //from 0x01, // Subclass code //0 à l'origine
|
|
0x00, //from 0x02, // Protocol code //0 à l'origine
|
|
0, // Interface string index
|
|
|
|
//added
|
|
/* HID Class-Specific Descriptor */
|
|
0x09,//sizeof(USB_HID_DSC)+3, // Size of this descriptor in bytes RRoj hack
|
|
DSC_HID, // HID descriptor type
|
|
0x11,0x01, //from DESC_CONFIG_WORD(0x0111), // HID Spec Release Number in BCD format (1.11)
|
|
0x00, // Country Code (0x00 for Not supported)
|
|
1, //from HID_NUM_OF_DSC, // Number of class descriptors, see usbcfg.h
|
|
DSC_RPT, // Report descriptor type
|
|
DESC_CONFIG_WORD(HID_RPT01_SIZE), //sizeof(hid_rpt01), // Size of the report descriptor
|
|
|
|
/* Endpoint Descriptor */
|
|
0x07,/*sizeof(USB_EP_DSC)*/
|
|
USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
|
|
JOYSTICK_EP | _EP_IN, //EndpointAddress
|
|
_INTERRUPT, //Attributes
|
|
0x40,0x00, //from DESC_CONFIG_WORD(64), //size
|
|
0x01, //from 0x0A, //Interval //0x01 a l'origine
|
|
|
|
//ADDED
|
|
/* Endpoint Descriptor */
|
|
0x07,/*sizeof(USB_EP_DSC)*/
|
|
USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
|
|
JOYSTICK_EP | _EP_OUT, //EndpointAddress
|
|
_INTERRUPT, //Attributes
|
|
0x40,0x00, //from DESC_CONFIG_WORD(64), //size
|
|
0x01, //from 0x0A, //Interval //0x01
|
|
//END ADDED
|
|
|
|
|
|
};
|
|
|
|
|
|
//Language code string descriptor
|
|
const struct{uint8_t bLength;uint8_t bDscType;uint16_t string[1];}sd000={
|
|
sizeof(sd000),USB_DESCRIPTOR_STRING,{0x0409
|
|
}};
|
|
|
|
//Manufacturer string descriptor
|
|
const struct{uint8_t bLength;uint8_t bDscType;uint16_t string[25];}sd001={
|
|
sizeof(sd001),USB_DESCRIPTOR_STRING,
|
|
{'M','i','c','r','o','c','h','i','p',' ',
|
|
'T','e','c','h','n','o','l','o','g','y',' ','I','n','c','.'
|
|
}};
|
|
|
|
//Product string descriptor
|
|
const struct{uint8_t bLength;uint8_t bDscType;uint16_t string[13];}sd002={
|
|
sizeof(sd002),USB_DESCRIPTOR_STRING,
|
|
{'J','o','y','s','t','i','c','k',' ','D','e','m','o'
|
|
}};
|
|
|
|
//Array of configuration descriptors
|
|
const uint8_t *const USB_CD_Ptr[]=
|
|
{
|
|
(const uint8_t *const)&configDescriptor1
|
|
};
|
|
|
|
//Array of string descriptors
|
|
const uint8_t *const USB_SD_Ptr[]=
|
|
{
|
|
(const uint8_t *const)&sd000,
|
|
(const uint8_t *const)&sd001,
|
|
(const uint8_t *const)&sd002
|
|
};
|
|
|
|
const struct{uint8_t report[HID_RPT01_SIZE];}hid_rpt01={{
|
|
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
|
0x09, 0x04, // USAGE (Joystick)
|
|
0xa1, 0x01, // COLLECTION (Application)
|
|
0x85, 0x01, // REPORT_ID (1)
|
|
0x05, 0x01, // USAGE_PAGE (generic)
|
|
0xa1, 0x00, // COLLECTION (Physical)
|
|
0x09, 0x30, // USAGE (X)
|
|
0x09, 0x31, // USAGE (Y)
|
|
0x09, 0x32, // USAGE (Z)
|
|
0x09, 0x33, // USAGE (RX)
|
|
0x09, 0x34, // USAGE (RY)
|
|
0x09, 0x35, // USAGE (RZ)
|
|
0x09, 0x36, // USAGE (SLIDER)
|
|
0x09, 0x37, // USAGE (DIAL)
|
|
0x75, 0x10, // REPORT_SIZE (16)
|
|
0x95, 0x08, // REPORT_COUNT (8)
|
|
0x81, 0x02, // INPUT (Data,Var,Abs)
|
|
0xc0,
|
|
0x05, 0x09, // USAGE_PAGE(Button)
|
|
0x19, 0x01, // USAGE_MINIMUM(Button 1)
|
|
0x29, 0x10, // USAGE_MAXIMUM(Button 16)
|
|
0x75, 0x01, // REPORT_SIZE(1)
|
|
0x95, 0x10, // REPORT_SIZE(16)
|
|
0x81, 0x02, // INPUT(Data,Var,Abs)
|
|
0xc0,
|
|
|
|
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
|
0x09, 0x04, // USAGE (Joystick)
|
|
0xa1, 0x01, // COLLECTION (Application)
|
|
0x85, 0x02, // REPORT_ID (2)
|
|
0x05, 0x01, // USAGE_PAGE (generic)
|
|
0xa1, 0x00, // COLLECTION (Physical)
|
|
0x09, 0x30, // USAGE (X)
|
|
0x09, 0x31, // USAGE (Y)
|
|
0x09, 0x32, // USAGE (Z)
|
|
0x09, 0x33, // USAGE (RX)
|
|
0x09, 0x34, // USAGE (RY)
|
|
0x09, 0x35, // USAGE (RZ)
|
|
0x09, 0x36, // USAGE (SLIDER)
|
|
0x09, 0x37, // USAGE (DIAL)
|
|
0x75, 0x10, // REPORT_SIZE (16)
|
|
0x95, 0x08, // REPORT_COUNT (8)
|
|
0x81, 0x02, // INPUT (Data,Var,Abs)
|
|
0xc0,
|
|
0x05, 0x09, // USAGE_PAGE(Button)
|
|
0x19, 0x01, // USAGE_MINIMUM(Button 1)
|
|
0x29, 0x10, // USAGE_MAXIMUM(Button 16)
|
|
0x75, 0x01, // REPORT_SIZE(1)
|
|
0x95, 0x10, // REPORT_SIZE(16)
|
|
0x81, 0x02, // INPUT(Data,Var,Abs)
|
|
0xc0, //END_COLLECTION
|
|
|
|
}
|
|
};
|
|
|
|
/** EOF usb_descriptors.c ***************************************************/
|
|
|