ST-LINK USB initial release
authorMathias K <kesmtp@freenet.de>
Wed, 21 Dec 2011 16:03:11 +0000 (17:03 +0100)
committerSpencer Oliver <spen@spen-soft.co.uk>
Tue, 3 Jan 2012 21:12:24 +0000 (21:12 +0000)
ST-Link USB support added.

Change-Id: I2812646f2895b1529ff3f911edbdce7fa0051c8f
Signed-off-by: Mathias K <kesmtp@freenet.de>
Reviewed-on: http://openocd.zylin.com/261
Tested-by: jenkins
Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
15 files changed:
configure.ac
src/jtag/Makefile.am
src/jtag/drivers/Makefile.am
src/jtag/drivers/stlink_usb.c [new file with mode: 0644]
src/jtag/drivers/stlink_usb.h [new file with mode: 0644]
src/jtag/interfaces.c
src/jtag/stlink/Makefile.am [new file with mode: 0644]
src/jtag/stlink/stlink_interface.c [new file with mode: 0644]
src/jtag/stlink/stlink_interface.h [new file with mode: 0644]
src/jtag/stlink/stlink_layout.c [new file with mode: 0644]
src/jtag/stlink/stlink_layout.h [new file with mode: 0644]
src/jtag/stlink/stlink_tcl.c [new file with mode: 0644]
src/jtag/stlink/stlink_tcl.h [new file with mode: 0644]
src/jtag/stlink/stlink_transport.c [new file with mode: 0644]
src/jtag/stlink/stlink_transport.h [new file with mode: 0644]

index ad7681a..ffab637 100644 (file)
@@ -474,6 +474,10 @@ AC_ARG_ENABLE([buspirate],
   AS_HELP_STRING([--enable-buspirate], [Enable building support for the Buspirate]),
   [build_buspirate=$enableval], [build_buspirate=no])
 
+AC_ARG_ENABLE([stlink],
+  AS_HELP_STRING([--enable-stlink], [Enable building support for the ST-Link JTAG Programmer]),
+  [build_stlink=$enableval], [build_stlink=no])
+
 AC_ARG_ENABLE([minidriver_dummy],
   AS_HELP_STRING([--enable-minidriver-dummy], [Enable the dummy minidriver.]),
   [build_minidriver_dummy=$enableval], [build_minidriver_dummy=no])
