versaloon driver update
authorSimonQian <simonqian@simonqian.com>
Mon, 11 Jul 2011 17:48:05 +0000 (01:48 +0800)
committerSpencer Oliver <ntfreak@users.sourceforge.net>
Tue, 16 Aug 2011 11:50:38 +0000 (12:50 +0100)
Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
14 files changed:
src/jtag/drivers/Makefile.am
src/jtag/drivers/versaloon/usbtoxxx/usbtogpio.c [new file with mode: 0644]
src/jtag/drivers/versaloon/usbtoxxx/usbtojtagraw.c [new file with mode: 0644]
src/jtag/drivers/versaloon/usbtoxxx/usbtopwr.c [new file with mode: 0644]
src/jtag/drivers/versaloon/usbtoxxx/usbtoswd.c [new file with mode: 0644]
src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c [new file with mode: 0644]
src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.h [new file with mode: 0644]
src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx_internal.h [new file with mode: 0644]
src/jtag/drivers/versaloon/versaloon.c [new file with mode: 0644]
src/jtag/drivers/versaloon/versaloon.h [new file with mode: 0644]
src/jtag/drivers/versaloon/versaloon_include.h [new file with mode: 0644]
src/jtag/drivers/versaloon/versaloon_internal.h [new file with mode: 0644]
src/jtag/drivers/vsllink.c
tcl/interface/vsllink.cfg

index 1e523581dc772de89dfa272cb89b558d21bf7b0e..805d1a49029e47cdbdde8b6d619e02029d2caca4 100644 (file)
@@ -67,6 +67,12 @@ DRIVERFILES += ulink.c
 nobase_dist_pkglib_DATA += $(ULINK_FIRMWARE)/ulink_firmware.hex
 endif
 if VSLLINK
+DRIVERFILES += versaloon/usbtoxxx/usbtogpio.c
+DRIVERFILES += versaloon/usbtoxxx/usbtojtagraw.c
+DRIVERFILES += versaloon/usbtoxxx/usbtoswd.c
+DRIVERFILES += versaloon/usbtoxxx/usbtopwr.c
+DRIVERFILES += versaloon/usbtoxxx/usbtoxxx.c
+DRIVERFILES += versaloon/versaloon.c
 DRIVERFILES += vsllink.c
 endif
 if ARMJTAGEW
diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtogpio.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtogpio.c
new file mode 100644 (file)
index 0000000..5be515f
--- /dev/null
@@ -0,0 +1,100 @@
+/***************************************************************************
+ *   Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com>     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   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.             *
+ ***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include "../versaloon_include.h"
+#include "../versaloon.h"
+#include "../versaloon_internal.h"
+#include "usbtoxxx.h"
+#include "usbtoxxx_internal.h"
+
+RESULT usbtogpio_init(uint8_t interface_index)
+{
+       return usbtoxxx_init_command(USB_TO_GPIO, interface_index);
+}
+
+RESULT usbtogpio_fini(uint8_t interface_index)
+{
+       return usbtoxxx_fini_command(USB_TO_GPIO, interface_index);
+}
+
+RESULT usbtogpio_config(uint8_t interface_index, uint32_t mask,
+                                               uint32_t dir_mask, uint32_t pull_en_mask,
+                                               uint32_t input_pull_mask)
+{
+       uint8_t conf[8];
+       
+#if PARAM_CHECK
+       if (interface_index > 7)
+       {
+               LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index);
+               return ERROR_FAIL;
+       }
+#endif
+       
+       dir_mask &= mask;
+       SET_LE_U16(&conf[0], mask);
+       SET_LE_U16(&conf[2], dir_mask);
+       SET_LE_U16(&conf[4], pull_en_mask);
+       SET_LE_U16(&conf[6], input_pull_mask);
+       
+       return usbtoxxx_conf_command(USB_TO_GPIO, interface_index, conf,
+                                                                       sizeof(conf));
+}
+
+RESULT usbtogpio_in(uint8_t interface_index, uint32_t mask, uint32_t *value)
+{
+       uint8_t buf[2];
+       
+#if PARAM_CHECK
+       if (interface_index > 7)
+       {
+               LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index);
+               return ERROR_FAIL;
+       }
+#endif
+       
+       SET_LE_U16(&buf[0], mask);
+       
+       return usbtoxxx_in_command(USB_TO_GPIO, interface_index, buf, 2, 2,
+                                                          (uint8_t*)value, 0, 2, 0);
+}
+
+RESULT usbtogpio_out(uint8_t interface_index, uint32_t mask, uint32_t value)
+{
+       uint8_t buf[4];
+       
+#if PARAM_CHECK
+       if (interface_index > 7)
+       {
+               LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index);
+               return ERROR_FAIL;
+       }
+#endif
+       
+       SET_LE_U16(&buf[0], mask);
+       SET_LE_U16(&buf[2], value);
+       
+       return usbtoxxx_out_command(USB_TO_GPIO, interface_index, buf, 4, 0);
+}
+
diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtojtagraw.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtojtagraw.c
new file mode 100644 (file)
index 0000000..11e8064
--- /dev/null
@@ -0,0 +1,84 @@
+/***************************************************************************
+ *   Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com>     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   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.             *
+ ***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include "../versaloon_include.h"
+#include "../versaloon.h"
+#include "../versaloon_internal.h"
+#include "usbtoxxx.h"
+#include "usbtoxxx_internal.h"
+
+RESULT usbtojtagraw_init(uint8_t interface_index)
+{
+       return usbtoxxx_init_command(USB_TO_JTAG_RAW, interface_index);
+}
+
+RESULT usbtojtagraw_fini(uint8_t interface_index)
+{
+       return usbtoxxx_fini_command(USB_TO_JTAG_RAW, interface_index);
+}
+
+RESULT usbtojtagraw_config(uint8_t interface_index, uint32_t kHz)
+{
+       uint8_t cfg_buf[4];
+       
+#if PARAM_CHECK
+       if (interface_index > 7)
+       {
+               LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index);
+               return ERROR_FAIL;
+       }
+#endif
+       
+       SET_LE_U32(&cfg_buf[0], kHz);
+       
+       return usbtoxxx_conf_command(USB_TO_JTAG_RAW, interface_index, cfg_buf, 4);
+}
+
+RESULT usbtojtagraw_execute(uint8_t interface_index, uint8_t *tdi,
+                                                       uint8_t *tms, uint8_t *tdo, uint32_t bitlen)
+{
+       uint16_t bytelen;
+       
+#if PARAM_CHECK
+       if (interface_index > 7)
+       {
+               LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index);
+               return ERROR_FAIL;
+       }
+#endif
+       
+       if (bitlen > 8 * 0xFFFF)
+       {
+               return ERROR_FAIL;
+       }
+       bytelen = (uint16_t)((bitlen + 7) >> 3);
+       
+       SET_LE_U32(&versaloon_cmd_buf[0], bitlen);
+       memcpy(versaloon_cmd_buf + 4, tdi, bytelen);
+       memcpy(versaloon_cmd_buf + 4 + bytelen, tms, bytelen);
+       
+       return usbtoxxx_inout_command(USB_TO_JTAG_RAW, interface_index,
+                       versaloon_cmd_buf, 4 + bytelen * 2, bytelen, tdo, 0, bytelen, 0);
+}
+
diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtopwr.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtopwr.c
new file mode 100644 (file)
index 0000000..13f7f15
--- /dev/null
@@ -0,0 +1,67 @@
+/***************************************************************************
+ *   Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com>     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   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.             *
+ ***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include "../versaloon_include.h"
+#include "../versaloon.h"
+#include "../versaloon_internal.h"
+#include "usbtoxxx.h"
+#include "usbtoxxx_internal.h"
+
+RESULT usbtopwr_init(uint8_t interface_index)
+{
+       return usbtoxxx_init_command(USB_TO_POWER, interface_index);
+}
+
+RESULT usbtopwr_fini(uint8_t interface_index)
+{
+       return usbtoxxx_fini_command(USB_TO_POWER, interface_index);
+}
+
+RESULT usbtopwr_config(uint8_t interface_index)
+{
+#if PARAM_CHECK
+       if (interface_index > 7)
+       {
+               LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index);
+               return ERROR_FAIL;
+       }
+#endif
+       
+       return usbtoxxx_conf_command(USB_TO_POWER, interface_index, NULL, 0);
+}
+
+RESULT usbtopwr_output(uint8_t interface_index, uint16_t mV)
+{
+#if PARAM_CHECK
+       if (interface_index > 7)
+       {
+               LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index);
+               return ERROR_FAIL;
+       }
+#endif
+       
+       return usbtoxxx_out_command(USB_TO_POWER, interface_index, (uint8_t *)&mV,
+                                                               2, 0);
+}
+
diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtoswd.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtoswd.c
new file mode 100644 (file)
index 0000000..93333f0
--- /dev/null
@@ -0,0 +1,158 @@
+/***************************************************************************
+ *   Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com>     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   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.             *
+ ***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "../versaloon_include.h"
+#include "../versaloon.h"
+#include "../versaloon_internal.h"
+#include "usbtoxxx.h"
+#include "usbtoxxx_internal.h"
+
+RESULT usbtoswd_callback(void *p, uint8_t *src, uint8_t *processed)
+{
+       struct versaloon_pending_t *pending = (struct versaloon_pending_t *)p;
+       
+       processed = processed;
+       
+       if (pending->extra_data != NULL)
+       {
+               *((uint8_t *)pending->extra_data) = src[0];
+       }
+       
+       return ERROR_OK;
+}
+
+RESULT usbtoswd_init(uint8_t interface_index)
+{
+       return usbtoxxx_init_command(USB_TO_SWD, interface_index);
+}
+
+RESULT usbtoswd_fini(uint8_t interface_index)
+{
+       return usbtoxxx_fini_command(USB_TO_SWD, interface_index);
+}
+
+RESULT usbtoswd_config(uint8_t interface_index, uint8_t trn, uint16_t retry,
+                                          uint16_t dly)
+{
+       uint8_t cfg_buf[5];
+       
+#if PARAM_CHECK
+       if (interface_index > 7)
+       {
+               LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index);
+               return ERROR_FAIL;
+       }
+#endif
+       
+       cfg_buf[0] = trn;
+       SET_LE_U16(&cfg_buf[1], retry);
+       SET_LE_U16(&cfg_buf[3], dly);
+       
+       return usbtoxxx_conf_command(USB_TO_SWD, interface_index, cfg_buf, 5);
+}
+
+RESULT usbtoswd_seqout(uint8_t interface_index, uint8_t *data, uint16_t bitlen)
+{
+       uint16_t bytelen = (bitlen + 7) >> 3;
+       
+#if PARAM_CHECK
+       if (interface_index > 7)
+       {
+               LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index);
+               return ERROR_FAIL;
+       }
+#endif
+       
+       SET_LE_U16(&versaloon_cmd_buf[0], bitlen);
+       memcpy(versaloon_cmd_buf + 2, data, bytelen);
+       
+       return usbtoxxx_out_command(USB_TO_SWD, interface_index,
+                                                               versaloon_cmd_buf, bytelen + 2, 0);
+}
+
+RESULT usbtoswd_seqin(uint8_t interface_index, uint8_t *data, uint16_t bitlen)
+{
+       uint16_t bytelen = (bitlen + 7) >> 3;
+       uint8_t buff[2];
+       
+#if PARAM_CHECK
+       if (interface_index > 7)
+       {
+               LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index);
+               return ERROR_FAIL;
+       }
+#endif
+       
+       SET_LE_U16(&buff[0], bitlen);
+       
+       return usbtoxxx_in_command(USB_TO_SWD, interface_index, buff, 2, bytelen,
+                                                               data, 0, bytelen, 0);
+}
+
+RESULT usbtoswd_transact(uint8_t interface_index, uint8_t request,
+                                                       uint32_t *data, uint8_t *ack)
+{
+       uint8_t parity;
+       uint8_t buff[5];
+       
+#if PARAM_CHECK
+       if (interface_index > 7)
+       {
+               LOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index);
+               return ERROR_FAIL;
+       }
+#endif
+       
+       parity = (request >> 1) & 1;
+       parity += (request >> 2) & 1;
+       parity += (request >> 3) & 1;
+       parity += (request >> 4) & 1;
+       parity &= 1;
+       buff[0] = (request | 0x81 | (parity << 5)) & ~0x40;
+       if (data != NULL)
+       {
+               SET_LE_U32(&buff[1], *data);
+       }
+       else
+       {
+               memset(buff + 1, 0, 4);
+       }
+       
+       versaloon_set_extra_data(ack);
+       versaloon_set_callback(usbtoswd_callback);
+       if (request & 0x04)
+       {
+               // read
+               return usbtoxxx_inout_command(USB_TO_SWD, interface_index, buff, 5, 5,
+                                                                               (uint8_t *)data, 1, 4, 0);
+       }
+       else
+       {
+               // write
+               return usbtoxxx_inout_command(USB_TO_SWD, interface_index, buff, 5, 5,
+                                                                               NULL, 0, 0, 0);
+       }
+}
+
diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c
new file mode 100644 (file)
index 0000000..64e31a6
--- /dev/null
@@ -0,0 +1,652 @@
+/***************************************************************************
+ *   Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com>     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   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.             *
+ ***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include "../versaloon_include.h"
+#include "../versaloon.h"
+#include "../versaloon_internal.h"
+#include "usbtoxxx.h"
+#include "usbtoxxx_internal.h"
+
+#define N_A            "n/a"
+const char* types_name[96] =
+{
+"usbtousart", "usbtospi", "usbtoi2c", "usbtogpio", "usbtocan", "usbtopwm",
+                                                                                                       "usbtoadc", "usbtodac",
+"usbtomicrowire", "usbtoswim", "usbtodusi", N_A, N_A, N_A, "usbtopower", "usbtodelay",
+N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A,
+N_A, N_A, N_A, N_A, N_A, N_A, N_A,
+"usbtojtagll", "usbtojtaghl", "usbtoissp", "usbtoc2", "usbtosbw",
+                                                                       "usbtolpcicp", "usbtoswd", "usbtojtagraw",
+"usbtobdm", N_A, N_A, N_A, N_A, N_A, N_A, N_A,
+N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A,
+"usbtomsp430jtag", N_A, N_A, N_A, N_A, N_A, N_A, N_A,
+"usbtopower", "usbtodelay", "usbtopoll", N_A, N_A, N_A, N_A, N_A,
+N_A, N_A, N_A, N_A, N_A, N_A, N_A, "usbtoall"
+};
+
+uint8_t usbtoxxx_abilities[USB_TO_XXX_ABILITIES_LEN];
+
+#define usbtoxxx_get_type_name(type)   \
+                       types_name[((type) - VERSALOON_USB_TO_XXX_CMD_START) \
+                                          % (sizeof(types_name) / sizeof(types_name[0]))]
+
+static uint8_t type_pre = 0;
+static uint16_t usbtoxxx_buffer_index = 0;
+static uint16_t usbtoxxx_current_cmd_index = 0;
+static uint8_t *usbtoxxx_buffer = NULL;
+
+uint16_t collect_index = 0;
+uint8_t collect_cmd;
+static uint8_t poll_nesting = 0;
+
+struct usbtoxxx_context_t
+{
+       uint8_t type_pre;
+       uint8_t *usbtoxxx_buffer;
+       uint16_t usbtoxxx_current_cmd_index;
+       uint16_t usbtoxxx_buffer_index;
+       uint16_t versaloon_pending_idx;
+};
+static struct usbtoxxx_context_t poll_context;
+
+static void usbtoxxx_save_context(struct usbtoxxx_context_t *c)
+{
+       c->type_pre = type_pre;
+       c->usbtoxxx_buffer = usbtoxxx_buffer;
+       c->usbtoxxx_buffer_index = usbtoxxx_buffer_index;
+       c->usbtoxxx_current_cmd_index = usbtoxxx_current_cmd_index;
+       c->versaloon_pending_idx = versaloon_pending_idx;
+}
+
+static void usbtoxxx_pop_context(struct usbtoxxx_context_t *c)
+{
+       type_pre = c->type_pre;
+       usbtoxxx_buffer = c->usbtoxxx_buffer;
+       usbtoxxx_buffer_index = c->usbtoxxx_buffer_index;
+       usbtoxxx_current_cmd_index = c->usbtoxxx_current_cmd_index;
+       versaloon_pending_idx = c->versaloon_pending_idx;
+}
+
+RESULT usbtoxxx_validate_current_command_type(void)
+{
+       if (type_pre > 0)
+       {
+               // not the first command
+               if (NULL == usbtoxxx_buffer)
+               {
+                       LOG_BUG(ERRMSG_INVALID_BUFFER, TO_STR(usbtoxxx_buffer));
+                       return ERRCODE_INVALID_BUFFER;
+               }
+               
+               usbtoxxx_buffer[0] = type_pre;
+               SET_LE_U16(&usbtoxxx_buffer[1], usbtoxxx_current_cmd_index);
+               
+               usbtoxxx_buffer_index += usbtoxxx_current_cmd_index;
+       }
+       else
+       {
+               // first command
+               usbtoxxx_buffer_index = 3;
+       }
+       
+       // prepare for next command
+       usbtoxxx_current_cmd_index = 3;
+       usbtoxxx_buffer = versaloon_buf + usbtoxxx_buffer_index;
+       
+       collect_index = 0;
+       collect_cmd = 0;
+       
+       return ERROR_OK;
+}
+
+
+
+RESULT usbtoxxx_execute_command(void)
+{
+       uint16_t i;
+       uint16_t inlen;
+       RESULT result = ERROR_OK;
+       
+       if (poll_nesting)
+       {
+               LOG_BUG(ERRMSG_INVALID_USAGE, "USB_TO_POLL");
+               versaloon_free_want_pos();
+               return ERROR_FAIL;
+       }
+       
+       if (ERROR_OK != usbtoxxx_validate_current_command_type())
+       {
+               LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands");
+               versaloon_free_want_pos();
+               return ERRCODE_FAILURE_OPERATION;
+       }
+       if (3 == usbtoxxx_buffer_index)
+       {
+               versaloon_free_want_pos();
+               return ERROR_OK;
+       }
+       
+       versaloon_buf[0] = USB_TO_ALL;
+       SET_LE_U16(&versaloon_buf[1], usbtoxxx_buffer_index);
+       
+       if (ERROR_OK != versaloon_send_command(usbtoxxx_buffer_index, &inlen))
+       {
+               versaloon_free_want_pos();
+               return ERROR_FAIL;
+       }
+       
+       // process return data
+       usbtoxxx_buffer_index = 0;
+       for (i = 0; i < versaloon_pending_idx; i++)
+       {
+               // check result
+               if ((0 == i) || !((versaloon_pending[i].collect)
+                                                       && (versaloon_pending[i - 1].collect)
+                                                       && (versaloon_pending[i].cmd
+                                                               == versaloon_pending[i - 1].cmd)))
+               {
+                       if (USB_TO_XXX_CMD_NOT_SUPPORT
+                               == versaloon_buf[usbtoxxx_buffer_index])
+                       {
+                               LOG_ERROR(ERRMSG_NOT_SUPPORT_BY,
+                                                       usbtoxxx_get_type_name(versaloon_pending[i].type),
+                                                       "current dongle");
+                               result = ERROR_FAIL;
+                               break;
+                       }
+                       else if (USB_TO_XXX_OK != versaloon_buf[usbtoxxx_buffer_index])
+                       {
+                               LOG_ERROR("%s command 0x%02x failed with 0x%02x",
+                                       usbtoxxx_get_type_name(versaloon_pending[i].type),
+                                       versaloon_pending[i].cmd,
+                                       versaloon_buf[usbtoxxx_buffer_index]);
+                               result = ERROR_FAIL;
+                               break;
+                       }
+                       usbtoxxx_buffer_index++;
+               }
+               
+               // get result data
+               if (versaloon_pending[i].pos != NULL)
+               {
+                       uint8_t processed = 0;
+                       
+                       if (versaloon_pending[i].callback != NULL)
+                       {
+                               versaloon_pending[i].callback(&versaloon_pending[i],
+                                                       versaloon_buf + usbtoxxx_buffer_index, &processed);
+                       }
+                       if (!processed)
+                       {
+                               struct versaloon_want_pos_t *tmp, *free_tmp;
+                               
+                               free_tmp = tmp = versaloon_pending[i].pos;
+                               while (tmp != NULL)
+                               {
+                                       if ((tmp->buff != NULL) && (tmp->size > 0))
+                                       {
+                                               memcpy(tmp->buff, versaloon_buf + usbtoxxx_buffer_index
+                                                       + tmp->offset, tmp->size);
+                                       }
+                                       free_tmp = tmp;
+                                       tmp = tmp->next;
+                                       free(free_tmp);
+                               }
+                               versaloon_pending[i].pos = NULL;
+                       }
+               }
+               else if ((versaloon_pending[i].want_data_size > 0)
+                       && (versaloon_pending[i].data_buffer != NULL))
+               {
+                       uint8_t processed = 0;
+                       
+                       if (versaloon_pending[i].callback != NULL)
+                       {
+                               versaloon_pending[i].callback(&versaloon_pending[i],
+                                                       versaloon_buf + usbtoxxx_buffer_index, &processed);
+                       }
+                       if (!processed)
+                       {
+                               memcpy(versaloon_pending[i].data_buffer,
+                                          versaloon_buf + usbtoxxx_buffer_index
+                                                       + versaloon_pending[i].want_data_pos,
+                                          versaloon_pending[i].want_data_size);
+                       }
+               }
+               usbtoxxx_buffer_index += versaloon_pending[i].actual_data_size;
+               if (usbtoxxx_buffer_index > inlen)
+               {
+                       LOG_BUG("%s command 0x%02x process error",
+                                       usbtoxxx_get_type_name(versaloon_pending[i].type),
+                                       versaloon_pending[i].cmd);
+                       result = ERROR_FAIL;
+                       break;
+               }
+       }
+       
+       // data is not the right size
+       if (inlen != usbtoxxx_buffer_index)
+       {
+               LOG_ERROR(ERRMSG_INVALID_TARGET, "length of return data");
+               result = ERROR_FAIL;
+       }
+       
+       if (versaloon_pending_idx > 0)
+       {
+               versaloon_pending_idx = 0;
+       }
+       else
+       {
+               // no receive data, avoid collision
+               sleep_ms(10);
+       }
+       
+       type_pre = 0;
+       collect_cmd = 0;
+       collect_index = 0;
+       versaloon_free_want_pos();
+       return result;
+}
+
+RESULT usbtoxxx_init(void)
+{
+       versaloon_pending_idx = 0;
+       
+       if ((ERROR_OK != usbtoinfo_get_abilities(usbtoxxx_abilities)) ||
+               (ERROR_OK != usbtoxxx_execute_command()))
+       {
+               return ERROR_FAIL;
+       }
+       LOG_INFO("USB_TO_XXX abilities: 0x%08X:0x%08X:0x%08X",
+               GET_LE_U32(&usbtoxxx_abilities[0]),
+               GET_LE_U32(&usbtoxxx_abilities[4]),
+               GET_LE_U32(&usbtoxxx_abilities[8]));
+       return ERROR_OK;
+}
+
+RESULT usbtoxxx_fini(void)
+{
+       usbtoxxx_buffer = NULL;
+       type_pre = 0;
+       return ERROR_OK;
+}
+
+bool usbtoxxx_interface_supported(uint8_t cmd)
+{
+       if ((cmd < VERSALOON_USB_TO_XXX_CMD_START) ||
+               (cmd > VERSALOON_USB_TO_XXX_CMD_END))
+       {
+               return false;
+       }
+       
+       cmd -= VERSALOON_USB_TO_XXX_CMD_START;
+       return (usbtoxxx_abilities[cmd  / 8] & (1 << (cmd % 8))) > 0;
+}
+
+
+
+RESULT usbtoxxx_ensure_buffer_size(uint16_t cmdlen)
+{
+       // check free space, commit if not enough
+       if (((usbtoxxx_buffer_index + usbtoxxx_current_cmd_index + cmdlen)
+                       >= versaloon_buf_size)
+               || (versaloon_pending_idx >= VERSALOON_MAX_PENDING_NUMBER))
+       {
+               struct usbtoxxx_context_t context_tmp;
+               uint8_t poll_nesting_tmp = 0;
+               
+               memset(&context_tmp, 0, sizeof(context_tmp));
+               if (poll_nesting)
+               {
+                       if (0 == poll_context.type_pre)
+                       {
+                               LOG_BUG("USB_TO_POLL toooooo long");
+                               return ERROR_OK;
+                       }
+                       
+                       usbtoxxx_save_context(&context_tmp);
+                       usbtoxxx_pop_context(&poll_context);
+                       poll_nesting_tmp = poll_nesting;
+                       poll_nesting = 0;
+               }
+               
+               if (usbtoxxx_execute_command() != ERROR_OK)
+               {
+                       return ERROR_FAIL;
+               }
+               
+               if (poll_nesting_tmp)
+               {
+                       uint16_t newlen, oldlen;
+                       
+                       newlen = context_tmp.versaloon_pending_idx
+                                                                       - poll_context.versaloon_pending_idx;
+                       memcpy(&versaloon_pending[0],
+                                       &versaloon_pending[poll_context.versaloon_pending_idx],
+                                       sizeof(versaloon_pending[0]) * newlen);
+                       context_tmp.versaloon_pending_idx = newlen;
+                       oldlen = poll_context.usbtoxxx_buffer_index
+                                                                       + poll_context.usbtoxxx_current_cmd_index;
+                       newlen = context_tmp.usbtoxxx_buffer_index
+                                                                       + context_tmp.usbtoxxx_current_cmd_index;
+                       memcpy(versaloon_buf + 3, versaloon_buf + oldlen, newlen - oldlen);
+                       oldlen -= 3;
+                       context_tmp.usbtoxxx_buffer -= oldlen;
+                       context_tmp.usbtoxxx_buffer_index -= oldlen;
+                       usbtoxxx_pop_context(&context_tmp);
+                       poll_nesting = poll_nesting_tmp;
+               }
+       }
+       return ERROR_OK;
+}
+
+RESULT usbtoxxx_add_command(uint8_t type, uint8_t cmd, uint8_t *cmdbuf,
+                                                       uint16_t cmdlen, uint16_t retlen, uint8_t *wantbuf,
+                                                       uint16_t wantpos, uint16_t wantlen, uint8_t collect)
+{
+       uint16_t len_tmp;
+       
+       // 3 more bytes by usbtoxxx_validate_current_command_type
+       // 3 more bytes when ((0 == collect_index) || (collect_cmd != cmd))
+       if (ERROR_OK != usbtoxxx_ensure_buffer_size(cmdlen + 6))
+       {
+               return ERROR_FAIL;
+       }
+       
+       if ((type_pre != type) || (NULL == usbtoxxx_buffer))
+       {
+               if (ERROR_OK != usbtoxxx_validate_current_command_type())
+               {
+                       LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands");
+                       return ERRCODE_FAILURE_OPERATION;
+               }
+               type_pre = type;
+       }
+       
+       if ((0 == collect_index) || (collect_cmd != cmd))
+       {
+               usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = cmd;
+               
+               if (collect)
+               {
+                       collect_index = usbtoxxx_current_cmd_index;
+                       collect_cmd = cmd;
+               }
+               else
+               {
+                       collect_index = 0;
+                       collect_cmd = 0;
+               }
+               SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], cmdlen);
+               usbtoxxx_current_cmd_index += 2;
+       }
+       else
+       {
+               len_tmp = GET_LE_U16(&usbtoxxx_buffer[collect_index]) + cmdlen;
+               SET_LE_U16(&usbtoxxx_buffer[collect_index], len_tmp);
+       }
+       
+       if (cmdbuf != NULL)
+       {
+               memcpy(usbtoxxx_buffer + usbtoxxx_current_cmd_index, cmdbuf, cmdlen);
+               usbtoxxx_current_cmd_index += cmdlen;
+       }
+       
+       return versaloon_add_pending(type, cmd, retlen, wantpos, wantlen,
+                                                                wantbuf, collect);
+}
+
+
+
+
+
+RESULT usbtoinfo_get_abilities(uint8_t abilities[USB_TO_XXX_ABILITIES_LEN])
+{
+       if (ERROR_OK != usbtoxxx_ensure_buffer_size(3))
+       {
+               return ERROR_FAIL;
+       }
+       
+       if (ERROR_OK != usbtoxxx_validate_current_command_type())
+       {
+               LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands");
+               return ERRCODE_FAILURE_OPERATION;
+       }
+       type_pre = USB_TO_INFO;
+       
+       return versaloon_add_pending(USB_TO_INFO, 0, USB_TO_XXX_ABILITIES_LEN, 0,
+                                                                       USB_TO_XXX_ABILITIES_LEN, abilities, 0);
+}
+
+
+
+
+RESULT usbtopoll_start(uint16_t retry_cnt, uint16_t interval_us)
+{
+       if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 5))
+       {
+               return ERROR_FAIL;
+       }
+       if (!poll_nesting)
+       {
+               usbtoxxx_save_context(&poll_context);
+       }
+       
+       if (ERROR_OK != usbtoxxx_validate_current_command_type())
+       {
+               LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands");
+               return ERRCODE_FAILURE_OPERATION;
+       }
+       poll_nesting++;
+       type_pre = USB_TO_POLL;
+       
+       usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_START;
+       SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], retry_cnt);
+       usbtoxxx_current_cmd_index += 2;
+       SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], interval_us);
+       usbtoxxx_current_cmd_index += 2;
+       
+       return versaloon_add_pending(USB_TO_POLL, 0, 0, 0, 0, NULL, 0);
+}
+
+RESULT usbtopoll_end(void)
+{
+       if (!poll_nesting)
+       {
+               LOG_BUG(ERRMSG_FAILURE_OPERATION, "check poll nesting");
+               return ERRCODE_FAILURE_OPERATION;
+       }
+       if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 1))
+       {
+               return ERROR_FAIL;
+       }
+       
+       if (ERROR_OK != usbtoxxx_validate_current_command_type())
+       {
+               LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands");
+               return ERRCODE_FAILURE_OPERATION;
+       }
+       
+       poll_nesting--;
+       type_pre = USB_TO_POLL;
+       
+       usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_END;
+       
+       return versaloon_add_pending(USB_TO_POLL, 0, 0, 0, 0, NULL, 0);
+}
+
+RESULT usbtopoll_checkok(uint8_t equ, uint16_t offset, uint8_t size,
+                                                       uint32_t mask, uint32_t value)
+{
+       uint8_t i;
+       
+       if (size > 4)
+       {
+               LOG_BUG(ERRMSG_INVALID_PARAMETER, __FUNCTION__);
+               return ERRCODE_INVALID_PARAMETER;
+       }
+       if (!poll_nesting)
+       {
+               LOG_BUG(ERRMSG_FAILURE_OPERATION, "check poll nesting");
+               return ERRCODE_FAILURE_OPERATION;
+       }
+       if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 4 + 2 * size))
+       {
+               return ERROR_FAIL;
+       }
+       
+       if (ERROR_OK != usbtoxxx_validate_current_command_type())
+       {
+               LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands");
+               return ERRCODE_FAILURE_OPERATION;
+       }
+       
+       type_pre = USB_TO_POLL;
+       
+       usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_CHECKOK;
+       SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], offset);
+       usbtoxxx_current_cmd_index += 2;
+       usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = size;
+       usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = equ;
+       for (i =0; i < size; i++)
+       {
+               usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = (mask >> (8 * i)) & 0xFF;
+       }
+       for (i =0; i < size; i++)
+       {
+               usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = (value >> (8 * i)) & 0xFF;
+       }
+       
+       return ERROR_OK;
+}
+
+RESULT usbtopoll_checkfail(uint8_t equ, uint16_t offset, uint8_t size,
+                                                       uint32_t mask, uint32_t value)
+{
+       uint8_t i;
+       
+       if (size > 4)
+       {
+               LOG_BUG(ERRMSG_INVALID_PARAMETER, __FUNCTION__);
+               return ERRCODE_INVALID_PARAMETER;
+       }
+       if (!poll_nesting)
+       {
+               LOG_BUG(ERRMSG_FAILURE_OPERATION, "check poll nesting");
+               return ERRCODE_FAILURE_OPERATION;
+       }
+       if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 4 + 2 * size))
+       {
+               return ERROR_FAIL;
+       }
+       
+       if (ERROR_OK != usbtoxxx_validate_current_command_type())
+       {
+               LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands");
+               return ERRCODE_FAILURE_OPERATION;
+       }
+       
+       type_pre = USB_TO_POLL;
+       
+       usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_CHECKFAIL;
+       SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], offset);
+       usbtoxxx_current_cmd_index += 2;
+       usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = size;
+       usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = equ;
+       for (i =0; i < size; i++)
+       {
+               usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = (mask >> (8 * i)) & 0xFF;
+       }
+       for (i =0; i < size; i++)
+       {
+               usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = (value >> (8 * i)) & 0xFF;
+       }
+       
+       return ERROR_OK;
+}
+
+RESULT usbtopoll_verifybuff(uint16_t offset, uint16_t size, uint8_t *buff)
+{
+       if (!poll_nesting)
+       {
+               LOG_BUG(ERRMSG_FAILURE_OPERATION, "check poll nesting");
+               return ERRCODE_FAILURE_OPERATION;
+       }
+       if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 5 + size))
+       {
+               return ERROR_FAIL;
+       }
+       
+       if (ERROR_OK != usbtoxxx_validate_current_command_type())
+       {
+               LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands");
+               return ERRCODE_FAILURE_OPERATION;
+       }
+       
+       type_pre = USB_TO_POLL;
+       
+       usbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_VERIFYBUFF;
+       SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], offset);
+       usbtoxxx_current_cmd_index += 2;
+       SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], size);
+       usbtoxxx_current_cmd_index += 2;
+       memcpy(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], buff, size);
+       usbtoxxx_current_cmd_index += size;
+       
+       return ERROR_OK;
+}
+
+
+
+
+RESULT usbtodelay_delay(uint16_t dly)
+{
+       if (ERROR_OK != usbtoxxx_ensure_buffer_size(3 + 2))
+       {
+               return ERROR_FAIL;
+       }
+       
+       if (ERROR_OK != usbtoxxx_validate_current_command_type())
+       {
+               LOG_BUG(ERRMSG_FAILURE_OPERATION, "validate previous commands");
+               return ERRCODE_FAILURE_OPERATION;
+       }
+       type_pre = USB_TO_DELAY;
+       
+       SET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], dly);
+       usbtoxxx_current_cmd_index += 2;
+       
+       return versaloon_add_pending(USB_TO_DELAY, 0, 0, 0, 0, NULL, 0);
+}
+
+RESULT usbtodelay_delayms(uint16_t ms)
+{
+       return usbtodelay_delay(ms | 0x8000);
+}
+
+RESULT usbtodelay_delayus(uint16_t us)
+{
+       return usbtodelay_delay(us & 0x7FFF);
+}
+
diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.h b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.h
new file mode 100644 (file)
index 0000000..092368e
--- /dev/null
@@ -0,0 +1,278 @@
+/***************************************************************************
+ *   Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com>     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   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.             *
+ ***************************************************************************/
+#ifndef __USBTOXXX_H_INCLUDED__
+#define __USBTOXXX_H_INCLUDED__
+
+RESULT usbtoxxx_init(void);
+RESULT usbtoxxx_fini(void);
+RESULT usbtoxxx_execute_command(void);
+
+#define USB_TO_XXX_ABILITIES_LEN                       12
+extern uint8_t usbtoxxx_abilities[USB_TO_XXX_ABILITIES_LEN];
+bool usbtoxxx_interface_supported(uint8_t cmd);
+
+// USB_TO_INFO
+RESULT usbtoinfo_get_abilities(uint8_t abilities[USB_TO_XXX_ABILITIES_LEN]);
+
+// USB_TO_DELAY
+RESULT usbtodelay_delay(uint16_t dly);
+RESULT usbtodelay_delayms(uint16_t ms);
+RESULT usbtodelay_delayus(uint16_t us);
+
+
+
+// USB_TO_USART
+RESULT usbtousart_init(uint8_t interface_index);
+RESULT usbtousart_fini(uint8_t interface_index);
+RESULT usbtousart_config(uint8_t interface_index, uint32_t baudrate,
+                                                       uint8_t datalength, uint8_t mode);
+RESULT usbtousart_send(uint8_t interface_index, uint8_t *buf, uint16_t len);
+RESULT usbtousart_receive(uint8_t interface_index, uint8_t *buf, uint16_t len);
+RESULT usbtousart_status(uint8_t interface_index,
+                                                       struct usart_status_t *status);
+
+// USB_TO_SPI
+RESULT usbtospi_init(uint8_t interface_index);
+RESULT usbtospi_fini(uint8_t interface_index);
+RESULT usbtospi_config(uint8_t interface_index, uint32_t kHz, uint8_t mode);
+RESULT usbtospi_io(uint8_t interface_index, uint8_t *out, uint8_t *in,
+                                       uint16_t bytelen);
+
+
+
+// USB_TO_GPIO
+RESULT usbtogpio_init(uint8_t interface_index);
+RESULT usbtogpio_fini(uint8_t interface_index);
+RESULT usbtogpio_config(uint8_t interface_index, uint32_t mask,
+                                               uint32_t dir_mask, uint32_t pull_en_mask,
+                                               uint32_t input_pull_mask);
+RESULT usbtogpio_in(uint8_t interface_index, uint32_t mask, uint32_t *value);
+RESULT usbtogpio_out(uint8_t interface_index, uint32_t mask, uint32_t value);
+
+
+
+// USB_TO_ISSP
+RESULT usbtoissp_init(uint8_t interface_index);
+RESULT usbtoissp_fini(uint8_t interface_index);
+RESULT usbtoissp_enter_program_mode(uint8_t interface_index, uint8_t mode);
+RESULT usbtoissp_leave_program_mode(uint8_t interface_index, uint8_t mode);
+RESULT usbtoissp_wait_and_poll(uint8_t interface_index);
+RESULT usbtoissp_vector(uint8_t interface_index, uint8_t operate, uint8_t addr,
+                                               uint8_t data, uint8_t *buf);
+
+
+
+// USB_TO_LPCICP
+RESULT usbtolpcicp_init(uint8_t interface_index);
+RESULT usbtolpcicp_fini(uint8_t interface_index);
+RESULT usbtolpcicp_config(uint8_t interface_index);
+RESULT usbtolpcicp_enter_program_mode(uint8_t interface_index);
+RESULT usbtolpcicp_in(uint8_t interface_index, uint8_t *buff, uint16_t len);
+RESULT usbtolpcicp_out(uint8_t interface_index, uint8_t *buff, uint16_t len);
+RESULT usbtolpcicp_poll_ready(uint8_t interface_index, uint8_t data,
+               uint8_t *ret, uint8_t setmask, uint8_t clearmask, uint16_t pollcnt);
+
+
+
+// USB_TO_JTAG_LL
+RESULT usbtojtagll_init(uint8_t interface_index);
+RESULT usbtojtagll_fini(uint8_t interface_index);
+RESULT usbtojtagll_config(uint8_t interface_index, uint32_t kHz);
+RESULT usbtojtagll_tms(uint8_t interface_index, uint8_t *tms, uint8_t bytelen);
+RESULT usbtojtagll_tms_clocks(uint8_t interface_index, uint32_t bytelen,
+                                                               uint8_t tms);
+RESULT usbtojtagll_scan(uint8_t interface_index, uint8_t* data,
+                                               uint16_t bitlen, uint8_t tms_before_valid,
+                                               uint8_t tms_before, uint8_t tms_after0,
+                                               uint8_t tms_after1);
+
+
+
+// USB_TO_JTAG_HL
+RESULT usbtojtaghl_init(uint8_t interface_index);
+RESULT usbtojtaghl_fini(uint8_t interface_index);
+RESULT usbtojtaghl_config(uint8_t interface_index, uint32_t kHz, uint8_t ub,
+                                                 uint8_t ua, uint16_t bb, uint16_t ba);
+RESULT usbtojtaghl_ir(uint8_t interface_index, uint8_t *ir, uint16_t bitlen,
+                                         uint8_t idle, uint8_t want_ret);
+RESULT usbtojtaghl_dr(uint8_t interface_index, uint8_t *dr, uint16_t bitlen,
+                                         uint8_t idle, uint8_t want_ret);
+RESULT usbtojtaghl_tms(uint8_t interface_index, uint8_t *tms, uint16_t bitlen);
+RESULT usbtojtaghl_runtest(uint8_t interface_index, uint32_t cycles);
+RESULT usbtojtaghl_register_callback(uint8_t index, jtag_callback_t send_callback,
+                                                                        jtag_callback_t receive_callback);
+
+
+
+// USB_TO_JTAG_RAW
+RESULT usbtojtagraw_init(uint8_t interface_index);
+RESULT usbtojtagraw_fini(uint8_t interface_index);
+RESULT usbtojtagraw_config(uint8_t interface_index, uint32_t kHz);
+RESULT usbtojtagraw_execute(uint8_t interface_index, uint8_t *tdi,
+                                                       uint8_t *tms, uint8_t *tdo, uint32_t bitlen);
+
+
+
+
+// USB_TO_C2
+RESULT usbtoc2_init(uint8_t interface_index);
+RESULT usbtoc2_fini(uint8_t interface_index);
+RESULT usbtoc2_writeaddr(uint8_t interface_index, uint8_t addr);
+RESULT usbtoc2_readaddr(uint8_t interface_index, uint8_t *data);
+RESULT usbtoc2_writedata(uint8_t interface_index, uint8_t *buf, uint8_t len);
+RESULT usbtoc2_readdata(uint8_t interface_index, uint8_t *buf, uint8_t len);
+
+
+
+// USB_TO_I2C
+RESULT usbtoi2c_init(uint8_t interface_index);
+RESULT usbtoi2c_fini(uint8_t interface_index);
+RESULT usbtoi2c_config(uint8_t interface_index, uint16_t kHz,
+                                               uint16_t byte_interval, uint16_t max_dly);
+RESULT usbtoi2c_read(uint8_t interface_index, uint16_t chip_addr,
+                                               uint8_t *data, uint16_t data_len, uint8_t stop,
+                                               bool nacklast);
+RESULT usbtoi2c_write(uint8_t interface_index, uint16_t chip_addr,
+                                               uint8_t *data, uint16_t data_len, uint8_t stop);
+
+
+
+// USB_TO_MSP430_JTAG
+RESULT usbtomsp430jtag_init(uint8_t interface_index);
+RESULT usbtomsp430jtag_fini(uint8_t interface_index);
+RESULT usbtomsp430jtag_config(uint8_t interface_index, uint8_t has_test);
+RESULT usbtomsp430jtag_ir(uint8_t interface_index, uint8_t *ir,
+                                                       uint8_t want_ret);
+RESULT usbtomsp430jtag_dr(uint8_t interface_index, uint32_t *dr,
+                                                       uint8_t bitlen, uint8_t want_ret);
+RESULT usbtomsp430jtag_tclk(uint8_t interface_index, uint8_t value);
+RESULT usbtomsp430jtag_tclk_strobe(uint8_t interface_index, uint16_t cnt);
+RESULT usbtomsp430jtag_reset(uint8_t interface_index);
+RESULT usbtomsp430jtag_poll(uint8_t interface_index, uint32_t dr,
+                                                       uint32_t mask, uint32_t value, uint8_t len,
+                                                       uint16_t poll_cnt, uint8_t toggle_tclk);
+
+
+
+// USB_TO_MSP430_SBW
+RESULT usbtomsp430sbw_init(uint8_t interface_index);
+RESULT usbtomsp430sbw_fini(uint8_t interface_index);
+RESULT usbtomsp430sbw_config(uint8_t interface_index, uint8_t has_test);
+RESULT usbtomsp430sbw_ir(uint8_t interface_index, uint8_t *ir,
+                                                       uint8_t want_ret);
+RESULT usbtomsp430sbw_dr(uint8_t interface_index, uint32_t *dr,
+                                                       uint8_t bitlen, uint8_t want_ret);
+RESULT usbtomsp430sbw_tclk(uint8_t interface_index, uint8_t value);
+RESULT usbtomsp430sbw_tclk_strobe(uint8_t interface_index, uint16_t cnt);
+RESULT usbtomsp430sbw_reset(uint8_t interface_index);
+RESULT usbtomsp430sbw_poll(uint8_t interface_index, uint32_t dr, uint32_t mask,
+                                                  uint32_t value, uint8_t len, uint16_t poll_cnt,
+                                                  uint8_t toggle_tclk);
+
+
+
+// USB_TO_POWER
+RESULT usbtopwr_init(uint8_t interface_index);
+RESULT usbtopwr_fini(uint8_t interface_index);
+RESULT usbtopwr_config(uint8_t interface_index);
+RESULT usbtopwr_output(uint8_t interface_index, uint16_t mV);
+
+
+
+// USB_TO_POLL
+RESULT usbtopoll_start(uint16_t retry_cnt, uint16_t interval_us);
+RESULT usbtopoll_end(void);
+RESULT usbtopoll_checkok(uint8_t equ, uint16_t offset, uint8_t size,
+                                                       uint32_t mask, uint32_t value);
+RESULT usbtopoll_checkfail(uint8_t equ, uint16_t offset, uint8_t size,
+                                                       uint32_t mask, uint32_t value);
+RESULT usbtopoll_verifybuff(uint16_t offset, uint16_t size, uint8_t *buff);
+
+
+
+// USB_TO_SWD
+RESULT usbtoswd_init(uint8_t interface_index);
+RESULT usbtoswd_fini(uint8_t interface_index);
+RESULT usbtoswd_config(uint8_t interface_index, uint8_t trn, uint16_t retry,
+                                          uint16_t dly);
+RESULT usbtoswd_seqout(uint8_t interface_index, uint8_t *data, uint16_t bitlen);
+RESULT usbtoswd_seqin(uint8_t interface_index, uint8_t *data, uint16_t bitlen);
+RESULT usbtoswd_transact(uint8_t interface_index, uint8_t request,
+                                                       uint32_t *data, uint8_t *ack);
+
+
+
+// USB_TO_SWIM
+RESULT usbtoswim_init(uint8_t interface_index);
+RESULT usbtoswim_fini(uint8_t interface_index);
+RESULT usbtoswim_config(uint8_t interface_index, uint8_t mHz, uint8_t cnt0,
+                                               uint8_t cnt1);
+RESULT usbtoswim_srst(uint8_t interface_index);
+RESULT usbtoswim_wotf(uint8_t interface_index, uint8_t *data,
+                                               uint16_t bytelen, uint32_t addr);
+RESULT usbtoswim_rotf(uint8_t interface_index, uint8_t *data,
+                                               uint16_t bytelen, uint32_t addr);
+RESULT usbtoswim_sync(uint8_t interface_index, uint8_t mHz);
+RESULT usbtoswim_enable(uint8_t interface_index);
+
+
+
+
+// USB_TO_BDM
+RESULT usbtobdm_init(uint8_t interface_index);
+RESULT usbtobdm_fini(uint8_t interface_index);
+RESULT usbtobdm_sync(uint8_t interface_index, uint16_t *khz);
+RESULT usbtobdm_transact(uint8_t interface_index, uint8_t *out,
+       uint8_t outlen, uint8_t *in, uint8_t inlen, uint8_t delay, uint8_t ack);
+
+
+
+// USB_TO_DUSI
+RESULT usbtodusi_init(uint8_t interface_index);
+RESULT usbtodusi_fini(uint8_t interface_index);
+RESULT usbtodusi_config(uint8_t interface_index, uint32_t kHz, uint8_t mode);
+RESULT usbtodusi_io(uint8_t interface_index, uint8_t *mo, uint8_t *mi,
+                                       uint8_t *so, uint8_t *si, uint32_t bitlen);
+
+
+
+// USB_TO_MICROWIRE
+RESULT usbtomicrowire_init(uint8_t interface_index);
+RESULT usbtomicrowire_fini(uint8_t interface_index);
+RESULT usbtomicrowire_config(uint8_t interface_index, uint16_t kHz,
+                                                               uint8_t sel_polarity);
+RESULT usbtomicrowire_transport(uint8_t interface_index,
+                                                               uint32_t opcode, uint8_t opcode_bitlen,
+                                                               uint32_t addr, uint8_t addr_bitlen,
+                                                               uint32_t data, uint8_t data_bitlen,
+                                                               uint8_t *reply, uint8_t reply_bitlen);
+RESULT usbtomicrowire_poll(uint8_t interface_index, uint16_t interval_us,
+                                                       uint16_t retry_cnt);
+
+
+
+// USB_TO_PWM
+RESULT usbtopwm_init(uint8_t interface_index);
+RESULT usbtopwm_fini(uint8_t interface_index);
+RESULT usbtopwm_config(uint8_t interface_index, uint16_t kHz, uint8_t mode);
+RESULT usbtopwm_out(uint8_t interface_index, uint16_t count, uint16_t *rate);
+RESULT usbtopwm_in(uint8_t interface_index, uint16_t count, uint16_t *rate);
+
+#endif /* __USBTOXXX_H_INCLUDED__ */
+
diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx_internal.h b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx_internal.h
new file mode 100644 (file)
index 0000000..837d694
--- /dev/null
@@ -0,0 +1,169 @@
+/***************************************************************************
+ *   Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com>     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   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.             *
+ ***************************************************************************/
+#ifndef __USBTOXXX_INTERNAL_H_INCLUDED__
+#define __USBTOXXX_INTERNAL_H_INCLUDED__
+
+// USB_TO_XXX USB Commands
+// Page0
+#define USB_TO_USART                           (VERSALOON_USB_TO_XXX_CMD_START + 0x00)
+#define USB_TO_SPI                                     (VERSALOON_USB_TO_XXX_CMD_START + 0x01)
+#define USB_TO_I2C                                     (VERSALOON_USB_TO_XXX_CMD_START + 0x02)
+#define USB_TO_GPIO                                    (VERSALOON_USB_TO_XXX_CMD_START + 0x03)
+#define USB_TO_CAN                                     (VERSALOON_USB_TO_XXX_CMD_START + 0x04)
+#define USB_TO_PWM                                     (VERSALOON_USB_TO_XXX_CMD_START + 0x05)
+#define USB_TO_ADC                                     (VERSALOON_USB_TO_XXX_CMD_START + 0x06)
+#define USB_TO_DAC                                     (VERSALOON_USB_TO_XXX_CMD_START + 0x07)
+#define USB_TO_MICROWIRE                       (VERSALOON_USB_TO_XXX_CMD_START + 0x08)
+#define USB_TO_SWIM                                    (VERSALOON_USB_TO_XXX_CMD_START + 0x09)
+#define USB_TO_DUSI                                    (VERSALOON_USB_TO_XXX_CMD_START + 0x0A)
+// Page1
+#define USB_TO_JTAG_LL                         (VERSALOON_USB_TO_XXX_CMD_START + 0x20)
+#define USB_TO_JTAG_HL                         (VERSALOON_USB_TO_XXX_CMD_START + 0x21)
+#define USB_TO_ISSP                                    (VERSALOON_USB_TO_XXX_CMD_START + 0x22)
+#define USB_TO_C2                                      (VERSALOON_USB_TO_XXX_CMD_START + 0x23)
+#define USB_TO_SBW                                     (VERSALOON_USB_TO_XXX_CMD_START + 0x24)
+#define USB_TO_LPCICP                          (VERSALOON_USB_TO_XXX_CMD_START + 0x25)
+#define USB_TO_SWD                                     (VERSALOON_USB_TO_XXX_CMD_START + 0x26)
+#define USB_TO_JTAG_RAW                                (VERSALOON_USB_TO_XXX_CMD_START + 0x27)
+#define USB_TO_BDM                                     (VERSALOON_USB_TO_XXX_CMD_START + 0x28)
+#define USB_TO_MSP430_JTAG                     (VERSALOON_USB_TO_XXX_CMD_START + 0x38)
+// Page2
+#define USB_TO_POWER                           (VERSALOON_USB_TO_XXX_CMD_START + 0x40)
+#define USB_TO_DELAY                           (VERSALOON_USB_TO_XXX_CMD_START + 0x41)
+#define USB_TO_POLL                                    (VERSALOON_USB_TO_XXX_CMD_START + 0x42)
+#define USB_TO_INFO                                    (VERSALOON_USB_TO_XXX_CMD_START + 0x5E)
+#define USB_TO_ALL                                     (VERSALOON_USB_TO_XXX_CMD_START + 0x5F)
+
+
+
+// USB_TO_XXX Masks
+#define USB_TO_XXX_CMDMASK                     0xF8
+#define USB_TO_XXX_CMDSHIFT                    3
+#define USB_TO_XXX_IDXMASK                     0x07
+// USB_TO_XXX Sub Commands
+// Common Sub Commands
+#define USB_TO_XXX_INIT                                (0x00 << USB_TO_XXX_CMDSHIFT)
+#define USB_TO_XXX_FINI                                (0x01 << USB_TO_XXX_CMDSHIFT)
+#define USB_TO_XXX_CONFIG                      (0x02 << USB_TO_XXX_CMDSHIFT)
+#define USB_TO_XXX_GETHWINFO           (0x03 << USB_TO_XXX_CMDSHIFT)
+#define USB_TO_XXX_STATUS                      (0X04 << USB_TO_XXX_CMDSHIFT)
+#define USB_TO_XXX_IN_OUT                      (0x05 << USB_TO_XXX_CMDSHIFT)
+#define USB_TO_XXX_IN                          (0x06 << USB_TO_XXX_CMDSHIFT)
+#define USB_TO_XXX_OUT                         (0x07 << USB_TO_XXX_CMDSHIFT)
+#define USB_TO_XXX_POLL                                (0x08 << USB_TO_XXX_CMDSHIFT)
+#define USB_TO_XXX_SPECIAL                     (0x09 << USB_TO_XXX_CMDSHIFT)
+#define USB_TO_XXX_RESET                       (0x0A << USB_TO_XXX_CMDSHIFT)
+#define USB_TO_XXX_SYNC                                (0x0B << USB_TO_XXX_CMDSHIFT)
+#define USB_TO_XXX_ENABLE                      (0x0C << USB_TO_XXX_CMDSHIFT)
+#define USB_TO_XXX_DISABLE                     (0x0D << USB_TO_XXX_CMDSHIFT)
+// USB_TO_POLL
+#define USB_TO_POLL_START                      0x00
+#define USB_TO_POLL_END                                0x01
+#define USB_TO_POLL_CHECKOK                    0x02
+#define USB_TO_POLL_CHECKFAIL          0x03
+#define USB_TO_POLL_VERIFYBUFF         0x04
+
+
+
+// USB_TO_XXX Replys
+#define USB_TO_XXX_OK                          0x00
+#define USB_TO_XXX_FAILED                      0x01
+#define USB_TO_XXX_TIME_OUT                    0x02
+#define USB_TO_XXX_INVALID_INDEX       0x03
+#define USB_TO_XXX_INVALID_PARA                0x04
+#define USB_TO_XXX_INVALID_CMD         0x05
+#define USB_TO_XXX_CMD_NOT_SUPPORT     0x06
+
+
+
+// USB_TO_XXX
+RESULT usbtoxxx_add_pending(uint8_t type, uint8_t cmd, uint16_t
+                                                       actual_szie, uint16_t want_pos,
+                                                       uint16_t want_size, uint8_t *buffer);
+
+RESULT usbtoxxx_add_command(uint8_t type, uint8_t cmd, uint8_t *cmdbuf,
+                                                       uint16_t cmdlen, uint16_t retlen,
+                                                       uint8_t *wantbuf, uint16_t wantpos,
+                                                       uint16_t wantlen, uint8_t collect);
+
+#define usbtoxxx_init_command(type, port)                                                      \
+                       usbtoxxx_add_command((type), (USB_TO_XXX_INIT | (port)), \
+                                                                       NULL, 0, 0, NULL, 0, 0, 0)
+#define usbtoxxx_fini_command(type, port)                                                                      \
+                       usbtoxxx_add_command((type), (USB_TO_XXX_FINI | (port)), \
+                                                                       NULL, 0, 0, NULL, 0, 0, 0)
+#define usbtoxxx_conf_command(type, port, cmdbuf, cmdlen)                                      \
+                       usbtoxxx_add_command((type), (USB_TO_XXX_CONFIG | (port)), \
+                                                                (cmdbuf), (cmdlen), 0, NULL, 0, 0, 0)
+#define usbtoxxx_inout_command(type, port, cmdbuf, cmdlen, retlen, wantbuf, \
+                                                          wantpos, wantlen, c)                                                 \
+                       usbtoxxx_add_command((type), (USB_TO_XXX_IN_OUT | (port)), \
+                                                                (cmdbuf), (cmdlen), (retlen), (wantbuf), \
+                                                                (wantpos), (wantlen), (c))
+#define usbtoxxx_in_command(type, port, cmdbuf, cmdlen, retlen, wantbuf, \
+                                                       wantpos, wantlen, c)                                                    \
+                       usbtoxxx_add_command((type), (USB_TO_XXX_IN | (port)), (cmdbuf), \
+                                                                (cmdlen), (retlen), (wantbuf), (wantpos), \
+                                                                (wantlen), (c))
+#define usbtoxxx_out_command(type, port, cmdbuf, cmdlen, c)                                    \
+                       usbtoxxx_add_command((type), (USB_TO_XXX_OUT | (port)), (cmdbuf), \
+                                                                (cmdlen), 0, NULL, 0, 0, (c))
+#define usbtoxxx_poll_command(type, port, cmdbuf, cmdlen, retbuf, retlen)      \
+                       usbtoxxx_add_command((type), (USB_TO_XXX_POLL | (port)), (cmdbuf),\
+                                                                (cmdlen), (retlen), (retbuf), 0, (retlen), 0)
+#define usbtoxxx_status_command(type, port, retlen, wantbuf, wantpos, wantlen, c)\
+                       usbtoxxx_add_command((type), (USB_TO_XXX_STATUS | (port)), \
+                                                                NULL, 0, (retlen), (wantbuf), (wantpos), \
+                                                                (wantlen), (c))
+#define usbtoxxx_special_command(type, port, cmdbuf, cmdlen, retlen, wantbuf, \
+                                                                wantpos, wantlen, c)                                           \
+                       usbtoxxx_add_command((type), (USB_TO_XXX_SPECIAL | (port)), \
+                                                                (cmdbuf), (cmdlen), retlen, wantbuf, \
+                                                                wantpos, wantlen, (c))
+#define usbtoxxx_reset_command(type, port, cmdbuf, cmdlen)                                     \
+                       usbtoxxx_add_command((type), (USB_TO_XXX_RESET | (port)), \
+                                                                (cmdbuf), (cmdlen), 0, NULL, 0, 0, 0)
+#define usbtoxxx_sync_command(type, port, cmdbuf, cmdlen, retlen, wantbuf)     \
+                       usbtoxxx_add_command((type), (USB_TO_XXX_SYNC | (port)), \
+                                                                (cmdbuf), (cmdlen), (retlen), (wantbuf), 0, \
+                                                                (retlen), 0)
+#define usbtoxxx_enable_command(type, port, cmdbuf, cmdlen)                                    \
+                       usbtoxxx_add_command((type), (USB_TO_XXX_ENABLE | (port)), \
+                                                                (cmdbuf), (cmdlen), 0, NULL, 0, 0, 0)
+#define usbtoxxx_disable_command(type, port, cmdbuf, cmdlen)                           \
+                       usbtoxxx_add_command((type), (USB_TO_XXX_DISABLE | (port)), \
+                                                                (cmdbuf), (cmdlen), 0, NULL, 0, 0, 0)
+
+// USB_TO_SPI
+#define USB_TO_SPI_BAUDRATE_MSK                0x1F
+#define USB_TO_SPI_CPOL_MSK                    0x20
+#define USB_TO_SPI_CPHA_MSK                    0x40
+#define USB_TO_SPI_MSB_FIRST           0x80
+
+// USB_TO_DUSI
+#define USB_TO_DUSI_BAUDRATE_MSK       0x1F
+#define USB_TO_DUSI_CPOL_MSK           0x20
+#define USB_TO_DUSI_CPHA_MSK           0x40
+#define USB_TO_DUSI_MSB_FIRST          0x80
+
+// USB_TO_GPIO
+#define USB_TO_GPIO_DIR_MSK                    0x01
+
+#endif /* __USBTOXXX_INTERNAL_H_INCLUDED__ */
+
diff --git a/src/jtag/drivers/versaloon/versaloon.c b/src/jtag/drivers/versaloon/versaloon.c
new file mode 100644 (file)
index 0000000..dbb8e4f
--- /dev/null
@@ -0,0 +1,398 @@
+/***************************************************************************
+ *   Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com>     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   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.             *
+ ***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "versaloon_include.h"
+#include "versaloon.h"
+#include "versaloon_internal.h"
+#include "usbtoxxx/usbtoxxx.h"
+
+uint8_t *versaloon_buf = NULL;
+uint8_t *versaloon_cmd_buf = NULL;
+uint16_t versaloon_buf_size;
+
+struct versaloon_pending_t versaloon_pending[VERSALOON_MAX_PENDING_NUMBER];
+uint16_t versaloon_pending_idx = 0;
+
+usb_dev_handle *versaloon_usb_device_handle = NULL;
+static uint32_t versaloon_usb_to = VERSALOON_TIMEOUT;
+
+RESULT versaloon_init(void);
+RESULT versaloon_fini(void);
+RESULT versaloon_get_target_voltage(uint16_t *voltage);
+RESULT versaloon_set_target_voltage(uint16_t voltage);
+RESULT versaloon_delay_ms(uint16_t ms);
+RESULT versaloon_delay_us(uint16_t us);
+struct versaloon_interface_t versaloon_interface =
+{
+       .init                                   = versaloon_init,
+       .fini                                   = versaloon_fini,
+       {// adaptors
+               {// target_voltage
+                       .get                    = versaloon_get_target_voltage,
+                       .set                    = versaloon_set_target_voltage,
+               },
+               {// gpio
+                       .init                   = usbtogpio_init,
+                       .fini                   = usbtogpio_fini,
+                       .config                 = usbtogpio_config,
+                       .out                    = usbtogpio_out,
+                       .in                             = usbtogpio_in,
+               },
+               {// delay
+                       .delayms                = versaloon_delay_ms,
+                       .delayus                = versaloon_delay_us,
+               },
+               {// swd
+                       .init                   = usbtoswd_init,
+                       .fini                   = usbtoswd_fini,
+                       .config                 = usbtoswd_config,
+                       .seqout                 = usbtoswd_seqout,
+                       .seqin                  = usbtoswd_seqin,
+                       .transact               = usbtoswd_transact,
+               },
+               {// jtag_raw
+                       .init                   = usbtojtagraw_init,
+                       .fini                   = usbtojtagraw_fini,
+                       .config                 = usbtojtagraw_config,
+                       .execute                = usbtojtagraw_execute,
+               },
+               .peripheral_commit      = usbtoxxx_execute_command,
+       },
+       {// usb_setting
+               .vid                            = VERSALOON_VID,
+               .pid                            = VERSALOON_PID,
+               .ep_out                         = VERSALOON_OUTP,
+               .ep_in                          = VERSALOON_INP,
+               .interface                      = VERSALOON_IFACE,
+               .serialstring           = NULL,
+               .buf_size                       = 256,
+       }
+};
+
+// programmer_cmd
+static uint32_t versaloon_pending_id = 0;
+static versaloon_callback_t versaloon_callback = NULL;
+static void *versaloon_extra_data = NULL;
+static struct versaloon_want_pos_t *versaloon_want_pos = NULL;
+void versaloon_set_pending_id(uint32_t id)
+{
+       versaloon_pending_id = id;
+}
+void versaloon_set_callback(versaloon_callback_t callback)
+{
+       versaloon_callback = callback;
+}
+void versaloon_set_extra_data(void * p)
+{
+       versaloon_extra_data = p;
+}
+
+void versaloon_free_want_pos(void)
+{
+       uint16_t i;
+       struct versaloon_want_pos_t *tmp, *free_tmp;
+
+       tmp = versaloon_want_pos;
+       while (tmp != NULL)
+       {
+               free_tmp = tmp;
+               tmp = tmp->next;
+               free(free_tmp);
+       }
+       versaloon_want_pos = NULL;
+
+       for (i = 0; i < dimof(versaloon_pending); i++)
+       {
+               tmp = versaloon_pending[i].pos;
+               while (tmp != NULL)
+               {
+                       free_tmp = tmp;
+                       tmp = tmp->next;
+                       free(free_tmp);
+               }
+               versaloon_pending[i].pos = NULL;
+       }
+}
+
+RESULT versaloon_add_want_pos(uint16_t offset, uint16_t size, uint8_t *buff)
+{
+       struct versaloon_want_pos_t *new_pos = NULL;
+
+       new_pos = (struct versaloon_want_pos_t *)malloc(sizeof(*new_pos));
+       if (NULL == new_pos)
+       {
+               LOG_ERROR(ERRMSG_NOT_ENOUGH_MEMORY);
+               return ERRCODE_NOT_ENOUGH_MEMORY;
+       }
+       new_pos->offset = offset;
+       new_pos->size = size;
+       new_pos->buff = buff;
+       new_pos->next = NULL;
+
+       if (NULL == versaloon_want_pos)
+       {
+               versaloon_want_pos = new_pos;
+       }
+       else
+       {
+               struct versaloon_want_pos_t *tmp = versaloon_want_pos;
+
+               while (tmp->next != NULL)
+               {
+                       tmp = tmp->next;
+               }
+               tmp->next = new_pos;
+       }
+
+       return ERROR_OK;
+}
+
+RESULT versaloon_add_pending(uint8_t type, uint8_t cmd, uint16_t actual_szie,
+       uint16_t want_pos, uint16_t want_size, uint8_t *buffer, uint8_t collect)
+{
+#if PARAM_CHECK
+       if (versaloon_pending_idx >= VERSALOON_MAX_PENDING_NUMBER)
+       {
+               LOG_BUG(ERRMSG_INVALID_INDEX, versaloon_pending_idx,
+                                       "versaloon pending data");
+               return ERROR_FAIL;
+       }
+#endif
+
+       versaloon_pending[versaloon_pending_idx].type = type;
+       versaloon_pending[versaloon_pending_idx].cmd = cmd;
+       versaloon_pending[versaloon_pending_idx].actual_data_size = actual_szie;
+       versaloon_pending[versaloon_pending_idx].want_data_pos = want_pos;
+       versaloon_pending[versaloon_pending_idx].want_data_size = want_size;
+       versaloon_pending[versaloon_pending_idx].data_buffer = buffer;
+       versaloon_pending[versaloon_pending_idx].collect = collect;
+       versaloon_pending[versaloon_pending_idx].id = versaloon_pending_id;
+       versaloon_pending_id = 0;
+       versaloon_pending[versaloon_pending_idx].extra_data = versaloon_extra_data;
+       versaloon_extra_data = NULL;
+       versaloon_pending[versaloon_pending_idx].callback = versaloon_callback;
+       versaloon_callback = NULL;
+       versaloon_pending[versaloon_pending_idx].pos = versaloon_want_pos;
+       versaloon_want_pos = NULL;
+       versaloon_pending_idx++;
+
+       return ERROR_OK;
+}
+
+RESULT versaloon_send_command(uint16_t out_len, uint16_t *inlen)
+{
+       int ret;
+
+#if PARAM_CHECK
+       if (NULL == versaloon_buf)
+       {
+               LOG_BUG(ERRMSG_INVALID_BUFFER, TO_STR(versaloon_buf));
+               return ERRCODE_INVALID_BUFFER;
+       }
+       if ((0 == out_len) || (out_len > versaloon_interface.usb_setting.buf_size))
+       {
+               LOG_BUG(ERRMSG_INVALID_PARAMETER, __FUNCTION__);
+               return ERRCODE_INVALID_PARAMETER;
+       }
+#endif
+
+       ret = usb_bulk_write(versaloon_usb_device_handle,
+               versaloon_interface.usb_setting.ep_out, (char *)versaloon_buf,
+               out_len, versaloon_usb_to);
+       if (ret != out_len)
+       {
+               LOG_ERROR(ERRMSG_FAILURE_OPERATION_ERRSTRING, "send usb data",
+                       usb_strerror());
+               return ERRCODE_FAILURE_OPERATION;
+       }
+
+       if (inlen != NULL)
+       {
+               ret = usb_bulk_read(versaloon_usb_device_handle,
+                       versaloon_interface.usb_setting.ep_in, (char *)versaloon_buf,
+                       versaloon_interface.usb_setting.buf_size, versaloon_usb_to);
+               if (ret > 0)
+               {
+                       *inlen = (uint16_t)ret;
+                       return ERROR_OK;
+               }
+               else
+               {
+                       LOG_ERROR(ERRMSG_FAILURE_OPERATION_ERRSTRING, "receive usb data",
+                                               usb_strerror());
+                       return ERROR_FAIL;
+               }
+       }
+       else
+       {
+               return ERROR_OK;
+       }
+}
+
+#define VERSALOON_RETRY_CNT                            10
+RESULT versaloon_init(void)
+{
+       uint16_t ret = 0;
+       uint8_t retry;
+       uint32_t timeout_tmp;
+
+       // malloc temporary buffer
+       versaloon_buf =
+               (uint8_t *)malloc(versaloon_interface.usb_setting.buf_size);
+       if (NULL == versaloon_buf)
+       {
+               LOG_ERROR(ERRMSG_NOT_ENOUGH_MEMORY);
+               return ERRCODE_NOT_ENOUGH_MEMORY;
+       }
+
+       // connect to versaloon
+       timeout_tmp = versaloon_usb_to;
+       // not output error message when connectting
+       // 100ms delay when connect
+       versaloon_usb_to = 100;
+       for (retry = 0; retry < VERSALOON_RETRY_CNT; retry++)
+       {
+               versaloon_buf[0] = VERSALOON_GET_INFO;
+               if ((ERROR_OK == versaloon_send_command(1, &ret)) && (ret >= 3))
+               {
+                       break;
+               }
+       }
+       versaloon_usb_to = timeout_tmp;
+       if (VERSALOON_RETRY_CNT == retry)
+       {
+               versaloon_fini();
+               LOG_ERROR(ERRMSG_FAILURE_OPERATION, "communicate with versaloon");
+               return ERRCODE_FAILURE_OPERATION;
+       }
+
+       versaloon_buf[ret] = 0;
+       versaloon_buf_size = versaloon_buf[0] + (versaloon_buf[1] << 8);
+       versaloon_interface.usb_setting.buf_size = versaloon_buf_size;
+       LOG_INFO("%s", versaloon_buf + 2);
+
+       // free temporary buffer
+       free(versaloon_buf);
+       versaloon_buf = NULL;
+
+       versaloon_buf =
+               (uint8_t *)malloc(versaloon_interface.usb_setting.buf_size);
+       if (NULL == versaloon_buf)
+       {
+               versaloon_fini();
+               LOG_ERROR(ERRMSG_NOT_ENOUGH_MEMORY);
+               return ERRCODE_NOT_ENOUGH_MEMORY;
+       }
+       versaloon_cmd_buf =
+               (uint8_t *)malloc(versaloon_interface.usb_setting.buf_size - 3);
+       if (NULL == versaloon_cmd_buf)
+       {
+               versaloon_fini();
+               LOG_ERROR(ERRMSG_NOT_ENOUGH_MEMORY);
+               return ERRCODE_NOT_ENOUGH_MEMORY;
+       }
+       if (ERROR_OK != usbtoxxx_init())
+       {
+               LOG_ERROR(ERRMSG_FAILURE_OPERATION, "initialize usbtoxxx");
+               return ERROR_FAIL;
+       }
+       return versaloon_get_target_voltage(&ret);
+}
+
+RESULT versaloon_fini(void)
+{
+       if (versaloon_usb_device_handle != NULL)
+       {
+               usbtoxxx_fini();
+               versaloon_free_want_pos();
+
+               versaloon_usb_device_handle = NULL;
+
+               if (versaloon_buf != NULL)
+               {
+                       free(versaloon_buf);
+                       versaloon_buf = NULL;
+               }
+               if (versaloon_cmd_buf != NULL)
+               {
+                       free(versaloon_cmd_buf);
+                       versaloon_cmd_buf = NULL;
+               }
+       }
+
+       return ERROR_OK;
+}
+
+RESULT versaloon_set_target_voltage(uint16_t voltage)
+{
+       usbtopwr_init(0);
+       usbtopwr_config(0);
+       usbtopwr_output(0, voltage);
+       usbtopwr_fini(0);
+
+       return usbtoxxx_execute_command();
+}
+
+RESULT versaloon_get_target_voltage(uint16_t *voltage)
+{
+       uint16_t inlen;
+
+#if PARAM_CHECK
+       if (NULL == versaloon_buf)
+       {
+               LOG_BUG(ERRMSG_INVALID_BUFFER, TO_STR(versaloon_buf));
+               return ERRCODE_INVALID_BUFFER;
+       }
+       if (NULL == voltage)
+       {
+               LOG_BUG(ERRMSG_INVALID_PARAMETER, __FUNCTION__);
+               return ERRCODE_INVALID_PARAMETER;
+       }
+#endif
+
+       versaloon_buf[0] = VERSALOON_GET_TVCC;
+
+       if ((ERROR_OK != versaloon_send_command(1, &inlen)) || (inlen != 2))
+       {
+               LOG_ERROR(ERRMSG_FAILURE_OPERATION, "communicate with versaloon");
+               return ERRCODE_FAILURE_OPERATION;
+       }
+       else
+       {
+               *voltage = versaloon_buf[0] + (versaloon_buf[1] << 8);
+               return ERROR_OK;
+       }
+}
+
+RESULT versaloon_delay_ms(uint16_t ms)
+{
+       return usbtodelay_delay(ms | 0x8000);
+}
+
+RESULT versaloon_delay_us(uint16_t us)
+{
+       return usbtodelay_delay(us & 0x7FFF);
+}
+
diff --git a/src/jtag/drivers/versaloon/versaloon.h b/src/jtag/drivers/versaloon/versaloon.h
new file mode 100644 (file)
index 0000000..18ccbea
--- /dev/null
@@ -0,0 +1,119 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by Simon Qian <SimonQian@SimonQian.com>            *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   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.             *
+ ***************************************************************************/
+#ifndef __VERSALOON_H_INCLUDED__
+#define __VERSALOON_H_INCLUDED__
+
+struct usart_status_t
+{
+       uint32_t tx_buff_avail;
+       uint32_t tx_buff_size;
+       uint32_t rx_buff_avail;
+       uint32_t rx_buff_size;
+};
+
+#include "usbtoxxx/usbtoxxx.h"
+
+// GPIO pins
+#define GPIO_SRST                              (1 << 0)
+#define GPIO_TRST                              (1 << 1)
+#define GPIO_USR1                              (1 << 2)
+#define GPIO_USR2                              (1 << 3)
+#define GPIO_TCK                               (1 << 4)
+#define GPIO_TDO                               (1 << 5)
+#define GPIO_TDI                               (1 << 6)
+#define GPIO_RTCK                              (1 << 7)
+#define GPIO_TMS                               (1 << 8)
+struct interface_gpio_t
+{
+       RESULT (*init)(uint8_t interface_index);
+       RESULT (*fini)(uint8_t interface_index);
+       RESULT (*config)(uint8_t interface_index, uint32_t pin_mask, uint32_t io,
+               uint32_t pull_en_mask, uint32_t input_pull_mask);
+       RESULT (*out)(uint8_t interface_index, uint32_t pin_mask, uint32_t value);
+       RESULT (*in)(uint8_t interface_index, uint32_t pin_mask, uint32_t *value);
+};
+
+struct interface_delay_t
+{
+       RESULT (*delayms)(uint16_t ms);
+       RESULT (*delayus)(uint16_t us);
+};
+
+struct interface_swd_t
+{
+       RESULT (*init)(uint8_t interface_index);
+       RESULT (*fini)(uint8_t interface_index);
+       RESULT (*config)(uint8_t interface_index, uint8_t trn, uint16_t retry,
+               uint16_t dly);
+       RESULT (*seqout)(uint8_t interface_index, uint8_t *data, uint16_t bitlen);
+       RESULT (*seqin)(uint8_t interface_index, uint8_t *data, uint16_t bitlen);
+       RESULT (*transact)(uint8_t interface_index, uint8_t request,
+               uint32_t *data, uint8_t *ack);
+};
+
+struct interface_jtag_raw_t
+{
+       RESULT (*init)(uint8_t interface_index);
+       RESULT (*fini)(uint8_t interface_index);
+       RESULT (*config)(uint8_t interface_index, uint32_t kHz);
+       RESULT (*execute)(uint8_t interface_index, uint8_t* tdi, uint8_t* tms,
+               uint8_t *tdo, uint32_t bitlen);
+};
+
+struct interface_target_voltage_t
+{
+       RESULT (*get)(uint16_t *voltage);
+       RESULT (*set)(uint16_t voltage);
+};
+
+struct versaloon_adaptors_t
+{
+       struct interface_target_voltage_t target_voltage;
+       struct interface_gpio_t gpio;
+       struct interface_delay_t delay;
+       struct interface_swd_t swd;
+       struct interface_jtag_raw_t jtag_raw;
+       RESULT (*peripheral_commit)(void);
+};
+
+struct versaloon_usb_setting_t
+{
+       uint16_t vid;
+       uint16_t pid;
+       uint8_t ep_out;
+       uint8_t ep_in;
+       uint8_t interface;
+       char *serialstring;
+
+       uint16_t buf_size;
+};
+
+struct versaloon_interface_t
+{
+       RESULT (*init)(void);
+       RESULT (*fini)(void);
+       struct versaloon_adaptors_t adaptors;
+       struct versaloon_usb_setting_t usb_setting;
+};
+
+extern struct versaloon_interface_t versaloon_interface;
+extern usb_dev_handle *versaloon_usb_device_handle;
+
+#endif /* __VERSALOON_H_INCLUDED__ */
+
diff --git a/src/jtag/drivers/versaloon/versaloon_include.h b/src/jtag/drivers/versaloon/versaloon_include.h
new file mode 100644 (file)
index 0000000..eacb2e6
--- /dev/null
@@ -0,0 +1,100 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by Simon Qian <SimonQian@SimonQian.com>            *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   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.             *
+ ***************************************************************************/
+// This file is used to include different header and macros
+// according to different platform
+#include <jtag/interface.h>
+#include <jtag/commands.h>
+#include "usb_common.h"
+
+#define PARAM_CHECK                                                    1
+
+#define sleep_ms(ms)                                           jtag_sleep((ms) * 1000)
+#define dimof(arr)                                                     (sizeof(arr) / sizeof((arr)[0]))
+#define TO_STR(name)                                           #name
+
+#define RESULT                                                         int
+#define LOG_BUG                                                                LOG_ERROR
+
+// Common error messages
+#define ERRMSG_NOT_ENOUGH_MEMORY                       "Lack of memory."
+#define ERRCODE_NOT_ENOUGH_MEMORY                      ERROR_FAIL
+
+#define ERRMSG_INVALID_VALUE                           "%d is invalid for %s."
+#define ERRMSG_INVALID_INDEX                           "Index %d is invalid for %s."
+#define ERRMSG_INVALID_USAGE                           "Invalid usage of %s"
+#define ERRMSG_INVALID_TARGET                          "Invalid %s"
+#define ERRMSG_INVALID_PARAMETER                       "Invalid parameter of %s."
+#define ERRMSG_INVALID_INTERFACE_NUM           "invalid inteface %d"
+#define ERRMSG_INVALID_BUFFER                          "Buffer %s is not valid."
+#define ERRCODE_INVALID_BUFFER                         ERROR_FAIL
+#define ERRCODE_INVALID_PARAMETER                      ERROR_FAIL
+
+#define ERRMSG_NOT_SUPPORT_BY                          "%s is not supported by %s."
+
+#define ERRMSG_FAILURE_OPERATION                       "Fail to %s."
+#define ERRMSG_FAILURE_OPERATION_ERRSTRING     "Fail to %s, error string is %s."
+#define ERRMSG_FAILURE_OPERATION_MESSAGE       "Fail to %s, %s"
+#define ERRCODE_FAILURE_OPERATION                      ERROR_FAIL
+
+#define GET_U16_MSBFIRST(p)                    (       ((*((uint8_t *)(p) + 0)) << 8) | \
+                                                                               ((*((uint8_t *)(p) + 1)) << 0))
+#define GET_U32_MSBFIRST(p)                    (       ((*((uint8_t *)(p) + 0)) << 24) | \
+                                                                               ((*((uint8_t *)(p) + 1)) << 16) | \
+                                                                               ((*((uint8_t *)(p) + 2)) << 8) | \
+                                                                               ((*((uint8_t *)(p) + 3)) << 0))
+#define GET_U16_LSBFIRST(p)                    (       ((*((uint8_t *)(p) + 0)) << 0) | \
+                                                                               ((*((uint8_t *)(p) + 1)) << 8))
+#define GET_U32_LSBFIRST(p)                    (       ((*((uint8_t *)(p) + 0)) << 0) | \
+                                                                               ((*((uint8_t *)(p) + 1)) << 8) | \
+                                                                               ((*((uint8_t *)(p) + 2)) << 16) | \
+                                                                               ((*((uint8_t *)(p) + 3)) << 24))
+
+#define SET_U16_MSBFIRST(p, v)         \
+       do{\
+               *((uint8_t *)(p) + 0) = (((uint16_t)(v)) >> 8) & 0xFF;\
+               *((uint8_t *)(p) + 1) = (((uint16_t)(v)) >> 0) & 0xFF;\
+       } while (0)
+#define SET_U32_MSBFIRST(p, v)         \
+       do{\
+               *((uint8_t *)(p) + 0) = (((uint32_t)(v)) >> 24) & 0xFF;\
+               *((uint8_t *)(p) + 1) = (((uint32_t)(v)) >> 16) & 0xFF;\
+               *((uint8_t *)(p) + 2) = (((uint32_t)(v)) >> 8) & 0xFF;\
+               *((uint8_t *)(p) + 3) = (((uint32_t)(v)) >> 0) & 0xFF;\
+       } while (0)
+#define SET_U16_LSBFIRST(p, v)         \
+       do{\
+               *((uint8_t *)(p) + 0) = (((uint16_t)(v)) >> 0) & 0xFF;\
+               *((uint8_t *)(p) + 1) = (((uint16_t)(v)) >> 8) & 0xFF;\
+       } while (0)
+#define SET_U32_LSBFIRST(p, v)         \
+       do{\
+               *((uint8_t *)(p) + 0) = (((uint32_t)(v)) >> 0) & 0xFF;\
+               *((uint8_t *)(p) + 1) = (((uint32_t)(v)) >> 8) & 0xFF;\
+               *((uint8_t *)(p) + 2) = (((uint32_t)(v)) >> 16) & 0xFF;\
+               *((uint8_t *)(p) + 3) = (((uint32_t)(v)) >> 24) & 0xFF;\
+       } while (0)
+
+#define GET_LE_U16(p)                          GET_U16_LSBFIRST(p)
+#define GET_LE_U32(p)                          GET_U32_LSBFIRST(p)
+#define GET_BE_U16(p)                          GET_U16_MSBFIRST(p)
+#define GET_BE_U32(p)                          GET_U32_MSBFIRST(p)
+#define SET_LE_U16(p, v)                       SET_U16_LSBFIRST(p, v)
+#define SET_LE_U32(p, v)                       SET_U32_LSBFIRST(p, v)
+#define SET_BE_U16(p, v)                       SET_U16_MSBFIRST(p, v)
+#define SET_BE_U32(p, v)                       SET_U32_MSBFIRST(p, v)
diff --git a/src/jtag/drivers/versaloon/versaloon_internal.h b/src/jtag/drivers/versaloon/versaloon_internal.h
new file mode 100644 (file)
index 0000000..c7c73b6
--- /dev/null
@@ -0,0 +1,118 @@
+/***************************************************************************
+ *   Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com>     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   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.             *
+ ***************************************************************************/
+#ifndef __VERSALOON_INTERNAL_H_INCLUDED__
+#define __VERSALOON_INTERNAL_H_INCLUDED__
+
+#define VERSALOON_PRODUCTSTRING_INDEX  2
+#define VERSALOON_SERIALSTRING_INDEX   3
+
+#define VERSALOON_PRODUCTSTRING                        "Versaloon"
+
+#define VERSALOON_VID                                  0x0483
+#define VERSALOON_PID                                  0xA038
+#define VERSALOON_INP                                  0x82
+#define VERSALOON_OUTP                                 0x03
+#define VERSALOON_IFACE                                        0x00
+
+#define VERSALOON_FULL                                 1
+#define VERSALOON_MINI                                 2
+#define VERSALOON_NANO                                 3
+
+#define VERSALOON_TIMEOUT                              5000
+#define VERSALOON_TIMEOUT_LONG                 60000
+
+// USB Commands
+// Common Commands
+#define VERSALOON_COMMON_CMD_START             0x00
+#define VERSALOON_COMMON_CMD_END               0x0F
+
+#define VERSALOON_GET_INFO                             0x00
+#define VERSALOON_GET_TVCC                             0x01
+#define VERSALOON_GET_HARDWARE                 0x02
+#define VERSALOON_GET_OFFLINE_SIZE             0x08
+#define VERSALOON_ERASE_OFFLINE_DATA   0x09
+#define VERSALOON_WRITE_OFFLINE_DATA   0x0A
+#define VERSALOON_GET_OFFLINE_CHECKSUM 0x0B
+#define VERSALOON_FW_UPDATE                            0x0F
+#define VERSALOON_FW_UPDATE_KEY                        0xAA
+
+// MCU Command
+#define VERSALOON_MCU_CMD_START                        0x10
+#define VERSALOON_MCU_CMD_END                  0x1F
+
+// USB_TO_XXX Command
+#define VERSALOON_USB_TO_XXX_CMD_START 0x20
+#define VERSALOON_USB_TO_XXX_CMD_END   0x7F
+
+// VSLLink Command
+#define VERSALOON_VSLLINK_CMD_START            0x80
+#define VERSALOON_VSLLINK_CMD_END              0xFF
+
+
+
+// Mass-product
+#define MP_OK                                                  0x00
+#define MP_FAIL                                                        0x01
+
+#define MP_ISSP                                                        0x11
+
+
+
+// pending struct
+#define VERSALOON_MAX_PENDING_NUMBER   4096
+typedef RESULT (*versaloon_callback_t)(void *, uint8_t *, uint8_t *);
+struct versaloon_want_pos_t
+{
+       uint16_t offset;
+       uint16_t size;
+       uint8_t *buff;
+       struct versaloon_want_pos_t *next;
+};
+struct versaloon_pending_t
+{
+       uint8_t type;
+       uint8_t cmd;
+       uint16_t want_data_pos;
+       uint16_t want_data_size;
+       uint16_t actual_data_size;
+       uint8_t *data_buffer;
+       uint8_t collect;
+       uint32_t id;
+       struct versaloon_want_pos_t *pos;
+       void *extra_data;
+       versaloon_callback_t callback;
+};
+extern struct versaloon_pending_t \
+                                                       versaloon_pending[VERSALOON_MAX_PENDING_NUMBER];
+extern uint16_t versaloon_pending_idx;
+void versaloon_set_pending_id(uint32_t id);
+void versaloon_set_callback(versaloon_callback_t callback);
+void versaloon_set_extra_data(void * p);
+RESULT versaloon_add_want_pos(uint16_t offset, uint16_t size, uint8_t *buff);
+RESULT versaloon_add_pending(uint8_t type, uint8_t cmd, uint16_t actual_szie,
+       uint16_t want_pos, uint16_t want_size, uint8_t *buffer, uint8_t collect);
+void versaloon_free_want_pos(void);
+
+RESULT versaloon_send_command(uint16_t out_len, uint16_t *inlen);
+extern uint8_t *versaloon_buf;
+extern uint8_t *versaloon_cmd_buf;
+extern uint16_t versaloon_buf_size;
+
+#endif /* __VERSALOON_INTERNAL_H_INCLUDED__ */
+
index 7533a090e3ab89a28cfb7a6983edfe06afb01183..2274be40d84cb069d4b7dcd13ed16ff9c8442c80 100644 (file)
@@ -19,7 +19,7 @@
 
 /* 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/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;
+#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 */
+       uint8_t *ack;
        uint8_t *buffer;
        bool last; /* indicate the last scan pending */
 };
