Extended the cable_flush() to take an argument regarding the amount of items to flush

git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@1002 b68d4a1b-bc3d-0410-92ed-d4ac073336b7
master
Kolja Waschk 17 years ago
parent ed000f1423
commit 109ff9d025

@ -3,7 +3,11 @@
* acinclude.m4, configure.ac: Use local copy of AC_PROG_SED macro (renamed
to ACI_PROG_SED) maintain compatibility with older autoconf; fixes
[1890192] - autogen.sh fails on AC_PROG_SED
* include/cable.h, src/tap/cable/usbblaster.c, src/tap/cable/generic.c,
src/tap/cable/generic.h, src/tap/cable/ft2232.c, src/tap/cable.c,
doc/UrJTAG.txt: Extended cable_flush() to take one extra argument
regarding the amount of items to flush (see UrJTAG.txt for doc)
2008-02-09 Arnim Laeuger <arniml@users.sourceforge.net>
* src/tap/cable/ft2232.c (ft2232_transfer_schedule): ensure max number of bytes for

@ -254,11 +254,11 @@ least the following are supported:
NOTE: Not all chips are supported in every possible configuration, there may
be untested combinations of chip type, bus width, ...
* Intel 28FxxxJ3A (28F320J3A, 28F640J3A, 28F128J3A)</para></listitem>
* Intel 28FxxxK3 (28F640K3, 28F128K3, 28F256K3)</para></listitem>
* Intel 28FxxxK18 (28F640K18, 28F128K18, 28F256K18)</para></listitem>
* AMD Am29LV64xD (Am29LV640D, Am29LV641D, Am29LV642D)</para></listitem>
* AMD Am29xx040B (Am29F040B, Am29LV040B)</para></listitem>
* Intel 28FxxxJ3A (28F320J3A, 28F640J3A, 28F128J3A)
* Intel 28FxxxK3 (28F640K3, 28F128K3, 28F256K3)
* Intel 28FxxxK18 (28F640K18, 28F128K18, 28F256K18)
* AMD Am29LV64xD (Am29LV640D, Am29LV641D, Am29LV642D)
* AMD Am29xx040B (Am29F040B, Am29LV040B)
//------------------------------------------------------------------------
@ -905,9 +905,9 @@ Currently the API provides five different functions for performing operations
at the JTAG interface on the low level signal level (using the four signals
TMS, TCK, TDI, and TDO).
* clock() takes values for TMS and TDI output as its parameters, ensures that actual cable signals are set accordingly, and does a 0-1 transition on TCK.
* clock(tms,tdi,n) takes values for TMS and TDI output as its parameters, ensures that actual cable signals are set accordingly, and does a 0-1 transition on TCK (n times)
* get_tdo() returns the current value at the TDO input.
* set_trst() sets the TRST signal and returns the current value.
* set_trst(x) sets the TRST signal and returns the current value.
* get_trst() returns the current value of the TRST signal.
For many JTAG adapters, there's almost no delay when doing alternating clock()
@ -924,6 +924,8 @@ which would limit the transfer rate to 1 kHz. One way to workaround this
is to transmit bits compacted into bytes and chunks of bytes, which is
possible with the transfer() function.
* transfer(in, out)
The transfer() function does a series of TCK pulses, with data for TDI read as
bytes from memory. The bytes are automatically serialized. TMS is set to zero
during transfer()s. Optionally, prior to each bit shifted out to the interface,
@ -969,7 +971,30 @@ second clock(), the sequence can be optimized into the following sequence (if
4. get_tdo_late()
5. get_tdo_late()
The next section explains the queueing mechanism and its limits in detail.
The next sections explain the queueing mechanism and its limits in detail.
===== When flushing occurs ======
The cable_flush() function is used to flush the queue towards the cable. It
takes one additional argument, "how_much", which may be one of
* OPTIONALLY: The cable driver may flush if it's reasonable (e.g. if the
queue has been filled so that some buffer limit for the cable interface
is reached). It would be wise to flush early to keep the queue small, if
there is no point in queueing up more items because the transfer to the
cable would have to be split into smaller chunks anyway. This is used by
UrJTAG immediately after adding items to the queue.
* TO_OUTPUT: The cable driver should at least flush as much so that one
output becomes available in the output queue. If there's already something
in the output queue, this should be interpreted similar to OPTIONALLY. This
is used by UrJTAG immediately before it wants to use that output.
* COMPLETELY: The cable driver has to flush the queue completely. This is
used by UrJTAG immediately before actions that circumvent the queueing
such as calls to the legacy clock/get_tdo functions. It could also be
used by application code to ensure that some action is actually done in
time.
===== JTAG activity queueing =====

