From f099c8784d5104043986acd7f41e00b9a14769ad Mon Sep 17 00:00:00 2001
From: Alexander Osipenko <sipych@gmail.com>
Date: Thu, 24 May 2012 16:55:27 +0400
Subject: [PATCH] J-Link: Forcibly select JTAG transport

Some versions of Segger's software does not select JTAG interface by default.
Do it in the intial setup.

Signed-off-by: Alexander Osipenko <sipych@gmail.com>
---
 src/jtag/drivers/jlink.c |   60 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 60 insertions(+), 0 deletions(-)

diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c
index 03fa46a..34bfa6b 100644
--- a/src/jtag/drivers/jlink.c
+++ b/src/jtag/drivers/jlink.c
@@ -75,22 +75,45 @@ static uint8_t usb_emu_result_buffer[JLINK_EMU_RESULT_BUFFER_SIZE];
 
 /* Constants for JLink command */
 #define EMU_CMD_VERSION			0x01
+#define EMU_CMD_RESET_TRST		0x02
+#define EMU_CMD_RESET_TARGET	0x03
 #define EMU_CMD_SET_SPEED		0x05
 #define EMU_CMD_GET_STATE		0x07
+#define EMU_CMD_SET_KS_POWER	0x08
+#define EMU_CMD_GET_SPEEDS		0xc0
+#define EMU_CMD_GET_HW_INFO		0xc1
+#define EMU_CMD_GET_COUNTERS	0xc2
+#define EMU_CMD_SELECT_IF		0xc7
 #define EMU_CMD_HW_CLOCK		0xc8
 #define EMU_CMD_HW_TMS0			0xc9
 #define EMU_CMD_HW_TMS1			0xca
+#define EMU_CMD_HW_DATA0		0xcb
+#define EMU_CMD_HW_DATA1		0xcc
+#define EMU_CMD_HW_JTAG			0xcd
 #define EMU_CMD_HW_JTAG2		0xce
 #define EMU_CMD_HW_JTAG3		0xcf
+#define EMU_CMD_HW_RELEASE_RESET_STOP_EX 0xd0
+#define EMU_CMD_HW_RELEASE_RESET_STOP_TIMED 0xd1
 #define EMU_CMD_GET_MAX_MEM_BLOCK	0xd4
+#define EMU_CMD_HW_JTAG_WRITE		0xd5
+#define EMU_CMD_HW_JTAG_GET_RESULT	0xd6
 #define EMU_CMD_HW_RESET0		0xdc
 #define EMU_CMD_HW_RESET1		0xdd
 #define EMU_CMD_HW_TRST0		0xde
 #define EMU_CMD_HW_TRST1		0xdf
 #define EMU_CMD_GET_CAPS		0xe8
+#define EMU_CMD_GET_CPU_CAPS	0xe9
+#define EMU_CMD_EXEC_CPU_CMD	0xea
+#define EMU_CMD_GET_CAPS_EX		0xed
 #define EMU_CMD_GET_HW_VERSION	0xf0
+#define EMU_CMD_WRITE_DCC		0xf1
 #define EMU_CMD_READ_CONFIG		0xf2
 #define EMU_CMD_WRITE_CONFIG		0xf3
+#define EMU_CMD_WRITE_MEM			0xf4
+#define EMU_CMD_READ_MEM			0xf5
+#define EMU_CMD_MEASURE_RTCK_REACT	0xf6
+#define EMU_CMD_WRITE_MEM_ARM79		0xf7
+#define EMU_CMD_READ_MEM_ARM79		0xf8
 
 /* bits return from EMU_CMD_GET_CAPS */
 #define EMU_CAP_RESERVED_1		0
@@ -399,6 +422,37 @@ static int jlink_khz(int khz, int *jtag_speed)
 	return ERROR_OK;
 }
 
+/*
+ * select transport interface
+ *
+ * @param iface 0=JTAG, 1=SWD
+ * @returns ERROR_ code
+ *
+ */
+static int jlink_select_interface(int iface)
+{
+	int result;
+
+	usb_out_buffer[0] = EMU_CMD_SELECT_IF;
+	usb_out_buffer[1] = (iface >> 0) & 0xff;
+
+	result = jlink_usb_write(jlink_handle, 2);
+	if (result != 2) {
+		LOG_ERROR("J-Link interface select failed (%d)", result);
+		return ERROR_JTAG_DEVICE_ERROR;
+	}
+
+	/* returns previously selected interface */
+	result = jlink_usb_read(jlink_handle, 4);
+	if (4 != result) {
+		LOG_ERROR("J-Link command EMU_CMD_SELECT_IF failed (%d)", result);
+		return ERROR_JTAG_DEVICE_ERROR;
+	}
+
+	return ERROR_OK;
+}
+
+
 static int jlink_init(void)
 {
 	int i;
@@ -440,6 +494,12 @@ static int jlink_init(void)
 		jlink_get_status();
 	}
 
+	/*
+	 * Some versions of Segger's software does not select JTAG interface by default.
+	 */
+	if (jlink_caps & EMU_CAP_SELECT_IF)
+		jlink_select_interface(0);
+
 	LOG_INFO("J-Link JTAG Interface ready");
 
 	jlink_reset(0, 0);
-- 
1.7.6.5

