X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fjtag%2Fcore.c;h=99a9eb75aeadd81bc925d4d99e04241703fc174c;hb=7743e0fb4390d09c315ce9c6edbb2c3ba6b8c2d9;hp=f87a66a559af4177a12219af6b4cbd21fc9481da;hpb=38f8e5eefac748a30a4bf5e9d7a7313c8ae0e4e9;p=openocd diff --git a/src/jtag/core.c b/src/jtag/core.c index f87a66a5..99a9eb75 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 @@ -113,11 +114,11 @@ static int jtag_ntrst_assert_width; /* width of assertion */ * when an event occurs. */ struct jtag_event_callback { - /* / a event callback */ + /** a event callback */ jtag_event_handler_t callback; - /* / the private data to pass to the callback */ + /** the private data to pass to the callback */ void *priv; - /* / the next callback */ + /** the next callback */ struct jtag_event_callback *next; }; @@ -206,7 +207,7 @@ unsigned jtag_tap_count_enabled(void) return n; } -/* / Append a new TAP to the chain of all taps. */ +/** Append a new TAP to the chain of all taps. */ void jtag_tap_add(struct jtag_tap *t) { t->abs_chain_position = jtag_num_taps++; @@ -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; @@ -716,7 +757,7 @@ void jtag_add_reset(int req_tlr_or_trst, int req_srst) void jtag_add_sleep(uint32_t us) { - /* / @todo Here, keep_alive() appears to be a layering violation!!! */ + /** @todo Here, keep_alive() appears to be a layering violation!!! */ keep_alive(); jtag_set_error(interface_jtag_add_sleep(us)); } @@ -958,8 +999,8 @@ static bool jtag_examine_chain_match_tap(const struct jtag_tap *tap) if (0 == tap->expected_ids_cnt && !idcode) return true; - /* optionally ignore the JTAG version field */ - uint32_t mask = tap->ignore_version ? ~(0xff << 24) : ~0; + /* optionally ignore the JTAG version field - bits 28-31 of IDCODE */ + uint32_t mask = tap->ignore_version ? ~(0xf << 28) : ~0; idcode &= mask; @@ -1260,7 +1301,7 @@ void jtag_tap_init(struct jtag_tap *tap) tap->expected_mask = calloc(1, ir_len_bytes); tap->cur_instr = malloc(ir_len_bytes); - /* / @todo cope better with ir_length bigger than 32 bits */ + /** @todo cope better with ir_length bigger than 32 bits */ if (ir_len_bits > 32) ir_len_bits = 32; @@ -1286,7 +1327,7 @@ void jtag_tap_free(struct jtag_tap *tap) { jtag_unregister_event_callback(&jtag_reset_callback, tap); - /* / @todo is anything missing? no memory leaks please */ + /** @todo is anything missing? no memory leaks please */ free((void *)tap->expected); free((void *)tap->expected_ids); free((void *)tap->chip); @@ -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"); +}