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

Subversion Repositories usb_fpga_2_14

[/] [usb_fpga_2_14/] [trunk/] [capi/] [c/] [ztex.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ZTEX
/*%
2
   ZTEX Core API for C with examples
3
   Copyright (C) 2009-2017 ZTEX GmbH.
4
   http://www.ztex.de
5
 
6
   This Source Code Form is subject to the terms of the Mozilla Public
7
   License, v. 2.0. If a copy of the MPL was not distributed with this file,
8
   You can obtain one at http://mozilla.org/MPL/2.0/.
9
 
10
   Alternatively, the contents of this file may be used under the terms
11
   of the GNU General Public License Version 3, as described below:
12
 
13
   This program is free software; you can redistribute it and/or modify
14
   it under the terms of the GNU General Public License version 3 as
15
   published by the Free Software Foundation.
16
 
17
   This program is distributed in the hope that it will be useful, but
18
   WITHOUT ANY WARRANTY; without even the implied warranty of
19
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20
   General Public License for more details.
21
 
22
   You should have received a copy of the GNU General Public License
23
   along with this program; if not, see http://www.gnu.org/licenses/.
24
%*/
25
 
26
/// @file ztex.h 
27
 
28
/** @mainpage
29
@brief
30
The C Core API of the <a href="http://www.ztex.de/firmware-kit/index.e.html">ZTEX SDK</a>.
31
<p>
32
This API is used for developing host software in C. It is a re-implementation a subset of the <a href="../../java/index.html">JAVA API</a>.
33
<p>
34
<h2>Features</h2>
35
The main features are:
36
<ul>
37
    <li> Full support of <a href="http://www.ztex.de/firmware-kit/default.e.html">Default Interface</a>
38
        <ul>
39
            <li> Multiple communication interfaces: high speed, low speed, GPIO's, reset signal
40
            <li> Compatibility allows board independent host software
41
        </ul>
42
    </li>
43
    <li> Bitstream upload directly to the FPGA
44
    <li> Utility functions (gathering information about FPGA Boards, finding devices using filters, ...)
45
</ul>
46
 
47
<p>
48
<h2>Usage, Examples</h2>
49
The library consists in the single file pair 'ztex.c' and 'ztex.h'. It has been tested with gcc and should work with no/minor
50
modifications with other compilers.
51
<p>
52
Its recommended to link the application directly against the object file.
53
<p>
54
The package contains two examples, 'ucecho.c' and 'memfifo.c' which demonstrate the usage of the API including the default interface.
55
<p>
56
Object files and examples can be built using make. Under Windows it has been tested with MSYS/MinGW, see
57
<a href="http://wiki.ztex.de/doku.php?id=en:software:windows_hints#hints">Hints for Windows users</a>
58
 
59
 
60
<h2>Related Resources</h2>
61
Additional information can be found at
62
<ul>
63
  <li> <a href="http://www.ztex.de/firmware-kit/index.e.html">ZTEX SDK</a>
64
  <li> <a href="http://wiki.ztex.de/">ZTEX Wiki</a>
65
</ul>
66
*/
67
 
68
#include <stdio.h>
69
#include <stdlib.h>
70
#include <string.h>
71
#include <sys/types.h>
72
#include <libusb-1.0/libusb.h>
73
#if defined(unix) || defined(_unix)
74
#include <unistd.h>
75
#endif
76
 
77
 
78
#include "ztex.h"
79
 
80
#define SPRINTF_INIT( buf, maxlen )     \
81
char* buf__ = buf;                      \
82
int bufptr__ = 0;                        \
83
int bufremain__ = maxlen-1;             \
84
buf__[0]=0;
85
 
86
#define SPRINTF_RETURN return bufptr__;
87
 
88
#define SPRINTF( args... ) {                                            \
89
    if ( bufremain__>0 ) {                                               \
90
        int bufincr = snprintf(buf__+bufptr__,bufremain__, args);       \
91
        if ( bufincr>0 ) {                                               \
92
            if (bufincr > bufremain__) bufincr = bufremain__;           \
93
            bufptr__+=bufincr;                                          \
94
            bufremain__-=bufincr;                                       \
95
            buf__[bufptr__] = 0;                                 \
96
        }                                                               \
97
    }                                                                   \
98
}
99
 
