I'm trying to convert the keyboard example for the Tiva C arms over to a custom data pipe with 64 byte frame size in and out. I started off by loading the keyboard example from the USB libraries (v1.1) into CCS. I've got that ported over for the TM4C123GH6PM launchpad and running.
I'm now just trying to mod the example to enumerate as a custom hid device so my windows application will see it. I have the custom data pipe running on an MSP430 board and it works fine with my application...no problems seeing the device. This keyboard example seems to still be enumerating as a system device though. I've got a packet sniffer to monitor the enumeration and it looks like no matter what I change in the usbdkeyb.c file (where all the descritpor values are) I can't change the USB_HID_SCLASS_BOOT and the USB_HID_PROTOCOL_KEYB. Those defines are for the keyboard and from what I understand I need to change them both to 0x00. I do this here, but when I check my packet sniffer log I still see it as 0x01 in the descriptors which says the subclass is of type keyboard. I've been struggling with this custom data pipe for a while now. I had to switch to these arm's and the usb support with the usblib library has been beyond confusing. Anyways, I feel like after fixing this it shouldn't come up as a keyboard anymore. It would be a huge help if someone could at least point me in the right direction as to what to modify where and if I've been on the right track or not. Below is some code snippets from the pertinant sections and I'll also upload my project. It isn't much different from the example since all I've been trying to do is get it to not come up as a keyboard (system device) but rather a custom hid device.
Descriptors:
static uint8_t g_pui8KeybDescriptor[] = { // // Configuration descriptor header. // 9, // Size of the configuration descriptor. USB_DTYPE_CONFIGURATION, // Type of this descriptor. USBShort(34), // The total size of this full structure. 1, // The number of interfaces in this // configuration. 1, // The unique value for this configuration. 5, // The string identifier that describes this // configuration. USB_CONF_ATTR_SELF_PWR, // Bus Powered, Self Powered, remote wake up. 250, // The maximum power in 2mA increments. }; //***************************************************************************** // // The remainder of the configuration descriptor is stored in flash since we // don't need to modify anything in it at runtime. // //***************************************************************************** static uint8_t g_pui8HIDInterface[HIDINTERFACE_SIZE] = { // // HID Device Class Interface Descriptor. // 9, // Size of the interface descriptor. USB_DTYPE_INTERFACE, // Type of this descriptor. 0, // The index for this interface. 0, // The alternate setting for this interface. 1, // The number of endpoints used by this // interface. USB_CLASS_HID, // The interface class //USB_HID_SCLASS_BOOT, // The interface sub-class. 0, //USB_HID_PROTOCOL_KEYB, // The interface protocol for the sub-class 0, // specified above. 4, // The string index for this interface. }; static const uint8_t g_pui8HIDInEndpoint[HIDINENDPOINT_SIZE] = { // // Interrupt IN endpoint descriptor // 7, // The size of the endpoint descriptor. USB_DTYPE_ENDPOINT, // Descriptor type is an endpoint. USB_EP_DESC_IN | USBEPToIndex(USB_EP_1), USB_EP_ATTR_INT, // Endpoint is an interrupt endpoint. USBShort(USBFIFOSizeToBytes(USB_FIFO_SZ_64)), // The maximum packet size. 16, // The polling interval for this endpoint. }; static const uint8_t g_pui8HIDOutEndpoint[HIDOUTENDPOINT_SIZE] = { // // Interrupt OUT endpoint descriptor // 7, // The size of the endpoint descriptor. USB_DTYPE_ENDPOINT, // Descriptor type is an endpoint. USB_EP_DESC_OUT | USBEPToIndex(USB_EP_2), USB_EP_ATTR_INT, // Endpoint is an interrupt endpoint. USBShort(USBFIFOSizeToBytes(USB_FIFO_SZ_64)), // The maximum packet size. 16, // The polling interval for this endpoint. }; //***************************************************************************** // // The following is the HID report structure definition that is passed back // to the host. // //***************************************************************************** static const uint8_t g_pui8KeybReportDescriptor[] = { //UsagePage(USB_HID_GENERIC_DESKTOP), //Usage(USB_HID_KEYBOARD), //Collection(USB_HID_APPLICATION), UsagePage(0xFF00), Usage(0x01), Collection(0x01), 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) 0x75, 0x08, // REPORT_SIZE (8) - bits // ------ input report ------ 0x95, 0x40, // REPORT_COUNT - bytes 0x09, 0x01, // USAGE (Vendor Usage 1) 0x81, 0x02, // INPUT (Data,Var,Abs) // ------ output report ------ EndCollection }; //***************************************************************************** // // The HID descriptor for the keyboard device. // //***************************************************************************** static const tHIDDescriptor g_sKeybHIDDescriptor = { 9, // bLength USB_HID_DTYPE_HID, // bDescriptorType //0x111, // bcdHID (version 1.11 compliant) 0x200 0, // bCountryCode (not localized) 1, // bNumDescriptors { { USB_HID_DTYPE_REPORT, // Report descriptor sizeof(g_pui8KeybReportDescriptor) // Size of report descriptor } } }; //***************************************************************************** // // The HID configuration descriptor is defined as four or five sections // depending upon the client's configuration choice. These sections are: // // 1. The 9 byte configuration descriptor (RAM). // 2. The interface descriptor (RAM). // 3. The HID report and physical descriptors (provided by the client) // (FLASH). // 4. The mandatory interrupt IN endpoint descriptor (FLASH). // 5. The optional interrupt OUT endpoint descriptor (FLASH). // //***************************************************************************** static const tConfigSection g_sHIDConfigSection = { sizeof(g_pui8KeybDescriptor), g_pui8KeybDescriptor }; static const tConfigSection g_sHIDInterfaceSection = { sizeof(g_pui8HIDInterface), g_pui8HIDInterface }; static const tConfigSection g_sHIDInEndpointSection = { sizeof(g_pui8HIDInEndpoint), g_pui8HIDInEndpoint }; static const tConfigSection g_sHIDOutEndpointSection = { sizeof(g_pui8HIDOutEndpoint), g_pui8HIDOutEndpoint }; //***************************************************************************** // // Place holder for the user's HID descriptor block. // //***************************************************************************** static tConfigSection g_sHIDDescriptorSection = { sizeof(g_sKeybHIDDescriptor), (const uint8_t *)&g_sKeybHIDDescriptor }; //***************************************************************************** // // This array lists all the sections that must be concatenated to make a // single, complete HID configuration descriptor. // //***************************************************************************** static const tConfigSection *g_psHIDSections[] = { &g_sHIDConfigSection, &g_sHIDInterfaceSection, &g_sHIDDescriptorSection, &g_sHIDInEndpointSection, &g_sHIDOutEndpointSection }; #define NUM_HID_SECTIONS ((sizeof(g_psHIDSections) / \ sizeof(g_psHIDSections[0])) - 1)
My report descriptor looks different because I initially thought it might be that and have tried a million different usage page configurations. Thats formed from the MSP430 like code. If that is wrong, I had something like this with the macros.
ReportSize(8), UsageMinimum(0), UsageMaximum(255), // Input report ReportCount(0x40), Usage(0x01), Input(USB_HID_INPUT_DATA | USB_HID_INPUT_VARIABLE | USB_HID_INPUT_ABS),
I realize these usb projects are somewhat complicated so I don't expect a solution, but after getting into the c files in the /usblib/dev directory I'm not sure where to go from here. Also here are some screen shots of what I see on the sniffer when the device is truned one/connected to my computer.
Here in the first descriptor response it looks like the subclass and protocol settings are applied b/c they are both 0. For some reason though my bcdUSB status shows a 0x0110 which is usb1.1. I set this to 0x200 (usb 2.0) in the descriptor in the usbdhidkeyb.c file.
Next is Configuration descriptor (I think first time it is sent) and it doesn't have a lot of info in it. It looks like it gets the self powered, no remote wake up settings correct, but i'm not sure why it says must be 1 for usb 1.1 and higher. It also looks like it gets the power setting correct.
This is the second sending of the configuration descriptor and this is where my settings are incorrect:
It shows the subclass and protocol, both, being 0x01 forcing it to the keyboard protocol. I'm assuming this is messing up my custom hid functionality. I'm not sure why one report says one thing and one says another.
That is the end of communication. I get this every time and when I compare it to the MSP430 in datapipe mode I don't see the subclass and protocol 0x01's. Here is a screen shot of the second configuration descriptor from the MSP430 board I have running the HID data pipe code:
My questions are: Why do the two config reports say different things? Is that a problem? If so, looking at my code, what have I missed or where should I look for these settings other thant the usbdhidkeyb.c library file where I've already changed them? Also, any input or advice to porting this project over to a simple hid data pipe would be greatly appreciated.
I've attached my project and the screenshots in case you can't see them well in this post.
Thanks,
Rob