FT2232: bulidfix
[openocd.git] / src / jtag / drivers / ft2232.c
index 30695a9ab0abada742bf80db447c6ebb845c917c..b45e8a4dd26f0658a2d9b2804b40af35293152e5 100644 (file)
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
 
-/* This code uses information contained in the MPSSE specification which was
+/**
+ * @file
+ * JTAG adapters based on the FT2232 full and high speed USB parts are
+ * popular low cost JTAG debug solutions.  Many FT2232 based JTAG adapters
+ * are discrete, but development boards may integrate them as alternatives
+ * to more capable (and expensive) third party JTAG pods.  Since JTAG uses
+ * only one of the two ports on these devices, on integrated boards the
+ * second port often serves as a USB-to-serial adapter for the target's
+ * console UART even when the JTAG port is not in use.  (Systems which
+ * support ARM's SWD in addition to JTAG, or instead of it, may use that
+ * second port for reading SWV trace data.)
+ *
+ * FT2232 based JTAG adapters are "dumb" not "smart", because most JTAG
+ * request/response interactions involve round trips over the USB link.
+ * A "smart" JTAG adapter has intelligence close to the scan chain, so it
+ * can for example poll quickly for a status change (usually taking on the
+ * order of microseconds not milliseconds) before beginning a queued
+ * transaction which require the previous one to have completed.
+ *
+ * There are dozens of adapters of this type, differing in details which
+ * this driver needs to understand.  Those "layout" details are required
+ * as part of FT2232 driver configuration.
+ *
+ * This code uses information contained in the MPSSE specification which was
  * found here:
  * http://www.ftdichip.com/Documents/AppNotes/AN2232C-01_MPSSE_Cmnd.pdf
  * Hereafter this is called the "MPSSE Spec".
  *
  * The datasheet for the ftdichip.com's FT2232D part is here:
  * http://www.ftdichip.com/Documents/DataSheets/DS_FT2232D.pdf
+ *
+ * Also note the issue with code 0x4b (clock data to TMS) noted in
+ * http://developer.intra2net.com/mailarchive/html/libftdi/2009/msg00292.html
+ * which can affect longer JTAG state paths.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -41,8 +68,7 @@
 #endif
 
 /* project specific includes */
-#include "interface.h"
-#include "commands.h"
+#include <jtag/interface.h>
 #include <helper/time_support.h>
 
 #if IS_CYGWIN == 1
 /* FT2232 access library includes */
 #if BUILD_FT2232_FTD2XX == 1
 #include <ftd2xx.h>
+
+enum ftdi_interface
+{
+    INTERFACE_ANY = 0,
+    INTERFACE_A   = 1,
+    INTERFACE_B   = 2,
+    INTERFACE_C   = 3,
+    INTERFACE_D   = 4
+};
+
 #elif BUILD_FT2232_LIBFTDI == 1
 #include <ftdi.h>
 #endif
@@ -105,7 +141,6 @@ static int ft2232_stableclocks(int num_cycles, struct jtag_command* cmd);
 static char *       ft2232_device_desc_A = NULL;
 static char*        ft2232_device_desc = NULL;
 static char*        ft2232_serial  = NULL;
-static char*        ft2232_layout  = NULL;
 static uint8_t         ft2232_latency = 2;
 static unsigned                ft2232_max_tck = FTDI_2232C_MAX_TCK;
 
@@ -119,6 +154,7 @@ struct ft2232_layout {
        int (*init)(void);
        void (*reset)(int trst, int srst);
        void (*blink)(void);
+       int channel;
 };
 
 /* init procedures for supported layouts */
@@ -135,6 +171,7 @@ static int icebear_jtag_init(void);
 static int cortino_jtag_init(void);
 static int signalyzer_h_init(void);
 static int ktlink_init(void);
+static int redbee_init(void);
 
 /* reset procedures for supported layouts */
 static void usbjtag_reset(int trst, int srst);
