#include <target/cortex_m.h>
#include "cmsis_dap.h"
+#include "libusb_helper.h"
static const struct cmsis_dap_backend *const cmsis_dap_backends[] = {
#if BUILD_CMSIS_DAP_USB == 1
static int cmsis_dap_backend = -1;
static bool swd_mode;
-#define USB_TIMEOUT 1000
-
/* CMSIS-DAP General Commands */
#define CMD_DAP_INFO 0x00
#define CMD_DAP_LED 0x01
}
uint8_t current_cmd = cmsis_dap_handle->command[0];
- int retval = dap->backend->write(dap, txlen, USB_TIMEOUT);
+ int retval = dap->backend->write(dap, txlen, LIBUSB_TIMEOUT_MS);
if (retval < 0)
return retval;
/* get reply */
- retval = dap->backend->read(dap, USB_TIMEOUT);
+ retval = dap->backend->read(dap, LIBUSB_TIMEOUT_MS);
if (retval < 0)
return retval;
}
}
- int retval = dap->backend->write(dap, idx, USB_TIMEOUT);
+ int retval = dap->backend->write(dap, idx, LIBUSB_TIMEOUT_MS);
if (retval < 0) {
queued_retval = retval;
goto skip;
/* get reply */
int retval = dap->backend->read(dap, timeout_ms);
- if (retval == ERROR_TIMEOUT_REACHED && timeout_ms < USB_TIMEOUT)
+ if (retval == ERROR_TIMEOUT_REACHED && timeout_ms < LIBUSB_TIMEOUT_MS)
return;
if (retval <= 0) {
cmsis_dap_swd_write_from_queue(cmsis_dap_handle);
while (pending_fifo_block_count)
- cmsis_dap_swd_read_process(cmsis_dap_handle, USB_TIMEOUT);
+ cmsis_dap_swd_read_process(cmsis_dap_handle, LIBUSB_TIMEOUT_MS);
pending_fifo_put_idx = 0;
pending_fifo_get_idx = 0;
cmsis_dap_swd_write_from_queue(cmsis_dap_handle);
if (pending_fifo_block_count >= cmsis_dap_handle->packet_count)
- cmsis_dap_swd_read_process(cmsis_dap_handle, USB_TIMEOUT);
+ cmsis_dap_swd_read_process(cmsis_dap_handle, LIBUSB_TIMEOUT_MS);
}
if (queued_retval != ERROR_OK)
#include <libusb.h>
+/* When we debug a target that works as a USB device, halting the target causes the
+ * USB communication with the USB host to become unresponsive. The host will try
+ * to reconnect/reset/setup the unresponsive device during which communication
+ * with other devices on the same USB bus can get stalled for several seconds.
+ * If the JTAG adapter is on the same bus, we need to make sure openOCD will wait
+ * for packets at least as long as the host USB stack. Otherwise the USB stack
+ * might deliver a valid packet, but openOCD would ignore it due to the timeout.
+ * The xHCI spec uses 5 sec timeouts, so let's use that in openOCD with some margin.
+ *
+ * Use this value in all libusb calls. HID API might have a libusb backend and
+ * would probably be victim to the same bug, so it should use this timeout, too.
+ */
+#define LIBUSB_TIMEOUT_MS (6000)
+
/* this callback should return a non NULL value only when the serial could not
* be retrieved by the standard 'libusb_get_string_descriptor_ascii' */
typedef char * (*adapter_get_alternate_serial_fn)(struct libusb_device_handle *device,
#include <hidapi.h>
-#define NULINK_READ_TIMEOUT 1000
+#include "libusb_helper.h"
+
+#define NULINK_READ_TIMEOUT LIBUSB_TIMEOUT_MS
#define NULINK_HID_MAX_SIZE (64)
#define NULINK2_HID_MAX_SIZE (1024)
#define USB_EP2IN_SIZE (USB_EP2OUT_SIZE)
#define USB_EP2BANK_SIZE (512)
-#define USB_TIMEOUT_MS (3 * 1000)
-
#define DTC_STATUS_POLL_BYTE (ST7_USB_BUF_EP0OUT + 0xff)
#define ST7_PD_NBUSY_LED ST7_PD0
hdev_param,
USB_EP1OUT_ADDR,
(char *)usb_buffer, sizeof(usb_buffer),
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
usb_ret = jtag_libusb_bulk_write(
hdev_param, USB_EP1OUT_ADDR,
(char *)usb_buffer, sizeof(usb_buffer),
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
usb_ret = jtag_libusb_bulk_read(
hdev_param, USB_EP1IN_ADDR,
(char *)buffer, length,
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
usb_ret = jtag_libusb_bulk_write(
hdev_param, USB_EP1OUT_ADDR,
(char *)usb_buffer, sizeof(usb_buffer),
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
usb_err = jtag_libusb_bulk_read(
hdev, USB_EP1IN_ADDR,
(char *)&ep2txr, 1,
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
if (usb_err != ERROR_OK)
usb_err = jtag_libusb_bulk_read(
hdev, USB_EP1IN_ADDR,
(char *)&ep2txr, 1,
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
hdev_param,
USB_EP2OUT_ADDR,
(char *)command_buffer, USB_EP2BANK_SIZE,
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
if (usb_err < 0)
hdev_param,
USB_EP1IN_ADDR,
&dtc_status, 1,
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
if (usb_err < 0)
hdev_param,
USB_EP2IN_ADDR,
(char *)reply_buffer, reply_buffer_size,
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
usb_err = jtag_libusb_bulk_read(
hdev, USB_EP1IN_ADDR,
(char *)&bitmap, 1,
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
if (usb_err != ERROR_OK || transferred < 1) {
usb_err = jtag_libusb_bulk_read(
hdev, USB_EP1IN_ADDR,
(char *)&bitmap, 1,
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
if (usb_err != ERROR_OK || transferred < 1) {
usb_err = jtag_libusb_bulk_read(
hdev, USB_EP1IN_ADDR,
(char *)&bitmap, 1,
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
if (usb_err != ERROR_OK || transferred < 1) {
jtag_libusb_bulk_read(
hdev, USB_EP1IN_ADDR,
(char *)reply_buffer, 1,
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
jtag_libusb_bulk_read(
hdev, USB_EP1IN_ADDR,
(char *)reply_buffer, 1,
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
#define ENDPOINT_IN 0x80
#define ENDPOINT_OUT 0x00
-#define STLINK_WRITE_TIMEOUT 1000
-#define STLINK_READ_TIMEOUT 1000
+#define STLINK_WRITE_TIMEOUT (LIBUSB_TIMEOUT_MS)
+#define STLINK_READ_TIMEOUT (LIBUSB_TIMEOUT_MS)
#define STLINK_RX_EP (1|ENDPOINT_IN)
#define STLINK_TX_EP (2|ENDPOINT_OUT)
#define ICDI_WRITE_ENDPOINT 0x02
#define ICDI_READ_ENDPOINT 0x83
-#define ICDI_WRITE_TIMEOUT 1000
-#define ICDI_READ_TIMEOUT 1000
+#define ICDI_WRITE_TIMEOUT (LIBUSB_TIMEOUT_MS)
+#define ICDI_READ_TIMEOUT (LIBUSB_TIMEOUT_MS)
#define ICDI_PACKET_SIZE 2048
#define PACKET_START "$"
/** USB interface number */
#define USB_INTERFACE 0
-/** libusb timeout in ms */
-#define USB_TIMEOUT 5000
-
/** Delay (in microseconds) to wait while EZ-USB performs ReNumeration. */
#define ULINK_RENUMERATION_DELAY 1500000
ret = libusb_control_transfer(device->usb_device_handle,
(LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE),
- REQUEST_FIRMWARE_LOAD, CPUCS_REG, 0, &reset_bit, 1, USB_TIMEOUT);
+ REQUEST_FIRMWARE_LOAD, CPUCS_REG, 0, &reset_bit, 1, LIBUSB_TIMEOUT_MS);
/* usb_control_msg() returns the number of bytes transferred during the
* DATA stage of the control transfer - must be exactly 1 in this case! */
ret = libusb_control_transfer(device->usb_device_handle,
(LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE),
REQUEST_FIRMWARE_LOAD, addr, FIRMWARE_ADDR, (unsigned char *)data_ptr,
- chunk_size, USB_TIMEOUT);
+ chunk_size, LIBUSB_TIMEOUT_MS);
if (ret != (int)chunk_size) {
/* Abort if libusb sent less data than requested */
if ((newsize_out > 64) || (newsize_in > 64)) {
/* New command does not fit. Execute all commands in queue before starting
* new queue with the current command as first entry. */
- ret = ulink_execute_queued_commands(device, USB_TIMEOUT);
+ ret = ulink_execute_queued_commands(device, LIBUSB_TIMEOUT_MS);
if (ret == ERROR_OK)
ret = ulink_post_process_queue(device);
}
if (ulink_handle->commands_in_queue > 0) {
- ret = ulink_execute_queued_commands(ulink_handle, USB_TIMEOUT);
+ ret = ulink_execute_queued_commands(ulink_handle, LIBUSB_TIMEOUT_MS);
if (ret != ERROR_OK)
return ret;