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

Subversion Repositories adv_debug_sys

[/] [adv_debug_sys/] [trunk/] [Software/] [adv_jtag_bridge/] [cable_ft2232.c] - Blame information for rev 21

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

Line No. Rev Author Line
1 21 nyawn
/* cable_ft2232.c - FT2232 based cable driver for the Advanced JTAG Bridge
2
   Copyright (C) 2008 Arnim Laeuger, arniml@opencores.org
3
   Copyright (C) 2009 José Ignacio Villar, jose@dte.us.es
4
 
5
   This program is free software; you can redistribute it and/or modify
6
   it under the terms of the GNU General Public License as published by
7
   the Free Software Foundation; either version 2 of the License, or
8
   (at your option) any later version.
9
 
10
   This program is distributed in the hope that it will be useful,
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
   GNU 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, write to the Free Software
17
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18
 
19
 
20
#include <time.h>
21
#include <sys/time.h>
22
#include <fcntl.h>
23
#include <stdio.h>
24
#include <string.h>
25
#include <stdlib.h>
26
#include <stdint.h>
27
#include <unistd.h>
28
#include <ftdi.h>
29
#include "cable_ft2232.h"
30
#include "cable_common.h"
31
#include "errcodes.h"
32
int debug = 0;
33
 
34
static int usbconn_ftdi_common_open( usbconn_t *conn);
35
static void usbconn_ftdi_free( usbconn_t *conn );
36
static int seq_purge(struct ftdi_context *ftdic, int purge_rx, int purge_tx);
37
static int seq_reset(struct ftdi_context *ftdic);
38
static int usbconn_ftdi_flush( ftdi_param_t *params );
39
static int usbconn_ftdi_read( usbconn_t *conn, uint8_t *buf, int len );
40
static int usbconn_ftdi_write( usbconn_t *conn, uint8_t *buf, int len, int recv );
41
static int usbconn_ftdi_mpsse_open( usbconn_t *conn );
42
static int usbconn_ftdi_close(usbconn_t *conn);
43
 
44
usbconn_driver_t usbconn_ft2232_mpsse_driver = {
45
        "ftdi-mpsse",
46
        usbconn_ftdi_connect,
47
        usbconn_ftdi_free,
48
        usbconn_ftdi_mpsse_open,
49
        usbconn_ftdi_close,
50
        usbconn_ftdi_read,
51
        usbconn_ftdi_write
52
};
53
 
54
usbconn_cable_t usbconn_ft2232_mpsse_CableID2= {
55
  "CableID2",         /* cable name */
56
  "CableID2",         /* string pattern, not used */
57
  "ftdi-mpsse",       /* default usbconn driver */
58
  0x0403,             /* VID */
59
  0x6010              /* PID */
60
};
61
 
62
static usbconn_t *ft2232_device;
63
 
64
 
65
 
66
/// ----------------------------------------------------------------------------------------------
67
/// libftdi wrappers for debugging purposes.
68
/// ----------------------------------------------------------------------------------------------
69
 
70
void print_buffer(unsigned char *buf, int size) {
71
        int i=0;
72
        for(i=0; i<size; i++)
73
                printf("[MYDBG]\tBUFFER[%d] = %02x\n", i, buf[i]);
74
 
75
}
76
 
77
int my_ftdi_write_data(struct ftdi_context *ftdi, unsigned char *buf, int size) {
78
        debug("[MYDBG] ftdi_write_data(ftdi, buf=BUFFER[%d], size=%d);\n", size, size);
79
        if(debug > 1) print_buffer(buf, size);
80
        return ftdi_write_data(ftdi, buf, size);
81
}
82
 
83
char *my_ftdi_get_error_string (struct ftdi_context *ftdi) {
84
        debug("[MYDBG] ftdi_get_error_string(ftdi);\n");
85
        return ftdi_get_error_string (ftdi);
86
}
87
 
88
int my_ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size) {
89
        int ret = 0;
90
        debug("[MYDBG] ftdi_read_data(ftdi, buf=BUFFER[%d], size=%d);\n", size, size);
91
        ret = ftdi_read_data(ftdi, buf, size);
92
        if(debug) print_buffer(buf, size);
93
        return ret;
94
}
95
 
96
int my_ftdi_usb_open_desc(struct ftdi_context *ftdi, int vendor, int product, const char* description, const char* serial) {
97
        debug("[MYDBG] ftdi_usb_open_desc(ftdi, vendor=%d, product=%d, description=DESCRIPTION, serial=SERIAL);\n", vendor, product);
98
        return ftdi_usb_open_desc(ftdi, vendor, product, description, serial);
99
}
100
 
101
void my_ftdi_deinit(struct ftdi_context *ftdi) {
102
        debug("[MYDBG] ftdi_deinit(ftdi);\n");
103
        ftdi_deinit(ftdi);
104
}
105
 
