OpenCores
URL https://opencores.org/ocsvn/usb_fpga_2_14/usb_fpga_2_14/trunk

Subversion Repositories usb_fpga_2_14

[/] [usb_fpga_2_14/] [trunk/] [examples/] [memfifo/] [MemFifo.java] - Rev 2

Compare with Previous | Blame | View Log

/*%
   memfifo -- Connects the bi-directional high speed interface of default firmware to a FIFO built of on-board SDRAM or on-chip BRAM
   Copyright (C) 2009-2017 ZTEX GmbH.
   http://www.ztex.de
 
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at
 
       http://www.apache.org/licenses/LICENSE-2.0
 
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
%*/
 
import java.io.*;
import java.util.*;
import java.text.*;
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" +
		"    -r             Reset EZ-USB\n" +
		"    -v             Print debug info\n" +
		"    -p             Print bus info\n" +
		"    -h             This help" );
 
    public ParameterException (String msg) {
	super( msg + "\n" + helpMsg );
    }
}
 
// *****************************************************************************
// ******* UsbTestWriter *******************************************************
// *****************************************************************************
class UsbTestWriter extends Thread {
    private volatile boolean terminate = true;
    private volatile boolean isAlive = false;
    private ZtexUsbWriter writer;
    private byte[] b;
    private int bufCount = 0;
 
    public UsbTestWriter ( Ztex1v1 p_ztex ) throws InvalidFirmwareException, UsbException, CapabilityException {
        super ();
	writer = new ZtexUsbWriter( p_ztex, 8, 512*1024 );
	b = new byte[writer.bufSize()];
    }
 
    public ZtexUsbWriter writer() {
	return writer;
    }
 
    public boolean terminate(int timeout) throws UsbException {
	terminate = true;
	writer.cancel();
	int i;
	for (i=0; isAlive && i<=timeout; i+=20 ) {
	    try { sleep(20); } catch ( InterruptedException e) { } 
	}
	return (!isAlive) && writer.cancelWait(timeout-i+100);
    }
 
    public void run() {
	isAlive = true;
	terminate = false;
	int k = 0;
	int cs = 47;
	int sync;
	Random random = new Random();
	while ( !terminate ) {
	    for ( int i=0; !terminate && i<writer.bufSize(); i++ ) {
		int j = k & 15;
		sync = ( ((j & 1)==1) || (j==14) ) ? 128 : 0;
		if ( j == 15 ) {
		    b[i] = (byte) (sync | ((cs & 127) ^ (cs>>7)));
		    cs = 47;
		}
		else {
//		    b[i] = (byte) ( (j==0 ? (k>>4) & 127 : random.nextInt(128)) | sync );
		    b[i] = (byte) ( (((k>>4)+j) & 127) | sync );
		    cs += (b[i] & 255);
		}
		k=(k+1) & 65535;
	    }
	    try {
		if ( writer.transmitBuffer(b,2000)<0 ) {
		    terminate = true;
		    System.err.println("Timeout error transmitting buffer "+bufCount);
		}
	    } 
	    catch ( Exception e) {
		terminate = true;
		System.err.println("Error transmitting buffer "+bufCount+": "+e);
	    }
	    bufCount += 1;
	}
	isAlive = false;
    }
}
 
 
// *****************************************************************************
// ******* MemFifo *************************************************************
// *****************************************************************************
class MemFifo extends Ztex1v1 {
 
    // constructor
    public MemFifo ( ZtexDevice1 pDev ) throws UsbException {
	super ( pDev );
    }
 
    // set mode
    public void setMode( int i ) throws InvalidFirmwareException, UsbException, CapabilityException {
	defaultGpioCtl(7,i & 3);
    }
 
    // manual PKTEND
    public void manPktend() throws InvalidFirmwareException, UsbException, CapabilityException {
	defaultGpioCtl(4,4);
	defaultGpioCtl(4,0);
    }
 
    // reset
    public void reset( ) throws  InvalidFirmwareException, UsbException, CapabilityException {
	defaultGpioCtl(7,0);
	defaultReset();
	debug2PrintNextLogMessages(System.out); 
    }
 
