help text: remove trailing space
[fw/openocd] / src / jtag / adapter.c
index acd434c440f58c79816f0d5c79b5de6096edff79..0dcb78fface9c6885918d0c7c3f9dfdd2e444902 100644 (file)
  *   GNU General Public License for more details.                          *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  ***************************************************************************/
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -36,6 +35,7 @@
 #include "interface.h"
 #include "interfaces.h"
 #include <transport/transport.h>
+#include <jtag/drivers/jtag_usb_common.h>
 
 #ifdef HAVE_STRINGS_H
 #include <strings.h>
  * Holds support for configuring debug adapters from TCl scripts.
  */
 
-extern struct jtag_interface *jtag_interface;
-const char *jtag_only[] = { "jtag", NULL };
+struct adapter_driver *adapter_driver;
+const char * const jtag_only[] = { "jtag", NULL };
 
-static int
-jim_adapter_name(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+static int jim_adapter_name(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
 {
        Jim_GetOptInfo goi;
        Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
@@ -62,45 +61,19 @@ jim_adapter_name(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
                Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)");
                return JIM_ERR;
        }
-       const char *name = jtag_interface ? jtag_interface->name : NULL;
+       const char *name = adapter_driver ? adapter_driver->name : NULL;
        Jim_SetResultString(goi.interp, name ? : "undefined", -1);
        return JIM_OK;
 }
 
-
-static int default_khz(int khz, int *jtag_speed)
-{
-       LOG_ERROR("Translation from khz to jtag_speed not implemented");
-       return ERROR_FAIL;
-}
-
-static int default_speed_div(int speed, int *khz)
-{
-       LOG_ERROR("Translation from jtag_speed to khz not implemented");
-       return ERROR_FAIL;
-}
-
-static int default_power_dropout(int *dropout)
-{
-       *dropout = 0; /* by default we can't detect power dropout */
-       return ERROR_OK;
-}
-
-static int default_srst_asserted(int *srst_asserted)
-{
-       *srst_asserted = 0; /* by default we can't detect srst asserted */
-       return ERROR_OK;
-}
-
-COMMAND_HANDLER(interface_transport_command)
+COMMAND_HANDLER(adapter_transports_command)
 {
        char **transports;
        int retval;
 
        retval = CALL_COMMAND_HANDLER(transport_list_parse, &transports);
-       if (retval != ERROR_OK) {
+       if (retval != ERROR_OK)
                return retval;
-       }
 
        retval = allow_transports(CMD_CTX, (const char **)transports);
 
@@ -112,28 +85,26 @@ COMMAND_HANDLER(interface_transport_command)
        return retval;
 }
 
-COMMAND_HANDLER(handle_interface_list_command)
+COMMAND_HANDLER(handle_adapter_list_command)
 {
-       if (strcmp(CMD_NAME, "interface_list") == 0 && CMD_ARGC > 0)
+       if (strcmp(CMD_NAME, "list") == 0 && CMD_ARGC > 0)
                return ERROR_COMMAND_SYNTAX_ERROR;
 
-       command_print(CMD_CTX, "The following debug interfaces are available:");
-       for (unsigned i = 0; NULL != jtag_interfaces[i]; i++)
-       {
-               const char *name = jtag_interfaces[i]->name;
-               command_print(CMD_CTX, "%u: %s", i + 1, name);
+       command_print(CMD, "The following debug adapters are available:");
+       for (unsigned i = 0; NULL != adapter_drivers[i]; i++) {
+               const char *name = adapter_drivers[i]->name;
+               command_print(CMD, "%u: %s", i + 1, name);
        }
 
        return ERROR_OK;
 }
 
-COMMAND_HANDLER(handle_interface_command)
+COMMAND_HANDLER(handle_adapter_driver_command)
 {
        int retval;
 
        /* check whether the interface is already configured */
-       if (jtag_interface)
-       {
+       if (adapter_driver) {
                LOG_WARNING("Interface already configured, ignoring");
                return ERROR_OK;
        }
@@ -142,44 +113,20 @@ COMMAND_HANDLER(handle_interface_command)
        if (CMD_ARGC != 1 || CMD_ARGV[0][0] == '\0')
                return ERROR_COMMAND_SYNTAX_ERROR;
 
-       for (unsigned i = 0; NULL != jtag_interfaces[i]; i++)
-       {
-               if (strcmp(CMD_ARGV[0], jtag_interfaces[i]->name) != 0)
+       for (unsigned i = 0; NULL != adapter_drivers[i]; i++) {
+               if (strcmp(CMD_ARGV[0], adapter_drivers[i]->name) != 0)
                        continue;
 
-               if (NULL != jtag_interfaces[i]->commands)
-               {
+               if (NULL != adapter_drivers[i]->commands) {
                        retval = register_commands(CMD_CTX, NULL,
-                                       jtag_interfaces[i]->commands);
+                                       adapter_drivers[i]->commands);
                        if (ERROR_OK != retval)
                                return retval;
                }
 
-               jtag_interface = jtag_interfaces[i];
-
-       /* LEGACY SUPPORT ... adapter drivers  must declare what
-        * transports they allow.  Until they all do so, assume
-        * the legacy drivers are JTAG-only
-        */
-       if (!jtag_interface->transports)
-               LOG_WARNING("Adapter driver '%s' did not declare "
-                       "which transports it allows; assuming "
-                       "legacy JTAG-only", jtag_interface->name);
-               retval = allow_transports(CMD_CTX, jtag_interface->transports
-                                               ? jtag_interface->transports : jtag_only);
-                       if (ERROR_OK != retval)
-                               return retval;
-
-               if (jtag_interface->khz == NULL)
-                       jtag_interface->khz = default_khz;
-               if (jtag_interface->speed_div == NULL)
-                       jtag_interface->speed_div = default_speed_div;
-               if (jtag_interface->power_dropout == NULL)
-                       jtag_interface->power_dropout = default_power_dropout;
-               if (jtag_interface->srst_asserted == NULL)
-                       jtag_interface->srst_asserted = default_srst_asserted;
+               adapter_driver = adapter_drivers[i];
 
-               return ERROR_OK;
+               return allow_transports(CMD_CTX, adapter_driver->transports);
        }
 
        /* no valid interface was found (i.e. the configuration option,
@@ -187,7 +134,7 @@ COMMAND_HANDLER(handle_interface_command)
         */
        LOG_ERROR("The specified debug interface was not found (%s)",
                                CMD_ARGV[0]);
-       CALL_COMMAND_HANDLER(handle_interface_list_command);
+       CALL_COMMAND_HANDLER(handle_adapter_list_command);
        return ERROR_JTAG_INVALID_INTERFACE;
 }
 
@@ -280,7 +227,7 @@ COMMAND_HANDLER(handle_reset_config_command)
                        goto next;
 
                /* srst_type (NOP without HAS_SRST) */
-               m |= RESET_SRST_PUSH_PULL;
+               m = RESET_SRST_PUSH_PULL;
                if (strcmp(*CMD_ARGV, "srst_push_pull") == 0)
                        tmp |= RESET_SRST_PUSH_PULL;
                else if (strcmp(*CMD_ARGV, "srst_open_drain") == 0)
@@ -295,6 +242,22 @@ COMMAND_HANDLER(handle_reset_config_command)
                if (m)
                        goto next;
 
+               /* connect_type - only valid when srst_nogate */
+               m = RESET_CNCT_UNDER_SRST;
+               if (strcmp(*CMD_ARGV, "connect_assert_srst") == 0)
+                       tmp |= RESET_CNCT_UNDER_SRST;
+               else if (strcmp(*CMD_ARGV, "connect_deassert_srst") == 0)
+                       /* connect normally - default */;
+               else
+                       m = 0;
+               if (mask & m) {
+                       LOG_ERROR("extra reset_config %s spec (%s)",
+                                       "connect_type", *CMD_ARGV);
+                       return ERROR_COMMAND_SYNTAX_ERROR;
+               }
+               if (m)
+                       goto next;
+
                /* caller provided nonsense; fail */
                LOG_ERROR("unknown reset_config flag (%s)", *CMD_ARGV);
                return ERROR_COMMAND_SYNTAX_ERROR;
@@ -317,42 +280,41 @@ next:
        } else
                new_cfg = jtag_get_reset_config();
 
-
        /*
         * Display the (now-)current reset mode
         */
-       char *modes[5];
+       char *modes[6];
 
        /* minimal JTAG has neither SRST nor TRST (so that's the default) */
        switch (new_cfg & (RESET_HAS_TRST | RESET_HAS_SRST)) {
-       case RESET_HAS_SRST:
-               modes[0] = "srst_only";
-               break;
-       case RESET_HAS_TRST:
-               modes[0] = "trst_only";
-               break;
-       case RESET_TRST_AND_SRST:
-               modes[0] = "trst_and_srst";
-               break;
-       default:
-               modes[0] = "none";
-               break;
+               case RESET_HAS_SRST:
+                       modes[0] = "srst_only";
+                       break;
+               case RESET_HAS_TRST:
+                       modes[0] = "trst_only";
+                       break;
+               case RESET_TRST_AND_SRST:
+                       modes[0] = "trst_and_srst";
+                       break;
+               default:
+                       modes[0] = "none";
+                       break;
        }
 
        /* normally SRST and TRST are decoupled; but bugs happen ... */
        switch (new_cfg & (RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST)) {
-       case RESET_SRST_PULLS_TRST:
-               modes[1] = "srst_pulls_trst";
-               break;
-       case RESET_TRST_PULLS_SRST:
-               modes[1] = "trst_pulls_srst";
-               break;
-       case RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST:
-               modes[1] = "combined";
-               break;
-       default:
-               modes[1] = "separate";
-               break;
+               case RESET_SRST_PULLS_TRST:
+                       modes[1] = "srst_pulls_trst";
+                       break;
+               case RESET_TRST_PULLS_SRST:
+                       modes[1] = "trst_pulls_srst";
+                       break;
+               case RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST:
+                       modes[1] = "combined";
+                       break;
+               default:
+                       modes[1] = "separate";
+                       break;
        }
 
        /* TRST-less connectors include Altera, Xilinx, and minimal JTAG */
@@ -375,58 +337,59 @@ next:
                        modes[4] = " srst_push_pull";
                else
                        modes[4] = " srst_open_drain";
+
+               if (new_cfg & RESET_CNCT_UNDER_SRST)
+                       modes[5] = " connect_assert_srst";
+               else
+                       modes[5] = " connect_deassert_srst";
        } else {
                modes[2] = "";
                modes[4] = "";
+               modes[5] = "";
        }
 
-       command_print(CMD_CTX, "%s %s%s%s%s",
+       command_print(CMD, "%s %s%s%s%s%s",
                        modes[0], modes[1],
-                       modes[2], modes[3], modes[4]);
+                       modes[2], modes[3], modes[4], modes[5]);
 
        return ERROR_OK;
 }
 
-COMMAND_HANDLER(handle_adapter_nsrst_delay_command)
+COMMAND_HANDLER(handle_adapter_srst_delay_command)
 {
        if (CMD_ARGC > 1)
                return ERROR_COMMAND_SYNTAX_ERROR;
-       if (CMD_ARGC == 1)
-       {
+       if (CMD_ARGC == 1) {
                unsigned delay;
                COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], delay);
 
                jtag_set_nsrst_delay(delay);
        }
-       command_print(CMD_CTX, "adapter_nsrst_delay: %u", jtag_get_nsrst_delay());
+       command_print(CMD, "adapter srst delay: %u", jtag_get_nsrst_delay());
        return ERROR_OK;
 }
 