100
// ******* ztex_scan_bus *******************************************************
101
/** Scans the bus and performs certain operations on it.
102
  * @param devs A null terminated list of devices
103
  * @param op Operation to perform. <0: print bus and ignore filters, 0: find a device using the filters, >0 print all devices matching the filters
104
  * @param id_vendor,id_product Filter by USB ID's that specify the device, ignored if negative
105
  * @param busnum,devnum Filter by bus number and device address, ignored if negative
106
  * @param sn Filter by serial number, ignored if NULL
107
  * @param ps Filter by product string, ignored if NULL
108
  * @param sbuf string buffer for output
109
  * @param sbuflen length of the string buffer
110
  * @return The device index if filter result unique, otherwise -1
111
  */
112
int ztex_scan_bus(char *sbuf, int sbuflen, libusb_device **devs, int op, int id_vendor, int id_product, int busnum, int devnum, char* sn, char* ps)
113
{
114
    libusb_device *dev;
115
    int status = 0;
116
    int bn = -1, dn = -1;
117
    struct libusb_device_descriptor dev_desc;
118
    libusb_device_handle *handle = NULL;
119
    char product_string[128];
120
    char sn_string[64];
121
 
122
    SPRINTF_INIT(sbuf,sbuflen);
123
 
124
    if (op<0) {
125
        id_vendor = id_product = busnum = devnum = -1;
126
        sn = ps = NULL;
127
    }
128
 
129
    int dev_idx=-1, result=-1;
130
    for (int i=0; (dev=devs[i]) != NULL; i++) {
131
        bn = libusb_get_bus_number(dev);
132
        dn = libusb_get_device_address(dev);
133
        status = libusb_get_device_descriptor(dev, &dev_desc);
134
        if (status < 0) {
135
            SPRINTF("Warning: Bus %d Device %d: can't read device descriptor %s\n",  bn, dn, libusb_error_name(status));
136
        } else if ( ((id_vendor<0) || (dev_desc.idVendor==id_vendor)) &&
137
                    ((id_product<0) || (dev_desc.idProduct==id_product)) &&
138
                    ((busnum<0) || (busnum==bn)) &&
139
                    ((devnum<0) || (devnum==dn)) ) {
140
            if ( (sn!=NULL) || (ps!=NULL) || (op!=0) ) {
141
                status = libusb_open(dev, &handle);
142
                if (status < 0) {
143
                    //SPRINTF(stderr, "Warning: libusb_open() failed: %s\n", libusb_error_name(status));
144
                    product_string[0] = 0;
145
                    sn_string[0] = 0;
146
                }
147
                else {
148
                    if ( libusb_get_string_descriptor_ascii(handle, dev_desc.iProduct, (unsigned char*)product_string, 128) < 0 ) product_string[0] = 0;
149
                    if ( libusb_get_string_descriptor_ascii(handle, dev_desc.iSerialNumber, (unsigned char*)sn_string, 64) < 0 ) sn_string[0] = 0;
150
                    libusb_close(handle);
151
                }
152
            }
153
 
154
            if ( ( (sn==NULL) || (strcmp(sn,sn_string)==0) ) && ( (ps==NULL) || (strcmp(ps,product_string)==0) ) ) {
155
                if ( op ) SPRINTF("Bus %d Device %d:    ID 0x%x:0x%x    Product '%s'    SN '%s'\n",bn, dn, dev_desc.idVendor, dev_desc.idProduct, product_string, sn_string);
156
                if ( dev_idx<=0 ) {
157
                    result = i;
158
                    dev_idx = i;
159
                }
160
                else {
161
                    result = -2;
162
                    if ( !op ) {
163
                        SPRINTF("Error: More than 1 matching devices found:\n");
164
                        i=dev_idx-1;
165
                        op=1;
166
                    }
167
                }
168
            }
169
        }
170
    }
171
    return result;
172
}
173
 
