December 9, 2020

USB - enumeration

When a USB device is first plugged in, resistors on the D+ and D- lines tell the host that a new device has appeared, and what speed device it is. The host should then begin enumeration by sending a GET_DESCRIPTOR request to USB device 0. This is the first thing I should see once I plug in my device.

The exact sequence may be operating system dependent. The host may decide to reset the device after the first response and then repeat the request (Windows). The first descriptor will include the max packet size (endpoint size), and once the host has that, it will send a SET_ADDRESS message and then continue with more GET_DESCRIPTOR messages.

STM32F411 interrupts and enumeration

The chip reports an "enumeration done" interrupt. It calls this "speed enumeration", so it may not necessarily mean that the enumeration we are talking about here is done (or has been abandoned). In fact, we see this interrupt immediately after a reset interrupt.

The chip also reports reset and suspend interrupts. These have nothing to do with receiving packets. The host resets the device by pulling both D+ and D- low for at least 10 ms. The host causes the device to suspend itself by not sending the SOF "keep alive" signals for at least 3ms (it normally sends them every 1ms).

My first setup packets

Now that I have the Rx level interrupt alive and working, I am getting setup packets. Here is what I have seen so far:
Setup:  80 06 00 01 00 00 40 00
Setup:  00 05 1B 00 00 00 00 00
Setup:  00 05 13 00 00 00 00 00
The first packet is what the host sends over and over for the first 63 seconds (with various resets). Then the host gets frustrated and performs a suspend followed by a reset and sends the second packet several times. After a total of 74 seconds, the host performs another reset, sends the third packet several times, then gives up entirely after 85 seconds and does a final suspend.

The first packet is a GET_DESCRIPTOR, which we are not responding to. This makes sense. The last two are SET_ADDRESS. The first SET_ADDRESS tries to set the address to 0x1b, then it tries 0x13. This seems odd, but there is probably some reason. I am not responding to any of this.


Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org