swd: Remove DAP from parameter list
[openocd.git] / src / jtag / drivers / vsllink.c
index 7533a090e3ab89a28cfb7a6983edfe06afb01183..801de650b1b48258d4608ca9cf56afc5c5bd9f8d 100644 (file)
  *   You should have received a copy of the GNU General Public License     *
  *   along with this program; if not, write to the                         *
  *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
  ***************************************************************************/
 
 /* Versaloon is a programming tool for multiple MCUs.
  * It's distributed under GPLv3.
- * You can find it at http://www.SimonQian.com/en/Versaloon.
+ * You can find it at http://www.Versaloon.com/.
  */
 
 #ifdef HAVE_CONFIG_H
 
 #include <jtag/interface.h>
 #include <jtag/commands.h>
-#include "usb_common.h"
+#include <jtag/swd.h>
+#include <libusb.h>
 
-//#define _VSLLINK_IN_DEBUG_MODE_
-
-static uint16_t vsllink_usb_vid;
-static uint16_t vsllink_usb_pid;
-static uint8_t  vsllink_usb_bulkout;
-static uint8_t  vsllink_usb_bulkin;
-static uint8_t  vsllink_usb_interface;
-static int      VSLLINK_USB_TIMEOUT = 1000;
+#include "versaloon/versaloon_include.h"
+#include "versaloon/versaloon.h"
 
 static int vsllink_tms_offset;
 
-/* Global USB buffers */
-static uint8_t *vsllink_usb_in_buffer;
-static uint8_t *vsllink_usb_out_buffer;
-static int      vsllink_buffer_size    = 128;
-
-/* Constants for Versaloon command */
-#define VERSALOON_GET_INFO                             0x00
-#define VERSALOON_GET_TVCC                             0x01
-
-/* Constants for VSLLink command */
-#define VSLLINK_CMD_CONN                               0x80
-#define VSLLINK_CMD_DISCONN                            0x81
-#define VSLLINK_CMD_SET_SPEED                  0x82
-#define VSLLINK_CMD_SET_PORT                   0x90
-#define VSLLINK_CMD_GET_PORT                   0x91
-#define VSLLINK_CMD_SET_PORTDIR                        0x92
-#define VSLLINK_CMD_HW_JTAGSEQCMD              0xA0
-#define VSLLINK_CMD_HW_JTAGHLCMD               0xA1
-#define VSLLINK_CMD_HW_SWDCMD                  0xA2
-#define VSLLINK_CMD_HW_JTAGRAWCMD              0xA3
-
-#define VSLLINK_CMDJTAGSEQ_TMSBYTE             0x00
-#define VSLLINK_CMDJTAGSEQ_TMSCLOCK            0x40
-#define VSLLINK_CMDJTAGSEQ_SCAN                        0x80
-
-#define VSLLINK_CMDJTAGSEQ_CMDMSK              0xC0
-#define VSLLINK_CMDJTAGSEQ_LENMSK              0x3F
-
-#define JTAG_PINMSK_SRST                               (1 << 0)
-#define JTAG_PINMSK_TRST                               (1 << 1)
-#define JTAG_PINMSK_USR1                               (1 << 2)
-#define JTAG_PINMSK_USR2                               (1 << 3)
-#define JTAG_PINMSK_TCK                                        (1 << 4)
-#define JTAG_PINMSK_TMS                                        (1 << 5)
-#define JTAG_PINMSK_TDI                                        (1 << 6)
-#define JTAG_PINMSK_TDO                                        (1 << 7)
-
 struct pending_scan_result {
        int src_offset;
        int dest_offset;
-       int length; /* Number of bits to read */
-       struct scan_command *command; /* Corresponding scan command */
+       int length;     /* Number of bits to read */
+       struct scan_command *command;   /* Corresponding scan command */
+       uint8_t *ack;
        uint8_t *buffer;
-       bool last; /* indicate the last scan pending */
+       bool last;      /* indicate the last scan pending */
 };
 
 #define MAX_PENDING_SCAN_RESULTS 256
 
 static int pending_scan_results_length;
 static struct pending_scan_result
-               pending_scan_results_buffer[MAX_PENDING_SCAN_RESULTS];
+       pending_scan_results_buffer[MAX_PENDING_SCAN_RESULTS];
 
 /* Queue command functions */
 static void vsllink_end_state(tap_state_t state);
 static void vsllink_state_move(void);
 static void vsllink_path_move(int num_states, tap_state_t *path);
+static void vsllink_tms(int num_bits, const uint8_t *bits);
 static void vsllink_runtest(int num_cycles);
 static void vsllink_stableclocks(int num_cycles, int tms);
 static void vsllink_scan(bool ir_scan, enum scan_type type,
-       uint8_t *buffer, int scan_size, struct scan_command *command);
+               uint8_t *buffer, int scan_size, struct scan_command *command);
 static void vsllink_reset(int trst, int srst);
-static void vsllink_simple_command(uint8_t command);
 
 /* VSLLink tap buffer functions */
 static void vsllink_tap_append_step(int tms, int tdi);
@@ -112,19 +71,20 @@ static void vsllink_tap_ensure_pending(int scans);
 static void vsllink_tap_append_scan(int length, uint8_t *buffer,
                struct scan_command *command);
 
+/* VSLLink SWD functions */
+static int_least32_t vsllink_swd_frequency(int_least32_t hz);
+static int vsllink_swd_switch_seq(enum swd_special_seq seq);
+
 /* VSLLink lowlevel functions */
 struct vsllink {
-       struct usb_dev_handle *usb_handle;
+       struct libusb_context *libusb_ctx;
+       struct libusb_device_handle *usb_device_handle;
 };
 
-static struct vsllink *vsllink_usb_open(void);
+static int vsllink_usb_open(struct vsllink *vsllink);
 static void vsllink_usb_close(struct vsllink *vsllink);
-static int vsllink_usb_message(struct vsllink *vsllink, int out_length,
-                                                               int in_length);
-static int vsllink_usb_write(struct vsllink *vsllink, int out_length);
-static int vsllink_usb_read(struct vsllink *vsllink);
 
-#if defined _DEBUG_USB_COMMS_ || defined _DEBUG_JTAG_IO_
+#if defined _DEBUG_JTAG_IO_
 static void vsllink_debug_buffer(uint8_t *buffer, int length);
 #endif
 
@@ -134,12 +94,9 @@ static uint8_t *tms_buffer;
 static uint8_t *tdi_buffer;
 static uint8_t *tdo_buffer;
 
