23 #define EUD_VID 0x05c6
24 #define EUD_CTL_PID 0x9501
25 #define EUD_SWD_PID 0x9504
26 #define EUD_INTERFACE 0
27 #define EUD_EP_OUT 0x02
28 #define EUD_EP_IN 0x81
29 #define EUD_USB_TIMEOUT_MS 6000
37 #define EUD_SWD_BUFFER_SIZE 32
43 #define EUD_SWD_QUEUE_TRAILER_SIZE 2
44 #define EUD_SWD_STATUS_SIZE 4
46 #define EUD_CTL_CMD_CTLOUT_SET 7
47 #define EUD_CTL_CMD_CTLOUT_CLR 8
49 #define EUD_CTL_RCTLR_SRST_N BIT(0)
50 #define EUD_CTL_SWD_PERIPH_EN BIT(2)
51 #define EUD_CTL_JTAG_PERIPH_EN BIT(4)
52 #define EUD_CTL_VDDMIN_TCK_EN BIT(6)
53 #define EUD_CTL_GPIO_JTAG_SEL BIT(7)
54 #define EUD_CTL_DAP_MUX_SEL BIT(10)
55 #define EUD_CTL_ACC_TDO_SEL BIT(17)
56 #define EUD_CTL_DAP_TDO_SEL BIT(18)
57 #define EUD_CTL_MTAP_TDO_SEL BIT(19)
58 #define EUD_CTL_DAP_SWDO_SEL BIT(20)
60 #define EUD_CTL_SWD_ON_CLEAR (EUD_CTL_JTAG_PERIPH_EN | \
61 EUD_CTL_GPIO_JTAG_SEL | \
62 EUD_CTL_ACC_TDO_SEL | \
63 EUD_CTL_DAP_TDO_SEL | \
65 #define EUD_CTL_SWD_ON_SET (EUD_CTL_RCTLR_SRST_N | \
66 EUD_CTL_SWD_PERIPH_EN | \
67 EUD_CTL_VDDMIN_TCK_EN | \
68 EUD_CTL_DAP_MUX_SEL | \
70 #define EUD_SWD_BB_RCTLR_SRST_N BIT(2)
71 #define EUD_SWD_BB_GPIO_SRST_N BIT(4)
72 #define EUD_SWD_BB_GPIO_TRST_N BIT(5)
73 #define EUD_SWD_BB_DAP_TRST_N BIT(6)
74 #define EUD_SWD_BB_RESET_DEFAULT (EUD_SWD_BB_RCTLR_SRST_N | \
75 EUD_SWD_BB_GPIO_SRST_N | \
76 EUD_SWD_BB_GPIO_TRST_N | \
77 EUD_SWD_BB_DAP_TRST_N)
79 #define EUD_SWD_CMD_FLUSH 1
80 #define EUD_SWD_CMD_FREQ 2
81 #define EUD_SWD_CMD_DELAY 3
83 #define SWD_CMD_DELAY_TIME GENMASK(7, 0)
84 #define SWD_CMD_DELAY_RESERVED GENMASK(31, 8)
85 #define EUD_SWD_CMD_BITBANG 4
86 #define EUD_SWD_CMD_DITMS 5
87 #define SWD_CMD_DITMS_DATA GENMASK(15, 0)
88 #define SWD_CMD_DITMS_DATA_BITS 16
89 #define SWD_CMD_DITMS_COUNT GENMASK(31, 16)
90 #define EUD_SWD_DITMS_MAX_BITS (FIELD_GET(SWD_CMD_DITMS_COUNT, SWD_CMD_DITMS_COUNT) + 1)
91 #define EUD_SWD_CMD_TIMING 6
94 #define SWD_CMD_TIMING_RETRY_COUNT GENMASK(15, 0)
96 #define SWD_CMD_TIMING_TURNAROUND_TIME GENMASK(17, 16)
99 #define SWD_CMD_TIMING_WAIT_35_IF_ERR BIT(18)
100 #define SWD_CMD_TIMING_RESERVED GENMASK(31, 19)
101 #define EUD_SWD_CMD_STATUS 7
105 #define SWD_CMD_STATUS_ACK GENMASK(2, 0)
107 #define SWD_CMD_STATUS_WAIT_TIMEOUT BIT(3)
109 #define SWD_CMD_STATUS_PARITY_ERR BIT(4)
113 #define SWD_CMD_STATUS_CMD_CNTR GENMASK(31, 16)
114 #define EUD_SWD_CMD_PERIPH_RST 8
166 libusb_close(dev->
handle);
178 if (ret != LIBUSB_SUCCESS) {
179 LOG_ERROR(
"libusb_init() failed: %s", libusb_error_name(ret));
196 if (ret != LIBUSB_SUCCESS) {
198 LOG_ERROR(
"libusb_claim_interface() failed: %s", libusb_error_name(ret));
215 LOG_DEBUG_IO(
"EUD pid 0x%04x write len %d opcode 0x%02x", dev->
pid, len, buf[0]);
217 int ret = libusb_bulk_transfer(dev->
handle,
EUD_EP_OUT, (
unsigned char *)buf,
219 if (ret != LIBUSB_SUCCESS) {
220 LOG_ERROR(
"EUD bulk write failed: %s", libusb_error_name(ret));
224 if (transferred != len) {
225 LOG_ERROR(
"short EUD bulk write: %d of %d bytes", transferred, len);
237 if (ret != LIBUSB_SUCCESS) {
238 LOG_ERROR(
"EUD bulk read failed: %s", libusb_error_name(ret));
242 if (transferred != len) {
243 LOG_ERROR(
"short EUD bulk read: %d of %d bytes", transferred, len);
288 for (
unsigned int i = 0; i < 5000; i++) {
313 LOG_ERROR(
"EUD speed index %d is out of range", speed_index);
378 unsigned int bit_pos = 0;
383 while (bit_pos < bit_len) {
384 unsigned int cmd_len = bit_len - bit_pos;
390 if (
buf_get_u32(seq, bit_pos + cmd_len, 1) != repeated_bit)
398 uint16_t tms =
buf_get_u32(seq, bit_pos, payload_bits);
435 LOG_ERROR(
"Sequence %d not supported", seq);
532 unsigned int out_len = 0;
533 unsigned int in_len = 0;
536 for (
unsigned int i = 0; i <
count; i++) {
546 out[out_len++] = eud_cmd;
573 assert(out_len <=
sizeof(out));
574 assert(in_len <=
sizeof(in));
576 LOG_DEBUG_IO(
"Flushing EUD SWD queue of %u transfers (%u bytes out, %u bytes in)",
577 count, out_len, in_len);
587 unsigned int in_pos = 0;
588 for (
unsigned int i = 0; i <
count; i++) {
623 LOG_ERROR(
"SWD parity error after %" PRIu32
" of %u transfers (status 0x%08" PRIx32
")",
630 LOG_DEBUG(
"SWD out of ACK.WAIT retries after %" PRIu32
" of %u transfers (status 0x%08" PRIx32
")",
637 LOG_DEBUG(
"SWD ack=%u after %" PRIu32
" of %u transfers (status 0x%08" PRIx32
")",
667 if (ret != LIBUSB_SUCCESS) {
668 LOG_ERROR(
"libusb_init() failed: %s", libusb_error_name(ret));
728 LOG_ERROR(
"EUD speed index %d is out of range", speed);
751 *jtag_speed = selected;
This defines formats and data structures used to talk to ADIv5 entities.
Support functions to access arbitrary bits in a byte array.
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned int first, unsigned int num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word.
#define FIELD_GET(_mask, _value)
FIELD_GET(_mask, _value) - Extract a value from a bitfield @_mask: Bitfield mask @_value: Bitfield va...
#define FIELD_PREP(_mask, _value)
FIELD_PREP(_mask, _value) - Prepare a value for insertion into a bitfield @_mask: Bitfield mask @_val...
uint32_t size
Size of dw_spi_transaction::buffer.
static const struct swd_driver eud_swd_driver
static int eud_swd_flush_queue(void)
static int eud_swd_init_defaults(void)
static unsigned int eud_queue_len
static int eud_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
#define EUD_CTL_CMD_CTLOUT_CLR
#define EUD_SWD_QUEUE_TRAILER_SIZE
#define SWD_CMD_STATUS_CMD_CNTR
#define SWD_CMD_TIMING_RETRY_COUNT
static int eud_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
static unsigned int eud_swd_transfer_out_size(const struct eud_swd_transfer *transfer)
#define EUD_SWD_CMD_DELAY
static int eud_reopen_swd(void)
#define EUD_CTL_SWD_ON_CLEAR
#define EUD_CTL_CMD_CTLOUT_SET
#define SWD_CMD_STATUS_PARITY_ERR
#define EUD_SWD_CMD_PERIPH_RST
static int eud_open_swd_after_enable(void)
static int eud_swd_switch_seq(enum swd_special_seq seq)
static int eud_speed_div(int speed, int *khz)
static unsigned int eud_queue_out_len
#define SWD_CMD_STATUS_WAIT_TIMEOUT
static int eud_bulk_read(struct eud_device *dev, uint8_t *buf, int len)
#define EUD_SWD_CMD_STATUS
static int eud_libusb_reinit(void)
static int eud_ctl_enable_swd(void)
static const unsigned int eud_speed_khz[]
static unsigned int eud_swd_transfer_in_size(const struct eud_swd_transfer *transfer)
static unsigned int eud_queue_in_len
static int eud_open_inner(uint16_t pid, struct eud_device *dev, bool quiet)
#define SWD_CMD_DITMS_DATA
#define EUD_SWD_BUFFER_SIZE
#define SWD_CMD_DITMS_DATA_BITS
#define SWD_CMD_DELAY_TIME
static int eud_ditms_u16(uint16_t tms, uint16_t count)
#define SWD_CMD_STATUS_ACK
#define EUD_SWD_BB_GPIO_SRST_N
static struct eud_device eud_ctl
static int eud_swd_set_speed_index(int speed_index)
#define EUD_USB_TIMEOUT_MS
static int eud_open(uint16_t pid, struct eud_device *dev)
static struct eud_device eud_swd
static int eud_khz(int khz, int *jtag_speed)
#define SWD_CMD_DITMS_COUNT
static int eud_swd_bitbang(uint32_t payload)
static int eud_swd_init(void)
static int eud_reset(int trst, int srst)
#define EUD_SWD_CMD_BITBANG
#define EUD_SWD_CMD_DITMS
#define EUD_SWD_BB_RCTLR_SRST_N
static libusb_context * eud_libusb_ctx
static struct eud_swd_transfer eud_queue[EUD_SWD_BUFFER_SIZE]
static int eud_ditms_sequence(const uint8_t *seq, unsigned int bit_len)
static int eud_speed_index
static int eud_op_no_payload(struct eud_device *dev, uint8_t opcode)
#define EUD_SWD_BB_DAP_TRST_N
#define EUD_SWD_STATUS_SIZE
static int eud_swd_queue_transfer(uint8_t cmd, uint32_t value, uint32_t *read_value, uint32_t ap_delay_clk)
#define EUD_SWD_CMD_FLUSH
static int eud_op(struct eud_device *dev, uint8_t opcode, uint32_t payload)
struct adapter_driver eud_adapter_driver
static int eud_quit(void)
static int eud_bulk_write(struct eud_device *dev, const uint8_t *buf, int len)
static int eud_swd_prepare(void)
#define EUD_CTL_SWD_ON_SET
static void eud_close(struct eud_device *dev)
static int eud_swd_run_queue(void)
#define EUD_SWD_CMD_TIMING
static int eud_init(void)
#define EUD_SWD_DITMS_MAX_BITS
static int eud_speed(int speed)
#define EUD_SWD_BB_RESET_DEFAULT
int jtag_libusb_error(int err)
void alive_sleep(uint64_t ms)
#define LOG_DEBUG_IO(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_DEBUG(expr ...)
Represents a driver for a debugging interface.
const char *const name
The name of the interface driver.
libusb_device_handle * handle
int(* init)(void)
Initialize the debug link so it can perform SWD operations.
static const unsigned int swd_seq_dormant_to_swd_len
static const uint8_t swd_seq_dormant_to_jtag[]
Dormant-to-JTAG sequence.
static const uint8_t swd_seq_dormant_to_swd[]
Dormant-to-SWD sequence.
static const uint8_t swd_seq_jtag_to_dormant[]
JTAG-to-dormant sequence.
static bool swd_cmd_returns_ack(uint8_t cmd)
Test if we can rely on ACK returned by SWD command.
static int swd_ack_to_error_code(uint8_t ack)
Convert SWD ACK value returned from DP to OpenOCD error code.
static const unsigned int swd_seq_jtag_to_swd_len
static const unsigned int swd_seq_line_reset_len
static const unsigned int swd_seq_dormant_to_jtag_len
static const unsigned int swd_seq_swd_to_dormant_len
static const uint8_t swd_seq_line_reset[]
SWD Line reset.
static const uint8_t swd_seq_jtag_to_swd[]
JTAG-to-SWD sequence.
static const unsigned int swd_seq_jtag_to_dormant_len
static const uint8_t swd_seq_swd_to_dormant[]
SWD-to-dormant sequence.
static void h_u32_to_le(uint8_t *buf, uint32_t val)
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.
static uint32_t le_to_h_u32(const uint8_t *buf)