106
int my_ftdi_usb_purge_buffers(struct ftdi_context *ftdi) {
107
        debug("[MYDBG] ftdi_usb_purge_buffers(ftdi);\n");
108
        return ftdi_usb_purge_buffers(ftdi);
109
}
110
 
111
int my_ftdi_usb_purge_rx_buffer(struct ftdi_context *ftdi) {
112
        debug("[MYDBG] ftdi_usb_purge_rx_buffer(ftdi);\n");
113
        return ftdi_usb_purge_rx_buffer(ftdi);
114
}
115
 
116
int my_ftdi_usb_purge_tx_buffer(struct ftdi_context *ftdi) {
117
        debug("[MYDBG] ftdi_usb_purge_tx_buffer(ftdi);\n");
118
        return ftdi_usb_purge_tx_buffer(ftdi);
119
}
120
 
121
int my_ftdi_usb_reset(struct ftdi_context *ftdi) {
122
        debug("[MYDBG] ftdi_usb_reset(ftdi);\n");
123
        return ftdi_usb_reset(ftdi);
124
}
125
 
126
int my_ftdi_set_latency_timer(struct ftdi_context *ftdi, unsigned char latency) {
127
        debug("[MYDBG] ftdi_set_latency_timer(ftdi, latency=0x%02x);\n", latency);
128
        return ftdi_set_latency_timer(ftdi, latency);
129
}
130
 
131
int my_ftdi_set_baudrate(struct ftdi_context *ftdi, int baudrate) {
132
        debug("[MYDBG] ftdi_set_baudrate(ftdi, baudrate=%d);\n", baudrate);
133
        return ftdi_set_baudrate(ftdi, baudrate);
134
}
135
 
136
int my_ftdi_read_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize) {
137
        debug("[MYDBG] ftdi_read_data_set_chunksize(ftdi, chunksize=%u);\n", chunksize);
138
        return ftdi_read_data_set_chunksize(ftdi, chunksize);
139
}
140
 
141
int my_ftdi_write_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize) {
142
        debug("[MYDBG] ftdi_write_data_set_chunksize(ftdi, chunksize=%u);\n", chunksize);
143
        return ftdi_write_data_set_chunksize(ftdi, chunksize);
144
}
145
 
146
int my_ftdi_set_event_char(struct ftdi_context *ftdi, unsigned char eventch, unsigned char enable) {
147
        debug("[MYDBG] ftdi_set_event_char(ftdi, eventch=0x%02x, enable=0x%02x);\n", eventch, enable);
148
        return ftdi_set_event_char(ftdi, eventch, enable);
149
}
150
 
151
int my_ftdi_set_error_char(struct ftdi_context *ftdi, unsigned char errorch, unsigned char enable) {
152
        debug("[MYDBG] ftdi_set_error_char(ftdi, errorch=0x%02x, enable=0x%02x);\n", errorch, enable);
153
        return ftdi_set_error_char(ftdi, errorch, enable);
154
}
155
 
156
int my_ftdi_set_bitmode(struct ftdi_context *ftdi, unsigned char bitmask, unsigned char mode) {
157
        debug("[MYDBG] ftdi_set_bitmode(ftdi, bitmask=0x%02x, mode=0x%02x);\n", bitmask, mode);
158
        return ftdi_set_bitmode(ftdi, bitmask, mode);
159
}
160
 
161
int my_ftdi_usb_close(struct ftdi_context *ftdi) {
162
        debug("[MYDBG] ftdi_usb_close(ftdi);\n");
163
        return ftdi_usb_close(ftdi);
164
}
165
 
166
 
167
 
168
/// ----------------------------------------------------------------------------------------------
169
/// USBconn FTDI MPSSE subsystem
170
/// ----------------------------------------------------------------------------------------------
171
 
172
 
173
static int usbconn_ftdi_common_open(usbconn_t *conn) {
174
        ftdi_param_t *params = conn->params;
175
        struct ftdi_context * ftdic = params->ftdic;
176
        int error;
177
 
178
        printf("Initializing USB device\n");
179
 
180
        if ((error = my_ftdi_usb_open_desc(ftdic, conn->cable->vid, conn->cable->pid, NULL, NULL))) {
181
                if      (error == -1) printf("usb_find_busses() failed\n");
182
                else if (error == -2) printf("usb_find_devices() failed\n");
183
                else if (error == -3) printf("usb device not found\n");
184
                else if (error == -4) printf("unable to open device\n");
185
                else if (error == -5) printf("unable to claim device\n");
186
                else if (error == -6) printf("reset failed\n");
187
                else if (error == -7) printf("set baudrate failed\n");
188
                else if (error == -8) printf("get product description failed\n");
189
                else if (error == -9) printf("get serial number failed\n");
190
                else if (error == -10) printf("unable to close device\n");
191
 
192
                my_ftdi_deinit(ftdic);
193
                ftdic = NULL;
194
 
195
                printf("Can't open FTDI usb device\n");
196
                return(-1);
197
        }
198
 
199
        return 0;
200
}
201
 