@@ -97,12 +55,12 @@ static struct pending_scan_result
 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_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);
@@ -119,10 +77,6 @@ struct vsllink {
 
 static struct vsllink *vsllink_usb_open(void);
 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_
 static void vsllink_debug_buffer(uint8_t *buffer, int length);
@@ -134,12 +88,7 @@ static uint8_t *tms_buffer;
 static uint8_t *tdi_buffer;
 static uint8_t *tdo_buffer;
 
-static struct vsllink *vsllink_handle;
-
-static void reset_command_pointer(void)
-{
-       tap_length = 0;
-}
+struct vsllink *vsllink_handle;
 
 static int vsllink_execute_queue(void)
 {
@@ -152,7 +101,6 @@ static int vsllink_execute_queue(void)
                " vsllink "
                "-------------------------------------");
 
-       reset_command_pointer();
        while (cmd != NULL) {
                switch (cmd->type) {
                        case JTAG_RUNTEST:
@@ -188,6 +136,8 @@ static int vsllink_execute_queue(void)
                                break;
 
                        case JTAG_SCAN:
+                               DEBUG_JTAG_IO("JTAG Scan...");
+
                                vsllink_end_state(cmd->cmd.scan->end_state);
 
                                scan_size = jtag_build_buffer(
@@ -244,6 +194,7 @@ static int vsllink_execute_queue(void)
                        case JTAG_STABLECLOCKS:
                                DEBUG_JTAG_IO("add %d clocks",
                                        cmd->cmd.stableclocks->num_cycles);
+
                                switch (tap_get_state()) {
                                case TAP_RESET:
                                        /* tms must be '1' to stay
@@ -271,6 +222,13 @@ static int vsllink_execute_queue(void)
                                                ->num_cycles, scan_size);
                                break;
 
+                       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);
@@ -284,22 +242,8 @@ 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)
-               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,20 +260,42 @@ 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;
+       }
+       if (tdo_buffer != NULL)
+       {
+               free(tdo_buffer);
+               tdo_buffer = NULL;
+       }
+       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);
+       versaloon_interface.adaptors.jtag_raw.fini(0);
+       versaloon_interface.adaptors.peripheral_commit();
+       versaloon_interface.fini();
+
+       vsllink_free_buffer();
+       vsllink_usb_close(vsllink_handle);
 
+       return ERROR_OK;
+}
+
+static int vsllink_init(void)
+{
        vsllink_handle = vsllink_usb_open();
        if (vsllink_handle == 0) {
                LOG_ERROR("Can't find USB JTAG Interface!"\
@@ -337,131 +303,44 @@ static int vsllink_init(void)
                return ERROR_JTAG_INIT_FAILED;
        }
        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++;
+                       versaloon_interface.usb_setting.vid,
+                       versaloon_interface.usb_setting.pid);
+       versaloon_usb_device_handle = vsllink_handle->usb_handle;
+
+       if (ERROR_OK != versaloon_interface.init())
+       {
+               return ERROR_FAIL;
        }
-       if (check_cnt == 3) {
-               /* Fail to access Versaloon */
-               LOG_ERROR("VSLLink initial failed");
-               exit(-1);
+       if (versaloon_interface.usb_setting.buf_size < 32)
+       {
+               versaloon_interface.fini();
+               return ERROR_FAIL;
        }
-       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");
-       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);
+
+       // malloc buffer size for tap
+       tap_buffer_size = versaloon_interface.usb_setting.buf_size - 32;
+       vsllink_free_buffer();
+       tdi_buffer = (uint8_t *)malloc(tap_buffer_size);
+       tdo_buffer = (uint8_t *)malloc(tap_buffer_size);
+       tms_buffer = (uint8_t *)malloc(tap_buffer_size);
+       if ((NULL == tdi_buffer) || (NULL == tdo_buffer) || (NULL == tms_buffer))
+       {
+               vsllink_quit();
+               return ERROR_FAIL;
        }
 
-       /* 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.jtag_raw.init(0);
+       versaloon_interface.adaptors.jtag_raw.config(0, jtag_get_speed_khz());
+       versaloon_interface.adaptors.gpio.init(0);
+       versaloon_interface.adaptors.gpio.config(0, GPIO_SRST | GPIO_TRST,
+                               GPIO_TRST, GPIO_SRST, GPIO_SRST);
+       if (ERROR_OK != versaloon_interface.adaptors.peripheral_commit())
+       {
+               return ERROR_FAIL;
        }
 
        vsllink_reset(0, 0);
-
-       LOG_INFO("VSLLink Interface ready");
-
        vsllink_tap_init();
-
-       return ERROR_OK;
-}
-
-static int vsllink_quit(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);
-               }
-
-               // disconnect
-               vsllink_simple_command(VSLLINK_CMD_DISCONN);
-               vsllink_usb_close(vsllink_handle);
-               vsllink_handle = NULL;
-       }
-
-       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;
-       }
-
        return ERROR_OK;
 }
 
@@ -513,6 +392,13 @@ 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) {
@@ -569,48 +455,18 @@ 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);
-
-       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);
-}
-
-COMMAND_HANDLER(vsllink_handle_mode_command)
-{
-       if (CMD_ARGC != 1) {
-               LOG_ERROR("parameter error, "
-                                       "should be one parameter for mode");
-               return ERROR_FAIL;
-       }
+       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);
 
-       return ERROR_OK;
+       if (!trst)
+               versaloon_interface.adaptors.gpio.out(0, GPIO_TRST, GPIO_TRST);
+       else
+               versaloon_interface.adaptors.gpio.out(0, GPIO_TRST, 0);
+       versaloon_interface.adaptors.peripheral_commit();
 }
 
 COMMAND_HANDLER(vsllink_handle_usb_vid_command)
@@ -621,7 +477,8 @@ COMMAND_HANDLER(vsllink_handle_usb_vid_command)
                return ERROR_OK;
        }
 
-       COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], vsllink_usb_vid);
+       COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0],
+               versaloon_interface.usb_setting.vid);
        return ERROR_OK;
 }
 
@@ -632,7 +489,8 @@ COMMAND_HANDLER(vsllink_handle_usb_pid_command)
                                        "should be one parameter for PID");
                return ERROR_OK;
        }
-       COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], vsllink_usb_pid);
+       COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0],
+               versaloon_interface.usb_setting.pid);
        return ERROR_OK;
 }
 
@@ -644,9 +502,10 @@ COMMAND_HANDLER(vsllink_handle_usb_bulkin_command)
                return ERROR_OK;
        }
 
-       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;
 }
@@ -659,9 +518,10 @@ COMMAND_HANDLER(vsllink_handle_usb_bulkout_command)
                return ERROR_OK;
        }
 
-       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;
 }
@@ -674,7 +534,8 @@ COMMAND_HANDLER(vsllink_handle_usb_interface_command)
                return ERROR_OK;
        }
 
-       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;
 }
 
@@ -760,94 +621,20 @@ static void vsllink_tap_append_scan(int length, uint8_t *buffer,
        }
 }
 
-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) {
+       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,12 +647,12 @@ 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));
 #endif
@@ -882,8 +669,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,42 +678,131 @@ static int vsllink_tap_execute(void)
        return ERROR_OK;
 }
 
+static int vsllink_tap_execute(void)
+{
+       return vsllink_jtag_execute();
+}
+
 /*****************************************************************************/
 /* VSLLink USB low-level functions */
 
+static uint8_t usb_check_string(usb_dev_handle *usb, uint8_t stringidx,
+                                                               char * string, char * buff, uint16_t buf_size)
+{
+       int len;
+       uint8_t alloced = 0;
+       uint8_t ret = 1;
+
+       if (NULL == buff)
+       {
+               buf_size = 256;
+               buff = (char*)malloc(buf_size);
+               if (NULL == buff)
+               {
+                       ret = 0;
+                       goto free_and_return;
+               }
+               alloced = 1;
+       }
+
+       strcpy(buff, "");
+       len = usb_get_string_simple(usb, stringidx, (char *)buff, buf_size);
+       if ((len < 0) || (len != ((int)strlen((const char *)buff))))
+       {
+               ret = 0;
+               goto free_and_return;
+       }
+
+       buff[len] = '\0';
+       if ((string != NULL) && strcmp((const char *)buff, string))
+       {
+               ret = 0;
+               goto free_and_return;
+       }
+
+free_and_return:
+       if (alloced && (buff != NULL))
+       {
+               free(buff);
+               buff = NULL;
+       }
+       return ret;
+}
+
+static usb_dev_handle* find_usb_device(uint16_t VID, uint16_t PID,
+               uint8_t interface, int8_t serialindex, char *serialstring,
+               int8_t productindex, char *productstring)
+{
+       usb_dev_handle *dev_handle = NULL;
+       struct usb_bus *busses;
+       struct usb_bus *bus;
+       struct usb_device *dev;
+
+       usb_init();
+       usb_find_busses();
+       usb_find_devices();
+       busses = usb_get_busses();
+
+       for (bus = busses; bus; bus = bus->next)
+       {
+               for (dev = bus->devices; dev; dev = dev->next)
+               {
+                       if ((dev->descriptor.idVendor == VID)
+                               && (dev->descriptor.idProduct == PID))
+                       {
+                               dev_handle = usb_open(dev);
+                               if (NULL == dev_handle)
+                               {
+                                       LOG_ERROR("failed to open %04X:%04X, %s", VID, PID,
+                                                               usb_strerror());
+                                       continue;
+                               }
+
+                               // check description string
+                               if (((productstring != NULL) && (productindex >= 0)
+                                               && !usb_check_string(dev_handle, productindex,
+                                                                                               productstring, NULL, 0))
+                                       || ((serialstring != NULL) && (serialindex >= 0)
+                                               && !usb_check_string(dev_handle, serialindex,
+                                                                                               serialstring, NULL, 0)))
+                               {
+                                       usb_close(dev_handle);
+                                       dev_handle = NULL;
+                                       continue;
+                               }
+
+                               if (usb_claim_interface(dev_handle, interface) != 0)
+                               {
+                                       LOG_ERROR(ERRMSG_FAILURE_OPERATION_MESSAGE,
+                                                               "claim interface", usb_strerror());
+                                       usb_close(dev_handle);
+                                       dev_handle = NULL;
+                                       continue;
+                               }
+
+                               if (dev_handle != NULL)
+                               {
+                                       return dev_handle;
+                               }
+                       }
+               }
+       }
+
+       return dev_handle;
+}
+
 static struct vsllink *vsllink_usb_open(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);
+       dev = find_usb_device(versaloon_interface.usb_setting.vid,
+                                                       versaloon_interface.usb_setting.pid,
+                                                       versaloon_interface.usb_setting.interface,
+                                                       0, NULL, 2, "Versaloon");
+       if (NULL == dev)
                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
 
        struct vsllink *result = malloc(sizeof(struct vsllink));
        result->usb_handle = dev;
@@ -939,10 +814,10 @@ static void vsllink_usb_close(struct vsllink *vsllink)
        int ret;
 
        ret = usb_release_interface(vsllink->usb_handle,
-                       vsllink_usb_interface);
+                       versaloon_interface.usb_setting.interface);
        if (ret != 0) {
                LOG_ERROR("fail to release interface %d, %d returned",
-                                       vsllink_usb_interface, ret);
+                                       versaloon_interface.usb_setting.interface, ret);
                exit(-1);
        }
 
@@ -955,79 +830,6 @@ static void vsllink_usb_close(struct vsllink *vsllink)
        free(vsllink);
 }
 
-/* Send a message and receive the reply. */
-static int vsllink_usb_message(struct vsllink *vsllink, int out_length,
-                                                               int in_length)
-{
-       int result;
-
-       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;
-       }
-}
-
-/* Write data from out_buffer to USB. */
-static int vsllink_usb_write(struct vsllink *vsllink, int out_length)
-{
-       int result;
-
-       if (out_length > vsllink_buffer_size) {
-               LOG_ERROR("vsllink_write illegal out_length=%d (max=%d)",
-                                       out_length, vsllink_buffer_size);
-               return -1;
-       }
-
-       result = usb_bulk_write(vsllink->usb_handle, vsllink_usb_bulkout,
-               (char *)vsllink_usb_out_buffer, out_length,
-                               VSLLINK_USB_TIMEOUT);
-
-       DEBUG_JTAG_IO("vsllink_usb_write, out_length = %d, result = %d",
-                                       out_length, result);
-
-#ifdef _DEBUG_USB_COMMS_
-       LOG_DEBUG("USB out:");
-       vsllink_debug_buffer(vsllink_usb_out_buffer, out_length);
-#endif
-
-#ifdef _VSLLINK_IN_DEBUG_MODE_
-       usleep(100000);
-#endif
-
-       return result;
-}
-
-/* Read data from USB into in_buffer. */
-static int vsllink_usb_read(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);
-
-       DEBUG_JTAG_IO("vsllink_usb_read, result = %d", result);
-
-#ifdef _DEBUG_USB_COMMS_
-       LOG_DEBUG("USB in:");
-       vsllink_debug_buffer(vsllink_usb_in_buffer, result);
-#endif
-       return result;
-}
-
 #define BYTES_PER_LINE  16
 
 #if defined _DEBUG_USB_COMMS_ || defined _DEBUG_JTAG_IO_