-COMMAND_HANDLER(handle_adapter_nsrst_assert_width_command)
+COMMAND_HANDLER(handle_adapter_srst_pulse_width_command)
 {
        if (CMD_ARGC > 1)
                return ERROR_COMMAND_SYNTAX_ERROR;
-       if (CMD_ARGC == 1)
-       {
+       if (CMD_ARGC == 1) {
                unsigned width;
                COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], width);
 
                jtag_set_nsrst_assert_width(width);
        }
-       command_print(CMD_CTX, "adapter_nsrst_assert_width: %u", jtag_get_nsrst_assert_width());
+       command_print(CMD, "adapter srst pulse_width: %u", jtag_get_nsrst_assert_width());
        return ERROR_OK;
 }
 
-
-
-COMMAND_HANDLER(handle_adapter_khz_command)
+COMMAND_HANDLER(handle_adapter_speed_command)
 {
        if (CMD_ARGC > 1)
                return ERROR_COMMAND_SYNTAX_ERROR;
 
        int retval = ERROR_OK;
-       if (CMD_ARGC == 1)
-       {
+       if (CMD_ARGC == 1) {
                unsigned khz = 0;
                COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], khz);
 
@@ -441,64 +404,219 @@ COMMAND_HANDLER(handle_adapter_khz_command)
                return retval;
 
        if (cur_speed)
-               command_print(CMD_CTX, "%d kHz", cur_speed);
+               command_print(CMD, "adapter speed: %d kHz", cur_speed);
        else
-               command_print(CMD_CTX, "RCLK - adaptive");
+               command_print(CMD, "adapter speed: RCLK - adaptive");
 
        return retval;
 }
 
