drivers/vsllink: add help and usage to commands
[openocd.git] / src / jtag / drivers / vsllink.c
index 451d5f8f05328c46d07421788e223411a5c95cb0..ea9152c090b93b3c53d9bb3d3e7236a798e4e83f 100644 (file)
  *   GNU General Public License for more details.                          *
  *                                                                         *
  *   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.             *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  ***************************************************************************/
 
 /* 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"
-
-//#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;
-
-static int vsllink_tms_offset = 0;
-
-/* Global USB buffers */
-static uint8_t* vsllink_usb_in_buffer  = NULL;
-static uint8_t* vsllink_usb_out_buffer = NULL;
-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)
+#include <jtag/swd.h>
+#include <libusb.h>
+
+#include "versaloon/versaloon_include.h"
+#include "versaloon/versaloon.h"
+
+static int vsllink_tms_offset;
 
 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];
+static struct pending_scan_result
+       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);
+static void vsllink_scan(bool ir_scan, enum scan_type type,
+               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);
 static void vsllink_tap_init(void);
 static int  vsllink_tap_execute(void);
 static void vsllink_tap_ensure_pending(int scans);
-static void vsllink_tap_append_scan(int length, uint8_t *buffer, \
-                                                                       struct scan_command *command);
+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
 
-static int tap_length = 0;
-static int tap_buffer_size = 0;
-static uint8_t *tms_buffer = NULL;
-static uint8_t *tdi_buffer = NULL;
-static uint8_t *tdo_buffer = NULL;
+static int tap_length;
+static int tap_buffer_size;
+static uint8_t *tms_buffer;
+static uint8_t *tdi_buffer;
+static uint8_t *tdo_buffer;
 
-static struct vsllink* vsllink_handle = NULL;
+static bool swd_mode;
 
