adapter: run at default speed when clock speed not specified
[fw/openocd] / src / jtag / adapter.c
index 0320d295d2af658ba6afd0f9d6f4a863d3e1e66b..519505dc32466fd68b538fc79b4e9dea79fddaab 100644 (file)
@@ -36,12 +36,15 @@ enum adapter_clk_mode {
        CLOCK_MODE_RCLK
 };
 
+#define DEFAULT_CLOCK_SPEED_KHZ                100U
+
 /**
  * Adapter configuration
  */
 static struct {
        bool adapter_initialized;
        char *usb_location;
+       char *serial;
        enum adapter_clk_mode clock_mode;
        int speed_khz;
        int rclk_fallback_speed_khz;
@@ -69,6 +72,18 @@ int adapter_init(struct command_context *cmd_ctx)
        }
 
        int retval;
+
+       if (adapter_config.clock_mode == CLOCK_MODE_UNSELECTED) {
+               LOG_WARNING("An adapter speed is not selected in the init scripts."
+                       " OpenOCD will try to run the adapter at the low speed (%d kHz)",
+                       DEFAULT_CLOCK_SPEED_KHZ);
+               LOG_WARNING("To remove this warnings and achieve reasonable communication speed with the target,"
+                   " set \"adapter speed\" or \"jtag_rclk\" in the init scripts.");
+               retval = adapter_config_khz(DEFAULT_CLOCK_SPEED_KHZ);
+               if (retval != ERROR_OK)
+                       return ERROR_JTAG_INIT_FAILED;
+       }
+
        retval = adapter_driver->init();
        if (retval != ERROR_OK)
                return retval;
@@ -79,12 +94,6 @@ int adapter_init(struct command_context *cmd_ctx)
                return ERROR_OK;
        }
 
-       if (adapter_config.clock_mode == CLOCK_MODE_UNSELECTED) {
-               LOG_ERROR("An adapter speed is not selected in the init script."
-                       " Insert a call to \"adapter speed\" or \"jtag_rclk\" to proceed.");
-               return ERROR_JTAG_INIT_FAILED;
-       }
-
        int requested_khz = adapter_get_speed_khz();
        int actual_khz = requested_khz;
        int speed_var = 0;
@@ -120,6 +129,9 @@ int adapter_quit(void)
                        LOG_ERROR("failed: %d", result);
        }
 
+       free(adapter_config.serial);
+       free(adapter_config.usb_location);
+
        struct jtag_tap *t = jtag_all_taps();
        while (t) {
                struct jtag_tap *n = t->next_tap;
@@ -221,6 +233,11 @@ int adapter_get_speed_readable(int *khz)
        return adapter_driver->speed_div(speed_var, khz);
 }
 
+const char *adapter_get_required_serial(void)
+{
+       return adapter_config.serial;
+}
+
 /*
  * 1 char: bus
  * 2 * 7 chars: max 7 ports
@@ -365,8 +382,7 @@ COMMAND_HANDLER(handle_adapter_driver_command)
                        continue;
 
                if (adapter_drivers[i]->commands) {
-                       retval = register_commands(CMD_CTX, NULL,
-                                       adapter_drivers[i]->commands);
+                       retval = register_commands(CMD_CTX, NULL, adapter_drivers[i]->commands);
                        if (retval != ERROR_OK)
                                return retval;
                }
@@ -658,6 +674,16 @@ COMMAND_HANDLER(handle_adapter_speed_command)
        return retval;
 }
 
+COMMAND_HANDLER(handle_adapter_serial_command)
+{
+       if (CMD_ARGC != 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       free(adapter_config.serial);
+       adapter_config.serial = strdup(CMD_ARGV[0]);
+       return ERROR_OK;
+}
+
 COMMAND_HANDLER(handle_adapter_reset_de_assert)
 {
        enum values {
@@ -805,6 +831,13 @@ static const struct command_registration adapter_command_handlers[] = {
                        "With or without argument, display current setting.",
                .usage = "[khz]",
        },
+       {
+               .name = "serial",
+               .handler = handle_adapter_serial_command,
+               .mode = COMMAND_CONFIG,
+               .help = "Set the serial number of the adapter",
+               .usage = "serial_string",
+       },
        {
                .name = "list",
                .handler = handle_adapter_list_command,
@@ -886,7 +919,7 @@ static const struct command_registration interface_command_handlers[] = {
  * @todo Remove internal assumptions that all debug adapters use JTAG for
  * transport.  Various types and data structures are not named generically.
  */
-int interface_register_commands(struct command_context *ctx)
+int adapter_register_commands(struct command_context *ctx)
 {
        return register_commands(ctx, NULL, interface_command_handlers);
 }