/******************************************************************************* * HID Report Descriptors ******************************************************************************/ const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = { HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ HID_RI_USAGE(8, 0x06), /* Keyboard */ HID_RI_COLLECTION(8, 0x01), /* Application */ HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */ HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */ HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */ HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MAXIMUM(8, 0x01), HID_RI_REPORT_COUNT(8, 0x08), HID_RI_REPORT_SIZE(8, 0x01), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), HID_RI_REPORT_COUNT(8, 0x01), HID_RI_REPORT_SIZE(8, 0x08), HID_RI_INPUT(8, HID_IOF_CONSTANT), /* reserved */ HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */ HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */ HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */ HID_RI_REPORT_COUNT(8, 0x05), HID_RI_REPORT_SIZE(8, 0x01), HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), HID_RI_REPORT_COUNT(8, 0x01), HID_RI_REPORT_SIZE(8, 0x03),
/** HID class report descriptor. This is a special descriptor constructed with values from the * USBIF HID class specification to describe the reports and capabilities of the HID device. This * descriptor is parsed by the host and its contents used to determine what data (and in what encoding) * the device will send, and what it may be sent back from the host. Refer to the HID specification for * more details on HID report descriptors. */ const USB_Descriptor_HIDReport_Datatype_t HIDReport[] = { HID_RI_USAGE_PAGE(16, 0xFFDC), /* Vendor Page 0xDC */ HID_RI_USAGE(8, 0xFB), /* Vendor Usage 0xFB */ HID_RI_COLLECTION(8, 0x01), /* Vendor Usage 1 */ HID_RI_USAGE(8, 0x02), /* Vendor Usage 2 */ HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MAXIMUM(8, 0xFF), HID_RI_REPORT_SIZE(8, 0x08), HID_RI_REPORT_COUNT(16, (sizeof(uint16_t) + SPM_PAGESIZE)), HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), HID_RI_END_COLLECTION(0), }; /** 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. */ const USB_Descriptor_Device_t DeviceDescriptor = { .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, .USBSpecification = VERSION_BCD(01.10), .Class = USB_CSCP_NoDeviceClass,
uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, uint16_t ReportSize, HID_ReportInfo_t* const ParserData) { HID_StateTable_t StateTable[HID_STATETABLE_STACK_DEPTH]; HID_StateTable_t* CurrStateTable = &StateTable[0]; HID_CollectionPath_t* CurrCollectionPath = NULL; HID_ReportSizeInfo_t* CurrReportIDInfo = &ParserData->ReportIDSizes[0]; uint16_t UsageList[HID_USAGE_STACK_DEPTH]; uint8_t UsageListSize = 0; HID_MinMax_t UsageMinMax = {0, 0}; memset(ParserData, 0x00, sizeof(HID_ReportInfo_t)); memset(CurrStateTable, 0x00, sizeof(HID_StateTable_t)); memset(CurrReportIDInfo, 0x00, sizeof(HID_ReportSizeInfo_t)); ParserData->TotalDeviceReports = 1; while (ReportSize) { uint8_t HIDReportItem = *ReportData; uint32_t ReportItemData = 0; ReportData++; ReportSize--; switch (HIDReportItem & HID_RI_DATA_SIZE_MASK) { case HID_RI_DATA_BITS_32: ReportItemData = le32_to_cpu(*((uint32_t*)ReportData)); ReportSize -= 4; ReportData += 4; break; case HID_RI_DATA_BITS_16: ReportItemData = le16_to_cpu(*((uint16_t*)ReportData)); ReportSize -= 2; ReportData += 2; break; case HID_RI_DATA_BITS_8: ReportItemData = *((uint8_t*)ReportData); ReportSize -= 1; ReportData += 1; break; } switch (HIDReportItem & (HID_RI_TYPE_MASK | HID_RI_TAG_MASK)) { case HID_RI_PUSH(0): if (CurrStateTable == &StateTable[HID_STATETABLE_STACK_DEPTH - 1]) return HID_PARSE_HIDStackOverflow; memcpy((CurrStateTable + 1), CurrStateTable, sizeof(HID_ReportItem_t)); CurrStateTable++; break; case HID_RI_POP(0): if (CurrStateTable == &StateTable[0]) return HID_PARSE_HIDStackUnderflow; CurrStateTable--; break; case HID_RI_USAGE_PAGE(0): if ((HIDReportItem & HID_RI_DATA_SIZE_MASK) == HID_RI_DATA_BITS_32) CurrStateTable->Attributes.Usage.Page = (ReportItemData >> 16); CurrStateTable->Attributes.Usage.Page = ReportItemData; break; case HID_RI_LOGICAL_MINIMUM(0): CurrStateTable->Attributes.Logical.Minimum = ReportItemData; break; case HID_RI_LOGICAL_MAXIMUM(0): CurrStateTable->Attributes.Logical.Maximum = ReportItemData; break; case HID_RI_PHYSICAL_MINIMUM(0): CurrStateTable->Attributes.Physical.Minimum = ReportItemData; break; case HID_RI_PHYSICAL_MAXIMUM(0): CurrStateTable->Attributes.Physical.Maximum = ReportItemData; break; case HID_RI_UNIT_EXPONENT(0): CurrStateTable->Attributes.Unit.Exponent = ReportItemData; break; case HID_RI_UNIT(0): CurrStateTable->Attributes.Unit.Type = ReportItemData; break; case HID_RI_REPORT_SIZE(0): CurrStateTable->Attributes.BitSize = ReportItemData; break; case HID_RI_REPORT_COUNT(0): CurrStateTable->ReportCount = ReportItemData; break; case HID_RI_REPORT_ID(0): CurrStateTable->ReportID = ReportItemData; if (ParserData->UsingReportIDs) { CurrReportIDInfo = NULL; for (uint8_t i = 0; i < ParserData->TotalDeviceReports; i++) { if (ParserData->ReportIDSizes[i].ReportID == CurrStateTable->ReportID) { CurrReportIDInfo = &ParserData->ReportIDSizes[i]; break; } } if (CurrReportIDInfo == NULL) { if (ParserData->TotalDeviceReports == HID_MAX_REPORT_IDS) return HID_PARSE_InsufficientReportIDItems; CurrReportIDInfo = &ParserData->ReportIDSizes[ParserData->TotalDeviceReports++]; memset(CurrReportIDInfo, 0x00, sizeof(HID_ReportSizeInfo_t)); } } ParserData->UsingReportIDs = true; CurrReportIDInfo->ReportID = CurrStateTable->ReportID; break; case HID_RI_USAGE(0): if (UsageListSize == HID_USAGE_STACK_DEPTH) return HID_PARSE_UsageListOverflow; UsageList[UsageListSize++] = ReportItemData; break; case HID_RI_USAGE_MINIMUM(0): UsageMinMax.Minimum = ReportItemData; break; case HID_RI_USAGE_MAXIMUM(0): UsageMinMax.Maximum = ReportItemData; break; case HID_RI_COLLECTION(0): if (CurrCollectionPath == NULL) { CurrCollectionPath = &ParserData->CollectionPaths[0]; } else { HID_CollectionPath_t* ParentCollectionPath = CurrCollectionPath; CurrCollectionPath = &ParserData->CollectionPaths[1]; while (CurrCollectionPath->Parent != NULL) { if (CurrCollectionPath == &ParserData->CollectionPaths[HID_MAX_COLLECTIONS - 1]) return HID_PARSE_InsufficientCollectionPaths; CurrCollectionPath++; } CurrCollectionPath->Parent = ParentCollectionPath; } CurrCollectionPath->Type = ReportItemData; CurrCollectionPath->Usage.Page = CurrStateTable->Attributes.Usage.Page; if (UsageListSize) { CurrCollectionPath->Usage.Usage = UsageList[0]; for (uint8_t i = 0; i < UsageListSize; i++) UsageList[i] = UsageList[i + 1]; UsageListSize--; } else if (UsageMinMax.Minimum <= UsageMinMax.Maximum) { CurrCollectionPath->Usage.Usage = UsageMinMax.Minimum++; } break; case HID_RI_END_COLLECTION(0): if (CurrCollectionPath == NULL) return HID_PARSE_UnexpectedEndCollection; CurrCollectionPath = CurrCollectionPath->Parent; break; case HID_RI_INPUT(0): case HID_RI_OUTPUT(0): case HID_RI_FEATURE(0): for (uint8_t ReportItemNum = 0; ReportItemNum < CurrStateTable->ReportCount; ReportItemNum++) { HID_ReportItem_t NewReportItem; memcpy(&NewReportItem.Attributes, &CurrStateTable->Attributes, sizeof(HID_ReportItem_Attributes_t)); NewReportItem.ItemFlags = ReportItemData; NewReportItem.CollectionPath = CurrCollectionPath; NewReportItem.ReportID = CurrStateTable->ReportID; if (UsageListSize) { NewReportItem.Attributes.Usage.Usage = UsageList[0]; for (uint8_t i = 0; i < UsageListSize; i++) UsageList[i] = UsageList[i + 1]; UsageListSize--; } else if (UsageMinMax.Minimum <= UsageMinMax.Maximum) { NewReportItem.Attributes.Usage.Usage = UsageMinMax.Minimum++; } uint8_t ItemTypeTag = (HIDReportItem & (HID_RI_TYPE_MASK | HID_RI_TAG_MASK)); if (ItemTypeTag == HID_RI_INPUT(0)) NewReportItem.ItemType = HID_REPORT_ITEM_In; else if (ItemTypeTag == HID_RI_OUTPUT(0)) NewReportItem.ItemType = HID_REPORT_ITEM_Out; else NewReportItem.ItemType = HID_REPORT_ITEM_Feature; NewReportItem.BitOffset = CurrReportIDInfo->ReportSizeBits[NewReportItem.ItemType]; CurrReportIDInfo->ReportSizeBits[NewReportItem.ItemType] += CurrStateTable->Attributes.BitSize; ParserData->LargestReportSizeBits = MAX(ParserData->LargestReportSizeBits, CurrReportIDInfo->ReportSizeBits[NewReportItem.ItemType]); if (ParserData->TotalReportItems == HID_MAX_REPORTITEMS) return HID_PARSE_InsufficientReportItems; memcpy(&ParserData->ReportItems[ParserData->TotalReportItems], &NewReportItem, sizeof(HID_ReportItem_t)); if (!(ReportItemData & HID_IOF_CONSTANT) && CALLBACK_HIDParser_FilterHIDReportItem(&NewReportItem)) ParserData->TotalReportItems++; } break; } if ((HIDReportItem & HID_RI_TYPE_MASK) == HID_RI_TYPE_MAIN) { UsageMinMax.Minimum = 0; UsageMinMax.Maximum = 0; UsageListSize = 0; } } if (!(ParserData->TotalReportItems)) return HID_PARSE_NoUnfilteredReportItems; return HID_PARSE_Successful; }
/** HID class report descriptor. This is a special descriptor constructed with values from the * USBIF HID class specification to describe the reports and capabilities of the HID device. This * descriptor is parsed by the host and its contents used to determine what data (and in what encoding) * the device will send, and what it may be sent back from the host. Refer to the HID specification for * more details on HID report descriptors. */ const USB_Descriptor_HIDReport_Datatype_t PROGMEM GenericReport[] = { HID_RI_USAGE_PAGE(16, 0xFF00), /* Vendor Page 0 */ HID_RI_USAGE(8, 0x01), /* Vendor Usage 1 */ HID_RI_COLLECTION(8, 0x01), /* Vendor Usage 1 */ HID_RI_USAGE(8, 0x02), /* Vendor Usage 2 */ HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MAXIMUM(8, 0xFF), HID_RI_REPORT_SIZE(8, 0x08), HID_RI_REPORT_COUNT(8, GENERIC_REPORT_SIZE), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), HID_RI_USAGE(8, 0x03), /* Vendor Usage 3 */ HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MAXIMUM(8, 0xFF), HID_RI_REPORT_SIZE(8, 0x08), HID_RI_REPORT_COUNT(8, GENERIC_REPORT_SIZE), HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), HID_RI_END_COLLECTION(0), }; /** 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. */
*/ const USB_Descriptor_HIDReport_Datatype_t PROGMEM HIDReport[] = { /* Mouse Report */ HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ HID_RI_USAGE(8, 0x02), /* Mouse */ HID_RI_COLLECTION(8, 0x01), /* Application */ HID_RI_REPORT_ID(8, HID_REPORTID_MouseReport), HID_RI_USAGE(8, 0x01), /* Pointer */ HID_RI_COLLECTION(8, 0x00), /* Physical */ HID_RI_USAGE_PAGE(8, 0x09), /* Button */ HID_RI_USAGE_MINIMUM(8, 0x01), HID_RI_USAGE_MAXIMUM(8, 0x03), HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MAXIMUM(8, 0x01), HID_RI_REPORT_COUNT(8, 0x03), HID_RI_REPORT_SIZE(8, 0x01), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), HID_RI_REPORT_COUNT(8, 0x01), HID_RI_REPORT_SIZE(8, 0x05), HID_RI_INPUT(8, HID_IOF_CONSTANT), HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ HID_RI_USAGE(8, 0x30), /* Usage X */ HID_RI_USAGE(8, 0x31), /* Usage Y */ HID_RI_LOGICAL_MINIMUM(8, -1), HID_RI_LOGICAL_MAXIMUM(8, 1), HID_RI_PHYSICAL_MINIMUM(8, -1), HID_RI_PHYSICAL_MAXIMUM(8, 1), HID_RI_REPORT_COUNT(8, 0x02), HID_RI_REPORT_SIZE(8, 0x08), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
* the device will send, and what it may be sent back from the host. Refer to the HID specification for * more details on HID report descriptors. */ const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] = { HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ HID_RI_USAGE(8, 0x02), /* Mouse */ HID_RI_COLLECTION(8, 0x01), /* Application */ HID_RI_USAGE(8, 0x01), /* Pointer */ HID_RI_COLLECTION(8, 0x00), /* Physical */ HID_RI_USAGE_PAGE(8, 0x09), /* Button */ HID_RI_USAGE_MINIMUM(8, 0x01), HID_RI_USAGE_MAXIMUM(8, 0x03), HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MAXIMUM(8, 0x01), HID_RI_REPORT_COUNT(8, 0x03), HID_RI_REPORT_SIZE(8, 0x01), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), HID_RI_REPORT_COUNT(8, 0x01), HID_RI_REPORT_SIZE(8, 0x05), HID_RI_INPUT(8, HID_IOF_CONSTANT), HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ HID_RI_USAGE(8, 0x30), /* Usage X */ HID_RI_USAGE(8, 0x31), /* Usage Y */ HID_RI_LOGICAL_MINIMUM(8, -1), HID_RI_LOGICAL_MAXIMUM(8, 1), HID_RI_PHYSICAL_MINIMUM(8, -1), HID_RI_PHYSICAL_MAXIMUM(8, 1), HID_RI_REPORT_COUNT(8, 0x02), HID_RI_REPORT_SIZE(8, 0x08), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
#define SHARED_REPORT_STARTED #else const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = { #endif HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ HID_RI_USAGE(8, 0x06), /* Keyboard */ HID_RI_COLLECTION(8, 0x01), /* Application */ # ifdef KEYBOARD_SHARED_EP HID_RI_REPORT_ID(8, REPORT_ID_KEYBOARD), # endif HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */ HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */ HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */ HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MAXIMUM(8, 0x01), HID_RI_REPORT_COUNT(8, 0x08), HID_RI_REPORT_SIZE(8, 0x01), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), HID_RI_REPORT_COUNT(8, 0x01), HID_RI_REPORT_SIZE(8, 0x08), HID_RI_INPUT(8, HID_IOF_CONSTANT), /* reserved */ HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */ HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */ HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */ HID_RI_REPORT_COUNT(8, 0x05), HID_RI_REPORT_SIZE(8, 0x01), HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), HID_RI_REPORT_COUNT(8, 0x01), HID_RI_REPORT_SIZE(8, 0x03),
#include "util.h" #include "descriptor.h" /******************************************************************************* * HID Report Descriptors ******************************************************************************/ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] = { HID_RI_USAGE_PAGE(16, 0xFF31), /* Vendor Page(PJRC Teensy compatible) */ HID_RI_USAGE(8, 0x74), /* Vendor Usage(PJRC Teensy compatible) */ HID_RI_COLLECTION(8, 0x01), /* Application */ HID_RI_USAGE(8, 0x75), /* Vendor Usage 0x75 */ HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MAXIMUM(8, 0xFF), HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE), HID_RI_REPORT_SIZE(8, 0x08), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), HID_RI_USAGE(8, 0x76), /* Vendor Usage 0x76 */ HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MAXIMUM(8, 0xFF), HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE), HID_RI_REPORT_SIZE(8, 0x08), HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), HID_RI_END_COLLECTION(0), }; /******************************************************************************* * Device Descriptors ******************************************************************************/
HID_RI_USAGE_PAGE(8, 0x0C), /* Consumer Page */ HID_RI_USAGE(8, 0x01), /* Consumer Controls */ HID_RI_COLLECTION(8, 0x01), /* Application */ HID_RI_USAGE(8, 0xB0), /* Play */ HID_RI_USAGE(8, 0xB1), /* Pause */ HID_RI_USAGE(8, 0xB3), /* Fast Forward */ HID_RI_USAGE(8, 0xB4), /* Rewind */ HID_RI_USAGE(8, 0xB5), /* Next Track */ HID_RI_USAGE(8, 0xB6), /* Previous Track */ HID_RI_USAGE(8, 0xB7), /* Stop */ HID_RI_USAGE(16, 0x09CD), /* Play/Pause (toggle) */ HID_RI_USAGE(8, 0xE2), /* Mute */ HID_RI_USAGE(8, 0xE9), /* Volume Up */ HID_RI_USAGE(8, 0xEA), /* Volume Down */ HID_RI_REPORT_SIZE(8, 0x01), HID_RI_REPORT_COUNT(8, 0x0B), HID_RI_LOGICAL_MINIMUM(8, 0), HID_RI_LOGICAL_MAXIMUM(8, 1), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE), HID_RI_REPORT_COUNT(8, 0x05), HID_RI_INPUT(8, HID_IOF_CONSTANT), HID_RI_END_COLLECTION(0), }; /** 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. */ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = {
*/ //HID_DESCRIPTOR_JOYSTICK(-100, 100, -1, 1, 2) //HID_DESCRIPTOR_JOYSTICK(MinAxisVal, MaxAxisVal, MinPhysicalVal, MaxPhysicalVal, Buttons) HID_RI_USAGE_PAGE(8, 0x01), HID_RI_USAGE(8, 0x04), HID_RI_COLLECTION(8, 0x01), HID_RI_USAGE(8, 0x01), HID_RI_COLLECTION(8, 0x00), HID_RI_USAGE(8, 0x30), HID_RI_USAGE(8, 0x31), HID_RI_USAGE(8, 0x32), HID_RI_LOGICAL_MINIMUM(16, -16384), HID_RI_LOGICAL_MAXIMUM(16, 16384), HID_RI_PHYSICAL_MINIMUM(16, -1), HID_RI_PHYSICAL_MAXIMUM(16, 1), HID_RI_REPORT_COUNT(8, 4), HID_RI_REPORT_SIZE(8, 16), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), HID_RI_END_COLLECTION(0), HID_RI_USAGE_PAGE(8, 0x09), HID_RI_USAGE_MINIMUM(8, 0x01), HID_RI_USAGE_MAXIMUM(8, 4), HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MAXIMUM(8, 0x01), HID_RI_REPORT_SIZE(8, 0x01), HID_RI_REPORT_COUNT(8, 4), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), HID_RI_REPORT_SIZE(8, 1), HID_RI_REPORT_COUNT(8, 0x01), HID_RI_INPUT(8, HID_IOF_CONSTANT), HID_RI_END_COLLECTION(0)
* descriptor is parsed by the host and its contents used to determine what data (and in what encoding) * the device will send, and what it may be sent back from the host. Refer to the HID specification for * more details on HID report descriptors. */ const USB_Descriptor_HIDReport_Datatype_t PROGMEM HapReport[] = { HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ HID_RI_USAGE(8, 0x05), /* Gamepad */ HID_RI_COLLECTION(8, 0x01), /* Application */ HID_RI_USAGE(8, 0x01), /* Pointer */ HID_RI_COLLECTION(8, 0x00), /* Physical */ HID_RI_USAGE(8, 0x30), /* Usage X */ HID_RI_USAGE(8, 0x31), /* Usage Y */ HID_RI_LOGICAL_MINIMUM(8, -1), HID_RI_LOGICAL_MAXIMUM(8, 1), HID_RI_REPORT_COUNT(8, 0x02), HID_RI_REPORT_SIZE(8, 0x02), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), HID_RI_INPUT(8, HID_IOF_CONSTANT), HID_RI_END_COLLECTION(0), HID_RI_USAGE_PAGE(8, 0x09), /* Button */ HID_RI_USAGE_MINIMUM(8, 0x01), HID_RI_USAGE_MAXIMUM(8, 0x08), HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MAXIMUM(8, 0x01), HID_RI_REPORT_SIZE(8, 0x01), HID_RI_REPORT_COUNT(8, 0x08), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), HID_RI_END_COLLECTION(0), };
/** HID class report descriptor. This is a special descriptor constructed with values from the * USBIF HID class specification to describe the reports and capabilities of the HID device. This * descriptor is parsed by the host and its contents used to determine what data (and in what encoding) * the device will send, and what it may be sent back from the host. Refer to the HID specification for * more details on HID report descriptors. */ const USB_Descriptor_HIDReport_Datatype_t PROGMEM GenericReport[] = { HID_RI_USAGE_PAGE(16, 0xFF00), /* Vendor Page 0 */ HID_RI_USAGE(8, 0x01), /* Vendor Usage 1 */ HID_RI_COLLECTION(8, 0x01), /* Vendor Usage 1 */ HID_RI_USAGE(8, 0x02), /* Vendor Usage 2 */ HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MAXIMUM(8, 0xFF), HID_RI_REPORT_SIZE(8, BUFFER_EPSIZE), HID_RI_REPORT_COUNT(8, BUFFER_EPSIZE), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), HID_RI_USAGE(8, 0x03), /* Vendor Usage 3 */ HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MAXIMUM(8, 0xFF), HID_RI_REPORT_SIZE(8, BUFFER_EPSIZE), HID_RI_REPORT_COUNT(8, BUFFER_EPSIZE), HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), HID_RI_END_COLLECTION(0), }; const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = { HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ HID_RI_USAGE(8, 0x06), /* Keyboard */ HID_RI_COLLECTION(8, 0x01), /* Application */
#define MY_EPADDR (ENDPOINT_DIR_IN | 1) #define MY_EPSIZE 1 // See http://msdn.microsoft.com/en-us/windows/hardware/gg462991.aspx const USB_Descriptor_HIDReport_Datatype_t PROGMEM reportDescriptor[] = { HID_RI_USAGE_PAGE(8, 0x0c), /* Consumer Page */ HID_RI_USAGE(8, 0x01), /* Consumer Controls */ HID_RI_COLLECTION(8, 0x01), /* Application */ HID_RI_LOGICAL_MINIMUM(8, 0), HID_RI_LOGICAL_MAXIMUM(8, 1), HID_RI_USAGE(8, 0xE9), /* Volume Up */ HID_RI_USAGE(8, 0xEA), /* Volume Down */ HID_RI_REPORT_SIZE(8, 1), HID_RI_REPORT_COUNT(8, 2), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), // Up/Down repeats on the host when you keep pressing. HID_RI_USAGE(8, 0xE2), /* Mute */ HID_RI_REPORT_COUNT(8, 1), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE), // Mute toggles the state on the host because this is 'Relative'. HID_RI_REPORT_COUNT(8, 5), HID_RI_INPUT(8, HID_IOF_CONSTANT), HID_RI_END_COLLECTION(0), }; typedef struct {
*outDescriptor = &kDescriptor; return pgm_read_byte(&kDescriptor.Header.Size); } static uint8_t const PROGMEM kMouseReportDescriptor[] = { HID_RI_USAGE_PAGE(8, 1), // 1 = Generic Desktop HID_RI_USAGE(8, 2), // 2 = Mouse HID_RI_COLLECTION(8, 1), // 1 = Application HID_RI_USAGE(8, 1), // 1 = Pointer HID_RI_COLLECTION(8, 0), // 0 = Physical HID_RI_USAGE_PAGE(8, 9), // 9 = Buttons HID_RI_USAGE_MINIMUM(8, 1), // 1 = first button number HID_RI_USAGE_MAXIMUM(8, 3), // 3 = last button number HID_RI_LOGICAL_MINIMUM(8, 0), // 0 = application value for bit value 0 HID_RI_LOGICAL_MAXIMUM(8, 1), // 1 = application value for bit value 1 HID_RI_REPORT_COUNT(8, 3), // 3 = number of buttons HID_RI_REPORT_SIZE(8, 1), // 1 = bits reported per button HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), // Define the button fields HID_RI_REPORT_COUNT(8, 1), // 1 = number of padding fields HID_RI_REPORT_SIZE(8, 5), // 5 = number of bits in padding field HID_RI_INPUT(8, HID_IOF_CONSTANT), // Define the padding field HID_RI_USAGE_PAGE(8, 1), // 1 = Generic Desktop HID_RI_USAGE(8, 0x30), // 0x30 = X axis HID_RI_USAGE(8, 0x31), // 0x31 = Y axis, HID_RI_LOGICAL_MINIMUM(8, -127), // -127 = minimum report value HID_RI_LOGICAL_MAXIMUM(8, 127), // 127 = maximum report value HID_RI_REPORT_SIZE(8, 8), // 8 = bits per axis HID_RI_REPORT_COUNT(8, 2), // 2 = number of axes HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE), // Define the axis fields HID_RI_END_COLLECTION(0), HID_RI_END_COLLECTION(0)
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ HID_RI_USAGE(8, 0x04), /* Joystick */ HID_RI_COLLECTION(8, 0x01), /* Application */ HID_RI_REPORT_ID(8, HID_REPORTID_JoystickReport), HID_RI_USAGE(8, 0x01), /* Pointer */ HID_RI_COLLECTION(8, 0x00), /* Physical */ HID_RI_USAGE(8, 0x30), /* Usage X */ HID_RI_USAGE(8, 0x31), /* Usage Y */ HID_RI_USAGE(8, 0x32), /* Usage X */ //JW added - can add more as 34, 35 etc HID_RI_USAGE(8, 0x33), /* Usage Y */ HID_RI_LOGICAL_MINIMUM(8, -128), HID_RI_LOGICAL_MAXIMUM(8, 127), HID_RI_PHYSICAL_MINIMUM(8, -1), HID_RI_PHYSICAL_MAXIMUM(8, 1), //HID_RI_REPORT_COUNT(8, 0x02), //increase axis from 2 to 4 HID_RI_REPORT_COUNT(8, 0x04), HID_RI_REPORT_SIZE(8, 0x08), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), HID_RI_END_COLLECTION(0), //Hat Switch Start (Working) HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop 0x09, 0x39, // USAGE (Hat switch) 0x95, 0x01, // REPORT_COUNT (1) 0x75, 0x04, // REPORT_SIZE (4) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x07, // LOGICAL_MAXIMUM (7) 0x46, 0x3B, 0x01, // PHYSICAL_MAXIMUM (315) 0x65, 0x14, // UNIT (Eng Rot:Angular Pos) 0x81, 0x42, // INPUT (Data,Var,Abs,Null) 4b Hat 0x75, 0x04, // REPORT_SIZE (4)
//Keyboard and media report const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = { /* Keyboard Report */ HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ HID_RI_USAGE(8, 0x06), /* Keyboard */ HID_RI_COLLECTION(8, 0x01), /* Application */ HID_RI_REPORT_ID(8, KEYBOARD_REPORTID_KeyboardReport), HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */ HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */ HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */ HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MAXIMUM(8, 0x01), HID_RI_REPORT_SIZE(8, 0x01), HID_RI_REPORT_COUNT(8, 0x08), HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), HID_RI_REPORT_COUNT(8, 0x01), HID_RI_REPORT_SIZE(8, 0x08), HID_RI_INPUT(8, HID_IOF_CONSTANT), HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */ HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */ HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */ HID_RI_REPORT_COUNT(8, 0x05), HID_RI_REPORT_SIZE(8, 0x01), HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), HID_RI_REPORT_COUNT(8, 0x01), HID_RI_REPORT_SIZE(8, 0x03), HID_RI_OUTPUT(8, HID_IOF_CONSTANT), HID_RI_LOGICAL_MINIMUM(8, 0x00), HID_RI_LOGICAL_MAXIMUM(8, 0x65),