swim: abstract the transport in stm8 target 28/5528/6
authorAntonio Borneo <borneo.antonio@gmail.com>
Sun, 26 Jan 2020 16:00:55 +0000 (17:00 +0100)
committerAntonio Borneo <borneo.antonio@gmail.com>
Sun, 24 May 2020 20:29:42 +0000 (21:29 +0100)
SWIM is implemented by (ab)using the HLA API. This was acceptable
when OpenOCD code did not provided a clear separation between
transports and related APIs. Still today SWIM in OpenOCD is only
supported by STLink, so the decision to re-use the HLA API was the
simpler way to implement it.
After commit efd1d642220a ("adapter: switch from struct
jtag_interface to adapter_driver") the transports API are better
split and SWIM can be implemented as a separate set of API. This
would open the possibility to extend OpenOCD for other adapters
that provide SWIM, e.g. versaloon, or through SPI emulation [1].

Introduce a new set of files swim.[ch] to handle the SWIM API.
Beside the API that almost match the transport low-level data
communication (system_reset, read_mem, write_mem), add a further
API reconnect. Today, inside HLA STLink code, the reconnect is
implemented by hacking the HLA API state(). Please notice that
due to this hack the return type is incorrect; stlink_usb_state()
returns ERROR_OK in SWIM mode, while its return type is enum
target_state. Ignore the type mismatch and still call the HLA API
state in the new SWIM API reconnect. Further commit will fix it.

[1] http://kuku.eu.org/?projects/stm8spi/stm8spi

Change-Id: I52018e1e2200cbd41af8e5031f7b35dc761b61d6
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: http://openocd.zylin.com/5528
Tested-by: jenkins
src/jtag/Makefile.am
src/jtag/swim.c [new file with mode: 0644]
src/jtag/swim.h [new file with mode: 0644]
src/target/stm8.c

index a764863991a475bbbd63065138b587a57b56ddd1..b82914bcbf1d40f90bcfee5a5b979ca0932b1bf4 100644 (file)
@@ -56,6 +56,7 @@ endif
        %D%/interface.c \
        %D%/interfaces.c \
        %D%/tcl.c \
+       %D%/swim.c \
        %D%/commands.h \
        %D%/driver.h \
        %D%/interface.h \
@@ -65,6 +66,7 @@ endif
        %D%/minidriver/minidriver_imp.h \
        %D%/minidummy/jtag_minidriver.h \
        %D%/swd.h \
+       %D%/swim.h \
        %D%/tcl.h \
        $(JTAG_SRCS)
 
diff --git a/src/jtag/swim.c b/src/jtag/swim.c
new file mode 100644 (file)
index 0000000..965018c
--- /dev/null
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/*
+ * Copyright (C) 2020 by Antonio Borneo <borneo.antonio@gmail.com
+ *
+ * SWIM (Single Wire Interface Module) is a low-pin-count debug protocol
+ * used by STMicroelectronics MCU family STM8 and documented in UM470
+ * https://www.st.com/resource/en/user_manual/cd00173911.pdf
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "interface.h"
+#include "swim.h"
+#include "jtag/hla/hla_transport.h"
+#include "jtag/hla/hla_interface.h"
+#include "jtag/hla/hla_layout.h"
+
+extern struct adapter_driver *adapter_driver;
+
+int swim_system_reset(void)
+{
+       assert(adapter_driver->hla_if);
+
+       return adapter_driver->hla_if->layout->api->reset(adapter_driver->hla_if->handle);
+}
+
+int swim_read_mem(uint32_t addr, uint32_t size, uint32_t count,
+                                 uint8_t *buffer)
+{
+       assert(adapter_driver->hla_if);
+
+       return adapter_driver->hla_if->layout->api->read_mem(adapter_driver->hla_if->handle, 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);
+
+       return adapter_driver->hla_if->layout->api->write_mem(adapter_driver->hla_if->handle, addr, size, count, buffer);
+}
+
+int swim_reconnect(void)
+{
+       assert(adapter_driver->hla_if);
+
+       return adapter_driver->hla_if->layout->api->state(adapter_driver->hla_if->handle);
+}
diff --git a/src/jtag/swim.h b/src/jtag/swim.h
new file mode 100644 (file)
index 0000000..d0ae18e
--- /dev/null
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/*
+ * Copyright (C) 2020 by Antonio Borneo <borneo.antonio@gmail.com
+ */
+
+/**
+ * @file
+ * This file implements support for STMicroelectronics debug protocol SWIM
+ * (Single Wire Interface Module).
+ */
+
+#ifndef OPENOCD_JTAG_SWIM_H
+#define OPENOCD_JTAG_SWIM_H
+
+struct swim_driver {
+       /**
+        * Send SRST (system reset) command to target.
+        *
+        * @return ERROR_OK on success, else a fault code.
+        */
+       int (*srst)(void);
+
+       /**
+        * Read target memory through ROTF (read on-the-fly) command.
+        *
+        * @param addr Start address to read data from target memory.
+        * @param size Size in bytes of data units, 1, 2 or 4.
+        * @param count Number of units (size units, not bytes) to read.
+        * @param buffer Data buffer to receive data.
+        * @return ERROR_OK on success, else a fault code.
+        */
+       int (*read_mem)(uint32_t addr, uint32_t size, uint32_t count,
+                                       uint8_t *buffer);
+
+       /**
+        * Write target memory through WOTF (write on-the-fly) command.
+        *
+        * @param addr Start address to write data to target memory.
+        * @param size Size in bytes of data units, 1, 2 or 4.
+        * @param count Number of units (size units, not bytes) to write.
+        * @param buffer Data buffer to write.
+        * @return ERROR_OK on success, else a fault code.
+        */
+       int (*write_mem)(uint32_t addr, uint32_t size, uint32_t count,
+                                        const uint8_t *buffer);
+
+       /**
+        * Reconnect to the target.
+        * Should be reworked to be more generic and not linked to current
+        * implementation in stlink driver.
+        *
+        * @return ERROR_OK on success, else a fault code.
+        */
+       int (*reconnect)(void);
+};
+
+int swim_system_reset(void);
+int swim_read_mem(uint32_t addr, uint32_t size, uint32_t count,
+                                 uint8_t *buffer);
+int swim_write_mem(uint32_t addr, uint32_t size, uint32_t count,
+                                  const uint8_t *buffer);
+int swim_reconnect(void);
+
+#endif /* OPENOCD_JTAG_SWIM_H */
index 6b03bb5a4ecd187cf19bc8b3273bd4b25a3ee3ce..ad05b54f9b24bbc72a54af9e87938d607f771678 100644 (file)
@@ -27,9 +27,7 @@
 #include "hello.h"
 #include "jtag/interface.h"
 #include "jtag/jtag.h"
-#include "jtag/hla/hla_transport.h"
-#include "jtag/hla/hla_interface.h"
-#include "jtag/hla/hla_layout.h"
+#include "jtag/swim.h"
 #include "register.h"
 #include "breakpoints.h"
 #include "algorithm.h"
@@ -180,68 +178,31 @@ struct stm8_comparator {
        enum hw_break_type type;
 };
 
-static inline struct hl_interface_s *target_to_adapter(struct target *target)
-{
-       return target->tap->priv;
-}
-
 static int stm8_adapter_read_memory(struct target *target,
                uint32_t addr, int size, int count, void *buf)
 {
-       int ret;
-       struct hl_interface_s *adapter = target_to_adapter(target);
-
-       ret = adapter->layout->api->read_mem(adapter->handle,
-               addr, size, count, buf);
-       if (ret != ERROR_OK)
-               return ret;
-       return ERROR_OK;
+       return swim_read_mem(addr, size, count, buf);
 }
 
 static int stm8_adapter_write_memory(struct target *target,
                uint32_t addr, int size, int count, const void *buf)
 {
-       int ret;
-       struct hl_interface_s *adapter = target_to_adapter(target);
-
-       ret = adapter->layout->api->write_mem(adapter->handle,
-               addr, size, count, buf);
-       if (ret != ERROR_OK)
-               return ret;
-       return ERROR_OK;
+       return swim_write_mem(addr, size, count, buf);
 }
 
 static int stm8_write_u8(struct target *target,
                uint32_t addr, uint8_t val)
 {
-       int ret;
        uint8_t buf[1];
-       struct hl_interface_s *adapter = target_to_adapter(target);
 
        buf[0] = val;
-       ret =  adapter->layout->api->write_mem(adapter->handle, addr, 1, 1, buf);
-       if (ret != ERROR_OK)
-               return ret;
-       return ERROR_OK;
+       return swim_write_mem(addr, 1, 1, buf);
 }
 
 static int stm8_read_u8(struct target *target,
                uint32_t addr, uint8_t *val)
 {
-       int ret;
-       struct hl_interface_s *adapter = target_to_adapter(target);
-
-       ret =  adapter->layout->api->read_mem(adapter->handle, addr, 1, 1, val);
-       if (ret != ERROR_OK)
-               return ret;
-       return ERROR_OK;
-}
-
-static int stm8_set_speed(struct target *target, int speed)
-{
-       struct hl_interface_s *adapter = target_to_adapter(target);
-       adapter->layout->api->speed(adapter->handle, speed, 0);
-       return ERROR_OK;
+       return swim_read_mem(addr, 1, 1, val);
 }
 
 /*
@@ -924,7 +885,6 @@ static int stm8_halt(struct target *target)
 static int stm8_reset_assert(struct target *target)
 {
        int res = ERROR_OK;
-       struct hl_interface_s *adapter = target_to_adapter(target);
        struct stm8_common *stm8 = target_to_stm8(target);
        bool use_srst_fallback = true;
 
@@ -942,7 +902,7 @@ static int stm8_reset_assert(struct target *target)
 
        if (use_srst_fallback) {
                LOG_DEBUG("Hardware srst not supported, falling back to swim reset");
-               res = adapter->layout->api->reset(adapter->handle);
+               res = swim_system_reset();
                if (res != ERROR_OK)
                        return res;
        }
@@ -1696,7 +1656,7 @@ static int stm8_examine(struct target *target)
        uint8_t csr1, csr2;
        /* get pointers to arch-specific information */
        struct stm8_common *stm8 = target_to_stm8(target);
-       struct hl_interface_s *adapter = target_to_adapter(target);
+       enum reset_types jtag_reset_config = jtag_get_reset_config();
 
        if (!target_was_examined(target)) {
                if (!stm8->swim_configured) {
@@ -1710,20 +1670,23 @@ static int stm8_examine(struct target *target)
                        retval = stm8_write_u8(target, SWIM_CSR, SAFE_MASK + SWIM_DM + HS);
                        if (retval != ERROR_OK)
                                return retval;
-                       retval = stm8_set_speed(target, 1);
-                       if (retval == ERROR_OK)
-                               stm8->swim_configured = true;
+                       jtag_config_khz(1);
+                       stm8->swim_configured = true;
                        /*
                                Now is the time to deassert reset if connect_under_reset.
                                Releasing reset line will cause the option bytes to load.
                                The core will still be stalled.
                        */
-                       if (adapter->param.connect_under_reset)
-                               stm8_reset_deassert(target);
+                       if (jtag_reset_config & RESET_CNCT_UNDER_SRST) {
+                               if (jtag_reset_config & RESET_SRST_NO_GATING)
+                                       stm8_reset_deassert(target);
+                               else
+                                       LOG_WARNING("\'srst_nogate\' reset_config option is required");
+                       }
                } else {
                        LOG_INFO("trying to reconnect");
 
-                       retval = adapter->layout->api->state(adapter->handle);
+                       retval = swim_reconnect();
                        if (retval != ERROR_OK) {
                                LOG_ERROR("reconnect failed");
                                return ERROR_FAIL;

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)