This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Write to USB HID with OUT interrupt endpoint via WriteFile()

Hello experts!

I'm trying to modify our existing HID descriptor and message handling that is based on one of Keil's examples, in such a way that our LPC2478-based hardware would use an OUT interrupt endpoint for receiving data from the PC.

What I currently have is a composite device that consists of an HID (on Interface 0) and MSC (on Interface 1). This setup was working already, and both HID and MSC were OK.

Now, I want to change the HID in such a way that the OUT data is sent to an OUT endpoint that I have set up just for the HID, and not via endpoint 0.

This is the relevant part from the USB_ConfigDescriptor:

        /* Interface 0, Alternate Setting 0, HID Class */
        USB_INTERFACE_DESC_SIZE,           /* bLength */
        USB_INTERFACE_DESCRIPTOR_TYPE,     /* bDescriptorType */
        0x00,                              /* bInterfaceNumber */
        0x00,                              /* bAlternateSetting */
        0x02,                              /* bNumEndpoints */
        USB_DEVICE_CLASS_HUMAN_INTERFACE,  /* bInterfaceClass */
        HID_SUBCLASS_NONE,                 /* bInterfaceSubClass */
        HID_PROTOCOL_NONE,                 /* bInterfaceProtocol */
        USB_STR_INTERFACE_OFFSET,          /* iInterface */
        /* HID Class Descriptor */
        /* HID_DESC_OFFSET = 0x0012 */
        HID_DESC_SIZE,                     /* bLength */
        HID_HID_DESCRIPTOR_TYPE,           /* bDescriptorType */
        WBVAL(0x0100), /* 1.00 */          /* bcdHID */
        0x00,                              /* bCountryCode */
        0x01,                              /* bNumDescriptors */
        HID_REPORT_DESCRIPTOR_TYPE,        /* bDescriptorType */
        WBVAL(HID_REPORT_DESC_SIZE),       /* wDescriptorLength */
        /* Endpoint, HID Interrupt In */
        USB_ENDPOINT_DESC_SIZE,            /* bLength */
        USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType */
        USB_ENDPOINT_IN(7),                /* bEndpointAddress */
        USB_ENDPOINT_TYPE_INTERRUPT,       /* bmAttributes */
        WBVAL(64),                         /* wMaxPacketSize */
        1,                                 /* bInterval */
        /* Endpoint, HID Interrupt Out */
        USB_ENDPOINT_DESC_SIZE,            /* bLength */
        USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType */
        USB_ENDPOINT_OUT(7),               /* bEndpointAddress */
        USB_ENDPOINT_TYPE_INTERRUPT,       /* bmAttributes */
        WBVAL(64),                         /* wMaxPacketSize */
        1,                                 /* bInterval */

I have a native testing program (that measures the transfer speed) that writes data to my device via WriteFile(...). The testing app seems to work, because when I remove the OUT endpoint from the descriptor, Windows uses the fallback via endpoint 0 feature reports, and the program works without problems.

This is what I see in USBlyzer when I use the additional OUT enpoint, as from the descriptor above:

URB     8798    0:00:01.109     Bulk or Interrupt Transfer      Output Report len:64    19 00 00 00 00 00 00 00...      out     01:00:07        8A1FA5E0h       000000c8        usbccgp 8A155A58h
URB     8799-8785       0:00:01.109     Bulk or Interrupt Transfer      Input Report len:64     02 2C 00 00 00 00 00 00...      in      01:00:87        8A9D4DE8h       USBPDO-9        usbhub  8A1FF008h       Success (Success)
URB     8800-8784       0:00:01.109     Bulk or Interrupt Transfer      Input Report len:64     02 2C 00 00 00 00 00 00...      in      01:00:87        8A1FA5E0h       000000c8        usbccgp 8A1FF008h       Success (Success)
URB     8801    0:00:01.109     Bulk or Interrupt Transfer      Output Report len:64    19 00 00 00 00 00 00 00...      out     01:00:07        8A9D4DE8h       USBPDO-9        usbhub  8A155A58h
URB     8802    0:00:01.109     Bulk or Interrupt Transfer      64 bytes buffer         in      01:00:87        8A1FA5E0h       000000c8        usbccgp 8A1FF008h
URB     8803    0:00:01.109     Bulk or Interrupt Transfer      64 bytes buffer         in      01:00:87        8A9D4DE8h       USBPDO-9        usbhub  8A1FF008h
URB     8804-8793       0:00:01.109     Bulk or Interrupt Transfer      Input Report len:64     02 2E 00 00 00 00 00 00...      in      01:00:87        8A9D4DE8h       USBPDO-9        usbhub  8A222008h       Success (Success)
URB     8805-8792       0:00:01.109     Bulk or Interrupt Transfer      Input Report len:64     02 2E 00 00 00 00 00 00...      in      01:00:87        8A1FA5E0h       000000c8        usbccgp 8A222008h       Success (Success)
URB     8806    0:00:01.109     Bulk or Interrupt Transfer      64 bytes buffer         in      01:00:87        8A1FA5E0h       000000c8        usbccgp 8A222008h
URB     8807    0:00:01.109     Bulk or Interrupt Transfer      64 bytes buffer         in      01:00:87        8A9D4DE8h       USBPDO-9        usbhub  8A222008h
... 6 more input reports like in the 4 lines above this line ...
URB     8828-8801       0:00:01.109     Bulk or Interrupt Transfer      64 bytes buffer         out     01:00:07        8A9D4DE8h       USBPDO-9        usbhub  8A155A58h       Success (Success)
URB     8829-8798       0:00:01.109     Bulk or Interrupt Transfer      64 bytes buffer         out     01:00:07        8A1FA5E0h       000000c8        usbccgp 8A155A58h       Success (Success)

The output report that sends "19 00 00 00 00 00 00 00..." is what I'm interested in, what my testing app sends. To me it looks like my device behaves correctly because of the two "Success" messages at the end.

The problem is that the call to WriteFile(...) never returns and the program hangs terribly (sometimes I have to restart the Win XP that I'm testing on).

The reason why I want to use the OUT endpoint of the HID is that I plan to add a few more HIDs to my composite device, and then hopefully to get a bigger overall transfer rate to the device. (The introduction of the Mass Storage Class was made for the same reason, but then we found out that some customers cannot use it).

I'm really looking forward to any tips, because I've already sunk quite a few days into making this work.

Best regards,
Florian

0