View USB device descriptors on Windows

I have occasionally fired up a Linux virtual machine just to view USB descriptors of devices using lsusb -v. This post briefly describes a couple of tools for Windows that can be used to view descriptors of USB devices.

Thesycon USB Descriptor Dumper

This single purpose utility, from a German device driver development company, does what it proposes. It lists all connected USB devices and dumps the information for the selected device.



This tool is part of the Windows Driver Kit (WDK) and Debugging Tools for Windows. Its source code is available as part of the Windows driver samples GitHub repo.



Arduino USB Serial firmware from scratch

I have need to change the USB descriptors of an Arduino Uno R3 acting as a peripheral to another device. This post describes how I built a USB Serial firmware for the ATmega16U2 on an Arduino Uno R3, using Atmel Studio 7 and its LUFA Library extension. It can be flashed using the built-in DFU firmware and Atmel’s FLIP tool.

Source files that perform the actual USB/serial proxying are derived from USB to Serial Converter example project for the at90usb1287 (File -> New -> Example Project…). I suggest creating a project based on that example and copying the files over. I have also borrowed code from the official source code at GitHub to enable additional functionality such as allowing a sketch to be uploaded from the Arduino IDE.


Install LUFA Library extension if not already installed (Tools -> Extensions and Updates…).


Create a new project for the ATmega16U2 (File -> New -> Project…).



Use ASF Wizard (ASF -> ASF Wizard) to add LUFA modules and remove the Generic board support (driver) module.


Configure GCC symbols (Project -> Properties). Change BOARD to BOARD_UNO, and add F_CPU=16000000UL, and F_USB=16000000UL.


Copy over source files from the example project mentioned earlier. Resolve any build errors.

Flash (Tools -> Device Programming) the firmware using the FLIP tool.


Reboot the Arduino.

Arduino USB DFU firmware from scratch

The Device Firmware Upgrade (DFU) firmware for the ATmega16U2 on Arduino UNO R3 is used to flash the USB Serial firmware, among others, using Atmel’s FLIP tool.

This post documents how you can build from scratch DFU firmware using Atmel Studio 7 and its LUFA Library extension. You’ll need an ISP/ICSP programmer to program the ATmega16U2.

You can install the LUFA extension from the Extensions and Updates dialog (Tools -> Extensions and Updates).


Create a new project based on the DFU Bootloader example (File -> New -> Example Project…).


Change the compiler optimization setting to -Os in toolchain properties (Project -> Properties).


Build the solution and flash (Tools -> Device Programming) using an ISP/ICSP programmer connected to the ICSP2 header.



USB Descriptors of Arduino UNO

I’ve been studying the USB interface of Arduino UNO so that I can interface it to an embedded host. It appears as a serial port on Linux, OS X, and Windows 10, without need for custom drivers. The Arduino IDE can reprogram the device over the serial port. Makers also use it to output debug information.



Here’s the detailed device descriptor as seen on Linux with lsusb -v

Bus 001 Device 005: ID 2341:0043 Arduino SA Uno R3 (CDC ACM)
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            2 Communications
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0         8
  idVendor           0x2341 Arduino SA
  idProduct          0x0043 Uno R3 (CDC ACM)
  bcdDevice            0.01
  iManufacturer           1
  iProduct                2
  iSerial               220
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           62
    bNumInterfaces          2
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0xc0
      Self Powered
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         2 Communications
      bInterfaceSubClass      2 Abstract (modem)
      bInterfaceProtocol      1 AT-commands (v.25ter)
      iInterface              0
      CDC Header:
        bcdCDC               10.01
      CDC ACM:
        bmCapabilities       0x06
          sends break
          line coding and serial state
      CDC Union:
        bMasterInterface        0
        bSlaveInterface         1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval             255
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass        10 CDC Data
      bInterfaceSubClass      0 Unused
      bInterfaceProtocol      0
      iInterface              0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x04  EP 4 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1

Interface descriptor with class Data Interface Class (bInterfaceClass=0x0A) is used for serial communications. Endpoint with bEndpointAddress 0x03 is used for input, and bEndpointAddress 0x04 for output.

Getting Started with the ESP-03

The ESP-03 is a very affordable Wi-Fi module built around the ESP8266EX chip by Espressif. The ESP8266 has become very popular among makers who want to add wireless smarts to things at home and work.

The ESP-03 has two useful modes of operation that can be initiated by controlling its GPIO pins – normal mode and flash mode.

