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

Some fundamental questions regarding the USB HID example

Hi there!
I'm still trying to get around USB HID communication. To that end I've added Keil's HIB example to my project (some LPC2478). Since it's lacking the buttons and LEDs that the example is expecting, I've slightly modified the user interface: the data provided by my device is the RTC's seconds, while the data sent to the device gets output to the LCD. Now everything is fine, data gets transferred to the PC every 32ms (as specified by the descriptor).

My general questions are:
1. In terms of the example project, do I work in usbuser.c or hiduser.c? I've commented out HID_GetReport and HID_SetReport, and still my device works. So obviously what's being called is USB_EndPoint1. Why is it that I have to declare my device an HID, and in the end the HID stuff doesn't even execute?
2. The USB Set Configuration Request is issued once, during enumeration, isn't it?
3. After reading a lot of Tsuneo's posts, I think there's two different ways that I can transfer data to/from the device: either via the control endpoint, or via the endpoints specified in my descriptor. So why do I even go through the trouble of defining my own endpoints?
5. How does "one interrupt-type data transfer" proceed? I think, it's something like: - the PC sends an InReport to the device, causing a USB_EVT_OUT there which leads to the execution of USB_EndPoint1. - Now by some magic, USB_EndPoint1 is called again with an argument of USB_EVT_IN. Is this somehow similar to reality?

Any answers would be greatly appreciated. I'm struggling with Axelson's USB Complete, with lots of forum threads (thanks, Tsuneo), but can't yet get a grip on this whole USB business.

Kind regards,
Peter

Parents
  • > 1. In terms of the example project, do I work in usbuser.c or hiduser.c? I've commented out HID_GetReport and HID_SetReport, and still my device works. So obviously what's being called is USB_EndPoint1.

    HID device has two ways to exchange reports
    - over interrupt IN / OUT endpoints
    - using GetReport / SetReport request over the default endpoint (EP0)

    You've disabled GetReport / SetReport request handlers.
    You may examine these requests using SimpleHIDWrite.

    SimpleHIDWrite (by Robert Marquardt) on Jan Axelson's site
    www.lvr.com/.../SimpleHIDWrite3.zip

    The source code (Delphi) of SimpleHIDWrite is included in
    Human Interface Device controller suite
    www.soft-gems.net/index.php

    Before running the device on SimpleHIDWrite, comment the USB_EVT_IN case in USB_EndPoint1(). Otherwise, the report pane of the application dialog is filled with repeated input reports from the interrupt IN endpoint.



    > 2. The USB Set Configuration Request is issued once, during enumeration, isn't it?

    SetConfiguration(1) is required at least once on enumeration.
    Usually, it's just once. But you may put SetConfiguration(0) to reset the configuration.



    > So why do I even go through the trouble of defining my own endpoints?

    The interrupt IN endpoint is mandatory by the HID spec. Interrupt OUT endpoint is optional.

    These two ways (interrupt IN endpoints and Requests) are assigned to the different tasks.

    Host puts GetReport request to know the status of the device immediately. Device has to respond to GetReport within given timeout (500ms). As HID interrupt IN endpoint is always polled by host, device may put an input report at any timing when the device likes.

    In the same way, host expects that the device processes SetReport request within timeout. Device may delay process of the output report over the interrupt OUT endpoint, as long as it likes.



    > the PC sends an InReport to the device, causing a USB_EVT_OUT there which leads to the execution of USB_EndPoint1. - Now by some magic, USB_EndPoint1 is called again with an argument of USB_EVT_IN.

    You don't need to wait for USB_EVT_IN. Rather, comment all lines of USB_EVT_IN case of USB_EndPoint1().
    Call USB_WriteEP(HID_EP_IN) in the USB_EVT_OUT case.

    Tsuneo

Reply
  • > 1. In terms of the example project, do I work in usbuser.c or hiduser.c? I've commented out HID_GetReport and HID_SetReport, and still my device works. So obviously what's being called is USB_EndPoint1.

    HID device has two ways to exchange reports
    - over interrupt IN / OUT endpoints
    - using GetReport / SetReport request over the default endpoint (EP0)

    You've disabled GetReport / SetReport request handlers.
    You may examine these requests using SimpleHIDWrite.

    SimpleHIDWrite (by Robert Marquardt) on Jan Axelson's site
    www.lvr.com/.../SimpleHIDWrite3.zip

    The source code (Delphi) of SimpleHIDWrite is included in
    Human Interface Device controller suite
    www.soft-gems.net/index.php

    Before running the device on SimpleHIDWrite, comment the USB_EVT_IN case in USB_EndPoint1(). Otherwise, the report pane of the application dialog is filled with repeated input reports from the interrupt IN endpoint.



    > 2. The USB Set Configuration Request is issued once, during enumeration, isn't it?

    SetConfiguration(1) is required at least once on enumeration.
    Usually, it's just once. But you may put SetConfiguration(0) to reset the configuration.



    > So why do I even go through the trouble of defining my own endpoints?

    The interrupt IN endpoint is mandatory by the HID spec. Interrupt OUT endpoint is optional.

    These two ways (interrupt IN endpoints and Requests) are assigned to the different tasks.

    Host puts GetReport request to know the status of the device immediately. Device has to respond to GetReport within given timeout (500ms). As HID interrupt IN endpoint is always polled by host, device may put an input report at any timing when the device likes.

    In the same way, host expects that the device processes SetReport request within timeout. Device may delay process of the output report over the interrupt OUT endpoint, as long as it likes.



    > the PC sends an InReport to the device, causing a USB_EVT_OUT there which leads to the execution of USB_EndPoint1. - Now by some magic, USB_EndPoint1 is called again with an argument of USB_EVT_IN.

    You don't need to wait for USB_EVT_IN. Rather, comment all lines of USB_EVT_IN case of USB_EndPoint1().
    Call USB_WriteEP(HID_EP_IN) in the USB_EVT_OUT case.

    Tsuneo

Children