X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Fdrivers%2Fjlink.c;h=63580f7f6eca2d92b6352b47b22b61c720a867a1;hb=d66f48d1f6923e46b81b790d6e02396b4f0f519f;hp=39be9412697c58ab30646bc7ccbc1831cbaa03dc;hpb=47eceaa229c98db9a308f6f890bc8740320903f0;p=openocd.git diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c index 39be941269..63580f7f6e 100644 --- a/src/jtag/drivers/jlink.c +++ b/src/jtag/drivers/jlink.c @@ -47,16 +47,12 @@ * 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 @@ -81,6 +77,7 @@ static uint8_t usb_out_buffer[JLINK_OUT_BUFFER_SIZE]; #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 @@ -116,6 +113,10 @@ static uint8_t usb_out_buffer[JLINK_OUT_BUFFER_SIZE]; #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 @@ -194,17 +195,9 @@ static const char * const jlink_cap_str[] = { #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_MAX 6 - -static const char * const jlink_hw_type_str[] = { - "J-Link", - "J-Trace", - "Flasher", - "J-Link Pro", - "Unknown", - "J-Link Lite-ADI", -}; +#define JLINK_HW_TYPE_LPCLINK2 18 +/* Interface selection */ #define JLINK_TIF_JTAG 0 #define JLINK_TIF_SWD 1 #define JLINK_SWD_DIR_IN 0 @@ -437,6 +430,41 @@ static int jlink_khz(int khz, int *jtag_speed) 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 * @@ -517,6 +545,10 @@ static int jlink_init(void) jlink_get_status(); } + /* Registration is sometimes necessary for SWD to work */ + if (jlink_caps & (1<= JLINK_HW_TYPE_MAX) - LOG_INFO("J-Link hw type unknown 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)) { @@ -1624,9 +1669,9 @@ static int jlink_swd_run_queue(struct adiv5_dap *dap) 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); @@ -1699,7 +1744,7 @@ static void jlink_swd_queue_cmd(struct adiv5_dap *dap, uint8_t cmd, uint32_t *ds 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 @@ -1713,7 +1758,15 @@ static struct jlink *jlink_usb_open() * 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); @@ -1723,7 +1776,7 @@ static struct jlink *jlink_usb_open() /* 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) @@ -1735,29 +1788,15 @@ static struct jlink *jlink_usb_open() #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;