Hi, My configuration is: OpenOCD r1461 + J-Link + NXP LPC2368 (on a custom board) + Windows Vista. I spent a few days trying to get this setup working, with intermittent success. I was getting errors like "usb_bulk_read failed" in the middle of flashing the image, and as my image was getting bigger, the chance of downloading it was getting smaller. With sufficiently large image, DCC downloads would fail almost 100% of the time.
Tired of playing with JTAG speed, clock settings on CPU and like that, I finally decided to look at the OpenOCD source, specifically, at the J-Link support. I quickly realized that it was written with assumption that reading from USB bulk pipe always returns exactly the same amount of data that the device has just sent to the pipe - which seems to be not always the case with libusb driver under Vista. Here is a (quick and dirty) patch which resolved the issue for me, and may improve the stability of J-Link support in other setups. Thanks in advance. ------------------ Index: jlink.c =================================================================== --- jlink.c (revision 1461) +++ jlink.c (working copy) @@ -114,7 +114,7 @@ void jlink_usb_close(jlink_jtag_t *jlink_jtag); int jlink_usb_message(jlink_jtag_t *jlink_jtag, int out_length, int in_length); int jlink_usb_write(jlink_jtag_t *jlink_jtag, int out_length); -int jlink_usb_read(jlink_jtag_t *jlink_jtag); +int jlink_usb_read(jlink_jtag_t *jlink_jtag, int expected_size); int jlink_usb_read_emu_result(jlink_jtag_t *jlink_jtag); /* helper functions */ @@ -485,7 +485,7 @@ int result; jlink_simple_command(EMU_CMD_GET_STATE); - result = jlink_usb_read(jlink_jtag_handle); + result = jlink_usb_read(jlink_jtag_handle, 8); if (result == 8) { @@ -515,12 +515,12 @@ /* query hardware version */ jlink_simple_command(EMU_CMD_VERSION); - result = jlink_usb_read(jlink_jtag_handle); + result = jlink_usb_read(jlink_jtag_handle, 2); if (result == 2) { len = buf_get_u32(usb_in_buffer, 0, 16); - result = jlink_usb_read(jlink_jtag_handle); + result = jlink_usb_read(jlink_jtag_handle, len); if (result == len) { @@ -794,7 +794,7 @@ result = jlink_usb_write(jlink_jtag, out_length); if (result == out_length) { - result = jlink_usb_read(jlink_jtag); + result = jlink_usb_read(jlink_jtag, in_length); if (result == in_length || result == in_length+1) { if (result == in_length) @@ -847,6 +847,54 @@ } } +int usb_bulk_write_ex(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout) { + + int rc = 0, tries = 3, this_size; + + while (tries && size) { + + this_size = usb_bulk_write (dev, ep, bytes, size, timeout); + + if (this_size > 0) { + + size -= this_size; + rc += this_size; + bytes += this_size; + + } else + tries --; + } + + return rc; + + +} + +int usb_bulk_read_ex(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout) { + + int rc = 0, tries = 3, this_size; + + while (tries && size) { + + this_size = usb_bulk_read (dev, ep, bytes, size, timeout); + + if (this_size > 0) { + + size -= this_size; + rc += this_size; + bytes += this_size; + + } else + tries --; + } + + return rc; + +} + + /* Write data from out_buffer to USB. */ int jlink_usb_write(jlink_jtag_t *jlink_jtag, int out_length) { @@ -858,7 +906,7 @@ return -1; } - result = usb_bulk_write(jlink_jtag->usb_handle, JLINK_WRITE_ENDPOINT, \ + result = usb_bulk_write_ex(jlink_jtag->usb_handle, JLINK_WRITE_ENDPOINT, \ usb_out_buffer, out_length, JLINK_USB_TIMEOUT); DEBUG_JTAG_IO("jlink_usb_write, out_length = %d, result = %d", out_length, result); @@ -870,10 +918,10 @@ } /* Read data from USB into in_buffer. */ -int jlink_usb_read(jlink_jtag_t *jlink_jtag) +int jlink_usb_read(jlink_jtag_t *jlink_jtag, int expected_size) { - int result = usb_bulk_read(jlink_jtag->usb_handle, JLINK_READ_ENDPOINT, \ - usb_in_buffer, JLINK_IN_BUFFER_SIZE, JLINK_USB_TIMEOUT); + int result = usb_bulk_read_ex(jlink_jtag->usb_handle, JLINK_READ_ENDPOINT, \ + usb_in_buffer, expected_size, JLINK_USB_TIMEOUT); DEBUG_JTAG_IO("jlink_usb_read, result = %d", result); @@ -886,8 +934,8 @@ /* Read the result from the previous EMU cmd into result_buffer. */ int jlink_usb_read_emu_result(jlink_jtag_t *jlink_jtag) { - int result = usb_bulk_read(jlink_jtag->usb_handle, JLINK_READ_ENDPOINT, \ - usb_emu_result_buffer, JLINK_EMU_RESULT_BUFFER_SIZE, JLINK_USB_TIMEOUT); + int result = usb_bulk_read_ex(jlink_jtag->usb_handle, JLINK_READ_ENDPOINT, \ + usb_emu_result_buffer, 1 /* JLINK_EMU_RESULT_BUFFER_SIZE */, JLINK_USB_TIMEOUT); DEBUG_JTAG_IO("jlink_usb_read_result, result = %d", result); _______________________________________________ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development