The following patch combines my previous patch with most of Ben's patch. It can use both EMU_CMD_HW_JTAG2 and EMU_CMD_HW_JTAG3

It defaults to EMU_CMD_HW_JTAG2 so it should work with all interfaces but EMU_CMD_HW_JTAG3 is recommended by SEgger, you can change the behaviour with

> jlink_hw_jtag  3
or
> jlink_hw_jtag  2

Autodetection can be done when we know which versions JLink can use what setting, (-d3 logs of setup messages )

Have a nice day
Magnus


Xiaofan Chen wrote:
On Wed, May 20, 2009 at 12:53 AM, Gene Smith <g...@chartertn.net> wrote:

OK, one more reply to self...
Using the Magnus patch, I just noticed that after openocd starts the
jlink LED goes off indicating further USB comm is not possible (it seems
to be true) and telnet cmds fail. If I try to restart oocd, I again get
the 3 failed retries on get caps and "don't worry" like before.  If I
revert to Benjamin's patch, it comes up clean with no errors. Now I can
do telnet commands with no problem (such as jlink_info, mdb, reg, etc).

Possibly the intention was to combine these patches, I am not sure. But
anyhow, for what its worth, it is now seems to be working for me with
Ben's patch. (I have not tried to do anything with gdb yet.)

I can see two big differences between the patches. In Ben's patch,
-#define EMU_CMD_HW_JTAG3               0xcf
+#define EMU_CMD_HW_JTAG3               0xce (maybe this is
EMU_CMD_HW_JTAG2 according to Ben's Mach 16 patch).

 /* max speed 12MHz v5.0 jlink */
-#define JLINK_MAX_SPEED 12000 (this is only for V5/6/7/Pro)
+#define JLINK_MAX_SPEED 4000 (this is for V1/2/3/4 according to Segger)

The common thing is to correct the endpoint and remove the
EMU_CMD_GET_MAX_MEM_BLOCK command.

Ben's patch remove more things. I will give it a try after work.


Index: src/jtag/jlink.c
===================================================================
--- src/jtag/jlink.c	(revision 1834)
+++ src/jtag/jlink.c	(working copy)
@@ -36,9 +36,13 @@
 #define JLINK_WRITE_ENDPOINT	0x02
 #define JLINK_READ_ENDPOINT		0x81
 
+unsigned int jlink_write_ep = JLINK_WRITE_ENDPOINT;
+unsigned int jlink_read_ep = JLINK_READ_ENDPOINT;
+unsigned int jlink_hw_jtag_version = 2;
+
 #define JLINK_USB_TIMEOUT		1000
 
-// See Section 1.3.2 of the Segger JLink USB protocol manual
+/* See Section 1.3.2 of the Segger JLink USB protocol manual */
 /* 2048 is the max value we can use here */
 //#define JLINK_TAP_BUFFER_SIZE 2048
 #define JLINK_TAP_BUFFER_SIZE 256
@@ -60,6 +64,7 @@
 #define EMU_CMD_HW_CLOCK			0xc8
 #define EMU_CMD_HW_TMS0 			0xc9
 #define EMU_CMD_HW_TMS1 			0xca
+#define EMU_CMD_HW_JTAG2    		0xce
 #define EMU_CMD_HW_JTAG3    		0xcf
 #define EMU_CMD_GET_MAX_MEM_BLOCK	0xd4
 #define EMU_CMD_HW_RESET0   		0xdc
@@ -67,6 +72,7 @@
 #define EMU_CMD_HW_TRST0    		0xde
 #define EMU_CMD_HW_TRST1    		0xdf
 #define EMU_CMD_GET_CAPS    		0xe8
+#define EMU_CMD_GET_HW_VERSION  	0xf0
 
 /* max speed 12MHz v5.0 jlink */
 #define JLINK_MAX_SPEED 12000
@@ -82,6 +88,7 @@
 
 /* CLI command handler functions */
 static int jlink_handle_jlink_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int jlink_handle_jlink_hw_jtag_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 
 /* Queue command functions */
 static void jlink_end_state(tap_state_t state);
@@ -301,8 +308,11 @@
 
 static int jlink_register_commands(struct command_context_s *cmd_ctx)
 {
+
 	register_command(cmd_ctx, NULL, "jlink_info", jlink_handle_jlink_info_command, COMMAND_EXEC,
 		"query jlink info");
+	register_command(cmd_ctx, NULL, "jlink_hw_jtag", jlink_handle_jlink_hw_jtag_command, COMMAND_EXEC,
+		"set/get jlink hw jtag command version [2|3]");
 	return ERROR_OK;
 }
 
@@ -318,6 +328,7 @@
 		return ERROR_JTAG_INIT_FAILED;
 	}
 
