Dick Hollenbeck <dick@softplc.com> adds jtag_add_clocks() and implements those in the bitbang and ft2232.c. nearly a full rewrite of the xsvf.c. improved some messaging only affected by _DEBUG_JTAG_IO_

git-svn-id: svn://svn.berlios.de/openocd/trunk@1308 b42882b7-edfa-0310-969c-e2dbd0fdcd60
This commit is contained in:
oharboe 2009-01-09 07:42:45 +00:00
parent ebd5afbb0e
commit 9324e6280e
6 changed files with 1005 additions and 321 deletions

View File

@ -37,6 +37,10 @@
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
static void bitbang_stableclocks(int num_cycles);
bitbang_interface_t *bitbang_interface; bitbang_interface_t *bitbang_interface;
/* DANGER!!!! clock absolutely *MUST* be 0 in idle or reset won't work! /* DANGER!!!! clock absolutely *MUST* be 0 in idle or reset won't work!
@ -61,6 +65,8 @@ bitbang_interface_t *bitbang_interface;
int bitbang_execute_queue(void); int bitbang_execute_queue(void);
/* The bitbang driver leaves the TCK 0 when in idle */ /* The bitbang driver leaves the TCK 0 when in idle */
void bitbang_end_state(enum tap_state state) void bitbang_end_state(enum tap_state state)
@ -153,6 +159,21 @@ void bitbang_runtest(int num_cycles)
bitbang_state_move(); bitbang_state_move();
} }
static void bitbang_stableclocks(int num_cycles)
{
int i;
/* send num_cycles clocks onto the cable */
for (i = 0; i < num_cycles; i++)
{
bitbang_interface->write(1, 0, 0);
bitbang_interface->write(0, 0, 0);
}
}
void bitbang_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size) void bitbang_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size)
{ {
enum tap_state saved_end_state = end_state; enum tap_state saved_end_state = end_state;
@ -247,7 +268,7 @@ int bitbang_execute_queue(void)
{ {
case JTAG_END_STATE: case JTAG_END_STATE:
#ifdef _DEBUG_JTAG_IO_ #ifdef _DEBUG_JTAG_IO_
LOG_DEBUG("end_state: %i", cmd->cmd.end_state->end_state); LOG_DEBUG("end_state: %s", jtag_state_name(cmd->cmd.end_state->end_state) );
#endif #endif
if (cmd->cmd.end_state->end_state != -1) if (cmd->cmd.end_state->end_state != -1)
bitbang_end_state(cmd->cmd.end_state->end_state); bitbang_end_state(cmd->cmd.end_state->end_state);
@ -264,15 +285,20 @@ int bitbang_execute_queue(void)
break; break;
case JTAG_RUNTEST: case JTAG_RUNTEST:
#ifdef _DEBUG_JTAG_IO_ #ifdef _DEBUG_JTAG_IO_
LOG_DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state); LOG_DEBUG("runtest %i cycles, end in %s", cmd->cmd.runtest->num_cycles, jtag_state_name(cmd->cmd.runtest->end_state) );
#endif #endif
if (cmd->cmd.runtest->end_state != -1) if (cmd->cmd.runtest->end_state != -1)
bitbang_end_state(cmd->cmd.runtest->end_state); bitbang_end_state(cmd->cmd.runtest->end_state);
bitbang_runtest(cmd->cmd.runtest->num_cycles); bitbang_runtest(cmd->cmd.runtest->num_cycles);
break; break;
case JTAG_STABLECLOCKS:
bitbang_stableclocks(cmd->cmd.stableclocks->num_cycles);
break;
case JTAG_STATEMOVE: case JTAG_STATEMOVE:
#ifdef _DEBUG_JTAG_IO_ #ifdef _DEBUG_JTAG_IO_
LOG_DEBUG("statemove end in %i", cmd->cmd.statemove->end_state); LOG_DEBUG("statemove end in %s", jtag_state_name(cmd->cmd.statemove->end_state));
#endif #endif
if (cmd->cmd.statemove->end_state != -1) if (cmd->cmd.statemove->end_state != -1)
bitbang_end_state(cmd->cmd.statemove->end_state); bitbang_end_state(cmd->cmd.statemove->end_state);
@ -280,13 +306,14 @@ int bitbang_execute_queue(void)
break; break;
case JTAG_PATHMOVE: case JTAG_PATHMOVE:
#ifdef _DEBUG_JTAG_IO_ #ifdef _DEBUG_JTAG_IO_
LOG_DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]); LOG_DEBUG("pathmove: %i states, end in %s", cmd->cmd.pathmove->num_states,
jtag_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]));
#endif #endif
bitbang_path_move(cmd->cmd.pathmove); bitbang_path_move(cmd->cmd.pathmove);
break; break;
case JTAG_SCAN: case JTAG_SCAN:
#ifdef _DEBUG_JTAG_IO_ #ifdef _DEBUG_JTAG_IO_
LOG_DEBUG("%s scan end in %i", (cmd->cmd.scan->ir_scan) ? "IR" : "DR", cmd->cmd.scan->end_state); LOG_DEBUG("%s scan end in %s", (cmd->cmd.scan->ir_scan) ? "IR" : "DR", jtag_state_name(cmd->cmd.scan->end_state) );
#endif #endif
if (cmd->cmd.scan->end_state != -1) if (cmd->cmd.scan->end_state != -1)
bitbang_end_state(cmd->cmd.scan->end_state); bitbang_end_state(cmd->cmd.scan->end_state);

