aboutsummaryrefslogtreecommitdiff
path: root/src/jtag/swd.h
diff options
context:
space:
mode:
authorAndreas Fritiofson <andreas.fritiofson@gmail.com>2014-03-02 20:35:32 +0100
committerAndreas Fritiofson <andreas.fritiofson@gmail.com>2014-06-28 09:33:12 +0000
commitae3bcd05f87c9caf7f8900d54a380415f8f37326 (patch)
treedd43d746363321b9b0c1dfe7560122d318d09674 /src/jtag/swd.h
parent003f8a1d04f4e82c32d11f86ef32173048ab610c (diff)
downloadriscv-openocd-ae3bcd05f87c9caf7f8900d54a380415f8f37326.zip
riscv-openocd-ae3bcd05f87c9caf7f8900d54a380415f8f37326.tar.gz
riscv-openocd-ae3bcd05f87c9caf7f8900d54a380415f8f37326.tar.bz2
swd: Add frequency setting and special/switching sequences to the API
Change-Id: I6f3950374f2525a18bbcb9cbd340c447c20fb704 Signed-off-by: Andreas Fritiofson <andreas.fritiofson@gmail.com> Reviewed-on: http://openocd.zylin.com/2134 Tested-by: jenkins Reviewed-by: Paul Fertser <fercerpav@gmail.com>
Diffstat (limited to 'src/jtag/swd.h')
-rw-r--r--src/jtag/swd.h103
1 files changed, 103 insertions, 0 deletions
diff --git a/src/jtag/swd.h b/src/jtag/swd.h
index b0db5d2..d6746dd 100644
--- a/src/jtag/swd.h
+++ b/src/jtag/swd.h
@@ -55,6 +55,80 @@ static inline uint8_t swd_cmd(bool is_read, bool is_ap, uint8_t regnum)
/* SWD_ACK_* bits are defined in <target/arm_adi_v5.h> */
+/**
+ * Line reset.
+ *
+ * Line reset is at least 50 SWCLK cycles with SWDIO driven high, followed
+ * by at least one idle (low) cycle.
+ */
+static const uint8_t swd_seq_line_reset[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03
+};
+static const unsigned swd_seq_line_reset_len = 51;
+
+/**
+ * JTAG-to-SWD sequence.
+ *
+ * The JTAG-to-SWD sequence is at least 50 TCK/SWCLK cycles with TMS/SWDIO
+ * high, putting either interface logic into reset state, followed by a
+ * specific 16-bit sequence and finally a line reset in case the SWJ-DP was
+ * already in SWD mode.
+ */
+static const uint8_t swd_seq_jtag_to_swd[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7b, 0x9e,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
+};
+static const unsigned swd_seq_jtag_to_swd_len = 118;
+
+/**
+ * SWD-to-JTAG sequence.
+ *
+ * The SWD-to-JTAG sequence is at least 50 TCK/SWCLK cycles with TMS/SWDIO
+ * high, putting either interface logic into reset state, followed by a
+ * specific 16-bit sequence and finally at least 5 TCK cycles to put the
+ * JTAG TAP in TLR.
+ */
+static const uint8_t swd_seq_swd_to_jtag[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x9c, 0xff
+};
+static const unsigned swd_seq_swd_to_jtag_len = 71;
+
+/**
+ * SWD-to-dormant sequence.
+ *
+ * This is at least 50 SWCLK cycles with SWDIO high to put the interface
+ * in reset state, followed by a specific 16-bit sequence.
+ */
+static const uint8_t swd_seq_swd_to_dormant[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x8e, 0x03
+};
+static const unsigned swd_seq_swd_to_dormant_len = 66;
+
+/**
+ * Dormant-to-SWD sequence.
+ *
+ * This is at least 8 TCK/SWCLK cycles with TMS/SWDIO high to abort any ongoing
+ * selection alert sequence, followed by a specific 128-bit selection alert
+ * sequence, followed by 4 TCK/SWCLK cycles with TMS/SWDIO low, followed by
+ * a specific protocol-dependent activation code. For SWD the activation code
+ * is an 8-bit sequence. The sequence ends with a line reset.
+ */
+static const uint8_t swd_seq_dormant_to_swd[] = {
+ 0xff,
+ 0x92, 0xf3, 0x09, 0x62, 0x95, 0x2d, 0x85, 0x86,
+ 0xe9, 0xaf, 0xdd, 0xe3, 0xa2, 0x0e, 0xbc, 0x19,
+ 0x10, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f
+};
+static const unsigned swd_seq_dormant_to_swd_len = 199;
+
+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.
@@ -67,6 +141,35 @@ struct swd_driver {
int (*init)(void);
/**
+ * Set the SWCLK frequency of the SWD link.
+ *
+ * The driver should round the desired value, downwards if possible, to
+ * the nearest supported frequency. A negative value should be ignored
+ * and can be used to query the current setting. If the driver does not
+ * support a variable frequency a fixed, nominal, value should be
+ * returned.
+ *
+ * If the frequency is increased, it must not apply before the currently
+ * 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);
+
+ /**
+ * 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);
+
+ /**
* Queued read of an AP or DP register.
*
* @param dap The DAP controlled by the SWD link.