/* * USB Descriptors file * * This file may be used by anyone for any purpose and may be used as a * starting point making your own application using M-Stack. * * It is worth noting that M-Stack itself is not under the same license as * this file. * * M-Stack is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. For details, see sections 7, 8, and 9 * of the Apache License, version 2.0 which apply to this file. If you have * purchased a commercial license for this software from Signal 11 Software, * your commerical license superceeds the information in this header. * * Alan Ott * Signal 11 Software */ #include "usb_config.h" #include "usb.h" #include "usb_ch9.h" #include "usb_hid.h" #ifdef __C18 #define ROMPTR rom #else #define ROMPTR #endif /* Configuration Packet * * This packet contains a configuration descriptor, one or more interface * descriptors, class descriptors(optional), and endpoint descriptors for a * single configuration of the device. This struct is specific to the * device, so the application will need to add any interfaces, classes and * endpoints it intends to use. It is sent to the host in response to a * GET_DESCRIPTOR[CONFIGURATION] request. * * While Most devices will only have one configuration, a device can have as * many configurations as it needs. To have more than one, simply make as * many of these structs as are required, one for each configuration. * * An instance of each configuration packet must be put in the * usb_application_config_descs[] array below (which is #defined in * usb_config.h) so that the USB stack can find it. * * See Chapter 9 of the USB specification from usb.org for details. * * It's worth noting that adding endpoints here does not automatically * enable them in the USB stack. To use an endpoint, it must be declared * here and also in usb_config.h. * * The configuration packet below is for the mouse demo application. * Yours will of course vary. */ struct configuration_1_packet { struct configuration_descriptor config; struct interface_descriptor interface; struct hid_descriptor hid; struct endpoint_descriptor ep; struct endpoint_descriptor ep1_out; }; /* Device Descriptor * * Each device has a single device descriptor describing the device. The * format is described in Chapter 9 of the USB specification from usb.org. * USB_DEVICE_DESCRIPTOR needs to be defined to the name of this object in * usb_config.h. For more information, see USB_DEVICE_DESCRIPTOR in usb.h. */ const ROMPTR struct device_descriptor this_device_descriptor = { sizeof(struct device_descriptor), // bLength DESC_DEVICE, // bDescriptorType 0x0200, // 0x0200 = USB 2.0, 0x0110 = USB 1.1 0x00, // Device class 0x00, // Device Subclass 0x00, // Protocol. EP_0_LEN, // bMaxPacketSize0 0x2965, // Vendor 0x5023, // Product 0x0001, // device release (1.0) 1, // Manufacturer 2, // Product 0, // Serial NUMBER_OF_CONFIGURATIONS // NumConfigurations }; /* HID Report descriptor. See the HID specification for more details. This * is the mouse example from the "HID Descriptor Tool" which can be downloaded * from USB.org. */ static const ROMPTR uint8_t touch_report_descriptor_2[] = { 0x05, 1, // USAGE_PAGE (Generic Desltop Controls) 0x09, 2, // USAGE (Mouse) 0xa1, 0x01, // COLLECTION (Application) 0x85, 114, // REPORT ID (115) 0x09, 1, // USAGE (Pointer) 0xa1, 0x01, // COLLECTION (Application) 0x05, 9, // USAGE_PAGE (Buttons) 0x19, 0, // USAGE_MINIMUM (Button 1) 0x29, 1, // USAGE_MAXIMUM (Button 3) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 1, // LOGICAL_MAXIMUM (1) 0x75, 1, // REPORT_SIZE (1) 0x95, 2, // REPORT_COUNT (3) 0x95, 6, // REPORT_COUNT (3) 0x81, 3, // INPUT (Data,Var,Abs) 0x05, 1, // USAGE_PAGE (Generic Desktop Controls) 0x09, 48, // USAGE (Mouse) 0x09, 49, // USAGE (Mouse) 0x15, -256, // LOGICAL_MINIMUM (0) 0x25, 4095, // LOGICAL_MAXIMUM (1) 0x35, 0, // Physical Minimum 0x45, 4095, //Physical Maximum 0x75, 16, // REPORT_SIZE (1) 0x95, 2, // REPORT_COUNT (3) 0x81, 2, // INPUT (Data,Var,Abs) 0xc0, // END_COLLECTION 0xc0 // END_COLLECTION }; static const ROMPTR uint8_t touch_report_descriptor_1[] = { 0x06, 00, 0xFF,//65280, // USAGE_PAGE (Digitizer) 0x09, 1, // USAGE (Unknown) 0xa1, 0x01, // COLLECTION (Application) 0x85, 118, // REPORT ID (115) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 255, // LOGICAL_MAXIMUM (1) 0x75, 8, // REPORT_SIZE (1) 0x95, 63, // REPORT_COUNT (3) 0x09, 1, // USAGE (Contact Count) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 1, // USAGE (Contact Count) 0x91, 0x02, // Output (Data,Var,Abs) 0xc0, // END_COLLECTION }; static const ROMPTR uint8_t mouse_report_descriptor_[] ={ 0x05, 0x0d, // USAGE_PAGE (Digitizers) 0x09, 0x02, // USAGE (Pen) 0xa1, 0x01, // COLLECTION (Application) 0x85, 0x01, // REPORT_ID (Pen) //To match this descriptor, byte[0] of IN packet should be = 0x01 always for this demo 0x09, 0x20, // USAGE (Stylus) 0xa1, 0x00, // COLLECTION (Physical) 0x09, 0x42, // USAGE (Tip Switch) //(byte[1] bit 0) 0x09, 0x44, // USAGE (Barrel Switch) //(byte[1] bit 1) 0x09, 0x45, // USAGE (Eraser Switch) //(byte[1] bit 2) 0x09, 0x3c, // USAGE (Invert) //(byte[1] bit 3) 0x09, 0x32, // USAGE (In Range) //(byte[1] bit 4) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x05, // REPORT_COUNT (5) 0x81, 0x02, // INPUT (Data,Var,Abs) //Makes five, 1-bit IN packet fields (byte[1] bits 0-4)) for (USAGE) tip sw, barrel sw, invert sw, in range sw. Send '1' here when switch is active. Send '0' when switch not active. 0x95, 0x0b, // REPORT_COUNT (11) 0x81, 0x03, // INPUT (Cnst,Var,Abs) //Makes eleven, 1-bit IN packet fields (byte[1] bits 5-7, and byte[2] all bits) with no usage. These are pad bits that don't contain useful data. 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x26, 0xff, 0x7f, // LOGICAL_MAXIMUM (32767) 0x75, 0x10, // REPORT_SIZE (16) 0x95, 0x01, // REPORT_COUNT (1) 0xa4, // PUSH 0x55, 0x0d, // UNIT_EXPONENT (-3) 0x65, 0x33, // UNIT (Inch,EngLinear) //(10^-3 inches = 1/1000 of an inch = 1 mil) 0x09, 0x30, // USAGE (X) //(byte[3] and byte[4]) 0x35, 0x00, // PHYSICAL_MINIMUM (0) 0x46, 0x00, 0x00, // PHYSICAL_MAXIMUM (0) 0x81, 0x02, // INPUT (Data,Var,Abs) //Makes one, 16-bit IN packet field used for (USAGE) X-coordinate input info. Valid values 0 to 32767. 0x09, 0x31, // USAGE (Y) //(byte[5] and byte[6]) 0x46, 0x00, 0x00, // PHYSICAL_MAXIMUM (0) 0x81, 0x02, // INPUT (Data,Var,Abs) //Makes one, 16-bit IN packet field used for (USAGE) Y-coordinate input info. Valid values 0 to 32767. 0xb4, // POP 0x05, 0x0d, // USAGE_PAGE (Digitizers) 0x09, 0x30, // USAGE (Tip Pressure) //(byte[7] and byte[8]) 0x81, 0x02, // INPUT (Data,Var,Abs) //Makes one, 16-bit IN packet field used for (USAGE) tip pressure input info. Valid values 0 to 32767 0x09, 0x3d, // USAGE (X Tilt) //(byte[9] and byte[10]) 0x09, 0x3e, // USAGE (Y Tilt) //(byte[11] and byte[12]) 0x16, 0x01, 0x80, // LOGICAL_MINIMUM (-32767) 0x95, 0x02, // REPORT_COUNT (2) 0x81, 0x02, // INPUT (Data,Var,Abs) //Makes two, 16-bit IN packet fields, used for (USAGE) X-Tilt and Y-Tilt. Valid values -32767 to 32767 0xc0, // END_COLLECTION 0xc0 // END_COLLECTION }; static const ROMPTR uint8_t mouse_report_descriptor[] = { 0x05, 13, // USAGE_PAGE (Digitizer) 0x09, 4, // USAGE (Mouse) 0xa1, 1, // COLLECTION (Application) 0x85, 115, // REPORT ID (115) 0x09, 84, // USAGE (Contact Count) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 31, // LOGICAL_MAXIMUM (1) 0x75, 0x08, // REPORT_SIZE (8) 0x95, 0x01, // REPORT_COUNT (1) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 34, // USAGE (Finger) 0xa1, 0, // COLLECTION (Physical) 0x09, 81, // USAGE (Contact ID) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 255, // LOGICAL_MAXIMUM (1) 0x75, 0x08, // REPORT_SIZE (1) 0x95, 0x01, // REPORT_COUNT (3) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 66, // USAGE (Tip Switch) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 1, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x01, // REPORT_COUNT (3) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 50, // USAGE (In Range) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 1, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x01, // REPORT_COUNT (3) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x75, 6, // REPORT_SIZE (1) 0x95, 1, // REPORT_COUNT (3) 0x81, 0x03, // INPUT (Data,Var,Abs) 0x09, 0x01, // USAGE (Generic Desktop Controls) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 4095, // LOGICAL_MAXIMUM (1) 0x35, 0, // Physical Minimum 0x45, 4095, //Physical Maximum 0x95, 16, // REPORT_COUNT (3) 0x75, 1, // REPORT_SIZE (1) 0x09, 48, // USAGE (Direction_x) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 49, // USAGE (Direction_y) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x05, 13, // USAGE_PAGE (Digitizer) 0xc0, // END_COLLECTION 0x09, 34, // USAGE (Finger) 0xa1, 0, // COLLECTION (Physical) 0x09, 81, // USAGE (Contact ID) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 255, // LOGICAL_MAXIMUM (1) 0x75, 0x08, // REPORT_SIZE (1) 0x95, 0x01, // REPORT_COUNT (3) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 66, // USAGE (Tip Switch) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 1, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x01, // REPORT_COUNT (3) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 50, // USAGE (In Range) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 1, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x01, // REPORT_COUNT (3) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x75, 6, // REPORT_SIZE (1) 0x95, 1, // REPORT_COUNT (3) 0x81, 0x03, // INPUT (Data,Var,Abs) 0x09, 0x01, // USAGE (Generic Desktop Controls) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 4095, // LOGICAL_MAXIMUM (1) 0x35, 0, // Physical Minimum 0x45, 4095, //Physical Maximum 0x75, 16, // REPORT_SIZE (1) 0x95, 1, // REPORT_COUNT (3) 0x09, 48, // USAGE (Direction_x) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 49, // USAGE (Direction_y) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x05, 13, // USAGE_PAGE (Digitizer) 0xc0, // END_COLLECTION 0x09, 34, // USAGE (Finger) 0xa1, 0, // COLLECTION (Physical) 0x09, 81, // USAGE (Contact ID) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 255, // LOGICAL_MAXIMUM (1) 0x75, 0x08, // REPORT_SIZE (1) 0x95, 0x01, // REPORT_COUNT (3) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 66, // USAGE (Tip Switch) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 1, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x01, // REPORT_COUNT (3) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 50, // USAGE (In Range) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 1, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x01, // REPORT_COUNT (3) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x75, 6, // REPORT_SIZE (1) 0x95, 1, // REPORT_COUNT (3) 0x81, 0x03, // INPUT (Data,Var,Abs) 0x09, 0x01, // USAGE (Generic Desktop Controls) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 4095, // LOGICAL_MAXIMUM (1) 0x35, 0, // Physical Minimum 0x45, 4095, //Physical Maximum 0x95, 16, // REPORT_COUNT (3) 0x75, 1, // REPORT_SIZE (1) 0x09, 48, // USAGE (Direction_x) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 49, // USAGE (Direction_y) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x05, 13, // USAGE_PAGE (Digitizer) 0xc0, // END_COLLECTION 0x09, 34, // USAGE (Finger) 0xa1, 0, // COLLECTION (Physical) 0x09, 81, // USAGE (Contact ID) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 255, // LOGICAL_MAXIMUM (1) 0x75, 0x08, // REPORT_SIZE (1) 0x95, 0x01, // REPORT_COUNT (3) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 66, // USAGE (Tip Switch) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 1, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x01, // REPORT_COUNT (3) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 50, // USAGE (In Range) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 1, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x01, // REPORT_COUNT (3) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x75, 6, // REPORT_SIZE (1) 0x95, 1, // REPORT_COUNT (3) 0x81, 0x03, // INPUT (Data,Var,Abs) 0x09, 0x01, // USAGE (Generic Desktop Controls) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 4095, // LOGICAL_MAXIMUM (1) 0x35, 0, // Physical Minimum 0x45, 4095, //Physical Maximum 0x75, 16, // REPORT_SIZE (1) 0x95, 1, // REPORT_COUNT (3) 0x09, 48, // USAGE (Direction_x) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 49, // USAGE (Direction_y) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x05, 13, // USAGE_PAGE (Digitizer) 0xc0, // END_COLLECTION 0x09, 34, // USAGE (Finger) 0xa1, 0, // COLLECTION (Physical) 0x09, 81, // USAGE (Contact ID) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 255, // LOGICAL_MAXIMUM (1) 0x75, 8, // REPORT_SIZE (1) 0x95, 1, // REPORT_COUNT (3) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 66, // USAGE (Tip Switch) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 1, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x01, // REPORT_COUNT (3) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 50, // USAGE (In Range) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 1, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x01, // REPORT_COUNT (3) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x75, 6, // REPORT_SIZE (1) 0x95, 1, // REPORT_COUNT (3) 0x81, 0x03, // INPUT (Data,Var,Abs) 0x09, 0x01, // USAGE (Generic Desktop Controls) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 4095, // LOGICAL_MAXIMUM (1) 0x35, 0, // Physical Minimum 0x45, 4095, //Physical Maximum 0x75, 16, // REPORT_SIZE (1) 0x95, 1, // REPORT_COUNT (3) 0x09, 48, // USAGE (Direction_x) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 49, // USAGE (Direction_y) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x05, 13, // USAGE_PAGE (Digitizer) 0xc0, // END_COLLECTION 0x05, 13, // USAGE_PAGE (Digitizer) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 65535, // LOGICAL_MAXIMUM (1) 0x55,12, //UNIT EXPONENT 0x65, 4097, //UNIT 0x75, 16, // REPORT_SIZE (1) 0x95, 1, // REPORT_COUNT (3) 0x09, 86, // USAGE (Unknown) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x85, 116, // REPORT ID (116) 0x09, 85, // USAGE (Max Contact Count) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 31, // LOGICAL_MAXIMUM (1) 0x75, 8, // REPORT_SIZE (1) 0x95, 1, // REPORT_COUNT (3) 0xB1, 0x02, // FEATURE (Data,Var,Abs) 0x85, 117, // REPORT ID (116) 0x06, 0,0xFF, // USAGE PAGE(Vendor Specific) 0x09, 197, // USAGE (Unknown) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 255, // LOGICAL_MAXIMUM (1) 0x75, 8, // REPORT_SIZE (1) 0x95, 256, // REPORT_COUNT (3) 0xB1, 0x02, // FEATURE (Data,Var,Abs) 0xc0, // END_COLLECTION 0x05, 13, // USAGE PAGE(Digitizer) 0x09, 0, // USAGE (Undefined) 0xa1, 0, // COLLECTION (Physical) 0x85, 119, // REPORT ID (116) 0x09, 32, // USAGE (Stylus) 0xa1, 0, // COLLECTION (Physical) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 1, // LOGICAL_MAXIMUM (1) 0x75, 1, // REPORT_SIZE (1) 0x95, 1, // REPORT_COUNT (3) 0x09, 66, // USAGE (Tip Switch) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 50, // USAGE (Direction_y) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 68, // USAGE (Direction_y) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 69, // USAGE (Direction_y) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x95, 4, // REPORT_COUNT (3) 0x81, 0x03, // INPUT (Data,Var,Abs) 0x05, 1, // USAGE_PAGE (Digitizer) 0x55, 0, //UNIT EXPONENT 0x65, 17, //UNIT 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 4095, // LOGICAL_MAXIMUM (1) 0x35, 0, // Physical Minimum 0x45, 4095, //Physical Maximum 0x75, 16, // REPORT_SIZE (1) 0x95, 1, // REPORT_COUNT (3) 0x09, 48, // USAGE (Direction_x) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x09, 49, // USAGE (Direction_y) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x05, 13, // USAGE PAGE(Digitizer) 0x09, 48, // USAGE (Tip Pressure) 0x15, 1, // LOGICAL_MINIMUM (0) 0x25, 255, // LOGICAL_MAXIMUM (1) 0x75, 8, // REPORT_SIZE (1) 0x95, 1, // REPORT_COUNT (3) 0x81, 0x02, // INPUT (Data,Var,Abs) 0xc0, // END_COLLECTION 0xc0, // END_COLLECTION 0x05, 13, // USAGE_PAGE (Digitizer) 0x09, 14, // USAGE (Unknown) 0xa1, 0, // COLLECTION (Physical) 0x85, 113, // REPORT ID (116) 0x09, 35, // USAGE (Unknown) 0xa1, 0, // COLLECTION (Physical) 0x09, 82, // USAGE (Tip Switch) 0x09, 83, // USAGE (Tip Switch) 0x15, 0, // LOGICAL_MINIMUM (0) 0x25, 10, // LOGICAL_MAXIMUM (1) 0x75, 8, // REPORT_SIZE (1) 0x95, 2, // REPORT_COUNT (3) 0xB1, 0x02, // FEATURE (Data,Var,Abs) 0xc0, // END_COLLECTION 0xc0, // END_COLLECTION }; /* Configuration Packet Instance * * This is an instance of the configuration_packet struct containing all the * data describing a single configuration of this device. It is wise to use * as much C here as possible, such as sizeof() operators, and #defines from * usb_config.h. When stuff is wrong here, it can be difficult to track * down exactly why, so it's good to get the compiler to do as much of it * for you as it can. */ static const ROMPTR struct configuration_1_packet configuration_1 = { { // Members from struct configuration_descriptor sizeof(struct configuration_descriptor), DESC_CONFIGURATION, sizeof(configuration_1), // wTotalLength (length of the whole packet) 3, // bNumInterfaces 1, // bConfigurationValue 2, // iConfiguration (index of string descriptor) 0b10000000, 100/2, // 100/2 indicates 100mA }, { // Members from struct interface_descriptor sizeof(struct interface_descriptor), // bLength; DESC_INTERFACE, 0x0, // InterfaceNumber 0x0, // AlternateSetting 0x2, // bNumEndpoints (num besides endpoint 0) HID_INTERFACE_CLASS, // bInterfaceClass 3=HID, 0xFF=VendorDefined 0x00, // bInterfaceSubclass (0=NoBootInterface for HID) 0x00, // bInterfaceProtocol 0x02, // iInterface (index of string describing interface) }, { // Members from struct hid_descriptor sizeof(struct hid_descriptor), DESC_HID, 0x0101, // bcdHID 0x0, // bCountryCode 1, // bNumDescriptors DESC_REPORT, // bDescriptorType2 sizeof(mouse_report_descriptor), // wDescriptorLength }, { // Members of the Endpoint Descriptor (EP1 IN) sizeof(struct endpoint_descriptor), DESC_ENDPOINT, 0x01 | 0x80, // endpoint #1 0x80=IN EP_INTERRUPT, // bmAttributes EP_1_IN_LEN, // wMaxPacketSize 1, // bInterval in ms. }, { // Members of the Endpoint Descriptor (EP1 OUT) sizeof(struct endpoint_descriptor), DESC_ENDPOINT, 0x01 /*| 0x00*/, // endpoint #1 0x00=OUT EP_INTERRUPT, // bmAttributes EP_1_OUT_LEN, // wMaxPacketSize 1, // bInterval in ms. }, }; /* String Descriptors * * String descriptors are optional. If strings are used, string #0 is * required, and must contain the language ID of the other strings. See * Chapter 9 of the USB specification from usb.org for more info. * * Strings are UTF-16 Unicode, and are not NULL-terminated, hence the * unusual syntax. */ /* String index 0, only has one character in it, which is to be set to the language ID of the language which the other strings are in. */ static const ROMPTR struct {uint8_t bLength;uint8_t bDescriptorType; uint16_t lang; } str00 = { sizeof(str00), DESC_STRING, 0x0409 // US English }; static const ROMPTR struct {uint8_t bLength;uint8_t bDescriptorType; uint16_t chars[6]; } vendor_string = { sizeof(vendor_string), DESC_STRING, {'K','o','r','t','e','k'} }; static const ROMPTR struct {uint8_t bLength;uint8_t bDescriptorType; uint16_t chars[14]; } product_string = { sizeof(product_string), DESC_STRING, {'K','o','r','t','e','k',' ','T','o','u','c','h'} }; static const ROMPTR struct {uint8_t bLength;uint8_t bDescriptorType; uint16_t chars[11]; } interface_string = { sizeof(interface_string), DESC_STRING, {'I','n','t','e','r','f','a','c','e',' ','1'} }; /* Get String function * * This function is called by the USB stack to get a pointer to a string * descriptor. If using strings, USB_STRING_DESCRIPTOR_FUNC must be defined * to the name of this function in usb_config.h. See * USB_STRING_DESCRIPTOR_FUNC in usb.h for information about this function. * This is a function, and not simply a list or map, because it is useful, * and advisable, to have a serial number string which may be read from * EEPROM or somewhere that's not part of static program memory. */ int16_t usb_application_get_string(uint8_t string_number, const void **ptr) { if (string_number == 0) { *ptr = &str00; return sizeof(str00); } else if (string_number == 1) { *ptr = &vendor_string; return sizeof(vendor_string); } else if (string_number == 2) { *ptr = &product_string; return sizeof(product_string); } else if (string_number == 3) { /* This is where you might have code to do something like read a serial number out of EEPROM and return it. */ return -1; } return -1; } /* Configuration Descriptor List * * This is the list of pointters to the device's configuration descriptors. * The USB stack will read this array looking for descriptors which are * requsted from the host. USB_CONFIG_DESCRIPTOR_MAP must be defined to the * name of this array in usb_config.h. See USB_CONFIG_DESCRIPTOR_MAP in * usb.h for information about this array. The order of the descriptors is * not important, as the USB stack reads bConfigurationValue for each * descriptor to know its index. Make sure NUMBER_OF_CONFIGURATIONS in * usb_config.h matches the number of descriptors in this array. */ const struct configuration_descriptor *usb_application_config_descs[] = { (struct configuration_descriptor*) &configuration_1, }; STATIC_SIZE_CHECK_EQUAL(USB_ARRAYLEN(USB_CONFIG_DESCRIPTOR_MAP), NUMBER_OF_CONFIGURATIONS); STATIC_SIZE_CHECK_EQUAL(sizeof(USB_DEVICE_DESCRIPTOR), 18); /* HID Descriptor Function */ int16_t usb_application_get_hid_descriptor(uint8_t interface, const void **ptr) { /* Only one interface in this demo. The two-step assignment avoids an * incorrect error in XC8 on PIC16. */ const void *p = &configuration_1.hid; *ptr = p; return sizeof(configuration_1.hid); } /** HID Report Descriptor Function */ int16_t usb_application_get_hid_report_descriptor(uint8_t interface, const void **ptr) { *ptr = mouse_report_descriptor; return sizeof(mouse_report_descriptor); }