View File

@ -32,8 +32,13 @@ static tap_state_t dummy_state = TAP_RESET;
static int dummy_clock; /* edge detector */ static int dummy_clock; /* edge detector */
static int clock_count; /* count clocks in any stable state, only stable states */
static tap_state_t tap_state_transition(tap_state_t cur_state, int tms); static tap_state_t tap_state_transition(tap_state_t cur_state, int tms);
static u32 dummy_data;
int dummy_speed(int speed); int dummy_speed(int speed);
int dummy_register_commands(struct command_context_s *cmd_ctx); int dummy_register_commands(struct command_context_s *cmd_ctx);
@ -76,7 +81,9 @@ bitbang_interface_t dummy_bitbang =
int dummy_read(void) int dummy_read(void)
{ {
return 1; int data = 1 & dummy_data;
dummy_data = (dummy_data >> 1) | (1<<31);
return data;
} }
@ -88,9 +95,30 @@ void dummy_write(int tck, int tms, int tdi)
if( tck ) if( tck )
{ {
int old_state = dummy_state; int old_state = dummy_state;
dummy_state = tap_state_transition( dummy_state, tms ); dummy_state = tap_state_transition( old_state, tms );
if( old_state != dummy_state ) if( old_state != dummy_state )
LOG_DEBUG( "dummy_tap=%s", jtag_state_name(dummy_state) ); {
if( clock_count )
{
LOG_DEBUG("dummy_tap: %d stable clocks", clock_count);
clock_count = 0;
}
LOG_DEBUG("dummy_tap: %s", jtag_state_name(dummy_state) );
#if defined(DEBUG)
if(dummy_state == TAP_DRCAPTURE)
dummy_data = 0x01255043;
#endif
}
else
{
/* this is a stable state clock edge, no change of state here,
* simply increment clock_count for subsequent logging
*/
++clock_count;
}
} }
dummy_clock = tck; dummy_clock = tck;
} }
@ -99,8 +127,11 @@ void dummy_write(int tck, int tms, int tdi)
void dummy_reset(int trst, int srst) void dummy_reset(int trst, int srst)
{ {
dummy_clock = 0; dummy_clock = 0;
dummy_state = TAP_RESET;
LOG_DEBUG( "reset to %s", jtag_state_name(dummy_state) ); if (trst || (srst && (jtag_reset_config & RESET_SRST_PULLS_TRST)))
dummy_state = TAP_RESET;
LOG_DEBUG("reset to: %s", jtag_state_name(dummy_state) );
} }
static int dummy_khz(int khz, int *jtag_speed) static int dummy_khz(int khz, int *jtag_speed)

View File

