]> git.sur5r.net Git - openocd/blobdiff - src/jtag/drivers/cmsis_dap_usb.c
drivers/cmsis_dap_usb: Return with ERROR_FAIL if no CMSIS-DAP device is found.
[openocd] / src / jtag / drivers / cmsis_dap_usb.c
index 29bb15bce0df0387b097ddd30c8c5d4e3210c68b..b8f004c4758dd19fd07fa86a07aea0909497833f 100644 (file)
@@ -60,6 +60,7 @@
 /* vid = pid = 0 marks the end of the list */
 static uint16_t cmsis_dap_vid[MAX_USB_IDS + 1] = { 0 };
 static uint16_t cmsis_dap_pid[MAX_USB_IDS + 1] = { 0 };
+static bool swd_mode;
 
 #define PACKET_SIZE       (64 + 1)     /* 64 bytes plus report id */
 #define USB_TIMEOUT       1000
@@ -173,12 +174,18 @@ static int cmsis_dap_usb_open(void)
        devs = hid_enumerate(0x0, 0x0);
        cur_dev = devs;
        while (NULL != cur_dev) {
-               if ((0 == cmsis_dap_vid[0]) && 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;
+               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
@@ -187,6 +194,8 @@ static int cmsis_dap_usb_open(void)
                                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;
@@ -199,6 +208,11 @@ static int cmsis_dap_usb_open(void)
 
        hid_free_enumeration(devs);
 
+       if (target_vid == 0 && target_pid == 0) {
+               LOG_ERROR("unable to find CMSIS-DAP device");
+               return ERROR_FAIL;
+       }
+
        if (hid_init() != 0) {
                LOG_ERROR("unable to open HIDAPI");
                return ERROR_FAIL;
@@ -231,7 +245,7 @@ static int cmsis_dap_usb_open(void)
        int packet_size = PACKET_SIZE;
 
        /* atmel cmsis-dap uses 512 byte reports */
-       if (target_vid == 0x03eb && target_pid == 0x2111)
+       if (target_vid == 0x03eb)
                packet_size = 512 + 1;
 
        cmsis_dap_handle->packet_buffer = malloc(packet_size);
@@ -284,7 +298,7 @@ static int cmsis_dap_usb_xfer(struct cmsis_dap *dap, int txlen)
        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;
@@ -293,10 +307,10 @@ static int cmsis_dap_cmd_DAP_SWJ_Pins(uint8_t pins, uint8_t mask, uint32_t wait,
        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) {
@@ -412,7 +426,7 @@ static int cmsis_dap_cmd_DAP_Disconnect(void)
        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;
@@ -420,8 +434,8 @@ static int cmsis_dap_cmd_DAP_TFER_Configure(uint8_t idle, uint16_t wait, uint16_
        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);
@@ -473,8 +487,13 @@ static int cmsis_dap_cmd_DAP_Delay(uint16_t delay_us)
 }
 #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;
@@ -491,7 +510,8 @@ static int cmsis_dap_swd_read_reg(uint8_t cmd, uint32_t *value)
        /* 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]);
@@ -500,11 +520,14 @@ static int cmsis_dap_swd_read_reg(uint8_t cmd, uint32_t *value)
        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);
@@ -525,46 +548,13 @@ static int cmsis_dap_swd_write_reg(uint8_t cmd, uint32_t 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;
 }
 
@@ -736,11 +726,50 @@ static int cmsis_dap_reset_link(void)
        return retval;
 }
 
+static int cmsis_dap_swd_open(void)
+{
+       int retval;
+
+       DEBUG_IO("CMSIS-DAP: cmsis_dap_swd_open");
+
+       if (cmsis_dap_handle == NULL) {
+
+               /* SWD init */
+               retval = cmsis_dap_usb_open();
+               if (retval != ERROR_OK)
+                       return retval;
+
+               retval = cmsis_dap_get_caps_info();
+               if (retval != ERROR_OK)
+                       return retval;
+       }
+
+       if (!(cmsis_dap_handle->caps & INFO_CAPS_SWD)) {
+               LOG_ERROR("CMSIS-DAP: SWD not supported");
+               return ERROR_JTAG_DEVICE_ERROR;
+       }
+
+       retval = cmsis_dap_cmd_DAP_Connect(CONNECT_SWD);
+       if (retval != ERROR_OK)
+               return retval;
+
+       /* Add more setup here.??... */
+
+       LOG_INFO("CMSIS-DAP: Interface Initialised (SWD)");
+       return ERROR_OK;
+}
+
 static int cmsis_dap_init(void)
 {
        int retval;
        uint8_t *data;
 
+       if (swd_mode) {
+               retval = cmsis_dap_swd_open();
+               if (retval != ERROR_OK)
+                       return retval;
+       }
+
        if (cmsis_dap_handle == NULL) {
 
                /* JTAG init */
@@ -846,36 +875,9 @@ static int cmsis_dap_init(void)
        return ERROR_OK;
 }
 
-static int cmsis_dap_swd_init(uint8_t trn)
+static int cmsis_dap_swd_init(void)
 {
-       int retval;
-
-       DEBUG_IO("CMSIS-DAP: cmsis_dap_swd_init");
-
-       if (cmsis_dap_handle == NULL) {
-
-               /* SWD init */
-               retval = cmsis_dap_usb_open();
-               if (retval != ERROR_OK)
-                       return retval;
-
-               retval = cmsis_dap_get_caps_info();
-               if (retval != ERROR_OK)
-                       return retval;
-       }
-
-       if (!(cmsis_dap_handle->caps & INFO_CAPS_SWD)) {
-               LOG_ERROR("CMSIS-DAP: SWD not supported");
-               return ERROR_JTAG_DEVICE_ERROR;
-       }
-
-       retval = cmsis_dap_cmd_DAP_Connect(CONNECT_SWD);
-       if (retval != ERROR_OK)
-               return retval;
-
-       /* Add more setup here.??... */
-
-       LOG_INFO("CMSIS-DAP: Interface Initialised (SWD)");
+       swd_mode = true;
        return ERROR_OK;
 }
 
@@ -1009,73 +1011,6 @@ static const struct command_registration cmsis_dap_subcommand_handlers[] = {
        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",
@@ -1091,22 +1026,14 @@ static const struct command_registration cmsis_dap_command_handlers[] = {
                .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};