#include "config.h"
#endif
+#include "replacements.h"
+
#if IS_CYGWIN == 1
#include "windows.h"
#endif
-#include "replacements.h"
-
/* project specific includes */
#include "log.h"
#include "types.h"
#include <ftdi.h>
#endif
-/* enable this to debug io latency
- */
-#if 0
-#define _DEBUG_USB_IO_
-#endif
-
-/* enable this to debug communication
- */
-#if 0
-#define _DEBUG_USB_COMMS_
-#endif
-
-int ft2232_execute_queue(void);
+static int ft2232_execute_queue(void);
-int ft2232_speed(int speed);
-int ft2232_speed_div(int speed, int* khz);
-int ft2232_khz(int khz, int* jtag_speed);
-int ft2232_register_commands(struct command_context_s* cmd_ctx);
-int ft2232_init(void);
-int ft2232_quit(void);
+static int ft2232_speed(int speed);
+static int ft2232_speed_div(int speed, int* khz);
+static int ft2232_khz(int khz, int* jtag_speed);
+static int ft2232_register_commands(struct command_context_s* cmd_ctx);
+static int ft2232_init(void);
+static int ft2232_quit(void);
-int ft2232_handle_device_desc_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc);
-int ft2232_handle_serial_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc);
-int ft2232_handle_layout_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);
+static int ft2232_handle_device_desc_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc);
+static int ft2232_handle_serial_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc);
+static int ft2232_handle_layout_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc);
+static int ft2232_handle_vid_pid_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc);
+static int ft2232_handle_latency_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc);
/**
static int ft2232_stableclocks(int num_cycles, jtag_command_t* cmd);
-char * ft2232_device_desc_A = NULL;
-char* ft2232_device_desc = NULL;
-char* ft2232_serial = NULL;
-char* ft2232_layout = NULL;
-unsigned char ft2232_latency = 2;
+static char * ft2232_device_desc_A = NULL;
+static char* ft2232_device_desc = NULL;
+static char* ft2232_serial = NULL;
+static char* ft2232_layout = NULL;
+static unsigned char ft2232_latency = 2;
#define MAX_USB_IDS 8
/* vid = pid = 0 marks the end of the list */
} ft2232_layout_t;
/* init procedures for supported layouts */
-int usbjtag_init(void);
-int jtagkey_init(void);
-int olimex_jtag_init(void);
-int flyswatter_init(void);
-int turtle_init(void);
-int comstick_init(void);
-int stm32stick_init(void);
-int axm0432_jtag_init(void);
-int sheevaplug_init(void);
+static int usbjtag_init(void);
+static int jtagkey_init(void);
+static int olimex_jtag_init(void);
+static int flyswatter_init(void);
+static int turtle_init(void);
+static int comstick_init(void);
+static int stm32stick_init(void);
+static int axm0432_jtag_init(void);
+static int sheevaplug_init(void);
+static int icebear_jtag_init(void);
/* reset procedures for supported layouts */
-void usbjtag_reset(int trst, int srst);
-void jtagkey_reset(int trst, int srst);
-void olimex_jtag_reset(int trst, int srst);
-void flyswatter_reset(int trst, int srst);
-void turtle_reset(int trst, int srst);
-void comstick_reset(int trst, int srst);
-void stm32stick_reset(int trst, int srst);
-void axm0432_jtag_reset(int trst, int srst);
-void sheevaplug_reset(int trst, int srst);
+static void usbjtag_reset(int trst, int srst);
+static void jtagkey_reset(int trst, int srst);
+static void olimex_jtag_reset(int trst, int srst);
+static void flyswatter_reset(int trst, int srst);
+static void turtle_reset(int trst, int srst);
+static void comstick_reset(int trst, int srst);
+static void stm32stick_reset(int trst, int srst);
+static void axm0432_jtag_reset(int trst, int srst);
+static void sheevaplug_reset(int trst, int srst);
+static void icebear_jtag_reset(int trst, int srst);
/* blink procedures for layouts that support a blinking led */
-void olimex_jtag_blink(void);
-void flyswatter_jtag_blink(void);
-void turtle_jtag_blink(void);
+static void olimex_jtag_blink(void);
+static void flyswatter_jtag_blink(void);
+static void turtle_jtag_blink(void);
ft2232_layout_t ft2232_layouts[] =
{
{ "stm32stick", stm32stick_init, stm32stick_reset, NULL },
{ "axm0432_jtag", axm0432_jtag_init, axm0432_jtag_reset, NULL },
{"sheevaplug", sheevaplug_init, sheevaplug_reset, NULL },
- { NULL, NULL, NULL },
+ { "icebear", icebear_jtag_init, icebear_jtag_reset, NULL },
+ { NULL, NULL, NULL, NULL },
};
static u8 nTRST, nTRSTnOE, nSRST, nSRSTnOE;
.quit = ft2232_quit,
};
-int ft2232_write(u8* buf, int size, u32* bytes_written)
+static int ft2232_write(u8* buf, int size, u32* bytes_written)
{
#if BUILD_FT2232_FTD2XX == 1
FT_STATUS status;
}
-int ft2232_read(u8* buf, int size, u32* bytes_read)
+static int ft2232_read(u8* buf, u32 size, u32* bytes_read)
{
#if BUILD_FT2232_FTD2XX == 1
DWORD dw_bytes_read;
}
-int ft2232_speed(int speed)
+static int ft2232_speed(int speed)
{
u8 buf[3];
int retval;
}
-int ft2232_speed_div(int speed, int* khz)
+static int ft2232_speed_div(int speed, int* khz)
{
/* Take a look in the FT2232 manual,
* AN2232C-01 Command Processor for
}
-int ft2232_khz(int khz, int* jtag_speed)
+static int ft2232_khz(int khz, int* jtag_speed)
{
if (khz==0)
{
}
-int ft2232_register_commands(struct command_context_s* cmd_ctx)
+static int ft2232_register_commands(struct command_context_s* cmd_ctx)
{
register_command(cmd_ctx, NULL, "ft2232_device_desc", ft2232_handle_device_desc_command,
COMMAND_CONFIG, "the USB device description of the FTDI FT2232 device");
}
-void ft2232_read_scan(enum scan_type type, u8* buffer, int scan_size)
+static void ft2232_read_scan(enum scan_type type, u8* buffer, int scan_size)
{
int num_bytes = (scan_size + 7) / 8;
int bits_left = scan_size;
}
-void ft2232_debug_dump_buffer(void)
+static void ft2232_debug_dump_buffer(void)
{
int i;
char line[256];
}
-int ft2232_send_and_recv(jtag_command_t* first, jtag_command_t* last)
+static int ft2232_send_and_recv(jtag_command_t* first, jtag_command_t* last)
{
jtag_command_t* cmd;
u8* buffer;
int scan_size;
enum scan_type type;
int retval;
- u32 bytes_written;
- u32 bytes_read;
+ u32 bytes_written=0;
+ u32 bytes_read=0;
#ifdef _DEBUG_USB_IO_
struct timeval start, inter, inter2, end;
timeval_subtract(&d_inter2, &inter2, &start);
timeval_subtract(&d_end, &end, &start);
- LOG_INFO("inter: %i.%06i, inter2: %i.%06i end: %i.%06i", d_inter.tv_sec, d_inter.tv_usec, d_inter2.tv_sec,
- d_inter2.tv_usec, d_end.tv_sec,
- d_end.tv_usec);
+ LOG_INFO("inter: %u.%06u, inter2: %u.%06u end: %u.%06u",
+ (unsigned)d_inter.tv_sec, (unsigned)d_inter.tv_usec,
+ (unsigned)d_inter2.tv_sec, (unsigned)d_inter2.tv_usec,
+ (unsigned)d_end.tv_sec, (unsigned)d_end.tv_usec);
#endif
ft2232_buffer_size = bytes_read;
}
-void ft2232_add_pathmove(pathmove_command_t* cmd)
+static void ft2232_add_pathmove(pathmove_command_t* cmd)
{
int num_states = cmd->num_states;
int state_count = 0;
}
-int ft2232_large_scan(scan_command_t* cmd, enum scan_type type, u8* buffer, int scan_size)
+static int ft2232_large_scan(scan_command_t* cmd, enum scan_type type, u8* buffer, int scan_size)
{
int num_bytes = (scan_size + 7) / 8;
int bits_left = scan_size;
}
-int ft2232_predict_scan_out(int scan_size, enum scan_type type)
+static int ft2232_predict_scan_out(int scan_size, enum scan_type type)
{
int predicted_size = 3;
int num_bytes = (scan_size - 1) / 8;
}
-int ft2232_predict_scan_in(int scan_size, enum scan_type type)
+static int ft2232_predict_scan_in(int scan_size, enum scan_type type)
{
int predicted_size = 0;
}
-void usbjtag_reset(int trst, int srst)
+static void usbjtag_reset(int trst, int srst)
{
if (trst == 1)
{
}
-void jtagkey_reset(int trst, int srst)
+static void jtagkey_reset(int trst, int srst)
{
if (trst == 1)
{
}
-void olimex_jtag_reset(int trst, int srst)
+static void olimex_jtag_reset(int trst, int srst)
{
if (trst == 1)
{
}
-void axm0432_jtag_reset(int trst, int srst)
+static void axm0432_jtag_reset(int trst, int srst)
{
if (trst == 1)
{
}
-void flyswatter_reset(int trst, int srst)
+static void flyswatter_reset(int trst, int srst)
{
if (trst == 1)
{
}
-void turtle_reset(int trst, int srst)
+static void turtle_reset(int trst, int srst)
{
trst = trst;
}
-void comstick_reset(int trst, int srst)
+static void comstick_reset(int trst, int srst)
{
if (trst == 1)
{
}
-void stm32stick_reset(int trst, int srst)
+static void stm32stick_reset(int trst, int srst)
{
if (trst == 1)
{
-void sheevaplug_reset(int trst, int srst)
+static void sheevaplug_reset(int trst, int srst)
{
if (trst == 1)
high_output &= ~nTRST;
LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction);
}
-int ft2232_execute_queue()
+static int ft2232_execute_end_state(jtag_command_t *cmd)
{
- jtag_command_t* cmd = jtag_command_queue; /* currently processed command */
- u8* buffer;
- int scan_size; /* size of IR or DR scan */
- enum scan_type type;
- int i;
- int predicted_size = 0;
- int retval;
+ int retval;
+ retval = ERROR_OK;
- first_unsent = cmd; /* next command that has to be sent */
- require_send = 0;
+ DEBUG_JTAG_IO("end_state: %i", cmd->cmd.end_state->end_state);
- /* return ERROR_OK, unless ft2232_send_and_recv reports a failed check
- * that wasn't handled by a caller-provided error handler
- */
- retval = ERROR_OK;
+ if (cmd->cmd.end_state->end_state != TAP_INVALID)
+ ft2232_end_state(cmd->cmd.end_state->end_state);
- ft2232_buffer_size = 0;
- ft2232_expect_read = 0;
+ return retval;
+}
- /* blink, if the current layout has that feature */
- if (layout->blink)
- layout->blink();
- while (cmd)
+static int ft2232_execute_runtest(jtag_command_t *cmd)
+{
+ int retval;
+ int i;
+ int predicted_size = 0;
+ retval = ERROR_OK;
+
+ DEBUG_JTAG_IO("runtest %i cycles, end in %i",
+ cmd->cmd.runtest->num_cycles,
+ cmd->cmd.runtest->end_state);
+ /* only send the maximum buffer size that FT2232C can handle */
+ predicted_size = 0;
+ if (tap_get_state() != TAP_IDLE)
+ predicted_size += 3;
+ predicted_size += 3 * CEIL(cmd->cmd.runtest->num_cycles, 7);
+ if ( (cmd->cmd.runtest->end_state != TAP_INVALID) && (cmd->cmd.runtest->end_state != TAP_IDLE) )
+ predicted_size += 3;
+ if ( (cmd->cmd.runtest->end_state == TAP_INVALID) && (tap_get_end_state() != TAP_IDLE) )
+ predicted_size += 3;
+ if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
{
- switch (cmd->type)
- {
- case JTAG_END_STATE:
- if (cmd->cmd.end_state->end_state != -1)
- ft2232_end_state(cmd->cmd.end_state->end_state);
- break;
+ if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
+ retval = ERROR_JTAG_QUEUE_FAILED;
+ require_send = 0;
+ first_unsent = cmd;
+ }
+ if (tap_get_state() != TAP_IDLE)
+ {
+ /* command "Clock Data to TMS/CS Pin (no Read)" */
+ BUFFER_ADD = 0x4b;
+ BUFFER_ADD = 0x6; /* scan 7 bits */
- case JTAG_RESET:
- /* only send the maximum buffer size that FT2232C can handle */
- predicted_size = 3;
- if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
- {
- if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
- retval = ERROR_JTAG_QUEUE_FAILED;
- require_send = 0;
- first_unsent = cmd;
- }
+ /* TMS data bits */
+ BUFFER_ADD = tap_get_tms_path(tap_get_state(), TAP_IDLE);
+ tap_set_state(TAP_IDLE);
+ require_send = 1;
+ }
+ i = cmd->cmd.runtest->num_cycles;
+ while (i > 0)
+ {
+ /* command "Clock Data to TMS/CS Pin (no Read)" */
+ BUFFER_ADD = 0x4b;
- if ( (cmd->cmd.reset->trst == 1) || ( cmd->cmd.reset->srst && (jtag_reset_config & RESET_SRST_PULLS_TRST) ) )
- {
- tap_set_state(TAP_RESET);
- }
- layout->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
- require_send = 1;
+ /* scan 7 bits */
+ BUFFER_ADD = (i > 7) ? 6 : (i - 1);
+ /* TMS data bits */
+ BUFFER_ADD = 0x0;
+ tap_set_state(TAP_IDLE);
+ i -= (i > 7) ? 7 : i;
+ /* LOG_DEBUG("added TMS scan (no read)"); */
+ }
+
+ if (cmd->cmd.runtest->end_state != TAP_INVALID)
+ ft2232_end_state(cmd->cmd.runtest->end_state);
+
+ if ( tap_get_state() != tap_get_end_state() )
+ {
+ /* command "Clock Data to TMS/CS Pin (no Read)" */
+ BUFFER_ADD = 0x4b;
+ /* scan 7 bit */
+ BUFFER_ADD = 0x6;
+ /* TMS data bits */
+ BUFFER_ADD = tap_get_tms_path( tap_get_state(), tap_get_end_state() );
+ tap_set_state( tap_get_end_state() );
+ /* LOG_DEBUG("added TMS scan (no read)"); */
+ }
+ require_send = 1;
#ifdef _DEBUG_JTAG_IO_
- LOG_DEBUG("trst: %i, srst: %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
+ LOG_DEBUG( "runtest: %i, end in %s", cmd->cmd.runtest->num_cycles, tap_state_name( tap_get_end_state() ) );
#endif
- break;
- case JTAG_RUNTEST:
- /* only send the maximum buffer size that FT2232C can handle */
- predicted_size = 0;
- if (tap_get_state() != TAP_IDLE)
- predicted_size += 3;
- predicted_size += 3 * CEIL(cmd->cmd.runtest->num_cycles, 7);
- if ( (cmd->cmd.runtest->end_state != -1) && (cmd->cmd.runtest->end_state != TAP_IDLE) )
- predicted_size += 3;
- if ( (cmd->cmd.runtest->end_state == -1) && (tap_get_end_state() != TAP_IDLE) )
- predicted_size += 3;
- if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
- {
- if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
- retval = ERROR_JTAG_QUEUE_FAILED;
- require_send = 0;
- first_unsent = cmd;
- }
- if (tap_get_state() != TAP_IDLE)
- {
- /* command "Clock Data to TMS/CS Pin (no Read)" */
- BUFFER_ADD = 0x4b;
- BUFFER_ADD = 0x6; /* scan 7 bits */
-
- /* TMS data bits */
- BUFFER_ADD = tap_get_tms_path(tap_get_state(), TAP_IDLE);
- tap_set_state(TAP_IDLE);
- require_send = 1;
- }
- i = cmd->cmd.runtest->num_cycles;
- while (i > 0)
- {
- /* command "Clock Data to TMS/CS Pin (no Read)" */
- BUFFER_ADD = 0x4b;
+ return retval;
+}
- /* scan 7 bits */
- BUFFER_ADD = (i > 7) ? 6 : (i - 1);
+static int ft2232_execute_statemove(jtag_command_t *cmd)
+{
+ int retval;
+ int predicted_size = 0;
+ retval = ERROR_OK;
- /* TMS data bits */
- BUFFER_ADD = 0x0;
- tap_set_state(TAP_IDLE);
- i -= (i > 7) ? 7 : i;
- /* LOG_DEBUG("added TMS scan (no read)"); */
- }
+ DEBUG_JTAG_IO("statemove end in %i", cmd->cmd.statemove->end_state);
- if (cmd->cmd.runtest->end_state != -1)
- ft2232_end_state(cmd->cmd.runtest->end_state);
+ /* only send the maximum buffer size that FT2232C can handle */
+ predicted_size = 3;
+ if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
+ {
+ if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
+ retval = ERROR_JTAG_QUEUE_FAILED;
+ require_send = 0;
+ first_unsent = cmd;
+ }
+ if (cmd->cmd.statemove->end_state != TAP_INVALID)
+ ft2232_end_state(cmd->cmd.statemove->end_state);
- if ( tap_get_state() != tap_get_end_state() )
- {
- /* command "Clock Data to TMS/CS Pin (no Read)" */
- BUFFER_ADD = 0x4b;
- /* scan 7 bit */
- BUFFER_ADD = 0x6;
- /* TMS data bits */
- BUFFER_ADD = tap_get_tms_path( tap_get_state(), tap_get_end_state() );
- tap_set_state( tap_get_end_state() );
- /* LOG_DEBUG("added TMS scan (no read)"); */
- }
- require_send = 1;
-#ifdef _DEBUG_JTAG_IO_
- LOG_DEBUG( "runtest: %i, end in %s", cmd->cmd.runtest->num_cycles, tap_state_name( tap_get_end_state() ) );
-#endif
- break;
+ /* command "Clock Data to TMS/CS Pin (no Read)" */
+ BUFFER_ADD = 0x4b;
- case JTAG_STATEMOVE:
- /* only send the maximum buffer size that FT2232C can handle */
- predicted_size = 3;
- if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
- {
- if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
- retval = ERROR_JTAG_QUEUE_FAILED;
- require_send = 0;
- first_unsent = cmd;
- }
- if (cmd->cmd.statemove->end_state != -1)
- ft2232_end_state(cmd->cmd.statemove->end_state);
+ BUFFER_ADD = 0x6; /* scan 7 bits */
- /* command "Clock Data to TMS/CS Pin (no Read)" */
- BUFFER_ADD = 0x4b;
+ /* TMS data bits */
+ BUFFER_ADD = tap_get_tms_path( tap_get_state(), tap_get_end_state() );
+ /* LOG_DEBUG("added TMS scan (no read)"); */
+ tap_set_state( tap_get_end_state() );
+ require_send = 1;
+#ifdef _DEBUG_JTAG_IO_
+ LOG_DEBUG( "statemove: %s", tap_state_name( tap_get_end_state() ) );
+#endif
+
+ return retval;
+}
- BUFFER_ADD = 0x6; /* scan 7 bits */
+static int ft2232_execute_pathmove(jtag_command_t *cmd)
+{
+ int retval;
+ int predicted_size = 0;
+ retval = ERROR_OK;
- /* TMS data bits */
- BUFFER_ADD = tap_get_tms_path( tap_get_state(), tap_get_end_state() );
- /* LOG_DEBUG("added TMS scan (no read)"); */
- tap_set_state( tap_get_end_state() );
- require_send = 1;
+ DEBUG_JTAG_IO("pathmove: %i states, end in %i",
+ cmd->cmd.pathmove->num_states,
+ cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
+ /* only send the maximum buffer size that FT2232C can handle */
+ predicted_size = 3 * CEIL(cmd->cmd.pathmove->num_states, 7);
+ if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
+ {
+ if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
+ retval = ERROR_JTAG_QUEUE_FAILED;
+ require_send = 0;
+ first_unsent = cmd;
+ }
+ ft2232_add_pathmove(cmd->cmd.pathmove);
+ require_send = 1;
#ifdef _DEBUG_JTAG_IO_
- LOG_DEBUG( "statemove: %s", tap_state_name( tap_get_end_state() ) );
+ LOG_DEBUG( "pathmove: %i states, end in %s", cmd->cmd.pathmove->num_states,
+ tap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]) );
#endif
- break;
+ return retval;
+}
- case JTAG_PATHMOVE:
- /* only send the maximum buffer size that FT2232C can handle */
- predicted_size = 3 * CEIL(cmd->cmd.pathmove->num_states, 7);
- if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
- {
- if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
- retval = ERROR_JTAG_QUEUE_FAILED;
- require_send = 0;
- first_unsent = cmd;
- }
- ft2232_add_pathmove(cmd->cmd.pathmove);
- require_send = 1;
+static int ft2232_execute_scan(jtag_command_t *cmd)
+{
+ int retval;
+ u8* buffer;
+ int scan_size; /* size of IR or DR scan */
+ enum scan_type type;
+ int predicted_size = 0;
+ retval = ERROR_OK;
+
+ scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
+ type = jtag_scan_type(cmd->cmd.scan);
+ predicted_size = ft2232_predict_scan_out(scan_size, type);
+ if ( (predicted_size + 1) > FT2232_BUFFER_SIZE )
+ {
+ LOG_DEBUG("oversized ft2232 scan (predicted_size > FT2232_BUFFER_SIZE)");
+ /* unsent commands before this */
+ if (first_unsent != cmd)
+ if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
+ retval = ERROR_JTAG_QUEUE_FAILED;
+
+ /* current command */
+ if (cmd->cmd.scan->end_state != TAP_INVALID)
+ ft2232_end_state(cmd->cmd.scan->end_state);
+ ft2232_large_scan(cmd->cmd.scan, type, buffer, scan_size);
+ require_send = 0;
+ first_unsent = cmd->next;
+ if (buffer)
+ free(buffer);
+ return retval;
+ }
+ else if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
+ {
+ LOG_DEBUG("ft2232 buffer size reached, sending queued commands (first_unsent: %p, cmd: %p)",
+ first_unsent,
+ cmd);
+ if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
+ retval = ERROR_JTAG_QUEUE_FAILED;
+ require_send = 0;
+ first_unsent = cmd;
+ }
+ ft2232_expect_read += ft2232_predict_scan_in(scan_size, type);
+ /* LOG_DEBUG("new read size: %i", ft2232_expect_read); */
+ if (cmd->cmd.scan->end_state != TAP_INVALID)
+ ft2232_end_state(cmd->cmd.scan->end_state);
+ ft2232_add_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
+ require_send = 1;
+ if (buffer)
+ free(buffer);
#ifdef _DEBUG_JTAG_IO_
- LOG_DEBUG( "pathmove: %i states, end in %s", cmd->cmd.pathmove->num_states,
- tap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]) );
+ LOG_DEBUG( "%s scan, %i bits, end in %s", (cmd->cmd.scan->ir_scan) ? "IR" : "DR", scan_size,
+ tap_state_name( tap_get_end_state() ) );
#endif
- break;
+ return retval;
+
+}
+
+static int ft2232_execute_reset(jtag_command_t *cmd)
+{
+ int retval;
+ int predicted_size = 0;
+ retval = ERROR_OK;
+
+ DEBUG_JTAG_IO("reset trst: %i srst %i",
+ cmd->cmd.reset->trst, cmd->cmd.reset->srst);
+
+ /* only send the maximum buffer size that FT2232C can handle */
+ predicted_size = 3;
+ if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
+ {
+ if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
+ retval = ERROR_JTAG_QUEUE_FAILED;
+ require_send = 0;
+ first_unsent = cmd;
+ }
+
+ if ( (cmd->cmd.reset->trst == 1) || ( cmd->cmd.reset->srst && (jtag_reset_config & RESET_SRST_PULLS_TRST) ) )
+ {
+ tap_set_state(TAP_RESET);
+ }
+ layout->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
+ require_send = 1;
- case JTAG_SCAN:
- scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
- type = jtag_scan_type(cmd->cmd.scan);
- predicted_size = ft2232_predict_scan_out(scan_size, type);
- if ( (predicted_size + 1) > FT2232_BUFFER_SIZE )
- {
- LOG_DEBUG("oversized ft2232 scan (predicted_size > FT2232_BUFFER_SIZE)");
- /* unsent commands before this */
- if (first_unsent != cmd)
- if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
- retval = ERROR_JTAG_QUEUE_FAILED;
-
- /* current command */
- if (cmd->cmd.scan->end_state != -1)
- ft2232_end_state(cmd->cmd.scan->end_state);
- ft2232_large_scan(cmd->cmd.scan, type, buffer, scan_size);
- require_send = 0;
- first_unsent = cmd->next;
- if (buffer)
- free(buffer);
- break;
- }
- else if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
- {
- LOG_DEBUG("ft2232 buffer size reached, sending queued commands (first_unsent: %p, cmd: %p)",
- first_unsent,
- cmd);
- if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
- retval = ERROR_JTAG_QUEUE_FAILED;
- require_send = 0;
- first_unsent = cmd;
- }
- ft2232_expect_read += ft2232_predict_scan_in(scan_size, type);
- /* LOG_DEBUG("new read size: %i", ft2232_expect_read); */
- if (cmd->cmd.scan->end_state != -1)
- ft2232_end_state(cmd->cmd.scan->end_state);
- ft2232_add_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
- require_send = 1;
- if (buffer)
- free(buffer);
#ifdef _DEBUG_JTAG_IO_
- LOG_DEBUG( "%s scan, %i bits, end in %s", (cmd->cmd.scan->ir_scan) ? "IR" : "DR", scan_size,
- tap_state_name( tap_get_end_state() ) );
+ LOG_DEBUG("trst: %i, srst: %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
#endif
- break;
+ return retval;
+}
- case JTAG_SLEEP:
- if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
+static int ft2232_execute_sleep(jtag_command_t *cmd)
+{
+ int retval;
+ retval = ERROR_OK;
+
+ DEBUG_JTAG_IO("sleep %i", cmd->cmd.sleep->us);
+
+ if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
retval = ERROR_JTAG_QUEUE_FAILED;
- first_unsent = cmd->next;
- jtag_sleep(cmd->cmd.sleep->us);
+ first_unsent = cmd->next;
+ jtag_sleep(cmd->cmd.sleep->us);
#ifdef _DEBUG_JTAG_IO_
LOG_DEBUG( "sleep %i usec while in %s", cmd->cmd.sleep->us, tap_state_name( tap_get_state() ) );
#endif
- break;
- case JTAG_STABLECLOCKS:
+ return retval;
+}
- /* this is only allowed while in a stable state. A check for a stable
- * state was done in jtag_add_clocks()
- */
- if (ft2232_stableclocks(cmd->cmd.stableclocks->num_cycles, cmd) != ERROR_OK)
- retval = ERROR_JTAG_QUEUE_FAILED;
+static int ft2232_execute_stableclocks(jtag_command_t *cmd)
+{
+ int retval;
+ retval = ERROR_OK;
+
+ /* this is only allowed while in a stable state. A check for a stable
+ * state was done in jtag_add_clocks()
+ */
+ 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, tap_state_name( tap_get_state() ) );
+ LOG_DEBUG( "clocks %i while in %s", cmd->cmd.stableclocks->num_cycles, tap_state_name( tap_get_state() ) );
#endif
- break;
+ return retval;
+}
+
+static int ft2232_execute_command(jtag_command_t *cmd)
+{
+ int retval;
+ retval = ERROR_OK;
+
+ switch (cmd->type)
+ {
+ case JTAG_END_STATE: retval = ft2232_execute_end_state(cmd); break;
+ case JTAG_RESET: retval = ft2232_execute_reset(cmd); break;
+ case JTAG_RUNTEST: retval = ft2232_execute_runtest(cmd); break;
+ case JTAG_STATEMOVE: retval = ft2232_execute_statemove(cmd); break;
+ case JTAG_PATHMOVE: retval = ft2232_execute_pathmove(cmd); break;
+ case JTAG_SCAN: retval = ft2232_execute_scan(cmd); break;
+ case JTAG_SLEEP: retval = ft2232_execute_sleep(cmd); break;
+ case JTAG_STABLECLOCKS: retval = ft2232_execute_stableclocks(cmd); break;
default:
LOG_ERROR("BUG: unknown JTAG command type encountered");
- exit(-1);
- }
+ exit(-1);
+ }
+ return retval;
+}
+static int ft2232_execute_queue()
+{
+ jtag_command_t* cmd = jtag_command_queue; /* currently processed command */
+ 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
+ * that wasn't handled by a caller-provided error handler
+ */
+ retval = ERROR_OK;
+
+ ft2232_buffer_size = 0;
+ ft2232_expect_read = 0;
+
+ /* blink, if the current layout has that feature */
+ if (layout->blink)
+ layout->blink();
+
+ while (cmd)
+ {
+ if (ft2232_execute_command(cmd) != ERROR_OK)
+ retval = ERROR_JTAG_QUEUE_FAILED;
+ /* Start reading input before FT2232 TX buffer fills up */
cmd = cmd->next;
+ if (ft2232_expect_read > 256)
+ {
+ if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
+ retval = ERROR_JTAG_QUEUE_FAILED;
+ first_unsent = cmd;
+ }
}
if (require_send > 0)
if (status == FT_OK)
{
char** desc_array = malloc( sizeof(char*) * (num_devices + 1) );
- int i;
+ u32 i;
for (i = 0; i < num_devices; i++)
desc_array[i] = malloc(64);
#endif /* BUILD_FT2232_LIBFTDI == 1 */
-int ft2232_init(void)
+static int ft2232_init(void)
{
u8 buf[1];
int retval;
}
-int usbjtag_init(void)
+static int usbjtag_init(void)
{
u8 buf[3];
u32 bytes_written;
}
-int axm0432_jtag_init(void)
+static int axm0432_jtag_init(void)
{
u8 buf[3];
u32 bytes_written;
}
-int jtagkey_init(void)
+static int jtagkey_init(void)
{
u8 buf[3];
u32 bytes_written;
}
-int olimex_jtag_init(void)
+static int olimex_jtag_init(void)
{
u8 buf[3];
u32 bytes_written;
}
-int flyswatter_init(void)
+static int flyswatter_init(void)
{
u8 buf[3];
u32 bytes_written;
}
-int turtle_init(void)
+static int turtle_init(void)
{
u8 buf[3];
u32 bytes_written;
}
-int comstick_init(void)
+static int comstick_init(void)
{
u8 buf[3];
u32 bytes_written;
}
-int stm32stick_init(void)
+static int stm32stick_init(void)
{
u8 buf[3];
u32 bytes_written;
}
-int sheevaplug_init(void)
+static int sheevaplug_init(void)
{
u8 buf[3];
u32 bytes_written;
return ERROR_OK;
}
-void olimex_jtag_blink(void)
+static void olimex_jtag_blink(void)
{
/* Olimex ARM-USB-OCD has a LED connected to ACBUS3
* ACBUS3 is bit 3 of the GPIOH port
}
-void flyswatter_jtag_blink(void)
+static void flyswatter_jtag_blink(void)
{
/*
* Flyswatter has two LEDs connected to ACBUS2 and ACBUS3
}
-void turtle_jtag_blink(void)
+static void turtle_jtag_blink(void)
{
/*
* Turtelizer2 has two LEDs connected to ACBUS2 and ACBUS3
}
-int ft2232_quit(void)
+static int ft2232_quit(void)
{
#if BUILD_FT2232_FTD2XX == 1
FT_STATUS status;
}
-int ft2232_handle_device_desc_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc)
+static int ft2232_handle_device_desc_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc)
{
char *cp;
char buf[200];
}
-int ft2232_handle_serial_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc)
+static int ft2232_handle_serial_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc)
{
if (argc == 1)
{
}
-int ft2232_handle_layout_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc)
+static int ft2232_handle_layout_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc)
{
if (argc == 0)
return ERROR_OK;
}
-int ft2232_handle_vid_pid_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc)
+static int ft2232_handle_vid_pid_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc)
{
int i;
}
-int ft2232_handle_latency_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc)
+static int ft2232_handle_latency_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc)
{
if (argc == 1)
{
return retval;
}
+
+/* ---------------------------------------------------------------------
+ * Support for IceBear JTAG adapter from Section5:
+ * http://section5.ch/icebear
+ *
+ * Author: Sten, debian@sansys-electronic.com
+ */
+
+/* Icebear pin layout
+ *
+ * ADBUS5 (nEMU) nSRST | 2 1| GND (10k->VCC)
+ * GND GND | 4 3| n.c.
+ * ADBUS3 TMS | 6 5| ADBUS6 VCC
+ * ADBUS0 TCK | 8 7| ADBUS7 (GND)
+ * ADBUS4 nTRST |10 9| ACBUS0 (GND)
+ * ADBUS1 TDI |12 11| ACBUS1 (GND)
+ * ADBUS2 TDO |14 13| GND GND
+ *
+ * ADBUS0 O L TCK ACBUS0 GND
+ * ADBUS1 O L TDI ACBUS1 GND
+ * ADBUS2 I TDO ACBUS2 n.c.
+ * ADBUS3 O H TMS ACBUS3 n.c.
+ * ADBUS4 O H nTRST
+ * ADBUS5 O H nSRST
+ * ADBUS6 - VCC
+ * ADBUS7 - GND
+ */
+static int icebear_jtag_init(void) {
+ u8 buf[3];
+ u32 bytes_written;
+
+ low_direction = 0x0b; /* output: TCK TDI TMS; input: TDO */
+ low_output = 0x08; /* high: TMS; low: TCK TDI */
+ nTRST = 0x10;
+ nSRST = 0x20;
+
+ if ((jtag_reset_config & RESET_TRST_OPEN_DRAIN) != 0) {
+ low_direction &= ~nTRST; /* nTRST high impedance */
+ }
+ else {
+ low_direction |= nTRST;
+ low_output |= nTRST;
+ }
+
+ low_direction |= nSRST;
+ low_output |= nSRST;
+
+ /* initialize low byte for jtag */
+ buf[0] = 0x80; /* command "set data bits low byte" */
+ buf[1] = low_output;
+ buf[2] = low_direction;
+ LOG_DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
+
+ if ( ( ( ft2232_write(buf, 3, &bytes_written) ) != ERROR_OK ) || (bytes_written != 3) ) {
+ LOG_ERROR("couldn't initialize FT2232 with 'IceBear' layout (low)");
+ return ERROR_JTAG_INIT_FAILED;
+ }
+
+ high_output = 0x0;
+ high_direction = 0x00;
+
+
+ /* initialize high port */
+ buf[0] = 0x82; /* command "set data bits high byte" */
+ buf[1] = high_output; /* value */
+ buf[2] = high_direction; /* all outputs (xRST and xRSTnOE) */
+ LOG_DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
+
+ if ( ( ( ft2232_write(buf, 3, &bytes_written) ) != ERROR_OK ) || (bytes_written != 3) ) {
+ LOG_ERROR("couldn't initialize FT2232 with 'IceBear' layout (high)");
+ return ERROR_JTAG_INIT_FAILED;
+ }
+
+ return ERROR_OK;
+}
+
+static void icebear_jtag_reset(int trst, int srst) {
+
+ if (trst == 1) {
+ low_direction |= nTRST;
+ low_output &= ~nTRST;
+ }
+ else if (trst == 0) {
+ if ((jtag_reset_config & RESET_TRST_OPEN_DRAIN) != 0)
+ low_direction &= ~nTRST;
+ else
+ low_output |= nTRST;
+ }
+
+ if (srst == 1) {
+ low_output &= ~nSRST;
+ }
+ else if (srst == 0) {
+ low_output |= nSRST;
+ }
+
+ /* command "set data bits low byte" */
+ BUFFER_ADD = 0x80;
+ BUFFER_ADD = low_output;
+ BUFFER_ADD = low_direction;
+ LOG_DEBUG("trst: %i, srst: %i, low_output: 0x%2.2x, low_direction: 0x%2.2x", trst, srst, low_output, low_direction);
+}