@ -76,6 +76,18 @@ int ft2232_handle_layout_command(struct command_context_s *cmd_ctx, char *cmd, c
int ft2232_handle_vid_pid_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int ft2232_handle_vid_pid_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int ft2232_handle_latency_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int ft2232_handle_latency_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
/**
* Function ft2232_stableclocks
* will send out \a num_cycles on the TCK line while the TAP(s)
* are in a stable state. Calling code must ensure that current state is
* stable, that verification is not done in here.
* @param num_cycles is the count of clocks cycles to send.
* @return int - ERROR_OK or ERROR_JTAG_QUEUE_FAILED
*/
static int ft2232_stableclocks(int num_cycles, jtag_command_t *cmd);
char *ft2232_device_desc = NULL; char *ft2232_device_desc = NULL;
char *ft2232_serial = NULL; char *ft2232_serial = NULL;
char *ft2232_layout = NULL; char *ft2232_layout = NULL;
@ -149,10 +161,15 @@ static FT_HANDLE ftdih = NULL;
static struct ftdi_context ftdic; static struct ftdi_context ftdic;
#endif #endif
static jtag_command_t *first_unsent; /* next command that has to be sent */
static int require_send;
static u8 *ft2232_buffer = NULL; static u8 *ft2232_buffer = NULL;
static int ft2232_buffer_size = 0; static int ft2232_buffer_size = 0;
static int ft2232_read_pointer = 0; static int ft2232_read_pointer = 0;
static int ft2232_expect_read = 0; static int ft2232_expect_read = 0;
#define FT2232_BUFFER_SIZE 131072 #define FT2232_BUFFER_SIZE 131072
#define BUFFER_ADD ft2232_buffer[ft2232_buffer_size++] #define BUFFER_ADD ft2232_buffer[ft2232_buffer_size++]
#define BUFFER_READ ft2232_buffer[ft2232_read_pointer++] #define BUFFER_READ ft2232_buffer[ft2232_read_pointer++]
@ -344,7 +361,7 @@ void ft2232_end_state(enum tap_state state)
void ft2232_read_scan(enum scan_type type, u8* buffer, int scan_size) void ft2232_read_scan(enum scan_type type, u8* buffer, int scan_size)
{ {
int num_bytes = ((scan_size + 7) / 8); int num_bytes = (scan_size + 7) / 8;
int bits_left = scan_size; int bits_left = scan_size;
int cur_byte = 0; int cur_byte = 0;
@ -903,14 +920,14 @@ int ft2232_predict_scan_out(int scan_size, enum scan_type type)
if (type == SCAN_IN) /* only from device to host */ if (type == SCAN_IN) /* only from device to host */
{ {
/* complete bytes */ /* complete bytes */
predicted_size += (CEIL(num_bytes, 65536)) * 3; predicted_size += CEIL(num_bytes, 65536) * 3;
/* remaining bits - 1 (up to 7) */ /* remaining bits - 1 (up to 7) */
predicted_size += ((scan_size - 1) % 8) ? 2 : 0; predicted_size += ((scan_size - 1) % 8) ? 2 : 0;
} }
else /* host to device, or bidirectional */ else /* host to device, or bidirectional */
{ {
/* complete bytes */ /* complete bytes */
predicted_size += num_bytes + (CEIL(num_bytes, 65536)) * 3; predicted_size += num_bytes + CEIL(num_bytes, 65536) * 3;
/* remaining bits -1 (up to 7) */ /* remaining bits -1 (up to 7) */
predicted_size += ((scan_size - 1) % 8) ? 3 : 0; predicted_size += ((scan_size - 1) % 8) ? 3 : 0;
} }
@ -1185,15 +1202,16 @@ void stm32stick_reset(int trst, int srst)
int ft2232_execute_queue() int ft2232_execute_queue()
{ {
jtag_command_t *cmd = jtag_command_queue; /* currently processed command */ jtag_command_t *cmd = jtag_command_queue; /* currently processed command */
jtag_command_t *first_unsent = cmd; /* next command that has to be sent */
u8 *buffer; u8 *buffer;
int scan_size; /* size of IR or DR scan */ int scan_size; /* size of IR or DR scan */
enum scan_type type; enum scan_type type;
int i; int i;
int predicted_size = 0; int predicted_size = 0;
int require_send = 0;
int retval; int retval;
first_unsent = cmd; /* next command that has to be sent */
require_send = 0;
/* return ERROR_OK, unless ft2232_send_and_recv reports a failed check /* return ERROR_OK, unless ft2232_send_and_recv reports a failed check
* that wasn't handled by a caller-provided error handler * that wasn't handled by a caller-provided error handler
*/ */
@ -1214,6 +1232,7 @@ int ft2232_execute_queue()
if (cmd->cmd.end_state->end_state != -1) if (cmd->cmd.end_state->end_state != -1)
ft2232_end_state(cmd->cmd.end_state->end_state); ft2232_end_state(cmd->cmd.end_state->end_state);
break; break;
case JTAG_RESET: case JTAG_RESET:
/* only send the maximum buffer size that FT2232C can handle */ /* only send the maximum buffer size that FT2232C can handle */
predicted_size = 3; predicted_size = 3;
@ -1236,6 +1255,7 @@ int ft2232_execute_queue()
LOG_DEBUG("trst: %i, srst: %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst); LOG_DEBUG("trst: %i, srst: %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
#endif #endif
break; break;
case JTAG_RUNTEST: case JTAG_RUNTEST:
/* only send the maximum buffer size that FT2232C can handle */ /* only send the maximum buffer size that FT2232C can handle */
predicted_size = 0; predicted_size = 0;
@ -1292,9 +1312,10 @@ int ft2232_execute_queue()
} }
require_send = 1; require_send = 1;
#ifdef _DEBUG_JTAG_IO_ #ifdef _DEBUG_JTAG_IO_
LOG_DEBUG("runtest: %i, end in %i", cmd->cmd.runtest->num_cycles, end_state); LOG_DEBUG("runtest: %i, end in %s", cmd->cmd.runtest->num_cycles, jtag_state_name(end_state));
#endif #endif
break; break;
case JTAG_STATEMOVE: case JTAG_STATEMOVE:
/* only send the maximum buffer size that FT2232C can handle */ /* only send the maximum buffer size that FT2232C can handle */
predicted_size = 3; predicted_size = 3;
@ -1317,9 +1338,10 @@ int ft2232_execute_queue()
cur_state = end_state; cur_state = end_state;
require_send = 1; require_send = 1;
#ifdef _DEBUG_JTAG_IO_ #ifdef _DEBUG_JTAG_IO_
LOG_DEBUG("statemove: %i", end_state); LOG_DEBUG("statemove: %s", jtag_state_name(end_state));
#endif #endif
break; break;
case JTAG_PATHMOVE: case JTAG_PATHMOVE:
/* only send the maximum buffer size that FT2232C can handle */ /* only send the maximum buffer size that FT2232C can handle */
predicted_size = 3 * CEIL(cmd->cmd.pathmove->num_states, 7); predicted_size = 3 * CEIL(cmd->cmd.pathmove->num_states, 7);
@ -1333,9 +1355,11 @@ int ft2232_execute_queue()
ft2232_add_pathmove(cmd->cmd.pathmove); ft2232_add_pathmove(cmd->cmd.pathmove);
require_send = 1; require_send = 1;
#ifdef _DEBUG_JTAG_IO_ #ifdef _DEBUG_JTAG_IO_
LOG_DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]); LOG_DEBUG("pathmove: %i states, end in %s", cmd->cmd.pathmove->num_states,
jtag_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]));
#endif #endif
break; break;
case JTAG_SCAN: case JTAG_SCAN:
scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer); scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
type = jtag_scan_type(cmd->cmd.scan); type = jtag_scan_type(cmd->cmd.scan);
@ -1375,18 +1399,45 @@ int ft2232_execute_queue()
if (buffer) if (buffer)
free(buffer); free(buffer);
#ifdef _DEBUG_JTAG_IO_ #ifdef _DEBUG_JTAG_IO_
LOG_DEBUG("%s scan, %i bit, end in %i", (cmd->cmd.scan->ir_scan) ? "IR" : "DR", scan_size, end_state); LOG_DEBUG("%s scan, %i bits, end in %s", (cmd->cmd.scan->ir_scan) ? "IR" : "DR", scan_size,
jtag_state_name(end_state));
#endif #endif
break; break;
case JTAG_SLEEP: case JTAG_SLEEP:
if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK) if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
retval = ERROR_JTAG_QUEUE_FAILED; retval = ERROR_JTAG_QUEUE_FAILED;
first_unsent = cmd->next; first_unsent = cmd->next;
jtag_sleep(cmd->cmd.sleep->us); jtag_sleep(cmd->cmd.sleep->us);
#ifdef _DEBUG_JTAG_IO_ #ifdef _DEBUG_JTAG_IO_
LOG_DEBUG("sleep %i usec", cmd->cmd.sleep->us); LOG_DEBUG("sleep %i usec while in %s", cmd->cmd.sleep->us, jtag_state_name(cur_state));
#endif #endif
break; break;
case JTAG_STABLECLOCKS:
/* "if (tap_move_map[cur_state] != -1)" is of no help when cur_state==TAP_IDLE */
switch(cur_state)
{
case TAP_DRSHIFT:
case TAP_IDLE:
case TAP_RESET:
case TAP_DRPAUSE:
case TAP_IRSHIFT:
case TAP_IRPAUSE:
break; /* above stable states are OK */
default:
LOG_ERROR( "jtag_add_clocks() was called with TAP in non-stable state \"%s\"",
jtag_state_name(cur_state) );
retval = ERROR_JTAG_QUEUE_FAILED;
}
if (ft2232_stableclocks(cmd->cmd.stableclocks->num_cycles, cmd) != ERROR_OK)
retval = ERROR_JTAG_QUEUE_FAILED;
#ifdef _DEBUG_JTAG_IO_
LOG_DEBUG("clocks %i while in %s", cmd->cmd.stableclocks->num_cycles, jtag_state_name(cur_state));
#endif
break;
default: default:
LOG_ERROR("BUG: unknown JTAG command type encountered"); LOG_ERROR("BUG: unknown JTAG command type encountered");
exit(-1); exit(-1);
@ -2279,3 +2330,42 @@ int ft2232_handle_latency_command(struct command_context_s *cmd_ctx, char *cmd,
return ERROR_OK; return ERROR_OK;
} }
static int ft2232_stableclocks(int num_cycles, jtag_command_t *cmd)
{
int retval = 0;
while (num_cycles > 0)
{
/* the command 0x4b, "Clock Data to TMS/CS Pin (no Read)" handles
* at most 7 bits per invocation. Here we invoke it potentially
* several times.
*/
int bitcount_per_command = (num_cycles > 7) ? 7 : num_cycles;
if (ft2232_buffer_size + 3 >= FT2232_BUFFER_SIZE)
{
if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
retval = ERROR_JTAG_QUEUE_FAILED;
first_unsent = cmd;
}
/* command "Clock Data to TMS/CS Pin (no Read)" */
BUFFER_ADD = 0x4b;
/* scan 7 bit */
BUFFER_ADD = bitcount_per_command - 1;
/* TMS data bits are all zeros to stay in the current stable state */
BUFFER_ADD = 0x0;
require_send = 1;
num_cycles -= bitcount_per_command;
}
return retval;
}

