USB Enumeration


In this article, we use universal serial bus (USB) communication data recorded by a logic analyzer to illustrate the USB enumeration process.











Introduction

A USB is the most common and successful computer interface. Learning about the USB is imperative for electronics engineers.

This article illustrates USB enumeration. USB enumeration is the process of USB device recognition by the host.



Why illustrate USB enumeration?

First, USB enumeration is one of the most important USB technologies. USB devices must complete the enumeration process to connect with hosts. USB product development engineers must understand USB enumeration before they can correctly design USB firmware.

Second, learning USB enumeration by only reading books is difficult. Almost all books on USB present the USB enumeration process by using various tables. Although these tables contain essential USB enumeration information, beginners find it difficult to understand USB enumeration if they only study these tables.

The purpose of this article is to provide supplemental information beyond that in books, thus allowing users to easily understand USB enumeration. We analyze USB communication data recorded by a logic analyzer to illustrate the USB enumeration process. Observing actual data is easier than studying tables in a book to understand USB enumeration.

Our focus on USB enumeration does not mean that other parts of USB are not vital. However, several books that illustrate USB technology are already available. Therefore, repeating the same information in our article is unnecessary. Because of length constraints, we have omitted basic USB knowledge. If you are unfamiliar with USB technology, we recommend that you read about it from a book or relevant documents. This article will simplify the USB enumeration chapter.



What is USB Enumeration?

USB enumeration is the process of USB device recognition by the host. An example of explaining USB enumeration is as follows: Imagine that a traveler wishes to stay at a hotel. To ensure that a suitable room is arranged for him or her, the hotel service staff must ask the traveler a few questions to determine his or her preferred room.

The conversation between the traveler and hotel staff might proceed as follows:

Hotel service staff: “How many people will be staying?”
Traveler: “One.”
Hotel service staff: “Would you like a room with a sea view or with a mountain view?”
Traveler: “I would like a room with a sea view.”
Hotel service staff: “Would you like a shower or a bathtub?”
Traveler: “A shower.”
......
......

After asking relevant questions, the hotel service staff can select a preferred room for the traveler. USB enumeration consists of a similar process. Once USB devices are connected to hosts, the hosts query to identify the types and needs of the devices. After the questions have been answered, the hosts determine whether they can be connected to the devices. If so, drivers are assigned to the devices to complete USB enumeration.



How to Use a Logic Analyzer to Measure USB Communication?

USB has two data transmission wires, namely D+ and D−. To measure USB communication, a user must connect the D+, D−, and ground (GND) wires to a logic analyzer. Peeling the skin of the USB cable reveals four wires—red, black, green, and white wires. The red, black, green, and white wires represent the power supply wire, GND, D+, and D−, respectively. To connect the USB to the logic analyzer, we peeled the black, green, and white wires (do not cut them off) and then connected them to the logic analyzer.


Alternatively, you can purchase a USB adapter board from Perytech. The adapter board connects USB wires to pins to facilitate measurements. The adapter board is very simple; you can construct an adapter board.



The device under test is a USB keyboard. We first connected channels A0 and A1 of the logic analyzer to D+ and D−, respectively, as displayed in the following image.



When the USB device is plugged into the host, USB enumeration begins immediately. Therefore, logic analyzer software must be set up before plugging the USB keyboard into the host. Next, the compression mode of the logic analyzer is turned on. USB enumeration takes a while. For instance, the USB keyboard took approximately 1 s to complete the USB enumeration. To measure the longtime signal, we enabled the compression mode of the logic analyzer. We set the sampling rate to 200 MS/s and the trigger condition to the A0 rising edge trigger.

We clicked “Run” after ensuring that everything was set. Because the USB device was not connected to the host, D+ and D− did not have signals and the logic analyzer was not triggered. After plugging the USB keyboard into the host, USB communication triggered the logic analyzer, which then began recording the data.

The recorded USB signals are depicted in the following image. The recording time was approximately 1.3 s. If no compression mode exists, a sampling rate of 200 MS/s can be used to record 1.3 s. Each channel requires 260 MB of memory.



On zooming, we can observe that at the beginning of communication, the D+ and D− signals were in a low voltage state for more than 10 ms during two time periods. These two time periods were reset signals that the USB hub sent to the USB device. For USB 2.0 high-speed devices, the reset signal is sent only once.