174
 
175
// ******* ztex_get_device_info ************************************************
176
/** Get device information.
177
  * @param handle device handle
178
  * @param info structure where device information are stored.
179
  * @return the error code or 0, if no error occurs.
180
 */
181
int ztex_get_device_info(libusb_device_handle *handle, ztex_device_info *info) {
182
    struct libusb_device_descriptor dev_desc;
183
    unsigned char *buf = info->product_string; // product string is used as buffer
184
    int status;
185
 
186
    // VR 0x33: fast configuration info
187
    TWO_TRIES(status, libusb_control_transfer(handle, 0xc0, 0x33, 0, 0, buf, 128, 1500));
188
    info->fast_config_ep = status > 0 ? buf[0] : 0;
189
    info->fast_config_if = status == 2 ? buf[1] : 0;
190
 
191
    // VR 0x3b: configuration data
192
    TWO_TRIES(status, libusb_control_transfer(handle, 0xc0, 0x3b, 0, 0, buf, 128, 1500));
193
    if ( status < 0 ) status = libusb_control_transfer(handle, 0xc0, 0x3b, 0, 0, buf, 128, 1500);
194
    if ( (status==128) && (buf[0]==67) && (buf[1]==68) && (buf[2]==48) ) {
195
        info->fx_version = buf[3];
196
        info->board_series = buf[4];
197
        info->board_number = buf[5];
198
        info->board_variant[0] = buf[6];
199
        info->board_variant[1] = buf[7];
200
        info->board_variant[2] = 0;
201
    }
202
    else {
203
        info->fx_version = 0;
204
        info->board_series = 255;
205
        info->board_number = 255;
206
        info->board_variant[0] = 0;
207
    }
208
 
209
    // VR 0x64: default interface info
210
    TWO_TRIES(status, libusb_control_transfer(handle, 0xc0, 0x64, 0, 0, buf, 128, 1500));
211
    if ( status>2 && buf[0]>0 ) {
212
        info->default_version1 = buf[0];
213
        info->default_version2 = status>3 ? buf[3] : 0;
214
        info->default_out_ep = buf[1] & 127;
215
        info->default_in_ep = buf[2] | 128;
216
    }
217
    else {
218
        info->default_version1 = 0;
219
        info->default_version2 = 0;
220
        info->default_out_ep = 255;
221
        info->default_in_ep = 255;
222
    }
223
 
224
    // string descriptors
225
    status = libusb_get_device_descriptor(libusb_get_device(handle), &dev_desc);
226
    if ( status < 0 ) return status;
227
    if ( libusb_get_string_descriptor_ascii(handle, dev_desc.iProduct, info->product_string, 128) < 0 ) info->product_string[0] = 0;
228
    if ( libusb_get_string_descriptor_ascii(handle, dev_desc.iSerialNumber, info->sn_string, 64) < 0 ) info->sn_string[0] = 0;
229
 
230
    return 0;
231
}
232
 
233
 
234
// ******* ztex_print_device_info **********************************************
235
/** Print device info to a string.
236
  * The output may be truncated and is always null-terminated.
237
  * @param sbuf string buffer for output
238
  * @param sbuflen length of the string buffer
239
  * @param info structure where device information are stored.
240
  * @return length of the output string (may be truncated)
241
  */
242
int ztex_print_device_info(char* sbuf, int sbuflen, const ztex_device_info *info) {
243
    SPRINTF_INIT(sbuf,sbuflen);
244
    SPRINTF("Product: '%s'\n", info->product_string);
245
    SPRINTF("Serial number: '%s'\n", info->sn_string);
246
    SPRINTF("USB-Controller: %s\n", info->fx_version==2 ? "EZ-USB FX2" : info->fx_version==3 ? "EZ-USB FX3" : "unknown" );
247
    if ( (info->board_series<255) && (info->board_number<255) )
248
        SPRINTF("Board: ZTEX USB-FPGA %d.%.2d%s\n",info->board_series, info->board_number, info->board_variant)
249
    else
250
        SPRINTF("Board: unknown\n")
251
    if ( info->fast_config_ep )
252
        SPRINTF("High speed FPGA configuration: EP %d,  IF %d\n",info->fast_config_ep, info->fast_config_if)
253
    else
254
        SPRINTF("High speed FPGA configuration: not supported\n")
255
    if ( (info->default_version1>0) )
256
        SPRINTF("Default interface: v%d.%d,  OUT EP %d,  IN EP %d\n", info->default_version1, info->default_version2, info->default_out_ep & 127, info->default_in_ep & 127)
257
    else
258
        SPRINTF("Default interface: not available\n")
259
    SPRINTF_RETURN;
260
}
261
 
