1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2017 by Texas Instruments, Inc. *
5 ***************************************************************************/
11 #include <transport/transport.h>
12 #include <jtag/adapter.h>
14 #include <jtag/interface.h>
15 #include <jtag/commands.h>
19 /* XDS110 stand-alone probe voltage supply limits */
20 #define XDS110_MIN_VOLTAGE 1800
21 #define XDS110_MAX_VOLTAGE 3600
23 /* XDS110 stand-alone probe hardware ID */
24 #define XDS110_STAND_ALONE_ID 0x21
26 /* Firmware version that introduced OpenOCD support via block accesses */
27 #define OCD_FIRMWARE_VERSION 0x02030011
28 #define OCD_FIRMWARE_UPGRADE \
29 "XDS110: upgrade to version 2.3.0.11+ for improved support"
31 /* Firmware version that introduced improved TCK performance */
32 #define FAST_TCK_FIRMWARE_VERSION 0x03000000
34 /* Firmware version that introduced 10 MHz and 12 MHz TCK support */
35 #define FAST_TCK_PLUS_FIRMWARE_VERSION 0x03000003
37 /***************************************************************************
38 * USB Connection Buffer Definitions *
39 ***************************************************************************/
41 /* Max USB packet size for up to USB 3.0 */
42 #define MAX_PACKET 1024
45 * Maximum data payload that can be handled in a single call
46 * Limitation is the size of the buffers in the XDS110 firmware
48 #define MAX_DATA_BLOCK 4096
50 #ifndef USB_PAYLOAD_SIZE
51 /* Largest data block plus parameters */
52 #define USB_PAYLOAD_SIZE (MAX_DATA_BLOCK + 60)
54 #define MAX_RESULT_QUEUE (MAX_DATA_BLOCK / 4)
56 /***************************************************************************
57 * XDS110 Firmware API Definitions *
58 ***************************************************************************/
61 * Default values controlling how the host communicates commands
62 * with XDS110 firmware (automatic retry count and wait timeout)
64 #define DEFAULT_ATTEMPTS (1)
65 #define DEFAULT_TIMEOUT (4000)
67 /* XDS110 API error codes */
69 #define SC_ERR_XDS110_FAIL -261
70 #define SC_ERR_SWD_WAIT -613
71 #define SC_ERR_SWD_FAULT -614
72 #define SC_ERR_SWD_PROTOCOL -615
73 #define SC_ERR_SWD_PARITY -616
74 #define SC_ERR_SWD_DEVICE_ID -617
76 /* TCK frequency limits */
77 #define XDS110_MIN_TCK_SPEED 100 /* kHz */
78 #define XDS110_MAX_SLOW_TCK_SPEED 2500 /* kHz */
79 #define XDS110_MAX_FAST_TCK_SPEED 14000 /* kHz */
80 #define XDS110_DEFAULT_TCK_SPEED 2500 /* kHz */
82 /* Fixed TCK delay values for "Fast" TCK frequencies */
83 #define FAST_TCK_DELAY_14000_KHZ 0
84 #define FAST_TCK_DELAY_10000_KHZ 0xfffffffd
85 #define FAST_TCK_DELAY_12000_KHZ 0xfffffffe
86 #define FAST_TCK_DELAY_8500_KHZ 1
87 #define FAST_TCK_DELAY_5500_KHZ 2
88 /* For TCK frequencies below 5500 kHz, use calculated delay */
90 /* Scan mode on connect */
93 /* XDS110 API JTAG state definitions */
94 #define XDS_JTAG_STATE_RESET 1
95 #define XDS_JTAG_STATE_IDLE 2
96 #define XDS_JTAG_STATE_SHIFT_DR 3
97 #define XDS_JTAG_STATE_SHIFT_IR 4
98 #define XDS_JTAG_STATE_PAUSE_DR 5
99 #define XDS_JTAG_STATE_PAUSE_IR 6
100 #define XDS_JTAG_STATE_EXIT1_DR 8
101 #define XDS_JTAG_STATE_EXIT1_IR 9
102 #define XDS_JTAG_STATE_EXIT2_DR 10
103 #define XDS_JTAG_STATE_EXIT2_IR 11
104 #define XDS_JTAG_STATE_SELECT_DR 12
105 #define XDS_JTAG_STATE_SELECT_IR 13
106 #define XDS_JTAG_STATE_UPDATE_DR 14
107 #define XDS_JTAG_STATE_UPDATE_IR 15
108 #define XDS_JTAG_STATE_CAPTURE_DR 16
109 #define XDS_JTAG_STATE_CAPTURE_IR 17
111 /* XDS110 API JTAG transit definitions */
112 #define XDS_JTAG_TRANSIT_QUICKEST 1
113 #define XDS_JTAG_TRANSIT_VIA_CAPTURE 2
114 #define XDS_JTAG_TRANSIT_VIA_IDLE 3
116 /* DAP register definitions as used by XDS110 APIs */
118 #define DAP_AP 0 /* DAP AP register type */
119 #define DAP_DP 1 /* DAP DP register type */
121 #define DAP_DP_IDCODE 0x0 /* DAP DP IDCODE register (read only) */
122 #define DAP_DP_ABORT 0x0 /* DAP DP ABORT register (write only) */
123 #define DAP_DP_STAT 0x4 /* DAP DP STAT register (for read only) */
124 #define DAP_DP_CTRL 0x4 /* DAP DP CTRL register (for write only) */
125 #define DAP_DP_ADDR 0x8 /* DAP DP SELECT register (legacy name) */
126 #define DAP_DP_RESEND 0x8 /* DAP DP RESEND register (read only) */
127 #define DAP_DP_SELECT 0x8 /* DAP DP SELECT register (write only) */
128 #define DAP_DP_RDBUFF 0xc /* DAP DP RDBUFF Read Buffer register */
130 #define DAP_AP_CSW 0x00 /* DAP AP Control Status Word */
131 #define DAP_AP_TAR 0x04 /* DAP AP Transfer Address */
132 #define DAP_AP_DRW 0x0C /* DAP AP Data Read/Write */
133 #define DAP_AP_BD0 0x10 /* DAP AP Banked Data 0 */
134 #define DAP_AP_BD1 0x14 /* DAP AP Banked Data 1 */
135 #define DAP_AP_BD2 0x18 /* DAP AP Banked Data 2 */
136 #define DAP_AP_BD3 0x1C /* DAP AP Banked Data 3 */
137 #define DAP_AP_RTBL 0xF8 /* DAP AP Debug ROM Table */
138 #define DAP_AP_IDR 0xFC /* DAP AP Identification Register */
140 /* Command packet definitions */
142 #define XDS_OUT_LEN 1 /* command (byte) */
143 #define XDS_IN_LEN 4 /* error code (int) */
145 /* XDS API Commands */
146 #define XDS_CONNECT 0x01 /* Connect JTAG connection */
147 #define XDS_DISCONNECT 0x02 /* Disconnect JTAG connection */
148 #define XDS_VERSION 0x03 /* Get firmware version and hardware ID */
149 #define XDS_SET_TCK 0x04 /* Set TCK delay (to set TCK frequency) */
150 #define XDS_SET_TRST 0x05 /* Assert or deassert nTRST signal */
151 #define XDS_CYCLE_TCK 0x07 /* Toggle TCK for a number of cycles */
152 #define XDS_GOTO_STATE 0x09 /* Go to requested JTAG state */
153 #define XDS_JTAG_SCAN 0x0c /* Send and receive JTAG scan */
154 #define XDS_SET_SRST 0x0e /* Assert or deassert nSRST signal */
155 #define CMAPI_CONNECT 0x0f /* CMAPI connect */
156 #define CMAPI_DISCONNECT 0x10 /* CMAPI disconnect */
157 #define CMAPI_ACQUIRE 0x11 /* CMAPI acquire */
158 #define CMAPI_RELEASE 0x12 /* CMAPI release */
159 #define CMAPI_REG_READ 0x15 /* CMAPI DAP register read */
160 #define CMAPI_REG_WRITE 0x16 /* CMAPI DAP register write */
161 #define SWD_CONNECT 0x17 /* Switch from JTAG to SWD connection */
162 #define SWD_DISCONNECT 0x18 /* Switch from SWD to JTAG connection */
163 #define CJTAG_CONNECT 0x2b /* Switch from JTAG to cJTAG connection */
164 #define CJTAG_DISCONNECT 0x2c /* Switch from cJTAG to JTAG connection */
165 #define XDS_SET_SUPPLY 0x32 /* Set up stand-alone probe upply voltage */
166 #define OCD_DAP_REQUEST 0x3a /* Handle block of DAP requests */
167 #define OCD_SCAN_REQUEST 0x3b /* Handle block of JTAG scan requests */
168 #define OCD_PATHMOVE 0x3c /* Handle PATHMOVE to navigate JTAG states */
170 #define CMD_IR_SCAN 1
171 #define CMD_DR_SCAN 2
172 #define CMD_RUNTEST 3
173 #define CMD_STABLECLOCKS 4
175 /* Array to convert from OpenOCD tap_state_t to XDS JTAG state */
176 static const uint32_t xds_jtag_state
[] = {
177 XDS_JTAG_STATE_EXIT2_DR
, /* TAP_DREXIT2 = 0x0 */
178 XDS_JTAG_STATE_EXIT1_DR
, /* TAP_DREXIT1 = 0x1 */
179 XDS_JTAG_STATE_SHIFT_DR
, /* TAP_DRSHIFT = 0x2 */
180 XDS_JTAG_STATE_PAUSE_DR
, /* TAP_DRPAUSE = 0x3 */
181 XDS_JTAG_STATE_SELECT_IR
, /* TAP_IRSELECT = 0x4 */
182 XDS_JTAG_STATE_UPDATE_DR
, /* TAP_DRUPDATE = 0x5 */
183 XDS_JTAG_STATE_CAPTURE_DR
, /* TAP_DRCAPTURE = 0x6 */
184 XDS_JTAG_STATE_SELECT_DR
, /* TAP_DRSELECT = 0x7 */
185 XDS_JTAG_STATE_EXIT2_IR
, /* TAP_IREXIT2 = 0x8 */
186 XDS_JTAG_STATE_EXIT1_IR
, /* TAP_IREXIT1 = 0x9 */
187 XDS_JTAG_STATE_SHIFT_IR
, /* TAP_IRSHIFT = 0xa */
188 XDS_JTAG_STATE_PAUSE_IR
, /* TAP_IRPAUSE = 0xb */
189 XDS_JTAG_STATE_IDLE
, /* TAP_IDLE = 0xc */
190 XDS_JTAG_STATE_UPDATE_IR
, /* TAP_IRUPDATE = 0xd */
191 XDS_JTAG_STATE_CAPTURE_IR
, /* TAP_IRCAPTURE = 0xe */
192 XDS_JTAG_STATE_RESET
, /* TAP_RESET = 0xf */
202 /* USB connection handles and data buffers */
203 struct libusb_context
*ctx
;
204 struct libusb_device_handle
*dev
;
205 unsigned char read_payload
[USB_PAYLOAD_SIZE
];
206 unsigned char write_packet
[3];
207 unsigned char write_payload
[USB_PAYLOAD_SIZE
];
211 /* Debug interface */
214 uint8_t endpoint_out
;
217 bool is_cmapi_connected
;
218 bool is_cmapi_acquired
;
221 /* DAP register caches */
225 /* TCK speed and delay count*/
227 uint32_t delay_count
;
228 /* XDS110 voltage supply setting */
230 /* XDS110 firmware and hardware version */
233 /* Transaction queues */
234 unsigned char txn_requests
[MAX_DATA_BLOCK
];
235 uint32_t *txn_dap_results
[MAX_DATA_BLOCK
/ 4];
236 struct scan_result txn_scan_results
[MAX_DATA_BLOCK
/ 4];
237 uint32_t txn_request_size
;
238 uint32_t txn_result_size
;
239 uint32_t txn_result_count
;
242 static struct xds110_info xds110
= {
250 .is_connected
= false,
251 .is_cmapi_connected
= false,
252 .is_cmapi_acquired
= false,
253 .is_swd_mode
= false,
254 .is_ap_dirty
= false,
255 .speed
= XDS110_DEFAULT_TCK_SPEED
,
260 .txn_request_size
= 0,
261 .txn_result_size
= 0,
262 .txn_result_count
= 0
265 static inline void xds110_set_u32(uint8_t *buffer
, uint32_t value
)
267 buffer
[3] = (value
>> 24) & 0xff;
268 buffer
[2] = (value
>> 16) & 0xff;
269 buffer
[1] = (value
>> 8) & 0xff;
270 buffer
[0] = (value
>> 0) & 0xff;
273 static inline void xds110_set_u16(uint8_t *buffer
, uint16_t value
)
275 buffer
[1] = (value
>> 8) & 0xff;
276 buffer
[0] = (value
>> 0) & 0xff;
279 static inline uint32_t xds110_get_u32(uint8_t *buffer
)
281 uint32_t value
= (((uint32_t)buffer
[3]) << 24) |
282 (((uint32_t)buffer
[2]) << 16) |
283 (((uint32_t)buffer
[1]) << 8) |
284 (((uint32_t)buffer
[0]) << 0);
288 static inline uint16_t xds110_get_u16(uint8_t *buffer
)
290 uint16_t value
= (((uint32_t)buffer
[1]) << 8) |
291 (((uint32_t)buffer
[0]) << 0);
295 /***************************************************************************
296 * usb connection routines *
298 * The following functions handle connecting, reading, and writing to *
299 * the XDS110 over USB using the libusb library. *
300 ***************************************************************************/
302 static bool usb_connect(void)
304 struct libusb_context
*ctx
= NULL
;
305 struct libusb_device
**list
= NULL
;
306 struct libusb_device_handle
*dev
= NULL
;
308 struct libusb_device_descriptor desc
;
310 /* The vid/pids of possible XDS110 configurations */
311 uint16_t vids
[] = { 0x0451, 0x0451, 0x1cbe };
312 uint16_t pids
[] = { 0xbef3, 0xbef4, 0x02a5 };
313 /* Corresponding interface and endpoint numbers for configurations */
314 uint8_t interfaces
[] = { 2, 2, 0 };
315 uint8_t endpoints_in
[] = { 3, 3, 1 };
316 uint8_t endpoints_out
[] = { 2, 2, 1 };
325 /* Initialize libusb context */
326 result
= libusb_init(&ctx
);
329 /* Get list of USB devices attached to system */
330 count
= libusb_get_device_list(ctx
, &list
);
338 /* Scan through list of devices for any XDS110s */
339 for (i
= 0; i
< count
; i
++) {
340 /* Check for device vid/pid match */
341 libusb_get_device_descriptor(list
[i
], &desc
);
343 for (device
= 0; device
< ARRAY_SIZE(vids
); device
++) {
344 if (desc
.idVendor
== vids
[device
] &&
345 desc
.idProduct
== pids
[device
]) {
351 result
= libusb_open(list
[i
], &dev
);
353 const int max_data
= 256;
354 unsigned char data
[max_data
+ 1];
357 /* May be the requested device if serial number matches */
358 if (!adapter_get_required_serial()) {
359 /* No serial number given; match first XDS110 found */
363 /* Get the device's serial number string */
364 result
= libusb_get_string_descriptor_ascii(dev
,
365 desc
.iSerialNumber
, data
, max_data
);
367 strcmp((char *)data
, adapter_get_required_serial()) == 0) {
373 /* If we fall though to here, we don't want this device */
382 * We can fall through the for() loop with two possible exit conditions:
383 * 1) found the right XDS110, and that device is open
384 * 2) didn't find the XDS110, and no devices are currently open
388 /* Free the device list, we're done with it */
389 libusb_free_device_list(list
, 1);
393 /* Save the vid/pid of the device we're using */
394 xds110
.vid
= vids
[device
];
395 xds110
.pid
= pids
[device
];
397 /* Save the debug interface and endpoints for the device */
398 xds110
.interface
= interfaces
[device
];
399 xds110
.endpoint_in
= endpoints_in
[device
] | LIBUSB_ENDPOINT_IN
;
400 xds110
.endpoint_out
= endpoints_out
[device
] | LIBUSB_ENDPOINT_OUT
;
402 /* Save the context and device handles */
406 /* Set libusb to auto detach kernel */
407 (void)libusb_set_auto_detach_kernel_driver(dev
, 1);
409 /* Claim the debug interface on the XDS110 */
410 result
= libusb_claim_interface(dev
, xds110
.interface
);
412 /* Couldn't find an XDS110, flag the error */
416 /* On an error, clean up what we can */
419 /* Release the debug and data interface on the XDS110 */
420 (void)libusb_release_interface(dev
, xds110
.interface
);
429 /* Log the results */
431 LOG_INFO("XDS110: connected");
433 LOG_ERROR("XDS110: failed to connect");
435 return (result
== 0) ? true : false;
438 static void usb_disconnect(void)
441 /* Release the debug and data interface on the XDS110 */
442 (void)libusb_release_interface(xds110
.dev
, xds110
.interface
);
443 libusb_close(xds110
.dev
);
447 libusb_exit(xds110
.ctx
);
451 LOG_INFO("XDS110: disconnected");
454 static bool usb_read(unsigned char *buffer
, int size
, int *bytes_read
,
459 if (!xds110
.dev
|| !buffer
|| !bytes_read
)
462 /* Force a non-zero timeout to prevent blocking */
464 timeout
= DEFAULT_TIMEOUT
;
466 result
= libusb_bulk_transfer(xds110
.dev
, xds110
.endpoint_in
, buffer
, size
,
467 bytes_read
, timeout
);
469 return (result
== 0) ? true : false;
472 static bool usb_write(unsigned char *buffer
, int size
, int *written
)
474 int bytes_written
= 0;
475 int result
= LIBUSB_SUCCESS
;
478 if (!xds110
.dev
|| !buffer
)
481 result
= libusb_bulk_transfer(xds110
.dev
, xds110
.endpoint_out
, buffer
,
482 size
, &bytes_written
, 0);
484 while (result
== LIBUSB_ERROR_PIPE
&& retries
< 3) {
485 /* Try clearing the pipe stall and retry transfer */
486 libusb_clear_halt(xds110
.dev
, xds110
.endpoint_out
);
487 result
= libusb_bulk_transfer(xds110
.dev
, xds110
.endpoint_out
, buffer
,
488 size
, &bytes_written
, 0);
493 *written
= bytes_written
;
495 return (result
== 0 && size
== bytes_written
) ? true : false;
498 static bool usb_get_response(uint32_t *total_bytes_read
, uint32_t timeout
)
500 static unsigned char buffer
[MAX_PACKET
];
509 success
= usb_read(buffer
, sizeof(buffer
), &bytes_read
, timeout
);
512 * Validate that this appears to be a good response packet
513 * First check it contains enough data for header and error
514 * code, plus the first character is the start character
516 if (bytes_read
>= 7 && '*' == buffer
[0]) {
517 /* Extract the payload size */
518 size
= xds110_get_u16(&buffer
[1]);
519 /* Sanity test on payload size */
520 if (USB_PAYLOAD_SIZE
>= size
&& 4 <= size
) {
521 /* Check we didn't get more data than expected */
522 if ((bytes_read
- 3) <= size
) {
523 /* Packet appears to be valid, move on */
530 * Somehow received an invalid packet, retry till we
531 * time out or a valid response packet is received
535 /* Abort now if we didn't receive a valid response */
537 if (total_bytes_read
)
538 *total_bytes_read
= 0;
542 /* Build the return payload into xds110.read_payload */
544 /* Copy over payload data from received buffer (skipping header) */
547 memcpy((void *)&xds110
.read_payload
[count
], (void *)&buffer
[3], bytes_read
);
550 * Drop timeout to just 1/2 second. Once the XDS110 starts sending
551 * a response, the remaining packets should arrive in short order
554 timeout
= 500; /* ms */
556 /* If there's more data to retrieve, get it now */
557 while ((count
< size
) && success
) {
558 success
= usb_read(buffer
, sizeof(buffer
), &bytes_read
, timeout
);
560 if ((count
+ bytes_read
) > size
) {
561 /* Read too much data, not a valid packet, abort */
564 /* Copy this data over to xds110.read_payload */
565 memcpy((void *)&xds110
.read_payload
[count
], (void *)buffer
,
574 if (total_bytes_read
)
575 *total_bytes_read
= count
;
580 static bool usb_send_command(uint16_t size
)
582 /* Check the packet length */
583 if (size
> USB_PAYLOAD_SIZE
)
586 /* Place the start character into the packet buffer */
587 xds110
.write_packet
[0] = '*';
589 /* Place the payload size into the packet buffer */
590 xds110_set_u16(&xds110
.write_packet
[1], size
);
592 /* Adjust size to include header */
595 /* Send the data via the USB connection */
596 return usb_write(xds110
.write_packet
, (int)size
, NULL
);
599 /***************************************************************************
600 * XDS110 firmware API routines *
602 * The following functions handle calling into the XDS110 firmware to *
603 * perform requested debug actions. *
604 ***************************************************************************/
606 static bool xds_execute(uint32_t out_length
, uint32_t in_length
,
607 uint32_t attempts
, uint32_t timeout
)
612 uint32_t bytes_read
= 0;
617 while (!done
&& attempts
> 0) {
620 /* Send command to XDS110 */
621 success
= usb_send_command(out_length
);
624 /* Get response from XDS110 */
625 success
= usb_get_response(&bytes_read
, timeout
);
629 /* Check for valid response from XDS code handling */
630 if (bytes_read
!= in_length
) {
631 /* Unexpected amount of data returned */
633 LOG_DEBUG("XDS110: command 0x%02x return %" PRIu32
" bytes, expected %" PRIu32
,
634 xds110
.write_payload
[0], bytes_read
, in_length
);
636 /* Extract error code from return packet */
637 error
= (int)xds110_get_u32(&xds110
.read_payload
[0]);
639 if (error
!= SC_ERR_NONE
)
640 LOG_DEBUG("XDS110: command 0x%02x returned error %d",
641 xds110
.write_payload
[0], error
);
647 error
= SC_ERR_XDS110_FAIL
;
655 static bool xds_connect(void)
659 xds110
.write_payload
[0] = XDS_CONNECT
;
661 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
667 static bool xds_disconnect(void)
671 xds110
.write_payload
[0] = XDS_DISCONNECT
;
673 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
679 static bool xds_version(uint32_t *firmware_id
, uint16_t *hardware_id
)
681 uint8_t *fw_id_pntr
= &xds110
.read_payload
[XDS_IN_LEN
+ 0]; /* 32-bits */
682 uint8_t *hw_id_pntr
= &xds110
.read_payload
[XDS_IN_LEN
+ 4]; /* 16-bits */
686 xds110
.write_payload
[0] = XDS_VERSION
;
688 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
+ 6, DEFAULT_ATTEMPTS
,
693 *firmware_id
= xds110_get_u32(fw_id_pntr
);
695 *hardware_id
= xds110_get_u16(hw_id_pntr
);
701 static bool xds_set_tck_delay(uint32_t delay
)
703 uint8_t *delay_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 32-bits */
707 xds110
.write_payload
[0] = XDS_SET_TCK
;
709 xds110_set_u32(delay_pntr
, delay
);
711 success
= xds_execute(XDS_OUT_LEN
+ 4, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
717 static bool xds_set_trst(uint8_t trst
)
719 uint8_t *trst_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 8-bits */
723 xds110
.write_payload
[0] = XDS_SET_TRST
;
727 success
= xds_execute(XDS_OUT_LEN
+ 1, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
733 static bool xds_cycle_tck(uint32_t count
)
735 uint8_t *count_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 32-bits */
739 xds110
.write_payload
[0] = XDS_CYCLE_TCK
;
741 xds110_set_u32(count_pntr
, count
);
743 success
= xds_execute(XDS_OUT_LEN
+ 4, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
749 static bool xds_goto_state(uint32_t state
)
751 uint8_t *state_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 32-bits */
752 uint8_t *transit_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+4]; /* 32-bits */
756 xds110
.write_payload
[0] = XDS_GOTO_STATE
;
758 xds110_set_u32(state_pntr
, state
);
759 xds110_set_u32(transit_pntr
, XDS_JTAG_TRANSIT_QUICKEST
);
761 success
= xds_execute(XDS_OUT_LEN
+8, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
767 static bool xds_jtag_scan(uint32_t shift_state
, uint16_t shift_bits
,
768 uint32_t end_state
, uint8_t *data_out
, uint8_t *data_in
)
770 uint8_t *bits_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 16-bits */
771 uint8_t *path_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 2]; /* 8-bits */
772 uint8_t *trans1_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 3]; /* 8-bits */
773 uint8_t *end_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 4]; /* 8-bits */
774 uint8_t *trans2_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 5]; /* 8-bits */
775 uint8_t *pre_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 6]; /* 16-bits */
776 uint8_t *pos_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 8]; /* 16-bits */
777 uint8_t *delay_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 10]; /* 16-bits */
778 uint8_t *rep_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 12]; /* 16-bits */
779 uint8_t *out_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 14]; /* 16-bits */
780 uint8_t *in_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 16]; /* 16-bits */
781 uint8_t *data_out_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 18];
782 uint8_t *data_in_pntr
= &xds110
.read_payload
[XDS_IN_LEN
+0];
784 uint16_t total_bytes
= DIV_ROUND_UP(shift_bits
, 8);
788 xds110
.write_payload
[0] = XDS_JTAG_SCAN
;
790 xds110_set_u16(bits_pntr
, shift_bits
); /* bits to scan */
791 *path_pntr
= (uint8_t)(shift_state
& 0xff); /* IR vs DR path */
792 *trans1_pntr
= (uint8_t)XDS_JTAG_TRANSIT_QUICKEST
; /* start state route */
793 *end_pntr
= (uint8_t)(end_state
& 0xff); /* JTAG state after scan */
794 *trans2_pntr
= (uint8_t)XDS_JTAG_TRANSIT_QUICKEST
; /* end state route */
795 xds110_set_u16(pre_pntr
, 0); /* number of preamble bits */
796 xds110_set_u16(pos_pntr
, 0); /* number of postamble bits */
797 xds110_set_u16(delay_pntr
, 0); /* number of extra TCKs after scan */
798 xds110_set_u16(rep_pntr
, 1); /* number of repetitions */
799 xds110_set_u16(out_pntr
, total_bytes
); /* out buffer offset (if repeats) */
800 xds110_set_u16(in_pntr
, total_bytes
); /* in buffer offset (if repeats) */
802 memcpy((void *)data_out_pntr
, (void *)data_out
, total_bytes
);
804 success
= xds_execute(XDS_OUT_LEN
+ 18 + total_bytes
,
805 XDS_IN_LEN
+ total_bytes
, DEFAULT_ATTEMPTS
, DEFAULT_TIMEOUT
);
808 memcpy((void *)data_in
, (void *)data_in_pntr
, total_bytes
);
813 static bool xds_set_srst(uint8_t srst
)
815 uint8_t *srst_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 8-bits */
819 xds110
.write_payload
[0] = XDS_SET_SRST
;
823 success
= xds_execute(XDS_OUT_LEN
+ 1, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
829 static bool cmapi_connect(uint32_t *idcode
)
831 uint8_t *idcode_pntr
= &xds110
.read_payload
[XDS_IN_LEN
+ 0]; /* 32-bits */
835 xds110
.write_payload
[0] = CMAPI_CONNECT
;
837 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
+4, DEFAULT_ATTEMPTS
,
842 *idcode
= xds110_get_u32(idcode_pntr
);
848 static bool cmapi_disconnect(void)
852 xds110
.write_payload
[0] = CMAPI_DISCONNECT
;
854 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
860 static bool cmapi_acquire(void)
864 xds110
.write_payload
[0] = CMAPI_ACQUIRE
;
866 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
872 static bool cmapi_release(void)
876 xds110
.write_payload
[0] = CMAPI_RELEASE
;
878 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
884 static bool cmapi_read_dap_reg(uint32_t type
, uint32_t ap_num
,
885 uint32_t address
, uint32_t *value
)
887 uint8_t *type_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 8-bits */
888 uint8_t *ap_num_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 1]; /* 8-bits */
889 uint8_t *address_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 2]; /* 8-bits */
890 uint8_t *value_pntr
= &xds110
.read_payload
[XDS_IN_LEN
+ 0]; /* 32-bits */
894 xds110
.write_payload
[0] = CMAPI_REG_READ
;
896 *type_pntr
= (uint8_t)(type
& 0xff);
897 *ap_num_pntr
= (uint8_t)(ap_num
& 0xff);
898 *address_pntr
= (uint8_t)(address
& 0xff);
900 success
= xds_execute(XDS_OUT_LEN
+ 3, XDS_IN_LEN
+ 4, DEFAULT_ATTEMPTS
,
905 *value
= xds110_get_u32(value_pntr
);
911 static bool cmapi_write_dap_reg(uint32_t type
, uint32_t ap_num
,
912 uint32_t address
, uint32_t *value
)
914 uint8_t *type_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 8-bits */
915 uint8_t *ap_num_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 1]; /* 8-bits */
916 uint8_t *address_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 2]; /* 8-bits */
917 uint8_t *value_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 3]; /* 32-bits */
924 xds110
.write_payload
[0] = CMAPI_REG_WRITE
;
926 *type_pntr
= (uint8_t)(type
& 0xff);
927 *ap_num_pntr
= (uint8_t)(ap_num
& 0xff);
928 *address_pntr
= (uint8_t)(address
& 0xff);
929 xds110_set_u32(value_pntr
, *value
);
931 success
= xds_execute(XDS_OUT_LEN
+ 7, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
937 static bool swd_connect(void)
941 xds110
.write_payload
[0] = SWD_CONNECT
;
943 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
949 static bool swd_disconnect(void)
953 xds110
.write_payload
[0] = SWD_DISCONNECT
;
955 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
961 static bool cjtag_connect(uint32_t format
)
963 uint8_t *format_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 32-bits */
967 xds110
.write_payload
[0] = CJTAG_CONNECT
;
969 xds110_set_u32(format_pntr
, format
);
971 success
= xds_execute(XDS_OUT_LEN
+ 4, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
977 static bool cjtag_disconnect(void)
981 xds110
.write_payload
[0] = CJTAG_DISCONNECT
;
983 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
989 static bool xds_set_supply(uint32_t voltage
)
991 uint8_t *volts_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 32-bits */
992 uint8_t *source_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 4]; /* 8-bits */
996 xds110
.write_payload
[0] = XDS_SET_SUPPLY
;
998 xds110_set_u32(volts_pntr
, voltage
);
999 *source_pntr
= (uint8_t)(voltage
!= 0 ? 1 : 0);
1001 success
= xds_execute(XDS_OUT_LEN
+ 5, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
1007 static bool ocd_dap_request(uint8_t *dap_requests
, uint32_t request_size
,
1008 uint32_t *dap_results
, uint32_t result_count
)
1010 uint8_t *request_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0];
1011 uint8_t *result_pntr
= &xds110
.read_payload
[XDS_IN_LEN
+ 0];
1015 if (!dap_requests
|| !dap_results
)
1018 xds110
.write_payload
[0] = OCD_DAP_REQUEST
;
1020 memcpy((void *)request_pntr
, (void *)dap_requests
, request_size
);
1022 success
= xds_execute(XDS_OUT_LEN
+ request_size
,
1023 XDS_IN_LEN
+ (result_count
* 4), DEFAULT_ATTEMPTS
,
1026 if (success
&& (result_count
> 0))
1027 memcpy((void *)dap_results
, (void *)result_pntr
, result_count
* 4);
1032 static bool ocd_scan_request(uint8_t *scan_requests
, uint32_t request_size
,
1033 uint8_t *scan_results
, uint32_t result_size
)
1035 uint8_t *request_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0];
1036 uint8_t *result_pntr
= &xds110
.read_payload
[XDS_IN_LEN
+ 0];
1040 if (!scan_requests
|| !scan_results
)
1043 xds110
.write_payload
[0] = OCD_SCAN_REQUEST
;
1045 memcpy((void *)request_pntr
, (void *)scan_requests
, request_size
);
1047 success
= xds_execute(XDS_OUT_LEN
+ request_size
,
1048 XDS_IN_LEN
+ result_size
, DEFAULT_ATTEMPTS
,
1051 if (success
&& (result_size
> 0))
1052 memcpy((void *)scan_results
, (void *)result_pntr
, result_size
);
1057 static bool ocd_pathmove(uint32_t num_states
, uint8_t *path
)
1059 uint8_t *num_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 32-bits */
1060 uint8_t *path_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 4];
1067 xds110
.write_payload
[0] = OCD_PATHMOVE
;
1069 xds110_set_u32(num_pntr
, num_states
);
1071 memcpy((void *)path_pntr
, (void *)path
, num_states
);
1073 success
= xds_execute(XDS_OUT_LEN
+ 4 + num_states
, XDS_IN_LEN
,
1074 DEFAULT_ATTEMPTS
, DEFAULT_TIMEOUT
);
1079 /***************************************************************************
1080 * swd driver interface *
1082 * The following functions provide SWD support to OpenOCD. *
1083 ***************************************************************************/
1085 static int xds110_swd_init(void)
1087 xds110
.is_swd_mode
= true;
1091 static int xds110_swd_switch_seq(enum swd_special_seq seq
)
1098 LOG_ERROR("Sequence SWD line reset (%d) not supported", seq
);
1101 LOG_DEBUG("JTAG-to-SWD");
1102 xds110
.is_swd_mode
= false;
1103 xds110
.is_cmapi_connected
= false;
1104 xds110
.is_cmapi_acquired
= false;
1105 /* Run sequence to put target in SWD mode */
1106 success
= swd_connect();
1107 /* Re-initialize CMAPI API for DAP access */
1109 xds110
.is_swd_mode
= true;
1110 success
= cmapi_connect(&idcode
);
1112 xds110
.is_cmapi_connected
= true;
1113 success
= cmapi_acquire();
1118 LOG_DEBUG("SWD-to-JTAG");
1119 xds110
.is_swd_mode
= false;
1120 xds110
.is_cmapi_connected
= false;
1121 xds110
.is_cmapi_acquired
= false;
1122 /* Run sequence to put target in JTAG mode */
1123 success
= swd_disconnect();
1125 /* Re-initialize JTAG interface */
1126 success
= cjtag_connect(MODE_JTAG
);
1130 LOG_ERROR("Sequence %d not supported", seq
);
1140 static bool xds110_legacy_read_reg(uint8_t cmd
, uint32_t *value
)
1142 /* Make sure this is a read request */
1143 bool is_read_request
= (0 != (SWD_CMD_RNW
& cmd
));
1144 /* Determine whether this is a DP or AP register access */
1145 uint32_t type
= (0 != (SWD_CMD_APNDP
& cmd
)) ? DAP_AP
: DAP_DP
;
1146 /* Determine the AP number from cached SELECT value */
1147 uint32_t ap_num
= (xds110
.select
& 0xff000000) >> 24;
1148 /* Extract register address from command */
1149 uint32_t address
= ((cmd
& SWD_CMD_A32
) >> 1);
1150 /* Extract bank address from cached SELECT value */
1151 uint32_t bank
= (xds110
.select
& 0x000000f0);
1153 uint32_t reg_value
= 0;
1154 uint32_t temp_value
= 0;
1158 if (!is_read_request
)
1161 if (type
== DAP_AP
) {
1162 /* Add bank address to register address for CMAPI call */
1166 if (DAP_DP
== type
&& DAP_DP_RDBUFF
== address
&& xds110
.use_rdbuff
) {
1167 /* If RDBUFF is cached and this is a DP RDBUFF read, use the cache */
1168 reg_value
= xds110
.rdbuff
;
1170 } else if (DAP_AP
== type
&& DAP_AP_DRW
== address
&& xds110
.use_rdbuff
) {
1171 /* If RDBUFF is cached and this is an AP DRW read, use the cache, */
1172 /* but still call into the firmware to get the next read. */
1173 reg_value
= xds110
.rdbuff
;
1174 success
= cmapi_read_dap_reg(type
, ap_num
, address
, &temp_value
);
1176 success
= cmapi_read_dap_reg(type
, ap_num
, address
, &temp_value
);
1178 reg_value
= temp_value
;
1181 /* Mark that we have consumed or invalidated the RDBUFF cache */
1182 xds110
.use_rdbuff
= false;
1184 /* Handle result of read attempt */
1186 LOG_ERROR("XDS110: failed to read DAP register");
1190 if (success
&& DAP_AP
== type
) {
1192 * On a successful DAP AP read, we actually have the value from RDBUFF,
1193 * the firmware will have run the AP request and made the RDBUFF read
1195 xds110
.use_rdbuff
= true;
1196 xds110
.rdbuff
= temp_value
;
1202 static bool xds110_legacy_write_reg(uint8_t cmd
, uint32_t value
)
1204 /* Make sure this isn't a read request */
1205 bool is_read_request
= (0 != (SWD_CMD_RNW
& cmd
));
1206 /* Determine whether this is a DP or AP register access */
1207 uint32_t type
= (0 != (SWD_CMD_APNDP
& cmd
)) ? DAP_AP
: DAP_DP
;
1208 /* Determine the AP number from cached SELECT value */
1209 uint32_t ap_num
= (xds110
.select
& 0xff000000) >> 24;
1210 /* Extract register address from command */
1211 uint32_t address
= ((cmd
& SWD_CMD_A32
) >> 1);
1212 /* Extract bank address from cached SELECT value */
1213 uint32_t bank
= (xds110
.select
& 0x000000f0);
1217 if (is_read_request
)
1220 /* Invalidate the RDBUFF cache */
1221 xds110
.use_rdbuff
= false;
1223 if (type
== DAP_AP
) {
1224 /* Add bank address to register address for CMAPI call */
1226 /* Any write to an AP register invalidates the firmware's cache */
1227 xds110
.is_ap_dirty
= true;
1228 } else if (address
== DAP_DP_SELECT
) {
1229 /* Any write to the SELECT register invalidates the firmware's cache */
1230 xds110
.is_ap_dirty
= true;
1233 success
= cmapi_write_dap_reg(type
, ap_num
, address
, &value
);
1236 LOG_ERROR("XDS110: failed to write DAP register");
1239 * If the debugger wrote to SELECT, cache the value
1240 * to use to build the apNum and address values above
1242 if ((type
== DAP_DP
) && (address
== DAP_DP_SELECT
))
1243 xds110
.select
= value
;
1249 static int xds110_swd_run_queue(void)
1251 static uint32_t dap_results
[MAX_RESULT_QUEUE
];
1256 bool success
= true;
1258 if (xds110
.txn_request_size
== 0)
1261 /* Terminate request queue */
1262 xds110
.txn_requests
[xds110
.txn_request_size
++] = 0;
1264 if (xds110
.firmware
>= OCD_FIRMWARE_VERSION
) {
1265 /* XDS110 firmware has the API to directly handle the queue */
1266 success
= ocd_dap_request(xds110
.txn_requests
,
1267 xds110
.txn_request_size
, dap_results
, xds110
.txn_result_count
);
1269 /* Legacy firmware needs to handle queue via discrete DAP calls */
1272 while (xds110
.txn_requests
[request
] != 0) {
1273 cmd
= xds110
.txn_requests
[request
++];
1274 if (0 == (SWD_CMD_RNW
& cmd
)) {
1275 /* DAP register write command */
1276 value
= (uint32_t)(xds110
.txn_requests
[request
++]) << 0;
1277 value
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 8;
1278 value
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 16;
1279 value
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 24;
1281 success
= xds110_legacy_write_reg(cmd
, value
);
1283 /* DAP register read command */
1286 success
= xds110_legacy_read_reg(cmd
, &value
);
1287 dap_results
[result
++] = value
;
1292 /* Transfer results into caller's buffers */
1293 for (result
= 0; result
< xds110
.txn_result_count
; result
++)
1294 if (xds110
.txn_dap_results
[result
])
1295 *xds110
.txn_dap_results
[result
] = dap_results
[result
];
1297 xds110
.txn_request_size
= 0;
1298 xds110
.txn_result_size
= 0;
1299 xds110
.txn_result_count
= 0;
1301 return (success
) ? ERROR_OK
: ERROR_FAIL
;
1304 static void xds110_swd_queue_cmd(uint8_t cmd
, uint32_t *value
)
1306 /* Check if this is a read or write request */
1307 bool is_read_request
= (0 != (SWD_CMD_RNW
& cmd
));
1308 /* Determine whether this is a DP or AP register access */
1309 uint32_t type
= (0 != (SWD_CMD_APNDP
& cmd
)) ? DAP_AP
: DAP_DP
;
1310 /* Extract register address from command */
1311 uint32_t address
= ((cmd
& SWD_CMD_A32
) >> 1);
1312 uint32_t request_size
= (is_read_request
) ? 1 : 5;
1314 /* Check if new request would be too large to fit */
1315 if (((xds110
.txn_request_size
+ request_size
+ 1) > MAX_DATA_BLOCK
) ||
1316 ((xds110
.txn_result_count
+ 1) > MAX_RESULT_QUEUE
))
1317 xds110_swd_run_queue();
1319 /* Set the START bit in cmd to ensure cmd is not zero */
1320 /* (a value of zero is used to terminate the buffer) */
1321 cmd
|= SWD_CMD_START
;
1323 /* Add request to queue; queue is built marshalled for XDS110 call */
1324 if (is_read_request
) {
1325 /* Queue read request, save pointer to pass back result */
1326 xds110
.txn_requests
[xds110
.txn_request_size
++] = cmd
;
1327 xds110
.txn_dap_results
[xds110
.txn_result_count
++] = value
;
1328 xds110
.txn_result_size
+= 4;
1330 /* Check for and prevent sticky overrun detection */
1331 if (DAP_DP
== type
&& DAP_DP_CTRL
== address
&&
1332 (*value
& CORUNDETECT
)) {
1333 LOG_DEBUG("XDS110: refusing to enable sticky overrun detection");
1334 *value
&= ~CORUNDETECT
;
1336 /* Queue write request, add value directly to queue buffer */
1337 xds110
.txn_requests
[xds110
.txn_request_size
++] = cmd
;
1338 xds110
.txn_requests
[xds110
.txn_request_size
++] = (*value
>> 0) & 0xff;
1339 xds110
.txn_requests
[xds110
.txn_request_size
++] = (*value
>> 8) & 0xff;
1340 xds110
.txn_requests
[xds110
.txn_request_size
++] = (*value
>> 16) & 0xff;
1341 xds110
.txn_requests
[xds110
.txn_request_size
++] = (*value
>> 24) & 0xff;
1345 static void xds110_swd_read_reg(uint8_t cmd
, uint32_t *value
,
1346 uint32_t ap_delay_clk
)
1348 assert(cmd
& SWD_CMD_RNW
);
1349 xds110_swd_queue_cmd(cmd
, value
);
1351 static void xds110_swd_write_reg(uint8_t cmd
, uint32_t value
,
1352 uint32_t ap_delay_clk
)
1354 assert(!(cmd
& SWD_CMD_RNW
));
1355 xds110_swd_queue_cmd(cmd
, &value
);
1358 /***************************************************************************
1361 * The following functions provide XDS110 interface to OpenOCD. *
1362 ***************************************************************************/
1364 static void xds110_show_info(void)
1366 uint32_t firmware
= xds110
.firmware
;
1368 LOG_INFO("XDS110: vid/pid = %04x/%04x", xds110
.vid
, xds110
.pid
);
1369 LOG_INFO("XDS110: firmware version = %" PRIu32
".%" PRIu32
".%" PRIu32
".%" PRIu32
,
1370 (((firmware
>> 28) & 0xf) * 10) + ((firmware
>> 24) & 0xf),
1371 (((firmware
>> 20) & 0xf) * 10) + ((firmware
>> 16) & 0xf),
1372 (((firmware
>> 12) & 0xf) * 10) + ((firmware
>> 8) & 0xf),
1373 (((firmware
>> 4) & 0xf) * 10) + ((firmware
>> 0) & 0xf));
1374 LOG_INFO("XDS110: hardware version = 0x%04x", xds110
.hardware
);
1375 if (adapter_get_required_serial())
1376 LOG_INFO("XDS110: serial number = %s", adapter_get_required_serial());
1377 if (xds110
.is_swd_mode
) {
1378 LOG_INFO("XDS110: connected to target via SWD");
1379 LOG_INFO("XDS110: SWCLK set to %" PRIu32
" kHz", xds110
.speed
);
1381 LOG_INFO("XDS110: connected to target via JTAG");
1382 LOG_INFO("XDS110: TCK set to %" PRIu32
" kHz", xds110
.speed
);
1385 /* Alert user that there's a better firmware to use */
1386 if (firmware
< OCD_FIRMWARE_VERSION
) {
1387 LOG_WARNING("XDS110: the firmware is not optimized for OpenOCD");
1388 LOG_WARNING(OCD_FIRMWARE_UPGRADE
);
1392 static int xds110_quit(void)
1394 if (xds110
.is_cmapi_acquired
) {
1395 (void)cmapi_release();
1396 xds110
.is_cmapi_acquired
= false;
1398 if (xds110
.is_cmapi_connected
) {
1399 (void)cmapi_disconnect();
1400 xds110
.is_cmapi_connected
= false;
1402 if (xds110
.is_connected
) {
1403 if (xds110
.is_swd_mode
) {
1404 /* Switch out of SWD mode */
1405 (void)swd_disconnect();
1407 /* Switch out of cJTAG mode */
1408 (void)cjtag_disconnect();
1410 /* Tell firmware we're disconnecting */
1411 (void)xds_disconnect();
1412 xds110
.is_connected
= false;
1414 /* Close down the USB connection to the XDS110 debug probe */
1420 static int xds110_init(void)
1424 /* Establish USB connection to the XDS110 debug probe */
1425 success
= usb_connect();
1428 /* Send connect message to XDS110 firmware */
1429 success
= xds_connect();
1431 xds110
.is_connected
= true;
1438 /* Retrieve version IDs from firmware */
1439 /* Version numbers are stored in BCD format */
1440 success
= xds_version(&firmware
, &hardware
);
1442 /* Save the firmware and hardware version */
1443 xds110
.firmware
= firmware
;
1444 xds110
.hardware
= hardware
;
1449 /* Set supply voltage for stand-alone probes */
1450 if (xds110
.hardware
== XDS110_STAND_ALONE_ID
) {
1451 success
= xds_set_supply(xds110
.voltage
);
1452 /* Allow time for target device to power up */
1453 /* (CC32xx takes up to 1300 ms before debug is enabled) */
1455 } else if (xds110
.voltage
!= 0) {
1456 /* Voltage supply not a feature of embedded probes */
1458 "XDS110: ignoring supply voltage, not supported on this probe");
1463 success
= xds_set_trst(0);
1465 success
= xds_cycle_tck(50);
1467 success
= xds_set_trst(1);
1469 success
= xds_cycle_tck(50);
1473 if (xds110
.is_swd_mode
) {
1474 /* Switch to SWD if needed */
1475 success
= swd_connect();
1477 success
= cjtag_connect(MODE_JTAG
);
1481 if (success
&& xds110
.is_swd_mode
) {
1484 /* Connect to CMAPI interface in XDS110 */
1485 success
= cmapi_connect(&idcode
);
1487 /* Acquire exclusive access to CMAPI interface */
1489 xds110
.is_cmapi_connected
= true;
1490 success
= cmapi_acquire();
1492 xds110
.is_cmapi_acquired
= true;
1502 return (success
) ? ERROR_OK
: ERROR_FAIL
;
1505 static void xds110_legacy_scan(uint32_t shift_state
, uint32_t total_bits
,
1506 uint32_t end_state
, uint8_t *data_out
, uint8_t *data_in
)
1508 (void)xds_jtag_scan(shift_state
, total_bits
, end_state
, data_out
, data_in
);
1511 static void xds110_legacy_runtest(uint32_t clocks
, uint32_t end_state
)
1513 xds_goto_state(XDS_JTAG_STATE_IDLE
);
1514 xds_cycle_tck(clocks
);
1515 xds_goto_state(end_state
);
1518 static void xds110_legacy_stableclocks(uint32_t clocks
)
1520 xds_cycle_tck(clocks
);
1523 static void xds110_flush(void)
1527 uint32_t shift_state
;
1534 uint8_t data_in
[MAX_DATA_BLOCK
];
1537 if (xds110
.txn_request_size
== 0)
1540 /* Terminate request queue */
1541 xds110
.txn_requests
[xds110
.txn_request_size
++] = 0;
1543 if (xds110
.firmware
>= OCD_FIRMWARE_VERSION
) {
1544 /* Updated firmware has the API to directly handle the queue */
1545 (void)ocd_scan_request(xds110
.txn_requests
, xds110
.txn_request_size
,
1546 data_in
, xds110
.txn_result_size
);
1548 /* Legacy firmware needs to handle queue via discrete JTAG calls */
1551 while (xds110
.txn_requests
[request
] != 0) {
1552 command
= xds110
.txn_requests
[request
++];
1556 if (command
== CMD_IR_SCAN
)
1557 shift_state
= XDS_JTAG_STATE_SHIFT_IR
;
1559 shift_state
= XDS_JTAG_STATE_SHIFT_DR
;
1560 end_state
= (uint32_t)(xds110
.txn_requests
[request
++]);
1561 bits
= (uint32_t)(xds110
.txn_requests
[request
++]) << 0;
1562 bits
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 8;
1563 data_out
= &xds110
.txn_requests
[request
];
1564 bytes
= DIV_ROUND_UP(bits
, 8);
1565 xds110_legacy_scan(shift_state
, bits
, end_state
, data_out
,
1571 clocks
= (uint32_t)(xds110
.txn_requests
[request
++]) << 0;
1572 clocks
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 8;
1573 clocks
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 16;
1574 clocks
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 24;
1575 end_state
= (uint32_t)xds110
.txn_requests
[request
++];
1576 xds110_legacy_runtest(clocks
, end_state
);
1578 case CMD_STABLECLOCKS
:
1579 clocks
= (uint32_t)(xds110
.txn_requests
[request
++]) << 0;
1580 clocks
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 8;
1581 clocks
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 16;
1582 clocks
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 24;
1583 xds110_legacy_stableclocks(clocks
);
1586 LOG_ERROR("BUG: unknown JTAG command type 0x%x encountered",
1594 /* Transfer results into caller's buffers from data_in buffer */
1595 bits
= 0; /* Bit offset into current scan result */
1596 data_pntr
= data_in
;
1597 for (result
= 0; result
< xds110
.txn_result_count
; result
++) {
1598 if (xds110
.txn_scan_results
[result
].first
) {
1600 bytes
= DIV_ROUND_UP(bits
, 8);
1605 if (xds110
.txn_scan_results
[result
].buffer
)
1606 bit_copy(xds110
.txn_scan_results
[result
].buffer
, 0, data_pntr
,
1607 bits
, xds110
.txn_scan_results
[result
].num_bits
);
1608 bits
+= xds110
.txn_scan_results
[result
].num_bits
;
1611 xds110
.txn_request_size
= 0;
1612 xds110
.txn_result_size
= 0;
1613 xds110
.txn_result_count
= 0;
1616 static int xds110_reset(int trst
, int srst
)
1620 int retval
= ERROR_OK
;
1624 /* Deassert nTRST (active low) */
1627 /* Assert nTRST (active low) */
1630 success
= xds_set_trst(value
);
1632 retval
= ERROR_FAIL
;
1637 /* Deassert nSRST (active low) */
1640 /* Assert nSRST (active low) */
1643 success
= xds_set_srst(value
);
1645 retval
= ERROR_FAIL
;
1647 /* Toggle TCK to trigger HIB on CC13x/CC26x devices */
1648 if (success
&& !xds110
.is_swd_mode
) {
1649 /* Toggle TCK for about 50 ms */
1650 success
= xds_cycle_tck(xds110
.speed
* 50);
1654 retval
= ERROR_FAIL
;
1660 static void xds110_execute_sleep(struct jtag_command
*cmd
)
1662 jtag_sleep(cmd
->cmd
.sleep
->us
);
1665 static void xds110_execute_tlr_reset(struct jtag_command
*cmd
)
1667 (void)xds_goto_state(XDS_JTAG_STATE_RESET
);
1670 static void xds110_execute_pathmove(struct jtag_command
*cmd
)
1673 uint32_t num_states
;
1676 num_states
= (uint32_t)cmd
->cmd
.pathmove
->num_states
;
1678 if (num_states
== 0)
1681 path
= malloc(num_states
* sizeof(uint8_t));
1683 LOG_ERROR("XDS110: unable to allocate memory");
1687 /* Convert requested path states into XDS API states */
1688 for (i
= 0; i
< num_states
; i
++)
1689 path
[i
] = (uint8_t)xds_jtag_state
[cmd
->cmd
.pathmove
->path
[i
]];
1691 if (xds110
.firmware
>= OCD_FIRMWARE_VERSION
) {
1692 /* Updated firmware fully supports pathmove */
1693 (void)ocd_pathmove(num_states
, path
);
1695 /* Notify user that legacy firmware simply cannot handle pathmove */
1696 LOG_ERROR("XDS110: the firmware does not support pathmove command");
1697 LOG_ERROR(OCD_FIRMWARE_UPGRADE
);
1698 /* If pathmove is required, then debug is not possible */
1705 static void xds110_queue_scan(struct jtag_command
*cmd
)
1709 uint32_t total_fields
;
1710 uint32_t total_bits
;
1711 uint32_t total_bytes
;
1715 /* Calculate the total number of bits to scan */
1718 for (i
= 0; i
< cmd
->cmd
.scan
->num_fields
; i
++) {
1720 total_bits
+= (uint32_t)cmd
->cmd
.scan
->fields
[i
].num_bits
;
1723 if (total_bits
== 0)
1726 total_bytes
= DIV_ROUND_UP(total_bits
, 8);
1728 /* Check if new request would be too large to fit */
1729 if (((xds110
.txn_request_size
+ 1 + total_bytes
+ sizeof(end_state
) + 1)
1730 > MAX_DATA_BLOCK
) || ((xds110
.txn_result_count
+ total_fields
) >
1734 /* Check if this single request is too large to fit */
1735 if ((1 + total_bytes
+ sizeof(end_state
) + 1) > MAX_DATA_BLOCK
) {
1736 LOG_ERROR("BUG: JTAG scan request is too large to handle (%" PRIu32
" bits)",
1738 /* Failing to run this scan mucks up debug on this target */
1742 if (cmd
->cmd
.scan
->ir_scan
)
1743 xds110
.txn_requests
[xds110
.txn_request_size
++] = CMD_IR_SCAN
;
1745 xds110
.txn_requests
[xds110
.txn_request_size
++] = CMD_DR_SCAN
;
1747 end_state
= (uint8_t)xds_jtag_state
[cmd
->cmd
.scan
->end_state
];
1748 xds110
.txn_requests
[xds110
.txn_request_size
++] = end_state
;
1750 xds110
.txn_requests
[xds110
.txn_request_size
++] = (total_bits
>> 0) & 0xff;
1751 xds110
.txn_requests
[xds110
.txn_request_size
++] = (total_bits
>> 8) & 0xff;
1753 /* Build request data by flattening fields into single buffer */
1754 /* also populate the results array to return the results when run */
1756 buffer
= &xds110
.txn_requests
[xds110
.txn_request_size
];
1757 /* Clear data out buffer to default value of all zeros */
1758 memset((void *)buffer
, 0x00, total_bytes
);
1759 for (i
= 0; i
< cmd
->cmd
.scan
->num_fields
; i
++) {
1760 if (cmd
->cmd
.scan
->fields
[i
].out_value
) {
1761 /* Copy over data to scan out into request buffer */
1762 bit_copy(buffer
, offset
, cmd
->cmd
.scan
->fields
[i
].out_value
, 0,
1763 cmd
->cmd
.scan
->fields
[i
].num_bits
);
1765 offset
+= cmd
->cmd
.scan
->fields
[i
].num_bits
;
1766 xds110
.txn_scan_results
[xds110
.txn_result_count
].first
= (i
== 0);
1767 xds110
.txn_scan_results
[xds110
.txn_result_count
].num_bits
=
1768 cmd
->cmd
.scan
->fields
[i
].num_bits
;
1769 xds110
.txn_scan_results
[xds110
.txn_result_count
++].buffer
=
1770 cmd
->cmd
.scan
->fields
[i
].in_value
;
1772 xds110
.txn_request_size
+= total_bytes
;
1773 xds110
.txn_result_size
+= total_bytes
;
1776 static void xds110_queue_runtest(struct jtag_command
*cmd
)
1778 uint32_t clocks
= (uint32_t)cmd
->cmd
.stableclocks
->num_cycles
;
1779 uint8_t end_state
= (uint8_t)xds_jtag_state
[cmd
->cmd
.runtest
->end_state
];
1781 /* Check if new request would be too large to fit */
1782 if ((xds110
.txn_request_size
+ 1 + sizeof(clocks
) + sizeof(end_state
) + 1)
1786 /* Queue request and cycle count directly to queue buffer */
1787 xds110
.txn_requests
[xds110
.txn_request_size
++] = CMD_RUNTEST
;
1788 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 0) & 0xff;
1789 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 8) & 0xff;
1790 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 16) & 0xff;
1791 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 24) & 0xff;
1792 xds110
.txn_requests
[xds110
.txn_request_size
++] = end_state
;
1795 static void xds110_queue_stableclocks(struct jtag_command
*cmd
)
1797 uint32_t clocks
= (uint32_t)cmd
->cmd
.stableclocks
->num_cycles
;
1799 /* Check if new request would be too large to fit */
1800 if ((xds110
.txn_request_size
+ 1 + sizeof(clocks
) + 1) > MAX_DATA_BLOCK
)
1803 /* Queue request and cycle count directly to queue buffer */
1804 xds110
.txn_requests
[xds110
.txn_request_size
++] = CMD_STABLECLOCKS
;
1805 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 0) & 0xff;
1806 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 8) & 0xff;
1807 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 16) & 0xff;
1808 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 24) & 0xff;
1811 static void xds110_execute_command(struct jtag_command
*cmd
)
1813 switch (cmd
->type
) {
1816 xds110_execute_sleep(cmd
);
1818 case JTAG_TLR_RESET
:
1820 xds110_execute_tlr_reset(cmd
);
1824 xds110_execute_pathmove(cmd
);
1827 xds110_queue_scan(cmd
);
1830 xds110_queue_runtest(cmd
);
1832 case JTAG_STABLECLOCKS
:
1833 xds110_queue_stableclocks(cmd
);
1837 LOG_ERROR("BUG: unknown JTAG command type 0x%x encountered",
1843 static int xds110_execute_queue(void)
1845 struct jtag_command
*cmd
= jtag_command_queue
;
1848 xds110_execute_command(cmd
);
1857 static int xds110_speed(int speed
)
1860 uint32_t delay_count
;
1864 LOG_INFO("XDS110: RTCK not supported");
1865 return ERROR_JTAG_NOT_IMPLEMENTED
;
1868 if (speed
< XDS110_MIN_TCK_SPEED
) {
1869 LOG_INFO("XDS110: increase speed request: %d kHz to %d kHz minimum",
1870 speed
, XDS110_MIN_TCK_SPEED
);
1871 speed
= XDS110_MIN_TCK_SPEED
;
1874 /* Older XDS110 firmware had inefficient scan routines and could only */
1875 /* achieve a peak TCK frequency of about 2500 kHz */
1876 if (xds110
.firmware
< FAST_TCK_FIRMWARE_VERSION
) {
1878 /* Check for request for top speed or higher */
1879 if (speed
>= XDS110_MAX_SLOW_TCK_SPEED
) {
1881 /* Inform user that speed was adjusted down to max possible */
1882 if (speed
> XDS110_MAX_SLOW_TCK_SPEED
) {
1884 "XDS110: reduce speed request: %d kHz to %d kHz maximum",
1885 speed
, XDS110_MAX_SLOW_TCK_SPEED
);
1886 speed
= XDS110_MAX_SLOW_TCK_SPEED
;
1892 const double XDS110_TCK_PULSE_INCREMENT
= 66.0;
1893 freq_to_use
= speed
* 1000; /* Hz */
1896 /* Calculate the delay count value */
1897 double one_giga
= 1000000000;
1898 /* Get the pulse duration for the max frequency supported in ns */
1899 double max_freq_pulse_duration
= one_giga
/
1900 (XDS110_MAX_SLOW_TCK_SPEED
* 1000);
1902 /* Convert frequency to pulse duration */
1903 double freq_to_pulse_width_in_ns
= one_giga
/ freq_to_use
;
1906 * Start with the pulse duration for the maximum frequency. Keep
1907 * decrementing time added by each count value till the requested
1908 * frequency pulse is less than the calculated value.
1910 double current_value
= max_freq_pulse_duration
;
1912 while (current_value
< freq_to_pulse_width_in_ns
) {
1913 current_value
+= XDS110_TCK_PULSE_INCREMENT
;
1918 * Determine which delay count yields the best match.
1919 * The one obtained above or one less.
1922 double diff_freq_1
= freq_to_use
-
1923 (one_giga
/ (max_freq_pulse_duration
+
1924 (XDS110_TCK_PULSE_INCREMENT
* delay_count
)));
1925 double diff_freq_2
= (one_giga
/ (max_freq_pulse_duration
+
1926 (XDS110_TCK_PULSE_INCREMENT
* (delay_count
- 1)))) -
1929 /* One less count value yields a better match */
1930 if (diff_freq_1
> diff_freq_2
)
1935 /* Newer firmware has reworked TCK routines that are much more efficient */
1936 /* and can now achieve a peak TCK frequency of 14000 kHz */
1939 if (speed
>= XDS110_MAX_FAST_TCK_SPEED
) {
1940 if (speed
> XDS110_MAX_FAST_TCK_SPEED
) {
1942 "XDS110: reduce speed request: %d kHz to %d kHz maximum",
1943 speed
, XDS110_MAX_FAST_TCK_SPEED
);
1944 speed
= XDS110_MAX_FAST_TCK_SPEED
;
1947 } else if (speed
>= 12000 && xds110
.firmware
>=
1948 FAST_TCK_PLUS_FIRMWARE_VERSION
) {
1949 delay_count
= FAST_TCK_DELAY_12000_KHZ
;
1950 } else if (speed
>= 10000 && xds110
.firmware
>=
1951 FAST_TCK_PLUS_FIRMWARE_VERSION
) {
1952 delay_count
= FAST_TCK_DELAY_10000_KHZ
;
1953 } else if (speed
>= 8500) {
1954 delay_count
= FAST_TCK_DELAY_8500_KHZ
;
1955 } else if (speed
>= 5500) {
1956 delay_count
= FAST_TCK_DELAY_5500_KHZ
;
1958 /* Calculate the delay count to set the frequency */
1959 /* Formula determined by measuring the waveform on Saeleae logic */
1960 /* analyzer using known values for delay count */
1961 const double m
= 17100000.0; /* slope */
1962 const double b
= -1.02; /* y-intercept */
1964 freq_to_use
= speed
* 1000; /* Hz */
1965 double period
= 1.0/freq_to_use
;
1966 double delay
= m
* period
+ b
;
1971 delay_count
= (uint32_t)delay
;
1975 /* Send the delay count to the XDS110 firmware */
1976 success
= xds_set_tck_delay(delay_count
);
1979 xds110
.delay_count
= delay_count
;
1980 xds110
.speed
= speed
;
1983 return (success
) ? ERROR_OK
: ERROR_FAIL
;
1986 static int xds110_speed_div(int speed
, int *khz
)
1992 static int xds110_khz(int khz
, int *jtag_speed
)
1998 COMMAND_HANDLER(xds110_handle_info_command
)
2004 COMMAND_HANDLER(xds110_handle_supply_voltage_command
)
2006 uint32_t voltage
= 0;
2008 if (CMD_ARGC
== 1) {
2009 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], voltage
);
2010 if (voltage
== 0 || (voltage
>= XDS110_MIN_VOLTAGE
&& voltage
2011 <= XDS110_MAX_VOLTAGE
)) {
2012 /* Requested voltage is in range */
2013 xds110
.voltage
= voltage
;
2015 LOG_ERROR("XDS110: voltage must be 0 or between %d and %d "
2016 "millivolts", XDS110_MIN_VOLTAGE
, XDS110_MAX_VOLTAGE
);
2019 xds110
.voltage
= voltage
;
2021 return ERROR_COMMAND_SYNTAX_ERROR
;
2026 static const struct command_registration xds110_subcommand_handlers
[] = {
2029 .handler
= &xds110_handle_info_command
,
2030 .mode
= COMMAND_EXEC
,
2031 .help
= "show XDS110 info",
2036 .handler
= &xds110_handle_supply_voltage_command
,
2037 .mode
= COMMAND_CONFIG
,
2038 .help
= "set the XDS110 probe supply voltage",
2039 .usage
= "voltage_in_millivolts",
2041 COMMAND_REGISTRATION_DONE
2044 static const struct command_registration xds110_command_handlers
[] = {
2047 .mode
= COMMAND_ANY
,
2048 .help
= "perform XDS110 management",
2050 .chain
= xds110_subcommand_handlers
,
2052 COMMAND_REGISTRATION_DONE
2055 static const struct swd_driver xds110_swd_driver
= {
2056 .init
= xds110_swd_init
,
2057 .switch_seq
= xds110_swd_switch_seq
,
2058 .read_reg
= xds110_swd_read_reg
,
2059 .write_reg
= xds110_swd_write_reg
,
2060 .run
= xds110_swd_run_queue
,
2063 static const char * const xds110_transport
[] = { "swd", "jtag", NULL
};
2065 static struct jtag_interface xds110_interface
= {
2066 .execute_queue
= xds110_execute_queue
,
2069 struct adapter_driver xds110_adapter_driver
= {
2071 .transports
= xds110_transport
,
2072 .commands
= xds110_command_handlers
,
2074 .init
= xds110_init
,
2075 .quit
= xds110_quit
,
2076 .reset
= xds110_reset
,
2077 .speed
= xds110_speed
,
2079 .speed_div
= xds110_speed_div
,
2081 .jtag_ops
= &xds110_interface
,
2082 .swd_ops
= &xds110_swd_driver
,
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)