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

Subversion Repositories usb_fpga_1_11

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /usb_fpga_1_11/trunk/java
    from Rev 7 to Rev 8
    Reverse comparison

Rev 7 → Rev 8

/FWLoader.java File deleted
/DeviceServer/DeviceServer.java
0,0 → 1,1807
/*!
Firmware / Bitstream loader for the ZTEX EZ-USB FX2 SDK
Copyright (C) 2009-2011 ZTEX GmbH.
http://www.ztex.de
 
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
published by the Free Software Foundation.
 
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, see http://www.gnu.org/licenses/.
!*/
 
/*
ZTEX device server
*/
 
import java.io.*;
import java.util.*;
import java.text.*;
import java.net.*;
 
import com.sun.net.httpserver.*;
 
import ch.ntb.usb.*;
 
import ztex.*;
 
// *****************************************************************************
// ******* ErrorBuffer *********************************************************
// *****************************************************************************
class ErrorBuffer {
private static final int bufsize = 128;
private static String cids[] = new String[bufsize];
private static StringBuilder messages[] = new StringBuilder[bufsize];
private static int id[] = new int[bufsize];
private static boolean initialized = false;
private static int idcnt = 0;
 
private static void initialize() {
if ( ! initialized ) {
for ( int i=0; i<bufsize; i++ )
id[i]=-1;
initialized = true;
}
}
public static void add (String cid, StringBuilder message) {
if (cid==null) return;
initialize();
int j=0, k=-1;
for ( int i=0; i<bufsize; i++ ) {
if ( id[i]<id[j] ) j=i;
if ( id[i]>=0 && cid.equals(cids[i]) ) k=i;
}
if ( k>=0 ) {
messages[k].append(message);
}
else {
id[j] = idcnt;
idcnt ++;
messages[j] = message;
cids[j] = cid;
}
}
 
public static StringBuilder get (String cid) {
if (cid==null) return null;
initialize();
for ( int i=0; i<bufsize; i++ ) {
if ( id[i]>=0 && cid.equals(cids[i]) ) {
id[i] = -1;
return messages[i];
}
}
return null;
}
}
 
// *****************************************************************************
// ******* NonBlockingBufferedInputStream **************************************
// *****************************************************************************
class NonBlockingBufferedInputStream extends BufferedInputStream {
private final int timeout = 1000;
private final int delay = 10;
NonBlockingBufferedInputStream(InputStream in) {
super(in);
}
public int read( byte[] b, int off, int len) throws IOException {
int cnt=0, a=1;
while ( len > 0 && a>0 ) {
a=available();
int to=0;
while ( a<1 && to<timeout ) {
try {
Thread.sleep( delay );
}
catch ( InterruptedException e) {
}
a=available();
to+=delay;
}
if (a > len ) a=len;
if ( a > 0 ) super.read(b, off, a);
off+=a;
len-=a;
cnt+=a;
}
return cnt;
}
 
public void close() {
}
 
}
 