202
static int seq_purge(struct ftdi_context *ftdic, int purge_rx, int purge_tx) {
203
        int r = 0;
204
        unsigned char buf;
205
 
206
        if ((r = my_ftdi_usb_purge_buffers( ftdic )) < 0)
207
                printf("my_ftdi_usb_purge_buffers() failed\n");
208
        if (r >= 0) if ((r = my_ftdi_read_data( ftdic, &buf, 1 )) < 0)
209
                printf("my_ftdi_read_data() failed\n");
210
 
211
        return r < 0 ? -1 : 0;
212
}
213
 
214
static int seq_reset(struct ftdi_context *ftdic) {
215
 
216
        if (my_ftdi_usb_reset( ftdic ) < 0) {
217
                printf("my_ftdi_usb_reset() failed\n");
218
                return -1;
219
        }
220
 
221
        if(seq_purge(ftdic, 1, 1) < 0)
222
                return -1;
223
 
224
        return 0;
225
}
226
 
227
static int usbconn_ftdi_flush( ftdi_param_t *params )
228
        {
229
        int xferred;
230
        int recvd = 0;
231
 
232
        if (!params->ftdic)
233
                return -1;
234
 
235
        if (params->send_buffered == 0)
236
                return 0;
237
 
238
        if ((xferred = my_ftdi_write_data( params->ftdic, params->send_buf, params->send_buffered )) < 0)
239
                printf("my_ftdi_write_data() failed\n");
240
 
241
        if (xferred < params->send_buffered) {
242
                printf("Written fewer bytes than requested.\n");
243
                return -1;
244
        }
245
 
246
        params->send_buffered = 0;
247
 
248
        /* now read all scheduled receive bytes */
249
        if (params->to_recv) {
250
                if (params->recv_write_idx + params->to_recv > params->recv_buf_len) {
251
                        /* extend receive buffer */
252
                        params->recv_buf_len = params->recv_write_idx + params->to_recv;
253
                        if (params->recv_buf)
254
                                params->recv_buf = (uint8_t *)realloc( params->recv_buf, params->recv_buf_len );
255
                }
256
 
257
                if (!params->recv_buf) {
258
                        printf("Receive buffer does not exist.\n");
259
                        return -1;
260
                }
261
 
262
                while (recvd == 0)
263
                        if ((recvd = my_ftdi_read_data( params->ftdic, &(params->recv_buf[params->recv_write_idx]), params->to_recv )) < 0)
264
                                printf("Error from my_ftdi_read_data()\n");
265
 
266
                if (recvd < params->to_recv)
267
                        printf("Received less bytes than requested.\n");
268
 
269
                params->to_recv -= recvd;
270
                params->recv_write_idx += recvd;
271
        }
272
 
273
        debug("[MYDBG] FLUSHING xferred=%u\n", xferred);
274
        return xferred < 0 ? -1 : xferred;
275
}
276
 
277
static int usbconn_ftdi_read( usbconn_t *conn, uint8_t *buf, int len ) {
278
        ftdi_param_t *params = conn->params;
279
        int cpy_len;
280
        int recvd = 0;
281
 
282
        if (!params->ftdic)
283
                return -1;
284
 
285
        /* flush send buffer to get all scheduled receive bytes */
286
        if (usbconn_ftdi_flush( params ) < 0)
287
                return -1;
288
 
289
        if (len == 0)
290
                return 0;
291
 
292
        /* check for number of remaining bytes in receive buffer */
293
        cpy_len = params->recv_write_idx - params->recv_read_idx;
294
        if (cpy_len > len)
295
                cpy_len = len;
296
        len -= cpy_len;
297
 
298
        if (cpy_len > 0) {
299
                /* get data from the receive buffer */
300
                memcpy( buf, &(params->recv_buf[params->recv_read_idx]), cpy_len );
301
                params->recv_read_idx += cpy_len;
302
                if (params->recv_read_idx == params->recv_write_idx)
303
                        params->recv_read_idx = params->recv_write_idx = 0;
304
        }
305
 
306
        if (len > 0) {
307
                /* need to get more data directly from the device */
308
                while (recvd == 0)
309
                        if ((recvd = my_ftdi_read_data( params->ftdic, &(buf[cpy_len]), len )) < 0)
310
                                printf("Error from my_ftdi_read_data()\n");
311
        }
312
        debug("[MYDBG] READ cpy_len=%u ; len=%u\n", cpy_len, len);
313
        return recvd < 0 ? -1 : cpy_len + len;
314
}
315
 
