#include <usb.h>
#include <string.h>
+#include <errno.h>
#include "log.h"
// See Section 1.3.2 of the Segger JLink USB protocol manual
#define JLINK_IN_BUFFER_SIZE 2048
-#define JLINK_OUT_BUFFER_SIZE 2048
+#define JLINK_OUT_BUFFER_SIZE 2*2048+4
#define JLINK_EMU_RESULT_BUFFER_SIZE 64
/* Global USB buffers */
static u8 usb_emu_result_buffer[JLINK_EMU_RESULT_BUFFER_SIZE];
/* Constants for JLink command */
-#define EMU_CMD_VERSION 0x01
-#define EMU_CMD_SET_SPEED 0x05
-#define EMU_CMD_GET_STATE 0x07
-#define EMU_CMD_HW_JTAG3 0xcf
-#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_VERSION 0x01
+#define EMU_CMD_SET_SPEED 0x05
+#define EMU_CMD_GET_STATE 0x07
+#define EMU_CMD_HW_JTAG3 0xcf
+#define EMU_CMD_GET_MAX_MEM_BLOCK 0xd4
+#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
/* max speed 12MHz v5.0 jlink */
#define JLINK_MAX_SPEED 12000
static void jlink_debug_buffer(u8 *buffer, int length);
#endif
+static enum tap_state jlink_last_state = TAP_RESET;
+
static jlink_jtag_t* jlink_jtag_handle;
/***************************************************************************/
{
int result;
int len;
+ u32 jlink_caps, jlink_max_size;
/* query hardware version */
jlink_simple_command(EMU_CMD_VERSION);
result = jlink_usb_read(jlink_jtag_handle, 2);
if (2 != result)
{
- LOG_ERROR("J-Link command EMU_CMD_VERSION failed (%d)\n",
- result);
+ LOG_ERROR("J-Link command EMU_CMD_VERSION failed (%d)\n", result);
return ERROR_JTAG_DEVICE_ERROR;
}
result = jlink_usb_read(jlink_jtag_handle, len);
if (result != len)
{
- LOG_ERROR("J-Link command EMU_CMD_VERSION failed (%d)\n",
- result);
+ LOG_ERROR("J-Link command EMU_CMD_VERSION failed (%d)\n", result);
return ERROR_JTAG_DEVICE_ERROR;
}
usb_in_buffer[result] = 0;
LOG_INFO("%s", (char *)usb_in_buffer);
+ /* query hardware capabilities */
+ jlink_simple_command(EMU_CMD_GET_CAPS);
+
+ result = jlink_usb_read(jlink_jtag_handle, 4);
+ if (4 != result)
+ {
+ LOG_ERROR("J-Link command EMU_CMD_GET_CAPS failed (%d)\n", result);
+ return ERROR_JTAG_DEVICE_ERROR;
+ }
+
+ jlink_caps = buf_get_u32(usb_in_buffer, 0, 32);
+ LOG_INFO("JLink caps 0x%x", jlink_caps);
+
+
+ /* 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;
}
static int pending_scan_results_length;
static pending_scan_result_t pending_scan_results_buffer[MAX_PENDING_SCAN_RESULTS];
-static int last_tms;
-
static void jlink_tap_init(void)
{
tap_length = 0;
static void jlink_tap_append_step(int tms, int tdi)
{
- last_tms = tms;
int index = tap_length / 8;
if (index >= JLINK_TAP_BUFFER_SIZE)
memcpy(usb_out_buffer + 4, tms_buffer, byte_length);
memcpy(usb_out_buffer + 4 + byte_length, tdi_buffer, byte_length);
+ jlink_last_state = jtag_debug_state_machine(tms_buffer, tdi_buffer,
+ tap_length, jlink_last_state);
+
result = jlink_usb_message(jlink_jtag_handle, 4 + 2 * byte_length, byte_length);
if (result != byte_length)
{
- LOG_ERROR("jlink_tap_execute, wrong result %d (expected %d)",
- result, byte_length);
+ LOG_ERROR("jlink_tap_execute, wrong result %d (expected %d)", result, byte_length);
+ jlink_tap_init();
return ERROR_JTAG_QUEUE_FAILED;
}
}
jlink_tap_init();
-
return ERROR_OK;
}
}
result = jlink_usb_read(jlink_jtag, in_length);
- if ((result != in_length) && (result != in_length + 1))
+ if ((result != in_length) && (result != (in_length + 1)))
{
LOG_ERROR("usb_bulk_read failed (requested=%d, result=%d)",
in_length, result);
usb_dev_handle *dev, int ep,
char *bytes, int size, int timeout)
{
- int rc = 0, tries = 3, this_size;
-
- while (tries && size) {
-
- this_size = f(dev, ep, bytes, size, timeout);
- if (this_size > 0) {
-
- size -= this_size;
- rc += this_size;
- bytes += this_size;
+ int tries = 3, count = 0;
- } else
- tries --;
+ while (tries && (count < size))
+ {
+ int result = f(dev, ep, bytes + count, size - count, timeout);
+ if (result > 0)
+ count += result;
+ else if ((-ETIMEDOUT != result) || !--tries)
+ return result;
}
- return rc;
+ return count;
+}
+
+static int wrap_usb_bulk_write(usb_dev_handle *dev, int ep,
+ char *buff, int size, int timeout)
+{
+ /* usb_bulk_write() takes const char *buff */
+ return usb_bulk_write(dev, ep, buff, size, timeout);
}
+
static inline int usb_bulk_write_ex(usb_dev_handle *dev, int ep,
char *bytes, int size, int timeout)
{
- return usb_bulk_with_retries(&usb_bulk_write,
+ return usb_bulk_with_retries(&wrap_usb_bulk_write,
dev, ep, bytes, size, timeout);
}
+
static inline int usb_bulk_read_ex(usb_dev_handle *dev, int ep,
char *bytes, int size, int timeout)
{