The method to send an arbitrary sequence to DAP depends on the
transport and is thus different on JTAG and SWD. This is already
coded in dap_to_jtag() and dap_to_swd().
Add a new API send_sequence() in struct dap_ops.
Add the implementations of send_sequence() in adi_v5_jtag.c and
adi_v5_swd.c
Rewrite dap_to_jtag() and dap_to_swd() using the new API.
Move the enum swd_special_seq in arm_adi_v5.h to solve a circular
dependencies among swd.h and arm_adi_v5.h
Change-Id: I9db13a00f129761eab283783c094cfff2dd92610
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: http://openocd.zylin.com/4902
Tested-by: jenkins
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
};
static const unsigned swd_seq_dormant_to_jtag_len = 160;
};
static const unsigned swd_seq_dormant_to_jtag_len = 160;
-enum swd_special_seq {
- LINE_RESET,
- JTAG_TO_SWD,
- SWD_TO_JTAG,
- SWD_TO_DORMANT,
- DORMANT_TO_SWD,
-};
-
struct swd_driver {
/**
* Initialize the debug link so it can perform SWD operations.
struct swd_driver {
/**
* Initialize the debug link so it can perform SWD operations.
#include "arm_adi_v5.h"
#include <helper/time_support.h>
#include <helper/list.h>
#include "arm_adi_v5.h"
#include <helper/time_support.h>
#include <helper/list.h>
+static int jtag_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq)
+{
+ int retval;
+
+ switch (seq) {
+ case JTAG_TO_SWD:
+ retval = jtag_add_tms_seq(swd_seq_jtag_to_swd_len,
+ swd_seq_jtag_to_swd, TAP_INVALID);
+ break;
+ case SWD_TO_JTAG:
+ retval = jtag_add_tms_seq(swd_seq_swd_to_jtag_len,
+ swd_seq_swd_to_jtag, TAP_RESET);
+ break;
+ default:
+ LOG_ERROR("Sequence %d not supported", seq);
+ return ERROR_FAIL;
+ }
+ if (retval == ERROR_OK)
+ retval = jtag_execute_queue();
+ return retval;
+}
+
static int jtag_dp_q_read(struct adiv5_dap *dap, unsigned reg,
uint32_t *data)
{
static int jtag_dp_q_read(struct adiv5_dap *dap, unsigned reg,
uint32_t *data)
{
*/
const struct dap_ops jtag_dp_ops = {
.connect = jtag_connect,
*/
const struct dap_ops jtag_dp_ops = {
.connect = jtag_connect,
+ .send_sequence = jtag_send_sequence,
.queue_dp_read = jtag_dp_q_read,
.queue_dp_write = jtag_dp_q_write,
.queue_ap_read = jtag_ap_q_read,
.queue_dp_read = jtag_dp_q_read,
.queue_dp_write = jtag_dp_q_write,
.queue_ap_read = jtag_ap_q_read,
+static int swd_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq)
+{
+ const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
+ assert(swd);
+
+ return swd->switch_seq(seq);
+}
+
static inline int check_sync(struct adiv5_dap *dap)
{
return do_sync ? swd_run_inner(dap) : ERROR_OK;
static inline int check_sync(struct adiv5_dap *dap)
{
return do_sync ? swd_run_inner(dap) : ERROR_OK;
const struct dap_ops swd_dap_ops = {
.connect = swd_connect,
const struct dap_ops swd_dap_ops = {
.connect = swd_connect,
+ .send_sequence = swd_send_sequence,
.queue_dp_read = swd_queue_dp_read,
.queue_dp_write = swd_queue_dp_write,
.queue_ap_read = swd_queue_ap_read,
.queue_dp_read = swd_queue_dp_read,
.queue_dp_write = swd_queue_dp_write,
.queue_ap_read = swd_queue_ap_read,
*/
int dap_to_swd(struct adiv5_dap *dap)
{
*/
int dap_to_swd(struct adiv5_dap *dap)
{
LOG_DEBUG("Enter SWD mode");
LOG_DEBUG("Enter SWD mode");
- if (transport_is_jtag()) {
- retval = jtag_add_tms_seq(swd_seq_jtag_to_swd_len,
- swd_seq_jtag_to_swd, TAP_INVALID);
- if (retval == ERROR_OK)
- retval = jtag_execute_queue();
- return retval;
- }
-
- if (transport_is_swd()) {
- const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
-
- return swd->switch_seq(JTAG_TO_SWD);
- }
-
- LOG_ERROR("Nor JTAG nor SWD transport");
- return ERROR_FAIL;
+ return dap_send_sequence(dap, JTAG_TO_SWD);
*/
int dap_to_jtag(struct adiv5_dap *dap)
{
*/
int dap_to_jtag(struct adiv5_dap *dap)
{
LOG_DEBUG("Enter JTAG mode");
LOG_DEBUG("Enter JTAG mode");
- if (transport_is_jtag()) {
- retval = jtag_add_tms_seq(swd_seq_swd_to_jtag_len,
- swd_seq_swd_to_jtag, TAP_RESET);
- if (retval == ERROR_OK)
- retval = jtag_execute_queue();
- return retval;
- }
-
- if (transport_is_swd()) {
- const struct swd_driver *swd = adiv5_dap_swd_driver(dap);
-
- return swd->switch_seq(SWD_TO_JTAG);
- }
-
- LOG_ERROR("Nor JTAG nor SWD transport");
- return ERROR_FAIL;
+ return dap_send_sequence(dap, SWD_TO_JTAG);
}
/* CID interpretation -- see ARM IHI 0029B section 3
}
/* CID interpretation -- see ARM IHI 0029B section 3
#define DP_APSEL_MAX (255)
#define DP_APSEL_INVALID (-1)
#define DP_APSEL_MAX (255)
#define DP_APSEL_INVALID (-1)
+/* FIXME: not SWD specific; should be renamed, e.g. adiv5_special_seq */
+enum swd_special_seq {
+ LINE_RESET,
+ JTAG_TO_SWD,
+ SWD_TO_JTAG,
+ SWD_TO_DORMANT,
+ DORMANT_TO_SWD,
+};
+
/**
* This represents an ARM Debug Interface (v5) Access Port (AP).
* Most common is a MEM-AP, for memory access.
/**
* This represents an ARM Debug Interface (v5) Access Port (AP).
* Most common is a MEM-AP, for memory access.
struct dap_ops {
/** connect operation for SWD */
int (*connect)(struct adiv5_dap *dap);
struct dap_ops {
/** connect operation for SWD */
int (*connect)(struct adiv5_dap *dap);
+
+ /** send a sequence to the DAP */
+ int (*send_sequence)(struct adiv5_dap *dap, enum swd_special_seq seq);
+
/** DP register read. */
int (*queue_dp_read)(struct adiv5_dap *dap, unsigned reg,
uint32_t *data);
/** DP register read. */
int (*queue_dp_read)(struct adiv5_dap *dap, unsigned reg,
uint32_t *data);
AP_TYPE_AHB5_AP = 0x5, /* AHB5 Memory-AP. */
};
AP_TYPE_AHB5_AP = 0x5, /* AHB5 Memory-AP. */
};
+/**
+ * Send an adi-v5 sequence to the DAP.
+ *
+ * @param dap The DAP used for reading.
+ * @param seq The sequence to send.
+ *
+ * @return ERROR_OK for success, else a fault code.
+ */
+static inline int dap_send_sequence(struct adiv5_dap *dap,
+ enum swd_special_seq seq)
+{
+ assert(dap->ops != NULL);
+ return dap->ops->send_sequence(dap, seq);
+}
+
/**
* Queue a DP register read.
* Note that not all DP registers are readable; also, that JTAG and SWD
/**
* Queue a DP register read.
* Note that not all DP registers are readable; also, that JTAG and SWD
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)