ZTEX

 
Produkte
FPGA-Board Serie 2
  USB-FPGA-Modul 2.18
  USB-FPGA-Modul 2.16
  USB-FPGA-Modul 2.14
  USB-FPGA-Modul 2.13
  USB-FPGA-Modul 2.04
  USB-FPGA-Modul 2.01
  FPGA-Modul 2.00
  Debug-Board
  Serie 1-Adapter
  Cluster-Board
Veraltete Produkte
  FPGA-Board Serie 1
Zum ZTEX Shop ZTEX Shop
 SDK und Beispiele 
  Übersicht
  Standard-Firmware
  Dokumentation
  Downloads
  Beispiel
  Lizenzen
  Versions-Geschichte
  ZTEX Wiki
 
 
Downloads
 
Kontakt
Impressum
AGB
RoHS
 

Twitter
    Hauptseite / Produkte         SDK    
    Zum ZTEX Shop Shop   
    Wiki         Downloads    
    deutsch     englisch    

SDK für ZTEX-FPGA Boards - Beispiel

ZTEX stellt ein leistungsfähiges Open-Source SDK für die Entwicklung der Host-Software und der Firmware für den EZ-USB FX2 und FX3 USB-Controller zur Verfügung. (Für die FPGA-Entwicklung wird Xilinx Software verwendet.) Diese Seite gibt einen Eindruck über die SDK-Verwendung.

Bitte beachten Sie auch, dass die Entwicklung von eigener Firmware für viele Anwendungen überflüssig ist, falls die Standard-Firmware verwendet wird.

Viele weitere und komplexere Bespiele sind Teil des SDK.

Firmware

Die Firmware definiert zwei Endpoints. Daten werden vom Host über Endpoint 4 eingelesen, in Großbuchstaben konvertiert und via Endpoint 2 zurück geschrieben. Da die USB-Deskriptoren und ISR vom Firmware-Kit automatisch erzeugt werden, ist der Quellcode relativ kompakt:

Firmware für den EZ-USB FX2: ucecho-fx2.c

#include[ztex-conf.h]   // Loads the configuration macros, see ztex-conf.h for available macros
#include[ztex-utils.h]  // include basic functions

// define endpoints 2 and 4, both belong to interface 0 (in/out are seen from the host
EP_CONFIG(2,0,BULK,IN,512,2);    
EP_CONFIG(4,0,BULK,OUT,512,2);   

// this product string is also used for identification by the host software
#define[PRODUCT_STRING]["ucecho for EZ-USB devices"]

// include the main part of the firmware kit, define the descriptors, ...
#include[ztex.h]

void main(void) 
{
    WORD i,size,j;
    BYTE b;

// init everything
    init_USB();

    REVCTL = 0x0;
    SYNCDELAY; 
    
    IFCONFIG = bmBIT7;  // Internal source, 48MHz
    SYNCDELAY; 

    EP2CS &= ~bmBIT0;   // stall = 0
    SYNCDELAY; 
    EP4CS &= ~bmBIT0;   // stall = 0
    SYNCDELAY; 

    EP2FIFOCFG = 0;
    SYNCDELAY;
    EP4FIFOCFG = 0;
    SYNCDELAY;

    FIFORESET = 0x80;   // reset FIFO ...
    SYNCDELAY;
    FIFORESET = 0x02;   // ... for EP 2
    SYNCDELAY;
    FIFORESET = 0x04;   // ... for EP 4
    SYNCDELAY;
    FIFORESET = 0x00;
    SYNCDELAY;  

    EP4BCL = 0x80;      // skip package, (re)arm EP4
    SYNCDELAY;
    EP4BCL = 0x80;      // skip package, (re)arm EP4
    SYNCDELAY;

    while (1) { 
        if ( !(EP4CS & bmBIT2) ) {                          // EP4 is not empty
            size = (EP4BCH << 8) | EP4BCL;
            if ( size>0 && size<=512 && !(EP2CS & bmBIT3)) {// EP2 is not full
                j = 0;
                for ( i=0; i<size; i++ ) {
                    b = EP4FIFOBUF[i];                      // data from EP4 ... 
                    if ( b>=(BYTE)'a' && b<=(BYTE)'z' ) {   // ... is converted to uppercase ...
                        b-=32;
                        j++;
                    }
                    EP2FIFOBUF[i] = b;                      // ... and written back to EP2 buffer
                } 

                EP2BCH = size >> 8;
                SYNCDELAY; 
                EP2BCL = size & 255;                       // arm EP2
            }
            SYNCDELAY; 
            EP4BCL = 0x80;                                 // skip package, (re)arm EP4
        }
    }
}

Firmware für den EZ-USB FX3: ucecho-fx3.c

Beachten Sie, dass das Cypress SDK einen sehr ähnliches Beispiel beinhaltet (cyfxisolpmaninout) welches mehr als 1000 Zeilen lang ist. Dieses verdeutlicht die Effizienz des ZTEX SDK.

#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, ) \
        ) \
    )

