]> git.sur5r.net Git - openocd/blobdiff - src/jtag/ft2232.c
Correctedout buffer size and missing jlink_tap_init() call.
[openocd] / src / jtag / ft2232.c
index 50ff6548d467e60d4e9f00d0e15cb5b34d3b00bb..3075b1b495c81aa78f9eaa512987e99ba6b0749e 100644 (file)
 #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);
 
 
 /**
@@ -97,10 +85,11 @@ int ft2232_handle_latency_command(struct command_context_s* cmd_ctx, char* cmd,
 static int ft2232_stableclocks(int num_cycles, jtag_command_t* cmd);
 
 
-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 */
@@ -116,30 +105,31 @@ typedef struct ft2232_layout_s
 } 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);
 
 /* 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);
 
 /* blink procedures for layouts that support a blinking led */
-void olimex_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[] =
 {
@@ -150,13 +140,13 @@ ft2232_layout_t            ft2232_layouts[] =
        { "signalyzer",           usbjtag_init,              usbjtag_reset,      NULL                    },
        { "evb_lm3s811",          usbjtag_init,              usbjtag_reset,      NULL                    },
        { "olimex-jtag",          olimex_jtag_init,          olimex_jtag_reset,  olimex_jtag_blink       },
-       { "flyswatter",           flyswatter_init,           flyswatter_reset,   NULL                    },
+       { "flyswatter",           flyswatter_init,           flyswatter_reset,   flyswatter_jtag_blink   },
        { "turtelizer2",          turtle_init,               turtle_reset,       turtle_jtag_blink       },
        { "comstick",             comstick_init,             comstick_reset,     NULL                    },
        { "stm32stick",           stm32stick_init,           stm32stick_reset,   NULL                    },
        { "axm0432_jtag",         axm0432_jtag_init,         axm0432_jtag_reset, NULL                    },
        {"sheevaplug",            sheevaplug_init,           sheevaplug_reset,   NULL                    },
-       { NULL,                   NULL,                      NULL },
+       { NULL,                   NULL,                      NULL,               NULL                    },
 };
 
 static u8                  nTRST, nTRSTnOE, nSRST, nSRSTnOE;
@@ -198,7 +188,7 @@ jtag_interface_t ft2232_interface =
        .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;
@@ -231,7 +221,7 @@ int ft2232_write(u8* buf, int size, u32* bytes_written)
 }
 
 
-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;
@@ -279,7 +269,7 @@ int ft2232_read(u8* buf, int size, u32* bytes_read)
 }
 
 
-int ft2232_speed(int speed)
+static int ft2232_speed(int speed)
 {
        u8  buf[3];
        int retval;
@@ -300,7 +290,7 @@ int ft2232_speed(int speed)
 }
 
 
-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
@@ -312,7 +302,7 @@ int ft2232_speed_div(int speed, int* khz)
 }
 
 
-int ft2232_khz(int khz, int* jtag_speed)
+static int ft2232_khz(int khz, int* jtag_speed)
 {
        if (khz==0)
        {
@@ -353,7 +343,7 @@ int ft2232_khz(int khz, int* jtag_speed)
 }
 
 
-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");
@@ -381,7 +371,7 @@ void ft2232_end_state(tap_state_t state)
 }
 
 
-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;
@@ -405,7 +395,7 @@ void ft2232_read_scan(enum scan_type type, u8* buffer, int scan_size)
 }
 
 
-void ft2232_debug_dump_buffer(void)
+static void ft2232_debug_dump_buffer(void)
 {
        int   i;
        char  line[256];
@@ -426,15 +416,15 @@ void ft2232_debug_dump_buffer(void)
 }
 
 
-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;
@@ -482,9 +472,10 @@ int ft2232_send_and_recv(jtag_command_t* first, jtag_command_t* last)
                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;
@@ -544,7 +535,7 @@ int ft2232_send_and_recv(jtag_command_t* first, jtag_command_t* last)
 }
 
 
-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;
@@ -740,7 +731,7 @@ void ft2232_add_scan(int ir_scan, enum scan_type type, u8* buffer, int scan_size
 }
 
 
-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;
@@ -950,7 +941,7 @@ int ft2232_large_scan(scan_command_t* cmd, enum scan_type type, u8* buffer, int
 }
 
 
-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;
@@ -977,7 +968,7 @@ int ft2232_predict_scan_out(int scan_size, enum scan_type type)
 }
 
 
-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;
 
@@ -999,7 +990,7 @@ int ft2232_predict_scan_in(int scan_size, enum scan_type type)
 }
 
 