316
static int usbconn_ftdi_write( usbconn_t *conn, uint8_t *buf, int len, int recv ) {
317
 
318
        ftdi_param_t *params = conn->params;
319
        int xferred = 0;
320
 
321
        if (!params->ftdic)
322
                return -1;
323
 
324
        /* this write function will try to buffer write data
325
           buffering will be ceased and a flush triggered in two cases. */
326
 
327
        /* Case A: max number of scheduled receive bytes will be exceeded
328
           with this write
329
           Case B: max number of scheduled send bytes has been reached */
330
        if ((params->to_recv + recv > FTDI_MAXRECV) || ((params->send_buffered > FTDX_MAXSEND) && (params->to_recv == 0)))
331
                xferred = usbconn_ftdi_flush(params);
332
 
333
        if (xferred < 0)
334
                return -1;
335
 
336
        /* now buffer this write */
337
        if (params->send_buffered + len > params->send_buf_len) {
338
                params->send_buf_len = params->send_buffered + len;
339
                if (params->send_buf)
340
                        params->send_buf = (uint8_t *)realloc( params->send_buf, params->send_buf_len);
341
        }
342
 
343
        if (params->send_buf) {
344
                memcpy( &(params->send_buf[params->send_buffered]), buf, len );
345
                params->send_buffered += len;
346
                if (recv > 0)
347
                        params->to_recv += recv;
348
 
349
                if (recv < 0) {
350
                        /* immediate write requested, so flush the buffered data */
351
                        xferred = usbconn_ftdi_flush( params );
352
                }
353
 
354
                debug("[MYDBG] WRITE inmediate=%s ; xferred=%u ; len=%u\n", ((recv < 0) ? "TRUE" : "FALSE"), xferred, len);
355
                return xferred < 0 ? -1 : len;
356
        }
357
        else {
358
                printf("Send buffer does not exist.\n");
359
                return -1;
360
        }
361
}
362
 
363
static int usbconn_ftdi_mpsse_open( usbconn_t *conn ) {
364
        ftdi_param_t *params = conn->params;
365
        struct ftdi_context *ftdic = params->ftdic;
366
 
367
        int r = 0;
368
 
369
        if (usbconn_ftdi_common_open(conn) < 0) {
370
                printf("Connection failed\n");
371
                return -1;
372
        }
373
 
374
        /* This sequence might seem weird and containing superfluous stuff.
375
           However, it's built after the description of JTAG_InitDevice
376
           Ref. FTCJTAGPG10.pdf
377
           Intermittent problems will occur when certain steps are skipped. */
378
 
379
        r = seq_reset( ftdic );
380
        if (r >= 0)
381
                r = seq_purge( ftdic, 1, 0 );
382
 
383
        if (r >= 0)
384
                if ((r = my_ftdi_write_data_set_chunksize( ftdic, FTDX_MAXSEND_MPSSE )) < 0)
385
                        puts( my_ftdi_get_error_string( ftdic ) );
386
 
387
        if (r >= 0)
388
                if ((r = my_ftdi_read_data_set_chunksize( ftdic, FTDX_MAXSEND_MPSSE )) < 0)
389
                        puts( my_ftdi_get_error_string( ftdic ) );
390
 
391
        /* set a reasonable latency timer value
392
           if this value is too low then the chip will send intermediate result data
393
           in short packets (suboptimal performance) */
394
        if (r >= 0)
395
                if ((r = my_ftdi_set_latency_timer( ftdic, 16 )) < 0)
396
                        printf("my_ftdi_set_latency_timer() failed\n");
397
 
398
        if (r >= 0)
399
                if ((r = my_ftdi_set_bitmode( ftdic, 0x0b, BITMODE_MPSSE )) < 0)
400
                        printf("my_ftdi_set_bitmode() failed\n");
401
 
402
        if (r >= 0)
403
                if ((r = my_ftdi_usb_reset( ftdic )) < 0)
404
                        printf("my_ftdi_usb_reset() failed\n");
405
 
406
        if (r >= 0)
407
                r = seq_purge( ftdic, 1, 0 );
408
 
409
        /* set TCK Divisor */
410
        if (r >= 0) {
411
                uint8_t buf[3] = {TCK_DIVISOR, 0x00, 0x00};
412
                r = usbconn_ftdi_write( conn, buf, 3, 0 );
413
        }
414
 
415
        /* switch off loopback */
416
        if (r >= 0) {
417
                uint8_t buf[1] = {LOOPBACK_END};
418
                r = usbconn_ftdi_write( conn, buf, 1, 0 );
419
        }
420
 
421
        if (r >= 0)
422
                r = usbconn_ftdi_read( conn, NULL, 0 );
423
 
424
        if (r >= 0)
425
                if ((r = my_ftdi_usb_reset( ftdic )) < 0)
426
                        printf("my_ftdi_usb_reset() failed\n");
427
 
428
        if (r >= 0)
429
                r = seq_purge( ftdic, 1, 0 );
430
 
431
        if (r < 0) {
432
                ftdi_usb_close( ftdic );
433
                ftdi_deinit( ftdic );
434
                /* mark ftdi layer as not initialized */
435
                params->ftdic = NULL;
436
        }
437
 
438
        return r < 0 ? -1 : 0;
439
}
440
 
