tinyusb icon indicating copy to clipboard operation
tinyusb copied to clipboard

"Set Address failed" error on Windows

Open aauer1 opened this issue 5 years ago • 17 comments

Set up

  • Board: A custom board with an STM32F401 controller
  • PC OS: Windows 10
  • Firmware: it's basically the examples/device/webusb_serial example.

Describe the bug What I have recognized is that at least on Windows 10 the device is not correctly enumerated. When I attach the device to the Windows 10 host, the device gets disabled and in the device manager I see "Set Address failed" error message. The strange thing is this is not happening on all USB ports. I only see this problem on USB 3.0 ports. If I connect it to an USB 2.0 port on the same PC it works just fine. Additionally, this error doesn't happen e.g. on Ubuntu 20.04 (I tested it on the same host on the same port). As mentioned above, I'm basically using the webusb_serial example. But I added it to my own simple application code. Maybe someone could probably run the original webusb_serial example on some stm32 board.

What could be the problem here? Has anybody an idea where to start looking to solve this problem? Could it be some kind of timing problem on USB 3.0 ports caused by the Windows driver?!

To reproduce Steps to reproduce the behavior:

  1. Start the STM32 board with the webusb_serial example
  2. Connect the board over USB to some USB 3.0 host port on a Windows 10 machine
  3. In the device manager the device should be visible with some "set address failed" error. Windows shows also an error popup message.

aauer1 avatar Jun 18 '20 12:06 aauer1

"basically the same" is not good enough, please run the exact stock example and, if possible with one of the official dev board. the condition for reproduce is already ambiguous enough. Also please provide the debug log and/or bus capture, it would help others to analyse without actually reproducing the issue

hathach avatar Jun 18 '20 12:06 hathach

I modified my setup and now I'm running the exact webusb_serial stock example. The result is the same. The device is not working under Windows 10 when it is connected to an USB 3.0 port. I also captured the log output:

USBD Bus Reset
USBD Setup Received 80 06 00 01 00 00 40 00 
  Get Descriptor Device
  Queue EP 80 with 18 bytes
USBD Xfer Complete on EP 80 with 18 bytes
  Queue EP 00 with zlp Status
USBD Xfer Complete on EP 00 with 0 bytes
USBD Bus Reset
USBD Setup Received 80 06 00 01 00 00 40 00 
  Get Descriptor Device
  Queue EP 80 with 18 bytes
USBD Xfer Complete on EP 80 with 18 bytes
  Queue EP 00 with zlp Status
USBD Xfer Complete on EP 00 with 0 bytes
USBD Bus Reset
USBD Setup Received 80 06 00 01 00 00 40 00 
  Get Descriptor Device
  Queue EP 80 with 18 bytes
USBD Xfer Complete on EP 80 with 18 bytes
  Queue EP 00 with zlp Status
USBD Xfer Complete on EP 00 with 0 bytes
USBD Bus Reset
USBD Setup Received 80 06 00 01 00 00 40 00 
  Get Descriptor Device
  Queue EP 80 with 18 bytes
USBD Xfer Complete on EP 80 with 18 bytes
  Queue EP 00 with zlp Status
USBD Xfer Complete on EP 00 with 0 bytes
USBD Suspend

On an USB 2.0 port the log output looks like this:

USBD Bus Reset
USBD Setup Received 80 06 00 01 00 00 40 00 
  Get Descriptor Device
  Queue EP 80 with 18 bytes
USBD Xfer Complete on EP 80 with 18 bytes
  Queue EP 00 with zlp Status
USBD Xfer Complete on EP 00 with 0 bytes
USBD Bus Reset
USBD Setup Received 00 05 0D 00 00 00 00 00 
  Set Address
USBD Xfer Complete on EP 80 with 0 bytes
USBD Setup Received 80 06 00 01 00 00 12 00 
  Get Descriptor Device
  Queue EP 80 with 18 bytes
USBD Xfer Complete on EP 80 with 18 bytes
  Queue EP 00 with zlp Status
USBD Xfer Complete on EP 00 with 0 bytes

So, the communication is starting the same way. But after the first transfer an "USBD Bus Reset" is logged. On USB 3.0 it starts over again and starts with the same "Get Descriptor Device" request. On the USB 2.0 port, it is setting the address correctly.

But why is this happening? Is it normal that a Bus reset is happening after the first descriptor request?

aauer1 avatar Jun 19 '20 06:06 aauer1

I tested another example. I used the "hid_generic_inout". And this one works!

USBD init
HID init
USBD Bus Reset
USBD Bus Reset
USBD Setup Received 80 06 00 01 00 00 40 00 
  Get Descriptor Device
  Queue EP 80 with 18 bytes
USBD Xfer Complete on EP 80 with 18 bytes
  Queue EP 00 with zlp Status
USBD Xfer Complete on EP 00 with 0 bytes
USBD Bus Reset
USBD Setup Received 00 05 16 00 00 00 00 00 
  Set Address
USBD Xfer Complete on EP 80 with 0 bytes
USBD Setup Received 80 06 00 01 00 00 12 00 
  Get Descriptor Device
  Queue EP 80 with 18 bytes

This is really strange. As you can see, after the bus reset, I get an address assigned. Has anyone a clue what may be the problem here.

aauer1 avatar Jun 19 '20 06:06 aauer1

I tried to figure out what's the difference between examples which are working and the webusb example which is not working. And I found out, that if I change the bcdUSB version number in the device descriptor to 0x0200, the device gets enumerated and the "Set Address failed" error is gone.

