Xilinx Vitis Drivers API Documentation
usbps Documentation

This file contains the implementation of the XUsbPs driver. It is the driver for an USB controller in DEVICE or HOST mode.


The Spartan-3AF Embedded Peripheral Block contains a USB controller for communication with serial peripherals or hosts. The USB controller supports Host, Device and On the Go (OTG) applications.

USB Controller Features

  • Supports Low Speed USB 1.1 (1.5Mbps), Full Speed USB 1.1 (12Mbps), and High Speed USB 2.0 (480Mbps) data speeds
  • Supports Device, Host and OTG operational modes
  • ULPI transceiver interface for USB 2.0 operation
  • Integrated USB Full and Low speed serial transceiver interfaces for lowest cost connections

Initialization & Configuration

The configuration of the USB driver happens in multiple stages:

  • (a) Configuration of the basic parameters: In this stage the basic parameters for the driver are configured, including the base address and the controller ID.
  • (b) Configuration of the DEVICE endpoints (if applicable): If DEVICE mode is desired, the endpoints of the controller need to be configured using the XUsbPs_DeviceConfig data structure. Once the endpoint configuration is set up in the data structure, The user then needs to allocate the required amount of DMAable memory and finalize the configuration of the XUsbPs_DeviceConfig data structure, e.g. setting the DMAMemVirt and DMAMemPhys members.
  • (c) Configuration of the DEVICE modes: In the second stage the parameters for DEVICE are configured. The caller only needs to configure the modes that are actually used. Configuration is done with the: XUsbPs_ConfigureDevice() Configuration parameters are defined and passed into these functions using the: XUsbPs_DeviceConfig data structures.

USB Device Endpoints

The USB core supports up to 4 endpoints. Each endpoint has two directions, an OUT (RX) and an IN (TX) direction. Note that the direction is viewed from the host's perspective. Endpoint 0 defaults to be the control endpoint and does not need to be set up. Other endpoints need to be configured and set up depending on the application. Only endpoints that are actuelly used by the application need to be initialized. See the example code (xusbps_intr_example.c) for more information.

Interrupt Handling

The USB core uses one interrupt line to report interrupts to the CPU. Interrupts are handled by the driver's interrupt handler function XUsbPs_IntrHandler(). It has to be registered with the OS's interrupt subsystem. The driver's interrupt handler divides incoming interrupts into two categories:

  • General device interrupts
  • Endopint related interrupts

The user (typically the adapter layer) can register general interrupt handler functions and endpoint specific interrupt handler functions with the driver to receive those interrupts by calling the XUsbPs_IntrSetHandler() and XUsbPs_EpSetHandler() functions respectively. Calling these functions with a NULL pointer as the argument for the function pointer will "clear" the handler function.

The user can register one handler function for the generic interrupts and two handler functions for each endpoint, one for the RX (OUT) and one for the TX (IN) direction. For some applications it may be useful to register a single endpoint handler function for muliple endpoints/directions.

When a callback function is called by the driver, parameters identifying the type of the interrupt will be passed into the handler functions. For general interrupts the interrupt mask will be passed into the handler function. For endpoint interrupts the parameters include the number of the endpoint, the direction (OUT/IN) and the type of the interrupt.

Data buffer handling

Data buffers are sent to and received from endpoint using the XUsbPs_EpBufferSend(), XUsbPs_EpBufferSendWithZLT() and XUsbPs_EpBufferReceive() functions.

User data buffer size is limited to 16 Kbytes. If the user wants to send a data buffer that is bigger than this limit it needs to break down the data buffer into multiple fragments and send the fragments individually.

From the controller perspective Data buffers can be aligned at any boundary. if the buffers are from cache region then the buffer and buffer size should be aligned to cache line aligned

Zero copy

The driver uses a zero copy mechanism which imposes certain restrictions to the way the user can handle the data buffers.

One restriction is that the user needs to release a buffer after it is done processing the data in the buffer.

Similarly, when the user sends a data buffer it MUST not re-use the buffer until it is notified by the driver that the buffer has been transmitted. The driver will notify the user via the registered endpoint interrupt handling function by sending a XUSBPS_EP_EVENT_DATA_TX event.


The driver uses DMA internally to move data from/to memory. This behaviour is transparent to the user. Keeping the DMA handling hidden from the user has the advantage that the same API can be used with USB cores that do not support DMA.

 Ver   Who  Date     Changes

1.00a wgr 10/10/10 First release 1.02a wgr 05/16/12 Removed comments as they are showing up in SDK Tabs for CR 657898 1.03a nm 09/21/12 Fixed CR#678977. Added proper sequence for setup packet handling. 1.04a nm 10/23/12 Fixed CR# 679106. 11/02/12 Fixed CR# 683931. Mult bits are set properly in dQH. 2.00a kpc 04/03/14 Fixed CR#777763. Corrected the setup tripwire macro val. 2.1 kpc 04/28/14 Removed unused function prototypes 2.2 kpc 08/23/14 Exported XUsbPs_DeviceReset API as global for calling in code coverage tests. 2.3 kpc 02/19/14 Fixed CR#873972, CR#873974. Corrected the logic for proper moving of dTD Head/Tail Pointers. Invalidate the cache after buffer receive in Endpoint Buffer Handler. 2.4 sg 04/26/16 Fixed CR#949693, Corrected the logic for EP flush ms 03/17/17 Added readme.txt file in examples folder for doxygen generation. ms 04/10/17 Modified filename tag to include the file in doxygen examples. 2.5 pm 02/20/20 Added ISO support for usb 2.0 and ch9 common framework calls.