Series 2 FPGA Boards
  USB-FPGA Module 2.18
  USB-FPGA Module 2.16
  USB-FPGA Module 2.14
  USB-FPGA Module 2.13
  USB-FPGA Module 2.12
  USB-FPGA Module 2.01
  FPGA Module 2.00
  Debug Board
  Series 1 Adapter
  Cluster Board
  USB-FPGA Module 2.04
Obsolete products
  Series 1 FPGA Boards
To the ZTEX Shop ZTEX Shop
 SDK and Examples 
  Default Firmware
  Release history
  ZTEX Wiki
Terms and Conditions
    Home / Products         SDK    
    To the ZTEX Shop Shop   
    Wiki         Downloads    

FX3 (USB 3.0) Port Status

Cypress has been released an USB 3.0 successor of the EZ-USB FX2, the EZ-USB FX3. ZTEX offers FPGA Boards based on that new USB controller. This page informs about the products and the state of the FX3 port.


The FX3 based FPGA Boards will be members of the Series 2 and therefore pin compatible with other products of this series. All boards will use the FX3S variant with one SD-Port. The features listed below may be subject of change.

USB-FPGA Module 2.14

Available since January 2016, see product page of USB-FPGA Modules 2.14.

USB-FPGA Module 2.18

Available since December 2016, see product page of the USB-FPGA Module 2.18.


This part of the FX3 port took most of the time.

Firmware Kit

The Firmware Kit for FX3 provides all necessary features. Similarly to the FX2 firmware, USB descriptors, DMA descriptors, USB configuration code and many other things are generated automatically by the SDK based upon settings defined by macros. But unlike to the FX2 version, no special macro processor is required.

The following example is the Firmware source code of the ucecho example for FX3.

#include "cyu3system.h"
#include "cyu3os.h"
#include "cyu3dma.h"

// loads default configuration macros
#include "ztex-conf.c"

CyU3PDmaChannel dma_out_handle, dma_in_handle;

/* Define endpoints 2 and 4. Both belong to interface 0 (in/out are seen from the host)
 * Burst size is 1 and DMA size is 2x1K. */
#undef EP_SETUP
#define EP_SETUP \
    INTERFACE(0, \
        EP_BULK(4, OUT, 1, /* direction as seen from the host */ \
            DMA(dma_in_handle, CY_U3P_DMA_TYPE_MANUAL_IN, 1, 2, CY_U3P_CPU_SOCKET_CONS, \
                CB(0,0) \
            ) \
        ) \
        EP_BULK(2, IN, 1, \
            DMA(dma_out_handle, CY_U3P_DMA_TYPE_MANUAL_OUT, 1, 2, CY_U3P_CPU_SOCKET_PROD, ) \
        ) \

#define ZTEX_PRODUCT_STRING "ucecho for EZ-USB FX3"

#include "ztex.c"       

void usb_start() {
    // start USB transfers as soon cable is connected
    ZTEX_REC(CyU3PDmaChannelSetXfer (&dma_in_handle, 0));
    ZTEX_REC(CyU3PDmaChannelSetXfer (&dma_out_handle, 0));

void usb_stop() {
    // nothing required here

void run () {
    CyU3PDmaBuffer_t inbuf, outbuf;
    CyU3PReturnStatus_t status;
    uint32_t i;

    ztex_log ( "ucecho for EZ-USB devices" );

    while (1) {
        if (ztex_usb_is_connected) {
            /* Wait for receiving a buffer from the producer socket (OUT endpoint). The call
             * will fail if there was an error or if the USB connection was reset / disconnected.
             * In case of error invoke the error handler and in case of reset / disconnection,
             * ztex_usb_is_connected will be 0; continue to beginning of the loop. */
            status = CyU3PDmaChannelGetBuffer (&dma_in_handle, &inbuf, CYU3P_WAIT_FOREVER);
            // ZTEX_LOG("EC=%d,  Read %d bytes", status, inbuf.count);
            if (!ztex_usb_is_connected || status==CY_U3P_ERROR_TIMEOUT) continue;

            /* Wait for a free buffer to transmit the received data. 
             * The failure cases are same as above. */
            status = CyU3PDmaChannelGetBuffer (&dma_out_handle, &outbuf, CYU3P_WAIT_FOREVER);
            if (!ztex_usb_is_connected || status==CY_U3P_ERROR_TIMEOUT) continue;

            /* Convert the data from the producer channel to the consumer channel. 
             * The inbuf.count holds the amount of valid data received. */
            CyU3PMemCopy (outbuf.buffer, inbuf.buffer, inbuf.count);
            for (i=0; i<inbuf.count; i++ )
                outbuf.buffer[i] = inbuf.buffer[i]>='a' && inbuf.buffer[i]<='z' ? 
                                   inbuf.buffer[i] - 32 : inbuf.buffer[i];

            /* Now discard the data from the producer channel so that the buffer is made
             * available to receive more data. */
            status = CyU3PDmaChannelDiscardBuffer (&dma_in_handle);
            if (!ztex_usb_is_connected) continue;

            /* Commit the received data to the consumer pipe so that the data can be
             * transmitted back to the USB host. Since the same data is sent back, the
             * count shall be same as received and the status field of the call shall
             * be 0 for default use case. */
            status = CyU3PDmaChannelCommitBuffer (&dma_out_handle, inbuf.count, 0);
            // ZTEX_LOG("EC=%d,  Sent %d bytes", status, outbuf.status);
            if (!ztex_usb_is_connected) continue;
        else {
            /* No active data transfer. Sleep for a small amount of time. */
            CyU3PThreadSleep (100);

 * Main function
int main (void)
    // global configuration
    ztex_app_thread_run = run;
    ztex_usb_start = usb_start;
    ztex_usb_stop = usb_stop;
    ztex_main();        // starts the OS and never returns
    return 0;           // makes the compiler happy

The Cypress SDK contains a similar example (cyfxisolpmaninout) which is more than 1000 long. This demonstrates the efficiency of firmware development using the ZTEX SDK.


API for FX2 and FX3 based FPGA boards is the same.

Since August 2016 a new SDK release which uses usb4java/libusb-1.0 is available. Updating to this release requires changes in in host software, see ZTEX Wiki.

With this last step of the FX3 port transfer rates of 207 MByte/s can be measured. This is very close to the theoretical limit of 208 MByte/s, the bandwidth between FX3 and FPGA.

[Home]  [Impressum]