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

Subversion Repositories usb_fpga_1_2

[/] [usb_fpga_1_2/] [trunk/] [java/] [ztex/] [Ztex1v1.java] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ZTEX
/*!
2
   Java Driver API for the ZTEX Firmware Kit
3
   Copyright (C) 2008-2009 ZTEX e.K.
4
   http://www.ztex.de
5
 
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License version 3 as
8
   published by the Free Software Foundation.
9
 
10
   This program is distributed in the hope that it will be useful, but
11
   WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
   General Public License for more details.
14
 
15
   You should have received a copy of the GNU General Public License
16
   along with this program; if not, see http://www.gnu.org/licenses/.
17
!*/
18
 
19
/*
20
    Functions for USB devices with ZTEX descriptor 1, Interface 1
21
    Interface capabilities and vendor requests (VR) / commands (VC):
22
    0.0  : EEPROM support
23
    0.1  : FPGA Configuration
24
        VR 0x31 : FPGA state
25
            Returns:
26
            Offs        Description
27
 
28
            1           checksum
29
            2-5         transfered bytes
30
            6           INIT_B state
31
 
32
*/
33
package ztex;
34
 
35
import java.io.*;
36
import java.util.*;
37
 
38
import ch.ntb.usb.*;
39
 
40
 
41
public class Ztex1v1 extends Ztex1 {
42
    public static final String capabilityStrings[] = {
43
        "EEPROM read/write" ,
44
        "FPGA configuration"
45
    };
46
 
47
    public boolean certainWorkarounds = false;  // setting to true will enable certain workarounds which may be required for vmware + windows
48
 
49
    private boolean fpgaConfigured = false;
50
    private int fpgaChecksum = 0;
51
    private int fpgaBytes = 0;
52
    private int fpgaInitB = 0;
53
 
54
    public int eepromBytes = 0;
55
    public int eepromChecksum = 0;
56
    public boolean eepromReady = true;
57
 
58
// ******* Ztex1v1 *************************************************************
59
    public Ztex1v1 ( ZtexDevice1 pDev ) throws UsbException, ZtexDescriptorException {
60
        super ( pDev );
61
        certainWorkarounds = false;
62
    }
63
 
64
// ******* valid ***************************************************************
65
    public boolean valid ( ) {
66
        return dev.valid() && dev.interfaceVersion()==1;
67
    }
68
 
69
    public boolean valid ( int i, int j) {
70
        return dev.valid() && dev.interfaceVersion()==1 && dev.interfaceCapabilities(i,j);
71
    }
72
 
73
// ******* compatible **********************************************************
74
    public boolean compatible ( int productId0, int productId1, int productId2, int productId3 ) {
75
        return dev.valid() && dev.compatible ( productId0, productId1, productId2, productId3 ) && dev.interfaceVersion()==1;
76
    }
77
 
78
// ******* checkValid **********************************************************
79
    public void checkValid () throws InvalidFirmwareException {
80
        super.checkValid();
81
        if ( dev.interfaceVersion() != 1 )
82
            throw new InvalidFirmwareException(this, "Wrong interface: " + dev.interfaceVersion() + ", expected: 1" );
83
    }
84
 
85
// ******* checkCapability *****************************************************
86
    public void checkCapability ( int i, int j ) throws InvalidFirmwareException, CapabilityException {
87
        checkValid();
88
        if ( ! dev.interfaceCapabilities(i,j) ) {
89
            int k = i*8 + j;
90
            if ( k>=0 && k<capabilityStrings.length )
91
            throw new CapabilityException( this, ( k>=0 && k<=capabilityStrings.length ) ? capabilityStrings[k] : ("Capabilty " + i + "," + j) );
92
        }
93
    }
94
 
95
// ******* checkCompatible *****************************************************
96
    public void checkCompatible ( int productId0, int productId1, int productId2, int productId3 ) throws InvalidFirmwareException {
97
        checkValid();
98
        if ( ! dev.compatible ( productId0, productId1, productId2, productId3 ) )
99
            throw new InvalidFirmwareException(this, "Incompatible Product ID");
100
    }
101
 
102
// ******* getFpgaState ********************************************************
103
    private void getFpgaState () throws UsbException, InvalidFirmwareException, CapabilityException {
104
        byte[] buffer = new byte[7];
105
        checkCapability(0,1);
106
        vendorRequest2(0x30, "getFpgaState", buffer, 7);
107
        fpgaConfigured = buffer[0] == 0;
108
        fpgaChecksum = buffer[1] & 0xff;
109
        fpgaBytes = ((buffer[5] & 0xff)<<24) | ((buffer[4] & 0xff)<<16) | ((buffer[3] & 0xff)<<8) | (buffer[2] & 0xff);
110
        fpgaInitB = buffer[6] & 0xff;
111
    }
112
 
113
// ******* getFpgaConfiguration ************************************************
114
    public boolean getFpgaConfiguration () throws UsbException, InvalidFirmwareException, CapabilityException {
115
        getFpgaState ();
116
        return fpgaConfigured;
117
    }
118
 
119
// ******* getFpgaConfigurationStr *********************************************
120
    public String getFpgaConfigurationStr () throws UsbException, InvalidFirmwareException, CapabilityException {
121
        getFpgaState ();
122
        return fpgaConfigured ? "FPGA configured" : "FPGA unconfigured";
123
    }
124
 
125
// ******* resetFGPA ***********************************************************
126
    public void resetFpga () throws UsbException, InvalidFirmwareException, CapabilityException {
127
        checkCapability(0,1);
128
        vendorCommand(0x31, "resetFpga" );
129
    }
130
 
131
// ******* configureFpga *******************************************************
132
//  returns configuration time in ms
133
    public long configureFpga ( String fwFileName, boolean force ) throws BitstreamReadException, UsbException, BitstreamUploadException, AlreadyConfiguredException, InvalidFirmwareException, CapabilityException {
134
        final int transactionBytes = certainWorkarounds ? 256 : 2048;
135
        long t0 = 0;
136
 
137
        checkCapability(0,1);
138
 
139
        if ( !force && getFpgaConfiguration() )
140
            throw new AlreadyConfiguredException();
141
 
142
// read the bitstream file      
143
        byte[][] buffer = new byte[4*1024*1024/transactionBytes][];
144
        int size = 0;
145
        try {
146
            InputStream inputStream = JInputStream.getInputStream( fwFileName );
147
            int j = transactionBytes;
148
            for ( int i=0; i<buffer.length && j==transactionBytes; i++ ) {
149
                buffer[i] = new byte[transactionBytes];
150
                j = inputStream.read( buffer[i] );
151
                if ( j < 0 )
152
                    j = 0;
153
                if ( j < transactionBytes && j % 64 == 0 )       // ensures size % 64 != 0
154
                    j+=1;
155
                size += j;
156
            }
157
 
158
            try {
159
                inputStream.close();
160
            }
161
            catch ( Exception e ) {
162
                System.err.println( "Warning: Error closing file " + fwFileName + ": " + e.getLocalizedMessage() );
163
            }
164
        }
165
        catch (IOException e) {
166
            throw new BitstreamReadException(e.getLocalizedMessage());
167
        }
168
        if ( size < 64 || size % 64 == 0 )
169
            throw new BitstreamReadException("Invalid file size: " + size );
170
 
171
// upload the bitstream file    
172
        for ( int tries=10; tries>0; tries-- ) {
173
 
174
            resetFpga();
175
 
176
            try {
177
                t0 = -new Date().getTime();
178
                int cs = 0;
179
                int bs = 0;
180
 
181
                for ( int i=0; i<buffer.length && i*transactionBytes < size; i++ ) {
182
                    int j = size-i*transactionBytes;
183
                    if (j>transactionBytes)
184
                        j = transactionBytes;
185
                    vendorCommand2(0x32, "sendFpgaData", 0,0, buffer[i], j);
186
 
187
                    bs+=j;
188
                    for ( int k=0; k<buffer[i].length; k++ )
189
                        cs = ( cs + (buffer[i][k] & 0xff) ) & 0xff;
190
                }
191
 
192
                getFpgaState();
193
//              System.err.println("fpgaConfigred=" + fpgaConfigured + "   fpgaBytes="+fpgaBytes + " ("+bs+")   fpgaChecksum="+fpgaChecksum + " ("+cs+")   fpgaInitB="+fpgaInitB );
194
                if ( ! fpgaConfigured ) {
195
                    throw new BitstreamUploadException( "FPGA configuration failed: DONE pin does not go high (size=" + fpgaBytes + " ,  " + (bs - fpgaBytes) + " bytes went lost;  checksum="
196
                        + fpgaChecksum + " , should be " + cs + ";  INIT_B_HIST=" + fpgaInitB +", should be 222)" );
197
                }
198
                if ( fpgaInitB != 222 )
199
                    System.err.println ( "Warning: FPGA configuration may have failed: DONE pin has gone high but INIT_B states are wrong: " + fpgaInitB +", should be 222");
200
 
201
                tries = 0;
202
                t0 += new Date().getTime();
203
 
204
            }
205
            catch ( BitstreamUploadException e ) {
206
                if ( tries>1 )
207
                    System.err.println("Warning: " + e.getLocalizedMessage() +": Retrying it ...");
208
                else
209
                    throw e;
210
            }
211
        }
212
 
213
        try {
214
            Thread.sleep( 200 );
215
        }
216
        catch ( InterruptedException e) {
217
        }
218
 
219
        return t0;
220
    }
221
 
222
// ******* eepromState *********************************************************
223
// returns true if EEPROM is ready
224
    public boolean eepromState ( ) throws UsbException, InvalidFirmwareException, CapabilityException {
225
        byte[] buf = new byte[4];
226
        checkCapability(0,0);
227
        vendorRequest2(0x3A, "EEPROM State", 0, 0, buf, 4);
228
        eepromBytes = (buf[0] & 255) | (buf[1] & 255)<<8;
229
        eepromChecksum = buf[2] & 255;
230
        eepromReady = buf[3] == 0;
231
        return eepromReady;
232
    }
233
 
234
// ******* eepromWrite *********************************************************
235
    public void eepromWrite ( int addr, byte[] buf, int length ) throws UsbException, InvalidFirmwareException, CapabilityException {
236
        checkCapability(0,0);
237
        vendorCommand2( 0x39, "EEPROM Write", addr, 0, buf, length );
238
    }
239
 
240
// ******* eepromRead **********************************************************
241
    public void eepromRead ( int addr, byte[] buf, int length ) throws UsbException, InvalidFirmwareException, CapabilityException {
242
        checkCapability(0,0);
243
        for ( int tries=4; tries>0; tries-- ) {
244
            try {
245
                vendorRequest2( 0x38, "EEPROM Read", addr, 0, buf, length );             // sometimes a little bit slow
246
                tries = 0;
247
            }
248
            catch ( UsbException e ) {
249
                if ( tries<=1 ) throw e;
250
            }
251
        }
252
    }
253
 
254
// ******* eepromUpload ********************************************************
255
//  returns upload time in ms
256
    public long eepromUpload ( String ihxFileName, boolean force ) throws IncompatibleFirmwareException, FirmwareUploadException, InvalidFirmwareException, CapabilityException {
257
        final int pagesMax = 256;
258
        final int pageSize = 256;
259
        int pages = 0;
260
        byte[][] buffer = new byte[pagesMax][];
261
 
262
        checkCapability(0,0);
263
 
264
// load the ihx file
265
        ZtexIhxFile1 ihxFile;
266
        try {
267
            ihxFile = new ZtexIhxFile1( ihxFileName );
268
        }
269
        catch ( IOException e ) {
270
            throw new FirmwareUploadException( e.getLocalizedMessage() );
271
        }
272
        catch ( IhxFileDamagedException e ) {
273
            throw new FirmwareUploadException( e.getLocalizedMessage() );
274
        }
275
//      ihxFile.dataInfo(System.out);
276
//      System.out.println(ihxFile);
277
 
278
// check for compatibility
279
        if ( ! force && dev.valid() ) {
280
            if ( ihxFile.interfaceVersion() != 1 )
281
                throw new IncompatibleFirmwareException("Wrong interface version: Expected 1, got " + ihxFile.interfaceVersion() );
282
 
283
            if ( ! dev.compatible ( ihxFile.productId(0), ihxFile.productId(1), ihxFile.productId(2), ihxFile.productId(3) ) )
284
                throw new IncompatibleFirmwareException("Incompatible productId's: Current firmware: " + ZtexDevice1.byteArrayString(dev.productId())
285
                    + "  Ihx File: " + ZtexDevice1.byteArrayString(ihxFile.productId()) );
286
        }
287
 
288
        Usb_Device_Descriptor dd = dev.dev().getDescriptor();
289
        int vid = dd.getIdVendor() & 65535;
290
        int pid = dd.getIdProduct() & 65535;
291
 
292
        buffer[0] = new byte[pageSize];
293
        buffer[0][0] = (byte) 0xc2;
294
        buffer[0][1] = (byte) (vid & 255);
295
        buffer[0][2] = (byte) ((vid >> 8) & 255);
296
        buffer[0][3] = (byte) (pid & 255);
297
        buffer[0][4] = (byte) ((pid >> 8) & 255);
298
        buffer[0][5] = 0;
299
        buffer[0][6] = 0;
300
        buffer[0][7] = 0;
301
 
302
        int ptr = 8, i = 0;
303
 
304
        while ( i < ihxFile.ihxData.length ) {
305
            if ( ihxFile.ihxData[i]>=0 && ihxFile.ihxData[i]<256 ) {                     // new data block
306
                int j = 1;
307
                while ( i+j<ihxFile.ihxData.length && ihxFile.ihxData[i+j]>=0 && ihxFile.ihxData[i+j]<255 )
308
                    j++;
309
 
310
                for (int k=ptr/pageSize + 1; k < (ptr+j+4)/pageSize + 1; k++ )  // also considers 5 bytes for the last data block
311
                    buffer[k] = new byte[pageSize];
312
 
313
                buffer[(ptr+0)/pageSize][(ptr+0) % pageSize] = (byte) ((j >> 8) & 255);
314
                buffer[(ptr+1)/pageSize][(ptr+1) % pageSize] = (byte) (j & 255);                // length
315
                buffer[(ptr+2)/pageSize][(ptr+2) % pageSize] = (byte) ((i >> 8) & 255);
316
                buffer[(ptr+3)/pageSize][(ptr+3) % pageSize] = (byte) (i & 255);                // address
317
                ptr+=4;
318
                for ( int k=0; k<j; k++ )                                        // data
319
                    buffer[(ptr+k)/pageSize][(ptr+k) % pageSize] = (byte) ihxFile.ihxData[i+k];
320
                ptr+=j;
321
                i+=j;
322
            }
323
            else {
324
                i+=1;
325
            }
326
        }
327
 
328
        buffer[(ptr+0)/pageSize][(ptr+0) % pageSize] = (byte) 0x80;               // last data block
329
        buffer[(ptr+1)/pageSize][(ptr+1) % pageSize] = (byte) 0x01;
330
        buffer[(ptr+2)/pageSize][(ptr+2) % pageSize] = (byte) 0xe6;
331
        buffer[(ptr+3)/pageSize][(ptr+3) % pageSize] = (byte) 0x00;
332
        buffer[(ptr+3)/pageSize][(ptr+4) % pageSize] = (byte) 0x00;
333
        ptr+=5;
334
 
335
 
336
        long t0 = new Date().getTime();
337
        byte[] rbuf = new byte[pageSize];
338
 
339
        for ( i=(ptr-1)/pageSize; i>=0; i-- ) {
340
 
341
            int k = (i+1)*pageSize < ptr ? pageSize : ptr-i*pageSize;
342
            int cs = 0;
343
            for (int j=0; j<k; j++ ) {
344
                cs = ( cs + (buffer[i][j] & 255) ) & 255;
345
            }
346
 
347
            for ( int tries=4; tries>0; tries-- ) {
348
                try {
349
                    eepromWrite(i*pageSize, buffer[i], k);
350
                    eepromState();
351
                    if ( eepromBytes!=k )
352
                        throw new FirmwareUploadException("Error writing data to EEPROM: Wrote " + eepromBytes + " bytes instead of "  + k + " bytes" );
353
                    if ( eepromChecksum!=cs )
354
                        throw new FirmwareUploadException("Error writing data to EEPROM: Checksum error");
355
 
356
                    eepromRead(i*pageSize, rbuf, k);
357
                    for (int j=0; j<k; j++ ) {
358
                        if ( rbuf[j] != buffer[i][j] )
359
                            throw new FirmwareUploadException("Error writing data to EEPROM: Verification failed");
360
                    }
361
                    tries = 0;
362
                }
363
                catch ( Exception e ) {
364
                    if ( tries > 1 ) {
365
                        System.err.println("Warning: " + e.getLocalizedMessage() +": Retrying it ...");
366
                    }
367
                    else {
368
                        throw new FirmwareUploadException(e.getLocalizedMessage());
369
                    }
370
                }
371
            }
372
        }
373
 
374
        return new Date().getTime() - t0;
375
    }
376
 
377
 
378
// ******* eepromDisable ********************************************************
379
    public void eepromDisable ( ) throws FirmwareUploadException, InvalidFirmwareException, CapabilityException {
380
        byte[] buf = { 0 };
381
 
382
        for ( int tries=4; tries>0; tries-- ) {
383
            try {
384
                eepromWrite(0, buf, 1);
385
 
386
                eepromRead(0, buf, 1);
387
                if ( buf[0] != 0 )
388
                    throw new FirmwareUploadException("Error disabeling EEPROM firmware: Verification failed");
389
                tries = 0;
390
 
391
            }
392
            catch ( Exception e ) {
393
                if ( tries > 1 ) {
394
                    System.err.println("Warning: " + e.getLocalizedMessage() +": Retrying it ...");
395
                }
396
                else {
397
                    throw new FirmwareUploadException(e.getLocalizedMessage());
398
                }
399
            }
400
        }
401
    }
402
 
403
// ******* toString ************************************************************
404
    public String toString () {
405
        String str = dev.toString();
406
        try {
407
            str += "\n   " + getFpgaConfigurationStr();
408
        }
409
        catch ( Exception e ) {
410
        }
411
        return str;
412
    }
413
 
414
// ******* capabilityInfo ******************************************************
415
    public String capabilityInfo ( String pf ) {
416
        String str = "";
417
        for ( int i=0; i<6; i++ )
418
            for (int j=0; j<8; j++ )
419
                if ( dev.interfaceCapabilities(i,j) ) {
420
                    if ( ! str.equals("") )
421
                        str+="\n";
422
                    if (i*8+j < capabilityStrings.length)
423
                        str+=pf+capabilityStrings[i*8+j];
424
                    else
425
                        str+=pf+i+"."+j;
426
                }
427
        return str;
428
    }
429
}
430
 

powered by: WebSVN 2.1.0

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