How to debug the driver inside a USB20 device using e.g win tools

I want to develop a USB2.0 composite device (STM32µC) consisting of a UVC and a HID component. Until now I used 2 separate devices – the UVC and HID component which I’ve connected to a HUB and which worked so far using WIN7 or WIN10. To put everything into one µC I have copy+ pasted everything together accordingly to some examples on how to make a composite. However this approach didn’t worked so far. What might work is that the composite device descriptor is read and both devices show up in the device manager for approx. 3 sec until the HID device fails with code 10 (but only in WIN10 – in WIN 7 just 2 HID devices show up with code 10 failure).

I am not sure how to debug this problem – both sides: the host (windows side) and the device (side inside the µC) are complicated and depend from each other. The reason why I posted this question here is that I was thinking to debug the driver inside the device using windows (host) tools.

An ideal tool would let me go step by step through the device enumeration process inside the win kernel while observing what happened inside my device. I tried so far WIN logman + network monitor and also USB20CV from which I understand that the descriptor of the 2/0 interface (which is the HID device) could not be retrieved. Overall something/a lot inside my device driver inside the µC device went wrong.

I would be very happy if someone could give some hints how to debug this problem from the windows (host) side.

Best Regards,
Matthias

You probably already know that the first thing we’re going to suggest is that you use a USB bus analyzer. They are not expensive and I would not undertake any USB project without one.

Having said that, one thing to do is enable USB tracing so you can see what the host-side drivers are doing.

Peter

1 Like

Do you want to post your descriptors? Remember that every interface must have a unique number. If you just combined the descriptors without giving the HID descriptor a unique interface number, that would cause this kind of problem. If the UVC is interface 1 and 2, then the HID needs to be 3.

wireshark has a somewhat useful usb trace component - I personally found it
more useful and much easier to use than the microsoft usdb trace facility.

That plus what peter said: go buy a real usb analyzer. For device
development this is simply a requirement.

Mark Roddy

1 Like

Dear community,

thank you very much for giving hints - I will definitely try to get an USB analyzer soon.

@Tim thank you very much for offering to look at the descriptor – I checked each value inside the descriptor which I got from USBlyzer against the values used inside the actual µC code (the descriptor consists of parts copied from STM32F105/7xx, STM32F2xx and STM32F4xx USB On the-Go Host and Device library and from the github repositoryhttps://github.com/iliasam/STM32_HOST_UVC_Camera made from iliasa - both devices work as standalone)- due a limit for each post I#ve attached the descriptor inside the file uvchiddescriptor.txt

Best Regards,
Matthias

OK, so your camera does 160x122 at 2 frames/second. Things look OK. The HID interface is now interface 2. Usually, the interface number isn’t used in the wire traffic, but a HID device gets requests over the control endpoint, and those specify an interface number. Have you changed the code to look for interface 2 instead of interface 0?

Dear Tim,
thank you for checking the descriptor – 160x122 at 2 frames is correct. It helped me very much that you’ve looked through the descriptor without complains – so this seems to be correct. The problem seems therefore more complicated than expected. Regarding your question how I check for the interfaces – it probably points directly into my lag of knowledge. What I’ve so far discovered is after receiving an interrupt from the USB core interrupt of the µC (this is inside the device) the following happens:

  1. handler reads the data from EP0…X and dispatches the data into FIFO0…X
  2. if the data from EP0 are of the sort “out” thus are from the PC → 3
  3. if the data are classified as setup data → 4
  4. the setup state machine is called and data are further processed either in
    USB_REQ_RECIPIENT_DEVICE or USB_REQ_RECIPIENT_INTERFACE
    state
  5. from USB_REQ_RECIPIENT_INTERFACE state the data (which are now severely enriched by other register read procedures from the USB core of the µC) are now relayed to the composite class driver.
  6. inside the composite class driver is a callback function that received that information and accordingly to examples on how to make a composite device I’ve placed some “if” statements inside that callback that further branch the request either into the video- or the hid- class driver.
    The video example was defined by default for interfaces 0 and 1 and the HID inside the HID-CDC example for Interface 0. I’m nearly sure that I’ve changed the HID class driver to now match interface 2 before replacing the CDC parts with that of the video example. Could be that I left out something.
    What I’ve found so far from debugging is not consistent since the host requests information about interface 1 via USB_REQ_RECIPIENT_INTERFACE (which is the second UVC interface) and after that it then requests information regarding the endpoint 0x82 via USB_REQ_RECIPIENT_ENDPOINT, which is that of the HID interface. Something is not correctly processed inside my device. I am also not sure whether I’ve configured the FIFO’s correctly (required in point 1) – I will double check this too.
    Best Regards,
    Matthias

Dear Community,
meanwhile I’ve got access to a hardware USB analyzer (ellisys) – from its output I can see that including the second request “SetInterface” everything does similar compared with other composite devices. Then a Class request “0x0A” request fails. I would be glad if someone could take a look into the screenshot or the more complex txt file I’ve attached to suggest what might be wrong inside my device.
Best Regards,
Matthias

Dear Community,
with the help of another community (ST community) I got one step ahead. Inside the device predefined max. Number of interfaces made the device to look only at the interfaces 0 and 1. After increasing the definevalue for max. interfaces (USBD_ITF_MAX_NUM) the problem seems to be solved. Now the process got stuck on one of the subsequent request – the analyzer says: “Device is not ready to send data.” If someone knows what kind of data the host expects at this stage from the device I would be glad to hear about it:

Best Regrads,
Matthias

Ummmm… There’s a read being sent to the device on Endpoint #2. The device does not have any data to send on EP #2, so it replies with a NAK (which is how USB works).

Peter

Dear Community,
after fixing numerous bugs I finally got nearly everything to work @Peter_Viscarola: Thankyou for giving this hint - there was a dead branch inside the firmware source code which led to the wrong answer of the device . Without an USBanalyzer it would definitely be impossible to get something to work which is beyond the examples given with a dev kit – I just wanted to post the log of the USB analyzer here for those who want to compare it with their own work.

1 Like