-static struct vsllink *vsllink_handle;
+static bool swd_mode;
 
-static void reset_command_pointer(void)
-{
-       tap_length = 0;
-}
+static struct vsllink *vsllink_handle;
 
 static int vsllink_execute_queue(void)
 {
@@ -152,14 +109,12 @@ static int vsllink_execute_queue(void)
                " vsllink "
                "-------------------------------------");
 
-       reset_command_pointer();
        while (cmd != NULL) {
                switch (cmd->type) {
                        case JTAG_RUNTEST:
                                DEBUG_JTAG_IO("runtest %i cycles, end in %s",
-                                       cmd->cmd.runtest->num_cycles,
-                                       tap_state_name(cmd->cmd.runtest
-                                                       ->end_state));
+                                               cmd->cmd.runtest->num_cycles,
+                                               tap_state_name(cmd->cmd.runtest->end_state));
 
                                vsllink_end_state(cmd->cmd.runtest->end_state);
                                vsllink_runtest(cmd->cmd.runtest->num_cycles);
@@ -167,51 +122,45 @@ static int vsllink_execute_queue(void)
 
                        case JTAG_TLR_RESET:
                                DEBUG_JTAG_IO("statemove end in %s",
-                                       tap_state_name(cmd->cmd.statemove
-                                                       ->end_state));
+                                               tap_state_name(cmd->cmd.statemove->end_state));
 
-                               vsllink_end_state(cmd->cmd.statemove
-                                                       ->end_state);
+                               vsllink_end_state(cmd->cmd.statemove->end_state);
                                vsllink_state_move();
                                break;
 
                        case JTAG_PATHMOVE:
                                DEBUG_JTAG_IO("pathmove: %i states, end in %s",
-                                       cmd->cmd.pathmove->num_states,
-                                       tap_state_name(cmd->cmd.pathmove
-                                               ->path[cmd->cmd.pathmove
-                                                       ->num_states - 1]));
-
-                               vsllink_path_move(
-                                       cmd->cmd.pathmove->num_states,
-                                       cmd->cmd.pathmove->path);
+                                               cmd->cmd.pathmove->num_states,
+                                               tap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]));
+
+                               vsllink_path_move(cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path);
                                break;
 
                        case JTAG_SCAN:
+                               DEBUG_JTAG_IO("JTAG Scan...");
+
                                vsllink_end_state(cmd->cmd.scan->end_state);
 
                                scan_size = jtag_build_buffer(
-                                       cmd->cmd.scan, &buffer);
+                                               cmd->cmd.scan, &buffer);
 
                                if (cmd->cmd.scan->ir_scan)
                                        DEBUG_JTAG_IO(
-                                               "JTAG Scan write IR(%d bits), "
-                                               "end in %s:",
-                                               scan_size,
-                                               tap_state_name(cmd->cmd.scan
-                                                               ->end_state));
+                                                       "JTAG Scan write IR(%d bits), "
+                                                       "end in %s:",
+                                                       scan_size,
+                                                       tap_state_name(cmd->cmd.scan->end_state));
 
                                else
                                        DEBUG_JTAG_IO(
-                                               "JTAG Scan write DR(%d bits), "
-                                               "end in %s:",
-                                               scan_size,
-                                               tap_state_name(cmd->cmd.scan
-                                                       ->end_state));
+                                                       "JTAG Scan write DR(%d bits), "
+                                                       "end in %s:",
+                                                       scan_size,
+                                                       tap_state_name(cmd->cmd.scan->end_state));
 
 #ifdef _DEBUG_JTAG_IO_
                                vsllink_debug_buffer(buffer,
-                                       DIV_ROUND_UP(scan_size, 8));
+                                               DIV_ROUND_UP(scan_size, 8));
 #endif
 
                                type = jtag_scan_type(cmd->cmd.scan);
@@ -243,7 +192,8 @@ static int vsllink_execute_queue(void)
 
                        case JTAG_STABLECLOCKS:
                                DEBUG_JTAG_IO("add %d clocks",
-                                       cmd->cmd.stableclocks->num_cycles);
+                                               cmd->cmd.stableclocks->num_cycles);
+
                                switch (tap_get_state()) {
                                case TAP_RESET:
                                        /* tms must be '1' to stay
@@ -259,22 +209,28 @@ static int vsllink_execute_queue(void)
                                        /* else, tms should be '0' */
                                        scan_size = 0;
                                        break;
-                                       /* above stable states are OK */
+                               /* above stable states are OK */
                                default:
-                                        LOG_ERROR("jtag_add_clocks() "
-                                               "in non-stable state \"%s\"",
-                                               tap_state_name(tap_get_state())
-                                               );
-                                exit(-1);
+                                       LOG_ERROR("jtag_add_clocks() "
+                                                       "in non-stable state \"%s\"",
+                                                       tap_state_name(tap_get_state())
+                                       );
+                                       exit(-1);
                                }
-                               vsllink_stableclocks(cmd->cmd.stableclocks
-                                               ->num_cycles, scan_size);
+                               vsllink_stableclocks(cmd->cmd.stableclocks->num_cycles, scan_size);
                                break;
 
-                       default:
-                               LOG_ERROR("BUG: unknown JTAG command type "
-                                       "encountered: %d", cmd->type);
-                               exit(-1);
+                               case JTAG_TMS:
+                                       DEBUG_JTAG_IO("add %d jtag tms",
+                                                       cmd->cmd.tms->num_bits);
+
+                                       vsllink_tms(cmd->cmd.tms->num_bits, cmd->cmd.tms->bits);
+                                       break;
+
+                               default:
+                                       LOG_ERROR("BUG: unknown JTAG command type "
+                                                       "encountered: %d", cmd->type);
+                                       exit(-1);
                }
                cmd = cmd->next;
        }
@@ -284,22 +240,13 @@ static int vsllink_execute_queue(void)
 
 static int vsllink_speed(int speed)
 {
-       int result;
-
-       vsllink_usb_out_buffer[0] = VSLLINK_CMD_SET_SPEED;
-       vsllink_usb_out_buffer[1] = (speed >> 0) & 0xff;
-       vsllink_usb_out_buffer[2] = (speed >> 8) & 0xFF;
-
-       result = vsllink_usb_write(vsllink_handle, 3);
-
-       if (result == 3)
+       if (swd_mode) {
+               vsllink_swd_frequency(speed * 1000);
                return ERROR_OK;
-       else {
-               LOG_ERROR("VSLLink setting speed failed (%d)", result);
-               return ERROR_JTAG_DEVICE_ERROR;
        }
 
-       return ERROR_OK;
+       versaloon_interface.adaptors.jtag_raw.config(0, (uint16_t)speed);
+       return versaloon_interface.adaptors.peripheral_commit();
 }
 
 static int vsllink_khz(int khz, int *jtag_speed)
@@ -316,157 +263,121 @@ static int vsllink_speed_div(int jtag_speed, int *khz)
        return ERROR_OK;
 }
 
