I'm trying to make a custom HID with following features: 32 bit data exchange between host and device, both directions. I'm doing this somewhat based on usb_dev_gamepad example for ek-tm4c123gxl and TivaWare USB library user guide 2.13 -> HID Device Class Driver. It means that I'm using tUSBDHIDDevice type instead of the tUSBDHIDGamepadDevice.
I created custom report descriptor using HID tools from usb dev site and I have problem with correct descriptor structures, which I found out using dmesg on linux:
[ 4552.256486] usb 4-1.1.3: new full-speed USB device number 85 using ehci-pci [ 4557.370017] usb 4-1.1.3: unable to read config index 0 descriptor/start: -110 [ 4557.370024] usb 4-1.1.3: can't read configurations, error -110
I also print some debug logs through UART0 and in RX handler I get USB_EVENT_SUSPENDED periodically.
Below I put my usb structures with descriptors. There is only one report concatenating both input and output usages (not sure about correctness of this) and I don't want it polled anyhow.
What I'm asking for is general verification of this (well fixing would be better case):
-is number of tUSBDHIDDevice.ui32NumStringDescriptors correct for my case?
-while writing this post I noticed that structure tUSBDHIDDevice differs in usblib/device/usbdhid.h from the one initialized in user guide, why there is this additional field ppsConfigDescriptor which is not initialized in user guide? ( I expect my dmesg log to be associated with it...)
-Does it matter which PID do I use? ( I picked USB_PID_MSC for no reason at all)
My descriptors:
//*****************************************************************************
const uint8_t g_pui8LangDescriptor[] =
{
4,
USB_DTYPE_STRING,
USBShort(USB_LANG_EN_US)
};
//*****************************************************************************
const uint8_t g_pui8ManufacturerString[] =
{
(9 + 1) * 2,
USB_DTYPE_STRING,
'R', 0, 'o', 0, 'b', 0, 'o', 0, 'm', 0, 'a', 0, 't', 0, 'i', 0, 'c', 0
};
//*****************************************************************************
//
// The product string.
//
//*****************************************************************************
const uint8_t g_pui8ProductString[] =
{
(8 + 1) * 2,
USB_DTYPE_STRING,
'B', 0, 'r', 0, 'a', 0, 'm', 0, 'k', 0, 'a', 0, 'L', 0, 'F', 0
};
//*****************************************************************************
//
// The serial number string.
//
//*****************************************************************************
const uint8_t g_pui8SerialNumberString[] =
{
(8 + 1) * 2,
USB_DTYPE_STRING,
'1', 0, '2', 0, '3', 0, '4', 0, '5', 0, '6', 0, '7', 0, '8', 0
};
//*****************************************************************************
const uint8_t g_pui8HIDInterfaceString[] =
{
(3 + 1) * 2,
USB_DTYPE_STRING,
'H', 0, 'I', 0, 'D', 0
};
//*****************************************************************************
const uint8_t g_pui8ConfigString[] =
{
(8 + 1) * 2,
USB_DTYPE_STRING,
'H', 0, 'i', 0, 'd', 0, ' ', 0, 'G', 0, 'a', 0, 't', 0, 'e', 0
};
//*****************************************************************************
//
// The descriptor string table.
//
//*****************************************************************************
const uint8_t * const g_ppui8StringDescriptors[] =
{
g_pui8LangDescriptor,
g_pui8ManufacturerString,
g_pui8ProductString,
g_pui8SerialNumberString,
g_pui8HIDInterfaceString,
g_pui8ConfigString
};
#define NUM_STRING_DESCRIPTORS (sizeof(g_ppui8StringDescriptors) / \
sizeof(uint8_t *))
static const uint8_t g_pui8TimeScoreReportDescriptor[] =
{
0x06, 0x00, 0xff, // USAGE_PAGE (Vendor Defined Page 1)
0xa1, 0x01, // COLLECTION (Application)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x27, 0xff, 0xff, 0xff, 0x7f, // LOGICAL_MAXIMUM (2147483647)
0x75, 0x20, // REPORT_SIZE (32)
0x85, 0x01, // REPORT_ID (1)
0x95, 0x01, // REPORT_COUNT (1)
0x09, 0x01, // USAGE (Vendor Usage 1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x85, 0x02, // REPORT_ID (2)
0x09, 0x01, // USAGE (Vendor Usage 1)
0x91, 0x02, // OUTPUT (Data,Var,Abs)
0xc0 // END_COLLECTION
};
static const uint8_t * const g_pGateClassDescriptors[] =
{
g_pui8TimeScoreReportDescriptor
};
static const tHIDDescriptor g_sGateHIDDescriptor =
{
9,
USB_HID_DTYPE_HID,
0x111,
0,
1,
USB_HID_DTYPE_REPORT,
sizeof(g_pui8TimeScoreReportDescriptor)
};
tHIDReportIdle g_psGateLFReportIdle[] =
{
{0, 1, 0, 0} // report 1 not polled to host in case of no state change
};
tUSBDHIDDevice g_sGateLFDevice =
{
USB_VID_TI_1CBE,
USB_PID_MSC,
0,
USB_STATUS_SELF_PWR,
USB_HID_SCLASS_NONE,
USB_HID_PROTOCOL_NONE,
1,
g_psGateLFReportIdle,
USBRxHandler,
(void *)&rxBuffer,
USBTxHandler,
(void *)&txBuffer,
true,
&g_sGateHIDDescriptor,
g_pGateClassDescriptors,
g_ppui8StringDescriptors,
7 //(1 + (5 + (num HID strings)) * (num languages))
};