Zooming in further, we can observe start-of-frame packets (SOFs), which are indicated by the yellow box in the following figure. These SOFs were sent at the beginning of each frame. For USB 1.1, the period of each frame is 1 ms. In the following figure, the interval between two SOFs is approximately 998.66 µs. The SOF interval plus the width of the SOF (approximately 1.34 μs) is 1 ms.



Zooming in even further, we can observe the packet content, which is depicted in the following figure. Observing signals and packets simultaneously provides us a deep understanding of USB signals. However, to save time, the “Packet List” function is a suitable choice for viewing packets. Click on “Tool” → “Packet List” to open the packet list.



The contents displayed on the screen after opening the Packet List function are depicted in the following figure. The Packet List function lists all the packet data. This allows users to view packet data more easily.



How to Analyze USB Packets?

These packets contain USB enumeration information. To interpret these packets, the USB specification can be referred. The USB specification referenced in this document is USB 2.0, which is available for download at usb.org.

A brief explanation of the USB communication format is provided. When a host needs to access a USB device (e.g., read data from a USB hard disk), the USB driver divides this request into one or more “Transactions.” A Transaction is the unit of USB data transmission, and each transaction comprises 2–3 USB packets. The first packet of the transaction is the token packet, which is used to indicate the type of transaction. If the transaction involves data transmission, then the second packet is the data packet. The direction of data transmission between a host and a USB device can be from the host to the USB device or from the USB device to the host. Not all transactions have data packets. Have data packets or not and the transmission direction of the data packet all depends on the token packet.

The last packet of the Transaction is the handshake packet. The receiver (host or the USB device) uses the packet to feedback whether correct data is obtained.

The three packets of the following figure form the first transmission. The packet number in the yellow box on the left is generated by the logic analyzer to assist users in viewing the desired packets quickly. The green box in the first packet contains the token (i.e., “setup”). Because the USB device is not yet assigned the “address” and “endpoint” value, the address and endpoint values of this setup packet are both zero.



The second USB packet is the data packet. This causes the data to be passed from the host to the USB device. To analyze the data in the data packet, users must refer to the section “Format of Setup Data” and Table 9-2 in the USB specification. The meaning of each byte is explained in the table.

Offset Field Size Value Description
0 bmRequestType 1 Bitmap Characteristics of request:

D7: Data transfer direction
  0 = Host-to-device
  1 = Device-to-host

D6...5: Type
  0 = Standard
  1 = Class
  2 = Vendor
  3 = Reserved

D4...0: Recipient
  0 = Device
  1 = Interface
  2 = Endpoint
  3 = Other
  4...31 = Reserved
1 bRequest 1 Value Specific request
2 wValue 2 Value Word-sized field that
varies according to request
4 wIndex 2 Index or Offset Word-sized field that varies
according to request; typically
used to pass an index or offset
6 wLength 2 Count Number of bytes to transfer
if there is a Data stage

Format of Setup Data. Source: USB 2.0 Specification Table 9-2



Byte 0 is a bmRequestType, and its value signifies the properties of the request. The bmRequestType function is divided into three parts—recipient, type, and data transfer direction. The logic analyzer automatically splits the bmRequestType into three fields. A recipient field value of 0 denotes “Device,” and a type field value of 0 denotes “Standard.” The data transfer direction (Dir) field is D→H, that is, the direction of data transmission is from the device to the host.

Byte 1 is a bRequest and has a value of 0 × 06, as indicated in Table 9-4 (i.e., Standard Request Codes) of the USB specification. According to the table, 0 × 06 is GET_DESCRIPTOR. Thus, the request is GET_DESCRIPTOR.

bRequest Value
GET_STATUS 0
CLEAR_FEATURE 1
Reserved for future use 2
SET_FEATURE 3
Reserved for future use 4
SET_ADDRESS 5
GET_DESCRIPTOR 6
SET_DESCRIPTOR 7
GET_CONFIGURATION 8
SET_CONFIGURATION 9
GET_INTERFACE 10
SET_INTERFACE 11
SYNCH_FRAME 12

Standard Request Codes. Source: USB 2.0 Specification Table 9-4



Bytes 2–7 are the fields for wValue, wIndex, and wLength. Each field is 2-bytes wide, and its meaning varies according to the request received. In this example, the request is GET_DESCRIPTOR. In Section 9.4.3 of the USB specification, the meanings of the three fields when the request is GET_DESCRIPTOR are explained (presented in the following table).

