adapter speed: require init script setting and centralize activation from drivers...
[fw/openocd] / src / jtag / core.c
index 6e923bd47a3a3c95ecdab59cc0af19f86803f690..0a9d72a846953f52a0361c60f426d47540dd645c 100644 (file)
@@ -124,7 +124,7 @@ static struct jtag_event_callback *jtag_event_callbacks;
 static int speed_khz = 0;
 /* 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 enum {CLOCK_MODE_UNSELECTED, CLOCK_MODE_KHZ, CLOCK_MODE_RCLK} clock_mode;
 static int jtag_speed = 0;
 
 static struct jtag_interface *jtag = NULL;
@@ -216,7 +216,7 @@ void jtag_tap_add(struct jtag_tap *t)
 }
 
 /* returns a pointer to the n-th device in the scan chain */
-static inline struct jtag_tap *jtag_tap_by_position(unsigned n)
+struct jtag_tap *jtag_tap_by_position(unsigned n)
 {
        struct jtag_tap *t = jtag_all_taps();
 
@@ -695,7 +695,7 @@ void jtag_add_reset(int req_tlr_or_trst, int req_srst)
                        retval = jtag_execute_queue();
 
                if (retval != ERROR_OK) {
-                       LOG_ERROR("TRST/SRST error %d", retval);
+                       LOG_ERROR("TRST/SRST error");
                        return;
                }
        }
@@ -871,9 +871,16 @@ static int jtag_reset_callback(enum jtag_event event, void *priv)
        return ERROR_OK;
 }
 
+/* sleep at least us microseconds. When we sleep more than 1000ms we
+ * do an alive sleep, i.e. keep GDB alive. Note that we could starve
+ * GDB if we slept for <1000ms many times.
+ */
 void jtag_sleep(uint32_t us)
 {
-       alive_sleep(us/1000);
+       if (us < 1000)
+               usleep(us);
+       else
+               alive_sleep((us+999)/1000);
 }
 
 /* Maximum number of enabled JTAG devices we expect in the scan chain,
@@ -1361,12 +1368,13 @@ int adapter_init(struct command_context *cmd_ctx)
                return ERROR_JTAG_INVALID_INTERFACE;
        }
 
-       jtag = jtag_interface;
-       if (jtag_interface->init() != ERROR_OK)
+       int retval;
+       retval = jtag_interface->init();
+       if (retval != ERROR_OK)
        {
-               jtag = NULL;
-               return ERROR_JTAG_INIT_FAILED;
+               return retval;
        }
+       jtag = jtag_interface;
 
        /* LEGACY SUPPORT ... adapter drivers  must declare what
         * transports they allow.  Until they all do so, assume
@@ -1376,15 +1384,25 @@ int adapter_init(struct command_context *cmd_ctx)
                LOG_ERROR("Adapter driver '%s' did not declare "
                        "which transports it allows; assuming "
                        "JTAG-only", jtag->name);
-               int retval = allow_transports(cmd_ctx, jtag_only);
+               retval = allow_transports(cmd_ctx, jtag_only);
                if (retval != ERROR_OK)
                        return retval;
        }
 
+       if (CLOCK_MODE_UNSELECTED == clock_mode)
+       {
+               LOG_ERROR("An adapter speed is not selected in the init script."
+                       " Insert a call to adapter_khz or jtag_rclk to proceed.");
+               return ERROR_JTAG_INIT_FAILED;
+       }
+
        int requested_khz = jtag_get_speed_khz();
        int actual_khz = requested_khz;
        int jtag_speed_var;
-       int retval = jtag_get_speed(&jtag_speed_var);
+       retval = jtag_get_speed(&jtag_speed_var);
+       if (retval != ERROR_OK)
+               return retval;
+       retval = jtag->speed(jtag_speed_var);
        if (retval != ERROR_OK)
                return retval;
        retval = jtag_get_speed_readable(&actual_khz);
@@ -1639,9 +1657,6 @@ int jtag_get_speed(int *speed)
 {
        switch(clock_mode)
        {
-               case CLOCK_MODE_SPEED:
-                       *speed = jtag_speed;
-                       break;
                case CLOCK_MODE_KHZ:
                        adapter_khz_to_speed(jtag_get_speed_khz(), speed);
                        break;