ADIv5 DAP ops switching to JTAG or SWD modes
[openocd.git] / src / target / arm_adi_v5.c
index 435d65979eb8017f77d05ac17576eaa3a6f37c04..6be60af3c49c94d46eceffaf12ce77fefc60d5b7 100644 (file)
@@ -866,14 +866,16 @@ int mem_ap_write_buf_u8(struct swjdp_common *swjdp, uint8_t *buffer, int count,
        return retval;
 }
 
-/*********************************************************************************
-*                                                                                *
-* mem_ap_read_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, int count, uint32_t address)  *
-*                                                                                *
-* Read block fast in target order (little endian) into a buffer                  *
-*                                                                                *
-**********************************************************************************/
-int mem_ap_read_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, int count, uint32_t address)
+/**
+ * Synchronously read a block of 32-bit words into a buffer
+ * @param swjdp The DAP connected to the MEM-AP.
+ * @param buffer where the words will be stored (in host byte order).
+ * @param count How many words to read.
+ * @param address Memory address from which to read words; all the
+ *     words must be readable by the currently selected MEM-AP.
+ */
+int mem_ap_read_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer,
+               int count, uint32_t address)
 {
        int wcount, blocksize, readcount, errorcount = 0, retval = ERROR_OK;
        uint32_t adr = address;
@@ -884,8 +886,12 @@ int mem_ap_read_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, int count,
 
        while (wcount > 0)
        {
-               /* Adjust to read blocks within boundaries aligned to the TAR autoincremnent size*/
-               blocksize = max_tar_block_size(swjdp->tar_autoincr_block, address);
+               /* Adjust to read blocks within boundaries aligned to the
+                * TAR autoincrement size (at least 2^10).  Autoincrement
+                * mode avoids an extra per-word roundtrip to update TAR.
+                */
+               blocksize = max_tar_block_size(swjdp->tar_autoincr_block,
+                               address);
                if (wcount < blocksize)
                        blocksize = wcount;
 
@@ -893,7 +899,8 @@ int mem_ap_read_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, int count,
                if (blocksize == 0)
                        blocksize = 1;
 
-               dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_SINGLE, address);
+               dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_SINGLE,
+                               address);
 
                /* Scan out first read */
                adi_jtag_dp_scan(swjdp, JTAG_DP_APACC, AP_REG_DRW,
@@ -928,7 +935,8 @@ int mem_ap_read_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, int count,
 
                if (errorcount > 1)
                {
-                       LOG_WARNING("Block read error address 0x%" PRIx32 ", count 0x%x", address, count);
+                       LOG_WARNING("Block read error address 0x%" PRIx32
+                               ", count 0x%x", address, count);
                        return ERROR_JTAG_DEVICE_ERROR;
                }
        }
@@ -944,7 +952,8 @@ int mem_ap_read_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, int count,
 
                        for (i = 0; i < 4; i++)
                        {
-                               *((uint8_t*)pBuffer) = (data >> 8 * (adr & 0x3));
+                               *((uint8_t*)pBuffer) =
+                                               (data >> 8 * (adr & 0x3));
                                pBuffer++;
                                adr++;
                        }
@@ -1005,7 +1014,16 @@ static int mem_ap_read_buf_packed_u16(struct swjdp_common *swjdp,
        return retval;
 }
 
