swim: add new transport 30/5530/6
authorAntonio Borneo <borneo.antonio@gmail.com>
Mon, 27 Jan 2020 17:45:10 +0000 (18:45 +0100)
committerAntonio Borneo <borneo.antonio@gmail.com>
Sun, 24 May 2020 20:32:05 +0000 (21:32 +0100)
Add SWIM and STM8 to documentation and update TODO file.
Introduce transport "swim" and command "swim newtap".
Switch in swim.c from HLA API to the new SWIM API.
Implement in stlink driver the SWIM APIs as wrappers of existing
HLA functions.
Remove any SWIM related reference from HLA files.
Update stm8 config files and stlink-dap interface config file.

Change-Id: I2bb9f58d52900f6eb4df05f979f7ef11fd439c24
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: http://openocd.zylin.com/5530
Tested-by: jenkins
12 files changed:
TODO
doc/openocd.texi
src/jtag/core.c
src/jtag/drivers/stlink_usb.c
src/jtag/hla/hla_transport.c
src/jtag/hla/hla_transport.h
src/jtag/interface.h
src/jtag/swim.c
src/transport/transport.h
tcl/interface/stlink-dap.cfg
tcl/target/stm8l.cfg
tcl/target/stm8s.cfg

diff --git a/TODO b/TODO
index c73d772e23ee8c37aa8d7b671e47047d66e4ba70..ebb6c9980832dd1d76a00d38c6d2e3b18e194dbd 100644 (file)
--- a/TODO
+++ b/TODO
@@ -59,8 +59,7 @@ changes pending in gerrit.
 - tap_set_state(TAP_RESET) is already done in src/jtag/core.c. No need
   to replicate it in the drivers, apart in case the driver sets TRST
   independently
-- separate SWIM from HLA and make it independent
-- add .hla_ops and .swim_ops to "adapter"
+- add .hla_ops to "adapter"
 - HLA is a API level (.hla_ops). Transport should simply be {jtag,swd},
   not {hla_jtag,hla_swd}.
 
index ef77993ec8ea77ea1fbda1b907fd3427a6535b8b..1ddf09ffab791f40e399e029dbc7ff2d6f789b04 100644 (file)
@@ -3304,6 +3304,24 @@ The Serial Peripheral Interface (SPI) is a general purpose transport
 which uses four wire signaling. Some processors use it as part of a
 solution for flash programming.
 
