*/
static void bitbang_stableclocks(int num_cycles);
+static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk);
+
struct bitbang_interface *bitbang_interface;
/* DANGER!!!! clock absolutely *MUST* be 0 in idle or reset won't work!
}
}
-int bitbang_swd_switch_seq(struct adiv5_dap *dap, enum swd_special_seq seq)
+int bitbang_swd_switch_seq(enum swd_special_seq seq)
{
LOG_DEBUG("bitbang_swd_switch_seq");
bitbang_exchange(false, (uint8_t *)swd_seq_jtag_to_swd, 0, swd_seq_jtag_to_swd_len);
}
-static void swd_clear_sticky_errors(struct adiv5_dap *dap)
+static void swd_clear_sticky_errors(void)
{
- const struct swd_driver *swd = jtag_interface->swd;
- assert(swd);
-
- swd->write_reg(dap, swd_cmd(false, false, DP_ABORT),
- STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR);
+ bitbang_swd_write_reg(swd_cmd(false, false, DP_ABORT),
+ STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0);
}
-static void bitbang_swd_read_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t *value)
+static void bitbang_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
{
LOG_DEBUG("bitbang_swd_read_reg");
assert(cmd & SWD_CMD_RnW);
if (value)
*value = data;
if (cmd & SWD_CMD_APnDP)
- bitbang_exchange(true, NULL, 0, dap->ap[dap_ap_get_select(dap)].memaccess_tck);
+ bitbang_exchange(true, NULL, 0, ap_delay_clk);
return;
case SWD_ACK_WAIT:
LOG_DEBUG("SWD_ACK_WAIT");
- swd_clear_sticky_errors(dap);
+ swd_clear_sticky_errors();
break;
case SWD_ACK_FAULT:
LOG_DEBUG("SWD_ACK_FAULT");
}
}
-static void bitbang_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t value)
+static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
{
LOG_DEBUG("bitbang_swd_write_reg");
assert(!(cmd & SWD_CMD_RnW));
switch (ack) {
case SWD_ACK_OK:
if (cmd & SWD_CMD_APnDP)
- bitbang_exchange(true, NULL, 0, dap->ap[dap_ap_get_select(dap)].memaccess_tck);
+ bitbang_exchange(true, NULL, 0, ap_delay_clk);
return;
case SWD_ACK_WAIT:
LOG_DEBUG("SWD_ACK_WAIT");
- swd_clear_sticky_errors(dap);
+ swd_clear_sticky_errors();
break;
case SWD_ACK_FAULT:
LOG_DEBUG("SWD_ACK_FAULT");
}
}
-static int bitbang_swd_run_queue(struct adiv5_dap *dap)
+static int bitbang_swd_run_queue(void)
{
LOG_DEBUG("bitbang_swd_run_queue");
/* A transaction must be followed by another transaction or at least 8 idle cycles to
extern struct bitbang_interface *bitbang_interface;
void bitbang_switch_to_swd(void);
-int bitbang_swd_switch_seq(struct adiv5_dap *dap, enum swd_special_seq seq);
+int bitbang_swd_switch_seq(enum swd_special_seq seq);
#endif /* BITBANG_H */
}
#endif
-static int cmsis_dap_swd_run_queue(struct adiv5_dap *dap)
+static int cmsis_dap_swd_run_queue(void)
{
uint8_t *buffer = cmsis_dap_handle->packet_buffer;
return retval;
}
-static void cmsis_dap_swd_queue_cmd(struct adiv5_dap *dap, uint8_t cmd, uint32_t *dst, uint32_t data)
+static void cmsis_dap_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data)
{
if (pending_transfer_count == pending_queue_len) {
/* Not enough room in the queue. Run the queue. */
- queued_retval = cmsis_dap_swd_run_queue(dap);
+ queued_retval = cmsis_dap_swd_run_queue();
}
if (queued_retval != ERROR_OK)
pending_transfer_count++;
}
-static void cmsis_dap_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t value)
+static void cmsis_dap_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
{
assert(!(cmd & SWD_CMD_RnW));
- cmsis_dap_swd_queue_cmd(dap, cmd, NULL, value);
+ cmsis_dap_swd_queue_cmd(cmd, NULL, value);
}
-static void cmsis_dap_swd_read_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t *value)
+static void cmsis_dap_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
{
assert(cmd & SWD_CMD_RnW);
- cmsis_dap_swd_queue_cmd(dap, cmd, value, 0);
+ cmsis_dap_swd_queue_cmd(cmd, value, 0);
}
static int cmsis_dap_get_version_info(void)
return retval;
}
-static int cmsis_dap_swd_switch_seq(struct adiv5_dap *dap, enum swd_special_seq seq)
+static int cmsis_dap_swd_switch_seq(enum swd_special_seq seq)
{
uint8_t *buffer = cmsis_dap_handle->packet_buffer;
const uint8_t *s;
return ERROR_OK;
}
-static int_least32_t cmsis_dap_swd_frequency(struct adiv5_dap *dap, int_least32_t hz)
+static int_least32_t cmsis_dap_swd_frequency(int_least32_t hz)
{
if (hz > 0)
cmsis_dap_speed(hz / 1000);
static uint16_t jtag_output_init;
static uint16_t jtag_direction_init;
-static int ftdi_swd_switch_seq(struct adiv5_dap *dap, enum swd_special_seq seq);
+static int ftdi_swd_switch_seq(enum swd_special_seq seq);
static struct signal *find_signal_by_name(const char *name)
{
* @param dap
* @return
*/
-static int ftdi_swd_run_queue(struct adiv5_dap *dap)
+static int ftdi_swd_run_queue(void)
{
LOG_DEBUG("Executing %zu queued transactions", swd_cmd_queue_length);
int retval;
return retval;
}
-static void ftdi_swd_queue_cmd(struct adiv5_dap *dap, uint8_t cmd, uint32_t *dst, uint32_t data)
+static void ftdi_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data, uint32_t ap_delay_clk)
{
if (swd_cmd_queue_length >= swd_cmd_queue_alloced) {
/* Not enough room in the queue. Run the queue and increase its size for next time.
* Note that it's not possible to avoid running the queue here, because mpsse contains
* pointers into the queue which may be invalid after the realloc. */
- queued_retval = ftdi_swd_run_queue(dap);
+ queued_retval = ftdi_swd_run_queue();
struct swd_cmd_queue_entry *q = realloc(swd_cmd_queue, swd_cmd_queue_alloced * 2 * sizeof(*swd_cmd_queue));
if (q != NULL) {
swd_cmd_queue = q;
/* Insert idle cycles after AP accesses to avoid WAIT */
if (cmd & SWD_CMD_APnDP)
- mpsse_clock_data_out(mpsse_ctx, NULL, 0, dap->ap[dap_ap_get_select(dap)].memaccess_tck, SWD_MODE);
+ mpsse_clock_data_out(mpsse_ctx, NULL, 0, ap_delay_clk, SWD_MODE);
}
-static void ftdi_swd_read_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t *value)
+static void ftdi_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
{
assert(cmd & SWD_CMD_RnW);
- ftdi_swd_queue_cmd(dap, cmd, value, 0);
+ ftdi_swd_queue_cmd(cmd, value, 0, ap_delay_clk);
}
-static void ftdi_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t value)
+static void ftdi_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
{
assert(!(cmd & SWD_CMD_RnW));
- ftdi_swd_queue_cmd(dap, cmd, NULL, value);
+ ftdi_swd_queue_cmd(cmd, NULL, value, ap_delay_clk);
}
-static int_least32_t ftdi_swd_frequency(struct adiv5_dap *dap, int_least32_t hz)
+static int_least32_t ftdi_swd_frequency(int_least32_t hz)
{
if (hz > 0)
freq = mpsse_set_frequency(mpsse_ctx, hz);
return freq;
}
-static int ftdi_swd_switch_seq(struct adiv5_dap *dap, enum swd_special_seq seq)
+static int ftdi_swd_switch_seq(enum swd_special_seq seq)
{
switch (seq) {
case LINE_RESET:
static void jlink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer,
int scan_size, struct scan_command *command);
static void jlink_reset(int trst, int srst);
-static int jlink_swd_run_queue(struct adiv5_dap *dap);
-static void jlink_swd_queue_cmd(struct adiv5_dap *dap, uint8_t cmd,
- uint32_t *dst, uint32_t data);
-static int jlink_swd_switch_seq(struct adiv5_dap *dap,
- enum swd_special_seq seq);
+static int jlink_swd_run_queue(void);
+static void jlink_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data, uint32_t ap_delay_clk);
+static int jlink_swd_switch_seq(enum swd_special_seq seq);
/* J-Link tap buffer functions */
static void jlink_tap_init(void);
return ERROR_OK;
}
-static void jlink_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd,
- uint32_t value)
+static void jlink_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
{
assert(!(cmd & SWD_CMD_RnW));
- jlink_swd_queue_cmd(dap, cmd, NULL, value);
+ jlink_swd_queue_cmd(cmd, NULL, value, ap_delay_clk);
}
-static void jlink_swd_read_reg(struct adiv5_dap *dap, uint8_t cmd,
- uint32_t *value)
+static void jlink_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
{
assert(cmd & SWD_CMD_RnW);
- jlink_swd_queue_cmd(dap, cmd, value, 0);
+ jlink_swd_queue_cmd(cmd, value, 0, ap_delay_clk);
}
-static int_least32_t jlink_swd_frequency(struct adiv5_dap *dap,
- int_least32_t hz)
+static int_least32_t jlink_swd_frequency(int_least32_t hz)
{
if (hz > 0)
jlink_speed(hz / 1000);
tap_length += len;
}
-static int jlink_swd_switch_seq(struct adiv5_dap *dap, enum swd_special_seq seq)
+static int jlink_swd_switch_seq(enum swd_special_seq seq)
{
const uint8_t *s;
unsigned int s_len;
return ERROR_OK;
}
-static int jlink_swd_run_queue(struct adiv5_dap *dap)
+static int jlink_swd_run_queue(void)
{
int i;
int ret;
return ret;
}
-static void jlink_swd_queue_cmd(struct adiv5_dap *dap, uint8_t cmd,
- uint32_t *dst, uint32_t data)
+static void jlink_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data, uint32_t ap_delay_clk)
{
uint8_t data_parity_trn[DIV_ROUND_UP(32 + 1, 8)];
- if (tap_length + 46 + 8 + dap->ap[dap_ap_get_select(dap)].memaccess_tck >= sizeof(tdi_buffer) * 8 ||
+ if (tap_length + 46 + 8 + ap_delay_clk >= sizeof(tdi_buffer) * 8 ||
pending_scan_results_length == MAX_PENDING_SCAN_RESULTS) {
/* Not enough room in the queue. Run the queue. */
- queued_retval = jlink_swd_run_queue(dap);
+ queued_retval = jlink_swd_run_queue();
}
if (queued_retval != ERROR_OK)
/* Insert idle cycles after AP accesses to avoid WAIT. */
if (cmd & SWD_CMD_APnDP)
- jlink_queue_data_out(NULL, dap->ap[dap_ap_get_select(dap)].memaccess_tck);
+ jlink_queue_data_out(NULL, ap_delay_clk);
}
static const struct swd_driver jlink_swd = {
if (sysfsgpio_swd_mode_possible()) {
if (swd_mode)
- bitbang_swd_switch_seq(NULL, JTAG_TO_SWD);
+ bitbang_swd_switch_seq(JTAG_TO_SWD);
else
- bitbang_swd_switch_seq(NULL, SWD_TO_JTAG);
+ bitbang_swd_switch_seq(SWD_TO_JTAG);
}
return ERROR_OK;
struct scan_command *command);
/* VSLLink SWD functions */
-static int_least32_t vsllink_swd_frequency(struct adiv5_dap *dap,
- int_least32_t hz);
-static int vsllink_swd_switch_seq(struct adiv5_dap *dap,
- enum swd_special_seq seq);
+static int_least32_t vsllink_swd_frequency(int_least32_t hz);
+static int vsllink_swd_switch_seq(enum swd_special_seq seq);
/* VSLLink lowlevel functions */
struct vsllink {
static int vsllink_speed(int speed)
{
if (swd_mode) {
- vsllink_swd_frequency(NULL, speed * 1000);
+ vsllink_swd_frequency(speed * 1000);
return ERROR_OK;
}
versaloon_interface.adaptors.gpio.config(0, GPIO_TRST, 0,
GPIO_TRST, GPIO_TRST);
versaloon_interface.adaptors.swd.init(0);
- vsllink_swd_frequency(NULL, jtag_get_speed_khz() * 1000);
- vsllink_swd_switch_seq(NULL, JTAG_TO_SWD);
+ vsllink_swd_frequency(jtag_get_speed_khz() * 1000);
+ vsllink_swd_switch_seq(JTAG_TO_SWD);
} else {
/* malloc buffer size for tap */
return ERROR_OK;
}
-static int_least32_t vsllink_swd_frequency(struct adiv5_dap *dap,
- int_least32_t hz)
+static int_least32_t vsllink_swd_frequency(int_least32_t hz)
{
const int_least32_t delay2hz[] = {
1850000, 235000, 130000, 102000, 85000, 72000
return hz;
}
-static int vsllink_swd_switch_seq(struct adiv5_dap *dap,
- enum swd_special_seq seq)
+static int vsllink_swd_switch_seq(enum swd_special_seq seq)
{
switch (seq) {
case LINE_RESET:
return ERROR_OK;
}
-static void vsllink_swd_read_reg(struct adiv5_dap *dap, uint8_t cmd,
- uint32_t *value)
+static void vsllink_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
{
versaloon_interface.adaptors.swd.transact(0, cmd, value, NULL);
}
-static void vsllink_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd,
- uint32_t value)
+static void vsllink_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
{
versaloon_interface.adaptors.swd.transact(0, cmd, &value, NULL);
}
-static int vsllink_swd_run_queue(struct adiv5_dap *dap)
+static int vsllink_swd_run_queue(void)
{
return versaloon_interface.adaptors.peripheral_commit();
}
* queued transactions are executed. If the frequency is lowered, it may
* apply immediately.
*
- * @param dap The DAP controlled by the SWD link.
* @param hz The desired frequency in Hz.
* @return The actual resulting frequency after rounding.
*/
- int_least32_t (*frequency)(struct adiv5_dap *dap, int_least32_t hz);
+ int_least32_t (*frequency)(int_least32_t hz);
/**
* Queue a special SWDIO sequence.
*
- * @param dap The DAP controlled by the SWD link.
* @param seq The special sequence to generate.
* @return ERROR_OK if the sequence was queued, negative error if the
* sequence is unsupported.
*/
- int (*switch_seq)(struct adiv5_dap *dap, enum swd_special_seq seq);
+ int (*switch_seq)(enum swd_special_seq seq);
/**
* Queued read of an AP or DP register.
*
- * @param dap The DAP controlled by the SWD link.
* @param Command byte with APnDP/RnW/addr/parity bits
* @param Where to store value to read from register
+ * @param ap_delay_hint Number of idle cycles that may be
+ * needed after an AP access to avoid WAITs
*/
- void (*read_reg)(struct adiv5_dap *dap, uint8_t cmd, uint32_t *value);
+ void (*read_reg)(uint8_t cmd, uint32_t *value, uint32_t ap_delay_hint);
/**
* Queued write of an AP or DP register.
*
- * @param dap The DAP controlled by the SWD link.
* @param Command byte with APnDP/RnW/addr/parity bits
* @param Value to be written to the register
+ * @param ap_delay_hint Number of idle cycles that may be
+ * needed after an AP access to avoid WAITs
*/
- void (*write_reg)(struct adiv5_dap *dap, uint8_t cmd, uint32_t value);
+ void (*write_reg)(uint8_t cmd, uint32_t value, uint32_t ap_delay_hint);
/**
* Execute any queued transactions and collect the result.
*
- * @param dap The DAP controlled by the SWD link.
* @return ERROR_OK on success, Ack response code on WAIT/FAULT
* or negative error code on other kinds of failure.
*/
- int (*run)(struct adiv5_dap *dap);
+ int (*run)(void);
/**
* Configures data collection from the Single-wire
*
* @return ERROR_OK on success, else a negative fault code.
*/
- int *(*trace)(struct adiv5_dap *dap, bool swo);
+ int *(*trace)(bool swo);
};
int swd_init_reset(struct command_context *cmd_ctx);
{
const struct swd_driver *swd = jtag_interface->swd;
if (dap->last_read != NULL) {
- swd->read_reg(dap, swd_cmd(true, false, DP_RDBUFF), dap->last_read);
+ swd->read_reg(swd_cmd(true, false, DP_RDBUFF), dap->last_read, 0);
dap->last_read = NULL;
}
}
const struct swd_driver *swd = jtag_interface->swd;
assert(swd);
- swd->write_reg(dap, swd_cmd(false, false, DP_ABORT),
- STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR);
+ swd->write_reg(swd_cmd(false, false, DP_ABORT),
+ STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0);
}
static int swd_run_inner(struct adiv5_dap *dap)
const struct swd_driver *swd = jtag_interface->swd;
int retval;
- retval = swd->run(dap);
+ retval = swd->run();
if (retval != ERROR_OK) {
/* fault response */
*/
/* Note, debugport_init() does setup too */
- jtag_interface->swd->switch_seq(dap, JTAG_TO_SWD);
+ jtag_interface->swd->switch_seq(JTAG_TO_SWD);
dap->do_reconnect = false;
const struct swd_driver *swd = jtag_interface->swd;
assert(swd);
- swd->write_reg(dap, swd_cmd(false, false, DP_ABORT),
- DAPABORT | STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR);
+ swd->write_reg(swd_cmd(false, false, DP_ABORT),
+ DAPABORT | STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0);
return check_sync(dap);
}
return retval;
swd_queue_dp_bankselect(dap, reg);
- swd->read_reg(dap, swd_cmd(true, false, reg), data);
+ swd->read_reg(swd_cmd(true, false, reg), data, 0);
return check_sync(dap);
}
swd_finish_read(dap);
swd_queue_dp_bankselect(dap, reg);
- swd->write_reg(dap, swd_cmd(false, false, reg), data);
+ swd->write_reg(swd_cmd(false, false, reg), data, 0);
return check_sync(dap);
}
return retval;
swd_queue_ap_bankselect(dap, reg);
- swd->read_reg(dap, swd_cmd(true, true, reg), dap->last_read);
+ swd->read_reg(swd_cmd(true, true, reg), dap->last_read, dap->ap[dap_ap_get_select(dap)].memaccess_tck);
dap->last_read = data;
return check_sync(dap);
swd_finish_read(dap);
swd_queue_ap_bankselect(dap, reg);
- swd->write_reg(dap, swd_cmd(false, true, reg), data);
+ swd->write_reg(swd_cmd(false, true, reg), data, dap->ap[dap_ap_get_select(dap)].memaccess_tck);
return check_sync(dap);
}