-/* SPDX-License-Identifier: GPL-2.0-or-later */
+// SPDX-License-Identifier: GPL-2.0-or-later
/***************************************************************************
* Copyright (C) 2007 by Juergen Stuber <juergen@jstuber.net> *
#define HID_COMMAND_CONFIGURE 0x8f
#define HID_COMMAND_BOOTLOADER 0xa0
-/* 512 bytes seems to work reliably */
-#define SWD_MAX_BUFFER_LENGTH 512
+/* 512 bytes seemed to work reliably.
+ * It works with both full queue of mostly reads or mostly writes.
+ *
+ * Unfortunately the commit 88f429ead019fd6df96ec15f0d897385f3cef0d0
+ * 5321: target/cortex_m: faster reading of all CPU registers
+ * revealed a serious Kitprog firmware problem:
+ * If the queue contains more than 63 transactions in the repeated pattern
+ * one write, two reads, the firmware fails badly.
+ * Sending 64 transactions makes the adapter to loose the connection with the
+ * device. Sending 65 or more transactions causes the adapter to stop
+ * receiving USB HID commands, next kitprog_hid_command() stops in hid_write().
+ *
+ * The problem was detected with KitProg v2.12 and v2.16.
+ * We can guess the problem is something like a buffer or stack overflow.
+ *
+ * Use shorter buffer as a workaround. 300 bytes (= 60 transactions) works.
+ */
+#define SWD_MAX_BUFFER_LENGTH 300
struct kitprog {
hid_device *hid_handle;
const uint16_t vids[] = { VID, 0 };
const uint16_t pids[] = { PID, 0 };
- if (jtag_libusb_open(vids, pids, &kitprog_handle->usb_handle, NULL) != ERROR_OK) {
+ if (jtag_libusb_open(vids, pids, NULL, &kitprog_handle->usb_handle, NULL) != ERROR_OK) {
LOG_ERROR("Failed to open or find the device");
return ERROR_FAIL;
}
int transferred;
char status = PROGRAMMER_NOK_NACK;
- transferred = jtag_libusb_control_transfer(kitprog_handle->usb_handle,
+ int retval = jtag_libusb_control_transfer(kitprog_handle->usb_handle,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
CONTROL_TYPE_WRITE,
(CONTROL_MODE_SET_PROGRAMMER_PROTOCOL << 8) | CONTROL_COMMAND_PROGRAM,
- protocol, &status, 1, 0);
+ protocol, &status, 1, 0, &transferred);
- if (transferred == 0) {
+ if (retval != ERROR_OK || transferred == 0) {
LOG_DEBUG("Zero bytes transferred");
return ERROR_FAIL;
}
/* Try a maximum of three times */
for (int i = 0; (i < 3) && (transferred == 0); i++) {
- transferred = jtag_libusb_control_transfer(kitprog_handle->usb_handle,
+ jtag_libusb_control_transfer(kitprog_handle->usb_handle,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
CONTROL_TYPE_READ,
(CONTROL_MODE_POLL_PROGRAMMER_STATUS << 8) | CONTROL_COMMAND_PROGRAM,
- 0, &status, 1, 0);
+ 0, &status, 1, 0, &transferred);
jtag_sleep(1000);
}
int transferred;
char status = PROGRAMMER_NOK_NACK;
- transferred = jtag_libusb_control_transfer(kitprog_handle->usb_handle,
+ int retval = jtag_libusb_control_transfer(kitprog_handle->usb_handle,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
CONTROL_TYPE_WRITE,
(0x03 << 8) | 0x04,
- 0, &status, 1, 0);
+ 0, &status, 1, 0, &transferred);
- if (transferred == 0) {
+ if (retval != ERROR_OK || transferred == 0) {
LOG_DEBUG("Zero bytes transferred");
return ERROR_FAIL;
}
int transferred;
char status = PROGRAMMER_NOK_NACK;
- transferred = jtag_libusb_control_transfer(kitprog_handle->usb_handle,
+ int retval = jtag_libusb_control_transfer(kitprog_handle->usb_handle,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
CONTROL_TYPE_WRITE,
(CONTROL_MODE_ACQUIRE_SWD_TARGET << 8) | CONTROL_COMMAND_PROGRAM,
- (max_attempts << 8) | (acquire_mode << 4) | psoc_type, &status, 1, 0);
+ (max_attempts << 8) | (acquire_mode << 4) | psoc_type, &status, 1, 0, &transferred);
- if (transferred == 0) {
+ if (retval != ERROR_OK || transferred == 0) {
LOG_DEBUG("Zero bytes transferred");
return ERROR_FAIL;
}
int transferred;
char status = PROGRAMMER_NOK_NACK;
- transferred = jtag_libusb_control_transfer(kitprog_handle->usb_handle,
+ int retval = jtag_libusb_control_transfer(kitprog_handle->usb_handle,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
CONTROL_TYPE_WRITE,
(CONTROL_MODE_RESET_TARGET << 8) | CONTROL_COMMAND_PROGRAM,
- 0, &status, 1, 0);
+ 0, &status, 1, 0, &transferred);
- if (transferred == 0) {
+ if (retval != ERROR_OK || transferred == 0) {
LOG_DEBUG("Zero bytes transferred");
return ERROR_FAIL;
}
int transferred;
char status = PROGRAMMER_NOK_NACK;
- transferred = jtag_libusb_control_transfer(kitprog_handle->usb_handle,
+ int retval = jtag_libusb_control_transfer(kitprog_handle->usb_handle,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
CONTROL_TYPE_WRITE,
(CONTROL_MODE_SYNCHRONIZE_TRANSFER << 8) | CONTROL_COMMAND_PROGRAM,
- 0, &status, 1, 0);
+ 0, &status, 1, 0, &transferred);
- if (transferred == 0) {
+ if (retval != ERROR_OK || transferred == 0) {
LOG_DEBUG("Zero bytes transferred");
return ERROR_FAIL;
}
int transferred;
char status = PROGRAMMER_NOK_NACK;
- transferred = jtag_libusb_control_transfer(kitprog_handle->usb_handle,
+ int retval = jtag_libusb_control_transfer(kitprog_handle->usb_handle,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
CONTROL_TYPE_WRITE,
(CONTROL_MODE_SEND_SWD_SEQUENCE << 8) | CONTROL_COMMAND_PROGRAM,
- seq_type, &status, 1, 0);
+ seq_type, &status, 1, 0, &transferred);
- if (transferred == 0) {
+ if (retval != ERROR_OK || transferred == 0) {
LOG_DEBUG("Zero bytes transferred");
return ERROR_FAIL;
}
if (ack != SWD_ACK_OK || (buffer[read_index] & 0x08)) {
LOG_DEBUG("SWD ack not OK: %d %s", i,
ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK");
- queued_retval = ack == SWD_ACK_WAIT ? ERROR_WAIT : ERROR_FAIL;
+ queued_retval = swd_ack_to_error_code(ack);
break;
}
read_index++;
.usage = "",
.help = "try to acquire a PSoC",
},
+ {
+ .name = "init_acquire_psoc",
+ .handler = &kitprog_handle_init_acquire_psoc_command,
+ .mode = COMMAND_CONFIG,
+ .help = "try to acquire a PSoC during init",
+ .usage = "",
+ },
COMMAND_REGISTRATION_DONE
};
.usage = "<cmd>",
.chain = kitprog_subcommand_handlers,
},
- {
- .name = "kitprog_init_acquire_psoc",
- .handler = &kitprog_handle_init_acquire_psoc_command,
- .mode = COMMAND_CONFIG,
- .help = "try to acquire a PSoC during init",
- .usage = "",
- },
COMMAND_REGISTRATION_DONE
};