Author Topic: Generic HID Enumeration Problems  (Read 16420 times)

mihooper

  • Member
  • ***
  • Posts: 24
Generic HID Enumeration Problems
« on: March 14, 2012, 02:02:54 pm »
Jan,
I am having trouble getting my TI C55xx DSP to properly enumerate with some of the sample code they (and Spectrum Digital) provide. The TI mouse HID (from my other post) does properly enumerate, but I wanted to try your generic HID code. It appears that during the enumeration process, the host attempts to "start" the device, but then promptly removes it. Here's a portion of the activity around the problem area.
Code: [Select]
PnP 0037-0036 43:35.4 8.669544 s 2 us Query ID Device ID FFFFFA8007E6A060h USBPDO-9 usbhub FFFFFA800478A0D0h Success
PnP 38 43:35.4 8.669609 s Start Device FFFFFA8007E8CB30h 0000009f HidUsb FFFFFA8007DCE7D0h
URB 39 43:35.4 8.669620 s Bulk or Interrupt Transfer 2 bytes buffer in 0.042604167 FFFFFA8007E6A060h USBPDO-9 usbhub FFFFFA8007C29C60h
URB 40 43:35.4 8.669640 s Bulk or Interrupt Transfer 2 bytes buffer in 0.042604167 FFFFFA8007E6A060h USBPDO-9 usbhub FFFFFA8007E425D0h
PnP 0041-0038 43:35.4 8.669731 s 122 us Start Device FFFFFA8007E8CB30h 0000009f HidUsb FFFFFA8007DCE7D0h Success
PnP 42 43:35.4 8.680423 s Remove Device FFFFFA8007E8CB30h 0000009f HidUsb FFFFFA8007E34010h
PnP 0043-0042 43:35.4 8.680429 s 7 us Remove Device FFFFFA8007E8CB30h 0000009f HidUsb FFFFFA8007E34010h Success
PnP 44 43:35.4 8.680467 s Query Device Relations Bus Relations FFFFFA8007E85B30h _HID0000000a HidUsb FFFFFA80066CA4F0h
PnP 45 43:35.4 8.680471 s Query Device Relations Bus Relations FFFFFA8007E6A060h USBPDO-9 usbhub FFFFFA80066CA4F0h
PnP 0046-0045 43:35.4 8.680473 s 2 us Query Device Relations Bus Relations FFFFFA8007E6A060h USBPDO-9 usbhub FFFFFA80066CA4F0h Success
PnP 0047-0044 43:35.4 8.680475 s 8 us Query Device Relations Bus Relations FFFFFA8007E85B30h _HID0000000a HidUsb FFFFFA80066CA4F0h Success

Can you tell from this what is happening? If you need to see more, let me know and I can post the entire enumeration process.

Thx,

MikeH
Thx,
MikeH

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Generic HID Enumeration Problems
« Reply #1 on: March 14, 2012, 05:50:52 pm »
How did you create the generic HID firmware for your controller? If you just changed the report descriptor, you will also need to edit the interface descriptor and add an interrupt OUT endpoint descriptor. 

Jan

mihooper

  • Member
  • ***
  • Posts: 24
Re: Generic HID Enumeration Problems
« Reply #2 on: March 14, 2012, 07:22:07 pm »
Jan,

I made an attempt to modify all relevant descriptors. Here are the structures:
Code: [Select]

//USB Device Descriptor: 18-bytes
const unsigned char deviceDesc[]=
  {0x12,       // bLength = 18d
   0x01,       // bDeviceDescriptorType=1(defined by USB spec)
   0x00, 0x02, // bcdUSB USB Version 2.0 (L-Byte/H-Byte)
   0x00,       // bDeviceClass
   0x00,       // bDeviceSubclass
   0x00,       // bDeviceProtocol
   0x40,       // bMaxPacketSize 64 Bytes
   0xB3, 0x04, // idVendor(L-Byte/H-Byte)
   0x0B, 0x31, // idProduct(L-Byte/H-Byte)
   0x10, 0x01, // bcdDevice(L-Byte/H-Byte): device's release number
   0,          // iManufacturer String Index
   0,          // iProduct String Index
   0,          // iSerialNumber String Index
   1};         // bNumberConfigurations