View File

@ -79,22 +79,22 @@ int tap_move_map[16] = {
tap_transition_t tap_transitions[16] = tap_transition_t tap_transitions[16] =
{ {
{TAP_RESET, TAP_IDLE}, /* RESET */ {TAP_RESET, TAP_IDLE}, /* RESET */
{TAP_IRSELECT, TAP_DRCAPTURE}, /* DRSELECT */ {TAP_IRSELECT, TAP_DRCAPTURE}, /* DRSELECT */
{TAP_DREXIT1, TAP_DRSHIFT}, /* DRCAPTURE */ {TAP_DREXIT1, TAP_DRSHIFT}, /* DRCAPTURE */
{TAP_DREXIT1, TAP_DRSHIFT}, /* DRSHIFT */ {TAP_DREXIT1, TAP_DRSHIFT}, /* DRSHIFT */
{TAP_DRUPDATE, TAP_DRPAUSE}, /* DREXIT1 */ {TAP_DRUPDATE, TAP_DRPAUSE}, /* DREXIT1 */
{TAP_DREXIT2, TAP_DRPAUSE}, /* DRPAUSE */ {TAP_DREXIT2, TAP_DRPAUSE}, /* DRPAUSE */
{TAP_DRUPDATE, TAP_DRSHIFT}, /* DREXIT2 */ {TAP_DRUPDATE, TAP_DRSHIFT}, /* DREXIT2 */
{TAP_DRSELECT, TAP_IDLE}, /* DRUPDATE */ {TAP_DRSELECT, TAP_IDLE}, /* DRUPDATE */
{TAP_DRSELECT, TAP_IDLE}, /* IDLE */ {TAP_DRSELECT, TAP_IDLE}, /* IDLE */
{TAP_RESET, TAP_IRCAPTURE}, /* IRSELECT */ {TAP_RESET, TAP_IRCAPTURE}, /* IRSELECT */
{TAP_IREXIT1, TAP_IRSHIFT}, /* IRCAPTURE */ {TAP_IREXIT1, TAP_IRSHIFT}, /* IRCAPTURE */
{TAP_IREXIT1, TAP_IRSHIFT}, /* IRSHIFT */ {TAP_IREXIT1, TAP_IRSHIFT}, /* IRSHIFT */
{TAP_IRUPDATE, TAP_IRPAUSE}, /* IREXIT1 */ {TAP_IRUPDATE, TAP_IRPAUSE}, /* IREXIT1 */
{TAP_IREXIT2, TAP_IRPAUSE}, /* IRPAUSE */ {TAP_IREXIT2, TAP_IRPAUSE}, /* IRPAUSE */
{TAP_IRUPDATE, TAP_IRSHIFT}, /* IREXIT2 */ {TAP_IRUPDATE, TAP_IRSHIFT}, /* IREXIT2 */
{TAP_DRSELECT, TAP_IDLE} /* IRUPDATE */ {TAP_DRSELECT, TAP_IDLE} /* IRUPDATE */
}; };
char* jtag_event_strings[] = char* jtag_event_strings[] =
@ -983,7 +983,6 @@ int MINIDRIVER(interface_jtag_add_tlr)()
(*last_cmd)->cmd.statemove = cmd_queue_alloc(sizeof(statemove_command_t)); (*last_cmd)->cmd.statemove = cmd_queue_alloc(sizeof(statemove_command_t));
(*last_cmd)->cmd.statemove->end_state = state; (*last_cmd)->cmd.statemove->end_state = state;
return ERROR_OK; return ERROR_OK;
} }
@ -1074,6 +1073,33 @@ void jtag_add_runtest(int num_cycles, enum tap_state state)
jtag_error=retval; jtag_error=retval;
} }
int MINIDRIVER(interface_jtag_add_clocks)( int num_cycles )
{
jtag_command_t **last_cmd = jtag_get_last_command_p();
/* allocate memory for a new list member */
*last_cmd = cmd_queue_alloc(sizeof(jtag_command_t));
(*last_cmd)->next = NULL;
last_comand_pointer = &((*last_cmd)->next);
(*last_cmd)->type = JTAG_STABLECLOCKS;
(*last_cmd)->cmd.stableclocks = cmd_queue_alloc(sizeof(stableclocks_command_t));
(*last_cmd)->cmd.stableclocks->num_cycles = num_cycles;
return ERROR_OK;
}
void jtag_add_clocks( int num_cycles )
{
int retval;
jtag_prelude1();
retval=interface_jtag_add_clocks(num_cycles);
if (retval!=ERROR_OK)
jtag_error=retval;
}
void jtag_add_reset(int req_tlr_or_trst, int req_srst) void jtag_add_reset(int req_tlr_or_trst, int req_srst)
{ {
int trst_with_tlr = 0; int trst_with_tlr = 0;
@ -1252,6 +1278,8 @@ int jtag_build_buffer(scan_command_t *cmd, u8 **buffer)
bit_count = 0; bit_count = 0;
LOG_DEBUG("num_fields: %i",cmd->num_fields);
for (i = 0; i < cmd->num_fields; i++) for (i = 0; i < cmd->num_fields; i++)
{ {
if (cmd->fields[i].out_value) if (cmd->fields[i].out_value)
@ -1261,12 +1289,13 @@ int jtag_build_buffer(scan_command_t *cmd, u8 **buffer)
#endif #endif
buf_set_buf(cmd->fields[i].out_value, 0, *buffer, bit_count, cmd->fields[i].num_bits); buf_set_buf(cmd->fields[i].out_value, 0, *buffer, bit_count, cmd->fields[i].num_bits);
#ifdef _DEBUG_JTAG_IO_ #ifdef _DEBUG_JTAG_IO_
LOG_DEBUG("fields[%i].out_value: 0x%s", i, char_buf); LOG_DEBUG("fields[%i].out_value[%i]: 0x%s", i, cmd->fields[i].num_bits, char_buf);
free(char_buf); free(char_buf);
#endif #endif
} }
bit_count += cmd->fields[i].num_bits; bit_count += cmd->fields[i].num_bits;
LOG_DEBUG("bit_count totalling: %i", bit_count );
} }
return bit_count; return bit_count;
@ -1292,10 +1321,8 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
u8 *captured = buf_set_buf(buffer, bit_count, malloc(CEIL(num_bits, 8)), 0, num_bits); u8 *captured = buf_set_buf(buffer, bit_count, malloc(CEIL(num_bits, 8)), 0, num_bits);
#ifdef _DEBUG_JTAG_IO_ #ifdef _DEBUG_JTAG_IO_
char *char_buf; char *char_buf = buf_to_str(captured, (num_bits > 64) ? 64 : num_bits, 16);
LOG_DEBUG("fields[%i].in_value[%i]: 0x%s", i, num_bits, char_buf);
char_buf = buf_to_str(captured, (num_bits > 64) ? 64 : num_bits, 16);
LOG_DEBUG("fields[%i].in_value: 0x%s", i, char_buf);
free(char_buf); free(char_buf);
#endif #endif