bmRequestType bRequest wValue wIndex wLength Data
10000000B GET_DESCRIPTOR Descriptor Type
and
Descriptor Index
Zero or
Language ID
Descriptor
Length
Descriptor

Get Descriptor. Source: USB 2.0 Specification



The high byte in wValue (value is 0 × 01) represents the descriptor type. The meaning of this value can be obtained from Table 9-5 of the USB specification. According to the table, a value of 1 signifies DEVICE. In other words, the type of the descriptor is DEVICE.

Descriptor Types Value
DEVICE 1
CONFIGURATION 2
STRING 3
INTERFACE 4
ENDPOINT 5
DEVICE_QUALIFIER 6
OTHER_SPEED_CONFIGURATION 7
INTERFACE_POWER 8

Descriptor Type. Source: USB 2.0 Specification



The third packet is ACK and is a response from the USB device to indicate that the data has been received correctly.

USB Packets 4 and 5 are In and NAK, respectively, as displayed in the following figure. The two packets form one transaction. Because this transaction contains no transmission data, only two packets are present. The USB IN and OUT are from the perspective of the host. In other words, IN indicates that the host wishes to read data from the USB device. The USB device’s response of NAK does not indicate a data error but rather that no data is available for transmission. The USB device is required to issue a response even if no data is available for transmission. If the USB device does not issue a response for some time, the USB device is assumed to be disconnected by the host. Because NAK packets contain no data, they are generally skipped in analysis.



The host continues to send In packets to request for data, and the USB device responds in the ninth packet. The response data contains 18 bytes separated into three data packets. The reason for separation is that in this transmission mode, each packet can contain a maximum of only 8 bytes. The content of the three packets is illustrated in the following figure.



These data are explained as follows. GET_DESCRIPTOR and DEVICE are the request and type functions, respectively. Thus, the data requested by the host are the device descriptors. The data format and description of the device descriptors are presented in Table 9-8.

Offset Field Size Value Description
0 bLength 1 Number Size of this descriptor in bytes
1 bDescriptorType 1 Constant DEVICE Descriptor Type
2 bcdUSB 2 BCD USB Specification Release Number in Binary-Coded Decimal.
4 bDeviceClass Class 1 Class code (assigned by the USB-IF).
5 bDeviceSubClass 1 SubClass Subclass code (assigned by the USB-IF).
6 bDeviceProtocol 1 Protocol Protocol code (assigned by the USB-IF).
7 bMaxPacketSize0 1 Number Maximum packet size for endpoint zero (only 8, 16, 32, or 64 are valid)
8 idVendor 2 ID Vendor ID (assigned by the USB-IF)
10 idProduct 2 ID Product ID (assigned by the manufacturer)
12 bcdDevice 2 BCD Device release number in binary-coded decimal
14 iManufacturer 1 Index Index of string descriptor describing manufacturer
15 iProduct 1 Index Index of string descriptor describing product
16 iSerialNumber 1 Index Index of string descriptor describing the device’s serial number
17 bNumConfigurations 1 Number Number of possible configurations

Standard Descriptor Type. Source: USB 2.0 Specification



The aforementioned table represents the flow of the host reading the device descriptor of the USB device. However, enumeration is not completed. To complete USB enumeration, the following five steps must be conducted:

1. The host reads the Device Descriptor from the USB device.
2. The host assigns an address for the USB device.
3. The host reads the Configuration Descriptor from the USB device.
4. The host reads the Interface Descriptor from the USB device.
5. The host reads the Endpoint Descriptor from the USB device.

The analyzed USB packet previously is step one. The analysis methods for the other steps are similar. Therefore, the description is not repeated. Because the order of the enumeration commands is random, the USB devices must be able to respond to any command at any time. Sometimes, a host may read a descriptor repeatedly.

A USB device has only one device descriptor but can have multiple configurations. The number of configurations is defined in a device descriptor. Each configuration can have multiple interfaces. The number of interfaces is defined in a configuration descriptor. Each interface may have multiple endpoints. The number of endpoints is defined in an interface descriptor. Overall, USB enumeration features a hierarchical data structure similar to that of a tree diagram. The top layer is the device descriptor, followed by the configuration, interface, and endpoint descriptors.