@@ -773,6 +777,12 @@ else
   AC_DEFINE([BUILD_BUSPIRATE], [0], [0 if you don't want the Buspirate JTAG driver.])
 fi
 
+if test $build_stlink = yes; then
+  AC_DEFINE(BUILD_STLINK, 1, [1 if you want the ST-Link JTAG driver.])
+else
+  AC_DEFINE(BUILD_STLINK, 0, [0 if you don't want the ST-Link JTAG driver.])
+fi
+
 if test "$use_internal_jimtcl" = yes; then
   if test -f "$srcdir/jimtcl/configure.ac"; then
     AX_CONFIG_SUBDIR_OPTION([jimtcl], [--disable-install-jim])
@@ -1059,7 +1069,7 @@ fi
 
 # Check for libusb1 ported drivers.
 build_usb_ng=no
-if test $build_jlink = yes; then
+if test $build_jlink = yes -o $build_stlink = yes; then
   build_usb_ng=yes
 fi
 
@@ -1107,6 +1117,7 @@ AM_CONDITIONAL([ULINK], [test $build_ulink = yes])
 AM_CONDITIONAL([ARMJTAGEW], [test $build_armjtagew = yes])
 AM_CONDITIONAL([REMOTE_BITBANG], [test $build_remote_bitbang = yes])
 AM_CONDITIONAL([BUSPIRATE], [test $build_buspirate = yes])
+AM_CONDITIONAL([STLINK], [test $build_stlink = yes])
 AM_CONDITIONAL([USB], [test $build_usb = yes])
 AM_CONDITIONAL([USB_NG], [test $build_usb_ng = yes])
 AM_CONDITIONAL([USE_LIBUSB0], [test $use_libusb0 = yes])
@@ -1219,6 +1230,7 @@ AC_CONFIG_FILES([
   src/helper/Makefile
   src/jtag/Makefile
   src/jtag/drivers/Makefile
+  src/jtag/stlink/Makefile
   src/transport/Makefile
   src/xsvf/Makefile
   src/svf/Makefile
index d8a71e2..b6692ee 100644 (file)
@@ -39,9 +39,15 @@ else
 MINIDRIVER_IMP_DIR = $(srcdir)/drivers
 DRIVERFILES += commands.c
 
+if STLINK
+SUBDIRS += stlink
+libjtag_la_LIBADD += $(top_builddir)/src/jtag/stlink/libocdstlink.la
+endif
+
 SUBDIRS += drivers
 libjtag_la_LIBADD += $(top_builddir)/src/jtag/drivers/libocdjtagdrivers.la
 
+
 endif
 
 # endif // MINIDRIVER
index 1f239b7..7dbaab2 100644 (file)
@@ -94,6 +94,9 @@ endif
 if REMOTE_BITBANG
 DRIVERFILES += remote_bitbang.c
 endif
+if STLINK
+DRIVERFILES += stlink_usb.c
+endif
 
 noinst_HEADERS = \
        bitbang.h \
@@ -103,6 +106,7 @@ noinst_HEADERS = \
        rlink_dtc_cmd.h \
        rlink_ep1_cmd.h \
        rlink_st7.h \
-       usb_common.h
+       usb_common.h \
+       stlink_usb.h
 
 MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c
new file mode 100644 (file)
index 0000000..aaf55b0
--- /dev/null
@@ -0,0 +1,658 @@
+/***************************************************************************
+ *   Copyright (C) 2011 by Mathias Kuester                                 *
+ *   Mathias Kuester <kesmtp@freenet.de>                                   *
+ *                                                                         *
+ *   This code is based on https://github.com/texane/stlink                *
+ *                                                                         *
+ *   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
+
+/* project specific includes */
+#include <helper/binarybuffer.h>
+#include <jtag/interface.h>
+#include <jtag/stlink/stlink_layout.h>
+#include <jtag/stlink/stlink_interface.h>
+#include <target/target.h>
+
+#include "libusb_common.h"
+
+#define ENDPOINT_IN    0x80
+#define ENDPOINT_OUT   0x00
+
+#define STLINK_RX_EP   (1|ENDPOINT_IN)
+#define STLINK_TX_EP   (2|ENDPOINT_OUT)
+#define STLINK_CMD_SIZE        (16)
+#define STLINK_TX_SIZE (4*128)
+#define STLINK_RX_SIZE (4*128)
+
+/** */
+struct stlink_usb_handle_s {
+       /** */
+       struct jtag_libusb_device_handle *fd;
+       /** */
+       struct libusb_transfer *trans;
+       /** */
+       uint8_t txbuf[STLINK_TX_SIZE];
+       /** */
+       uint8_t rxbuf[STLINK_RX_SIZE];
+};
+
+#define STLINK_OK                      0x80
+#define STLINK_FALSE                   0x81
+#define STLINK_CORE_RUNNING            0x80
+#define STLINK_CORE_HALTED             0x81
+#define STLINK_CORE_STAT_UNKNOWN       -1
+
+#define STLINK_GET_VERSION             0xf1
+#define STLINK_GET_CURRENT_MODE                0xf5
+
+#define STLINK_DEBUG_COMMAND           0xF2
+#define STLINK_DFU_COMMAND             0xF3
+#define STLINK_DFU_EXIT                        0x07
+
+#define STLINK_DEV_DFU_MODE            0x00
+#define STLINK_DEV_MASS_MODE           0x01
+#define STLINK_DEV_DEBUG_MODE          0x02
+#define STLINK_DEV_UNKNOWN_MODE                -1
+
+#define STLINK_DEBUG_ENTER             0x20
+#define STLINK_DEBUG_EXIT              0x21
+#define STLINK_DEBUG_READCOREID                0x22
+
+#define STLINK_DEBUG_GETSTATUS         0x01
+#define STLINK_DEBUG_FORCEDEBUG                0x02
+#define STLINK_DEBUG_RESETSYS          0x03
+#define STLINK_DEBUG_READALLREGS       0x04
+#define STLINK_DEBUG_READREG           0x05
+#define STLINK_DEBUG_WRITEREG          0x06
+#define STLINK_DEBUG_READMEM_32BIT     0x07
+#define STLINK_DEBUG_WRITEMEM_32BIT    0x08
+#define STLINK_DEBUG_RUNCORE           0x09
+#define STLINK_DEBUG_STEPCORE          0x0a
+#define STLINK_DEBUG_SETFP             0x0b
+#define STLINK_DEBUG_WRITEMEM_8BIT     0x0d
+#define STLINK_DEBUG_CLEARFP           0x0e
+#define STLINK_DEBUG_WRITEDEBUGREG     0x0f
+#define STLINK_DEBUG_ENTER_SWD         0xa3
+#define STLINK_DEBUG_ENTER_JTAG                0x00
+
+#define STLINK_SWD_ENTER               0x30
+#define STLINK_SWD_READCOREID          0x32
+
+/** */
+int stlink_usb_recv(void *handle, uint8_t *txbuf, int txsize, uint8_t *rxbuf,
+                   int rxsize)
+{
+       struct stlink_usb_handle_s *h;
+
+       assert(handle != NULL);
+
+       h = (struct stlink_usb_handle_s *)handle;
+
+       if (jtag_libusb_bulk_write(h->fd, STLINK_TX_EP, (char *)txbuf, txsize,
+                                  1000) != txsize) {
+               return ERROR_FAIL;
+       }
+       if (rxsize && rxbuf) {
+               if (jtag_libusb_bulk_read(h->fd, STLINK_RX_EP, (char *)rxbuf,
+                                         rxsize, 1000) != rxsize) {
+                       return ERROR_FAIL;
+               }
+       }
+       return ERROR_OK;
+}
+
+/** */
+void stlink_usb_init_buffer(void *handle)
+{
+       struct stlink_usb_handle_s *h;
+
+       assert(handle != NULL);
+
+       h = (struct stlink_usb_handle_s *)handle;
+
+       memset(h->txbuf, 0, STLINK_CMD_SIZE);
+}
+
+/** */
+int stlink_usb_version(void *handle)
+{
+       int res;
+       uint16_t v;
+       struct stlink_usb_handle_s *h;
+
+       assert(handle != NULL);
+
+       h = (struct stlink_usb_handle_s *)handle;
+
+       stlink_usb_init_buffer(handle);
+
+       h->txbuf[0] = STLINK_GET_VERSION;
+
+       res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, 6);
+
+       if (res != ERROR_OK)
+               return res;
+
+       v = (h->rxbuf[0] << 8) | h->rxbuf[1];
+
+       LOG_DEBUG("STLINK v%d", (v >> 12) & 0x0f);
+       LOG_DEBUG("JTAG   v%d", (v >> 6) & 0x3f);
+       LOG_DEBUG("SWIM   v%d", v & 0x3f);
+       LOG_DEBUG("VID    %04X", buf_get_u32(h->rxbuf, 16, 16));
+       LOG_DEBUG("PID    %04X", buf_get_u32(h->rxbuf, 32, 16));
+
+       return ERROR_OK;
+}
+
+/** */
+int stlink_usb_current_mode(void *handle, uint8_t *mode)
+{
+       int res;
+       struct stlink_usb_handle_s *h;
+
+       assert(handle != NULL);
+
+       h = (struct stlink_usb_handle_s *)handle;
+
+       stlink_usb_init_buffer(handle);
+
+       h->txbuf[0] = STLINK_GET_CURRENT_MODE;
+
+       res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, 2);
+
+       if (res != ERROR_OK)
+               return res;
+
+       *mode = h->rxbuf[0];
+
+       return ERROR_OK;
+}
+
+/** */
+int stlink_usb_dfu_mode_leave(void *handle)
+{
+       int res;
+       struct stlink_usb_handle_s *h;
+
+       assert(handle != NULL);
+
+       h = (struct stlink_usb_handle_s *)handle;
+
+       stlink_usb_init_buffer(handle);
+
+       h->txbuf[0] = STLINK_DFU_COMMAND;
+       h->txbuf[1] = STLINK_DFU_EXIT;
+
+       res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, 0, 0);
+
+       if (res != ERROR_OK)
+               return res;
+
+       return ERROR_OK;
+}
+
+/** */
+int stlink_usb_swd_mode_enter(void *handle)
+{
+       int res;
+       struct stlink_usb_handle_s *h;
+
+       assert(handle != NULL);
+
+       h = (struct stlink_usb_handle_s *)handle;
+
+       stlink_usb_init_buffer(handle);
+
+       h->txbuf[0] = STLINK_DEBUG_COMMAND;
+       h->txbuf[1] = STLINK_DEBUG_ENTER;
+       h->txbuf[2] = STLINK_DEBUG_ENTER_SWD;
+
+       res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, 0, 0);
+       if (res != ERROR_OK)
+               return res;
+
+       return ERROR_OK;
+}
+
+/** */
+int stlink_usb_debug_mode_leave(void *handle)
+{
+       int res;
+       struct stlink_usb_handle_s *h;
+
+       assert(handle != NULL);
+
+       h = (struct stlink_usb_handle_s *)handle;
+
+       stlink_usb_init_buffer(handle);
+
+       h->txbuf[0] = STLINK_DEBUG_COMMAND;
+       h->txbuf[1] = STLINK_DEBUG_EXIT;
+
+       res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, 0, 0);
+       if (res != ERROR_OK)
+               return res;
+
+       return ERROR_OK;
+}
+
+/** */
+int stlink_usb_init_mode(void *handle)
+{
+       int res;
+       uint8_t mode;
+
+       assert(handle != NULL);
+
+       res = stlink_usb_current_mode(handle, &mode);
+
+       if (res != ERROR_OK)
+               return res;
+
+       LOG_DEBUG("MODE: %02X", mode);
+
+       if (mode == STLINK_DEV_DFU_MODE) {
+               res = stlink_usb_dfu_mode_leave(handle);
+
+               if (res != ERROR_OK)
+                       return res;
+       }
+
+       res = stlink_usb_current_mode(handle, &mode);
+
+       if (res != ERROR_OK)
+               return res;
+
+       LOG_DEBUG("MODE: %02X", mode);
+
+       if (mode != STLINK_DEV_DEBUG_MODE) {
+               res = stlink_usb_swd_mode_enter(handle);
+
+               if (res != ERROR_OK)
+                       return res;
+       }
+
+       res = stlink_usb_current_mode(handle, &mode);
+
+       if (res != ERROR_OK)
+               return res;
+
+       LOG_DEBUG("MODE: %02X", mode);
+
+       return ERROR_OK;
+}
+
+/** */
+int stlink_usb_idcode(void *handle, uint32_t *idcode)
+{
+       int res;
+       struct stlink_usb_handle_s *h;
+
+       assert(handle != NULL);
+
+       h = (struct stlink_usb_handle_s *)handle;
+
+       stlink_usb_init_buffer(handle);
+
+       h->txbuf[0] = STLINK_DEBUG_COMMAND;
+       h->txbuf[1] = STLINK_DEBUG_READCOREID;
+
+       res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, 4);
+
+       if (res != ERROR_OK)
+               return res;
+
+       *idcode = le_to_h_u32(h->rxbuf);
+
+       LOG_DEBUG("IDCODE: %08X", *idcode);
+
+       return ERROR_OK;
+}
+
+/** */
+enum target_state stlink_usb_state(void *handle)
+{
+       int res;
+       struct stlink_usb_handle_s *h;
+
+       assert(handle != NULL);
+
+       h = (struct stlink_usb_handle_s *)handle;
+
+       stlink_usb_init_buffer(handle);
+
+       h->txbuf[0] = STLINK_DEBUG_COMMAND;
+       h->txbuf[1] = STLINK_DEBUG_GETSTATUS;
+
+       res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, 2);
+
+       if (res != ERROR_OK)
+               return TARGET_UNKNOWN;
+
+       if (h->rxbuf[0] == STLINK_CORE_RUNNING)
+               return TARGET_RUNNING;
+       if (h->rxbuf[0] == STLINK_CORE_HALTED)
+               return TARGET_HALTED;
+
+       return TARGET_UNKNOWN;
+}
+
+/** */
+int stlink_usb_reset(void *handle)
+{
+       int res;
+       struct stlink_usb_handle_s *h;
+
+       assert(handle != NULL);
+
+       h = (struct stlink_usb_handle_s *)handle;
+
+       stlink_usb_init_buffer(handle);
+
+       h->txbuf[0] = STLINK_DEBUG_COMMAND;
+       h->txbuf[1] = STLINK_DEBUG_RESETSYS;
+
+       res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, 2);
+
+       if (res != ERROR_OK)
+               return res;
+
+       LOG_DEBUG("RESET: %08X", h->rxbuf[0]);
+
+       return ERROR_OK;
+}
+
+/** */
+int stlink_usb_run(void *handle)
+{
+       int res;
+       struct stlink_usb_handle_s *h;
+
+       assert(handle != NULL);
+
+       h = (struct stlink_usb_handle_s *)handle;
+
+       stlink_usb_init_buffer(handle);
+
+       h->txbuf[0] = STLINK_DEBUG_COMMAND;
+       h->txbuf[1] = STLINK_DEBUG_RUNCORE;
+
+       res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, 2);
+
+       if (res != ERROR_OK)
+               return res;
+
+       return ERROR_OK;
+}
+
+/** */
+int stlink_usb_halt(void *handle)
+{
+       int res;
+       struct stlink_usb_handle_s *h;
+
+       assert(handle != NULL);
+
+       h = (struct stlink_usb_handle_s *)handle;
+
+       stlink_usb_init_buffer(handle);
+
+       h->txbuf[0] = STLINK_DEBUG_COMMAND;
+       h->txbuf[1] = STLINK_DEBUG_FORCEDEBUG;
+
+       res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, 2);
+
+       if (res != ERROR_OK)
+               return res;
+
+       return ERROR_OK;
+}
+
+/** */
+int stlink_usb_step(void *handle)
+{
+       int res;
+       struct stlink_usb_handle_s *h;
+
+       assert(handle != NULL);
+
+       h = (struct stlink_usb_handle_s *)handle;
+
+       stlink_usb_init_buffer(handle);
+
+       h->txbuf[0] = STLINK_DEBUG_COMMAND;
+       h->txbuf[1] = STLINK_DEBUG_STEPCORE;
+
+       res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, 2);
+
+       if (res != ERROR_OK)
+               return res;
+
+       return ERROR_OK;
+}
+
+/** */
+int stlink_usb_read_regs(void *handle)
+{
+       int res;
+       struct stlink_usb_handle_s *h;
+
+       assert(handle != NULL);
+
+       h = (struct stlink_usb_handle_s *)handle;
+
+       stlink_usb_init_buffer(handle);
+
+       h->txbuf[0] = STLINK_DEBUG_COMMAND;
+       h->txbuf[1] = STLINK_DEBUG_READALLREGS;
+
+       res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, 84);
+
+       if (res != ERROR_OK)
+               return res;
+
+       return ERROR_OK;
+}
+
+/** */
+int stlink_usb_read_reg(void *handle, int num, uint32_t *val)
+{
+       int res;
+       struct stlink_usb_handle_s *h;
+
+       assert(handle != NULL);
+
+       h = (struct stlink_usb_handle_s *)handle;
+
+       stlink_usb_init_buffer(handle);
+
+       h->txbuf[0] = STLINK_DEBUG_COMMAND;
+       h->txbuf[1] = STLINK_DEBUG_READREG;
+       h->txbuf[2] = num;
+
+       res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, 4);
+
+       if (res != ERROR_OK)
+               return res;
+
+       *val = le_to_h_u32(h->rxbuf);
+
+       return ERROR_OK;
+}
+
+/** */
+int stlink_usb_write_reg(void *handle, int num, uint32_t val)
+{
+       int res;
+       struct stlink_usb_handle_s *h;
+
+       assert(handle != NULL);
+
+       h = (struct stlink_usb_handle_s *)handle;
+
+       stlink_usb_init_buffer(handle);
+
+       h->txbuf[0] = STLINK_DEBUG_COMMAND;
+       h->txbuf[1] = STLINK_DEBUG_WRITEREG;
+       h->txbuf[2] = num;
+       h_u32_to_le(h->txbuf + 3, val);
+
+       res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, 2);
+
+       if (res != ERROR_OK)
+               return res;
+
+       return ERROR_OK;
+}
+
+/** */
+int stlink_usb_read_mem32(void *handle, uint32_t addr, uint16_t len,
+                         uint32_t *buffer)
+{
+       int res;
+       struct stlink_usb_handle_s *h;
+
+       assert(handle != NULL);
+
+       h = (struct stlink_usb_handle_s *)handle;
+
+       stlink_usb_init_buffer(handle);
+
+       len *= 4;
+
+       h->txbuf[0] = STLINK_DEBUG_COMMAND;
+       h->txbuf[1] = STLINK_DEBUG_READMEM_32BIT;
+       h_u32_to_le(h->txbuf + 2, addr);
+       h_u16_to_le(h->txbuf + 2 + 4, len);
+
+       res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, h->rxbuf, len);
+
+       if (res != ERROR_OK)
+               return res;
+
+       memcpy(buffer, h->rxbuf, len);
+
+       return ERROR_OK;
+}
+
+/** */
+int stlink_usb_write_mem32(void *handle, uint32_t addr, uint16_t len,
+                          uint32_t *buffer)
+{
+       int res;
+       struct stlink_usb_handle_s *h;
+
+       assert(handle != NULL);
+
+       h = (struct stlink_usb_handle_s *)handle;
+
+       stlink_usb_init_buffer(handle);
+
+       len *= 4;
+
+       h->txbuf[0] = STLINK_DEBUG_COMMAND;
+       h->txbuf[1] = STLINK_DEBUG_WRITEMEM_32BIT;
+       h_u32_to_le(h->txbuf + 2, addr);
+       h_u16_to_le(h->txbuf + 2 + 4, len);
+
+       res = stlink_usb_recv(handle, h->txbuf, STLINK_CMD_SIZE, 0, 0);
+
+       if (res != ERROR_OK)
+               return res;
+
+       res = stlink_usb_recv(handle, (uint8_t *) buffer, len, 0, 0);
+
+       if (res != ERROR_OK)
+               return res;
+
+       memcpy(buffer, h->rxbuf, len);
+
+       return ERROR_OK;
+}
+
+/** */
+int stlink_usb_open(struct stlink_interface_param_s *param, void **fd)
+{
+       struct stlink_usb_handle_s *h;
+
+       LOG_DEBUG("stlink_usb_open");
+
+       h = malloc(sizeof(struct stlink_usb_handle_s));
+
+       if (h == 0) {
+               LOG_DEBUG("stlink_open_usb: malloc failed");
+               return ERROR_FAIL;
+       }
+
+       const uint16_t vids[] = { param->vid, 0 };
+       const uint16_t pids[] = { param->pid, 0 };
+
+       LOG_DEBUG("stlink_open_usb: vid: %04x pid: %04x", param->vid,
+                 param->pid);
+
+       if (jtag_libusb_open(vids, pids, &h->fd) != ERROR_OK) {
+               LOG_DEBUG("stlink_open_usb: open failed");
+               return ERROR_FAIL;
+       }
+
+       jtag_libusb_set_configuration(h->fd, 0);
+
+       if (jtag_libusb_claim_interface(h->fd, 0) != ERROR_OK) {
+               LOG_DEBUG("stlink_open_usb: claim failed");
+               return ERROR_FAIL;
+       }
+
+       stlink_usb_init_mode(h);
+
+       stlink_usb_version(h);
+
+       *fd = h;
+
+       return ERROR_OK;
+}
+
+/** */
+struct stlink_layout_api_s stlink_layout_api = {
+       /** */
+       .open = stlink_usb_open,
+       /** */
+       .idcode = stlink_usb_idcode,
+       /** */
+       .state = stlink_usb_state,
+       /** */
+       .reset = stlink_usb_reset,
+       /** */
+       .run = stlink_usb_run,
+       /** */
+       .halt = stlink_usb_halt,
+       /** */
+       .step = stlink_usb_step,
+       /** */
+       .read_regs = stlink_usb_read_regs,
+       /** */
+       .read_reg = stlink_usb_read_reg,
+       /** */
+       .write_reg = stlink_usb_write_reg,
+       /** */
+       .read_mem32 = stlink_usb_read_mem32,
+       /** */
+       .write_mem32 = stlink_usb_write_mem32,
+};
diff --git a/src/jtag/drivers/stlink_usb.h b/src/jtag/drivers/stlink_usb.h
new file mode 100644 (file)
index 0000000..f564a0c
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _STLINK_USB_H_
+#define _STLINK_USB_H_
+
+/** */
+void *stlink_open_usb(struct stlink_interface_param_s *param);
+
+#endif
index 76a4e8d..7e8748a 100644 (file)
@@ -100,6 +100,9 @@ extern struct jtag_interface buspirate_interface;
 #if BUILD_REMOTE_BITBANG == 1
 extern struct jtag_interface remote_bitbang_interface;
 #endif