-static int vsllink_init(void)
+static void vsllink_free_buffer(void)
 {
-       int check_cnt, to_tmp;
-       int result;
-       char version_str[100];
-
-       vsllink_usb_in_buffer = malloc(vsllink_buffer_size);
-       vsllink_usb_out_buffer = malloc(vsllink_buffer_size);
-       if ((vsllink_usb_in_buffer == NULL)
-                       || (vsllink_usb_out_buffer == NULL)) {
-               LOG_ERROR("Not enough memory");
-               exit(-1);
-       }
-
-       vsllink_handle = vsllink_usb_open();
-       if (vsllink_handle == 0) {
-               LOG_ERROR("Can't find USB JTAG Interface!"\
-                               "Please check connection and permissions.");
-               return ERROR_JTAG_INIT_FAILED;
+       if (tdi_buffer != NULL) {
+               free(tdi_buffer);
+               tdi_buffer = NULL;
        }
-       LOG_DEBUG("vsllink found on %04X:%04X",
-                       vsllink_usb_vid, vsllink_usb_pid);
-
-       to_tmp = VSLLINK_USB_TIMEOUT;
-       VSLLINK_USB_TIMEOUT = 100;
-       check_cnt = 0;
-       while (check_cnt < 5) {
-               vsllink_simple_command(VERSALOON_GET_INFO);
-               result = vsllink_usb_read(vsllink_handle);
-
-               if (result > 2) {
-                       vsllink_usb_in_buffer[result] = 0;
-                       vsllink_buffer_size = vsllink_usb_in_buffer[0]
-                                       + (vsllink_usb_in_buffer[1] << 8);
-                       strncpy(version_str, (char *)vsllink_usb_in_buffer + 2,
-                                       sizeof(version_str));
-                       LOG_INFO("%s", version_str);
-
-                       /* free the pre-allocated memory */
-                       free(vsllink_usb_in_buffer);
-                       free(vsllink_usb_out_buffer);
-                       vsllink_usb_in_buffer = NULL;
-                       vsllink_usb_out_buffer = NULL;
-
-                       /* alloc new memory */
-                       vsllink_usb_in_buffer = malloc(vsllink_buffer_size);
-                       vsllink_usb_out_buffer = malloc(vsllink_buffer_size);
-                       if ((vsllink_usb_in_buffer == NULL) ||
-                               (vsllink_usb_out_buffer == NULL)) {
-                               LOG_ERROR("Not enough memory");
-                               exit(-1);
-                       } else
-                               LOG_INFO("buffer size for USB is %d bytes",
-                                                       vsllink_buffer_size);
-
-                       /* alloc tms/tdi/tdo buffer */
-                       tap_buffer_size = (vsllink_buffer_size - 3) / 2;
-                       tms_buffer = (uint8_t *)malloc(tap_buffer_size);
-                       tdi_buffer = (uint8_t *)malloc(tap_buffer_size);
-                       tdo_buffer = (uint8_t *)malloc(tap_buffer_size);
-                       if ((tms_buffer == NULL) || (tdi_buffer == NULL) ||
-                               (tdo_buffer == NULL)) {
-                               LOG_ERROR("Not enough memory");
-                               exit(-1);
-                       }
-                       break;
-               }
-               vsllink_simple_command(VSLLINK_CMD_DISCONN);
-               check_cnt++;
+       if (tdo_buffer != NULL) {
+               free(tdo_buffer);
+               tdo_buffer = NULL;
        }
-       if (check_cnt == 3) {
-               /* Fail to access Versaloon */
-               LOG_ERROR("VSLLink initial failed");
-               exit(-1);
+       if (tms_buffer != NULL) {
+               free(tms_buffer);
+               tms_buffer = NULL;
        }
-       VSLLINK_USB_TIMEOUT = to_tmp;
-
-       /* Some older firmware versions sometimes fail if the
-        * voltage isn't read first.
-        */
-       vsllink_simple_command(VERSALOON_GET_TVCC);
-       result = vsllink_usb_read(vsllink_handle);
-       if (result != 2)
-               LOG_WARNING("Fail to get target voltage");
+}
+
+static int vsllink_quit(void)
+{
+       versaloon_interface.adaptors.gpio.config(0, GPIO_SRST | GPIO_TRST,
+               0, 0, GPIO_SRST | GPIO_TRST);
+       versaloon_interface.adaptors.gpio.fini(0);
+
+       if (swd_mode)
+               versaloon_interface.adaptors.swd.fini(0);
        else
-               LOG_INFO("Target runs at %d mV", vsllink_usb_in_buffer[0] +
-                                       (vsllink_usb_in_buffer[1] << 8));
-
-       /* connect to vsllink */
-       vsllink_usb_out_buffer[0] = VSLLINK_CMD_CONN;
-       vsllink_usb_out_buffer[1] = 1;
-       vsllink_usb_message(vsllink_handle, 2, 0);
-       if (vsllink_usb_read(vsllink_handle) > 2) {
-               strncpy(version_str, (char *)vsllink_usb_in_buffer + 2,
-                               sizeof(version_str));
-               LOG_INFO("%s", version_str);
-       }
+               versaloon_interface.adaptors.jtag_raw.fini(0);
 
-       /* Set SRST and TRST to output, Set USR1 and USR2 to input */
-       vsllink_usb_out_buffer[0] = VSLLINK_CMD_SET_PORTDIR;
-       vsllink_usb_out_buffer[1] = JTAG_PINMSK_SRST | JTAG_PINMSK_TRST
-                               | JTAG_PINMSK_USR1 | JTAG_PINMSK_USR2;
-       vsllink_usb_out_buffer[2] = JTAG_PINMSK_SRST | JTAG_PINMSK_TRST;
-       if (vsllink_usb_write(vsllink_handle, 3) != 3) {
-               LOG_ERROR("VSLLink USB send data error");
-               exit(-1);
+       versaloon_interface.adaptors.peripheral_commit();
+       versaloon_interface.fini();
+
+       vsllink_free_buffer();
+       vsllink_usb_close(vsllink_handle);
+
+       free(vsllink_handle);
+
+       return ERROR_OK;
+}
+
+static int vsllink_interface_init(void)
+{
+       vsllink_handle = malloc(sizeof(struct vsllink));
+       if (NULL == vsllink_handle) {
+               LOG_ERROR("unable to allocate memory");
+               return ERROR_FAIL;
        }
 
-       vsllink_reset(0, 0);
+       libusb_init(&vsllink_handle->libusb_ctx);
 
-       LOG_INFO("VSLLink Interface ready");
+       if (ERROR_OK != vsllink_usb_open(vsllink_handle)) {
+               LOG_ERROR("Can't find USB JTAG Interface!" \
+                       "Please check connection and permissions.");
+               return ERROR_JTAG_INIT_FAILED;
+       }
+       LOG_DEBUG("vsllink found on %04X:%04X",
+               versaloon_interface.usb_setting.vid,
+               versaloon_interface.usb_setting.pid);
+       versaloon_usb_device_handle = vsllink_handle->usb_device_handle;
 
-       vsllink_tap_init();
+       if (ERROR_OK != versaloon_interface.init())
+               return ERROR_FAIL;
+       if (versaloon_interface.usb_setting.buf_size < 32) {
+               versaloon_interface.fini();
+               return ERROR_FAIL;
+       }
 
        return ERROR_OK;
 }
 
-static int vsllink_quit(void)
+static int vsllink_init(void)
 {
-       if ((vsllink_usb_in_buffer != NULL)
-                       && (vsllink_usb_out_buffer != NULL)) {
-               // Set all pins to input
-               vsllink_usb_out_buffer[0] = VSLLINK_CMD_SET_PORTDIR;
-               vsllink_usb_out_buffer[1] = JTAG_PINMSK_SRST | JTAG_PINMSK_TRST
-                               | JTAG_PINMSK_USR1 | JTAG_PINMSK_USR2;
-               vsllink_usb_out_buffer[2] = 0;
-               if (vsllink_usb_write(vsllink_handle, 3) != 3) {
-                       LOG_ERROR("VSLLink USB send data error");
-                       exit(-1);
+       int retval = vsllink_interface_init();
+       if (ERROR_OK != retval)
+               return retval;
+
+       versaloon_interface.adaptors.gpio.init(0);
+       versaloon_interface.adaptors.gpio.config(0, GPIO_SRST, 0, GPIO_SRST,
+               GPIO_SRST);
+       versaloon_interface.adaptors.delay.delayms(100);
+       versaloon_interface.adaptors.peripheral_commit();
+
+       if (swd_mode) {
+               versaloon_interface.adaptors.gpio.config(0, GPIO_TRST, 0,
+                       GPIO_TRST, GPIO_TRST);
+               versaloon_interface.adaptors.swd.init(0);
+               vsllink_swd_frequency(jtag_get_speed_khz() * 1000);
+               vsllink_swd_switch_seq(JTAG_TO_SWD);
+
+       } else {
+               /* malloc buffer size for tap */
+               tap_buffer_size = versaloon_interface.usb_setting.buf_size / 2 - 32;
+               vsllink_free_buffer();
+               tdi_buffer = malloc(tap_buffer_size);
+               tdo_buffer = malloc(tap_buffer_size);
+               tms_buffer = malloc(tap_buffer_size);
+               if ((NULL == tdi_buffer) || (NULL == tdo_buffer) || (NULL == tms_buffer)) {
+                       vsllink_quit();
+                       return ERROR_FAIL;
                }
 
-               // disconnect
-               vsllink_simple_command(VSLLINK_CMD_DISCONN);
-               vsllink_usb_close(vsllink_handle);
-               vsllink_handle = NULL;
+               versaloon_interface.adaptors.jtag_raw.init(0);
+               versaloon_interface.adaptors.jtag_raw.config(0, jtag_get_speed_khz());
+               versaloon_interface.adaptors.gpio.config(0, GPIO_SRST | GPIO_TRST,
+                       GPIO_TRST, GPIO_SRST, GPIO_SRST);
        }
 
-       if (vsllink_usb_in_buffer != NULL) {
-               free(vsllink_usb_in_buffer);
-               vsllink_usb_in_buffer = NULL;
-       }
-       if (vsllink_usb_out_buffer != NULL) {
-               free(vsllink_usb_out_buffer);
-               vsllink_usb_out_buffer = NULL;
-       }
+       if (ERROR_OK != versaloon_interface.adaptors.peripheral_commit())
+               return ERROR_FAIL;
 
+       vsllink_reset(0, 0);
+       vsllink_tap_init();
        return ERROR_OK;
 }
 
-/***************************************************************************/
-/* Queue command implementations */
+/**************************************************************************
+ * Queue command implementations */
 
 static void vsllink_end_state(tap_state_t state)
 {
@@ -483,9 +394,9 @@ static void vsllink_state_move(void)
 {
        int i;
        uint8_t tms_scan = tap_get_tms_path(tap_get_state(),
-                                       tap_get_end_state());
+                       tap_get_end_state());
        uint8_t tms_scan_bits = tap_get_tms_path_len(tap_get_state(),
-                                       tap_get_end_state());
+                       tap_get_end_state());
 
        for (i = 0; i < tms_scan_bits; i++)
                vsllink_tap_append_step((tms_scan >> i) & 1, 0);
@@ -502,8 +413,8 @@ static void vsllink_path_move(int num_states, tap_state_t *path)
                        vsllink_tap_append_step(1, 0);
                else {
                        LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
-                                               tap_state_name(tap_get_state()),
-                                               tap_state_name(path[i]));
+                               tap_state_name(tap_get_state()),
+                               tap_state_name(path[i]));
                        exit(-1);
                }
 
@@ -513,6 +424,12 @@ static void vsllink_path_move(int num_states, tap_state_t *path)
        tap_set_end_state(tap_get_state());
 }
 
+static void vsllink_tms(int num_bits, const uint8_t *bits)
+{
+       for (int i = 0; i < num_bits; i++)
+               vsllink_tap_append_step((bits[i / 8] >> (i % 8)) & 1, 0);
+}
+
 static void vsllink_stableclocks(int num_cycles, int tms)
 {
        while (num_cycles > 0) {
@@ -533,15 +450,15 @@ static void vsllink_runtest(int num_cycles)
 
        vsllink_stableclocks(num_cycles, 0);
 
-       // post-process
-       // set end_state
+       /* post-process */
+       /* set end_state */
        vsllink_end_state(saved_end_state);
        if (tap_get_end_state() != tap_get_end_state())
                vsllink_state_move();
 }
 
 static void vsllink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer,
-                               int scan_size, struct scan_command *command)
+       int scan_size, struct scan_command *command)
 {
        tap_state_t saved_end_state;
 
@@ -569,117 +486,95 @@ static void vsllink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer,
 
 static void vsllink_reset(int trst, int srst)
 {
-       int result;
-
        LOG_DEBUG("trst: %i, srst: %i", trst, srst);
 
-       /* Signals are active low */
-       vsllink_usb_out_buffer[0] = VSLLINK_CMD_SET_PORT;
-       vsllink_usb_out_buffer[1] = JTAG_PINMSK_SRST | JTAG_PINMSK_TRST;
-       vsllink_usb_out_buffer[2] = 0;
-       if (srst == 0)
-               vsllink_usb_out_buffer[2] |= JTAG_PINMSK_SRST;
-       if (trst == 0)
-               vsllink_usb_out_buffer[2] |= JTAG_PINMSK_TRST;
-
-       result = vsllink_usb_write(vsllink_handle, 3);
-       if (result != 3)
-               LOG_ERROR("VSLLink command VSLLINK_CMD_SET_PORT failed (%d)",
-                               result);
-}
-
-static void vsllink_simple_command(uint8_t command)
-{
-       int result;
-
-       DEBUG_JTAG_IO("0x%02x", command);
+       if (!srst)
+               versaloon_interface.adaptors.gpio.config(0, GPIO_SRST, 0, GPIO_SRST, GPIO_SRST);
+       else
+               versaloon_interface.adaptors.gpio.config(0, GPIO_SRST, GPIO_SRST, 0, 0);
 
-       vsllink_usb_out_buffer[0] = command;
-       result = vsllink_usb_write(vsllink_handle, 1);
+       if (!swd_mode) {
+               if (!trst)
+                       versaloon_interface.adaptors.gpio.out(0, GPIO_TRST, GPIO_TRST);
+               else
+                       versaloon_interface.adaptors.gpio.out(0, GPIO_TRST, 0);
+       }
 
-       if (result != 1)
-               LOG_ERROR("VSLLink command 0x%02x failed (%d)",
-                               command, result);
+       versaloon_interface.adaptors.peripheral_commit();
 }
 
-COMMAND_HANDLER(vsllink_handle_mode_command)
+COMMAND_HANDLER(vsllink_handle_usb_vid_command)
 {
-       if (CMD_ARGC != 1) {
-               LOG_ERROR("parameter error, "
-                                       "should be one parameter for mode");
-               return ERROR_FAIL;
-       }
+       if (CMD_ARGC != 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
+       COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0],
+               versaloon_interface.usb_setting.vid);
        return ERROR_OK;
 }
 
-COMMAND_HANDLER(vsllink_handle_usb_vid_command)
+COMMAND_HANDLER(vsllink_handle_usb_pid_command)
 {
-       if (CMD_ARGC != 1) {
-               LOG_ERROR("parameter error, "
-                                       "should be one parameter for VID");
-               return ERROR_OK;
-       }
-
-       COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], vsllink_usb_vid);
+       if (CMD_ARGC != 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0],
+               versaloon_interface.usb_setting.pid);
        return ERROR_OK;
 }
 
