aboutsummaryrefslogtreecommitdiff
path: root/src/jtag/drivers
diff options
context:
space:
mode:
authorTomas Vanek <vanekt@fbl.cz>2017-04-09 10:59:57 +0200
committerPaul Fertser <fercerpav@gmail.com>2018-01-03 10:56:32 +0000
commitbb976e3c387bc82e20ab7304f0cfac3e5eede3a1 (patch)
treece1fddfeee5bfa2a44b720e72f435aede83b4b8f /src/jtag/drivers
parent1c2e3d41de30c5e47d3fc8eda3de0a0a8229895a (diff)
jtag/drivers/cmsis-dap: fix connect under reset
Commit ef02b69b14d133b061217a91add5a028a77e86bc included a call to cmsis_dap_cmd_DAP_Connect() before calling cmsis_dap_cmd_DAP_SWJ_Sequence(). According to comment it is necessary for at least Keil ULINK-ME. Commit 72c3464be42088dc75245cf2fcc8f5c6e6959b4b added a cmsis_dap_cmd_DAP_Disconnect() before connect call to pair connection/disconnection. It solves some problems on Atmel EDBG. Unfortunately calling either of cmsis_dap_cmd_DAP_Connect() or cmsis_dap_cmd_DAP_Disconnect() deasserts reset signal. So these workarounds break ability to connect under reset. Use cmsis_dap_cmd_DAP_Disconnect() and cmsis_dap_cmd_DAP_Connect() pair only if both SRST and TRST are deasserted. Change-Id: I0914dae0a1360b8c7fe48231ff3867caedfb2dbe Signed-off-by: Tomas Vanek <vanekt@fbl.cz> Reported-by: Leonardo Sabino dos Santos <leonardo.sabino@gmail.com> Reviewed-on: http://openocd.zylin.com/4100 Tested-by: jenkins Reviewed-by: Paul Fertser <fercerpav@gmail.com>
Diffstat (limited to 'src/jtag/drivers')
-rw-r--r--src/jtag/drivers/cmsis_dap_usb.c30
1 files changed, 19 insertions, 11 deletions
diff --git a/src/jtag/drivers/cmsis_dap_usb.c b/src/jtag/drivers/cmsis_dap_usb.c
index 345c1fd7..b8181d6a 100644
--- a/src/jtag/drivers/cmsis_dap_usb.c
+++ b/src/jtag/drivers/cmsis_dap_usb.c
@@ -206,6 +206,8 @@ static uint8_t queued_seq_buf[1024]; /* TODO: make dynamic / move into cmsis obj
static int queued_retval;
+static uint8_t output_pins = SWJ_PIN_SRST | SWJ_PIN_TRST;
+
static struct cmsis_dap *cmsis_dap_handle;
static int cmsis_dap_usb_open(void)
@@ -790,15 +792,21 @@ static int cmsis_dap_swd_switch_seq(enum swd_special_seq seq)
unsigned int s_len;
int retval;
- /* First disconnect before connecting, Atmel EDBG needs it for SAMD/R/L/C */
- cmsis_dap_cmd_DAP_Disconnect();
+ if ((output_pins & (SWJ_PIN_SRST | SWJ_PIN_TRST)) == (SWJ_PIN_SRST | SWJ_PIN_TRST)) {
+ /* Following workaround deasserts reset on most adapters.
+ * Do not reconnect if a reset line is active!
+ * Reconnecting would break connecting under reset. */
- /* When we are reconnecting, DAP_Connect needs to be rerun, at
- * least on Keil ULINK-ME */
- retval = cmsis_dap_cmd_DAP_Connect(seq == LINE_RESET || seq == JTAG_TO_SWD ?
+ /* First disconnect before connecting, Atmel EDBG needs it for SAMD/R/L/C */
+ cmsis_dap_cmd_DAP_Disconnect();
+
+ /* When we are reconnecting, DAP_Connect needs to be rerun, at
+ * least on Keil ULINK-ME */
+ retval = cmsis_dap_cmd_DAP_Connect(seq == LINE_RESET || seq == JTAG_TO_SWD ?
CONNECT_SWD : CONNECT_JTAG);
- if (retval != ERROR_OK)
- return retval;
+ if (retval != ERROR_OK)
+ return retval;
+ }
switch (seq) {
case LINE_RESET:
@@ -1010,14 +1018,14 @@ static void cmsis_dap_execute_reset(struct jtag_command *cmd)
{
/* Set both TRST and SRST even if they're not enabled as
* there's no way to tristate them */
- uint8_t pins = 0;
+ output_pins = 0;
if (!cmd->cmd.reset->srst)
- pins |= SWJ_PIN_SRST;
+ output_pins |= SWJ_PIN_SRST;
if (!cmd->cmd.reset->trst)
- pins |= SWJ_PIN_TRST;
+ output_pins |= SWJ_PIN_TRST;
- int retval = cmsis_dap_cmd_DAP_SWJ_Pins(pins,
+ int retval = cmsis_dap_cmd_DAP_SWJ_Pins(output_pins,
SWJ_PIN_TRST | SWJ_PIN_SRST, 0, NULL);
if (retval != ERROR_OK)
LOG_ERROR("CMSIS-DAP: Interface reset failed");