wiki:USB

Universal Serial Bus (USB)

Universal Serial Bus (USB) is an industry standard developed in the mid-90's that defines cables, connectors and communication protocols used in a bus between computers and peripherals.

References:

Versions

Summary of USB versions:

  • USB 1.0 - USB LowSpeed (1.5mbps) and USB FullSpeed (12mbps)
  • USB 2.0 - adds USB HighSpeed (480mbps)
  • USB 3.0 - adds USB SuperSpeed (5gbps)

Host Controllers

The following types of USB host controllers exist:

  • Universal Host Controller Interface (UHCI): Produced by Intel for USB 1.0 and USB 1.1. Using UHCI requires a license from Intel. This controller supports both LowSpeed and Full-Speed.
  • Open Host Controller Interface (OHCI): Produced for USB 1.0 and 1.1 by Compaq, Microsoft, and National Semiconductor. Supports Low-Speed and Full-Speed and tends to be more efficient then UHCI by performing more functionality in hardware.
  • Extended Host Controller Interface (EHCI): Created for USB 2.0 after USB-IF requested that a single host controller specification be created. EHCI is used for HighSpeed transactions and delegates LowSpeed and FullSpeed transactions to an OHCI or UHCI sister controller.
  • eXtensible Host Controller Interface (xHCI): Created for USB 3.0 and also known as the USB 3.0 host controller specification.

USB Speeds

The following is a set of supported theoretical speeds per USB specification:

  • USB LowSpeed (1.5mbps) (USB 1.0 UHCI/OHCI) - Only supports Control and Interrupt transfer types
  • USB FullSpeed (12mbps) (USB 1.0 UHCI/OHCI)
  • USB HighSpeed (480mbps) (USB 2.0 EHCI)
  • USB SuperSpeed (5000mbps) (USB 3.0 XHCI)

Note that the USB software stack and chipset vendor host controller implementation have overhead that reduce actual USB performance from theoretical bandwidth. Embedded SoC's typically do not prioritize USB performance like modern desktop computers. Additionally there may be Linux build-time and run-time tuning that can be done that affect performance.

Note that typical speeds of around 1200Mbps have been reported for the Venice USB 3.0.

USB Transfer types

There are four types of transfers in USB:

  • Control Transfers Used for sending commands to the device, make inquiries, and configure the device. This transfer uses the control pipe.
  • Interrupt Transfers Used for sending small amounts of bursty data that requires a guaranteed minimum latency. This transfer uses a data pipe.
  • Bulk Transfers Used for large data transfers that use all available USB bandwidth with no guarantee on transfer speed or latency. This transfer uses a data pipe.
  • Isochronous Transfers Used for data that requires a guaranteed data delivery rate. Isochronous transfers are capable of this guaranteed delivery time due to their guaranteed latency, guaranteed bus bandwidth, and lack of error correction. Without the error correction, there is no halt in transmission while packets containing errors are resent. This transfer uses a data pipe.

USB Device Classes

USB has a list of recognized and approved USB device classes in order to simplify driver development. The most common device classes are:

  • Human Interface Device (HID):
    • Supports Control and Interrupt transfer types
    • has a max FullSpeed rate of ~64KB/s
    • standard driver in all modern OS
  • Mass Storage Device (MSD)
    • standard driver in all modern OS
  • Communication Device Class (CDC)
    • Supports Bulk and Isochronous transfer types
    • has a max FullSpeed rate of ~80KB/s
    • standard driver in all modern OS
  • Mobile Broadband Interface Model (MBIM)
    • implemented as a solution for generalizing the configuration and data management of USB-based mobile broadband devices (modems)
  • Vendor (Vendor Specific)
    • Supports all four transfer types
    • has a max FullSpeed rate of ~1MB/s
    • requires custom driver (but can be userspace through libusb)

Human Interface Device