441
static int usbconn_ftdi_close(usbconn_t *conn) {
442
        ftdi_param_t *params = conn->params;
443
 
444
        if (params->ftdic) {
445
                my_ftdi_usb_close(params->ftdic);
446
                my_ftdi_deinit(params->ftdic);
447
                params->ftdic = NULL;
448
        }
449
 
450
        return 0;
451
}
452
 
453
static void usbconn_ftdi_free( usbconn_t *conn )
454
{
455
  ftdi_param_t *params = conn->params;
456
 
457
  if (params->send_buf) free( params->send_buf );
458
  if (params->recv_buf) free( params->recv_buf );
459
  if (params->ftdic)    free( params->ftdic );
460
  if (params->serial)   free( params->serial );
461
 
462
  free( conn->params );
463
  free( conn );
464
}
465
 
466
usbconn_t * usbconn_ftdi_connect() {
467
 
468
        usbconn_t *conn            = malloc( sizeof( usbconn_t ) );
469
        ftdi_param_t *params       = malloc( sizeof( ftdi_param_t ) );
470
        struct ftdi_context *ftdic = malloc( sizeof( struct ftdi_context ) );
471
 
472
        if (params) {
473
                params->send_buf_len   = FTDX_MAXSEND;
474
                params->send_buffered  = 0;
475
                params->send_buf       = (uint8_t *) malloc( params->send_buf_len );
476
                params->recv_buf_len   = FTDI_MAXRECV;
477
                params->to_recv        = 0;
478
                params->recv_write_idx = 0;
479
                params->recv_read_idx  = 0;
480
                params->recv_buf       = (uint8_t *) malloc( params->recv_buf_len );
481
        }
482
 
483
        if (!conn || !params || !ftdic || !params->send_buf || !params->recv_buf) {
484
                printf("Can't allocate memory for ftdi context structures\n");
485
 
486
                if (conn) free( conn );
487
                if (params) free( params );
488
                if (ftdic) free( ftdic );
489
                if (params->send_buf) free( params->send_buf );
490
                if (params->recv_buf) free( params->recv_buf );
491
                return NULL;
492
        }
493
 
494
        conn->driver = &usbconn_ft2232_mpsse_driver;
495
        conn->cable  = &usbconn_ft2232_mpsse_CableID2;
496
 
497
        ftdi_init( ftdic );
498
        params->ftdic  = ftdic;
499
        params->pid    = conn->cable->pid;
500
        params->vid    = conn->cable->vid;
501
        params->serial = NULL;
502
 
503
        conn->params = params;
504
 
505
        printf("Structs successfully initialized\n");
506
 
507
        /* do a test open with the specified cable paramters,
508
           alternatively we could use libusb to detect the presence of the
509
           specified USB device         */
510
        if (usbconn_ftdi_common_open(conn) != 0) {
511
                printf("Connection failed\n");
512
                usbconn_ftdi_free(conn);
513
                printf("Freeing structures.\n");
514
                return NULL;
515
        }
516
 
517
        my_ftdi_usb_close( ftdic );
518
 
519
        printf("Connected to libftdi driver.\n");
520
 
521
        return conn;
522
}
523
 
524
 
525
 
526
/// ----------------------------------------------------------------------------------------------
527
/// High level functions to generate Tx/Rx commands
528
/// ----------------------------------------------------------------------------------------------
529
 
