Optimize TMS clocks for FT2232 cables.

git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@1765 b68d4a1b-bc3d-0410-92ed-d4ac073336b7
master
Jie Zhang 15 years ago
parent dcfde97c1d
commit 5c3e634a0e

@ -1,3 +1,11 @@
2010-02-06 Jie Zhang <jie.zhang@analog.com>
* include/urjtag/cable.h (enum action): Add URJ_TAP_CABLE_CLOCK_COMPACT.
* src/tap/cable/generic.c (do_one_queued_action): Handle
URJ_TAP_CABLE_CLOCK_COMPACT to turn off GCC warning.
* src/tap/cable/ft2232.c (ft2232_clock_compact_schedule): New.
(ft2232_flush): Compact consecutive clocks.
2010-02-05 Mike Frysinger <vapier@gentoo.org>
* acinclude.m4 (AS_VAR_APPEND): Fix a few typos.

@ -102,6 +102,7 @@ struct URJ_CABLE_QUEUE
enum
{
URJ_TAP_CABLE_CLOCK,
URJ_TAP_CABLE_CLOCK_COMPACT,
URJ_TAP_CABLE_GET_TDO,
URJ_TAP_CABLE_TRANSFER,
URJ_TAP_CABLE_SET_SIGNAL,

@ -1254,6 +1254,29 @@ ft2232_clock_schedule (urj_cable_t *cable, int tms, int tdi, int n)
}
static void
ft2232_clock_compact_schedule (urj_cable_t *cable, int length, uint8_t byte)
{
params_t *params = (params_t *)cable->params;
urj_tap_cable_cx_cmd_root_t *cmd_root = &(params->cmd_root);
urj_tap_cable_cx_cmd_queue (cmd_root, 0);
/* Clock Data to TMS/CS Pin (no Read) */
urj_tap_cable_cx_cmd_push (cmd_root, MPSSE_WRITE_TMS |
MPSSE_LSB | MPSSE_BITMODE |
MPSSE_WRITE_NEG );
urj_tap_cable_cx_cmd_push (cmd_root, length);
urj_tap_cable_cx_cmd_push (cmd_root, byte);
params->signals &= ~(URJ_POD_CS_TMS | URJ_POD_CS_TDI | URJ_POD_CS_TCK);
if (byte >> length)
params->signals |= URJ_POD_CS_TMS;
if (byte >> 7)
params->signals |= URJ_POD_CS_TDI;
// if (tck) params->signals |= URJ_POD_CS_TCK;
}
static void
ft2232_clock (urj_cable_t *cable, int tms, int tdi, int n)
{
@ -1627,6 +1650,12 @@ ft2232_flush (urj_cable_t *cable, urj_cable_flush_amount_t how_much)
int last_tdo_valid_schedule = params->last_tdo_valid;
int last_tdo_valid_finish = params->last_tdo_valid;
if (cable->todo.num_items == 1
&& cable->todo.data[cable->todo.next_item].action
== URJ_TAP_CABLE_CLOCK_COMPACT
&& how_much != URJ_TAP_CABLE_COMPLETELY)
break;
for (j = i = cable->todo.next_item, n = 0; n < cable->todo.num_items;
n++)
{
@ -1634,12 +1663,68 @@ ft2232_flush (urj_cable_t *cable, urj_cable_flush_amount_t how_much)
switch (cable->todo.data[i].action)
{
case URJ_TAP_CABLE_CLOCK:
ft2232_clock_schedule (cable,
cable->todo.data[i].arg.clock.tms,
cable->todo.data[i].arg.clock.tdi,
cable->todo.data[i].arg.clock.n);
last_tdo_valid_schedule = 0;
break;
case URJ_TAP_CABLE_CLOCK_COMPACT:
{
int tdi = cable->todo.data[i].arg.clock.tdi ? 1 << 7 : 0;
int length = 0;
uint8_t byte = 0;
int tms = 0;
int cn = 0;
if (cable->todo.data[i].action == URJ_TAP_CABLE_CLOCK_COMPACT)
{
length = cable->todo.data[i].arg.clock.n;
byte = cable->todo.data[i].arg.clock.tms;
}
more_cable_clock:
if (cable->todo.data[i].action == URJ_TAP_CABLE_CLOCK)
{
tms = cable->todo.data[i].arg.clock.tms ? 1 : 0;
cn = cable->todo.data[i].arg.clock.n;
}
while (cn > 0)
{
byte |= tms << length;
cn--;
length++;
if (length == 7)
{
ft2232_clock_compact_schedule (cable, 6, byte | tdi);
length = 0;
byte = 0;
}
}
if (n + 1 < cable->todo.num_items
&& cable->todo.data[(i + 1) % cable->todo.max_items].action == URJ_TAP_CABLE_CLOCK
&& (cable->todo.data[(i + 1) % cable->todo.max_items].arg.clock.tdi ? 1 << 7 : 0) == tdi)
{
i++;
if (i >= cable->todo.max_items)
i = 0;
n++;
goto more_cable_clock;
}
if (length)
{
if (n + 1 < cable->todo.num_items
|| how_much == URJ_TAP_CABLE_COMPLETELY)
ft2232_clock_compact_schedule (cable, length - 1, byte | tdi);
else
{
cable->todo.data[i].action = URJ_TAP_CABLE_CLOCK_COMPACT;
cable->todo.data[i].arg.clock.tms = byte;
cable->todo.data[i].arg.clock.n = length;
i--;
if (i == -1)
i = cable->todo.max_items;
}
}
last_tdo_valid_schedule = 0;
break;
}
case URJ_TAP_CABLE_GET_TDO:
if (!last_tdo_valid_schedule)
@ -1697,6 +1782,20 @@ ft2232_flush (urj_cable_t *cable, urj_cable_flush_amount_t how_much)
params->last_tdo_valid = last_tdo_valid_finish = 0;
break;
}
case URJ_TAP_CABLE_CLOCK_COMPACT:
{
post_signals &=
~(URJ_POD_CS_TCK | URJ_POD_CS_TDI | URJ_POD_CS_TMS);
post_signals |=
((cable->todo.data[j].arg.clock.
tms >> cable->todo.data[j].arg.clock.
n) ? URJ_POD_CS_TMS : 0);
post_signals |=
(cable->todo.data[j].arg.clock.
tdi ? URJ_POD_CS_TDI : 0);
params->last_tdo_valid = last_tdo_valid_finish = 0;
break;
}
case URJ_TAP_CABLE_GET_TDO:
{
int tdo;

@ -177,6 +177,8 @@ do_one_queued_action (urj_cable_t *cable)
cable->driver->get_signal (cable,
cable->todo.data[i].arg.value.sig);
break;
case URJ_TAP_CABLE_CLOCK_COMPACT: /* Turn off GCC warning */
break;
}
urj_log (URJ_LOG_LEVEL_DETAIL, "do_one_queued done\n");

Loading…
Cancel
Save