+	jlink_hw_jtag_version = 2;
 	check_cnt = 0;
 	while (check_cnt < 3)
 	{
@@ -543,7 +554,7 @@
 {
 	int result;
 	int len;
-	u32 jlink_caps, jlink_max_size;
+	u32 jlink_caps, jlink_max_size, jlink_hw_version;
 
 	/* query hardware version */
 	jlink_simple_command(EMU_CMD_VERSION);
@@ -579,21 +590,38 @@
 	jlink_caps = buf_get_u32(usb_in_buffer, 0, 32);
 	LOG_INFO("JLink caps 0x%x", jlink_caps);
 
+	if (jlink_caps & (1<<1)) /* EMU_CAP_GET_HW_VERSION */
+	{
+		/* query hardware version */
+		jlink_simple_command(EMU_CMD_GET_HW_VERSION);
 
-	/* query hardware maximum memory block */
-	jlink_simple_command(EMU_CMD_GET_MAX_MEM_BLOCK);
+		result = jlink_usb_read(jlink_jtag_handle, 4);
+		if (4 != result)
+		{
+			LOG_ERROR("J-Link command EMU_CMD_GET_HW_VERSION failed (%d)\n", result);
+			return ERROR_JTAG_DEVICE_ERROR;
+		}
 
-	result = jlink_usb_read(jlink_jtag_handle, 4);
-	if (4 != result)
-	{
-		LOG_ERROR("J-Link command EMU_CMD_GET_MAX_MEM_BLOCK failed (%d)\n", result);
-		return ERROR_JTAG_DEVICE_ERROR;
+		jlink_hw_version = buf_get_u32(usb_in_buffer, 0, 32);
+		LOG_INFO("JLink hw version %i", jlink_hw_version);
 	}
 
-	jlink_max_size = buf_get_u32(usb_in_buffer, 0, 32);
-	LOG_INFO("JLink max mem block %i", jlink_max_size);
+	if (jlink_caps & (1<<11)) /* EMU_CAP_GET_MAX_BLOCK_SIZE */
+	{
+		/* query hardware maximum memory block */
+		jlink_simple_command(EMU_CMD_GET_MAX_MEM_BLOCK);
 
+		result = jlink_usb_read(jlink_jtag_handle, 4);
+		if (4 != result)
+		{
+			LOG_ERROR("J-Link command EMU_CMD_GET_MAX_MEM_BLOCK failed (%d)\n", result);
+			return ERROR_JTAG_DEVICE_ERROR;
+		}
 
+		jlink_max_size = buf_get_u32(usb_in_buffer, 0, 32);
+		LOG_INFO("JLink max mem block %i", jlink_max_size);
+	}
+
 	return ERROR_OK;
 }
 
@@ -608,6 +636,31 @@
 	return ERROR_OK;
 }
 
+static int jlink_handle_jlink_hw_jtag_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+	if (argc == 1)
+	{
+		if (strcmp(args[0], "2") == 0)
+		{
+			jlink_hw_jtag_version = 2;
+		}
+		else if (strcmp(args[0], "3") == 0)
+		{
+			jlink_hw_jtag_version = 3;
+		} else
+		{
+			return ERROR_COMMAND_SYNTAX_ERROR;
+		}
+	} else if (argc != 0)
+	{
+		return ERROR_COMMAND_SYNTAX_ERROR;
+	}
+
+	command_print(cmd_ctx, "jlink hw jtag  %i", jlink_hw_jtag_version);
+
+	return ERROR_OK;
+}
+
 /***************************************************************************/
 /* J-Link tap functions */
 
@@ -661,7 +714,7 @@
 	int bit_index = tap_length % 8;
 	u8 bit = 1 << bit_index;
 
-	// we do not pad TMS, so be sure to initialize all bits
+	/* we do not pad TMS, so be sure to initialize all bits */
 	if (0 == bit_index)
 	{
 		tms_buffer[index] = tdi_buffer[index] = 0;
@@ -721,7 +774,14 @@
 	// number of full bytes (plus one if some would be left over)
 	byte_length = TAP_SCAN_BYTES(tap_length);
 
-	usb_out_buffer[0] = EMU_CMD_HW_JTAG3;
+	if (jlink_hw_jtag_version >= 3)
+	{
+		usb_out_buffer[0] = EMU_CMD_HW_JTAG3;
+	}
+	else
+	{
+		usb_out_buffer[0] = EMU_CMD_HW_JTAG2;
+	}
 	usb_out_buffer[1] = 0;
 	usb_out_buffer[2] = (tap_length >> 0) & 0xff;
 	usb_out_buffer[3] = (tap_length >> 8) & 0xff;
@@ -814,6 +874,24 @@
 				 */
 				usb_set_altinterface(result->usb_handle, 0);
 #endif
+				int i;
+				for (i =0 ; i<dev->config[0].interface[0].altsetting[0].bNumEndpoints; i++)
+				{
+					u8 epnum = dev->config[0].interface[0].altsetting[0].endpoint[i].bEndpointAddress;
+					{						
+						if (epnum&0x80)
+						{ 
+							LOG_DEBUG("usb ep in %02x",epnum);
+							jlink_read_ep = epnum;
+						}
+						else
+						{
+							LOG_DEBUG("usb ep out %02x",epnum);
+							jlink_write_ep = epnum;
+						}
+					}
+				}
+
 				return result;
 			}
 		}
