jtag: esp_usb_jtag: remove macro __packed
[openocd.git] / src / jtag / drivers / cmsis_dap.c
index 68fd470a806c4483fc4a769ffa28dfba0fbaebfc..44a7dd8cb6ba835cfac7a14ea6d31eb42757c86a 100644 (file)
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
 /***************************************************************************
  *   Copyright (C) 2021 by Adrian Negreanu                                 *
  *   groleo@gmail.com                                                      *
  *                                                                         *
  *   Copyright (C) 2013 by Spencer Oliver                                  *
  *   spen@spen-soft.co.uk                                                  *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  ***************************************************************************/
 
 #ifdef HAVE_CONFIG_H
@@ -40,6 +29,7 @@
 
 #include <transport/transport.h>
 #include "helper/replacements.h"
+#include <jtag/adapter.h>
 #include <jtag/swd.h>
 #include <jtag/interface.h>
 #include <jtag/commands.h>
@@ -47,6 +37,7 @@
 #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
@@ -75,12 +66,9 @@ static const struct cmsis_dap_backend *const cmsis_dap_backends[] = {
 /* 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 char *cmsis_dap_serial;
 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
@@ -102,10 +90,16 @@ static bool swd_mode;
 #define INFO_ID_PKT_SZ            0xff      /* short */
 #define INFO_ID_SWO_BUF_SZ        0xfd      /* word */
 
-#define INFO_CAPS_SWD             BIT(0)
-#define INFO_CAPS_JTAG            BIT(1)
-#define INFO_CAPS_SWO_UART        BIT(2)
-#define INFO_CAPS_SWO_MANCHESTER  BIT(3)
+#define INFO_CAPS_SWD                 BIT(0)
+#define INFO_CAPS_JTAG                BIT(1)
+#define INFO_CAPS_SWO_UART            BIT(2)
+#define INFO_CAPS_SWO_MANCHESTER      BIT(3)
+#define INFO_CAPS_ATOMIC_CMDS         BIT(4)
+#define INFO_CAPS_TEST_DOMAIN_TIMER   BIT(5)
+#define INFO_CAPS_SWO_STREAMING_TRACE BIT(6)
+#define INFO_CAPS_UART_PORT           BIT(7)
+#define INFO_CAPS_USB_COM_PORT        BIT(8)
+#define INFO_CAPS__NUM_CAPS               9
 
 /* CMD_LED */
 #define LED_ID_CONNECT            0x00
@@ -203,11 +197,16 @@ static bool swd_mode;
 /* CMSIS-DAP Vendor Commands
  * None as yet... */
 
-static const char * const info_caps_str[] = {
-       "SWD  Supported",
-       "JTAG Supported",
-       "SWO-UART Supported",
-       "SWO-MANCHESTER Supported"
+static const char * const info_caps_str[INFO_CAPS__NUM_CAPS] = {
+       "SWD supported",
+       "JTAG supported",
+       "SWO-UART supported",
+       "SWO-MANCHESTER supported",
+       "Atomic commands supported",
+       "Test domain timer supported",
+       "SWO streaming trace supported",
+       "UART communication port supported",
+       "UART via USB COM port supported",
 };
 
 struct pending_transfer_result {
@@ -277,13 +276,13 @@ static int cmsis_dap_open(void)
        if (cmsis_dap_backend >= 0) {
                /* Use forced backend */
                backend = cmsis_dap_backends[cmsis_dap_backend];
-               if (backend->open(dap, cmsis_dap_vid, cmsis_dap_pid, cmsis_dap_serial) != ERROR_OK)
+               if (backend->open(dap, cmsis_dap_vid, cmsis_dap_pid, adapter_get_required_serial()) != ERROR_OK)
                        backend = NULL;
        } else {
                /* Try all backends */
                for (unsigned int i = 0; i < ARRAY_SIZE(cmsis_dap_backends); i++) {
                        backend = cmsis_dap_backends[i];
-                       if (backend->open(dap, cmsis_dap_vid, cmsis_dap_pid, cmsis_dap_serial) == ERROR_OK)
+                       if (backend->open(dap, cmsis_dap_vid, cmsis_dap_pid, adapter_get_required_serial()) == ERROR_OK)
                                break;
                        else
                                backend = NULL;
@@ -313,8 +312,6 @@ static void cmsis_dap_close(struct cmsis_dap *dap)
        free(cmsis_dap_handle->packet_buffer);
        free(cmsis_dap_handle);
        cmsis_dap_handle = NULL;
-       free(cmsis_dap_serial);
-       cmsis_dap_serial = NULL;
 
        for (int i = 0; i < MAX_PENDING_REQUESTS; i++) {
                free(pending_fifo[i].transfers);
@@ -351,12 +348,12 @@ static int cmsis_dap_xfer(struct cmsis_dap *dap, int txlen)
        }
 
        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;
 
@@ -576,6 +573,8 @@ static int cmsis_dap_metacmd_targetsel(uint32_t instance_id)
        The purpose of this operation is to select the target
        corresponding to the instance_id that is written */
 
+       LOG_DEBUG_IO("DP write reg TARGETSEL %" PRIx32, instance_id);
+
        size_t idx = 0;
        command[idx++] = CMD_DAP_SWD_SEQUENCE;
        command[idx++] = 3;     /* sequence count */
@@ -661,7 +660,7 @@ static int cmsis_dap_cmd_dap_swo_baudrate(
        command[0] = CMD_DAP_SWO_BAUDRATE;
        h_u32_to_le(&command[1], in_baudrate);
 
-       int retval = cmsis_dap_xfer(cmsis_dap_handle, 4);
+       int retval = cmsis_dap_xfer(cmsis_dap_handle, 5);
        uint32_t rvbr = le_to_h_u32(&cmsis_dap_handle->response[1]);
        if (retval != ERROR_OK || rvbr == 0) {
                LOG_ERROR("CMSIS-DAP: command CMD_SWO_Baudrate(%u) -> %u failed.", in_baudrate, rvbr);
@@ -786,7 +785,7 @@ static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap)
                uint8_t cmd = transfer->cmd;
                uint32_t data = transfer->data;
 
-               LOG_DEBUG_IO("%s %s reg %x %"PRIx32,
+               LOG_DEBUG_IO("%s %s reg %x %" PRIx32,
                                cmd & SWD_CMD_APNDP ? "AP" : "DP",
                                cmd & SWD_CMD_RNW ? "read" : "write",
                          (cmd & SWD_CMD_A32) >> 1, data);
@@ -817,7 +816,7 @@ static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap)
                }
        }
 
-       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;
@@ -845,7 +844,7 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, int timeout_ms)
 
        /* 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) {
@@ -892,7 +891,7 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, int timeout_ms)
                        uint32_t tmp = data;
                        idx += 4;
 
-                       LOG_DEBUG_IO("Read result: %"PRIx32, data);
+                       LOG_DEBUG_IO("Read result: %" PRIx32, data);
 
                        /* Imitate posted AP reads */
                        if ((transfer->cmd & SWD_CMD_APNDP) ||
@@ -920,7 +919,7 @@ static int cmsis_dap_swd_run_queue(void)
        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;
@@ -944,7 +943,7 @@ static void cmsis_dap_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data)
                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)
@@ -1016,19 +1015,17 @@ static int cmsis_dap_get_caps_info(void)
        if (retval != ERROR_OK)
                return retval;
 
-       if (data[0] == 1) {
-               uint8_t caps = data[1];
+       if (data[0] == 1 || data[0] == 2) {
+               uint16_t caps = data[1];
+               if (data[0] == 2)
+                       caps |= (uint16_t)data[2] << 8;
 
                cmsis_dap_handle->caps = caps;
 
-               if (caps & INFO_CAPS_SWD)
-                       LOG_INFO("CMSIS-DAP: %s", info_caps_str[0]);
-               if (caps & INFO_CAPS_JTAG)
-                       LOG_INFO("CMSIS-DAP: %s", info_caps_str[1]);
-               if (caps & INFO_CAPS_SWO_UART)
-                       LOG_INFO("CMSIS-DAP: %s", info_caps_str[2]);
-               if (caps & INFO_CAPS_SWO_MANCHESTER)
-                       LOG_INFO("CMSIS-DAP: %s", info_caps_str[3]);
+               for (int i = 0; i < INFO_CAPS__NUM_CAPS; ++i) {
+                       if (caps & BIT(i))
+                               LOG_INFO("CMSIS-DAP: %s", info_caps_str[i]);
+               }
        }
 
        return ERROR_OK;
@@ -1124,6 +1121,11 @@ static int cmsis_dap_swd_switch_seq(enum swd_special_seq seq)
                s = swd_seq_dormant_to_swd;
                s_len = swd_seq_dormant_to_swd_len;
                break;
+       case DORMANT_TO_JTAG:
+               LOG_DEBUG("DORMANT-to-JTAG");
+               s = swd_seq_dormant_to_jtag;
+               s_len = swd_seq_dormant_to_jtag_len;
+               break;
        default:
                LOG_ERROR("Sequence %d not supported", seq);
                return ERROR_FAIL;
@@ -1135,7 +1137,7 @@ static int cmsis_dap_swd_switch_seq(enum swd_special_seq seq)
 
        /* Atmel EDBG needs renew clock setting after SWJ_Sequence
         * otherwise default frequency is used */
-       return cmsis_dap_cmd_dap_swj_clock(jtag_get_speed_khz());
+       return cmsis_dap_cmd_dap_swj_clock(adapter_get_speed_khz());
 }
 
 static int cmsis_dap_swd_open(void)
@@ -1252,7 +1254,7 @@ static int cmsis_dap_init(void)
 
        /* Now try to connect to the target
         * TODO: This is all SWD only @ present */
-       retval = cmsis_dap_cmd_dap_swj_clock(jtag_get_speed_khz());
+       retval = cmsis_dap_cmd_dap_swj_clock(adapter_get_speed_khz());
        if (retval != ERROR_OK)
                goto init_err;
 
@@ -1394,18 +1396,18 @@ static void debug_parse_cmsis_buf(const uint8_t *cmd, int cmdlen)
        for (int i = 0; i < cmdlen; ++i)
                printf(" %02x", cmd[i]);
        printf("\n");
-       switch (cmd[1]) {
+       switch (cmd[0]) {
                case CMD_DAP_JTAG_SEQ: {
-                       printf("cmsis-dap jtag sequence command %02x (n=%d)\n", cmd[1], cmd[2]);
+                       printf("cmsis-dap jtag sequence command %02x (n=%d)\n", cmd[0], cmd[1]);
                        /*
-                        * #2 = number of sequences
-                        * #3 = sequence info 1
-                        * #4...4+n_bytes-1 = sequence 1
+                        * #1 = number of sequences
+                        * #2 = sequence info 1
+                        * #3...4+n_bytes-1 = sequence 1
                         * #4+n_bytes = sequence info 2
                         * #5+n_bytes = sequence 2 (single bit)
                         */
-                       int pos = 3;
-                       for (int seq = 0; seq < cmd[2]; ++seq) {
+                       int pos = 2;
+                       for (int seq = 0; seq < cmd[1]; ++seq) {
                                uint8_t info = cmd[pos++];
                                int len = info & DAP_JTAG_SEQ_TCK;
                                if (len == 0)
@@ -1513,7 +1515,7 @@ static void cmsis_dap_add_jtag_sequence(int s_len, const uint8_t *sequence, int
                                s_offset + offset,
                                tms,
                                tdo_buffer,
-                               tdo_buffer == NULL ? 0 : (tdo_buffer_offset + offset)
+                               !tdo_buffer ? 0 : (tdo_buffer_offset + offset)
                                );
                }
                LOG_DEBUG_IO("END JTAG SEQ SPLIT");
@@ -1530,7 +1532,7 @@ static void cmsis_dap_add_jtag_sequence(int s_len, const uint8_t *sequence, int
        /* control byte */
        queued_seq_buf[queued_seq_buf_end] =
                (tms ? DAP_JTAG_SEQ_TMS : 0) |
-               (tdo_buffer != NULL ? DAP_JTAG_SEQ_TDO : 0) |
+               (tdo_buffer ? DAP_JTAG_SEQ_TDO : 0) |
                (s_len == 64 ? 0 : s_len);
 
        if (sequence)
@@ -1995,7 +1997,7 @@ COMMAND_HANDLER(cmsis_dap_handle_cmd_command)
        uint8_t *command = cmsis_dap_handle->command;
 
        for (unsigned i = 0; i < CMD_ARGC; i++)
-               command[i] = strtoul(CMD_ARGV[i], NULL, 16);
+               COMMAND_PARSE_NUMBER(u8, CMD_ARGV[i], command[i]);
 
        int retval = cmsis_dap_xfer(cmsis_dap_handle, CMD_ARGC);
 
@@ -2041,16 +2043,6 @@ COMMAND_HANDLER(cmsis_dap_handle_vid_pid_command)
        return ERROR_OK;
 }
 
-COMMAND_HANDLER(cmsis_dap_handle_serial_command)
-{
-       if (CMD_ARGC == 1)
-               cmsis_dap_serial = strdup(CMD_ARGV[0]);
-       else
-               LOG_ERROR("expected exactly one argument to cmsis_dap_serial <serial-number>");
-
-       return ERROR_OK;
-}
-
 COMMAND_HANDLER(cmsis_dap_handle_backend_command)
 {
        if (CMD_ARGC == 1) {
@@ -2107,13 +2099,6 @@ static const struct command_registration cmsis_dap_command_handlers[] = {
                .help = "the vendor ID and product ID of the CMSIS-DAP device",
                .usage = "(vid pid)*",
        },
-       {
-               .name = "cmsis_dap_serial",
-               .handler = &cmsis_dap_handle_serial_command,
-               .mode = COMMAND_CONFIG,
-               .help = "set the serial number of the adapter",
-               .usage = "serial_string",
-       },
        {
                .name = "cmsis_dap_backend",
                .handler = &cmsis_dap_handle_backend_command,

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)