|
|
|
@ -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;
|
|
|
|
|