]> git.sur5r.net Git - openocd/commitdiff
Jonas Horberg [jhorberg@sauer-danfoss.com]
authorntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Tue, 18 Aug 2009 12:14:01 +0000 (12:14 +0000)
committerntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Tue, 18 Aug 2009 12:14:01 +0000 (12:14 +0000)
Change jtag_rclk behaviour so it can be called before the interface init function

git-svn-id: svn://svn.berlios.de/openocd/trunk@2590 b42882b7-edfa-0310-969c-e2dbd0fdcd60

src/helper/startup.tcl
src/jtag/core.c
src/jtag/jtag.h
src/jtag/tcl.c

index 9fb537dc1037d464010b5e084d958366fd9c2663..14b209205a5162b527f13cba8ac63abed60671a4 100644 (file)
@@ -134,15 +134,6 @@ proc ocd_gdb_restart {target_num} {
        reset halt
 }
 
-# If RCLK is not supported, use fallback_speed_khz
-proc jtag_rclk {fallback_speed_khz} {
-       if {[catch {jtag_khz 0}]!=0} {
-               jtag_khz $fallback_speed_khz
-       }
-}
-
-add_help_text jtag_rclk "fallback_speed_khz - set JTAG speed to RCLK or use fallback speed"
-
 proc ocd_process_reset { MODE } {
 
        # If this target must be halted...
index 4e6e5b59fec612ea6ae44dc218e80395765d30f4..222bff13ac15a10f8875c462923f9623a5dfc033 100644 (file)
@@ -101,8 +101,9 @@ static jtag_event_callback_t *jtag_event_callbacks;
 
 /* speed in kHz*/
 static int speed_khz = 0;
-/* flag if the kHz speed was defined */
-static bool hasKHz = false;
+/* speed to fallback to when RCLK is requested but not supported */
+static int rclk_fallback_speed_khz = 0;
+static enum {CLOCK_MODE_SPEED, CLOCK_MODE_KHZ, CLOCK_MODE_RCLK} clock_mode;
 static int jtag_speed = 0;
 
 static struct jtag_interface_s *jtag = NULL;
@@ -1140,16 +1141,34 @@ int jtag_interface_init(struct command_context_s *cmd_ctx)
                LOG_ERROR("JTAG interface has to be specified, see \"interface\" command");
                return ERROR_JTAG_INVALID_INTERFACE;
        }
-       if (hasKHz)
-       {
-               jtag_interface->khz(jtag_get_speed_khz(), &jtag_speed);
-               hasKHz = false;
-       }
 
+       jtag = jtag_interface;
        if (jtag_interface->init() != ERROR_OK)
+       {
+               jtag = NULL;
                return ERROR_JTAG_INIT_FAILED;
+       }
+
+       int requested_khz = jtag_get_speed_khz();
+       int actual_khz = requested_khz;
+       int retval = jtag_get_speed_readable(&actual_khz);
+       if (ERROR_OK != retval)
+               return retval;
+
+       if (actual_khz)
+       {
+               if ((CLOCK_MODE_RCLK == clock_mode)
+                       || ((CLOCK_MODE_KHZ == clock_mode) && !requested_khz))
+               {
+                       LOG_INFO("RCLK (adaptive clock speed) not supported - fallback to %d kHz"
+                               , actual_khz);
+               }
+               else
+                       LOG_INFO("clock speed %d kHz", actual_khz);
+       }
+       else
+               LOG_INFO("RCLK (adaptive clock speed)");
 
-       jtag = jtag_interface;
        return ERROR_OK;
 }
 
@@ -1255,20 +1274,15 @@ int jtag_init(struct command_context_s *cmd_ctx)
        return jtag_init_reset(cmd_ctx);
 }
 
-void jtag_set_speed_khz(unsigned khz)
-{
-       speed_khz = khz;
-}
 unsigned jtag_get_speed_khz(void)
 {
        return speed_khz;
 }
