adapter: add command "adapter [de]assert srst|trst [[de]assert srst|trst]"
authorAntonio Borneo <borneo.antonio@gmail.com>
Thu, 10 Jan 2019 09:58:15 +0000 (10:58 +0100)
committerTomas Vanek <vanekt@fbl.cz>
Thu, 2 Jan 2020 21:24:30 +0000 (21:24 +0000)
Inspired from http://openocd.zylin.com/#/c/3720/1

Add commands to control the adapter's signals srst and trst.
Add macros for the flag's values assert/deassert to make clear what
they mean and to propose a uniform set of values across the code.

Change-Id: Ia8b13f4ded892942916cad7bda49540a896e7218
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Signed-off-by: Tomas Vanek <vanekt@fbl.cz>
Reviewed-on: http://openocd.zylin.com/5277
Tested-by: jenkins
src/jtag/adapter.c
src/jtag/core.c
src/jtag/hla/hla_interface.c
src/jtag/hla/hla_interface.h
src/jtag/interface.h
src/jtag/jtag.h

index 29a9613381a854dc79e63e8b36874d5ebe5a8deb..d23f79ec41f36228e18700764a17e6288c6976cb 100644 (file)
@@ -411,6 +411,92 @@ COMMAND_HANDLER(handle_adapter_khz_command)
        return retval;
 }
 
+COMMAND_HANDLER(handle_adapter_reset_de_assert)
+{
+       enum values {
+               VALUE_UNDEFINED = -1,
+               VALUE_DEASSERT  = 0,
+               VALUE_ASSERT    = 1,
+       };
+       enum values value;
+       enum values srst = VALUE_UNDEFINED;
+       enum values trst = VALUE_UNDEFINED;
+       enum reset_types jtag_reset_config = jtag_get_reset_config();
+       char *signal;
+
+       if (CMD_ARGC == 0) {
+               if (transport_is_jtag()) {
+                       if (jtag_reset_config & RESET_HAS_TRST)
+                               signal = jtag_get_trst() ? "asserted" : "deasserted";
+                       else
+                               signal = "not present";
+                       command_print(CMD, "trst %s", signal);
+               }
+
+               if (jtag_reset_config & RESET_HAS_SRST)
+                       signal = jtag_get_srst() ? "asserted" : "deasserted";
+               else
+                       signal = "not present";
+               command_print(CMD, "srst %s", signal);
+
+               return ERROR_OK;
+       }
+
+       if (CMD_ARGC != 1 && CMD_ARGC != 3)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       value = (strcmp(CMD_NAME, "assert") == 0) ? VALUE_ASSERT : VALUE_DEASSERT;
+       if (strcmp(CMD_ARGV[0], "srst") == 0)
+               srst = value;
+       else if (strcmp(CMD_ARGV[0], "trst") == 0)
+               trst = value;
+       else
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       if (CMD_ARGC == 3) {
+               if (strcmp(CMD_ARGV[1], "assert") == 0)
+                       value = VALUE_ASSERT;
+               else if (strcmp(CMD_ARGV[1], "deassert") == 0)
+                       value = VALUE_DEASSERT;
+               else
+                       return ERROR_COMMAND_SYNTAX_ERROR;
+
+               if (strcmp(CMD_ARGV[2], "srst") == 0 && srst == VALUE_UNDEFINED)
+                       srst = value;
+               else if (strcmp(CMD_ARGV[2], "trst") == 0 && trst == VALUE_UNDEFINED)
+                       trst = value;
+               else
+                       return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       if (trst == VALUE_UNDEFINED) {
+               if (transport_is_jtag())
+                       trst = jtag_get_trst() ? VALUE_ASSERT : VALUE_DEASSERT;
+               else
+                       trst = VALUE_DEASSERT; /* unused, safe value */
+       }
+
+       if (srst == VALUE_UNDEFINED) {
+               if (jtag_reset_config & RESET_HAS_SRST)
+                       srst = jtag_get_srst() ? VALUE_ASSERT : VALUE_DEASSERT;
+               else
+                       srst = VALUE_DEASSERT; /* unused, safe value */
+       }
+
+       if (trst == VALUE_ASSERT && !transport_is_jtag()) {
+               LOG_ERROR("transport has no trst signal");
+               return ERROR_FAIL;
+       }
+
+       if (srst == VALUE_ASSERT && !(jtag_reset_config & RESET_HAS_SRST)) {
+               LOG_ERROR("adapter has no srst signal");
+               return ERROR_FAIL;
+       }
+
+       return adapter_resets((trst == VALUE_DEASSERT) ? TRST_DEASSERT : TRST_ASSERT,
+                                                 (srst == VALUE_DEASSERT) ? SRST_DEASSERT : SRST_ASSERT);
+}
+
 #ifndef HAVE_JTAG_MINIDRIVER_H
 #ifdef HAVE_LIBUSB_GET_PORT_NUMBERS
 COMMAND_HANDLER(handle_usb_location_command)
@@ -448,6 +534,20 @@ static const struct command_registration adapter_command_handlers[] = {
                .chain = adapter_usb_command_handlers,
        },
 #endif /* MINIDRIVER */
+       {
+               .name = "assert",
+               .handler = handle_adapter_reset_de_assert,
+               .mode = COMMAND_EXEC,
+               .help = "Controls SRST and TRST lines.",
+               .usage = "|deassert [srst|trst [assert|deassert srst|trst]]",
+       },
+       {
+               .name = "deassert",
+               .handler = handle_adapter_reset_de_assert,
+               .mode = COMMAND_EXEC,
+               .help = "Controls SRST and TRST lines.",
+               .usage = "|assert [srst|trst [deassert|assert srst|trst]]",
+       },
        COMMAND_REGISTRATION_DONE
 };
 
