X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Fcore.c;h=5d5803a3604a4c2350d72f5dfc19c82195801cf1;hb=09f9596ae0cfb70a6ddceefd144b0e892a984b16;hp=6de168e61630ec2b94e100a550d16e2c07ddd4df;hpb=7719e2188e89a93813caf2ac8cfd7457cb605631;p=openocd.git diff --git a/src/jtag/core.c b/src/jtag/core.c index 6de168e616..5d5803a360 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; @@ -853,7 +894,7 @@ void jtag_sleep(uint32_t us) /* A reserved manufacturer ID is used in END_OF_CHAIN_FLAG, so we * know that no valid TAP will have it as an IDCODE value. */ -#define END_OF_CHAIN_FLAG 0x000000ff +#define END_OF_CHAIN_FLAG 0xffffffff /* a larger IR length than we ever expect to autoprobe */ #define JTAG_IRLEN_MAX 60 @@ -921,10 +962,10 @@ static bool jtag_idcode_is_final(uint32_t idcode) { /* * Some devices, such as AVR8, will output all 1's instead - * of TDI input value at end of chain. Allow those values + * of TDI input value at end of chain. Allow those values * instead of failing. */ - return idcode == END_OF_CHAIN_FLAG || idcode == 0xFFFFFFFF; + return idcode == END_OF_CHAIN_FLAG; } /** @@ -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; @@ -1273,13 +1314,13 @@ void jtag_tap_init(struct jtag_tap *tap) /* register the reset callback for the TAP */ jtag_register_event_callback(&jtag_reset_callback, tap); + jtag_tap_add(tap); LOG_DEBUG("Created Tap: %s @ abs position %d, " - "irlen %d, capture: 0x%x mask: 0x%x", tap->dotted_name, - tap->abs_chain_position, tap->ir_length, - (unsigned) tap->ir_capture_value, - (unsigned) tap->ir_capture_mask); - jtag_tap_add(tap); + "irlen %d, capture: 0x%x mask: 0x%x", tap->dotted_name, + tap->abs_chain_position, tap->ir_length, + (unsigned) tap->ir_capture_value, + (unsigned) tap->ir_capture_mask); } void jtag_tap_free(struct jtag_tap *tap) @@ -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"); +}