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

Subversion Repositories usb_fpga_1_2

[/] [usb_fpga_1_2/] [trunk/] [java/] [ztex/] [Ztex1.java] - Diff between revs 2 and 3

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 2 Rev 3
Line 24... Line 24...
import java.io.*;
import java.io.*;
import java.util.*;
import java.util.*;
 
 
import ch.ntb.usb.*;
import ch.ntb.usb.*;
 
 
 
/**
 
  * This class implements the interface-independent part of the communication protocol for the interaction with the ZTEX firmware.<p>
 
  * All firmware implementations that provide the ZTEX descriptor 1 are supported.
 
  * A description of this descriptor can be found in {@link ZtexDevice1}.
 
  * <p>
 
  * The most important features of this class are the functions for uploading the firmware
 
  * and the renumeration management.
 
  * <p>
 
  * The interface dependent part of the communication protocol (currently only one is supported)
 
  * can be found in {@link Ztex1v1}.
 
  * @see ZtexDevice1
 
  * @see Ztex1v1
 
  */
public class Ztex1 {
public class Ztex1 {
    protected int handle;
    private int handle;
    protected ZtexDevice1 dev = null;
    private ZtexDevice1 dev = null;
    private boolean oldDevices[] = new boolean[128];
    private boolean oldDevices[] = new boolean[128];
    private String usbBusName = null;
    private String usbBusName = null;
 
/** * Setting to true will enable certain workarounds, e.g. to deal with bad driver/OS implementations. */
 
    public boolean certainWorkarounds = false;
 
/** * The timeout for  control messages in ms. */
 
    public int controlMsgTimeout = 1000;        // in ms
 