262
 
263
// ******* ztex_get_fpga_config ************************************************
264
/** Get device information.
265
  * @param handle device handle
266
  * @return <0 if an USB error occurred, 0 if unconfigured, 1 if configured
267
 */
268
int ztex_get_fpga_config(libusb_device_handle *handle) {
269
    unsigned char buf[16];
270
    int status;
271
    TWO_TRIES(status, libusb_control_transfer(handle, 0xc0, 0x30, 0, 0, buf, 16, 1500));
272
    return status < 0 ? status : status == 0 ? -255 : buf[0] == 0 ? 1 : 0;
273
}
274
 
275
#if defined(unix) || defined(_unix)
276
#define FILE_EXISTS(fn) access(fn,R_OK)
277
#else
278
// the ugly method for ugly windows
279
int FILE_EXISTS(const char* fn) {
280
    FILE *f = fopen(fn,"rb");
281
    if ( !f ) return -1;
282
    fclose(f);
283
    return 0;
284
}
285
#endif
286
 
287
// ******* ztex_find_bitstream *************************************************
288
/** Search for bitstream at standard locations.
289
    @param info device information, used for determining locations of the SDK examples, ignored if NULL
290
    @param path additional path to search, ignored if NULL
291
    @param name without suffix '.bit'
292
    @return the file name or NULL no file found
293
  */
294
char* ztex_find_bitstream(const ztex_device_info *info, const char *path, const char* name) {
295
    char *fn = malloc(256);
296
    if ( !fn )  return NULL;  // out of memory, should not occur
297
    int status = -1;
298
 
299
    if ( snprintf(fn, 256, "%s.bit", name) > 0 ) status=FILE_EXISTS(fn);
300
    if ( (status<0) && path && (snprintf(fn, 256, "%s"DIRSEP"%s.bit", path, name) > 0 ) ) status=FILE_EXISTS(fn);
301
 
302
    if ( (info!=NULL) && (info->board_series<255) && (info->board_number<255) ) {
303
        if ( (status<0) && (snprintf(fn, 256, "fpga-%d.%.2d%s"DIRSEP"%s.bit", info->board_series, info->board_number, info->board_variant, name)) ) status=FILE_EXISTS(fn);
304
        if ( (status<0) && (snprintf(fn, 256, "fpga-%d.%.2d"DIRSEP"%s.runs"DIRSEP"impl_%d_%.2d%s"DIRSEP"%s.bit" , info->board_series, info->board_number, name, info->board_series, info->board_number, info->board_variant, name)) ) status=FILE_EXISTS(fn);
305
        if ( (status<0) && path && (snprintf(fn, 256, "%s"DIRSEP"fpga-%d.%.2d%s"DIRSEP"%s.bit", path, info->board_series, info->board_number, info->board_variant, name)) ) status=FILE_EXISTS(fn);
306
        if ( (status<0) && path && (snprintf(fn, 256, "%s"DIRSEP"fpga-%d.%.2d"DIRSEP"%s.runs"DIRSEP"impl_%d_%.2d%s"DIRSEP"%s.bit" , path, info->board_series, info->board_number, name, info->board_series, info->board_number, info->board_variant, name)) ) status=FILE_EXISTS(fn);
307
    }
308
 
309
    if ( (status<0) && (snprintf(fn, 256, "fpga"DIRSEP"%s.bit", name) > 0) ) status=FILE_EXISTS(fn);
310
    if ( (status<0) && path && (snprintf(fn, 256, "%s"DIRSEP"fpga"DIRSEP"%s.bit", path, name) > 0) ) status=FILE_EXISTS(fn);
311
    if ( status<0 ) return NULL;
312
    return fn;
313
}
314
 