View File

@ -29,6 +29,7 @@
#include "command.h" #include "command.h"
#if 0 #if 0
#define _DEBUG_JTAG_IO_ #define _DEBUG_JTAG_IO_
#endif #endif
@ -112,6 +113,13 @@ typedef struct runtest_command_s
enum tap_state end_state; /* TAP state in which JTAG commands should finish */ enum tap_state end_state; /* TAP state in which JTAG commands should finish */
} runtest_command_t; } runtest_command_t;
typedef struct stableclocks_command_s
{
int num_cycles; /* number of clock cycles that should be sent */
} stableclocks_command_t;
typedef struct reset_command_s typedef struct reset_command_s
{ {
int trst; /* trst/srst 0: deassert, 1: assert, -1: don't change */ int trst; /* trst/srst 0: deassert, 1: assert, -1: don't change */
@ -134,6 +142,7 @@ typedef union jtag_command_container_u
statemove_command_t *statemove; statemove_command_t *statemove;
pathmove_command_t *pathmove; pathmove_command_t *pathmove;
runtest_command_t *runtest; runtest_command_t *runtest;
stableclocks_command_t *stableclocks;
reset_command_t *reset; reset_command_t *reset;
end_state_command_t *end_state; end_state_command_t *end_state;
sleep_command_t *sleep; sleep_command_t *sleep;
@ -144,7 +153,8 @@ enum jtag_command_type
JTAG_SCAN = 1, JTAG_SCAN = 1,
JTAG_STATEMOVE = 2, JTAG_RUNTEST = 3, JTAG_STATEMOVE = 2, JTAG_RUNTEST = 3,
JTAG_RESET = 4, JTAG_END_STATE = 5, JTAG_RESET = 4, JTAG_END_STATE = 5,
JTAG_PATHMOVE = 6, JTAG_SLEEP = 7 JTAG_PATHMOVE = 6, JTAG_SLEEP = 7,
JTAG_STABLECLOCKS = 8
}; };
typedef struct jtag_command_s typedef struct jtag_command_s
@ -434,6 +444,16 @@ extern int interface_jtag_add_end_state(enum tap_state endstate);
extern void jtag_add_sleep(u32 us); extern void jtag_add_sleep(u32 us);
extern int interface_jtag_add_sleep(u32 us); extern int interface_jtag_add_sleep(u32 us);
/**
* Function jtag_add_stable_clocks
* first checks that the state in which the clocks are to be issued is
* stable, then queues up clock_count clocks for transmission.
*/
void jtag_add_clocks( int num_cycles );
int interface_jtag_add_clocks( int num_cycles );
/* /*
* For software FIFO implementations, the queued commands can be executed * For software FIFO implementations, the queued commands can be executed
* during this call or earlier. A sw queue might decide to push out * during this call or earlier. A sw queue might decide to push out

File diff suppressed because it is too large Load Diff