* 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. *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
/* 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
static struct jlink *jlink_usb_open(void);
static void jlink_usb_close(struct jlink *jlink);
static int jlink_usb_message(struct jlink *jlink, int out_length, int in_length);
+static int jlink_usb_io(struct jlink *jlink, int out_length, int in_length);
static int jlink_usb_write(struct jlink *jlink, int out_length);
static int jlink_usb_read(struct jlink *jlink, int expected_size);
static int jlink_usb_read_emu_result(struct jlink *jlink);
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<<iface))) {
+ LOG_ERROR("J-Link requesting to select unsupported interface (%x)", iface_mask);
+ return ERROR_JTAG_DEVICE_ERROR;
+ }
+
+ /* Select interface */
+ usb_out_buffer[0] = EMU_CMD_SELECT_IF;
+ usb_out_buffer[1] = iface;
+
+ result = jlink_usb_io(jlink_handle, 2, 4);
+ if (result != ERROR_OK) {
+ LOG_ERROR("J-Link interface select failed (%d)", result);
+ return ERROR_JTAG_DEVICE_ERROR;
+ }
+
+ return ERROR_OK;
+}
+
static int jlink_init(void)
{
int i;
jlink_get_status();
}
+ /*
+ * Some versions of Segger's software do not select JTAG interface by default.
+ *
+ * Segger recommends to select interface necessarily as a part of init process,
+ * in case any previous session leaves improper interface selected.
+ *
+ * Until SWD implemented, select only JTAG interface here.
+ */
+ if (jlink_caps & (1<<EMU_CAP_SELECT_IF))
+ jlink_select_interface(0);
+
LOG_INFO("J-Link JTAG Interface ready");
jlink_reset(0, 0);
int result;
int size = sizeof(struct jlink_config);
- jlink_simple_command(EMU_CMD_READ_CONFIG);
+ usb_out_buffer[0] = EMU_CMD_READ_CONFIG;
+ result = jlink_usb_io(jlink_handle, 1, size);
- result = jlink_usb_read(jlink_handle, size);
- if (size != result) {
+ if (result != ERROR_OK) {
LOG_ERROR("jlink_usb_read failed (requested=%d, result=%d)", size, result);
return ERROR_FAIL;
}
memcpy(cfg, usb_in_buffer, size);
-
- /*
- * Section 4.2.4 IN-transaction
- * read dummy 0-byte packet
- */
- jlink_usb_read(jlink_handle, 1);
-
return ERROR_OK;
}
return ERROR_OK;
}
+/*
+ * List of unsupported version string markers.
+ *
+ * The firmware versions does not correspond directly with
+ * "Software and documentation pack for Windows", it may be
+ * distinguished by the "compile" date in the information string.
+ *
+ * For example, version string is:
+ * "J-Link ARM V8 compiled May 3 2012 18:36:22"
+ * Marker sould be:
+ * "May 3 2012"
+ *
+ * The list must be terminated by NULL string.
+ */
+static const char * const unsupported_versions[] = {
+ "Jan 31 2011",
+ "JAN 31 2011",
+ NULL /* End of list */
+};
+
+static void jlink_check_supported(const char *str)
+{
+ const char * const *p = unsupported_versions;
+ while (*p) {
+ if (NULL != strstr(str, *p)) {
+ LOG_WARNING(
+ "Unsupported J-Link firmware version.\n"
+ " Please check http://www.segger.com/j-link-older-versions.html for updates");
+ return;
+ }
+ p++;
+ }
+}
+
static int jlink_get_version_info(void)
{
int result;
usb_in_buffer[result] = 0;
LOG_INFO("%s", (char *)usb_in_buffer);
+ jlink_check_supported((char *)usb_in_buffer);
/* query hardware capabilities */
jlink_simple_command(EMU_CMD_GET_CAPS);
struct jtag_interface jlink_interface = {
.name = "jlink",
.commands = jlink_command_handlers,
+ .transports = jtag_only,
.execute_queue = jlink_execute_queue,
.speed = jlink_speed,
{
int index_var = tap_length / 8;
- if (index_var >= JLINK_TAP_BUFFER_SIZE) {
- LOG_ERROR("jlink_tap_append_step: overflow");
- *(uint32_t *)0xFFFFFFFF = 0;
- exit(-1);
- }
+ assert(index_var < JLINK_TAP_BUFFER_SIZE);
int bit_index = tap_length % 8;
uint8_t bit = 1 << bit_index;
return result;
}
+/*
+ * Send a message and receive the reply - simple messages.
+ *
+ * @param jlink pointer to driver data
+ * @param out_length data length in @c usb_out_buffer
+ * @param in_length data length to be read to @c usb_in_buffer
+ */
+static int jlink_usb_io(struct jlink *jlink, int out_length, int in_length)
+{
+ int result;
+
+ result = jlink_usb_write(jlink, out_length);
+ if (result != out_length) {
+ LOG_ERROR("usb_bulk_write failed (requested=%d, result=%d)",
+ out_length, result);
+ return ERROR_JTAG_DEVICE_ERROR;
+ }
+
+ result = jlink_usb_read(jlink, in_length);
+ if (result != in_length) {
+ LOG_ERROR("usb_bulk_read failed (requested=%d, result=%d)",
+ in_length, result);
+ return ERROR_JTAG_DEVICE_ERROR;
+ }
+
+ /*
+ * Section 4.2.4 IN-transaction:
+ * read dummy 0-byte packet if transaction size is
+ * multiple of 64 bytes but not max. size of 0x8000
+ */
+ if ((in_length % 64) == 0 && in_length != 0x8000) {
+ char dummy_buffer;
+ result = usb_bulk_read_ex(jlink->usb_handle, jlink_read_ep,
+ &dummy_buffer, 1, JLINK_USB_TIMEOUT);
+ if (result != 0) {
+ LOG_ERROR("dummy byte read failed");
+ return ERROR_JTAG_DEVICE_ERROR;
+ }
+ }
+ return ERROR_OK;
+}
+
#ifdef _DEBUG_USB_COMMS_
#define BYTES_PER_LINE 16