    private long lastVendorCommandT = 0;
 
 
// ******* Ztex1 ***************************************************************
// ******* Ztex1 ***************************************************************
 
/**
 
  * Constructs an instance from a given device.
 
  * @param pDev The given device.
 
  * @throws UsbException if an communication error occurred.
 
  */
    public Ztex1 ( ZtexDevice1 pDev ) throws UsbException {
    public Ztex1 ( ZtexDevice1 pDev ) throws UsbException {
        dev = pDev;
        dev = pDev;
 
 
        handle = LibusbJava.usb_open(dev.dev());
        handle = LibusbJava.usb_open(dev.dev());
        if ( handle<=0 )
        if ( handle<=0 )
            throw new UsbException(dev.dev(), "Error opening device");
            throw new UsbException(dev.dev(), "Error opening device");
    }
    }
 
 
// ******* finalize ************************************************************
// ******* finalize ************************************************************
 
/** * The destructor closes the USB file handle. */
    protected void finalize () {
    protected void finalize () {
        LibusbJava.usb_close(handle);
        LibusbJava.usb_close(handle);
    }
    }
 
 
// ******* handle **************************************************************
// ******* handle **************************************************************
 
/** * Returns the USB file handle. */
    public final int handle()
    public final int handle()
    {
    {
        return handle;
        return handle;
    }
    }
 
 
// ******* dev *****************************************************************
// ******* dev *****************************************************************
 
/**
 
  * Returns the corresponding {@link ZtexDevice1}.
 
  * @return the corresponding {@link ZtexDevice1}.
 
  */
    public final ZtexDevice1 dev()
    public final ZtexDevice1 dev()
    {
    {
        return dev;
        return dev;
    }
    }
 
 
// ******* valid ***************************************************************
// ******* valid ***************************************************************
 
/**
 
  * Returns true if ZTEX descriptor 1 is available.
 
  * @return true if ZTEX descriptor 1 is available.
 
  */
    public boolean valid ( ) {
    public boolean valid ( ) {
        return dev.valid();
        return dev.valid();
    }
    }
 
 
// ******* checkValid **********************************************************
// ******* checkValid **********************************************************
 
/**
 
  * Checks whether ZTEX descriptor 1 is available.
 
  * @throws InvalidFirmwareException if ZTEX descriptor 1 is not available.
 
  */
    public void checkValid () throws InvalidFirmwareException {
    public void checkValid () throws InvalidFirmwareException {
        if ( ! dev.valid() )
        if ( ! dev.valid() )
            throw new InvalidFirmwareException(this, "Can't read ZTEX descriptor 1");
            throw new InvalidFirmwareException(this, "Can't read ZTEX descriptor 1");
    }
    }
 
 
// ******* vendorCommand *******************************************************
// ******* vendorCommand *******************************************************
    public int vendorCommand (int cmd, String func, int value, int index, byte[] buf, int length) throws UsbException {
/**
        int i;
  * Sends a vendor command to Endpoint 0 of the EZ-USB device.
        if ( (i=LibusbJava.usb_control_msg(handle, 0x40, cmd, value, index, buf, length, 1000)) < 0 )
  * The command may be send multiple times until the {@link #controlMsgTimeout} is reached.
            throw new UsbException( dev.dev(), (func != null ? func + ": " : "" ) + LibusbJava.usb_strerror());
  * @param cmd The command number (0..255).
 
  * @param func The name of the command. This string is used for the generation of error messages.
 
  * @param value The value (0..65535), i.e bytes 2 and 3 of the setup data.
 
  * @param index The index (0..65535), i.e. bytes 4 and 5 of the setup data.
 
  * @param length The size of the payload data (0..65535), i.e. bytes 6 and 7 of the setup data.
 
  * @param buf The payload data buffer.
 
  * @return the number of bytes sent.
 
  * @throws UsbException if a communication error occurs.
 
  */
 
    public synchronized int vendorCommand (int cmd, String func, int value, int index, byte[] buf, int length) throws UsbException {
 
        long t0 = new Date().getTime()-100;
 
        int trynum = 0;
 
        int i = -1;
 
        if ( controlMsgTimeout < 200 )
 
            controlMsgTimeout = 200;
 
        while ( i<=0 && new Date().getTime()-t0<controlMsgTimeout ) {            // we repeat the message until the timeout has reached
 
            i = LibusbJava.usb_control_msg(handle, 0x40, cmd, value, index, buf, length, controlMsgTimeout);
 
            if ( certainWorkarounds ) {
        try {
        try {
            Thread.sleep(1);                            // avoid package loss (due to interrupts ?)
                    Thread.sleep(2);
        }
        }
            catch ( InterruptedException e ) {
            catch ( InterruptedException e ) {
        }
        }
 
            }
 
            lastVendorCommandT = new Date().getTime();
 
            if ( i < 0 ) {
 
                System.err.println("Warning (try " + (trynum+1) + "): " + LibusbJava.usb_strerror() );
 
                try {
 
                    Thread.sleep( 1 << trynum );                                // we don't want to bother the USB device to often
 
                }
 
                    catch ( InterruptedException e ) {
 
                }
 
                trynum++;
 
            }
 
        }
 
        if ( i < 0 )
 
            throw new UsbException( dev.dev(), (func != null ? func + ": " : "" )+ LibusbJava.usb_strerror());
        return i;
        return i;
    }
    }
 
 
 
/**
 
  * Sends a vendor command with no payload data to Endpoint 0 of the EZ-USB device.
 
  * The command may be send multiple times until the {@link #controlMsgTimeout} is reached.
 
  * @param cmd The command number (0..255).
 
  * @param func The name of the command. This string is used for the generation of error messages.
 
  * @param value The value (0..65535), i.e bytes 2 and 3 of the setup data.
 
  * @param index The index (0..65535), i.e. bytes 4 and 5 of the setup data.
 
  * @return the number of bytes sent.
 
  * @throws UsbException if a communication error occurs.
 
  */
    public int vendorCommand (int cmd, String func, int value, int index) throws UsbException {
    public int vendorCommand (int cmd, String func, int value, int index) throws UsbException {
        byte[] buf = { 0 };
        byte[] buf = { 0 };
        return vendorCommand (cmd, func, value, index, buf, 0);
        return vendorCommand (cmd, func, value, index, buf, 0);
    }
    }
 
 
 
/**
 
  * Sends a vendor command with no payload data and no setup data to Endpoint 0 of the EZ-USB device.
 
  * The command may be send multiple times until the {@link #controlMsgTimeout} is reached.
 
  * @param cmd The command number (0..255).
 
  * @param func The name of the command. This string is used for the generation of error messages.
 
  * @return the number of bytes sent.
 
  * @throws UsbException if a communication error occurs.
 
  */
    public int vendorCommand (int cmd, String func) throws UsbException {
    public int vendorCommand (int cmd, String func) throws UsbException {
        byte[] buf = { 0 };
        byte[] buf = { 0 };
        return vendorCommand (cmd, func, 0, 0, buf, 0);
        return vendorCommand (cmd, func, 0, 0, buf, 0);
    }
    }
 
 
// ******* vendorRequest *******************************************************
// ******* vendorRequest *******************************************************
    public int vendorRequest (int cmd, String func, int value, int index, byte[] buf, int maxlen) throws UsbException {
/**
        int i = LibusbJava.usb_control_msg(handle, 0xc0, cmd, value, index, buf, maxlen, 1000);
  * Sends a vendor request to Endpoint 0 of the EZ-USB device.
        if ( i < 0 )
  * The request may be send multiple times until the {@link #controlMsgTimeout} is reached.
            throw new UsbException( dev.dev(), (func != null ? func + ": " : "" ) + LibusbJava.usb_strerror());
  * @param cmd The request number (0..255).
 
  * @param func The name of the request. This string is used for the generation of error messages.
 
  * @param value The value (0..65535), i.e bytes 2 and 3 of the setup data.
 
  * @param index The index (0..65535), i.e. bytes 4 and 5 of the setup data.
 
  * @param maxlen The size of the requested payload data (0..65535), i.e. bytes 6 and 7 of the setup data.
 
  * @param buf The payload data buffer.
 
  * @return the number of bytes received.
 
  * @throws UsbException if a communication error occurs.
 
  */
 
    public synchronized int vendorRequest (int cmd, String func, int value, int index, byte[] buf, int maxlen) throws UsbException {
 
        long t0 = new Date().getTime()-100;
 
        int trynum = 0;
 
        int i = -1;
 
        if ( controlMsgTimeout < 200 )
 
            controlMsgTimeout = 200;
 
        while ( i<=0 && new Date().getTime()-t0<controlMsgTimeout ) {            // we repeat the message until the timeout has reached
 
            /*
 
                The HSNAK mechanism of EP0 usually avoids that a request is sent before a command has been completed.
 
                Unfortunately this mechanism is only 99.99% reliable. Therefore we wait at least 1ms after the last
 
                command has been send before we transmit a new request.
 
            */
 
            long ms = new Date().getTime() - lastVendorCommandT;
 
            if ( ms < 2 ) {     //
        try {
        try {
            Thread.sleep(1);                            // avoid package loss (due to interrupts ?)
                    Thread.sleep(1);
        }
        }
            catch ( InterruptedException e ) {
            catch ( InterruptedException e ) {
        }
        }
 
            }
 
 
 
            i = LibusbJava.usb_control_msg(handle, 0xc0, cmd, value, index, buf, maxlen, controlMsgTimeout);
 
            if ( certainWorkarounds ) {
 
                try {
 
                    Thread.sleep(2);
 
                }
 
                    catch ( InterruptedException e ) {
 
                }
 
            }
 
            if ( i < 0 ) {
 
                System.err.println("Warning (try " + (trynum+1) + "): " + LibusbJava.usb_strerror() );
 
                try {
 
                    Thread.sleep( 1 << trynum );                                // we don't want to bother the USB device to often
 
                }
 
                    catch ( InterruptedException e ) {
 
                }
 
                trynum++;
 
            }
 
        }
 
        if ( i < 0 )
 
            throw new UsbException( dev.dev(), (func != null ? func + ": " : "" ) + LibusbJava.usb_strerror());
        return i;
        return i;
    }
    }
 
 
 
/**
 
  * Sends a vendor request to Endpoint 0 of the EZ-USB device.
 
  * The request may be send multiple times until the {@link #controlMsgTimeout} is reached.
 
  * @param cmd The request number (0..255).
 
  * @param func The name of the request. This string is used for the generation of error messages.
 
  * @param maxlen The size of the requested payload data (0..65535), i.e. bytes 6 and 7 of the setup data.
 
  * @param buf The payload data buffer.
 
  * @return the number of bytes sent.
 
  * @throws UsbException if a communication error occurs.
 
  */
    public int vendorRequest (int cmd, String func, byte[] buf, int maxlen) throws UsbException {
    public int vendorRequest (int cmd, String func, byte[] buf, int maxlen) throws UsbException {
        return vendorRequest (cmd, func, 0, 0, buf, maxlen);
        return vendorRequest (cmd, func, 0, 0, buf, maxlen);
    }
    }
 
 
// ******* vendorCommand2 ******************************************************
// ******* vendorCommand2 ******************************************************
    public void vendorCommand2 (int cmd, String func, int value, int index, byte[] buf, int length) throws UsbException {
/**
 
  * Sends a vendor command to Endpoint 0 of the EZ-USB device and throws an {@link UsbException} if not all of the payload has been sent.
 
  * The command may be send multiple times until the {@link #controlMsgTimeout} is reached.
 
  * @param cmd The command number (0..255).
 
  * @param func The name of the command. This string is used for the generation of error messages.
 
  * @param value The value (0..65535), i.e bytes 2 and 3 of the setup data.
 
  * @param index The index (0..65535), i.e. bytes 4 and 5 of the setup data.
 
  * @param length The size of the payload data (0..65535), i.e. bytes 6 and 7 of the setup data.
 
  * @param buf The payload data buffer.
 
  * @throws UsbException if a communication error occurs or if not all of the payload has been sent.
 
  */
 
    public synchronized void vendorCommand2 (int cmd, String func, int value, int index, byte[] buf, int length) throws UsbException {
        int i = vendorCommand (cmd, func, value, index, buf, length);
        int i = vendorCommand (cmd, func, value, index, buf, length);
        if ( i != length )
        if ( i != length )
            throw new UsbException( dev.dev(), (func != null ? func + ": " : "" ) + "Send " + i + " byte of data instead of " + length + " bytes");
            throw new UsbException( dev.dev(), (func != null ? func + ": " : "" ) + "Send " + i + " byte of data instead of " + length + " bytes");
    }
    }
 
 
    public void vendorCommand2 (int cmd, String func, int value, int index) throws UsbException {
 
        byte[] buf = { 0 };
 
        vendorCommand2 (cmd, func, value, index, buf, 0);
 
    }
 
 
 
