}
}
-void swd_add_reset(int req_srst)
+static int adapter_system_reset(int req_srst)
{
+ int retval;
+
if (req_srst) {
if (!(jtag_reset_config & RESET_HAS_SRST)) {
LOG_ERROR("BUG: can't assert SRST");
- jtag_set_error(ERROR_FAIL);
- return;
+ return ERROR_FAIL;
}
req_srst = 1;
}
/* Maybe change SRST signal state */
if (jtag_srst != req_srst) {
+ retval = jtag->reset(0, req_srst);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("SRST error");
+ return ERROR_FAIL;
+ }
+ jtag_srst = req_srst;
+
+ if (req_srst) {
+ LOG_DEBUG("SRST line asserted");
+ if (adapter_nsrst_assert_width)
+ jtag_sleep(adapter_nsrst_assert_width * 1000);
+ } else {
+ LOG_DEBUG("SRST line released");
+ if (adapter_nsrst_delay)
+ jtag_sleep(adapter_nsrst_delay * 1000);
+ }
+ }
+
+ return ERROR_OK;
+}
+
+static void legacy_jtag_add_reset(int req_tlr_or_trst, int req_srst)
+{
+ int trst_with_tlr = 0;
+ int new_srst = 0;
+ int new_trst = 0;
+
+ /* Without SRST, we must use target-specific JTAG operations
+ * on each target; callers should not be requesting SRST when
+ * that signal doesn't exist.
+ *
+ * RESET_SRST_PULLS_TRST is a board or chip level quirk, which
+ * can kick in even if the JTAG adapter can't drive TRST.
+ */
+ if (req_srst) {
+ if (!(jtag_reset_config & RESET_HAS_SRST)) {
+ LOG_ERROR("BUG: can't assert SRST");
+ jtag_set_error(ERROR_FAIL);
+ return;
+ }
+ if ((jtag_reset_config & RESET_SRST_PULLS_TRST) != 0
+ && !req_tlr_or_trst) {
+ LOG_ERROR("BUG: can't assert only SRST");
+ jtag_set_error(ERROR_FAIL);
+ return;
+ }
+ new_srst = 1;
+ }
+
+ /* JTAG reset (entry to TAP_RESET state) can always be achieved
+ * using TCK and TMS; that may go through a TAP_{IR,DR}UPDATE
+ * state first. TRST accelerates it, and bypasses those states.
+ *
+ * RESET_TRST_PULLS_SRST is a board or chip level quirk, which
+ * can kick in even if the JTAG adapter can't drive SRST.
+ */
+ if (req_tlr_or_trst) {
+ if (!(jtag_reset_config & RESET_HAS_TRST))
+ trst_with_tlr = 1;
+ else if ((jtag_reset_config & RESET_TRST_PULLS_SRST) != 0
+ && !req_srst)
+ trst_with_tlr = 1;
+ else
+ new_trst = 1;
+ }
+
+ /* Maybe change TRST and/or SRST signal state */
+ if (jtag_srst != new_srst || jtag_trst != new_trst) {
int retval;
- retval = interface_jtag_add_reset(0, req_srst);
+ retval = interface_jtag_add_reset(new_trst, new_srst);
if (retval != ERROR_OK)
jtag_set_error(retval);
else
LOG_ERROR("TRST/SRST error");
return;
}
+ }
- /* SRST resets everything hooked up to that signal */
- jtag_srst = req_srst;
+ /* SRST resets everything hooked up to that signal */
+ if (jtag_srst != new_srst) {
+ jtag_srst = new_srst;
if (jtag_srst) {
LOG_DEBUG("SRST line asserted");
if (adapter_nsrst_assert_width)
if (adapter_nsrst_delay)
jtag_add_sleep(adapter_nsrst_delay * 1000);
}
+ }
- retval = jtag_execute_queue();
- if (retval != ERROR_OK) {
- LOG_ERROR("SRST timings error");
- return;
+ /* Maybe enter the JTAG TAP_RESET state ...
+ * - using only TMS, TCK, and the JTAG state machine
+ * - or else more directly, using TRST
+ *
+ * TAP_RESET should be invisible to non-debug parts of the system.
+ */
+ if (trst_with_tlr) {
+ LOG_DEBUG("JTAG reset with TLR instead of TRST");
+ jtag_add_tlr();
+
+ } else if (jtag_trst != new_trst) {
+ jtag_trst = new_trst;
+ if (jtag_trst) {
+ LOG_DEBUG("TRST line asserted");
+ tap_set_state(TAP_RESET);
+ if (jtag_ntrst_assert_width)
+ jtag_add_sleep(jtag_ntrst_assert_width * 1000);
+ } else {
+ LOG_DEBUG("TRST line released");
+ if (jtag_ntrst_delay)
+ jtag_add_sleep(jtag_ntrst_delay * 1000);
+
+ /* We just asserted nTRST, so we're now in TAP_RESET.
+ * Inform possible listeners about this, now that
+ * JTAG instructions and data can be shifted. This
+ * sequence must match jtag_add_tlr().
+ */
+ jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
+ jtag_notify_event(JTAG_TRST_ASSERTED);
}
}
}
+/* FIXME: name is misleading; we do not plan to "add" reset into jtag queue */
void jtag_add_reset(int req_tlr_or_trst, int req_srst)
{
+ int retval;
int trst_with_tlr = 0;
int new_srst = 0;
int new_trst = 0;
+ if (!jtag->reset) {
+ legacy_jtag_add_reset(req_tlr_or_trst, req_srst);
+ return;
+ }
+
/* Without SRST, we must use target-specific JTAG operations
* on each target; callers should not be requesting SRST when
* that signal doesn't exist.
/* Maybe change TRST and/or SRST signal state */
if (jtag_srst != new_srst || jtag_trst != new_trst) {
- int retval;
-
- retval = interface_jtag_add_reset(new_trst, new_srst);
- if (retval != ERROR_OK)
- jtag_set_error(retval);
- else
- retval = jtag_execute_queue();
+ /* guarantee jtag queue empty before changing reset status */
+ jtag_execute_queue();
+ retval = jtag->reset(new_trst, new_srst);
if (retval != ERROR_OK) {
+ jtag_set_error(retval);
LOG_ERROR("TRST/SRST error");
return;
}
int swd_init_reset(struct command_context *cmd_ctx)
{
- int retval = adapter_init(cmd_ctx);
+ int retval, retval1;
+
+ retval = adapter_init(cmd_ctx);
if (retval != ERROR_OK)
return retval;
LOG_DEBUG("Initializing with hard SRST reset");
if (jtag_reset_config & RESET_HAS_SRST)
- swd_add_reset(1);
- swd_add_reset(0);
- retval = jtag_execute_queue();
- return retval;
+ retval = adapter_system_reset(1);
+ retval1 = adapter_system_reset(0);
+
+ return (retval == ERROR_OK) ? retval1 : retval;
}
int jtag_init_reset(struct command_context *cmd_ctx)
LOG_ERROR("adapter has no srst signal");
return ERROR_FAIL;
}
- swd_add_reset(srst);
+ adapter_system_reset(srst);
return ERROR_OK;
} else if (transport_is_hla()) {
if (trst == TRST_ASSERT) {
else
jtag_add_reset(0, 1);
} else if (transport_is_swd())
- swd_add_reset(1);
+ adapter_system_reset(1);
else if (get_current_transport() != NULL)
LOG_ERROR("reset is not supported on %s",
get_current_transport()->name);
if (transport_is_jtag())
jtag_add_reset(0, 0);
else if (transport_is_swd())
- swd_add_reset(0);
+ adapter_system_reset(0);
else if (get_current_transport() != NULL)
LOG_ERROR("reset is not supported on %s",
get_current_transport()->name);
static bb_value_t bcm2835gpio_read(void);
static int bcm2835gpio_write(int tck, int tms, int tdi);
-static int bcm2835gpio_reset(int trst, int srst);
static int bcm2835_swdio_read(void);
static void bcm2835_swdio_drive(bool is_output);
static struct bitbang_interface bcm2835gpio_bitbang = {
.read = bcm2835gpio_read,
.write = bcm2835gpio_write,
- .reset = bcm2835gpio_reset,
.swdio_read = bcm2835_swdio_read,
.swdio_drive = bcm2835_swdio_drive,
.blink = NULL
.commands = bcm2835gpio_command_handlers,
.init = bcm2835gpio_init,
.quit = bcm2835gpio_quit,
+ .reset = bcm2835gpio_reset,
};
static bool bcm2835gpio_jtag_mode_possible(void)
static int buspirate_execute_queue(void);
static int buspirate_init(void);
static int buspirate_quit(void);
+static int buspirate_reset(int trst, int srst);
static void buspirate_end_state(tap_state_t state);
static void buspirate_state_move(void);
struct scan_command *command);
static void buspirate_tap_make_space(int scan, int bits);
-static void buspirate_reset(int trst, int srst);
static void buspirate_set_feature(int, char, char);
static void buspirate_set_mode(int, char);
static void buspirate_set_speed(int, char);
buffer, scan_size, cmd->cmd.scan);
break;
- case JTAG_RESET:
- LOG_DEBUG_IO("reset trst: %i srst %i",
- cmd->cmd.reset->trst, cmd->cmd.reset->srst);
-
- /* flush buffers, so we can reset */
- buspirate_tap_execute();
-
- if (cmd->cmd.reset->trst == 1)
- tap_set_state(TAP_RESET);
- buspirate_reset(cmd->cmd.reset->trst,
- cmd->cmd.reset->srst);
- break;
case JTAG_SLEEP:
LOG_DEBUG_IO("sleep %i", cmd->cmd.sleep->us);
buspirate_tap_execute();
.transports = buspirate_transports,
.swd = &buspirate_swd,
.init = buspirate_init,
- .quit = buspirate_quit
+ .quit = buspirate_quit,
+ .reset = buspirate_reset,
};
/*************** jtag execute commands **********************/
/*************** wrapper functions *********************/
/* (1) assert or (0) deassert reset lines */
-static void buspirate_reset(int trst, int srst)
+static int buspirate_reset(int trst, int srst)
{
LOG_DEBUG("trst: %i, srst: %i", trst, srst);
buspirate_set_feature(buspirate_fd, FEATURE_SRST, ACTION_DISABLE);
else
buspirate_set_feature(buspirate_fd, FEATURE_SRST, ACTION_ENABLE);
+
+ return ERROR_OK;
}
static void buspirate_set_feature(int fd, char feat, char action)
return ERROR_OK;
}
-static void cmsis_dap_execute_reset(struct jtag_command *cmd)
+static int cmsis_dap_reset(int trst, int srst)
{
/* Set both TRST and SRST even if they're not enabled as
* there's no way to tristate them */
output_pins = 0;
- if (!cmd->cmd.reset->srst)
+ if (!srst)
output_pins |= SWJ_PIN_SRST;
- if (!cmd->cmd.reset->trst)
+ if (!trst)
output_pins |= SWJ_PIN_TRST;
int retval = cmsis_dap_cmd_DAP_SWJ_Pins(output_pins,
SWJ_PIN_TRST | SWJ_PIN_SRST, 0, NULL);
if (retval != ERROR_OK)
LOG_ERROR("CMSIS-DAP: Interface reset failed");
+ return retval;
}
static void cmsis_dap_execute_sleep(struct jtag_command *cmd)
static void cmsis_dap_execute_command(struct jtag_command *cmd)
{
switch (cmd->type) {
- case JTAG_RESET:
- cmsis_dap_flush();
- cmsis_dap_execute_reset(cmd);
- break;
case JTAG_SLEEP:
cmsis_dap_flush();
cmsis_dap_execute_sleep(cmd);
.khz = cmsis_dap_khz,
.init = cmsis_dap_init,
.quit = cmsis_dap_quit,
+ .reset = cmsis_dap_reset,
};
tap_state_name(tap_get_end_state()));
}
-static void ftdi_execute_reset(struct jtag_command *cmd)
+static int ftdi_reset(int trst, int srst)
{
- LOG_DEBUG_IO("reset trst: %i srst %i",
- cmd->cmd.reset->trst, cmd->cmd.reset->srst);
-
- if (cmd->cmd.reset->trst == 1
- || (cmd->cmd.reset->srst
- && (jtag_get_reset_config() & RESET_SRST_PULLS_TRST)))
- tap_set_state(TAP_RESET);
-
- struct signal *trst = find_signal_by_name("nTRST");
- if (cmd->cmd.reset->trst == 1) {
- if (trst)
- ftdi_set_signal(trst, '0');
+ struct signal *sig_ntrst = find_signal_by_name("nTRST");
+ struct signal *sig_nsrst = find_signal_by_name("nSRST");
+
+ LOG_DEBUG_IO("reset trst: %i srst %i", trst, srst);
+
+ if (trst == 1) {
+ if (sig_ntrst)
+ ftdi_set_signal(sig_ntrst, '0');
else
LOG_ERROR("Can't assert TRST: nTRST signal is not defined");
- } else if (trst && jtag_get_reset_config() & RESET_HAS_TRST &&
- cmd->cmd.reset->trst == 0) {
+ } else if (sig_ntrst && jtag_get_reset_config() & RESET_HAS_TRST &&
+ trst == 0) {
if (jtag_get_reset_config() & RESET_TRST_OPEN_DRAIN)
- ftdi_set_signal(trst, 'z');
+ ftdi_set_signal(sig_ntrst, 'z');
else
- ftdi_set_signal(trst, '1');
+ ftdi_set_signal(sig_ntrst, '1');
}
- struct signal *srst = find_signal_by_name("nSRST");
- if (cmd->cmd.reset->srst == 1) {
- if (srst)
- ftdi_set_signal(srst, '0');
+ if (srst == 1) {
+ if (sig_nsrst)
+ ftdi_set_signal(sig_nsrst, '0');
else
LOG_ERROR("Can't assert SRST: nSRST signal is not defined");
- } else if (srst && jtag_get_reset_config() & RESET_HAS_SRST &&
- cmd->cmd.reset->srst == 0) {
+ } else if (sig_nsrst && jtag_get_reset_config() & RESET_HAS_SRST &&
+ srst == 0) {
if (jtag_get_reset_config() & RESET_SRST_PUSH_PULL)
- ftdi_set_signal(srst, '1');
+ ftdi_set_signal(sig_nsrst, '1');
else
- ftdi_set_signal(srst, 'z');
+ ftdi_set_signal(sig_nsrst, 'z');
}
- LOG_DEBUG_IO("trst: %i, srst: %i",
- cmd->cmd.reset->trst, cmd->cmd.reset->srst);
+ LOG_DEBUG_IO("trst: %i, srst: %i", trst, srst);
+ return ERROR_OK;
}
static void ftdi_execute_sleep(struct jtag_command *cmd)
static void ftdi_execute_command(struct jtag_command *cmd)
{
switch (cmd->type) {
- case JTAG_RESET:
- ftdi_execute_reset(cmd);
- break;
case JTAG_RUNTEST:
ftdi_execute_runtest(cmd);
break;
.init = ftdi_initialize,
.quit = ftdi_quit,
+ .reset = ftdi_reset,
.speed = ftdi_speed,
.speed_div = ftdi_speed_div,
.khz = ftdi_khz,
static bb_value_t imx_gpio_read(void);
static int imx_gpio_write(int tck, int tms, int tdi);
-static int imx_gpio_reset(int trst, int srst);
static int imx_gpio_swdio_read(void);
static void imx_gpio_swdio_drive(bool is_output);
static struct bitbang_interface imx_gpio_bitbang = {
.read = imx_gpio_read,
.write = imx_gpio_write,
- .reset = imx_gpio_reset,
.swdio_read = imx_gpio_swdio_read,
.swdio_drive = imx_gpio_swdio_drive,
.blink = NULL
.commands = imx_gpio_command_handlers,
.init = imx_gpio_init,
.quit = imx_gpio_quit,
+ .reset = imx_gpio_reset,
};
static bool imx_gpio_jtag_mode_possible(void)
static void jlink_stableclocks(int num_cycles);
static void jlink_runtest(int num_cycles);
static void jlink_reset(int trst, int srst);
+static int jlink_reset_safe(int trst, int srst);
static int jlink_swd_run_queue(void);
static void jlink_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data, uint32_t ap_delay_clk);
static int jlink_swd_switch_seq(enum swd_special_seq seq);
tap_state_name(tap_get_end_state()));
}
-static void jlink_execute_reset(struct jtag_command *cmd)
-{
- LOG_DEBUG_IO("reset trst: %i srst %i", cmd->cmd.reset->trst,
- cmd->cmd.reset->srst);
-
- jlink_flush();
- jlink_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
- jlink_flush();
-}
-
static void jlink_execute_sleep(struct jtag_command *cmd)
{
LOG_DEBUG_IO("sleep %" PRIi32 "", cmd->cmd.sleep->us);
case JTAG_SCAN:
jlink_execute_scan(cmd);
break;
- case JTAG_RESET:
- jlink_execute_reset(cmd);
- break;
case JTAG_SLEEP:
jlink_execute_sleep(cmd);
break;
jaylink_jtag_set_trst(devh);
}
+static int jlink_reset_safe(int trst, int srst)
+{
+ jlink_flush();
+ jlink_reset(trst, srst);
+ return jlink_flush();
+}
+
COMMAND_HANDLER(jlink_usb_command)
{
int tmp;
.khz = &jlink_khz,
.init = &jlink_init,
.quit = &jlink_quit,
+ .reset = &jlink_reset_safe,
.config_trace = &config_trace,
.poll_trace = &poll_trace,
};
/*************** jtag lowlevel functions ********************/
-static void kitprog_execute_reset(struct jtag_command *cmd)
+static int kitprog_reset(int trst, int srst)
{
int retval = ERROR_OK;
- if (cmd->cmd.reset->srst == 1) {
+ if (trst == 1) {
+ LOG_ERROR("KitProg: Interface has no TRST");
+ return ERROR_FAIL;
+ }
+
+ if (srst == 1) {
retval = kitprog_reset_target();
/* Since the previous command also disables SWCLK output, we need to send an
* SWD bus reset command to re-enable it. For some reason, running
if (retval != ERROR_OK)
LOG_ERROR("KitProg: Interface reset failed");
+ return retval;
}
static void kitprog_execute_sleep(struct jtag_command *cmd)
static void kitprog_execute_command(struct jtag_command *cmd)
{
switch (cmd->type) {
- case JTAG_RESET:
- kitprog_execute_reset(cmd);
- break;
case JTAG_SLEEP:
kitprog_execute_sleep(cmd);
break;
.swd = &kitprog_swd,
.execute_queue = kitprog_execute_queue,
.init = kitprog_init,
- .quit = kitprog_quit
+ .quit = kitprog_quit,
+ .reset = kitprog_reset,
};
.commands = sysfsgpio_command_handlers,
.init = sysfsgpio_init,
.quit = sysfsgpio_quit,
+ .reset = sysfsgpio_reset,
};
static struct bitbang_interface sysfsgpio_bitbang = {
.read = sysfsgpio_read,
.write = sysfsgpio_write,
- .reset = sysfsgpio_reset,
.swdio_read = sysfsgpio_swdio_read,
.swdio_drive = sysfsgpio_swdio_drive,
.blink = 0
static void vsllink_stableclocks(int num_cycles, int tms);
static void vsllink_scan(bool ir_scan, enum scan_type type,
uint8_t *buffer, int scan_size, struct scan_command *command);
-static void vsllink_reset(int trst, int srst);
+static int vsllink_reset(int trst, int srst);
/* VSLLink tap buffer functions */
static void vsllink_tap_append_step(int tms, int tdi);
cmd->cmd.scan);
break;
- case JTAG_RESET:
- LOG_DEBUG_IO("reset trst: %i srst %i",
- cmd->cmd.reset->trst,
- cmd->cmd.reset->srst);
-
- vsllink_tap_execute();
-
- if (cmd->cmd.reset->trst == 1)
- tap_set_state(TAP_RESET);
-
- vsllink_reset(cmd->cmd.reset->trst,
- cmd->cmd.reset->srst);
- break;
-
case JTAG_SLEEP:
LOG_DEBUG_IO("sleep %i", cmd->cmd.sleep->us);
vsllink_tap_execute();
vsllink_state_move();
}
-static void vsllink_reset(int trst, int srst)
+static int vsllink_reset(int trst, int srst)
{
LOG_DEBUG("trst: %i, srst: %i", trst, srst);
versaloon_interface.adaptors.gpio.out(0, GPIO_TRST, 0);
}
- versaloon_interface.adaptors.peripheral_commit();
+ return versaloon_interface.adaptors.peripheral_commit();
}
COMMAND_HANDLER(vsllink_handle_usb_vid_command)
.init = vsllink_init,
.quit = vsllink_quit,
+ .reset = vsllink_reset,
.khz = vsllink_khz,
.speed = vsllink_speed,
.speed_div = vsllink_speed_div,
xds110.txn_result_count = 0;
}
-static void xds110_execute_reset(struct jtag_command *cmd)
+static int xds110_reset(int trst, int srst)
{
- char trst;
- char srst;
+ uint8_t value;
+ bool success;
+ int retval = ERROR_OK;
- if (cmd->cmd.reset->trst != -1) {
- if (cmd->cmd.reset->trst == 0) {
+ if (trst != -1) {
+ if (trst == 0) {
/* Deassert nTRST (active low) */
- trst = 1;
+ value = 1;
} else {
/* Assert nTRST (active low) */
- trst = 0;
+ value = 0;
}
- (void)xds_set_trst(trst);
+ success = xds_set_trst(value);
+ if (!success)
+ retval = ERROR_FAIL;
}
- if (cmd->cmd.reset->srst != -1) {
- if (cmd->cmd.reset->srst == 0) {
+ if (srst != -1) {
+ if (srst == 0) {
/* Deassert nSRST (active low) */
- srst = 1;
+ value = 1;
} else {
/* Assert nSRST (active low) */
- srst = 0;
+ value = 0;
}
- (void)xds_set_srst(srst);
+ success = xds_set_srst(value);
+ if (!success)
+ retval = ERROR_FAIL;
/* Toggle TCK to trigger HIB on CC13x/CC26x devices */
- (void)xds_cycle_tck(60000);
+ success = xds_cycle_tck(60000);
+ if (!success)
+ retval = ERROR_FAIL;
}
+
+ return retval;
}
static void xds110_execute_sleep(struct jtag_command *cmd)
static void xds110_execute_command(struct jtag_command *cmd)
{
switch (cmd->type) {
- case JTAG_RESET:
- xds110_flush();
- xds110_execute_reset(cmd);
- break;
case JTAG_SLEEP:
xds110_flush();
xds110_execute_sleep(cmd);
.khz = xds110_khz,
.init = xds110_init,
.quit = xds110_quit,
+ .reset = xds110_reset,
};
*/
int (*quit)(void);
+ /**
+ * Control (assert/deassert) the signals SRST and TRST on the interface.
+ * This function is optional.
+ * Adapters that don't support resets can either not define this function
+ * or return an error code.
+ * Adapters that don't support one of the two reset should ignore the
+ * request to assert the missing signal and eventually log an error.
+ *
+ * @param srst 1 to assert SRST, 0 to deassert SRST.
+ * @param trst 1 to assert TRST, 0 to deassert TRST.
+ * @returns ERROR_OK on success, or an error code on failure.
+ */
+ int (*reset)(int srst, int trst);
+
/**
* Returns JTAG maxium speed for KHz. 0 = RTCK. The function returns
* a failure if it can't support the KHz/RTCK.
};
int swd_init_reset(struct command_context *cmd_ctx);
-void swd_add_reset(int req_srst);
#endif /* OPENOCD_JTAG_SWD_H */
if (jtag_reset_config & RESET_CNCT_UNDER_SRST) {
if (jtag_reset_config & RESET_SRST_NO_GATING)
- swd_add_reset(1);
+ adapter_assert_reset();
else
LOG_WARNING("\'srst_nogate\' reset_config option is required");
}