//Configuration Descriptors
const unsigned char cfgDesc[]=
  {
  // CONFIGURATION Descriptor
  0x09,      // bLength
  0x02,      // bDescriptorType = Config (constant)
  0x29,  0x00, // wTotalLength(L/H)
  0x01,      // bNumInterfaces
  0x01,      // bConfigValue
  0x00,      // iConfiguration
  0xA0,      // bmAttributes;
  0x32,      // MaxPower is 200mA
  // INTERFACE Descriptor
  0x09,      // length = 9
  0x04,      // type = IF; constant 4 for INTERFACE
  0x00,      // IF #0; Interface Identification #
  0x00,      // bAlternate Setting
  0x02,      // bNumber of Endpoints = 1 for 5515 mouse
  0x03,      // bInterfaceClass = HID
  0x00,      // bInterfaceSubClass
  0x00,      // bInterfaceProtocol
  0x00,      // iInterface
  // HID Descriptor
  0x09,      // length = 9
  0x21,      // bDescriptorType = HID
  0x00,      // bcdHID = HID Class Spec version
  0x01,      //
  0x00,      //
  0x01,      // bNumDescriptors = Number of Descriptors
  0x22,      // bDescriptorType = 34 (REPORT)
  0x2F,      // wDescriptorLength = 47
//  0x34,      // wDescriptorLength = 52
//   0x2E,      // wDescriptorLength = 46

  0x00,      //
  // EndPoint_1_IN Descriptor
  0x07,      // bLength
  0x05,      // bDescriptorType (Endpoint)
  0x81,      // bEndpointAddress and direction(IN)   
  0x03,      // bmAttributes: B1B0->transfer-type: control=00; Iso=01; bulk=10; interrupt=11   
  0x40,0x00, // wMaxPacketSize(L/H)=4
  0x0A,      // bInterval: Max latency
  // EndPoint_1_OUT Descriptor
  0x07,      // bLength
  0x05,      // bDescriptorType (Endpoint)
  0x01,      // bEndpointAddress and direction(OUT)
  0x03,      // bmAttributes: B1B0->transfer-type: control=00; Iso=01; bulk=10; interrupt=11
  0x40,0x00, // wMaxPacketSize(L/H)=4
  0x0A,      // bInterval: Max latency
  };
I did add the EndPoint_OUT Descriptor to the original code.

And here's the report descriptor:
Code: [Select]
Uint8 reportDesc[] =
{
  0x06, 0xA0, 0xFF, // Usage page (vendor defined)
  0x09, 0x01, // Usage ID (vendor defined)
  0xA1, 0x01, // Collection (application)

// The Input report
       0x09, 0x03,      // Usage ID - vendor defined
       0x15, 0x00,      // Logical Minimum (0)
       0x26, 0xFF, 0x00,    // Logical Maximum (255)
       0x75, 0x08,      // Report Size (8 bits)
       0x95, 0x02,      // Report Count (2 fields)
       0x81, 0x02,      // Input (Data, Variable, Absolute)

// The Output report
       0x09, 0x04,      // Usage ID - vendor defined
       0x15, 0x00,      // Logical Minimum (0)
       0x26, 0xFF, 0x00,    // Logical Maximum (255)
       0x75, 0x08,      // Report Size (8 bits)
       0x95, 0x02,      // Report Count (2 fields)
       0x91, 0x02,      // Output (Data, Variable, Absolute)

// The Feature report
       0x09, 0x05,      // Usage ID - vendor defined
       0x15, 0x00,      // Logical Minimum (0)
       0x26, 0xFF, 0x00,    // Logical Maximum (255)
       0x75, 0x08, // Report Size (8 bits)
       0x95, 0x02, // Report Count (2 fields)
       0xB1, 0x02,      // Feature (Data, Variable, Absolute)

  0xC0}; // end collection
Which should be very close to the code you gave us in your book.

USBlyzer shows the following analysis of the transactions, all of which look OK to me. But then again, I'm a rookie...:)

Code: [Select]
Get Descriptor
This request returns the specified descriptor if the descriptor exists.
Offset Field Size Value Description
0 bmRequestType 1 80h 
 4..0: Recipient  ...00000  Device
 6..5: Type  .00.....  Standard
 7: Direction  1.......  Device-to-Host
1 bRequest 1 06h Get Descriptor
2 wValue.LowByte 1 00h 
3 wValue.HiByte 1 01h Device Descriptor
4 wIndex 2 0000h 
6 wLength 2 0012h Descriptor Length

Device Descriptor
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 04B3h IBM Corp.
10 idProduct 2 310Bh 
12 bcdDevice 2 0110h 1.10
14 iManufacturer 1 00h 
15 iProduct 1 00h 
16 iSerialNumber 1 00h 
17 bNumConfigurations 1 01h

Code: [Select]
Get Descriptor
This request returns the specified descriptor if the descriptor exists.
Offset Field Size Value Description
0 bmRequestType 1 80h 
 4..0: Recipient  ...00000  Device
 6..5: Type  .00.....  Standard
 7: Direction  1.......  Device-to-Host
