1 /***************************************************************************
2 * Copyright (C) 2017 by Texas Instruments, Inc. *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
16 ***************************************************************************/
22 #include <transport/transport.h>
24 #include <jtag/interface.h>
25 #include <jtag/commands.h>
29 /* XDS110 USB serial number length */
30 #define XDS110_SERIAL_LEN 8
32 /* XDS110 stand-alone probe voltage supply limits */
33 #define XDS110_MIN_VOLTAGE 1800
34 #define XDS110_MAX_VOLTAGE 3600
36 /* XDS110 stand-alone probe hardware ID */
37 #define XDS110_STAND_ALONE_ID 0x21
39 /* Firmware version that introduced OpenOCD support via block accesses */
40 #define OCD_FIRMWARE_VERSION 0x02030011
41 #define OCD_FIRMWARE_UPGRADE \
42 "XDS110: upgrade to version 2.3.0.11+ for improved support"
44 /***************************************************************************
45 * USB Connection Buffer Definitions *
46 ***************************************************************************/
48 /* Max USB packet size for up to USB 3.0 */
49 #define MAX_PACKET 1024
52 * Maximum data payload that can be handled in a single call
53 * Limitation is the size of the buffers in the XDS110 firmware
55 #define MAX_DATA_BLOCK 4096
57 #ifndef USB_PAYLOAD_SIZE
58 /* Largest data block plus parameters */
59 #define USB_PAYLOAD_SIZE (MAX_DATA_BLOCK + 60)
61 #define MAX_RESULT_QUEUE (MAX_DATA_BLOCK / 4)
63 /***************************************************************************
64 * USB Connection Endpoints *
65 ***************************************************************************/
67 /* Bulk endpoints used by the XDS110 debug interface */
68 #define INTERFACE_DEBUG (2)
69 #define ENDPOINT_DEBUG_IN (3 | LIBUSB_ENDPOINT_IN)
70 #define ENDPOINT_DEBUG_OUT (2 | LIBUSB_ENDPOINT_OUT)
72 /***************************************************************************
73 * XDS110 Firmware API Definitions *
74 ***************************************************************************/
77 * Default values controlling how the host communicates commands
78 * with XDS110 firmware (automatic retry count and wait timeout)
80 #define DEFAULT_ATTEMPTS (1)
81 #define DEFAULT_TIMEOUT (4000)
83 /* XDS110 API error codes */
85 #define SC_ERR_XDS110_FAIL -261
86 #define SC_ERR_SWD_WAIT -613
87 #define SC_ERR_SWD_FAULT -614
88 #define SC_ERR_SWD_PROTOCOL -615
89 #define SC_ERR_SWD_PARITY -616
90 #define SC_ERR_SWD_DEVICE_ID -617
92 /* TCK frequency limits */
93 #define XDS110_MIN_TCK_SPEED 100 /* kHz */
94 #define XDS110_MAX_TCK_SPEED 2500 /* kHz */
95 #define XDS110_TCK_PULSE_INCREMENT 66.0
97 /* Scan mode on connect */
100 /* XDS110 API JTAG state definitions */
101 #define XDS_JTAG_STATE_RESET 1
102 #define XDS_JTAG_STATE_IDLE 2
103 #define XDS_JTAG_STATE_SHIFT_DR 3
104 #define XDS_JTAG_STATE_SHIFT_IR 4
105 #define XDS_JTAG_STATE_PAUSE_DR 5
106 #define XDS_JTAG_STATE_PAUSE_IR 6
107 #define XDS_JTAG_STATE_EXIT1_DR 8
108 #define XDS_JTAG_STATE_EXIT1_IR 9
109 #define XDS_JTAG_STATE_EXIT2_DR 10
110 #define XDS_JTAG_STATE_EXIT2_IR 11
111 #define XDS_JTAG_STATE_SELECT_DR 12
112 #define XDS_JTAG_STATE_SELECT_IR 13
113 #define XDS_JTAG_STATE_UPDATE_DR 14
114 #define XDS_JTAG_STATE_UPDATE_IR 15
115 #define XDS_JTAG_STATE_CAPTURE_DR 16
116 #define XDS_JTAG_STATE_CAPTURE_IR 17
118 /* XDS110 API JTAG transit definitions */
119 #define XDS_JTAG_TRANSIT_QUICKEST 1
120 #define XDS_JTAG_TRANSIT_VIA_CAPTURE 2
121 #define XDS_JTAG_TRANSIT_VIA_IDLE 3
123 /* DAP register definitions as used by XDS110 APIs */
125 #define DAP_AP 0 /* DAP AP register type */
126 #define DAP_DP 1 /* DAP DP register type */
128 #define DAP_DP_IDCODE 0x0 /* DAP DP IDCODE register (read only) */
129 #define DAP_DP_ABORT 0x0 /* DAP DP ABORT register (write only) */
130 #define DAP_DP_STAT 0x4 /* DAP DP STAT register (for read only) */
131 #define DAP_DP_CTRL 0x4 /* DAP DP CTRL register (for write only) */
132 #define DAP_DP_ADDR 0x8 /* DAP DP SELECT register (legacy name) */
133 #define DAP_DP_RESEND 0x8 /* DAP DP RESEND register (read only) */
134 #define DAP_DP_SELECT 0x8 /* DAP DP SELECT register (write only) */
135 #define DAP_DP_RDBUFF 0xc /* DAP DP RDBUFF Read Buffer register */
137 #define DAP_AP_CSW 0x00 /* DAP AP Control Status Word */
138 #define DAP_AP_TAR 0x04 /* DAP AP Transfer Address */
139 #define DAP_AP_DRW 0x0C /* DAP AP Data Read/Write */
140 #define DAP_AP_BD0 0x10 /* DAP AP Banked Data 0 */
141 #define DAP_AP_BD1 0x14 /* DAP AP Banked Data 1 */
142 #define DAP_AP_BD2 0x18 /* DAP AP Banked Data 2 */
143 #define DAP_AP_BD3 0x1C /* DAP AP Banked Data 3 */
144 #define DAP_AP_RTBL 0xF8 /* DAP AP Debug ROM Table */
145 #define DAP_AP_IDR 0xFC /* DAP AP Identification Register */
147 /* Command packet definitions */
149 #define XDS_OUT_LEN 1 /* command (byte) */
150 #define XDS_IN_LEN 4 /* error code (int) */
152 /* XDS API Commands */
153 #define XDS_CONNECT 0x01 /* Connect JTAG connection */
154 #define XDS_DISCONNECT 0x02 /* Disconnect JTAG connection */
155 #define XDS_VERSION 0x03 /* Get firmware version and hardware ID */
156 #define XDS_SET_TCK 0x04 /* Set TCK delay (to set TCK frequency) */
157 #define XDS_SET_TRST 0x05 /* Assert or deassert nTRST signal */
158 #define XDS_CYCLE_TCK 0x07 /* Toggle TCK for a number of cycles */
159 #define XDS_GOTO_STATE 0x09 /* Go to requested JTAG state */
160 #define XDS_JTAG_SCAN 0x0c /* Send and receive JTAG scan */
161 #define XDS_SET_SRST 0x0e /* Assert or deassert nSRST signal */
162 #define CMAPI_CONNECT 0x0f /* CMAPI connect */
163 #define CMAPI_DISCONNECT 0x10 /* CMAPI disconnect */
164 #define CMAPI_ACQUIRE 0x11 /* CMAPI acquire */
165 #define CMAPI_RELEASE 0x12 /* CMAPI release */
166 #define CMAPI_REG_READ 0x15 /* CMAPI DAP register read */
167 #define CMAPI_REG_WRITE 0x16 /* CMAPI DAP register write */
168 #define SWD_CONNECT 0x17 /* Switch from JTAG to SWD connection */
169 #define SWD_DISCONNECT 0x18 /* Switch from SWD to JTAG connection */
170 #define CJTAG_CONNECT 0x2b /* Switch from JTAG to cJTAG connection */
171 #define CJTAG_DISCONNECT 0x2c /* Switch from cJTAG to JTAG connection */
172 #define XDS_SET_SUPPLY 0x32 /* Set up stand-alone probe upply voltage */
173 #define OCD_DAP_REQUEST 0x3a /* Handle block of DAP requests */
174 #define OCD_SCAN_REQUEST 0x3b /* Handle block of JTAG scan requests */
175 #define OCD_PATHMOVE 0x3c /* Handle PATHMOVE to navigate JTAG states */
177 #define CMD_IR_SCAN 1
178 #define CMD_DR_SCAN 2
179 #define CMD_RUNTEST 3
180 #define CMD_STABLECLOCKS 4
182 /* Array to convert from OpenOCD tap_state_t to XDS JTAG state */
183 const uint32_t xds_jtag_state
[] = {
184 XDS_JTAG_STATE_EXIT2_DR
, /* TAP_DREXIT2 = 0x0 */
185 XDS_JTAG_STATE_EXIT1_DR
, /* TAP_DREXIT1 = 0x1 */
186 XDS_JTAG_STATE_SHIFT_DR
, /* TAP_DRSHIFT = 0x2 */
187 XDS_JTAG_STATE_PAUSE_DR
, /* TAP_DRPAUSE = 0x3 */
188 XDS_JTAG_STATE_SELECT_IR
, /* TAP_IRSELECT = 0x4 */
189 XDS_JTAG_STATE_UPDATE_DR
, /* TAP_DRUPDATE = 0x5 */
190 XDS_JTAG_STATE_CAPTURE_DR
, /* TAP_DRCAPTURE = 0x6 */
191 XDS_JTAG_STATE_SELECT_DR
, /* TAP_DRSELECT = 0x7 */
192 XDS_JTAG_STATE_EXIT2_IR
, /* TAP_IREXIT2 = 0x8 */
193 XDS_JTAG_STATE_EXIT1_IR
, /* TAP_IREXIT1 = 0x9 */
194 XDS_JTAG_STATE_SHIFT_IR
, /* TAP_IRSHIFT = 0xa */
195 XDS_JTAG_STATE_PAUSE_IR
, /* TAP_IRPAUSE = 0xb */
196 XDS_JTAG_STATE_IDLE
, /* TAP_IDLE = 0xc */
197 XDS_JTAG_STATE_UPDATE_IR
, /* TAP_IRUPDATE = 0xd */
198 XDS_JTAG_STATE_CAPTURE_IR
, /* TAP_IRCAPTURE = 0xe */
199 XDS_JTAG_STATE_RESET
, /* TAP_RESET = 0xf */
209 /* USB connection handles and data buffers */
211 libusb_device_handle
*dev
;
212 unsigned char read_payload
[USB_PAYLOAD_SIZE
];
213 unsigned char write_packet
[3];
214 unsigned char write_payload
[USB_PAYLOAD_SIZE
];
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 serial number */
229 char serial
[XDS110_SERIAL_LEN
+ 1];
230 /* XDS110 voltage supply setting */
232 /* XDS110 firmware and hardware version */
235 /* Transaction queues */
236 unsigned char txn_requests
[MAX_DATA_BLOCK
];
237 uint32_t *txn_dap_results
[MAX_DATA_BLOCK
/ 4];
238 struct scan_result txn_scan_results
[MAX_DATA_BLOCK
/ 4];
239 uint32_t txn_request_size
;
240 uint32_t txn_result_size
;
241 uint32_t txn_result_count
;
244 static struct xds110_info xds110
= {
247 .is_connected
= false,
248 .is_cmapi_connected
= false,
249 .is_cmapi_acquired
= false,
250 .is_swd_mode
= false,
251 .is_ap_dirty
= false,
252 .speed
= XDS110_MAX_TCK_SPEED
,
258 .txn_request_size
= 0,
259 .txn_result_size
= 0,
260 .txn_result_count
= 0
263 static inline void xds110_set_u32(uint8_t *buffer
, uint32_t value
)
265 buffer
[3] = (value
>> 24) & 0xff;
266 buffer
[2] = (value
>> 16) & 0xff;
267 buffer
[1] = (value
>> 8) & 0xff;
268 buffer
[0] = (value
>> 0) & 0xff;
271 static inline void xds110_set_u16(uint8_t *buffer
, uint16_t value
)
273 buffer
[1] = (value
>> 8) & 0xff;
274 buffer
[0] = (value
>> 0) & 0xff;
277 static inline uint32_t xds110_get_u32(uint8_t *buffer
)
279 uint32_t value
= (((uint32_t)buffer
[3]) << 24) |
280 (((uint32_t)buffer
[2]) << 16) |
281 (((uint32_t)buffer
[1]) << 8) |
282 (((uint32_t)buffer
[0]) << 0);
286 static inline uint16_t xds110_get_u16(uint8_t *buffer
)
288 uint16_t value
= (((uint32_t)buffer
[1]) << 8) |
289 (((uint32_t)buffer
[0]) << 0);
293 /***************************************************************************
294 * usb connection routines *
296 * The following functions handle connecting, reading, and writing to *
297 * the XDS110 over USB using the libusb library. *
298 ***************************************************************************/
300 static bool usb_connect(void)
302 libusb_context
*ctx
= NULL
;
303 libusb_device
**list
= NULL
;
304 libusb_device_handle
*dev
= NULL
;
306 struct libusb_device_descriptor desc
;
308 uint16_t vid
= 0x0451;
309 uint16_t pid
= 0xbef3;
315 /* Initialize libusb context */
316 result
= libusb_init(&ctx
);
319 /* Get list of USB devices attached to system */
320 count
= libusb_get_device_list(ctx
, &list
);
328 /* Scan through list of devices for any XDS110s */
329 for (i
= 0; i
< count
; i
++) {
330 /* Check for device VID/PID match */
331 libusb_get_device_descriptor(list
[i
], &desc
);
332 if (desc
.idVendor
== vid
&& desc
.idProduct
== pid
) {
333 result
= libusb_open(list
[i
], &dev
);
335 const int MAX_DATA
= 256;
336 unsigned char data
[MAX_DATA
+ 1];
339 /* May be the requested device if serial number matches */
340 if (0 == xds110
.serial
[0]) {
341 /* No serial number given; match first XDS110 found */
345 /* Get the device's serial number string */
346 result
= libusb_get_string_descriptor_ascii(dev
,
347 desc
.iSerialNumber
, data
, MAX_DATA
);
349 0 == strcmp((char *)data
, (char *)xds110
.serial
)) {
355 /* If we fall though to here, we don't want this device */
364 * We can fall through the for() loop with two possible exit conditions:
365 * 1) found the right XDS110, and that device is open
366 * 2) didn't find the XDS110, and no devices are currently open
370 /* Free the device list, we're done with it */
371 libusb_free_device_list(list
, 1);
375 /* Save the context and device handles */
379 /* Set libusb to auto detach kernel */
380 (void)libusb_set_auto_detach_kernel_driver(dev
, 1);
382 /* Claim the debug interface on the XDS110 */
383 result
= libusb_claim_interface(dev
, INTERFACE_DEBUG
);
385 /* Couldn't find an XDS110, flag the error */
389 /* On an error, clean up what we can */
392 /* Release the debug and data interface on the XDS110 */
393 (void)libusb_release_interface(dev
, INTERFACE_DEBUG
);
402 /* Log the results */
404 LOG_INFO("XDS110: connected");
406 LOG_ERROR("XDS110: failed to connect");
408 return (0 == result
) ? true : false;
411 static void usb_disconnect(void)
413 if (NULL
!= xds110
.dev
) {
414 /* Release the debug and data interface on the XDS110 */
415 (void)libusb_release_interface(xds110
.dev
, INTERFACE_DEBUG
);
416 libusb_close(xds110
.dev
);
419 if (NULL
!= xds110
.ctx
) {
420 libusb_exit(xds110
.ctx
);
424 LOG_INFO("XDS110: disconnected");
427 static bool usb_read(unsigned char *buffer
, int size
, int *bytes_read
,
432 if (NULL
== xds110
.dev
|| NULL
== buffer
|| NULL
== bytes_read
)
435 /* Force a non-zero timeout to prevent blocking */
437 timeout
= DEFAULT_TIMEOUT
;
439 result
= libusb_bulk_transfer(xds110
.dev
, ENDPOINT_DEBUG_IN
, buffer
, size
,
440 bytes_read
, timeout
);
442 return (0 == result
) ? true : false;
445 static bool usb_write(unsigned char *buffer
, int size
, int *written
)
447 int bytes_written
= 0;
448 int result
= LIBUSB_SUCCESS
;
451 if (NULL
== xds110
.dev
|| NULL
== buffer
)
454 result
= libusb_bulk_transfer(xds110
.dev
, ENDPOINT_DEBUG_OUT
, buffer
,
455 size
, &bytes_written
, 0);
457 while (LIBUSB_ERROR_PIPE
== result
&& retries
< 3) {
458 /* Try clearing the pipe stall and retry transfer */
459 libusb_clear_halt(xds110
.dev
, ENDPOINT_DEBUG_OUT
);
460 result
= libusb_bulk_transfer(xds110
.dev
, ENDPOINT_DEBUG_OUT
, buffer
,
461 size
, &bytes_written
, 0);
466 *written
= bytes_written
;
468 return (0 == result
&& size
== bytes_written
) ? true : false;
471 static bool usb_get_response(uint32_t *total_bytes_read
, uint32_t timeout
)
473 static unsigned char buffer
[MAX_PACKET
];
482 success
= usb_read(buffer
, sizeof(buffer
), &bytes_read
, timeout
);
485 * Validate that this appears to be a good response packet
486 * First check it contains enough data for header and error
487 * code, plus the first character is the start character
489 if (bytes_read
>= 7 && '*' == buffer
[0]) {
490 /* Extract the payload size */
491 size
= xds110_get_u16(&buffer
[1]);
492 /* Sanity test on payload size */
493 if (USB_PAYLOAD_SIZE
>= size
&& 4 <= size
) {
494 /* Check we didn't get more data than expected */
495 if ((bytes_read
- 3) <= size
) {
496 /* Packet appears to be valid, move on */
503 * Somehow received an invalid packet, retry till we
504 * time out or a valid response packet is received
508 /* Abort now if we didn't receive a valid response */
510 if (NULL
!= total_bytes_read
)
511 *total_bytes_read
= 0;
515 /* Build the return payload into xds110.read_payload */
517 /* Copy over payload data from received buffer (skipping header) */
520 memcpy((void *)&xds110
.read_payload
[count
], (void *)&buffer
[3], bytes_read
);
523 * Drop timeout to just 1/2 second. Once the XDS110 starts sending
524 * a response, the remaining packets should arrive in short order
527 timeout
= 500; /* ms */
529 /* If there's more data to retrieve, get it now */
530 while ((count
< size
) && success
) {
531 success
= usb_read(buffer
, sizeof(buffer
), &bytes_read
, timeout
);
533 if ((count
+ bytes_read
) > size
) {
534 /* Read too much data, not a valid packet, abort */
537 /* Copy this data over to xds110.read_payload */
538 memcpy((void *)&xds110
.read_payload
[count
], (void *)buffer
,
547 if (NULL
!= total_bytes_read
)
548 *total_bytes_read
= count
;
553 static bool usb_send_command(uint16_t size
)
558 /* Check the packet length */
559 if (size
> USB_PAYLOAD_SIZE
)
562 /* Place the start character into the packet buffer */
563 xds110
.write_packet
[0] = '*';
565 /* Place the payload size into the packet buffer */
566 xds110_set_u16(&xds110
.write_packet
[1], size
);
568 /* Adjust size to include header */
571 /* Send the data via the USB connection */
572 success
= usb_write(xds110
.write_packet
, (int)size
, &written
);
574 /* Check if the correct number of bytes was written */
575 if (written
!= (int)size
)
581 /***************************************************************************
582 * XDS110 firmware API routines *
584 * The following functions handle calling into the XDS110 firmware to *
585 * perform requested debug actions. *
586 ***************************************************************************/
588 static bool xds_execute(uint32_t out_length
, uint32_t in_length
,
589 uint32_t attempts
, uint32_t timeout
)
594 uint32_t bytes_read
= 0;
596 if (NULL
== xds110
.dev
)
599 while (!done
&& attempts
> 0) {
602 /* Send command to XDS110 */
603 success
= usb_send_command(out_length
);
606 /* Get response from XDS110 */
607 success
= usb_get_response(&bytes_read
, timeout
);
611 /* Check for valid response from XDS code handling */
612 if (bytes_read
!= in_length
) {
613 /* Unexpected amount of data returned */
615 LOG_DEBUG("XDS110: command 0x%02x return %d bytes, expected %d",
616 xds110
.write_payload
[0], bytes_read
, in_length
);
618 /* Extract error code from return packet */
619 error
= (int)xds110_get_u32(&xds110
.read_payload
[0]);
621 if (SC_ERR_NONE
!= error
)
622 LOG_DEBUG("XDS110: command 0x%02x returned error %d",
623 xds110
.write_payload
[0], error
);
629 error
= SC_ERR_XDS110_FAIL
;
637 static bool xds_connect(void)
641 xds110
.write_payload
[0] = XDS_CONNECT
;
643 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
649 static bool xds_disconnect(void)
653 xds110
.write_payload
[0] = XDS_DISCONNECT
;
655 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
661 static bool xds_version(uint32_t *firmware_id
, uint16_t *hardware_id
)
663 uint8_t *fw_id_pntr
= &xds110
.read_payload
[XDS_IN_LEN
+ 0]; /* 32-bits */
664 uint8_t *hw_id_pntr
= &xds110
.read_payload
[XDS_IN_LEN
+ 4]; /* 16-bits */
668 xds110
.write_payload
[0] = XDS_VERSION
;
670 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
+ 6, DEFAULT_ATTEMPTS
,
674 if (NULL
!= firmware_id
)
675 *firmware_id
= xds110_get_u32(fw_id_pntr
);
676 if (NULL
!= hardware_id
)
677 *hardware_id
= xds110_get_u16(hw_id_pntr
);
683 static bool xds_set_tck_delay(uint32_t delay
)
685 uint8_t *delay_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 32-bits */
689 xds110
.write_payload
[0] = XDS_SET_TCK
;
691 xds110_set_u32(delay_pntr
, delay
);
693 success
= xds_execute(XDS_OUT_LEN
+ 4, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
699 static bool xds_set_trst(uint8_t trst
)
701 uint8_t *trst_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 8-bits */
705 xds110
.write_payload
[0] = XDS_SET_TRST
;
709 success
= xds_execute(XDS_OUT_LEN
+ 1, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
715 static bool xds_cycle_tck(uint32_t count
)
717 uint8_t *count_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 32-bits */
721 xds110
.write_payload
[0] = XDS_CYCLE_TCK
;
723 xds110_set_u32(count_pntr
, count
);
725 success
= xds_execute(XDS_OUT_LEN
+ 4, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
731 static bool xds_goto_state(uint32_t state
)
733 uint8_t *state_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 32-bits */
734 uint8_t *transit_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+4]; /* 32-bits */
738 xds110
.write_payload
[0] = XDS_GOTO_STATE
;
740 xds110_set_u32(state_pntr
, state
);
741 xds110_set_u32(transit_pntr
, XDS_JTAG_TRANSIT_QUICKEST
);
743 success
= xds_execute(XDS_OUT_LEN
+8, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
749 static bool xds_jtag_scan(uint32_t shift_state
, uint16_t shift_bits
,
750 uint32_t end_state
, uint8_t *data_out
, uint8_t *data_in
)
752 uint8_t *bits_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 16-bits */
753 uint8_t *path_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 2]; /* 8-bits */
754 uint8_t *trans1_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 3]; /* 8-bits */
755 uint8_t *end_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 4]; /* 8-bits */
756 uint8_t *trans2_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 5]; /* 8-bits */
757 uint8_t *pre_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 6]; /* 16-bits */
758 uint8_t *pos_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 8]; /* 16-bits */
759 uint8_t *delay_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 10]; /* 16-bits */
760 uint8_t *rep_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 12]; /* 16-bits */
761 uint8_t *out_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 14]; /* 16-bits */
762 uint8_t *in_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 16]; /* 16-bits */
763 uint8_t *data_out_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 18];
764 uint8_t *data_in_pntr
= &xds110
.read_payload
[XDS_IN_LEN
+0];
766 uint16_t total_bytes
= DIV_ROUND_UP(shift_bits
, 8);
770 xds110
.write_payload
[0] = XDS_JTAG_SCAN
;
772 xds110_set_u16(bits_pntr
, shift_bits
); /* bits to scan */
773 *path_pntr
= (uint8_t)(shift_state
& 0xff); /* IR vs DR path */
774 *trans1_pntr
= (uint8_t)XDS_JTAG_TRANSIT_QUICKEST
; /* start state route */
775 *end_pntr
= (uint8_t)(end_state
& 0xff); /* JTAG state after scan */
776 *trans2_pntr
= (uint8_t)XDS_JTAG_TRANSIT_QUICKEST
; /* end state route */
777 xds110_set_u16(pre_pntr
, 0); /* number of preamble bits */
778 xds110_set_u16(pos_pntr
, 0); /* number of postamble bits */
779 xds110_set_u16(delay_pntr
, 0); /* number of extra TCKs after scan */
780 xds110_set_u16(rep_pntr
, 1); /* number of repetitions */
781 xds110_set_u16(out_pntr
, total_bytes
); /* out buffer offset (if repeats) */
782 xds110_set_u16(in_pntr
, total_bytes
); /* in buffer offset (if repeats) */
784 memcpy((void *)data_out_pntr
, (void *)data_out
, total_bytes
);
786 success
= xds_execute(XDS_OUT_LEN
+ 18 + total_bytes
,
787 XDS_IN_LEN
+ total_bytes
, DEFAULT_ATTEMPTS
, DEFAULT_TIMEOUT
);
790 memcpy((void *)data_in
, (void *)data_in_pntr
, total_bytes
);
795 static bool xds_set_srst(uint8_t srst
)
797 uint8_t *srst_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 8-bits */
801 xds110
.write_payload
[0] = XDS_SET_SRST
;
805 success
= xds_execute(XDS_OUT_LEN
+ 1, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
811 static bool cmapi_connect(uint32_t *idcode
)
813 uint8_t *idcode_pntr
= &xds110
.read_payload
[XDS_IN_LEN
+ 0]; /* 32-bits */
817 xds110
.write_payload
[0] = CMAPI_CONNECT
;
819 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
+4, DEFAULT_ATTEMPTS
,
824 *idcode
= xds110_get_u32(idcode_pntr
);
830 static bool cmapi_disconnect(void)
834 xds110
.write_payload
[0] = CMAPI_DISCONNECT
;
836 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
842 static bool cmapi_acquire(void)
846 xds110
.write_payload
[0] = CMAPI_ACQUIRE
;
848 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
854 static bool cmapi_release(void)
858 xds110
.write_payload
[0] = CMAPI_RELEASE
;
860 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
866 static bool cmapi_read_dap_reg(uint32_t type
, uint32_t ap_num
,
867 uint32_t address
, uint32_t *value
)
869 uint8_t *type_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 8-bits */
870 uint8_t *ap_num_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 1]; /* 8-bits */
871 uint8_t *address_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 2]; /* 8-bits */
872 uint8_t *value_pntr
= &xds110
.read_payload
[XDS_IN_LEN
+ 0]; /* 32-bits */
876 xds110
.write_payload
[0] = CMAPI_REG_READ
;
878 *type_pntr
= (uint8_t)(type
& 0xff);
879 *ap_num_pntr
= (uint8_t)(ap_num
& 0xff);
880 *address_pntr
= (uint8_t)(address
& 0xff);
882 success
= xds_execute(XDS_OUT_LEN
+ 3, XDS_IN_LEN
+ 4, DEFAULT_ATTEMPTS
,
887 *value
= xds110_get_u32(value_pntr
);
893 static bool cmapi_write_dap_reg(uint32_t type
, uint32_t ap_num
,
894 uint32_t address
, uint32_t *value
)
896 uint8_t *type_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 8-bits */
897 uint8_t *ap_num_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 1]; /* 8-bits */
898 uint8_t *address_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 2]; /* 8-bits */
899 uint8_t *value_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 3]; /* 32-bits */
906 xds110
.write_payload
[0] = CMAPI_REG_WRITE
;
908 *type_pntr
= (uint8_t)(type
& 0xff);
909 *ap_num_pntr
= (uint8_t)(ap_num
& 0xff);
910 *address_pntr
= (uint8_t)(address
& 0xff);
911 xds110_set_u32(value_pntr
, *value
);
913 success
= xds_execute(XDS_OUT_LEN
+ 7, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
919 static bool swd_connect(void)
923 xds110
.write_payload
[0] = SWD_CONNECT
;
925 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
931 static bool swd_disconnect(void)
935 xds110
.write_payload
[0] = SWD_DISCONNECT
;
937 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
943 static bool cjtag_connect(uint32_t format
)
945 uint8_t *format_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 32-bits */
949 xds110
.write_payload
[0] = CJTAG_CONNECT
;
951 xds110_set_u32(format_pntr
, format
);
953 success
= xds_execute(XDS_OUT_LEN
+ 4, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
959 static bool cjtag_disconnect(void)
963 xds110
.write_payload
[0] = CJTAG_DISCONNECT
;
965 success
= xds_execute(XDS_OUT_LEN
, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
971 static bool xds_set_supply(uint32_t voltage
)
973 uint8_t *volts_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 32-bits */
974 uint8_t *source_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 4]; /* 8-bits */
978 xds110
.write_payload
[0] = XDS_SET_SUPPLY
;
980 xds110_set_u32(volts_pntr
, voltage
);
981 *source_pntr
= (uint8_t)(0 != voltage
? 1 : 0);
983 success
= xds_execute(XDS_OUT_LEN
+ 5, XDS_IN_LEN
, DEFAULT_ATTEMPTS
,
989 static bool ocd_dap_request(uint8_t *dap_requests
, uint32_t request_size
,
990 uint32_t *dap_results
, uint32_t result_count
)
992 uint8_t *request_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0];
993 uint8_t *result_pntr
= &xds110
.read_payload
[XDS_IN_LEN
+ 0];
997 if (NULL
== dap_requests
|| NULL
== dap_results
)
1000 xds110
.write_payload
[0] = OCD_DAP_REQUEST
;
1002 memcpy((void *)request_pntr
, (void *)dap_requests
, request_size
);
1004 success
= xds_execute(XDS_OUT_LEN
+ request_size
,
1005 XDS_IN_LEN
+ (result_count
* 4), DEFAULT_ATTEMPTS
,
1008 if (success
&& (result_count
> 0))
1009 memcpy((void *)dap_results
, (void *)result_pntr
, result_count
* 4);
1014 static bool ocd_scan_request(uint8_t *scan_requests
, uint32_t request_size
,
1015 uint8_t *scan_results
, uint32_t result_size
)
1017 uint8_t *request_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0];
1018 uint8_t *result_pntr
= &xds110
.read_payload
[XDS_IN_LEN
+ 0];
1022 if (NULL
== scan_requests
|| NULL
== scan_results
)
1025 xds110
.write_payload
[0] = OCD_SCAN_REQUEST
;
1027 memcpy((void *)request_pntr
, (void *)scan_requests
, request_size
);
1029 success
= xds_execute(XDS_OUT_LEN
+ request_size
,
1030 XDS_IN_LEN
+ result_size
, DEFAULT_ATTEMPTS
,
1033 if (success
&& (result_size
> 0))
1034 memcpy((void *)scan_results
, (void *)result_pntr
, result_size
);
1039 static bool ocd_pathmove(uint32_t num_states
, uint8_t *path
)
1041 uint8_t *num_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 0]; /* 32-bits */
1042 uint8_t *path_pntr
= &xds110
.write_payload
[XDS_OUT_LEN
+ 4];
1049 xds110
.write_payload
[0] = OCD_PATHMOVE
;
1051 xds110_set_u32(num_pntr
, num_states
);
1053 memcpy((void *)path_pntr
, (void *)path
, num_states
);
1055 success
= xds_execute(XDS_OUT_LEN
+ 4 + num_states
, XDS_IN_LEN
,
1056 DEFAULT_ATTEMPTS
, DEFAULT_TIMEOUT
);
1061 /***************************************************************************
1062 * swd driver interface *
1064 * The following functions provide SWD support to OpenOCD. *
1065 ***************************************************************************/
1067 static int xds110_swd_init(void)
1069 xds110
.is_swd_mode
= true;
1073 static int xds110_swd_switch_seq(enum swd_special_seq seq
)
1080 LOG_ERROR("Sequence SWD line reset (%d) not supported", seq
);
1083 LOG_DEBUG("JTAG-to-SWD");
1084 xds110
.is_swd_mode
= false;
1085 xds110
.is_cmapi_connected
= false;
1086 xds110
.is_cmapi_acquired
= false;
1087 /* Run sequence to put target in SWD mode */
1088 success
= swd_connect();
1089 /* Re-iniitialize CMAPI API for DAP access */
1091 xds110
.is_swd_mode
= true;
1092 success
= cmapi_connect(&idcode
);
1094 xds110
.is_cmapi_connected
= true;
1095 success
= cmapi_acquire();
1100 LOG_DEBUG("SWD-to-JTAG");
1101 xds110
.is_swd_mode
= false;
1102 xds110
.is_cmapi_connected
= false;
1103 xds110
.is_cmapi_acquired
= false;
1104 /* Run sequence to put target in JTAG mode */
1105 success
= swd_disconnect();
1107 /* Re-initialize JTAG interface */
1108 success
= cjtag_connect(MODE_JTAG
);
1112 LOG_ERROR("Sequence %d not supported", seq
);
1122 static bool xds110_legacy_read_reg(uint8_t cmd
, uint32_t *value
)
1124 /* Make sure this is a read request */
1125 bool is_read_request
= (0 != (SWD_CMD_RnW
& cmd
));
1126 /* Determine whether this is a DP or AP register access */
1127 uint32_t type
= (0 != (SWD_CMD_APnDP
& cmd
)) ? DAP_AP
: DAP_DP
;
1128 /* Determine the AP number from cached SELECT value */
1129 uint32_t ap_num
= (xds110
.select
& 0xff000000) >> 24;
1130 /* Extract register address from command */
1131 uint32_t address
= ((cmd
& SWD_CMD_A32
) >> 1);
1132 /* Extract bank address from cached SELECT value */
1133 uint32_t bank
= (xds110
.select
& 0x000000f0);
1135 uint32_t reg_value
= 0;
1136 uint32_t temp_value
= 0;
1140 if (!is_read_request
)
1143 if (DAP_AP
== type
) {
1144 /* Add bank address to register address for CMAPI call */
1148 if (DAP_DP
== type
&& DAP_DP_RDBUFF
== address
&& xds110
.use_rdbuff
) {
1149 /* If RDBUFF is cached and this is a DP RDBUFF read, use the cache */
1150 reg_value
= xds110
.rdbuff
;
1152 } else if (DAP_AP
== type
&& DAP_AP_DRW
== address
&& xds110
.use_rdbuff
) {
1153 /* If RDBUFF is cached and this is an AP DRW read, use the cache, */
1154 /* but still call into the firmware to get the next read. */
1155 reg_value
= xds110
.rdbuff
;
1156 success
= cmapi_read_dap_reg(type
, ap_num
, address
, &temp_value
);
1158 success
= cmapi_read_dap_reg(type
, ap_num
, address
, &temp_value
);
1160 reg_value
= temp_value
;
1163 /* Mark that we have consumed or invalidated the RDBUFF cache */
1164 xds110
.use_rdbuff
= false;
1166 /* Handle result of read attempt */
1168 LOG_ERROR("XDS110: failed to read DAP register");
1169 else if (NULL
!= value
)
1172 if (success
&& DAP_AP
== type
) {
1174 * On a successful DAP AP read, we actually have the value from RDBUFF,
1175 * the firmware will have run the AP request and made the RDBUFF read
1177 xds110
.use_rdbuff
= true;
1178 xds110
.rdbuff
= temp_value
;
1184 static bool xds110_legacy_write_reg(uint8_t cmd
, uint32_t value
)
1186 /* Make sure this isn't a read request */
1187 bool is_read_request
= (0 != (SWD_CMD_RnW
& cmd
));
1188 /* Determine whether this is a DP or AP register access */
1189 uint32_t type
= (0 != (SWD_CMD_APnDP
& cmd
)) ? DAP_AP
: DAP_DP
;
1190 /* Determine the AP number from cached SELECT value */
1191 uint32_t ap_num
= (xds110
.select
& 0xff000000) >> 24;
1192 /* Extract register address from command */
1193 uint32_t address
= ((cmd
& SWD_CMD_A32
) >> 1);
1194 /* Extract bank address from cached SELECT value */
1195 uint32_t bank
= (xds110
.select
& 0x000000f0);
1199 if (is_read_request
)
1202 /* Invalidate the RDBUFF cache */
1203 xds110
.use_rdbuff
= false;
1205 if (DAP_AP
== type
) {
1206 /* Add bank address to register address for CMAPI call */
1208 /* Any write to an AP register invalidates the firmware's cache */
1209 xds110
.is_ap_dirty
= true;
1210 } else if (DAP_DP_SELECT
== address
) {
1211 /* Any write to the SELECT register invalidates the firmware's cache */
1212 xds110
.is_ap_dirty
= true;
1215 success
= cmapi_write_dap_reg(type
, ap_num
, address
, &value
);
1218 LOG_ERROR("XDS110: failed to write DAP register");
1221 * If the debugger wrote to SELECT, cache the value
1222 * to use to build the apNum and address values above
1224 if ((DAP_DP
== type
) && (DAP_DP_SELECT
== address
))
1225 xds110
.select
= value
;
1231 static int xds110_swd_run_queue(void)
1233 static uint32_t dap_results
[MAX_RESULT_QUEUE
];
1238 bool success
= true;
1240 if (0 == xds110
.txn_request_size
)
1243 /* Terminate request queue */
1244 xds110
.txn_requests
[xds110
.txn_request_size
++] = 0;
1246 if (xds110
.firmware
>= OCD_FIRMWARE_VERSION
) {
1247 /* XDS110 firmware has the API to directly handle the queue */
1248 success
= ocd_dap_request(xds110
.txn_requests
,
1249 xds110
.txn_request_size
, dap_results
, xds110
.txn_result_count
);
1251 /* Legacy firmware needs to handle queue via discrete DAP calls */
1254 while (xds110
.txn_requests
[request
] != 0) {
1255 cmd
= xds110
.txn_requests
[request
++];
1256 if (0 == (SWD_CMD_RnW
& cmd
)) {
1257 /* DAP register write command */
1258 value
= (uint32_t)(xds110
.txn_requests
[request
++]) << 0;
1259 value
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 8;
1260 value
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 16;
1261 value
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 24;
1263 success
= xds110_legacy_write_reg(cmd
, value
);
1265 /* DAP register read command */
1268 success
= xds110_legacy_read_reg(cmd
, &value
);
1269 dap_results
[result
++] = value
;
1274 /* Transfer results into caller's buffers */
1275 for (result
= 0; result
< xds110
.txn_result_count
; result
++)
1276 if (0 != xds110
.txn_dap_results
[result
])
1277 *xds110
.txn_dap_results
[result
] = dap_results
[result
];
1279 xds110
.txn_request_size
= 0;
1280 xds110
.txn_result_size
= 0;
1281 xds110
.txn_result_count
= 0;
1283 return (success
) ? ERROR_OK
: ERROR_FAIL
;
1286 static void xds110_swd_queue_cmd(uint8_t cmd
, uint32_t *value
)
1288 /* Check if this is a read or write request */
1289 bool is_read_request
= (0 != (SWD_CMD_RnW
& cmd
));
1290 /* Determine whether this is a DP or AP register access */
1291 uint32_t type
= (0 != (SWD_CMD_APnDP
& cmd
)) ? DAP_AP
: DAP_DP
;
1292 /* Extract register address from command */
1293 uint32_t address
= ((cmd
& SWD_CMD_A32
) >> 1);
1294 uint32_t request_size
= (is_read_request
) ? 1 : 5;
1296 /* Check if new request would be too large to fit */
1297 if (((xds110
.txn_request_size
+ request_size
+ 1) > MAX_DATA_BLOCK
) ||
1298 ((xds110
.txn_result_count
+ 1) > MAX_RESULT_QUEUE
))
1299 xds110_swd_run_queue();
1301 /* Set the START bit in cmd to ensure cmd is not zero */
1302 /* (a value of zero is used to terminate the buffer) */
1303 cmd
|= SWD_CMD_START
;
1305 /* Add request to queue; queue is built marshalled for XDS110 call */
1306 if (is_read_request
) {
1307 /* Queue read request, save pointer to pass back result */
1308 xds110
.txn_requests
[xds110
.txn_request_size
++] = cmd
;
1309 xds110
.txn_dap_results
[xds110
.txn_result_count
++] = value
;
1310 xds110
.txn_result_size
+= 4;
1312 /* Check for and prevent sticky overrun detection */
1313 if (DAP_DP
== type
&& DAP_DP_CTRL
== address
&&
1314 (*value
& CORUNDETECT
)) {
1315 LOG_DEBUG("XDS110: refusing to enable sticky overrun detection");
1316 *value
&= ~CORUNDETECT
;
1318 /* Queue write request, add value directly to queue buffer */
1319 xds110
.txn_requests
[xds110
.txn_request_size
++] = cmd
;
1320 xds110
.txn_requests
[xds110
.txn_request_size
++] = (*value
>> 0) & 0xff;
1321 xds110
.txn_requests
[xds110
.txn_request_size
++] = (*value
>> 8) & 0xff;
1322 xds110
.txn_requests
[xds110
.txn_request_size
++] = (*value
>> 16) & 0xff;
1323 xds110
.txn_requests
[xds110
.txn_request_size
++] = (*value
>> 24) & 0xff;
1327 static void xds110_swd_read_reg(uint8_t cmd
, uint32_t *value
,
1328 uint32_t ap_delay_clk
)
1330 xds110_swd_queue_cmd(cmd
, value
);
1332 static void xds110_swd_write_reg(uint8_t cmd
, uint32_t value
,
1333 uint32_t ap_delay_clk
)
1335 xds110_swd_queue_cmd(cmd
, &value
);
1338 /***************************************************************************
1341 * The following functions provide XDS110 interface to OpenOCD. *
1342 ***************************************************************************/
1344 static void xds110_show_info(void)
1346 uint32_t firmware
= xds110
.firmware
;
1348 LOG_INFO("XDS110: firmware version = %d.%d.%d.%d",
1349 (((firmware
>> 28) & 0xf) * 10) + ((firmware
>> 24) & 0xf),
1350 (((firmware
>> 20) & 0xf) * 10) + ((firmware
>> 16) & 0xf),
1351 (((firmware
>> 12) & 0xf) * 10) + ((firmware
>> 8) & 0xf),
1352 (((firmware
>> 4) & 0xf) * 10) + ((firmware
>> 0) & 0xf));
1353 LOG_INFO("XDS110: hardware version = 0x%04x", xds110
.hardware
);
1354 if (0 != xds110
.serial
[0])
1355 LOG_INFO("XDS110: serial number = %s", xds110
.serial
);
1356 if (xds110
.is_swd_mode
) {
1357 LOG_INFO("XDS110: connected to target via SWD");
1358 LOG_INFO("XDS110: SWCLK set to %d kHz", xds110
.speed
);
1360 LOG_INFO("XDS110: connected to target via JTAG");
1361 LOG_INFO("XDS110: TCK set to %d kHz", xds110
.speed
);
1364 /* Alert user that there's a better firmware to use */
1365 if (firmware
< OCD_FIRMWARE_VERSION
) {
1366 LOG_WARNING("XDS110: the firmware is not optimized for OpenOCD");
1367 LOG_WARNING(OCD_FIRMWARE_UPGRADE
);
1371 static int xds110_quit(void)
1373 if (xds110
.is_cmapi_acquired
) {
1374 (void)cmapi_release();
1375 xds110
.is_cmapi_acquired
= false;
1377 if (xds110
.is_cmapi_connected
) {
1378 (void)cmapi_disconnect();
1379 xds110
.is_cmapi_connected
= false;
1381 if (xds110
.is_connected
) {
1382 if (xds110
.is_swd_mode
) {
1383 /* Switch out of SWD mode */
1384 (void)swd_disconnect();
1386 /* Switch out of cJTAG mode */
1387 (void)cjtag_disconnect();
1389 /* Tell firmware we're disconnecting */
1390 (void)xds_disconnect();
1391 xds110
.is_connected
= false;
1393 /* Close down the USB connection to the XDS110 debug probe */
1399 static int xds110_init(void)
1403 /* Establish USB connection to the XDS110 debug probe */
1404 success
= usb_connect();
1407 /* Send connect message to XDS110 firmware */
1408 success
= xds_connect();
1410 xds110
.is_connected
= true;
1417 /* Retrieve version IDs from firmware */
1418 /* Version numbers are stored in BCD format */
1419 success
= xds_version(&firmware
, &hardware
);
1421 /* Save the firmware and hardware version */
1422 xds110
.firmware
= firmware
;
1423 xds110
.hardware
= hardware
;
1428 /* Set supply voltage for stand-alone probes */
1429 if (XDS110_STAND_ALONE_ID
== xds110
.hardware
) {
1430 success
= xds_set_supply(xds110
.voltage
);
1431 /* Allow time for target device to power up */
1432 /* (CC32xx takes up to 1300 ms before debug is enabled) */
1434 } else if (0 != xds110
.voltage
) {
1435 /* Voltage supply not a feature of embedded probes */
1437 "XDS110: ignoring supply voltage, not supported on this probe");
1442 success
= xds_set_trst(0);
1444 success
= xds_cycle_tck(50);
1446 success
= xds_set_trst(1);
1448 success
= xds_cycle_tck(50);
1452 if (xds110
.is_swd_mode
) {
1453 /* Switch to SWD if needed */
1454 success
= swd_connect();
1456 success
= cjtag_connect(MODE_JTAG
);
1460 if (success
&& xds110
.is_swd_mode
) {
1463 /* Connect to CMAPI interface in XDS110 */
1464 success
= cmapi_connect(&idcode
);
1466 /* Acquire exclusive access to CMAPI interface */
1468 xds110
.is_cmapi_connected
= true;
1469 success
= cmapi_acquire();
1471 xds110
.is_cmapi_acquired
= true;
1481 return (success
) ? ERROR_OK
: ERROR_FAIL
;
1484 static void xds110_legacy_scan(uint32_t shift_state
, uint32_t total_bits
,
1485 uint32_t end_state
, uint8_t *data_out
, uint8_t *data_in
)
1487 (void)xds_jtag_scan(shift_state
, total_bits
, end_state
, data_out
, data_in
);
1490 static void xds110_legacy_runtest(uint32_t clocks
, uint32_t end_state
)
1492 xds_goto_state(XDS_JTAG_STATE_IDLE
);
1493 xds_cycle_tck(clocks
);
1494 xds_goto_state(end_state
);
1497 static void xds110_legacy_stableclocks(uint32_t clocks
)
1499 xds_cycle_tck(clocks
);
1502 static void xds110_flush(void)
1506 uint32_t shift_state
;
1513 uint8_t data_in
[MAX_DATA_BLOCK
];
1516 if (0 == xds110
.txn_request_size
)
1519 /* Terminate request queue */
1520 xds110
.txn_requests
[xds110
.txn_request_size
++] = 0;
1522 if (xds110
.firmware
>= OCD_FIRMWARE_VERSION
) {
1523 /* Updated firmware has the API to directly handle the queue */
1524 (void)ocd_scan_request(xds110
.txn_requests
, xds110
.txn_request_size
,
1525 data_in
, xds110
.txn_result_size
);
1527 /* Legacy firmware needs to handle queue via discrete JTAG calls */
1530 while (xds110
.txn_requests
[request
] != 0) {
1531 command
= xds110
.txn_requests
[request
++];
1535 if (command
== CMD_IR_SCAN
)
1536 shift_state
= XDS_JTAG_STATE_SHIFT_IR
;
1538 shift_state
= XDS_JTAG_STATE_SHIFT_DR
;
1539 end_state
= (uint32_t)(xds110
.txn_requests
[request
++]);
1540 bits
= (uint32_t)(xds110
.txn_requests
[request
++]) << 0;
1541 bits
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 8;
1542 data_out
= &xds110
.txn_requests
[request
];
1543 bytes
= DIV_ROUND_UP(bits
, 8);
1544 xds110_legacy_scan(shift_state
, bits
, end_state
, data_out
,
1550 clocks
= (uint32_t)(xds110
.txn_requests
[request
++]) << 0;
1551 clocks
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 8;
1552 clocks
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 16;
1553 clocks
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 24;
1554 end_state
= (uint32_t)xds110
.txn_requests
[request
++];
1555 xds110_legacy_runtest(clocks
, end_state
);
1557 case CMD_STABLECLOCKS
:
1558 clocks
= (uint32_t)(xds110
.txn_requests
[request
++]) << 0;
1559 clocks
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 8;
1560 clocks
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 16;
1561 clocks
|= (uint32_t)(xds110
.txn_requests
[request
++]) << 24;
1562 xds110_legacy_stableclocks(clocks
);
1565 LOG_ERROR("BUG: unknown JTAG command type 0x%x encountered",
1573 /* Transfer results into caller's buffers from data_in buffer */
1574 bits
= 0; /* Bit offset into current scan result */
1575 data_pntr
= data_in
;
1576 for (result
= 0; result
< xds110
.txn_result_count
; result
++) {
1577 if (xds110
.txn_scan_results
[result
].first
) {
1579 bytes
= DIV_ROUND_UP(bits
, 8);
1584 if (xds110
.txn_scan_results
[result
].buffer
!= 0)
1585 bit_copy(xds110
.txn_scan_results
[result
].buffer
, 0, data_pntr
,
1586 bits
, xds110
.txn_scan_results
[result
].num_bits
);
1587 bits
+= xds110
.txn_scan_results
[result
].num_bits
;
1590 xds110
.txn_request_size
= 0;
1591 xds110
.txn_result_size
= 0;
1592 xds110
.txn_result_count
= 0;
1595 static int xds110_reset(int trst
, int srst
)
1599 int retval
= ERROR_OK
;
1603 /* Deassert nTRST (active low) */
1606 /* Assert nTRST (active low) */
1609 success
= xds_set_trst(value
);
1611 retval
= ERROR_FAIL
;
1616 /* Deassert nSRST (active low) */
1619 /* Assert nSRST (active low) */
1622 success
= xds_set_srst(value
);
1624 retval
= ERROR_FAIL
;
1626 /* Toggle TCK to trigger HIB on CC13x/CC26x devices */
1627 success
= xds_cycle_tck(60000);
1629 retval
= ERROR_FAIL
;
1635 static void xds110_execute_sleep(struct jtag_command
*cmd
)
1637 jtag_sleep(cmd
->cmd
.sleep
->us
);
1641 static void xds110_execute_tlr_reset(struct jtag_command
*cmd
)
1643 (void)xds_goto_state(XDS_JTAG_STATE_RESET
);
1648 static void xds110_execute_pathmove(struct jtag_command
*cmd
)
1651 uint32_t num_states
;
1654 num_states
= (uint32_t)cmd
->cmd
.pathmove
->num_states
;
1656 if (num_states
== 0)
1659 path
= (uint8_t *)malloc(num_states
* sizeof(uint8_t));
1661 LOG_ERROR("XDS110: unable to allocate memory");
1665 /* Convert requested path states into XDS API states */
1666 for (i
= 0; i
< num_states
; i
++)
1667 path
[i
] = (uint8_t)xds_jtag_state
[cmd
->cmd
.pathmove
->path
[i
]];
1669 if (xds110
.firmware
>= OCD_FIRMWARE_VERSION
) {
1670 /* Updated firmware fully supports pathmove */
1671 (void)ocd_pathmove(num_states
, path
);
1673 /* Notify user that legacy firmware simply cannot handle pathmove */
1674 LOG_ERROR("XDS110: the firmware does not support pathmove command");
1675 LOG_ERROR(OCD_FIRMWARE_UPGRADE
);
1676 /* If pathmove is required, then debug is not possible */
1685 static void xds110_queue_scan(struct jtag_command
*cmd
)
1689 uint32_t total_fields
;
1690 uint32_t total_bits
;
1691 uint32_t total_bytes
;
1695 /* Calculate the total number of bits to scan */
1698 for (i
= 0; i
< cmd
->cmd
.scan
->num_fields
; i
++) {
1700 total_bits
+= (uint32_t)cmd
->cmd
.scan
->fields
[i
].num_bits
;
1703 if (total_bits
== 0)
1706 total_bytes
= DIV_ROUND_UP(total_bits
, 8);
1708 /* Check if new request would be too large to fit */
1709 if (((xds110
.txn_request_size
+ 1 + total_bytes
+ sizeof(end_state
) + 1)
1710 > MAX_DATA_BLOCK
) || ((xds110
.txn_result_count
+ total_fields
) >
1714 /* Check if this single request is too large to fit */
1715 if ((1 + total_bytes
+ sizeof(end_state
) + 1) > MAX_DATA_BLOCK
) {
1716 LOG_ERROR("BUG: JTAG scan request is too large to handle (%d bits)",
1718 /* Failing to run this scan mucks up debug on this target */
1722 if (cmd
->cmd
.scan
->ir_scan
)
1723 xds110
.txn_requests
[xds110
.txn_request_size
++] = CMD_IR_SCAN
;
1725 xds110
.txn_requests
[xds110
.txn_request_size
++] = CMD_DR_SCAN
;
1727 end_state
= (uint8_t)xds_jtag_state
[cmd
->cmd
.scan
->end_state
];
1728 xds110
.txn_requests
[xds110
.txn_request_size
++] = end_state
;
1730 xds110
.txn_requests
[xds110
.txn_request_size
++] = (total_bits
>> 0) & 0xff;
1731 xds110
.txn_requests
[xds110
.txn_request_size
++] = (total_bits
>> 8) & 0xff;
1733 /* Build request data by flattening fields into single buffer */
1734 /* also populate the results array to return the results when run */
1736 buffer
= &xds110
.txn_requests
[xds110
.txn_request_size
];
1737 /* Clear data out buffer to default value of all zeros */
1738 memset((void *)buffer
, 0x00, total_bytes
);
1739 for (i
= 0; i
< cmd
->cmd
.scan
->num_fields
; i
++) {
1740 if (cmd
->cmd
.scan
->fields
[i
].out_value
!= 0) {
1741 /* Copy over data to scan out into request buffer */
1742 bit_copy(buffer
, offset
, cmd
->cmd
.scan
->fields
[i
].out_value
, 0,
1743 cmd
->cmd
.scan
->fields
[i
].num_bits
);
1745 offset
+= cmd
->cmd
.scan
->fields
[i
].num_bits
;
1746 xds110
.txn_scan_results
[xds110
.txn_result_count
].first
= (i
== 0);
1747 xds110
.txn_scan_results
[xds110
.txn_result_count
].num_bits
=
1748 cmd
->cmd
.scan
->fields
[i
].num_bits
;
1749 xds110
.txn_scan_results
[xds110
.txn_result_count
++].buffer
=
1750 cmd
->cmd
.scan
->fields
[i
].in_value
;
1752 xds110
.txn_request_size
+= total_bytes
;
1753 xds110
.txn_result_size
+= total_bytes
;
1758 static void xds110_queue_runtest(struct jtag_command
*cmd
)
1760 uint32_t clocks
= (uint32_t)cmd
->cmd
.stableclocks
->num_cycles
;
1761 uint8_t end_state
= (uint8_t)xds_jtag_state
[cmd
->cmd
.runtest
->end_state
];
1763 /* Check if new request would be too large to fit */
1764 if ((xds110
.txn_request_size
+ 1 + sizeof(clocks
) + sizeof(end_state
) + 1)
1768 /* Queue request and cycle count directly to queue buffer */
1769 xds110
.txn_requests
[xds110
.txn_request_size
++] = CMD_RUNTEST
;
1770 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 0) & 0xff;
1771 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 8) & 0xff;
1772 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 16) & 0xff;
1773 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 24) & 0xff;
1774 xds110
.txn_requests
[xds110
.txn_request_size
++] = end_state
;
1779 static void xds110_queue_stableclocks(struct jtag_command
*cmd
)
1781 uint32_t clocks
= (uint32_t)cmd
->cmd
.stableclocks
->num_cycles
;
1783 /* Check if new request would be too large to fit */
1784 if ((xds110
.txn_request_size
+ 1 + sizeof(clocks
) + 1) > MAX_DATA_BLOCK
)
1787 /* Queue request and cycle count directly to queue buffer */
1788 xds110
.txn_requests
[xds110
.txn_request_size
++] = CMD_STABLECLOCKS
;
1789 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 0) & 0xff;
1790 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 8) & 0xff;
1791 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 16) & 0xff;
1792 xds110
.txn_requests
[xds110
.txn_request_size
++] = (clocks
>> 24) & 0xff;
1797 static void xds110_execute_command(struct jtag_command
*cmd
)
1799 switch (cmd
->type
) {
1802 xds110_execute_sleep(cmd
);
1804 case JTAG_TLR_RESET
:
1806 xds110_execute_tlr_reset(cmd
);
1810 xds110_execute_pathmove(cmd
);
1813 xds110_queue_scan(cmd
);
1816 xds110_queue_runtest(cmd
);
1818 case JTAG_STABLECLOCKS
:
1819 xds110_queue_stableclocks(cmd
);
1823 LOG_ERROR("BUG: unknown JTAG command type 0x%x encountered",
1829 static int xds110_execute_queue(void)
1831 struct jtag_command
*cmd
= jtag_command_queue
;
1833 while (cmd
!= NULL
) {
1834 xds110_execute_command(cmd
);
1843 static int xds110_speed(int speed
)
1848 LOG_INFO("XDS110: RTCK not supported");
1849 return ERROR_JTAG_NOT_IMPLEMENTED
;
1852 if (speed
> XDS110_MAX_TCK_SPEED
) {
1853 LOG_INFO("XDS110: reduce speed request: %dkHz to %dkHz maximum",
1854 speed
, XDS110_MAX_TCK_SPEED
);
1855 speed
= XDS110_MAX_TCK_SPEED
;
1858 if (speed
< XDS110_MIN_TCK_SPEED
) {
1859 LOG_INFO("XDS110: increase speed request: %dkHz to %dkHz minimum",
1860 speed
, XDS110_MIN_TCK_SPEED
);
1861 speed
= XDS110_MIN_TCK_SPEED
;
1864 /* The default is the maximum frequency the XDS110 can support */
1865 uint32_t freq_to_use
= XDS110_MAX_TCK_SPEED
* 1000; /* Hz */
1866 uint32_t delay_count
= 0;
1868 if (XDS110_MAX_TCK_SPEED
!= speed
) {
1869 freq_to_use
= speed
* 1000; /* Hz */
1871 /* Calculate the delay count value */
1872 double one_giga
= 1000000000;
1873 /* Get the pulse duration for the maximum frequency supported in ns */
1874 double max_freq_pulse_duration
= one_giga
/
1875 (XDS110_MAX_TCK_SPEED
* 1000);
1877 /* Convert frequency to pulse duration */
1878 double freq_to_pulse_width_in_ns
= one_giga
/ freq_to_use
;
1881 * Start with the pulse duration for the maximum frequency. Keep
1882 * decrementing the time added by each count value till the requested
1883 * frequency pulse is less than the calculated value.
1885 double current_value
= max_freq_pulse_duration
;
1887 while (current_value
< freq_to_pulse_width_in_ns
) {
1888 current_value
+= XDS110_TCK_PULSE_INCREMENT
;
1893 * Determine which delay count yields the best match.
1894 * The one obtained above or one less.
1897 double diff_freq_1
= freq_to_use
-
1898 (one_giga
/ (max_freq_pulse_duration
+
1899 (XDS110_TCK_PULSE_INCREMENT
* delay_count
)));
1900 double diff_freq_2
= (one_giga
/ (max_freq_pulse_duration
+
1901 (XDS110_TCK_PULSE_INCREMENT
* (delay_count
- 1)))) -
1904 /* One less count value yields a better match */
1905 if (diff_freq_1
> diff_freq_2
)
1910 /* Send the delay count to the XDS110 firmware */
1911 success
= xds_set_tck_delay(delay_count
);
1914 xds110
.delay_count
= delay_count
;
1915 xds110
.speed
= speed
;
1918 return (success
) ? ERROR_OK
: ERROR_FAIL
;
1921 static int xds110_speed_div(int speed
, int *khz
)
1927 static int xds110_khz(int khz
, int *jtag_speed
)
1933 COMMAND_HANDLER(xds110_handle_info_command
)
1939 COMMAND_HANDLER(xds110_handle_serial_command
)
1941 wchar_t serial
[XDS110_SERIAL_LEN
+ 1];
1943 xds110
.serial
[0] = 0;
1945 if (CMD_ARGC
== 1) {
1946 size_t len
= mbstowcs(0, CMD_ARGV
[0], 0);
1947 if (len
> XDS110_SERIAL_LEN
) {
1948 LOG_ERROR("XDS110: serial number is limited to %d characters",
1952 if ((size_t)-1 == mbstowcs(serial
, CMD_ARGV
[0], len
+ 1)) {
1953 LOG_ERROR("XDS110: unable to convert serial number");
1957 for (uint32_t i
= 0; i
< len
; i
++)
1958 xds110
.serial
[i
] = (char)serial
[i
];
1960 xds110
.serial
[len
] = 0;
1962 LOG_ERROR("XDS110: expected exactly one argument to xds110_serial "
1970 COMMAND_HANDLER(xds110_handle_supply_voltage_command
)
1972 uint32_t voltage
= 0;
1974 if (CMD_ARGC
== 1) {
1975 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], voltage
);
1976 if (voltage
== 0 || (voltage
>= XDS110_MIN_VOLTAGE
&& voltage
1977 <= XDS110_MAX_VOLTAGE
)) {
1978 /* Requested voltage is in range */
1979 xds110
.voltage
= voltage
;
1981 LOG_ERROR("XDS110: voltage must be 0 or between %d and %d "
1982 "millivolts", XDS110_MIN_VOLTAGE
, XDS110_MAX_VOLTAGE
);
1985 xds110
.voltage
= voltage
;
1987 LOG_ERROR("XDS110: expected one argument to xds110_supply_voltage "
1995 static const struct command_registration xds110_subcommand_handlers
[] = {
1998 .handler
= &xds110_handle_info_command
,
1999 .mode
= COMMAND_EXEC
,
2001 .help
= "show XDS110 info",
2003 COMMAND_REGISTRATION_DONE
2006 static const struct command_registration xds110_command_handlers
[] = {
2009 .mode
= COMMAND_ANY
,
2010 .help
= "perform XDS110 management",
2012 .chain
= xds110_subcommand_handlers
,
2015 .name
= "xds110_serial",
2016 .handler
= &xds110_handle_serial_command
,
2017 .mode
= COMMAND_CONFIG
,
2018 .help
= "set the XDS110 probe serial number",
2019 .usage
= "serial_string",
2022 .name
= "xds110_supply_voltage",
2023 .handler
= &xds110_handle_supply_voltage_command
,
2024 .mode
= COMMAND_CONFIG
,
2025 .help
= "set the XDS110 probe supply voltage",
2026 .usage
= "supply_voltage (millivolts)",
2028 COMMAND_REGISTRATION_DONE
2031 static const struct swd_driver xds110_swd_driver
= {
2032 .init
= xds110_swd_init
,
2033 .switch_seq
= xds110_swd_switch_seq
,
2034 .read_reg
= xds110_swd_read_reg
,
2035 .write_reg
= xds110_swd_write_reg
,
2036 .run
= xds110_swd_run_queue
,
2039 static const char * const xds110_transport
[] = { "swd", "jtag", NULL
};
2041 static struct jtag_interface xds110_interface
= {
2042 .execute_queue
= xds110_execute_queue
,
2045 struct adapter_driver xds110_adapter_driver
= {
2047 .transports
= xds110_transport
,
2048 .commands
= xds110_command_handlers
,
2050 .init
= xds110_init
,
2051 .quit
= xds110_quit
,
2052 .reset
= xds110_reset
,
2053 .speed
= xds110_speed
,
2055 .speed_div
= xds110_speed_div
,
2057 .jtag_ops
= &xds110_interface
,
2058 .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)