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

Subversion Repositories usb_fpga_1_11

[/] [usb_fpga_1_11/] [trunk/] [java/] [ztex/] [Ztex1v1.java] - Diff between revs 8 and 9

Only display areas with differences | Details | Blame | View Log

Rev 8 Rev 9
/*!
/*!
   Java host software API of ZTEX EZ-USB FX2 SDK
   Java host software API of ZTEX SDK
   Copyright (C) 2009-2011 ZTEX GmbH.
   Copyright (C) 2009-2014 ZTEX GmbH.
   http://www.ztex.de
   http://www.ztex.de
 
 
   This program is free software; you can redistribute it and/or modify
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 3 as
   it under the terms of the GNU General Public License version 3 as
   published by the Free Software Foundation.
   published by the Free Software Foundation.
 
 
   This program is distributed in the hope that it will be useful, but
   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   General Public License for more details.
   General Public License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program; if not, see http://www.gnu.org/licenses/.
   along with this program; if not, see http://www.gnu.org/licenses/.
!*/
!*/
 
 
/*
/*
    Functions for USB devices with ZTEX descriptor 1, Interface 1
    Functions for USB devices with ZTEX descriptor 1, Interface 1
    Interface capabilities and vendor requests (VR) / commands (VC):
    Interface capabilities and vendor requests (VR) / commands (VC):
    0.0  : EEPROM support
    0.0  : EEPROM support
        VR 0x38 : read from EEPROM
        VR 0x38 : read from EEPROM
            Returns:
            Returns:
                EEPROM data
                EEPROM data
        VC 0x39 : write to EEPROM
        VC 0x39 : write to EEPROM
        VR 0x3a : EEPROM state
        VR 0x3a : EEPROM state
            Returns:
            Returns:
                Offs    Description
                Offs    Description
                0-1     bytes written
                0-1     bytes written
                2       checksum
                2       checksum
                3       0:idle, 1:busy or error
                3       0:idle, 1:busy or error
 
 
    0.1  : FPGA Configuration
    0.1  : FPGA Configuration
        VR 0x30 : get FPGA state
        VR 0x30 : get FPGA state
            Returns:
            Returns:
                Offs    Description
                Offs    Description
                0        1: unconfigured, 0:configured
                0        1: unconfigured, 0:configured
                1       checksum
                1       checksum
                2-5     transferred bytes
                2-5     transferred bytes
                6       INIT_B state
                6       INIT_B state
                7       Flash configuration result
                7       Flash configuration result
                8       Flash bitstream bit order (1=swapped)
                8       Flash bitstream bit order (1=swapped)
 
 
        VC 0x31 : reset FPGA
        VC 0x31 : reset FPGA
        VC 0x32 : send FPGA configuration data (Bitstream)
        VC 0x32 : send FPGA configuration data (Bitstream)
 
 
    0.2  : Flash memory support
    0.2  : Flash memory support
        VR 0x40 : read Flash state
        VR 0x40 : read Flash state
            Returns:
            Returns:
                Offs    Description
                Offs    Description
                0        1:enabled, 0:disabled
                0        1:enabled, 0:disabled
                1-2     Sector size <sector size> = MSB==0 : flash_sector_size and 0x7fff ? 1<<(flash_sector_size and 0x7fff)
                1-2     Sector size <sector size> = MSB==0 : flash_sector_size and 0x7fff ? 1<<(flash_sector_size and 0x7fff)
                3-6     Number of sectors
                3-6     Number of sectors
                7       Error code
                7       Error code
        VR 0x41 : read from Flash
        VR 0x41 : read from Flash
        VC 0x42 : write to Flash
        VC 0x42 : write to Flash
    0.3  : Debug helper support
    0.3  : Debug helper support
        VR 0x28 : read debug data
        VR 0x28 : read debug data
            Returns:
            Returns:
                Offs    Description
                Offs    Description
                0-1     number of messages
                0-1     number of messages
                2       stack size in messages
                2       stack size in messages
                3       message size in bytes
                3       message size in bytes
                >=4     message stack
                >=4     message stack
    0.4  : XMEGA support
    0.4  : XMEGA support
        VR 0x48 : read XMEGA status information
        VR 0x48 : read XMEGA status information
            Returns:
            Returns:
                Offs    Description
                Offs    Description
                0        error code
                0        error code
                1-2     Flash size in pages
                1-2     Flash size in pages
                3-4     EEPROM size in pages
                3-4     EEPROM size in pages
                5       Flash page size as power of two (e.g. 9 means 512 bytes)
                5       Flash page size as power of two (e.g. 9 means 512 bytes)
                6       EEPROM page size as power of two
                6       EEPROM page size as power of two
        VC 0x49 : reset XMEGA
        VC 0x49 : reset XMEGA
        VR 0x4A,0x4B,0x4C,0x4D : read XMEGA NVM using PDI address space / relative to Flash address base / EEPROM address base / Fuse address base
        VR 0x4A,0x4B,0x4C,0x4D : read XMEGA NVM using PDI address space / relative to Flash address base / EEPROM address base / Fuse address base
        VC 0x4B,0x4C : write exactly one Flash / EEPROM page
        VC 0x4B,0x4C : write exactly one Flash / EEPROM page
        VC 0x4D : write Fuse
        VC 0x4D : write Fuse
 
 
    0.5  : High speed FPGA configuration support
    0.5  : High speed FPGA configuration support
        VR 0x33 : Return Endpoint settings
        VR 0x33 : Return Endpoint settings
            Returns:
            Returns:
                Offs    Description
                Offs    Description
                0        Endpoint number
                0        Endpoint number
                1       Interface number
                1       Interface number
        VC 0x34 : Start high speed FPGA configuration
        VC 0x34 : Start high speed FPGA configuration
        VC 0x35 : Finish high speed FPGA configuration
        VC 0x35 : Finish high speed FPGA configuration
 
 
    0.6  : MAC EEPROM support
    0.6  : MAC EEPROM support
        VR 0x3B : read from MAC EEPROM
        VR 0x3B : read from MAC EEPROM
            Returns:
            Returns:
                MAC EEPROM data
                MAC EEPROM data
        VC 0x3C : write to MAC EEPROM
        VC 0x3C : write to MAC EEPROM
        VR 0x3D : MAC EEPROM state
        VR 0x3D : MAC EEPROM state
            Returns:
            Returns:
                Offs    Description
                Offs    Description
                0        0:idle, 1:busy or error
                0        0:idle, 1:busy or error
 
 
    0.7  : Multi-FPGA support
    0.7  : Multi-FPGA support
        VR 0x50 : Return multi-FPGA information
        VR 0x50 : Return multi-FPGA information
            Returns:
            Returns:
                Offs    Description
                Offs    Description
                0       Number of FPGA's - 1
                0       Number of FPGA's - 1
                1       Selected FPGA - 1
                1       Selected FPGA - 1
                2       Parallel configuration support (0:no, 1:yes)
                2       Parallel configuration support (0:no, 1:yes)
        VC 0x51 : set CS
        VC 0x51 : set CS
            Parameters:
            Parameters:
                index: Select command
                index: Select command
                    0 : select single FPGA
                    0 : select single FPGA
                    1 : select all FPGA's for configuration
                    1 : select all FPGA's for configuration
                value: FPGA to select - 1
                value: FPGA to select - 1
 
 
    1.0  : Temperature sensor
    1.0  : Temperature sensor
        VR 0x58 : Return temperature data
        VR 0x58 : Return temperature data
            Returns:
            Returns:
                Offs    Description
                Offs    Description
                0       Protocol number
                0       Protocol number
                1..n    Data
                1..n    Data
 
 
*/
*/
package ztex;
package ztex;
 
 
import java.io.*;
import java.io.*;
import java.util.*;
import java.util.*;
 
 
import ch.ntb.usb.*;
import ch.ntb.usb.*;
 
 
/**
/**
  * This class implements the communication protocol of the interface version 1 for the interaction with the ZTEX firmware.
  * This class implements the communication protocol of the interface version 1 for the interaction with the ZTEX firmware.
  * <p>
  * <p>
  * The features supported by this interface can be accessed via vendor commands and vendor requests via Endpoint 0.
  * The features supported by this interface can be accessed via vendor commands and vendor requests via Endpoint 0.
  * Each feature can be enabled or disabled by the firmware and also depends from the hardware.
  * Each feature can be enabled or disabled by the firmware and also depends from the hardware.
  * The presence of a feature is indicated by a 1 in the corresponding feature bit of the ZTEX descriptor 1, see {@link ZtexDevice1}.
  * The presence of a feature is indicated by a 1 in the corresponding feature bit of the ZTEX descriptor 1, see {@link ZtexDevice1}.
  * The following table gives an overview about the features
  * The following table gives an overview about the features
  * <table bgcolor="#404040" cellspacing=1 cellpadding=10>
  * <table bgcolor="#404040" cellspacing=1 cellpadding=10>
  *   <tr>
  *   <tr>
  *     <td bgcolor="#d0d0d0" valign="bottom"><b>Capability bit</b></td>
  *     <td bgcolor="#d0d0d0" valign="bottom"><b>Capability bit</b></td>
  *     <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *     <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *   </tr>
  *   </tr>
  *   <tr>
  *   <tr>
  *     <td bgcolor="#ffffff" valign="top">0.0</td>
  *     <td bgcolor="#ffffff" valign="top">0.0</td>
  *     <td bgcolor="#ffffff" valign="top" colspan=2>
  *     <td bgcolor="#ffffff" valign="top" colspan=2>
  *       EEPROM support<p>
  *       EEPROM support<p>
  *       <table bgcolor="#404040" cellspacing=1 cellpadding=6>
  *       <table bgcolor="#404040" cellspacing=1 cellpadding=6>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Vendor request (VR)<br> or command (VC)</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Vendor request (VR)<br> or command (VC)</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VR 0x38</td>
  *           <td bgcolor="#ffffff" valign="top">VR 0x38</td>
  *           <td bgcolor="#ffffff" valign="top">Read from EEPROM</td>
  *           <td bgcolor="#ffffff" valign="top">Read from EEPROM</td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VC 0x39</td>
  *           <td bgcolor="#ffffff" valign="top">VC 0x39</td>
  *           <td bgcolor="#ffffff" valign="top">Write to EEPROM</td>
  *           <td bgcolor="#ffffff" valign="top">Write to EEPROM</td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VR 0x3a</td>
  *           <td bgcolor="#ffffff" valign="top">VR 0x3a</td>
  *           <td bgcolor="#ffffff" valign="top">Get EEPROM state. Returns:
  *           <td bgcolor="#ffffff" valign="top">Get EEPROM state. Returns:
  *             <table bgcolor="#404040" cellspacing=1 cellpadding=4>
  *             <table bgcolor="#404040" cellspacing=1 cellpadding=4>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Bytes</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Bytes</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">0-1</td>
  *                 <td bgcolor="#ffffff" valign="top">0-1</td>
  *                 <td bgcolor="#ffffff" valign="top">Number of bytes written.</td>
  *                 <td bgcolor="#ffffff" valign="top">Number of bytes written.</td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">2</td>
  *                 <td bgcolor="#ffffff" valign="top">2</td>
  *                 <td bgcolor="#ffffff" valign="top">Checksum</td>
  *                 <td bgcolor="#ffffff" valign="top">Checksum</td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">3</td>
  *                 <td bgcolor="#ffffff" valign="top">3</td>
  *                 <td bgcolor="#ffffff" valign="top">0:idle, 1:busy or error</td>
  *                 <td bgcolor="#ffffff" valign="top">0:idle, 1:busy or error</td>
  *               </tr>
  *               </tr>
  *             </table>
  *             </table>
  *           </td>
  *           </td>
  *         </tr>
  *         </tr>
  *       </table>
  *       </table>
  *     </td>
  *     </td>
  *   </tr>
  *   </tr>
  *   <tr>
  *   <tr>
  *     <td bgcolor="#ffffff" valign="top">0.1</td>
  *     <td bgcolor="#ffffff" valign="top">0.1</td>
  *     <td bgcolor="#ffffff" valign="top" colspan=2>
  *     <td bgcolor="#ffffff" valign="top" colspan=2>
  *       FPGA Configuration<p>
  *       FPGA Configuration<p>
  *       <table bgcolor="#404040" cellspacing=1 cellpadding=6>
  *       <table bgcolor="#404040" cellspacing=1 cellpadding=6>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Vendor request (VR)<br> or command (VC)</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Vendor request (VR)<br> or command (VC)</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VR 0x30</td>
  *           <td bgcolor="#ffffff" valign="top">VR 0x30</td>
  *           <td bgcolor="#ffffff" valign="top">Get FPGA state. Returns:
  *           <td bgcolor="#ffffff" valign="top">Get FPGA state. Returns:
  *             <table bgcolor="#404040" cellspacing=1 cellpadding=4>
  *             <table bgcolor="#404040" cellspacing=1 cellpadding=4>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Bytes</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Bytes</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">0</td>
  *                 <td bgcolor="#ffffff" valign="top">0</td>
  *                 <td bgcolor="#ffffff" valign="top">1: unconfigured, 0:configured</td>
  *                 <td bgcolor="#ffffff" valign="top">1: unconfigured, 0:configured</td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">1</td>
  *                 <td bgcolor="#ffffff" valign="top">1</td>
  *                 <td bgcolor="#ffffff" valign="top">Checksum</td>
  *                 <td bgcolor="#ffffff" valign="top">Checksum</td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">2-5</td>
  *                 <td bgcolor="#ffffff" valign="top">2-5</td>
  *                 <td bgcolor="#ffffff" valign="top">Number of bytes transferred.</td>
  *                 <td bgcolor="#ffffff" valign="top">Number of bytes transferred.</td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">6</td>
  *                 <td bgcolor="#ffffff" valign="top">6</td>
  *                 <td bgcolor="#ffffff" valign="top">INIT_B states.</td>
  *                 <td bgcolor="#ffffff" valign="top">INIT_B states.</td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">7</td>
  *                 <td bgcolor="#ffffff" valign="top">7</td>
  *                 <td bgcolor="#ffffff" valign="top">Flash configuration result.</td>
  *                 <td bgcolor="#ffffff" valign="top">Flash configuration result.</td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">8</td>
  *                 <td bgcolor="#ffffff" valign="top">8</td>
  *                 <td bgcolor="#ffffff" valign="top">Flash Bitstreambit order (1=swapped).</td>
  *                 <td bgcolor="#ffffff" valign="top">Flash Bitstreambit order (1=swapped).</td>
  *               </tr>
  *               </tr>
  *             </table>
  *             </table>
  *           </td>
  *           </td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VC 0x31</td>
  *           <td bgcolor="#ffffff" valign="top">VC 0x31</td>
  *           <td bgcolor="#ffffff" valign="top">Reset FPGA</td>
  *           <td bgcolor="#ffffff" valign="top">Reset FPGA</td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VR 0x32</td>
  *           <td bgcolor="#ffffff" valign="top">VR 0x32</td>
  *           <td bgcolor="#ffffff" valign="top">Send Bitstream</td>
  *           <td bgcolor="#ffffff" valign="top">Send Bitstream</td>
  *         </tr>
  *         </tr>
  *       </table>
  *       </table>
  *     </td>
  *     </td>
  *   </tr>
  *   </tr>
  *   <tr>
  *   <tr>
  *     <td bgcolor="#ffffff" valign="top">0.2</td>
  *     <td bgcolor="#ffffff" valign="top">0.2</td>
  *     <td bgcolor="#ffffff" valign="top" colspan=2>
  *     <td bgcolor="#ffffff" valign="top" colspan=2>
  *       Flash memory support<p>
  *       Flash memory support<p>
  *       <table bgcolor="#404040" cellspacing=1 cellpadding=6>
  *       <table bgcolor="#404040" cellspacing=1 cellpadding=6>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Vendor request (VR)<br> or command (VC)</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Vendor request (VR)<br> or command (VC)</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VR 0x40</td>
  *           <td bgcolor="#ffffff" valign="top">VR 0x40</td>
  *           <td bgcolor="#ffffff" valign="top">Get Flash state. Returns:
  *           <td bgcolor="#ffffff" valign="top">Get Flash state. Returns:
  *             <table bgcolor="#404040" cellspacing=1 cellpadding=4>
  *             <table bgcolor="#404040" cellspacing=1 cellpadding=4>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Bytes</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Bytes</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">0</td>
  *                 <td bgcolor="#ffffff" valign="top">0</td>
  *                 <td bgcolor="#ffffff" valign="top">1:enabled, 0:disabled</td>
  *                 <td bgcolor="#ffffff" valign="top">1:enabled, 0:disabled</td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">1-2</td>
  *                 <td bgcolor="#ffffff" valign="top">1-2</td>
  *                 <td bgcolor="#ffffff" valign="top">Sector size</td>
  *                 <td bgcolor="#ffffff" valign="top">Sector size</td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">3-6</td>
  *                 <td bgcolor="#ffffff" valign="top">3-6</td>
  *                 <td bgcolor="#ffffff" valign="top">Number of sectors</td>
  *                 <td bgcolor="#ffffff" valign="top">Number of sectors</td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">7</td>
  *                 <td bgcolor="#ffffff" valign="top">7</td>
  *                 <td bgcolor="#ffffff" valign="top">Error code</td>
  *                 <td bgcolor="#ffffff" valign="top">Error code</td>
  *               </tr>
  *               </tr>
  *             </table>
  *             </table>
  *           </td>
  *           </td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VR 0x41</td>
  *           <td bgcolor="#ffffff" valign="top">VR 0x41</td>
  *           <td bgcolor="#ffffff" valign="top">Read one sector from Flash</td>
  *           <td bgcolor="#ffffff" valign="top">Read one sector from Flash</td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VC 0x42</td>
  *           <td bgcolor="#ffffff" valign="top">VC 0x42</td>
  *           <td bgcolor="#ffffff" valign="top">Write one sector to Flash</td>
  *           <td bgcolor="#ffffff" valign="top">Write one sector to Flash</td>
  *         </tr>
  *         </tr>
  *       </table>
  *       </table>
  *     </td>
  *     </td>
  *   </tr>
  *   </tr>
  *   <tr>
  *   <tr>
  *     <td bgcolor="#ffffff" valign="top">0.3</td>
  *     <td bgcolor="#ffffff" valign="top">0.3</td>
  *     <td bgcolor="#ffffff" valign="top" colspan=2>
  *     <td bgcolor="#ffffff" valign="top" colspan=2>
  *       Debug helper support<p>
  *       Debug helper support<p>
  *       <table bgcolor="#404040" cellspacing=1 cellpadding=6>
  *       <table bgcolor="#404040" cellspacing=1 cellpadding=6>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Vendor request (VR)<br> or command (VC)</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Vendor request (VR)<br> or command (VC)</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VR 0x28</td>
  *           <td bgcolor="#ffffff" valign="top">VR 0x28</td>
  *           <td bgcolor="#ffffff" valign="top">Get debug data. Returns:
  *           <td bgcolor="#ffffff" valign="top">Get debug data. Returns:
  *             <table bgcolor="#404040" cellspacing=1 cellpadding=4>
  *             <table bgcolor="#404040" cellspacing=1 cellpadding=4>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Bytes</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Bytes</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">0-1</td>
  *                 <td bgcolor="#ffffff" valign="top">0-1</td>
  *                 <td bgcolor="#ffffff" valign="top">Number of the last message</td>
  *                 <td bgcolor="#ffffff" valign="top">Number of the last message</td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">2</td>
  *                 <td bgcolor="#ffffff" valign="top">2</td>
  *                 <td bgcolor="#ffffff" valign="top">Stack size in messages</td>
  *                 <td bgcolor="#ffffff" valign="top">Stack size in messages</td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">3</td>
  *                 <td bgcolor="#ffffff" valign="top">3</td>
  *                 <td bgcolor="#ffffff" valign="top">Message size in bytes</td>
  *                 <td bgcolor="#ffffff" valign="top">Message size in bytes</td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">&ge;4</td>
  *                 <td bgcolor="#ffffff" valign="top">&ge;4</td>
  *                 <td bgcolor="#ffffff" valign="top">Message stack</td>
  *                 <td bgcolor="#ffffff" valign="top">Message stack</td>
  *               </tr>
  *               </tr>
  *             </table>
  *             </table>
  *           </td>
  *           </td>
  *         </tr>
  *         </tr>
  *       </table>
  *       </table>
  *     </td>
  *     </td>
  *   </tr>
  *   </tr>
  *   <tr>
  *   <tr>
  *     <td bgcolor="#ffffff" valign="top">0.4</td>
  *     <td bgcolor="#ffffff" valign="top">0.4</td>
  *     <td bgcolor="#ffffff" valign="top" colspan=2>
  *     <td bgcolor="#ffffff" valign="top" colspan=2>
  *       XMEGA support<p>
  *       XMEGA support<p>
  *       <table bgcolor="#404040" cellspacing=1 cellpadding=6>
  *       <table bgcolor="#404040" cellspacing=1 cellpadding=6>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Vendor request (VR)<br> or command (VC)</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Vendor request (VR)<br> or command (VC)</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VR 0x48</td>
  *           <td bgcolor="#ffffff" valign="top">VR 0x48</td>
  *           <td bgcolor="#ffffff" valign="top">Read XMEGA status information. Returns:
  *           <td bgcolor="#ffffff" valign="top">Read XMEGA status information. Returns:
  *             <table bgcolor="#404040" cellspacing=1 cellpadding=4>
  *             <table bgcolor="#404040" cellspacing=1 cellpadding=4>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Bytes</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Bytes</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">0</td>
  *                 <td bgcolor="#ffffff" valign="top">0</td>
  *                 <td bgcolor="#ffffff" valign="top">Error code</td>
  *                 <td bgcolor="#ffffff" valign="top">Error code</td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">1-2</td>
  *                 <td bgcolor="#ffffff" valign="top">1-2</td>
  *                 <td bgcolor="#ffffff" valign="top">Flash size in pages</td>
  *                 <td bgcolor="#ffffff" valign="top">Flash size in pages</td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">3-4</td>
  *                 <td bgcolor="#ffffff" valign="top">3-4</td>
  *                 <td bgcolor="#ffffff" valign="top">EEPROM sie in pages</td>
  *                 <td bgcolor="#ffffff" valign="top">EEPROM sie in pages</td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">5</td>
  *                 <td bgcolor="#ffffff" valign="top">5</td>
  *                 <td bgcolor="#ffffff" valign="top">Flash page size as power of two  (e.g. 9 means 512 bytes)</td>
  *                 <td bgcolor="#ffffff" valign="top">Flash page size as power of two  (e.g. 9 means 512 bytes)</td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">6</td>
  *                 <td bgcolor="#ffffff" valign="top">6</td>
  *                 <td bgcolor="#ffffff" valign="top">EEPROM page size as power of two</td>
  *                 <td bgcolor="#ffffff" valign="top">EEPROM page size as power of two</td>
  *               </tr>
  *               </tr>
  *             </table>
  *             </table>
  *           </td>
  *           </td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VC 0x49</td>
  *           <td bgcolor="#ffffff" valign="top">VC 0x49</td>
  *           <td bgcolor="#ffffff" valign="top">Reset XMEGA</td>
  *           <td bgcolor="#ffffff" valign="top">Reset XMEGA</td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VRs 0x4A, 0x4B, 0x4C, 0x4D</td>
  *           <td bgcolor="#ffffff" valign="top">VRs 0x4A, 0x4B, 0x4C, 0x4D</td>
  *           <td bgcolor="#ffffff" valign="top">Read XMEGA NVM using PDI address space / relative to Flash address base / EEPROM address base / Fuse address base</td>
  *           <td bgcolor="#ffffff" valign="top">Read XMEGA NVM using PDI address space / relative to Flash address base / EEPROM address base / Fuse address base</td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VCs 0x4B, 0x4C</td>
  *           <td bgcolor="#ffffff" valign="top">VCs 0x4B, 0x4C</td>
  *           <td bgcolor="#ffffff" valign="top">Write exactly one Flash / EEPROM page</td>
  *           <td bgcolor="#ffffff" valign="top">Write exactly one Flash / EEPROM page</td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VCs 0x4D</td>
  *           <td bgcolor="#ffffff" valign="top">VCs 0x4D</td>
  *           <td bgcolor="#ffffff" valign="top">Write Fuse</td>
  *           <td bgcolor="#ffffff" valign="top">Write Fuse</td>
  *         </tr>
  *         </tr>
  *       </table>
  *       </table>
  *     </td>
  *     </td>
  *   </tr>
  *   </tr>
  *   <tr>
  *   <tr>
  *     <td bgcolor="#ffffff" valign="top">0.5</td>
  *     <td bgcolor="#ffffff" valign="top">0.5</td>
  *     <td bgcolor="#ffffff" valign="top" colspan=2>
  *     <td bgcolor="#ffffff" valign="top" colspan=2>
  *       High speed FPGA configuration support<p>
  *       High speed FPGA configuration support<p>
  *       <table bgcolor="#404040" cellspacing=1 cellpadding=6>
  *       <table bgcolor="#404040" cellspacing=1 cellpadding=6>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Vendor request (VR)<br> or command (VC)</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Vendor request (VR)<br> or command (VC)</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VR 0x33</td>
  *           <td bgcolor="#ffffff" valign="top">VR 0x33</td>
  *           <td bgcolor="#ffffff" valign="top">Read Endpoint settings. Returns:
  *           <td bgcolor="#ffffff" valign="top">Read Endpoint settings. Returns:
  *             <table bgcolor="#404040" cellspacing=1 cellpadding=4>
  *             <table bgcolor="#404040" cellspacing=1 cellpadding=4>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Bytes</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Bytes</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">0</td>
  *                 <td bgcolor="#ffffff" valign="top">0</td>
  *                 <td bgcolor="#ffffff" valign="top">Endpoint number</td>
  *                 <td bgcolor="#ffffff" valign="top">Endpoint number</td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">1</td>
  *                 <td bgcolor="#ffffff" valign="top">1</td>
  *                 <td bgcolor="#ffffff" valign="top">Interface number</td>
  *                 <td bgcolor="#ffffff" valign="top">Interface number</td>
  *               </tr>
  *               </tr>
  *             </table>
  *             </table>
  *           </td>
  *           </td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VR 0x34</td>
  *           <td bgcolor="#ffffff" valign="top">VR 0x34</td>
  *           <td bgcolor="#ffffff" valign="top">Start FPGA configuration</td>
  *           <td bgcolor="#ffffff" valign="top">Start FPGA configuration</td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VC 0x35</td>
  *           <td bgcolor="#ffffff" valign="top">VC 0x35</td>
  *           <td bgcolor="#ffffff" valign="top">Finish FPGA configuration</td>
  *           <td bgcolor="#ffffff" valign="top">Finish FPGA configuration</td>
  *         </tr>
  *         </tr>
  *       </table>
  *       </table>
  *     </td>
  *     </td>
  *   </tr>
  *   </tr>
  *   <tr>
  *   <tr>
  *     <td bgcolor="#ffffff" valign="top">0.6</td>
  *     <td bgcolor="#ffffff" valign="top">0.6</td>
  *     <td bgcolor="#ffffff" valign="top" colspan=2>
  *     <td bgcolor="#ffffff" valign="top" colspan=2>
  *       MAC EEPROM support<p>
  *       MAC EEPROM support<p>
  *       <table bgcolor="#404040" cellspacing=1 cellpadding=6>
  *       <table bgcolor="#404040" cellspacing=1 cellpadding=6>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Vendor request (VR)<br> or command (VC)</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Vendor request (VR)<br> or command (VC)</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VR 0x3B</td>
  *           <td bgcolor="#ffffff" valign="top">VR 0x3B</td>
  *           <td bgcolor="#ffffff" valign="top">Read from MAC EEPROM</td>
  *           <td bgcolor="#ffffff" valign="top">Read from MAC EEPROM</td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VC 0x3C</td>
  *           <td bgcolor="#ffffff" valign="top">VC 0x3C</td>
  *           <td bgcolor="#ffffff" valign="top">Write to MAC EEPROM</td>
  *           <td bgcolor="#ffffff" valign="top">Write to MAC EEPROM</td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VR 0x3D</td>
  *           <td bgcolor="#ffffff" valign="top">VR 0x3D</td>
  *           <td bgcolor="#ffffff" valign="top">Get MAC EEPROM state. Returns:
  *           <td bgcolor="#ffffff" valign="top">Get MAC EEPROM state. Returns:
  *             <table bgcolor="#404040" cellspacing=1 cellpadding=4>
  *             <table bgcolor="#404040" cellspacing=1 cellpadding=4>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Bytes</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Bytes</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">0</td>
  *                 <td bgcolor="#ffffff" valign="top">0</td>
  *                 <td bgcolor="#ffffff" valign="top">0:idle, 1:busy or error</td>
  *                 <td bgcolor="#ffffff" valign="top">0:idle, 1:busy or error</td>
  *               </tr>
  *               </tr>
  *             </table>
  *             </table>
  *           </td>
  *           </td>
  *         </tr>
  *         </tr>
  *       </table>
  *       </table>
  *     </td>
  *     </td>
  *   </tr>
  *   </tr>
  *   <tr>
  *   <tr>
  *     <td bgcolor="#ffffff" valign="top">0.7</td>
  *     <td bgcolor="#ffffff" valign="top">0.7</td>
  *     <td bgcolor="#ffffff" valign="top" colspan=2>
  *     <td bgcolor="#ffffff" valign="top" colspan=2>
  *       Multi-FPGA support<p>
  *       Multi-FPGA support<p>
  *       <table bgcolor="#404040" cellspacing=1 cellpadding=6>
  *       <table bgcolor="#404040" cellspacing=1 cellpadding=6>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Vendor request (VR)<br> or command (VC)</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Vendor request (VR)<br> or command (VC)</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VR 0x50</td>
  *           <td bgcolor="#ffffff" valign="top">VR 0x50</td>
  *           <td bgcolor="#ffffff" valign="top">Return multi-FPGA information:
  *           <td bgcolor="#ffffff" valign="top">Return multi-FPGA information:
  *             <table bgcolor="#404040" cellspacing=1 cellpadding=4>
  *             <table bgcolor="#404040" cellspacing=1 cellpadding=4>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Bytes</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Bytes</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">0</td>
  *                 <td bgcolor="#ffffff" valign="top">0</td>
  *                 <td bgcolor="#ffffff" valign="top">Number of FPGA's - 1</td>
  *                 <td bgcolor="#ffffff" valign="top">Number of FPGA's - 1</td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">1</td>
  *                 <td bgcolor="#ffffff" valign="top">1</td>
  *                 <td bgcolor="#ffffff" valign="top">Selected FPGA - 1</td>
  *                 <td bgcolor="#ffffff" valign="top">Selected FPGA - 1</td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">2</td>
  *                 <td bgcolor="#ffffff" valign="top">2</td>
  *                 <td bgcolor="#ffffff" valign="top">Parallel configuration support (0:no, 1:yes)</td>
  *                 <td bgcolor="#ffffff" valign="top">Parallel configuration support (0:no, 1:yes)</td>
  *               </tr>
  *               </tr>
  *             </table>
  *             </table>
  *           </td>
  *           </td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VC 0x51</td>
  *           <td bgcolor="#ffffff" valign="top">VC 0x51</td>
  *           <td bgcolor="#ffffff" valign="top">Parameters:
  *           <td bgcolor="#ffffff" valign="top">Parameters:
  *             <table bgcolor="#404040" cellspacing=1 cellpadding=4>
  *             <table bgcolor="#404040" cellspacing=1 cellpadding=4>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Parameter</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Parameter</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">index</td>
  *                 <td bgcolor="#ffffff" valign="top">index</td>
  *                 <td bgcolor="#ffffff" valign="top">Select command<br> 0: Select single FPGA <br> 1: Select all FPGA's for configuration</td>
  *                 <td bgcolor="#ffffff" valign="top">Select command<br> 0: Select single FPGA <br> 1: Select all FPGA's for configuration</td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">value</td>
  *                 <td bgcolor="#ffffff" valign="top">value</td>
  *                 <td bgcolor="#ffffff" valign="top">FPGA to select - 1</td>
  *                 <td bgcolor="#ffffff" valign="top">FPGA to select - 1</td>
  *               </tr>
  *               </tr>
  *             </table>
  *             </table>
  *           </td>
  *           </td>
  *         </tr>
  *         </tr>
  *       </table>
  *       </table>
  *     </td>
  *     </td>
  *   </tr>
  *   </tr>
  *   <tr>
  *   <tr>
  *     <td bgcolor="#ffffff" valign="top">1.0</td>
  *     <td bgcolor="#ffffff" valign="top">1.0</td>
  *     <td bgcolor="#ffffff" valign="top" colspan=2>
  *     <td bgcolor="#ffffff" valign="top" colspan=2>
  *       Temperature sensor support<p>
  *       Temperature sensor support<p>
  *       <table bgcolor="#404040" cellspacing=1 cellpadding=6>
  *       <table bgcolor="#404040" cellspacing=1 cellpadding=6>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Vendor request (VR)<br> or command (VC)</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Vendor request (VR)<br> or command (VC)</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *           <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *         </tr>
  *         </tr>
  *         <tr>
  *         <tr>
  *           <td bgcolor="#ffffff" valign="top">VR 0x58</td>
  *           <td bgcolor="#ffffff" valign="top">VR 0x58</td>
  *           <td bgcolor="#ffffff" valign="top">Return temperature data:
  *           <td bgcolor="#ffffff" valign="top">Return temperature data:
  *             <table bgcolor="#404040" cellspacing=1 cellpadding=4>
  *             <table bgcolor="#404040" cellspacing=1 cellpadding=4>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Bytes</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Bytes</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *                 <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">0</td>
  *                 <td bgcolor="#ffffff" valign="top">0</td>
  *                 <td bgcolor="#ffffff" valign="top">Protocol</td>
  *                 <td bgcolor="#ffffff" valign="top">Protocol</td>
  *               </tr>
  *               </tr>
  *               <tr>
  *               <tr>
  *                 <td bgcolor="#ffffff" valign="top">1..n</td>
  *                 <td bgcolor="#ffffff" valign="top">1..n</td>
  *                 <td bgcolor="#ffffff" valign="top">Data</td>
  *                 <td bgcolor="#ffffff" valign="top">Data</td>
  *               </tr>
  *               </tr>
  *             </table>
  *             </table>
  *           </td>
  *           </td>
  *         </tr>
  *         </tr>
  *       </table>
  *       </table>
  *     </td>
  *     </td>
  *   </tr>
  *   </tr>
  * </table>
  * </table>
  * @see ZtexDevice1
  * @see ZtexDevice1
  * @see Ztex1
  * @see Ztex1
  */
  */
 
 
 
 
