Device Connection Status Detection

For self-powered USB devices, when the USB connection status changes, the USB device class driver and application layer must promptly detect these events and implement corresponding handling procedures for hot-plug support and/or power consumption reduction.

The USB device core driver provides following APIs for connection status monitoring:

These APIs require USB register access after USB power on to return valid data, thus they should only be invoked after USB core driver initialization.

For pre-power status detection, external circuitry shall be employed - such as GPIO interrupt monitoring VBUS power events, refer to the reference design of USB insert detection circuit in Hardware Design Guide.

This hybrid hardware/software solution enables detection of the following USB connection status change events:

Event

usbd_get_status

status_changed

VBUS GPIO Interrupt

VBUS Status

Reset (attached to host)

ATTACHED

INIT -> ATTACHED

N/A

ON

Reset (detached from host)

INIT

N/A

N/A

OFF

Reset (attached to charger)

INIT

N/A

N/A

ON

Attach to host

ATTACHED

DETACHED -> ATTACHED

Y (rising edge)

OFF -> ON

Detach from host

DETACHED

ATTACHED -> DETACHED

Y (falling edge)

ON -> OFF

Attach to charger

INIT

or

DETACHED

N/A

Y (rising edge)

OFF -> ON

Detach from charger

INIT

or

DETACHED

N/A

Y (falling edge)

ON -> OFF

Suspend

DETACHED

ATTACHED -> DETACHED

By USB host configuration

By USB host configuration

Resume

ATTACHED

DETACHED -> ATTACHED

By USB host configuration

By USB host configuration

​​Two typical application scenarios:

Software-Only Implementation (Recommended for Non-Power-Sensitive Applications)

When maintaining constant USB power is acceptable, the status_changed API provides sufficient software-based detection capability. Typical workflow includes:

  • Upon USB host disconnection: Terminate USB communications, deinitialize / re-initialize USB device, then await reconnection

  • Upon USB host connection: Resume USB communications

../../../_images/usb_status_detection_sw.svg

Hardware-Assisted Implementation (For Power-Critical Applications)

When minimizing power consumption during USB idle states is required, hardware solution such as GPIO-interrupt VBUS monitoring shall be implemented. Typical workflow includes:

  • Upon USB host disconnection or USB charger connection: Terminate USB communications, deinitialize USB device to enter low-power state

  • Upon USB host connection: Initialize USB device and resume communications

../../../_images/usb_status_detection_hw.svg

Device Descriptor Customization

Overview

USB devices define their functionality through descriptors. The hierarchical structure of USB descriptors is illustrated below:

../../../_images/usb_device_descriptors.svg

Where:

  • Each USB device contains exactly 1 Device Descriptor

  • One or multiple Configuration Descriptors (specified by bNumConfigurations), with only 1 active at any time

  • One or multiple Interface Descriptors per configuration (specified by bNumInterfaces), which can operate simultaneously

  • Zero, one or multiple Endpoint Descriptors per interface (specified by bNumEndPoints), which can operate simultaneously

Additional descriptor types include:

  • String Descriptors: Localized text descriptions for device/configuration/interface

  • Device Qualifier Descriptor: Required for dual-speed (HS/FS) devices

  • Other Speed Configuration Descriptor: Required for dual-speed (HS/FS) devices, alternate configuration for different speeds

  • Interface Association Descriptor (IAD): Mandatory for composite devices

  • Class-specific Descriptors: e.g., HID Report Descriptor

High-speed Mode:
Device Descriptor
└─ Identifies basic device information (USB version, class, VID/PID, EP0 MPS, etc)

Configuration Descriptor
└─ Contains total length of the entire configuration(power supply information, interface count, etc)

Device Qualifier Descriptor
└─ Provides device class/EP0 MPS/config count for the other speed (HS↔FS)

Other Speed Configuration Descriptor
└─ Mirrors the configuration at the other speed (interfaces/endpoints/attributes)

String Descriptor
└─ Provides language IDs and textual identifiers (Manufacturer/Product, etc)

Note

Refer to USB specifications for complete descriptor definitions.

Data Structure

Standard host enumeration sequence:

  • Device Descriptor

  • Configuration Descriptor chain (active Configuration Descriptor and all subordinate descriptors)

  • String Descriptors (language ID, serial number, manufacturer, product)

Optional host requests:

  • Device Qualifier Descriptor (for dual-speed devices)

  • Other Speed Configuration chain (for dual-speed devices)

  • Class-specific descriptors (e.g., HID Report Descriptor for HID devices)

  • OS-specific descriptors (e.g., Microsoft OS String Descriptor @ index 0xEE)

Note

Unsupported descriptors should return STALL status without affecting functionality.

Based on standard USB host enumeration behavior, USB devices shall implement the following independent descriptor arrays:

  • Device Descriptor: Contains only the Device Descriptor

  • Configuration Descriptor:

    • One array per configuration

    • Includes the Configuration Descriptor plus all subordinate descriptors, e.g., Interface Descriptors and Endpoint Descriptors

  • String Descriptor

    • Language ID descriptor

    • Individual arrays for each string descriptor

  • Device Qualifier Descriptor: Contains only the Device Qualifier Descriptor

  • Other Speed Configuration Descriptor

    • One array per alternate speed configuration descriptor

    • Includes the Other Speed Configuration Descriptor plus all subordinate descriptors, e.g., Interface Descriptors and Endpoint Descriptors

    • May reuse Configuration Descriptor memory through dynamic descriptor type field replacement

  • Class-Specific Descriptor: Defined per device class specifications

  • Host-Specific Descriptor: Implemented per host requirements and application needs

