This is an automated email from Gerrit.

Paul Fertser ([email protected]) just uploaded a new patch set to Gerrit, 
which you can find at http://openocd.zylin.com/3097

-- gerrit

commit ceb3b4d6e9f21da2213fad592662af5cd964aef3
Author: Paul Fertser <[email protected]>
Date:   Wed Nov 4 19:52:35 2015 +0300

    drivers: jlink: introduce ad-hoc SWD WAIT handling
    
    Change-Id: I88d07e594a0f4f32d85acbb883e9d47fc537defb
    Signed-off-by: Paul Fertser <[email protected]>

diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c
index 7a4a0ea..4ec760e 100644
--- a/src/jtag/drivers/jlink.c
+++ b/src/jtag/drivers/jlink.c
@@ -1838,36 +1838,65 @@ static int jlink_swd_run_queue(struct adiv5_dap *dap)
         */
        jlink_queue_data_out(NULL, 8);
 
-       ret = jaylink_swd_io(devh, tms_buffer, tdi_buffer, tdo_buffer, 
tap_length);
+       unsigned int tries;
+       size_t tap_position = 0;
+       i = 0;
 
-       if (ret != JAYLINK_OK) {
-               LOG_ERROR("jaylink_swd_io() failed: %s.", 
jaylink_strerror_name(ret));
-               goto skip;
-       }
+       for (tries = 10; tries; tries--) {
+               assert(!(tap_position % 8));
+               ret = jaylink_swd_io(devh, tms_buffer + tap_position / 8,
+                                    tdi_buffer + tap_position / 8,
+                                    tdo_buffer + tap_position / 8,
+                                    tap_length - tap_position);
 
-       for (i = 0; i < pending_scan_results_length; i++) {
-               int ack = buf_get_u32(tdo_buffer, 
pending_scan_results_buffer[i].first, 3);
-
-               if (ack != SWD_ACK_OK) {
-                       LOG_DEBUG("SWD ack not OK: %d %s", ack,
-                                 ack == SWD_ACK_WAIT ? "WAIT" : ack == 
SWD_ACK_FAULT ? "FAULT" : "JUNK");
-                       queued_retval = ack == SWD_ACK_WAIT ? ERROR_WAIT : 
ERROR_FAIL;
+               if (ret != JAYLINK_OK) {
+                       LOG_ERROR("jaylink_swd_io() failed: %s.", 
jaylink_strerror_name(ret));
                        goto skip;
-               } else if (pending_scan_results_buffer[i].length) {
-                       uint32_t data = buf_get_u32(tdo_buffer, 3 + 
pending_scan_results_buffer[i].first, 32);
-                       int parity = buf_get_u32(tdo_buffer, 3 + 32 + 
pending_scan_results_buffer[i].first, 1);
+               }
 
-                       if (parity != parity_u32(data)) {
-                               LOG_ERROR("SWD: Read data parity mismatch.");
-                               queued_retval = ERROR_FAIL;
+               for (; i < pending_scan_results_length; i++) {
+                       int ack = buf_get_u32(tdo_buffer, 
pending_scan_results_buffer[i].first, 3);
+
+                       if (ack != SWD_ACK_OK) {
+                               LOG_ERROR("SWD ack not OK: %d %s", ack,
+                                         ack == SWD_ACK_WAIT ? "WAIT" : ack == 
SWD_ACK_FAULT ? "FAULT" : "JUNK");
+                               queued_retval = ack == SWD_ACK_WAIT ? 
ERROR_WAIT : ERROR_FAIL;
+                               if (ack == SWD_ACK_WAIT) {
+                                       /* Try to clear STICKYORUN; if it fails 
anyhow, the next
+                                        * transaction will fail too and then 
get handled properly */
+                                       uint8_t dir[6] = { 0xff, 0xe0, 0xff, 
0xff, 0xff, 0xff };
+                                       uint8_t out[6] = { 0x81, 0x00, 0x02, 
0x00, 0x00, 0x04 };
+                                       uint8_t in[6];
+                                       jaylink_swd_io(devh, dir, out, in, 48);
+
+                                       /* Roll back to the failed transaction 
*/
+                                       tap_position = 
pending_scan_results_buffer[i].first - 8;
+                                       break;
+                               }
                                goto skip;
-                       }
+                       } else if (pending_scan_results_buffer[i].length) {
+                               uint32_t data = buf_get_u32(tdo_buffer, 3 + 
pending_scan_results_buffer[i].first, 32);
+                               int parity = buf_get_u32(tdo_buffer, 3 + 32 + 
pending_scan_results_buffer[i].first, 1);
+
+                               if (parity != parity_u32(data)) {
+                                       LOG_ERROR("SWD: Read data parity 
mismatch.");
+                                       queued_retval = ERROR_FAIL;
+                                       goto skip;
+                               }
 
-                       if (pending_scan_results_buffer[i].buffer)
-                               *(uint32_t 
*)pending_scan_results_buffer[i].buffer = data;
+                               if (pending_scan_results_buffer[i].buffer)
+                                       *(uint32_t 
*)pending_scan_results_buffer[i].buffer = data;
+
+                               queued_retval = ERROR_OK;
+                       }
                }
+               if (i == pending_scan_results_length)
+                       break;
        }
 
+       if (!tries)
+               LOG_ERROR("Got too many SWD WAIT replies, giving up");
+
 skip:
        jlink_tap_init();
        ret = queued_retval;
@@ -1913,6 +1942,10 @@ static void jlink_swd_queue_cmd(struct adiv5_dap *dap, 
uint8_t cmd,
                jlink_queue_data_out(data_parity_trn, 32 + 1);
        }
 
+       /* Align the next command on byte boundary */
+       uint8_t dummy = 0;
+       jlink_queue_data_out(&dummy, 2);
+
        pending_scan_results_length++;
 
        /* Insert idle cycles after AP accesses to avoid WAIT. */

-- 

------------------------------------------------------------------------------
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to