public class Ztex1v1 extends Ztex1 {
public class Ztex1v1 extends Ztex1 {
    /** * Capability index for EEPROM support. */
    /** * Capability index for EEPROM support. */
    public static final int CAPABILITY_EEPROM = 0;
    public static final int CAPABILITY_EEPROM = 0;
    /** * Capability index for FPGA configuration support. */
    /** * Capability index for FPGA configuration support. */
    public static final int CAPABILITY_FPGA = 1;
    public static final int CAPABILITY_FPGA = 1;
    /** * Capability index for FLASH memory support. */
    /** * Capability index for FLASH memory support. */
    public static final int CAPABILITY_FLASH = 2;
    public static final int CAPABILITY_FLASH = 2;
    /** * Capability index for DEBUG helper support. */
    /** * Capability index for DEBUG helper support. */
    public static final int CAPABILITY_DEBUG = 3;
    public static final int CAPABILITY_DEBUG = 3;
    /** * Capability index for AVR XMEGA support. */
    /** * Capability index for AVR XMEGA support. */
    public static final int CAPABILITY_XMEGA = 4;
    public static final int CAPABILITY_XMEGA = 4;
    /** * Capability index for AVR XMEGA support. */
    /** * Capability index for AVR XMEGA support. */
    public static final int CAPABILITY_HS_FPGA = 5;
    public static final int CAPABILITY_HS_FPGA = 5;
    /** * Capability index for AVR XMEGA support. */
    /** * Capability index for AVR XMEGA support. */
    public static final int CAPABILITY_MAC_EEPROM = 6;
    public static final int CAPABILITY_MAC_EEPROM = 6;
    /** * Capability index for multi FPGA support */
    /** * Capability index for multi FPGA support */
    public static final int CAPABILITY_MULTI_FPGA = 7;
    public static final int CAPABILITY_MULTI_FPGA = 7;
    /** * Capability index for Temperature sensor support */
    /** * Capability index for Temperature sensor support */
    public static final int CAPABILITY_TEMP_SENSOR = 9;
    public static final int CAPABILITY_TEMP_SENSOR = 9;
 
 
    /** * The names of the capabilities */
    /** * The names of the capabilities */
    public static final String capabilityStrings[] = {
    public static final String capabilityStrings[] = {
        "EEPROM read/write" ,
        "EEPROM read/write" ,
        "FPGA configuration" ,
        "FPGA configuration" ,
        "Flash memory support",
        "Flash memory support",
        "Debug helper",
        "Debug helper",
        "XMEGA support",
        "XMEGA support",
        "High speed FPGA configuration",
        "High speed FPGA configuration",
        "MAC EEPROM read/write",
        "MAC EEPROM read/write",
        "Multi FPGA support",
        "Multi FPGA support",
        "Temperature Sensor support" ,
        "Temperature Sensor support" ,
    };
    };
 
 
    /** * Enables extra FPGA configuration checks. Certain Bistream settings may cause false warnings.  */
    /** * Enables extra FPGA configuration checks. Certain Bistream settings may cause false warnings.  */
    public boolean enableExtraFpgaConfigurationChecks = false;
    public boolean enableExtraFpgaConfigurationChecks = false;
 
 
    private boolean fpgaConfigured = false;
    private boolean fpgaConfigured = false;
    private int fpgaChecksum = 0;
    private int fpgaChecksum = 0;
    private int fpgaBytes = 0;
    private int fpgaBytes = 0;
    private int fpgaInitB = 0;
    private int fpgaInitB = 0;
    private int fpgaFlashResult = 255;
    private int fpgaFlashResult = 255;
    private boolean fpgaFlashBitSwap = false;
    private boolean fpgaFlashBitSwap = false;
 
 
    /** * Number of bytes written to EEPROM. (Obtained by {@link #eepromState()}.) */
    /** * Number of bytes written to EEPROM. (Obtained by {@link #eepromState()}.) */
    public int eepromBytes = 0;
    public int eepromBytes = 0;
    /** * Checksum of the last EEPROM transfer. (Obtained by {@link #eepromState()}.) */
    /** * Checksum of the last EEPROM transfer. (Obtained by {@link #eepromState()}.) */
    public int eepromChecksum = 0;
    public int eepromChecksum = 0;
 
 
    private int flashEnabled = -1;
    private int flashEnabled = -1;
    private int flashSectorSize = -1;
    private int flashSectorSize = -1;
    private int flashSectors = -1;
    private int flashSectors = -1;
 
 
    /** * Last Flash error code obtained by {@link #flashState()}. See FLASH_EC_* for possible error codes. */
    /** * Last Flash error code obtained by {@link #flashState()}. See FLASH_EC_* for possible error codes. */
    public int flashEC = 0;
    public int flashEC = 0;
    /** * Means no error. */
    /** * Means no error. */
    public static final int FLASH_EC_NO_ERROR = 0;
    public static final int FLASH_EC_NO_ERROR = 0;
    /** * Signals an error while attempting to execute a command. */
    /** * Signals an error while attempting to execute a command. */
    public static final int FLASH_EC_CMD_ERROR = 1;
    public static final int FLASH_EC_CMD_ERROR = 1;
    /** * Signals that a timeout occurred. */
    /** * Signals that a timeout occurred. */
    public static final int FLASH_EC_TIMEOUT = 2;
    public static final int FLASH_EC_TIMEOUT = 2;
    /** * Signals that Flash memory it busy. */
    /** * Signals that Flash memory it busy. */
    public static final int FLASH_EC_BUSY = 3;
    public static final int FLASH_EC_BUSY = 3;
    /** * Signals that another Flash operation is pending. */
    /** * Signals that another Flash operation is pending. */
    public static final int FLASH_EC_PENDING = 4;
    public static final int FLASH_EC_PENDING = 4;
    /** * Signals an error while attempting to read from Flash. */
    /** * Signals an error while attempting to read from Flash. */
    public static final int FLASH_EC_READ_ERROR = 5;
    public static final int FLASH_EC_READ_ERROR = 5;
    /** * Signals an error while attempting to write to Flash. */
    /** * Signals an error while attempting to write to Flash. */
    public static final int FLASH_EC_WRITE_ERROR = 6;
    public static final int FLASH_EC_WRITE_ERROR = 6;
    /** * Signals the the installed Flash memory is not supported. */
    /** * Signals the the installed Flash memory is not supported. */
    public static final int FLASH_EC_NOTSUPPORTED = 7;
    public static final int FLASH_EC_NOTSUPPORTED = 7;
 
 
    private int debugStackSize = -1;
    private int debugStackSize = -1;
    private int debugMsgSize = -1;
    private int debugMsgSize = -1;
    private int debugLastMsg = 0;
    private int debugLastMsg = 0;
    /** * Is set by {@link #debugReadMessages(boolean,byte[])} and contains the number of new messages. */
    /** * Is set by {@link #debugReadMessages(boolean,byte[])} and contains the number of new messages. */
    public int debugNewMessages = 0;
    public int debugNewMessages = 0;
 
 
    private int xmegaFlashPages = -1;
    private int xmegaFlashPages = -1;
    private int xmegaEepromPages = -1;
    private int xmegaEepromPages = -1;
    private int xmegaFlashPageSize;
    private int xmegaFlashPageSize;
    private int xmegaEepromPageSize;
    private int xmegaEepromPageSize;
 
 
    /** * Last ATxmega error code obtained by {@link #xmegaState()}. See XMEGA_EC_* for possible error codes. */
    /** * Last ATxmega error code obtained by {@link #xmegaState()}. See XMEGA_EC_* for possible error codes. */
    public int xmegaEC = 0;
    public int xmegaEC = 0;
    /** * Means no error. */
    /** * Means no error. */
    public static final int XMEGA_EC_NO_ERROR = 0;
    public static final int XMEGA_EC_NO_ERROR = 0;
    /** * Signals a PDI read error. */
    /** * Signals a PDI read error. */
    public static final int XMEGA_EC_PDI_READ_ERROR = 1;
    public static final int XMEGA_EC_PDI_READ_ERROR = 1;
    /** * Signals that an NVM timeout occurred. */
    /** * Signals that an NVM timeout occurred. */
    public static final int XMEGA_EC_NVM_TIMEOUT = 2;
    public static final int XMEGA_EC_NVM_TIMEOUT = 2;
    /** * Signals that the ATxmega controller is not supported. */
    /** * Signals that the ATxmega controller is not supported. */
    public static final int XMEGA_EC_INVALID_DEVICE = 3;
    public static final int XMEGA_EC_INVALID_DEVICE = 3;
    /** * Signals an address error (invalid address or wrong page size). */
    /** * Signals an address error (invalid address or wrong page size). */
    public static final int XMEGA_EC_ADDRESS_ERROR = 4;
    public static final int XMEGA_EC_ADDRESS_ERROR = 4;
    /** * Signals that the NVM is busy. */
    /** * Signals that the NVM is busy. */
    public static final int XMEGA_EC_NVM_BUSY = 5;
    public static final int XMEGA_EC_NVM_BUSY = 5;
 
 
    private int numberOfFpgas = -1;
    private int numberOfFpgas = -1;
    private int selectedFpga = -1;
    private int selectedFpga = -1;
    private boolean parallelConfigSupport = false;
    private boolean parallelConfigSupport = false;
 
 
    private long lastTempSensorReadTime = 0;
    private long lastTempSensorReadTime = 0;
    private byte[] tempSensorBuf = new byte[9];
    private byte[] tempSensorBuf = new byte[9];
    /** * smallest temperature sensor update interval in ms */
    /** * smallest temperature sensor update interval in ms */
    public int tempSensorUpdateInterval = 100;
    public int tempSensorUpdateInterval = 100;
 
 
/**
/**
  * The configuration data structure
  * The configuration data structure
  * is initialized if this kind of data is present in MAC EEPROM.
  * is initialized if this kind of data is present in MAC EEPROM.
  * In this case MAC EEPROM writes to addresses 0 to 79 are disabled, see {@link #macEepromWrite(int,byte[],int)}.
  * In this case MAC EEPROM writes to addresses 0 to 79 are disabled, see {@link #macEepromWrite(int,byte[],int)}.
  * In order to override this behavior set this variable to null.
  * In order to override this behavior set this variable to null.
  * If no configuration data is present {@link #config} is null.
  * If no configuration data is present {@link #config} is null.
  */
  */
    public ConfigData config;
    public ConfigData config;
 
 
// ******* Ztex1v1 *************************************************************
// ******* Ztex1v1 *************************************************************
/**
/**
  * Constructs an instance from a given device.
  * Constructs an instance from a given device.
  * @param pDev The given device.
  * @param pDev The given device.
  * @throws UsbException if an communication error occurred.
  * @throws UsbException if an communication error occurred.
  */
  */
    public Ztex1v1 ( ZtexDevice1 pDev ) throws UsbException {
    public Ztex1v1 ( ZtexDevice1 pDev ) throws UsbException {
        super ( pDev );
        super ( pDev );
    }
    }
 
 
// ******* init ****************************************************************
// ******* init ****************************************************************
/**
/**
  * Initializates the class.
  * Initializates the class.
  * @throws UsbException if an communication error occurred.
  * @throws UsbException if an communication error occurred.
  */
  */
    protected void init () throws UsbException {
    protected void init () throws UsbException {
        super.init();
        super.init();
        config = new ConfigData ();
        config = new ConfigData ();
        try {
        try {
            if ( ! config.connect( this ) )
            if ( ! config.connect( this ) )
                config = null;
                config = null;
        }
        }
        catch ( Exception e ) {
        catch ( Exception e ) {
            config = null;
            config = null;
        }
        }
    }
    }
 
 
// ******* valid ***************************************************************
// ******* valid ***************************************************************
/**
/**
  * Returns true if ZTEX interface 1 is available.
  * Returns true if ZTEX interface 1 is available.
  * @return true if ZTEX interface 1 is available.
  * @return true if ZTEX interface 1 is available.
  */
  */
    public boolean valid ( ) {
    public boolean valid ( ) {
        return dev().valid() && dev().interfaceVersion()==1;
        return dev().valid() && dev().interfaceVersion()==1;
    }
    }
 
 
/**
/**
  * Returns true if ZTEX interface 1 and capability i.j are available.
  * Returns true if ZTEX interface 1 and capability i.j are available.
  * @param i byte index of the capability
  * @param i byte index of the capability
  * @param j bit index of the capability
  * @param j bit index of the capability
  * @return true if ZTEX interface 1 and capability i.j are available.
  * @return true if ZTEX interface 1 and capability i.j are available.
  */
  */
    public boolean valid ( int i, int j) {
    public boolean valid ( int i, int j) {
        return dev().valid() && dev().interfaceVersion()==1 && dev().interfaceCapabilities(i,j);
        return dev().valid() && dev().interfaceVersion()==1 && dev().interfaceCapabilities(i,j);
    }
    }
 
 
// ******* compatible **********************************************************
// ******* compatible **********************************************************
/**
/**
  * Checks whether the given product ID is compatible to the device corresponding to this class and whether interface 1 is supported.<br>
  * Checks whether the given product ID is compatible to the device corresponding to this class and whether interface 1 is supported.<br>
  * The given product ID is compatible
  * The given product ID is compatible
  * <pre>if ( this.productId(0)==0 || productId0<=0 || this.productId(0)==productId0 ) &&
  * <pre>if ( this.productId(0)==0 || productId0<=0 || this.productId(0)==productId0 ) &&
   ( this.productId(0)==0 || productId1<=0 || this.productId(1)==productId1 ) &&
   ( this.productId(0)==0 || productId1<=0 || this.productId(1)==productId1 ) &&
   ( this.productId(2)==0 || productId2<=0 || this.productId(2)==productId2 ) &&
   ( this.productId(2)==0 || productId2<=0 || this.productId(2)==productId2 ) &&
   ( this.productId(3)==0 || productId3<=0 || this.productId(3)==productId3 ) </pre>
   ( this.productId(3)==0 || productId3<=0 || this.productId(3)==productId3 ) </pre>
  * @param productId0 Byte 0 of the given product ID
  * @param productId0 Byte 0 of the given product ID
  * @param productId1 Byte 1 of the given product ID
  * @param productId1 Byte 1 of the given product ID
  * @param productId2 Byte 2 of the given product ID
  * @param productId2 Byte 2 of the given product ID
  * @param productId3 Byte 3 of the given product ID
  * @param productId3 Byte 3 of the given product ID
  * @return true if the given product ID is compatible and interface 1 is supported.
  * @return true if the given product ID is compatible and interface 1 is supported.
  */
  */
    public boolean compatible ( int productId0, int productId1, int productId2, int productId3 ) {
    public boolean compatible ( int productId0, int productId1, int productId2, int productId3 ) {
        return dev().valid() && dev().compatible ( productId0, productId1, productId2, productId3 ) && dev().interfaceVersion()==1;
        return dev().valid() && dev().compatible ( productId0, productId1, productId2, productId3 ) && dev().interfaceVersion()==1;
    }
    }
 
 
// ******* checkValid **********************************************************
// ******* checkValid **********************************************************
/**
/**
  * Checks whether ZTEX descriptor 1 is available and interface 1 is supported.
  * Checks whether ZTEX descriptor 1 is available and interface 1 is supported.
  * @throws InvalidFirmwareException if ZTEX descriptor 1 is not available or interface 1 is not supported.
  * @throws InvalidFirmwareException if ZTEX descriptor 1 is not available or interface 1 is not supported.
  */
  */
    public void checkValid () throws InvalidFirmwareException {
    public void checkValid () throws InvalidFirmwareException {
        super.checkValid();
        super.checkValid();
        if ( dev().interfaceVersion() != 1 )
        if ( dev().interfaceVersion() != 1 )
            throw new InvalidFirmwareException(this, "Wrong interface: " + dev().interfaceVersion() + ", expected: 1" );
            throw new InvalidFirmwareException(this, "Wrong interface: " + dev().interfaceVersion() + ", expected: 1" );
    }
    }
 
 
// ******* checkCapability *****************************************************
// ******* checkCapability *****************************************************
/**
/**
  * Checks whether ZTEX descriptor 1 is available and interface 1 and a given capability are supported.
  * Checks whether ZTEX descriptor 1 is available and interface 1 and a given capability are supported.
  * @param i byte index of the capability
  * @param i byte index of the capability
  * @param j bit index of the capability
  * @param j bit index of the capability
  * @throws InvalidFirmwareException if ZTEX descriptor 1 is not available or interface 1 is not supported.
  * @throws InvalidFirmwareException if ZTEX descriptor 1 is not available or interface 1 is not supported.
  * @throws CapabilityException if the given capability is not supported.
  * @throws CapabilityException if the given capability is not supported.
  */
  */
    public void checkCapability ( int i, int j ) throws InvalidFirmwareException, CapabilityException {
    public void checkCapability ( int i, int j ) throws InvalidFirmwareException, CapabilityException {
        checkValid();
        checkValid();
        if ( ! dev().interfaceCapabilities(i,j) ) {
        if ( ! dev().interfaceCapabilities(i,j) ) {
            int k = i*8 + j;
            int k = i*8 + j;
            if ( k>=0 && k<capabilityStrings.length )
            if ( k>=0 && k<capabilityStrings.length )
            throw new CapabilityException( this, ( k>=0 && k<=capabilityStrings.length ) ? capabilityStrings[k] : ("Capabilty " + i + "," + j) );
            throw new CapabilityException( this, ( k>=0 && k<=capabilityStrings.length ) ? capabilityStrings[k] : ("Capabilty " + i + "," + j) );
        }
        }
    }
    }
 
 
/**
/**
  * Checks whether ZTEX descriptor 1 is available and interface 1 and a given capability are supported.
  * Checks whether ZTEX descriptor 1 is available and interface 1 and a given capability are supported.
  * @param i capability index (0..47)
  * @param i capability index (0..47)
  * @throws InvalidFirmwareException if ZTEX descriptor 1 is not available or interface 1 is not supported.
  * @throws InvalidFirmwareException if ZTEX descriptor 1 is not available or interface 1 is not supported.
  * @throws CapabilityException if the given capability is not supported.
  * @throws CapabilityException if the given capability is not supported.
  */
  */
    public void checkCapability ( int i ) throws InvalidFirmwareException, CapabilityException {
    public void checkCapability ( int i ) throws InvalidFirmwareException, CapabilityException {
        checkCapability(i/8, i%8);
        checkCapability(i/8, i%8);
    }
    }
 
 
// ******* InterfaceCapabilities ***********************************************
// ******* InterfaceCapabilities ***********************************************
/**
/**
  * Returns interface capability bit.
  * Returns interface capability bit.
  * @return interface capability bit.
  * @return interface capability bit.
  * @param i capability index (0..47)
  * @param i capability index (0..47)
  */
  */
    public boolean InterfaceCapabilities ( int i ) {
    public boolean InterfaceCapabilities ( int i ) {
        return dev().interfaceCapabilities(i/8, i%8);
        return dev().interfaceCapabilities(i/8, i%8);
    }
    }
 
 
// ******* checkCompatible *****************************************************
// ******* checkCompatible *****************************************************
/**
/**
  * Checks whether the given product ID is compatible to the device corresponding to this class and whether interface 1 is supported.
  * Checks whether the given product ID is compatible to the device corresponding to this class and whether interface 1 is supported.
  * See {@link #compatible(int,int,int,int)}.
  * See {@link #compatible(int,int,int,int)}.
  * @param productId0 Byte 0 of the given product ID
  * @param productId0 Byte 0 of the given product ID
  * @param productId1 Byte 1 of the given product ID
  * @param productId1 Byte 1 of the given product ID
  * @param productId2 Byte 2 of the given product ID
  * @param productId2 Byte 2 of the given product ID
  * @param productId3 Byte 3 of the given product ID
  * @param productId3 Byte 3 of the given product ID
  * @throws InvalidFirmwareException if the given product ID is not compatible or interface 1 is not supported.
  * @throws InvalidFirmwareException if the given product ID is not compatible or interface 1 is not supported.
  */
  */
    public void checkCompatible ( int productId0, int productId1, int productId2, int productId3 ) throws InvalidFirmwareException {
    public void checkCompatible ( int productId0, int productId1, int productId2, int productId3 ) throws InvalidFirmwareException {
        checkValid();
        checkValid();
        if ( ! dev().compatible ( productId0, productId1, productId2, productId3 ) )
        if ( ! dev().compatible ( productId0, productId1, productId2, productId3 ) )
            throw new InvalidFirmwareException(this, "Incompatible Product ID");
            throw new InvalidFirmwareException(this, "Incompatible Product ID");
    }
    }
 
 
// ******* getFpgaState ********************************************************
// ******* getFpgaState ********************************************************
    private void getFpgaState () throws UsbException, InvalidFirmwareException, CapabilityException {
    private void getFpgaState () throws UsbException, InvalidFirmwareException, CapabilityException {
        byte[] buffer = new byte[9];
        byte[] buffer = new byte[9];
        checkCapability(CAPABILITY_FPGA);
        checkCapability(CAPABILITY_FPGA);
        vendorRequest2(0x30, "getFpgaState", buffer, 9);
        vendorRequest2(0x30, "getFpgaState", buffer, 9);
        fpgaConfigured = buffer[0] == 0;
        fpgaConfigured = buffer[0] == 0;
        fpgaChecksum = buffer[1] & 0xff;
        fpgaChecksum = buffer[1] & 0xff;
        fpgaBytes = ((buffer[5] & 0xff)<<24) | ((buffer[4] & 0xff)<<16) | ((buffer[3] & 0xff)<<8) | (buffer[2] & 0xff);
        fpgaBytes = ((buffer[5] & 0xff)<<24) | ((buffer[4] & 0xff)<<16) | ((buffer[3] & 0xff)<<8) | (buffer[2] & 0xff);
        fpgaInitB = buffer[6] & 0xff;
        fpgaInitB = buffer[6] & 0xff;
        fpgaFlashResult = buffer[7];
        fpgaFlashResult = buffer[7];
        fpgaFlashBitSwap = buffer[8] != 0;
        fpgaFlashBitSwap = buffer[8] != 0;
    }
    }
 
 
// ******* printFpgaState ******************************************************
// ******* printFpgaState ******************************************************
/**
/**
  * Prints out the FPGA state.
  * Prints out the FPGA state.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if FPGA configuration is not supported by the firmware.
  * @throws CapabilityException if FPGA configuration is not supported by the firmware.
  */
  */
    public void printFpgaState () throws UsbException, InvalidFirmwareException, CapabilityException {
    public void printFpgaState () throws UsbException, InvalidFirmwareException, CapabilityException {
 
 
        final String flashResultStr[] = {
        final String flashResultStr[] = {
         "Configuration successful",
         "Configuration successful",
         "FPGA already configured",
         "FPGA already configured",
         "Flash error",
         "Flash error",
         "No bitstream found",
         "No bitstream found",
         "Configuration error"
         "Configuration error"
        };
        };
 
 
        getFpgaState();
        getFpgaState();
        System.out.println( "size=" + fpgaBytes + ";  checksum=" + fpgaChecksum + "; INIT_B_HIST=" + fpgaInitB +"; flash_configuration_result=" + fpgaFlashResult +
        System.out.println( "size=" + fpgaBytes + ";  checksum=" + fpgaChecksum + "; INIT_B_HIST=" + fpgaInitB +"; flash_configuration_result=" + fpgaFlashResult +
          (fpgaFlashResult>=0 && fpgaFlashResult<flashResultStr.length ? " ("+flashResultStr[fpgaFlashResult]+")" : "" )
          (fpgaFlashResult>=0 && fpgaFlashResult<flashResultStr.length ? " ("+flashResultStr[fpgaFlashResult]+")" : "" )
        );
        );
    }
    }
 
 
// ******* getFpgaConfiguration ************************************************
// ******* getFpgaConfiguration ************************************************
/**
/**
  * Returns true if the FPGA is configured.
  * Returns true if the FPGA is configured.
  * @return true if the FPGA is configured.
  * @return true if the FPGA is configured.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if FPGA configuration is not supported by the firmware.
  * @throws CapabilityException if FPGA configuration is not supported by the firmware.
  */
  */
    public boolean getFpgaConfiguration () throws UsbException, InvalidFirmwareException, CapabilityException {
    public boolean getFpgaConfiguration () throws UsbException, InvalidFirmwareException, CapabilityException {
        getFpgaState ();
        getFpgaState ();
        return fpgaConfigured;
        return fpgaConfigured;
    }
    }
 
 
// ******* getFpgaConfigurationStr *********************************************
// ******* getFpgaConfigurationStr *********************************************
/**
/**
  * Returns a string that indicates the FPGA configuration status.
  * Returns a string that indicates the FPGA configuration status.
  * @return a string that indicates the FPGA configuration status.
  * @return a string that indicates the FPGA configuration status.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if FPGA configuration is not supported by the firmware.
  * @throws CapabilityException if FPGA configuration is not supported by the firmware.
  */
  */
    public String getFpgaConfigurationStr () throws UsbException, InvalidFirmwareException, CapabilityException {
    public String getFpgaConfigurationStr () throws UsbException, InvalidFirmwareException, CapabilityException {
        getFpgaState ();
        getFpgaState ();
        return fpgaConfigured ? "FPGA configured" : "FPGA unconfigured";
        return fpgaConfigured ? "FPGA configured" : "FPGA unconfigured";
    }
    }
 
 
// ******* resetFGPA ***********************************************************
// ******* resetFGPA ***********************************************************
/**
/**
  * Resets the FPGA.
  * Resets the FPGA.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if FPGA configuration is not supported by the firmware.
  * @throws CapabilityException if FPGA configuration is not supported by the firmware.
  */
  */
    public void resetFpga () throws UsbException, InvalidFirmwareException, CapabilityException {
    public void resetFpga () throws UsbException, InvalidFirmwareException, CapabilityException {
        checkCapability(CAPABILITY_FPGA);
        checkCapability(CAPABILITY_FPGA);
        vendorCommand(0x31, "resetFpga" );
        vendorCommand(0x31, "resetFpga" );
    }
    }
 
 
 
 
// ******* detectBitstreamBitOrder *********************************************
// ******* detectBitstreamBitOrder *********************************************
    private int detectBitstreamBitOrder ( byte[] buf ) {
    private int detectBitstreamBitOrder ( byte[] buf ) {
        for ( int i=0; i<buf.length-3; i++ ) {
        for ( int i=0; i<buf.length-3; i++ ) {
            if ( ((buf[i] & 255)==0xaa) && ((buf[i+1] & 255)==0x99) && ((buf[i+2] & 255)==0x55) && ((buf[i+3] & 255)==0x66) )
            if ( ((buf[i] & 255)==0xaa) && ((buf[i+1] & 255)==0x99) && ((buf[i+2] & 255)==0x55) && ((buf[i+3] & 255)==0x66) )
                return 1;
                return 1;
            if ( ((buf[i] & 255)==0x55) && ((buf[i+1] & 255)==0x99) && ((buf[i+2] & 255)==0xaa) && ((buf[i+3] & 255)==0x66) )
            if ( ((buf[i] & 255)==0x55) && ((buf[i+1] & 255)==0x99) && ((buf[i+2] & 255)==0xaa) && ((buf[i+3] & 255)==0x66) )
                return 0;
                return 0;
        }
        }
        System.err.println("Warning: Unable to determine bitstream bit order: no signature found");
        System.err.println("Warning: Unable to determine bitstream bit order: no signature found");
        return 0;
        return 0;
    }
    }
 
 
 
// ******* detectBitstreamStart ************************************************
 
