diff --git a/jtag/include/tap.h b/jtag/include/tap.h index 765126d6..75742d00 100644 --- a/jtag/include/tap.h +++ b/jtag/include/tap.h @@ -31,6 +31,8 @@ void tap_reset( chain_t *chain ); void tap_capture_dr( chain_t *chain ); void tap_capture_ir( chain_t *chain ); +void tap_defer_shift_register( chain_t *chain, const tap_register *in, tap_register *out, int exit ); +void tap_shift_register_output( chain_t *chain, const tap_register *in, tap_register *out, int exit ); void tap_shift_register( chain_t *chain, const tap_register *in, tap_register *out, int exit ); #endif /* TAP_H */ diff --git a/jtag/src/tap/chain.c b/jtag/src/tap/chain.c index 64eb0a53..654c9573 100644 --- a/jtag/src/tap/chain.c +++ b/jtag/src/tap/chain.c @@ -178,7 +178,7 @@ chain_shift_data_registers_mode( chain_t *chain, int capture_output, int capture capture_output ? ps->parts[i]->active_instruction->data_register->out : NULL, (i + 1) == ps->len ? exit : EXITMODE_SHIFT ); } -#else +#elif 1 { /* new implementation: combine the data registers of all parts in the chain into one temporary register, @@ -219,6 +219,26 @@ chain_shift_data_registers_mode( chain_t *chain, int capture_output, int capture data_register_free( temp_reg ); } +#else + /* new^2 implementation: split into defer + retrieve part + shift the data register of each part in the chain one by one */ + + for (i = 0; i < ps->len; i++) { + puts("tap_defer_shift_register"); + tap_defer_shift_register( chain, ps->parts[i]->active_instruction->data_register->in, + capture_output ? ps->parts[i]->active_instruction->data_register->out : NULL, + (i + 1) == ps->len ? exit : EXITMODE_SHIFT ); + } + + if(capture_output) + { + for (i = 0; i < ps->len; i++) { + puts("tap_shift_register_output"); + tap_shift_register_output( chain, ps->parts[i]->active_instruction->data_register->in, + ps->parts[i]->active_instruction->data_register->out, + (i + 1) == ps->len ? exit : EXITMODE_SHIFT ); + } + } #endif } diff --git a/jtag/src/tap/tap.c b/jtag/src/tap/tap.c index 9e88d94c..5ba467ef 100644 --- a/jtag/src/tap/tap.c +++ b/jtag/src/tap/tap.c @@ -43,9 +43,9 @@ tap_reset( chain_t *chain ) } void -tap_shift_register( chain_t *chain, const tap_register *in, tap_register *out, int exit ) +tap_defer_shift_register( chain_t *chain, const tap_register *in, tap_register *out, int exit ) { - int i,j; + int i; if (!(tap_state( chain ) & TAPSTAT_SHIFT)) printf( _("%s: Invalid state: %2X\n"), "tap_shift_register", tap_state( chain ) ); @@ -63,7 +63,6 @@ tap_shift_register( chain_t *chain, const tap_register *in, tap_register *out, i else cable_defer_transfer( chain->cable, i, in->data, NULL ); - j = i; for (; i < in->len; i++) { if (out != NULL && (i < out->len)) out->data[i] = cable_defer_get_tdo( chain->cable ); @@ -75,16 +74,35 @@ tap_shift_register( chain_t *chain, const tap_register *in, tap_register *out, i chain_defer_clock( chain, 1, 0, 1 ); /* Update-DR or Update-IR */ chain_defer_clock( chain, 0, 0, 1 ); /* Run-Test/Idle */ } +} +void +tap_shift_register_output( chain_t *chain, const tap_register *in, tap_register *out, int exit ) +{ if(out != NULL) { - /* Asking for the result of the cable transfer actually flushes the queue */ + int j; + + j = in->len; + if(exit) j--; + if(out && out->len < j) j = out->len; + + /* Asking for the result of the cable transfer + * actually flushes the queue */ + (void)cable_transfer_late( chain->cable, out->data ); for (; j < in->len && j < out->len; j++) out->data[j] = cable_get_tdo_late( chain->cable ); } } +void +tap_shift_register( chain_t *chain, const tap_register *in, tap_register *out, int exit ) +{ + tap_defer_shift_register( chain, in, out, exit ); + tap_shift_register_output( chain, in, out, exit ); +} + void tap_capture_dr( chain_t *chain ) {