530
int cable_ft2232_write_bytes(usbconn_t *conn, unsigned char *buf, int len, int postread) {
531
 
532
        int cur_command_size;
533
        int max_command_size;
534
        int cur_chunk_len;
535
        int recv;
536
        int xferred;
537
        int i;
538
        unsigned char *mybuf;
539
 
540
        if(len == 0)
541
                return 0;
542
        debug("write_bytes(length=%d, postread=%s)\n", len, ((postread > 0) ? "TRUE" : "FALSE"));
543
        recv = 0;
544
        max_command_size = min(len, 65536)+3;
545
        mybuf = (unsigned char *) malloc( max_command_size );
546
 
547
        /// Command OPCODE: write bytes
548
        mybuf[0] = MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_WRITE_NEG;
549
        if(postread) // if postread is enabled it will buffer incoming bytes
550
                mybuf[0] = mybuf[0] | MPSSE_DO_READ;
551
 
552
        // We divide the transmitting stream of bytes in chunks with a maximun length of 65536 bytes each.
553
        while(len > 0) {
554
                cur_chunk_len = min(len, 65536);
555
                len = len - cur_chunk_len;
556
                cur_command_size = cur_chunk_len + 3;
557
 
558
                /// Low and High bytes of the length field
559
                mybuf[1] = (unsigned char) ( cur_chunk_len - 1);
560
                mybuf[2] = (unsigned char) ((cur_chunk_len - 1) >> 8);
561
 
562
                debug("\tOPCODE:  0x%x\n", mybuf[0]);
563
                debug("\tLENGTL:  0x%02x\n", mybuf[1]);
564
                debug("\tLENGTH:  0x%02x\n", mybuf[2]);
565
 
566
                /// The rest of the command is filled with the bytes that will be transferred
567
                memcpy(&(mybuf[3]), buf, cur_chunk_len );
568
                buf = buf + cur_chunk_len;
569
                for(i = 0; i< cur_chunk_len; i++)
570
                        if(debug>1) debug("\tBYTE%3d: 0x%02x\n", i, mybuf[3+i]);
571
 
572
                /// Finally we can ransmit the command
573
                xferred = usbconn_ftdi_write( conn, mybuf, cur_command_size, (postread ? cur_chunk_len : 0) );
574
                if(xferred != cur_command_size)
575
                        return -1;
576
 
577
                // If OK, the update the number of incoming bytes that are being buffered for a posterior read
578
                if(postread)
579
                        recv = recv + cur_chunk_len;
580
        }
581
        debug("\tPOSTREAD: %u bytes\n", recv);
582
 
583
        // Returns the number of buffered incoming bytes
584
        return recv;
585
}
586
 
587
int cable_ft2232_write_bits(usbconn_t *conn, unsigned char *buf, int len, int postread, int with_tms)
588
{
589
        int max_command_size;
590
        int max_chunk_len;
591
        int cur_chunk_len;
592
        int recv;
593
        int xferred;
594
        int i;
595
        unsigned char *mybuf;
596
 
597
        if(len == 0)
598
                return 0;
599
 
600
        max_command_size = 3;
601
        mybuf = (unsigned char *) malloc( max_command_size );
602
 
603
        if(!with_tms) {
604
                /// Command OPCODE: write bits (can write up to 8 bits in a single command)
605
                max_chunk_len = 8;
606
                mybuf[0] = MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_WRITE_NEG | MPSSE_BITMODE;
607
        }
608
        else {
609
                /// Command OPCODE: 0x4B write bit with tms (can write up to 1 bits in a single command)
610
                max_chunk_len = 1;
611
                mybuf[0] = MPSSE_WRITE_TMS|MPSSE_LSB|MPSSE_BITMODE|MPSSE_WRITE_NEG;
612
        }
613
 
614
        if(postread) // (OPCODE += 0x20) if postread is enabled it will buffer incoming bits
615
                mybuf[0] = mybuf[0] | MPSSE_DO_READ;
616
 
617
        // We divide the transmitting stream of bytes in chunks with a maximun length of max_chunk_len bits each.
618
        i=0;
619
        recv = 0;
620
        while(len > 0) {
621
                cur_chunk_len = min(len, max_chunk_len);
622
                len = len - cur_chunk_len;
623
 
624
                /// Bits length field
625
                mybuf[1] = (unsigned char) ( cur_chunk_len - 1);
626
 
627
                debug("\tOPCODE:  0x%x\n", mybuf[0]);
628
                debug("\tLENGTH:  0x%02x\n", mybuf[1]);
629
 
630
                if(!with_tms) {
631
                        /// The last byte of the command is filled with the bits that will be transferred
632
                        debug("\tDATA[%d]  0x%02x\n", (i/8), buf[i/8]);
633
                        mybuf[2] = buf[i/8];
634
                        i=i+8;
635
                }
636
                else {
637
                        //TODO: seleccionar el bit a transmitir
638
                        mybuf[2] = 0x01 | ((buf[(i/8)] >> (i%8)) << 7);
639
                        i++;
640
                }
641
 
642
                debug("\tBYTE%3d: 0x%02x\n", i, mybuf[2]);
643
 
644
                /// Finally we can transmmit the command
645
                xferred = usbconn_ftdi_write( conn, mybuf, max_command_size, (postread ? 1 : 0) );
646
                if(xferred != max_command_size)
647
                        return -1;
648
 
649
                // If OK, the update the number of incoming bytes that are being buffered for a posterior read
650
                if(postread)
651
                        recv = recv + 1;
652
        }
653
        debug("\tPOSTREAD: %u bytes\n", recv);
654
 
655
        return recv;
656
}
657
 
