* pid = ( usb_address > 0x4) ? 0x0101 : (0x101 + usb_address)
*/
-#define JLINK_OB_PID 0x0105
+#define JLINK_USB_INTERFACE_CLASS 0xff
+#define JLINK_USB_INTERFACE_SUBCLASS 0xff
+#define JLINK_USB_INTERFACE_PROTOCOL 0xff
-#define JLINK_WRITE_ENDPOINT 0x02
-#define JLINK_READ_ENDPOINT 0x81
-
-#define JLINK_OB_WRITE_ENDPOINT 0x06
-#define JLINK_OB_READ_ENDPOINT 0x85
-
-static unsigned int jlink_write_ep = JLINK_WRITE_ENDPOINT;
-static unsigned int jlink_read_ep = JLINK_READ_ENDPOINT;
+static unsigned int jlink_write_ep;
+static unsigned int jlink_read_ep;
static unsigned int jlink_hw_jtag_version = 2;
#define JLINK_USB_TIMEOUT 1000
#define EMU_CMD_SET_SPEED 0x05
#define EMU_CMD_GET_STATE 0x07
#define EMU_CMD_SET_KS_POWER 0x08
+#define EMU_CMD_REGISTER 0x09
#define EMU_CMD_GET_SPEEDS 0xc0
#define EMU_CMD_GET_HW_INFO 0xc1
#define EMU_CMD_GET_COUNTERS 0xc2
#define EMU_CMD_WRITE_MEM_ARM79 0xf7
#define EMU_CMD_READ_MEM_ARM79 0xf8
+/* Register subcommands */
+#define REG_CMD_REGISTER 100
+#define REG_CMD_UNREGISTER 101
+
/* bits return from EMU_CMD_GET_CAPS */
#define EMU_CAP_RESERVED_1 0
#define EMU_CAP_GET_HW_VERSION 1
#define EMU_CAP_RAWTRACE 30
#define EMU_CAP_RESERVED_3 31
-static char *jlink_cap_str[] = {
+static const char * const jlink_cap_str[] = {
"Always 1.",
"Supports command EMU_CMD_GET_HARDWARE_VERSION",
"Supports command EMU_CMD_WRITE_DCC",
#define JLINK_MAX_SPEED 12000
/* J-Link hardware versions */
-#define JLINK_HW_TYPE_JLINK 0
-#define JLINK_HW_TYPE_JTRACE 1
-#define JLINK_HW_TYPE_FLASHER 2
-#define JLINK_HW_TYPE_JLINK_PRO 3
-#define JLINK_HW_TYPE_MAX 4
-
-static char *jlink_hw_type_str[] = {
- "J-Link",
- "J-Trace",
- "Flasher",
- "J-Link Pro",
-};
-
+#define JLINK_HW_TYPE_JLINK 0
+#define JLINK_HW_TYPE_JTRACE 1
+#define JLINK_HW_TYPE_FLASHER 2
+#define JLINK_HW_TYPE_JLINK_PRO 3
+#define JLINK_HW_TYPE_JLINK_LITE_ADI 5
+#define JLINK_HW_TYPE_LPCLINK2 18
+
+/* Interface selection */
#define JLINK_TIF_JTAG 0
#define JLINK_TIF_SWD 1
#define JLINK_SWD_DIR_IN 0
return ERROR_OK;
}
+static int jlink_register(void)
+{
+ int result;
+ usb_out_buffer[0] = EMU_CMD_REGISTER;
+ usb_out_buffer[1] = REG_CMD_REGISTER;
+ /* 2 - 11 is "additional parameter",
+ * 12 - 13 is connection handle, zero initially */
+ memset(&usb_out_buffer[2], 0, 10 + 2);
+
+ result = jlink_usb_write(jlink_handle, 14);
+ if (result != 14) {
+ LOG_ERROR("J-Link register write failed (%d)", result);
+ return ERROR_JTAG_DEVICE_ERROR;
+ }
+
+ /* Returns:
+ * 0 - 1 connection handle,
+ * 2 - 3 number of information entities,
+ * 4 - 5 size of a single information struct,
+ * 6 - 7 number of additional bytes,
+ * 8 - ... reply data
+ *
+ * Try to read the whole USB bulk packet
+ */
+ result = jtag_libusb_bulk_read(jlink_handle->usb_handle, jlink_read_ep,
+ (char *)usb_in_buffer, sizeof(usb_in_buffer),
+ JLINK_USB_TIMEOUT);
+ if (!result) {
+ LOG_ERROR("J-Link register read failed (0 bytes received)");
+ return ERROR_JTAG_DEVICE_ERROR;
+ }
+
+ return ERROR_OK;
+}
+
/*
* select transport interface
*
jlink_get_status();
}
+ /* Registration is sometimes necessary for SWD to work */
+ if (jlink_caps & (1<<EMU_CAP_REGISTER))
+ jlink_register();
+
/*
* Some versions of Segger's software do not select JTAG interface by default.
*
jlink_tap_execute();
}
- if (swd_mode)
- jlink_swd_switch_seq(NULL, JTAG_TO_SWD);
- else
- jlink_swd_switch_seq(NULL, SWD_TO_JTAG);
- jlink_swd_run_queue(NULL);
-
return ERROR_OK;
}
LOG_INFO("J-Link hw version %i", (int)jlink_hw_version);
- if (jlink_hw_type >= JLINK_HW_TYPE_MAX)
- LOG_INFO("J-Link hw type uknown 0x%" PRIx32, jlink_hw_type);
- else
- LOG_INFO("J-Link hw type %s", jlink_hw_type_str[jlink_hw_type]);
+ switch (jlink_hw_type) {
+ case JLINK_HW_TYPE_JLINK:
+ LOG_INFO("J-Link hw type J-Link");
+ break;
+ case JLINK_HW_TYPE_JTRACE:
+ LOG_INFO("J-Link hw type J-Trace");
+ break;
+ case JLINK_HW_TYPE_FLASHER:
+ LOG_INFO("J-Link hw type Flasher");
+ break;
+ case JLINK_HW_TYPE_JLINK_PRO:
+ LOG_INFO("J-Link hw type J-Link Pro");
+ break;
+ case JLINK_HW_TYPE_JLINK_LITE_ADI:
+ LOG_INFO("J-Link hw type J-Link Lite-ADI");
+ break;
+ case JLINK_HW_TYPE_LPCLINK2:
+ LOG_INFO("J-Link hw type J-Link on LPC-Link2");
+ break;
+ default:
+ LOG_INFO("J-Link hw type unknown 0x%" PRIx32, jlink_hw_type);
+ break;
+ }
}
if (jlink_caps & (1 << EMU_CAP_GET_MAX_BLOCK_SIZE)) {
int ack = buf_get_u32(usb_in_buffer, pending_scan_results_buffer[i].first, 3);
if (ack != SWD_ACK_OK) {
- LOG_ERROR("SWD ack not OK: %d %s", ack,
+ LOG_DEBUG("SWD ack not OK: %d %s", ack,
ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK");
- queued_retval = ack;
+ queued_retval = ack == SWD_ACK_WAIT ? ERROR_WAIT : ERROR_FAIL;
goto skip;
} else if (pending_scan_results_buffer[i].length) {
uint32_t data = buf_get_u32(usb_in_buffer, 3 + pending_scan_results_buffer[i].first, 32);
static struct jlink *jlink_usb_open()
{
struct jtag_libusb_device_handle *devh;
- if (jtag_libusb_open(vids, pids, &devh) != ERROR_OK)
+ if (jtag_libusb_open(vids, pids, NULL, &devh) != ERROR_OK)
return NULL;
/* BE ***VERY CAREFUL*** ABOUT MAKING CHANGES IN THIS
* committing them!
*/
-#if IS_WIN32 == 0
+/* This entire block can probably be removed. It was a workaround for
+ * libusb0.1 and old JLink firmware. It has already be removed for
+ * windows and causing problems (LPC Link-2 with JLink firmware) on
+ * Linux with libusb1.0.
+ *
+ * However, for now the behavior will be left unchanged for non-windows
+ * platforms using libusb0.1 due to lack of testing.
+ */
+#if IS_WIN32 == 0 && HAVE_LIBUSB1 == 0
jtag_libusb_reset_device(devh);
/* reopen jlink after usb_reset
* on win32 this may take a second or two to re-enumerate */
int retval;
- while ((retval = jtag_libusb_open(vids, pids, &devh)) != ERROR_OK) {
+ while ((retval = jtag_libusb_open(vids, pids, NULL, &devh)) != ERROR_OK) {
usleep(1000);
timeout--;
if (!timeout)
#endif
- /* usb_set_configuration required under win32 */
- struct jtag_libusb_device *udev = jtag_libusb_get_device(devh);
+ /* usb_set_configuration is only required under win32
+ * with libusb 0.1 and libusb0.sys. For libusb 1.0 it is a no-op
+ * since the configuration is already set. */
jtag_libusb_set_configuration(devh, 0);
- jtag_libusb_claim_interface(devh, 0);
-
-#if 0
- /*
- * This makes problems under Mac OS X. And is not needed
- * under Windows. Hopefully this will not break a linux build
- */
- usb_set_altinterface(result->usb_handle, 0);
-#endif
-
- /* Use the OB endpoints if the JLink we matched is a Jlink-OB adapter */
- uint16_t matched_pid;
- if (jtag_libusb_get_pid(udev, &matched_pid) == ERROR_OK) {
- if (matched_pid == JLINK_OB_PID) {
- jlink_read_ep = JLINK_OB_WRITE_ENDPOINT;
- jlink_write_ep = JLINK_OB_READ_ENDPOINT;
- }
- }
- jtag_libusb_get_endpoints(udev, &jlink_read_ep, &jlink_write_ep);
+ jtag_libusb_choose_interface(devh, &jlink_read_ep, &jlink_write_ep,
+ JLINK_USB_INTERFACE_CLASS,
+ JLINK_USB_INTERFACE_SUBCLASS,
+ JLINK_USB_INTERFACE_PROTOCOL);
struct jlink *result = malloc(sizeof(struct jlink));
result->usb_handle = devh;