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:
parent
ebd5afbb0e
commit
9324e6280e
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
1053
src/xsvf/xsvf.c
1053
src/xsvf/xsvf.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue