swd: Remove DAP from parameter list

Making the SWD driver aware of the DAP that controls it is a layering
violation.

The only usage for the DAP pointer is to store the number of idle cycles
the AP may need to avoid WAITs. Replace the DAP pointer with a cycle
count hint instead to avoid future misuse.

Change-Id: I3e64e11a43ba2396bd646a4cf8f9bc331805d802
Signed-off-by: Andreas Fritiofson <andreas.fritiofson@gmail.com>
Reviewed-on: http://openocd.zylin.com/3141
Tested-by: jenkins
Reviewed-by: Paul Fertser <fercerpav@gmail.com>
This commit is contained in:
Andreas Fritiofson 2015-11-13 23:48:46 +01:00
parent bf4cf76631
commit a6c4eb0345
9 changed files with 81 additions and 95 deletions

View File

@ -45,6 +45,8 @@ extern struct jtag_interface *jtag_interface;
*/ */
static void bitbang_stableclocks(int num_cycles); 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; struct bitbang_interface *bitbang_interface;
/* DANGER!!!! clock absolutely *MUST* be 0 in idle or reset won't work! /* DANGER!!!! clock absolutely *MUST* be 0 in idle or reset won't work!
@ -378,7 +380,7 @@ static void bitbang_exchange(bool rnw, uint8_t buf[], unsigned int offset, unsig
} }
} }
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"); LOG_DEBUG("bitbang_swd_switch_seq");
@ -409,16 +411,13 @@ void bitbang_switch_to_swd(void)
bitbang_exchange(false, (uint8_t *)swd_seq_jtag_to_swd, 0, swd_seq_jtag_to_swd_len); 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; bitbang_swd_write_reg(swd_cmd(false, false, DP_ABORT),
assert(swd); STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0);
swd->write_reg(dap, swd_cmd(false, false, DP_ABORT),
STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR);
} }
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"); LOG_DEBUG("bitbang_swd_read_reg");
assert(cmd & SWD_CMD_RnW); assert(cmd & SWD_CMD_RnW);
@ -459,11 +458,11 @@ static void bitbang_swd_read_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t *v
if (value) if (value)
*value = data; *value = data;
if (cmd & SWD_CMD_APnDP) 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; return;
case SWD_ACK_WAIT: case SWD_ACK_WAIT:
LOG_DEBUG("SWD_ACK_WAIT"); LOG_DEBUG("SWD_ACK_WAIT");
swd_clear_sticky_errors(dap); swd_clear_sticky_errors();
break; break;
case SWD_ACK_FAULT: case SWD_ACK_FAULT:
LOG_DEBUG("SWD_ACK_FAULT"); LOG_DEBUG("SWD_ACK_FAULT");
@ -477,7 +476,7 @@ static void bitbang_swd_read_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t *v
} }
} }
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"); LOG_DEBUG("bitbang_swd_write_reg");
assert(!(cmd & SWD_CMD_RnW)); assert(!(cmd & SWD_CMD_RnW));
@ -511,11 +510,11 @@ static void bitbang_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t v
switch (ack) { switch (ack) {
case SWD_ACK_OK: case SWD_ACK_OK:
if (cmd & SWD_CMD_APnDP) 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; return;
case SWD_ACK_WAIT: case SWD_ACK_WAIT:
LOG_DEBUG("SWD_ACK_WAIT"); LOG_DEBUG("SWD_ACK_WAIT");
swd_clear_sticky_errors(dap); swd_clear_sticky_errors();
break; break;
case SWD_ACK_FAULT: case SWD_ACK_FAULT:
LOG_DEBUG("SWD_ACK_FAULT"); LOG_DEBUG("SWD_ACK_FAULT");
@ -529,7 +528,7 @@ static void bitbang_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t v
} }
} }
static int bitbang_swd_run_queue(struct adiv5_dap *dap) static int bitbang_swd_run_queue(void)
{ {
LOG_DEBUG("bitbang_swd_run_queue"); LOG_DEBUG("bitbang_swd_run_queue");
/* A transaction must be followed by another transaction or at least 8 idle cycles to /* A transaction must be followed by another transaction or at least 8 idle cycles to

View File

@ -45,6 +45,6 @@ int bitbang_execute_queue(void);
extern struct bitbang_interface *bitbang_interface; extern struct bitbang_interface *bitbang_interface;
void bitbang_switch_to_swd(void); 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 /* BITBANG_H */

View File

@ -515,7 +515,7 @@ static int cmsis_dap_cmd_DAP_Delay(uint16_t delay_us)
} }
#endif #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; uint8_t *buffer = cmsis_dap_handle->packet_buffer;
@ -619,11 +619,11 @@ skip:
return retval; 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) { if (pending_transfer_count == pending_queue_len) {
/* Not enough room in the queue. Run the queue. */ /* 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) if (queued_retval != ERROR_OK)
@ -638,16 +638,16 @@ static void cmsis_dap_swd_queue_cmd(struct adiv5_dap *dap, uint8_t cmd, uint32_t
pending_transfer_count++; 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)); 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); 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) static int cmsis_dap_get_version_info(void)
@ -707,7 +707,7 @@ static int cmsis_dap_get_status(void)
return retval; 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; uint8_t *buffer = cmsis_dap_handle->packet_buffer;
const uint8_t *s; const uint8_t *s;
@ -1002,7 +1002,7 @@ static int cmsis_dap_khz(int khz, int *jtag_speed)
return ERROR_OK; 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) if (hz > 0)
cmsis_dap_speed(hz / 1000); cmsis_dap_speed(hz / 1000);

View File

@ -128,7 +128,7 @@ static uint16_t direction;
static uint16_t jtag_output_init; static uint16_t jtag_output_init;
static uint16_t jtag_direction_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) static struct signal *find_signal_by_name(const char *name)
{ {
@ -941,7 +941,7 @@ static void ftdi_swd_swdio_en(bool enable)
* @param dap * @param dap
* @return * @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); LOG_DEBUG("Executing %zu queued transactions", swd_cmd_queue_length);
int retval; int retval;
@ -1008,13 +1008,13 @@ skip:
return 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) { 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. /* 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 * 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. */ * 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)); struct swd_cmd_queue_entry *q = realloc(swd_cmd_queue, swd_cmd_queue_alloced * 2 * sizeof(*swd_cmd_queue));
if (q != NULL) { if (q != NULL) {
swd_cmd_queue = q; swd_cmd_queue = q;
@ -1057,23 +1057,23 @@ static void ftdi_swd_queue_cmd(struct adiv5_dap *dap, uint8_t cmd, uint32_t *dst
/* Insert idle cycles after AP accesses to avoid WAIT */ /* Insert idle cycles after AP accesses to avoid WAIT */
if (cmd & SWD_CMD_APnDP) 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); 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)); 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) if (hz > 0)
freq = mpsse_set_frequency(mpsse_ctx, hz); freq = mpsse_set_frequency(mpsse_ctx, hz);
@ -1081,7 +1081,7 @@ static int_least32_t ftdi_swd_frequency(struct adiv5_dap *dap, int_least32_t hz)
return freq; 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) { switch (seq) {
case LINE_RESET: case LINE_RESET:

View File

@ -87,11 +87,9 @@ static void jlink_runtest(int num_cycles);
static void jlink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, static void jlink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer,
int scan_size, struct scan_command *command); int scan_size, struct scan_command *command);
static void jlink_reset(int trst, int srst); static void jlink_reset(int trst, int srst);
static int jlink_swd_run_queue(struct adiv5_dap *dap); static int jlink_swd_run_queue(void);
static void jlink_swd_queue_cmd(struct adiv5_dap *dap, uint8_t cmd, static void jlink_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data, uint32_t ap_delay_clk);
uint32_t *dst, uint32_t data); static int jlink_swd_switch_seq(enum swd_special_seq seq);
static int jlink_swd_switch_seq(struct adiv5_dap *dap,
enum swd_special_seq seq);
/* J-Link tap buffer functions */ /* J-Link tap buffer functions */
static void jlink_tap_init(void); static void jlink_tap_init(void);
@ -1568,22 +1566,19 @@ static int jlink_swd_init(void)
return ERROR_OK; return ERROR_OK;
} }
static void jlink_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd, static void jlink_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
uint32_t value)
{ {
assert(!(cmd & SWD_CMD_RnW)); 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, static void jlink_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
uint32_t *value)
{ {
assert(cmd & SWD_CMD_RnW); 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, static int_least32_t jlink_swd_frequency(int_least32_t hz)
int_least32_t hz)
{ {
if (hz > 0) if (hz > 0)
jlink_speed(hz / 1000); jlink_speed(hz / 1000);
@ -1762,7 +1757,7 @@ static void jlink_queue_data_in(uint32_t len)
tap_length += len; 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; const uint8_t *s;
unsigned int s_len; unsigned int s_len;
@ -1793,7 +1788,7 @@ static int jlink_swd_switch_seq(struct adiv5_dap *dap, enum swd_special_seq seq)
return ERROR_OK; return ERROR_OK;
} }
static int jlink_swd_run_queue(struct adiv5_dap *dap) static int jlink_swd_run_queue(void)
{ {
int i; int i;
int ret; int ret;
@ -1849,14 +1844,13 @@ skip:
return ret; return ret;
} }
static void jlink_swd_queue_cmd(struct adiv5_dap *dap, uint8_t cmd, static void jlink_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data, uint32_t ap_delay_clk)
uint32_t *dst, uint32_t data)
{ {
uint8_t data_parity_trn[DIV_ROUND_UP(32 + 1, 8)]; 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) { pending_scan_results_length == MAX_PENDING_SCAN_RESULTS) {
/* Not enough room in the queue. Run the queue. */ /* 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) if (queued_retval != ERROR_OK)
@ -1889,7 +1883,7 @@ static void jlink_swd_queue_cmd(struct adiv5_dap *dap, uint8_t cmd,
/* Insert idle cycles after AP accesses to avoid WAIT. */ /* Insert idle cycles after AP accesses to avoid WAIT. */
if (cmd & SWD_CMD_APnDP) 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 = { static const struct swd_driver jlink_swd = {

View File

@ -663,9 +663,9 @@ static int sysfsgpio_init(void)
if (sysfsgpio_swd_mode_possible()) { if (sysfsgpio_swd_mode_possible()) {
if (swd_mode) if (swd_mode)
bitbang_swd_switch_seq(NULL, JTAG_TO_SWD); bitbang_swd_switch_seq(JTAG_TO_SWD);
else else
bitbang_swd_switch_seq(NULL, SWD_TO_JTAG); bitbang_swd_switch_seq(SWD_TO_JTAG);
} }
return ERROR_OK; return ERROR_OK;

View File

@ -72,10 +72,8 @@ static void vsllink_tap_append_scan(int length, uint8_t *buffer,
struct scan_command *command); struct scan_command *command);
/* VSLLink SWD functions */ /* VSLLink SWD functions */
static int_least32_t vsllink_swd_frequency(struct adiv5_dap *dap, static int_least32_t vsllink_swd_frequency(int_least32_t hz);
int_least32_t hz); static int vsllink_swd_switch_seq(enum swd_special_seq seq);
static int vsllink_swd_switch_seq(struct adiv5_dap *dap,
enum swd_special_seq seq);
/* VSLLink lowlevel functions */ /* VSLLink lowlevel functions */
struct vsllink { struct vsllink {
@ -243,7 +241,7 @@ static int vsllink_execute_queue(void)
static int vsllink_speed(int speed) static int vsllink_speed(int speed)
{ {
if (swd_mode) { if (swd_mode) {
vsllink_swd_frequency(NULL, speed * 1000); vsllink_swd_frequency(speed * 1000);
return ERROR_OK; return ERROR_OK;
} }
@ -349,8 +347,8 @@ static int vsllink_init(void)
versaloon_interface.adaptors.gpio.config(0, GPIO_TRST, 0, versaloon_interface.adaptors.gpio.config(0, GPIO_TRST, 0,
GPIO_TRST, GPIO_TRST); GPIO_TRST, GPIO_TRST);
versaloon_interface.adaptors.swd.init(0); versaloon_interface.adaptors.swd.init(0);
vsllink_swd_frequency(NULL, jtag_get_speed_khz() * 1000); vsllink_swd_frequency(jtag_get_speed_khz() * 1000);
vsllink_swd_switch_seq(NULL, JTAG_TO_SWD); vsllink_swd_switch_seq(JTAG_TO_SWD);
} else { } else {
/* malloc buffer size for tap */ /* malloc buffer size for tap */
@ -730,8 +728,7 @@ static int vsllink_swd_init(void)
return ERROR_OK; return ERROR_OK;
} }
static int_least32_t vsllink_swd_frequency(struct adiv5_dap *dap, static int_least32_t vsllink_swd_frequency(int_least32_t hz)
int_least32_t hz)
{ {
const int_least32_t delay2hz[] = { const int_least32_t delay2hz[] = {
1850000, 235000, 130000, 102000, 85000, 72000 1850000, 235000, 130000, 102000, 85000, 72000
@ -764,8 +761,7 @@ static int_least32_t vsllink_swd_frequency(struct adiv5_dap *dap,
return hz; return hz;
} }
static int vsllink_swd_switch_seq(struct adiv5_dap *dap, static int vsllink_swd_switch_seq(enum swd_special_seq seq)
enum swd_special_seq seq)
{ {
switch (seq) { switch (seq) {
case LINE_RESET: case LINE_RESET:
@ -791,19 +787,17 @@ static int vsllink_swd_switch_seq(struct adiv5_dap *dap,
return ERROR_OK; return ERROR_OK;
} }
static void vsllink_swd_read_reg(struct adiv5_dap *dap, uint8_t cmd, static void vsllink_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
uint32_t *value)
{ {
versaloon_interface.adaptors.swd.transact(0, cmd, value, NULL); versaloon_interface.adaptors.swd.transact(0, cmd, value, NULL);
} }
static void vsllink_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd, static void vsllink_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
uint32_t value)
{ {
versaloon_interface.adaptors.swd.transact(0, cmd, &value, NULL); 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(); return versaloon_interface.adaptors.peripheral_commit();
} }

View File

@ -153,48 +153,47 @@ struct swd_driver {
* queued transactions are executed. If the frequency is lowered, it may * queued transactions are executed. If the frequency is lowered, it may
* apply immediately. * apply immediately.
* *
* @param dap The DAP controlled by the SWD link.
* @param hz The desired frequency in Hz. * @param hz The desired frequency in Hz.
* @return The actual resulting frequency after rounding. * @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. * Queue a special SWDIO sequence.
* *
* @param dap The DAP controlled by the SWD link.
* @param seq The special sequence to generate. * @param seq The special sequence to generate.
* @return ERROR_OK if the sequence was queued, negative error if the * @return ERROR_OK if the sequence was queued, negative error if the
* sequence is unsupported. * 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. * 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 Command byte with APnDP/RnW/addr/parity bits
* @param Where to store value to read from register * @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. * 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 Command byte with APnDP/RnW/addr/parity bits
* @param Value to be written to the register * @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. * 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 * @return ERROR_OK on success, Ack response code on WAIT/FAULT
* or negative error code on other kinds of failure. * 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 * Configures data collection from the Single-wire
@ -208,7 +207,7 @@ struct swd_driver {
* *
* @return ERROR_OK on success, else a negative fault code. * @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); int swd_init_reset(struct command_context *cmd_ctx);

View File

@ -63,7 +63,7 @@ static void swd_finish_read(struct adiv5_dap *dap)
{ {
const struct swd_driver *swd = jtag_interface->swd; const struct swd_driver *swd = jtag_interface->swd;
if (dap->last_read != NULL) { 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; dap->last_read = NULL;
} }
} }
@ -78,8 +78,8 @@ static void swd_clear_sticky_errors(struct adiv5_dap *dap)
const struct swd_driver *swd = jtag_interface->swd; const struct swd_driver *swd = jtag_interface->swd;
assert(swd); assert(swd);
swd->write_reg(dap, swd_cmd(false, false, DP_ABORT), swd->write_reg(swd_cmd(false, false, DP_ABORT),
STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR); STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0);
} }
static int swd_run_inner(struct adiv5_dap *dap) static int swd_run_inner(struct adiv5_dap *dap)
@ -87,7 +87,7 @@ static int swd_run_inner(struct adiv5_dap *dap)
const struct swd_driver *swd = jtag_interface->swd; const struct swd_driver *swd = jtag_interface->swd;
int retval; int retval;
retval = swd->run(dap); retval = swd->run();
if (retval != ERROR_OK) { if (retval != ERROR_OK) {
/* fault response */ /* fault response */
@ -110,7 +110,7 @@ static int swd_connect(struct adiv5_dap *dap)
*/ */
/* Note, debugport_init() does setup too */ /* 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; dap->do_reconnect = false;
@ -148,8 +148,8 @@ static int swd_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack)
const struct swd_driver *swd = jtag_interface->swd; const struct swd_driver *swd = jtag_interface->swd;
assert(swd); assert(swd);
swd->write_reg(dap, swd_cmd(false, false, DP_ABORT), swd->write_reg(swd_cmd(false, false, DP_ABORT),
DAPABORT | STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR); DAPABORT | STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0);
return check_sync(dap); return check_sync(dap);
} }
@ -181,7 +181,7 @@ static int swd_queue_dp_read(struct adiv5_dap *dap, unsigned reg,
return retval; return retval;
swd_queue_dp_bankselect(dap, reg); 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); return check_sync(dap);
} }
@ -198,7 +198,7 @@ static int swd_queue_dp_write(struct adiv5_dap *dap, unsigned reg,
swd_finish_read(dap); swd_finish_read(dap);
swd_queue_dp_bankselect(dap, reg); 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 check_sync(dap);
} }
@ -228,7 +228,7 @@ static int swd_queue_ap_read(struct adiv5_dap *dap, unsigned reg,
return retval; return retval;
swd_queue_ap_bankselect(dap, reg); 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; dap->last_read = data;
return check_sync(dap); return check_sync(dap);
@ -246,7 +246,7 @@ static int swd_queue_ap_write(struct adiv5_dap *dap, unsigned reg,
swd_finish_read(dap); swd_finish_read(dap);
swd_queue_ap_bankselect(dap, reg); 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); return check_sync(dap);
} }