    // reads data and verifies them. It exits either if iz buffers are read of if a short package occurs
    // returns number of read bytes
    // rate is data rate in kBytes; <=0 means unlimited
    public long verify ( ZtexUsbReader reader, int iz, int rate, boolean verbose, boolean manPktend) throws UsbException {
    	boolean valid = false;
	int byte_cnt = 0, sync_cnt = 0, cs = 47;
	boolean memError = false;
	byte[] b = new byte[reader.bufSize()];
	long size = 0;
 
	for (int i=0; i<iz; i++) {
	    if ( i>0 && rate>0 ) {
		try {
		    Thread.sleep(reader.bufSize()/rate);
        	}
        	catch ( InterruptedException e) {
        	} 
	    }
	    int bb = reader.getBuffer(b, 5000);
	    size += bb;
 
	    // manually assert PKTEND in after 21 buffers
	    try {
		if (manPktend && (i==20)) manPktend();
	    }
	    catch ( Exception e) {
		System.err.println(e);
	    }
 
	    if ( bb<0 ) throw new UsbException("Timeout during reading buffer "+i);
	    else if (bb==0) {
		System.out.println("Received no data for buffer "+i+"                                  ");
		return 0;
	    }
 
	    int serrors = 0;
	    int merrors = 0;
 
	    for (int k=0; k<bb; k++ ) {
		byte_cnt++;
		sync_cnt++;
		if ( (b[k] & 128) == 0 ) sync_cnt=0;
		if ( sync_cnt == 3 ) {
		    boolean serror = byte_cnt != 16;
		    boolean merror = (byte_cnt == 16) && ( ( b[k] & 127 ) != ((cs & 127) ^ (cs>>7)) );
		    valid = valid || ( !serror && !merror );
		    if ( valid ) {
			if ( serror ) serrors += 1;
			if ( merror ) merrors += 1;
			if ( verbose && ((serror && serrors <= 2) || (merror && merrors <= 2) )) {
			    if ( serror ) System.out.print( "Sync Error: " + byte_cnt + " at " + k + ": " );
			    else System.out.print( "Data Error: at " + k + ": " );
			    for ( int l=k-byte_cnt-2; l<k+3; l++ )
				if ( (l>=0) && (l<bb) ) 
				    System.out.print((b[l] < 0 ? "*" : "" ) + (b[l] & 127) + " ");
			}
		    }
		    cs=47;
		    byte_cnt = 0;
		} else {
		    cs += b[k] & 255;
		}
	    } 
 
	    if ( ! valid ) {
		System.out.println("Invalid data");
		return size;
	    }
 
	    System.out.print("Buffer " + i + (bb==reader.bufSize() ? ": " : "(short packet): ") + serrors + " sync errors,    " + merrors + " memory or transfer errors" + "                 \r" );
	    if ( bb!=reader.bufSize() ) {
	        System.out.println();
	        return size;
	    }
	    if ( merrors + serrors > (i==0 ? 2 : 0 ) ) { // two errors in first buffer may occurs after changing mode
	        System.out.println();
	        memError |= (bb!=reader.bufSize());
	    } else if (bb!=reader.bufSize()) {
	        System.out.println();
	    }  
	}
        System.out.println();
	return size;
    }
 
// ******* main ****************************************************************
    public static void main (String args[]) {
 
	int devNum = 0;
	boolean verbose = false;
	boolean reset = false;
	ZtexUsbReader reader = null;
	UsbTestWriter writer = null;
	ZtexEventHandler eventHandler = null;
 
	if ( ! System.getProperty("os.name").equalsIgnoreCase("linux") ) {
	    Runtime.getRuntime().addShutdownHook(new Thread() {
		public void run() { 
    		    Scanner s=new Scanner(System.in);
    		    System.out.println("Press <enter> to continue ...");
    		    s.nextLine();
		}
	    });	
	}
 
	try {
// Scan the USB. This also creates and initializes a new USB context.
	    ZtexScanBus1 bus = new ZtexScanBus1( ZtexDevice1.ztexVendorId, ZtexDevice1.ztexProductId, true, false, 1);
 
// 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("-v") ) {
		    verbose = true;
		}
		else if ( args[i].equals("-r") ) {
		    reset = 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]);
	    }
 
	    String errStr = "";
 