-int mem_ap_read_buf_u16(struct swjdp_common *swjdp, uint8_t *buffer, int count, uint32_t address)
+/**
+ * Synchronously read a block of 16-bit halfwords into a buffer
+ * @param swjdp The DAP connected to the MEM-AP.
+ * @param buffer where the halfwords will be stored (in host byte order).
+ * @param count How many halfwords to read.
+ * @param address Memory address from which to read words; all the
+ *     words must be readable by the currently selected MEM-AP.
+ */
+int mem_ap_read_buf_u16(struct swjdp_common *swjdp, uint8_t *buffer,
+               int count, uint32_t address)
 {
        uint32_t invalue, i;
        int retval = ERROR_OK;
@@ -1094,7 +1112,16 @@ static int mem_ap_read_buf_packed_u8(struct swjdp_common *swjdp,
        return retval;
 }
 
-int mem_ap_read_buf_u8(struct swjdp_common *swjdp, uint8_t *buffer, int count, uint32_t address)
+/**
+ * Synchronously read a block of bytes into a buffer
+ * @param swjdp The DAP connected to the MEM-AP.
+ * @param buffer where the bytes will be stored.
+ * @param count How many bytes to read.
+ * @param address Memory address from which to read data; all the
+ *     data must be readable by the currently selected MEM-AP.
+ */
+int mem_ap_read_buf_u8(struct swjdp_common *swjdp, uint8_t *buffer,
+               int count, uint32_t address)
 {
        uint32_t invalue;
        int retval = ERROR_OK;
@@ -1689,3 +1716,116 @@ DAP_COMMAND_HANDLER(dap_apid_command)
 
        return retval;
 }
+
+/*
+ * This represents the bits which must be sent out on TMS/SWDIO to
+ * switch a DAP implemented using an SWJ-DP module into SWD mode.
+ * These bits are stored (and transmitted) LSB-first.
+ *
+ * See the DAP-Lite specification, section 2.2.5 for information
+ * about making the debug link select SWD or JTAG.  (Similar info
+ * is in a few other ARM documents.)
+ */
+static const uint8_t jtag2swd_bitseq[] = {
+       /* More than 50 TCK/SWCLK cycles with TMS/SWDIO high,
+        * putting both JTAG and SWD logic into reset state.
+        */
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       /* Switching sequence enables SWD and disables JTAG
+        * NOTE: bits in the DP's IDCODE may expose the need for
+        * an old/deprecated sequence (0xb6 0xed).
+        */
+       0x9e, 0xe7,
+       /* More than 50 TCK/SWCLK cycles with TMS/SWDIO high,
+        * putting both JTAG and SWD logic into reset state.
+        */
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+};
+
+/**
+ * Put the debug link into SWD mode, if the target supports it.
+ * The link's initial mode may be either JTAG (for example,
+ * with SWJ-DP after reset) or SWD.
+ *
+ * @param target Enters SWD mode (if possible).
+ *
+ * Note that targets using the JTAG-DP do not support SWD, and that
+ * some targets which could otherwise support it may have have been
+ * configured to disable SWD signaling
+ *
+ * @return ERROR_OK or else a fault code.
+ */
+int dap_to_swd(struct target *target)
+{
+       int retval;
+
+       LOG_DEBUG("Enter SWD mode");
+
+       /* REVISIT it's nasty to need to make calls to a "jtag"
+        * subsystem if the link isn't in JTAG mode...
+        */
+
+       retval =  jtag_add_tms_seq(8 * sizeof(jtag2swd_bitseq),
+                       jtag2swd_bitseq, TAP_INVALID);
+       if (retval == ERROR_OK)
+               retval = jtag_execute_queue();
+
+       /* REVISIT set up the DAP's ops vector for SWD mode. */
+
+       return retval;
+}
+
+/**
+ * This represents the bits which must be sent out on TMS/SWDIO to
+ * switch a DAP implemented using an SWJ-DP module into JTAG mode.
+ * These bits are stored (and transmitted) LSB-first.
+ *
+ * These bits are stored (and transmitted) LSB-first.
+ */
+static const uint8_t swd2jtag_bitseq[] = {
+       /* More than 50 TCK/SWCLK cycles with TMS/SWDIO high,
+        * putting both JTAG and SWD logic into reset state.
+        */
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       /* Switching equence disables SWD and enables JTAG
+        * NOTE: bits in the DP's IDCODE can expose the need for
+        * the old/deprecated sequence (0xae 0xde).
+        */
+       0x3c, 0xe7,
+       /* At least 50 TCK/SWCLK cycles with TMS/SWDIO high,
+        * putting both JTAG and SWD logic into reset state.
+        * NOTE:  some docs say "at least 5".
+        */
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+};
+
+/** Put the debug link into JTAG mode, if the target supports it.
+ * The link's initial mode may be either SWD or JTAG.
+ *
+ * @param target Enters JTAG mode (if possible).
+ *
+ * Note that targets implemented with SW-DP do not support JTAG, and
+ * that some targets which could otherwise support it may have been
+ * configured to disable JTAG signaling
+ *
+ * @return ERROR_OK or else a fault code.
+ */
+int dap_to_jtag(struct target *target)
+{
+       int retval;
+
+       LOG_DEBUG("Enter JTAG mode");
+
+       /* REVISIT it's nasty to need to make calls to a "jtag"
+        * subsystem if the link isn't in JTAG mode...
+        */
+
+       retval = jtag_add_tms_seq(8 * sizeof(swd2jtag_bitseq),
+                       swd2jtag_bitseq, TAP_RESET);
+       if (retval == ERROR_OK)
+               retval = jtag_execute_queue();
+
+       /* REVISIT set up the DAP's ops vector for JTAG mode. */
+
+       return retval;
+}

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)