    public void vendorCommand2 (int cmd, String func) throws UsbException {
 
        byte[] buf = { 0 };
 
        vendorCommand2 (cmd, func, 0, 0, buf, 0);
 
    }
 
 
 
// ******* vendorRequest2 ******************************************************
// ******* vendorRequest2 ******************************************************
 
/**
 
  * Sends a vendor request to Endpoint 0 of the EZ-USB device and throws an {@link UsbException} if not all of the payload has been received.
 
  * The request may be send multiple times until the {@link #controlMsgTimeout} is reached.
 
  * @param cmd The request number (0..255).
 
  * @param func The name of the request. This string is used for the generation of error messages.
 
  * @param value The value (0..65535), i.e bytes 2 and 3 of the setup data.
 
  * @param index The index (0..65535), i.e. bytes 4 and 5 of the setup data.
 
  * @param maxlen The size of the requested payload data (0..65535), i.e. bytes 6 and 7 of the setup data.
 
  * @param buf The payload data buffer.
 
  * @throws UsbException if a communication error occurs or not all of the payload has been received.
 
  */
    public void vendorRequest2 (int cmd, String func, int value, int index, byte[] buf, int maxlen) throws UsbException {
    public void vendorRequest2 (int cmd, String func, int value, int index, byte[] buf, int maxlen) throws UsbException {
        int i = vendorRequest(cmd, func, value, index, buf, maxlen);
        int i = vendorRequest(cmd, func, value, index, buf, maxlen);
        if ( i != maxlen )
        if ( i != maxlen )
            throw new UsbException( dev.dev(), (func != null ? func + ": " : "" ) + "Received " + i + " byte of data, expected "+maxlen+" bytes");
            throw new UsbException( dev.dev(), (func != null ? func + ": " : "" ) + "Received " + i + " byte of data, expected "+maxlen+" bytes");
    }
    }
 
 
 
/**
 
  * Sends a vendor request to Endpoint 0 of the EZ-USB device and throws an {@link UsbException} if not all of the payload has been received.
 
  * The request may be send multiple times until the {@link #controlMsgTimeout} is reached.
 
  * @param cmd The request number (0..255).
 
  * @param func The name of the request. This string is used for the generation of error messages.
 
  * @param maxlen The size of the requested payload data (0..65535), i.e. bytes 6 and 7 of the setup data.
 
  * @param buf The payload data buffer.
 
  * @throws UsbException if a communication error occurs or not all of the payload has been received.
 
  */
    public void vendorRequest2 (int cmd, String func, byte[] buf, int maxlen) throws UsbException {
    public void vendorRequest2 (int cmd, String func, byte[] buf, int maxlen) throws UsbException {
        vendorRequest2(cmd, func, 0, 0, buf, maxlen);
        vendorRequest2(cmd, func, 0, 0, buf, maxlen);
    }
    }
 
 
// ******* findOldDevices ******************************************************
// ******* findOldDevices ******************************************************
    private void findOldDevices () {
    private synchronized void findOldDevices () {
        Usb_Bus bus = dev.dev().getBus();
        Usb_Bus bus = dev.dev().getBus();
        usbBusName = bus.getDirname();
        usbBusName = bus.getDirname();
 
 
        for ( int i=0; i<=127; i++ )
        for ( int i=0; i<=127; i++ )
            oldDevices[i] = false;
            oldDevices[i] = false;
Line 154... Line 315...
        }
        }
        oldDevices[dev.dev().getDevnum()] = false;
        oldDevices[dev.dev().getDevnum()] = false;
    }
    }
 
 