-static void reset_command_pointer(void)
-{
-       tap_length = 0;
-}
+static struct vsllink *vsllink_handle;
 
 static int vsllink_execute_queue(void)
 {
@@ -148,80 +103,83 @@ static int vsllink_execute_queue(void)
        enum scan_type type;
        uint8_t *buffer;
 
-       DEBUG_JTAG_IO(  "-------------------------------------"
-                                       " vsllink "
-                                       "-------------------------------------");
+       DEBUG_JTAG_IO("-------------------------------------"
+               " vsllink "
+               "-------------------------------------");
 
-       reset_command_pointer();
-       while (cmd != NULL)
-       {
-               switch (cmd->type)
-               {
+       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));
+                               DEBUG_JTAG_IO("runtest %i cycles, end in %s",
+                                               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);
                                break;
 
-                       case JTAG_STATEMOVE:
-                               DEBUG_JTAG_IO("statemove end in %s", \
-                                                               tap_state_name(cmd->cmd.statemove->end_state));
+                       case JTAG_TLR_RESET:
+                               DEBUG_JTAG_IO("statemove end in %s",
+                                               tap_state_name(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]));
+                               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);
+                               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);
+                               scan_size = jtag_build_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));
-                               }
+                                       DEBUG_JTAG_IO(
+                                                       "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));
-                               }
+                                       DEBUG_JTAG_IO(
+                                                       "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));
+                               vsllink_debug_buffer(buffer,
+                                               DIV_ROUND_UP(scan_size, 8));
 #endif
 
                                type = jtag_scan_type(cmd->cmd.scan);
 
-                               vsllink_scan(cmd->cmd.scan->ir_scan, type, buffer, \
-                                                               scan_size, cmd->cmd.scan);
+                               vsllink_scan(cmd->cmd.scan->ir_scan,
+                                               type, buffer, scan_size,
+                                               cmd->cmd.scan);
                                break;
 
                        case JTAG_RESET:
-                               DEBUG_JTAG_IO("reset trst: %i srst %i", \
-                                                               cmd->cmd.reset->trst, \
-                                                               cmd->cmd.reset->srst);
+                               DEBUG_JTAG_IO("reset trst: %i srst %i",
+                                               cmd->cmd.reset->trst,
+                                               cmd->cmd.reset->srst);
 
                                vsllink_tap_execute();
 
                                if (cmd->cmd.reset->trst == 1)
-                               {
                                        tap_set_state(TAP_RESET);
-                               }
-                               vsllink_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
+
+                               vsllink_reset(cmd->cmd.reset->trst,
+                                               cmd->cmd.reset->srst);
                                break;
 
                        case JTAG_SLEEP:
@@ -231,12 +189,14 @@ static int vsllink_execute_queue(void)
                                break;
 
                        case JTAG_STABLECLOCKS:
-                               DEBUG_JTAG_IO("add %d clocks", \
-                                                               cmd->cmd.stableclocks->num_cycles);
-                               switch (tap_get_state())
-                               {
+                               DEBUG_JTAG_IO("add %d clocks",
+                                               cmd->cmd.stableclocks->num_cycles);
+
+                               switch (tap_get_state()) {
                                case TAP_RESET:
-                                       // tms should be '1' to stay in TAP_RESET mode
+                                       /* tms must be '1' to stay
+                                        * n TAP_RESET mode
+                                        */
                                        scan_size = 1;
                                        break;
                                case TAP_DRSHIFT:
@@ -244,22 +204,31 @@ static int vsllink_execute_queue(void)
                                case TAP_DRPAUSE:
                                case TAP_IRSHIFT:
                                case TAP_IRPAUSE:
-                                       // in other mode, tms should be '0'
+                                       /* else, tms should be '0' */
                                        scan_size = 0;
-                                       break;                  /* above stable states are OK */
+                                       break;
+                               /* 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;
        }
@@ -269,25 +238,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)
@@ -304,182 +261,127 @@ 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);
+       if (tdi_buffer != NULL) {
+               free(tdi_buffer);
+               tdi_buffer = NULL;
        }
-
-       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 (tdo_buffer != NULL) {
+               free(tdo_buffer);
+               tdo_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-alloc memroy
-                       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 (check_cnt == 3)
-       {
-               // Fail to access Versaloon
-               LOG_ERROR("VSLLink initial failed");
-               exit(-1);
-       }
-       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");
+       if (tms_buffer != NULL) {
+               free(tms_buffer);
+               tms_buffer = NULL;
        }
+}
+
+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));
-       }
+               versaloon_interface.adaptors.jtag_raw.fini(0);
 
-       // 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.peripheral_commit();
+       versaloon_interface.fini();
 
-       // 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);
+       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)
 {
        if (tap_is_state_stable(state))
-       {
                tap_set_end_state(state);
-       }
-       else
-       {
+       else {
                LOG_ERROR("BUG: %i is not a valid end state", state);
                exit(-1);
        }
@@ -489,35 +391,28 @@ static void vsllink_end_state(tap_state_t state)
 static void vsllink_state_move(void)
 {
        int i;
-       uint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());
-       uint8_t tms_scan_bits = \
-                               tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
+       uint8_t tms_scan = tap_get_tms_path(tap_get_state(),
+                       tap_get_end_state());
+       uint8_t tms_scan_bits = tap_get_tms_path_len(tap_get_state(),
+                       tap_get_end_state());
 
        for (i = 0; i < tms_scan_bits; i++)
-       {
                vsllink_tap_append_step((tms_scan >> i) & 1, 0);
-       }
 
        tap_set_state(tap_get_end_state());
 }
 
 static void vsllink_path_move(int num_states, tap_state_t *path)
 {
-       for (int i = 0; i < num_states; i++)
-       {
+       for (int i = 0; i < num_states; i++) {
                if (path[i] == tap_state_transition(tap_get_state(), false))
-               {
                        vsllink_tap_append_step(0, 0);
-               }
                else if (path[i] == tap_state_transition(tap_get_state(), true))
-               {
                        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]));
+               else {
+                       LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
+                               tap_state_name(tap_get_state()),
+                               tap_state_name(path[i]));
                        exit(-1);
                }
 
@@ -527,10 +422,15 @@ 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)
-       {
+       while (num_cycles > 0) {
                vsllink_tap_append_step(tms, 0);
                num_cycles--;
        }
@@ -540,26 +440,23 @@ static void vsllink_runtest(int num_cycles)
 {
        tap_state_t saved_end_state = tap_get_end_state();
 
-       if (tap_get_state() != TAP_IDLE)
-       {
-               // enter into IDLE state
+       if (tap_get_state() != TAP_IDLE) {
+               /* enter IDLE state */
                vsllink_end_state(TAP_IDLE);
                vsllink_state_move();
        }
 
        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)
+static void vsllink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer,
+       int scan_size, struct scan_command *command)
 {
        tap_state_t saved_end_state;
 
@@ -569,9 +466,7 @@ static void vsllink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, \
        vsllink_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);
 
        if (tap_get_state() != tap_get_end_state())
