From: Andreas Fritiofson Date: Sat, 10 May 2014 16:49:44 +0000 (+0200) Subject: adi_v5_swd: Separate sticky error clearing from AP abort X-Git-Tag: v0.9.0-rc1~364 X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=commitdiff_plain;h=0e95ec4070258649f2638780581f61a1082d171c adi_v5_swd: Separate sticky error clearing from AP abort Swd_queue_ap_abort should set DAPABORT, not only clear sticky errors. However, DAPABORT should not be set as soon as there is a single FAULT/WAIT response. It's an "emergency only" operations for use only when the AP have stalled the transfer for a long time. So these need to be separate functions. Change-Id: I37618447884faad54d846c2b07fa668ad505919d Signed-off-by: Andreas Fritiofson Reviewed-on: http://openocd.zylin.com/1956 Tested-by: jenkins Reviewed-by: Paul Fertser --- diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c index 4c9897394a..104832e6f4 100644 --- a/src/target/adi_v5_swd.c +++ b/src/target/adi_v5_swd.c @@ -72,7 +72,7 @@ static int swd_finish_read(struct adiv5_dap *dap) static int (swd_queue_dp_write)(struct adiv5_dap *dap, unsigned reg, uint32_t data); -static int swd_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack) +static int swd_clear_sticky_errors(struct adiv5_dap *dap) { const struct swd_driver *swd = jtag_interface->swd; assert(swd); @@ -81,6 +81,15 @@ static int swd_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack) STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR); } +static int swd_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack) +{ + const struct swd_driver *swd = jtag_interface->swd; + assert(swd); + + return swd->write_reg(swd_cmd(false, false, DP_ABORT), + DAPABORT | STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR); +} + /** Select the DP register bank matching bits 7:4 of reg. */ static int swd_queue_dp_bankselect(struct adiv5_dap *dap, unsigned reg) { @@ -114,8 +123,7 @@ static int swd_queue_dp_read(struct adiv5_dap *dap, unsigned reg, if (retval != ERROR_OK) { /* fault response */ - uint8_t ack = retval & 0xff; - swd_queue_ap_abort(dap, &ack); + swd_clear_sticky_errors(dap); } return retval; @@ -142,8 +150,7 @@ static int (swd_queue_dp_write)(struct adiv5_dap *dap, unsigned reg, if (retval != ERROR_OK) { /* fault response */ - uint8_t ack = retval & 0xff; - swd_queue_ap_abort(dap, &ack); + swd_clear_sticky_errors(dap); } return retval; @@ -179,8 +186,7 @@ static int (swd_queue_ap_read)(struct adiv5_dap *dap, unsigned reg, if (retval != ERROR_OK) { /* fault response */ - uint8_t ack = retval & 0xff; - swd_queue_ap_abort(dap, &ack); + swd_clear_sticky_errors(dap); return retval; } @@ -207,8 +213,7 @@ static int (swd_queue_ap_write)(struct adiv5_dap *dap, unsigned reg, if (retval != ERROR_OK) { /* fault response */ - uint8_t ack = retval & 0xff; - swd_queue_ap_abort(dap, &ack); + swd_clear_sticky_errors(dap); } return retval; @@ -447,15 +452,13 @@ static int swd_init(struct command_context *ctx) /* Note, debugport_init() does setup too */ - uint8_t ack; - status = swd_queue_dp_read(dap, DP_IDCODE, &idcode); if (status == ERROR_OK) LOG_INFO("SWD IDCODE %#8.8" PRIx32, idcode); /* force clear all sticky faults */ - swd_queue_ap_abort(dap, &ack); + swd_clear_sticky_errors(dap); /* this is a workaround to get polling working */ jtag_add_reset(0, 0);