A demonstration mode is available in logic analyzer software, which allows the use of software without a logic analyzer. Please visit our web page to download the software. The software contains a file that records the USB enumeration process. You can use logic analyzer software to load this file for observing the USB enumeration process. By observing the USB enumeration process and referring to the USB specification document, you will understand USB enumeration.



How to Design USB Enumeration Programs

After understanding how USB enumeration functions, how should one start writing a USB enumeration program? In general, writing a USB program is similar to filling a USB data table. A CPU with a USB interface possesses a USB controller. The USB controller submits data to the host during the enumeration process to accomplish USB enumeration.

The format of the enumeration data table for each USB controller is not necessarily the same. Some tables are designed using the C language, and others are designed using assembly languages. Most USB IC companies provide sample codes. An example code of the Device Descriptor is listed as follows:

code uint8 DeviceDescriptor[0x12] =
{
/* bLength */
0x12,
/* bDescriptorType */
0x01,
/* bcdUSB */
0x10,
0x01,
/* bDeviceClass */
0x00,
/* bDeviceSubClass */
0x00,
/* bDeviceProtocol */
0x00,
/* bMaxPacketSize0, the pdiusbd12 chip has a maximize size of 16 */
0x10,
/* idVender, just for test, for commercial use, you should apply for it from the usb association */
0xF3,
0x04,
/* idProduct */
0x03,
0x01,
/* bcdDevice, version number of product */
0x07,
0x01,
/* iManufacturer */
0x00,
/* iProduct */
0x00,
/* iSerialNumber */
0x00,
/* bNumConfigurations, the number of configurations of a device, most device have only one configuration */
0x01
};



Importance of the Compression Mode for Measuring USB Signals

The compression function of logic analyzers is key to measuring USB signals. The difference between using and not using the function is demonstrated in the following image. The first figure illustrates the USB signals measured without using the compression function. Here, we set the memory size to 64 k and the sampling rate to 200 MS/s. The recording time was approximately 327.67 µs.



The packet list recorded only four packets.



Next, a logic analyzer produced by a different manufacturer was tested. This logic analyzer has a maximum compression rate of 256. The test conditions were the same as before, and the recording time was approximately 40.478 ms.



The packet list recorded 20 packets, which is still insufficient. USB keyboards require at least 400 USB packets to complete USB enumeration. The 20 packets recorded were only 1/20 of the required amount.



Finally, the Perytech logic analyzer was tested. The test conditions were the same as before, and the recording time was approximately 3.36 s.



With the Perytech logic analyzer, 1680 packets were recorded in the packet list. This logic analyzer has a maximum compression rate of 1 million. The test result revealed that the compression mode substantially improved the recording time.



Why USB 1.1 is More Suitable for Learning USB Programming than USB 2.0 is?

We used USB 1.1 to illustrate USB enumeration. Although USB 3.1 is now available, USB 1.1 is more suitable for learning USB enumeration because of the following reasons. First, USB 1.1 is the basis of all USB specifications. USB 2.0 is the extension of USB 1.1, and its structure is very similar to that of USB 1.1. Therefore, if you are familiar with USB 1.1, you can understand USB 2.0 in a short time. Although USB 3.0 contains additional features, it still needs to be compatible with USB 2.0 and USB 1.1. Thus, the engineer who learns USB 3.0 must also understand USB 2.0 and 1.1.

Second, USB 1.1 comprises a cheaper and wider selection of chips than USB 2.0 does. Many low-end 8-bit processors have built-in USB 1.1, whereas only a few have built-in USB 2.0. Moreover, chips with built-in USB 2.0 are more expensive than chips with built-in USB 1.1. Because of the high speed of USB 2.0, impedance matching requirements for the PCB and wires are high. This increases the PCB costs and development time. By contrast, the requirements for USB 1.1 are less stringent and hardware design is less difficult.

In terms of speed, USB 3.0 is more suitable in applications where large amounts of data must be transmitted. However, most controls require the transmission of only a small amount of data. To this day, the RS232 with Baud Rate 19200 (19200 bits per second) is still very common in industrial control, and USB 1.1 with a speed of 12 M is sufficient.

Finally, USB 2.0 analysis instruments are markedly expensive and in the price range from thousands of dollars to ten thousands of dollars. Thus, beginners may not be able to purchase them. For analyzing USB 1.1 signals, only Perytech logic analyzers are required. A single Perytech analyzer costs less than $100. The Perytech logic analyzer is powerful, and analyzing the USB is only one of its features.