-       {
                vsllink_state_move();
-       }
        vsllink_end_state(saved_end_state);
 
        /* Scan */
@@ -584,100 +479,71 @@ static void vsllink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, \
        tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);
 
        if (tap_get_state() != tap_get_end_state())
-       {
                vsllink_state_move();
-       }
 }
 
 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;
-       }
+       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);
 
-       result = vsllink_usb_write(vsllink_handle, 3);
-       if (result != 3)
-       {
-               LOG_ERROR("VSLLink command VSLLINK_CMD_SET_PORT failed (%d)", result);
+       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);
        }
-}
-
-static void vsllink_simple_command(uint8_t command)
-{
-       int result;
-
-       DEBUG_JTAG_IO("0x%02x", command);
 
-       vsllink_usb_out_buffer[0] = command;
-       result = vsllink_usb_write(vsllink_handle, 1);
-
-       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);
+               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;
-       }
+               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;
 }
@@ -685,15 +551,12 @@ COMMAND_HANDLER(vsllink_handle_usb_bulkin_command)
 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;
-       }
+               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;
 }
@@ -701,18 +564,15 @@ COMMAND_HANDLER(vsllink_handle_usb_bulkout_command)
 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;
-       }
+               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)
 {
@@ -723,69 +583,55 @@ 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;
+       int available_scans =
+               MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;
 
        if (scans > available_scans)
-       {
                vsllink_tap_execute();
-       }
 }
 
 static void vsllink_tap_append_step(int tms, int tdi)
 {
-       int index = tap_length / 8;
+       int index_var = tap_length / 8;
 
        int bit_index = tap_length % 8;
        uint8_t bit = 1 << bit_index;
 
        if (tms)
-       {
-               tms_buffer[index] |= bit;
-       }
+               tms_buffer[index_var] |= bit;
        else
-       {
-               tms_buffer[index] &= ~bit;
-       }
+               tms_buffer[index_var] &= ~bit;
 
        if (tdi)
-       {
-               tdi_buffer[index] |= bit;
-       }
+               tdi_buffer[index_var] |= bit;
        else
-       {
-               tdi_buffer[index] &= ~bit;
-       }
+               tdi_buffer[index_var] &= ~bit;
 
        tap_length++;
+
        if (tap_buffer_size * 8 <= tap_length)
-       {
                vsllink_tap_execute();
-       }
 }
 
-static void vsllink_tap_append_scan(int length, uint8_t *buffer, \
-                                                                               struct scan_command *command)
+static void vsllink_tap_append_scan(int length, uint8_t *buffer,
+       struct scan_command *command)
 {
        struct pending_scan_result *pending_scan_result;
        int len_tmp, len_all, i;
 
        len_all = 0;
-       while (len_all < length)
-       {
+       while (len_all < length) {
                vsllink_tap_ensure_pending(1);
-               pending_scan_result = \
-                               &pending_scan_results_buffer[pending_scan_results_length];
+               pending_scan_result =
+                       &pending_scan_results_buffer[
+                               pending_scan_results_length];
 
-               if ((length - len_all) > (tap_buffer_size * 8 - tap_length))
-               {
-                       /* Use all memory available 
+               if ((length - len_all) > (tap_buffer_size * 8 - tap_length)) {
+                       /* Use all memory available
                           vsllink_tap_append_step will commit automatically */
                        len_tmp = tap_buffer_size * 8 - tap_length;
                        pending_scan_result->last = false;
-               }
-               else
-               {
+               } else {
                        len_tmp = length - len_all;
                        pending_scan_result->last = true;
                }
@@ -796,134 +642,66 @@ static void vsllink_tap_append_scan(int length, uint8_t *buffer, \
                pending_scan_result->buffer = buffer;
                pending_scan_results_length++;
 
-               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);
+               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);
                }
 
                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;
-
-       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;
+       versaloon_interface.adaptors.jtag_raw.execute(0, tdi_buffer, tms_buffer,
+               tdo_buffer, tap_length);
 
-       memcpy(&vsllink_usb_out_buffer[3], tdi_buffer, byte_length);
-       memcpy(&vsllink_usb_out_buffer[3 + byte_length], tms_buffer, byte_length);
+       result = versaloon_interface.adaptors.peripheral_commit();
 
-       result = vsllink_usb_message(vsllink_handle, 3 + 2 * byte_length, \
-                                                                       byte_length);
-
-       if (result == byte_length)
-       {
-               for (i = 0; i < pending_scan_results_length; i++)
-               {
-                       struct pending_scan_result *pending_scan_result = \
-                                                                                       &pending_scan_results_buffer[i];
+       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];
                        uint8_t *buffer = pending_scan_result->buffer;
                        int length = pending_scan_result->length;
                        int src_first = pending_scan_result->src_offset;
                        int dest_first = pending_scan_result->dest_offset;
                        bool last = pending_scan_result->last;
 
-                       struct scan_command *command = pending_scan_result->command;
-                       buf_set_buf(vsllink_usb_in_buffer, src_first, buffer, \
-                                                       dest_first, length);
+                       struct scan_command *command;
+
+                       command = pending_scan_result->command;
+                       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_
-                       vsllink_debug_buffer(buffer + dest_first / 8, DIV_ROUND_UP(length, 7));
+                       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));
 #endif
 
