static int cmsis_dap_clear_sticky_errors(struct adiv5_dap *dap)
{
- LOG_DEBUG("CMSIS-ADI: %s", __func__);
+ LOG_DEBUG(" ");
const struct swd_driver *swd = jtag_interface->swd;
assert(swd);
- return swd->write_reg(swd_cmd(false, false, DP_ABORT),
- STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR);
+ swd->write_reg(dap, (CMSIS_CMD_DP | CMSIS_CMD_WRITE | CMSIS_CMD_A32(DP_ABORT)),
+ STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR);
+ return ERROR_OK;
}
static int cmsis_dap_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack)
{
- LOG_DEBUG("CMSIS-ADI: %s", __func__);
+ LOG_DEBUG(" ");
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);
+ swd->write_reg(dap, (CMSIS_CMD_DP | CMSIS_CMD_WRITE | CMSIS_CMD_A32(DP_ABORT)),
+ DAPABORT | STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR);
+ return ERROR_OK;
}
static int cmsis_dap_queue_dp_read(struct adiv5_dap *dap, unsigned reg, uint32_t *data)
{
- LOG_DEBUG("CMSIS-ADI: cmsis_dap_queue_dp_read %d", reg);
-
- int retval = jtag_interface->swd->read_reg(
- (CMSIS_CMD_DP | CMSIS_CMD_READ | CMSIS_CMD_A32(reg)), data);
+ LOG_DEBUG("reg = %d", reg);
- if (retval != ERROR_OK)
- cmsis_dap_clear_sticky_errors(dap);
+ const struct swd_driver *swd = jtag_interface->swd;
+ assert(swd);
- return retval;
+ swd->read_reg(dap, (CMSIS_CMD_DP | CMSIS_CMD_READ | CMSIS_CMD_A32(reg)), data);
+ return ERROR_OK;
}
static int (cmsis_dap_queue_dp_write)(struct adiv5_dap *dap, unsigned reg, uint32_t data)
{
- LOG_DEBUG("CMSIS-ADI: cmsis_dap_queue_dp_write %d 0x%08" PRIx32, reg, data);
+ LOG_DEBUG("reg = %d, data = 0x%08" PRIx32, reg, data);
/* setting the ORUNDETECT bit causes issues for some targets,
* disable until we find out why */
data &= ~CORUNDETECT;
}
- int retval = jtag_interface->swd->write_reg(
- (CMSIS_CMD_DP | CMSIS_CMD_WRITE | CMSIS_CMD_A32(reg)), data);
-
- if (retval != ERROR_OK)
- cmsis_dap_clear_sticky_errors(dap);
+ const struct swd_driver *swd = jtag_interface->swd;
+ assert(swd);
- return retval;
+ swd->write_reg(dap, (CMSIS_CMD_DP | CMSIS_CMD_WRITE | CMSIS_CMD_A32(reg)), data);
+ return ERROR_OK;
}
/** Select the AP register bank matching bits 7:4 of reg. */
dap->ap_bank_value = select_ap_bank;
select_ap_bank |= dap->ap_current;
- return cmsis_dap_queue_dp_write(dap, DP_SELECT, select_ap_bank);
+ cmsis_dap_queue_dp_write(dap, DP_SELECT, select_ap_bank);
+ return ERROR_OK;
}
static int (cmsis_dap_queue_ap_read)(struct adiv5_dap *dap, unsigned reg, uint32_t *data)
{
- int retval = cmsis_dap_ap_q_bankselect(dap, reg);
- if (retval != ERROR_OK)
- return retval;
+ cmsis_dap_ap_q_bankselect(dap, reg);
- LOG_DEBUG("CMSIS-ADI: cmsis_dap_queue_ap_read %d", reg);
+ LOG_DEBUG("reg = %d", reg);
- retval = jtag_interface->swd->read_reg(
- (CMSIS_CMD_AP | CMSIS_CMD_READ | CMSIS_CMD_A32(reg)), data);
+ const struct swd_driver *swd = jtag_interface->swd;
+ assert(swd);
- if (retval != ERROR_OK)
- cmsis_dap_clear_sticky_errors(dap);
+ swd->read_reg(dap, (CMSIS_CMD_AP | CMSIS_CMD_READ | CMSIS_CMD_A32(reg)), data);
- return retval;
+ return ERROR_OK;
}
static int (cmsis_dap_queue_ap_write)(struct adiv5_dap *dap, unsigned reg, uint32_t data)
{
-
-
/* TODO: CSW_DBGSWENABLE (bit31) causes issues for some targets
* disable until we find out why */
if (reg == AP_REG_CSW)
data &= ~CSW_DBGSWENABLE;
- int retval = cmsis_dap_ap_q_bankselect(dap, reg);
- if (retval != ERROR_OK)
- return retval;
+ cmsis_dap_ap_q_bankselect(dap, reg);
- LOG_DEBUG("CMSIS-ADI: cmsis_dap_queue_ap_write %d 0x%08" PRIx32, reg, data);
+ LOG_DEBUG("reg = %d, data = 0x%08" PRIx32, reg, data);
- retval = jtag_interface->swd->write_reg(
- (CMSIS_CMD_AP | CMSIS_CMD_WRITE | CMSIS_CMD_A32(reg)), data);
+ const struct swd_driver *swd = jtag_interface->swd;
+ assert(swd);
- if (retval != ERROR_OK)
- cmsis_dap_clear_sticky_errors(dap);
+ swd->write_reg(dap, (CMSIS_CMD_AP | CMSIS_CMD_WRITE | CMSIS_CMD_A32(reg)), data);
- return retval;
+ return ERROR_OK;
}
/** Executes all queued DAP operations. */
static int cmsis_dap_run(struct adiv5_dap *dap)
{
- LOG_DEBUG("CMSIS-ADI: cmsis_dap_run");
- /* FIXME: for now the CMSIS-DAP interface hard-wires a zero-size queue. */
+ LOG_DEBUG(" ");
+ /*
+ Some debug dongles do more than asked for(e.g. EDBG from
+ Atmel) behind the scene and issuing an AP write
+ may result in more than just APACC SWD transaction, which in
+ turn can possibly set sticky error bit in CTRL/STAT register
+ of the DP(an example would be writing SYSRESETREQ to AIRCR).
+ Such adapters may interpret CMSIS-DAP secification
+ differently and not guarantee to be report those failures
+ via status byte of the return USB packet from CMSIS-DAP, so
+ we need to check CTRL/STAT and if that happens to clear it.
+ Note that once the CMSIS-DAP SWD implementation starts queueing
+ transfers this will cause loss of the transfers after the
+ failed one. At least a warning is printed.
+ */
+ uint32_t ctrlstat;
+ cmsis_dap_queue_dp_read(dap, DP_CTRL_STAT, &ctrlstat);
- return ERROR_OK;
+ int retval = jtag_interface->swd->run(dap);
+
+ if (retval == ERROR_OK && (ctrlstat & SSTICKYERR))
+ LOG_WARNING("Adapter returned success despite SSTICKYERR being set.");
+
+ if (retval != ERROR_OK || (ctrlstat & SSTICKYERR))
+ cmsis_dap_clear_sticky_errors(dap);
+
+ return retval;
}
const struct dap_ops cmsis_dap_ops = {
return ERROR_FAIL;
}
- retval = swd->init(1);
+ retval = swd->init();
if (retval != ERROR_OK) {
LOG_ERROR("unable to init CMSIS-DAP driver");
return retval;
uint32_t idcode;
int status;
- LOG_DEBUG("CMSIS-ADI: cmsis_dap_init");
+ LOG_DEBUG("CMSIS-ADI init");
/* Force the DAP's ops vector for CMSIS-DAP mode.
* messy - is there a better way? */