usb_blaster: Don't unnecessarily go through DR-/IR-Pause

There is no need to pass through DR-/IR-Pause after a scan if we want to
go to DR-/IR-Update. We just have to skip the first step of the path to
the end state because we already did that step when shifting the last
bit.

v2:
 - Fix comments as remarked in review of v1

Change-Id: I3c10f02794b2233f63d2150934e2768430873caa
Signed-off-by: Daniel Glöckner <daniel-gl@gmx.net>
Reviewed-on: http://openocd.zylin.com/4245
Tested-by: jenkins
Reviewed-by: Christopher Head <chead@zaber.com>
Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de>
bscan_tunnel
Daniel Glöckner 2017-10-04 23:07:53 +02:00 committed by Matthias Welwarsky
parent a51ab8ddf6
commit e57f8e12da
1 changed files with 19 additions and 22 deletions

View File

@ -445,6 +445,7 @@ static void ublast_queue_bytes(uint8_t *bytes, int nb_bytes)
* ublast_tms_seq - write a TMS sequence transition to JTAG * ublast_tms_seq - write a TMS sequence transition to JTAG
* @bits: TMS bits to be written (bit0, bit1 .. bitN) * @bits: TMS bits to be written (bit0, bit1 .. bitN)
* @nb_bits: number of TMS bits (between 1 and 8) * @nb_bits: number of TMS bits (between 1 and 8)
* @skip: number of TMS bits to skip at the beginning of the series
* *
* Write a serie of TMS transitions, where each transition consists in : * Write a serie of TMS transitions, where each transition consists in :
* - writing out TCK=0, TMS=<new_state>, TDI=<???> * - writing out TCK=0, TMS=<new_state>, TDI=<???>
@ -452,12 +453,12 @@ static void ublast_queue_bytes(uint8_t *bytes, int nb_bytes)
* The function ensures that at the end of the sequence, the clock (TCK) is put * The function ensures that at the end of the sequence, the clock (TCK) is put
* low. * low.
*/ */
static void ublast_tms_seq(const uint8_t *bits, int nb_bits) static void ublast_tms_seq(const uint8_t *bits, int nb_bits, int skip)
{ {
int i; int i;
DEBUG_JTAG_IO("(bits=%02x..., nb_bits=%d)", bits[0], nb_bits); DEBUG_JTAG_IO("(bits=%02x..., nb_bits=%d)", bits[0], nb_bits);
for (i = 0; i < nb_bits; i++) for (i = skip; i < nb_bits; i++)
ublast_clock_tms((bits[i / 8] >> (i % 8)) & 0x01); ublast_clock_tms((bits[i / 8] >> (i % 8)) & 0x01);
ublast_idle_clock(); ublast_idle_clock();
} }
@ -469,7 +470,7 @@ static void ublast_tms_seq(const uint8_t *bits, int nb_bits)
static void ublast_tms(struct tms_command *cmd) static void ublast_tms(struct tms_command *cmd)
{ {
DEBUG_JTAG_IO("(num_bits=%d)", cmd->num_bits); DEBUG_JTAG_IO("(num_bits=%d)", cmd->num_bits);
ublast_tms_seq(cmd->bits, cmd->num_bits); ublast_tms_seq(cmd->bits, cmd->num_bits, 0);
} }
/** /**
@ -501,11 +502,12 @@ static void ublast_path_move(struct pathmove_command *cmd)
/** /**
* ublast_state_move - move JTAG state to the target state * ublast_state_move - move JTAG state to the target state
* @state: the target state * @state: the target state
* @skip: number of bits to skip at the beginning of the path
* *
* Input the correct TMS sequence to the JTAG TAP so that we end up in the * Input the correct TMS sequence to the JTAG TAP so that we end up in the
* target state. This assumes the current state (tap_get_state()) is correct. * target state. This assumes the current state (tap_get_state()) is correct.
*/ */
static void ublast_state_move(tap_state_t state) static void ublast_state_move(tap_state_t state, int skip)
{ {
uint8_t tms_scan; uint8_t tms_scan;
int tms_len; int tms_len;
@ -516,7 +518,7 @@ static void ublast_state_move(tap_state_t state)
return; return;
tms_scan = tap_get_tms_path(tap_get_state(), state); tms_scan = tap_get_tms_path(tap_get_state(), state);
tms_len = tap_get_tms_path_len(tap_get_state(), state); tms_len = tap_get_tms_path_len(tap_get_state(), state);
ublast_tms_seq(&tms_scan, tms_len); ublast_tms_seq(&tms_scan, tms_len, skip);
tap_set_state(state); tap_set_state(state);
} }
@ -688,9 +690,9 @@ static void ublast_runtest(int cycles, tap_state_t state)
{ {
DEBUG_JTAG_IO("%s(cycles=%i, end_state=%d)", __func__, cycles, state); DEBUG_JTAG_IO("%s(cycles=%i, end_state=%d)", __func__, cycles, state);
ublast_state_move(TAP_IDLE); ublast_state_move(TAP_IDLE, 0);
ublast_queue_tdi(NULL, cycles, SCAN_OUT); ublast_queue_tdi(NULL, cycles, SCAN_OUT);
ublast_state_move(state); ublast_state_move(state, 0);
} }
static void ublast_stableclocks(int cycles) static void ublast_stableclocks(int cycles)
@ -720,9 +722,9 @@ static int ublast_scan(struct scan_command *cmd)
scan_bits = jtag_build_buffer(cmd, &buf); scan_bits = jtag_build_buffer(cmd, &buf);
if (cmd->ir_scan) if (cmd->ir_scan)
ublast_state_move(TAP_IRSHIFT); ublast_state_move(TAP_IRSHIFT, 0);
else else
ublast_state_move(TAP_DRSHIFT); ublast_state_move(TAP_DRSHIFT, 0);
log_buf = hexdump(buf, DIV_ROUND_UP(scan_bits, 8)); log_buf = hexdump(buf, DIV_ROUND_UP(scan_bits, 8));
DEBUG_JTAG_IO("%s(scan=%s, type=%s, bits=%d, buf=[%s], end_state=%d)", __func__, DEBUG_JTAG_IO("%s(scan=%s, type=%s, bits=%d, buf=[%s], end_state=%d)", __func__,
@ -733,20 +735,15 @@ static int ublast_scan(struct scan_command *cmd)
ublast_queue_tdi(buf, scan_bits, type); ublast_queue_tdi(buf, scan_bits, type);
/*
* As our JTAG is in an unstable state (IREXIT1 or DREXIT1), move it
* forward to a stable IRPAUSE or DRPAUSE.
*/
ublast_clock_tms(0);
if (cmd->ir_scan)
tap_set_state(TAP_IRPAUSE);
else
tap_set_state(TAP_DRPAUSE);
ret = jtag_read_buffer(buf, cmd); ret = jtag_read_buffer(buf, cmd);
if (buf) if (buf)
free(buf); free(buf);
ublast_state_move(cmd->end_state); /*
* ublast_queue_tdi sends the last bit with TMS=1. We are therefore
* already in Exit1-DR/IR and have to skip the first step on our way
* to end_state.
*/
ublast_state_move(cmd->end_state, 1);
return ret; return ret;
} }
@ -776,7 +773,7 @@ static void ublast_initial_wipeout(void)
/* /*
* Put JTAG in RESET state (five 1 on TMS) * Put JTAG in RESET state (five 1 on TMS)
*/ */
ublast_tms_seq(&tms_reset, 5); ublast_tms_seq(&tms_reset, 5, 0);
tap_set_state(TAP_RESET); tap_set_state(TAP_RESET);
} }
@ -805,7 +802,7 @@ static int ublast_execute_queue(void)
ublast_stableclocks(cmd->cmd.stableclocks->num_cycles); ublast_stableclocks(cmd->cmd.stableclocks->num_cycles);
break; break;
case JTAG_TLR_RESET: case JTAG_TLR_RESET:
ublast_state_move(cmd->cmd.statemove->end_state); ublast_state_move(cmd->cmd.statemove->end_state, 0);
break; break;
case JTAG_PATHMOVE: case JTAG_PATHMOVE:
ublast_path_move(cmd->cmd.pathmove); ublast_path_move(cmd->cmd.pathmove);