Author Topic: Strange HID SetConfiguration Request error  (Read 14860 times)

bajwa

  • Member
  • ***
  • Posts: 2
Strange HID SetConfiguration Request error
« on: April 20, 2011, 10:29:06 am »
Hello everyone,

i am writing the custom Firmware code in assembly for a USB Stack implementing HID class for communication. i am facing a very strange problem:

When i attach the Device to the bus, The device is enumerated by windows without any error. After that the Host sends the device a SET_CONFIGURATION request with bConfigurationValue = 0 (indicating the device should remain in ADDRESSED_STATE), whilst when i see Port's description using USBTrace, i see correct Descriptor values that the device was programmed for. If the values are correct, then why the host is not sending a NonZero bConfigurationValue?  ???  Due to this, the Device Manager tells me that the "Device is not functional".

Also, If i attach the hardware with a Windows XP installed PC, the computer recognizes it as a Generic HID Device, but i am unable to communicate anything to the device (using the Generic HID c# example by Jan Axelson) as the software throws the exception of "The device is not functional".


i am unable to understand how should i tackle this hurdle and where exactly the problem lies..


Please help, i have taken this up as my University project and i only have a week left  :(


Following are the details:

Controller:    PIC18F4550
Windows:     Windows 7 (64 bit), Windows XP (32 bit)



The descriptor values:
(in PIC18F assembly, i am using RETLW instruction to keep the bytes word aligned in ROM space):




; Device Descriptor
Device_Descriptor
               retlw    0x12                   ; Size of this descriptor in bytes (ref USB 2.0 spec)
               retlw    USB_DESCRIPTOR_DEVICE      ; Descriptor ID (ref USB 2.0 spec) (2 bytes)
               retlw    0x00                  ; USB Specification (BCD format) 2.00 (ref USB 2.0 spec) (2 bytes)
               retlw   0x02

               retlw    0x00                   ; Class Code
               retlw    0x00                   ; Subclass code
               retlw    0x00                  ; Protocol code
               retlw    EP0_BUFFER_SIZE            ; Max. Packet size for EP0

               retlw   0x06
               retlw   0xfe                   ; Vender ID (2 bytes)

               retlw    0x3F
               retlw   0x00                  ; Product ID (2 bytes)

               retlw   0x01
               retlw   0x00                  ; Device release number (BCD format) (2 bytes)

               retlw   0x01                  ; Manufacturer string index
               retlw    0x02                  ; Product string index
               retlw    0x00                  ; Device Serial Number String
               retlw   0x01                  ; Number of possible configurations
Device_Descriptor_End



; Configuration Descriptor
Config_Descriptor
               retlw   0x09
               retlw    USB_DESCRIPTOR_CONFIG
               retlw   0x29
               retlw   0x00                        ; Length of the subordinate descriptors

               retlw   0x01                        ; Number of interfaces in this config
               retlw   0x01                        ; ID for this config
               retlw   0x00                        ; Configuration String Index - none defined
               retlw   (0x80 | USB_POWER_OPTION)         ; Attributes
               retlw   0x40                        ; Maximum Power Consumption
Config_Descriptor_End


; Interface Descriptor
Interface_Descriptor
               retlw   0x09                     ; Descriptor Size
               retlw   USB_DESCRIPTOR_INTERFACE      ; Descriptor Type
               retlw   0x00                     ; Interface number
               retlw   0x00                     ; Alternate Setting number
               retlw   0x02                     ; Number of EndPoints in this interface
               retlw   USB_HID_DEVICE               ; Class code
               retlw   0x00                     ; Subclass code
               retlw   0x00                     ; Protocol code
               retlw   0x00                     ; Interface string index


; 0x06 -> Usage page
; 0xff00 to 0xffff -> user specific range code by Specification
; 0x09 -> Usage item
; HID Class Specific Descriptors
HID_Class_Descriptor
               retlw   0x09                     ; Size
               retlw   USB_HID_CLASS_DESCRIPTOR      ; Desccriptor Type
               retlw     0x11
               retlw   0x01                     ; HID Specification Number (In BCD) => 1.11
               retlw   0x00                     ; Country Code (0x00 - not supported)
               retlw   0x01                     ; HID Number of Class Descriptors
               retlw   0x22                     ; Report Descriptor Type
               retlw   .28                      ; Size of the report descriptor
               retlw   0x00
HID_Class_Descriptor_End


;EndPoint Descriptor
Endpoint_Descriptor1_In
               retlw   0x07                     ; Size
               retlw   USB_DESCRIPTOR_ENDPOINT         ; Type
               retlw   HID_EP | _EP_IN               ; Endpoint Number
               retlw   _INTERRUPT                  ; Attribute - Type of transfer
               retlw   0x40
               retlw   0x00                     ; Size
               retlw   0x01                     ; Interval of polling
Endpoint_Descriptor1_In_End



;EndPoint Descriptor
Endpoint_Descriptor1_Out
               retlw   0x07                     ; Size
               retlw   USB_DESCRIPTOR_ENDPOINT         ; Type
               retlw   HID_EP | _EP_OUT            ; Endpoint Number
               retlw   _INTERRUPT                  ; Attribute
               retlw   0x40
               retlw   0x00                     ; Size
               retlw   0x01                     ; Interval of polling
Endpoint_Descriptor1_Out_End
Subordinate_Descriptors_End





; Language Code Descriptor 0 - Special descriptor to notify Host which language ID it uses
String_Descriptor0   
               retlw   0x04                     ; Length
               retlw   USB_DESCRIPTOR_STRING         ; Type
               retlw     0x09                     ; Language ID: 0x409 for U.S. English
               retlw   0x04
String_Descriptor0_End



; Language Code Descriptor 1 - Manufacturer String
String_Descriptor1
               retlw   String_Descriptor2_Length
               retlw   USB_DESCRIPTOR_STRING
               retlw   0x00
               retlw   'S'
               retlw   0x00
               retlw   'i'
               retlw   0x00
               retlw   'g'
               retlw   0x00
               retlw   'm'
               retlw   0x00
               retlw   'a'
               retlw   0x00
               retlw   ' '

               retlw   'I'
               retlw   0x00
               retlw   'n'
               retlw   0x00
               retlw   'd'
               retlw   0x00
               retlw   'u'
               retlw   0x00
               retlw   's'
               retlw   0x00
               retlw   't'
               retlw   0x00
               retlw   'r'
               retlw   0x00
               retlw   'i'
               retlw   0x00
               retlw   'a'
               retlw   0x00
               retlw   'l'
               retlw   0x00
               retlw   's'
               retlw   0x00
               retlw   ' '
               retlw   0x00
               retlw   'c'
               retlw   0x00
               retlw   'o'
               retlw   0x00
               retlw   'n'
               retlw   0x00
               retlw   't'
               retlw   0x00
               retlw   'r'
               retlw   0x00
               retlw   'o'
               retlw   0x00
               retlw   'l'
               retlw   0x00
               retlw   's'
               retlw   0x00
String_Descriptor1_End


; Language Code Descriptor 2 - Product String
String_Descriptor2
               retlw   String_Descriptor2_Length
               retlw   USB_DESCRIPTOR_STRING
               retlw    'U'
               retlw   0x00
               retlw    'S'
               retlw   0x00
               retlw    'B'
               retlw   0x00

               retlw    ' '
               retlw   0x00
               retlw    'F'
               retlw   0x00
               retlw    'i'
               retlw   0x00
               retlw    'r'
               retlw   0x00
               retlw    'm'
               retlw   0x00
               retlw    'w'
               retlw   0x00
               retlw    'a'
               retlw   0x00
               retlw    'r'
               retlw   0x00
               retlw    'e'
               retlw   0x00
String_Descriptor2_End



; String Descriptor - Unknown string, transmitted in case Host sent a non valid string descriptor index
unknown_string_Descriptor   
               retlw   unknown_string_Descriptor_Length
               retlw   USB_DESCRIPTOR_STRING
               retlw    'U'
               retlw   0x00
               retlw    'n'
               retlw   0x00
               retlw    'k'
               retlw   0x00
               retlw    'n'
               retlw   0x00
               retlw    'o'
               retlw   0x00
               retlw    'w'
               retlw   0x00
               retlw    'n'
               retlw   0x00
               retlw    '!'
               retlw   0x00
unknown_string_Descriptor_End



; Class Specific Descriptors - HID
HID_Descriptor1
               retlw   0x06            ; Usage Page = 0xff00 (Vender Defined Page 1)
               retlw   0x00
               retlw   0xff
               retlw   0x09
               retlw   0x01         ; Usage = Vender Usage 1
               retlw   0xa1
               retlw    0x01         ; Collection = Application
               retlw   0x19
               retlw   0x01         ; Usage Minimum
               retlw   0x29
               retlw    0x40         ; Usage Maximum   => 64 input usages total (0x01 to 0x40)
         ; POTENTIAL ERROR ! ->
               retlw   0x15
               retlw    0x00         ; Logical Mimimum (Data values can have the minimum value of 0)
               retlw   0x25
               retlw    0x40         ; Logical Maximum (Data values can have the maximum value of 255)
               retlw   0x75
               retlw    0x08         ; Report Size (8 bit filed size)
               retlw     0x95
               retlw   0x40          ; Report Count: Make sixty-four 8-bit fields (the next time the parser hits an "Input",
                                 ; "Output", or "Feature" item)
               retlw   0x81
               retlw   0x00          ; Input (Data, Array, Abs): Instantiates input packet fields based on the above report
                                 ; size, count, logical min/max, and usage.
               retlw     0x19
               retlw    0x01          ; Usage Minimum
                retlw   0x29
               retlw    0x40          ; Usage Maximum    //64 output usages total (0x01 to 0x40)
                   retlw   0x91
               retlw    0x00          ; Output (Data, Array, Abs): Instantiates output packet fields. Uses same report size
                                 ; and count as "Input" fields, since nothing new/different was specified to the parser
                                 ; since the "Input" item.
               retlw   0xc0            ; End Collection
HID_Descriptor1_End

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Strange HID SetConfiguration Request error
« Reply #1 on: April 20, 2011, 05:48:35 pm »
Enumeration isn't complete until the host sends a Set Configuration request > 0.

If the comment here is accurate:

retlw    0x40         ; Logical Maximum (Data values can have the maximum value of 255)

the value should be 0x00FF

Be sure the host is retrieving the entire report descriptor.

Array data is intended for devices like keyboards, where the device reports only the keys pressed rather than pressed/not pressed for every key. Your report has 64 Usages and 64 bytes. If each byte corresponds to a Usage, "data, variable, absolute" might be more appropriate. 

You could try simplifying the report descriptor as a way to isolate the problem.

Jan

Pat Crowe

  • Member
  • ***
  • Posts: 39
Re: Strange HID SetConfiguration Request error
« Reply #2 on: April 22, 2011, 09:41:28 am »
; Language Code Descriptor 1 - Manufacturer String
String_Descriptor1
               retlw   String_Descriptor2_Length


I can't see where you are defining String_Descriptor2_Length,
but it should probably be String_Descriptor1_Length ?


bajwa

  • Member
  • ***
  • Posts: 2
Update
« Reply #3 on: April 22, 2011, 12:37:24 pm »
Well, the update is that the system is working now (at least sufficient to submit it in my university).

Thanks for the corrections  :).


However there are still a couple problems unsolved:

1. The device is ALWAYS recognized by Windows XP (running on a 32 bit machine), but when i attach the same device with a 64 bit machine running Windows 7, the percentage drops down to 30-35%.. but once it's recognized, the system works perfect. What can be the reasons?

2. Also, if we attach other USB Devices, we see Manufacturer's string and Product's string in a balloon, but there are no such notifications for this device.. Should i assume that there are no such notifications for HID Class Devices, or there is some problem in the code?

3. Lastly, write now the windows desktop application has to query the system for any new data.. This is extremely cumbersome in case polling interval has to be less than 50 ms, as it will introduce huge lags (due to multiple abstraction layers in windows). Is there someway that the Generic Windows HID Driver (as the specification suggests) queries the device every frame for if it has any new data to send, and when the device does send, the desktop application is notified (maybe by some callback routine)? Please suggest some techniques.


Thank You so much for Your time and efforts :).

To Jan Axelson: Your books are wonderfully written and Your website is equally supportive! Great resources! Thank You for Your efforts that gives developers an easy time! :)

Regards,
bajwa.

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Update
« Reply #4 on: April 22, 2011, 02:26:19 pm »
1. A hardware protocol analyzer will show what is happening on the bus and is the quickest way to identify the problem. Otherwise use whatever debugging tools you have to watch what happens during enumeration.

2. You may need a digitally signed INF files to cause the strings to display.

3. Create a thread that constantly looks for new received HID data and notifies the main application. In my WinUSB example at lvr.com/winusb.htm, see the ReadDataViaInterruptTransfer routine.

I'm glad to hear you've found my books and website useful!

Jan