diff --git a/src/jtag/core.c b/src/jtag/core.c index 871b4d2bd..97caeb18a 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -613,53 +613,42 @@ void jtag_add_clocks(int num_cycles) } } -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) { - int retval; - - retval = interface_jtag_add_reset(0, req_srst); - if (retval != ERROR_OK) - jtag_set_error(retval); - else - retval = jtag_execute_queue(); - + retval = jtag->reset(0, req_srst); if (retval != ERROR_OK) { - LOG_ERROR("TRST/SRST error"); - return; + LOG_ERROR("SRST error"); + return ERROR_FAIL; } - - /* SRST resets everything hooked up to that signal */ jtag_srst = req_srst; - if (jtag_srst) { + + if (req_srst) { LOG_DEBUG("SRST line asserted"); if (adapter_nsrst_assert_width) - jtag_add_sleep(adapter_nsrst_assert_width * 1000); + jtag_sleep(adapter_nsrst_assert_width * 1000); } else { LOG_DEBUG("SRST line released"); 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; + jtag_sleep(adapter_nsrst_delay * 1000); } } + + return ERROR_OK; } -void jtag_add_reset(int req_tlr_or_trst, int req_srst) +static void legacy_jtag_add_reset(int req_tlr_or_trst, int req_srst) { int trst_with_tlr = 0; int new_srst = 0; @@ -767,6 +756,118 @@ void jtag_add_reset(int req_tlr_or_trst, int req_srst) } } +/* 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. + * + * 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) { + /* 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; + } + } + + /* 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) + jtag_add_sleep(adapter_nsrst_assert_width * 1000); + } else { + LOG_DEBUG("SRST line released"); + if (adapter_nsrst_delay) + jtag_add_sleep(adapter_nsrst_delay * 1000); + } + } + + /* 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); + } + } +} + void jtag_add_sleep(uint32_t us) { /** @todo Here, keep_alive() appears to be a layering violation!!! */ @@ -1557,17 +1658,19 @@ int adapter_quit(void) 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) @@ -1916,7 +2019,7 @@ int adapter_resets(int trst, int srst) 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) { @@ -1949,7 +2052,7 @@ void adapter_assert_reset(void) 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); @@ -1962,7 +2065,7 @@ void adapter_deassert_reset(void) 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); diff --git a/src/jtag/drivers/bcm2835gpio.c b/src/jtag/drivers/bcm2835gpio.c index 36e10b6da..60316f17d 100644 --- a/src/jtag/drivers/bcm2835gpio.c +++ b/src/jtag/drivers/bcm2835gpio.c @@ -51,7 +51,6 @@ static volatile uint32_t *pio_base; 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); @@ -62,7 +61,6 @@ static int bcm2835gpio_quit(void); 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 @@ -419,6 +417,7 @@ struct jtag_interface bcm2835gpio_interface = { .commands = bcm2835gpio_command_handlers, .init = bcm2835gpio_init, .quit = bcm2835gpio_quit, + .reset = bcm2835gpio_reset, }; static bool bcm2835gpio_jtag_mode_possible(void) diff --git a/src/jtag/drivers/buspirate.c b/src/jtag/drivers/buspirate.c index 872896ba3..23d1547a9 100644 --- a/src/jtag/drivers/buspirate.c +++ b/src/jtag/drivers/buspirate.c @@ -34,6 +34,7 @@ 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); @@ -133,7 +134,6 @@ static void buspirate_tap_append_scan(int length, uint8_t *buffer, 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); @@ -213,18 +213,6 @@ static int buspirate_execute_queue(void) 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(); @@ -555,7 +543,8 @@ struct jtag_interface buspirate_interface = { .transports = buspirate_transports, .swd = &buspirate_swd, .init = buspirate_init, - .quit = buspirate_quit + .quit = buspirate_quit, + .reset = buspirate_reset, }; /*************** jtag execute commands **********************/ @@ -860,7 +849,7 @@ static void buspirate_tap_append_scan(int length, uint8_t *buffer, /*************** 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); @@ -873,6 +862,8 @@ static void buspirate_reset(int trst, int 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) diff --git a/src/jtag/drivers/cmsis_dap_usb.c b/src/jtag/drivers/cmsis_dap_usb.c index d52d698a4..c54b70c7d 100644 --- a/src/jtag/drivers/cmsis_dap_usb.c +++ b/src/jtag/drivers/cmsis_dap_usb.c @@ -1126,21 +1126,22 @@ static int cmsis_dap_quit(void) 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) @@ -1581,10 +1582,6 @@ static void cmsis_dap_execute_tms(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); @@ -1802,4 +1799,5 @@ struct jtag_interface cmsis_dap_interface = { .khz = cmsis_dap_khz, .init = cmsis_dap_init, .quit = cmsis_dap_quit, + .reset = cmsis_dap_reset, }; diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c index 5cd44a9d1..e645e9fae 100644 --- a/src/jtag/drivers/ftdi.c +++ b/src/jtag/drivers/ftdi.c @@ -517,46 +517,41 @@ static void ftdi_execute_scan(struct jtag_command *cmd) 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); + struct signal *sig_ntrst = find_signal_by_name("nTRST"); + struct signal *sig_nsrst = find_signal_by_name("nSRST"); - if (cmd->cmd.reset->trst == 1 - || (cmd->cmd.reset->srst - && (jtag_get_reset_config() & RESET_SRST_PULLS_TRST))) - tap_set_state(TAP_RESET); + LOG_DEBUG_IO("reset trst: %i srst %i", trst, srst); - struct signal *trst = find_signal_by_name("nTRST"); - if (cmd->cmd.reset->trst == 1) { - if (trst) - ftdi_set_signal(trst, '0'); + 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) @@ -597,9 +592,6 @@ static void ftdi_execute_stableclocks(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; @@ -1248,6 +1240,7 @@ struct jtag_interface ftdi_interface = { .init = ftdi_initialize, .quit = ftdi_quit, + .reset = ftdi_reset, .speed = ftdi_speed, .speed_div = ftdi_speed_div, .khz = ftdi_khz, diff --git a/src/jtag/drivers/imx_gpio.c b/src/jtag/drivers/imx_gpio.c index 4923dab39..d677e8a7e 100644 --- a/src/jtag/drivers/imx_gpio.c +++ b/src/jtag/drivers/imx_gpio.c @@ -84,7 +84,6 @@ static inline bool gpio_level(int g) 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); @@ -95,7 +94,6 @@ static int imx_gpio_quit(void); 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 @@ -441,6 +439,7 @@ struct jtag_interface imx_gpio_interface = { .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) diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c index d2a871225..402ff9917 100644 --- a/src/jtag/drivers/jlink.c +++ b/src/jtag/drivers/jlink.c @@ -94,6 +94,7 @@ static void jlink_path_move(int num_states, tap_state_t *path); 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); @@ -251,16 +252,6 @@ static void jlink_execute_scan(struct jtag_command *cmd) 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); @@ -286,9 +277,6 @@ static int jlink_execute_command(struct jtag_command *cmd) case JTAG_SCAN: jlink_execute_scan(cmd); break; - case JTAG_RESET: - jlink_execute_reset(cmd); - break; case JTAG_SLEEP: jlink_execute_sleep(cmd); break; @@ -956,6 +944,13 @@ static void jlink_reset(int trst, int srst) 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; @@ -2283,6 +2278,7 @@ struct jtag_interface jlink_interface = { .khz = &jlink_khz, .init = &jlink_init, .quit = &jlink_quit, + .reset = &jlink_reset_safe, .config_trace = &config_trace, .poll_trace = &poll_trace, }; diff --git a/src/jtag/drivers/kitprog.c b/src/jtag/drivers/kitprog.c index e3ad84d30..dcca8a0e8 100644 --- a/src/jtag/drivers/kitprog.c +++ b/src/jtag/drivers/kitprog.c @@ -819,11 +819,16 @@ static void kitprog_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data) /*************** 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 @@ -836,6 +841,7 @@ static void kitprog_execute_reset(struct jtag_command *cmd) if (retval != ERROR_OK) LOG_ERROR("KitProg: Interface reset failed"); + return retval; } static void kitprog_execute_sleep(struct jtag_command *cmd) @@ -846,9 +852,6 @@ 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; @@ -968,5 +971,6 @@ struct jtag_interface kitprog_interface = { .swd = &kitprog_swd, .execute_queue = kitprog_execute_queue, .init = kitprog_init, - .quit = kitprog_quit + .quit = kitprog_quit, + .reset = kitprog_reset, }; diff --git a/src/jtag/drivers/sysfsgpio.c b/src/jtag/drivers/sysfsgpio.c index c6ffa3205..706300005 100644 --- a/src/jtag/drivers/sysfsgpio.c +++ b/src/jtag/drivers/sysfsgpio.c @@ -560,12 +560,12 @@ struct jtag_interface sysfsgpio_interface = { .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 diff --git a/src/jtag/drivers/vsllink.c b/src/jtag/drivers/vsllink.c index 4907ef0e2..5dd1bca40 100644 --- a/src/jtag/drivers/vsllink.c +++ b/src/jtag/drivers/vsllink.c @@ -59,7 +59,7 @@ static void vsllink_runtest(int num_cycles); 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); @@ -164,20 +164,6 @@ static int vsllink_execute_queue(void) 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(); @@ -478,7 +464,7 @@ static void vsllink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, 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); @@ -494,7 +480,7 @@ static void vsllink_reset(int trst, int 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) @@ -971,6 +957,7 @@ struct jtag_interface vsllink_interface = { .init = vsllink_init, .quit = vsllink_quit, + .reset = vsllink_reset, .khz = vsllink_khz, .speed = vsllink_speed, .speed_div = vsllink_speed_div, diff --git a/src/jtag/drivers/xds110.c b/src/jtag/drivers/xds110.c index f25023ba7..f0899246b 100644 --- a/src/jtag/drivers/xds110.c +++ b/src/jtag/drivers/xds110.c @@ -1592,35 +1592,44 @@ static void xds110_flush(void) 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) @@ -1788,10 +1797,6 @@ static void xds110_queue_stableclocks(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); @@ -2045,4 +2050,5 @@ struct jtag_interface xds110_interface = { .khz = xds110_khz, .init = xds110_init, .quit = xds110_quit, + .reset = xds110_reset, }; diff --git a/src/jtag/interface.h b/src/jtag/interface.h index 410eef980..6e4237afc 100644 --- a/src/jtag/interface.h +++ b/src/jtag/interface.h @@ -246,6 +246,20 @@ struct jtag_interface { */ 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. diff --git a/src/jtag/swd.h b/src/jtag/swd.h index 0d1702c73..487cb85bf 100644 --- a/src/jtag/swd.h +++ b/src/jtag/swd.h @@ -277,6 +277,5 @@ struct swd_driver { }; int swd_init_reset(struct command_context *cmd_ctx); -void swd_add_reset(int req_srst); #endif /* OPENOCD_JTAG_SWD_H */ diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c index a3735661b..68a50b189 100644 --- a/src/target/adi_v5_swd.c +++ b/src/target/adi_v5_swd.c @@ -112,7 +112,7 @@ static int swd_connect(struct adiv5_dap *dap) 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"); }