drivers/cmsis-dap: flush read
authorTomas Vanek <vanekt@fbl.cz>
Tue, 6 Apr 2021 16:55:22 +0000 (18:55 +0200)
committerTomas Vanek <vanekt@fbl.cz>
Sun, 18 Apr 2021 20:21:44 +0000 (21:21 +0100)
Some CMSIS-DAP adapters keep buffered packets over
USB close/open so we need to flush up to 64 old packets
to be sure all buffers are empty.

Flush just after cmsis_dap_open() and in the case of command mismatch.

Change-Id: If21a118639e64d90635b4ecf81013d29a7b9f78d
Signed-off-by: Tomas Vanek <vanekt@fbl.cz>
Reviewed-on: http://openocd.zylin.com/6135
Tested-by: jenkins
Reviewed-by: Adrian M Negreanu <adrian.negreanu@nxp.com>
src/jtag/drivers/cmsis_dap.c

index b5ceb6cefbc7f5fe68d3f6cf6904e663b07f9d19..6ab0875982beda7a312537e5ca28b52e1e2d66c2 100644 (file)
@@ -281,6 +281,21 @@ static void cmsis_dap_close(struct cmsis_dap *dap)
        }
 }
 
+static void cmsis_dap_flush_read(struct cmsis_dap *dap)
+{
+       unsigned int i;
+       /* Some CMSIS-DAP adapters keep buffered packets over
+        * USB close/open so we need to flush up to 64 old packets
+        * to be sure all buffers are empty */
+       for (i = 0; i < 64; i++) {
+               int retval = dap->backend->read(dap, 10);
+               if (retval == ERROR_TIMEOUT_REACHED)
+                       break;
+       }
+       if (i)
+               LOG_DEBUG("Flushed %u packets", i);
+}
+
 /* Send a message and receive the reply */
 static int cmsis_dap_xfer(struct cmsis_dap *dap, int txlen)
 {
@@ -313,6 +328,8 @@ static int cmsis_dap_xfer(struct cmsis_dap *dap, int txlen)
        if (resp[0] != current_cmd) {
                LOG_ERROR("CMSIS-DAP command mismatch. Sent 0x%" PRIx8
                         " received 0x%" PRIx8, current_cmd, resp[0]);
+
+               cmsis_dap_flush_read(dap);
                return ERROR_FAIL;
        }
 
@@ -885,6 +902,8 @@ static int cmsis_dap_init(void)
        if (retval != ERROR_OK)
                return retval;
 
+       cmsis_dap_flush_read(cmsis_dap_handle);
+
        retval = cmsis_dap_get_caps_info();
        if (retval != ERROR_OK)
                return retval;