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 ad7681afc637f2e31627e640ee1177b0c951514e..ffab637cf1948c26a3e1a682ed27e31bcfbf7730 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 d8a71e2915761e6c5ce3adfbdc3c1e88596a4478..b6692eeedb7ee60f2eb5f559b226e23b8c3de2c1 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 1f239b7b0e2042abb675c750e5562e0b418d5a15..7dbaab2f9049f2d7ec14db9a023a11abb8889dbf 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 76a4e8d103eca81067adcfc5ee33c57a1b5c5983..7e8748a0da65493d696a73fac41515900daa8ef0 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

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)