-void usbjtag_reset(int trst, int srst)
+static void usbjtag_reset(int trst, int srst)
 {
        if (trst == 1)
        {
@@ -1038,7 +1029,7 @@ void usbjtag_reset(int trst, int srst)
 }
 
 
-void jtagkey_reset(int trst, int srst)
+static void jtagkey_reset(int trst, int srst)
 {
        if (trst == 1)
        {
@@ -1079,7 +1070,7 @@ void jtagkey_reset(int trst, int srst)
 }
 
 
-void olimex_jtag_reset(int trst, int srst)
+static void olimex_jtag_reset(int trst, int srst)
 {
        if (trst == 1)
        {
@@ -1114,7 +1105,7 @@ void olimex_jtag_reset(int trst, int srst)
 }
 
 
-void axm0432_jtag_reset(int trst, int srst)
+static void axm0432_jtag_reset(int trst, int srst)
 {
        if (trst == 1)
        {
@@ -1144,7 +1135,7 @@ void axm0432_jtag_reset(int trst, int srst)
 }
 
 
-void flyswatter_reset(int trst, int srst)
+static void flyswatter_reset(int trst, int srst)
 {
        if (trst == 1)
        {
@@ -1172,7 +1163,7 @@ void flyswatter_reset(int trst, int srst)
 }
 
 
-void turtle_reset(int trst, int srst)
+static void turtle_reset(int trst, int srst)
 {
        trst = trst;
 
@@ -1193,7 +1184,7 @@ void turtle_reset(int trst, int srst)
 }
 
 
-void comstick_reset(int trst, int srst)
+static void comstick_reset(int trst, int srst)
 {
        if (trst == 1)
        {
@@ -1222,7 +1213,7 @@ void comstick_reset(int trst, int srst)
 }
 
 
-void stm32stick_reset(int trst, int srst)
+static void stm32stick_reset(int trst, int srst)
 {
        if (trst == 1)
        {
@@ -1257,7 +1248,7 @@ void stm32stick_reset(int trst, int srst)
 
 
 
-void sheevaplug_reset(int trst, int srst)
+static void sheevaplug_reset(int trst, int srst)
 {
        if (trst == 1)
                high_output &= ~nTRST;
@@ -1276,247 +1267,336 @@ void sheevaplug_reset(int trst, int srst)
        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)
@@ -1569,7 +1649,28 @@ static int ft2232_init_ftd2xx(u16 vid, u16 pid, int more, int* try_more)
                return ERROR_JTAG_INIT_FAILED;
        }
 
-       if ( ( status = FT_OpenEx(openex_string, openex_flags, &ftdih) ) != FT_OK )
+       status = FT_OpenEx(openex_string, openex_flags, &ftdih);
+       if( status != FT_OK ){
+               // under Win32, the FTD2XX driver appends an "A" to the end
+               // of the description, if we tried by the desc, then
+               // try by the alternate "A" description.
+               if( openex_string == ft2232_device_desc ){
+                       // Try the alternate method.
+                       openex_string = ft2232_device_desc_A;
+                       status = FT_OpenEx(openex_string, openex_flags, &ftdih);
+                       if( status == FT_OK ){
+                               // yea, the "alternate" method worked!
+                       } else {
+                               // drat, give the user a meaningfull message.
+                               // telling the use we tried *BOTH* methods.
+                               LOG_WARNING("Unable to open FTDI Device tried: '%s' and '%s'\n",
+                                                       ft2232_device_desc,
+                                                       ft2232_device_desc_A );
+                       }
+               }
+       }
+
+       if ( status != FT_OK )
        {
                DWORD num_devices;
 
@@ -1584,7 +1685,7 @@ static int ft2232_init_ftd2xx(u16 vid, u16 pid, int more, int* try_more)
                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);
@@ -1732,7 +1833,7 @@ static int ft2232_purge_libftdi(void)
 
 #endif /* BUILD_FT2232_LIBFTDI == 1 */
 
-int ft2232_init(void)
+static int ft2232_init(void)
 {
        u8  buf[1];
        int retval;
@@ -1814,7 +1915,7 @@ int ft2232_init(void)
 }
 
 
-int usbjtag_init(void)
+static int usbjtag_init(void)
 {
        u8  buf[3];
        u32 bytes_written;
@@ -1889,7 +1990,7 @@ int usbjtag_init(void)
 }
 
 
-int axm0432_jtag_init(void)
+static int axm0432_jtag_init(void)
 {
        u8  buf[3];
        u32 bytes_written;
@@ -1959,7 +2060,7 @@ int axm0432_jtag_init(void)
 }
 
 
-int jtagkey_init(void)
+static int jtagkey_init(void)
 {
        u8  buf[3];
        u32 bytes_written;
@@ -2041,7 +2142,7 @@ int jtagkey_init(void)
 }
 
 
-int olimex_jtag_init(void)
+static int olimex_jtag_init(void)
 {
        u8  buf[3];
        u32 bytes_written;
@@ -2108,7 +2209,7 @@ int olimex_jtag_init(void)
 }
 
 
-int flyswatter_init(void)
+static int flyswatter_init(void)
 {
        u8  buf[3];
        u32 bytes_written;
@@ -2136,7 +2237,7 @@ int flyswatter_init(void)
        high_output    = 0x00;
        high_direction = 0x0c;
 
-       /* turn red LED1 on, LED2 off */
+       /* turn red LED3 on, LED2 off */
        high_output |= 0x08;
 
        /* initialize high port */
@@ -2155,7 +2256,7 @@ int flyswatter_init(void)
 }
 
 
-int turtle_init(void)
+static int turtle_init(void)
 {
        u8  buf[3];
        u32 bytes_written;
@@ -2196,7 +2297,7 @@ int turtle_init(void)
 }
 
 
-int comstick_init(void)
+static int comstick_init(void)
 {
        u8  buf[3];
        u32 bytes_written;
@@ -2240,7 +2341,7 @@ int comstick_init(void)
 }
 
 
-int stm32stick_init(void)
+static int stm32stick_init(void)
 {
        u8  buf[3];
        u32 bytes_written;
@@ -2284,7 +2385,7 @@ int stm32stick_init(void)
 }
 
 
-int sheevaplug_init(void)
+static int sheevaplug_init(void)
 {
        u8 buf[3];
        u32 bytes_written;
@@ -2335,7 +2436,7 @@ int sheevaplug_init(void)
        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
@@ -2357,7 +2458,20 @@ void olimex_jtag_blink(void)
 }
 
 
-void turtle_jtag_blink(void)
+static void flyswatter_jtag_blink(void)
+{
+       /*
+        * Flyswatter has two LEDs connected to ACBUS2 and ACBUS3
+        */
+       high_output ^= 0x0c;
+
+       BUFFER_ADD = 0x82;
+       BUFFER_ADD = high_output;
+       BUFFER_ADD = high_direction;
+}
+
+
+static void turtle_jtag_blink(void)
 {
        /*
         * Turtelizer2 has two LEDs connected to ACBUS2 and ACBUS3
@@ -2377,7 +2491,7 @@ void turtle_jtag_blink(void)
 }
 
 
-int ft2232_quit(void)
+static int ft2232_quit(void)
 {
 #if BUILD_FT2232_FTD2XX == 1
        FT_STATUS status;
@@ -2398,11 +2512,31 @@ int ft2232_quit(void)
 }
 
 
-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];
        if (argc == 1)
        {
                ft2232_device_desc = strdup(args[0]);
+               cp = strchr( ft2232_device_desc, 0 );
+               // under Win32, the FTD2XX driver appends an "A" to the end
+               // of the description, this examines the given desc
+               // and creates the 'missing' _A or non_A variable.
+               if( (cp[-1] == 'A') && (cp[-2]==' ') ){
+                       // it was, so make this the "A" version.
+                       ft2232_device_desc_A = ft2232_device_desc;
+                       // and *CREATE* the non-A version.
+                       strcpy( buf, ft2232_device_desc );
+                       cp = strchr( buf, 0 );
+                       cp[-2] = 0;
+                       ft2232_device_desc =  strdup( buf );
+               } else {
+                       // <space>A not defined
+                       // so create it
+                       sprintf( buf, "%s A", ft2232_device_desc );
+                       ft2232_device_desc_A = strdup( buf );
+               }
        }
        else
        {
@@ -2413,7 +2547,7 @@ int ft2232_handle_device_desc_command(struct command_context_s* cmd_ctx, char* c
 }
 
 
-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)
        {
@@ -2428,7 +2562,7 @@ int ft2232_handle_serial_command(struct command_context_s* cmd_ctx, char* cmd, c
 }
 
 
-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;
@@ -2440,7 +2574,7 @@ 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)
+static int ft2232_handle_vid_pid_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc)
 {
        int i;
 
@@ -2473,7 +2607,7 @@ int ft2232_handle_vid_pid_command(struct command_context_s* cmd_ctx, char* cmd,
 }
 
 
-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)
        {