658
int cable_ft2232_read_packed_bits(usbconn_t *conn, uint8_t *buf, int packet_len, int bits_per_packet, int offset)
659
{
660
        unsigned char *mybuf;
661
        unsigned char dst_mask;
662
        unsigned char src_mask;
663
        int row_offset;
664
        int dst_row;
665
        int dst_col;
666
        int src_row;
667
        int src_col;
668
        int i;
669
        int r;
670
 
671
        if(packet_len == 0 || bits_per_packet == 0)
672
                return 0;
673
 
674
        mybuf = (unsigned char *) malloc( packet_len );
675
        if((r=usbconn_ftdi_read( conn, mybuf, packet_len )) < 0) {
676
                debug("Read failed\n");
677
                return -1;
678
        }
679
 
680
        if(bits_per_packet < 8) {
681
                for(i=0; i < packet_len; i++){ // rotate bits to the left side
682
//                      debug("[MYDBG] unaligned bits[%d]=%02x\n", i, mybuf[i]);                        
683
                        mybuf[i] = (mybuf[i] >> (8-bits_per_packet));
684
//                      debug("[MYDBG]   aligned bits[%d]=%02x\n", i, mybuf[i]);
685
                }
686
                for(i=offset; i < (packet_len*bits_per_packet+offset); i++) {
687
                        dst_row = i / 8;
688
                        dst_col = i % 8;
689
                        src_row = (i-offset) / bits_per_packet;
690
                        src_col = (i-offset) % bits_per_packet;
691
                        dst_mask = ~(1 << dst_col);
692
                        src_mask = (1 << src_col);
693
//                      debug("[MYDBG] i=%4d dst[%3d][%3d] dst_mask=%02x dst_val=%02x dst_masked=%02x\n", i, dst_row, dst_col, dst_mask, buf[dst_row], (buf[dst_row] & dst_mask));
694
//                      debug("[MYDBG] i=%4d src[%3d][%3d] src_mask=%02x src_val=%02x src_masked=%02x\n", i, src_row, src_col, src_mask, mybuf[src_row], (mybuf[src_row] & src_mask));
695
                        if(dst_col >= src_col)
696
                                buf[dst_row] = (buf[dst_row] & dst_mask) | ((mybuf[src_row] & src_mask) << (dst_col - src_col));
697
                        else
698
                                buf[dst_row] = (buf[dst_row] & dst_mask) | ((mybuf[src_row] & src_mask) >> (dst_col - src_col));
699
                }
700
 
701
        }
702
        else if(bits_per_packet == 8){
703
                row_offset = offset / 8;
704
//              debug("[MYDBG] Row offset=%d\n", row_offset);
705
                memcpy( &(buf[row_offset]), mybuf, packet_len);
706
        }
707
        else {
708
                return -1;
709
        }
710
 
711
//      debug("read_bits()-> %x\n", *buf);
712
        return ((r < 1) ? -1 : 0);
713
}
714
 
715
int cable_ft2232_write_stream(usbconn_t *conn, unsigned char *buf, int len, int postread, int with_tms) {
716
        int len_bytes;
717
        int len_bits;
718
        int len_tms_bits;
719
        unsigned char mybuf;
720
 
721
        len_tms_bits = ((with_tms) ? 1 : 0);
722
        len_bytes = ((len -len_tms_bits) / 8);
723
        len_bits  = ((len -len_tms_bits) % 8);
724
 
725
        debug("[MYDBG] cable_ft2232_write_stream(len=%d postread=%d tms=%d) = %d bytes %dbits %dtms_bits\n", len, postread, with_tms, len_bytes, len_bits, len_tms_bits);
726
 
727
        if(len_bytes > 0)
728
                cable_ft2232_write_bytes(conn, buf, len_bytes, postread);
729
 
730
        if(len_bits > 0)
731
                cable_ft2232_write_bits(conn, &(buf[len_bytes]), len_bits, postread, 0);
732
 
733
        if(len_tms_bits > 0) {
734
                mybuf = (buf[len_bytes] >> len_bits);
735
                cable_ft2232_write_bits(conn, &mybuf, 1, postread, 1);
736
        }
737
 
738
        return 0;
739
}
740
 
741
int cable_ft2232_read_stream(usbconn_t *conn, unsigned char *buf, int len, int with_tms) {
742
        int len_bytes;
743
        int len_bits;
744
        int len_tms_bits;
745
 
746
        len_tms_bits = ((with_tms) ? 1 : 0);
747
        len_bytes = ((len -len_tms_bits) / 8);
748
        len_bits  = ((len -len_tms_bits) % 8);
749
 
750
        debug("[MYDBG] cable_ft2232_read_stream(len=%d tms=%d) = %d bytes %dbits %dtms_bits\n", len, with_tms, len_bytes, len_bits, len_tms_bits);
751
 
752
        if(len_bytes > 0)
753
                cable_ft2232_read_packed_bits(conn, buf, len_bytes, 8, 0);
754
 
755
        if(len_bits > 0)
756
                cable_ft2232_read_packed_bits(conn, buf, 1, len_bits, (len_bytes * 8));
757
 
758
        if(len_tms_bits > 0)
759
                cable_ft2232_read_packed_bits(conn, buf, 1, 1, (len_bits + (len_bytes * 8)));
760
 
761
        return 0;
762
}
763
 
