From 7743e0fb4390d09c315ce9c6edbb2c3ba6b8c2d9 Mon Sep 17 00:00:00 2001 From: Simon Qian Date: Sat, 17 Mar 2012 15:21:59 +0800 Subject: [PATCH] topic: add reset functions for SWD Add swd_init_reset and swd_add_reset. Add adapter_assert_reset and adapter_deassert_reset, and call them instead of JTAG reset functions. Change-Id: Ib2551c6fbb45513e0ae0dc331cfe3ee3f922298a Signed-off-by: Simon Qian Reviewed-on: http://openocd.zylin.com/526 Tested-by: jenkins Reviewed-by: Freddie Chopin Reviewed-by: Spencer Oliver --- src/flash/nor/stellaris.c | 5 ++- src/jtag/core.c | 84 +++++++++++++++++++++++++++++++++++++++ src/jtag/interface.h | 3 ++ src/jtag/swd.h | 8 ++++ src/jtag/tcl.c | 8 +++- src/target/arm_adi_v5.c | 6 +-- src/target/cortex_m.c | 8 ++-- 7 files changed, 110 insertions(+), 12 deletions(-) diff --git a/src/flash/nor/stellaris.c b/src/flash/nor/stellaris.c index 0c4169c7f9..96a15d4281 100644 --- a/src/flash/nor/stellaris.c +++ b/src/flash/nor/stellaris.c @@ -29,6 +29,7 @@ #include "config.h" #endif +#include "jtag/interface.h" #include "imp.h" #include #include @@ -1330,7 +1331,7 @@ COMMAND_HANDLER(stellaris_handle_recover_command) LOG_ERROR("Can't recover Stellaris flash without SRST"); return ERROR_FAIL; } - jtag_add_reset(0, 1); + adapter_assert_reset(); for (int i = 0; i < 5; i++) { retval = dap_to_swd(bank->target); @@ -1343,7 +1344,7 @@ COMMAND_HANDLER(stellaris_handle_recover_command) } /* de-assert SRST */ - jtag_add_reset(0, 0); + adapter_deassert_reset(); retval = jtag_execute_queue(); /* wait 400+ msec ... OK, "1+ second" is simpler */ diff --git a/src/jtag/core.c b/src/jtag/core.c index a36345b77a..99a9eb75ae 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; @@ -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"); +} diff --git a/src/jtag/interface.h b/src/jtag/interface.h index 9c11d9dfb8..72af2fed28 100644 --- a/src/jtag/interface.h +++ b/src/jtag/interface.h @@ -304,4 +304,7 @@ extern const char *jtag_only[]; extern const struct swd_driver *swd; +void adapter_assert_reset(void); +void adapter_deassert_reset(void); + #endif /* OPENOCD_JTAG_INTERFACE_H */ diff --git a/src/jtag/swd.h b/src/jtag/swd.h index 9a591f38c6..9041ce088d 100644 --- a/src/jtag/swd.h +++ b/src/jtag/swd.h @@ -17,6 +17,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +#ifndef SWD_H +#define SWD_H + /* Bits in SWD command packets, written from host to target * first bit on the wire is START */ @@ -128,4 +131,9 @@ struct swd_driver { int *(*trace)(bool swo); }; +int swd_init_reset(struct command_context *cmd_ctx); +void swd_add_reset(int req_srst); + bool transport_is_swd(void); + +#endif /* SWD_H */ diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index c74df5ed79..b279b1f2bd 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -33,6 +33,7 @@ #endif #include "jtag.h" +#include "swd.h" #include "minidriver.h" #include "interface.h" #include "interfaces.h" @@ -672,6 +673,7 @@ static int jim_jtag_arp_init(Jim_Interp *interp, int argc, Jim_Obj *const *argv) static int jim_jtag_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { + int e = ERROR_OK; Jim_GetOptInfo goi; Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1); if (goi.argc != 0) { @@ -679,7 +681,11 @@ static int jim_jtag_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj *const return JIM_ERR; } struct command_context *context = current_command_context(interp); - int e = jtag_init_reset(context); + if (transport_is_jtag()) + e = jtag_init_reset(context); + else if (transport_is_swd()) + e = swd_init_reset(context); + if (e != ERROR_OK) { Jim_Obj *eObj = Jim_NewIntObj(goi.interp, e); Jim_SetResultFormatted(goi.interp, "error: %#s", eObj); diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index 1ef7c1a004..9a98f61d56 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -69,6 +69,7 @@ #include "config.h" #endif +#include "jtag/interface.h" #include "arm.h" #include "arm_adi_v5.h" #include @@ -977,10 +978,7 @@ int dap_syssec_kinetis_mdmap(struct adiv5_dap *dap) /* we need to assert reset */ if (jtag_reset_config & RESET_HAS_SRST) { /* default to asserting srst */ - if (jtag_reset_config & RESET_SRST_PULLS_TRST) - jtag_add_reset(1, 1); - else - jtag_add_reset(0, 1); + adapter_assert_reset(); } else { LOG_DEBUG("SRST not configured"); dap_ap_select(dap, 0); diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 488899cbe9..09a51b7b3b 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -31,6 +31,7 @@ #include "config.h" #endif +#include "jtag/interface.h" #include "breakpoints.h" #include "cortex_m.h" #include "target_request.h" @@ -995,10 +996,7 @@ static int cortex_m3_assert_reset(struct target *target) if (jtag_reset_config & RESET_HAS_SRST) { /* default to asserting srst */ - if (jtag_reset_config & RESET_SRST_PULLS_TRST) - jtag_add_reset(1, 1); - else - jtag_add_reset(0, 1); + adapter_assert_reset(); } else { /* Use a standard Cortex-M3 software reset mechanism. * We default to using VECRESET as it is supported on all current cores. @@ -1051,7 +1049,7 @@ static int cortex_m3_deassert_reset(struct target *target) target_state_name(target)); /* deassert reset lines */ - jtag_add_reset(0, 0); + adapter_deassert_reset(); return ERROR_OK; } -- 2.30.2