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

Parents
  • Hello Tsuneo and other experts,

    we have now decided that we want to use multiple HID endpoints, and I finally got it to work.

    I'm using 5 HIDs with Interrupt OUT endpoints, configured with a bInterval of 1ms to send data to our device.

    When I measured the bandwidth, I got around 320KB/s on Win 7, but only 160KB/s on Win XP. It seems that Win XP ignores the bInterval of 1ms of the device and instead "rounds up" to 2ms. I think it is not a limitation of the USB physical hardware because I get the speed limit at around 160KB/s even when running inside a VM on the Win 7 instance that gets the full speed.

    Do you have any tips for increasing the bandwidth on Windows XP?

    Looking forward to your replies,

    Florian

Reply
  • Hello Tsuneo and other experts,

    we have now decided that we want to use multiple HID endpoints, and I finally got it to work.

    I'm using 5 HIDs with Interrupt OUT endpoints, configured with a bInterval of 1ms to send data to our device.

    When I measured the bandwidth, I got around 320KB/s on Win 7, but only 160KB/s on Win XP. It seems that Win XP ignores the bInterval of 1ms of the device and instead "rounds up" to 2ms. I think it is not a limitation of the USB physical hardware because I get the speed limit at around 160KB/s even when running inside a VM on the Win 7 instance that gets the full speed.

    Do you have any tips for increasing the bandwidth on Windows XP?

    Looking forward to your replies,

    Florian

Children
No data