@ -35,6 +35,14 @@ typedef struct cable_t cable_t;
typedef struct cable_driver_t cable_driver_t;
typedef enum
{
OPTIONALLY,
TO_OUTPUT,
COMPLETELY
}
cable_flush_amount_t;
struct cable_driver_t {
const char *name;
const char *description;
@ -48,7 +56,7 @@ struct cable_driver_t {
int (*transfer)( cable_t *, int, char *, char * );
int (*set_trst)( cable_t *, int );
int (*get_trst)( cable_t * );
void (*flush)( cable_t * );
void (*flush)( cable_t *, cable_flush_amount_t );
void (*help)( const char * );
};
@ -110,7 +118,7 @@ struct cable_t {
void cable_free( cable_t *cable );
int cable_init( cable_t *cable );
void cable_done( cable_t *cable );
void cable_flush( cable_t *cable );
void cable_flush( cable_t *cable, cable_flush_amount_t );
void cable_clock( cable_t *cable, int tms, int tdi, int n );
int cable_defer_clock( cable_t *cable, int tms, int tdi, int n );
int cable_get_tdo( cable_t *cable );

@ -138,15 +138,15 @@ cable_init( cable_t *cable )
}
void
cable_flush ( cable_t *cable )
cable_flush ( cable_t *cable, cable_flush_amount_t how_much )
{
cable->driver->flush( cable );
cable->driver->flush( cable, how_much );
}
void
cable_done( cable_t *cable )
{
cable_flush( cable );
cable_flush( cable, COMPLETELY );
if( cable->todo.data != NULL)
{
free( cable->todo.data );
@ -296,7 +296,7 @@ cable_purge_queue( cable_queue_info_t *q, int io )
void
cable_clock( cable_t *cable, int tms, int tdi, int n )
{
cable_flush( cable );
cable_flush( cable, COMPLETELY );
cable->driver->clock( cable, tms, tdi, n );
}
@ -309,13 +309,14 @@ cable_defer_clock ( cable_t *cable, int tms, int tdi, int n )
cable->todo.data[i].arg.clock.tms = tms;
cable->todo.data[i].arg.clock.tdi = tdi;
cable->todo.data[i].arg.clock.n = n;
cable_flush( cable, OPTIONALLY );
return 0; /* success */
}
int
cable_get_tdo( cable_t *cable )
{
cable_flush( cable );
cable_flush( cable, COMPLETELY );
return cable->driver->get_tdo( cable );
}
@ -323,7 +324,7 @@ int
cable_get_tdo_late( cable_t *cable )
{
int i;
cable_flush( cable );
cable_flush( cable, TO_OUTPUT );
i = cable_get_queue_item( cable, &(cable->done) );
if( i >= 0 )
{
@ -347,13 +348,14 @@ cable_defer_get_tdo( cable_t *cable )
int i = cable_add_queue_item( cable, &(cable->todo) );
if( i < 0 ) return 1; /* report failure */
cable->todo.data[i].action = CABLE_GET_TDO;
cable_flush( cable, OPTIONALLY );
return 0; /* success */
}
int
cable_set_trst( cable_t *cable, int trst )
{
cable_flush( cable );
cable_flush( cable, COMPLETELY );
return cable->driver->set_trst( cable, trst );
}
@ -364,13 +366,14 @@ cable_defer_set_trst( cable_t *cable, int trst )
if( i < 0 ) return 1; /* report failure */
cable->todo.data[i].action = CABLE_SET_TRST;
cable->todo.data[i].arg.value.trst = trst;
cable_flush( cable, OPTIONALLY );
return 0; /* success */
}
int
cable_get_trst( cable_t *cable )
{
cable_flush( cable );
cable_flush( cable, COMPLETELY );
return cable->driver->get_trst( cable );
}
@ -378,7 +381,7 @@ int
cable_get_trst_late( cable_t *cable )
{
int i;
cable_flush( cable );
cable_flush( cable, TO_OUTPUT );
i = cable_get_queue_item( cable, &(cable->done) );
if( i >= 0 )
{
@ -402,13 +405,14 @@ cable_defer_get_trst( cable_t *cable )
int i = cable_add_queue_item( cable, &(cable->todo) );
if( i < 0 ) return 1; /* report failure */
cable->todo.data[i].action = CABLE_GET_TRST;
cable_flush( cable, OPTIONALLY );
return 0; /* success */
}
int
cable_transfer( cable_t *cable, int len, char *in, char *out )
{
cable_flush( cable );
cable_flush( cable, COMPLETELY );
return cable->driver->transfer( cable, len, in, out );
}
@ -416,7 +420,7 @@ int
cable_transfer_late( cable_t *cable, char *out )
{
int i;
cable_flush( cable );
cable_flush( cable, TO_OUTPUT );
i = cable_get_queue_item( cable, &(cable->done) );
if( i >= 0 && cable->done.data[i].action == CABLE_TRANSFER)
@ -479,6 +483,7 @@ cable_defer_transfer( cable_t *cable, int len, char *in, char *out )
if(in) memcpy(ibuf, in, len);
cable->todo.data[i].arg.transfer.in = ibuf;
cable->todo.data[i].arg.transfer.out = obuf;
cable_flush( cable, OPTIONALLY );
return 0; /* success */
}

@ -676,7 +676,7 @@ ft2232_transfer( cable_t *cable, int len, char *in, char *out )
static void
ft2232_flush( cable_t *cable )
ft2232_flush( cable_t *cable, cable_flush_amount_t how_much )
{
params_t *params = (params_t *)cable->params;

@ -225,13 +225,13 @@ do_one_queued_action( cable_t *cable )
}
void
generic_flush_one_by_one( cable_t *cable )
generic_flush_one_by_one( cable_t *cable, cable_flush_amount_t how_much )
{
while( do_one_queued_action( cable ) );
}
void
generic_flush_using_transfer( cable_t *cable )
generic_flush_using_transfer( cable_t *cable, cable_flush_amount_t how_much )
{
int i, j, n;
char *in, *out;
@ -308,7 +308,7 @@ generic_flush_using_transfer( cable_t *cable )
{
if(in != NULL) free(in);
if(out != NULL) free(out);
generic_flush_one_by_one( cable );
generic_flush_one_by_one( cable, how_much );
break;
};

@ -42,8 +42,8 @@ void generic_cable_free( cable_t *cable );
void generic_done( cable_t *cable );
int generic_transfer( cable_t *cable, int len, char *in, char *out );
int generic_get_trst( cable_t *cable );
void generic_flush_one_by_one( cable_t *cable );
void generic_flush_using_transfer( cable_t *cable );
void generic_flush_one_by_one( cable_t *cable, cable_flush_amount_t hm );
void generic_flush_using_transfer( cable_t *cable, cable_flush_amount_t hm );
void generic_lptcable_help( const char *name );
#endif /* GENERIC_H */

@ -187,7 +187,7 @@ usbblaster_transfer( cable_t *cable, int len, char *in, char *out )
}
static void
usbblaster_flush( cable_t *cable )
usbblaster_flush( cable_t *cable, cable_flush_amount_t how_much )
{
while (cable->todo.num_items > 0)
{

Loading…
Cancel
Save