#undef ZTEX_PRODUCT_STRING 
#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;
            ZTEX_REC_CONT(status);

            /* 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;
            ZTEX_REC(status);

            /* 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;
            ZTEX_REC(status);

            /* 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;
            ZTEX_REC(status);
        }
        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
}

Host-Software: UCEcho.java

Die Java Host-Software schreibt durch den Benutzer eingegebene Zeichenketten zum Endpoint 4 und gibt das via Endpoint 2 eingelesene Resultat aus. Falls keine oder falsche Firmware installiert ist, wird die EZ-USB Variante festgestellt und automatisch das korrekte Firmware-Abbild hochgeladen.

import java.io.*;
import java.util.*;
import java.nio.*;

import org.usb4java.*;

import ztex.*;

// *****************************************************************************
// ******* ParameterException **************************************************
// *****************************************************************************
// Exception the prints a help message
class ParameterException extends Exception {
    public final static String helpMsg = new String (
                "Parameters:\n"+
                "    -d <number>       Device Number (default: 0)\n" +
                "    -f                Force uploads\n" +
                "    -p                Print bus info\n" +
                "    -h                This help" );
    
    public ParameterException (String msg) {
        super( msg + "\n" + helpMsg );
    }
}

// *****************************************************************************
// ******* UCEcho *************************************************************
// *****************************************************************************
class UCEcho extends Ztex1v1 {

// ******* Debug ***************************************************************
// constructor
    public UCEcho ( ZtexDevice1 pDev ) throws UsbException {
        super ( pDev );
    }

// ******* echo ****************************************************************
// writes a string to Endpoint 4, reads it back from Endpoint 2 and outputs the result
    public void echo ( String input ) throws UsbException {
        int i = bulkWrite(0x04, allocateByteBuffer(input.getBytes()) , 1000);
        if ( i<0 ) throw new UsbException("Error sending data: " + LibUsb.strError(i));
        System.out.println("Send "+i+" bytes: `"+input+"'" );

        try { Thread.sleep( 10 ); } catch ( InterruptedException e ) { }

        ByteBuffer buffer = BufferUtils.allocateByteBuffer(1024);
        i = bulkRead(0x82, buffer, 1000);
        if ( i<0 ) throw new UsbException("Error receiving data: " + LibUsb.strError(i));
        else if (i==0) System.out.println("Read "+0+" bytes" );  
        else {
            byte[] buf = new byte[i];
            buffer.get(buf);
            System.out.println("Read "+i+" bytes: `"+new String(buf,0,i)+"'" );  
        } 
    }


// ******* main ****************************************************************
    public static void main (String args[]) {
    
        int devNum = 0;
        boolean force = false;
        
        try {

// Scan the USB. This also creates and initializes a new USB context.
            ZtexScanBus1 bus = new ZtexScanBus1( ZtexDevice1.ztexVendorId, 
                                                 ZtexDevice1.ztexProductId, true, false, 1);
            if ( bus.numberOfDevices() <= 0) {
                System.err.println("No devices found");
                System.exit(0);
            }
            
// scan the command line arguments
            for (int i=0; i<args.length; i++ ) {
                if ( args[i].equals("-d") ) {
                    i++;
                    try {
                        if (i>=args.length) throw new Exception();
                        devNum = Integer.parseInt( args[i] );
                    } 
                    catch (Exception e) {
                        throw new ParameterException("Device number expected after -d");
                    }
                }
                else if ( args[i].equals("-f") ) {
                    force = true;
                }
                else if ( args[i].equals("-p") ) {
                    bus.printBus(System.out);
                    System.exit(0);
                }
                else if ( args[i].equals("-h") ) {
                        System.err.println(ParameterException.helpMsg);
                        System.exit(0);
                }
                else throw new ParameterException("Invalid Parameter: "+args[i]);
            }
            

// create the main class            
            UCEcho ztex = new UCEcho ( bus.device(devNum) );
            bus.unref();
            
// upload the firmware if necessary
            if ( force || ! ztex.valid() || 
                 ! ztex.dev().productString().equals("ucecho for EZ-USB devices") ) {
                String imgfn = "ucecho-fx2.ihx";
                if ( ztex.dev().fx3() ) {
                    System.out.println( "Trying to overwrite firmware in RAM. This only " + 
                                        "works if a board specific firmware with reset\n" + 
                                        "support is running. If uploading firmware fails "+
                                        " please restart board with disabled firmware." );
                    imgfn = "ucecho-fx3.img";
                }
                System.out.println( "Firmware upload time: " + 
                                    ztex.uploadFirmware( imgfn, force ) + " ms");
            }
            
// claim interface 0
            ztex.trySetConfiguration ( 1 );
            ztex.claimInterface ( 0 );
            
// print board log
            ztex.debug2PrintNextLogMessages(System.out);

// read string from stdin and write it to USB device
            try {
                String str = "";
                BufferedReader reader = new BufferedReader( new InputStreamReader( System.in ) );
                while ( ! str.equals("quit") ) {
                    System.out.print("Enter a string or `quit' to exit the program: ");
                    str = reader.readLine();
                    if ( ! str.equals("") ) ztex.echo(str);
                    System.out.println("");
                    ztex.debug2PrintNextLogMessages(System.out);
                }
            }
            catch ( Exception e ) {
                System.out.println("ucecho test failed: " + e.getLocalizedMessage() );
            }

            ztex.debug2PrintNextLogMessages(System.out); 

            ztex.dispose();  // this also releases claimed interfaces

        }
        catch (Exception e) {
            System.out.println("Error: "+e.getLocalizedMessage() );
        } 
   } 
   
}

Beispiel Aufruf

Es folgt ein Beispiel-Aufruf mit Ausgabe einschließlich FX3 Log-Meldungen.

stefan@ws2:/drv_s2/usb-fpga/ucecho$ java -cp UCEcho.jar UCEcho
Trying to overwrite firmware in RAM. This only works if a board specific firmware with reset
support is running. If uploading firmware fails please restart board with disabled firmware.
Firmware upload time: 144 ms
Info: Found 128 MBit SPI Flash
ucecho for EZ-USB devices
Info: USB setup finished: super speed
Info: USB disconnected.
Info: USB setup finished: super speed
Enter a string or `quit' to exit the program: hello world!
Send 12 bytes: `hello world!'
Read 12 bytes: `HELLO WORLD!'

Enter a string or `quit' to exit the program: quit
Send 4 bytes: `quit'
Read 4 bytes: `QUIT'


[Home]  [Impressum]   
© ZTEX GmbH