-int jtag_config_khz(unsigned khz)
-{
-       LOG_DEBUG("handle jtag khz");
-       jtag_set_speed_khz(khz);
 
-       int cur_speed = 0;
+static int jtag_khz_to_speed(unsigned khz, int* speed)
+{
+       LOG_DEBUG("convert khz to interface specific speed value");
+       speed_khz = khz;
        if (jtag != NULL)
        {
                LOG_DEBUG("have interface set up");
@@ -1276,33 +1290,84 @@ int jtag_config_khz(unsigned khz)
                int retval = jtag->khz(jtag_get_speed_khz(), &speed_div1);
                if (ERROR_OK != retval)
                {
-                       jtag_set_speed_khz(0);
                        return retval;
                }
-               cur_speed = speed_div1;
+               *speed = speed_div1;
        }
-       return jtag_set_speed(cur_speed);
+       return ERROR_OK;
 }
 
-int jtag_get_speed(void)
+static int jtag_rclk_to_speed(unsigned fallback_speed_khz, int* speed)
 {
-       return jtag_speed;
+       int retval = jtag_khz_to_speed(0, speed);
+       if ((ERROR_OK != retval) && fallback_speed_khz)
+       {
+               LOG_DEBUG("trying fallback speed...");
+               retval = jtag_khz_to_speed(fallback_speed_khz, speed);
+       }
+       return retval;
 }
 
-int jtag_set_speed(int speed)
+static int jtag_set_speed(int speed)
 {
        jtag_speed = speed;
        /* this command can be called during CONFIG,
         * in which case jtag isn't initialized */
-       hasKHz = !jtag;
        return jtag ? jtag->speed(speed) : ERROR_OK;
 }
 
-int jtag_get_speed_readable(int *speed)
+int jtag_config_speed(int speed)
+{
+       LOG_DEBUG("handle jtag speed");
+       clock_mode = CLOCK_MODE_SPEED;
+       return jtag_set_speed(speed);
+}
+
+int jtag_config_khz(unsigned khz)
+{
+       LOG_DEBUG("handle jtag khz");
+       clock_mode = CLOCK_MODE_KHZ;
+       int speed = 0;
+       int retval = jtag_khz_to_speed(khz, &speed);
+       return (ERROR_OK != retval) ? retval : jtag_set_speed(speed);
+}
+
+int jtag_config_rclk(unsigned fallback_speed_khz)
 {
-       return jtag ? jtag->speed_div(jtag_get_speed(), speed) : ERROR_OK;
+       LOG_DEBUG("handle jtag rclk");
+       clock_mode = CLOCK_MODE_RCLK;
+       rclk_fallback_speed_khz = fallback_speed_khz;
+       int speed = 0;
+       int retval = jtag_rclk_to_speed(fallback_speed_khz, &speed);
+       return (ERROR_OK != retval) ? retval : jtag_set_speed(speed);
 }
 
+int jtag_get_speed(void)
+{
+       int speed;
+       switch(clock_mode)
+       {
+               case CLOCK_MODE_SPEED:
+                       speed = jtag_speed;
+                       break;
+               case CLOCK_MODE_KHZ:
+                       jtag_khz_to_speed(jtag_get_speed_khz(), &speed);
+                       break;
+               case CLOCK_MODE_RCLK:
+                       jtag_rclk_to_speed(rclk_fallback_speed_khz, &speed);
+                       break;
+               default:
+                       LOG_ERROR("BUG: unknown jtag clock mode");
+                       speed = 0;
+                       break;
+       }
+       return speed;
+}
+
+int jtag_get_speed_readable(int *khz)
+{
+       return jtag ? jtag->speed_div(jtag_get_speed(), khz) : ERROR_OK;
+}
 
 void jtag_set_verify(bool enable)
 {
index 3c6c5ce2827ec48667d457d54d92da9f9470823d..37a90b193177338ce2d4a67a3ee6955602bc5c76 100644 (file)
@@ -252,13 +252,16 @@ int jtag_get_speed_readable(int *speed);
  * @returns ERROR_OK during configuration or on success, or an error
  *   code returned from the interface @c speed callback.
  */
-int jtag_set_speed(int speed);
+int jtag_config_speed(int speed);
 
 
 /// Attempt to configure the interface for the specified KHz.
 int jtag_config_khz(unsigned khz);
-/// Set the clock speed of the JTAG interface in KHz.
-void jtag_set_speed_khz(unsigned speed);
+/**
+ * Attempt to enable RTCK/RCLK. If that fails, fallback to the
+ * specified frequency.
+ */
+int jtag_config_rclk(unsigned fallback_speed_khz);
 /// Retreives the clock speed of the JTAG interface in KHz.
 unsigned jtag_get_speed_khz(void);
 
index c81f161740c4195943b837f29d2068dfdb2ae37b..ff16a56647831ce837d6b8272998b58734aa77a3 100644 (file)
@@ -55,6 +55,7 @@ static int handle_interface_list_command(struct command_context_s *cmd_ctx,
 static int handle_interface_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 static int handle_jtag_speed_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 static int handle_jtag_khz_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int handle_jtag_rclk_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 static int handle_jtag_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 static int handle_reset_config_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 static int handle_jtag_nsrst_delay_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
@@ -577,6 +578,8 @@ int jtag_register_commands(struct command_context_s *cmd_ctx)
        register_command(cmd_ctx, NULL, "jtag_khz", handle_jtag_khz_command,
                COMMAND_ANY, "set maximum jtag speed (if supported); "
                "parameter is maximum khz, or 0 for adaptive clocking (RTCK).");
+       register_command(cmd_ctx, NULL, "jtag_rclk", handle_jtag_rclk_command,
+               COMMAND_ANY, "fallback_speed_khz - set JTAG speed to RCLK or use fallback speed");
        register_command(cmd_ctx, NULL, "jtag_device", handle_jtag_device_command,
                COMMAND_CONFIG, "(DEPRECATED) jtag_device <ir_length> <ir_expected> <ir_mask>");
        register_command(cmd_ctx, NULL, "reset_config", handle_reset_config_command,
@@ -955,7 +958,7 @@ static int handle_jtag_speed_command(struct command_context_s *cmd_ctx, char *cm
                int retval = parse_uint(args[0], &cur_speed);
                if (ERROR_OK != retval)
                        return retval;
-               retval = jtag_set_speed(cur_speed);
+               retval = jtag_config_speed(cur_speed);
 
        }
        command_print(cmd_ctx, "jtag_speed: %d", jtag_get_speed());
@@ -993,6 +996,36 @@ static int handle_jtag_khz_command(struct command_context_s *cmd_ctx, char *cmd,
        return retval;
 }
 
+static int handle_jtag_rclk_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       if (argc > 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       int retval = ERROR_OK;
+       if (argc == 1)
+       {
+               unsigned khz = 0;
+               int retval = parse_uint(args[0], &khz);
+               if (ERROR_OK != retval)
+                       return retval;
+               retval = jtag_config_rclk(khz);
+               if (ERROR_OK != retval)
+                       return retval;
+       }
+
+       int cur_khz = jtag_get_speed_khz();
+       retval = jtag_get_speed_readable(&cur_khz);
+       if (ERROR_OK != retval)
+               return retval;
+
+       if (cur_khz)
+               command_print(cmd_ctx, "RCLK not supported - fallback to %d kHz", cur_khz);
+       else
+               command_print(cmd_ctx, "RCLK - adaptive");
+
+       return retval;
+}
+
 static int handle_jtag_reset_command(struct command_context_s *cmd_ctx,
                char *cmd, char **args, int argc)
 {