So, what's the difference between bcdUSB 0x0210 and 0x0200? Would the webUSB stuff also work with bcdUSB set to 0x0200 instead of 0x0210? Because the comment in the code is telling me that it needs to be "at least 2.1 or 3.x for BOS & webUSB"?! Is that true?

aauer1 avatar Jun 19 '20 11:06 aauer1

So, what's the difference between bcdUSB 0x0210 and 0x0200? Would the webUSB stuff also work with bcdUSB set to 0x0200 instead of 0x0210? Because the comment in the code is telling me that it needs to be "at least 2.1 or 3.x for BOS & webUSB"?! Is that true?

BCD = 2.1 will trigger host to request BOS descriptors, windows will go further to also request MS OS 2.0 descriptor https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-os-2-0-descriptors-specification which is needed for WebUSB. in your 1st log, host indeed doesn't attempt to Set Address at all, maybe the device descriptor does not make sense. Can you try with another PC with 3.0 port, maybe windows driver somehow expect device to have at least highspeed with 2.1, I am not sure, please also update your 1st port with windows build number as well. I am on Linux, so my help is limited, but other windows user could help.

PS: it can be racing condition as well, it is hard to know without a usb analyzer, though you can also try to capture the bus data with wireshark as well. It will definitely help to analyze the problem.

hathach avatar Jun 20 '20 18:06 hathach

I think I'm using the latest version of windows 10. It is Windows 10 Pro Version: 2004 Build Number: 19041.2020

aauer1 avatar Jun 23 '20 07:06 aauer1

I think I'm using the latest version of windows 10. It is Windows 10 Pro Version: 2004 Build Number: 19041.2020

Could you be able to reproduce this on another machine with USB 3.0 port ?

hathach avatar Jun 23 '20 17:06 hathach

Yes, I was able to reproduce the same error on two other windows 10 machines. But I don't know the exact version and build number of them. BTW with windows 7 on the very same machine and the same USB 3.0 port it works fine. I think somehow the windows 10 USB 3 driver is different. I also tested to set bcdUSB version to 0x0200 and manually install the winusb driver with zadig. This workaround seems to work at least on my machine. I will test this on another machine tomorrow.

aauer1 avatar Jun 23 '20 19:06 aauer1

I can confirm that I had this issue as well, setting bcdUSB to 0x0200 is what I'm doing as well now to get around it. I have an analyzer and will look into this more in depth if I get time to. For reference, I am using an STM32H750 with a USB3300 ULPI PHY.

MimitechIndustries avatar Feb 05 '21 10:02 MimitechIndustries

I am experiencing the exact same problem. Is there already a workaround available that doesn't involve fiddling around with drivers?

I'm trying to implement a composite device that has RNDIS capabilities and a serial interface. This works fine as long as I only provide one configuration descriptor. As soon as I add a second configuration (for CDC_ECM support since Mac OSX devices don't support RNDIS), my windows PC will only pick the very first interface it sees in a descriptor.

After doing some googling I concluded that I need to provide a BOS descriptor for Windows to tell it to use all available interfaces contained in the first configuration. However, when I change bcdUSB to 0x0210, enumeration fails entirely under Windows.

On a side note: Using my Ubuntu system, any combination/order of the descriptors work fine. There I can also change the bcdUSB version without getting into any trouble.

MatiMcFly avatar Jul 08 '22 13:07 MatiMcFly

It seems that windows 10 decides that our descriptors aren't correct and refuse to proceed with enumerate. I still haven't tried this out

@MatiMcFly your issue is different, in this issue, device isn't got it address assigned yet. Double check your descriptor, length, type etc... You could create your own issue with detail of setup/code/log for reproducing/troubleshooting.

hathach avatar Jul 18 '22 15:07 hathach

Since setting up a new project takes some time, I decided to look further into the composition of my descriptors. I am sure they contain correct data since I checked them multiple times.

The only real difference is that in the device descriptor I set .bcdUSB = 0x0210 or .bcdUSB = 0x0200 respectively.

Here is some log output which hopefully helps with understanding my issue:

.bcdUSB = 0x02100 (not working): bcdUSB_0x0210.txt

I noted that after the reset in line 53 the startup behavior seems to repeat itself. I cannot explain this.

.bcdUSB = 0x0200 (working)*: bcdUSB_0x0200.txt

In this log file, we can see that the enumeration seems to work since the endpoints for actual communication are opened in lines 92 and onwards.

side note: by working I mean that the device gets enumerated. Of course, Windows only detects one of the two interfaces present in the very first configuration. Therefore I need to provide the Windows BOS headers in order to have it read all my available interfaces.

Edit: the logs have all been acquired on a USB 3.0 port. I could also provide logs for a Linux machine as well as logs for a USB 2.0 port.

MatiMcFly avatar Jul 27 '22 07:07 MatiMcFly

Setting bcdUSB to 0x0210 also causes enumeration to fail on RP2040 it seems. 0x0200 works there too, but it means BOS/MS OS descriptors won't be requested 😔

EDIT: Actually I just tried the webusb_serial example and that works..? I was trying to do it through the Adafruit TinyUSB library if that makes any difference, but I wouldn't have expected it to...

EDIT 2: Okay did some debugging and my problem seems to be specific to Adafruit TinyUSB so I'll make an issue over there

JonnyHaystack avatar Sep 14 '22 18:09 JonnyHaystack