From a0647227439434c4a71470e336ec8715d43d0501 Mon Sep 17 00:00:00 2001 From: oharboe Date: Wed, 9 Apr 2008 05:50:34 +0000 Subject: - added "init" command. "init" and "reset" at end of startup script is equivalent to daemon_startup(still supported). - print warning if srst and trst change state at the same time when srst_and_trst is seperate - reset now performs a trst, examines and validates the jtag chain before targets assert reset - if startup fails to examine and validate the jtag chain, try a reset before trying again git-svn-id: svn://svn.berlios.de/openocd/trunk@552 b42882b7-edfa-0310-969c-e2dbd0fdcd60 --- src/jtag/jtag.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/jtag/jtag.h | 10 ++++++++- 2 files changed, 77 insertions(+), 2 deletions(-) (limited to 'src/jtag') diff --git a/src/jtag/jtag.c b/src/jtag/jtag.c index c73e0c9a..291c4010 100644 --- a/src/jtag/jtag.c +++ b/src/jtag/jtag.c @@ -898,6 +898,23 @@ void jtag_add_reset(int req_tlr_or_trst, int req_srst) int trst_with_tlr = 0; int retval; + /* FIX!!! there are *many* different cases here. A better + * approach is needed for legal combinations of transitions... + */ + if ((jtag_reset_config & RESET_HAS_SRST)&& + (jtag_reset_config & RESET_HAS_TRST)&& + ((jtag_reset_config & RESET_SRST_PULLS_TRST)==0)&& + ((jtag_reset_config & RESET_TRST_PULLS_SRST)==0)) + { + if (((req_tlr_or_trst&&!jtag_trst)|| + (!req_tlr_or_trst&&jtag_trst))&& + ((req_srst&&!jtag_srst)|| + (!req_srst&&jtag_srst))) + { + LOG_ERROR("BUG: transition of req_tlr_or_trst and req_srst in the same jtag_add_reset() call is undefined"); + } + } + /* 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_tlr_or_trst)) @@ -1477,7 +1494,7 @@ int jtag_interface_init(struct command_context_s *cmd_ctx) return ERROR_OK; } -int jtag_init(struct command_context_s *cmd_ctx) +static int jtag_init_inner(struct command_context_s *cmd_ctx) { int validate_tries = 0; jtag_device_t *device; @@ -1521,6 +1538,56 @@ int jtag_init(struct command_context_s *cmd_ctx) return ERROR_OK; } +int jtag_init_reset(struct command_context_s *cmd_ctx) +{ + int retval; + LOG_DEBUG("Trying to bring the JTAG controller to life by asserting TRST / tms"); + + /* Reset can happen after a power cycle. + * + * Ideally we would only assert TRST or run tms before the target reset. + * + * However w/srst_pulls_trst, trst is asserted together with the target + * reset whether we want it or not. + * + * NB! Some targets have JTAG circuitry disabled until a + * trst & srst has been asserted. + * + * NB! here we assume nsrst/ntrst delay are sufficient! + * + * NB! order matters!!!! srst *can* disconnect JTAG circuitry + * + */ + jtag_add_reset(1, 0); /* TMS or TRST */ + if (jtag_reset_config & RESET_HAS_SRST) + { + jtag_add_reset(1, 1); + if ((jtag_reset_config & RESET_SRST_PULLS_TRST)==0) + jtag_add_reset(0, 1); + } + jtag_add_reset(0, 0); + if ((retval = jtag_execute_queue()) != ERROR_OK) + return retval; + + /* Check that we can communication on the JTAG chain + eventually we want to + * be able to perform enumeration only after OpenOCD has started + * telnet and GDB server + * + * That would allow users to more easily perform any magic they need to before + * reset happens. + */ + return jtag_init_inner(cmd_ctx); +} + +int jtag_init(struct command_context_s *cmd_ctx) +{ + if (jtag_init_inner(cmd_ctx)==ERROR_OK) + { + return ERROR_OK; + } + return jtag_init_reset(cmd_ctx); +} + static int default_khz(int khz, int *jtag_speed) { diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index 19329447..b7ce094d 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -241,8 +241,12 @@ enum reset_types extern enum reset_types jtag_reset_config; -/* JTAG subsystem */ +/* initialize JTAG chain using only a TLR reset. If init fails, + * try reset + init. + */ extern int jtag_init(struct command_context_s *cmd_ctx); +/* reset, then initialize JTAG chain */ +extern int jtag_init_reset(struct command_context_s *cmd_ctx); extern int jtag_register_commands(struct command_context_s *cmd_ctx); /* JTAG interface, can be implemented with a software or hardware fifo @@ -325,6 +329,10 @@ extern int interface_jtag_add_runtest(int num_cycles, enum tap_state endstate); * This is why combinations such as "reset_config srst_only srst_pulls_trst" * are supported. * + * only req_tlr_or_trst and srst can have a transition for a + * call as the effects of transitioning both at the "same time" + * are undefined, but when srst_pulls_trst or vice versa, + * then trst & srst *must* be asserted together. */ extern void jtag_add_reset(int req_tlr_or_trst, int srst); /* this drives the actual srst and trst pins. srst will always be 0 -- cgit v1.2.3