-COMMAND_HANDLER(vsllink_handle_usb_pid_command)
+COMMAND_HANDLER(vsllink_handle_usb_serial_command)
 {
-       if (CMD_ARGC != 1) {
-               LOG_ERROR("parameter error, "
-                                       "should be one parameter for PID");
-               return ERROR_OK;
-       }
-       COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], vsllink_usb_pid);
+       if (CMD_ARGC > 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       free(versaloon_interface.usb_setting.serialstring);
+
+       if (CMD_ARGC == 1)
+               versaloon_interface.usb_setting.serialstring = strdup(CMD_ARGV[0]);
+       else
+               versaloon_interface.usb_setting.serialstring = NULL;
+
        return ERROR_OK;
 }
 
 COMMAND_HANDLER(vsllink_handle_usb_bulkin_command)
 {
-       if (CMD_ARGC != 1) {
-               LOG_ERROR("parameter error, "
-                       "should be one parameter for BULKIN endpoint");
-               return ERROR_OK;
-       }
+       if (CMD_ARGC != 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
-       COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], vsllink_usb_bulkin);
+       COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],
+               versaloon_interface.usb_setting.ep_in);
 
-       vsllink_usb_bulkin |= 0x80;
+       versaloon_interface.usb_setting.ep_in |= 0x80;
 
        return ERROR_OK;
 }
 
 COMMAND_HANDLER(vsllink_handle_usb_bulkout_command)
 {
-       if (CMD_ARGC != 1) {
-               LOG_ERROR("parameter error, "
-                       "should be one parameter for BULKOUT endpoint");
-               return ERROR_OK;
-       }
+       if (CMD_ARGC != 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
-       COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], vsllink_usb_bulkout);
+       COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],
+               versaloon_interface.usb_setting.ep_out);
 