+@anchor{swimtransport}
+@subsection SWIM Transport
+@cindex SWIM
+@cindex Single Wire Interface Module
+The Single Wire Interface Module (SWIM) is a low-pin-count debug protocol used
+by the STMicroelectronics MCU family STM8 and documented in the
+@uref{https://www.st.com/resource/en/user_manual/cd00173911.pdf, User Manual UM470}.
+
+SWIM does not support boundary scan testing nor multiple cores.
+
+The SWIM transport is selected with the command @command{transport select swim}.
+
+The concept of TAPs does not fit in the protocol since SWIM does not implement
+a scan chain. Nevertheless, the current SW model of OpenOCD requires defining a
+virtual SWIM TAP through the command @command{swim newtap basename tap_type}.
+The TAP definition must precede the target definition command
+@command{target create target_name stm8 -chain-position basename.tap_type}.
+
 @anchor{jtagspeed}
 @section JTAG Speed
 JTAG clock setup is part of system setup.
@@ -9831,6 +9849,12 @@ This command is similar to @command{arc jtag get-aux-reg} but is for core
 registers.
 @end deffn
 
+@section STM8 Architecture
+@uref{http://st.com/stm8/, STM8} is a 8-bit microcontroller platform from
+STMicroelectronics, based on a proprietary 8-bit core architecture.
+
+OpenOCD supports debugging STM8 through the STMicroelectronics debug
+protocol SWIM, @pxref{swimtransport,,SWIM}.
 
 @anchor{softwaredebugmessagesandtracing}
 @section Software Debug Messages and Tracing
index d83f19503cbafad93b66efe290ab4d5f15b725ec..1d424b2e423fd1b47c179830afcaa124285c5dd1 100644 (file)
@@ -2027,7 +2027,8 @@ int adapter_resets(int trst, int srst)
                jtag_execute_queue();
                return ERROR_OK;
        } else if (transport_is_swd() || transport_is_hla() ||
-                          transport_is_dapdirect_swd() || transport_is_dapdirect_jtag()) {
+                          transport_is_dapdirect_swd() || transport_is_dapdirect_jtag() ||
+                          transport_is_swim()) {
                if (trst == TRST_ASSERT) {
                        LOG_ERROR("transport %s has no trst signal",
                                get_current_transport()->name);
@@ -2060,7 +2061,8 @@ int adapter_assert_reset(void)
                        jtag_add_reset(0, 1);
                return ERROR_OK;
        } else if (transport_is_swd() || transport_is_hla() ||
-                          transport_is_dapdirect_jtag() || transport_is_dapdirect_swd())
+                          transport_is_dapdirect_jtag() || transport_is_dapdirect_swd() ||
+                          transport_is_swim())
                return adapter_system_reset(1);
        else if (get_current_transport() != NULL)
                LOG_ERROR("reset is not supported on %s",
@@ -2076,7 +2078,8 @@ int adapter_deassert_reset(void)
                jtag_add_reset(0, 0);
                return ERROR_OK;
        } else if (transport_is_swd() || transport_is_hla() ||
-                        transport_is_dapdirect_jtag() || transport_is_dapdirect_swd())
+                          transport_is_dapdirect_jtag() || transport_is_dapdirect_swd() ||
+                          transport_is_swim())
                return adapter_system_reset(0);
        else if (get_current_transport() != NULL)
                LOG_ERROR("reset is not supported on %s",
index 485a95c6b660219ff3b030e380b73760eebbb4e3..4c5081c9e36917ce6bb8b2dc6607a0e062e83e57 100644 (file)
@@ -1288,8 +1288,6 @@ static enum stlink_mode stlink_get_mode(enum hl_transports t)
                return STLINK_MODE_DEBUG_SWD;
        case HL_TRANSPORT_JTAG:
                return STLINK_MODE_DEBUG_JTAG;
-       case HL_TRANSPORT_SWIM:
-               return STLINK_MODE_DEBUG_SWIM;
        default:
                return STLINK_MODE_UNKNOWN;
        }
@@ -3546,6 +3544,28 @@ static void stlink_dap_op_quit(struct adiv5_dap *dap)
                LOG_ERROR("Error closing APs");
 }
 
