David Brownell <david-b@pacbell.net> Some jtag_add_reset() cleanup:

- Track whether TRST and/or SRST actually change:

    * If they're not changing, don't ask the JTAG adapter to do anything!
      (JTAG TCK/TMS ops might still be used to enter TAP_RESET though.)
    * Don't change their recorded values until after the adapter says it
      did so ... so fault paths can't leave corrupt state.
    * Detect and report jtag_execute_queue() failure mode
    * Only emit messages saying what really changed; this includes adding
      an omitted "deasserted TRST" message.
    * Only apply delays after deasserting SRST/TRST if we *DID* deassert!

 - Messages say "TLR" not "RESET", to be less confusing; there are many
   kinds of reset.  (Though "TLR" isn't quite ideal either, since it's
   the name of the TAP state being entered by TMS+TCK or TRST; it's at
   least non-ambiguous in context.)

So the main effect is to do only the work this routine was told to do;
and to have debug messaging make more sense.

git-svn-id: svn://svn.berlios.de/openocd/trunk@2621 b42882b7-edfa-0310-969c-e2dbd0fdcd60
__archive__
oharboe 2009-08-25 19:55:32 +00:00
parent bd7cbd01e8
commit 6f359fba68
1 changed files with 63 additions and 43 deletions

View File

@ -60,11 +60,15 @@ static int jtag_error = ERROR_OK;
static const char *jtag_event_strings[] = static const char *jtag_event_strings[] =
{ {
[JTAG_TRST_ASSERTED] = "JTAG controller reset (RESET or TRST)", [JTAG_TRST_ASSERTED] = "JTAG controller reset (TLR or TRST)",
[JTAG_TAP_EVENT_ENABLE] = "TAP enabled", [JTAG_TAP_EVENT_ENABLE] = "TAP enabled",
[JTAG_TAP_EVENT_DISABLE] = "TAP disabled", [JTAG_TAP_EVENT_DISABLE] = "TAP disabled",
}; };
/*
* JTAG adapters must initialize with TRST and SRST de-asserted
* (they're negative logic, so that means *high*)
*/
static int jtag_trst = 0; static int jtag_trst = 0;
static int jtag_srst = 0; static int jtag_srst = 0;
@ -581,6 +585,8 @@ void jtag_add_clocks(int num_cycles)
void jtag_add_reset(int req_tlr_or_trst, int req_srst) void jtag_add_reset(int req_tlr_or_trst, int req_srst)
{ {
int trst_with_tlr = 0; int trst_with_tlr = 0;
int new_srst;
int new_trst = 0;
/* FIX!!! there are *many* different cases here. A better /* FIX!!! there are *many* different cases here. A better
* approach is needed for legal combinations of transitions... * approach is needed for legal combinations of transitions...
@ -625,60 +631,74 @@ void jtag_add_reset(int req_tlr_or_trst, int req_srst)
{ {
if (!trst_with_tlr && (jtag_reset_config & RESET_HAS_TRST)) if (!trst_with_tlr && (jtag_reset_config & RESET_HAS_TRST))
{ {
jtag_trst = 1; new_trst = 1;
} else } else
{ {
trst_with_tlr = 1; trst_with_tlr = 1;
} }
} else
{
jtag_trst = 0;
} }
jtag_srst = req_srst; new_srst = req_srst;
int retval = interface_jtag_add_reset(jtag_trst, jtag_srst); /* Maybe change TRST and/or SRST signal state */
if (jtag_srst != new_srst || jtag_trst != new_trst) {
int retval;
retval = interface_jtag_add_reset(new_trst, new_srst);
if (retval != ERROR_OK) if (retval != ERROR_OK)
{
jtag_set_error(retval); jtag_set_error(retval);
else
retval = jtag_execute_queue();
if (retval != ERROR_OK) {
LOG_ERROR("TRST/SRST error %d", retval);
return; return;
} }
jtag_execute_queue();
if (jtag_srst)
{
LOG_DEBUG("SRST line asserted");
} }
else
{ /* 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");
else {
LOG_DEBUG("SRST line released"); LOG_DEBUG("SRST line released");
if (jtag_nsrst_delay) if (jtag_nsrst_delay)
jtag_add_sleep(jtag_nsrst_delay * 1000); jtag_add_sleep(jtag_nsrst_delay * 1000);
} }
if (trst_with_tlr)
{
LOG_DEBUG("JTAG reset with RESET instead of TRST");
jtag_set_end_state(TAP_RESET);
jtag_add_tlr();
return;
} }
if (jtag_trst) /* Maybe enter the JTAG TAP_RESET state ...
{ * - using only TMS, TCK, and the JTAG state machine
/* we just asserted nTRST, so we're now in Test-Logic-Reset, * - or else more directly, using TRST
* and inform possible listeners about this *
* 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_set_end_state(TAP_RESET);
jtag_add_tlr();
} else if (jtag_trst != new_trst) {
jtag_trst = new_trst;
if (jtag_trst) {
/* we just asserted nTRST, so we're now in TAP_RESET;
* inform possible listeners about this
*
* REVISIT asserting TRST is less significant than
* being in TAP_RESET ... both entries (TRST, TLR)
* should trigger a callback.
*/ */
LOG_DEBUG("TRST line asserted"); LOG_DEBUG("TRST line asserted");
tap_set_state(TAP_RESET); tap_set_state(TAP_RESET);
jtag_call_event_callbacks(JTAG_TRST_ASSERTED); jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
} } else {
else LOG_DEBUG("TRST line released");
{
if (jtag_ntrst_delay) if (jtag_ntrst_delay)
jtag_add_sleep(jtag_ntrst_delay * 1000); jtag_add_sleep(jtag_ntrst_delay * 1000);
} }
} }
}
tap_state_t jtag_set_end_state(tap_state_t state) tap_state_t jtag_set_end_state(tap_state_t state)
{ {
@ -1223,11 +1243,11 @@ int jtag_init_reset(struct command_context_s *cmd_ctx)
if ((retval = jtag_interface_init(cmd_ctx)) != ERROR_OK) if ((retval = jtag_interface_init(cmd_ctx)) != ERROR_OK)
return retval; return retval;
LOG_DEBUG("Trying to bring the JTAG controller to life by asserting TRST / RESET"); LOG_DEBUG("Trying to bring the JTAG controller to life by asserting TRST / TLR");
/* Reset can happen after a power cycle. /* Reset can happen after a power cycle.
* *
* Ideally we would only assert TRST or run RESET before the target reset. * Ideally we would only assert TRST or run TLR before the target reset.
* *
* However w/srst_pulls_trst, trst is asserted together with the target * However w/srst_pulls_trst, trst is asserted together with the target
* reset whether we want it or not. * reset whether we want it or not.
@ -1240,7 +1260,7 @@ int jtag_init_reset(struct command_context_s *cmd_ctx)
* NB! order matters!!!! srst *can* disconnect JTAG circuitry * NB! order matters!!!! srst *can* disconnect JTAG circuitry
* *
*/ */
jtag_add_reset(1, 0); /* RESET or TRST */ jtag_add_reset(1, 0); /* TAP_RESET, using TMS+TCK or TRST */
if (jtag_reset_config & RESET_HAS_SRST) if (jtag_reset_config & RESET_HAS_SRST)
{ {
jtag_add_reset(1, 1); jtag_add_reset(1, 1);