#define MAX_USB_IDS 8
/* vid = pid = 0 marks the end of the list */
-static uint16_t cmsis_dap_vid[MAX_USB_IDS + 1] = { 0xc251, 0xc251, 0xc251, 0x0d28, 0x03eb, 0 };
-static uint16_t cmsis_dap_pid[MAX_USB_IDS + 1] = { 0xf001, 0xf002, 0x2722, 0x0204, 0x2111, 0 };
+static uint16_t cmsis_dap_vid[MAX_USB_IDS + 1] = { 0 };
+static uint16_t cmsis_dap_pid[MAX_USB_IDS + 1] = { 0 };
#define PACKET_SIZE (64 + 1) /* 64 bytes plus report id */
#define USB_TIMEOUT 1000
{
hid_device *dev = NULL;
int i;
+ struct hid_device_info *devs, *cur_dev;
+ unsigned short target_vid, target_pid;
+
+ target_vid = 0;
+ target_pid = 0;
+
+ /*
+ The CMSIS-DAP specification stipulates:
+ "The Product String must contain "CMSIS-DAP" somewhere in the string. This is used by the
+ debuggers to idenify a CMSIS-DAP compliant Debug Unit that is connected to a host computer."
+ */
+ devs = hid_enumerate(0x0, 0x0);
+ cur_dev = devs;
+ while (NULL != cur_dev) {
+ if (0 == cmsis_dap_vid[0]) {
+ if (NULL == cur_dev->product_string) {
+ LOG_DEBUG("Cannot read product string of device 0x%x:0x%x",
+ cur_dev->vendor_id, cur_dev->product_id);
+ } else {
+ if (wcsstr(cur_dev->product_string, L"CMSIS-DAP"))
+ /*
+ if the user hasn't specified VID:PID *and*
+ product string contains "CMSIS-DAP", pick it
+ */
+ break;
+ }
+ } else {
+ /*
+ otherwise, exhaustively compare against all VID:PID in list
+ */
+ for (i = 0; cmsis_dap_vid[i] || cmsis_dap_pid[i]; i++) {
+ if ((cmsis_dap_vid[i] == cur_dev->vendor_id) && (cmsis_dap_pid[i] == cur_dev->product_id))
+ break;
+ }
+ if (cmsis_dap_vid[i] || cmsis_dap_pid[i])
+ break;
+ }
+
+ cur_dev = cur_dev->next;
+ }
+
+ if (NULL != cur_dev) {
+ target_vid = cur_dev->vendor_id;
+ target_pid = cur_dev->product_id;
+ }
+
+ hid_free_enumeration(devs);
if (hid_init() != 0) {
LOG_ERROR("unable to open HIDAPI");
return ERROR_FAIL;
}
- for (i = 0; cmsis_dap_vid[i] || cmsis_dap_pid[i]; i++) {
- dev = hid_open(cmsis_dap_vid[i], cmsis_dap_pid[i], NULL);
- if (dev != NULL)
- break;
- }
+ dev = hid_open(target_vid, target_pid, NULL);
if (dev == NULL) {
LOG_ERROR("unable to open CMSIS-DAP device");
int packet_size = PACKET_SIZE;
/* atmel cmsis-dap uses 512 byte reports */
- if (cmsis_dap_vid[i] == 0x03eb && cmsis_dap_pid[i] == 0x2111)
+ if (target_vid == 0x03eb)
packet_size = 512 + 1;
cmsis_dap_handle->packet_buffer = malloc(packet_size);
return ERROR_OK;
}
-static int cmsis_dap_cmd_DAP_SWJ_Pins(uint8_t pins, uint8_t mask, uint32_t wait, uint8_t *input)
+static int cmsis_dap_cmd_DAP_SWJ_Pins(uint8_t pins, uint8_t mask, uint32_t delay, uint8_t *input)
{
int retval;
uint8_t *buffer = cmsis_dap_handle->packet_buffer;
buffer[1] = CMD_DAP_SWJ_PINS;
buffer[2] = pins;
buffer[3] = mask;
- buffer[4] = wait & 0xff;
- buffer[5] = (wait >> 8) & 0xff;
- buffer[6] = (wait >> 16) & 0xff;
- buffer[7] = (wait >> 24) & 0xff;
+ buffer[4] = delay & 0xff;
+ buffer[5] = (delay >> 8) & 0xff;
+ buffer[6] = (delay >> 16) & 0xff;
+ buffer[7] = (delay >> 24) & 0xff;
retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 8);
if (retval != ERROR_OK) {
return ERROR_OK;
}
-static int cmsis_dap_cmd_DAP_TFER_Configure(uint8_t idle, uint16_t wait, uint16_t retry)
+static int cmsis_dap_cmd_DAP_TFER_Configure(uint8_t idle, uint16_t delay, uint16_t retry)
{
int retval;
uint8_t *buffer = cmsis_dap_handle->packet_buffer;
buffer[0] = 0; /* report number */
buffer[1] = CMD_DAP_TFER_CONFIGURE;
buffer[2] = idle;
- buffer[3] = wait & 0xff;
- buffer[4] = (wait >> 8) & 0xff;
+ buffer[3] = delay & 0xff;
+ buffer[4] = (delay >> 8) & 0xff;
buffer[5] = retry & 0xff;
buffer[6] = (retry >> 8) & 0xff;
retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 7);
}
#endif
-static int cmsis_dap_swd_read_reg(uint8_t cmd, uint32_t *value)
+static int queued_retval;
+
+static void cmsis_dap_swd_read_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t *value)
{
+ if (queued_retval != ERROR_OK)
+ return;
+
uint8_t *buffer = cmsis_dap_handle->packet_buffer;
int retval;
uint32_t val;
/* TODO - need better response checking */
if (retval != ERROR_OK || buffer[1] != 0x01) {
LOG_ERROR("CMSIS-DAP: Read Error (0x%02" PRIx8 ")", buffer[2]);
- return buffer[2];
+ queued_retval = buffer[2];
+ return;
}
val = le_to_h_u32(&buffer[3]);
if (value)
*value = val;
- return retval;
+ queued_retval = retval;
}
-static int cmsis_dap_swd_write_reg(uint8_t cmd, uint32_t value)
+static void cmsis_dap_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t value)
{
+ if (queued_retval != ERROR_OK)
+ return;
+
uint8_t *buffer = cmsis_dap_handle->packet_buffer;
DEBUG_IO("CMSIS-DAP: Write Reg 0x%02" PRIx8 " 0x%08" PRIx32, cmd, value);
retval = buffer[2];
}
- return retval;
+ queued_retval = retval;
}
-static int cmsis_dap_swd_read_block(uint8_t cmd, uint32_t blocksize, uint8_t *dest_buf)
+static int cmsis_dap_swd_run(struct adiv5_dap *dap)
{
- uint8_t *buffer;
- int tfer_sz;
- int retval = ERROR_OK;
- uint16_t read_count;
-
- DEBUG_IO("CMSIS-DAP: Read Block 0x%02" PRIx8 " %" PRIu32, cmd, blocksize);
-
- while (blocksize) {
-
- buffer = cmsis_dap_handle->packet_buffer;
- tfer_sz = blocksize;
- if (tfer_sz > 15)
- tfer_sz = 8;
-
- buffer[0] = 0; /* report number */
- buffer[1] = CMD_DAP_TFER_BLOCK;
- buffer[2] = 0x00;
- buffer[3] = tfer_sz;
- buffer[4] = 0x00;
- buffer[5] = cmd;
- retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 6);
-
- read_count = le_to_h_u16(&buffer[1]);
- if (read_count != tfer_sz) {
- LOG_ERROR("CMSIS-DAP: Block Read Error (0x%02" PRIx8 ")", buffer[3]);
- retval = buffer[3];
- }
-
- read_count *= 4;
- memcpy(dest_buf, &buffer[4], read_count);
-
- dest_buf += read_count;
- blocksize -= tfer_sz;
- }
-
+ int retval = queued_retval;
+ queued_retval = ERROR_OK;
return retval;
}
return ERROR_OK;
}
-static int cmsis_dap_swd_init(uint8_t trn)
+static int cmsis_dap_swd_init(void)
{
int retval;
COMMAND_REGISTRATION_DONE
};
-COMMAND_HANDLER(cmsis_dap_reset_command)
-{
- LOG_DEBUG("cmsis_dap_reset_command");
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(cmsis_dap_jtag_command)
-{
- LOG_DEBUG("cmsis_dap_jtag_command");
- return ERROR_OK;
-}
-
-static const struct command_registration cmsis_dap_jtag_subcommand_handlers[] = {
- {
- .name = "init",
- .mode = COMMAND_ANY,
- .handler = cmsis_dap_jtag_command,
- .usage = ""
- },
- {
- .name = "arp_init",
- .mode = COMMAND_ANY,
- .handler = cmsis_dap_jtag_command,
- .usage = ""
- },
- {
- .name = "arp_init-reset",
- .mode = COMMAND_ANY,
- .handler = cmsis_dap_reset_command,
- .usage = ""
- },
- {
- .name = "tapisenabled",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_jtag_tap_enabler,
- },
- {
- .name = "tapenable",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_jtag_tap_enabler,
- },
- {
- .name = "tapdisable",
- .mode = COMMAND_EXEC,
- .handler = cmsis_dap_jtag_command,
- .usage = "",
- },
- {
- .name = "configure",
- .mode = COMMAND_EXEC,
- .handler = cmsis_dap_jtag_command,
- .usage = "",
- },
- {
- .name = "cget",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_jtag_configure,
- },
- {
- .name = "names",
- .mode = COMMAND_ANY,
- .handler = cmsis_dap_jtag_command,
- .usage = "",
- },
- COMMAND_REGISTRATION_DONE
-};
-
static const struct command_registration cmsis_dap_command_handlers[] = {
{
.name = "cmsis-dap",
.help = "the vendor ID and product ID of the CMSIS-DAP device",
.usage = "(vid pid)* ",
},
- {
- /* this is currently a nasty hack so we get
- * reset working with non jtag interfaces */
- .name = "jtag",
- .mode = COMMAND_ANY,
- .usage = "",
- .chain = cmsis_dap_jtag_subcommand_handlers,
- },
COMMAND_REGISTRATION_DONE
};
static const struct swd_driver cmsis_dap_swd_driver = {
- .init = cmsis_dap_swd_init,
- .read_reg = cmsis_dap_swd_read_reg,
- .write_reg = cmsis_dap_swd_write_reg,
- .read_block = cmsis_dap_swd_read_block
+ .init = cmsis_dap_swd_init,
+ .read_reg = cmsis_dap_swd_read_reg,
+ .write_reg = cmsis_dap_swd_write_reg,
+ .run = cmsis_dap_swd_run,
};
const char *cmsis_dap_transport[] = {"cmsis-dap", NULL};