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

No HID interrupt IN transfers

Hi,

For a LPC23xx device, I'm adding HID besides MSC. I got everything working fine, except for HID interrupt IN transfers. So I can get and set HID reports via control transfers. Also, I can set reports via interrupt OUT transfers, but not IN.

Using USBlyzer, I diagnosed the packet stream. As soon as I attach my device, I do see two interrupt IN transfer attempts at 01:00:81 (C:I:E). If my host application reads EP 1, USBlyzer does not show any packets passing by.

I'm a bit out of options. Does anyone have a clue where to look for a fix?

Thanks,

Mark

Connection Status Device connected
Current Configuration 1
Speed Full
Device Address 3
Number Of Open Pipes 4

Device Descriptor Swinxs Game Console
Offset Field Size Value Description
0 bLength 1 12h
1 bDescriptorType 1 01h Device
2 bcdUSB 2 0200h USB Spec 2.0
4 bDeviceClass 1 00h Class info in Ifc Descriptors
5 bDeviceSubClass 1 00h
6 bDeviceProtocol 1 00h
7 bMaxPacketSize0 1 40h 64 bytes
8 idVendor 2 C251h Keil Software, Inc.
10 idProduct 2 1708h
12 bcdDevice 2 0203h 2.03
14 iManufacturer 1 04h "Swinxs BV "
15 iProduct 1 20h "Swinxs Game Console"
16 iSerialNumber 1 48h "000050020801"
17 bNumConfigurations 1 01h

Configuration Descriptor 1 Bus Powered, 300 mA
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 02h Configuration
2 wTotalLength 2 0040h
4 bNumInterfaces 1 02h
5 bConfigurationValue 1 01h
6 iConfiguration 1 00h
7 bmAttributes 1 80h Bus Powered
 4..0: Reserved  ...00000
 5: Remote Wakeup  ..0.....  No
 6: Self Powered  .0......  No, Bus Powered
 7: Reserved (set to one)
(bus-powered for 1.0)  1.......
8 bMaxPower 1 96h 300 mA

Interface Descriptor 0/0 HID, 2 Endpoints
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 04h Interface
2 bInterfaceNumber 1 00h
3 bAlternateSetting 1 00h
4 bNumEndpoints 1 02h
5 bInterfaceClass 1 03h HID
6 bInterfaceSubClass 1 00h
7 bInterfaceProtocol 1 00h
8 iInterface 1 80h "Swinxs HID"

HID Descriptor
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 21h HID
2 bcdHID 2 0110h 1.10
4 bCountryCode 1 00h
5 bNumDescriptors 1 01h
6 bDescriptorType 1 22h Report
7 wDescriptorLength 2 0045h 69 bytes

Endpoint Descriptor 81 1 In, Interrupt
Offset Field Size Value Description
0 bLength 1 07h
1 bDescriptorType 1 05h Endpoint
2 bEndpointAddress 1 81h 1 In
3 bmAttributes 1 03h Interrupt
 1..0: Transfer Type  ......11  Interrupt
 7..2: Reserved  000000..
4 wMaxPacketSize 2 0001h 1 byte
6 bInterval 1 00h

Endpoint Descriptor 01 1 Out, Interrupt
Offset Field Size Value Description
0 bLength 1 07h
1 bDescriptorType 1 05h Endpoint
2 bEndpointAddress 1 01h 1 Out
3 bmAttributes 1 03h Interrupt
 1..0: Transfer Type  ......11  Interrupt
 7..2: Reserved  000000..
4 wMaxPacketSize 2 0006h 6 bytes
6 bInterval 1 00h

Interface Descriptor 1/0 Mass Storage, 2 Endpoints
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 04h Interface
2 bInterfaceNumber 1 01h
3 bAlternateSetting 1 00h
4 bNumEndpoints 1 02h
5 bInterfaceClass 1 08h Mass Storage
6 bInterfaceSubClass 1 06h SCSI Transparent Command Set
7 bInterfaceProtocol 1 50h Bulk-Only Transport
8 iInterface 1 62h "Swinxs Storage"

Endpoint Descriptor 82 2 In, Bulk, 64 bytes
Offset Field Size Value Description
0 bLength 1 07h
1 bDescriptorType 1 05h Endpoint
2 bEndpointAddress 1 82h 2 In
3 bmAttributes 1 02h Bulk
 1..0: Transfer Type  ......10  Bulk
 7..2: Reserved  000000..
4 wMaxPacketSize 2 0040h 64 bytes
6 bInterval 1 00h

Endpoint Descriptor 02 2 Out, Bulk, 64 bytes
Offset Field Size Value Description
0 bLength 1 07h
1 bDescriptorType 1 05h Endpoint
2 bEndpointAddress 1 02h 2 Out
3 bmAttributes 1 02h Bulk
 1..0: Transfer Type  ......10  Bulk
 7..2: Reserved  000000..
4 wMaxPacketSize 2 0040h 64 bytes
6 bInterval 1 00h