@@ -1075,17 +877,16 @@ 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 *vsllink_transports[] = {"jtag", "swd", NULL};
+
 struct jtag_interface vsllink_interface = {
        .name = "vsllink",
+       .supported = DEBUG_CAP_TMS_SEQ,
        .commands = vsllink_command_handlers,
+       .transports = vsllink_transports,
 
        .init = vsllink_init,
        .quit = vsllink_quit,
index 07a5a0680e84ebc5b965364b794485cf8361324e..fad7934904c664c2a29d1086dd524832f0806c31 100644 (file)
@@ -1,25 +1,8 @@
 #
 # Versaloon Link -- VSLLink
 #
-# http://www.simonqian.com/en/Versaloon
+# http://www.versaloon.com/
 #
 
 interface vsllink
 
-#vsllink_usb_vid               0x03EB
-#vsllink_usb_pid               0x2103
-#vsllink_usb_bulkin    0x02
-#vsllink_usb_bulkout   0x02
-#vsllink_usb_interface 0
-
-vsllink_usb_vid                0x0483
-vsllink_usb_pid                0x5740
-vsllink_usb_bulkin     0x02
-vsllink_usb_bulkout    0x03
-vsllink_usb_interface  1
-
-# vsllink mode, dma or normal
-# for low adapter_khz, use normal
-# for high adapter_khz, use dma
-#vsllink_mode dma
-vsllink_mode normal

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)