From: Alexander Osipenko Date: Mon, 28 May 2012 07:26:34 +0000 (+0400) Subject: J-Link: Forcibly select JTAG transport X-Git-Tag: v0.6.0-rc1~50 X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=commitdiff_plain;h=4b6af9797846b07c6aee3eb45898c2044bdf167e J-Link: Forcibly select JTAG transport Some versions of Segger's software do not select JTAG interface by default. Do it in the intial setup. Firmware version check code still present, with updated set of unsupported. Note from Segger: Alright, we were not aware of that OpenOCD does not select the interface before it starts communicating with the target. A debugger should always select the appropriate target interface before it starts communicating with the target, since otherwise it could also happen that a previous session with another debugger had selected SWD and the interface was not switched again by OpenOCD. Change-Id: I5b4eab7e0e3625ec32be75a36d89e16d17e899bf Signed-off-by: Alexander Osipenko Reviewed-on: http://openocd.zylin.com/667 Tested-by: jenkins Reviewed-by: Xiaofan Reviewed-by: Spencer Oliver --- diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c index 5dd09bc13c..54fc4c1111 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 @@ -400,6 +423,67 @@ static int jlink_khz(int khz, int *jtag_speed) return ERROR_OK; } +/* + * select transport interface + * + * @param iface [0..31] currently: 0=JTAG, 1=SWD + * @returns ERROR_OK or ERROR_ code + * + * @pre jlink_handle must be opened + * @pre function may be called only for devices, that have + * EMU_CAP_SELECT_IF capability enabled + */ +static int jlink_select_interface(int iface) +{ + /* According to Segger's document RM08001-R7 Date: October 8, 2010, + * http://www.segger.com/admin/uploads/productDocs/RM08001_JLinkUSBProtocol.pdf + * section 5.5.3 EMU_CMD_SELECT_IF + * > SubCmd 1..31 to select interface (0..31) + * + * The table below states: + * 0 TIF_JTAG + * 1 TIF_SWD + * + * This obviosly means that to select TIF_JTAG one should write SubCmd = 1. + * + * In fact, JTAG interface operates when SubCmd=0 + * + * It looks like a typo in documentation, because interfaces 0..31 could not + * be selected by 1..31 range command. + */ + assert(iface >= 0 && iface < 32); + int result; + + /* get available interfaces */ + usb_out_buffer[0] = EMU_CMD_SELECT_IF; + usb_out_buffer[1] = 0xff; + + result = jlink_usb_io(jlink_handle, 2, 4); + if (result != ERROR_OK) { + LOG_ERROR("J-Link query interface failed (%d)", result); + return ERROR_JTAG_DEVICE_ERROR; + } + + uint32_t iface_mask = buf_get_u32(usb_in_buffer, 0, 32); + + if (!(iface_mask & (1<