764
 
765
 
766
/// ----------------------------------------------------------------------------------------------
767
/// Advanced Jtag debugger driver interface.
768
/// ----------------------------------------------------------------------------------------------
769
 
770
int cable_ftdi_init() {
771
        int err = APP_ERR_NONE;
772
        int res = 0;
773
        unsigned char  *buf = malloc(10);
774
 
775
        ft2232_device = usbconn_ftdi_connect();
776
 
777
        if((res = usbconn_ftdi_mpsse_open(ft2232_device)) != 0)
778
                err |= APP_ERR_USB;
779
        printf("Open MPSSE mode returned: %s\n", ((res != 0) ? "FAIL" : "OK") );
780
 
781
        ftdi_param_t *params = ft2232_device->params;
782
        //struct ftdi_context * ftdic = params->ftdic;
783
 
784
        buf[0]= SET_BITS_LOW;
785
        buf[1]= 0x00;
786
        buf[2]= 0x0b;
787
        buf[3]= TCK_DIVISOR;
788
        buf[4]= 0x01;
789
        buf[5]= 0x00;
790
        buf[6]= SET_BITS_HIGH;
791
        buf[7]= ~0x04;
792
        buf[8]= 0x04;
793
        buf[9]= SEND_IMMEDIATE;
794
        if(usbconn_ftdi_write( ft2232_device , buf, 10, 0) != 10) {
795
                err |= APP_ERR_USB;
796
                printf("Initial write failed\n");
797
        }
798
 
799
        usbconn_ftdi_flush( params );
800
 
801
        return err;
802
}
803
 
804
int cable_ftdi_close() {
805
        usbconn_ftdi_close(ft2232_device);
806
        usbconn_ftdi_free(ft2232_device);
807
 
808
        return APP_ERR_NONE;
809
}
810
 
811
int cable_ftdi_flush() {
812
        ftdi_param_t *params = ft2232_device->params;
813
        usbconn_ftdi_flush( params );
814
 
815
        return APP_ERR_NONE;
816
}
817
 
818
int cable_ftdi_write_bit(uint8_t packet) {
819
        int err = APP_ERR_NONE;
820
        unsigned char buf;
821
        int tms;
822
 
823
        buf = ((packet & TDO) ? 0x01 : 0x00);
824
        tms = ((packet & TMS) ? 1 : 0);
825
 
826
        if(cable_ft2232_write_stream(ft2232_device, &buf, 1, 0, tms) < 0)
827
                err |= APP_ERR_COMM;
828
 
829
        cable_ftdi_flush();
830
 
831
        return err;
832
 
833
}
834
 
835
int cable_ftdi_read_write_bit(uint8_t packet_out, uint8_t *bit_in) {
836
 
837
        int err = APP_ERR_NONE;
838
        unsigned char buf;
839
        int tms;
840
 
841
        buf = ((packet_out & TDO) ? 0x01 : 0x00);
842
        tms = ((packet_out & TMS) ? 1 : 0);
843
 
844
        if(cable_ft2232_write_stream(ft2232_device, &buf, 1, 1, tms) < 0)
845
                err = APP_ERR_COMM;
846
 
847
        if(cable_ft2232_read_stream(ft2232_device, ((unsigned char *)bit_in), 1, tms) < 0)
848
                err = APP_ERR_COMM;
849
 
850
        return err;
851
}
852
 
853
int cable_ftdi_write_stream(uint32_t *stream, int len_bits, int set_last_bit) {
854
        int err = APP_ERR_NONE;
855
 
856
        if(cable_ft2232_write_stream(ft2232_device, ((unsigned char *)stream), len_bits, 0, set_last_bit) < 0)
857
                err |= APP_ERR_COMM;
858
 
859
        cable_ftdi_flush();
860
 
861
        return err;
862
}
863
 
864
int cable_ftdi_read_stream(uint32_t *outstream, uint32_t *instream, int len_bits, int set_last_bit) {
865
        int err = APP_ERR_NONE;
866
        if(cable_ft2232_write_stream(ft2232_device, ((unsigned char *)outstream), len_bits, 1, set_last_bit) < 0)
867
                err |= APP_ERR_COMM;
868
        if(cable_ft2232_read_stream(ft2232_device, ((unsigned char *)instream), len_bits, set_last_bit) < 0)
869
                err |= APP_ERR_COMM;
870
 
871
        return err;
872
}
873
 
874
int cable_ftdi_opt(int c, char *str) {
875
        fprintf(stderr, "Unknown parameter '%c'\n", c);
876
        return APP_ERR_BAD_PARAM;
877
}
878
 
879
/// ----------------------------------------------------------------------------------------------
880
 

powered by: WebSVN 2.1.0

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