315
 
316
// ******* ztex_upload_bitstream ***********************************************
317
/** Upload bitstream to volatile memory.
318
  * @param sbuf string buffer for error messages
319
  * @param sbuflen length of the string buffer
320
  * @param handle device handle
321
  * @param info device information, used for determining high speed configuration settings, ignored if NULL
322
  * @param fd File to read from. I/O errors are ignored.
323
  * @param bs 0: disable bit swapping, 1: enable bit swapping, all other values: automatic detection of bit order.
324
  * @return -1 if an error occurred, otherwise 0. Error messages are printed to sbuf.
325
  */
326
int ztex_upload_bitstream(char* sbuf, int sbuflen, libusb_device_handle *handle, const ztex_device_info *info, FILE *fd, int bs) {
327
#define EP0_TRANSACTION_SIZE 2048
328
#define BUF_SIZE 32768
329
#define BUFS_SIZE 2048
330
    unsigned char *bufs[BUFS_SIZE];     // up to 64MB
331
    uint8_t *buf;
332
    int status, size = 0, bufs_idx, buf_idx=BUF_SIZE;
333
    SPRINTF_INIT(sbuf,sbuflen);
334
 
335
    if ( bs > 1 ) bs=-1;
336
    // read bitstream
337
    for ( bufs_idx=0; (bufs_idx<BUFS_SIZE) && (buf_idx==BUF_SIZE); bufs_idx++ ) {
338
        buf = malloc(BUF_SIZE);
339
        bufs[bufs_idx] = buf;
340
        if ( buf == NULL ) {
341
            SPRINTF("Error allocating memory\n");
342
            return -1;
343
        }
344
        // prepend 512 bytes dummy data
345
        if ( bufs_idx==0 ) {
346
            buf_idx  = 512;
347
            for (int i=0; i<512; i++) buf[i]=0;
348
        }
349
        else {
350
            buf_idx=0;
351
        }
352
 
353
        do {
354
            status = fread(buf+buf_idx, 1, BUF_SIZE-buf_idx, fd);
355
            if ( status > 0 ) {
356
                size += status;
357
                buf_idx+=status;
358
            }
359
        } while ( (buf_idx<BUF_SIZE) && (status>0) );
360
        if ( (buf_idx<BUF_SIZE) && (buf_idx % 64 == 0 ) )  {
361
            buf_idx ++;         // append a dummy byte for proper end of transfer detection
362
        }
363
 
364
        // detect bit order
365
        if ( bs<0 ) {
366
            for ( int i=0; (bs<0) && (i<buf_idx-3); i++ ) {
367
                if ( (buf[i]==0xaa) && (buf[i+1]==0x99) && (buf[i+2]==0x55) && (buf[i+3]==0x66) )
368
                    bs = 1;
369
                if ( (buf[i]==0x55) && (buf[i+1]==0x99) && (buf[i+2]==0xaa) && (buf[i+3]==0x66) )
370
                    bs = 0;
371
            }
372
            if (bs<0) {
373
                SPRINTF("Warning: Unable to detect bitstream order\n");
374
                bs = 0;
375
            }
376
        }
377
        if ( bs > 0 ) {
378
            for (int i=0; i<buf_idx; i++ ) {
379
                char b = buf[i];
380
                buf[i] = ((b & 128) >> 7) |
381
                         ((b &  64) >> 5) |
382
                         ((b &  32) >> 3) |
383
                         ((b &  16) >> 1) |
384
                         ((b &   8) << 1) |
385
                         ((b &   4) << 3) |
386
                         ((b &   2) << 5) |
387
                         ((b &   1) << 7);
388
            }
389
        }
390
    }
391
 
392
    if ( size < 1024 || size % 64 == 0 ) {
393
        SPRINTF("Error: Invalid bitstream size: %d\n",size);
394
        free(bufs[0]);
395
        return -1;
396
    }
397
 
398
    status = -1;
399
    int claimed_if = -1;
400
    for (int try=0; (status<0) && (try<5); try++) {
401
        // choose EP and claim interface if necessary
402
        int ep = ((try<2) && (info!=NULL)) ? (info->fast_config_ep & 127) : 0;
403
        //printf("Try %d: EP=%d  \n",try,ep);
404
        if ( (ep>0) && (info->fast_config_if!=claimed_if) ) {
405
            claimed_if = info->fast_config_if;
406
            status = libusb_claim_interface(handle, claimed_if);
407
            if ( status < 0 ) SPRINTF("Warning: Unable to claim interface %d: %s\n", claimed_if, libusb_error_name(status));
408
 
409
        }
410
 
411
        // reset FPGA
412
        TWO_TRIES(status, libusb_control_transfer(handle, 0x40, 0x31, 0, 0, NULL, 0,  1500));
413
        if ( status < 0 ) SPRINTF("Warning: Unable to reset FPGA: %s\n", libusb_error_name(status));
414
 
415
        // init FPGA configuration
416
        if ( ep>0 ) {
417
            TWO_TRIES( status, libusb_control_transfer(handle, 0x40, 0x34, 0, 0, NULL, 0,  1500));
418
            if ( status < 0 ) {
419
                SPRINTF("Warning: Unable to initialize high speed configuration: %s\n", libusb_error_name(status));
420
                break;
421
            }
422
        }
423
 
424
        // transfer data
425
        status = 0;
426
        for ( int i=0; (status>=0) && (i<bufs_idx); i++ ) {
427
            int j = i == (bufs_idx-1) ? buf_idx : BUF_SIZE;
428
            int k;
429
            buf=bufs[i];
430
            if ( ep>0 ) {
431
                while ( (status>=0) && (j > 0) ) {
432
                    TWO_TRIES(status, libusb_bulk_transfer(handle, ep, buf, j, &k, 2000));
433
                    if ( status<0 ) {
434
                        //printf("try=%d, i=%d, j=%d, k=%d\n",try,i,j,k);
435
                        SPRINTF("Warning: Error transferring bitstream: %s\n", libusb_error_name(status));
436
                    } else if (k<1 ) {
437
                        SPRINTF("Warning: Unknown transfer error\n");
438
                        status=-1;
439
                    } else {
440
                        buf+=k;
441
                        j-=k;
442
                    }
443
                }
444
            }
445
            else {
446
                for (int k=0; (status>=0) && (k<j); k+=EP0_TRANSACTION_SIZE) {
447
                    int l = j-k < EP0_TRANSACTION_SIZE ? j-k : EP0_TRANSACTION_SIZE;
448
                    TWO_TRIES( status, libusb_control_transfer(handle, 0x40, 0x32, 0, 0, buf+k, l, 1500));
449
                    if ( status<0 ) {
450
                        SPRINTF("Warning: Error transferring bitstream: %s\n", libusb_error_name(status));
451
                    }
452
                    else if ( status!=l ) {
453
                        SPRINTF("Warning: Error transferring bitstream: %d bytes lost\n", l-status);
454
                        status=-1;
455
                    }
456
                }
457
            }
458
        }
459
 
460
        // finish FPGA configuration
461
        if ( ep>0 ) {
462
            TWO_TRIES(status, libusb_control_transfer(handle, 0x40, 0x35, 0, 0, NULL, 0,  1500));
463
            if ( status < 0 ) SPRINTF("Warning: Unable to finish high speed configuration: %s\n", libusb_error_name(status));
464
        }
465
 
466
        // check configuration state
467
        status = ztex_get_fpga_config(handle);
468
        if ( status < 0 ) {
469
            SPRINTF("Error: Unable to get FPGA configuration state: %s\n", libusb_error_name(status));
470
            status = -1;
471
            break;
472
        }
473
        if ( status==0 ) {
474
            SPRINTF("Warning: %s FPGA configuration failed\n", ep>0 ? "high-speed" : "low-speed");
475
            status = -1;
476
        } else {
477
            status = 0;
478
        }
479
    }
480
 
481
    if ( claimed_if>=0 ) {
482
        libusb_release_interface(handle, claimed_if);
483
    }
484
 
485
    for ( int i=0; i<bufs_idx; i++ ) {
486
        free(bufs[i]);
487
    }
488
 
489
    return status;
490
}
491
 