@@ -149,6 +186,7 @@ static void sheevaplug_reset(int trst, int srst);
 static void icebear_jtag_reset(int trst, int srst);
 static void signalyzer_h_reset(int trst, int srst);
 static void ktlink_reset(int trst, int srst);
+static void redbee_reset(int trst, int srst);
 
 /* blink procedures for layouts that support a blinking led */
 static void olimex_jtag_blink(void);
@@ -159,30 +197,100 @@ static void ktlink_blink(void);
 
 static const struct ft2232_layout  ft2232_layouts[] =
 {
-       { "usbjtag",              usbjtag_init,              usbjtag_reset,      NULL                    },
-       { "jtagkey",              jtagkey_init,              jtagkey_reset,      NULL                    },
-       { "jtagkey_prototype_v1", jtagkey_init,              jtagkey_reset,      NULL                    },
-       { "oocdlink",             jtagkey_init,              jtagkey_reset,      NULL                    },
-       { "signalyzer",           usbjtag_init,              usbjtag_reset,      NULL                    },
-       { "evb_lm3s811",          usbjtag_init,              usbjtag_reset,      NULL                    },
-       { "luminary_icdi",        usbjtag_init,              usbjtag_reset,      NULL                    },
-       { "olimex-jtag",          olimex_jtag_init,          olimex_jtag_reset,  olimex_jtag_blink       },
-       { "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                    },
-       { "icebear",              icebear_jtag_init,         icebear_jtag_reset, NULL                    },
-       { "cortino",              cortino_jtag_init,         comstick_reset, NULL                        },
-       { "signalyzer-h",         signalyzer_h_init,         signalyzer_h_reset, signalyzer_h_blink      },
-       { "ktlink",               ktlink_init,               ktlink_reset,       ktlink_blink            },
-       { NULL,                   NULL,                      NULL,               NULL                    },
+       { .name = "usbjtag",
+               .init = usbjtag_init,
+               .reset = usbjtag_reset,
+       },
+       { .name = "jtagkey",
+               .init = jtagkey_init,
+               .reset = jtagkey_reset,
+       },
+       { .name = "jtagkey_prototype_v1",
+               .init = jtagkey_init,
+               .reset = jtagkey_reset,
+       },
+       { .name = "oocdlink",
+               .init = jtagkey_init,
+               .reset = jtagkey_reset,
+       },
+       { .name = "signalyzer",
+               .init = usbjtag_init,
+               .reset = usbjtag_reset,
+       },
+       { .name = "evb_lm3s811",
+               .init = usbjtag_init,
+               .reset = usbjtag_reset,
+       },
+       { .name = "luminary_icdi",
+               .init = usbjtag_init,
+               .reset = usbjtag_reset,
+       },
+       { .name = "olimex-jtag",
+               .init = olimex_jtag_init,
+               .reset = olimex_jtag_reset,
+               .blink = olimex_jtag_blink
+       },
+       { .name = "flyswatter",
+               .init = flyswatter_init,
+               .reset = flyswatter_reset,
+               .blink = flyswatter_jtag_blink
+       },
+       { .name = "turtelizer2",
+               .init = turtle_init,
+               .reset = turtle_reset,
+               .blink = turtle_jtag_blink
+       },
+       { .name = "comstick",
+               .init = comstick_init,
+               .reset = comstick_reset,
+       },
+       { .name = "stm32stick",
+               .init = stm32stick_init,
+               .reset = stm32stick_reset,
+       },
+       { .name = "axm0432_jtag",
+               .init = axm0432_jtag_init,
+               .reset = axm0432_jtag_reset,
+       },
+       { .name = "sheevaplug",
+               .init = sheevaplug_init,
+               .reset = sheevaplug_reset,
+       },
+       { .name = "icebear",
+               .init = icebear_jtag_init,
+               .reset = icebear_jtag_reset,
+       },
+       { .name = "cortino",
+               .init = cortino_jtag_init,
+               .reset = comstick_reset,
+       },
+       { .name = "signalyzer-h",
+               .init = signalyzer_h_init,
+               .reset = signalyzer_h_reset,
+               .blink = signalyzer_h_blink
+       },
+       { .name = "ktlink",
+               .init = ktlink_init,
+               .reset = ktlink_reset,
+               .blink = ktlink_blink
+       },
+       { .name = "redbee-econotag",
+               .init = redbee_init,
+               .reset = redbee_reset,
+       },
+       { .name = "redbee-usb",
+               .init = redbee_init,
+               .reset = redbee_reset,
+               .channel = INTERFACE_B,
+       },
+       { .name = NULL, /* END OF TABLE */ },
 };
 
 static uint8_t                  nTRST, nTRSTnOE, nSRST, nSRSTnOE;
 
+/** the layout being used with this debug session */
 static const struct ft2232_layout *layout;
+
 static uint8_t                  low_output     = 0x0;
 static uint8_t                  low_direction  = 0x0;
 static uint8_t                  high_output    = 0x0;
@@ -1491,6 +1599,36 @@ static 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);
 }
 
