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