492
 
493
// ******* ztex_default_gpio_ctl ***********************************************
494
/**
495
  * Reads and modifies the 4 GPIO pins.
496
  * @param handle device handle
497
  * @param mask Bitmask for the pins which are modified. 1 means a bit is set. Only the lowest 4 bits are significant.
498
  * @param value The bit values which are to be set. Only the lowest 4 bits are significant.
499
  * @return current values of the GPIO's or <0 if an USB error occurred
500
  */
501
int ztex_default_gpio_ctl (libusb_device_handle *handle, int mask, int value) {
502
    unsigned char buf[8];
503
    int status;
504
    TWO_TRIES(status, libusb_control_transfer(handle, 0xc0, 0x61, value, mask, buf, 8, 1500));
505
    return status < 0 ? status : buf[0];
506
}
507
 
508
// ******* ztex_default_reset **************************************************
509
/**
510
  * Assert the reset signal.
511
  * @param handle device handle
512
  * @param leave if >0, the signal is left active. Otherwise only a short impulse is sent.
513
  * @return 0 on success or <0 if an USB error occurred
514
  */
515
int ztex_default_reset(libusb_device_handle *handle,  int leave ) {
516
    int status;
517
    TWO_TRIES(status, libusb_control_transfer(handle, 0x40, 0x60, leave ? 1 : 0, 0, NULL, 0 , 1500));
518
    return status;
519
}
520
 