// ******* findNewDevice *******************************************************
// ******* findNewDevice *******************************************************
    private Usb_Device findNewDevice ( String errMsg ) throws DeviceLostException {
    private synchronized Usb_Device findNewDevice ( String errMsg ) throws DeviceLostException {
        Usb_Device newDev = null;
        Usb_Device newDev = null;
        LibusbJava.usb_find_busses();
        LibusbJava.usb_find_busses();
        LibusbJava.usb_find_devices();
        LibusbJava.usb_find_devices();
 
 
        Usb_Bus bus = LibusbJava.usb_get_busses();
        Usb_Bus bus = LibusbJava.usb_get_busses();
Line 178... Line 339...
 
 
        return newDev;
        return newDev;
    }
    }
 
 
// ******* initNewDevice *******************************************************
// ******* initNewDevice *******************************************************
    private void initNewDevice ( String errBase ) throws DeviceLostException, UsbException, ZtexDescriptorException {
    private void initNewDevice ( String errBase ) throws DeviceLostException, UsbException, InvalidFirmwareException {
// scan the bus for up to 5 s for a new device
// scan the bus for up to 60 s for a new device. Boot sequence may take a while.
        Usb_Device newDev = null;
        Usb_Device newDev = null;
        for ( int i=0; i<20 && newDev==null; i++ ) {
        for ( int i=0; i<300 && newDev==null; i++ ) {
            try {
            try {
                Thread.sleep( 250 );
                Thread.sleep( 200 );
            }
            }
                catch ( InterruptedException e ) {
                catch ( InterruptedException e ) {
            }
            }
            newDev = findNewDevice( errBase + ": " );
            newDev = findNewDevice( errBase + ": " );
        }
        }
Line 199... Line 360...
        int vid = dd.getIdVendor() & 65535;
        int vid = dd.getIdVendor() & 65535;
        int pid = dd.getIdProduct() & 65535;
        int pid = dd.getIdProduct() & 65535;
        try {
        try {
            dev = new ZtexDevice1( newDev, vid, pid );
            dev = new ZtexDevice1( newDev, vid, pid );
        }
        }
        catch ( ZtexDescriptorException e ) {
        catch ( InvalidFirmwareException e ) {
            if ( vid == ZtexDevice1.cypressVendorId && pid == ZtexDevice1.cypressProductId ) {
            if ( vid == ZtexDevice1.cypressVendorId && pid == ZtexDevice1.cypressProductId ) {
                dev = new ZtexDevice1( newDev, -1, -1 );
                dev = new ZtexDevice1( newDev, -1, -1 );
            }
            }
            else {
            else {
                throw e;
                throw e;
Line 211... Line 372...
        }
        }
        handle = LibusbJava.usb_open( dev.dev() );
        handle = LibusbJava.usb_open( dev.dev() );
    }
    }
 
 
// ******* uploadFirmware ******************************************************
// ******* uploadFirmware ******************************************************
 
/**
 
  * Uploads the firmware to the EZ-USB and manages the renumeration process.
 
  * <p>
 
  * Before the firmware is uploaded the device is set into a reset state.
 
  * After the upload the firmware is booted and the renumeration starts.
 
  * During this process the device disappears from the bus and a new one
 
  * occurs which will be assigned to this class automatically (instead of the disappeared one).
 
  * @param ihxFileName The file name of the firmware image in ihx format. The file can be a regular file or a system resource (e.g. a file from the current jar archive).
 
  * @param force The compatibility check is skipped if true.
 
  * @throws IncompatibleFirmwareException if the given firmware is not compatible to the installed one, see {@link ZtexDevice1#compatible(int,int,int,int)} (Upload can be enforced using the <tt>force</tt> parameter)
 
  * @throws FirmwareUploadException If an error occurred while attempting to upload the firmware.
 
  * @throws UsbException if a communication error occurs.
 
  * @throws InvalidFirmwareException if ZTEX descriptor 1 is not available.
 
  * @throws DeviceLostException if a device went lost after renumeration.
 
  */
//  returns upload time in ms
//  returns upload time in ms
    public long uploadFirmware ( String ihxFileName, boolean force ) throws IncompatibleFirmwareException, FirmwareUploadException, UsbException, ZtexDescriptorException, DeviceLostException {
    public long uploadFirmware ( String ihxFileName, boolean force ) throws IncompatibleFirmwareException, FirmwareUploadException, UsbException, InvalidFirmwareException, DeviceLostException {
// load the ihx file
// load the ihx file
        ZtexIhxFile1 ihxFile;
        ZtexIhxFile1 ihxFile;
        try {
        try {
            ihxFile = new ZtexIhxFile1( ihxFileName );
            ihxFile = new ZtexIhxFile1( ihxFileName );
        }
        }
Line 250... Line 426...
 
 
        return time;
        return time;
    }
    }
 
 
// ******* resetEzUsb **********************************************************
// ******* resetEzUsb **********************************************************
    public void resetEzUsb () throws IncompatibleFirmwareException, FirmwareUploadException, UsbException, ZtexDescriptorException, DeviceLostException {
/**
 
  * Resets the EZ-USB and manages the renumeration process.
 
  * <p>
 
  * After the reset the renumeration starts.
 
  * During this process the device disappears from the bus and a new one
 
  * occurs which will be assigned to this class automatically (instead of the disappeared one).
 
  * @throws FirmwareUploadException If an error occurred while attempting to upload the firmware.
 
  * @throws UsbException if a communication error occurs.
 
  * @throws InvalidFirmwareException if ZTEX descriptor 1 is not available.
 
  * @throws DeviceLostException if a device went lost after renumeration.
 
  */
 
    public void resetEzUsb () throws FirmwareUploadException, UsbException, InvalidFirmwareException, DeviceLostException {
// scan the bus for comparison
// scan the bus for comparison
        findOldDevices();
        findOldDevices();
 
 
// reset the EZ-USB
// reset the EZ-USB
        EzUsb.reset(handle,true);
        EzUsb.reset(handle,true);
        try {
        try {
            EzUsb.reset(handle,false);          // error (may caused re-numeration) can be ignored
            EzUsb.reset(handle,false);          // error (may caused by re-numeration) can be ignored
        }
        }
        catch ( FirmwareUploadException e ) {
        catch ( FirmwareUploadException e ) {
        }
        }
 
 
// find and init new device
// find and init new device
        initNewDevice( "Device lost after resetting the EZ-USB" );
        initNewDevice( "Device lost after resetting the EZ-USB" );
    }
    }
 
 
// ******* toString ************************************************************
// ******* toString ************************************************************
 
/**
 
  * Returns a lot of useful information about the corresponding device.
 
  * @return a lot of useful information about the corresponding device.
 
  */
    public String toString () {
    public String toString () {
        return dev.toString();
        return dev.toString();
    }
    }
 
 
}
}

powered by: WebSVN 2.1.0

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