// create the main class	    
	    if ( bus.numberOfDevices() <= 0) {
		System.err.println("No devices found");
	        System.exit(0);
	    }
	    MemFifo ztex = new MemFifo ( bus.device(devNum) );
	    bus.unref();
 
	    try {
 
// reset EZ-USB
		if ( reset ) {
		    System.out.println("Reset EZ-USB");
		    ztex.resetEzUsb();
		}
		else {
		    ztex.resetDevice(false);	// sync data toggles
		}
 
 
// check for firmware
		ztex.defaultCheckVersion(1);
		ztex.debug2PrintNextLogMessages(System.out); 
		if (ztex.config == null ) throw new Exception("Invalid configuration data");
 
// upload the bitstream 
		String configFN = ztex.config.defaultBitstreamPath("memfifo");
		System.out.println("Found " + ztex.config.getName()+",  using bitstream "+configFN);
	        System.out.println("FPGA configuration time: " + ztex.configureFpga( configFN , true, -1 ) + " ms");
 
// upload the bitstream 
		boolean isFx3 = ztex.dev().fx3();
	        int sizeFact = isFx3 ? 2 : 1;
 
// claim interface
    	    	ztex.trySetConfiguration ( 1 );
    	    	ztex.claimInterface ( 0 );
		ztex.debug2PrintNextLogMessages(System.out); 
		eventHandler = new ZtexEventHandler(ztex);
		eventHandler.start();
 
// start bulk reader
		reader = new ZtexUsbReader( ztex, 8, 512*1024 );
		reader.start(-1);
 
// Mode 1: 208 MByte/s Test data generator: used for speed test
		ztex.setMode(1);
		System.out.println((isFx3 ? "208" : "48") + " MByte/s test data generator: ");
 
		long oldByteCount = 0;
		for (int i=0; i<4; i++) {
		    System.out.print("2s read only test: ");
		    try { Thread.sleep(2000); } catch ( InterruptedException e) { } 
		    System.out.println(Math.round((reader.byteCount()-oldByteCount)/2000000.0) + " MByte/s");
		    oldByteCount = reader.byteCount();
		}
 
		reader.cancelWait(5000);
		reader.start(0);
		long t0 = new Date().getTime();
		long l = ztex.verify(reader, 1000*sizeFact, 0, verbose, false);
		System.out.println("Read + verify data rate: " + Math.round(l/((new Date().getTime()-t0)*1000.0)) + " MByte/s");
		ztex.debug2PrintNextLogMessages(System.out); 
 
// Mode 2: 13 MByte/s Test data generator: used for speed test
		ztex.setMode(2);
		System.out.println((isFx3 ? "\n13" : "\n12") + " MByte/s test data generator: ");
		t0 = new Date().getTime();
		ztex.verify(reader, 500*sizeFact, 0, verbose, false);
		ztex.debug2PrintNextLogMessages(System.out);
 
// PKTEND tests
		if ( (ztex.defaultVersion() > 1) || (ztex.defaultSubVersion() > 2) ) {
		    System.out.println("\nPKTEND tests (may not work on all platforms)");
		    try {
			System.out.println("Manual PKTEND test (1/2):");
			l = ztex.verify(reader, 500, 0, verbose, true);
			System.out.println("Seems" + (l<500*reader.bufSize() ? "" : " not") + " to work: received " + (l >> 9) +"*512 + " + (l&511) + " bytes");
			System.out.println("Manual PKTEND test (2/2):");
			l = ztex.verify(reader, 500, 0, verbose, true);
			System.out.println("Seems" + (l<500*reader.bufSize() ? "" : " not") + " to work: received " + (l >> 9) +"*512 + " + (l&511) + " bytes"); 
			System.out.println("Automatic PKTEND assertion after 0.5s timeout test:");
   			try { Thread.sleep(1000); } catch ( InterruptedException e) { } 
			ztex.setMode(0);
			l = ztex.verify(reader, 1000, 0, verbose, false);
			System.out.println("Seems" + (l<1000*reader.bufSize() ? "" : " not") + " to work: received " + (l >> 9) +"*512 + " + (l&511) + " bytes");
			System.out.println("Zero length packet test:");
			ztex.manPktend();
			l = ztex.verify(reader, 1000, 0, verbose, false);
			System.out.println("Seems" + (l==0 ? "" : " not") + " to work: received " + l + " bytes");
		    }
		    catch ( Exception e ) {
			System.err.println("Error during PKTEND tests: "+e);
		    } 
		}
 
 
// Mode 0: write+read mode
		reader.cancel();
		System.out.println("\nUSB write + read mode: on some USB implementations concurrent reading / writing may cause deadlocks or timeout errors");
		writer = new UsbTestWriter( ztex );
		ztex.reset();
//		ztex.setMode(3);
		writer.start();
		if ( !reader.cancelWait(5000) ) System.err.println("Unable to cancel transfers. Following data may be invalid");
		reader.start(0);
 
		ztex.debug2PrintNextLogMessages(System.out); 
 
		System.out.println("USB write + read mode: speed test");
		t0 = new Date().getTime();
		l = ztex.verify(reader, 750*sizeFact, 0, verbose, false);
		System.out.println("Read + Write data rate: " + Math.round(l/((new Date().getTime()-t0)*100.0)*0.1) + " MByte/s");
		ztex.debug2PrintNextLogMessages(System.out); 
 
		System.out.println("USB write + read mode: 10 MByte/s read test");
		ztex.verify(reader, 300, 10000, verbose, false);
		ztex.debug2PrintNextLogMessages(System.out); 
    	    }
	    catch (Exception e) {
		System.out.println("Error: "+e.getLocalizedMessage() );
		ztex.debug2PrintNextLogMessages(System.out); 
	    } 
 
// terminating threads and releasing resources
	    if ( reader!=null ) reader.cancel();
	    if ( (writer!=null) && (!writer.terminate(10000)) ) System.err.println("Unable to cancel writing");
	    if ( (eventHandler!=null) && !eventHandler.terminate() ) System.err.println("Unable to terminate event handler");
	    if ( (reader!=null) && (!reader.cancelWait(10000)) ) System.err.println("Unable to cancel reading");
	    ztex.dispose();  // this also releases claimed interfaces
	}
	catch (Exception e) {
	    System.out.println("Error: "+e.getLocalizedMessage() );
	} 
 
   } 
 
}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.