// *****************************************************************************
// ******* SocketThread ********************************************************
// *****************************************************************************
class SocketThread extends Thread {
private Socket socket;
private PrintStream printer = null;
private BufferedOutputStream binOut = null;
private NonBlockingBufferedInputStream in = null;
// ******* SocketThread ********************************************************
public SocketThread ( Socket s ) {
socket = s;
DeviceServer.addSocket(socket);
start();
}
// ******* out *****************************************************************
private BufferedOutputStream binOut() throws IOException {
if ( binOut == null ) binOut = new BufferedOutputStream( socket.getOutputStream() );
if ( printer != null ) {
printer.flush();
printer = new PrintStream( binOut );
}
return binOut;
}
// ******* writer **************************************************************
private PrintStream printer() throws IOException {
if ( printer == null ) printer = new PrintStream( binOut==null ? socket.getOutputStream() : binOut, true);
return printer;
}
// ******* printHelp ***********************************************************
private void printHelp ( String cmd ) throws IOException {
boolean all = cmd.equalsIgnoreCase("all");
PrintStream out = printer();
boolean b = false;
if ( all || cmd.equalsIgnoreCase("help") ) {
out.println( "Supported commands:\n" +
" scan Scan buses\n" +
" info Print device capabilities\n" +
" upload Upload firmware\n" +
" config Configure FPGA\n" +
" read Read data from given endpoint\n" +
" write Write data to given endpoint\n" +
" errors Returns errors\n" +
" help Help\n" +
" quit Quit Device Server\n" +
"\n" +
"See help <command>|all for detailed info\n" );
b=true;
}
 
if ( all || cmd.equalsIgnoreCase("scan") ) {
out.println( "[<cid:>]scan [-bin]\n" +
" (Re)scan buses and returns the device list. If <cid> and -bin are specified\n" +
" errors are stored and can be read out using \"errors <cid>\". If -bin is not\n" +
" specified errors are returned directly.\n" +
" -bin print it in (computer friendly) binary format\n"
);
b=true;
}
 
if ( all || cmd.equalsIgnoreCase("info") ) {
out.println( "info <bus index> <device number>\n" +
" Returns device capabilities.\n"
);
b=true;
}
 
if ( all || cmd.equalsIgnoreCase("upload") ) {
out.println( "upload <bus index> <device number> [-v] [-nv] [-e] [-f]\n" +
" Upload firmware to USB controller. Returns errors, if any.\n" +
" -v upload to volatile memory (default if neither -nv nor -env is given)\n" +
" -nv upload to non-volatile memory\n" +
" -e erase / disable firmware in non-volatile memory\n" +
" -f force upload of incompatible firmware\n"
);
b=true;
}
 
if ( all || cmd.equalsIgnoreCase("config") ) {
out.println( "config <bus index> <device number> [-v] [-nv] [-e] [-f]\n" +
" Configure FPGA. Returns errors, if any.\n" +
" -v upload to volatile memory (default if -nv is not given)\n" +
" -nv upload to non-volatile memory\n" +
" -e erase / disable bitstream in non-volatile memory\n" +
" -f force upload if already configured\n"
);
b=true;
}
 
if ( all || cmd.equalsIgnoreCase("read") ) {
out.println( "[<cid>:]read <bus index> <device number> <ep> [<max. bytes>]\n" +
" Read data from endpoint and returns them. If <max. bytes> if not specified\n" +
" data is read until end. If <cid> is specified errors are stored and can be\n" +
" read out using \"errors <cid>\" \n"
);
b=true;
}
if ( all || cmd.equalsIgnoreCase("write") ) {
out.println( "write <bus number> <device number> <ep>\n" +
" write data to endpoint. Returns errors, if any.\n"
);
b=true;
}
 
if ( all || cmd.equalsIgnoreCase("errors") ) {
out.println( "errors <cid>\n" +
" Returns errors stored under <cid>.\n"
);
b=true;
}
 
if ( all || cmd.equalsIgnoreCase("quit") ) {
out.println( "quit\n" +
" Quit Device Server\n"
);
b=true;
}
 
if ( ! b ) {
out.println( "No help available for command " + cmd + "\n");
}
}
 
// ******* str2bin *************************************************************
private static void str2bin( String s, byte buf[], int start, int len ) {
byte bytes[] = null;
int l = 0;
if ( s != null ) {
bytes = s.getBytes();
l = Math.min(bytes.length,len);
}
for ( int i=0; i<l; i++ )
buf[start+i]=bytes[i];
for ( int i=l; i<len; i++ )
buf[start+i]=0;
}
 
// ******* scan ****************************************************************
private void scan ( boolean bin ) throws IOException {
DeviceServer.scanUSB();
int n = DeviceServer.numberOfDevices();
if ( bin ) {
byte buf[] = new byte[7+15+64+64];
BufferedOutputStream out = binOut();
if ( n>255 ) n=255;
out.write(n);
for ( int i=0; i<n; i++ ) {
try {
ZtexDevice1 dev = DeviceServer.device(i);
buf[0] = (byte) DeviceServer.busIdx(i);
buf[1] = (byte) DeviceServer.devNum(i);
buf[2] = (byte) (dev.valid() ? 1 : 0);
buf[3] = (byte) dev.productId(0);
buf[4] = (byte) dev.productId(1);
buf[5] = (byte) dev.productId(2);
buf[6] = (byte) dev.productId(3);
str2bin( dev.snString(), buf,7,15);
str2bin( dev.manufacturerString(), buf,22,64);
str2bin( dev.productString(), buf,86,64);
out.write(buf);
}
catch ( IndexOutOfBoundsException e ) {
}
}
out.flush();
}
else {
PrintStream out = printer();
if ( n<1 ) {
out.println("(No devices)");
}
else {
out.println("# <busIdx>:<devNum> <busName> <product ID'S> <serial number string> <manufacturer string> <product name>");
}
for ( int i=0; i<n; i++ ) {
try {
ZtexDevice1 dev = DeviceServer.device(i);
out.println(DeviceServer.busIdx(i) + ":" + DeviceServer.devNum(i)
+ " " + dev.dev().getBus().getDirname()
+ ( dev.valid() ? ( " " + ZtexDevice1.byteArrayString(dev.productId()) ) : " (unconfigured)" )
+ " \"" + ( dev.snString() == null ? "" : dev.snString() ) + "\""
+ " \"" + ( dev.manufacturerString() == null ? "" : dev.manufacturerString() ) + "\""
+ " \"" + ( dev.productString() == null ? "" : dev.productString() ) + "\"" );
}
catch ( IndexOutOfBoundsException e ) {
}
}
}
}
 
// ******* info ****************************************************************
private void info ( int busIdx, int devNum ) throws IOException, Exception {
ZtexDevice1 dev = DeviceServer.findDevice(busIdx,devNum);
EPDescriptorVector eps = DeviceServer.getEps(busIdx,devNum);
if ( dev == null ) throw new Exception("Device " + busIdx + ":" + devNum + " not found");
Ztex1v1 ztex = new Ztex1v1(dev);
PrintStream out = printer();
out.println("Bus name: " + dev.dev().getBus().getDirname() );
out.println("Device Number: " + devNum );
out.println("USB ID's: " + Integer.toHexString(dev.usbVendorId()) + ":" + Integer.toHexString(dev.usbProductId()) );
out.println("Product ID's: " + ( dev.valid() ? ( ZtexDevice1.byteArrayString(dev.productId()) ) : "(unconfigured)" ) );
out.println("Firmware version: " + ( dev.valid() ? (dev.fwVersion() & 255) : "" ) );
out.println("Serial Number String: " + ( dev.snString() == null ? "" : dev.snString() ) );
out.println("Manufacturer String: " + ( dev.manufacturerString() == null ? "" : dev.manufacturerString() ) );
out.println("Product String: " + ( dev.productString() == null ? "" : dev.productString() ) );
String s = ztex.capabilityInfo("\nCapability: ");
if ( s.length()>0 ) out.println("Capability: " + s);
if ( ztex.config != null ) {
out.println("ZTEX Product: " + ztex.config.getName());
out.println("FPGA: " + ztex.config.getFpga());
if (ztex.config.getRamSize()>0) out.println("RAM: " + (ztex.config.getRamSize() >> 20) + " MByte " + ztex.config.getRamType());
}
s = ztex.flashInfo(); if ( s.length()>0 ) out.println("Flash: " + s);
try {
s = ztex.getFpgaConfigurationStr();
out.println("FPGA State: " + s);
} catch ( Exception e ) {
}
if ( eps!=null ) {
for ( int i=0; i<eps.size(); i++ ) {
EPDescriptor ep = eps.elementAt(i);
out.println("Endpoint: "+ep.num()+" "+(ep.in() ? "read" : "write"));
}
}
}
// ******* run *****************************************************************
public void run () {
final int bufSize = 512;
final int maxArgs = 32;
byte buf[] = new byte[bufSize];
String args[] = new String[maxArgs];
int bufN=0, argsN=0;
String cid="", cid2=null;
boolean noErrors = false;
try {
in = new NonBlockingBufferedInputStream( socket.getInputStream() );
// read command and args
int b = 0;
do {
b = in.read();
if ( b <= 32 ) {
if ( bufN > 0 ) {
if ( argsN >= maxArgs ) throw new Exception("Error reading command: Argument buffer overflow");
args[argsN] = new String(buf,0,bufN);
argsN+=1;
bufN=0;
}
}
else {
if ( bufN >= bufSize ) throw new Exception("Error reading command: Buffer overflow");
buf[bufN] = (byte) b;
bufN+=1;
}
} while (b!=10 && b>0);
if ( argsN == 0 ) throw new Exception ("Command missed");
}
catch (Exception e) {
// DeviceServer.error("Error: "+e.getLocalizedMessage() );
try {
printer().println("Error: "+e.getLocalizedMessage());
}
catch (IOException f) {
DeviceServer.error("Error: "+e.getLocalizedMessage() );
}
}
StringBuilder messages = new StringBuilder();
if ( args[0].indexOf(':') > 0 ) {
int i = args[0].lastIndexOf(':');
cid = args[0].substring(0,i);
args[0] = args[0].substring(i+1);
}
 
// process commands
try {
// quit
if ( args[0].equalsIgnoreCase("quit") ) {
DeviceServer.quit = true;
}
// help [<command>]
else if ( args[0].equalsIgnoreCase("help") ) {
if ( argsN < 2 ) printHelp("help");
for ( int i=1; i<argsN; i++ ) {
printHelp( args[i] );
}
}
// [<cid>:]scan [-bin]
else if ( args[0].equalsIgnoreCase("scan") ) {
if ( argsN > 2 ) throw new Exception("scan: to much parameters" );
if ( argsN==2 && ! args[1].equalsIgnoreCase("-bin") ) throw new Exception("scan: invalid parameter: " + args[1] );
if ( argsN == 2 ) noErrors = true;
scan( argsN==2 );
}
// info <bus index> <device number>
else if ( args[0].equalsIgnoreCase("info") ) {
if ( argsN !=3 ) throw new Exception("info: invalid number of parameters" );
info( Integer.valueOf(args[1]), Integer.valueOf(args[2]) );
}
// upload <bus index> <device number> [-v] [-nv] [-e] [-f]
// config <bus index> <device number> [-v] [-nv] [-e] [-f]
else if ( args[0].equalsIgnoreCase("upload") || args[0].equalsIgnoreCase("config") ) {
if ( argsN<3 ) throw new Exception(args[0]+": to less parameters" );
boolean vola=false, nonvola=false, erase=false, force=false;
for ( int i=3; i<argsN; i++) {
if ("-v".equalsIgnoreCase(args[i])) vola=true;
else if ("-nv".equalsIgnoreCase(args[i])) nonvola=true;
else if ("-e".equalsIgnoreCase(args[i])) erase=true;
else if ("-f".equalsIgnoreCase(args[i])) force=true;
else throw new Exception("Invalid parameter: "+args[i]);
}
int busIdx=Integer.valueOf(args[1]);
int devNum=Integer.valueOf(args[2]);
ZtexDevice1 dev = DeviceServer.findDevice(busIdx, devNum);
if ( dev == null ) throw new Exception("Device " + busIdx + ":" + devNum + " not found");
Ztex1v1 ztex = new Ztex1v1(dev);
if ( args[0].equalsIgnoreCase("upload")) {
DeviceServer.loadFirmware ( ztex, messages, in, IPPermissions.toString( socket.getInetAddress() ), force, vola, nonvola, erase );
int ndn = ztex.dev().dev().getDevnum();
if ( ndn != devNum ) {
messages.append("Device re-numerated: " + busIdx + ":" + devNum + " -> " + busIdx + ":" + ndn + "\n");
DeviceServer.scanUSB();
}
}
else {
DeviceServer.loadBitstream ( ztex, messages, in, IPPermissions.toString( socket.getInetAddress() ), force, vola, nonvola, erase );
}
}
// write <bus number> <device number> <ep>
else if ( args[0].equalsIgnoreCase("write") ) {
if ( argsN !=4 ) throw new Exception("write: invalid number of parameters" );
int busIdx=Integer.valueOf(args[1]);
int devNum=Integer.valueOf(args[2]);
ZtexDevice1 dev = DeviceServer.findDevice(busIdx, devNum);
if ( dev == null ) throw new Exception("Device " + busIdx + ":" + devNum + " not found");
Ztex1v1 ztex = new Ztex1v1(dev);
EPDescriptorVector eps = DeviceServer.getEps(busIdx,devNum);
try {
DeviceServer.epUpload (ztex, eps.find(Integer.valueOf(args[3])), in, messages);
}
finally {
DeviceServer.release(ztex);
}
}
// [<cid>:]read <bus index> <device number> <ep> [<max. bytes>]
else if ( args[0].equalsIgnoreCase("read") ) {
noErrors = true;
if ( argsN<4 || argsN>5 ) throw new Exception("read: invalid number of parameters" );
int busIdx=Integer.valueOf(args[1]);
int devNum=Integer.valueOf(args[2]);
ZtexDevice1 dev = DeviceServer.findDevice(busIdx, devNum);
if ( dev == null ) throw new Exception("Device " + busIdx + ":" + devNum + " not found");
Ztex1v1 ztex = new Ztex1v1(dev);
EPDescriptorVector eps = DeviceServer.getEps(busIdx,devNum);
int max_size = argsN==5 ? Integer.valueOf(args[4]) : Integer.MAX_VALUE;
try {
DeviceServer.epDownload (ztex, eps.find(Integer.valueOf(args[3])), binOut(), max_size, messages);
binOut.flush();
}
finally {
DeviceServer.release(ztex);
}
}
// error <cid>
else if ( args[0].equalsIgnoreCase("errors") ) {
cid2 = cid;
cid = null;
if ( argsN > 2 ) throw new Exception("errors: to much parameters" );
if ( argsN == 2 ) cid2 = args[1];
messages = ErrorBuffer.get(cid2);
if (messages != null) printer().print( messages );
messages = new StringBuilder();
}
else {
throw new Exception("Invalid command: "+args[0] );
}
}
catch ( IOException e) {
DeviceServer.error("Error: "+e.getLocalizedMessage() );
}
catch (NumberFormatException e) {
messages.append("Error: Number expected: "+e.getLocalizedMessage()+"\n");
}
catch (Exception e) {
messages.append("Error: "+e.getLocalizedMessage()+"\n");
}
try {
if ( messages != null && messages.length()>0 ) {
if ( ! noErrors ) printer().print(messages);
ErrorBuffer.add(cid,messages);
}
}
catch ( IOException e) {
DeviceServer.error("Error2: "+e.getLocalizedMessage() );
}
 
try {
socket.getInputStream().close();
}
catch (Exception e) {
DeviceServer.error("Error closing input stream: "+e.getLocalizedMessage() );
}
 
try {
if ( binOut!=null ) binOut.close();
else if ( printer != null ) printer.close();
}
catch (Exception e) {
DeviceServer.error("Error closing output stream: "+e.getLocalizedMessage() );
}
DeviceServer.removeSocket(socket);
try {
socket.close();
}
catch (Exception e) {
DeviceServer.error("Error closing output socket: "+e.getLocalizedMessage() );
}
}
}
 
 
// *****************************************************************************
// ******* MultipartFormDataReader ********************************************
// *****************************************************************************
class MultipartFormDataReader {
private final byte eol[] = { 13, 10 };
private InputStream in;
private byte sep[] = null;
private boolean eof = false;
public String name = "";
public String fileName = "";
// ******* readTo **************************************************************
private boolean readTo ( OutputStream out, byte s[] ) {
byte buf[] = new byte[s.length];
int eq = 0;
while ( eq<s.length && !eof ) {
int i = 0;
try {
i = in.read();
eof = i<0;
}
catch ( IOException e ) {
eof = true;
}
if ( !eof ) {
buf[eq] = (byte) i;
if ( buf[eq] == s[eq] ) {
eq++;
}
else {
try {
if ( out != null ) out.write(buf,0,eq+1);
}
catch ( IOException e ) {
}
eq=0;
}
}
}
return !eof;
}
 
// ******* MultiPartFormDataReader *********************************************
MultipartFormDataReader ( InputStream in_ ) {
in = in_;
do {
try {
if ( in.read() == 45 && in.read() == 45 ) {
ByteArrayOutputStream buf = new ByteArrayOutputStream();
buf.write(eol,0,eol.length);
buf.write(45);
buf.write(45);
readTo( buf, eol );
sep = buf.toByteArray();
// System.out.println("sep: -->" + new String(sep) + "<--");
}
else {
readTo( null, eol );
}
}
catch ( IOException e ) {
eof = true;
}
} while ( sep == null && !eof );
}
 
// ******* readField ***********************************************************
public boolean readField ( OutputStream data ) {
if ( sep == null ) return false;
ByteArrayOutputStream lineBuf = new ByteArrayOutputStream();
String line;
name = "";
fileName = "";
do {
readTo ( lineBuf, eol );
line = lineBuf.toString();
// System.out.println("line: "+line);
int i=0;
while ( i<line.length() && line.codePointAt(i) <= 32 ) i++;
if ( line.length()>=i+19 && line.substring(i,i+19).equalsIgnoreCase("Content-Disposition") ) {
String tokens[] = line.split(";");
for ( int j=1; j<tokens.length; j++ ) {
String t = tokens[j];
i=0;
while ( t.codePointAt(i) <= 32 && i < t.length() ) i++;
String s=t.substring(i,i+5);
if ( s.equalsIgnoreCase("name ") || s.equalsIgnoreCase("name=") ) {
int a = t.indexOf("\"");
int z = t.lastIndexOf("\"");
if ( a>0 && z>a ) name=t.substring(a+1,z);
}
s=t.substring(i,i+9);
if ( s.equalsIgnoreCase("filename ") || s.equalsIgnoreCase("filename=") ) {
int a = t.indexOf("\"");
int z = t.lastIndexOf("\"");
if ( a>0 && z>a ) fileName=t.substring(a+1,z);
}
}
// System.out.println("name: "+name);
// System.out.println("filename: "+fileName);
}
lineBuf.reset();
} while ( line.length()>0 && !eof );
if ( ! eof ) readTo( data, sep );
boolean result = !eof;
try {
in.read();
in.read();
}
catch ( IOException e ) {
eof = true;
}
return result;
}
}
 
 
// *****************************************************************************
// ******* ZtexHttpHandler *****************************************************
// *****************************************************************************
class ZtexHttpHandler implements HttpHandler {
 
// ******* htmlHeader **********************************************************
private StringBuilder htmlHeader ( String title ) {
StringBuilder sb = new StringBuilder();
sb.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n");
sb.append("<html>\n");
sb.append("<head>\n");
sb.append(" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n");
sb.append(" <meta http-equiv=\"Content-Language\" content=\"en\">\n");
sb.append(" <meta name=\"author\" content=\"ZTEX GmbH\">\n");
sb.append("<title>" + title + "</title>\n");
sb.append("<style type=\"text/css\">\n");
sb.append("body { background-color:#f0f0f0; color:#202020; font-family:Helvetica,Helv,sans-serif; font-size:11pt}\n");
sb.append("a:link { color:#2020a0; }\n");
sb.append("a:visited { color:#a02020; }\n");
sb.append("a:active { color:#208020; }\n");
sb.append("a.topmenu { color:#ffffff; font-size:12pt; text-decoration:none; font-weight:bold }\n");
sb.append("a.topmenu:link { color:#ffffff; }\n");
sb.append("a.topmenu:visited { color:#ffffff; }\n");
sb.append("a.topmenu:hover { color:#202020; }\n");
sb.append("</style>\n");
sb.append("</head>\n");
sb.append("<body>\n");
sb.append("<center><table border=0 bgcolor=\"#7870a0\" cellpadding=2 cellspacing=0><tr><td>\n");
sb.append("<table border=0 bgcolor=\"#eae6ff\" cellpadding=5 cellspacing=10>\n");
sb.append(" <tr><th bgcolor=\"#cac4ec\">\n");
sb.append(" <span style=\"font-size:125%\">" + title + "</span>\n");
sb.append(" </th></tr>\n");
sb.append(" <tr><td align=center>\n");
return sb;
}
 
// ******* heading *************************************************************
private StringBuilder heading ( StringBuilder sb, String s ) {
sb.append ( "</td></tr>\n");
sb.append(" <tr><th bgcolor=\"#cac4ec\">\n");
sb.append(" <span style=\"font-size:125%\">" + s + "</span>\n");
sb.append(" </th></tr>\n");
sb.append(" <tr><td align=center>\n");
return sb;
}
// ******* htmlConvert *********************************************************
private byte[] htmlConvert ( StringBuilder sb ) {
sb.append ( "</td></tr>\n");
sb.append ( "</table>\n");
sb.append ( "</td></tr></table><center>\n");
sb.append ( "<p>\n");
sb.append ( "<hr>\n");
sb.append ( "<center>\n");
sb.append ( " <a href=\"http://www.ztex.de/\">[ZTEX Homepage]</a>&nbsp;\n");
sb.append ( " <a href=\"http://wiki.ztex.de/\">[ZTEX Wiki]</a>&nbsp;\n");
sb.append ( " <span style=\"font-size:80%\">&#169; ZTEX GmbH</span>\n");
sb.append ( "</center>\n");
sb.append ( "</body></html>" );
return sb.toString().getBytes();
}
// ******* test ****************************************************************
private byte[] test (HttpExchange t) throws IOException {
InputStream in = new BufferedInputStream( t.getRequestBody() );
System.out.println("Request Body: " + in.available() + "Bytes");
int i;
do {
i = in.read();
if ( i>=0 ) System.out.print((char)i);
} while (i>=0);
 
Headers h = t.getResponseHeaders();
h.add("Content-Type", "text/html;Charset=iso-8859-1");
StringBuilder sb = htmlHeader ("Test");
sb.append ("<form action=\"test\" method=\"post\" enctype=\"multipart/form-data\">\n");
sb.append (" <p>W&auml;hlen Sie eine Textdatei (txt, html usw.) von Ihrem Rechner aus:<br>\n");
sb.append (" <input name=\"Datei\" type=\"file\" size=\"50\" maxlength=\"100000\" >\n");
sb.append (" </p>\n");
sb.append (" <input type=\"checkbox\" name=\"upload_to\" value=\"v\">Volatile Memory &nbsp;&nbsp;&nbsp;&nbsp;\n");
sb.append (" <input type=\"checkbox\" name=\"upload_to\" value=\"v\">Non-Volatile Memory &nbsp;&nbsp;&nbsp;&nbsp;\n");
sb.append (" <input type=\"submit\" value=\"Submit\">\n");
sb.append ("</form>\n");
 
return htmlConvert(sb);
}
 
// ******* test2 ***************************************************************
private byte[] test2 (HttpExchange t) throws IOException {
MultipartFormDataReader form = new MultipartFormDataReader( new BufferedInputStream( t.getRequestBody() ) );
ByteArrayOutputStream data = new ByteArrayOutputStream();
while ( form.readField( data ) ) {
System.out.println( "Name=\"" + form.name + "\"" );
System.out.println( "Filename=\"" + form.fileName + "\"" );
System.out.println( "Data -->" + data + "<--" );
data.reset();
}
 
Headers h = t.getResponseHeaders();
h.add("Content-Type", "text/html;Charset=iso-8859-1");
StringBuilder sb = htmlHeader ("Test2");
sb.append ("<form action=\"test2\" method=\"post\" enctype=\"multipart/form-data\">\n");
sb.append (" <p>W&auml;hlen Sie eine Textdatei (txt, html usw.) von Ihrem Rechner aus:<br>\n");
sb.append (" <input name=\"Datei\" type=\"file\" size=\"50\" maxlength=\"100000\" >\n");
sb.append (" </p>\n");
sb.append (" <input type=\"checkbox\" name=\"upload_to\" value=\"v\">Volatile Memory &nbsp;&nbsp;&nbsp;&nbsp;\n");
sb.append (" <input type=\"checkbox\" name=\"upload_to\" value=\"nv\">Non-Volatile Memory &nbsp;&nbsp;&nbsp;&nbsp;\n");
sb.append (" <input type=\"submit\" value=\"Submit\">\n");
sb.append ("</form>\n");
 
return htmlConvert(sb);
}
 
// ******* scan ****************************************************************
private byte[] scan (HttpExchange t) {
DeviceServer.scanUSB();
int n = DeviceServer.numberOfDevices();
Headers h = t.getResponseHeaders();
h.add("Content-Type", "text/html;Charset=iso-8859-1");
StringBuilder sb = htmlHeader ("Device overview");
sb.append ("<table border=\"0\" bgcolor=\"#808080\" cellspacing=1 cellpadding=4>\n");
sb.append (" <tr>\n");
sb.append (" <td align=center bgcolor=\"#e0e0e0\">Device Link / <br> &lt;Bus Index&gt;:&lt;Device Number&gt;</td>\n");
sb.append (" <td align=center bgcolor=\"#e0e0e0\">Bus Name</td>\n");
sb.append (" <td align=center bgcolor=\"#e0e0e0\">Product ID's</td>\n");
sb.append (" <td align=center bgcolor=\"#e0e0e0\">Serial Number String</td>\n");
sb.append (" <td align=center bgcolor=\"#e0e0e0\">Manufacturer String</td>\n");
sb.append (" <td align=center bgcolor=\"#e0e0e0\">Product String</td>\n");
sb.append (" </tr>\n");
if ( n<1 ) {
sb.append("<tr><td align=center bgcolor=\"#f0f0f0\" colspan=6>(No devices)</td>");
} else {
for ( int i=0; i<n; i++ ) {
try {
ZtexDevice1 dev = DeviceServer.device(i);
sb.append(" <tr>\n");
sb.append(" <td align=center bgcolor=\"#f0f0f0\"><a href=\"" + DeviceServer.busIdx(i) + ":" + DeviceServer.devNum(i) + "\">" + DeviceServer.busIdx(i) + ":" + DeviceServer.devNum(i) + "</a></td>\n");
sb.append(" <td align=center bgcolor=\"#f0f0f0\">" + dev.dev().getBus().getDirname() + "</td>\n");
sb.append(" <td align=center bgcolor=\"#f0f0f0\">" + ( dev.valid() ? ( ZtexDevice1.byteArrayString(dev.productId()) ) : "(unconfigured)" ) + "</td>\n");
sb.append(" <td align=center bgcolor=\"#f0f0f0\">" + ( dev.snString() == null ? "" : dev.snString() ) + "</td>\n");
sb.append(" <td align=center bgcolor=\"#f0f0f0\">" + ( dev.manufacturerString() == null ? "" : dev.manufacturerString() ) + "</td>\n");
sb.append(" <td align=center bgcolor=\"#f0f0f0\">" + ( dev.productString() == null ? "" : dev.productString() ) + "</td>\n");
sb.append(" </tr>\n");
}
catch ( IndexOutOfBoundsException e ) {
}
}
}
sb.append ("</table>\n");
sb.append ("<p>\n");
sb.append ("<a href=\"/scan\"><button>Re-Scan</button></a>\n");
return htmlConvert(sb);
}
 
// ******* device **************************************************************
private byte[] device ( HttpExchange t, int busIdx, int devNum, int epnum, ZtexDevice1 dev ) {
 
StringBuilder messages = new StringBuilder();
EPDescriptorVector eps = DeviceServer.getEps(busIdx,devNum);
Headers h = t.getResponseHeaders();
// ***********
// * request *
// ***********
boolean fw_force = false;
boolean fw_upload_v = false;
boolean fw_upload_nv = false;
boolean fw_erase = false;
ByteArrayInputStream fw_data = null;
String fw_data_name = null;
 
boolean bs_force = false;
boolean bs_upload_v = false;
boolean bs_upload_nv = false;
boolean bs_erase = false;
byte bs_data[] = null;
String bs_data_name = null;
 
ByteArrayInputStream ep_data = null;
String ep_data_name = null;
int ep_data_num = -1;
int ep_down_size = -1;
MultipartFormDataReader form = new MultipartFormDataReader( new BufferedInputStream( t.getRequestBody() ) );
ByteArrayOutputStream data = new ByteArrayOutputStream();
while ( form.readField( data ) ) {
/* System.out.println( "Name=\"" + form.name + "\"" );
System.out.println( "Filename=\"" + form.fileName + "\"" );
System.out.println( "Data -->" + data + "<--" ); */
if ( data.size()>0 ) {
if ( form.name.equalsIgnoreCase("fw_force" ) ) fw_force=true;
else if ( form.name.equalsIgnoreCase("fw_upload_v" ) ) fw_upload_v=true;
else if ( form.name.equalsIgnoreCase("fw_upload_nv" ) ) fw_upload_nv=true;
else if ( form.name.equalsIgnoreCase("fw_erase" ) ) fw_erase=true;
else if ( form.name.equalsIgnoreCase("fw_data" ) ) {
fw_data = new ByteArrayInputStream(data.toByteArray());
fw_data_name = IPPermissions.toString( t.getRemoteAddress().getAddress() ) + ":" + form.fileName;
}
else if ( form.name.equalsIgnoreCase("bs_force" ) ) bs_force=true;
else if ( form.name.equalsIgnoreCase("bs_upload_v" ) ) bs_upload_v=true;
else if ( form.name.equalsIgnoreCase("bs_upload_nv" ) ) bs_upload_nv=true;
else if ( form.name.equalsIgnoreCase("bs_erase" ) ) bs_erase=true;
else if ( form.name.equalsIgnoreCase("bs_data" ) ) {
bs_data = data.toByteArray();
bs_data_name = IPPermissions.toString( t.getRemoteAddress().getAddress() ) + ":" + form.fileName;
}
else if ( form.name.equalsIgnoreCase("ep_down_size" ) ) {
try {
ep_down_size = Integer.valueOf(data.toString());
}
catch (Exception e) {
ep_down_size = -1;
}
// System.out.println(ep_down_size);
}
else {
for ( int i=0; eps!=null && i<eps.size(); i++ ) {
EPDescriptor ep = eps.elementAt(i);
if ( ! ep.in() && form.name.equalsIgnoreCase("ep_"+ep.num()+"_data" ) ) {
ep_data = new ByteArrayInputStream(data.toByteArray());
ep_data_name = IPPermissions.toString( t.getRemoteAddress().getAddress() ) + ":" + form.fileName;
ep_data_num = ep.num();
}
}
}
data.reset();
}
}
 
// **********
// * action *
// **********
Ztex1v1 ztex = null;
try {
ztex = new Ztex1v1(dev);
} catch ( Exception e ) {
ztex = null;
messages.append( "Error: " + e.getLocalizedMessage() + "\n");
}
int oldDevNum = devNum;
try {
DeviceServer.loadFirmware ( ztex, messages, fw_data, fw_data_name, fw_force, fw_upload_v, fw_upload_nv, fw_erase );
if ( ztex != null ) {
devNum = ztex.dev().dev().getDevnum();
if ( devNum != oldDevNum ) {
messages.append("Device re-numerated: " + busIdx + ":" + oldDevNum + " -> " + busIdx + ":" + devNum + "\n");
DeviceServer.scanUSB();
eps = DeviceServer.getEps(busIdx,devNum);
}
}
} catch ( Exception e ) {
messages.append( "Error: " + e.getLocalizedMessage() + '\n' );
}
 
try {
if ( ztex != null ) DeviceServer.loadBitstream ( ztex, messages, bs_data, bs_data_name, bs_force, bs_upload_v, bs_upload_nv, bs_erase );
} catch ( Exception e ) {
messages.append( "Error: " + e.getLocalizedMessage() + '\n' );
}
 
try {
if ( ep_data != null ) DeviceServer.epUpload (ztex, eps.find(ep_data_num), ep_data, messages);
} catch ( Exception e ) {
messages.append( "Error: " + e.getLocalizedMessage() + '\n' );
}
 
try {
if ( epnum>0 ){
ByteArrayOutputStream out = new ByteArrayOutputStream();
DeviceServer.epDownload (ztex, eps.find(epnum), out, ep_down_size, messages);
h.add("Content-Type", "application/octet-stream");
return out.toByteArray();
}
} catch ( Exception e ) {
messages.append( "Error: " + e.getLocalizedMessage() + '\n' );
}
DeviceServer.release (ztex);
// ************
// * response *
// ************
h.add("Content-Type", "text/html;Charset=iso-8859-1");
StringBuilder sb = htmlHeader ("Device " + busIdx + ":" + devNum + ( devNum!=oldDevNum ? ( " (was " + busIdx + ":" + oldDevNum +")" ) : "" ) );
 
// info
sb.append ("<table border=\"0\" bgcolor=\"#808080\" cellspacing=1 cellpadding=4>\n");
sb.append(" <tr><td align=left bgcolor=\"#e0e0e0\"> Bus name: </td><td align=left bgcolor=\"#f0f0f0\">" + dev.dev().getBus().getDirname() + "</td></tr>\n");
sb.append(" <tr><td align=left bgcolor=\"#e0e0e0\"> Device Number: </td><td align=left bgcolor=\"#f0f0f0\">" + devNum + "</td></tr>\n");
sb.append(" <tr><td align=left bgcolor=\"#e0e0e0\"> USB ID's: </td><td align=left bgcolor=\"#f0f0f0\">" + Integer.toHexString(dev.usbVendorId()) + ":" + Integer.toHexString(dev.usbProductId()) + "</td></tr>\n");
sb.append(" <tr><td align=left bgcolor=\"#e0e0e0\"> Product ID's: </td><td align=left bgcolor=\"#f0f0f0\">" + ( dev.valid() ? ( ZtexDevice1.byteArrayString(dev.productId()) ) : "(unconfigured)" ) + "</td></tr>\n");
sb.append(" <tr><td align=left bgcolor=\"#e0e0e0\"> Firmware version: </td><td align=left bgcolor=\"#f0f0f0\">" + ( dev.valid() ? (dev.fwVersion() & 255) : "" ) + "</td></tr>\n");
sb.append(" <tr><td align=left bgcolor=\"#e0e0e0\"> Serial Number String: </td><td align=left bgcolor=\"#f0f0f0\">" + ( dev.snString() == null ? "" : dev.snString() ) + "</td></tr>\n");
sb.append(" <tr><td align=left bgcolor=\"#e0e0e0\"> Manufacturer String: </td><td align=left bgcolor=\"#f0f0f0\">" + ( dev.manufacturerString() == null ? "" : dev.manufacturerString() ) + "</td></tr>\n");
sb.append(" <tr><td align=left bgcolor=\"#e0e0e0\"> Product String: </td><td align=left bgcolor=\"#f0f0f0\">" + ( dev.productString() == null ? "" : dev.productString() ) + "</td></tr>\n");
if ( ztex != null ) {
String s = ztex.capabilityInfo(", ");
if ( s.length()>0 ) sb.append(" <tr><td align=left bgcolor=\"#e0e0e0\"> Capabilities: </td><td align=left bgcolor=\"#f0f0f0\">" + s + "</td></tr>\n");
if ( ztex.config != null ) {
sb.append(" <tr><td align=left bgcolor=\"#e0e0e0\"> ZTEX Product: </td><td align=left bgcolor=\"#f0f0f0\">" + ztex.config.getName() + "</td></tr>\n");
sb.append(" <tr><td align=left bgcolor=\"#e0e0e0\"> FPGA: </td><td align=left bgcolor=\"#f0f0f0\">" + ztex.config.getFpga() + "</td></tr>\n");
if (ztex.config.getRamSize()>0) sb.append(" <tr><td align=left bgcolor=\"#e0e0e0\"> RAM: </td><td align=left bgcolor=\"#f0f0f0\">" + (ztex.config.getRamSize() >> 20) + " MByte " + ztex.config.getRamType() + "</td></tr>\n");
s = ztex.flashInfo(); if ( s.length()>0 ) sb.append(" <tr><td align=left bgcolor=\"#e0e0e0\"> Flash: </td><td align=left bgcolor=\"#f0f0f0\">" + s + "</td></tr>\n");
}
try {
s = ztex.getFpgaConfigurationStr();
sb.append(" <tr><td align=left bgcolor=\"#e0e0e0\"> FPGA State: </td><td align=left bgcolor=\"#f0f0f0\">" + s + "</td></tr>\n");
} catch ( Exception e ) {
}
}
sb.append ("</table>\n");
sb.append ("<p><a href=\"/\"><button>Device Overview</button></a>\n");
 
// firmware
heading(sb,"Firmware Upload");
sb.append ("<form action=\"" + busIdx + ":" + devNum + "\" method=\"post\" enctype=\"multipart/form-data\">\n");
sb.append (" <div align=left>\n");
sb.append (" Firmware file: <input name=\"fw_data\" type=\"file\" size=\"70\" accept=\".ihx\" maxlength=\"5000000\"><p>\n");
sb.append (" <input type=\"checkbox\" name=\"fw_upload_v\" value=\"x\" " + ( fw_upload_v ? "checked" : "" ) + ">Upload to volatile Memory &nbsp;&nbsp;&nbsp;&nbsp;\n");
// try {
// if ( ztex != null ) {
// ztex.checkCapability(ztex.CAPABILITY_EEPROM);
sb.append (" <input type=\"checkbox\" name=\"fw_upload_nv\" value=\"x\"" + ( fw_upload_nv ? "checked" : "" ) + ">Upload to non-Volatile Memory &nbsp;&nbsp;&nbsp;&nbsp;\n");
sb.append (" <input type=\"checkbox\" name=\"fw_erase\" value=\"x\"" + ( fw_erase ? "checked" : "" ) + ">Erase firmware in non-volatile memory");
// }
// }
// catch ( Exception a ) {
// }
sb.append (" <input type=\"checkbox\" name=\"fw_force\" value=\"x\"" + ( fw_force ? "checked" : "" ) + ">Enforce upload<p>");
sb.append (" (Before firmware can be loaded into non-volatile memory some firmware must be installed in volatile memory.)<p>\n");
sb.append (" </div>\n");
sb.append (" <input type=\"submit\" value=\"Submit\">\n");
sb.append ("</form>\n");
 
// bitstream
try {
if ( ztex == null ) throw new Exception();
ztex.checkCapability(ztex.CAPABILITY_FPGA);
heading(sb,"Bitstream Upload");
sb.append ("<form action=\"" + busIdx + ":" + devNum + "\" method=\"post\" enctype=\"multipart/form-data\">\n");
sb.append (" <div align=left>\n");
sb.append (" Bitstream file: <input name=\"bs_data\" type=\"file\" size=\"70\" accept=\".ihx\" maxlength=\"5000000\"><p>\n");
sb.append (" <input type=\"checkbox\" name=\"bs_upload_v\" value=\"x\" " + ( bs_upload_v ? "checked" : "" ) + ">Upload to volatile Memory &nbsp;&nbsp;&nbsp;&nbsp;\n");
try {
if ( ztex != null && ztex.flashEnabled() ) {
sb.append (" <input type=\"checkbox\" name=\"bs_upload_nv\" value=\"x\"" + ( bs_upload_nv ? "checked" : "" ) + ">Upload to non-Volatile Memory &nbsp;&nbsp;&nbsp;&nbsp;\n");
sb.append (" <input type=\"checkbox\" name=\"bs_erase\" value=\"x\"" + ( bs_erase ? "checked" : "" ) + ">Erase bitstream in non-volatile memory");
}
}
catch ( Exception a ) {
}
sb.append (" <input type=\"checkbox\" name=\"bs_force\" value=\"x\"" + ( bs_force ? "checked" : "" ) + ">Enforce upload<p>");
sb.append (" </div>\n");
sb.append (" <input type=\"submit\" value=\"Submit\">\n");
sb.append ("</form>\n");
}
catch ( Exception a ) {
}
 
// endpoints
if ( eps!=null && eps.size()>0) {
heading(sb,"Endpoints");
sb.append ("<table border=\"0\" bgcolor=\"#808080\" cellspacing=1 cellpadding=12>\n");
for (int i=0; i<eps.size(); i++ ) {
EPDescriptor ep = eps.elementAt(i);
if ( ep.in() ) {
sb.append(" <tr><td align=left bgcolor=\"#e0e0e0\"> IN EP " + ep.num() +":</td> <td align=left bgcolor=\"#f0f0f0\">"
+ "<form action=\"" + busIdx + ":" + devNum + ":" + ep.num() + "\" method=\"post\" enctype=\"multipart/form-data\">"
+ "Maximum size: <input type=\"text\" name=\"ep_down_size\" value=\"1000000\" size=12 maxlength=11>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;<input type=\"submit\" value=\"Download\">"
+ "</form></td></tr>\n" );
} else {
sb.append(" <tr><td align=left bgcolor=\"#e0e0e0\"> OUT EP " + ep.num() +":</td> <td align=left bgcolor=\"#f0f0f0\">"
+ "<form action=\"" + busIdx + ":" + devNum + "\" method=\"post\" enctype=\"multipart/form-data\">"
+ "File: <input name=\"ep_"+ep.num()+"_data\" type=\"file\" size=\"60\" accept=\"\" maxlength=\"50000000\">"
+ "&nbsp;&nbsp;&nbsp;&nbsp;<input type=\"submit\" value=\"Upload\">"
+ "</form></td></tr>\n" );
}
}
sb.append ("</table>\n");
}
 
// messages
if ( messages.length() > 0 ) {
heading(sb,"Messages");
sb.append ("<div align=left><pre>\n");
sb.append(messages);
sb.append ("</pre></div>");
}
 
return htmlConvert(sb);
}
 
// ******* handle **************************************************************
public void handle(HttpExchange t) throws IOException {
String path = t.getRequestURI().getPath();
int responseCode = 200;
byte buf[] = {};
if ( path.charAt(0) != '/' ) path = '/' + path;
int rcvd = t.getRequestBody().available();
 
if ( ! DeviceServer.httpPermissions().checkAddress( t.getRemoteAddress().getAddress() ) ) {
responseCode = 400;
StringBuilder sb = htmlHeader ("400 Bad Request");
sb.append("Access denied" );
buf = htmlConvert(sb);
}
/* else if ( path.equalsIgnoreCase("/test") ) {
buf = test(t);
}
else if ( path.equalsIgnoreCase("/test2") ) {
buf = test2(t);
} */
else if ( path.equalsIgnoreCase("/") || path.equalsIgnoreCase("/scan") ) {
buf = scan(t);
}
else if ( path.indexOf(':') > 0 ) {
try {
int i = path.indexOf(':');
int j = path.lastIndexOf(':');
if (j<=i) j=path.length();
int busIdx = Integer.valueOf(path.substring(1,i));
int devNum = Integer.valueOf(path.substring(i+1,j ));
int epNum = j < path.length() ? Integer.valueOf(path.substring(j+1)) : -1;
ZtexDevice1 dev = DeviceServer.findDevice(busIdx,devNum);
if ( dev == null ) throw new Exception();
buf = device(t, busIdx, devNum, epNum, dev);
}
catch ( Exception e ) {
responseCode = 400;
StringBuilder sb = htmlHeader ("400 Bad Request");
sb.append("Invalid device path: " + path );
sb.append ("<p>\n");
sb.append ("<a href=\"/\"><button>Device Overview</button></a>\n");
buf = htmlConvert(sb);
}
}
else {
responseCode = 404;
StringBuilder sb = htmlHeader ("404 Not Found");
sb.append("Invalid path: " + path );
sb.append ("<p>\n");
sb.append ("<a href=\"/\"><button>Device Overview</button></a>\n");
buf = htmlConvert(sb);
}
DeviceServer.info( "Connection from " + IPPermissions.toString( t.getRemoteAddress().getAddress() ) + ": " + path + ": " + responseCode + ": received " + rcvd + " bytes, sent " + buf.length + " bytes" );
t.sendResponseHeaders(responseCode, buf.length);
OutputStream os = t.getResponseBody();
os.write(buf);
os.close();
}
}
 
 
// *****************************************************************************
// ******* IPPermissionList ****************************************************
// *****************************************************************************
class IPPermissions {
private byte ip[][] = { { 127, 0, 0, 1 } };
private boolean deny[] = { false };
private int mask[] = { 32 };
public IPPermissions(String adrs) throws UnknownHostException,IllegalArgumentException {
String strs[] = adrs.split(",");
ip = new byte[strs.length][];
deny = new boolean[strs.length];
mask = new int[strs.length];
for (int i=0; i<strs.length; i++ ) {
if ( strs[i].length()==0 ) throw new IllegalArgumentException( "Invalid address format at position " + (i+1) + ": empty string");
deny[i] = strs[i].charAt(0) == '-';
int start = deny[i] ? 1 : 0;
int end = strs[i].lastIndexOf("/");
if ( end < 0 ) end = strs[i].length();
ip[i] = InetAddress.getByName(strs[i].substring(start,end)).getAddress();
try {
mask[i] = ( end+1 < strs[i].length() ) ? Integer.parseInt(strs[i].substring(end+1)) : ip[i].length*8;
}
catch (Exception e) {
throw new IllegalArgumentException("Invalid mask format at position " + (i+1) + ": `" + strs[i].substring(end+1) + "'" );
}
}
}
 
public IPPermissions() {
}
public boolean checkAddress ( byte rip[]) {
boolean allow = false;
for ( int i=0; i<ip.length; i++ ) {
if ( ip[i].length == rip.length ) {
boolean eq = true;
for ( int j=0; j<rip.length; j++ ) {
int k = Math.max( (j+1)*8-mask[i], 0);
eq = eq && ( (ip[i][j] & 255)>>k == (rip[j] & 255)>>k );
}
if ( eq ) allow = ! deny[i];
}
}
return allow;
}
 
public boolean checkAddress ( InetAddress adr ) {
return checkAddress( adr.getAddress() );
}
public static String toString(byte ip[]) {
StringBuilder sb = new StringBuilder();
if ( ip.length<6 || (ip.length & 1) != 0 ) {
for (int i=0; i<ip.length; i++ ) {
if (i>0) sb.append('.');
sb.append(ip[i] & 255);
}
}
else {
for (int i=0; i+1<ip.length; i+=2 ) {
if (i>0) sb.append(':');
sb.append(Integer.toString( ((ip[i] & 255)<<8) | (ip[i+1] & 255), 16 ) );
}
}
return sb.toString();
}
 
public static String toString(InetAddress adr) {
return toString( adr.getAddress() );
}
 
public String toString() {
StringBuilder sb = new StringBuilder();
for (int i=0; i<ip.length; i++ ) {
if (i>0) sb.append(',');
if (deny[i]) sb.append('-');
sb.append(toString(ip[i])+"/"+mask[i]);
}
return sb.toString();
}
}
 
