]> git.sur5r.net Git - openocd/commitdiff
jtag/drivers/cmsis-dap: fix connect under reset
authorTomas Vanek <vanekt@fbl.cz>
Sun, 9 Apr 2017 08:59:57 +0000 (10:59 +0200)
committerPaul Fertser <fercerpav@gmail.com>
Wed, 3 Jan 2018 10:56:32 +0000 (10:56 +0000)
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>
src/jtag/drivers/cmsis_dap_usb.c

index 345c1fd7e8f62b127c1abbbe41c16eda5dd3b861..b8181d6ae7421a403d81589c161a268779dccbae 100644 (file)
@@ -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");