Descriptor Customization

All the USB descriptors defined in USB device class drivers are open for modification, but for better compatibility, it is recommended to limit changes to:

VID/PID

  • Default: Realtek VID/PID

  • Custom VID: Requires USB-IF membership (https://www.usb.org/members)

  • Custom PID with Realtek VID: Contact Realtek FAE

Note

Using Realtek VID/PID doesn’t imply USB-IF compliance - certification still required.

String Descriptors

String descriptors are optional. The Device Descriptor, Configuration Descriptor, and Interface Descriptor all possess string descriptor index fields. If string descriptors are not supported, the descriptor index is 0. Non-zero index values can be defined along with their corresponding string descriptors:

Device Descriptor
│   iManufacturer            (Manufacturer String Index)
│   iProduct                 (Product String Index)
│   iSerialNumber            (SerialNumber String Index)
│
├── Configuration Descriptor
│   ├── iConfiguration       (Configuration String Index)
│   └── Interface Descriptor
│       └── iInterface       (Interface String Index)
│
└── USB String Table
    ├── String Descriptor    (Index 0, Must be read first)
    ├── String Descriptor    (Index 1)
    ├── String Descriptor    (Index 2)
    ├── String Descriptor    (Index 3)
    │    ...

String Descriptor Structure

The host reads the device descriptor during the initial enumeration stage, which contains three fields: iManufacturer/iProduct/iSerialNumber. The values of these fields are merely index numbers; for devices that do not have corresponding strings, developers only need to set these string index values to 0.

When the device is plugged into a computer, the operating system reads these strings and displays them in the Device Manager or popup windows. For example, if set sequentially to 1, 2, 3:

  • Index 1 (iManufacturer): Manufacturer Name. E.g., “Realtek Semiconductor Corp.”

  • Index 2 (iProduct): Product Name. E.g., “Realtek USB Controller”

  • Index 3 (iSerialNumber): Serial Number. E.g., “00E04C000001”

USB String Table
│
├── String Descriptor     (Index 0: Must be read first!)
│   └── LANGID Code Array (Language ID Array)
│       └── 0x0409        (English - United States)
│
├── String Descriptor     (Index 1: Pointed by `iManufacturer` index)
│   └── "Realtek Semiconductor Corp." (Unicode)
│
├── String Descriptor     (Index 2: Pointed by the `iProduct` index)
│   └── "Realtek USB Controller" (Unicode)
│
├── String Descriptor     (Index 3: Pointed by the `iSerialNumber` index)
│   └── "00E04C000001" (Unicode)
│
└── String Descriptor     (Index 4/5/6/...: Optional/Customizable)
  • String Descriptor (Index 0)

    String Descriptor     (Special: Language ID)
    │   bLength           (Descriptor length)
    │   bDescriptorType   (String descriptor type. Fixed to 0x03)
    └── LANGID Code Array
        │ wLANGUAGEID(0)  (First Language ID)
        │ wLANGUAGEID(1)  (Second Language ID)
        │ ...
    
    • Role: It is the “descriptor of string descriptors”. Before retrieving any specific string, the host must first read Index 0 to confirm the language types supported by the device.

    • Specialty: It does not contain a string but rather a list of Language IDs supported by the device. When the host sends a request to get string index 0, it does not mean getting the string at index 0, but rather getting the list of supported Language IDs (LANGID).

    • Parameter Value: Typically, the Language ID is 0x0409 for American English. For Chinese, the Language ID can be set to 0x0804.

    Note

    Even if the developer’s device is used only in a specific country, it is recommended to support 0x0409, as this is the default ID attempted by Windows/Linux.

  • String Descriptor (Indices 1, 2, 3)

    String Descriptor
    │   bLength         (Descriptor length)
    │   bDescriptorType (String descriptor type. Fixed to 0x03)
    └── bString         (UNICODE encoded string)
    

    The bString string must be UNICODE (UTF-16LE) encoded, with each character occupying 2 bytes. For example ‘A’ -> 0x41, 0x00.

    Note

    • The USB specification requires string descriptors to use UNICODE encoding. The device core driver provides the usbd_get_str_desc() function to convert ASCII encoded strings into UNICODE encoded string descriptors, making it convenient for developers to maintain string information using ASCII strings.

    • The protocol stack currently only provides examples of English string descriptors. If support for other language types is needed, please refer to the USB specification to define the required Language ID descriptor and corresponding string descriptors.

  • Other Custom Strings (Indices 4, 5, 6…)

    As long as there is no conflict with the standard, custom strings with indices 4, 5, 6… can be defined.

Endpoint Descriptor

Customizable parameters:

  • bEndpointAddress: Endpoint address.

  • wMaxPacketSize: Maximum packet size. It is generally recommended to set it according to the maximum value defined by the USB specification (not higher than the maximum value supported by the SoC hardware). Unless there are special requirements, it is not recommended to modify it arbitrarily

  • bInterval: Transfer interval.

Note

Default configurations guarantee SoC and USB specification compatibility. Any modifications require:

  • Thorough understanding of SoC limitations, refer to Hardware Features

  • Compliance with USB specifications