521
 
522
// ******* ztex_default_lsi_set1 ***********************************************
523
/**
524
  * Send data to the low speed interface of default firmwares.
525
  * It's implemented as a SRAM-like interface and is typically used used to read/write configuration data, debug information or other things.
526
  * This function sets one register.
527
  * @param handle device handle
528
  * @param addr The address. Valid values are 0 to 255.
529
  * @param val The register data with a width of 32 bit.
530
  * @return 0 on success or <0 if an USB error occurred
531
  */
532
int ztex_default_lsi_set1 (libusb_device_handle *handle, uint8_t addr, uint32_t val) {
533
    unsigned char buf[] = { val, val>>8, val>>16, val>>24, addr & 255 };
534
    int status;
535
    TWO_TRIES(status, libusb_control_transfer(handle, 0x40, 0x62, 0, 0, buf, 5, 1500));
536
    return status;
537
}
538
 
539
 
540
// ******* ztex_default_lsi_set2 ***********************************************
541
/**
542
  * Send data to the low speed interface of default firmwares.
543
  * It's implemented as a SRAM-like interface and is typically used used to read/write configuration data, debug information or other things.
544
  * This function sets a sequential set of registers.
545
  * @param handle device handle
546
  * @param addr The starting address address. Valid values are 0 to 255. Address is wrapped from 255 to 0.
547
  * @param val The register data array with a word width of 32 bit.
548
  * @param length The length of the data array.
549
  * @return 0 on success or <0 if an USB error occurred
550
  */
551
int ztex_default_lsi_set2 (libusb_device_handle *handle, uint8_t addr, const uint32_t *val, int length) {
552
    if (length<0) return 0;
553
    int ia = length-256;
554
    if (ia<0) ia = 0;
555
    uint8_t *buf = malloc((length-ia)*5);
556
    for (int i=ia; i<length; i++) {
557
        buf[(i-ia)*5+0]=val[i];
558
        buf[(i-ia)*5+1]=val[i]>>8;
559
        buf[(i-ia)*5+2]=val[i]>>16;
560
        buf[(i-ia)*5+3]=val[i]>>24;
561
        buf[(i-ia)*5+4]=addr+i;
562
    }
563
    int status;
564
    TWO_TRIES(status, libusb_control_transfer(handle, 0x40, 0x62, 0, 0, buf, (length-ia)*5, 1500));
565
    free(buf);
566
    return status;
567
}
568
 