1 bRequest 1 06h Get Descriptor
2 wValue.LowByte 1 00h Descriptor Index
3 wValue.HiByte 1 02h Configuration Descriptor
4 wIndex 2 0000h 
6 wLength 2 0009h Descriptor Length

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

Code: [Select]
Get Descriptor
This request returns the specified descriptor if the descriptor exists.
Offset Field Size Value Description
0 bmRequestType 1 80h 
 4..0: Recipient  ...00000  Device
 6..5: Type  .00.....  Standard
 7: Direction  1.......  Device-to-Host
1 bRequest 1 06h Get Descriptor
2 wValue.LowByte 1 00h Descriptor Index
3 wValue.HiByte 1 02h Configuration Descriptor
4 wIndex 2 0000h 
6 wLength 2 0009h Descriptor Length

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

Code: [Select]
Set Idle
Silences a particular report on the interrupt in pipe until a new event occurs or the specified amount of time passes.
Offset Field Size Value Description
0 bmRequestType 1 21h 
 4..0: Recipient  ...00001  Interface
 6..5: Type  .01.....  Class
 7: Direction  0.......  Host-to-Device
1 bRequest 1 0Ah Set Idle
2 wValue.LowByte 1 00h Report ID
3 wValue.HiByte 1 00h Infinite Idle Rate
4 wIndex 2 0000h Interface
6 wLength 2 0000h 
And then the report descriptor
Code: [Select]
Get Descriptor
This request returns the specified descriptor if the descriptor exists.
Offset Field Size Value Description
0 bmRequestType 1 81h 
 4..0: Recipient  ...00001  Interface
 6..5: Type  .00.....  Standard
 7: Direction  1.......  Device-to-Host
1 bRequest 1 06h Get Descriptor
2 wValue.LowByte 1 00h 
3 wValue.HiByte 1 22h Report Descriptor
4 wIndex 2 0000h Interface
6 wLength 2 006Fh Descriptor Length

Interface 0 HID Report Descriptor Vendor-Defined 1
Item Tag (Value) Raw Data
Usage Page (Vendor-Defined 161) 06 A0 FF 
Usage (Vendor-Defined 1) 09 01 
Collection (Application) A1 01 
    Usage (Vendor-Defined 3) 09 03 
    Logical Minimum (0) 15 00 
    Logical Maximum (255) 26 FF 00 
    Report Size (8) 75 08 
    Report Count (2) 95 02 
    Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02 
    Usage (Vendor-Defined 4) 09 04 
    Logical Minimum (0) 15 00 
    Logical Maximum (255) 26 FF 00 
    Report Size (8) 75 08 
    Report Count (2) 95 02 
    Output (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 02 
    Usage (Vendor-Defined 5) 09 05 
    Logical Minimum (0) 15 00 
    Logical Maximum (255) 26 FF 00 
    Report Size (8) 75 08 
    Report Count (2) 95 02 
    Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) B1 02 
End Collection C0 

The problem happens after this when the host appears to attempt to "start" the device, the promptly "removes" the device.

Any further thoughts would be appreciated....

thx

MikeH



[attachment deleted by admin]
Thx,
MikeH

Tsuneo

  • Frequent Contributor
  • ****
  • Posts: 145
Re: Generic HID Enumeration Problems
« Reply #3 on: March 14, 2012, 09:35:30 pm »
Hi Mike,

The sniffer trace doesn't tell any device fault.
Your descriptors and request handling seem fine.

Sound like VID/PID conflict.
Windows hold devices's USB / HID profile (device instance) on its registry, sorted by VID/PID. Maybe, you've changed just the descriptors, but not for VID/PID? Windows dislike inconsistency of the device with the former profile.

a) Assign another VID/PID to the device
OR
b) Delete device instance on the registry.

Just for testing, you may assign any VID/PID to your device, as long as the VID/PID is not used on your PC. I often assign VID = 0xFFFF for testing. Get official VID/PID before release.

To delete (uninstall) device instance(s), this utility is handy.
USBDeview
http://www.nirsoft.net/utils/usb_devices_view.html

On this utility, sort the list by touching to the VID column.
Find the VID/PID of the target device, and right click - uninstall.

Tsuneo

mihooper

  • Member
  • ***
  • Posts: 24
Re: Generic HID Enumeration Problems
« Reply #4 on: March 15, 2012, 06:36:05 am »
Tsuneo,
Quote
Sound like VID/PID conflict.
That was the problem!!! I uninstalled the device from the device manager window (it did show up there, but with a yellow exclamation point). After uninstalling, the device enumerates properly and I can find it with Jan's Generic HID C# program!!

Great progress! Thanks so much for taking the time to wade through the captures. I really appreciate it. ;D

MikeH
Thx,
MikeH