-                       if (last)
-                       {
-                               if (jtag_read_buffer(buffer, command) != ERROR_OK)
-                               {
+                       if (last) {
+                               if (jtag_read_buffer(buffer, command)
+                                   != ERROR_OK) {
                                        vsllink_tap_init();
                                        return ERROR_JTAG_QUEUE_FAILED;
                                }
 
                                if (pending_scan_result->buffer != NULL)
-                               {
                                        free(pending_scan_result->buffer);
-                               }
                        }
                }
-       }
-       else
-       {
-               LOG_ERROR("vsllink_tap_execute, wrong result %d, expected %d", \
-                                       result, byte_length);
+       } else {
+               LOG_ERROR("vsllink_jtag_execute failure");
                return ERROR_JTAG_QUEUE_FAILED;
        }
 
@@ -932,153 +710,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;
 
-static struct vsllink* vsllink_usb_open(void)
+       return vsllink_jtag_execute();
+}
+
+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;
+
+       if (strstr(desc_string, "Versaloon") == NULL)
+               return ERROR_FAIL;
 
-       return result;
+       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];
@@ -1086,56 +903,80 @@ static void vsllink_debug_buffer(uint8_t *buffer, int length)
        int i;
        int j;
 
-       for (i = 0; i < length; i += BYTES_PER_LINE)
-       {
+       for (i = 0; i < length; i += BYTES_PER_LINE) {
                snprintf(line, 5, "%04x", i);
-               for (j = i; j < i + BYTES_PER_LINE && j < length; j++)
-               {
+               for (j = i; j < i + BYTES_PER_LINE && j < length; j++) {
                        snprintf(s, 4, " %02x", buffer[j]);
                        strcat(line, s);
                }
                LOG_DEBUG("%s", line);
        }
 }
-#endif // _DEBUG_USB_COMMS_ || _DEBUG_JTAG_IO_
+#endif /* _DEBUG_JTAG_IO_ */
 
 static const struct command_registration vsllink_command_handlers[] = {
        {
                .name = "vsllink_usb_vid",
                .handler = &vsllink_handle_usb_vid_command,
                .mode = COMMAND_CONFIG,
+               .help = "Set USB VID",
+               .usage = "<vid>",
        },
        {
                .name = "vsllink_usb_pid",
                .handler = &vsllink_handle_usb_pid_command,
                .mode = COMMAND_CONFIG,
+               .help = "Set USB PID",
+               .usage = "<pid>",
+       },
+       {
+               .name = "vsllink_usb_serial",
+               .handler = &vsllink_handle_usb_serial_command,
+               .mode = COMMAND_CONFIG,
+               .help = "Set or disable check for USB serial",
+               .usage = "[<serial>]",
        },
        {
                .name = "vsllink_usb_bulkin",
                .handler = &vsllink_handle_usb_bulkin_command,
                .mode = COMMAND_CONFIG,
+               .help = "Set USB input endpoint",
+               .usage = "<ep_in>",
        },
        {
                .name = "vsllink_usb_bulkout",
                .handler = &vsllink_handle_usb_bulkout_command,
                .mode = COMMAND_CONFIG,
+               .help = "Set USB output endpoint",
+               .usage = "<ep_out>",
        },
        {
                .name = "vsllink_usb_interface",
                .handler = &vsllink_handle_usb_interface_command,
                .mode = COMMAND_CONFIG,
-       },
-       {
-               .name = "vsllink_mode",
-               .handler = &vsllink_handle_mode_command,
-               .mode = COMMAND_CONFIG,
+               .help = "Set USB output interface",
+               .usage = "<interface>",
        },
        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)