return retval;
}
-static int cmsis_dap_swd_read_block(uint8_t cmd, uint32_t blocksize, uint8_t *dest_buf)
-{
- uint8_t *buffer;
- int tfer_sz;
- int retval = ERROR_OK;
- uint16_t read_count;
-
- DEBUG_IO("CMSIS-DAP: Read Block 0x%02" PRIx8 " %" PRIu32, cmd, blocksize);
-
- while (blocksize) {
-
- buffer = cmsis_dap_handle->packet_buffer;
- tfer_sz = blocksize;
- if (tfer_sz > 15)
- tfer_sz = 8;
-
- buffer[0] = 0; /* report number */
- buffer[1] = CMD_DAP_TFER_BLOCK;
- buffer[2] = 0x00;
- buffer[3] = tfer_sz;
- buffer[4] = 0x00;
- buffer[5] = cmd;
- retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 6);
-
- read_count = le_to_h_u16(&buffer[1]);
- if (read_count != tfer_sz) {
- LOG_ERROR("CMSIS-DAP: Block Read Error (0x%02" PRIx8 ")", buffer[3]);
- retval = buffer[3];
- }
-
- read_count *= 4;
- memcpy(dest_buf, &buffer[4], read_count);
-
- dest_buf += read_count;
- blocksize -= tfer_sz;
- }
-
- return retval;
-}
-
static int cmsis_dap_get_version_info(void)
{
uint8_t *data;
.init = cmsis_dap_swd_init,
.read_reg = cmsis_dap_swd_read_reg,
.write_reg = cmsis_dap_swd_write_reg,
- .read_block = cmsis_dap_swd_read_block
};
const char *cmsis_dap_transport[] = {"cmsis-dap", NULL};
/*
* FOR NOW ... SWD driver ops are synchronous and return ACK
- * status ... no quueueing.
+ * status ... no queuing.
*
* Individual ops are request/response, and fast-fail permits much
* better fault handling. Upper layers may queue if desired.
*/
int (*write_reg)(uint8_t cmd, uint32_t value);
- /**
- * Synchronous block read of an AP or DP register.
- *
- * @param cmd with APnDP/RnW/addr/parity bits
- * @param number of reads from register to be executed
- * @param buffer to store data read from register
- *
- * @return SWD_ACK_* code for the transaction
- * or (negative) fault code
- */
- int (*read_block)(uint8_t cmd, uint32_t blocksize, uint8_t *buffer);
-
/**
* Configures data collection from the Single-wire
* trace (SWO) signal.
return retval;
}
-static int cmsis_dap_queue_idcode_read(struct adiv5_dap *dap, uint8_t *ack, uint32_t *data)
-{
- LOG_DEBUG("CMSIS-ADI: cmsis_dap_queue_idcode_read");
-
- int retval = cmsis_dap_queue_dp_read(dap, DP_IDCODE, data);
- if (retval != ERROR_OK)
- return retval;
-
- *ack = retval;
-
- 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);
return retval;
}
-static int (cmsis_dap_queue_ap_read_block)(struct adiv5_dap *dap, unsigned reg,
- uint32_t blocksize, uint8_t *buffer)
-{
- LOG_DEBUG("CMSIS-ADI: cmsis_dap_queue_ap_read_block 0x%08" PRIx32, blocksize);
-
- int retval = jtag_interface->swd->read_block(
- (CMSIS_CMD_AP | CMSIS_CMD_READ | CMSIS_CMD_A32(AP_REG_DRW)),
- blocksize, buffer);
-
- if (retval != ERROR_OK) {
- /* fault response */
- uint8_t ack = retval & 0xff;
- cmsis_dap_queue_ap_abort(dap, &ack);
- }
-
- return retval;
-}
-
/** Executes all queued DAP operations. */
static int cmsis_dap_run(struct adiv5_dap *dap)
{
const struct dap_ops cmsis_dap_ops = {
.is_swd = true,
- .queue_idcode_read = cmsis_dap_queue_idcode_read,
.queue_dp_read = cmsis_dap_queue_dp_read,
.queue_dp_write = cmsis_dap_queue_dp_write,
.queue_ap_read = cmsis_dap_queue_ap_read,
.queue_ap_write = cmsis_dap_queue_ap_write,
- .queue_ap_read_block = cmsis_dap_queue_ap_read_block,
.queue_ap_abort = cmsis_dap_queue_ap_abort,
.run = cmsis_dap_run,
};
}
#endif
- uint8_t ack;
+ uint8_t ack = 0;
- status = cmsis_dap_queue_idcode_read(dap, &ack, &idcode);
+ status = cmsis_dap_queue_dp_read(dap, DP_IDCODE, &idcode);
if (status == ERROR_OK)
LOG_INFO("IDCODE 0x%08" PRIx32, idcode);
/*--------------------------------------------------------------------------*/
-static int jtag_idcode_q_read(struct adiv5_dap *dap,
- uint8_t *ack, uint32_t *data)
-{
- struct arm_jtag *jtag_info = dap->jtag_info;
- int retval;
- struct scan_field fields[1];
-
- /* This is a standard JTAG operation -- no DAP tweakage */
- retval = arm_jtag_set_instr(jtag_info, JTAG_DP_IDCODE, NULL, TAP_IDLE);
- if (retval != ERROR_OK)
- return retval;
-
- fields[0].num_bits = 32;
- fields[0].out_value = NULL;
- fields[0].in_value = (uint8_t *) data;
-
- jtag_add_dr_scan(jtag_info->tap, 1, fields, TAP_IDLE);
-
- jtag_add_callback(arm_le_to_h_u32,
- (jtag_callback_data_t) data);
-
- return ERROR_OK;
-}
-
static int jtag_dp_q_read(struct adiv5_dap *dap, unsigned reg,
uint32_t *data)
{
return adi_jtag_ap_write_check(dap, reg, out_value_buf);
}
-static int jtag_ap_q_read_block(struct adiv5_dap *dap, unsigned reg,
- uint32_t blocksize, uint8_t *buffer)
-{
- uint32_t readcount;
- int retval = ERROR_OK;
-
- /* Scan out first read */
- retval = adi_jtag_dp_scan(dap, JTAG_DP_APACC, reg,
- DPAP_READ, 0, NULL, NULL);
- if (retval != ERROR_OK)
- return retval;
-
- for (readcount = 0; readcount < blocksize - 1; readcount++) {
- /* Scan out next read; scan in posted value for the
- * previous one. Assumes read is acked "OK/FAULT",
- * and CTRL_STAT says that meant "OK".
- */
- retval = adi_jtag_dp_scan(dap, JTAG_DP_APACC, reg,
- DPAP_READ, 0, buffer + 4 * readcount,
- &dap->ack);
- if (retval != ERROR_OK)
- return retval;
- }
-
- /* Scan in last posted value; RDBUFF has no other effect,
- * assuming ack is OK/FAULT and CTRL_STAT says "OK".
- */
- retval = adi_jtag_dp_scan(dap, JTAG_DP_DPACC, DP_RDBUFF,
- DPAP_READ, 0, buffer + 4 * readcount,
- &dap->ack);
-
- return retval;
-}
-
static int jtag_ap_q_abort(struct adiv5_dap *dap, uint8_t *ack)
{
/* for JTAG, this is the only valid ABORT register operation */
* part of DAP setup
*/
const struct dap_ops jtag_dp_ops = {
- .queue_idcode_read = jtag_idcode_q_read,
.queue_dp_read = jtag_dp_q_read,
.queue_dp_write = jtag_dp_q_write,
.queue_ap_read = jtag_ap_q_read,
.queue_ap_write = jtag_ap_q_write,
- .queue_ap_read_block = jtag_ap_q_read_block,
.queue_ap_abort = jtag_ap_q_abort,
.run = jtag_dp_run,
};
return retval;
}
-static int swd_queue_idcode_read(struct adiv5_dap *dap,
- uint8_t *ack, uint32_t *data)
-{
- int status = swd_queue_dp_read(dap, DP_IDCODE, data);
- if (status < 0)
- return status;
- *ack = status;
- /* ?? */
- return ERROR_OK;
-}
static int (swd_queue_dp_write)(struct adiv5_dap *dap, unsigned reg,
uint32_t data)
const struct dap_ops swd_dap_ops = {
.is_swd = true,
- .queue_idcode_read = swd_queue_idcode_read,
.queue_dp_read = swd_queue_dp_read,
.queue_dp_write = swd_queue_dp_write,
.queue_ap_read = swd_queue_ap_read,
uint8_t ack;
- status = swd_queue_idcode_read(dap, &ack, &idcode);
+ status = swd_queue_dp_read(dap, DP_IDCODE, &idcode);
if (status == ERROR_OK)
LOG_INFO("SWD IDCODE %#8.8" PRIx32, idcode);
* both JTAG and SWD transports. All submitted transactions are logically
* queued, until the queue is executed by run(). Some implementations might
* execute transactions as soon as they're submitted, but no status is made
- * availablue until run().
+ * available until run().
*/
struct dap_ops {
/** If the DAP transport isn't SWD, it must be JTAG. Upper level
*/
bool is_swd;
- /** Reads the DAP's IDCODe register. */
- int (*queue_idcode_read)(struct adiv5_dap *dap,
- uint8_t *ack, uint32_t *data);
-
/** DP register read. */
int (*queue_dp_read)(struct adiv5_dap *dap, unsigned reg,
uint32_t *data);
/** AP register write. */
int (*queue_ap_write)(struct adiv5_dap *dap, unsigned reg,
uint32_t data);
- /** AP read block. */
- int (*queue_ap_read_block)(struct adiv5_dap *dap, unsigned reg,
- uint32_t blocksize, uint8_t *buffer);
/** AP operation abort. */
int (*queue_ap_abort)(struct adiv5_dap *dap, uint8_t *ack);
AP_TYPE_JTAG_AP = 0x10 /* JTAG-AP - JTAG master for controlling other JTAG devices */
};
-/**
- * Queue an IDCODE register read. This is primarily useful for SWD
- * transports, where it is required as part of link initialization.
- * (For JTAG, this register is read as part of scan chain setup.)
- *
- * @param dap The DAP used for reading.
- * @param ack Pointer to where transaction status will be stored.
- * @param data Pointer saying where to store the IDCODE value.
- *
- * @return ERROR_OK for success, else a fault code.
- */
-static inline int dap_queue_idcode_read(struct adiv5_dap *dap,
- uint8_t *ack, uint32_t *data)
-{
- assert(dap->ops != NULL);
- return dap->ops->queue_idcode_read(dap, ack, data);
-}
-
/**
* Queue a DP register read.
* Note that not all DP registers are readable; also, that JTAG and SWD
return dap->ops->queue_ap_write(dap, reg, data);
}
-/**
- * Queue an AP block read.
- *
- * @param dap The DAP used for reading.
- * @param reg The number of the AP register being read.
- * @param blocksize The number of the AP register being read.
- * @param buffer Pointer saying where to store the data
- * (in host endianness).
- *
- * @return ERROR_OK for success, else a fault code.
- */
-static inline int dap_queue_ap_read_block(struct adiv5_dap *dap,
- unsigned reg, unsigned blocksize, uint8_t *buffer)
-{
- assert(dap->ops != NULL);
- return dap->ops->queue_ap_read_block(dap, reg, blocksize, buffer);
-}
-
/**
* Queue an AP abort operation. The current AP transaction is aborted,
* including any update of the transaction counter. The AP is left in