+static void redbee_reset(int trst, int srst)
+{
+       if (trst == 1)
+       {
+               tap_set_state(TAP_RESET);
+               high_output &= ~nTRST;
+       }
+       else if (trst == 0)
+       {
+               high_output |= nTRST;
+       }
+
+       if (srst == 1)
+       {
+               high_output &= ~nSRST;
+       }
+       else if (srst == 0)
+       {
+               high_output |= nSRST;
+       }
+
+       /* command "set data bits low byte" */
+       buffer_write(0x82);
+       buffer_write(high_output);
+       buffer_write(high_direction);
+       LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, "
+                       "high_direction: 0x%2.2x", trst, srst, high_output,
+                       high_direction);
+}
+
 static int ft2232_execute_runtest(struct jtag_command *cmd)
 {
        int retval;
@@ -1592,6 +1730,72 @@ static int ft2232_execute_statemove(struct jtag_command *cmd)
        return retval;
 }
 
+/**
+ * Clock a bunch of TMS (or SWDIO) transitions, to change the JTAG
+ * (or SWD) state machine.
+ */
+static int ft2232_execute_tms(struct jtag_command *cmd)
+{
+       int             retval = ERROR_OK;
+       unsigned        num_bits = cmd->cmd.tms->num_bits;
+       const uint8_t   *bits = cmd->cmd.tms->bits;
+       unsigned        count;
+
+       DEBUG_JTAG_IO("TMS: %d bits", num_bits);
+
+       /* only send the maximum buffer size that FT2232C can handle */
+       count = 3 * DIV_ROUND_UP(num_bits, 4);
+       if (ft2232_buffer_size + 3*count + 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;
+       }
+
+       /* Shift out in batches of at most 6 bits; there's a report of an
+        * FT2232 bug in this area, where shifting exactly 7 bits can make
+        * problems with TMS signaling for the last clock cycle:
+        *
+        *    http://developer.intra2net.com/mailarchive/html/
+        *              libftdi/2009/msg00292.html
+        *
+        * Command 0x4b is: "Clock Data to TMS/CS Pin (no Read)"
+        *
+        * Note that pathmoves in JTAG are not often seven bits, so that
+        * isn't a particularly likely situation outside of "special"
+        * signaling such as switching between JTAG and SWD modes.
+        */
+       while (num_bits) {
+               if (num_bits <= 6) {
+                       buffer_write(0x4b);
+                       buffer_write(num_bits - 1);
+                       buffer_write(*bits & 0x3f);
+                       break;
+               }
+
+               /* Yes, this is lazy ... we COULD shift out more data
+                * bits per operation, but doing it in nybbles is easy
+                */
+               buffer_write(0x4b);
+               buffer_write(3);
+               buffer_write(*bits & 0xf);
+               num_bits -= 4;
+
+               count  = (num_bits > 4) ? 4 : num_bits;
+
+               buffer_write(0x4b);
+               buffer_write(count - 1);
+               buffer_write((*bits >> 4) & 0xf);
+               num_bits -= count;
+
+               bits++;
+       }
+
+       require_send = 1;
+       return retval;
+}
+
 static int ft2232_execute_pathmove(struct jtag_command *cmd)
 {
        int     predicted_size = 0;
@@ -1744,7 +1948,6 @@ static int ft2232_execute_stableclocks(struct jtag_command *cmd)
 static int ft2232_execute_command(struct jtag_command *cmd)
 {
        int retval;
-       retval = ERROR_OK;
 
        switch (cmd->type)
        {
@@ -1755,9 +1958,13 @@ static int ft2232_execute_command(struct jtag_command *cmd)
        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;
+       case JTAG_TMS:
+               retval = ft2232_execute_tms(cmd);
+               break;
        default:
                LOG_ERROR("BUG: unknown JTAG command type encountered");
-               exit(-1);
+               retval = ERROR_JTAG_QUEUE_FAILED;
+               break;
        }
        return retval;
 }
@@ -1814,7 +2021,12 @@ static int ft2232_init_ftd2xx(uint16_t vid, uint16_t pid, int more, int* try_mor
        char*   openex_string = NULL;
        uint8_t latency_timer;
 
-       LOG_DEBUG("'ft2232' interface using FTD2XX with '%s' layout (%4.4x:%4.4x)", ft2232_layout, vid, pid);
+       if (layout == NULL) {
+               LOG_WARNING("No ft2232 layout specified'");
+               return ERROR_JTAG_INIT_FAILED;
+       }
+
+       LOG_DEBUG("'ft2232' interface using FTD2XX with '%s' layout (%4.4x:%4.4x)", layout->name, vid, pid);
 
 #if IS_WIN32 == 0
        /* Add non-standard Vid/Pid to the linux driver */
@@ -1977,17 +2189,25 @@ static int ft2232_purge_ftd2xx(void)
 #endif /* BUILD_FT2232_FTD2XX == 1 */
 
 #if BUILD_FT2232_LIBFTDI == 1
-static int ft2232_init_libftdi(uint16_t vid, uint16_t pid, int more, int* try_more)
+static int ft2232_init_libftdi(uint16_t vid, uint16_t pid, int more, int* try_more, int channel)
 {
        uint8_t latency_timer;
 
+       if (layout == NULL) {
+               LOG_WARNING("No ft2232 layout specified'");
+               return ERROR_JTAG_INIT_FAILED;
+       }
+
        LOG_DEBUG("'ft2232' interface using libftdi with '%s' layout (%4.4x:%4.4x)",
-                       ft2232_layout, vid, pid);
+                       layout->name, vid, pid);
 
        if (ftdi_init(&ftdic) < 0)
                return ERROR_JTAG_INIT_FAILED;
 
-       if (ftdi_set_interface(&ftdic, INTERFACE_A) < 0)
+       /* default to INTERFACE_A */
+       if(channel == INTERFACE_ANY) { channel = INTERFACE_A; }
+
+       if (ftdi_set_interface(&ftdic, channel) < 0)
        {
                LOG_ERROR("unable to select FT2232 channel A: %s", ftdic.error_str);
                return ERROR_JTAG_INIT_FAILED;
@@ -2059,8 +2279,6 @@ static int ft2232_init(void)
        uint8_t  buf[1];
        int retval;
        uint32_t bytes_written;
-       const struct ft2232_layout* cur_layout = ft2232_layouts;
-       int i;
 
        if (tap_get_tms_path_len(TAP_IRPAUSE,TAP_IRPAUSE) == 7)
        {
@@ -2071,29 +2289,12 @@ static int ft2232_init(void)
                LOG_DEBUG("ft2232 interface using shortest path jtag state transitions");
 
        }
-       if ((ft2232_layout == NULL) || (ft2232_layout[0] == 0))
-       {
-               ft2232_layout = "usbjtag";
-               LOG_WARNING("No ft2232 layout specified, using default 'usbjtag'");
-       }
-
-       while (cur_layout->name)
-       {
-               if (strcmp(cur_layout->name, ft2232_layout) == 0)
-               {
-                       layout = cur_layout;
-                       break;
-               }
-               cur_layout++;
-       }
-
-       if (!layout)
-       {
-               LOG_ERROR("No matching layout found for %s", ft2232_layout);
+       if (layout == NULL) {
+               LOG_WARNING("No ft2232 layout specified'");
                return ERROR_JTAG_INIT_FAILED;
        }
 
-       for (i = 0; 1; i++)
+       for (int i = 0; 1; i++)
        {
                /*
                 * "more indicates that there are more IDs to try, so we should
@@ -2112,7 +2313,7 @@ static int ft2232_init(void)
                                more, &try_more);
 #elif BUILD_FT2232_LIBFTDI == 1
                retval = ft2232_init_libftdi(ft2232_vid[i], ft2232_pid[i],
-                               more, &try_more);
+                                            more, &try_more, layout->channel);
 #endif
                if (retval >= 0)
                        break;
@@ -2162,6 +2363,7 @@ static int usbjtag_init(void)
 {
        uint8_t  buf[3];
        uint32_t bytes_written;
+       char *ft2232_layout = layout->name;
 
        low_output    = 0x08;
        low_direction = 0x0b;
@@ -2182,6 +2384,11 @@ static int usbjtag_init(void)
        }
        else if (strcmp(ft2232_layout, "evb_lm3s811") == 0)
        {
+               /* There are multiple revisions of LM3S811 eval boards:
+                * - Rev B (and older?) boards have no SWO trace support.
+                * - Rev C boards add ADBUS_6 DBG_ENn and BDBUS_4 SWO_EN;
+                *   they should use the "luminary_icdi" layout instead.
+                */
                nTRST = 0x0;
                nTRSTnOE = 0x00;
                nSRST = 0x20;
@@ -2191,6 +2398,9 @@ static int usbjtag_init(void)
        }
        else if (strcmp(ft2232_layout, "luminary_icdi") == 0)
        {
+               /* Most Luminary eval boards support SWO trace output,
+                * and should use this "luminary_icdi" layout.
+                */
                nTRST = 0x0;
                nTRSTnOE = 0x00;
                nSRST = 0x20;
@@ -2312,6 +2522,73 @@ static int axm0432_jtag_init(void)
        return ERROR_OK;
 }
 
+static int redbee_init(void)
+{
+       uint8_t  buf[3];
+       uint32_t bytes_written;
+
+       low_output    = 0x08;
+       low_direction = 0x2b;
+
+       /* initialize low byte for jtag */
+       /* command "set data bits low byte" */
+       buf[0] = 0x80;
+       /* value (TMS = 1,TCK = 0, TDI = 0, nOE = 0) */
+       buf[2] = low_direction;
+       /* dir (output = 1), TCK/TDI/TMS = out, TDO = in, nOE = out */
+       buf[1] = low_output;
+       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 'redbee' layout");
+               return ERROR_JTAG_INIT_FAILED;
+       }
+
+       nTRST    = 0x08;
+       nTRSTnOE = 0x0;     /* No output enable for TRST*/
+       nSRST    = 0x04;
+       nSRSTnOE = 0x0;     /* No output enable for SRST*/
+
+       high_output    = 0x0;
+       high_direction = 0x0c;
+
+       enum reset_types jtag_reset_config = jtag_get_reset_config();
+       if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
+       {
+               LOG_ERROR("can't set nTRSTOE to push-pull on redbee");
+       }
+       else
+       {
+               high_output |= nTRST;
+       }
+
+       if (jtag_reset_config & RESET_SRST_PUSH_PULL)
+       {
+               LOG_ERROR("can't set nSRST to push-pull on redbee");
+       }
+       else
+       {
+               high_output |= nSRST;
+       }
+
+       /* 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 'redbee' layout");
+               return ERROR_JTAG_INIT_FAILED;
+       }
+
+       return ERROR_OK;
+}
+
 static int jtagkey_init(void)
 {
        uint8_t  buf[3];
@@ -2847,13 +3124,28 @@ COMMAND_HANDLER(ft2232_handle_serial_command)
 
 COMMAND_HANDLER(ft2232_handle_layout_command)
 {
-       if (CMD_ARGC == 0)
-               return ERROR_OK;
+       if (CMD_ARGC != 1) {
+               LOG_ERROR("Need exactly one argument to ft2232_layout");
+               return ERROR_FAIL;
+       }
 
-       ft2232_layout = malloc(strlen(CMD_ARGV[0]) + 1);
-       strcpy(ft2232_layout, CMD_ARGV[0]);
+       if (layout) {
+               LOG_ERROR("already specified ft2232_layout %s",
+                               layout->name);
+               return (strcmp(layout->name, CMD_ARGV[0]) != 0)
+                               ? ERROR_FAIL
+                               : ERROR_OK;
+       }
 
-       return ERROR_OK;
+       for (const struct ft2232_layout *l = ft2232_layouts; l->name; l++) {
+               if (strcmp(l->name, CMD_ARGV[0]) == 0) {
+                       layout = l;
+                       return ERROR_OK;
+               }
+       }
+
+       LOG_ERROR("No FT2232 layout '%s' found", CMD_ARGV[0]);
+       return ERROR_FAIL;
 }
 
 COMMAND_HANDLER(ft2232_handle_vid_pid_command)
@@ -3975,14 +4267,14 @@ static const struct command_registration ft2232_command_handlers[] = {
                .handler = &ft2232_handle_device_desc_command,
                .mode = COMMAND_CONFIG,
                .help = "set the USB device description of the FTDI FT2232 device",
-               .usage = "<description>",
+               .usage = "description_string",
        },
        {
                .name = "ft2232_serial",
                .handler = &ft2232_handle_serial_command,
                .mode = COMMAND_CONFIG,
                .help = "set the serial number of the FTDI FT2232 device",
-               .usage = "<serial#>",
+               .usage = "serial_string",
        },
        {
                .name = "ft2232_layout",
@@ -3990,32 +4282,34 @@ static const struct command_registration ft2232_command_handlers[] = {
                .mode = COMMAND_CONFIG,
                .help = "set the layout of the FT2232 GPIO signals used "
                        "to control output-enables and reset signals",
-               .usage = "<layout>",
+               .usage = "layout_name",
        },
        {
                .name = "ft2232_vid_pid",
                .handler = &ft2232_handle_vid_pid_command,
                .mode = COMMAND_CONFIG,
                .help = "the vendor ID and product ID of the FTDI FT2232 device",
-               .usage = "<vid> <pid> [...]",
+               .usage = "(vid pid)* ",
        },
        {
                .name = "ft2232_latency",
                .handler = &ft2232_handle_latency_command,
                .mode = COMMAND_CONFIG,
                .help = "set the FT2232 latency timer to a new value",
-               .usage = "<vid> <pid> [...]",
+               .usage = "value",
        },
        COMMAND_REGISTRATION_DONE
 };
 
 struct jtag_interface ft2232_interface = {
-               .name = "ft2232",
-               .commands = ft2232_command_handlers,
-               .init = &ft2232_init,
-               .quit = &ft2232_quit,
-               .speed = &ft2232_speed,
-               .speed_div = &ft2232_speed_div,
-               .khz = &ft2232_khz,
-               .execute_queue = &ft2232_execute_queue,
-       };
+       .name = "ft2232",
+       .supported = DEBUG_CAP_TMS_SEQ,
+       .commands = ft2232_command_handlers,
+
+       .init = ft2232_init,
+       .quit = ft2232_quit,
+       .speed = ft2232_speed,
+       .speed_div = ft2232_speed_div,
+       .khz = ft2232_khz,
+       .execute_queue = ft2232_execute_queue,
+};

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)