X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Fcore.c;h=99a9eb75aeadd81bc925d4d99e04241703fc174c;hb=7743e0fb4390d09c315ce9c6edbb2c3ba6b8c2d9;hp=a36345b77af194b6fba39cd7865ed5dc60c7bc23;hpb=5793056d96fd88845cde0d107c002a5fce413909;p=openocd.git diff --git a/src/jtag/core.c b/src/jtag/core.c index a36345b77a..99a9eb75ae 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -33,6 +33,7 @@ #endif #include "jtag.h" +#include "swd.h" #include "interface.h" #include @@ -606,6 +607,46 @@ void jtag_add_clocks(int num_cycles) } } +void swd_add_reset(int req_srst) +{ + if (req_srst) { + if (!(jtag_reset_config & RESET_HAS_SRST)) { + LOG_ERROR("BUG: can't assert SRST"); + jtag_set_error(ERROR_FAIL); + return; + } + 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(); + + if (retval != ERROR_OK) { + LOG_ERROR("TRST/SRST error"); + return; + } + + /* SRST resets everything hooked up to that signal */ + jtag_srst = req_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); + } + } +} + void jtag_add_reset(int req_tlr_or_trst, int req_srst) { int trst_with_tlr = 0; @@ -1455,6 +1496,20 @@ int adapter_quit(void) return ERROR_OK; } +int swd_init_reset(struct command_context *cmd_ctx) +{ + int 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; +} int jtag_init_reset(struct command_context *cmd_ctx) { @@ -1738,3 +1793,32 @@ bool transport_is_jtag(void) { return get_current_transport() == &jtag_transport; } + +void adapter_assert_reset(void) +{ + if (transport_is_jtag()) { + if (jtag_reset_config & RESET_SRST_PULLS_TRST) + jtag_add_reset(1, 1); + else + jtag_add_reset(0, 1); + } else if (transport_is_swd()) + swd_add_reset(1); + else if (get_current_transport() != NULL) + LOG_ERROR("reset is not supported on %s", + get_current_transport()->name); + else + LOG_ERROR("transport is not selected"); +} + +void adapter_deassert_reset(void) +{ + if (transport_is_jtag()) + jtag_add_reset(0, 0); + else if (transport_is_swd()) + swd_add_reset(0); + else if (get_current_transport() != NULL) + LOG_ERROR("reset is not supported on %s", + get_current_transport()->name); + else + LOG_ERROR("transport is not selected"); +}