Normal mode wiring is show in the figure below. ESP-03 shown here is powered using SparkFun’s FTDI Basic Breakout – 3.3V – USB to serial module.

Normal Mode

In this mode, ESP-03 executes firmware programmed to the SPI Flash. SPI Flash is an external NOR Flash chip where program instructions are stored, and retrieved during execution.

The ESP-03 has a 4 Mbit 25Q40BT part which allows for 512 KB of program space. Of that, about 423 KB is available for your own programs.

Serial Flash Chip

In flash mode, new program instructions can be flashed to SPI Flash, using tools such as the ESP Flash Download Tool. The wiring is similar to that for normal mode, with the addition of GPIO0 connected to GND.

Flash Mode

ESP8266 can be programmed using an SDK distributed by Espressif. Popular embedded development platforms such as the Arduino IDE, MicroPython, and Lua can also be used.

Adafruit provides instructions for configuring the Arduino IDE for ESP8266 development. Here’re the settings I use with the Arduino IDE – under Tools menu.

Arduino Settings

Try the example project under File -> Examples -> ESP8266WiFi. With it, you’ll be controlling a GPIO pin on the ESP-03, over your Wi-Fi network, in no time at all.

Wi-Fi Web Server

USB bulk data transfer

USB bulk data transfers are the more commonly used method of communication between a USB host and a peripheral. In this post, I’ll show how you can analyze bulk data transfers captured using a Total Phase Beagle USB 480.

The figure below, shows USB bulk data transfers captured using Total Phase’s Data Center software and a Beagle USB 480. According to the USB specification, all bits in a byte are written to the bus in little-endian fashion, and multi-byte values are also written in little-endian order. While the latter is valid with the Beagle USB 480, single byte values appear in a more readable big-endian order.

bulk transfer

Each USB bulk data transfer is broken into smaller data transfers. Each of the smaller data transfers is initiated by a token packet, followed by data packets, and an ACK packet.

Incoming transfers are initiated by the host using a token packet that has a packet identifier (PID) of IN (byte 0x69). The PID is contained in the last 4 bits (0x9), the first 4 bits are a one’s complement of that value (0x6). The second and third bytes, form a single word in little-endian byte order, containing a 5-bit CRC, followed by a 4-bit endpoint ID, followed by a 7-bit device ID. Thus ASCII hex sequence 81 58 in the figure above, should be interpreted as 0x5881, which results in a CRC of 0x0B, an endpoint ID of 0x1, and a device ID of 0x01.

The device responds to the token packet with data packets, or NAK packet if it is unable to handle the request. The PID of the data packets may be DATA0 (0xC3) or DATA1 (0x4B) for full-speed, and also DATA2 (0x87) for high-speed bulk transfers. The data packet has a maximum payload size determined by the USB specification, and is described by wMaxPacketSize attribute in the endpoint descriptor. It may be 8, 16, 32, or 64 bytes for full-speed bulk endpoints (USB 1.1), and also 512 bytes for high-speed (USB 2.0) bulk endpoints. It is 64 bytes in the capture shown above. The payload is followed by a 2-byte CRC.

The end of a bulk data transfer is signaled by a data packet that has less than wMaxPacketSize bytes. If the last, or only, data packet has wMaxPacketSize bytes, the end is signaled by sending a data packet with a payload size of 0 bytes. The device acknowledges a successful transfer using an ACK packet.

Outgoing transfers work in the same manner. The host initiates data transfer using token packet with PID of OUT (0xE1), followed by data packets. The device acknowledges a successful transfer using an ACK packet. If it is unable to receive data, it sends a NAK packet.

Outgoing bulk data transfers can appear jumbled up with incoming bulk data transfers. Applications that leverage Beagle API need to take this into consideration when parsing data captured on the bus.

Physical serial port redirection

I have previously posted about Virtual serial port redirection on Windows, to develop and test applications that use serial ports. I’ve found the available drivers increasingly buggy on Windows 8.1. This post shows how you can wire two USB-Serial cables to achieve the same objective.

Serial Port Redirection

You’ll need two USB-Serial cables such as USB to TTL Serial Cable for Raspberry Pi from Adafruit or several similar ones from Amazon. Wire the cables so that the ground wires are connected, and receive wire of one cable is connected to the transmit of another and vice-versa. Plug the cables in and install the appropriate drivers. Windows usually works with FTDI chipset based cables without requiring installation of drivers.

Now, you should see two serial ports, which redirect data to each other.