569
 
570
// ******* ztex_default_lsi_set3 **********************************************
571
/**
572
  * Send data to the low speed interface of default firmwares.
573
  * It's implemented as a SRAM-like interface and is typically used used to read/write configuration data, debug information or other things.
574
  * This function sets a sequential set of registers.
575
  * @param handle device handle
576
  * @param addr The register addresses. Valid values are 0 to 255.
577
  * @param val The register data array with a word width of 32 bit.
578
  * @param length The length of the data array.
579
  * @return 0 on success or <0 if an USB error occurred
580
  */
581
int ztex_default_lsi_set3 (libusb_device_handle *handle, const uint8_t *addr, const uint32_t *val, int length) {
582
    if (length<0) return 0;
583
    int ia = length-256;
584
    if (ia<0) ia = 0;
585
    uint8_t *buf = malloc((length-ia)*5);
586
    for (int i=ia; i<length; i++) {
587
        buf[(i-ia)*5+0]=val[i];
588
        buf[(i-ia)*5+1]=val[i]>>8;
589
        buf[(i-ia)*5+2]=val[i]>>16;
590
        buf[(i-ia)*5+3]=val[i]>>24;
591
        buf[(i-ia)*5+4]=addr[i];
592
    }
593
    int status;
594
    TWO_TRIES(status, libusb_control_transfer(handle, 0x40, 0x62, 0, 0, buf, (length-ia)*5, 1500));
595
    free(buf);
596
    return status;
597
}
598
 
599
 
600
// ******* ztex_default_lsi_get1 ***********************************************
601
/**
602
  * Read data from the low speed interface of default firmwares.
603
  * It's implemented as a SRAM-like interface and is typically used used to read/write configuration data, debug information or other things.
604
  * This function reads one register.
605
  * @param handle device handle
606
  * @param addr The address. Valid values are 0 to 255.
607
  * @return The unsigned register value (32 Bits) or <0 if an error occurred.
608
  */
609
int64_t ztex_default_lsi_get1 (libusb_device_handle *handle, uint8_t addr) {
610
    uint8_t buf[4];
611
    int status;
612
    TWO_TRIES(status, libusb_control_transfer(handle, 0xc0, 0x63, 0, addr, buf, 4, 1500));
613
    return status<0 ? status : buf[0] | (buf[1]<<8) | (buf[2]<<16) | (buf[3]<<24);
614
}
615
 
616
// ******* ztex_default_lsi_get2 ***********************************************
617
/**
618
  * Read data from the low speed interface of default firmwares.
619
  * It's implemented as a SRAM-like interface and is typically used used to read/write configuration data, debug information or other things.
620
  * This function reads a sequential set of registers.
621
  * @param handle device handle
622
  * @param addr The start address. Valid values are 0 to 255. Address is wrapped from 255 to 0.
623
  * @param val The array where to store the register data with a word width of 32 Bit.
624
  * @param length The amount of register to be read.
625
  * @return 0 on success or <0 if an USB error occurred
626
  */
627
int ztex_default_lsi_get2 (libusb_device_handle *handle, uint8_t addr, uint32_t *val, int length) {
628
    int l=length;
629
    if (l>256) l=256;
630
    uint8_t *buf = malloc(l*4);
631
    int status;
632
    TWO_TRIES(status, libusb_control_transfer(handle, 0xc0, 0x63, 0, addr, buf, l*4, 1500));
633
    if (status < 0 ) return status;
634
    for (int i=0; i<length; i++) {
635
        int j = i & 255;
636
        val[i] = buf[j*4+0] | (buf[j*4+1]<<8) | (buf[j*4+2]<<16) | (buf[j*4+3]<<24);
637
    }
638
    free(buf);
639
    return 0;
640
}

powered by: WebSVN 2.1.0

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