stlink: dump version in the same format of ST firmware upgrade tool
[openocd.git] / src / jtag / drivers / stlink_usb.c
index f05ffadf9e1896257426df3252ba2c7a318286d5..5837393ca31104d782094ff3be2bf49acbff1a16 100644 (file)
@@ -242,6 +242,8 @@ struct stlink_usb_handle_s {
 #define STLINK_DEBUG_APIV2_GETLASTRWSTATUS 0x3B
 #define STLINK_DEBUG_APIV2_DRIVE_NRST      0x3C
 
+#define STLINK_DEBUG_APIV2_GETLASTRWSTATUS2 0x3E
+
 #define STLINK_DEBUG_APIV2_START_TRACE_RX  0x40
 #define STLINK_DEBUG_APIV2_STOP_TRACE_RX   0x41
 #define STLINK_DEBUG_APIV2_GET_TRACE_NB    0x42
@@ -279,6 +281,7 @@ enum stlink_mode {
 #define STLINK_F_HAS_SWD_SET_FREQ       (1UL << 1)
 #define STLINK_F_HAS_JTAG_SET_FREQ      (1UL << 2)
 #define STLINK_F_HAS_MEM_16BIT          (1UL << 3)
+#define STLINK_F_HAS_GETLASTRWSTATUS2   (1UL << 4)
 
 /* aliases */
 #define STLINK_F_HAS_TARGET_VOLT        STLINK_F_HAS_TRACE
@@ -634,7 +637,10 @@ static int stlink_usb_version(void *handle)
 {
        int res;
        uint32_t flags;
-       uint16_t v;
+       uint16_t version;
+       uint8_t v, x, y, jtag, swim, msd;
+       char v_str[4 * (1 + 3) + 1]; /* VvJjMmSs */
+       char *p;
        struct stlink_usb_handle_s *h = handle;
 
        assert(handle != NULL);
@@ -648,13 +654,32 @@ static int stlink_usb_version(void *handle)
        if (res != ERROR_OK)
                return res;
 
-       v = (h->databuf[0] << 8) | h->databuf[1];
+       version = be_to_h_u16(h->databuf);
+       v = (version >> 12) & 0x0f;
+       x = (version >> 6) & 0x3f;
+       y = version & 0x3f;
+
+       h->vid = le_to_h_u16(h->databuf + 2);
+       h->pid = le_to_h_u16(h->databuf + 4);
+
+       switch (h->pid) {
+       case STLINK_V2_1_PID:
+       case STLINK_V2_1_NO_MSD_PID:
+               /* JxMy : STM32 V2.1 - JTAG/SWD only */
+               jtag = x;
+               msd = y;
+               swim = 0;
+               break;
+       default:
+               jtag = x;
+               swim = y;
+               msd = 0;
+               break;
+       }
 
-       h->version.stlink = (v >> 12) & 0x0f;
-       h->version.jtag = (v >> 6) & 0x3f;
-       h->version.swim = v & 0x3f;
-       h->vid = buf_get_u32(h->databuf, 16, 16);
-       h->pid = buf_get_u32(h->databuf, 32, 16);
+       h->version.stlink = v;
+       h->version.jtag = jtag;
+       h->version.swim = swim;
 
        flags = 0;
        switch (h->version.stlink) {
@@ -675,6 +700,10 @@ static int stlink_usb_version(void *handle)
                if (h->version.jtag >= 13)
                        flags |= STLINK_F_HAS_TRACE;
 
+               /* preferred API to get last R/W status from J15 */
+               if (h->version.jtag >= 15)
+                       flags |= STLINK_F_HAS_GETLASTRWSTATUS2;
+
                /* API to set SWD frequency from J22 */
                if (h->version.jtag >= 22)
                        flags |= STLINK_F_HAS_SWD_SET_FREQ;
@@ -693,11 +722,18 @@ static int stlink_usb_version(void *handle)
        }
        h->version.flags = flags;
 
-       LOG_INFO("STLINK v%d JTAG v%d API v%d SWIM v%d VID 0x%04X PID 0x%04X",
-               h->version.stlink,
-               h->version.jtag,
-               (h->version.jtag_api == STLINK_JTAG_API_V1) ? 1 : 2,
-               h->version.swim,
+       p = v_str;
+       p += sprintf(p, "V%d", v);
+       if (jtag || !msd)
+               p += sprintf(p, "J%d", jtag);
+       if (msd)
+               p += sprintf(p, "M%d", msd);
+       if (swim || !msd)
+               p += sprintf(p, "S%d", swim);
+
+       LOG_INFO("STLINK %s (API v%d) VID:PID %04X:%04X",
+               v_str,
+               h->version.jtag_api,
                h->vid,
                h->pid);
 
@@ -1659,9 +1695,15 @@ static int stlink_usb_get_rw_status(void *handle)
        stlink_usb_init_buffer(handle, h->rx_ep, 2);
 
        h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;
-       h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_GETLASTRWSTATUS;
+       if (h->version.flags & STLINK_F_HAS_GETLASTRWSTATUS2) {
+               h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_GETLASTRWSTATUS2;
 
-       res = stlink_usb_xfer(handle, h->databuf, 2);
+               res = stlink_usb_xfer(handle, h->databuf, 12);
+       } else {
+               h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_GETLASTRWSTATUS;
+
+               res = stlink_usb_xfer(handle, h->databuf, 2);
+       }
 
        if (res != ERROR_OK)
                return res;

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)