From 1ee93ee5f3a9696d3b9decf7443a6947c7c82e03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnim=20L=C3=A4uger?= Date: Thu, 7 Feb 2008 00:06:48 +0000 Subject: [PATCH] fix problem with send suspend detection in ft2232 driver git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@998 b68d4a1b-bc3d-0410-92ed-d4ac073336b7 --- jtag/ChangeLog | 9 ++++++++ jtag/src/tap/cable/ft2232.c | 39 ++++++++++++++++++++++++----------- jtag/src/tap/parport/ftd2xx.c | 2 +- jtag/src/tap/parport/ftdi.c | 4 +++- 4 files changed, 40 insertions(+), 14 deletions(-) diff --git a/jtag/ChangeLog b/jtag/ChangeLog index 696ae5f5..3f692d55 100644 --- a/jtag/ChangeLog +++ b/jtag/ChangeLog @@ -1,3 +1,12 @@ +2008-02-07 Arnim Laeuger + + * src/tap/cable/ft2232.c (ft2232_connect): check parport driver setting + and set maxrecv accordingly + (send_and_receive): fix problem with send suspend detection + * src/tap/parport/ftdi.c (ftdi_mpsse_open): decreased latency timer + (ftdi_flush_output): return error code from ftdi_write_data + * src/tap/parport/ftd2xx.c (ftd2xx_mpsse_open): decreased latency timer + 2008-02-05 Arnim Laeuger * src/tap/cable/ft2232.c: massive rewrite to support deferred transfers diff --git a/jtag/src/tap/cable/ft2232.c b/jtag/src/tap/cable/ft2232.c index 8e65dd21..df2ff5f5 100644 --- a/jtag/src/tap/cable/ft2232.c +++ b/jtag/src/tap/cable/ft2232.c @@ -39,9 +39,10 @@ /* Maximum chunk to write to parport driver. Larger values might speed up comm, but there's an upper limit - when too many bytes are sent and libftdi doesn't fetch the - returned data in time -> deadlock */ -#define MAXRECV (6 * 64) + when too many bytes are sent and the underlying libftdi or libftd2xx + don't fetch the returned data in time -> deadlock */ +#define MAXRECV_FTD2XX (63 * 64) +#define MAXRECV_FTDI ( 4 * 64) /* Maximum TCK frequency of FT2232 */ #define FT2232_MAX_TCK_FREQ 6000000 @@ -105,6 +106,7 @@ typedef struct { uint32_t to_recv; uint32_t recv_idx; uint8_t *recv_buffer; + uint16_t maxrecv; } params_t; @@ -170,8 +172,7 @@ send_and_receive( cable_t *cable ) if (*send_idx & 0x8000) { uint16_t num_recv = *send_idx & 0x7fff; - if (bytes_recvd + num_recv > MAXRECV) { - puts("Suspend sending"); + if (bytes_to_recv + num_recv > params->maxrecv) { /* suspend sending since we can't handle the receive data of this command */ break; @@ -516,9 +517,9 @@ ft2232_transfer_schedule( cable_t *cable, int len, char *in, char *out ) while (chunkbytes > 0) { int byte_idx; - /* reduce chunkbytes to the maximum about we can receive in one step */ - if (out && chunkbytes > MAXRECV) - chunkbytes = MAXRECV; + /* reduce chunkbytes to the maximum amount we can receive in one step */ + if (out && chunkbytes > params->maxrecv) + chunkbytes = params->maxrecv; /*********************************************************************** * Step 1: @@ -779,14 +780,26 @@ ft2232_flush( cable_t *cable ) static int ft2232_connect( char *params[], cable_t *cable ) { - params_t *cable_params = (params_t *)malloc( sizeof(params_t) ); + params_t *cable_params; parport_t *port; int i; + uint16_t maxrecv; if ( cmd_params( params ) < 3 ) { - printf( _("not enough arguments!\n") ); + puts( _("not enough arguments!") ); return 1; } + + if (strcasecmp( params[1], "ftdi-mpsse" ) == 0) { + maxrecv = MAXRECV_FTDI; + puts( _("FT2232 driver based on libftdi selected.") ); + puts( _("Expect suboptimal performance for large shifts in comparison to libftd2xx.") ); + } else if (strcasecmp( params[1], "ftd2xx-mpsse" ) == 0) { + maxrecv = MAXRECV_FTD2XX; + } else { + puts( _("Wrong parport driver selected!") ); + return 1; + } /* search parport driver list */ for (i = 0; parport_drivers[i]; i++) @@ -806,6 +819,7 @@ ft2232_connect( char *params[], cable_t *cable ) return 3; } + cable_params = (params_t *)malloc( sizeof(params_t) ); if (!cable_params) { free( cable ); return 4; @@ -814,11 +828,12 @@ ft2232_connect( char *params[], cable_t *cable ) cable_params->last_tdo_valid = 0; cable_params->send_buffer_len = 1024; cable_params->to_send = 0; - cable_params->send_buffer = (uint16_t *)malloc( 1024 * sizeof(uint16_t) ); + cable_params->send_buffer = (uint16_t *)malloc( cable_params->send_buffer_len * sizeof(uint16_t) ); cable_params->recv_buffer_len = 1024; cable_params->to_recv = 0; cable_params->recv_idx = 0; - cable_params->recv_buffer = (uint8_t *)malloc( 1024 ); + cable_params->recv_buffer = (uint8_t *)malloc( cable_params->recv_buffer_len ); + cable_params->maxrecv = maxrecv; cable->port = port; cable->params = cable_params; diff --git a/jtag/src/tap/parport/ftd2xx.c b/jtag/src/tap/parport/ftd2xx.c index 6ebf58fd..691f10d2 100644 --- a/jtag/src/tap/parport/ftd2xx.c +++ b/jtag/src/tap/parport/ftd2xx.c @@ -312,7 +312,7 @@ ftd2xx_mpsse_open( parport_t *parport ) FT_Close(fc); return -1; } - if ((status = FT_SetLatencyTimer(fc, 2)) != FT_OK) { + if ((status = FT_SetLatencyTimer(fc, 1)) != FT_OK) { fprintf(stderr, "Can't set latency timer: %li\n", status); FT_Close(fc); return -1; diff --git a/jtag/src/tap/parport/ftdi.c b/jtag/src/tap/parport/ftdi.c index 1579823c..346118cc 100644 --- a/jtag/src/tap/parport/ftdi.c +++ b/jtag/src/tap/parport/ftdi.c @@ -356,7 +356,7 @@ ftdi_mpsse_open( parport_t *parport ) return -1; } - if(ftdi_set_latency_timer(fc, 2) < 0) + if(ftdi_set_latency_timer(fc, 1) < 0) { fprintf (stderr, "Can't set minimum latency: %s\n", ftdi_get_error_string (fc)); @@ -375,6 +375,8 @@ ftdi_flush_output ( ftdi_params_t *p ) int xferred; xferred = ftdi_write_data(p->fc, p->outbuf, p->outcount); + if (xferred < 0) + printf( _("Error from ftdi_write_data(): %d\n"), xferred); if(xferred > 0 && xferred < p->outcount) {