+#if BUILD_STLINK == 1
+extern struct jtag_interface stlink_interface;
+#endif
 #endif // standard drivers
 
 /**
@@ -169,6 +172,9 @@ struct jtag_interface *jtag_interfaces[] = {
 #if BUILD_REMOTE_BITBANG == 1
                &remote_bitbang_interface,
 #endif
+#if BUILD_STLINK == 1
+               &stlink_interface,
+#endif
 #endif // standard drivers
                NULL,
        };
diff --git a/src/jtag/stlink/Makefile.am b/src/jtag/stlink/Makefile.am
new file mode 100644 (file)
index 0000000..ac5b3af
--- /dev/null
@@ -0,0 +1,22 @@
+include $(top_srcdir)/common.mk
+
+noinst_LTLIBRARIES = libocdstlink.la
+
+libocdstlink_la_SOURCES = \
+       $(STLINKFILES)
+
+nobase_dist_pkglib_DATA =
+
+STLINKFILES =
+
+if STLINK
+STLINKFILES += stlink_transport.c
+STLINKFILES += stlink_tcl.c
+STLINKFILES += stlink_interface.c
+STLINKFILES += stlink_layout.c
+endif
+
+noinst_HEADERS = \
+       stlink_tcl.h
+
+MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
diff --git a/src/jtag/stlink/stlink_interface.c b/src/jtag/stlink/stlink_interface.c
new file mode 100644 (file)
index 0000000..a2ac99f
--- /dev/null
@@ -0,0 +1,225 @@
+/***************************************************************************
+ *   Copyright (C) 2011 by Mathias Kuester                                 *
+ *   Mathias Kuester <kesmtp@freenet.de>                                   *
+ *                                                                         *
+ *   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
+
+/* project specific includes */
+#include <jtag/interface.h>
+#include <transport/transport.h>
+#include <helper/time_support.h>
+
+#include <jtag/stlink/stlink_tcl.h>
+#include <jtag/stlink/stlink_layout.h>
+#include <jtag/stlink/stlink_interface.h>
+
+#include <target/target.h>
+
+static struct stlink_interface_s stlink_if = { {0, 0, 0, 0}, 0, 0 };
+
+int stlink_interface_open(void)
+{
+       LOG_DEBUG("stlink_interface_open");
+
+       return stlink_if.layout->open(&stlink_if);
+}
+
+int stlink_interface_init_target(struct target *t)
+{
+       int res;
+
+       /* this is the interface for the current target and we
+        * can setup the private pointer in the tap structure
+        * if the interface match the tap idcode
+        */
+       res = stlink_if.layout->api->idcode(stlink_if.fd, &t->tap->idcode);
+
+       if (res != ERROR_OK)
+               return res;
+
+       unsigned ii, limit = t->tap->expected_ids_cnt;
+       int found = 0;
+
+       for (ii = 0; ii < limit; ii++) {
+               uint32_t expected = t->tap->expected_ids[ii];
+
+               if (t->tap->idcode == expected) {
+                       found = 1;
+                       break;
+               }
+       }
+
+       if (found == 0) {
+               LOG_ERROR
+                   ("stlink_interface_init_target: target not found: idcode: %x ",
+                    t->tap->idcode);
+               return ERROR_FAIL;
+       }
+
+       t->tap->priv = &stlink_if;
+       t->tap->hasidcode = 1;
+
+       return ERROR_OK;
+}
+
+static int stlink_interface_init(void)
+{
+       LOG_DEBUG("stlink_interface_init");
+
+       /* here we can initialize the layout */
+       return stlink_layout_init(&stlink_if);
+}
+
+static int stlink_interface_quit(void)
+{
+       LOG_DEBUG("stlink_interface_quit");
+
+       return ERROR_OK;
+}
+
+static int stlink_interface_speed(int speed)
+{
+       LOG_DEBUG("stlink_interface_speed: ignore speed %d", speed);
+
+       return ERROR_OK;
+}
+
+static int stlink_interface_execute_queue(void)
+{
+       LOG_DEBUG("stlink_interface_execute_queue: ignored");
+
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(stlink_interface_handle_device_desc_command)
+{
+       LOG_DEBUG("stlink_interface_handle_device_desc_command");
+
+       if (CMD_ARGC == 1) {
+               stlink_if.param.device_desc = strdup(CMD_ARGV[0]);
+       } else {
+               LOG_ERROR
+                   ("expected exactly one argument to stlink_device_desc <description>");
+       }
+
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(stlink_interface_handle_serial_command)
+{
+       LOG_DEBUG("stlink_interface_handle_serial_command");
+
+       if (CMD_ARGC == 1) {
+               stlink_if.param.serial = strdup(CMD_ARGV[0]);
+       } else {
+               LOG_ERROR
+                   ("expected exactly one argument to stlink_serial <serial-number>");
+       }
+
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(stlink_interface_handle_layout_command)
+{
+       LOG_DEBUG("stlink_interface_handle_layout_command");
+
+       if (CMD_ARGC != 1) {
+               LOG_ERROR("Need exactly one argument to stlink_layout");
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       if (stlink_if.layout) {
+               LOG_ERROR("already specified stlink_layout %s",
+                         stlink_if.layout->name);
+               return (strcmp(stlink_if.layout->name, CMD_ARGV[0]) != 0)
+                   ? ERROR_FAIL : ERROR_OK;
+       }
+
+       for (const struct stlink_layout *l = stlink_layout_get_list(); l->name;
+            l++) {
+               if (strcmp(l->name, CMD_ARGV[0]) == 0) {
+                       stlink_if.layout = l;
+                       return ERROR_OK;
+               }
+       }
+
+       LOG_ERROR("No STLINK layout '%s' found", CMD_ARGV[0]);
+       return ERROR_FAIL;
+}
+
+COMMAND_HANDLER(stlink_interface_handle_vid_pid_command)
+{
+       LOG_DEBUG("stlink_interface_handle_vid_pid_command");
+
+       if (CMD_ARGC != 2) {
+               LOG_WARNING
+                   ("ignoring extra IDs in stlink_vid_pid (maximum is 1 pair)");
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], stlink_if.param.vid);
+       COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], stlink_if.param.pid);
+
+       return ERROR_OK;
+}
+
+static const struct command_registration stlink_interface_command_handlers[] = {
+       {
+        .name = "stlink_device_desc",
+        .handler = &stlink_interface_handle_device_desc_command,
+        .mode = COMMAND_CONFIG,
+        .help = "set the stlink device description of the STLINK device",
+        .usage = "description_string",
+        },
+       {
+        .name = "stlink_serial",
+        .handler = &stlink_interface_handle_serial_command,
+        .mode = COMMAND_CONFIG,
+        .help = "set the serial number of the STLINK device",
+        .usage = "serial_string",
+        },
+       {
+        .name = "stlink_layout",
+        .handler = &stlink_interface_handle_layout_command,
+        .mode = COMMAND_CONFIG,
+        .help = "set the layout of the STLINK to usb or sg",
+        .usage = "layout_name",
+        },
+       {
+        .name = "stlink_vid_pid",
+        .handler = &stlink_interface_handle_vid_pid_command,
+        .mode = COMMAND_CONFIG,
+        .help = "the vendor and product ID of the STLINK device",
+        .usage = "(vid pid)* ",
+        },
+       COMMAND_REGISTRATION_DONE
+};
+
+struct jtag_interface stlink_interface = {
+       .name = "stlink",
+       .supported = 0,
+       .commands = stlink_interface_command_handlers,
+       .transports = stlink_transports,
+
+       .init = stlink_interface_init,
+       .quit = stlink_interface_quit,
+       .speed = stlink_interface_speed,
+       .execute_queue = stlink_interface_execute_queue,
+};
diff --git a/src/jtag/stlink/stlink_interface.h b/src/jtag/stlink/stlink_interface.h
new file mode 100644 (file)
index 0000000..9b3f791
--- /dev/null
@@ -0,0 +1,53 @@
+/***************************************************************************
+ *   Copyright (C) 2011 by Mathias Kuester                                 *
+ *   Mathias Kuester <kesmtp@freenet.de>                                   *
+ *                                                                         *
+ *   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 _STLINK_INTERFACE_
+#define _STLINK_INTERFACE_
+
+/** */
+struct target;
+/** */
+extern const char *stlink_transports[];
+
+struct stlink_interface_param_s {
+       /** */
+       char *device_desc;
+       /** */
+       char *serial;
+       /** */
+       uint16_t vid;
+       /** */
+       uint16_t pid;
+};
+
+struct stlink_interface_s {
+       /** */
+       struct stlink_interface_param_s param;
+       /** */
+       const struct stlink_layout *layout;
+       /** */
+       void *fd;
+};
+
+/** */
+int stlink_interface_open(void);
+/** */
+int stlink_interface_init_target(struct target *t);
+
+#endif
diff --git a/src/jtag/stlink/stlink_layout.c b/src/jtag/stlink/stlink_layout.c
new file mode 100644 (file)
index 0000000..dfcfbf4
--- /dev/null
@@ -0,0 +1,85 @@
+/***************************************************************************
+ *   Copyright (C) 2011 by Mathias Kuester                                 *
+ *   Mathias Kuester <kesmtp@freenet.de>                                   *
+ *                                                                         *
+ *   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
+
+/* project specific includes */
+#include <jtag/interface.h>
+#include <transport/transport.h>
+#include <helper/time_support.h>
+
+#include <jtag/stlink/stlink_layout.h>
+#include <jtag/stlink/stlink_tcl.h>
+#include <jtag/stlink/stlink_interface.h>
+
+#define STLINK_LAYOUT_UNKNOWN  0
+#define STLINK_LAYOUT_SG       1
+#define STLINK_LAYOUT_USB      2
+
+static int stlink_layout_open(struct stlink_interface_s *stlink_if)
+{
+       int res;
+
+       LOG_DEBUG("stlink_layout_open");
+
+       stlink_if->fd = NULL;
+
+       res = stlink_if->layout->api->open(&stlink_if->param, &stlink_if->fd);
+
+       if (res != ERROR_OK) {
+               LOG_DEBUG("stlink_layout_open: failed");
+               return res;
+       }
+
+       return ERROR_OK;
+}
+
+static int stlink_layout_close(struct stlink_interface_s *stlink_if)
+{
+       return ERROR_OK;
+}
+
+static const struct stlink_layout stlink_layouts[] = {
+       {
+        .name = "usb",
+        .type = STLINK_LAYOUT_USB,
+        .open = stlink_layout_open,
+        .close = stlink_layout_close,
+        .api = &stlink_layout_api,
+        },
+       {.name = NULL, /* END OF TABLE */ },
+};
+
+/** */
+const struct stlink_layout *stlink_layout_get_list(void)
+{
+       return stlink_layouts;
+}
+
+int stlink_layout_init(struct stlink_interface_s *stlink_if)
+{
+       LOG_DEBUG("stlink_layout_init");
+
+       stlink_if->layout = &stlink_layouts[0];
+
+       return ERROR_OK;
+}
diff --git a/src/jtag/stlink/stlink_layout.h b/src/jtag/stlink/stlink_layout.h
new file mode 100644 (file)
index 0000000..46517a7
--- /dev/null
@@ -0,0 +1,81 @@
+/***************************************************************************
+ *   Copyright (C) 2011 by Mathias Kuester                                 *
+ *   Mathias Kuester <kesmtp@freenet.de>                                   *
+ *                                                                         *
+ *   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 _STLINK_LAYOUT_H_
+#define _STLINK_LAYOUT_H_
+
+/** */
+struct stlink_interface_s;
+struct stlink_interface_param_s;
+
+/** */
+extern struct stlink_layout_api_s stlink_layout_api;
+
+/** */
+struct stlink_layout_api_s {
+       /** */
+       int (*open) (struct stlink_interface_param_s *param, void **fd);
+       /** */
+       int (*close) (void *fd);
+       /** */
+       int (*reset) (void *fd);
+       /** */
+       int (*run) (void *fd);
+       /** */
+       int (*halt) (void *fd);
+       /** */
+       int (*step) (void *fd);
+       /** */
+       int (*read_regs) (void *fd);
+       /** */
+       int (*read_reg) (void *fd, int num, uint32_t *val);
+       /** */
+       int (*write_reg) (void *fd, int num, uint32_t val);
+       /** */
+       int (*read_mem32) (void *handle, uint32_t addr, uint16_t len,
+                          uint32_t *buffer);
+       /** */
+       int (*write_mem32) (void *handle, uint32_t addr, uint16_t len,
+                           uint32_t *buffer);
+       /** */
+       int (*idcode) (void *fd, uint32_t *idcode);
+       /** */
+       enum target_state (*state) (void *fd);
+};
+
+/** */
+struct stlink_layout {
+       /** */
+       char *name;
+       /** */
+       int type;
+       /** */
+       int (*open) (struct stlink_interface_s *stlink_if);
+       /** */
+       int (*close) (struct stlink_interface_s *stlink_if);
+       /** */
+       struct stlink_layout_api_s *api;
+};
+
+/** */
+const struct stlink_layout *stlink_layout_get_list(void);
+/** */
+int stlink_layout_init(struct stlink_interface_s *stlink_if);
+
+#endif
diff --git a/src/jtag/stlink/stlink_tcl.c b/src/jtag/stlink/stlink_tcl.c
new file mode 100644 (file)
index 0000000..a73afa3
--- /dev/null
@@ -0,0 +1,136 @@
+/***************************************************************************
+ *   Copyright (C) 2011 by Mathias Kuester                                 *
+ *   Mathias Kuester <kesmtp@freenet.de>                                   *
+ *                                                                         *
+ *   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
+
+/* project specific includes */
+#include <jtag/interface.h>
+#include <transport/transport.h>
+#include <helper/time_support.h>
+
+static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi,
+                                 struct jtag_tap *pTap)
+{
+       jim_wide w;
+       int e = Jim_GetOpt_Wide(goi, &w);
+       if (e != JIM_OK) {
+               Jim_SetResultFormatted(goi->interp, "option: %s bad parameter",
+                                      n->name);
+               return e;
+       }
+
+       unsigned expected_len = sizeof(uint32_t) * pTap->expected_ids_cnt;
+       uint32_t *new_expected_ids = malloc(expected_len + sizeof(uint32_t));
+       if (new_expected_ids == NULL) {
+               Jim_SetResultFormatted(goi->interp, "no memory");
+               return JIM_ERR;
+       }
+
+       memcpy(new_expected_ids, pTap->expected_ids, expected_len);
+
+       new_expected_ids[pTap->expected_ids_cnt] = w;
+
+       free(pTap->expected_ids);
+       pTap->expected_ids = new_expected_ids;
+       pTap->expected_ids_cnt++;
+
+       return JIM_OK;
+}
+
+#define NTAP_OPT_EXPECTED_ID 0
+
+static int jim_stlink_newtap_cmd(Jim_GetOptInfo *goi)
+{
+       struct jtag_tap *pTap;
+       int x;
+       int e;
+       Jim_Nvp *n;
+       char *cp;
+       const Jim_Nvp opts[] = {
+               {.name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID},
+               {.name = NULL, .value = -1},
+       };
+
+       pTap = calloc(1, sizeof(struct jtag_tap));
+       if (!pTap) {
+               Jim_SetResultFormatted(goi->interp, "no memory");
+               return JIM_ERR;
+       }
+
+       /*
+        * we expect CHIP + TAP + OPTIONS
+        * */
+       if (goi->argc < 3) {
+               Jim_SetResultFormatted(goi->interp,
+                                      "Missing CHIP TAP OPTIONS ....");
+               free(pTap);
+               return JIM_ERR;
+       }
+       Jim_GetOpt_String(goi, &cp, NULL);
+       pTap->chip = strdup(cp);
+
+       Jim_GetOpt_String(goi, &cp, NULL);
+       pTap->tapname = strdup(cp);
+
+       /* name + dot + name + null */
+       x = strlen(pTap->chip) + 1 + strlen(pTap->tapname) + 1;
+       cp = malloc(x);
+       sprintf(cp, "%s.%s", pTap->chip, pTap->tapname);
+       pTap->dotted_name = cp;
+
+       LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
+                 pTap->chip, pTap->tapname, pTap->dotted_name, goi->argc);
+
+       while (goi->argc) {
+               e = Jim_GetOpt_Nvp(goi, opts, &n);
+               if (e != JIM_OK) {
+                       Jim_GetOpt_NvpUnknown(goi, opts, 0);
+                       free((void *)pTap->dotted_name);
+                       free(pTap);
+                       return e;
+               }
+               LOG_DEBUG("Processing option: %s", n->name);
+               switch (n->value) {
+               case NTAP_OPT_EXPECTED_ID:
+                       e = jim_newtap_expected_id(n, goi, pTap);
+                       if (JIM_OK != e) {
+                               free((void *)pTap->dotted_name);
+                               free(pTap);
+                               return e;
+                       }
+                       break;
+               }               /* switch (n->value) */
+       }                       /* while (goi->argc) */
+
+       /* default is enabled-after-reset */
+       pTap->enabled = !pTap->disabled_after_reset;
+
+       jtag_tap_init(pTap);
+       return JIM_OK;
+}
+
+int jim_stlink_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
+{
+       Jim_GetOptInfo goi;
+       Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
+       return jim_stlink_newtap_cmd(&goi);
+}
diff --git a/src/jtag/stlink/stlink_tcl.h b/src/jtag/stlink/stlink_tcl.h
new file mode 100644 (file)
index 0000000..395d546
--- /dev/null
@@ -0,0 +1,26 @@
+/***************************************************************************
+ *   Copyright (C) 2011 by Mathias Kuester                                 *
+ *   Mathias Kuester <kesmtp@freenet.de>                                   *
+ *                                                                         *
+ *   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 _STLINK_TCL_
+#define _STLINK_TCL_
+
+/** */
+int jim_stlink_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv);
+
+#endif
diff --git a/src/jtag/stlink/stlink_transport.c b/src/jtag/stlink/stlink_transport.c
new file mode 100644 (file)
index 0000000..6f16195
--- /dev/null
@@ -0,0 +1,180 @@
+/***************************************************************************
+ *   Copyright (C) 2011 by Mathias Kuester                                 *
+ *   Mathias Kuester <kesmtp@freenet.de>                                   *
+ *                                                                         *
+ *   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
+
+/* project specific includes */
+#include <jtag/interface.h>
+#include <jtag/tcl.h>
+#include <transport/transport.h>
+#include <helper/time_support.h>
+#include <target/target.h>
+#include <jtag/stlink/stlink_tcl.h>
+#include <jtag/stlink/stlink_interface.h>
+
+COMMAND_HANDLER(stlink_transport_jtag_command)
+{
+       LOG_DEBUG("stlink_transport_jtag_command");
+
+       return ERROR_OK;
+}
+
+static const struct command_registration
+stlink_transport_stlink_subcommand_handlers[] = {
+       {
+        .name = "newtap",
+        .mode = COMMAND_CONFIG,
+        .jim_handler = jim_stlink_newtap,
+        .help = "Create a new TAP instance named basename.tap_type, "
+        "and appends it to the scan chain.",
+        .usage = "basename tap_type '-irlen' count "
+        "['-expected_id' number] ",
+        },
+
+       COMMAND_REGISTRATION_DONE
+};
+
+static const struct command_registration
+stlink_transport_jtag_subcommand_handlers[] = {
+       {
+        .name = "init",
+        .mode = COMMAND_ANY,
+        .handler = stlink_transport_jtag_command,
+        },
+       {
+        .name = "arp_init",
+        .mode = COMMAND_ANY,
+        .handler = stlink_transport_jtag_command,
+        },
+       {
+        .name = "arp_init-reset",
+        .mode = COMMAND_ANY,
+        .handler = stlink_transport_jtag_command,
+        },
+       {
+        .name = "tapisenabled",
+        .mode = COMMAND_EXEC,
+        .jim_handler = jim_jtag_tap_enabler,
+        },
+       {
+        .name = "tapenable",
+        .mode = COMMAND_EXEC,
+        .jim_handler = jim_jtag_tap_enabler,
+        },
+       {
+        .name = "tapdisable",
+        .mode = COMMAND_EXEC,
+        .handler = stlink_transport_jtag_command,
+        },
+       {
+        .name = "configure",
+        .mode = COMMAND_EXEC,
+        .handler = stlink_transport_jtag_command,
+        },
+       {
+        .name = "cget",
+        .mode = COMMAND_EXEC,
+        .jim_handler = jim_jtag_configure,
+        },
+       {
+        .name = "names",
+        .mode = COMMAND_ANY,
+        .handler = stlink_transport_jtag_command,
+        },
+
+       COMMAND_REGISTRATION_DONE
+};
+
+static const struct command_registration stlink_transport_command_handlers[] = {
+
+       {
+        .name = "stlink",
+        .mode = COMMAND_ANY,
+        .help = "perform stlink actions",
+        .chain = stlink_transport_stlink_subcommand_handlers,
+        },
+       {
+        .name = "jtag",
+        .mode = COMMAND_ANY,
+        .chain = stlink_transport_jtag_subcommand_handlers,
+        },
+       COMMAND_REGISTRATION_DONE
+};
+
+static int stlink_transport_register_commands(struct command_context *cmd_ctx)
+{
+       return register_commands(cmd_ctx, NULL,
+                                stlink_transport_command_handlers);
+}
+
+static int stlink_transport_init(struct command_context *cmd_ctx)
+{
+       LOG_DEBUG("stlink_transport_init");
+       struct target *t = get_current_target(cmd_ctx);
+
+       if (!t) {
+               LOG_ERROR("stlink_transport_init: no current target");
+               return ERROR_FAIL;
+
+       }
+
+       stlink_interface_open();
+
+       return stlink_interface_init_target(t);
+}
+
+static int stlink_transport_select(struct command_context *ctx)
+{
+       LOG_DEBUG("stlink_transport_select");
+
+       int retval;
+
+       /* NOTE:  interface init must already have been done.
+        * That works with only C code ... no Tcl glue required.
+        */
+
+       retval = stlink_transport_register_commands(ctx);
+
+       if (retval != ERROR_OK)
+               return retval;
+
+       return ERROR_OK;
+}
+
+static struct transport stlink_transport = {
+       .name = "stlink",
+       .select = stlink_transport_select,
+       .init = stlink_transport_init,
+};
+
+const char *stlink_transports[] = { "stlink", NULL };
+
+static void stlink_constructor(void) __attribute__ ((constructor));
+static void stlink_constructor(void)
+{
+       transport_register(&stlink_transport);
+}
+
+bool transport_is_stlink(void)
+{
+       return get_current_transport() == &stlink_transport;
+}
diff --git a/src/jtag/stlink/stlink_transport.h b/src/jtag/stlink/stlink_transport.h
new file mode 100644 (file)
index 0000000..066b194
--- /dev/null
@@ -0,0 +1,23 @@
+/***************************************************************************
+ *   Copyright (C) 2011 by Mathias Kuester                                 *
+ *   Mathias Kuester <kesmtp@freenet.de>                                   *
+ *                                                                         *
+ *   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 _STLINK_TRANSPORT_
+#define _STLINK_TRANSPORT_
+
+#endif