-       vsllink_usb_bulkout &= ~0x80;
+       versaloon_interface.usb_setting.ep_out &= ~0x80;
 
        return ERROR_OK;
 }
 
 COMMAND_HANDLER(vsllink_handle_usb_interface_command)
 {
-       if (CMD_ARGC != 1) {
-               LOG_ERROR("parameter error, "
-                       "should be one parameter for interface number");
-               return ERROR_OK;
-       }
+       if (CMD_ARGC != 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
-       COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], vsllink_usb_interface);
+       COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],
+               versaloon_interface.usb_setting.interface);
        return ERROR_OK;
 }
 
-/***************************************************************************/
-/* VSLLink tap functions */
+/**************************************************************************
+ * VSLLink tap functions */
 
 static void vsllink_tap_init(void)
 {
@@ -691,7 +586,7 @@ static void vsllink_tap_init(void)
 static void vsllink_tap_ensure_pending(int scans)
 {
        int available_scans =
-                       MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;
+               MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;
 
        if (scans > available_scans)
                vsllink_tap_execute();
@@ -721,7 +616,7 @@ static void vsllink_tap_append_step(int tms, int tdi)
 }
 
 static void vsllink_tap_append_scan(int length, uint8_t *buffer,
-               struct scan_command *command)
+       struct scan_command *command)
 {
        struct pending_scan_result *pending_scan_result;
        int len_tmp, len_all, i;
@@ -730,8 +625,8 @@ static void vsllink_tap_append_scan(int length, uint8_t *buffer,
        while (len_all < length) {
                vsllink_tap_ensure_pending(1);
                pending_scan_result =
-                               &pending_scan_results_buffer[
-                                       pending_scan_results_length];
+                       &pending_scan_results_buffer[
+                               pending_scan_results_length];
 
                if ((length - len_all) > (tap_buffer_size * 8 - tap_length)) {
                        /* Use all memory available
@@ -751,103 +646,29 @@ static void vsllink_tap_append_scan(int length, uint8_t *buffer,
 
                for (i = 0; i < len_tmp; i++) {
                        vsllink_tap_append_step(((len_all + i) < length-1
-                                               ? 0 : 1),
-                                       (buffer[(len_all + i)/8]
-                                               >> ((len_all + i)%8)) & 1);
+                                                ? 0 : 1),
+                               (buffer[(len_all + i)/8]
+                                >> ((len_all + i)%8)) & 1);
                }
 
                len_all += len_tmp;
        }
 }
 
-static int vsllink_tap_execute(void)
+static int vsllink_jtag_execute(void)
 {
-       int byte_length;
        int i;
        int result;
 
        if (tap_length <= 0)
                return ERROR_OK;
 
-       /* Pad data so that tap_length is divisible by 8 */
-       if ((tap_length % 8) != 0) {
-               if (vsllink_tms_offset > 0) {
-                       /* append tms:0 at vsllink_tms_offset,
-                        * which is in Pause
-                        */
-                       int start_pos = DIV_ROUND_UP(tap_length, 8) - 1;
-                       int end_pos = DIV_ROUND_UP(vsllink_tms_offset, 8) - 1;
-                       int shift_cnt = (start_pos + 1) * 8 - tap_length;
-                       uint8_t last_mask = ~(
-                               (1 << (vsllink_tms_offset % 8)) - 1);
-
-                       while (1) {
-                               if (start_pos == end_pos) {
-                                       tms_buffer[start_pos] =
-                                               (tms_buffer[start_pos]
-                                                       & ~last_mask)
-                                               | ((tms_buffer[start_pos]
-                                                               & last_mask)
-                                                       << shift_cnt);
-                                       tdi_buffer[start_pos] =
-                                               (tdi_buffer[start_pos]
-                                                       & ~last_mask)
-                                               |
-                                               ((tdi_buffer[start_pos]
-                                                               & last_mask)
-                                                               << shift_cnt);
-                                       break;
-                               } else if (start_pos == (end_pos + 1)) {
-                                       tms_buffer[start_pos] =
-                                               (tms_buffer[start_pos]
-                                                       << shift_cnt) |
-                                               ((tms_buffer[start_pos - 1]
-                                                               & last_mask)
-                                                       >> (8 - shift_cnt));
-                                       tdi_buffer[start_pos] =
-                                               (tdi_buffer[start_pos]
-                                                       << shift_cnt) |
-                                               ((tdi_buffer[start_pos - 1]
-                                                               & last_mask)
-                                                       >> (8 - shift_cnt));
-                               } else {
-                                       tms_buffer[start_pos] =
-                                               (tms_buffer[start_pos]
-                                                       << shift_cnt) |
-                                               (tms_buffer[start_pos - 1]
-                                                       >> (8 - shift_cnt));
-                                       tdi_buffer[start_pos] =
-                                               (tdi_buffer[start_pos]
-                                                       << shift_cnt) |
-                                               (tdi_buffer[start_pos - 1]
-                                                       >> (8 - shift_cnt));
-                               }
-                               start_pos--;
-                       }
-                       tap_length = DIV_ROUND_UP(tap_length, 8) * 8;
-               } else {
-                       /* append data at last */
-                       while ((tap_length % 8) != 0) {
-                               vsllink_tap_append_step(
-                                       (tap_get_state() == TAP_RESET)
-                                               ? 1 : 0, 0);
-                       }
-               }
-       }
-       byte_length = tap_length / 8;
+       versaloon_interface.adaptors.jtag_raw.execute(0, tdi_buffer, tms_buffer,
+               tdo_buffer, tap_length);
 
-       vsllink_usb_out_buffer[0] = VSLLINK_CMD_HW_JTAGRAWCMD;
-       vsllink_usb_out_buffer[1] = ((byte_length * 2 + 3) >> 0) & 0xff;
-       vsllink_usb_out_buffer[2] = ((byte_length * 2 + 3) >> 8) & 0xff;
+       result = versaloon_interface.adaptors.peripheral_commit();
 
-       memcpy(&vsllink_usb_out_buffer[3], tdi_buffer, byte_length);
-       memcpy(&vsllink_usb_out_buffer[3 + byte_length], tms_buffer,
-                       byte_length);
-
-       result = vsllink_usb_message(vsllink_handle, 3 + 2 * byte_length,
-                       byte_length);
-
-       if (result == byte_length) {
+       if (result == ERROR_OK) {
                for (i = 0; i < pending_scan_results_length; i++) {
                        struct pending_scan_result *pending_scan_result =
                                &pending_scan_results_buffer[i];
@@ -860,19 +681,19 @@ static int vsllink_tap_execute(void)
                        struct scan_command *command;
 
                        command = pending_scan_result->command;
-                       buf_set_buf(vsllink_usb_in_buffer, src_first, buffer,
-                                                       dest_first, length);
+                       buf_set_buf(tdo_buffer, src_first, buffer, dest_first, length);
 
-                       DEBUG_JTAG_IO("JTAG scan read(%d bits, from %d bits):",
-                                       length, dest_first);
 #ifdef _DEBUG_JTAG_IO_
+                       DEBUG_JTAG_IO(
+                               "JTAG scan read(%d bits, from src %d bits to dest %d bits):",
+                               length, src_first, dest_first);
                        vsllink_debug_buffer(buffer + dest_first / 8,
-                                       DIV_ROUND_UP(length, 7));
+                               DIV_ROUND_UP(length, 7));
 #endif
 
                        if (last) {
                                if (jtag_read_buffer(buffer, command)
-                                               != ERROR_OK) {
+                                   != ERROR_OK) {
                                        vsllink_tap_init();
                                        return ERROR_JTAG_QUEUE_FAILED;
                                }
@@ -882,8 +703,7 @@ static int vsllink_tap_execute(void)
                        }
                }
        } else {
-               LOG_ERROR("vsllink_tap_execute, wrong result %d, expected %d",
-                                       result, byte_length);
+               LOG_ERROR("vsllink_jtag_execute failure");
                return ERROR_JTAG_QUEUE_FAILED;
        }
 
@@ -892,145 +712,192 @@ static int vsllink_tap_execute(void)
        return ERROR_OK;
 }
 
-/*****************************************************************************/
-/* VSLLink USB low-level functions */
+static int vsllink_tap_execute(void)
+{
+       if (swd_mode)
+               return ERROR_OK;
+
+       return vsllink_jtag_execute();
+}
 
-static struct vsllink *vsllink_usb_open(void)
+static int vsllink_swd_init(void)
 {
-       usb_init();
-
-       const uint16_t vids[] = { vsllink_usb_vid, 0 };
-       const uint16_t pids[] = { vsllink_usb_pid, 0 };
-       struct usb_dev_handle *dev;
-       if (jtag_usb_open(vids, pids, &dev) != ERROR_OK)
-               return NULL;
-
-       /* usb_set_configuration required under win32 */
-       struct usb_device *udev = usb_device(dev);
-       int ret = usb_set_configuration(dev,
-                       udev->config[0].bConfigurationValue);
-       if (ret != 0) {
-               LOG_ERROR("fail to set configuration to %d (error %d)."
-                               "Not enough permissions for the device?",
-                               udev->config[0].bConfigurationValue, ret);
-               return NULL;
-       }
-       ret = usb_claim_interface(dev, vsllink_usb_interface);
-       if (ret != 0) {
-               LOG_ERROR("fail to claim interface %d, %d returned",
-                               vsllink_usb_interface, ret);
-               return NULL;
-       }
-#if 0
-       /*
-       * This makes problems under Mac OS X. And is not needed
-       * under Windows. Hopefully this will not break a linux build
-       */
-       usb_set_altinterface(dev, 0);
-#endif
+       LOG_INFO("VSLLink SWD mode enabled");
+       swd_mode = true;
 
-       struct vsllink *result = malloc(sizeof(struct vsllink));
-       result->usb_handle = dev;
-       return result;
+       return ERROR_OK;
 }
 
-static void vsllink_usb_close(struct vsllink *vsllink)
+static int_least32_t vsllink_swd_frequency(int_least32_t hz)
 {
-       int ret;
+       const int_least32_t delay2hz[] = {
+               1850000, 235000, 130000, 102000, 85000, 72000
+       };
 
-       ret = usb_release_interface(vsllink->usb_handle,
-                       vsllink_usb_interface);
-       if (ret != 0) {
-               LOG_ERROR("fail to release interface %d, %d returned",
-                                       vsllink_usb_interface, ret);
-               exit(-1);
+       if (hz > 0) {
+               uint16_t delay = UINT16_MAX;
+
+               for (uint16_t i = 0; i < ARRAY_SIZE(delay2hz); i++) {
+                       if (hz >= delay2hz[i]) {
+                               hz = delay2hz[i];
+                               delay = i;
+                               break;
+                       }
+               }
+
+               if (delay == UINT16_MAX)
+                       delay = (500000 / hz) - 1;
+
+               /* Calculate retry count after a WAIT response. This will give
+                * a retry timeout at about ~250 ms. 54 is the number of bits
+                * found in a transaction. */
+               uint16_t retry_count = 250 * hz / 1000 / 54;
+
+               LOG_DEBUG("SWD delay: %d, retry count: %d", delay, retry_count);
+
+               versaloon_interface.adaptors.swd.config(0, 2, retry_count, delay);
        }
 
-       ret = usb_close(vsllink->usb_handle);
-       if (ret != 0) {
-               LOG_ERROR("fail to close usb, %d returned", ret);
-               exit(-1);
+       return hz;
+}
+
+static int vsllink_swd_switch_seq(enum swd_special_seq seq)
+{
+       switch (seq) {
+       case LINE_RESET:
+               LOG_DEBUG("SWD line reset");
+               versaloon_interface.adaptors.swd.seqout(0, swd_seq_line_reset,
+                               swd_seq_line_reset_len);
+               break;
+       case JTAG_TO_SWD:
+               LOG_DEBUG("JTAG-to-SWD");
+               versaloon_interface.adaptors.swd.seqout(0, swd_seq_jtag_to_swd,
+                               swd_seq_jtag_to_swd_len);
+               break;
+       case SWD_TO_JTAG:
+               LOG_DEBUG("SWD-to-JTAG");
+               versaloon_interface.adaptors.swd.seqout(0, swd_seq_swd_to_jtag,
+                               swd_seq_swd_to_jtag_len);
+               break;
+       default:
+               LOG_ERROR("Sequence %d not supported", seq);
+               return ERROR_FAIL;
        }
 
-       free(vsllink);
+       return ERROR_OK;
 }
 
-/* Send a message and receive the reply. */
-static int vsllink_usb_message(struct vsllink *vsllink, int out_length,
-                                                               int in_length)
+static void vsllink_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
 {
-       int result;
+       versaloon_interface.adaptors.swd.transact(0, cmd, value, NULL);
+}
 
-       result = vsllink_usb_write(vsllink, out_length);
-       if (result == out_length) {
-               if (in_length > 0) {
-                       result = vsllink_usb_read(vsllink);
-                       if (result == in_length)
-                               return result;
-                       else {
-                               LOG_ERROR("usb_bulk_read failed "
-                                       "(requested=%d, result=%d)",
-                                                       in_length, result);
-                               return -1;
-                       }
-               }
-               return 0;
-       } else {
-               LOG_ERROR("usb_bulk_write failed (requested=%d, result=%d)",
-                                       out_length, result);
-               return -1;
-       }
+static void vsllink_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
+{
+       versaloon_interface.adaptors.swd.transact(0, cmd, &value, NULL);
 }
 
-/* Write data from out_buffer to USB. */
-static int vsllink_usb_write(struct vsllink *vsllink, int out_length)
+static int vsllink_swd_run_queue(void)
 {
-       int result;
+       return versaloon_interface.adaptors.peripheral_commit();
+}
 
-       if (out_length > vsllink_buffer_size) {
-               LOG_ERROR("vsllink_write illegal out_length=%d (max=%d)",
-                                       out_length, vsllink_buffer_size);
-               return -1;
-       }
+/****************************************************************************
+ * VSLLink USB low-level functions */
 
-       result = usb_bulk_write(vsllink->usb_handle, vsllink_usb_bulkout,
-               (char *)vsllink_usb_out_buffer, out_length,
-                               VSLLINK_USB_TIMEOUT);
+static int vsllink_check_usb_strings(
+       struct libusb_device_handle *usb_device_handle,
+       struct libusb_device_descriptor *usb_desc)
+{
+       char desc_string[256];
+       int retval;
 
-       DEBUG_JTAG_IO("vsllink_usb_write, out_length = %d, result = %d",
-                                       out_length, result);
+       if (NULL != versaloon_interface.usb_setting.serialstring) {
+               retval = libusb_get_string_descriptor_ascii(usb_device_handle,
+                       usb_desc->iSerialNumber, (unsigned char *)desc_string,
+                       sizeof(desc_string));
+               if (retval < 0)
+                       return ERROR_FAIL;
 
-#ifdef _DEBUG_USB_COMMS_
-       LOG_DEBUG("USB out:");
-       vsllink_debug_buffer(vsllink_usb_out_buffer, out_length);
-#endif
+               if (strncmp(desc_string, versaloon_interface.usb_setting.serialstring,
+                               sizeof(desc_string)))
+                       return ERROR_FAIL;
+       }
 
-#ifdef _VSLLINK_IN_DEBUG_MODE_
-       usleep(100000);
-#endif
+       retval = libusb_get_string_descriptor_ascii(usb_device_handle,
+               usb_desc->iProduct, (unsigned char *)desc_string,
+               sizeof(desc_string));
+       if (retval < 0)
+               return ERROR_FAIL;
 
-       return result;
+       if (strstr(desc_string, "Versaloon") == NULL)
+               return ERROR_FAIL;
+
+       return ERROR_OK;
 }
 
-/* Read data from USB into in_buffer. */
-static int vsllink_usb_read(struct vsllink *vsllink)
+static int vsllink_usb_open(struct vsllink *vsllink)
 {
-       int result = usb_bulk_read(vsllink->usb_handle, vsllink_usb_bulkin,
-               (char *)vsllink_usb_in_buffer, vsllink_buffer_size,
-               VSLLINK_USB_TIMEOUT);
+       ssize_t num_devices, i;
+       libusb_device **usb_devices;
+       struct libusb_device_descriptor usb_desc;
+       struct libusb_device_handle *usb_device_handle;
+       int retval;
 
-       DEBUG_JTAG_IO("vsllink_usb_read, result = %d", result);
+       num_devices = libusb_get_device_list(vsllink->libusb_ctx, &usb_devices);
 
-#ifdef _DEBUG_USB_COMMS_
-       LOG_DEBUG("USB in:");
-       vsllink_debug_buffer(vsllink_usb_in_buffer, result);
-#endif
-       return result;
+       if (num_devices <= 0)
+               return ERROR_FAIL;
+
+       for (i = 0; i < num_devices; i++) {
+               libusb_device *device = usb_devices[i];
+
+               retval = libusb_get_device_descriptor(device, &usb_desc);
+               if (retval != 0)
+                       continue;
+
+               if (usb_desc.idVendor != versaloon_interface.usb_setting.vid ||
+                       usb_desc.idProduct != versaloon_interface.usb_setting.pid)
+                       continue;
+
+               retval = libusb_open(device, &usb_device_handle);
+               if (retval != 0)
+                       continue;
+
+               retval = vsllink_check_usb_strings(usb_device_handle, &usb_desc);
+               if (ERROR_OK == retval)
+                       break;
+
+               libusb_close(usb_device_handle);
+       }
+
+       libusb_free_device_list(usb_devices, 1);
+
+       if (i == num_devices)
+               return ERROR_FAIL;
+
+       retval = libusb_claim_interface(usb_device_handle,
+               versaloon_interface.usb_setting.interface);
+       if (retval != 0) {
+               LOG_ERROR("unable to claim interface");
+               libusb_close(usb_device_handle);
+               return ERROR_FAIL;
+       }
+
+       vsllink->usb_device_handle = usb_device_handle;
+       return ERROR_OK;
+}
+
+static void vsllink_usb_close(struct vsllink *vsllink)
+{
+       libusb_release_interface(vsllink->usb_device_handle,
+               versaloon_interface.usb_setting.interface);
+       libusb_close(vsllink->usb_device_handle);
 }
 
 #define BYTES_PER_LINE  16
 
-#if defined _DEBUG_USB_COMMS_ || defined _DEBUG_JTAG_IO_
+#if defined _DEBUG_JTAG_IO_
 static void vsllink_debug_buffer(uint8_t *buffer, int length)
 {
        char line[81];
@@ -1047,7 +914,7 @@ static void vsllink_debug_buffer(uint8_t *buffer, int length)
                LOG_DEBUG("%s", line);
        }
 }
-#endif /* _DEBUG_USB_COMMS_ || _DEBUG_JTAG_IO_ */
+#endif /* _DEBUG_JTAG_IO_ */
 
 static const struct command_registration vsllink_command_handlers[] = {
        {
@@ -1060,6 +927,11 @@ static const struct command_registration vsllink_command_handlers[] = {
                .handler = &vsllink_handle_usb_pid_command,
                .mode = COMMAND_CONFIG,
        },
+       {
+               .name = "vsllink_usb_serial",
+               .handler = &vsllink_handle_usb_serial_command,
+               .mode = COMMAND_CONFIG,
+       },
        {
                .name = "vsllink_usb_bulkin",
                .handler = &vsllink_handle_usb_bulkin_command,
@@ -1075,17 +947,26 @@ static const struct command_registration vsllink_command_handlers[] = {
                .handler = &vsllink_handle_usb_interface_command,
                .mode = COMMAND_CONFIG,
        },
-       {
-               .name = "vsllink_mode",
-               .handler = &vsllink_handle_mode_command,
-               .mode = COMMAND_CONFIG,
-       },
        COMMAND_REGISTRATION_DONE
 };
 
+static const char * const vsllink_transports[] = {"jtag", "swd", NULL};
+
+static const struct swd_driver vsllink_swd_driver = {
+       .init = vsllink_swd_init,
+       .frequency = vsllink_swd_frequency,
+       .switch_seq = vsllink_swd_switch_seq,
+       .read_reg = vsllink_swd_read_reg,
+       .write_reg = vsllink_swd_write_reg,
+       .run = vsllink_swd_run_queue,
+};
+
 struct jtag_interface vsllink_interface = {
        .name = "vsllink",
+       .supported = DEBUG_CAP_TMS_SEQ,
        .commands = vsllink_command_handlers,
+       .transports = vsllink_transports,
+       .swd = &vsllink_swd_driver,
 
        .init = vsllink_init,
        .quit = vsllink_quit,

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)