+static int stlink_swim_op_srst(void)
+{
+       return stlink_usb_reset(stlink_dap_handle);
+}
+
+static int stlink_swim_op_read_mem(uint32_t addr, uint32_t size,
+                                                                  uint32_t count, uint8_t *buffer)
+{
+       return stlink_usb_read_mem(stlink_dap_handle, addr, size, count, buffer);
+}
+
+static int stlink_swim_op_write_mem(uint32_t addr, uint32_t size,
+                                                                       uint32_t count, const uint8_t *buffer)
+{
+       return stlink_usb_write_mem(stlink_dap_handle, addr, size, count, buffer);
+}
+
+static int stlink_swim_op_reconnect(void)
+{
+       return stlink_usb_state(stlink_dap_handle);
+}
+
 static int stlink_dap_config_trace(bool enabled,
                enum tpiu_pin_protocol pin_protocol, uint32_t port_size,
                unsigned int *trace_freq, unsigned int traceclkin_freq,
@@ -3656,6 +3676,8 @@ static int stlink_dap_init(void)
                mode = STLINK_MODE_DEBUG_SWD;
        else if (transport_is_dapdirect_jtag())
                mode = STLINK_MODE_DEBUG_JTAG;
+       else if (transport_is_swim())
+               mode = STLINK_MODE_DEBUG_SWIM;
        else {
                LOG_ERROR("Unsupported transport");
                return ERROR_FAIL;
@@ -3665,7 +3687,8 @@ static int stlink_dap_init(void)
        if (retval != ERROR_OK)
                return retval;
 
-       if (!(stlink_dap_handle->version.flags & STLINK_F_HAS_DAP_REG)) {
+       if ((mode != STLINK_MODE_DEBUG_SWIM) &&
+               !(stlink_dap_handle->version.flags & STLINK_F_HAS_DAP_REG)) {
                LOG_ERROR("ST-Link version does not support DAP direct transport");
                return ERROR_FAIL;
        }
@@ -3737,7 +3760,14 @@ static const struct dap_ops stlink_dap_ops = {
        .quit = stlink_dap_op_quit, /* optional */
 };
 
-static const char *const stlink_dap_transport[] = { "dapdirect_jtag", "dapdirect_swd", NULL };
+static const struct swim_driver stlink_swim_ops = {
+       .srst = stlink_swim_op_srst,
+       .read_mem = stlink_swim_op_read_mem,
+       .write_mem = stlink_swim_op_write_mem,
+       .reconnect = stlink_swim_op_reconnect,
+};
+
+static const char *const stlink_dap_transport[] = { "dapdirect_jtag", "dapdirect_swd", "swim", NULL };
 
 struct adapter_driver stlink_dap_adapter_driver = {
        .name = "st-link",
@@ -3755,4 +3785,5 @@ struct adapter_driver stlink_dap_adapter_driver = {
 
        .dap_jtag_ops = &stlink_dap_ops,
        .dap_swd_ops = &stlink_dap_ops,
+       .swim_ops = &stlink_swim_ops,
 };
index ddacea36aa25ffec45bc3f2d1c8412523cd0dae1..fbdddfd651de724487688e3bdb36d986c70b0fc1 100644 (file)
@@ -175,8 +175,6 @@ static int hl_transport_init(struct command_context *cmd_ctx)
                tr = HL_TRANSPORT_SWD;
        else if (strcmp(transport->name, "hla_jtag") == 0)
                tr = HL_TRANSPORT_JTAG;
-       else if (strcmp(transport->name, "stlink_swim") == 0)
-               tr = HL_TRANSPORT_SWIM;
 
        int retval = hl_interface_open(tr);
 
@@ -218,26 +216,18 @@ static struct transport hl_jtag_transport = {
        .override_target = hl_interface_override_target,
 };
 
-static struct transport stlink_swim_transport = {
-       .name = "stlink_swim",
-       .select = hl_transport_select,
-       .init = hl_transport_init,
-};
-
-const char *hl_transports[] = { "hla_swd", "hla_jtag", "stlink_swim", NULL };
+const char *hl_transports[] = { "hla_swd", "hla_jtag", NULL };
 
 static void hl_constructor(void) __attribute__ ((constructor));
 static void hl_constructor(void)
 {
        transport_register(&hl_swd_transport);
        transport_register(&hl_jtag_transport);
-       transport_register(&stlink_swim_transport);
 }
 
 bool transport_is_hla(void)
 {
        struct transport *t;
        t = get_current_transport();
-       return t == &hl_swd_transport || t == &hl_jtag_transport
-                  || t == &stlink_swim_transport;
+       return t == &hl_swd_transport || t == &hl_jtag_transport;
 }
index 07eb751e2afc3279c6d3bc7c70b661f470e76482..0e0bea25f47e897dcf9459ba116f0f1bc5ad1c0a 100644 (file)
@@ -26,7 +26,6 @@ enum hl_transports {
        HL_TRANSPORT_UNKNOWN = 0,
        HL_TRANSPORT_SWD,
        HL_TRANSPORT_JTAG,
-       HL_TRANSPORT_SWIM
 };
 
 #endif /* OPENOCD_JTAG_HLA_HLA_TRANSPORT_H */
index 91291dbd1d715ead59b05f0e39649645a188391f..a471aa96dfd311744b642b86efe8ff09c5f8b4b3 100644 (file)
@@ -26,6 +26,7 @@
 #define OPENOCD_JTAG_INTERFACE_H
 
 #include <jtag/jtag.h>
+#include <jtag/swim.h>
 #include <target/armv7m_trace.h>
 
 /* @file
@@ -363,6 +364,9 @@ struct adapter_driver {
        /* DAP APIs over SWD transport */
        const struct dap_ops *dap_swd_ops;
 
+       /* SWIM APIs */
+       const struct swim_driver *swim_ops;
+
        /* FIXME: helper to simplify transition of HLA drivers. To be removed */
        struct hl_interface_s *hla_if;
 };
index 965018c2707c69bded0b366e36d5ac1b492a253e..936268b25a81113928b38e80dc5497a3a93d3353 100644 (file)
 
 #include "interface.h"
 #include "swim.h"
-#include "jtag/hla/hla_transport.h"
-#include "jtag/hla/hla_interface.h"
-#include "jtag/hla/hla_layout.h"
+#include <helper/command.h>
+#include <transport/transport.h>
 
 extern struct adapter_driver *adapter_driver;
 
 int swim_system_reset(void)
 {
-       assert(adapter_driver->hla_if);
+       assert(adapter_driver->swim_ops);
 
-       return adapter_driver->hla_if->layout->api->reset(adapter_driver->hla_if->handle);
+       return adapter_driver->swim_ops->srst();
 }
 
 int swim_read_mem(uint32_t addr, uint32_t size, uint32_t count,
                                  uint8_t *buffer)
 {
-       assert(adapter_driver->hla_if);
+       assert(adapter_driver->swim_ops);
 
-       return adapter_driver->hla_if->layout->api->read_mem(adapter_driver->hla_if->handle, addr, size, count, buffer);
+       return adapter_driver->swim_ops->read_mem(addr, size, count, buffer);
 }
 
 int swim_write_mem(uint32_t addr, uint32_t size, uint32_t count,
                                   const uint8_t *buffer)
 {
-       assert(adapter_driver->hla_if);
+       assert(adapter_driver->swim_ops);
 
-       return adapter_driver->hla_if->layout->api->write_mem(adapter_driver->hla_if->handle, addr, size, count, buffer);
+       return adapter_driver->swim_ops->write_mem(addr, size, count, buffer);
 }
 
 int swim_reconnect(void)
 {
-       assert(adapter_driver->hla_if);
+       assert(adapter_driver->swim_ops);
 
-       return adapter_driver->hla_if->layout->api->state(adapter_driver->hla_if->handle);
+       return adapter_driver->swim_ops->reconnect();
+}
+
+COMMAND_HANDLER(handle_swim_newtap_command)
+{
+       struct jtag_tap *tap;
+
+       /*
+        * only need "basename" and "tap_type", but for backward compatibility
+        * ignore extra parameters
+        */
+       if (CMD_ARGC < 2)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       tap = calloc(1, sizeof(*tap));
+       if (!tap) {
+               LOG_ERROR("Out of memory");
+               return ERROR_FAIL;
+       }
+
+       tap->chip = strdup(CMD_ARGV[0]);
+       tap->tapname = strdup(CMD_ARGV[1]);
+       tap->dotted_name = alloc_printf("%s.%s", CMD_ARGV[0], CMD_ARGV[1]);
+       if (!tap->chip || !tap->tapname || !tap->dotted_name) {
+               LOG_ERROR("Out of memory");
+               free(tap->dotted_name);
+               free(tap->tapname);
+               free(tap->chip);
+               free(tap);
+               return ERROR_FAIL;
+       }
+
+       LOG_DEBUG("Creating new SWIM \"tap\", Chip: %s, Tap: %s, Dotted: %s",
+                         tap->chip, tap->tapname, tap->dotted_name);
+
+       /* default is enabled-after-reset */
+       tap->enabled = true;
+
+       jtag_tap_init(tap);
+       return ERROR_OK;
+}
+
+static const struct command_registration swim_transport_subcommand_handlers[] = {
+       {
+               .name = "newtap",
+               .handler = handle_swim_newtap_command,
+               .mode = COMMAND_CONFIG,
+               .help = "Create a new TAP instance named basename.tap_type, "
+                               "and appends it to the scan chain.",
+               .usage = "basename tap_type",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+static const struct command_registration swim_transport_command_handlers[] = {
+       {
+               .name = "swim",
+               .mode = COMMAND_ANY,
+               .help = "perform swim adapter actions",
+               .usage = "",
+               .chain = swim_transport_subcommand_handlers,
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+static int swim_transport_select(struct command_context *cmd_ctx)
+{
+       LOG_DEBUG(__func__);
+
+       return register_commands(cmd_ctx, NULL, swim_transport_command_handlers);
+}
+
+static int swim_transport_init(struct command_context *cmd_ctx)
+{
+       enum reset_types jtag_reset_config = jtag_get_reset_config();
+
+       LOG_DEBUG(__func__);
+
+       if (jtag_reset_config & RESET_CNCT_UNDER_SRST) {
+               if (jtag_reset_config & RESET_SRST_NO_GATING)
+                       adapter_assert_reset();
+               else
+                       LOG_WARNING("\'srst_nogate\' reset_config option is required");
+       } else
+               adapter_deassert_reset();
+
+       return ERROR_OK;
+}
+
+static struct transport swim_transport = {
+       .name = "swim",
+       .select = swim_transport_select,
+       .init = swim_transport_init,
+};
+
+static void swim_constructor(void) __attribute__ ((constructor));
+static void swim_constructor(void)
+{
+       transport_register(&swim_transport);
+}
+
+bool transport_is_swim(void)
+{
+       return get_current_transport() == &swim_transport;
 }
index 4effca5d5e2f1254d08076ef2d7de9d6dad93e29..809564e789b5c158bc3f93ea1fa42fe05ed927db 100644 (file)
@@ -98,6 +98,7 @@ bool transport_is_jtag(void);
 bool transport_is_swd(void);
 bool transport_is_dapdirect_jtag(void);
 bool transport_is_dapdirect_swd(void);
+bool transport_is_swim(void);
 
 #if BUILD_HLADAPTER
 bool transport_is_hla(void);
index 4576ad388e1a7f66d987287621cc8c88cf4dfb8e..ac4de18f9bbb76d9388089609d39754c64f1c9f7 100644 (file)
@@ -1,16 +1,19 @@
 #
-# STMicroelectronics ST-LINK/V2, ST-LINK/V2-1, STLINK-V3 in-circuit
+# STMicroelectronics ST-LINK/V1, ST-LINK/V2, ST-LINK/V2-1, STLINK-V3 in-circuit
 # debugger/programmer
 #
-# This new interface driver creates a ST-Link wrapper for ARM-DAP
-# Old ST-LINK/V1 and ST-LINK/V2 pre version V2J24 don't support this method
+# This new interface driver creates a ST-Link wrapper for ARM-DAP named "dapdirect"
+# Old ST-LINK/V1 and ST-LINK/V2 pre version V2J24 don't support "dapdirect"
+#
+# SWIM transport is natively supported
 #
 
 adapter driver st-link
-st-link vid_pid 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753
+st-link vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753
 
 # transport select dapdirect_jtag
 # transport select dapdirect_swd
+# transport select swim
 
 # Optionally specify the serial number of usb device
 # e.g.
index f3c94280aed288573cf448a1373994473549eea6..782350f785651cb6936f5dce6aaa5e9109e91275 100644 (file)
@@ -4,7 +4,7 @@
 # stm8 devices support SWIM transports only.
 #
 
-transport select stlink_swim
+transport select swim
 
 if { [info exists CHIPNAME] } {
    set _CHIPNAME $CHIPNAME
@@ -62,7 +62,7 @@ if { [info exists BLOCKSIZE] } {
    set _BLOCKSIZE 0x80
 }
 
-hla newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0
+swim newtap $_CHIPNAME cpu
 
 set _TARGETNAME $_CHIPNAME.cpu
 
index 5d52aea12b78027e6dd43d68d75e31842f9f2676..277cdc9fb2102ee2c4170a0e38afb512f51171c1 100644 (file)
@@ -4,7 +4,7 @@
 # stm8 devices support SWIM transports only.
 #
 
-transport select stlink_swim
+transport select swim
 
 if { [info exists CHIPNAME] } {
    set _CHIPNAME $CHIPNAME
@@ -62,7 +62,7 @@ if { [info exists BLOCKSIZE] } {
    set _BLOCKSIZE 0x80
 }
 
-hla newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0
+swim newtap $_CHIPNAME cpu
 
 set _TARGETNAME $_CHIPNAME.cpu
 

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)