static struct jtag_interface *jtag = NULL;
+
+const struct swd_driver *swd = NULL;
+
/* configuration */
struct jtag_interface *jtag_interface = NULL;
}
/* 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();
int jtag_unregister_event_callback(jtag_event_handler_t callback, void *priv)
{
- struct jtag_event_callback **callbacks_p;
- struct jtag_event_callback **next;
+ struct jtag_event_callback **p = &jtag_event_callbacks, *temp;
if (callback == NULL)
{
return ERROR_INVALID_ARGUMENTS;
}
- for (callbacks_p = &jtag_event_callbacks;
- *callbacks_p != NULL;
- callbacks_p = next)
+ while (*p)
{
- next = &((*callbacks_p)->next);
-
- if ((*callbacks_p)->priv != priv)
- continue;
-
- if ((*callbacks_p)->callback == callback)
+ if (((*p)->priv != priv) || ((*p)->callback != callback))
{
- free(*callbacks_p);
- *callbacks_p = *next;
+ p = &(*p)->next;
+ continue;
}
+
+ temp = *p;
+ *p = (*p)->next;
+ free(temp);
}
return ERROR_OK;
retval = jtag_execute_queue();
if (retval != ERROR_OK) {
- LOG_ERROR("TRST/SRST error %d", retval);
+ LOG_ERROR("TRST/SRST error");
return;
}
}
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,
int requested_khz = jtag_get_speed_khz();
int actual_khz = requested_khz;
- int retval = jtag_get_speed_readable(&actual_khz);
+ int jtag_speed_var;
+ int retval = jtag_get_speed(&jtag_speed_var);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = jtag_get_speed_readable(&actual_khz);
if (ERROR_OK != retval)
- LOG_INFO("adapter-specific clock speed value %d", jtag_get_speed());
+ LOG_INFO("adapter-specific clock speed value %d", jtag_speed_var);
else if (actual_khz)
{
/* Adaptive clocking -- JTAG-specific */
return (ERROR_OK != retval) ? retval : jtag_set_speed(speed);
}
-int jtag_get_speed(void)
+int jtag_get_speed(int *speed)
{
- int speed;
switch(clock_mode)
{
case CLOCK_MODE_SPEED:
- speed = jtag_speed;
+ *speed = jtag_speed;
break;
case CLOCK_MODE_KHZ:
- adapter_khz_to_speed(jtag_get_speed_khz(), &speed);
+ adapter_khz_to_speed(jtag_get_speed_khz(), speed);
break;
case CLOCK_MODE_RCLK:
- jtag_rclk_to_speed(rclk_fallback_speed_khz, &speed);
+ jtag_rclk_to_speed(rclk_fallback_speed_khz, speed);
break;
default:
LOG_ERROR("BUG: unknown jtag clock mode");
- speed = 0;
- break;
+ return ERROR_FAIL;
}
- return speed;
+ return ERROR_OK;
}
int jtag_get_speed_readable(int *khz)
{
- return jtag ? jtag->speed_div(jtag_get_speed(), khz) : ERROR_OK;
+ int jtag_speed_var;
+ int retval = jtag_get_speed(&jtag_speed_var);
+ if (retval != ERROR_OK)
+ return retval;
+ return jtag ? jtag->speed_div(jtag_speed_var, khz) : ERROR_OK;
}
void jtag_set_verify(bool enable)