Often vendors choose HID device class to allow control via userspace applications without needing a OS specific driver (as all modern OS's have an HID driver).

The ​HIDAPI (open-source and cross-platform Linux/Windows/MacOS) provides simple USB HID enumeration, read and write functions.

The HID device class uses HID reports to describe details about the data input and output a device supports. The sub class can be 'Generic HID' and the report type can be 'Vendor Defined' which makes it generic. The maximum report size is 64B.

Vendor Specific

Vendors sometimes choose to implement a Vendor specific device which has an undefined class.

The ​libusb (open-source and cross-platform Linux/Windows/MacOS) can be used for generic USB communication. Vendor specific commands can be implemented.

Gateworks USB devices

In an effort to define these options available to developers, Gateworks has created the following table with the fields as follows:

  • Family: Board Product family.
  • SBC: The base SBC (Single Board Computer) model that the proceeding rows apply to.
  • USB Port: The particular USB port and controller in question.
  • Ref: The reference part designator that can be found on the PCB silkscreen (white lettering).
  • Reset Type: How the usb device is re-enumerated and/or reset, which will be either:
    • Soft - Both data lines of the usb bus are driven low, signalling a reset condition that is handled differently from device to device.
    • VBUS - The 5V power rail of the port is brought down (when indicated with the manual control of a gpio).
  • Bus-Device[.Port]: The bus, device, and port (if behind a hub) of the port in question.
  • Bus Steering: The conditions for the bus to be electrically steered to this port if applicable.

In all cases the miniPCIe slots get their VBUS directly from the board power rail, which has no power control.

Gateworks USB device Table:

Family SBC USB Port Ref Reset Bus-Device[.Port] Bus Steering
Venice GW710x USB 2.0 (GW700x SOM) / USB 3.0 (GW702x SOM)
GW720x USB 2.0 (GW700x SOM) / USB 3.0 (GW702x SOM)
GW730x USB 2.0 (GW700x SOM) / USB 3.0 (GW702x SOM)
GW740x USB 3.0 & 2.0
Newport GW610x Front Panel USB-C J11 Soft/VBUS
miniPCIe HS J6 Soft 1-1
miniPCIe SS J6 Soft
GW620x Front Panel Top SS J11 Soft/VBUS 2-1.2
Front Panel Top HS J11 Soft/VBUS 1-1.2
Front Panel Bot SS J11 Soft/VBUS 2-1.1
Front Panel Bot HS J11 Soft/VBUS 1-1.1
Bot Right miniPCIe HS J8 Soft 1-1.3
Bot Left miniPCIe SS J6 Soft 1-1.4
Bot Left miniPCIe HS J6 Soft 3-1
GW630x Front Panel Top SS J21 Soft/VBUS 2-1.2
Front Panel Top HS J21 Soft/VBUS 1-1.2
Front Panel Bot SS J21 Soft/VBUS 2-1.1
Front Panel Bot HS J21 Soft/VBUS 1-1.1
Bot Right miniPCIe HS J9 Soft 1-1.3
Bot Mid miniPCIe HS J10 Soft 1-1.4
Bot Left miniPCIe SS J11 Soft 4-1
Bot Left miniPCIe HS J11 Soft 3-1
GW640x Front Panel Top SS J23 Soft/VBUS 2-1.2
Front Panel Top HS J23 Soft/VBUS 1-1.2 CN80XX gpio 20 / linux gpio484
Front Panel Bot SS J23 Soft/VBUS 2-1.1
Front Panel Bot HS J23 Soft/VBUS 1-1.1
Bot Right miniPCIe HS J9 Soft 1-1.3
Bot Mid miniPCIe HS J11 Soft 1-1.4
Bot Left miniPCIe SS J12 Soft 4-1
Bot Left miniPCIe HS J12 Soft 3-1
Ventana GW51xx Front Panel OTG J20 Soft/VBUS 1-1
miniPCIe USB EHCI J6 Soft 2-1
GW52xx Front Panel OTG J15 Soft/VBUS 1-1 gpio2 low (default)
Bot Right miniPCIe EHCI J7 Soft 2-1
Bot Left miniPCIe OTG J8 Soft 2-1 gpio2 high
GW53xx Front Panel OTG J20 Soft/VBUS 1-1
Front Panel EHCI J18 Soft/VBUS 2-1.1
Bot Left miniPCIe EHCI J9 Soft 2-1.2
Bot Center miniPCIe EHCI J8 Soft 2-1.3
Bot Right miniPCIe EHCI J6 Soft 2-1.4
GW54xx Front Panel OTG J23 Soft/VBUS 1-1
Bot Right miniPCIe EHCI J6 Soft 2-1.1
Top Right miniPCIe EHCI J9 Soft 2-1.2
Top Left miniPCIe EHCI J7 Soft 2-1.3
Front Panel EHCI J21 Soft/VBUS 2-1.4
GW551x Adapter Board OTG J3 (J9 on Adapter) Soft 1-1
Bot miniPCIe EHCI J2 Soft 2-1
GW552x Bot Left miniPCIe EHCI J6 Soft 1-1.1
Bot Right miniPCIe EHCI J5 Soft 1-1.2
Front Panel EHCI J10 (Top) Soft/VBUS 1-1.3
Front Panel EHCI J10 (Bot) Soft/VBUS 1-1.4
GW553x Front Panel OTG J8 Soft/VBUS 1-1
miniPCIe EHCI J5 Soft 2-1

USB 2.0 Host Controllers

USB 2.0 host controllers provide EHCI for 2.0 'HighSpeed' connections and OHCI for 1.0 'LowSpeed' connections. Both interfaces will exist depending on your connections.

USB 3.0 Host Controllers

USB 3.0 introduced the eXtensible Host Controller Interface (XHCI) to standardize software control of USB 3.0 host controllers. USB 3.0 host controllers provide only XHCI connections which support 'SuperSpeed', 'HighSpeed', and 'LowSpeed' connections. This means for boards such as Newport that support USB 3.0 you do not need to have support for the older EHCI/OHCI specificaitons.

USB Steering

Some boards allow USB to be steered via a software controlled gpio. Refer to the 'bus steering' column for details which show which gpio to use, what the default is set to (via bootloader), and where it can be steered to. Typically a bus may be steerable between a front-panel connector and a miniPCIe socket in which case the front-panel is always the default configured by the bootloader. You can change the steering at run-time if you whish which would be like physically removing a USB device from the bus and adding another (re-enumerates).

Examples:

  • Newport GW640x: steer the front panel USB2 signals to the J10 miniPCIe socket which uses CN80XX GPIO_20 which is Linux gpio-484:
    # export and configure the GPIO as an output high
    GPIO=484
    echo $GPIO > /sys/class/gpio/export
    echo out > /sys/class/gpio/gpio$GPIO/direction
    echo 1 > /sys/class/gpio/gpio$GPIO/value # 0=front-panel 1=miniPCIe-J10
    
  • Ventana GW52xx: steer the USB OTG bus to the miniPCIe socket (device-mode only) which uses gpio2:
    # export and configure the GPIO as an output high
    GPIO=2
    echo $GPIO > /sys/class/gpio/export
    echo out > /sys/class/gpio/gpio$GPIO/direction
    echo 1 > /sys/class/gpio/gpio$GPIO/value # 0=front-panel 1=miniPCIe-J8
    

USB Reset

The best way to reset a USB device is to 'hot plug' the device by physically removing and reinserting it. However this is not typically possible and there are other options.

Note that BUS Steering can sometimes be a useful alternative to resetting a device as it forces a re-enumeration of the device.

VBUS reset

The next best thing to physically removing and re-inserting a USB device is to toggle power to that device. While this is not possible on the USB bus routed to miniPCIe sockets (which run off an always 3.3V power rail) this is possible on:

  • OTG ports with Host capability (because they must have the ability to turn on and off their VBUS)
  • Front panel ports that have over-current/fault-detect capability
  • Ports that have a gpio controlled VBUS

Ports provided by a USB OTG controller ('OTG' in USB Port name) which support host mode can have their VBUS reset by unbinding and rebinding the host controller via sysfs:

  • Ventana (where the OTG controller is '2184000.usb'):
    echo 2184000.usb > /sys/bus/platform/drivers/imx_usb/unbind
    sleep 1
    echo 2184000.usb > /sys/bus/platform/drivers/imx_usb/bind
    

Ports provided by a USB Hub's (will have a '.<port>' in their bus-device.port entry in the table above) with over-current/fault detection such as those found on a GW530x/GW540x/GW630x/GW640x can have their VBUS reset by unbinding their upstream bus-dev (no '.<port>') from the USB bus:

  • Examples:
    • GW640x (must disable/enable both SS/HS for VBUS to switch):
      echo 2-1 > /sys/bus/usb/drivers/usb/unbind # SS
      echo 1-1 > /sys/bus/usb/drivers/usb/unbind # HS
      sleep 1
      echo 2-1 > /sys/bus/usb/drivers/usb/bind # SS
      echo 1-1 > /sys/bus/usb/drivers/usb/bind # HS
      
  • Note that for USB 3.0 capable devices (Newport) not need to bind/unbind both HS and SS for VBUS to be affected.
  • this is not possible for MiniPCIe sockets as their VBUS comes from the 3.0V rail

Refer to the USB device table above for the bus-dev and/or VBUS capabilities per board.

Soft reset via sysfs bind/unbind (re-enumerate)

In some scenarios (ie Mini-PCIe modem) having command line options to reset these devices via sysfs is preferable and can be found via modern kernel drivers. Refer to the USB Device Table above for the bus-device.port reference for your board/port.

Note that commands targeting a hub cause a soft reset for all child devices which include the front panel and any pcie ports with "usb" on the silk screen. VBUS is only brought down on the front panel port(s) connected to the internal hub.

Examples:

  • Reset GW54xx Front panel OTG device (bus-device 1-1). Note this will cause VBUS to be toggled for a full power reset - see above:
    echo 1-1 > /sys/bus/usb/drivers/usb/unbind
    sleep 1
    echo 1-1 > /sys/bus/usb/drivers/usb/bind
    
  • Reset GW54xx EHCI devices by unbinding/binding the USB hub (bus-device 2-1). The bot right, top right, top left miniPCIe sockets will get a 'soft reset' (because they power off 3P3V which can't be toggled) and front panel EHCI will get a full VBUS power cycle:
    echo 2-1 > /sys/bus/usb/drivers/usb/unbind
    sleep 1
    echo 2-1 > /sys/bus/usb/drivers/usb/bind
    
  • Reset GW54xx EHCI device in the top right miniPCIe socket J6 (bus-device 2-1.1):
    echo 2-1.1 > /sys/bus/usb/drivers/usb/unbind
    sleep 1
    echo 2-1.1 > /sys/bus/usb/drivers/usb/bind
    

Soft reset via ioctl

There are also ioctls that can accomplish the same results programmaticlly and in some cases give even finer control than the above table. An example of a simple program that uses some of these ioctls is the usbreset command (present in OpenWrt):

Further information regarding these ioctls can be found throughout the ​Linux source documentation.

Switched miniPCIe Socket Power

On some Gateworks boards the 3.3V power to certain miniPCIe sockets is run through a power switch connected to a GPIO to allow power-cycling devices in the socket. Note that certain miniPCIe form-factor devices may not power-cycle if they backfeed power through PERST# or WLAN_DIS# signals. If power disable capability is provided on a board/socket it is typically on the miniPCIe socket intended for USB based modems (as you can't power cycle devices on the PCI bus without re-enumerating them).

Boards featuring miniPCIe socket power disable:

Board miniPCIe socket enable gpio Notes
GW53xx-G+ J6 (modem) PAD_EIM_DA15_GPIO3_IO15 gpio79 active-high enable
GW54xx-G+ J7 (modem) PAD_EIM_DA15_GPIO3_IO15 gpio79 active-high enable

Examples:

  • Toggle socket power in Linux on a GW53xx-G+ (J6) or GW54xx-G+ (J7):
    # export gpio79 and configure it as an output
    echo 79 > /sys/class/gpio/export 
    echo out > /sys/class/gpio/gpio79/direction
    echo 0 > /sys/class/gpio/gpio79/value # disable power
    echo 1 > /sys/class/gpio/gpio79/value # enable power  
    

Linux USB Auto-suspend

USB autosuspend is problematic with several embedded SoC's due to host controller chip errata. This is the case for both the i.MX6 on Ventana and the CN80XX on Newport. To work around these errata we find it safest to just disable USB autosuspend with a kernel command-line argument of 'usbcore.autosuspend=-1'. This is done in several of our bootscripts.

Driver Binding based on Vendor ID and Device ID

USB drivers bind to devices based on 16bit vendor ID device ID numbers that the card reports during bus enumeration.

Sometimes a new USB device is not bound to a driver because it's ID's have not yet been added. You can overcome this at runtime by adding the hex ID's via the drivers sysfs 'new_id' node.

For example, to allow the qmi_wwan driver to bind to a card who's VID/PID is 0x1bc7 0x110a:

echo "1bc7 110a" > /sys/bus/usb/drivers/qmi_wwan/new_id
Last modified 4 months ago Last modified on 07/29/2024 11:08:19 PM
Note: See TracWiki for help on using the wiki.