Interface 0 HID Report Descriptor
Item Tag (Value) Raw Data
Usage Page (Vendor-Defined 1) 06 00 FF
Usage (Undefined) 09 00
Collection (Application) A1 01
    Usage Page (Vendor-Defined 2) 06 01 FF
    Usage (Vendor-Defined 1) 09 01
    Logical Minimum (1) 15 01
    Logical Maximum (16777215) 27 FF FF FF 00
    Report Count (1) 95 01
    Report Size (24) 75 18
    Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
    Usage (Vendor-Defined 2) 09 02
    Report Count (1) 95 01
    Report Size (16) 75 10
    Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
    Usage Minimum (Vendor-Defined 1) 19 01
    Usage Maximum (Vendor-Defined 3) 29 03
    Logical Minimum (0) 15 00
    Logical Maximum (1) 25 01
    Report Count (3) 95 03
    Report Size (1) 75 01
    Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
    Report Count (1) 95 01
    Report Size (5) 75 05
    Input (Cnst,Ary,Abs) 81 01
    Usage Page (Vendor-Defined 3) 06 02 FF
    Usage (Vendor-Defined 16) 09 10
    Logical Minimum (0) 15 00
    Logical Maximum (100) 25 64
    Report Count (1) 95 01
    Report Size (8) 75 08
    Output (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 02
End Collection C0

Parents
  • > now I see that it's a bit tricky to use the ISR to fill the buffer.

    Natural.
    The endpoint ISR is triggered by the host.
    In most cases, the timing isn't suitable for the device side.
    Devices want to pass a packet to the USB engine, just at the timing when it is available on the device.
    And then, the code flow gets straighten out on the firmware source.

    When you take this strategy, you don't need to put a packet in USB_Configure_Event(), any more.

    To make this strategy robust,
    Shorter bInterval of the endpoint descriptor
    - less than or equal to 1/3 of expected interval on the firmware.

    Suppose that, you have keypad scan in 20 ms interval. Just when any key change occurs, the result is sent to host using an input report over the HID interrupt IN EP. The least interval of the report is 20 ms. (with debounce, it may be longer, though) In this case, bInterval is set to 6 ms (<= 20 / 3), or less.

    The magic number 3 derives as follows,
    The host repeats to poll the IN EP at bInterval (*1) using IN transactions. When noise disturbs the transaction, host retires it after bInterval. Host repeats three error-retry (including the first one - "Three strikes, OUT" rule), while error occurs. Until host succeeds, the EP buffer is occupied by the last packet. The transfer delays for three bInterval duration, at most.

    (*1)
    USB spec doesn't guarantee that the IN EP is polled exactly at bInterval. It allows that the actual polling interval is equal to or less than bInterval.
    Actual interval is determined by the host controller spec and device driver implementation on the host side.
    OHCI clearly notes that it reduces bInterval to 1, 2, 4, 8, 16, 32 ms
    The Other inplementations of host controllers also follow this rule.

    OpenHCI - OHCI spec (hcir1_0a.pdf)
    download.microsoft.com/.../hci_1.exe

    5.2.7.2 Interrupt
    The lower five bits of the current frame number is used as an index into an array of 32 interrupt Endpoint Descriptor lists found in the HCCA. This means each list is revisited once every 32 ms.

    5.2.7.2.1 Polling Rate
    Interrupt Endpoint Descriptors have a minimum rate for which they need to be scheduled. When this information is provided to Host Controller Driver, it determines the closest power of 2 rate below the endpoints requirement and determines which scheduling queue for that rate has the smallest committed bandwidth.

    Tsuneo

Reply
  • > now I see that it's a bit tricky to use the ISR to fill the buffer.

    Natural.
    The endpoint ISR is triggered by the host.
    In most cases, the timing isn't suitable for the device side.
    Devices want to pass a packet to the USB engine, just at the timing when it is available on the device.
    And then, the code flow gets straighten out on the firmware source.

    When you take this strategy, you don't need to put a packet in USB_Configure_Event(), any more.

    To make this strategy robust,
    Shorter bInterval of the endpoint descriptor
    - less than or equal to 1/3 of expected interval on the firmware.

    Suppose that, you have keypad scan in 20 ms interval. Just when any key change occurs, the result is sent to host using an input report over the HID interrupt IN EP. The least interval of the report is 20 ms. (with debounce, it may be longer, though) In this case, bInterval is set to 6 ms (<= 20 / 3), or less.

    The magic number 3 derives as follows,
    The host repeats to poll the IN EP at bInterval (*1) using IN transactions. When noise disturbs the transaction, host retires it after bInterval. Host repeats three error-retry (including the first one - "Three strikes, OUT" rule), while error occurs. Until host succeeds, the EP buffer is occupied by the last packet. The transfer delays for three bInterval duration, at most.

    (*1)
    USB spec doesn't guarantee that the IN EP is polled exactly at bInterval. It allows that the actual polling interval is equal to or less than bInterval.
    Actual interval is determined by the host controller spec and device driver implementation on the host side.
    OHCI clearly notes that it reduces bInterval to 1, 2, 4, 8, 16, 32 ms
    The Other inplementations of host controllers also follow this rule.

    OpenHCI - OHCI spec (hcir1_0a.pdf)
    download.microsoft.com/.../hci_1.exe

    5.2.7.2 Interrupt
    The lower five bits of the current frame number is used as an index into an array of 32 interrupt Endpoint Descriptor lists found in the HCCA. This means each list is revisited once every 32 ms.

    5.2.7.2.1 Polling Rate
    Interrupt Endpoint Descriptors have a minimum rate for which they need to be scheduled. When this information is provided to Host Controller Driver, it determines the closest power of 2 rate below the endpoints requirement and determines which scheduling queue for that rate has the smallest committed bandwidth.

    Tsuneo

Children
No data