-static const struct command_registration interface_command_handlers[] = {
+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);
+}
+
+#ifdef HAVE_LIBUSB_GET_PORT_NUMBERS
+COMMAND_HANDLER(handle_usb_location_command)
+{
+       if (CMD_ARGC == 1)
+               jtag_usb_set_location(CMD_ARGV[0]);
+
+       command_print(CMD, "adapter usb location: %s", jtag_usb_get_location());
+
+       return ERROR_OK;
+}
+#endif /* HAVE_LIBUSB_GET_PORT_NUMBERS */
+
+static const struct command_registration adapter_usb_command_handlers[] = {
+#ifdef HAVE_LIBUSB_GET_PORT_NUMBERS
+       {
+               .name = "location",
+               .handler = &handle_usb_location_command,
+               .mode = COMMAND_CONFIG,
+               .help = "display or set the USB bus location of the USB device",
+               .usage = "[<bus>-port[.port]...]",
+       },
+#endif /* HAVE_LIBUSB_GET_PORT_NUMBERS */
+       COMMAND_REGISTRATION_DONE
+};
+
+static const struct command_registration adapter_srst_command_handlers[] = {
+       {
+               .name = "delay",
+               .handler = handle_adapter_srst_delay_command,
+               .mode = COMMAND_ANY,
+               .help = "delay after deasserting SRST in ms",
+               .usage = "[milliseconds]",
+       },
+       {
+               .name = "pulse_width",
+               .handler = handle_adapter_srst_pulse_width_command,
+               .mode = COMMAND_ANY,
+               .help = "SRST assertion pulse width in ms",
+               .usage = "[milliseconds]",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+static const struct command_registration adapter_command_handlers[] = {
+       {
+               .name = "driver",
+               .handler = handle_adapter_driver_command,
+               .mode = COMMAND_CONFIG,
+               .help = "Select a debug adapter driver",
+               .usage = "driver_name",
+       },
        {
-               .name = "adapter_khz",
-               .handler = handle_adapter_khz_command,
+               .name = "speed",
+               .handler = handle_adapter_speed_command,
                .mode = COMMAND_ANY,
                .help = "With an argument, change to the specified maximum "
                        "jtag speed.  For JTAG, 0 KHz signifies adaptive "
-                       " clocking. "
+                       "clocking. "
                        "With or without argument, display current setting.",
                .usage = "[khz]",
        },
        {
-               .name = "adapter_name",
+               .name = "list",
+               .handler = handle_adapter_list_command,
+               .mode = COMMAND_ANY,
+               .help = "List all built-in debug adapter drivers",
+               .usage = "",
+       },
+       {
+               .name = "name",
                .mode = COMMAND_ANY,
                .jim_handler = jim_adapter_name,
                .help = "Returns the name of the currently "
                        "selected adapter (driver)",
        },
        {
-               .name = "adapter_nsrst_delay",
-               .handler = handle_adapter_nsrst_delay_command,
+               .name = "srst",
                .mode = COMMAND_ANY,
-               .help = "delay after deasserting SRST in ms",
-               .usage = "[milliseconds]",
+               .help = "srst adapter command group",
+               .usage = "",
+               .chain = adapter_srst_command_handlers,
        },
        {
-               .name = "adapter_nsrst_assert_width",
-               .handler = handle_adapter_nsrst_assert_width_command,
+               .name = "transports",
+               .handler = adapter_transports_command,
+               .mode = COMMAND_CONFIG,
+               .help = "Declare transports the adapter supports.",
+               .usage = "transport ...",
+       },
+       {
+               .name = "usb",
                .mode = COMMAND_ANY,
-               .help = "delay after asserting SRST in ms",
-               .usage = "[milliseconds]",
+               .help = "usb adapter command group",
+               .usage = "",
+               .chain = adapter_usb_command_handlers,
        },
        {
-               .name = "interface",
-               .handler = handle_interface_command,
-               .mode = COMMAND_CONFIG,
-               .help = "Select a debug adapter interface (driver)",
-               .usage = "driver_name",
+               .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 = "interface_transports",
-               .handler = interface_transport_command,
-               .mode = COMMAND_CONFIG,
-               .help = "Declare transports the interface supports.",
-               .usage = "transport ... ",
+               .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
+};
+
+static const struct command_registration interface_command_handlers[] = {
        {
-               .name = "interface_list",
-               .handler = handle_interface_list_command,
+               .name = "adapter",
                .mode = COMMAND_ANY,
-               .help = "List all built-in debug adapter interfaces (drivers)",
+               .help = "adapter command group",
+               .usage = "",
+               .chain = adapter_command_handlers,
        },
        {
                .name = "reset_config",
@@ -509,7 +627,8 @@ static const struct command_registration interface_command_handlers[] = {
                        "[srst_pulls_trst|trst_pulls_srst|combined|separate] "
                        "[srst_gates_jtag|srst_nogate] "
                        "[trst_push_pull|trst_open_drain] "
-                       "[srst_push_pull|srst_open_drain]",
+                       "[srst_push_pull|srst_open_drain] "
+                       "[connect_deassert_srst|connect_assert_srst]",
        },
        COMMAND_REGISTRATION_DONE
 };