]> git.sur5r.net Git - openocd/commitdiff
arm_adi_v5: put SWJ-DP back to JTAG mode at exit
authorAntonio Borneo <borneo.antonio@gmail.com>
Sun, 10 Jun 2018 12:39:26 +0000 (14:39 +0200)
committerMatthias Welwarsky <matthias@welwarsky.de>
Tue, 24 Jul 2018 12:06:59 +0000 (13:06 +0100)
When SWD mode is used, current OpenOCD code left the SWJ-DP in
SWD mode at exit. Also, current code is unable to switch back the
SWJ-DP in JTAG at next run, thus a power cycle of both target and
interface is required in order to run OpenOCD in JTAG mode again.

Put the SWJ-DP back to JTAG mode before exit from OpenOCD.

Use switch_seq(SWD_TO_JTAG) instead of dap_to_jtag(), because the
latter is not implemented on some interfaces. This is aligned
with the use of switch_seq(JTAG_TO_SWD) in swd_connect().

Change-Id: I55d3faebe60d6402037ec39dd9700dc5f17c53b0
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: http://openocd.zylin.com/4493
Tested-by: jenkins
Reviewed-by: Bohdan Tymkiv <bhdt@cypress.com>
Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de>
src/target/adi_v5_swd.c
src/target/arm_adi_v5.h
src/target/arm_dap.c

index 0de272dd9ae75bd9dd1b9db7568465139e06a5df..b520223b0e7940cb93080b1b3a1c4e2ba0f5cd25 100644 (file)
@@ -276,6 +276,16 @@ static int swd_run(struct adiv5_dap *dap)
        return swd_run_inner(dap);
 }
 
+/** Put the SWJ-DP back to JTAG mode */
+static void swd_quit(struct adiv5_dap *dap)
+{
+       const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
+
+       swd->switch_seq(SWD_TO_JTAG);
+       /* flush the queue before exit */
+       swd->run();
+}
+
 const struct dap_ops swd_dap_ops = {
        .connect = swd_connect,
        .queue_dp_read = swd_queue_dp_read,
@@ -284,6 +294,7 @@ const struct dap_ops swd_dap_ops = {
        .queue_ap_write = swd_queue_ap_write,
        .queue_ap_abort = swd_queue_ap_abort,
        .run = swd_run,
+       .quit = swd_quit,
 };
 
 /*
index 22c316630691331d0e686f221eac26a8ef17bc1d..883ac8b5d8df582225eba60d1f67a14a00d09a43 100644 (file)
@@ -286,6 +286,9 @@ struct dap_ops {
        /** Executes all queued DAP operations but doesn't check
         * sticky error conditions */
        int (*sync)(struct adiv5_dap *dap);
+
+       /** Optional; called at OpenOCD exit */
+       void (*quit)(struct adiv5_dap *dap);
 };
 
 /*
index 8c081800fcb37111a909955f261ff9c9560eca81..3be4d7199c1c9122d33d4ee7b335b36ade13cc55 100644 (file)
@@ -132,8 +132,13 @@ static int dap_init_all(void)
 int dap_cleanup_all(void)
 {
        struct arm_dap_object *obj, *tmp;
+       struct adiv5_dap *dap;
 
        list_for_each_entry_safe(obj, tmp, &all_dap, lh) {
+               dap = &obj->dap;
+               if (dap->ops && dap->ops->quit)
+                       dap->ops->quit(dap);
+
                free(obj->name);
                free(obj);
        }