// *****************************************************************************
// ******* EPDescriptor ********************************************************
// *****************************************************************************
class EPDescriptor {
private boolean in, bulk;
public int num;
public int size;
public EPDescriptor ( boolean p_in, int p_num, boolean p_bulk, int p_size ) {
in = p_in;
num = p_num;
bulk = p_bulk;
size = p_size;
// System.out.println((in ? "IN" : "OUT" ) + " EP "+num + ": " + (bulk ? "BULK" : "INT" ) + ", " + size);
}
public boolean in () {
return in;
}
public int num () {
return num;
}
public boolean bulk () {
return bulk;
}
 
public int size () {
return size;
}
}
// *****************************************************************************
// ******* EPDescriptorVector **************************************************
// *****************************************************************************
class EPDescriptorVector extends Vector<EPDescriptor> {
public EPDescriptor find(int num) {
for (int i=0; i<size(); i++) {
if ( elementAt(i).num() == num ) return elementAt(i);
}
return null;
}
}
 
// *****************************************************************************
// ******* DeviceServer ********************************************************
// *****************************************************************************
class DeviceServer {
public static final int maxConnections = 128;
public final static SimpleDateFormat msgDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
 
public static int usbVendorId = ZtexDevice1.ztexVendorId;
public static int usbProductId = -1;
public static boolean cypress = true;
public static int httpPort = 9080;
public static int socketPort = 9081;
public static boolean quit = false;
private static Vector<Socket> socketVector = new Vector<Socket>();
private static boolean verbose = false;
private static boolean quiet = false;
private static PrintStream logFile = null;
private static PrintStream log2File = null;
private static IPPermissions httpPermissions = new IPPermissions();
private static IPPermissions socketPermissions = new IPPermissions();
private static String httpBind = null, socketBind = null;
private static ZtexScanBus1 scanBus;
private static int busIdx[];
private static int devNum[];
private static int confNum[];
private static EPDescriptorVector eps[];
private static Vector<String> dirnameDB = new Vector<String>();
 
// ******* addSocket ***********************************************************
public synchronized static void addSocket( Socket socket ) {
info( "Connection from " + IPPermissions.toString( socket.getInetAddress() ) + " established" );
socketVector.addElement(socket);
}
 
// ******* removeSocket ********************************************************
public synchronized static void removeSocket(Socket socket) {
info( "Connection from " + IPPermissions.toString( socket.getInetAddress() ) + " closed" );
socketVector.remove(socket);
}
 
// ******* httpPermissions *****************************************************
public static IPPermissions httpPermissions() {
return httpPermissions;
}
// ******* sleep ***************************************************************
public static void sleep(int ms) {
try {
Thread.sleep(ms);
}
catch ( InterruptedException e ) {
}
}
 
// ******* info ****************************************************************
public synchronized static void info (String msg) {
if ( verbose ) System.err.println( msg );
if ( log2File != null ) log2File.println( msgDateFormat.format(new Date()) + ": " + msg );
}
 
// ******* error ***************************************************************
public synchronized static void error (String msg) {
if ( ! quiet ) System.err.println( msg );
if ( logFile != null ) logFile.println( msgDateFormat.format(new Date()) + ": " + msg );
if ( log2File != null ) log2File.println( msgDateFormat.format(new Date()) + ": " + msg );
}
 
// ******* getDirnameNum *******************************************************
public static int getDirnameIdx ( String dirname ) {
if ( dirname == null ) return -1;
for ( int i=0; i<dirnameDB.size(); i++ ) {
if ( dirname.equals(dirnameDB.elementAt(i)) ) return i;
}
dirnameDB.add(dirname);
info("Found bus \"" +dirname + "\": assigned bus index " + (dirnameDB.size()-1));
return dirnameDB.size()-1;
}
 
// ******* scanUSB *************************************************************
public synchronized static void scanUSB () {
info("Scanning USB ...");
scanBus = new ZtexScanBus1( usbVendorId, usbProductId, cypress, false, 1 );
int n = scanBus.numberOfDevices();
if ( n > 0 ) {
busIdx = new int[n];
devNum = new int[n];
confNum = new int[n];
eps = new EPDescriptorVector[n];
for ( int i=0; i<n; i++ ) {
Usb_Device dev = scanBus.device(i).dev();
busIdx[i] = getDirnameIdx( dev.getBus().getDirname() );
devNum[i] = dev.getDevnum();
confNum[i] = -1;
eps[i] = new EPDescriptorVector();
try {
if ( dev.getDescriptor().getBNumConfigurations() < 1 ) throw new Exception();
Usb_Config_Descriptor conf = dev.getConfig()[0];
confNum[i] = conf.getBConfigurationValue();
if ( conf.getBNumInterfaces() < 1 ) throw new Exception();
Usb_Interface iface = conf.getInterface()[0];
if ( iface.getNumAltsetting() < 1 ) throw new Exception();
Usb_Interface_Descriptor desc = iface.getAltsetting()[0];
if ( desc.getBNumEndpoints() < 1 ) throw new Exception();
Usb_Endpoint_Descriptor epd[] = desc.getEndpoint();
for ( int j=0; j<epd.length; j++ ) {
int t = epd[j].getBmAttributes() & Usb_Endpoint_Descriptor.USB_ENDPOINT_TYPE_MASK;
if ( t == Usb_Endpoint_Descriptor.USB_ENDPOINT_TYPE_BULK || t == Usb_Endpoint_Descriptor.USB_ENDPOINT_TYPE_INTERRUPT )
eps[i].addElement(new EPDescriptor(
(epd[j].getBEndpointAddress() & Usb_Endpoint_Descriptor.USB_ENDPOINT_DIR_MASK) != 0,
epd[j].getBEndpointAddress() & Usb_Endpoint_Descriptor.USB_ENDPOINT_ADDRESS_MASK,
t == Usb_Endpoint_Descriptor.USB_ENDPOINT_TYPE_BULK,
epd[j].getWMaxPacketSize()
) );
}
}
catch (Exception e) {
}
}
}
}
 
// ******* loadFirmware ********************************************************
public synchronized static void loadFirmware ( Ztex1v1 ztex, StringBuilder messages, InputStream in, String inName, boolean force, boolean toVolatile, boolean toNonVolatile, boolean eraseEeprom ) throws Exception {
if ( ztex == null ) return;
eraseEeprom = eraseEeprom && (! toNonVolatile );
if ( toVolatile || toNonVolatile ) {
if ( in == null ) throw new Exception("No firmware defined.");
ZtexIhxFile1 ihxFile = new ZtexIhxFile1( in, inName );
if ( toVolatile ) {
long i = ztex.uploadFirmware( ihxFile, force );
if ( messages != null ) messages.append("Firmware uploaded to volatile memory: "+i+"ms\n");
}
if ( toNonVolatile ) {
long i = ztex.eepromUpload( ihxFile, force );
if ( messages != null ) messages.append("Firmware uploaded to non-volatile memory: "+i+"ms\n");
}
}
if ( eraseEeprom ) {
ztex.eepromDisable();
if ( messages != null ) messages.append("Firmware in non-volatile memory disabled\n");
}
}
 
// ******* loadBitstream *******************************************************
public synchronized static void loadBitstream ( Ztex1v1 ztex, StringBuilder messages, byte[] buf, String inName, boolean force, boolean toVolatile, boolean toNonVolatile, boolean eraseFlash ) throws Exception {
if ( ztex == null ) return;
eraseFlash = eraseFlash && (! toNonVolatile );
if ( toVolatile || toNonVolatile ) {
if ( buf == null ) throw new Exception("No firmware defined.");
if ( toVolatile ) {
long i = ztex.configureFpga( new ByteArrayInputStream(buf), force, -1 );
if ( messages != null ) messages.append("Bitstream uploaded to volatile memory: "+i+"ms\n");
}
if ( toNonVolatile ) {
long i = ztex.flashUploadBitstream( new ByteArrayInputStream(buf), -1 );
if ( messages != null ) messages.append("Bitstream uploaded to non-volatile memory: "+i+"ms\n");
}
}
if ( eraseFlash ) {
ztex.flashResetBitstream();
if ( messages != null ) messages.append("Bitstream in non-volatile memory disabled\n");
}
}
 
public synchronized static void loadBitstream ( Ztex1v1 ztex, StringBuilder messages, InputStream in, String inName, boolean force, boolean toVolatile, boolean toNonVolatile, boolean eraseFlash ) throws Exception {
byte buf[] = new byte[65536];
ByteArrayOutputStream out = new ByteArrayOutputStream();
int i;
do {
i=in.read(buf);
if (i>0) out.write(buf,0,i);
} while (i>0);
loadBitstream(ztex, messages, out.toByteArray(), inName, force, toVolatile, toNonVolatile, eraseFlash);
}
 
// ******* claim ***************************************************************
public synchronized static void claim ( Ztex1v1 ztex, StringBuilder messages ) {
int c = 1;
for (int i=0; i<scanBus.numberOfDevices(); i++ ) {
if ( scanBus.device(i) == ztex.dev() ) {
c=confNum[i];
}
}
try {
ztex.setConfiguration(c);
}
catch ( UsbException e ) {
if (messages!=null) messages.append("Warning: "+e.getLocalizedMessage()+'\n');
}
 
try {
ztex.claimInterface(0);
}
catch ( UsbException e ) {
if (messages!=null) messages.append("Warning: "+e.getLocalizedMessage()+'\n');
}
}
 
// ******* release *************************************************************
public synchronized static void release ( Ztex1v1 ztex ) {
if (ztex!=null) ztex.releaseInterface(0);
}
 
// ******* epUpload ************************************************************
public synchronized static void epUpload ( Ztex1v1 ztex, EPDescriptor ep, InputStream in, StringBuilder messages ) throws Exception {
if ( ztex == null ) return;
if ( ep == null || ep.in() ) throw new UsbException(ztex.dev().dev(), "No valid endpoint defined");
claim(ztex,messages);
int bufSize = ep.num()==1 ? 64 : 256*1024;
byte buf[] = new byte[bufSize];
int r,i;
do {
i = r = Math.max(in.read(buf),0);
if ( i>0 ) i = ep.bulk() ? LibusbJava.usb_bulk_write(ztex.handle(), ep.num, buf, r, 1000) : LibusbJava.usb_interrupt_write(ztex.handle(), ep.num, buf, r, 1000);
} while (r>0 && r==i);
 
if (i<0) throw new UsbException("Write error: " + LibusbJava.usb_strerror());
if ( r!=i ) throw new UsbException("Write error: wrote " + i + " bytes instead of " + r + " bytes");
}
 
// ******* epDownload **********************************************************
public synchronized static void epDownload ( Ztex1v1 ztex, EPDescriptor ep, OutputStream out, int maxSize, StringBuilder messages ) throws Exception {
if ( ztex == null ) return;
if ( ep == null || ! ep.in() ) throw new UsbException(ztex.dev().dev(), "No valid endpoint defined");
if ( maxSize < 1 ) maxSize = Integer.MAX_VALUE;
claim(ztex,messages);
int bufSize = ep.num()==1 ? 64 : 256*1024;
byte buf[] = new byte[bufSize];
int r,i;
int j=0;
do {
r = Math.min(bufSize,maxSize);
maxSize-=r;
i = ep.bulk() ? LibusbJava.usb_bulk_read(ztex.handle(), 0x80 | ep.num, buf, r, j==0 ? 5000 : 1000) : LibusbJava.usb_interrupt_read(ztex.handle(), 0x80 | ep.num, buf, r, 1000);
if (i>0) out.write(buf,0,i);
// System.out.println("r: "+i);
j++;
} while (maxSize>0 && r==i);
 
if (i<0) throw new UsbException("Read error: " + LibusbJava.usb_strerror());
}
 
// ******* numberOfDevices *****************************************************
public synchronized static int numberOfDevices() {
return scanBus.numberOfDevices();
}
 
// ******* device **************************************************************
public synchronized static ZtexDevice1 device (int i) throws IndexOutOfBoundsException {
return scanBus.device(i);
}
 
// ******* findDevice **********************************************************
public synchronized static ZtexDevice1 findDevice (int b, int d) {
int n = numberOfDevices();
for ( int i=0; i<n; i++ ) {
try {
if ( busIdx[i]==b && devNum[i]==d ) return scanBus.device(i);
} catch ( IndexOutOfBoundsException e ) {
}
}
return null;
}
 
// ******* busIdx **************************************************************
public synchronized static int busIdx (int i) throws IndexOutOfBoundsException {
if ( i<0 || i>=busIdx.length) throw new IndexOutOfBoundsException( "Device number out of range. Valid numbers are 0.." + (busIdx.length-1) );
return busIdx[i];
}
 
// ******* devNum **************************************************************
public synchronized static int devNum (int i) throws IndexOutOfBoundsException {
if ( i<0 || i>=devNum.length) throw new IndexOutOfBoundsException( "Device number out of range. Valid numbers are 0.." + (devNum.length-1) );
return devNum[i];
}
 
// ******* getEps *************************************************************
public synchronized static EPDescriptorVector getEps (int b, int d) {
int n = numberOfDevices();
for ( int i=0; i<n; i++ ) {
try {
if ( busIdx[i]==b && devNum[i]==d ) return eps[i];
} catch ( IndexOutOfBoundsException e ) {
}
}
return null;
}
 
// ******* main ****************************************************************
public static void main (String args[]) {
LibusbJava.usb_init();
 
final String helpMsg = new String (
"Global parameters:\n"+
" -nc Do not scan for Cypress EZ-USB devices without ZTEX firmware\n"+
" -id <VID> <PID> Scan for devices with given Vendor ID and Product ID\n"+
" -sp <port> Port number for the socket interface (default: 9081; <0: disabled)\n"+
" -hp <port> Port number for the HTTP interface (default: 9080; <0: disabled)\n"+
" -sa [-]<address>[/<mask>][,...] Allow (permit if '-' is given) HTTP connection from this address(es),\n"+
" <mask> 24 is equivalent to 255.255.255.0, default: 127.0.0.1\n"+
" -ha [-]<address>[/<mask>][,...] Allow (permit if '-' is given) HTTP connection from this address(es),\n"+
" <mask> 24 is equivalent to 255.255.255.0, default: 127.0.0.1\n"+
" -sb <address> Bind socket server to this address (default: listen on all interfaces)\n"+
" -hb <address> Bind HTTP server to this address (default: listen on all interfaces)\n"+
" -v Be verbose\n"+
" -q Be quiet\n"+
" -l Log file\n"+
" -l2 Verbose log file\n"+
" -h Help" );
// process parameters
try {
 
for (int i=0; i<args.length; i++ ) {
if ( args[i].equals("-nc") ) {
cypress = false;
}
else if ( args[i].equals("-id") ) {
i++;
try {
if (i>=args.length)
throw new Exception();
usbVendorId = Integer.decode( args[i] );
}
catch (Exception e) {
System.err.println("Error: Vendor ID expected after -id");
System.err.println(helpMsg);
System.exit(1);
}
i++;
try {
if (i>=args.length)
throw new Exception();
usbProductId = Integer.decode( args[i] );
}
catch (Exception e) {
System.err.println("Error: Product ID expected after -id <VID>");
System.err.println(helpMsg);
System.exit(1);
}
}
else if ( args[i].equals("-hp") ) {
i++;
try {
if (i>=args.length)
throw new Exception();
httpPort = Integer.parseInt( args[i] );
}
catch (Exception e) {
System.err.println("Error: Port number expected after -hp");
System.err.println(helpMsg);
System.exit(1);
}
}
else if ( args[i].equals("-sp") ) {
i++;
try {
if (i>=args.length)
throw new Exception();
socketPort = Integer.parseInt( args[i] );
}
catch (Exception e) {
System.err.println("Error: Port number expected after -sp");
System.err.println(helpMsg);
System.exit(1);
}
}
else if ( args[i].equals("-ha") ) {
i++;
try {
if (i>=args.length)
throw new Exception("Argument expected after -ha");
httpPermissions = new IPPermissions( args[i] );
}
catch (Exception e) {
System.err.println("Error parsing HTTP permissions:");
System.exit(1);
}
}
else if ( args[i].equals("-sa") ) {
i++;
try {
if (i>=args.length)
throw new Exception("Argument expected after -hs");
socketPermissions = new IPPermissions( args[i] );
}
catch (Exception e) {
System.err.println("Error parsing socket permissions:");
System.exit(1);
}
}
else if ( args[i].equals("-hb") ) {
i++;
try {
if (i>=args.length)
throw new Exception("Argument expected after -hb");
httpBind = args[i];
}
catch (Exception e) {
System.err.println("Error parsing HTTP permissions:");
System.exit(1);
}
}
else if ( args[i].equals("-sb") ) {
i++;
try {
if (i>=args.length)
throw new Exception("Argument expected after -sb");
socketBind = args[i];
}
catch (Exception e) {
System.err.println("Error parsing HTTP permissions:");
System.exit(1);
}
}
else if ( args[i].equals("-hb") ) {
i++;
try {
if (i>=args.length)
throw new Exception("Argument expected after -hb");
httpBind = args[i];
}
catch (Exception e) {
System.err.println("Error parsing HTTP permissions:");
System.exit(1);
}
}
else if ( args[i].equals("-v") ) {
verbose = true;
}
else if ( args[i].equals("-q") ) {
quiet = true;
}
else if ( args[i].equals("-l") ) {
i++;
if (i>=args.length) {
System.err.println("Error: File name expected after `-l'");
System.err.println(helpMsg);
System.exit(1);
}
try {
logFile = new PrintStream ( new FileOutputStream ( args[i], true ), true );
}
catch (Exception e) {
System.err.println("Error: File name expected after `-l': "+e.getLocalizedMessage() );
System.err.println(helpMsg);
System.exit(1);
}
}
else if ( args[i].equals("-l2") ) {
i++;
if (i>=args.length) {
System.err.println("Error: File name expected after `-l2'");
System.err.println(helpMsg);
System.exit(1);
}
try {
log2File = new PrintStream ( new FileOutputStream ( args[i], true ), true );
}
catch (Exception e) {
System.err.println("Error: File name expected after `-l2': "+e.getLocalizedMessage() );
System.err.println(helpMsg);
System.exit(1);
}
}
else if ( args[i].equals("-h") ) {
System.err.println(helpMsg);
System.exit(0);
}
else {
System.err.println("Error: Invalid option: `"+args[i]+"'");
System.err.println(helpMsg);
System.exit(1);
}
}
 
if ( httpPort < 0 && socketPort < 0 ) {
error("neither HTTP nor socket interface enabled: exiting");
System.exit(0);
}
 
// init USB stuff
LibusbJava.usb_init();
LibusbJava.usb_find_busses();
Usb_Bus bus = LibusbJava.usb_get_busses();
while ( bus != null ) {
getDirnameIdx(bus.getDirname());
bus = bus.getNext();
}
scanUSB();
 
// start http server
HttpServer httpServer = null;
if ( httpPort > 0 ) {
error ( "Listening for http connections at port " + httpPort + " from addresses " + httpPermissions ); // not really an error
httpServer = HttpServer.create( ( httpBind == null ) ? new InetSocketAddress(httpPort) : new InetSocketAddress(InetAddress.getByName(httpBind),httpPort), 0);
httpServer.createContext("/", new ZtexHttpHandler());
httpServer.setExecutor(null);
httpServer.start();
}
 
// run socket server
if ( socketPort > 0 ) {
error ( "Listening for socket connections at port " + socketPort + " from addresses " + socketPermissions ); // not really an error
ServerSocket ss = (socketBind == null) ? new ServerSocket ( socketPort, 20 ) : new ServerSocket ( socketPort, 20, InetAddress.getByName(socketBind));
ss.setSoTimeout(500);
while ( ! quit ) {
if ( socketVector.size() < maxConnections ) {
try {
Socket cs = ss.accept();
if ( socketPermissions.checkAddress( cs.getInetAddress() ) ) {
new SocketThread( cs );
}
else {
info( "Connection from " + IPPermissions.toString( cs.getInetAddress() ) + " refused" );
}
}
catch ( SocketTimeoutException e ) {
}
}
else {
sleep(1000);
}
}
}
else {
while ( ! quit ) {
sleep(1000);
}
}
 
// stop http server
if ( httpServer!=null ) httpServer.stop(1);
}
catch (Exception e) {
error("Error: "+e.getLocalizedMessage() );
}
}
}
/DeviceServer/DeviceServer
0,0 → 1,9
#!/bin/bash
DIR=${0%/*}
if [ -r $DIR/DeviceServer.jar ]; then
java -cp $DIR/DeviceServer.jar DeviceServer $@
else
export CLASSPATH=$CLASSPATH:/usr/local/share/java:/usr/share/java
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib:/usr/lib
java DeviceServer $@
fi
DeviceServer/DeviceServer Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: DeviceServer/Makefile =================================================================== --- DeviceServer/Makefile (nonexistent) +++ DeviceServer/Makefile (revision 8) @@ -0,0 +1,16 @@ +######################### +# configuration section # +######################### + +ZTEXPREFIX=../.. + +JARTARGET=DeviceServer.jar +CLASSTARGETS=DeviceServer.class +CLASSEXTRADEPS= +#CLASSEXTRADEPS:=$(wildcard $(ZTEXPREFIX)/java/ztex/*.java) + +################################ +# DO NOT CHANAGE THE FOLLOWING # +################################ + +include $(ZTEXPREFIX)/Makefile.mk Index: DeviceServer/ReadMe =================================================================== --- DeviceServer/ReadMe (nonexistent) +++ DeviceServer/ReadMe (revision 8) @@ -0,0 +1,8 @@ +DeviceServer is an easy-to-use user interface for ZTEX Boards. It allows to +access the device through HTTP or a simple socket protocol and support Supports +uploading of Firmware / Bitstream into volatile and non-volatile memory and +simple simple I/O (reading and writing to endpoints) + +The documentation can be found at +http://wiki.ztex.de/doku.php?id=en:software:deviceserver + Index: ztex/ConfigData.java =================================================================== --- ztex/ConfigData.java (nonexistent) +++ ztex/ConfigData.java (revision 8) @@ -0,0 +1,491 @@ +/*! + Java host software API of ZTEX EZ-USB FX2 SDK + Copyright (C) 2009-2011 ZTEX GmbH. + http://www.ztex.de + + 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 + published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see http://www.gnu.org/licenses/. +!*/ + +package ztex; + +import ch.ntb.usb.*; + +/** + * This class represents the configuration data space of ZTEX FPGA Boards that support it. + * The internal format is + *








    +  * <Address> <Description>








    +  * 0..2      Signature "CD0"








    +  * 3         Kind of FPGA Board, see {@link #boardNames}, e.g. 2 for "ZTEX USB-FPGA Module",








    +  * 4         FPGA Board series, e.g. 2








    +  * 5         FPGA Board number (number behind the dot), e.g. 16








    +  * 6..7      FPGA Board variant (letter), e.g. "b"








    +  * 8..9      FPGA, see {@link #fpgas}, e.g. 12 for X7A200T








    +  * 10        FPGA package, see {@link #packages}, e.g. 3 for FBG484








    +  * 11..13    Speed grade + temperature range, e.g. "2C"








    +  * 14        RAM size, format is ( n & 0xf0 ) << ( (n & 0xf) + 16 ) bytes








    +  * 15        RAM type, see {@link #ramTypes}








    +  * 16..25    Serial number, overwrites SN_STRING of the ZTEX descriptor.








    +  *           If it is equal to "0000000000" (default) it is replaced by the unique MAC address.








    +  * 26..27    Actual size of Bitstream in 4K sectors; 0 means Bitstream disabled (default)








    +  * 28..29    Maximum size of Bitstream in 4K sectors; 0 means that either no Flash








    +  *           is present or that this information is stored in Flash (exchangeable media)








    +  * 30..79    Reserved








    +  * 80..127   48 bytes user space








    +  * 
+ */ + +public class ConfigData { + +/** + * Kinds of FPGA Boards. + * It's defined as + *
{@code








    +public static final String boardNames[] = {








    +    "(unknown)" ,             // 0








    +    "ZTEX FPGA Module" ,      // 1








    +    "ZTEX USB-FPGA Module"    // 2








    +};}
+ **/ + public static final String boardNames[] = { + "(unknown)" , // 0 + "ZTEX FPGA Module" , // 1 + "ZTEX USB-FPGA Module" // 2 + }; + +/** + * FPGA's used on ZTEX FPGA Boards. + * It's defined as + *
{@code








    +public static final String fpgas[] = {








    +	"(unknown)" ,  // 0








    +	"XC6SLX9" ,    // 1








    +	"XC6SLX16" ,   // 2








    +	"XC6SLX25" ,   // 3








    +	"XC6SLX45" ,   // 4








    +	"XC6SLX75" ,   // 5








    +	"XC6SLX100" ,  // 6








    +	"XC6SLX150" ,  // 7








    +	"XC7A35T",     // 8








    +	"XC7A50T",     // 9








    +	"XC7A75T",     // 10








    +	"XC7A100T",    // 11








    +	"XC7A200T",    // 12








    +	"Quad-XC6SLX150"  // 13








    +};}
+ **/ + public static final String fpgas[] = { + "(unknown)" , // 0 + "XC6SLX9" , // 1 + "XC6SLX16" , // 2 + "XC6SLX25" , // 3 + "XC6SLX45" , // 4 + "XC6SLX75" , // 5 + "XC6SLX100" , // 6 + "XC6SLX150" , // 7 + "XC7A35T", // 8 + "XC7A50T", // 9 + "XC7A75T", // 10 + "XC7A100T", // 11 + "XC7A200T", // 12 + "Quad-XC6SLX150" // 13 + }; + +/** * FPGA packages used on ZTEX FPGA boards. + * It's defined as + *
{@code








    +public static final String packages[] = {








    +	"(unknown)",  // 0








    +	"FTG256" ,    // 1  256 balls, 1.0mm








    +	"CSG324" ,    // 2  324 balls, 0.8mm








    +	"CSG484" ,    // 3  484 balls, 0.8mm








    +	"FBG484"      // 4  484 balls, 1.0mm








    +};}
+ **/ + public static final String packages[] = { + "(unknown)", // 0 + "FTG256" , // 1 256 balls, 1.0mm + "CSG324" , // 2 324 balls, 0.8mm + "CSG484" , // 3 484 balls, 0.8mm + "FBG484" // 4 484 balls, 1.0mm + }; + +/** * RAM types and speed used on ZTEX FPGA boards. + * It's defined as + *
{@code








    +public static final String ramTypes[] = {








    +	"(unknown)",        // 0








    +	"DDR-200 SDRAM",    // 1








    +	"DDR-266 SDRAM",    // 2








    +	"DDR-333 SDRAM",    // 3








    +	"DDR-400 SDRAM",    // 4








    +	"DDR2-400 SDRAM",   // 5








    +	"DDR2-533 SDRAM",   // 6








    +	"DDR2-667 SDRAM",   // 7








    +	"DDR2-800 SDRAM",   // 8








    +	"DDR2-1066 SDRAM"   // 9








    +};}
+ **/ + public static final String ramTypes[] = { + "(unknown)", // 0 + "DDR-200 SDRAM", // 1 + "DDR-266 SDRAM", // 2 + "DDR-333 SDRAM", // 3 + "DDR-400 SDRAM", // 4 + "DDR2-400 SDRAM", // 5 + "DDR2-533 SDRAM", // 6 + "DDR2-667 SDRAM", // 7 + "DDR2-800 SDRAM", // 8 + "DDR2-1066 SDRAM", // 9 + "DDR3-800 SDRAM", // 10 + "DDR3-1066 SDRAM" // 11 + }; + + private byte[] data = new byte[128]; // data buffer + private Ztex1v1 ztex = null; + + +/** + * Constructs an empty instance. + */ + public ConfigData() { + data[0] = 67; + data[1] = 68; + data[2] = 48; + for ( int i=3; i<128; i++) + data[i] = 0; + for ( int i=16; i<26; i++) + data[i] = 48; + } + +/** + * Constructs an instance and connects it with z. Also see {@link #connect(Ztex1v1)}. + * @param z The ztex device to connect with. + * @throws InvalidFirmwareException if interface 1 is not supported. + * @throws UsbException If a communication error occurs. + * @throws CapabilityException If no MAC-EEPROM support is present. + */ + public ConfigData( Ztex1v1 z ) throws InvalidFirmwareException, UsbException, CapabilityException { + this(); + connect(z); + } + + +/** + * Reads the configuration data (if existent) from a device and connects it to this instance. + * After this user defined settings (e.g. serial number, bitstream size) are + * stored on device immediately after they are altered. + * @param z The ztex device to connect with. + * @return True if configuration data could be read. + * @throws InvalidFirmwareException If interface 1 is not supported. + * @throws UsbException If a communication error occurs. + * @throws CapabilityException If no MAC-EEPROM support is present. + */ + public boolean connect( Ztex1v1 z ) throws InvalidFirmwareException, UsbException, CapabilityException { + ztex = z; + if ( ztex == null ) return false; + + byte[] buf = new byte[128]; + ztex.macEepromRead(0,buf,128); + if ( buf[0]==67 && buf[1]==68 && buf[2]==48 ) { + for ( int i=3; i<128; i++) + data[i] = buf[i]; + return true; + } + return false; + } + + +/** + * Disconnects the currently connected device. + * After this modified settings are not stored on device anymore. + * @return True if a device was connected. + */ + public boolean disconnect() { + if ( ztex == null ) return false; + ztex = null; + return true; + } + + +/** + * Returns a copy of the configuration data array. + * @return A copy of the configuration data array. + */ + public byte[] data () { + byte[] buf = new byte[128]; + for ( int i=0; i<128; i++) + buf[i] = data[i]; + return buf; + } + + +/** + * Returns a string of an array of strings including range check. + */ + private String stringOfArray (String[] a, int i) { + if ( i > a.length || i < 0 ) i = 0; + return a[i]; + } + + +/** + * Finds a string from array. + */ + private int findFromArray ( String[] a, String s) { + int i = 0; + while ( i < a.length && !a[i].equals(s) ) i++; + if ( i >= a.length ) { + System.err.print("Invalid value: `" + s + "'. Possible values: `" + a[1] + "'"); + for (int j=2; j 128-start ) len = 128-start; + if ( len <= 0 ) return false; + byte[] buf = new byte[len]; + for ( int i=0; isetName("ZTEX USB-FPGA Module", 2, 16, "b"); // denotes "ZTEX USB-FPGA Module 2.16b" + * This setting is not transferred to the FPGA Board because is should not be altered by the user. + * @param kind Kind of FPGA Board, see {@link #boardNames} for possible values, e.g. "ZTEX USB-FPGA Module" + * @param series FPGA Board series, e.g. 2 + * @param number FPGA Board number (number behind the dot), e.g. 16 + * @param variant FPGA Board variant (letter), e.g. "b" + */ + public void setName ( String kind, int series, int number, String variant) { + data[3] = (byte) findFromArray(boardNames, kind); + data[4] = (byte) (series & 255); + data[5] = (byte) (number & 255); + stringToData(variant,6,2); + } + +/** + * Returns FPGA information. + * Notation of the result is <name>-<package>-<speed grade and temperature range>, e.g. XC7A200T-FBG484-2C. + * @return FPGA Information. + */ + public String getFpga () { + return stringOfArray(fpgas, (data[8] & 255) | ((data[9] & 255) << 8)) + "-" + stringOfArray(packages, data[10]) + "-" + stringFromData(11,3); + } + +/** + * Sets FPGA information. + * Example:
setFpga("XC7A200T", "FBG484", "2C");   // denotes Xilinx part number XC7A200T-2FBG484C
+ * This setting is not transferred to the FPGA Board because is should not be altered by the user. + * @param name Name of the FPGA, see {@link #fpgas} for possible values, e.g. "XC7A200T" + * @param pckg FPGA package, see {@link #packages} for possible values, e.g. "FBG484" + * @param sg Speed grade and temperature range, e.g. "2C" + */ + public void setFpga ( String name, String pckg, String sg) { + int i = findFromArray(fpgas, name); + data[8] = (byte) (i & 255); + data[9] = (byte) ((i>>8) & 255); + data[10] = (byte) findFromArray(packages, pckg); + stringToData(sg,11,3); + } + +/** + * Returns RAM type and speed. + * @return FPGA Information. + */ + public String getRamType () { + return stringOfArray(ramTypes, (data[15] & 255)); + } + +/** + * Returns RAM size in bytes. + * @return RAM size in bytes. + */ + public int getRamSize () { + return (data[14] & 0xf0) << ( (data[14] & 0xf) + 16 ); + } + +/** + * Sets RAM information. + * Example:
setRam(128, "DDR2-800 SDRAM");   // sets RAM info to 128 MB DDR2-800 SDRAM
+ * This setting is not transferred to the FPGA Board because is should not be altered by the user. + * @param size RAM size in MBytes, e.g. 128 + * @param type RAM type and speed, see {@link #ramTypes} for possible values, e.g. "DDR2-800 SDRAM" + */ + public void setRam ( int size, String type) { + if (size<0 || size>480) { + System.err.println("Warning: Invalid RAM size: `" + size + "'. Possible values are 0 to 480."); + size = 0; + } + int i=0; + while (size >= 16) { + i++; + size = size >> 1; + } + data[14] = (byte) ((size << 4) | (i & 15)); + data[15] = (byte) findFromArray(ramTypes, type); + } + +/** + * Returns maximum size of bitstream in bytes. + * This is the amount of flash which should be reserved for the bitstream. + * @return Maximum size of bitstream in bytes sectors. + */ + public int getMaxBitstreamSize () { + return ( (data[28] & 255) | ((data[29] & 255) << 8) ) * 4096; + } + +/** + * Sets the maximum size of bitstream in 4 KByte sectors. + * This setting is not transferred to the FPGA Board because is should not be altered by the user. + * @param size4k Maximum size of bitstream in 4 KByte sectors. E.g. a value of 256 reserves 1 MByte for the bitstream. + */ + public void setMaxBitstreamSize ( int size4k ) { + data[28] = (byte) (size4k & 255); + data[29] = (byte) ((size4k>> 8) & 255); + } + +/** + * Returns actual size of bitstream in bytes sectors. + * 0 means that no bitstream is stored. The value is rounded up to a multiples of 4096. + * @return Actual size of bitstream in byte sectors. + */ + public int getBitstreamSize () { + return ( (data[26] & 255) | ((data[27] & 255) << 8) ) * 4096; + } + +/** + * Sets the actual size of bitstream in bytes. The value is rounded up to a multiple of 4096. + * If a device is connected, this setting is transferred to the FPGA Board. + * A warning is printed if bitstream size is larger then the reserved size (see {@link #getMaxBitstreamSize()}). + * @param size Actual size of bitstream in bytes. + * @return True if a device is connected and setting was send. + * @throws InvalidFirmwareException If interface 1 is not supported. + * @throws UsbException If a communication error occurs. + * @throws CapabilityException If no MAC-EEPROM support is present. + */ + public boolean setBitstreamSize ( int size ) throws InvalidFirmwareException, UsbException, CapabilityException { + if ( size < 0 ) size = 0; + size = (size + 4095) >> 12; + int i = (data[28] & 255) | ((data[29] & 255) << 8); + if ( size > i ) System.err.println("Warning: Bitstream size of " + size + " 4K sectors larger than reserved memory of " + i + " 4K sectors"); + data[26] = (byte) (size & 255); + data[27] = (byte) ((size>> 8) & 255); + return sendData(26,2); + } + +/** + * Returns the serial number. This is not necessarily the serial number + * returned by the FPGA board according to the USB specification, see {@link #setSN(String)} + * @return Serial number as stored in the configuration data space. + */ + public String getSN () { + return stringFromData(16,10); + } + +/** + * Sets the serial number. + * During start-up the firmware overwrites SN_STRING from the ZTEX descriptor (see {@link ZtexDevice1}) by this value. + * If it is equal to "0000000000" (default) it is replaced by the unique MAC address.

+ * This setting is transferred to the FPGA Board. + * Change takes effect after the next restart of the firmware. + * @param sn Serial number string. Only the first 10 characters are considered. + * @return True if a device is connected and setting was send. + * @throws InvalidFirmwareException If interface 1 is not supported. + * @throws UsbException If a communication error occurs. + * @throws CapabilityException If no MAC-EEPROM support is present. + */ + public boolean setSN ( String sn ) throws InvalidFirmwareException, UsbException, CapabilityException { + stringToData(sn,16,10); + return sendData(16,10); + } + +/** + * Returns user data at index i. + * @param i the index. Valid values are 0 to 47. + * @return User data. + * @throws IndexOutOfBoundsException If i is smaller than 0 or greater than 47. + */ + public byte getUserData (int i) { + if ( i<0 || i>47 ) throw new IndexOutOfBoundsException ( "Invalid index: " + i + ". Valid range is 0 to 47."); + return data[80+i]; + } + +/** + * Sets user data at index i to value v. Use the method {@link #getMaxBitstreamSize()} + * to transfer the data to the FPGA Board. + * @param i The index. Valid values are 0 to 47. + * @param v The value. + * @throws IndexOutOfBoundsException If i is smaller than 0 or greater than 47. + */ + public void setUserData (int i, byte v) throws IndexOutOfBoundsException { + if ( i<0 || i>47 ) throw new IndexOutOfBoundsException ( "Invalid index: " + i + ". Valid range is 0 to 47."); + data[80+i] = v; + } + +/** + * Sends the user data to the FPGA Board. + * @return True if a device is connected and data could be send. + * @throws InvalidFirmwareException If interface 1 is not supported. + * @throws UsbException If a communication error occurs. + * @throws CapabilityException If no MAC-EEPROM support is present. + */ + public boolean sendtUserData () throws InvalidFirmwareException, UsbException, CapabilityException { + return sendData(80,48); + } +} Index: ztex/Ztex1.java =================================================================== --- ztex/Ztex1.java (revision 7) +++ ztex/Ztex1.java (revision 8) @@ -55,7 +55,6 @@ private long lastVendorCommandT = 0; - // ******* Ztex1 *************************************************************** /** * Constructs an instance from a given device. @@ -64,7 +63,15 @@ */ public Ztex1 ( ZtexDevice1 pDev ) throws UsbException { dev = pDev; - + init(); + } + +// ******* init **************************************************************** +/** + * Initializates the class. + * @throws UsbException if an communication error occurred. + */ + protected void init () throws UsbException { for (int i=0; i<256; i++) interfaceClaimed[i] = false; @@ -463,7 +470,7 @@ throw new InvalidFirmwareException( e.getLocalizedMessage() ); } - handle = LibusbJava.usb_open( dev.dev() ); + init(); } // ******* uploadFirmware ****************************************************** @@ -543,6 +550,39 @@ return uploadFirmware( ihxFile, force ); } +/** + * Uploads the firmware to the EZ-USB and manages the renumeration process. + *

+ * Before the firmware is uploaded the device is set into a reset state. + * After the upload the firmware is booted and the renumeration starts. + * During this process the device disappears from the bus and a new one + * occurs which will be assigned to this class automatically (instead of the disappeared one). + * @param ihxIn Input stream from which the ihx file is read. + * @param name Name of the input. + * @param force The compatibility check is skipped if true. + * @throws IncompatibleFirmwareException if the given firmware is not compatible to the installed one, see {@link ZtexDevice1#compatible(int,int,int,int)} (Upload can be enforced using the force parameter) + * @throws FirmwareUploadException If an error occurred while attempting to upload the firmware. + * @throws UsbException if a communication error occurs. + * @throws InvalidFirmwareException if ZTEX descriptor 1 is not available. + * @throws DeviceLostException if a device went lost after renumeration. + * @return the upload time in ms. + */ +// returns upload time in ms + public long uploadFirmware ( InputStream ihxIn, String name, boolean force ) throws IncompatibleFirmwareException, FirmwareUploadException, UsbException, InvalidFirmwareException, DeviceLostException { +// load the ihx file + ZtexIhxFile1 ihxFile; + try { + ihxFile = new ZtexIhxFile1( ihxIn, name ); + } + catch ( IOException e ) { + throw new FirmwareUploadException( e.getLocalizedMessage() ); + } + catch ( IhxFileDamagedException e ) { + throw new FirmwareUploadException( e.getLocalizedMessage() ); + } + return uploadFirmware( ihxFile, force ); + } + // ******* resetEzUsb ********************************************************** /** * Resets the EZ-USB and manages the renumeration process.

/ztex/Ztex1v1.java
50,7 → 50,7
Returns:
Offs Description
0 1:enabled, 0:disabled
1-2 Sector size
1-2 Sector size <sector size> = MSB==0 : flash_sector_size and 0x7fff ? 1<<(flash_sector_size and 0x7fff)
3-6 Number of sectors
7 Error code
VR 0x41 : read from Flash
110,6 → 110,13
1 : select all FPGA's for configuration
value: FPGA to select - 1
 
1.0 : Temperature sensor
VR 0x58 : Return temperature data
Returns:
Offs Description
0 Protocol number
1..n Data
 
*/
package ztex;
 
501,6 → 508,37
* </table>
* </td>
* </tr>
* <tr>
* <td bgcolor="#ffffff" valign="top">1.0</td>
* <td bgcolor="#ffffff" valign="top" colspan=2>
* Temperature sensor support<p>
* <table bgcolor="#404040" cellspacing=1 cellpadding=6>
* <tr>
* <td bgcolor="#d0d0d0" valign="bottom"><b>Vendor request (VR)<br> or command (VC)</b></td>
* <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
* </tr>
* <tr>
* <td bgcolor="#ffffff" valign="top">VR 0x58</td>
* <td bgcolor="#ffffff" valign="top">Return temperature data:
* <table bgcolor="#404040" cellspacing=1 cellpadding=4>
* <tr>
* <td bgcolor="#d0d0d0" valign="bottom"><b>Bytes</b></td>
* <td bgcolor="#d0d0d0" valign="bottom"><b>Description</b></td>
* </tr>
* <tr>
* <td bgcolor="#ffffff" valign="top">0</td>
* <td bgcolor="#ffffff" valign="top">Protocol</td>
* </tr>
* <tr>
* <td bgcolor="#ffffff" valign="top">1..n</td>
* <td bgcolor="#ffffff" valign="top">Data</td>
* </tr>
* </table>
* </td>
* </tr>
* </table>
* </td>
* </tr>
* </table>
* @see ZtexDevice1
* @see Ztex1
524,6 → 562,8
public static final int CAPABILITY_MAC_EEPROM = 6;
/** * Capability index for multi FPGA support */
public static final int CAPABILITY_MULTI_FPGA = 7;
/** * Capability index for Temperature sensor support */
public static final int CAPABILITY_TEMP_SENSOR = 9;
 
/** * The names of the capabilities */
public static final String capabilityStrings[] = {
534,7 → 574,8
"XMEGA support",
"High speed FPGA configuration",
"MAC EEPROM read/write",
"Multi FPGA Support"
"Multi FPGA support",
"Temperature Sensor support" ,
};
/** * Enables extra FPGA configuration checks. Certain Bistream settings may cause false warnings. */
605,6 → 646,20
private int selectedFpga = -1;
private boolean parallelConfigSupport = false;
private long lastTempSensorReadTime = 0;
private byte[] tempSensorBuf = new byte[9];
/** * smallest temperature sensor update interval in ms */
public int tempSensorUpdateInterval = 100;
 
/**
* The configuration data structure
* 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 order to override this behavior set this variable to null.
* If no configuration data is present {@link #config} is null.
*/
public ConfigData config;
// ******* Ztex1v1 *************************************************************
/**
* Constructs an instance from a given device.
615,6 → 670,23
super ( pDev );
}
 
// ******* init ****************************************************************
/**
* Initializates the class.
* @throws UsbException if an communication error occurred.
*/
protected void init () throws UsbException {
super.init();
config = new ConfigData ();
try {
if ( ! config.connect( this ) )
config = null;
}
catch ( Exception e ) {
config = null;
}
}
 
// ******* valid ***************************************************************
/**
* Returns true if ZTEX interface 1 is available.
689,6 → 761,16
public void checkCapability ( int i ) throws InvalidFirmwareException, CapabilityException {
checkCapability(i/8, i%8);
}
// ******* InterfaceCapabilities ***********************************************
/**
* Returns interface capability bit.
* @return interface capability bit.
* @param i capability index (0..47)
*/
public boolean InterfaceCapabilities ( int i ) {
return dev().interfaceCapabilities(i/8, i%8);
}
 
// ******* checkCompatible *****************************************************
/**
818,7 → 900,7
// returns configuration time in ms
/**
* 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 inputStream for reading the Bitstream.
* @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.
* @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
828,7 → 910,7
* @throws UsbException if a communication error occurs.
* @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 ( InputStream inputStream, boolean force, int bs ) throws BitstreamReadException, UsbException, BitstreamUploadException, AlreadyConfiguredException, InvalidFirmwareException, CapabilityException {
final int transactionBytes = certainWorkarounds ? 256 : 2048;
long t0 = 0;
 
841,7 → 923,6
byte[][] buffer = new byte[16*1024*1024/transactionBytes][];
int size = 0;
try {
InputStream inputStream = JInputStream.getInputStream( fwFileName );
int j = transactionBytes;
for ( int i=0; i<buffer.length && j==transactionBytes; i++ ) {
buffer[i] = new byte[transactionBytes];
864,7 → 945,6
inputStream.close();
}
catch ( Exception e ) {
System.err.println( "Warning: Error closing file " + fwFileName + ": " + e.getLocalizedMessage() );
}
}
catch (IOException e) {
936,6 → 1016,27
}
 
 
/**
* 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 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.
* @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 AlreadyConfiguredException if the FPGA is already configured.
* @throws InvalidFirmwareException if interface 1 is not supported.
* @throws UsbException if a communication error occurs.
* @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 {
try {
return configureFpgaLS( JInputStream.getInputStream( fwFileName ), force, bs );
}
catch (IOException e) {
throw new BitstreamReadException(e.getLocalizedMessage());
}
}
 
// ******* eepromState *********************************************************
// returns true if EEPROM is ready
/**
1270,6 → 1371,8
}
flashEnabled = buf[0] & 255;
flashSectorSize = flashEnabled == 1 ? ((buf[2] & 255) << 8) | (buf[1] & 255) : 0;
if ( (flashSectorSize & 0x8000) != 0 )
flashSectorSize = 1 << (flashSectorSize & 0x7fff);
flashSectors = flashEnabled == 1 ? ((buf[6] & 255) << 24) | ((buf[5] & 255) << 16) | ((buf[4] & 255) << 8) | (buf[3] & 255) : 0;
return flashEnabled == 1;
}
1291,33 → 1394,8
return flashEC;
}
 
 
// ******* flashReadSector ****************************************************
// read exactly one sector
/**
* Reads one sector from the Flash.
* @param sector The sector number to be read.
* @param buf A buffer for the storage of the data.
* @throws InvalidFirmwareException if interface 1 is not supported.
* @throws UsbException if a communication error occurs.
* @throws CapabilityException if Flash memory access is not possible.
* @throws IndexOutOfBoundsException If the buffer is smaller than the Flash sector size.
*/
public void flashReadSector ( int sector, byte[] buf ) throws UsbException, InvalidFirmwareException, CapabilityException, IndexOutOfBoundsException {
if ( buf.length < flashSectorSize() )
throw new IndexOutOfBoundsException( "Buffer smaller than the Flash sector size: " + buf.length + " < " + flashSectorSize());
 
checkCapability(CAPABILITY_FLASH);
if ( ! flashEnabled() )
throw new CapabilityException(this, "No Flash memory installed or");
 
try {
vendorRequest2( 0x41, "Flash Read", sector, sector >> 16, buf, flashSectorSize );
}
catch ( UsbException e ) {
throw new UsbException( dev().dev(), "Flash Read: " + flashStrError() );
}
}
 
// read a integer number of sectors
/**
* Reads a integer number of sectors from the Flash.
1330,6 → 1408,8
* @throws IndexOutOfBoundsException If the buffer is to small.
*/
public void flashReadSector ( int sector, int num, byte[] buf ) throws UsbException, InvalidFirmwareException, CapabilityException, IndexOutOfBoundsException {
if ( num<1 ) return;
 
if ( buf.length < flashSectorSize() )
throw new IndexOutOfBoundsException( "Buffer is to small: " + buf.length + " < " + (num*flashSectorSize()) );
 
1338,7 → 1418,24
throw new CapabilityException(this, "No Flash memory installed or");
 
try {
vendorRequest2( 0x41, "Flash Read", sector, sector >> 16, buf, flashSectorSize*num );
if ( flashSectorSize()>2048 ) {
byte[] buf2 = new byte[2048];
int iz = (flashSectorSize-1) >> 11;
for (int sn=0; sn<num; sn++ ) {
for (int i=0; i<iz; i++) {
// System.out.println("r: "+i);
vendorRequest2( 0x41, "Flash Read", sector, i==0 ? 0 : 256, buf2, 2048 );
System.arraycopy(buf2,0, buf, sn*flashSectorSize + i*2048, 2048);
}
int len = flashSectorSize-iz*2048;
vendorRequest2( 0x41, "Flash Read", sector, 512, buf2, len);
System.arraycopy(buf2,0, buf, sn*flashSectorSize + iz*2048, len);
}
}
else {
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 );
}
}
catch ( UsbException e ) {
throw new UsbException( dev().dev(), "Flash Read: " + flashStrError() );
1345,33 → 1442,21
}
}
 
// ******* flashWriteSector ***************************************************
// write exactly one sector
// read one sector
/**
* Writes one sector to the Flash.
* @param sector The sector number to be written.
* @param buf The data.
* Reads one sector from the Flash.
* @param sector The sector number to be read.
* @param buf A buffer for the storage of the data.
* @throws InvalidFirmwareException if interface 1 is not supported.
* @throws UsbException if a communication error occurs.
* @throws CapabilityException if Flash memory access is not possible.
* @throws IndexOutOfBoundsException If the buffer is smaller than the Flash sector size.
*/
public void flashWriteSector ( int sector, byte[] buf ) throws UsbException, InvalidFirmwareException, CapabilityException, IndexOutOfBoundsException {
if ( buf.length < flashSectorSize() )
throw new IndexOutOfBoundsException( "Buffer smaller than the Flash sector size: " + buf.length + " < " + flashSectorSize());
public void flashReadSector ( int sector, byte[] buf ) throws UsbException, InvalidFirmwareException, CapabilityException, IndexOutOfBoundsException {
flashReadSector ( sector, 1, buf );
}
 
checkCapability(CAPABILITY_FLASH);
if ( ! flashEnabled() )
throw new CapabilityException(this, "No Flash memory installed or");
 
try {
vendorCommand2( 0x42, "Flash Write", sector, sector >> 16, buf, flashSectorSize );
}
catch ( UsbException e ) {
throw new UsbException( dev().dev(), "Flash Write: " + flashStrError() );
}
}
 
// ******* flashWriteSector ***************************************************
// write integer number of sectors
/**
1385,15 → 1470,42
* @throws IndexOutOfBoundsException If the buffer is to small.
*/
public void flashWriteSector ( int sector, int num, byte[] buf ) throws UsbException, InvalidFirmwareException, CapabilityException, IndexOutOfBoundsException {
if ( buf.length < flashSectorSize() )
throw new IndexOutOfBoundsException( "Buffer smaller than the Flash sector size: " + buf.length + " < " + (num*flashSectorSize()));
if ( num<1 ) return;
 
if ( buf.length < flashSectorSize()*num )
throw new IndexOutOfBoundsException( "Buffer to small: " + buf.length + " < " + (num*flashSectorSize()));
 
checkCapability(CAPABILITY_FLASH);
if ( ! flashEnabled() )
throw new CapabilityException(this, "No Flash memory installed or");
 
try {
vendorCommand2( 0x42, "Flash Write", sector, sector >> 16, buf, flashSectorSize*num );
if ( flashSectorSize()>2048 ) {
byte[] buf2 = new byte[2048];
int iz = (flashSectorSize-1) >> 11;
for (int sn=0; sn<num; sn++ ) {
int oto = controlMsgTimeout;
controlMsgTimeout = 12000; // 12s timeout for erase
System.arraycopy(buf,sn*flashSectorSize, buf2,0, 2048);
vendorCommand2( 0x42, "Flash Write", sector, 0, buf, 2048 );
controlMsgTimeout = oto;
for (int i=1; i<iz; i++) {
// System.out.println("w: "+i);
System.arraycopy(buf,sn*flashSectorSize+i*2048, buf2,0, 2048);
vendorCommand2( 0x42, "Flash Write", sector, 256, buf2, 2048 );
}
int len = flashSectorSize-iz*2048;
System.arraycopy(buf,sn*flashSectorSize+iz*2048, buf2,0, len);
vendorCommand2( 0x42, "Flash Write", sector, 512, buf2, len );
}
}
else {
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 );
}
}
catch ( UsbException e ) {
throw new UsbException( dev().dev(), "Flash Write: " + flashStrError() );
1400,6 → 1512,20
}
}
 
// write one sector
/**
* Writes one sector to the Flash.
* @param sector The sector number to be written.
* @param buf The data.
* @throws InvalidFirmwareException if interface 1 is not supported.
* @throws UsbException if a communication error occurs.
* @throws CapabilityException if Flash memory access is not possible.
* @throws IndexOutOfBoundsException If the buffer is smaller than the Flash sector size.
*/
public void flashWriteSector ( int sector, byte[] buf ) throws UsbException, InvalidFirmwareException, CapabilityException, IndexOutOfBoundsException {
flashWriteSector(sector,1,buf);
}
 
// ******* flashEnabled ********************************************************
// returns enabled / disabled state
/**
1489,9 → 1615,9
/*
Returns configuration time in ms.
The format of the boot sector (sector 0 of the Flash memory) is
0..7
8..9 Number of sectors, or 0 is disabled
10..11 Number of bytes in the last sector, i.e. th total size of Bitstream is ((bs[8] | (bs[9]<<8) - 1) * flash_sector_size + ((bs[10] | (bs[11]<<8))
0..7 ID
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))
*/
/**
* Uploads a Bitstream to the Flash.
1498,7 → 1624,10
* 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.
* <p>
* Information about the bitstream is stored in sector 0.
* If configuration data is present information about bitstream are stored there and Bitstream starts
* at sector 0.
* <p>
* On all other devices the information about the bitstream is stored in sector 0.
* This so called boot sector has the following format:
* <table bgcolor="#404040" cellspacing=1 cellpadding=4>
* <tr>
1527,7 → 1656,7
* where bs[i] denotes byte i of the boot sector.
* <p>
* The first sector of the Bitstream is sector 1.
* @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 inputStream for reading the Bitstream.
* @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 UsbException if a communication error occurs.
1534,8 → 1663,8
* @throws CapabilityException if Flash memory access is not possible.
* @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
*/
public long flashUploadBitstream ( String fwFileName, int bs ) throws BitstreamReadException, UsbException, InvalidFirmwareException, CapabilityException {
int secNum = 2048 / flashSectorSize;
public long flashUploadBitstream ( InputStream inputStream, int bs ) throws BitstreamReadException, UsbException, InvalidFirmwareException, CapabilityException {
int secNum = Math.max(1, 2048 / flashSectorSize());
final int bufferSize = secNum * flashSectorSize;
checkCapability(CAPABILITY_FPGA);
checkCapability(CAPABILITY_FLASH);
1545,9 → 1674,10
// read the Bitstream file
byte[][] buffer = new byte[32768][];
byte[] buf1 = new byte[flashSectorSize()];
 
int i,j,k;
try {
InputStream inputStream = JInputStream.getInputStream( fwFileName );
j = bufferSize;
for ( i=0; i<buffer.length && j==bufferSize; i++ ) {
buffer[i] = new byte[bufferSize];
1565,7 → 1695,6
inputStream.close();
}
catch ( Exception e ) {
System.err.println( "Warning: Error closing file " + fwFileName + ": " + e.getLocalizedMessage() );
}
}
catch (IOException e) {
1579,26 → 1708,48
swapBits( buffer, bufferSize*i );
 
// upload the Bitstream file
byte[] sector = new byte[flashSectorSize];
byte[] ID = new String("ZTEXBS").getBytes();
 
flashReadSector(0,sector); // read the boot sector (only the first 16 bytes are overwritten)
for (k=0; k<6; k++)
sector[k]=ID[k];
sector[6] = 1;
sector[7] = 1;
k = (i-1)*secNum + (j-1)/flashSectorSize + 1;
sector[8] = (byte) (k & 255);
sector[9] = (byte) ((k>>8) & 255);
k = ((j-1) % flashSectorSize) + 1;
sector[10] = (byte) (k & 255);
sector[11] = (byte) ((k>>8) & 255);
int startSector = 0;
long t0 = new Date().getTime();
flashWriteSector(0,sector); // write the boot sector
for (k=0; k<i-1; k++)
flashWriteSector( 1+k*secNum, secNum, buffer[k] ); // write the Bitstream sectors
flashWriteSector( 1+k*secNum, (j-1)/flashSectorSize + 1, buffer[k] );
 
if ( config!=null && config.getMaxBitstreamSize()>0 ) {
config.setBitstreamSize( ((i-1)*secNum + (j-1)/flashSectorSize + 1)*flashSectorSize );
}
else {
byte[] sector = new byte[flashSectorSize];
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)
boolean b = true;
for (k=0; k<6; k++) {
b = b && (sector[k] == ID[k]);
sector[k]=ID[k];
}
if ( ! b )
sector[6] = 1;
sector[7] = 1;
k = (i-1)*secNum + (j-1)/flashSectorSize + 1;
sector[8] = (byte) (k & 255);
sector[9] = (byte) ((k>>8) & 255);
k = ((j-1) % flashSectorSize) + 1;
sector[10] = (byte) (k & 255);
sector[11] = (byte) ((k>>8) & 255);
if ( ! b ) {
for ( k=12; k<flashSectorSize; k++ )
sector[k]=0;
}
System.out.print("\rWriting boot sector");
flashWriteSector(0,sector); // write the boot sector
startSector = 1;
}
for (k=0; k<i-1; k++) {
System.out.print("\rWriting sector " + (k+1)*secNum + " of " + i*secNum);
flashWriteSector( startSector+k*secNum, secNum, buffer[k] ); // write the Bitstream sectors
}
System.out.println("\rWriting sector " + i*secNum + " of " + i*secNum);
flashWriteSector( startSector+k*secNum, (j-1)/flashSectorSize + 1, buffer[k] );
 
return new Date().getTime() - t0;
}
 
1606,13 → 1757,34
* Uploads a Bitstream to the Flash.
* 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.
* See {@link #flashUploadBitstream(String,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 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 UsbException if a communication error occurs.
* @throws CapabilityException if Flash memory access is not possible.
* @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
*/
public long flashUploadBitstream ( String fwFileName, int bs ) throws BitstreamReadException, UsbException, InvalidFirmwareException, CapabilityException {
try {
return flashUploadBitstream ( JInputStream.getInputStream( fwFileName ), bs );
}
catch (IOException e) {
throw new BitstreamReadException(e.getLocalizedMessage());
}
}
 
/**
* Uploads a Bitstream to the Flash.
* 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.
* 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).
* @throws InvalidFirmwareException if interface 1 is not supported.
* @throws UsbException if a communication error occurs.
* @throws CapabilityException if Flash memory access is not possible.
* @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
*/
public long flashUploadBitstream ( String fwFileName ) throws BitstreamReadException, UsbException, InvalidFirmwareException, CapabilityException {
return flashUploadBitstream(fwFileName, -1);
}
1630,8 → 1802,14
public void flashResetBitstream ( ) throws UsbException, InvalidFirmwareException, CapabilityException {
checkCapability(CAPABILITY_FLASH);
if ( ! flashEnabled() )
throw new CapabilityException(this, "No Flash memory installed or");
byte[] sector = new byte[flashSectorSize];
throw new CapabilityException(this, "Flash memory not installed or");
 
if ( config!=null && config.getMaxBitstreamSize()>0 ) {
config.setBitstreamSize(0);
return;
}
 
byte[] sector = new byte[flashSectorSize()];
byte[] ID = new String("ZTEXBS").getBytes();
 
flashReadSector(0,sector); // read the boot sector
1646,6 → 1824,7
}
 
// ******* 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.
1660,7 → 1839,11
if ( ! flashEnabled() )
throw new CapabilityException(this, "No Flash memory installed or");
 
byte[] sector = new byte[flashSectorSize];
if ( config!=null && config.getMaxBitstreamSize()>0 ) {
return (Math.max(config.getMaxBitstreamSize(), config.getBitstreamSize())+flashSectorSize()-1) / flashSectorSize();
}
byte[] sector = new byte[flashSectorSize()];
byte[] ID = new String("ZTEXBS").getBytes();
 
flashReadSector(0,sector); // read the boot sector
1671,8 → 1854,49
return 0;
return (sector[8] & 255) + ((sector[9] & 255) << 8) + 1;
}
 
// ******* toHumanStr **********************************************************
private String toHumanStr ( long i ) {
if ( i==0 ) return "0";
StringBuilder sb = new StringBuilder();
int k = 0;
if ( i<0 ) {
sb.append("-");
i=-i;
k=1;
}
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) + "M"); i=i>>10;
if ( i != 0 ) sb.append(i + "G");;
return sb.toString();
}
 
// ******* flashInfo **********************************************************
/**
* Returns information about Flash memory.
* 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.
* Returns Information about Flash memory.
*/
public String flashInfo ( ) {
StringBuilder sb = new StringBuilder();
try {
if ( flashSize() > 0 ) {
sb.append( "Size: " + toHumanStr(flashSize()) + " Bytes" );
if ( config!=null && config.getMaxBitstreamSize()>0 ) {
sb.append( "; Bitstream (used / reserved): " + toHumanStr(config.getBitstreamSize()) + " / " + toHumanStr(config.getMaxBitstreamSize()) + " Bytes" );
}
else {
sb.append( "; Bitstream (used): " + toHumanStr(flashFirstFreeSector()*flashSectorSize()) + " Bytes" );
}
}
}
catch ( Exception e ) {
}
return sb.toString();
}
 
// ******* debugStackSize ******************************************************
/**
* Returns the size of message stack in messages.
2259,7 → 2483,7
// returns configuration time in ms
/**
* 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 inputStream for reading the Bitstream.
* @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.
* @throws BitstreamReadException if an error occurred while attempting to read the Bitstream.
2269,7 → 2493,7
* @throws UsbException if a communication error occurs.
* @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 ( InputStream inputStream, boolean force, int bs ) throws BitstreamReadException, UsbException, BitstreamUploadException, AlreadyConfiguredException, InvalidFirmwareException, CapabilityException {
final int transactionBytes = 16384;
long t0 = 0;
byte[] settings = new byte[2];
2288,7 → 2512,6
byte[][] buffer = new byte[16*1024*1024/transactionBytes][];
int size = 0;
try {
InputStream inputStream = JInputStream.getInputStream( fwFileName );
int j = transactionBytes;
for ( int i=0; i<buffer.length && j==transactionBytes; i++ ) {
buffer[i] = new byte[transactionBytes];
2308,7 → 2531,6
inputStream.close();
}
catch ( Exception e ) {
System.err.println( "Warning: Error closing file " + fwFileName + ": " + e.getLocalizedMessage() );
}
}
catch (IOException e) {
2401,10 → 2623,66
return t0;
}
 
// returns configuration time in ms
/**
* 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 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.
* @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 AlreadyConfiguredException if the FPGA is already configured.
* @throws InvalidFirmwareException if interface 1 is not supported.
* @throws UsbException if a communication error occurs.
* @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 {
try {
return configureFpgaHS( JInputStream.getInputStream( fwFileName ), force, bs );
}
catch (IOException e) {
throw new BitstreamReadException(e.getLocalizedMessage());
}
}
 
// ******* configureFpga *****************************************************
// returns configuration time in ms
/**
* Upload a Bitstream to the FPGA using high speed mode (if available) or low speed mode.
* @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 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 BitstreamUploadException if an error occurred while attempting to upload the Bitstream.
* @throws AlreadyConfiguredException if the FPGA is already configured.
* @throws InvalidFirmwareException if interface 1 is not supported.
* @throws UsbException if a communication error occurs.
* @throws CapabilityException if FPGA configuration is not supported by the firmware.
* @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 {
try {
inputStream.mark(64*1024*1024);
return configureFpgaHS( inputStream, force, bs );
}
catch ( CapabilityException e ) {
return configureFpgaLS( inputStream, force, bs );
}
catch ( UsbException e ) {
System.err.println("Warning: High speed FPGA configuration failed, trying low speed mode:" + e.getLocalizedMessage() +": Trying low speed mode");
inputStream.reset();
return configureFpgaLS( inputStream, force, bs );
}
catch ( BitstreamUploadException e ) {
System.err.println("Warning: High speed FPGA configuration failed, trying low speed mode:" + e.getLocalizedMessage() +": Trying low speed mode");
inputStream.reset();
return configureFpgaLS( inputStream, force, bs );
}
}
 
// returns configuration time in ms
/**
* 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 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.
2455,26 → 2733,18
* @param length The amount of bytes to be sent.
* @throws InvalidFirmwareException if interface 1 is not supported.
* @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 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 {
checkCapability(CAPABILITY_MAC_EEPROM);
byte[] buf2 = new byte[8];
int ptr = 0;
while (length>0 ) {
int i = Math.min( 8 - (addr & 7), length );
for ( int j=0; j<i; j++ )
buf2[j] = buf[ptr+j];
vendorCommand2( 0x3C, "MAC EEPROM Write", addr, 0, buf2, i );
try {
Thread.sleep( 10 );
}
catch ( InterruptedException e) {
}
addr+=i;
length-=i;
ptr += i;
}
if ( ( config != null ) && ( addr<80 ))
throw new CapabilityException(this, "Overwriting configuration data in MAC EEPROM");
vendorCommand2( 0x3C, "MAC EEPROM Write", addr, 0, buf, length );
try {
Thread.sleep( 10 );
}
catch ( InterruptedException e) {
}
}
 
// ******* macEepromRead *******************************************************
2579,5 → 2849,63
selectedFpga = num;
}
 
// ******* TempSensorRead ******************************************************
/**
* Read temperature sensor data.
* @param idx Temperature sensor index
* @return Temperature in deg. C
* @throws InvalidFirmwareException If interface 1 or temperature sensor protocol is not supported.
* @throws UsbException If a communication error occurs.
* @throws CapabilityException If NVRAM access to ATxmega is not supported by the firmware.
* @throws IndexOutOfBoundsException If idx is not in range.
*/
public double tempSensorRead ( int idx ) throws UsbException, InvalidFirmwareException, CapabilityException, IndexOutOfBoundsException {
int[] xIdx = { 3, 4, 1, 2 };
checkCapability(CAPABILITY_TEMP_SENSOR);
int len = 0;
if ( tempSensorUpdateInterval < 40 )
tempSensorUpdateInterval = 40;
if ( new Date().getTime() > lastTempSensorReadTime+tempSensorUpdateInterval ) {
len = vendorRequest( 0x58, "Temperature Sensor Read", 0, 0, tempSensorBuf, tempSensorBuf.length );
lastTempSensorReadTime = new Date().getTime();
 
if ( len != 5 || tempSensorBuf[0] != 1 )
throw new InvalidFirmwareException("tempSensorRead: Invalid temperature sensor protocol");
}
if ( idx<0 || idx>3 )
throw new IndexOutOfBoundsException( "tempSensorRead: Invalid temperature sensor index" );
return ((tempSensorBuf[xIdx[idx]] & 255)-77.2727)/1.5454;
}
 
// ******* printSpiState *******************************************************
// returns true if Flash is available
/**
* Prints out some debug information about SPI Flash.<br>
* <b>Only use this method if such kind of Flash is installed.</b>
* @throws InvalidFirmwareException if interface 1 is not supported.
* @throws UsbException if a communication error occurs.
* @throws CapabilityException if Flash memory access is not supported by the firmware.
*/
public boolean printSpiState ( ) throws UsbException, InvalidFirmwareException, CapabilityException {
byte[] buf = new byte[10];
checkCapability(CAPABILITY_FLASH);
vendorRequest2(0x43, "SPI State", 0, 0, buf, 10);
System.out.println("ec=" + buf[0] +
" vendor=" + Integer.toHexString(buf[1] & 255).toUpperCase() + "h" +
" device=" + Integer.toHexString(buf[2] & 255).toUpperCase() + "h" +
" memType=" + Integer.toHexString(buf[3] & 255).toUpperCase() + "h" +
" eraseCmd=" + Integer.toHexString(buf[4] & 255).toUpperCase() + "h" +
" lastCmd=" + Integer.toHexString(buf[5] & 255).toUpperCase() + "h" +
" buf=" + (buf[6] & 255)+" "+(buf[7] & 255)+" "+(buf[8] & 255)+" "+(buf[9] & 255)
);
return flashEnabled == 1;
}
 
}
 
/ztex/ZtexIhxFile1.java
47,14 → 47,15
/**
* Constructs an instance from a given file name and descriptor position.<br>
* This method can also read system resources, e.g. files from the current jar archive.
* @param fileName The file name.
* @param in Input stream from which the ihx file is read.
* @param name Name of the input.
* @param pZtexDescriptorOffs The position of the descriptor in bytes. The default position is 0x6c.
* @throws IOException If an read error occurred.
* @throws IhxFileDamagedException If the ihx file is damaged.
* @throws IncompatibleFirmwareException If the firmware image contains no valid ZTEX descriptor 1 at the specified position.
*/
public ZtexIhxFile1( String fileName, int pZtexDescriptorOffs ) throws IOException, IhxFileDamagedException, IncompatibleFirmwareException {
super( fileName );
public ZtexIhxFile1( InputStream in, String name, int pZtexDescriptorOffs ) throws IOException, IhxFileDamagedException, IncompatibleFirmwareException {
super( in, name );
 
ztexDescriptorOffs = pZtexDescriptorOffs;
103,6 → 104,34
}
 
/**
* Constructs an instance from a given file name and descriptor position.<br>
* The ZTEX descriptor 1 is expected to be at the position 0x6c of the firmware image.<br>
* This method can also read system resources, e.g. files from the current jar archive.
* @param in Input stream from which the ihx file is read.
* @param name Name of the input.
* @throws IOException If an read error occurred.
* @throws IhxFileDamagedException If the ihx file is damaged.
* @throws IncompatibleFirmwareException If the firmware image contains no valid ZTEX descriptor 1 at the specified position.
*/
public ZtexIhxFile1( InputStream in, String name ) throws IOException, IhxFileDamagedException, IncompatibleFirmwareException {
this( in, name, defaultZtexDescriptorOffs );
}
 
/**
* Constructs an instance from a given file name and descriptor position.<br>
* This method can also read system resources, e.g. files from the current jar archive.
* @param fileName The file name.
* @param pZtexDescriptorOffs The position of the descriptor in bytes. The default position is 0x6c.
* @throws IOException If an read error occurred.
* @throws IhxFileDamagedException If the ihx file is damaged.
* @throws IncompatibleFirmwareException If the firmware image contains no valid ZTEX descriptor 1 at the specified position.
*/
public ZtexIhxFile1( String fileName , int pZtexDescriptorOffs ) throws IOException, IhxFileDamagedException, IncompatibleFirmwareException {
this( JInputStream.getInputStream(fileName), fileName, pZtexDescriptorOffs );
}
 
/**
* Constructs an instance from a given file name.
* The ZTEX descriptor 1 is expected to be at the position 0x6c of the firmware image.<br>
* This method can also read system resources, e.g. files from the current jar archive.
112,7 → 141,7
* @throws IncompatibleFirmwareException If the firmware image contains no valid ZTEX descriptor 1 at the specified position.
*/
public ZtexIhxFile1( String fileName ) throws IOException, IhxFileDamagedException, IncompatibleFirmwareException {
this( fileName, defaultZtexDescriptorOffs );
this( JInputStream.getInputStream(fileName), fileName, defaultZtexDescriptorOffs );
}
 
// ******* productId ***********************************************************
/ztex/IhxFile.java
58,12 → 58,12
/**
* Constructs an instance from a given file name.
* This method can also read system resources, e.g. files from the current jar archive.
* @param fileName The file name.
* @param in Input stream from which the ihx file is read.
* @param name Name of the input.
* @throws IOException If an read error occurred.
* @throws IhxFileDamagedException If the ihx file is damaged.
*/
public IhxFile ( String fileName ) throws IOException, IhxFileDamagedException {
InputStream in = JInputStream.getInputStream( fileName );
public IhxFile ( InputStream in, String name ) throws IOException, IhxFileDamagedException {
int b, len, cs, addr;
byte buf[] = new byte[255];
boolean eof = false;
120,7 → 120,7
}
}
catch ( IhxParseException e ) {
throw new IhxFileDamagedException ( fileName, line, e.getLocalizedMessage() );
throw new IhxFileDamagedException ( name, line, e.getLocalizedMessage() );
}
 
try {
127,10 → 127,21
in.close();
}
catch ( Exception e ) {
System.err.println( "Warning: Error closing file " + fileName + ": " + e.getLocalizedMessage() );
System.err.println( "Warning: Error closing file " + name + ": " + e.getLocalizedMessage() );
}
}
 
/**
* Constructs an instance from a given file name.
* This method can also read system resources, e.g. files from the current jar archive.
* @param fileName The file name.
* @throws IOException If an read error occurred.
* @throws IhxFileDamagedException If the ihx file is damaged.
*/
public IhxFile ( String fileName ) throws IOException, IhxFileDamagedException {
this( JInputStream.getInputStream( fileName ), fileName );
}
 
// ******* dataInfo ************************************************************
/**
* Print out some information about the memory usage.
/ztex/ZtexDevice1.java
72,10 → 72,16
* <tr><td>0.0.0.0</td> <td>default Product ID (no product specified)</td></tr>
* <tr><td>1.*.*.*</td> <td>may be used for experimental purposes</td></tr>
* <tr><td>10.*.*.*</td> <td>used for ZTEX products</td></tr>
* <tr><td>10.11.*.*</td> <td><a href="http://www.ztex.de/usb-fpga-1/usb-fpga-1.2.e.html">ZTEX USB-FPGA-Module 1.2</a></td></tr>
* <tr><td>10.20.*.*</td> <td><a href="http://www.ztex.de/usb-1/usb-1.0.e.html">ZTEX USB-Module 1.0</a></td></tr>
* <tr><td>10.11.*.*</td> <td>ZTEX USB-FPGA-Module 1.2</td></tr>
* <tr><td>10.12.*.*</td> <td>ZTEX USB-FPGA-Module 1.11</td></tr>
* <tr><td>10.13.*.*</td> <td>ZTEX USB-FPGA-Module 1.15 (not 1.15y)</td></tr>
* <tr><td>10.14.*.*</td> <td>ZTEX USB-FPGA-Module 1.15x</td></tr>
* <tr><td>10.15.*.*</td> <td>ZTEX USB-FPGA-Module 1.15y</td></tr>
* <tr><td>10.20.*.*</td> <td>ZTEX USB-Module 1.0</td></tr>
* <tr><td>10.30.*.*</td> <td>ZTEX USB-XMEGA-Module 1.0</td></tr>
* <tr><td>10.0.1.1</td> <td>ZTEX BTCMiner firmware</td></tr>
* </table></td></tr></table>
* Please contact me (<a href="http://www.ztex.de/contact.e.html">http://www.ztex.de/contact.e.html</a>) if you want to register or reserve a Product ID (range).
* Please contact us (<a href="http://www.ztex.de/contact.e.html">http://www.ztex.de/contact.e.html</a>) if you want to register or reserve a Product ID (range).
* </td>
* </tr>
* <tr>
/ztex/Makefile
0,0 → 1,60
#########################
# configuration section #
#########################
 
ZTEXPREFIX=../..
 
#PREFIX base directory for installing
#default: /usr/local for OS=UNIX and c:\usr else
#e.g. PREFIX=/usr
 
#JAVADIR where to install jar's
#default: $(PREFIX)/share/java
 
#BINDIR where to install bin's
#default: $(PREFIX)/bin
 
#MANDIR where to install mans's
#default: $(PREFIX)/share/man/man1
 
################################
# DO NOT CHANAGE THE FOLLOWING #
################################
 
.PHONY: all clean distclean install
 
 
JAVAC=javac
INSTALL=install
INSTALLDIR=$(INSTALL) -d
INSTALLEXE=$(INSTALL) -m 0755
INSTALLFILE=$(INSTALL) -m 0644
 
CLASSPATH:=.:$(ZTEXPREFIX)/libusbJava:$(ZTEXPREFIX)/java:/usr/local/share/java:/usr/share/java:$(CLASSPATH)
JAVAFILES:=$(wildcard *.java)
 
ifndef PREFIX
PREFIX=/usr/local
endif
 
ifndef JAVADIR
JAVADIR=$(PREFIX)/share/java
endif
 
ifndef BINDIR
BINDIR=$(DESTDIR)$(PREFIX)/bin
endif
 
all : $(JAVAFILES)
$(JAVAC) -cp "$(CLASSPATH)" $(JAVAFILES)
 
install: $(CLASSTARGETS)
$(INSTALLDIR) $(JAVADIR)/ztex
$(INSTALLFILE) *.class $(JAVADIR)/ztex
 
clean:
rm -f *~ *.bak *.old
 
distclean: clean
rm -f $(JARTARGET)
rm -f *.class
/Makefile
1,84 → 1,25
#########################
# configuration section #
#########################
DIRS=ztex FWLoader DeviceServer
 
ZTEXPREFIX=..
.PHONY: default all clean distclean avr avrclean avrdistclean
 
#PREFIX base directory for installing
#default: /usr/local for OS=UNIX and c:\usr else
#e.g. PREFIX=/usr
default:
@echo "This makefile is intended to clean up the project or to build all examples in this subdirectory"
@echo "Usage: make all | clean | distclean"
 
#JAVADIR where to install jar's
#default: $(PREFIX)/share/java
all:
set -e; for i in $(DIRS); do make -C $$i all; done
 
#BINDIR where to install bin's
#default: $(PREFIX)/bin
clean:
set -e; for i in $(DIRS); do make -C $$i clean; done
 
#MANDIR where to install mans's
#default: $(PREFIX)/share/man/man1
distclean:
set -e; for i in $(DIRS); do make -C $$i distclean; done
 
################################
# DO NOT CHANAGE THE FOLLOWING #
################################
avr:
set -e; for i in $(DIRS); do make -C $$i avr; done
 
.PHONY: all jar clean distclean install
avrclean:
set -e; for i in $(DIRS); do make -C $$i avrclean; done
 
JARTARGET=FWLoader.jar
CLASSTARGETS=FWLoader.class
 
JAVAC=javac
INSTALL=install
INSTALLDIR=$(INSTALL) -d
INSTALLEXE=$(INSTALL) -m 0755
INSTALLFILE=$(INSTALL) -m 0644
 
CLASSPATH:=.:$(ZTEXPREFIX)/libusbJava:$(ZTEXPREFIX)/java:/usr/local/share/java:/usr/share/java:$(CLASSPATH)
CLASSEXTRADEPS:=$(wildcard ztex/*.java)
 
ifndef PREFIX
PREFIX=/usr/local
endif
 
ifndef JAVADIR
JAVADIR=$(PREFIX)/share/java
endif
 
ifndef BINDIR
BINDIR=$(DESTDIR)$(PREFIX)/bin
endif
 
ifndef MANDIR
MANDIR=$(DESTDIR)$(PREFIX)/share/man/man1
endif
 
all : jar
 
jar : $(JARTARGET)
 
%.class: %.java $(CLASSEXTRADEPS)
$(JAVAC) -cp "$(CLASSPATH)" $< $(CLASSEXTRADEPS)
 
$(JARTARGET) : $(CLASSTARGETS) $(EXTRAJARFILES)
jar cf $(JARTARGET) *.class $(EXTRAJARFILES) -C $(ZTEXPREFIX)/libusbJava . $(shell cd $(ZTEXPREFIX)/java; ls ztex/*.class | while read a; do echo "-C $(ZTEXPREFIX)/java $$a"; done)
 
install: $(CLASSTARGETS)
# $(INSTALLDIR) $(JAVADIR)
# jar cf $(JAVADIR)/ztex.jar *.class ztex/*.class
$(INSTALLDIR) $(JAVADIR)/ztex
$(INSTALLFILE) *.class $(JAVADIR)
$(INSTALLFILE) ztex/*.class $(JAVADIR)/ztex
$(INSTALLDIR) $(BINDIR)
$(INSTALLEXE) FWLoader $(BINDIR)
$(INSTALLDIR) $(MANDIR)
$(INSTALLFILE) FWLoader.1 $(MANDIR)
 
clean:
rm -f *~ *.bak *.old
rm -f ztex/*~ ztex/*.bak ztex/*.old
rm -f *.class
rm -f *.rel *.rst *.lnk *.lst *.map *.asm *.sym *.mem *.tmp.c
 
distclean: clean
rm -f $(JARTARGET)
rm -f ztex/*.class
rm -f *.ihx
avrdistclean:
set -e; for i in $(DIRS); do make -C $$i avrdistclean; done

powered by: WebSVN 2.1.0

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