    private int detectBitstreamStart ( byte[] buf ) {
 
        int l=0;
 
        for ( int i=0; i<buf.length-3; i++ ) {
 
            if ( (l>=4) && ((buf[i+1] & 255)==0x99) && ((buf[i+3] & 255)==0x66) ) {
 
                if ( ((buf[i] & 255)==0xaa) && ((buf[i+2] & 255)==0x55) )
 
                    return i-l;
 
                if ( ((buf[i] & 255)==0x55) && ((buf[i+2] & 255)==0xaa) )
 
                    return i-l;
 
            }
 
            l = buf[i]==-1 ? l+1 : 0;
 
        }
 
        System.err.println("Warning: Unable to determine start of raw bitstream");
 
        return 0;
 
    }
 
 
// ******* swapBits ************************************************************
// ******* swapBits ************************************************************
    private void swapBits ( byte[][] buf, int size ) {
    private void swapBits ( byte[][] buf, int size ) {
        int j=0, k=0;
        int j=0, k=0;
        for (int i=0; i<size; i++ ) {
        for (int i=0; i<size; i++ ) {
            while ( k >= buf[j].length ) {
            while ( k >= buf[j].length ) {
                j++;
                j++;
                k=0;
                k=0;
            }
            }
            byte b = buf[j][k];
            byte b = buf[j][k];
            buf[j][k] = (byte) ( ((b & 128) >> 7) |
            buf[j][k] = (byte) ( ((b & 128) >> 7) |
                                 ((b &  64) >> 5) |
                                 ((b &  64) >> 5) |
                                 ((b &  32) >> 3) |
                                 ((b &  32) >> 3) |
                                 ((b &  16) >> 1) |
                                 ((b &  16) >> 1) |
                                 ((b &   8) << 1) |
                                 ((b &   8) << 1) |
                                 ((b &   4) << 3) |
                                 ((b &   4) << 3) |
                                 ((b &   2) << 5) |
                                 ((b &   2) << 5) |
                                 ((b &   1) << 7) );
                                 ((b &   1) << 7) );
            k++;
            k++;
        }
        }
    }
    }
 
 
// ******* configureFpgaLS *****************************************************
// ******* configureFpgaLS *****************************************************
//  returns configuration time in ms
//  returns configuration time in ms
/**
/**
  * Upload a Bitstream to the FPGA using low speed mode.
  * Upload a Bitstream to the FPGA using low speed mode.
  * @param inputStream for reading the Bitstream.
  * @param inputStream for reading the Bitstream.
  * @param force If set to true existing configurations will be overwritten. (By default an {@link AlreadyConfiguredException} is thrown).
  * @param force If set to true existing configurations will be overwritten. (By default an {@link AlreadyConfiguredException} is thrown).
  * @param bs 0: disable bit swapping, 1: enable bit swapping, all other values: automatic detection of bit order.
  * @param bs 0: disable bit swapping, 1: enable bit swapping, all other values: automatic detection of bit order.
  * @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
  * @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
  * @throws BitstreamUploadException if an error occurred while attempting to upload the Bitstream.
  * @throws BitstreamUploadException if an error occurred while attempting to upload the Bitstream.
  * @throws AlreadyConfiguredException if the FPGA is already configured.
  * @throws AlreadyConfiguredException if the FPGA is already configured.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if FPGA configuration is not supported by the firmware.
  * @throws CapabilityException if FPGA configuration is not supported by the firmware.
  */
  */
    public long configureFpgaLS ( InputStream inputStream, boolean force, int bs ) throws BitstreamReadException, UsbException, BitstreamUploadException, AlreadyConfiguredException, InvalidFirmwareException, CapabilityException {
    public long configureFpgaLS ( InputStream inputStream, boolean force, int bs ) throws BitstreamReadException, UsbException, BitstreamUploadException, AlreadyConfiguredException, InvalidFirmwareException, CapabilityException {
        final int transactionBytes = certainWorkarounds ? 256 : 2048;
        final int transactionBytes = certainWorkarounds ? 256 : 2048;
        long t0 = 0;
        long t0 = 0;
 
 
        checkCapability(CAPABILITY_FPGA);
        checkCapability(CAPABILITY_FPGA);
 
 
        if ( !force && getFpgaConfiguration() )
        if ( !force && getFpgaConfiguration() )
            throw new AlreadyConfiguredException();
            throw new AlreadyConfiguredException();
 
 
// read the Bitstream file      
// read the Bitstream file      
        byte[][] buffer = new byte[16*1024*1024/transactionBytes][];
        byte[][] buffer = new byte[16*1024*1024/transactionBytes][];
        int size = 0;
        int size = 0;
        try {
        try {
            int j = transactionBytes;
            int j = transactionBytes;
            for ( int i=0; i<buffer.length && j==transactionBytes; i++ ) {
            for ( int i=0; i<buffer.length && j==transactionBytes; i++ ) {
                buffer[i] = new byte[transactionBytes];
                buffer[i] = new byte[transactionBytes];
                int k;
                int k;
                j = 0;
                j = 0;
                do {
                do {
                    k = inputStream.read( buffer[i], j, transactionBytes-j );
                    k = inputStream.read( buffer[i], j, transactionBytes-j );
                    if ( k < 0 )
                    if ( k < 0 )
                        k = 0;
                        k = 0;
                    j += k;
                    j += k;
                }
                }
                while ( j<transactionBytes && k>0 );
                while ( j<transactionBytes && k>0 );
 
 
                if ( j < transactionBytes && j % 64 == 0 )       // ensures size % 64 != 0
                if ( j < transactionBytes && j % 64 == 0 )       // ensures size % 64 != 0
                    j+=1;
                    j+=1;
                size += j;
                size += j;
            }
            }
 
 
            try {
            try {
                inputStream.close();
                inputStream.close();
            }
            }
            catch ( Exception e ) {
            catch ( Exception e ) {
            }
            }
        }
        }
        catch (IOException e) {
        catch (IOException e) {
            throw new BitstreamReadException(e.getLocalizedMessage());
            throw new BitstreamReadException(e.getLocalizedMessage());
        }
        }
        if ( size < 64 || size % 64 == 0 )
        if ( size < 64 || size % 64 == 0 )
            throw new BitstreamReadException("Invalid file size: " + size );
            throw new BitstreamReadException("Invalid file size: " + size );
 
 
// detect bitstream bit order and swap bits if necessary 
// detect bitstream bit order and swap bits if necessary 
        if ( bs<0 || bs>1 )
        if ( bs<0 || bs>1 )
            bs = detectBitstreamBitOrder ( buffer[0] );
            bs = detectBitstreamBitOrder ( buffer[0] );
        if ( bs == 1 )
        if ( bs == 1 )
            swapBits(buffer,size);
            swapBits(buffer,size);
 
 
// upload the Bitstream file    
// upload the Bitstream file    
        for ( int tries=10; tries>0; tries-- ) {
        for ( int tries=10; tries>0; tries-- ) {
 
 
            resetFpga();
            resetFpga();
 
 
            try {
            try {
                t0 = -new Date().getTime();
                t0 = -new Date().getTime();
                int cs = 0;
                int cs = 0;
                bs = 0;
                bs = 0;
 
 
                for ( int i=0; i<buffer.length && i*transactionBytes < size; i++ ) {
                for ( int i=0; i<buffer.length && i*transactionBytes < size; i++ ) {
                    int j = size-i*transactionBytes;
                    int j = size-i*transactionBytes;
                    if (j>transactionBytes)
                    if (j>transactionBytes)
                        j = transactionBytes;
                        j = transactionBytes;
                    vendorCommand2(0x32, "sendFpgaData", 0,0, buffer[i], j);
                    vendorCommand2(0x32, "sendFpgaData", 0,0, buffer[i], j);
 
 
                    bs+=j;
                    bs+=j;
                    for ( int k=0; k<buffer[i].length; k++ )
                    for ( int k=0; k<buffer[i].length; k++ )
                        cs = ( cs + (buffer[i][k] & 0xff) ) & 0xff;
                        cs = ( cs + (buffer[i][k] & 0xff) ) & 0xff;
                }
                }
 
 
                getFpgaState();
                getFpgaState();
//              System.err.println("fpgaConfigred=" + fpgaConfigured + "   fpgaBytes="+fpgaBytes + " ("+bs+")   fpgaChecksum="+fpgaChecksum + " ("+cs+")   fpgaInitB="+fpgaInitB );
//              System.err.println("fpgaConfigred=" + fpgaConfigured + "   fpgaBytes="+fpgaBytes + " ("+bs+")   fpgaChecksum="+fpgaChecksum + " ("+cs+")   fpgaInitB="+fpgaInitB );
                if ( ! fpgaConfigured ) {
                if ( ! fpgaConfigured ) {
                    throw new BitstreamUploadException( "FPGA configuration failed: DONE pin does not go high (size=" + fpgaBytes + " ,  " + (bs - fpgaBytes) + " bytes got lost;  checksum="
                    throw new BitstreamUploadException( "FPGA configuration failed: DONE pin does not go high (size=" + fpgaBytes + " ,  " + (bs - fpgaBytes) + " bytes got lost;  checksum="
                        + fpgaChecksum + " , should be " + cs + ";  INIT_B_HIST=" + fpgaInitB +")" );
                        + fpgaChecksum + " , should be " + cs + ";  INIT_B_HIST=" + fpgaInitB +")" );
                }
                }
                if ( enableExtraFpgaConfigurationChecks ) {
                if ( enableExtraFpgaConfigurationChecks ) {
                    if ( fpgaBytes!=0 && fpgaBytes!=bs )
                    if ( fpgaBytes!=0 && fpgaBytes!=bs )
                        System.err.println("Warning: Possible FPGA configuration data loss: " + (bs - fpgaBytes) + " bytes got lost");
                        System.err.println("Warning: Possible FPGA configuration data loss: " + (bs - fpgaBytes) + " bytes got lost");
                    if ( fpgaInitB!=222 )
                    if ( fpgaInitB!=222 )
                        System.err.println("Warning: Possible Bitstream CRC error: INIT_B_HIST=" + fpgaInitB );
                        System.err.println("Warning: Possible Bitstream CRC error: INIT_B_HIST=" + fpgaInitB );
                }
                }
//              System.out.println( "FPGA configuration: size=" + fpgaBytes + " ,  " + (bs - fpgaBytes) + " bytes got lost;  checksum=" + fpgaChecksum + " , should be " + cs + ";  INIT_B_HIST=" + fpgaInitB );
//              System.out.println( "FPGA configuration: size=" + fpgaBytes + " ,  " + (bs - fpgaBytes) + " bytes got lost;  checksum=" + fpgaChecksum + " , should be " + cs + ";  INIT_B_HIST=" + fpgaInitB );
 
 
                tries = 0;
                tries = 0;
                t0 += new Date().getTime();
                t0 += new Date().getTime();
 
 
            }
            }
            catch ( BitstreamUploadException e ) {
            catch ( BitstreamUploadException e ) {
                if ( tries>1 )
                if ( tries>1 )
                    System.err.println("Warning: " + e.getLocalizedMessage() +": Retrying it ...");
                    System.err.println("Warning: " + e.getLocalizedMessage() +": Retrying it ...");
                else
                else
                    throw e;
                    throw e;
            }
            }
        }
        }
 
 
        try {
        try {
            Thread.sleep( 100 );
            Thread.sleep( 100 );
        }
        }
        catch ( InterruptedException e) {
        catch ( InterruptedException e) {
        }
        }
 
 
        return t0;
        return t0;
    }
    }
 
 
 
 
/**
/**
  * Upload a Bitstream to the FPGA using low speed mode.
  * Upload a Bitstream to the FPGA using low speed mode.
  * @param fwFileName The file name of the Bitstream. The file can be a regular file or a system resource (e.g. a file from the current jar archive).
  * @param fwFileName The file name of the Bitstream. The file can be a regular file or a system resource (e.g. a file from the current jar archive).
  * @param force If set to true existing configurations will be overwritten. (By default an {@link AlreadyConfiguredException} is thrown).
  * @param force If set to true existing configurations will be overwritten. (By default an {@link AlreadyConfiguredException} is thrown).
  * @param bs 0: disable bit swapping, 1: enable bit swapping, all other values: automatic detection of bit order.
  * @param bs 0: disable bit swapping, 1: enable bit swapping, all other values: automatic detection of bit order.
  * @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
  * @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
  * @throws BitstreamUploadException if an error occurred while attempting to upload the Bitstream.
  * @throws BitstreamUploadException if an error occurred while attempting to upload the Bitstream.
  * @throws AlreadyConfiguredException if the FPGA is already configured.
  * @throws AlreadyConfiguredException if the FPGA is already configured.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if FPGA configuration is not supported by the firmware.
  * @throws CapabilityException if FPGA configuration is not supported by the firmware.
  */
  */
    public long configureFpgaLS ( String fwFileName, boolean force, int bs ) throws BitstreamReadException, UsbException, BitstreamUploadException, AlreadyConfiguredException, InvalidFirmwareException, CapabilityException {
    public long configureFpgaLS ( String fwFileName, boolean force, int bs ) throws BitstreamReadException, UsbException, BitstreamUploadException, AlreadyConfiguredException, InvalidFirmwareException, CapabilityException {
        try {
        try {
            return configureFpgaLS( JInputStream.getInputStream( fwFileName ), force, bs );
            return configureFpgaLS( JInputStream.getInputStream( fwFileName ), force, bs );
        }
        }
        catch (IOException e) {
        catch (IOException e) {
            throw new BitstreamReadException(e.getLocalizedMessage());
            throw new BitstreamReadException(e.getLocalizedMessage());
        }
        }
    }
    }
 
 
// ******* eepromState *********************************************************
// ******* eepromState *********************************************************
// returns true if EEPROM is ready
// returns true if EEPROM is ready
/**
/**
  * Reads the current EEPROM status.
  * Reads the current EEPROM status.
  * This method also sets the varibles {@link #eepromBytes} and {@link #eepromChecksum}.
  * This method also sets the varibles {@link #eepromBytes} and {@link #eepromChecksum}.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if EEPROM access is not supported by the firmware.
  * @throws CapabilityException if EEPROM access is not supported by the firmware.
  * @return true if EEPROM is ready.
  * @return true if EEPROM is ready.
  */
  */
    public boolean eepromState ( ) throws UsbException, InvalidFirmwareException, CapabilityException {
    public boolean eepromState ( ) throws UsbException, InvalidFirmwareException, CapabilityException {
        byte[] buf = new byte[4];
        byte[] buf = new byte[4];
        checkCapability(CAPABILITY_EEPROM);
        checkCapability(CAPABILITY_EEPROM);
        vendorRequest2(0x3A, "EEPROM State", 0, 0, buf, 4);
        vendorRequest2(0x3A, "EEPROM State", 0, 0, buf, 4);
        eepromBytes = (buf[0] & 255) | (buf[1] & 255)<<8;
        eepromBytes = (buf[0] & 255) | (buf[1] & 255)<<8;
        eepromChecksum = buf[2] & 255;
        eepromChecksum = buf[2] & 255;
        return buf[3] == 0;
        return buf[3] == 0;
    }
    }
 
 
// ******* eepromWrite *********************************************************
// ******* eepromWrite *********************************************************
/**
/**
  * Writes data to the EEPROM.
  * Writes data to the EEPROM.
  * @param addr The destination address of the EEPROM.
  * @param addr The destination address of the EEPROM.
  * @param buf The data.
  * @param buf The data.
  * @param length The amount of bytes to be sent.
  * @param length The amount of bytes to be sent.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if EEPROM access is not supported by the firmware.
  * @throws CapabilityException if EEPROM access is not supported by the firmware.
  */
  */
    public void eepromWrite ( int addr, byte[] buf, int length ) throws UsbException, InvalidFirmwareException, CapabilityException {
    public void eepromWrite ( int addr, byte[] buf, int length ) throws UsbException, InvalidFirmwareException, CapabilityException {
        checkCapability(CAPABILITY_EEPROM);
        checkCapability(CAPABILITY_EEPROM);
        if ( (addr & 63) != 0 ) {
        if ( (addr & 63) != 0 ) {
            int i = Math.min(length, 64-(addr & 63));
            int i = Math.min(length, 64-(addr & 63));
            vendorCommand2( 0x39, "EEPROM Write", addr, 0, buf, i );
            vendorCommand2( 0x39, "EEPROM Write", addr, 0, buf, i );
            try {
            try {
                Thread.sleep( 10 );
                Thread.sleep( 10 );
            }
            }
            catch ( InterruptedException e) {
            catch ( InterruptedException e) {
            }
            }
            addr+=i;
            addr+=i;
            length-=i;
            length-=i;
            if ( length > 0 ) {
            if ( length > 0 ) {
                byte[] buf2 = new byte[length];
                byte[] buf2 = new byte[length];
                for (int j=0; j<length; j++ )
                for (int j=0; j<length; j++ )
                    buf2[j] = buf[i+j];
                    buf2[j] = buf[i+j];
                vendorCommand2( 0x39, "EEPROM Write", addr, 0, buf2, length );
                vendorCommand2( 0x39, "EEPROM Write", addr, 0, buf2, length );
            }
            }
        }
        }
        else {
        else {
            vendorCommand2( 0x39, "EEPROM Write", addr, 0, buf, length );
            vendorCommand2( 0x39, "EEPROM Write", addr, 0, buf, length );
        }
        }
 
 
        try {
        try {
                Thread.sleep( 10 );
                Thread.sleep( 10 );
        }
        }
            catch ( InterruptedException e) {
            catch ( InterruptedException e) {
        }
        }
    }
    }
 
 
// ******* eepromRead **********************************************************
// ******* eepromRead **********************************************************
/**
/**
  * Reads data from the EEPROM.
  * Reads data from the EEPROM.
  * @param addr The source address of the EEPROM.
  * @param addr The source address of the EEPROM.
  * @param buf A buffer for the storage of the data.
  * @param buf A buffer for the storage of the data.
  * @param length The amount of bytes to be read.
  * @param length The amount of bytes to be read.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if EEPROM access is not supported by the firmware.
  * @throws CapabilityException if EEPROM access is not supported by the firmware.
  */
  */
    public void eepromRead ( int addr, byte[] buf, int length ) throws UsbException, InvalidFirmwareException, CapabilityException {
    public void eepromRead ( int addr, byte[] buf, int length ) throws UsbException, InvalidFirmwareException, CapabilityException {
        checkCapability(CAPABILITY_EEPROM);
        checkCapability(CAPABILITY_EEPROM);
        vendorRequest2( 0x38, "EEPROM Read", addr, 0, buf, length );             // sometimes a little bit slow
        vendorRequest2( 0x38, "EEPROM Read", addr, 0, buf, length );             // sometimes a little bit slow
        try {
        try {
            Thread.sleep( 10 );
            Thread.sleep( 10 );
        }
        }
        catch ( InterruptedException e) {
        catch ( InterruptedException e) {
        }
        }
    }
    }
 
 
// ******* eepromUpload ********************************************************
// ******* eepromUpload ********************************************************
//  returns upload time in ms
//  returns upload time in ms
/**
/**
  * Upload the firmware to the EEPROM.
  * Upload the firmware to the EEPROM.
  * In order to start the uploaded firmware the device must be reset.
  * In order to start the uploaded firmware the device must be reset.
  * @param ihxFile The firmware image.
  * @param ihxFile The firmware image.
  * @param force Skips the compatibility check if true.
  * @param force Skips the compatibility check if true.
  * @throws IncompatibleFirmwareException if the given firmware is not compatible to the installed one, see {@link #compatible(int,int,int,int)} (Upload can be enforced using the <tt>force</tt> parameter.)
  * @throws IncompatibleFirmwareException if the given firmware is not compatible to the installed one, see {@link #compatible(int,int,int,int)} (Upload can be enforced using the <tt>force</tt> parameter.)
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws CapabilityException if EEPROM access is not supported by the firmware.
  * @throws CapabilityException if EEPROM access is not supported by the firmware.
  * @throws FirmwareUploadException if an error occurred while attempting to upload the firmware.
  * @throws FirmwareUploadException if an error occurred while attempting to upload the firmware.
  */
  */
    public long eepromUpload ( ZtexIhxFile1 ihxFile, boolean force ) throws IncompatibleFirmwareException, FirmwareUploadException, InvalidFirmwareException, CapabilityException {
    public long eepromUpload ( ZtexIhxFile1 ihxFile, boolean force ) throws IncompatibleFirmwareException, FirmwareUploadException, InvalidFirmwareException, CapabilityException {
        final int pagesMax = 256;
        final int pagesMax = 256;
        final int pageSize = 256;
        final int pageSize = 256;
        int pages = 0;
        int pages = 0;
        byte[][] buffer = new byte[pagesMax][];
        byte[][] buffer = new byte[pagesMax][];
 
 
        checkCapability(CAPABILITY_EEPROM);
        checkCapability(CAPABILITY_EEPROM);
 
 
//      ihxFile.dataInfo(System.out);
//      ihxFile.dataInfo(System.out);
//      System.out.println(ihxFile);
//      System.out.println(ihxFile);
 
 
// check for compatibility
// check for compatibility
        if ( ! force && dev().valid() ) {
        if ( ! force && dev().valid() ) {
            if ( ihxFile.interfaceVersion() != 1 )
            if ( ihxFile.interfaceVersion() != 1 )
                throw new IncompatibleFirmwareException("Wrong interface version: Expected 1, got " + ihxFile.interfaceVersion() );
                throw new IncompatibleFirmwareException("Wrong interface version: Expected 1, got " + ihxFile.interfaceVersion() );
 
 
            if ( ! dev().compatible ( ihxFile.productId(0), ihxFile.productId(1), ihxFile.productId(2), ihxFile.productId(3) ) )
            if ( ! dev().compatible ( ihxFile.productId(0), ihxFile.productId(1), ihxFile.productId(2), ihxFile.productId(3) ) )
                throw new IncompatibleFirmwareException("Incompatible productId's: Current firmware: " + ZtexDevice1.byteArrayString(dev().productId())
                throw new IncompatibleFirmwareException("Incompatible productId's: Current firmware: " + ZtexDevice1.byteArrayString(dev().productId())
                    + "  Ihx File: " + ZtexDevice1.byteArrayString(ihxFile.productId()) );
                    + "  Ihx File: " + ZtexDevice1.byteArrayString(ihxFile.productId()) );
        }
        }
 
 
        Usb_Device_Descriptor dd = dev().dev().getDescriptor();
        Usb_Device_Descriptor dd = dev().dev().getDescriptor();
        int vid = dd.getIdVendor() & 65535;
        int vid = dd.getIdVendor() & 65535;
        int pid = dd.getIdProduct() & 65535;
        int pid = dd.getIdProduct() & 65535;
 
 
        buffer[0] = new byte[pageSize];
        buffer[0] = new byte[pageSize];
        buffer[0][0] = (byte) 0xc2;
        buffer[0][0] = (byte) 0xc2;
        buffer[0][1] = (byte) (vid & 255);
        buffer[0][1] = (byte) (vid & 255);
        buffer[0][2] = (byte) ((vid >> 8) & 255);
        buffer[0][2] = (byte) ((vid >> 8) & 255);
        buffer[0][3] = (byte) (pid & 255);
        buffer[0][3] = (byte) (pid & 255);
        buffer[0][4] = (byte) ((pid >> 8) & 255);
        buffer[0][4] = (byte) ((pid >> 8) & 255);
        buffer[0][5] = 0;
        buffer[0][5] = 0;
        buffer[0][6] = 0;
        buffer[0][6] = 0;
        buffer[0][7] = 0;
        buffer[0][7] = 0;
 
 
        int ptr = 8, i = 0;
        int ptr = 8, i = 0;
 
 
        while ( i < ihxFile.ihxData.length ) {
        while ( i < ihxFile.ihxData.length ) {
            if ( ihxFile.ihxData[i]>=0 && ihxFile.ihxData[i]<256 ) {                     // new data block
            if ( ihxFile.ihxData[i]>=0 && ihxFile.ihxData[i]<256 ) {                     // new data block
                int j = 1;
                int j = 1;
                while ( i+j<ihxFile.ihxData.length && ihxFile.ihxData[i+j]>=0 && ihxFile.ihxData[i+j]<256 )
                while ( i+j<ihxFile.ihxData.length && ihxFile.ihxData[i+j]>=0 && ihxFile.ihxData[i+j]<256 )
                    j++;
                    j++;
 
 
                for (int k=ptr/pageSize + 1; k < (ptr+j+9)/pageSize + 1; k++ )  // also considers 5 bytes for the last data block
                for (int k=ptr/pageSize + 1; k < (ptr+j+9)/pageSize + 1; k++ )  // also considers 5 bytes for the last data block
                    buffer[k] = new byte[pageSize];
                    buffer[k] = new byte[pageSize];
 
 
                buffer[(ptr+0)/pageSize][(ptr+0) % pageSize] = (byte) ((j >> 8) & 255);
                buffer[(ptr+0)/pageSize][(ptr+0) % pageSize] = (byte) ((j >> 8) & 255);
                buffer[(ptr+1)/pageSize][(ptr+1) % pageSize] = (byte) (j & 255);                // length
                buffer[(ptr+1)/pageSize][(ptr+1) % pageSize] = (byte) (j & 255);                // length
                buffer[(ptr+2)/pageSize][(ptr+2) % pageSize] = (byte) ((i >> 8) & 255);
                buffer[(ptr+2)/pageSize][(ptr+2) % pageSize] = (byte) ((i >> 8) & 255);
                buffer[(ptr+3)/pageSize][(ptr+3) % pageSize] = (byte) (i & 255);                // address
                buffer[(ptr+3)/pageSize][(ptr+3) % pageSize] = (byte) (i & 255);                // address
                ptr+=4;
                ptr+=4;
                for ( int k=0; k<j; k++ )                                        // data
                for ( int k=0; k<j; k++ )                                        // data
                    buffer[(ptr+k)/pageSize][(ptr+k) % pageSize] = (byte) ihxFile.ihxData[i+k];
                    buffer[(ptr+k)/pageSize][(ptr+k) % pageSize] = (byte) ihxFile.ihxData[i+k];
                ptr+=j;
                ptr+=j;
                i+=j;
                i+=j;
            }
            }
            else {
            else {
                i+=1;
                i+=1;
            }
            }
        }
        }
 
 
        buffer[(ptr+0)/pageSize][(ptr+0) % pageSize] = (byte) 0x80;               // last data block
        buffer[(ptr+0)/pageSize][(ptr+0) % pageSize] = (byte) 0x80;               // last data block
        buffer[(ptr+1)/pageSize][(ptr+1) % pageSize] = (byte) 0x01;
        buffer[(ptr+1)/pageSize][(ptr+1) % pageSize] = (byte) 0x01;
        buffer[(ptr+2)/pageSize][(ptr+2) % pageSize] = (byte) 0xe6;
        buffer[(ptr+2)/pageSize][(ptr+2) % pageSize] = (byte) 0xe6;
        buffer[(ptr+3)/pageSize][(ptr+3) % pageSize] = (byte) 0x00;
        buffer[(ptr+3)/pageSize][(ptr+3) % pageSize] = (byte) 0x00;
        buffer[(ptr+3)/pageSize][(ptr+4) % pageSize] = (byte) 0x00;
        buffer[(ptr+3)/pageSize][(ptr+4) % pageSize] = (byte) 0x00;
        ptr+=5;
        ptr+=5;
 
 
 
 
        long t0 = new Date().getTime();
        long t0 = new Date().getTime();
        byte[] rbuf = new byte[pageSize];
        byte[] rbuf = new byte[pageSize];
 
 
        for ( i=(ptr-1)/pageSize; i>=0; i-- ) {
        for ( i=(ptr-1)/pageSize; i>=0; i-- ) {
 
 
            int k = (i+1)*pageSize < ptr ? pageSize : ptr-i*pageSize;
            int k = (i+1)*pageSize < ptr ? pageSize : ptr-i*pageSize;
            int cs = 0;
            int cs = 0;
            for (int j=0; j<k; j++ ) {
            for (int j=0; j<k; j++ ) {
                cs = ( cs + (buffer[i][j] & 255) ) & 255;
                cs = ( cs + (buffer[i][j] & 255) ) & 255;
            }
            }
 
 
            for ( int tries=3; tries>0; tries-- ) {
            for ( int tries=3; tries>0; tries-- ) {
                try {
                try {
                    eepromWrite(i*pageSize, buffer[i], k);
                    eepromWrite(i*pageSize, buffer[i], k);
                    eepromState();
                    eepromState();
                    if ( eepromBytes!=k )
                    if ( eepromBytes!=k )
                        throw new FirmwareUploadException("Error writing data to EEPROM: Wrote " + eepromBytes + " bytes instead of "  + k + " bytes" );
                        throw new FirmwareUploadException("Error writing data to EEPROM: Wrote " + eepromBytes + " bytes instead of "  + k + " bytes" );
                    if ( eepromChecksum!=cs )
                    if ( eepromChecksum!=cs )
                        throw new FirmwareUploadException("Error writing data to EEPROM: Checksum error");
                        throw new FirmwareUploadException("Error writing data to EEPROM: Checksum error");
 
 
                    eepromRead(i*pageSize, rbuf, k);
                    eepromRead(i*pageSize, rbuf, k);
                    for (int j=0; j<k; j++ ) {
                    for (int j=0; j<k; j++ ) {
                        if ( rbuf[j] != buffer[i][j] )
                        if ( rbuf[j] != buffer[i][j] )
                            throw new FirmwareUploadException("Error writing data to EEPROM: Verification failed");
                            throw new FirmwareUploadException("Error writing data to EEPROM: Verification failed");
                    }
                    }
                    tries = 0;
                    tries = 0;
                }
                }
                catch ( Exception e ) {
                catch ( Exception e ) {
                    if ( tries > 1 ) {
                    if ( tries > 1 ) {
                        System.err.println("Warning: " + e.getLocalizedMessage() +": Retrying it ...");
                        System.err.println("Warning: " + e.getLocalizedMessage() +": Retrying it ...");
                    }
                    }
                    else {
                    else {
                        throw new FirmwareUploadException(e.getLocalizedMessage());
                        throw new FirmwareUploadException(e.getLocalizedMessage());
                    }
                    }
                }
                }
            }
            }
        }
        }
 
 
        return new Date().getTime() - t0;
        return new Date().getTime() - t0;
    }
    }
 
 
//  returns upload time in ms
//  returns upload time in ms
/**
/**
  * Upload the firmware to the EEPROM.
  * Upload the firmware to the EEPROM.
  * In order to start the uploaded firmware the device must be reset.
  * In order to start the uploaded firmware the device must be reset.
  * @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 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 Skips the compatibility check if true.
  * @param force Skips the compatibility check if true.
  * @throws IncompatibleFirmwareException if the given firmware is not compatible to the installed one, see {@link #compatible(int,int,int,int)} (Upload can be enforced using the <tt>force</tt> parameter.)
  * @throws IncompatibleFirmwareException if the given firmware is not compatible to the installed one, see {@link #compatible(int,int,int,int)} (Upload can be enforced using the <tt>force</tt> parameter.)
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws CapabilityException if EEPROM access is not supported by the firmware.
  * @throws CapabilityException if EEPROM access is not supported by the firmware.
  * @throws FirmwareUploadException if an error occurred while attempting to upload the firmware.
  * @throws FirmwareUploadException if an error occurred while attempting to upload the firmware.
  */
  */
    public long eepromUpload ( String ihxFileName, boolean force ) throws IncompatibleFirmwareException, FirmwareUploadException, InvalidFirmwareException, CapabilityException {
    public long eepromUpload ( String ihxFileName, boolean force ) throws IncompatibleFirmwareException, FirmwareUploadException, InvalidFirmwareException, CapabilityException {
        checkCapability(CAPABILITY_EEPROM);
        checkCapability(CAPABILITY_EEPROM);
 
 
// load the ihx file
// load the ihx file
        ZtexIhxFile1 ihxFile;
        ZtexIhxFile1 ihxFile;
        try {
        try {
            ihxFile = new ZtexIhxFile1( ihxFileName );
            ihxFile = new ZtexIhxFile1( ihxFileName );
        }
        }
        catch ( IOException e ) {
        catch ( IOException e ) {
            throw new FirmwareUploadException( e.getLocalizedMessage() );
            throw new FirmwareUploadException( e.getLocalizedMessage() );
        }
        }
        catch ( IhxFileDamagedException e ) {
        catch ( IhxFileDamagedException e ) {
            throw new FirmwareUploadException( e.getLocalizedMessage() );
            throw new FirmwareUploadException( e.getLocalizedMessage() );
        }
        }
 
 
        return eepromUpload( ihxFile, force );
        return eepromUpload( ihxFile, force );
    }
    }
 
 
 
 
// ******* eepromDisable ********************************************************
// ******* eepromDisable ********************************************************
/**
/**
  * Disables the firmware stored in the EEPROM.
  * Disables the firmware stored in the EEPROM.
  * This is achived by writing a "0" to the address 0 of the EEPROM.
  * This is achived by writing a "0" to the address 0 of the EEPROM.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws CapabilityException if EEPROM access is not supported by the firmware.
  * @throws CapabilityException if EEPROM access is not supported by the firmware.
  * @throws FirmwareUploadException if an error occurred while attempting to disable the firmware.
  * @throws FirmwareUploadException if an error occurred while attempting to disable the firmware.
  */
  */
    public void eepromDisable ( ) throws FirmwareUploadException, InvalidFirmwareException, CapabilityException {
    public void eepromDisable ( ) throws FirmwareUploadException, InvalidFirmwareException, CapabilityException {
        byte[] buf = { 0 };
        byte[] buf = { 0 };
 
 
        for ( int tries=3; tries>0; tries-- ) {
        for ( int tries=3; tries>0; tries-- ) {
            try {
            try {
                eepromWrite(0, buf, 1);
                eepromWrite(0, buf, 1);
 
 
                eepromRead(0, buf, 1);
                eepromRead(0, buf, 1);
                if ( buf[0] != 0 )
                if ( buf[0] != 0 )
                    throw new FirmwareUploadException("Error disabling EEPROM firmware: Verification failed");
                    throw new FirmwareUploadException("Error disabling EEPROM firmware: Verification failed");
                tries = 0;
                tries = 0;
 
 
            }
            }
            catch ( Exception e ) {
            catch ( Exception e ) {
                if ( tries > 1 ) {
                if ( tries > 1 ) {
                    System.err.println("Warning: " + e.getLocalizedMessage() +": Retrying it ...");
                    System.err.println("Warning: " + e.getLocalizedMessage() +": Retrying it ...");
                }
                }
                else {
                else {
                    throw new FirmwareUploadException(e.getLocalizedMessage());
                    throw new FirmwareUploadException(e.getLocalizedMessage());
                }
                }
            }
            }
        }
        }
    }
    }
 
 
// ******* flashStrError *******************************************************
// ******* flashStrError *******************************************************
/**
/**
  * Converts a given error code into a String.
  * Converts a given error code into a String.
  * @param errNum The error code.
  * @param errNum The error code.
  * @return an error message.
  * @return an error message.
  */
  */
    public static String flashStrError ( int errNum ) {
    public static String flashStrError ( int errNum ) {
        switch ( errNum ) {
        switch ( errNum ) {
            case FLASH_EC_NO_ERROR:
            case FLASH_EC_NO_ERROR:
                return "USB error: " + LibusbJava.usb_strerror();
                return "USB error: " + LibusbJava.usb_strerror();
            case FLASH_EC_CMD_ERROR:
            case FLASH_EC_CMD_ERROR:
                return "Command error";
                return "Command error";
            case FLASH_EC_TIMEOUT:
            case FLASH_EC_TIMEOUT:
                return "Timeout error";
                return "Timeout error";
            case FLASH_EC_BUSY:
            case FLASH_EC_BUSY:
                return "Busy";
                return "Busy";
            case FLASH_EC_PENDING:
            case FLASH_EC_PENDING:
                return "Another operation is pending";
                return "Another operation is pending";
            case FLASH_EC_READ_ERROR:
            case FLASH_EC_READ_ERROR:
                return "Read error";
                return "Read error";
            case FLASH_EC_WRITE_ERROR:
            case FLASH_EC_WRITE_ERROR:
                return "Write error";
                return "Write error";
            case FLASH_EC_NOTSUPPORTED:
            case FLASH_EC_NOTSUPPORTED:
                return "Not supported";
                return "Not supported";
        }
        }
        return "Error " + errNum;
        return "Error " + errNum;
    }
    }
 
 
/**
/**
  * Gets the last Flash error from the device.
  * Gets the last Flash error from the device.
  * @return an error message.
  * @return an error message.
  */
  */
    public String flashStrError ( ) {
    public String flashStrError ( ) {
        try {
        try {
            return flashStrError( getFlashEC() );
            return flashStrError( getFlashEC() );
        }
        }
        catch ( Exception e ) {
        catch ( Exception e ) {
            return "Unknown error (Error receiving errorcode: "+e.getLocalizedMessage() +")";
            return "Unknown error (Error receiving errorcode: "+e.getLocalizedMessage() +")";
        }
        }
    }
    }
 
 
// ******* flashState **********************************************************
// ******* flashState **********************************************************
/**
/**
  * Reads the the Flash memory status and information.
  * Reads the the Flash memory status and information.
  * This method also sets the variables {@link #flashEnabled()}, {@link #flashSectorSize()} and {@link #flashSectors()}.
  * This method also sets the variables {@link #flashEnabled()}, {@link #flashSectorSize()} and {@link #flashSectors()}.
  * @return true if Flash memory is installed.
  * @return true if Flash memory is installed.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if Flash memory access is not supported by the firmware.
  * @throws CapabilityException if Flash memory access is not supported by the firmware.
  */
  */
    public boolean flashState () throws UsbException, InvalidFirmwareException, CapabilityException {
    public boolean flashState () throws UsbException, InvalidFirmwareException, CapabilityException {
        byte[] buf = new byte[8];
        byte[] buf = new byte[8];
        checkCapability(CAPABILITY_FLASH);
        checkCapability(CAPABILITY_FLASH);
 
 
        // device may be busy due to initialization, we try it up to up to 4s
        // device may be busy due to initialization, we try it up to up to 4s
        vendorRequest2(0x40, "Flash State", 0, 0, buf, 8);
        vendorRequest2(0x40, "Flash State", 0, 0, buf, 8);
        flashEC = buf[7] & 255;
        flashEC = buf[7] & 255;
        int tries=20;
        int tries=20;
        while ( flashEC==FLASH_EC_BUSY && tries>0 )
        while ( flashEC==FLASH_EC_BUSY && tries>0 )
        {
        {
            try {
            try {
                Thread.sleep( 200 );
                Thread.sleep( 200 );
            }
            }
            catch ( InterruptedException e) {
            catch ( InterruptedException e) {
            }
            }
            tries-=1;
            tries-=1;
            vendorRequest2(0x40, "Flash State", 0, 0, buf, 8);
            vendorRequest2(0x40, "Flash State", 0, 0, buf, 8);
            flashEC = buf[7] & 255;
            flashEC = buf[7] & 255;
        }
        }
        flashEnabled = buf[0] & 255;
        flashEnabled = buf[0] & 255;
        flashSectorSize = flashEnabled == 1 ? ((buf[2] & 255) << 8) | (buf[1] & 255) : 0;
        flashSectorSize = flashEnabled == 1 ? ((buf[2] & 255) << 8) | (buf[1] & 255) : 0;
        if ( (flashSectorSize & 0x8000) != 0 )
        if ( (flashSectorSize & 0x8000) != 0 )
            flashSectorSize = 1 << (flashSectorSize & 0x7fff);
            flashSectorSize = 1 << (flashSectorSize & 0x7fff);
        flashSectors = flashEnabled == 1 ? ((buf[6] & 255) << 24) | ((buf[5] & 255) << 16) | ((buf[4] & 255) << 8) | (buf[3] & 255) : 0;
        flashSectors = flashEnabled == 1 ? ((buf[6] & 255) << 24) | ((buf[5] & 255) << 16) | ((buf[4] & 255) << 8) | (buf[3] & 255) : 0;
        return flashEnabled == 1;
        return flashEnabled == 1;
    }
    }
 
 
// ******* getFlashEC **********************************************************
// ******* getFlashEC **********************************************************
// reads the current error code
// reads the current error code
/**
/**
  * Gets the last Flash error from the device.
  * Gets the last Flash error from the device.
  * @return The last error code.
  * @return The last error code.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if Flash memory access is not supported by the firmware.
  * @throws CapabilityException if Flash memory access is not supported by the firmware.
  */
  */
    public int getFlashEC () throws UsbException, InvalidFirmwareException, CapabilityException {
    public int getFlashEC () throws UsbException, InvalidFirmwareException, CapabilityException {
        byte[] buf = new byte[8];
        byte[] buf = new byte[8];
        checkCapability(CAPABILITY_FLASH);
        checkCapability(CAPABILITY_FLASH);
        vendorRequest2(0x40, "Flash State", 0, 0, buf, 8);
        vendorRequest2(0x40, "Flash State", 0, 0, buf, 8);
        flashEC = buf[7] & 255;
        flashEC = buf[7] & 255;
        return flashEC;
        return flashEC;
    }
    }
 
 
 
 
// ******* flashReadSector ****************************************************
// ******* flashReadSector ****************************************************
// read a integer number of sectors
// read a integer number of sectors
/**
/**
  * Reads a integer number of sectors from the Flash.
  * Reads a integer number of sectors from the Flash.
  * @param sector The number of the first sector to be read.
  * @param sector The number of the first sector to be read.
  * @param num The number of sectors to be read.
  * @param num The number of sectors to be read.
  * @param buf A buffer for the storage of the data.
  * @param buf A buffer for the storage of the data.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if Flash memory access is not possible.
  * @throws CapabilityException if Flash memory access is not possible.
  * @throws IndexOutOfBoundsException If the buffer is to small.
  * @throws IndexOutOfBoundsException If the buffer is to small.
  */
  */
    public void flashReadSector ( int sector, int num, byte[] buf ) throws UsbException, InvalidFirmwareException, CapabilityException, IndexOutOfBoundsException  {
    public void flashReadSector ( int sector, int num, byte[] buf ) throws UsbException, InvalidFirmwareException, CapabilityException, IndexOutOfBoundsException  {
        if ( num<1 ) return;
        if ( num<1 ) return;
 
 
        if ( buf.length < flashSectorSize() )
        if ( buf.length < flashSectorSize() )
            throw new IndexOutOfBoundsException( "Buffer is to small: " + buf.length + " < " + (num*flashSectorSize()) );
            throw new IndexOutOfBoundsException( "Buffer is to small: " + buf.length + " < " + (num*flashSectorSize()) );
 
 
        checkCapability(CAPABILITY_FLASH);
        checkCapability(CAPABILITY_FLASH);
        if ( ! flashEnabled() )
        if ( ! flashEnabled() )
            throw new CapabilityException(this, "No Flash memory installed or");
            throw new CapabilityException(this, "No Flash memory installed or");
 
 
        try {
        try {
            if ( flashSectorSize()>2048 ) {
            if ( flashSectorSize()>2048 ) {
                byte[] buf2 = new byte[2048];
                byte[] buf2 = new byte[2048];
                int iz = (flashSectorSize-1) >> 11;
                int iz = (flashSectorSize-1) >> 11;
                for (int sn=0; sn<num; sn++ ) {
                for (int sn=0; sn<num; sn++ ) {
                    for (int i=0; i<iz; i++) {
                    for (int i=0; i<iz; i++) {
//                      System.out.println("r: "+i);
//                      System.out.println("r: "+i);
                        vendorRequest2( 0x41, "Flash Read", sector, i==0 ? 0 : 256, buf2, 2048 );
                        vendorRequest2( 0x41, "Flash Read", sector, i==0 ? 0 : 256, buf2, 2048 );
                        System.arraycopy(buf2,0, buf, sn*flashSectorSize + i*2048, 2048);
                        System.arraycopy(buf2,0, buf, sn*flashSectorSize + i*2048, 2048);
                    }
                    }
                    int len = flashSectorSize-iz*2048;
                    int len = flashSectorSize-iz*2048;
                    vendorRequest2( 0x41, "Flash Read", sector, 512, buf2,  len);
                    vendorRequest2( 0x41, "Flash Read", sector, 512, buf2,  len);
                    System.arraycopy(buf2,0, buf, sn*flashSectorSize + iz*2048, len);
                    System.arraycopy(buf2,0, buf, sn*flashSectorSize + iz*2048, len);
                }
                }
            }
            }
            else {
            else {
                if ( flashSectorSize*num>2048 ) System.err.println("Warning: flashReadSector: Transaction size " + flashSectorSize*num + " may be too large");
                if ( flashSectorSize*num>2048 ) System.err.println("Warning: flashReadSector: Transaction size " + flashSectorSize*num + " may be too large");
                vendorRequest2( 0x41, "Flash Read", sector, sector >> 16, buf, flashSectorSize*num );
                vendorRequest2( 0x41, "Flash Read", sector, sector >> 16, buf, flashSectorSize*num );
            }
            }
        }
        }
        catch ( UsbException e ) {
        catch ( UsbException e ) {
            throw new UsbException( dev().dev(), "Flash Read: " + flashStrError() );
            throw new UsbException( dev().dev(), "Flash Read: " + flashStrError() );
        }
        }
    }
    }
 
 
// read one sector
// read one sector
/**
/**
  * Reads one sector from the Flash.
  * Reads one sector from the Flash.
  * @param sector The sector number to be read.
  * @param sector The sector number to be read.
  * @param buf A buffer for the storage of the data.
  * @param buf A buffer for the storage of the data.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if Flash memory access is not possible.
  * @throws CapabilityException if Flash memory access is not possible.
  * @throws IndexOutOfBoundsException If the buffer is smaller than the Flash sector size.
  * @throws IndexOutOfBoundsException If the buffer is smaller than the Flash sector size.
  */
  */
    public void flashReadSector ( int sector, byte[] buf ) throws UsbException, InvalidFirmwareException, CapabilityException, IndexOutOfBoundsException  {
    public void flashReadSector ( int sector, byte[] buf ) throws UsbException, InvalidFirmwareException, CapabilityException, IndexOutOfBoundsException  {
        flashReadSector ( sector, 1, buf );
        flashReadSector ( sector, 1, buf );
    }
    }
 
 
 
 
// ******* flashWriteSector ***************************************************
// ******* flashWriteSector ***************************************************
// write integer number of sectors
// write integer number of sectors
/**
/**
  * Writes a integer number of sectors to the Flash.
  * Writes a integer number of sectors to the Flash.
  * @param sector The sector number to be written.
  * @param sector The sector number to be written.
  * @param num The number of sectors to be read.
  * @param num The number of sectors to be read.
  * @param buf The data.
  * @param buf The data.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if Flash memory access is not possible.
  * @throws CapabilityException if Flash memory access is not possible.
  * @throws IndexOutOfBoundsException If the buffer is to small.
  * @throws IndexOutOfBoundsException If the buffer is to small.
  */
  */
    public void flashWriteSector ( int sector, int num, byte[] buf ) throws UsbException, InvalidFirmwareException, CapabilityException, IndexOutOfBoundsException {
    public void flashWriteSector ( int sector, int num, byte[] buf ) throws UsbException, InvalidFirmwareException, CapabilityException, IndexOutOfBoundsException {
        if ( num<1 ) return;
        if ( num<1 ) return;
 
 
        if ( buf.length < flashSectorSize()*num )
        if ( buf.length < flashSectorSize()*num )
            throw new IndexOutOfBoundsException( "Buffer to small: " + buf.length + " < " + (num*flashSectorSize()));
            throw new IndexOutOfBoundsException( "Buffer to small: " + buf.length + " < " + (num*flashSectorSize()));
 
 
        checkCapability(CAPABILITY_FLASH);
        checkCapability(CAPABILITY_FLASH);
        if ( ! flashEnabled() )
        if ( ! flashEnabled() )
            throw new CapabilityException(this, "No Flash memory installed or");
            throw new CapabilityException(this, "No Flash memory installed or");
 
 
        try {
        try {
            if ( flashSectorSize()>2048 ) {
            if ( flashSectorSize()>2048 ) {
                byte[] buf2 = new byte[2048];
                byte[] buf2 = new byte[2048];
                int iz = (flashSectorSize-1) >> 11;
                int iz = (flashSectorSize-1) >> 11;
                for (int sn=0; sn<num; sn++ ) {
                for (int sn=0; sn<num; sn++ ) {
 
 
                    int oto = controlMsgTimeout;
                    int oto = controlMsgTimeout;
                    controlMsgTimeout = 12000; // 12s timeout for erase
                    controlMsgTimeout = 12000; // 12s timeout for erase
                    System.arraycopy(buf,sn*flashSectorSize, buf2,0, 2048);
                    System.arraycopy(buf,sn*flashSectorSize, buf2,0, 2048);
                    vendorCommand2( 0x42, "Flash Write", sector, 0, buf, 2048 );
                    vendorCommand2( 0x42, "Flash Write", sector, 0, buf, 2048 );
                    controlMsgTimeout = oto;
                    controlMsgTimeout = oto;
 
 
                    for (int i=1; i<iz; i++) {
                    for (int i=1; i<iz; i++) {
//                      System.out.println("w: "+i);
//                      System.out.println("w: "+i);
                        System.arraycopy(buf,sn*flashSectorSize+i*2048, buf2,0, 2048);
                        System.arraycopy(buf,sn*flashSectorSize+i*2048, buf2,0, 2048);
                        vendorCommand2( 0x42, "Flash Write", sector, 256, buf2, 2048 );
                        vendorCommand2( 0x42, "Flash Write", sector, 256, buf2, 2048 );
                    }
                    }
 
 
                    int len = flashSectorSize-iz*2048;
                    int len = flashSectorSize-iz*2048;
                    System.arraycopy(buf,sn*flashSectorSize+iz*2048, buf2,0, len);
                    System.arraycopy(buf,sn*flashSectorSize+iz*2048, buf2,0, len);
                    vendorCommand2( 0x42, "Flash Write", sector, 512, buf2, len );
                    vendorCommand2( 0x42, "Flash Write", sector, 512, buf2, len );
                }
                }
            }
            }
            else {
            else {
                if ( flashSectorSize*num>2048) System.err.println("Warning: flashWriteSector: Transaction size " + flashSectorSize*num + " may be too large");
                if ( flashSectorSize*num>2048) System.err.println("Warning: flashWriteSector: Transaction size " + flashSectorSize*num + " may be too large");
                vendorCommand2( 0x42, "Flash Write", sector, sector >> 16, buf, flashSectorSize*num );
                vendorCommand2( 0x42, "Flash Write", sector, sector >> 16, buf, flashSectorSize*num );
            }
            }
        }
        }
        catch ( UsbException e ) {
        catch ( UsbException e ) {
            throw new UsbException( dev().dev(), "Flash Write: " + flashStrError() );
            throw new UsbException( dev().dev(), "Flash Write: " + flashStrError() );
        }
        }
    }
    }
 
 
// write one sector
// write one sector
/**
/**
  * Writes one sector to the Flash.
  * Writes one sector to the Flash.
  * @param sector The sector number to be written.
  * @param sector The sector number to be written.
  * @param buf The data.
  * @param buf The data.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if Flash memory access is not possible.
  * @throws CapabilityException if Flash memory access is not possible.
  * @throws IndexOutOfBoundsException If the buffer is smaller than the Flash sector size.
  * @throws IndexOutOfBoundsException If the buffer is smaller than the Flash sector size.
  */
  */
    public void flashWriteSector ( int sector, byte[] buf ) throws UsbException, InvalidFirmwareException, CapabilityException, IndexOutOfBoundsException {
    public void flashWriteSector ( int sector, byte[] buf ) throws UsbException, InvalidFirmwareException, CapabilityException, IndexOutOfBoundsException {
        flashWriteSector(sector,1,buf);
        flashWriteSector(sector,1,buf);
    }
    }
 
 
// ******* flashEnabled ********************************************************
// ******* flashEnabled ********************************************************
// returns enabled / disabled state 
// returns enabled / disabled state 
/**
/**
  * Returns true if Flash memory is installed.
  * Returns true if Flash memory is installed.
  * @return true if Flash memory is installed.
  * @return true if Flash memory is installed.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if Flash memory access is not supported by the firmware.
  * @throws CapabilityException if Flash memory access is not supported by the firmware.
  */
  */
    public boolean flashEnabled () throws UsbException, InvalidFirmwareException, CapabilityException {
    public boolean flashEnabled () throws UsbException, InvalidFirmwareException, CapabilityException {
        if ( flashEnabled < 0 ) // init variable
        if ( flashEnabled < 0 ) // init variable
            flashState();
            flashState();
        return flashEnabled == 1;
        return flashEnabled == 1;
    }
    }
 
 
// ******* flashSectorSize *****************************************************
// ******* flashSectorSize *****************************************************
// returns sector size of Flash memory, if available
// returns sector size of Flash memory, if available
/**
/**
  * Returns the sector size of the Flash memory or 0, if no flash memory is installed.
  * Returns the sector size of the Flash memory or 0, if no flash memory is installed.
  * If required, the sector size is determined form the device first.
  * If required, the sector size is determined form the device first.
  * @return the sector size of the Flash memory.
  * @return the sector size of the Flash memory.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if Flash memory access is not supported by the firmware.
  * @throws CapabilityException if Flash memory access is not supported by the firmware.
  */
  */
    public int flashSectorSize () throws UsbException, InvalidFirmwareException, CapabilityException {
    public int flashSectorSize () throws UsbException, InvalidFirmwareException, CapabilityException {
        if ( flashSectorSize < 0 ) // init variable
        if ( flashSectorSize < 0 ) // init variable
            flashState();
            flashState();
        return flashSectorSize;
        return flashSectorSize;
    }
    }
 
 
// ******* flashSectors ********************************************************
// ******* flashSectors ********************************************************
// returns number of sectors of Flash memory, if available
// returns number of sectors of Flash memory, if available
/**
/**
  * Returns the number of sectors of the Flash memory or 0, if no Flash memory is installed.
  * Returns the number of sectors of the Flash memory or 0, if no Flash memory is installed.
  * If required, the number of sectors is determined form the device first.
  * If required, the number of sectors is determined form the device first.
  * @return the number of sectors of the Flash memory.
  * @return the number of sectors of the Flash memory.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if Flash memory access is not supported by the firmware.
  * @throws CapabilityException if Flash memory access is not supported by the firmware.
  */
  */
    public int flashSectors () throws UsbException, InvalidFirmwareException, CapabilityException {
    public int flashSectors () throws UsbException, InvalidFirmwareException, CapabilityException {
        if ( flashSectors < 0 ) // init variable
        if ( flashSectors < 0 ) // init variable
            flashState();
            flashState();
        return flashSectors;
        return flashSectors;
    }
    }
 
 
// ******* flashSize ***********************************************************
// ******* flashSize ***********************************************************
// returns size of Flash memory, if available
// returns size of Flash memory, if available
/**
/**
  * Returns the size of Flash memory or 0, if no Flash memory is installed.
  * Returns the size of Flash memory or 0, if no Flash memory is installed.
  * If required, the Flash size is determined form the device first.
  * If required, the Flash size is determined form the device first.
  * @return the size of Flash memory.
  * @return the size of Flash memory.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if Flash memory access is not supported by the firmware.
  * @throws CapabilityException if Flash memory access is not supported by the firmware.
  */
  */
    public long flashSize () throws UsbException, InvalidFirmwareException, CapabilityException {
    public long flashSize () throws UsbException, InvalidFirmwareException, CapabilityException {
        return flashSectorSize() * (long)flashSectors();
        return flashSectorSize() * (long)flashSectors();
    }
    }
 
 
// ******* printMmcState *******************************************************
// ******* printMmcState *******************************************************
// returns true if Flash is available
// returns true if Flash is available
/**
/**
  * Prints out some debug information about *SD/MMC Flash cards in SPI mode.<br>
  * Prints out some debug information about *SD/MMC Flash cards in SPI mode.<br>
  * <b>Only use this method if such kind of Flash is installed.</b>
  * <b>Only use this method if such kind of Flash is installed.</b>
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if Flash memory access is not supported by the firmware.
  * @throws CapabilityException if Flash memory access is not supported by the firmware.
  */
  */
    public boolean printMmcState ( ) throws UsbException, InvalidFirmwareException, CapabilityException {
    public boolean printMmcState ( ) throws UsbException, InvalidFirmwareException, CapabilityException {
        byte[] buf = new byte[23];
        byte[] buf = new byte[23];
        checkCapability(CAPABILITY_FLASH);
        checkCapability(CAPABILITY_FLASH);
        vendorRequest2(0x43, "MMC State", 0, 0, buf, 23);
        vendorRequest2(0x43, "MMC State", 0, 0, buf, 23);
        System.out.println("status=" + Integer.toBinaryString(256+(buf[0] & 255)).substring(1) + "." + Integer.toBinaryString(256+(buf[1] & 255)).substring(1) +
        System.out.println("status=" + Integer.toBinaryString(256+(buf[0] & 255)).substring(1) + "." + Integer.toBinaryString(256+(buf[1] & 255)).substring(1) +
                "   lastCmd=" + buf[3] +
                "   lastCmd=" + buf[3] +
                "   lastCmdResponse=" + Integer.toBinaryString(256+(buf[4] & 255)).substring(1) +
                "   lastCmdResponse=" + Integer.toBinaryString(256+(buf[4] & 255)).substring(1) +
                "   ec=" + buf[2] +
                "   ec=" + buf[2] +
                "   BUSY=" + buf[22] +
                "   BUSY=" + buf[22] +
                "   SDHC=" + buf[5] +
                "   SDHC=" + buf[5] +
                "   buf=" + (buf[6] & 255)+" "+(buf[7] & 255)+" "+(buf[8] & 255)+" "+(buf[9] & 255)+" "+(buf[10] & 255)+" "+(buf[11] & 255)+"  "+(buf[12] & 255)); // +" "+(buf[13] & 255)+" "+(buf[14] & 255)+" "+(buf[15] & 255)+" "+(buf[16] & 255)+" "+(buf[17] & 255));
                "   buf=" + (buf[6] & 255)+" "+(buf[7] & 255)+" "+(buf[8] & 255)+" "+(buf[9] & 255)+" "+(buf[10] & 255)+" "+(buf[11] & 255)+"  "+(buf[12] & 255)); // +" "+(buf[13] & 255)+" "+(buf[14] & 255)+" "+(buf[15] & 255)+" "+(buf[16] & 255)+" "+(buf[17] & 255));
 
 
        return flashEnabled == 1;
        return flashEnabled == 1;
    }
    }
 
 
 
 
// ******* flashUploadBitstream ************************************************
// ******* flashUploadBitstream ************************************************
/*
/*
    Returns configuration time in ms.
    Returns configuration time in ms.
    The format of the boot sector (sector 0 of the Flash memory) is
    The format of the boot sector (sector 0 of the Flash memory) is
        0..7    ID
        0..7    ID
        8..9    Number of BS sectors, or 0 is disabled
        8..9    Number of BS sectors, or 0 is disabled
        10..11  Number of bytes in the last sector, i.e. the total size of Bitstream is ((bs[8] | (bs[9]<<8) - 1) * flash_sector_size + ((bs[10] | (bs[11]<<8))
        10..11  Number of bytes in the last sector, i.e. the total size of Bitstream is ((bs[8] | (bs[9]<<8) - 1) * flash_sector_size + ((bs[10] | (bs[11]<<8))
*/
*/
/**
/**
  * Uploads a Bitstream to the Flash.
  * Uploads a Bitstream to the Flash.
  * This allows the firmware to load the Bitstream from Flash. Together with installation of the firmware in EEPROM
  * This allows the firmware to load the Bitstream from Flash. Together with installation of the firmware in EEPROM
  * it is possible to construct fully autonomous devices.
  * it is possible to construct fully autonomous devices.
  * <p>
  * <p>
  * If configuration data is present information about bitstream are stored there and Bitstream starts
  * If configuration data is present information about bitstream are stored there and Bitstream starts
  * at sector 0.
  * at sector 0.
  * <p>
  * <p>
  * On all other devices the information about the bitstream is stored in sector 0.
  * On all other devices the information about the bitstream is stored in sector 0.
  * This so called boot sector has the following format:
  * This so called boot sector has the following format:
  * <table bgcolor="#404040" cellspacing=1 cellpadding=4>
  * <table bgcolor="#404040" cellspacing=1 cellpadding=4>
  *   <tr>
  *   <tr>
  *     <td bgcolor="#d0d0d0" valign="bottom"><b>Bytes</b></td>
  *     <td bgcolor="#d0d0d0" valign="bottom"><b>Bytes</b></td>
  *     <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *     <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
  *   </tr>
  *   </tr>
  *   <tr>
  *   <tr>
  *     <td bgcolor="#ffffff" valign="top">0..7</td>
  *     <td bgcolor="#ffffff" valign="top">0..7</td>
  *     <td bgcolor="#ffffff" valign="top">ID, must be "ZTEXBS",1,1</td>
  *     <td bgcolor="#ffffff" valign="top">ID, must be "ZTEXBS",1,1</td>
  *   </tr>
  *   </tr>
  *   <tr>
  *   <tr>
  *     <td bgcolor="#ffffff" valign="top">8..9</td>
  *     <td bgcolor="#ffffff" valign="top">8..9</td>
  *     <td bgcolor="#ffffff" valign="top">The number of sectors used to store the Bitstream. 0 means no Bitstream.</td>
  *     <td bgcolor="#ffffff" valign="top">The number of sectors used to store the Bitstream. 0 means no Bitstream.</td>
  *   </tr>
  *   </tr>
  *   <tr>
  *   <tr>
  *     <td bgcolor="#ffffff" valign="top">10..11</td>
  *     <td bgcolor="#ffffff" valign="top">10..11</td>
  *     <td bgcolor="#ffffff" valign="top">The number of bytes in the last sector.</td>
  *     <td bgcolor="#ffffff" valign="top">The number of bytes in the last sector.</td>
  *   </tr>
  *   </tr>
  *   <tr>
  *   <tr>
  *     <td bgcolor="#ffffff" valign="top">12..sectorSize-1</td>
  *     <td bgcolor="#ffffff" valign="top">12..sectorSize-1</td>
  *     <td bgcolor="#ffffff" valign="top">This data is reserved for future use and preserved by this method.</td>
  *     <td bgcolor="#ffffff" valign="top">This data is reserved for future use and preserved by this method.</td>
  *   </tr>
  *   </tr>
  * </table>
  * </table>
  * <p>
  * <p>
  * The total size of the Bitstream is computed as ((bs[8] | (bs[9]<<8) - 1) * flash_sector_size + ((bs[10] | (bs[11]<<8))
  * The total size of the Bitstream is computed as ((bs[8] | (bs[9]<<8) - 1) * flash_sector_size + ((bs[10] | (bs[11]<<8))
  * where bs[i] denotes byte i of the boot sector.
  * where bs[i] denotes byte i of the boot sector.
  * <p>
  * <p>
  * The first sector of the Bitstream is sector 1.
  * The first sector of the Bitstream is sector 1.
  * @param inputStream for reading the Bitstream.
  * @param inputStream for reading the Bitstream.
  * @param bs 0: disable bit swapping, 1: enable bit swapping, all other values: automatic detection of bit order.
  * @param bs 0: disable bit swapping, 1: enable bit swapping, all other values: automatic detection of bit order.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if Flash memory access is not possible.
  * @throws CapabilityException if Flash memory access is not possible.
  * @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
  * @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
  */
  */
    public long flashUploadBitstream ( InputStream inputStream, int bs ) throws BitstreamReadException, UsbException, InvalidFirmwareException, CapabilityException {
    public long flashUploadBitstream ( InputStream inputStream, int bs ) throws BitstreamReadException, UsbException, InvalidFirmwareException, CapabilityException {
        int secNum = Math.max(1, 2048 / flashSectorSize());
        int secNum = Math.max(1, 2048 / flashSectorSize());
        final int bufferSize = secNum * flashSectorSize;
        final int bufferSize = secNum * flashSectorSize;
        checkCapability(CAPABILITY_FPGA);
        checkCapability(CAPABILITY_FPGA);
        checkCapability(CAPABILITY_FLASH);
        checkCapability(CAPABILITY_FLASH);
        if ( ! flashEnabled() )
        if ( ! flashEnabled() )
            throw new CapabilityException(this, "No Flash memory installed or");
            throw new CapabilityException(this, "No Flash memory installed or");
        getFpgaState();
        getFpgaState();
 
 
// read the Bitstream file      
// read the Bitstream file      
        byte[][] buffer = new byte[32768][];
        byte[][] buffer = new byte[32768][];
        byte[] buf1 = new byte[flashSectorSize()];
        byte[] buf1 = new byte[flashSectorSize()];
 
 
        int i,j,k;
        int i,j,k,l;
        try {
        try {
            j = bufferSize;
            j = bufferSize;
            for ( i=0; i<buffer.length && j==bufferSize; i++ ) {
            for ( i=0; i<buffer.length && j==bufferSize; i++ ) {
                buffer[i] = new byte[bufferSize];
                buffer[i] = new byte[bufferSize];
                j = 0;
                j = 0;
                do {
                do {
                    k = inputStream.read( buffer[i], j, bufferSize-j );
                    k = inputStream.read( buffer[i], j, bufferSize-j );
                    if ( k < 0 )
                    if ( k < 0 )
                        k = 0;
                        k = 0;
                    j += k;
                    j += k;
 
 
 
                    // remove header because S6 FPGA's does not support bitstream start word detection
 
                    if ( i==0 && j==bufferSize && (l=detectBitstreamStart(buffer[0]))>0 ) {
 
                        for (int m=0; m<bufferSize-l; m++ )
 
                            buffer[0][m]=buffer[0][m+l];
 
                        j-=l;
 
                    }
                }
                }
                while ( j<bufferSize && k>0 );
                while ( j<bufferSize && k>0 );
            }
            }
 
 
            try {
            try {
                inputStream.close();
                inputStream.close();
            }
            }
            catch ( Exception e ) {
            catch ( Exception e ) {
            }
            }
        }
        }
        catch (IOException e) {
        catch (IOException e) {
            throw new BitstreamReadException(e.getLocalizedMessage());
            throw new BitstreamReadException(e.getLocalizedMessage());
        }
        }
 
 
// detect bitstream bit order and swap bits if necessary 
// detect bitstream bit order and swap bits if necessary 
        if ( bs<0 || bs>1 )
        if ( bs<0 || bs>1 )
            bs = detectBitstreamBitOrder(buffer[0]);
            bs = detectBitstreamBitOrder(buffer[0]);
        if ( fpgaFlashBitSwap != (bs==1) )
        if ( fpgaFlashBitSwap != (bs==1) )
            swapBits( buffer, bufferSize*i );
            swapBits( buffer, bufferSize*i );
 
 
// upload the Bitstream file    
// upload the Bitstream file    
        int startSector = 0;
        int startSector = 0;
        long t0 = new Date().getTime();
        long t0 = new Date().getTime();
 
 
        if ( config!=null && config.getMaxBitstreamSize()>0 ) {
        if ( config!=null && config.getMaxBitstreamSize()>0 ) {
            config.setBitstreamSize( ((i-1)*secNum + (j-1)/flashSectorSize + 1)*flashSectorSize );
            config.setBitstreamSize( ((i-1)*secNum + (j-1)/flashSectorSize + 1)*flashSectorSize );
        }
        }
        else {
        else {
            byte[] sector = new byte[flashSectorSize];
            byte[] sector = new byte[flashSectorSize];
            byte[] ID = new String("ZTEXBS").getBytes();
            byte[] ID = new String("ZTEXBS").getBytes();
 
 
            flashReadSector(0,sector);                           // read the boot sector (only the first 16 bytes are overwritten if boot sector is valid)
            flashReadSector(0,sector);                           // read the boot sector (only the first 16 bytes are overwritten if boot sector is valid)
            boolean b = true;
            boolean b = true;
            for (k=0; k<6; k++) {
            for (k=0; k<6; k++) {
                b = b && (sector[k] == ID[k]);
                b = b && (sector[k] == ID[k]);
                sector[k]=ID[k];
                sector[k]=ID[k];
            }
            }
            if ( ! b )
            if ( ! b )
            sector[6] = 1;
            sector[6] = 1;
            sector[7] = 1;
            sector[7] = 1;
            k = (i-1)*secNum + (j-1)/flashSectorSize + 1;
            k = (i-1)*secNum + (j-1)/flashSectorSize + 1;
            sector[8] = (byte) (k & 255);
            sector[8] = (byte) (k & 255);
            sector[9] = (byte) ((k>>8) & 255);
            sector[9] = (byte) ((k>>8) & 255);
            k = ((j-1) % flashSectorSize) + 1;
            k = ((j-1) % flashSectorSize) + 1;
            sector[10] = (byte) (k & 255);
            sector[10] = (byte) (k & 255);
            sector[11] = (byte) ((k>>8) & 255);
            sector[11] = (byte) ((k>>8) & 255);
            if ( ! b ) {
            if ( ! b ) {
                for ( k=12; k<flashSectorSize; k++ )
                for ( k=12; k<flashSectorSize; k++ )
                    sector[k]=0;
                    sector[k]=0;
            }
            }
            System.out.print("\rWriting boot sector");
            System.out.print("\rWriting boot sector");
            flashWriteSector(0,sector);                          // write the boot sector
            flashWriteSector(0,sector);                          // write the boot sector
 
 
            startSector = 1;
            startSector = 1;
        }
        }
 
 
        for (k=0; k<i-1; k++) {
        for (k=0; k<i-1; k++) {
            System.out.print("\rWriting sector " + (k+1)*secNum + " of " + i*secNum);
            System.out.print("\rWriting sector " + (k+1)*secNum + " of " + i*secNum);
            flashWriteSector( startSector+k*secNum, secNum, buffer[k] );        // write the Bitstream sectors
            flashWriteSector( startSector+k*secNum, secNum, buffer[k] );        // write the Bitstream sectors
        }
        }
        System.out.println("\rWriting sector " + i*secNum + " of " + i*secNum);
        System.out.println("\rWriting sector " + i*secNum + " of " + i*secNum);
        flashWriteSector( startSector+k*secNum, (j-1)/flashSectorSize + 1, buffer[k] );
        flashWriteSector( startSector+k*secNum, (j-1)/flashSectorSize + 1, buffer[k] );
 
 
        return new Date().getTime() - t0;
        return new Date().getTime() - t0;
    }
    }
 
 
/**
/**
  * Uploads a Bitstream to the Flash.
  * Uploads a Bitstream to the Flash.
  * This allows the firmware to load the Bitstream from Flash. Together with installation of the firmware in EEPROM
  * This allows the firmware to load the Bitstream from Flash. Together with installation of the firmware in EEPROM
  * it is possible to construct fully autonomous devices.
  * it is possible to construct fully autonomous devices.
  * See {@link #flashUploadBitstream(InputStream,int)} for further details.
  * See {@link #flashUploadBitstream(InputStream,int)} for further details.
  * @param fwFileName The file name of the Bitstream. The file can be a regular file or a system resource (e.g. a file from the current jar archive).
  * @param fwFileName The file name of the Bitstream. The file can be a regular file or a system resource (e.g. a file from the current jar archive).
  * @param bs 0: disable bit swapping, 1: enable bit swapping, all other values: automatic detection of bit order.
  * @param bs 0: disable bit swapping, 1: enable bit swapping, all other values: automatic detection of bit order.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if Flash memory access is not possible.
  * @throws CapabilityException if Flash memory access is not possible.
  * @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
  * @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
  */
  */
    public long flashUploadBitstream ( String fwFileName, int bs ) throws BitstreamReadException, UsbException, InvalidFirmwareException, CapabilityException {
    public long flashUploadBitstream ( String fwFileName, int bs ) throws BitstreamReadException, UsbException, InvalidFirmwareException, CapabilityException {
        try {
        try {
            return flashUploadBitstream ( JInputStream.getInputStream( fwFileName ), bs );
            return flashUploadBitstream ( JInputStream.getInputStream( fwFileName ), bs );
        }
        }
        catch (IOException e) {
        catch (IOException e) {
            throw new BitstreamReadException(e.getLocalizedMessage());
            throw new BitstreamReadException(e.getLocalizedMessage());
        }
        }
    }
    }
 
 
/**
/**
  * Uploads a Bitstream to the Flash.
  * Uploads a Bitstream to the Flash.
  * This allows the firmware to load the Bitstream from Flash. Together with installation of the firmware in EEPROM
  * This allows the firmware to load the Bitstream from Flash. Together with installation of the firmware in EEPROM
  * it is possible to construct fully autonomous devices.
  * it is possible to construct fully autonomous devices.
  * See {@link #flashUploadBitstream(InputStream,int)} for further details.
  * See {@link #flashUploadBitstream(InputStream,int)} for further details.
  * @param fwFileName The file name of the Bitstream. The file can be a regular file or a system resource (e.g. a file from the current jar archive).
  * @param fwFileName The file name of the Bitstream. The file can be a regular file or a system resource (e.g. a file from the current jar archive).
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if Flash memory access is not possible.
  * @throws CapabilityException if Flash memory access is not possible.
  * @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
  * @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
  */
  */
    public long flashUploadBitstream ( String fwFileName ) throws BitstreamReadException, UsbException, InvalidFirmwareException, CapabilityException {
    public long flashUploadBitstream ( String fwFileName ) throws BitstreamReadException, UsbException, InvalidFirmwareException, CapabilityException {
        return flashUploadBitstream(fwFileName, -1);
        return flashUploadBitstream(fwFileName, -1);
    }
    }
 
 
// ******* flashResetBitstream *************************************************
// ******* flashResetBitstream *************************************************
// Clears a Bitstream from the Flash.
// Clears a Bitstream from the Flash.
/**
/**
  * Clears a Bitstream from the Flash.
  * Clears a Bitstream from the Flash.
  * This is achieved by writing 0 to bytes 8..9 of the boot sector, see {@link #flashUploadBitstream(String)}.
  * This is achieved by writing 0 to bytes 8..9 of the boot sector, see {@link #flashUploadBitstream(String)}.
  * If no boot sector is installed the method returns without any write action.
  * If no boot sector is installed the method returns without any write action.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if Flash memory access is not possible.
  * @throws CapabilityException if Flash memory access is not possible.
  */
  */
    public void flashResetBitstream ( ) throws UsbException, InvalidFirmwareException, CapabilityException {
    public void flashResetBitstream ( ) throws UsbException, InvalidFirmwareException, CapabilityException {
        checkCapability(CAPABILITY_FLASH);
        checkCapability(CAPABILITY_FLASH);
        if ( ! flashEnabled() )
        if ( ! flashEnabled() )
            throw new CapabilityException(this, "Flash memory not installed or");
            throw new CapabilityException(this, "Flash memory not installed or");
 
 
        if ( config!=null && config.getMaxBitstreamSize()>0 ) {
        if ( config!=null && config.getMaxBitstreamSize()>0 ) {
            config.setBitstreamSize(0);
            config.setBitstreamSize(0);
            return;
            return;
        }
        }
 
 
        byte[] sector = new byte[flashSectorSize()];
        byte[] sector = new byte[flashSectorSize()];
        byte[] ID = new String("ZTEXBS").getBytes();
        byte[] ID = new String("ZTEXBS").getBytes();
 
 
        flashReadSector(0,sector);                       // read the boot sector
        flashReadSector(0,sector);                       // read the boot sector
        for (int k=0; k<6; k++)
        for (int k=0; k<6; k++)
            if ( sector[k] != ID[k] )
            if ( sector[k] != ID[k] )
                return;
                return;
        if (sector[6]!=1 || sector[7]!=1 )
        if (sector[6]!=1 || sector[7]!=1 )
            return;
            return;
        sector[8] = 0;
        sector[8] = 0;
        sector[9] = 0;
        sector[9] = 0;
        flashWriteSector(0,sector);                      // write the boot sector
        flashWriteSector(0,sector);                      // write the boot sector
    }
    }
 
 
// ******* flashFirstFreeSector ************************************************
// ******* flashFirstFreeSector ************************************************
 
 
// Returns the first free sector of the Flash memory, i.e. the first sector behind the Bitstream
// Returns the first free sector of the Flash memory, i.e. the first sector behind the Bitstream
/**
/**
  * Returns the first free sector of the Flash memory.
  * Returns the first free sector of the Flash memory.
  * This is the first sector behind the Bitstream, or 0 if no boot sector is installed (or 1 if a boot sector but no Bitstream is installed).
  * This is the first sector behind the Bitstream, or 0 if no boot sector is installed (or 1 if a boot sector but no Bitstream is installed).
  * @return the first free sector of the Flash memory.
  * @return the first free sector of the Flash memory.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if Flash memory access is not possible.
  * @throws CapabilityException if Flash memory access is not possible.
  */
  */
    public int flashFirstFreeSector ( ) throws UsbException, InvalidFirmwareException, CapabilityException {
    public int flashFirstFreeSector ( ) throws UsbException, InvalidFirmwareException, CapabilityException {
        checkCapability(CAPABILITY_FLASH);
        checkCapability(CAPABILITY_FLASH);
        if ( ! flashEnabled() )
        if ( ! flashEnabled() )
            throw new CapabilityException(this, "No Flash memory installed or");
            throw new CapabilityException(this, "No Flash memory installed or");
 
 
        if ( config!=null && config.getMaxBitstreamSize()>0 ) {
        if ( config!=null && config.getMaxBitstreamSize()>0 ) {
            return (Math.max(config.getMaxBitstreamSize(), config.getBitstreamSize())+flashSectorSize()-1) / flashSectorSize();
            return (Math.max(config.getMaxBitstreamSize(), config.getBitstreamSize())+flashSectorSize()-1) / flashSectorSize();
        }
        }
 
 
        byte[] sector = new byte[flashSectorSize()];
        byte[] sector = new byte[flashSectorSize()];
        byte[] ID = new String("ZTEXBS").getBytes();
        byte[] ID = new String("ZTEXBS").getBytes();
 
 
        flashReadSector(0,sector);                       // read the boot sector
        flashReadSector(0,sector);                       // read the boot sector
        for (int k=0; k<6; k++)
        for (int k=0; k<6; k++)
            if ( sector[k] != ID[k] )
            if ( sector[k] != ID[k] )
                return 0;
                return 0;
        if (sector[6]!=1 || sector[7]!=1 )
        if (sector[6]!=1 || sector[7]!=1 )
            return 0;
            return 0;
        return (sector[8] & 255) + ((sector[9] & 255) << 8) + 1;
        return (sector[8] & 255) + ((sector[9] & 255) << 8) + 1;
    }
    }
 
 
// ******* toHumanStr **********************************************************
// ******* toHumanStr **********************************************************
    private String toHumanStr ( long i ) {
    private String toHumanStr ( long i ) {
        if ( i==0 ) return "0";
        if ( i==0 ) return "0";
        StringBuilder sb = new StringBuilder();
        StringBuilder sb = new StringBuilder();
        int k = 0;
        int k = 0;
        if ( i<0 ) {
        if ( i<0 ) {
            sb.append("-");
            sb.append("-");
            i=-i;
            i=-i;
            k=1;
            k=1;
        }
        }
        if ( (i & 1023) != 0 ) sb.insert(k, i & 1023); i=i>>10;
        if ( (i & 1023) != 0 ) sb.insert(k, i & 1023); i=i>>10;
        if ( (i & 1023) != 0 ) sb.insert(k, (i & 1023) + "K"); i=i>>10;
        if ( (i & 1023) != 0 ) sb.insert(k, (i & 1023) + "K"); i=i>>10;
        if ( (i & 1023) != 0 ) sb.insert(k, (i & 1023) + "M"); i=i>>10;
        if ( (i & 1023) != 0 ) sb.insert(k, (i & 1023) + "M"); i=i>>10;
        if ( i != 0 ) sb.append(i + "G");;
        if ( i != 0 ) sb.append(i + "G");;
        return sb.toString();
        return sb.toString();
    }
    }
 
 
// ******* flashInfo **********************************************************
// ******* flashInfo **********************************************************
/**
/**
  * Returns information about Flash memory.
  * Returns information about Flash memory.
  * The result contains the size and how much of the Flash is us used / reserved for / by the Bitstream.
  * The result contains the size and how much of the Flash is us used / reserved for / by the Bitstream.
  * If no Flash memeory is suppported an empty string is returned.
  * If no Flash memeory is suppported an empty string is returned.
  * Returns Information about Flash memory.
  * Returns Information about Flash memory.
  */
  */
    public String flashInfo ( ) {
    public String flashInfo ( ) {
        StringBuilder sb = new StringBuilder();
        StringBuilder sb = new StringBuilder();
        try {
        try {
            if ( flashSize() > 0 ) {
            if ( flashSize() > 0 ) {
                sb.append( "Size: " + toHumanStr(flashSize()) + " Bytes" );
                sb.append( "Size: " + toHumanStr(flashSize()) + " Bytes" );
                if ( config!=null && config.getMaxBitstreamSize()>0 ) {
                if ( config!=null && config.getMaxBitstreamSize()>0 ) {
                    sb.append( ";  Bitstream (used / reserved): " + toHumanStr(config.getBitstreamSize()) + " / "  + toHumanStr(config.getMaxBitstreamSize()) + " Bytes" );
                    sb.append( ";  Bitstream (used / reserved): " + toHumanStr(config.getBitstreamSize()) + " / "  + toHumanStr(config.getMaxBitstreamSize()) + " Bytes" );
                }
                }
                else {
                else {
                    sb.append( ";  Bitstream (used): " + toHumanStr(flashFirstFreeSector()*flashSectorSize()) + " Bytes" );
                    sb.append( ";  Bitstream (used): " + toHumanStr(flashFirstFreeSector()*flashSectorSize()) + " Bytes" );
                }
                }
            }
            }
        }
        }
        catch ( Exception e ) {
        catch ( Exception e ) {
        }
        }
        return sb.toString();
        return sb.toString();
    }
    }
 
 
// ******* debugStackSize ******************************************************
// ******* debugStackSize ******************************************************
/**
/**
  * Returns the size of message stack in messages.
  * Returns the size of message stack in messages.
  * @return the size of message stack in messages.
  * @return the size of message stack in messages.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if Flash memory access is not possible.
  * @throws CapabilityException if Flash memory access is not possible.
  */
  */
    public int debugStackSize ( ) throws UsbException, InvalidFirmwareException, CapabilityException {
    public int debugStackSize ( ) throws UsbException, InvalidFirmwareException, CapabilityException {
        checkCapability(CAPABILITY_DEBUG);
        checkCapability(CAPABILITY_DEBUG);
        if ( debugStackSize<=0 || debugMsgSize<=0 ) {
        if ( debugStackSize<=0 || debugMsgSize<=0 ) {
            byte[] buf = new byte[7];
            byte[] buf = new byte[7];
            vendorRequest2(0x28, "Read debug data", 0, 0, buf, 4);
            vendorRequest2(0x28, "Read debug data", 0, 0, buf, 4);
            debugStackSize = buf[2] & 255;
            debugStackSize = buf[2] & 255;
            debugMsgSize = buf[3] & 255;
            debugMsgSize = buf[3] & 255;
        }
        }
        return debugStackSize;
        return debugStackSize;
    }
    }
 
 
// ******* debugMsgSize ********************************************************
// ******* debugMsgSize ********************************************************
/**
/**
  * Returns the size of messages in bytes.
  * Returns the size of messages in bytes.
  * @return the size of messages in bytes.
  * @return the size of messages in bytes.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if Flash memory access is not possible.
  * @throws CapabilityException if Flash memory access is not possible.
  */
  */
    public int debugMsgSize ( ) throws UsbException, InvalidFirmwareException, CapabilityException {
    public int debugMsgSize ( ) throws UsbException, InvalidFirmwareException, CapabilityException {
        checkCapability(CAPABILITY_DEBUG);
        checkCapability(CAPABILITY_DEBUG);
        if ( debugMsgSize<=0 )
        if ( debugMsgSize<=0 )
            debugStackSize();
            debugStackSize();
 
 
        return debugMsgSize;
        return debugMsgSize;
    }
    }
 
 
// ******* debugLastMsg ********************************************************
// ******* debugLastMsg ********************************************************
/**
/**
  * Returns the number of the last message read out by {@link #debugReadMessages(boolean,byte[])}
  * Returns the number of the last message read out by {@link #debugReadMessages(boolean,byte[])}
  * @return the number of the last message read out by {@link #debugReadMessages(boolean,byte[])}
  * @return the number of the last message read out by {@link #debugReadMessages(boolean,byte[])}
  */
  */
    public final int debugLastMsg ( )  {
    public final int debugLastMsg ( )  {
        return debugLastMsg;
        return debugLastMsg;
    }
    }
 
 
// ******* debugReadMessages ***************************************************
// ******* debugReadMessages ***************************************************
/**
/**
  * Reads debug messages from message stack.
  * Reads debug messages from message stack.
  * The number of messages stored in buf is returned. The total number of new messages is stored in {@link #debugNewMessages}.
  * The number of messages stored in buf is returned. The total number of new messages is stored in {@link #debugNewMessages}.
  * The number of the latest message is returned by {@link #debugLastMsg()}.
  * The number of the latest message is returned by {@link #debugLastMsg()}.
  * @param all If true, all messages from stack are written to buf. If it is false, only the new messages are written to buf.
  * @param all If true, all messages from stack are written to buf. If it is false, only the new messages are written to buf.
  * @param buf The buffer to store the messages.
  * @param buf The buffer to store the messages.
  * @return the size of messages stored in buffer.
  * @return the size of messages stored in buffer.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if Flash memory access is not possible.
  * @throws CapabilityException if Flash memory access is not possible.
  */
  */
    public int debugReadMessages ( boolean all, byte[] buf ) throws UsbException, InvalidFirmwareException, CapabilityException {
    public int debugReadMessages ( boolean all, byte[] buf ) throws UsbException, InvalidFirmwareException, CapabilityException {
        checkCapability(CAPABILITY_DEBUG);
        checkCapability(CAPABILITY_DEBUG);
        byte buf2[] = new byte[ debugStackSize()*debugMsgSize() + 4 ];
        byte buf2[] = new byte[ debugStackSize()*debugMsgSize() + 4 ];
        vendorRequest2(0x28, "Read debug data", 0, 0, buf2, buf2.length);
        vendorRequest2(0x28, "Read debug data", 0, 0, buf2, buf2.length);
        int lm = (buf2[0] & 255) | ((buf2[1] & 255) << 8);
        int lm = (buf2[0] & 255) | ((buf2[1] & 255) << 8);
        debugNewMessages = lm - debugLastMsg;
        debugNewMessages = lm - debugLastMsg;
 
 
        int r = Math.min( Math.min( buf.length/debugMsgSize() , debugStackSize ), lm);
        int r = Math.min( Math.min( buf.length/debugMsgSize() , debugStackSize ), lm);
        if ( !all ) r = Math.min(r,debugNewMessages);
        if ( !all ) r = Math.min(r,debugNewMessages);
        for (int i = 0; i<r; i++) {
        for (int i = 0; i<r; i++) {
            int k=(lm-r+i) % debugStackSize;
            int k=(lm-r+i) % debugStackSize;
            for (int j=0; j<debugMsgSize; j++ )
            for (int j=0; j<debugMsgSize; j++ )
                buf[i*debugMsgSize+j] = buf2[k*debugMsgSize+j+4];
                buf[i*debugMsgSize+j] = buf2[k*debugMsgSize+j+4];
        }
        }
 
 
        debugLastMsg = lm;
        debugLastMsg = lm;
        return r;
        return r;
    }
    }
 
 
// ******* xmegaStrError *******************************************************
// ******* xmegaStrError *******************************************************
/**
/**
  * Converts a given error code into a String.
  * Converts a given error code into a String.
  * @param errNum The error code.
  * @param errNum The error code.
  * @return an error message.
  * @return an error message.
  */
  */
    public String xmegaStrError ( int errNum ) {
    public String xmegaStrError ( int errNum ) {
        switch ( errNum ) {
        switch ( errNum ) {
            case XMEGA_EC_NO_ERROR:
            case XMEGA_EC_NO_ERROR:
                return "USB error: " + LibusbJava.usb_strerror();
                return "USB error: " + LibusbJava.usb_strerror();
            case XMEGA_EC_PDI_READ_ERROR:
            case XMEGA_EC_PDI_READ_ERROR:
                return "PDI read error";
                return "PDI read error";
            case XMEGA_EC_NVM_TIMEOUT:
            case XMEGA_EC_NVM_TIMEOUT:
                return "NVM timeout error";
                return "NVM timeout error";
            case XMEGA_EC_INVALID_DEVICE:
            case XMEGA_EC_INVALID_DEVICE:
                return "Invalid or unsupported ATxmega";
                return "Invalid or unsupported ATxmega";
            case XMEGA_EC_ADDRESS_ERROR:
            case XMEGA_EC_ADDRESS_ERROR:
                return "Address error (invalid address or wrong page size)";
                return "Address error (invalid address or wrong page size)";
            case XMEGA_EC_NVM_BUSY:
            case XMEGA_EC_NVM_BUSY:
                return "NVM busy";
                return "NVM busy";
        }
        }
        return "Error " + errNum;
        return "Error " + errNum;
    }
    }
 
 
/**
/**
  * Gets the last ATxmega error from the device.
  * Gets the last ATxmega error from the device.
  * @return an error message.
  * @return an error message.
  */
  */
    public String xmegaStrError ( ) {
    public String xmegaStrError ( ) {
        try {
        try {
            return xmegaStrError( xmegaState() );
            return xmegaStrError( xmegaState() );
        }
        }
        catch ( Exception e ) {
        catch ( Exception e ) {
            return "Unknown error (Error receiving error code: "+e.getLocalizedMessage() +")";
            return "Unknown error (Error receiving error code: "+e.getLocalizedMessage() +")";
        }
        }
    }
    }
 
 
// ******* xmegaState **********************************************************
// ******* xmegaState **********************************************************
/**
/**
  * Read ATxmega error and status information from the device.
  * Read ATxmega error and status information from the device.
  * @return The last error code.
  * @return The last error code.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if ATxmega controllers are not supported by the firmware.
  * @throws CapabilityException if ATxmega controllers are not supported by the firmware.
  */
  */
    public int xmegaState () throws UsbException, InvalidFirmwareException, CapabilityException {
    public int xmegaState () throws UsbException, InvalidFirmwareException, CapabilityException {
        byte[] buf = new byte[7];
        byte[] buf = new byte[7];
        checkCapability(CAPABILITY_XMEGA);
        checkCapability(CAPABILITY_XMEGA);
        vendorRequest2(0x48, "Xmega state", 0, 0, buf, 7);
        vendorRequest2(0x48, "Xmega state", 0, 0, buf, 7);
        xmegaEC = buf[0] & 255;
        xmegaEC = buf[0] & 255;
 
 
        xmegaFlashPages = ((buf[2] & 255) << 8) | (buf[1] & 255);
        xmegaFlashPages = ((buf[2] & 255) << 8) | (buf[1] & 255);
        xmegaEepromPages = ((buf[4] & 255) << 8) | (buf[3] & 255);
        xmegaEepromPages = ((buf[4] & 255) << 8) | (buf[3] & 255);
        xmegaFlashPageSize = 1 << (buf[5] & 15);
        xmegaFlashPageSize = 1 << (buf[5] & 15);
        xmegaEepromPageSize = 1 << (buf[6] & 15);
        xmegaEepromPageSize = 1 << (buf[6] & 15);
        return xmegaEC;
        return xmegaEC;
    }
    }
 
 
// ******* xmegaEnabled ********************************************************
// ******* xmegaEnabled ********************************************************
/**
/**
  * Returns true if ATxmega controller is available.
  * Returns true if ATxmega controller is available.
  * @return true if ATxmega controller is available.
  * @return true if ATxmega controller is available.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if ATxmega controllers are not supported by the firmware.
  * @throws CapabilityException if ATxmega controllers are not supported by the firmware.
  */
  */
    public boolean xmegaEnabled () throws UsbException, InvalidFirmwareException, CapabilityException {
    public boolean xmegaEnabled () throws UsbException, InvalidFirmwareException, CapabilityException {
        if ( xmegaFlashPages < 0 || xmegaEepromPages < 0 ) // init variables
        if ( xmegaFlashPages < 0 || xmegaEepromPages < 0 ) // init variables
            xmegaState();
            xmegaState();
        return xmegaFlashPages > 0 && xmegaEepromPages > 0;
        return xmegaFlashPages > 0 && xmegaEepromPages > 0;
    }
    }
 
 
// ******* xmegaFlashPages *****************************************************
// ******* xmegaFlashPages *****************************************************
/**
/**
  * Returns the number of the ATxmega Flash pages.
  * Returns the number of the ATxmega Flash pages.
  * @return The number of the ATxmega Flash pages.
  * @return The number of the ATxmega Flash pages.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if ATxmega controllers are not supported by the firmware.
  * @throws CapabilityException if ATxmega controllers are not supported by the firmware.
  */
  */
    public int xmegaFlashPages () throws UsbException, InvalidFirmwareException, CapabilityException {
    public int xmegaFlashPages () throws UsbException, InvalidFirmwareException, CapabilityException {
        if ( xmegaFlashPages < 0 || xmegaEepromPages < 0 ) // init variables
        if ( xmegaFlashPages < 0 || xmegaEepromPages < 0 ) // init variables
            xmegaState();
            xmegaState();
        return xmegaFlashPages;
        return xmegaFlashPages;
    }
    }
 
 
// ******* xmegaEepromPages ****************************************************
// ******* xmegaEepromPages ****************************************************
/**
/**
  * Returns the number of the ATxmega EEPROM pages.
  * Returns the number of the ATxmega EEPROM pages.
  * @return The number of the ATxmega EEPROM pages.
  * @return The number of the ATxmega EEPROM pages.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if ATxmega controllers are not supported by the firmware.
  * @throws CapabilityException if ATxmega controllers are not supported by the firmware.
  */
  */
    public int xmegaEepromPages () throws UsbException, InvalidFirmwareException, CapabilityException {
    public int xmegaEepromPages () throws UsbException, InvalidFirmwareException, CapabilityException {
        if ( xmegaFlashPages < 0 || xmegaEepromPages < 0 ) // init variables
        if ( xmegaFlashPages < 0 || xmegaEepromPages < 0 ) // init variables
            xmegaState();
            xmegaState();
        return xmegaEepromPages;
        return xmegaEepromPages;
    }
    }
 
 
// ******* xmegaFlashPageSize **************************************************
// ******* xmegaFlashPageSize **************************************************
/**
/**
  * Returns the size of the ATxmega Flash pages.
  * Returns the size of the ATxmega Flash pages.
  * @return The size of the ATxmega Flash pages.
  * @return The size of the ATxmega Flash pages.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if ATxmega controllers are not supported by the firmware.
  * @throws CapabilityException if ATxmega controllers are not supported by the firmware.
  */
  */
    public int xmegaFlashPageSize () throws UsbException, InvalidFirmwareException, CapabilityException {
    public int xmegaFlashPageSize () throws UsbException, InvalidFirmwareException, CapabilityException {
        if ( xmegaFlashPages < 0 || xmegaEepromPages < 0 ) // init variables
        if ( xmegaFlashPages < 0 || xmegaEepromPages < 0 ) // init variables
            xmegaState();
            xmegaState();
        return xmegaFlashPageSize;
        return xmegaFlashPageSize;
    }
    }
 
 
// ******* xmegaEEpromPageSize *************************************************
// ******* xmegaEEpromPageSize *************************************************
/**
/**
  * Returns the size of the ATXmega EEPROM pages.
  * Returns the size of the ATXmega EEPROM pages.
  * @return The size of the ATXmega EEPROM pages.
  * @return The size of the ATXmega EEPROM pages.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if ATXmega controllers are not supported by the firmware.
  * @throws CapabilityException if ATXmega controllers are not supported by the firmware.
  */
  */
    public int xmegaEepromPageSize () throws UsbException, InvalidFirmwareException, CapabilityException {
    public int xmegaEepromPageSize () throws UsbException, InvalidFirmwareException, CapabilityException {
        if ( xmegaFlashPages < 0 || xmegaEepromPages < 0 ) // init variables
        if ( xmegaFlashPages < 0 || xmegaEepromPages < 0 ) // init variables
            xmegaState();
            xmegaState();
        return xmegaEepromPageSize;
        return xmegaEepromPageSize;
    }
    }
 
 
// ******* xmegaReset **********************************************************
// ******* xmegaReset **********************************************************
/**
/**
  * Resets the ATxmega.
  * Resets the ATxmega.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if NVRAM access to ATxmega is not supported by the firmware.
  * @throws CapabilityException if NVRAM access to ATxmega is not supported by the firmware.
  */
  */
    public void xmegaReset () throws UsbException, InvalidFirmwareException, CapabilityException {
    public void xmegaReset () throws UsbException, InvalidFirmwareException, CapabilityException {
        checkCapability(CAPABILITY_XMEGA);
        checkCapability(CAPABILITY_XMEGA);
        try {
        try {
            vendorCommand( 0x49, "XMEGA Reset" );
            vendorCommand( 0x49, "XMEGA Reset" );
        }
        }
        catch ( UsbException e ) {
        catch ( UsbException e ) {
            throw new UsbException( dev().dev(), "NVM Reset: " + xmegaStrError() );
            throw new UsbException( dev().dev(), "NVM Reset: " + xmegaStrError() );
        }
        }
    }
    }
 
 
 
 
// ******* xmegaNvmRead ********************************************************
// ******* xmegaNvmRead ********************************************************
/**
/**
  * Reads data from the NVM of ATxmega.
  * Reads data from the NVM of ATxmega.
  * @param addr The source address of the NVM (PDI address space).
  * @param addr The source address of the NVM (PDI address space).
  * @param buf A buffer for the storage of the data.
  * @param buf A buffer for the storage of the data.
  * @param length The amount of bytes to be read.
  * @param length The amount of bytes to be read.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if NVRAM access to ATxmega is not supported by the firmware.
  * @throws CapabilityException if NVRAM access to ATxmega is not supported by the firmware.
  */
  */
    public void xmegaNvmRead ( int addr, byte[] buf, int length ) throws UsbException, InvalidFirmwareException, CapabilityException {
    public void xmegaNvmRead ( int addr, byte[] buf, int length ) throws UsbException, InvalidFirmwareException, CapabilityException {
        checkCapability(CAPABILITY_XMEGA);
        checkCapability(CAPABILITY_XMEGA);
 
 
        try {
        try {
            vendorRequest2( 0x4a, "XMEGA NVM Read", addr, addr>> 16, buf, length );
            vendorRequest2( 0x4a, "XMEGA NVM Read", addr, addr>> 16, buf, length );
        }
        }
        catch ( UsbException e ) {
        catch ( UsbException e ) {
            throw new UsbException( dev().dev(), "NVM Read: " + xmegaStrError() );
            throw new UsbException( dev().dev(), "NVM Read: " + xmegaStrError() );
        }
        }
        try {
        try {
            Thread.sleep( 3 );
            Thread.sleep( 3 );
        }
        }
        catch ( InterruptedException e) {
        catch ( InterruptedException e) {
        }
        }
    }
    }
 
 
 
 
// ******* xmegaFlashRead ******************************************************
// ******* xmegaFlashRead ******************************************************
/**
/**
  * Reads data from Flash memory of ATxmega.
  * Reads data from Flash memory of ATxmega.
  * @param addr The source address relative to the Flash memory base.
  * @param addr The source address relative to the Flash memory base.
  * @param buf A buffer for the storage of the data.
  * @param buf A buffer for the storage of the data.
  * @param length The amount of bytes to be read.
  * @param length The amount of bytes to be read.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException If a communication error occurs.
  * @throws UsbException If a communication error occurs.
  * @throws CapabilityException If NVRAM access to ATxmega is not supported by the firmware.
  * @throws CapabilityException If NVRAM access to ATxmega is not supported by the firmware.
  */
  */
    public void xmegaFlashRead ( int addr, byte[] buf, int length ) throws UsbException, InvalidFirmwareException, CapabilityException {
    public void xmegaFlashRead ( int addr, byte[] buf, int length ) throws UsbException, InvalidFirmwareException, CapabilityException {
        checkCapability(CAPABILITY_XMEGA);
        checkCapability(CAPABILITY_XMEGA);
 
 
        try {
        try {
            vendorRequest2( 0x4b, "XMEGA Flash Read", addr, addr>> 16, buf, length );
            vendorRequest2( 0x4b, "XMEGA Flash Read", addr, addr>> 16, buf, length );
        }
        }
        catch ( UsbException e ) {
        catch ( UsbException e ) {
            throw new UsbException( dev().dev(), "XMEGA Flash Read: " + xmegaStrError() );
            throw new UsbException( dev().dev(), "XMEGA Flash Read: " + xmegaStrError() );
        }
        }
        try {
        try {
            Thread.sleep( 3 );
            Thread.sleep( 3 );
        }
        }
        catch ( InterruptedException e) {
        catch ( InterruptedException e) {
        }
        }
    }
    }
 
 
 
 
 
 
// ******* xmegaEepromRead *****************************************************
// ******* xmegaEepromRead *****************************************************
/**
/**
  * Reads data from EEPROM memory of ATxmega.
  * Reads data from EEPROM memory of ATxmega.
  * @param addr The source address relative to the EEPROM memory base.
  * @param addr The source address relative to the EEPROM memory base.
  * @param buf A buffer for the storage of the data.
  * @param buf A buffer for the storage of the data.
  * @param length The amount of bytes to be read.
  * @param length The amount of bytes to be read.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException If a communication error occurs.
  * @throws UsbException If a communication error occurs.
  * @throws CapabilityException If NVRAM access to ATxmega is not supported by the firmware.
  * @throws CapabilityException If NVRAM access to ATxmega is not supported by the firmware.
  */
  */
    public void xmegaEepromRead ( int addr, byte[] buf, int length ) throws UsbException, InvalidFirmwareException, CapabilityException {
    public void xmegaEepromRead ( int addr, byte[] buf, int length ) throws UsbException, InvalidFirmwareException, CapabilityException {
        checkCapability(CAPABILITY_XMEGA);
        checkCapability(CAPABILITY_XMEGA);
 
 
        try {
        try {
            vendorRequest2( 0x4c, "XMEGA EEPROM Read", addr, addr>> 16, buf, length );
            vendorRequest2( 0x4c, "XMEGA EEPROM Read", addr, addr>> 16, buf, length );
        }
        }
        catch ( UsbException e ) {
        catch ( UsbException e ) {
            throw new UsbException( dev().dev(), "XMEGA EEPROM Read: " + xmegaStrError() );
            throw new UsbException( dev().dev(), "XMEGA EEPROM Read: " + xmegaStrError() );
        }
        }
        try {
        try {
            Thread.sleep( 3 );
            Thread.sleep( 3 );
        }
        }
        catch ( InterruptedException e) {
        catch ( InterruptedException e) {
        }
        }
    }
    }
 
 
 
 
// ******* xmegaFuseRead *******************************************************
// ******* xmegaFuseRead *******************************************************
/**
/**
  * Reads data from Fuse memory of ATxmega.
  * Reads data from Fuse memory of ATxmega.
  * @param addr The source address relative to the Fuse memory base.
  * @param addr The source address relative to the Fuse memory base.
  * @param buf A buffer for the storage of the data.
  * @param buf A buffer for the storage of the data.
  * @param length The amount of bytes to be read.
  * @param length The amount of bytes to be read.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException If a communication error occurs.
  * @throws UsbException If a communication error occurs.
  * @throws CapabilityException If NVRAM access to ATxmega is not supported by the firmware.
  * @throws CapabilityException If NVRAM access to ATxmega is not supported by the firmware.
  */
  */
    public void xmegaFuseRead ( int addr, byte[] buf, int length ) throws UsbException, InvalidFirmwareException, CapabilityException {
    public void xmegaFuseRead ( int addr, byte[] buf, int length ) throws UsbException, InvalidFirmwareException, CapabilityException {
        checkCapability(CAPABILITY_XMEGA);
        checkCapability(CAPABILITY_XMEGA);
 
 
        try {
        try {
            vendorRequest2( 0x4d, "XMEGA Fuse Read", addr, addr>> 16, buf, length );
            vendorRequest2( 0x4d, "XMEGA Fuse Read", addr, addr>> 16, buf, length );
        }
        }
        catch ( UsbException e ) {
        catch ( UsbException e ) {
            throw new UsbException( dev().dev(), "XMEGA Fuse Read: " + xmegaStrError() );
            throw new UsbException( dev().dev(), "XMEGA Fuse Read: " + xmegaStrError() );
        }
        }
        try {
        try {
            Thread.sleep( 3 );
            Thread.sleep( 3 );
        }
        }
        catch ( InterruptedException e) {
        catch ( InterruptedException e) {
        }
        }
    }
    }
 
 
/**
/**
  * Reads data one Fuse of ATxmega.
  * Reads data one Fuse of ATxmega.
  * @param addr The index of th Fuse.
  * @param addr The index of th Fuse.
  * @return The Fuse read.
  * @return The Fuse read.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException If a communication error occurs.
  * @throws UsbException If a communication error occurs.
  * @throws CapabilityException If NVRAM access to ATxmega is not supported by the firmware.
  * @throws CapabilityException If NVRAM access to ATxmega is not supported by the firmware.
  */
  */
    public int xmegaFuseRead ( int addr ) throws UsbException, InvalidFirmwareException, CapabilityException {
    public int xmegaFuseRead ( int addr ) throws UsbException, InvalidFirmwareException, CapabilityException {
        byte[] buf = new byte[1];
        byte[] buf = new byte[1];
        checkCapability(CAPABILITY_XMEGA);
        checkCapability(CAPABILITY_XMEGA);
        try {
        try {
            vendorRequest2( 0x4d, "XMEGA Fuse Read", addr, 0, buf, 1 );
            vendorRequest2( 0x4d, "XMEGA Fuse Read", addr, 0, buf, 1 );
        }
        }
        catch ( UsbException e ) {
        catch ( UsbException e ) {
            throw new UsbException( dev().dev(), "XMEGA Fuse Read: " + xmegaStrError() );
            throw new UsbException( dev().dev(), "XMEGA Fuse Read: " + xmegaStrError() );
        }
        }
        try {
        try {
            Thread.sleep( 3 );
            Thread.sleep( 3 );
        }
        }
        catch ( InterruptedException e) {
        catch ( InterruptedException e) {
        }
        }
        return buf[0] & 255;
        return buf[0] & 255;
    }
    }
 
 
 
 
// ******* xmegaFlashPageWrite *************************************************
// ******* xmegaFlashPageWrite *************************************************
/**
/**
  * Writes data to Flash memory of ATxmega.
  * Writes data to Flash memory of ATxmega.
  * @param addr The source address relative to the Flash memory base.
  * @param addr The source address relative to the Flash memory base.
  * @param buf A buffer that stores the data.
  * @param buf A buffer that stores the data.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if NVRAM access to ATxmega is not supported by the firmware.
  * @throws CapabilityException if NVRAM access to ATxmega is not supported by the firmware.
  * @throws IndexOutOfBoundsException If the buffer is smaller than the Flash page size.
  * @throws IndexOutOfBoundsException If the buffer is smaller than the Flash page size.
*/
*/
    public void xmegaFlashPageWrite ( int addr, byte[] buf ) throws UsbException, InvalidFirmwareException, CapabilityException, IndexOutOfBoundsException {
    public void xmegaFlashPageWrite ( int addr, byte[] buf ) throws UsbException, InvalidFirmwareException, CapabilityException, IndexOutOfBoundsException {
        checkCapability(CAPABILITY_XMEGA);
        checkCapability(CAPABILITY_XMEGA);
 
 
        if ( buf.length < xmegaFlashPageSize() )
        if ( buf.length < xmegaFlashPageSize() )
            throw new IndexOutOfBoundsException( "Buffer smaller than the Flash page size: " + buf.length + " < " + xmegaFlashPageSize);
            throw new IndexOutOfBoundsException( "Buffer smaller than the Flash page size: " + buf.length + " < " + xmegaFlashPageSize);
 
 
        try {
        try {
            vendorCommand2( 0x4b, "XMEGA Flash page write", addr, addr>> 16, buf, xmegaFlashPageSize );
            vendorCommand2( 0x4b, "XMEGA Flash page write", addr, addr>> 16, buf, xmegaFlashPageSize );
        }
        }
        catch ( UsbException e ) {
        catch ( UsbException e ) {
            throw new UsbException( dev().dev(), "XMEGA Flash page write: " + xmegaStrError() );
            throw new UsbException( dev().dev(), "XMEGA Flash page write: " + xmegaStrError() );
        }
        }
        try {
        try {
            Thread.sleep( 3 );
            Thread.sleep( 3 );
        }
        }
        catch ( InterruptedException e) {
        catch ( InterruptedException e) {
        }
        }
    }
    }
 
 
// ******* xmegaEpromPageWrite *************************************************
// ******* xmegaEpromPageWrite *************************************************
/**
/**
  * Writes data to EEPROM memory of ATxmega.
  * Writes data to EEPROM memory of ATxmega.
  * @param addr The source address relative to the EEPROM memory base.
  * @param addr The source address relative to the EEPROM memory base.
  * @param buf A buffer that stores the data.
  * @param buf A buffer that stores the data.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if NVRAM access to ATxmega is not supported by the firmware.
  * @throws CapabilityException if NVRAM access to ATxmega is not supported by the firmware.
  * @throws IndexOutOfBoundsException If the buffer is smaller than the EEPROM page size.
  * @throws IndexOutOfBoundsException If the buffer is smaller than the EEPROM page size.
*/
*/
    public void xmegaEepromPageWrite ( int addr, byte[] buf ) throws UsbException, InvalidFirmwareException, CapabilityException, IndexOutOfBoundsException {
    public void xmegaEepromPageWrite ( int addr, byte[] buf ) throws UsbException, InvalidFirmwareException, CapabilityException, IndexOutOfBoundsException {
        checkCapability(CAPABILITY_XMEGA);
        checkCapability(CAPABILITY_XMEGA);
 
 
        if ( buf.length < xmegaEepromPageSize() )
        if ( buf.length < xmegaEepromPageSize() )
            throw new IndexOutOfBoundsException( "Buffer smaller than the EEPROM page size: " + buf.length + " < " + xmegaEepromPageSize);
            throw new IndexOutOfBoundsException( "Buffer smaller than the EEPROM page size: " + buf.length + " < " + xmegaEepromPageSize);
 
 
        try {
        try {
            vendorCommand2( 0x4c, "XMEGA EEPROM page write", addr, addr>> 16, buf, xmegaEepromPageSize );
            vendorCommand2( 0x4c, "XMEGA EEPROM page write", addr, addr>> 16, buf, xmegaEepromPageSize );
        }
        }
        catch ( UsbException e ) {
        catch ( UsbException e ) {
            throw new UsbException( dev().dev(), "XMEGA EEPROM page write: " + xmegaStrError() );
            throw new UsbException( dev().dev(), "XMEGA EEPROM page write: " + xmegaStrError() );
        }
        }
        try {
        try {
            Thread.sleep( 3 );
            Thread.sleep( 3 );
        }
        }
        catch ( InterruptedException e) {
        catch ( InterruptedException e) {
        }
        }
    }
    }
 
 
// ******* xmegaFuseWrite ******************************************************
// ******* xmegaFuseWrite ******************************************************
/**
/**
  * Writes one Fuse of the ATxmega.
  * Writes one Fuse of the ATxmega.
  * @param addr The index of th Fuse.
  * @param addr The index of th Fuse.
  * @param val The value of th Fuse.
  * @param val The value of th Fuse.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if NVRAM access to ATxmega is not supported by the firmware.
  * @throws CapabilityException if NVRAM access to ATxmega is not supported by the firmware.
*/
*/
    public void xmegaFuseWrite ( int addr, int val ) throws UsbException, InvalidFirmwareException, CapabilityException {
    public void xmegaFuseWrite ( int addr, int val ) throws UsbException, InvalidFirmwareException, CapabilityException {
        checkCapability(CAPABILITY_XMEGA);
        checkCapability(CAPABILITY_XMEGA);
 
 
        try {
        try {
            vendorCommand( 0x4d, "XMEGA Fuse write", val, addr);
            vendorCommand( 0x4d, "XMEGA Fuse write", val, addr);
        }
        }
        catch ( UsbException e ) {
        catch ( UsbException e ) {
            throw new UsbException( dev().dev(), "XMEGA Fuse write: " + xmegaStrError() );
            throw new UsbException( dev().dev(), "XMEGA Fuse write: " + xmegaStrError() );
        }
        }
        try {
        try {
            Thread.sleep( 3 );
            Thread.sleep( 3 );
        }
        }
        catch ( InterruptedException e) {
        catch ( InterruptedException e) {
        }
        }
    }
    }
 
 
// ******* xmegaIhxWrite *******************************************************
// ******* xmegaIhxWrite *******************************************************
/**
/**
  * Uploads data to NVM
  * Uploads data to NVM
*/
*/
    private long xmegaIhxWrite ( boolean toFlash, IhxFile ihxFile ) throws UsbException, InvalidFirmwareException, CapabilityException, FirmwareUploadException {
    private long xmegaIhxWrite ( boolean toFlash, IhxFile ihxFile ) throws UsbException, InvalidFirmwareException, CapabilityException, FirmwareUploadException {
        final int maxTries = 3;  // maximum amount of tries
        final int maxTries = 3;  // maximum amount of tries
        int pageSize = toFlash ? xmegaFlashPageSize() : xmegaEepromPageSize();
        int pageSize = toFlash ? xmegaFlashPageSize() : xmegaEepromPageSize();
        checkCapability(CAPABILITY_XMEGA);
        checkCapability(CAPABILITY_XMEGA);
 
 
        long t0 = new Date().getTime();
        long t0 = new Date().getTime();
 
 
        byte buf1[] = new byte[pageSize];
        byte buf1[] = new byte[pageSize];
        byte buf2[] = new byte[pageSize];
        byte buf2[] = new byte[pageSize];
 
 
        for (int i = 0; i<65536; i+=pageSize ) {
        for (int i = 0; i<65536; i+=pageSize ) {
 
 
            boolean b = false;
            boolean b = false;
            boolean c = true;
            boolean c = true;
            for ( int j=0; (j < pageSize ) && ( i+j < 65536 ); j++ ) {
            for ( int j=0; (j < pageSize ) && ( i+j < 65536 ); j++ ) {
                boolean d = (ihxFile.ihxData[i+j]>=0) && (ihxFile.ihxData[i+j]<=255);    // data vaild ?
                boolean d = (ihxFile.ihxData[i+j]>=0) && (ihxFile.ihxData[i+j]<=255);    // data vaild ?
                b |= d;
                b |= d;
                c &= d;
                c &= d;
            }
            }
            if ( b ) {   // page contains data ==> has to be written
            if ( b ) {   // page contains data ==> has to be written
//              System.out.print("Page " + i +": " );
//              System.out.print("Page " + i +": " );
 
 
                // read page, if firmware image contains undefined bytes
                // read page, if firmware image contains undefined bytes
                if ( ! c ) {
                if ( ! c ) {
//                  System.out.print("R");
//                  System.out.print("R");
                    if ( toFlash )
                    if ( toFlash )
                        xmegaFlashRead ( i, buf1, pageSize );
                        xmegaFlashRead ( i, buf1, pageSize );
                    else
                    else
                        xmegaEepromRead ( i, buf1, pageSize );
                        xmegaEepromRead ( i, buf1, pageSize );
                }
                }
 
 
                // prepare the page buffer
                // prepare the page buffer
                for ( int j=0; (j < pageSize ) && ( i+j < 65536 ); j++ ) {
                for ( int j=0; (j < pageSize ) && ( i+j < 65536 ); j++ ) {
                    if ( (ihxFile.ihxData[i+j]>=0) && (ihxFile.ihxData[i+j]<=255) )
                    if ( (ihxFile.ihxData[i+j]>=0) && (ihxFile.ihxData[i+j]<=255) )
                        buf1[j]= (byte) ihxFile.ihxData[i+j];
                        buf1[j]= (byte) ihxFile.ihxData[i+j];
                }
                }
 
 
                for ( int k=1; b ; k++ ) {
                for ( int k=1; b ; k++ ) {
                    // write the page
                    // write the page
//                  System.out.print("W");
//                  System.out.print("W");
                    if ( toFlash )
                    if ( toFlash )
                        xmegaFlashPageWrite ( i, buf1 );
                        xmegaFlashPageWrite ( i, buf1 );
                    else
                    else
                        xmegaEepromPageWrite ( i, buf1 );
                        xmegaEepromPageWrite ( i, buf1 );
 
 
                    // verify it
                    // verify it
//                  System.out.print("V");
//                  System.out.print("V");
                    if ( toFlash )
                    if ( toFlash )
                        xmegaFlashRead ( i, buf2, pageSize );
                        xmegaFlashRead ( i, buf2, pageSize );
                    else
                    else
                        xmegaEepromRead ( i, buf2, pageSize );
                        xmegaEepromRead ( i, buf2, pageSize );
                    b=false;
                    b=false;
                    for ( int j=0; (j < pageSize) && (! b ); j++ ) {
                    for ( int j=0; (j < pageSize) && (! b ); j++ ) {
                        b |= buf1[j] != buf2[j];
                        b |= buf1[j] != buf2[j];
                    }
                    }
                    if ( b ) {
                    if ( b ) {
                        if ( k<maxTries ) {
                        if ( k<maxTries ) {
                            System.err.println("Warning: xmegaWriteFirmware: Verification of " + ( toFlash ? "Flash" : "EEPROM" ) + " page" + i + " failed (try " + k +")" );
                            System.err.println("Warning: xmegaWriteFirmware: Verification of " + ( toFlash ? "Flash" : "EEPROM" ) + " page" + i + " failed (try " + k +")" );
                        }
                        }
                        else {
                        else {
                            System.err.println("Warning: xmegaWriteFirmware: Verification of " + ( toFlash ? "Flash" : "EEPROM" ) + " page " + i + " failed");
                            System.err.println("Warning: xmegaWriteFirmware: Verification of " + ( toFlash ? "Flash" : "EEPROM" ) + " page " + i + " failed");
                        }
                        }
                    }
                    }
                    b = false;
                    b = false;
 
 
//                  System.out.println();
//                  System.out.println();
                }
                }
            }
            }
        }
        }
 
 
        return new Date().getTime() - t0;
        return new Date().getTime() - t0;
    }
    }
 
 
 
 
 
 
// ******* xmegaWriteFirmware **************************************************
// ******* xmegaWriteFirmware **************************************************
/**
/**
  * Uploads firmware to the flash memory
  * Uploads firmware to the flash memory
  * @param ihxFile The firmware / data image.
  * @param ihxFile The firmware / data image.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if NVRAM access to ATxmega is not supported by the firmware.
  * @throws CapabilityException if NVRAM access to ATxmega is not supported by the firmware.
  * @throws FirmwareUploadException if the verification fails.
  * @throws FirmwareUploadException if the verification fails.
  * @return the upload time in ms.
  * @return the upload time in ms.
*/
*/
    public long xmegaWriteFirmware ( IhxFile ihxFile ) throws UsbException, InvalidFirmwareException, CapabilityException, FirmwareUploadException {
    public long xmegaWriteFirmware ( IhxFile ihxFile ) throws UsbException, InvalidFirmwareException, CapabilityException, FirmwareUploadException {
        return xmegaIhxWrite( true, ihxFile);
        return xmegaIhxWrite( true, ihxFile);
    }
    }
 
 
 
 
// ******* xmegaWriteEeprom ****************************************************
// ******* xmegaWriteEeprom ****************************************************
/**
/**
  * Uploads data to the EEPROM memory
  * Uploads data to the EEPROM memory
  * @param ihxFile The firmware / data image.
  * @param ihxFile The firmware / data image.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if NVRAM access to ATxmega is not supported by the firmware.
  * @throws CapabilityException if NVRAM access to ATxmega is not supported by the firmware.
  * @throws FirmwareUploadException if the verification fails.
  * @throws FirmwareUploadException if the verification fails.
  * @return the upload time in ms.
  * @return the upload time in ms.
*/
*/
    public long xmegaWriteEeprom ( IhxFile ihxFile ) throws UsbException, InvalidFirmwareException, CapabilityException, FirmwareUploadException {
    public long xmegaWriteEeprom ( IhxFile ihxFile ) throws UsbException, InvalidFirmwareException, CapabilityException, FirmwareUploadException {
        return xmegaIhxWrite( false, ihxFile);
        return xmegaIhxWrite( false, ihxFile);
    }
    }
 
 
 
 
// ******* toString ************************************************************
// ******* toString ************************************************************
/**
/**
  * Returns a lot of useful information about the corresponding device.
  * Returns a lot of useful information about the corresponding device.
  * @return 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 () {
        String str = dev().toString();
        String str = dev().toString();
        try {
        try {
            str += "\n   " + getFpgaConfigurationStr();
            str += "\n   " + getFpgaConfigurationStr();
        }
        }
        catch ( Exception e ) {
        catch ( Exception e ) {
        }
        }
        return str;
        return str;
    }
    }
 
 
// ******* capabilityInfo ******************************************************
// ******* capabilityInfo ******************************************************
/**
/**
  * Creates a String with capability information.
  * Creates a String with capability information.
  * @param pf A separator between the single capabilities, e.g. ", "
  * @param pf A separator between the single capabilities, e.g. ", "
  * @return a string of the supported capabilities.
  * @return a string of the supported capabilities.
  */
  */
    public String capabilityInfo ( String pf ) {
    public String capabilityInfo ( String pf ) {
        String str = "";
        String str = "";
        for ( int i=0; i<6; i++ )
        for ( int i=0; i<6; i++ )
            for (int j=0; j<8; j++ )
            for (int j=0; j<8; j++ )
                if ( dev().interfaceCapabilities(i,j) ) {
                if ( dev().interfaceCapabilities(i,j) ) {
                    if ( ! str.equals("") )
                    if ( ! str.equals("") )
                        str+=pf;
                        str+=pf;
                    if (i*8+j < capabilityStrings.length)
                    if (i*8+j < capabilityStrings.length)
                        str+=capabilityStrings[i*8+j];
                        str+=capabilityStrings[i*8+j];
                    else
                    else
                        str+=i+"."+j;
                        str+=i+"."+j;
                }
                }
        return str;
        return str;
    }
    }
// ******* configureFpgaHS *****************************************************
// ******* configureFpgaHS *****************************************************
//  returns configuration time in ms
//  returns configuration time in ms
/**
/**
  * Upload a Bitstream to the FPGA using high speed mode.
  * Upload a Bitstream to the FPGA using high speed mode.
  * @param inputStream for reading the Bitstream.
  * @param inputStream for reading the Bitstream.
  * @param force If set to true existing configurations will be overwritten. (By default an {@link AlreadyConfiguredException} is thrown).
  * @param force If set to true existing configurations will be overwritten. (By default an {@link AlreadyConfiguredException} is thrown).
  * @param bs 0: disable bit swapping, 1: enable bit swapping, all other values: automatic detection of bit order.
  * @param bs 0: disable bit swapping, 1: enable bit swapping, all other values: automatic detection of bit order.
  * @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
  * @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
  * @throws BitstreamUploadException if an error occurred while attempting to upload the Bitstream.
  * @throws BitstreamUploadException if an error occurred while attempting to upload the Bitstream.
  * @throws AlreadyConfiguredException if the FPGA is already configured.
  * @throws AlreadyConfiguredException if the FPGA is already configured.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if FPGA configuration is not supported by the firmware.
  * @throws CapabilityException if FPGA configuration is not supported by the firmware.
  */
  */
    public long configureFpgaHS ( InputStream inputStream, boolean force, int bs ) throws BitstreamReadException, UsbException, BitstreamUploadException, AlreadyConfiguredException, InvalidFirmwareException, CapabilityException {
    public long configureFpgaHS ( InputStream inputStream, boolean force, int bs ) throws BitstreamReadException, UsbException, BitstreamUploadException, AlreadyConfiguredException, InvalidFirmwareException, CapabilityException {
        final int transactionBytes = 16384;
        final int transactionBytes = 16384;
        long t0 = 0;
        long t0 = 0;
        byte[] settings = new byte[2];
        byte[] settings = new byte[2];
        boolean releaseIF;
        boolean releaseIF;
 
 
        checkCapability(CAPABILITY_HS_FPGA);
        checkCapability(CAPABILITY_HS_FPGA);
        vendorRequest2(0x33, "getHSFpgaSettings", settings, 2);
        vendorRequest2(0x33, "getHSFpgaSettings", settings, 2);
 
 
        if ( !force && getFpgaConfiguration() )
        if ( !force && getFpgaConfiguration() )
            throw new AlreadyConfiguredException();
            throw new AlreadyConfiguredException();
 
 
        releaseIF = ! getInterfaceClaimed(settings[1] & 255);
        releaseIF = ! getInterfaceClaimed(settings[1] & 255);
//      System.out.println("EP "+ settings[0] + "    IF "+settings[1]+ "   claim " + releaseIF);
//      System.out.println("EP "+ settings[0] + "    IF "+settings[1]+ "   claim " + releaseIF);
 
 
// read the Bitstream file      
// read the Bitstream file      
        byte[][] buffer = new byte[16*1024*1024/transactionBytes][];
        byte[][] buffer = new byte[16*1024*1024/transactionBytes][];
        int size = 0;
        int size = 0;
        try {
        try {
            int j = transactionBytes;
            int j = transactionBytes;
            for ( int i=0; i<buffer.length && j==transactionBytes; i++ ) {
            for ( int i=0; i<buffer.length && j==transactionBytes; i++ ) {
                buffer[i] = new byte[transactionBytes];
                buffer[i] = new byte[transactionBytes];
                int k;
                int k;
                j = 0;
                j = 0;
                do {
                do {
                    k = inputStream.read( buffer[i], j, transactionBytes-j );
                    k = inputStream.read( buffer[i], j, transactionBytes-j );
                    if ( k < 0 )
                    if ( k < 0 )
                        k = 0;
                        k = 0;
                    j += k;
                    j += k;
                }
                }
                while ( j<transactionBytes && k>0 );
                while ( j<transactionBytes && k>0 );
                size += j;
                size += j;
            }
            }
 
 
            try {
            try {
                inputStream.close();
                inputStream.close();
            }
            }
            catch ( Exception e ) {
            catch ( Exception e ) {
            }
            }
        }
        }
        catch (IOException e) {
        catch (IOException e) {
            throw new BitstreamReadException(e.getLocalizedMessage());
            throw new BitstreamReadException(e.getLocalizedMessage());
        }
        }
 
 
        if ( size < 64 )
        if ( size < 64 )
            throw new BitstreamReadException("Invalid file size: " + size );
            throw new BitstreamReadException("Invalid file size: " + size );
 
 
// detect bitstream bit order and swap bits if necessary 
// detect bitstream bit order and swap bits if necessary 
        if ( bs<0 || bs>1 )
        if ( bs<0 || bs>1 )
            bs = detectBitstreamBitOrder ( buffer[0] );
            bs = detectBitstreamBitOrder ( buffer[0] );
        if ( bs == 1 )
        if ( bs == 1 )
            swapBits(buffer,size);
            swapBits(buffer,size);
 
 
// remove NOP's from the end
// remove NOP's from the end
/*      System.out.println(size);
/*      System.out.println(size);
        while ( size-2>=0 && buffer[(size-2) / transactionBytes][(size-2) % transactionBytes] == 4 && buffer[(size-1) / transactionBytes][(size-1) % transactionBytes]==0 )
        while ( size-2>=0 && buffer[(size-2) / transactionBytes][(size-2) % transactionBytes] == 4 && buffer[(size-1) / transactionBytes][(size-1) % transactionBytes]==0 )
            size-=2;
            size-=2;
        System.out.println(size);
        System.out.println(size);
*/
*/
 
 
// claim interface if required
// claim interface if required
        if ( releaseIF ) claimInterface( settings[1] & 255 );
        if ( releaseIF ) claimInterface( settings[1] & 255 );
 
 
//      System.out.println(size & 127);
//      System.out.println(size & 127);
 
 
// upload the Bitstream file    
// upload the Bitstream file    
        for ( int tries=3; tries>0; tries-- ) {
        for ( int tries=3; tries>0; tries-- ) {
 
 
            vendorCommand(0x34, "initHSFPGAConfiguration" );
            vendorCommand(0x34, "initHSFPGAConfiguration" );
 
 
            try {
            try {
                t0 = -new Date().getTime();
                t0 = -new Date().getTime();
 
 
                for ( int i=0; i<buffer.length && i*transactionBytes < size; i++ ) {
                for ( int i=0; i<buffer.length && i*transactionBytes < size; i++ ) {
                    int j = size-i*transactionBytes;
                    int j = size-i*transactionBytes;
                    if (j>transactionBytes)
                    if (j>transactionBytes)
                        j = transactionBytes;
                        j = transactionBytes;
 
 
                    if ( j>0 ) {
                    if ( j>0 ) {
                        int l = LibusbJava.usb_bulk_write(handle(), settings[0] & 255, buffer[i], j, 1000);
                        int l = LibusbJava.usb_bulk_write(handle(), settings[0] & 255, buffer[i], j, 1000);
                        if ( l < 0 )
                        if ( l < 0 )
                            throw new UsbException("Error sending Bitstream: " + l + ": " + LibusbJava.usb_strerror());
                            throw new UsbException("Error sending Bitstream: " + l + ": " + LibusbJava.usb_strerror());
                        else if ( l != j )
                        else if ( l != j )
                            throw new UsbException("Error sending Bitstream: Sent " + l +" of " + j + " bytes");
                            throw new UsbException("Error sending Bitstream: Sent " + l +" of " + j + " bytes");
                    }
                    }
                }
                }
 
 
                try {
                try {
                    Thread.sleep( (size % transactionBytes) / 1000 + 10 );
                    Thread.sleep( (size % transactionBytes) / 1000 + 10 );
                }
                }
                catch ( InterruptedException e) {
                catch ( InterruptedException e) {
                }
                }
 
 
                vendorCommand(0x35, "finishHSFPGAConfiguration" );
                vendorCommand(0x35, "finishHSFPGAConfiguration" );
                t0 += new Date().getTime();
                t0 += new Date().getTime();
 
 
                getFpgaState();
                getFpgaState();
//              System.err.println("fpgaConfigred=" + fpgaConfigured + "   fpgaBytes="+fpgaBytes + " ("+size+")   fpgaInitB="+fpgaInitB + "  time=" + t0);
//              System.err.println("fpgaConfigred=" + fpgaConfigured + "   fpgaBytes="+fpgaBytes + " ("+size+")   fpgaInitB="+fpgaInitB + "  time=" + t0);
                if ( ! fpgaConfigured ) {
                if ( ! fpgaConfigured ) {
                    throw new BitstreamUploadException( "FPGA configuration failed: DONE pin does not go high, possible USB transfer errors (INIT_B_HIST=" + fpgaInitB + (fpgaBytes==0 ? "" : "; " + (size - fpgaBytes) + " bytes got lost") + ")" );
                    throw new BitstreamUploadException( "FPGA configuration failed: DONE pin does not go high, possible USB transfer errors (INIT_B_HIST=" + fpgaInitB + (fpgaBytes==0 ? "" : "; " + (size - fpgaBytes) + " bytes got lost") + ")" );
                }
                }
 
 
                if ( enableExtraFpgaConfigurationChecks ) {
                if ( enableExtraFpgaConfigurationChecks ) {
                    if ( fpgaBytes!=0 && fpgaBytes!=size )
                    if ( fpgaBytes!=0 && fpgaBytes!=size )
                        System.err.println("Warning: Possible FPGA configuration data loss: " + (size - fpgaBytes) + " bytes got lost");
                        System.err.println("Warning: Possible FPGA configuration data loss: " + (size - fpgaBytes) + " bytes got lost");
                    if ( fpgaInitB!=222 )
                    if ( fpgaInitB!=222 )
                        System.err.println("Warning: Possible Bitstream CRC error: INIT_B_HIST=" + fpgaInitB );
                        System.err.println("Warning: Possible Bitstream CRC error: INIT_B_HIST=" + fpgaInitB );
                }
                }
 
 
                tries = 0;
                tries = 0;
            }
            }
            catch ( BitstreamUploadException e ) {
            catch ( BitstreamUploadException e ) {
                if (tries == 1)
                if (tries == 1)
                    throw e;
                    throw e;
                else if ( tries<3 || enableExtraFpgaConfigurationChecks )
                else if ( tries<3 || enableExtraFpgaConfigurationChecks )
                    System.err.println("Warning: " + e.getLocalizedMessage() +": Retrying it ...");
                    System.err.println("Warning: " + e.getLocalizedMessage() +": Retrying it ...");
            }
            }
        }
        }
 
 
        if ( releaseIF ) releaseInterface( settings[1] & 255 );
        if ( releaseIF ) releaseInterface( settings[1] & 255 );
 
 
        try {
        try {
            Thread.sleep( 25 );
            Thread.sleep( 25 );
        }
        }
        catch ( InterruptedException e) {
        catch ( InterruptedException e) {
        }
        }
 
 
        return t0;
        return t0;
    }
    }
 
 
//  returns configuration time in ms
//  returns configuration time in ms
/**
/**
  * Upload a Bitstream to the FPGA using high speed mode.
  * Upload a Bitstream to the FPGA using high speed mode.
  * @param fwFileName The file name of the Bitstream. The file can be a regular file or a system resource (e.g. a file from the current jar archive).
  * @param fwFileName The file name of the Bitstream. The file can be a regular file or a system resource (e.g. a file from the current jar archive).
  * @param force If set to true existing configurations will be overwritten. (By default an {@link AlreadyConfiguredException} is thrown).
  * @param force If set to true existing configurations will be overwritten. (By default an {@link AlreadyConfiguredException} is thrown).
  * @param bs 0: disable bit swapping, 1: enable bit swapping, all other values: automatic detection of bit order.
  * @param bs 0: disable bit swapping, 1: enable bit swapping, all other values: automatic detection of bit order.
  * @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
  * @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
  * @throws BitstreamUploadException if an error occurred while attempting to upload the Bitstream.
  * @throws BitstreamUploadException if an error occurred while attempting to upload the Bitstream.
  * @throws AlreadyConfiguredException if the FPGA is already configured.
  * @throws AlreadyConfiguredException if the FPGA is already configured.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if FPGA configuration is not supported by the firmware.
  * @throws CapabilityException if FPGA configuration is not supported by the firmware.
  */
  */
    public long configureFpgaHS ( String fwFileName, boolean force, int bs ) throws BitstreamReadException, UsbException, BitstreamUploadException, AlreadyConfiguredException, InvalidFirmwareException, CapabilityException {
    public long configureFpgaHS ( String fwFileName, boolean force, int bs ) throws BitstreamReadException, UsbException, BitstreamUploadException, AlreadyConfiguredException, InvalidFirmwareException, CapabilityException {
        try {
        try {
            return configureFpgaHS( JInputStream.getInputStream( fwFileName ), force, bs );
            return configureFpgaHS( JInputStream.getInputStream( fwFileName ), force, bs );
        }
        }
        catch (IOException e) {
        catch (IOException e) {
            throw new BitstreamReadException(e.getLocalizedMessage());
            throw new BitstreamReadException(e.getLocalizedMessage());
        }
        }
    }
    }
 
 
// ******* configureFpga *****************************************************
// ******* configureFpga *****************************************************
//  returns configuration time in ms
//  returns configuration time in ms
/**
/**
  * Upload a Bitstream to the FPGA using high speed mode (if available) or low speed mode.
  * Upload a Bitstream to the FPGA using high speed mode (if available) or low speed mode.
  * @param inputStream for reading the Bitstream.
  * @param inputStream for reading the Bitstream.
  * @param force If set to true existing configurations will be overwritten. (By default an {@link AlreadyConfiguredException} is thrown).
  * @param force If set to true existing configurations will be overwritten. (By default an {@link AlreadyConfiguredException} is thrown).
  * @param bs 0: disable bit swapping, 1: enable bit swapping, all other values: automatic detection of bit order.
  * @param bs 0: disable bit swapping, 1: enable bit swapping, all other values: automatic detection of bit order.
  * @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
  * @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
  * @throws BitstreamUploadException if an error occurred while attempting to upload the Bitstream.
  * @throws BitstreamUploadException if an error occurred while attempting to upload the Bitstream.
  * @throws AlreadyConfiguredException if the FPGA is already configured.
  * @throws AlreadyConfiguredException if the FPGA is already configured.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if FPGA configuration is not supported by the firmware.
  * @throws CapabilityException if FPGA configuration is not supported by the firmware.
  * @throws IOException if mark/reset is not supported
  * @throws IOException if mark/reset is not supported
  */
  */
    public long configureFpga ( InputStream inputStream, boolean force, int bs ) throws BitstreamReadException, UsbException, BitstreamUploadException, AlreadyConfiguredException, InvalidFirmwareException, CapabilityException, IOException {
    public long configureFpga ( InputStream inputStream, boolean force, int bs ) throws BitstreamReadException, UsbException, BitstreamUploadException, AlreadyConfiguredException, InvalidFirmwareException, CapabilityException, IOException {
        try {
        try {
            inputStream.mark(64*1024*1024);
            inputStream.mark(64*1024*1024);
            return configureFpgaHS( inputStream, force, bs );
            return configureFpgaHS( inputStream, force, bs );
        }
        }
        catch ( CapabilityException e ) {
        catch ( CapabilityException e ) {
            return configureFpgaLS( inputStream, force, bs );
            return configureFpgaLS( inputStream, force, bs );
        }
        }
        catch ( UsbException e ) {
        catch ( UsbException e ) {
            System.err.println("Warning: High speed FPGA configuration failed, trying low speed mode:" + e.getLocalizedMessage() +": Trying low speed mode");
            System.err.println("Warning: High speed FPGA configuration failed, trying low speed mode:" + e.getLocalizedMessage() +": Trying low speed mode");
            inputStream.reset();
            inputStream.reset();
            return configureFpgaLS( inputStream, force, bs );
            return configureFpgaLS( inputStream, force, bs );
        }
        }
        catch ( BitstreamUploadException e ) {
        catch ( BitstreamUploadException e ) {
            System.err.println("Warning: High speed FPGA configuration failed, trying low speed mode:" + e.getLocalizedMessage() +": Trying low speed mode");
            System.err.println("Warning: High speed FPGA configuration failed, trying low speed mode:" + e.getLocalizedMessage() +": Trying low speed mode");
            inputStream.reset();
            inputStream.reset();
            return configureFpgaLS( inputStream, force, bs );
            return configureFpgaLS( inputStream, force, bs );
        }
        }
    }
    }
 
 
//  returns configuration time in ms
//  returns configuration time in ms
/**
/**
  * Upload a Bitstream to the FPGA using high speed mode (if available) or low speed mode.
  * Upload a Bitstream to the FPGA using high speed mode (if available) or low speed mode.
  * @param fwFileName The file name of the Bitstream. The file can be a regular file or a system resource (e.g. a file from the current jar archive).
  * @param fwFileName The file name of the Bitstream. The file can be a regular file or a system resource (e.g. a file from the current jar archive).
  * @param force If set to true existing configurations will be overwritten. (By default an {@link AlreadyConfiguredException} is thrown).
  * @param force If set to true existing configurations will be overwritten. (By default an {@link AlreadyConfiguredException} is thrown).
  * @param bs 0: disable bit swapping, 1: enable bit swapping, all other values: automatic detection of bit order.
  * @param bs 0: disable bit swapping, 1: enable bit swapping, all other values: automatic detection of bit order.
  * @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
  * @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
  * @throws BitstreamUploadException if an error occurred while attempting to upload the Bitstream.
  * @throws BitstreamUploadException if an error occurred while attempting to upload the Bitstream.
  * @throws AlreadyConfiguredException if the FPGA is already configured.
  * @throws AlreadyConfiguredException if the FPGA is already configured.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if FPGA configuration is not supported by the firmware.
  * @throws CapabilityException if FPGA configuration is not supported by the firmware.
  */
  */
    public long configureFpga ( String fwFileName, boolean force, int bs ) throws BitstreamReadException, UsbException, BitstreamUploadException, AlreadyConfiguredException, InvalidFirmwareException, CapabilityException {
    public long configureFpga ( String fwFileName, boolean force, int bs ) throws BitstreamReadException, UsbException, BitstreamUploadException, AlreadyConfiguredException, InvalidFirmwareException, CapabilityException {
        try {
        try {
            return configureFpgaHS( fwFileName, force, bs );
            return configureFpgaHS( fwFileName, force, bs );
        }
        }
        catch ( CapabilityException e ) {
        catch ( CapabilityException e ) {
            return configureFpgaLS( fwFileName, force, bs );
            return configureFpgaLS( fwFileName, force, bs );
        }
        }
        catch ( UsbException e ) {
        catch ( UsbException e ) {
            System.err.println("Warning: High speed FPGA configuration failed, trying low speed mode:" + e.getLocalizedMessage() +": Trying low speed mode");
            System.err.println("Warning: High speed FPGA configuration failed, trying low speed mode:" + e.getLocalizedMessage() +": Trying low speed mode");
            return configureFpgaLS( fwFileName, force, bs );
            return configureFpgaLS( fwFileName, force, bs );
        }
        }
        catch ( BitstreamUploadException e ) {
        catch ( BitstreamUploadException e ) {
            System.err.println("Warning: High speed FPGA configuration failed, trying low speed mode:" + e.getLocalizedMessage() +": Trying low speed mode");
            System.err.println("Warning: High speed FPGA configuration failed, trying low speed mode:" + e.getLocalizedMessage() +": Trying low speed mode");
            return configureFpgaLS( fwFileName, force, bs );
            return configureFpgaLS( fwFileName, force, bs );
        }
        }
    }
    }
 
 
/**
/**
  * Upload a Bitstream to the FPGA using high speed mode (if available) or low speed mode.
  * Upload a Bitstream to the FPGA using high speed mode (if available) or low speed mode.
  * @param fwFileName The file name of the Bitstream. The file can be a regular file or a system resource (e.g. a file from the current jar archive).
  * @param fwFileName The file name of the Bitstream. The file can be a regular file or a system resource (e.g. a file from the current jar archive).
  * @param force If set to true existing configurations will be overwritten. (By default an {@link AlreadyConfiguredException} is thrown).
  * @param force If set to true existing configurations will be overwritten. (By default an {@link AlreadyConfiguredException} is thrown).
  * @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
  * @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
  * @throws BitstreamUploadException if an error occurred while attempting to upload the Bitstream.
  * @throws BitstreamUploadException if an error occurred while attempting to upload the Bitstream.
  * @throws AlreadyConfiguredException if the FPGA is already configured.
  * @throws AlreadyConfiguredException if the FPGA is already configured.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if FPGA configuration is not supported by the firmware.
  * @throws CapabilityException if FPGA configuration is not supported by the firmware.
  */
  */
    public long configureFpga ( String fwFileName, boolean force ) throws BitstreamReadException, UsbException, BitstreamUploadException, AlreadyConfiguredException, InvalidFirmwareException, CapabilityException {
    public long configureFpga ( String fwFileName, boolean force ) throws BitstreamReadException, UsbException, BitstreamUploadException, AlreadyConfiguredException, InvalidFirmwareException, CapabilityException {
        return configureFpga(fwFileName, force, -1);
        return configureFpga(fwFileName, force, -1);
    }
    }
 
 
// ******* macEepromWrite ******************************************************
// ******* macEepromWrite ******************************************************
/**
/**
  * Writes data to the MAC EEPROM.
  * Writes data to the MAC EEPROM.
  * @param addr The destination address of the MAC EEPROM.
  * @param addr The destination address of the MAC EEPROM.
  * @param buf The data.
  * @param buf The data.
  * @param length The amount of bytes to be sent.
  * @param length The amount of bytes to be sent.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if MAC EEPROM access is not supported by the firmware or if configuration data is present and there is a write to addresses 0 to 79. In order to override this behavior set {@link #config} variable to null.
  * @throws CapabilityException if MAC EEPROM access is not supported by the firmware or if configuration data is present and there is a write to addresses 0 to 79. In order to override this behavior set {@link #config} variable to null.
  */
  */
    public void macEepromWrite ( int addr, byte[] buf, int length ) throws UsbException, InvalidFirmwareException, CapabilityException {
    public void macEepromWrite ( int addr, byte[] buf, int length ) throws UsbException, InvalidFirmwareException, CapabilityException {
        checkCapability(CAPABILITY_MAC_EEPROM);
        checkCapability(CAPABILITY_MAC_EEPROM);
        if ( ( config != null ) && ( addr<80 ))
        if ( ( config != null ) && ( addr<80 ))
            throw new CapabilityException(this, "Overwriting configuration data in MAC EEPROM");
            throw new CapabilityException(this, "Overwriting configuration data in MAC EEPROM");
        vendorCommand2( 0x3C, "MAC EEPROM Write", addr, 0, buf, length );
        vendorCommand2( 0x3C, "MAC EEPROM Write", addr, 0, buf, length );
        try {
        try {
            Thread.sleep( 10 );
            Thread.sleep( 10 );
        }
        }
        catch ( InterruptedException e) {
        catch ( InterruptedException e) {
        }
        }
    }
    }
 
 
// ******* macEepromRead *******************************************************
// ******* macEepromRead *******************************************************
/**
/**
  * Reads data from the MAC EEPROM.
  * Reads data from the MAC EEPROM.
  * @param addr The source address of the MAC EEPROM.
  * @param addr The source address of the MAC EEPROM.
  * @param buf A buffer for the storage of the data.
  * @param buf A buffer for the storage of the data.
  * @param length The amount of bytes to be read.
  * @param length The amount of bytes to be read.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if MAC EEPROM access is not supported by the firmware.
  * @throws CapabilityException if MAC EEPROM access is not supported by the firmware.
  */
  */
    public void macEepromRead ( int addr, byte[] buf, int length ) throws UsbException, InvalidFirmwareException, CapabilityException {
    public void macEepromRead ( int addr, byte[] buf, int length ) throws UsbException, InvalidFirmwareException, CapabilityException {
        checkCapability(CAPABILITY_MAC_EEPROM);
        checkCapability(CAPABILITY_MAC_EEPROM);
        vendorRequest2( 0x3B, "MAC EEPROM Read", addr, 0, buf, length );
        vendorRequest2( 0x3B, "MAC EEPROM Read", addr, 0, buf, length );
        try {
        try {
            Thread.sleep( 10 );
            Thread.sleep( 10 );
        }
        }
        catch ( InterruptedException e) {
        catch ( InterruptedException e) {
        }
        }
    }
    }
 
 
// ******* macEepromState ******************************************************
// ******* macEepromState ******************************************************
// returns true if MAC EEPROM is ready
// returns true if MAC EEPROM is ready
/**
/**
  * Reads the current MAC EEPROM status.
  * Reads the current MAC EEPROM status.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if MAC EEPROM access is not supported by the firmware.
  * @throws CapabilityException if MAC EEPROM access is not supported by the firmware.
  * @return true if MAC EEPROM is ready.
  * @return true if MAC EEPROM is ready.
  */
  */
    public boolean macEepromState ( ) throws UsbException, InvalidFirmwareException, CapabilityException {
    public boolean macEepromState ( ) throws UsbException, InvalidFirmwareException, CapabilityException {
        byte[] buf = new byte[1];
        byte[] buf = new byte[1];
        checkCapability(CAPABILITY_MAC_EEPROM);
        checkCapability(CAPABILITY_MAC_EEPROM);
        vendorRequest2(0x3D, "MAC EEPROM State", 0, 0, buf, 1);
        vendorRequest2(0x3D, "MAC EEPROM State", 0, 0, buf, 1);
        return buf[0] == 0;
        return buf[0] == 0;
    }
    }
 
 
// ******* macRead *************************************************************
// ******* macRead *************************************************************
/**
/**
  * Reads MAC address from MAC EEPROM.
  * Reads MAC address from MAC EEPROM.
  * @param buf A buffer with a minimum size of 6 bytes.
  * @param buf A buffer with a minimum size of 6 bytes.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if MAC EEPROM access is not supported by the firmware.
  * @throws CapabilityException if MAC EEPROM access is not supported by the firmware.
  * @throws IndexOutOfBoundsException If the buffer is smaller than 6 bytes.
  * @throws IndexOutOfBoundsException If the buffer is smaller than 6 bytes.
  */
  */
    public void macRead ( byte[] buf ) throws UsbException, InvalidFirmwareException, CapabilityException, IndexOutOfBoundsException {
    public void macRead ( byte[] buf ) throws UsbException, InvalidFirmwareException, CapabilityException, IndexOutOfBoundsException {
        if ( buf.length < 6 )
        if ( buf.length < 6 )
            throw new IndexOutOfBoundsException( "macRead: Buffer smaller than 6 Bytes" );
            throw new IndexOutOfBoundsException( "macRead: Buffer smaller than 6 Bytes" );
        macEepromRead(250, buf, 6);
        macEepromRead(250, buf, 6);
    }
    }
 
 
// ******* numberOfFpgas *******************************************************
// ******* numberOfFpgas *******************************************************
/**
/**
  * Returns the number of FPGA's
  * Returns the number of FPGA's
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @return number of FPGA's
  * @return number of FPGA's
  */
  */
    public int numberOfFpgas ( ) throws UsbException, InvalidFirmwareException {
    public int numberOfFpgas ( ) throws UsbException, InvalidFirmwareException {
        if ( numberOfFpgas < 0 ) {
        if ( numberOfFpgas < 0 ) {
            try {
            try {
                byte[] buffer = new byte[3];
                byte[] buffer = new byte[3];
                checkCapability(CAPABILITY_MULTI_FPGA);
                checkCapability(CAPABILITY_MULTI_FPGA);
                vendorRequest2(0x50, "getMultiFpgaInfo", buffer, 3);
                vendorRequest2(0x50, "getMultiFpgaInfo", buffer, 3);
                numberOfFpgas = (buffer[0] & 255)+1;
                numberOfFpgas = (buffer[0] & 255)+1;
                selectedFpga = buffer[1] & 255;
                selectedFpga = buffer[1] & 255;
                parallelConfigSupport = buffer[2]==1;
                parallelConfigSupport = buffer[2]==1;
            }
            }
            catch ( CapabilityException e ) {
            catch ( CapabilityException e ) {
                numberOfFpgas = 1;
                numberOfFpgas = 1;
                selectedFpga = 0;
                selectedFpga = 0;
                parallelConfigSupport = false;
                parallelConfigSupport = false;
            }
            }
        }
        }
        return numberOfFpgas;
        return numberOfFpgas;
    }
    }
 
 
// ******* selectFpga **********************************************************
// ******* selectFpga **********************************************************
/**
/**
  * Select a FPGA
  * Select a FPGA
  * @param num FPGA to select. Valid values are 0 to {@link #numberOfFpgas()}-1
  * @param num FPGA to select. Valid values are 0 to {@link #numberOfFpgas()}-1
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws IndexOutOfBoundsException If FPGA number is not in range.
  * @throws IndexOutOfBoundsException If FPGA number is not in range.
  */
  */
    public void selectFpga ( int num ) throws UsbException, InvalidFirmwareException, IndexOutOfBoundsException {
    public void selectFpga ( int num ) throws UsbException, InvalidFirmwareException, IndexOutOfBoundsException {
        numberOfFpgas();
        numberOfFpgas();
        if ( num<0 || num>=numberOfFpgas )
        if ( num<0 || num>=numberOfFpgas )
            throw new IndexOutOfBoundsException( "selectFPGA: Invalid FPGA number" );
            throw new IndexOutOfBoundsException( "selectFPGA: Invalid FPGA number" );
 
 
        if ( numberOfFpgas != 1 ) {
        if ( numberOfFpgas != 1 ) {
            try {
            try {
                checkCapability(CAPABILITY_MULTI_FPGA);
                checkCapability(CAPABILITY_MULTI_FPGA);
                vendorCommand( 0x51, "selectFPGA", num, 0);
                vendorCommand( 0x51, "selectFPGA", num, 0);
            }
            }
            catch ( CapabilityException e ) {
            catch ( CapabilityException e ) {
                // should'nt occur
                // should'nt occur
            }
            }
        }
        }
        selectedFpga = num;
        selectedFpga = num;
    }
    }
 
 
// ******* TempSensorRead ******************************************************
// ******* TempSensorRead ******************************************************
/**
/**
  * Read temperature sensor data.
  * Read temperature sensor data.
  * @param idx Temperature sensor index
  * @param idx Temperature sensor index
  * @return Temperature in deg. C
  * @return Temperature in deg. C
  * @throws InvalidFirmwareException If interface 1 or temperature sensor protocol is not supported.
  * @throws InvalidFirmwareException If interface 1 or temperature sensor protocol is not supported.
  * @throws UsbException If a communication error occurs.
  * @throws UsbException If a communication error occurs.
  * @throws CapabilityException If NVRAM access to ATxmega is not supported by the firmware.
  * @throws CapabilityException If NVRAM access to ATxmega is not supported by the firmware.
  * @throws IndexOutOfBoundsException If idx is not in range.
  * @throws IndexOutOfBoundsException If idx is not in range.
  */
  */
    public double tempSensorRead ( int idx ) throws UsbException, InvalidFirmwareException, CapabilityException, IndexOutOfBoundsException {
    public double tempSensorRead ( int idx ) throws UsbException, InvalidFirmwareException, CapabilityException, IndexOutOfBoundsException {
        int[] xIdx = { 3, 4, 1, 2 };
        int[] xIdx = { 3, 4, 1, 2 };
 
 
        checkCapability(CAPABILITY_TEMP_SENSOR);
        checkCapability(CAPABILITY_TEMP_SENSOR);
 
 
        int len = 0;
        int len = 0;
 
 
        if ( tempSensorUpdateInterval < 40 )
        if ( tempSensorUpdateInterval < 40 )
            tempSensorUpdateInterval = 40;
            tempSensorUpdateInterval = 40;
 
 
        if ( new Date().getTime() > lastTempSensorReadTime+tempSensorUpdateInterval ) {
        if ( new Date().getTime() > lastTempSensorReadTime+tempSensorUpdateInterval ) {
            len = vendorRequest( 0x58, "Temperature Sensor Read", 0, 0, tempSensorBuf, tempSensorBuf.length );
            len = vendorRequest( 0x58, "Temperature Sensor Read", 0, 0, tempSensorBuf, tempSensorBuf.length );
            lastTempSensorReadTime = new Date().getTime();
            lastTempSensorReadTime = new Date().getTime();
 
 
            if ( len != 5 || tempSensorBuf[0] != 1 )
            if ( len != 5 || tempSensorBuf[0] != 1 )
                throw new InvalidFirmwareException("tempSensorRead: Invalid temperature sensor protocol");
                throw new InvalidFirmwareException("tempSensorRead: Invalid temperature sensor protocol");
        }
        }
 
 
        if ( idx<0 || idx>3 )
        if ( idx<0 || idx>3 )
            throw new IndexOutOfBoundsException( "tempSensorRead: Invalid temperature sensor index" );
            throw new IndexOutOfBoundsException( "tempSensorRead: Invalid temperature sensor index" );
 
 
        return ((tempSensorBuf[xIdx[idx]] & 255)-77.2727)/1.5454;
        return ((tempSensorBuf[xIdx[idx]] & 255)-77.2727)/1.5454;
    }
    }
 
 
// ******* printSpiState *******************************************************
// ******* printSpiState *******************************************************
// returns true if Flash is available
// returns true if Flash is available
/**
/**
  * Prints out some debug information about SPI Flash.<br>
  * Prints out some debug information about SPI Flash.<br>
  * <b>Only use this method if such kind of Flash is installed.</b>
  * <b>Only use this method if such kind of Flash is installed.</b>
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws InvalidFirmwareException if interface 1 is not supported.
  * @throws UsbException if a communication error occurs.
  * @throws UsbException if a communication error occurs.
  * @throws CapabilityException if Flash memory access is not supported by the firmware.
  * @throws CapabilityException if Flash memory access is not supported by the firmware.
  */
  */
    public boolean printSpiState ( ) throws UsbException, InvalidFirmwareException, CapabilityException {
    public boolean printSpiState ( ) throws UsbException, InvalidFirmwareException, CapabilityException {
        byte[] buf = new byte[10];
        byte[] buf = new byte[10];
        checkCapability(CAPABILITY_FLASH);
        checkCapability(CAPABILITY_FLASH);
        vendorRequest2(0x43, "SPI State", 0, 0, buf, 10);
        vendorRequest2(0x43, "SPI State", 0, 0, buf, 10);
        System.out.println("ec=" + buf[0] +
        System.out.println("ec=" + buf[0] +
                "   vendor=" + Integer.toHexString(buf[1] & 255).toUpperCase() + "h" +
                "   vendor=" + Integer.toHexString(buf[1] & 255).toUpperCase() + "h" +
                "   device=" + Integer.toHexString(buf[2] & 255).toUpperCase() + "h" +
                "   device=" + Integer.toHexString(buf[2] & 255).toUpperCase() + "h" +
                "   memType=" + Integer.toHexString(buf[3] & 255).toUpperCase() + "h" +
                "   memType=" + Integer.toHexString(buf[3] & 255).toUpperCase() + "h" +
                "   eraseCmd=" + Integer.toHexString(buf[4] & 255).toUpperCase() + "h" +
                "   eraseCmd=" + Integer.toHexString(buf[4] & 255).toUpperCase() + "h" +
                "   lastCmd=" + Integer.toHexString(buf[5] & 255).toUpperCase() + "h" +
                "   lastCmd=" + Integer.toHexString(buf[5] & 255).toUpperCase() + "h" +
                "   buf=" + (buf[6] & 255)+" "+(buf[7] & 255)+" "+(buf[8] & 255)+" "+(buf[9] & 255)
                "   buf=" + (buf[6] & 255)+" "+(buf[7] & 255)+" "+(buf[8] & 255)+" "+(buf[9] & 255)
            );
            );
        return flashEnabled == 1;
        return flashEnabled == 1;
    }
    }
 
 
}
}
 
 
 
 

powered by: WebSVN 2.1.0

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