index a498a8cf48f25e0334824e526e569ad9cd8e6264..871b4d2bd07b83fe6010c3d63d5a787747ee945c 100644 (file)
@@ -35,6 +35,8 @@
 #include "interface.h"
 #include <transport/transport.h>
 #include <helper/jep106.h>
+#include <jtag/hla/hla_transport.h>
+#include <jtag/hla/hla_interface.h>
 
 #ifdef HAVE_STRINGS_H
 #include <strings.h>
@@ -1888,6 +1890,57 @@ bool transport_is_jtag(void)
        return get_current_transport() == &jtag_transport;
 }
 
+int adapter_resets(int trst, int srst)
+{
+       if (get_current_transport() == NULL) {
+               LOG_ERROR("transport is not selected");
+               return ERROR_FAIL;
+       }
+
+       if (transport_is_jtag()) {
+               if (srst == SRST_ASSERT && !(jtag_reset_config & RESET_HAS_SRST)) {
+                       LOG_ERROR("adapter has no srst signal");
+                       return ERROR_FAIL;
+               }
+
+               /* adapters without trst signal will eventually use tlr sequence */
+               jtag_add_reset(trst, srst);
+               return ERROR_OK;
+       } else if (transport_is_swd()) {
+               if (trst == TRST_ASSERT) {
+                       LOG_ERROR("transport swd has no trst signal");
+                       return ERROR_FAIL;
+               }
+
+               if (srst == SRST_ASSERT && !(jtag_reset_config & RESET_HAS_SRST)) {
+                       LOG_ERROR("adapter has no srst signal");
+                       return ERROR_FAIL;
+               }
+               swd_add_reset(srst);
+               return ERROR_OK;
+       } else if (transport_is_hla()) {
+               if (trst == TRST_ASSERT) {
+                       LOG_ERROR("transport %s has no trst signal",
+                               get_current_transport()->name);
+                       return ERROR_FAIL;
+               }
+
+               if (srst == SRST_ASSERT && !(jtag_reset_config & RESET_HAS_SRST)) {
+                       LOG_ERROR("adapter has no srst signal");
+                       return ERROR_FAIL;
+               }
+               return hl_interface_reset(srst);
+       }
+
+       if (trst == TRST_DEASSERT && srst == SRST_DEASSERT)
+               return ERROR_OK;
+
+       LOG_ERROR("reset is not supported on transport %s",
+               get_current_transport()->name);
+
+       return ERROR_FAIL;
+}
+
 void adapter_assert_reset(void)
 {
        if (transport_is_jtag()) {
index 7d9dea05e36f2ae44723b1ae5aeb62e75b89d30d..b50cb9c0fd31767b6efba334856c49c7fba97e29 100644 (file)
@@ -148,6 +148,21 @@ int hl_interface_init_reset(void)
        return ERROR_OK;
 }
 
+/* FIXME: hla abuses of jtag_add_reset() to track srst status and for timings */
+int hl_interface_reset(int srst)
+{
+       int result;
+
+       if (srst == 1) {
+               jtag_add_reset(0, 1);
+               result = hl_if.layout->api->assert_srst(hl_if.handle, 0);
+       } else {
+               result = hl_if.layout->api->assert_srst(hl_if.handle, 1);
+               jtag_add_reset(0, 0);
+       }
+       return result;
+}
+
 static int hl_interface_khz(int khz, int *jtag_speed)
 {
        if (hl_if.layout->api->speed == NULL)
index 262025e9818b7e59e3bc46bd133f19d80cfd49bf..84b0098b63619c81d13b18911c2d1d459160c73b 100644 (file)
@@ -67,4 +67,13 @@ int hl_interface_init_target(struct target *t);
 int hl_interface_init_reset(void);
 int hl_interface_override_target(const char **targetname);
 
+#if BUILD_HLADAPTER == 1
+int hl_interface_reset(int srst);
+#else
+static inline int hl_interface_reset(int srst)
+{
+       return ERROR_OK;
+}
+#endif
+
 #endif /* OPENOCD_JTAG_HLA_HLA_INTERFACE_H */
index ba3dea6d703d24b3fe6c34c4ea209bc92acec30d..410eef98079ac64187f59d4893afcc8e906c8882 100644 (file)
@@ -326,6 +326,7 @@ struct jtag_interface {
 
 extern const char * const jtag_only[];
 
+int adapter_resets(int assert_trst, int assert_srst);
 void adapter_assert_reset(void);
 void adapter_deassert_reset(void);
 int adapter_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol,
index c93243c4782f818c5ab26d1942edc7edf3876f74..ff178315832a97fed8c3e60588817200b5c55715 100644 (file)
@@ -76,6 +76,14 @@ typedef enum tap_state {
 #endif
 } tap_state_t;
 
+/**
+ * Defines arguments for reset functions
+ */
+#define SRST_DEASSERT   0
+#define SRST_ASSERT     1
+#define TRST_DEASSERT   0
+#define TRST_ASSERT     1
+
 /**
  * Function tap_state_name
  * Returns a string suitable for display representing the JTAG tap_state