]> git.sur5r.net Git - openocd/commitdiff
jtag/drivers/stlink: allow to reconnect seamlessly after polling failure
authorPaul Fertser <fercerpav@gmail.com>
Fri, 23 May 2014 11:53:59 +0000 (15:53 +0400)
committerAndreas Fritiofson <andreas.fritiofson@gmail.com>
Sun, 1 Jun 2014 17:28:49 +0000 (17:28 +0000)
If the communication with the target was failing (either because of an
intermittent connection or the target was rebooted), this is needed to
reestablish operational state.

Reported-by: Tim Sander <tim@krieglstein.org>
Tested-by: Tim Sander <tim@krieglstein.org>
Change-Id: I91ea2e2b2b5ef8eb27dfe9bae95ef2a919f67e4e
Signed-off-by: Paul Fertser <fercerpav@gmail.com>
Reviewed-on: http://openocd.zylin.com/2152
Tested-by: jenkins
Reviewed-by: Tim Sander <tim@krieglstein.org>
Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
src/jtag/drivers/stlink_usb.c

index b4dc0de3c9e646d665d34473de32b82ed37ca755..5574a40bae49ec9e1a377908bbf2963c26158e67 100644 (file)
@@ -126,6 +126,9 @@ struct stlink_usb_handle_s {
                /** trace module clock prescaler */
                uint32_t prescale;
        } trace;
+       /** reconnect is needed next time we try to query the
+        * status */
+       bool reconnect_pending;
 };
 
 #define STLINK_DEBUG_ERR_OK            0x80
@@ -618,6 +621,20 @@ static int stlink_usb_mode_leave(void *handle, enum stlink_mode type)
 
 static int stlink_usb_assert_srst(void *handle, int srst);
 
+static enum stlink_mode stlink_get_mode(enum hl_transports t)
+{
+       switch (t) {
+       case HL_TRANSPORT_SWD:
+               return STLINK_MODE_DEBUG_SWD;
+       case HL_TRANSPORT_JTAG:
+               return STLINK_MODE_DEBUG_JTAG;
+       case HL_TRANSPORT_SWIM:
+               return STLINK_MODE_DEBUG_SWIM;
+       default:
+               return STLINK_MODE_UNKNOWN;
+       }
+}
+
 /** */
 static int stlink_usb_init_mode(void *handle, bool connect_under_reset)
 {
@@ -691,20 +708,7 @@ static int stlink_usb_init_mode(void *handle, bool connect_under_reset)
        LOG_DEBUG("MODE: 0x%02X", mode);
 
        /* set selected mode */
-       switch (h->transport) {
-               case HL_TRANSPORT_SWD:
-                       emode = STLINK_MODE_DEBUG_SWD;
-                       break;
-               case HL_TRANSPORT_JTAG:
-                       emode = STLINK_MODE_DEBUG_JTAG;
-                       break;
-               case HL_TRANSPORT_SWIM:
-                       emode = STLINK_MODE_DEBUG_SWIM;
-                       break;
-               default:
-                       emode = STLINK_MODE_UNKNOWN;
-                       break;
-       }
+       emode = stlink_get_mode(h->transport);
 
        if (emode == STLINK_MODE_UNKNOWN) {
                LOG_ERROR("selected mode (transport) not supported");
@@ -877,8 +881,22 @@ static enum target_state stlink_usb_state(void *handle)
 
        assert(handle != NULL);
 
-       if (h->jtag_api == STLINK_JTAG_API_V2)
-               return stlink_usb_v2_get_status(handle);
+       if (h->reconnect_pending) {
+               LOG_INFO("Previous state query failed, trying to reconnect");
+               res = stlink_usb_mode_enter(handle, stlink_get_mode(h->transport));
+
+               if (res != ERROR_OK)
+                       return TARGET_UNKNOWN;
+
+               h->reconnect_pending = false;
+       }
+
+       if (h->jtag_api == STLINK_JTAG_API_V2) {
+               res = stlink_usb_v2_get_status(handle);
+               if (res == TARGET_UNKNOWN)
+                       h->reconnect_pending = true;
+               return res;
+       }
 
        stlink_usb_init_buffer(handle, h->rx_ep, 2);
 
@@ -895,6 +913,8 @@ static enum target_state stlink_usb_state(void *handle)
        if (h->databuf[0] == STLINK_CORE_HALTED)
                return TARGET_HALTED;
 
+       h->reconnect_pending = true;
+
        return TARGET_UNKNOWN;
 }