diff --git a/src/jtag/bitbang.c b/src/jtag/bitbang.c index a4e415c2e..16b5f1918 100644 --- a/src/jtag/bitbang.c +++ b/src/jtag/bitbang.c @@ -239,7 +239,7 @@ int bitbang_execute_queue(void) #ifdef _DEBUG_JTAG_IO_ LOG_DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst); #endif - if (cmd->cmd.reset->trst == 1) + if ((cmd->cmd.reset->trst == 1) || (cmd->cmd.reset->srst && (jtag_reset_config & RESET_SRST_PULLS_TRST))) { cur_state = TAP_TLR; } diff --git a/src/jtag/ft2232.c b/src/jtag/ft2232.c index 747a383a9..20824bbbd 100644 --- a/src/jtag/ft2232.c +++ b/src/jtag/ft2232.c @@ -889,7 +889,6 @@ void usbjtag_reset(int trst, int srst) { if (trst == 1) { - cur_state = TAP_TLR; if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) low_direction |= nTRSTnOE; /* switch to output pin (output is low) */ else @@ -929,7 +928,6 @@ void jtagkey_reset(int trst, int srst) { if (trst == 1) { - cur_state = TAP_TLR; if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) high_output &= ~nTRSTnOE; else @@ -969,7 +967,6 @@ void olimex_jtag_reset(int trst, int srst) { if (trst == 1) { - cur_state = TAP_TLR; if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) high_output &= ~nTRSTnOE; else @@ -1003,7 +1000,6 @@ void flyswatter_reset(int trst, int srst) { if (trst == 1) { - cur_state = TAP_TLR; low_output &= ~nTRST; } else if (trst == 0) @@ -1051,7 +1047,6 @@ void comstick_reset(int trst, int srst) { if (trst == 1) { - cur_state = TAP_TLR; high_output &= ~nTRST; } else if (trst == 0) @@ -1079,7 +1074,6 @@ void stm32stick_reset(int trst, int srst) { if (trst == 1) { - cur_state = TAP_TLR; high_output &= ~nTRST; } else if (trst == 0) @@ -1151,6 +1145,10 @@ int ft2232_execute_queue() first_unsent = cmd; } + if ((cmd->cmd.reset->trst == 1) || (cmd->cmd.reset->srst && (jtag_reset_config & RESET_SRST_PULLS_TRST))) + { + cur_state = TAP_TLR; + } layout->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); require_send = 1; diff --git a/src/jtag/jtag.c b/src/jtag/jtag.c index 671c7ac97..34147651a 100644 --- a/src/jtag/jtag.c +++ b/src/jtag/jtag.c @@ -224,7 +224,6 @@ int jtag_speed_post_reset = 0; /* forward declarations */ void jtag_add_pathmove(int num_states, enum tap_state *path); void jtag_add_runtest(int num_cycles, enum tap_state endstate); -void jtag_add_reset(int trst, int srst); void jtag_add_end_state(enum tap_state endstate); void jtag_add_sleep(u32 us); int jtag_execute_queue(void); @@ -884,14 +883,14 @@ void jtag_add_runtest(int num_cycles, enum tap_state state) jtag_error=retval; } -void jtag_add_reset(int req_trst, int req_srst) +void jtag_add_reset(int req_tms_or_trst, int req_srst) { int trst_with_tms = 0; int retval; /* Make sure that jtag_reset_config allows the requested reset */ /* if SRST pulls TRST, we can't fulfill srst == 1 with trst == 0 */ - if (((jtag_reset_config & RESET_SRST_PULLS_TRST) && (req_srst == 1)) && (req_trst == 0)) + if (((jtag_reset_config & RESET_SRST_PULLS_TRST) && (req_srst == 1)) && (!req_tms_or_trst)) { LOG_ERROR("BUG: requested reset would assert trst"); jtag_error=ERROR_FAIL; @@ -899,29 +898,35 @@ void jtag_add_reset(int req_trst, int req_srst) } /* if TRST pulls SRST, we reset with TAP T-L-R */ - if (((jtag_reset_config & RESET_TRST_PULLS_SRST) && (req_trst == 1)) && (req_srst == 0)) + if (((jtag_reset_config & RESET_TRST_PULLS_SRST) && (req_tms_or_trst)) && (req_srst == 0)) { - req_trst = 0; trst_with_tms = 1; } if (req_srst && !(jtag_reset_config & RESET_HAS_SRST)) { - LOG_ERROR("BUG: requested nSRST assertion, but the current configuration doesn't support this"); + LOG_ERROR("BUG: requested SRST assertion, but the current configuration doesn't support this"); jtag_error=ERROR_FAIL; return; } - if (req_trst && !(jtag_reset_config & RESET_HAS_TRST)) + if (req_tms_or_trst) { - req_trst = 0; - trst_with_tms = 1; + if (!trst_with_tms && (jtag_reset_config & RESET_HAS_TRST)) + { + jtag_trst = 1; + } else + { + trst_with_tms = 1; + } + } else + { + jtag_trst = 0; } - - jtag_trst = req_trst; + jtag_srst = req_srst; - retval = interface_jtag_add_reset(req_trst, req_srst); + retval = interface_jtag_add_reset(jtag_trst, jtag_srst); if (retval!=ERROR_OK) { jtag_error=retval; @@ -959,10 +964,6 @@ void jtag_add_reset(int req_trst, int req_srst) } else { - /* the nTRST line got deasserted, so we're still in Test-Logic-Reset, - * but we might want to add a delay to give the TAP time to settle - */ - LOG_DEBUG("Now in TAP_TLR - Test-Logic-Reset(either due to TRST line asserted or tms reset)"); if (jtag_ntrst_delay) jtag_add_sleep(jtag_ntrst_delay * 1000); } @@ -1608,6 +1609,9 @@ int handle_scan_chain_command(struct command_context_s *cmd_ctx, char *cmd, char int handle_reset_config_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { + if (argc < 1) + return ERROR_COMMAND_SYNTAX_ERROR; + if (argc >= 1) { if (strcmp(args[0], "none") == 0) @@ -1628,19 +1632,23 @@ int handle_reset_config_command(struct command_context_s *cmd_ctx, char *cmd, ch if (argc >= 2) { - if (strcmp(args[1], "srst_pulls_trst") == 0) - jtag_reset_config |= RESET_SRST_PULLS_TRST; - else if (strcmp(args[1], "trst_pulls_srst") == 0) - jtag_reset_config |= RESET_TRST_PULLS_SRST; - else if (strcmp(args[1], "combined") == 0) - jtag_reset_config |= RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST; - else if (strcmp(args[1], "separate") == 0) - jtag_reset_config &= ~(RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST); - else + if (strcmp(args[1], "separate") == 0) { - LOG_ERROR("invalid reset_config argument, defaulting to none"); - jtag_reset_config = RESET_NONE; - return ERROR_INVALID_ARGUMENTS; + /* seperate reset lines - default */ + } else + { + if (strcmp(args[1], "srst_pulls_trst") == 0) + jtag_reset_config |= RESET_SRST_PULLS_TRST; + else if (strcmp(args[1], "trst_pulls_srst") == 0) + jtag_reset_config |= RESET_TRST_PULLS_SRST; + else if (strcmp(args[1], "combined") == 0) + jtag_reset_config |= RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST; + else + { + LOG_ERROR("invalid reset_config argument, defaulting to none"); + jtag_reset_config = RESET_NONE; + return ERROR_INVALID_ARGUMENTS; + } } } diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index 2c186e9cb..114e6aa36 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -308,13 +308,32 @@ extern int interface_jtag_add_pathmove(int num_states, enum tap_state *path); */ extern void jtag_add_runtest(int num_cycles, enum tap_state endstate); extern int interface_jtag_add_runtest(int num_cycles, enum tap_state endstate); -/* Invoking jtag_add_reset() with unsupported combinations is - * not allowed and constitutes a bug in the calling code. +/* A reset of the TAP state machine can be requested. * - * trst & srst must be 0 or 1. There is no way to - * read the current reset state. + * Whether tms or trst reset is used depends on the capabilities of + * the target and jtag interface(reset_config command configures this). + * + * srst can driver a reset of the TAP state machine and vice + * versa + * + * Application code may need to examine value of jtag_reset_config + * to determine the proper codepath + * + * DANGER! Even though srst drives trst, trst might not be connected to + * the interface, and it might actually be *harmful* to assert trst in this case. + * + * This is why combinations such as "reset_config srst_only srst_pulls_trst" + * are supported. + * + */ +extern void jtag_add_reset(int req_tms_or_trst, int srst); +/* this drives the actual srst and trst pins. srst will always be 0 + * if jtag_reset_config & RESET_SRST_PULLS_TRST != 0 and ditto for + * trst. + * + * the higher level jtag_add_reset will invoke jtag_add_tms() if + * approperiate */ -extern void jtag_add_reset(int trst, int srst); extern int interface_jtag_add_reset(int trst, int srst); extern void jtag_add_end_state(enum tap_state endstate); extern int interface_jtag_add_end_state(enum tap_state endstate);