@@ -833,7 +911,7 @@
 static int jlink_usb_message(jlink_jtag_t *jlink_jtag, int out_length, int in_length)
 {
 	int result;
-	int result2;
+	int result2 = ERROR_OK;
 
 	result = jlink_usb_write(jlink_jtag, out_length);
 	if (result != out_length)
@@ -851,38 +929,41 @@
 		return ERROR_JTAG_DEVICE_ERROR;
 	}
 
-	if (result == in_length)
+	if (jlink_hw_jtag_version >= 3)
 	{
-		/* Must read the result from the EMU too */
-		result2 = jlink_usb_read_emu_result(jlink_jtag);
-		if (1 != result2)
+		if (result == in_length)
 		{
-			LOG_ERROR("jlink_usb_read_emu_result retried requested=1, result=%d, in_length=%i", result2,in_length);
-			/* Try again once, should only happen if (in_length%64==0) */
+			/* Must read the result from the EMU too */
 			result2 = jlink_usb_read_emu_result(jlink_jtag);
 			if (1 != result2)
 			{
-				LOG_ERROR("jlink_usb_read_emu_result failed "
-					"(requested=1, result=%d)", result2);
-				return ERROR_JTAG_DEVICE_ERROR;
+				LOG_ERROR("jlink_usb_read_emu_result retried requested=1, result=%d, in_length=%i", result2,in_length);
+				/* Try again once, should only happen if (in_length%64==0) */
+				result2 = jlink_usb_read_emu_result(jlink_jtag);
+				if (1 != result2)
+				{
+					LOG_ERROR("jlink_usb_read_emu_result failed "
+						"(requested=1, result=%d)", result2);
+					return ERROR_JTAG_DEVICE_ERROR;
+				}
 			}
+
+			/* Check the result itself */
+			result2 = usb_emu_result_buffer[0];
 		}
+		else
+		{
+			/* Save the result, then remove it from return value */
+			result2 = usb_in_buffer[result--];
+		}
 
-		/* Check the result itself */
-		result2 = usb_emu_result_buffer[0];
+		if (result2)
+		{
+			LOG_ERROR("jlink_usb_message failed with result=%d)", result2);
+			return ERROR_JTAG_DEVICE_ERROR;
+		}
 	}
-	else
-	{
-		/* Save the result, then remove it from return value */
-		result2 = usb_in_buffer[result--];
-	}
 
-	if (result2)
-	{
-		LOG_ERROR("jlink_usb_message failed with result=%d)", result2);
-		return ERROR_JTAG_DEVICE_ERROR;
-	}
-
 	return result;
 }
 
@@ -937,7 +1018,7 @@
 		return -1;
 	}
 
-	result = usb_bulk_write_ex(jlink_jtag->usb_handle, JLINK_WRITE_ENDPOINT,
+	result = usb_bulk_write_ex(jlink_jtag->usb_handle, jlink_write_ep,
 		(char *)usb_out_buffer, out_length, JLINK_USB_TIMEOUT);
 
 	DEBUG_JTAG_IO("jlink_usb_write, out_length = %d, result = %d", out_length, result);
@@ -951,7 +1032,7 @@
 /* Read data from USB into in_buffer. */
 static int jlink_usb_read(jlink_jtag_t *jlink_jtag, int expected_size)
 {
-	int result = usb_bulk_read_ex(jlink_jtag->usb_handle, JLINK_READ_ENDPOINT,
+	int result = usb_bulk_read_ex(jlink_jtag->usb_handle, jlink_read_ep,
 		(char *)usb_in_buffer, expected_size, JLINK_USB_TIMEOUT);
 
 	DEBUG_JTAG_IO("jlink_usb_read, result = %d", result);
@@ -965,7 +1046,7 @@
 /* Read the result from the previous EMU cmd into result_buffer. */
 static int jlink_usb_read_emu_result(jlink_jtag_t *jlink_jtag)
 {
-	int result = usb_bulk_read_ex(jlink_jtag->usb_handle, JLINK_READ_ENDPOINT,
+	int result = usb_bulk_read_ex(jlink_jtag->usb_handle, jlink_read_ep,
 		(char *)usb_emu_result_buffer, 1 /* JLINK_EMU_RESULT_BUFFER_SIZE */,
 		JLINK_USB_TIMEOUT);
 
_______________________________________________
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to