#endif
#define MAX_RESULT_QUEUE (MAX_DATA_BLOCK / 4)
-/***************************************************************************
- * USB Connection Endpoints *
- ***************************************************************************/
-
-/* Bulk endpoints used by the XDS110 debug interface */
-#define INTERFACE_DEBUG (2)
-#define ENDPOINT_DEBUG_IN (3 | LIBUSB_ENDPOINT_IN)
-#define ENDPOINT_DEBUG_OUT (2 | LIBUSB_ENDPOINT_OUT)
-
/***************************************************************************
* XDS110 Firmware API Definitions *
***************************************************************************/
#define CMD_STABLECLOCKS 4
/* Array to convert from OpenOCD tap_state_t to XDS JTAG state */
-const uint32_t xds_jtag_state[] = {
+static const uint32_t xds_jtag_state[] = {
XDS_JTAG_STATE_EXIT2_DR, /* TAP_DREXIT2 = 0x0 */
XDS_JTAG_STATE_EXIT1_DR, /* TAP_DREXIT1 = 0x1 */
XDS_JTAG_STATE_SHIFT_DR, /* TAP_DRSHIFT = 0x2 */
struct xds110_info {
/* USB connection handles and data buffers */
- libusb_context *ctx;
- libusb_device_handle *dev;
+ struct libusb_context *ctx;
+ struct libusb_device_handle *dev;
unsigned char read_payload[USB_PAYLOAD_SIZE];
unsigned char write_packet[3];
unsigned char write_payload[USB_PAYLOAD_SIZE];
+ /* Device vid/pid */
+ uint16_t vid;
+ uint16_t pid;
+ /* Debug interface */
+ uint8_t interface;
+ uint8_t endpoint_in;
+ uint8_t endpoint_out;
/* Status flags */
bool is_connected;
bool is_cmapi_connected;
static struct xds110_info xds110 = {
.ctx = NULL,
.dev = NULL,
+ .vid = 0,
+ .pid = 0,
+ .interface = 0,
+ .endpoint_in = 0,
+ .endpoint_out = 0,
.is_connected = false,
.is_cmapi_connected = false,
.is_cmapi_acquired = false,
static bool usb_connect(void)
{
- libusb_context *ctx = NULL;
- libusb_device **list = NULL;
- libusb_device_handle *dev = NULL;
+ struct libusb_context *ctx = NULL;
+ struct libusb_device **list = NULL;
+ struct libusb_device_handle *dev = NULL;
struct libusb_device_descriptor desc;
- uint16_t vid = 0x0451;
- uint16_t pid = 0xbef3;
+ /* The vid/pids of possible XDS110 configurations */
+ uint16_t vids[] = { 0x0451, 0x0451, 0x1cbe };
+ uint16_t pids[] = { 0xbef3, 0xbef4, 0x02a5 };
+ /* Corresponding interface and endpoint numbers for configurations */
+ uint8_t interfaces[] = { 2, 2, 0 };
+ uint8_t endpoints_in[] = { 3, 3, 1 };
+ uint8_t endpoints_out[] = { 2, 2, 1 };
+
ssize_t count = 0;
ssize_t i = 0;
int result = 0;
bool found = false;
+ uint32_t device = 0;
+ bool match = false;
/* Initialize libusb context */
result = libusb_init(&ctx);
if (0 == result) {
/* Scan through list of devices for any XDS110s */
for (i = 0; i < count; i++) {
- /* Check for device VID/PID match */
+ /* Check for device vid/pid match */
libusb_get_device_descriptor(list[i], &desc);
- if (desc.idVendor == vid && desc.idProduct == pid) {
+ match = false;
+ for (device = 0; device < ARRAY_SIZE(vids); device++) {
+ if (desc.idVendor == vids[device] &&
+ desc.idProduct == pids[device]) {
+ match = true;
+ break;
+ }
+ }
+ if (match) {
result = libusb_open(list[i], &dev);
if (0 == result) {
- const int MAX_DATA = 256;
- unsigned char data[MAX_DATA + 1];
+ const int max_data = 256;
+ unsigned char data[max_data + 1];
*data = '\0';
/* May be the requested device if serial number matches */
} else {
/* Get the device's serial number string */
result = libusb_get_string_descriptor_ascii(dev,
- desc.iSerialNumber, data, MAX_DATA);
- if (0 < result &&
- 0 == strcmp((char *)data, (char *)xds110.serial)) {
+ desc.iSerialNumber, data, max_data);
+ if (result > 0 &&
+ strcmp((char *)data, (char *)xds110.serial) == 0) {
found = true;
break;
}
}
if (found) {
+ /* Save the vid/pid of the device we're using */
+ xds110.vid = vids[device];
+ xds110.pid = pids[device];
+
+ /* Save the debug interface and endpoints for the device */
+ xds110.interface = interfaces[device];
+ xds110.endpoint_in = endpoints_in[device] | LIBUSB_ENDPOINT_IN;
+ xds110.endpoint_out = endpoints_out[device] | LIBUSB_ENDPOINT_OUT;
+
/* Save the context and device handles */
xds110.ctx = ctx;
xds110.dev = dev;
(void)libusb_set_auto_detach_kernel_driver(dev, 1);
/* Claim the debug interface on the XDS110 */
- result = libusb_claim_interface(dev, INTERFACE_DEBUG);
+ result = libusb_claim_interface(dev, xds110.interface);
} else {
/* Couldn't find an XDS110, flag the error */
result = -1;
if (0 != result) {
if (NULL != dev) {
/* Release the debug and data interface on the XDS110 */
- (void)libusb_release_interface(dev, INTERFACE_DEBUG);
+ (void)libusb_release_interface(dev, xds110.interface);
libusb_close(dev);
}
if (NULL != ctx)
{
if (NULL != xds110.dev) {
/* Release the debug and data interface on the XDS110 */
- (void)libusb_release_interface(xds110.dev, INTERFACE_DEBUG);
+ (void)libusb_release_interface(xds110.dev, xds110.interface);
libusb_close(xds110.dev);
xds110.dev = NULL;
}
if (0 == timeout)
timeout = DEFAULT_TIMEOUT;
- result = libusb_bulk_transfer(xds110.dev, ENDPOINT_DEBUG_IN, buffer, size,
+ result = libusb_bulk_transfer(xds110.dev, xds110.endpoint_in, buffer, size,
bytes_read, timeout);
return (0 == result) ? true : false;
if (NULL == xds110.dev || NULL == buffer)
return false;
- result = libusb_bulk_transfer(xds110.dev, ENDPOINT_DEBUG_OUT, buffer,
+ result = libusb_bulk_transfer(xds110.dev, xds110.endpoint_out, buffer,
size, &bytes_written, 0);
- while (LIBUSB_ERROR_PIPE == result && retries < 3) {
+ while (result == LIBUSB_ERROR_PIPE && retries < 3) {
/* Try clearing the pipe stall and retry transfer */
- libusb_clear_halt(xds110.dev, ENDPOINT_DEBUG_OUT);
- result = libusb_bulk_transfer(xds110.dev, ENDPOINT_DEBUG_OUT, buffer,
+ libusb_clear_halt(xds110.dev, xds110.endpoint_out);
+ result = libusb_bulk_transfer(xds110.dev, xds110.endpoint_out, buffer,
size, &bytes_written, 0);
retries++;
}
if (NULL != written)
*written = bytes_written;
- return (0 == result && size == bytes_written) ? true : false;
+ return (result == 0 && size == bytes_written) ? true : false;
}
static bool usb_get_response(uint32_t *total_bytes_read, uint32_t timeout)
if (bytes_read != in_length) {
/* Unexpected amount of data returned */
success = false;
- LOG_DEBUG("XDS110: command 0x%02x return %d bytes, expected %d",
+ LOG_DEBUG("XDS110: command 0x%02x return %" PRIu32 " bytes, expected %" PRIu32,
xds110.write_payload[0], bytes_read, in_length);
} else {
/* Extract error code from return packet */
error = (int)xds110_get_u32(&xds110.read_payload[0]);
done = true;
- if (SC_ERR_NONE != error)
+ if (error != SC_ERR_NONE)
LOG_DEBUG("XDS110: command 0x%02x returned error %d",
xds110.write_payload[0], error);
}
xds110.write_payload[0] = XDS_SET_SUPPLY;
xds110_set_u32(volts_pntr, voltage);
- *source_pntr = (uint8_t)(0 != voltage ? 1 : 0);
+ *source_pntr = (uint8_t)(voltage != 0 ? 1 : 0);
success = xds_execute(XDS_OUT_LEN + 5, XDS_IN_LEN, DEFAULT_ATTEMPTS,
DEFAULT_TIMEOUT);
xds110.is_cmapi_acquired = false;
/* Run sequence to put target in SWD mode */
success = swd_connect();
- /* Re-iniitialize CMAPI API for DAP access */
+ /* Re-initialize CMAPI API for DAP access */
if (success) {
xds110.is_swd_mode = true;
success = cmapi_connect(&idcode);
static bool xds110_legacy_read_reg(uint8_t cmd, uint32_t *value)
{
/* Make sure this is a read request */
- bool is_read_request = (0 != (SWD_CMD_RnW & cmd));
+ bool is_read_request = (0 != (SWD_CMD_RNW & cmd));
/* Determine whether this is a DP or AP register access */
- uint32_t type = (0 != (SWD_CMD_APnDP & cmd)) ? DAP_AP : DAP_DP;
+ uint32_t type = (0 != (SWD_CMD_APNDP & cmd)) ? DAP_AP : DAP_DP;
/* Determine the AP number from cached SELECT value */
uint32_t ap_num = (xds110.select & 0xff000000) >> 24;
/* Extract register address from command */
if (!is_read_request)
return false;
- if (DAP_AP == type) {
+ if (type == DAP_AP) {
/* Add bank address to register address for CMAPI call */
address |= bank;
}
static bool xds110_legacy_write_reg(uint8_t cmd, uint32_t value)
{
/* Make sure this isn't a read request */
- bool is_read_request = (0 != (SWD_CMD_RnW & cmd));
+ bool is_read_request = (0 != (SWD_CMD_RNW & cmd));
/* Determine whether this is a DP or AP register access */
- uint32_t type = (0 != (SWD_CMD_APnDP & cmd)) ? DAP_AP : DAP_DP;
+ uint32_t type = (0 != (SWD_CMD_APNDP & cmd)) ? DAP_AP : DAP_DP;
/* Determine the AP number from cached SELECT value */
uint32_t ap_num = (xds110.select & 0xff000000) >> 24;
/* Extract register address from command */
/* Invalidate the RDBUFF cache */
xds110.use_rdbuff = false;
- if (DAP_AP == type) {
+ if (type == DAP_AP) {
/* Add bank address to register address for CMAPI call */
address |= bank;
/* Any write to an AP register invalidates the firmware's cache */
xds110.is_ap_dirty = true;
- } else if (DAP_DP_SELECT == address) {
+ } else if (address == DAP_DP_SELECT) {
/* Any write to the SELECT register invalidates the firmware's cache */
xds110.is_ap_dirty = true;
}
* If the debugger wrote to SELECT, cache the value
* to use to build the apNum and address values above
*/
- if ((DAP_DP == type) && (DAP_DP_SELECT == address))
+ if ((type == DAP_DP) && (address == DAP_DP_SELECT))
xds110.select = value;
}
result = 0;
while (xds110.txn_requests[request] != 0) {
cmd = xds110.txn_requests[request++];
- if (0 == (SWD_CMD_RnW & cmd)) {
+ if (0 == (SWD_CMD_RNW & cmd)) {
/* DAP register write command */
value = (uint32_t)(xds110.txn_requests[request++]) << 0;
value |= (uint32_t)(xds110.txn_requests[request++]) << 8;
static void xds110_swd_queue_cmd(uint8_t cmd, uint32_t *value)
{
/* Check if this is a read or write request */
- bool is_read_request = (0 != (SWD_CMD_RnW & cmd));
+ bool is_read_request = (0 != (SWD_CMD_RNW & cmd));
/* Determine whether this is a DP or AP register access */
- uint32_t type = (0 != (SWD_CMD_APnDP & cmd)) ? DAP_AP : DAP_DP;
+ uint32_t type = (0 != (SWD_CMD_APNDP & cmd)) ? DAP_AP : DAP_DP;
/* Extract register address from command */
uint32_t address = ((cmd & SWD_CMD_A32) >> 1);
uint32_t request_size = (is_read_request) ? 1 : 5;
{
uint32_t firmware = xds110.firmware;
- LOG_INFO("XDS110: firmware version = %d.%d.%d.%d",
+ LOG_INFO("XDS110: vid/pid = %04x/%04x", xds110.vid, xds110.pid);
+ LOG_INFO("XDS110: firmware version = %" PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32,
(((firmware >> 28) & 0xf) * 10) + ((firmware >> 24) & 0xf),
(((firmware >> 20) & 0xf) * 10) + ((firmware >> 16) & 0xf),
(((firmware >> 12) & 0xf) * 10) + ((firmware >> 8) & 0xf),
LOG_INFO("XDS110: serial number = %s", xds110.serial);
if (xds110.is_swd_mode) {
LOG_INFO("XDS110: connected to target via SWD");
- LOG_INFO("XDS110: SWCLK set to %d kHz", xds110.speed);
+ LOG_INFO("XDS110: SWCLK set to %" PRIu32 " kHz", xds110.speed);
} else {
LOG_INFO("XDS110: connected to target via JTAG");
- LOG_INFO("XDS110: TCK set to %d kHz", xds110.speed);
+ LOG_INFO("XDS110: TCK set to %" PRIu32 " kHz", xds110.speed);
}
/* Alert user that there's a better firmware to use */
static void xds110_execute_sleep(struct jtag_command *cmd)
{
jtag_sleep(cmd->cmd.sleep->us);
- return;
}
static void xds110_execute_tlr_reset(struct jtag_command *cmd)
{
(void)xds_goto_state(XDS_JTAG_STATE_RESET);
-
- return;
}
static void xds110_execute_pathmove(struct jtag_command *cmd)
}
free((void *)path);
-
- return;
}
static void xds110_queue_scan(struct jtag_command *cmd)
/* Check if this single request is too large to fit */
if ((1 + total_bytes + sizeof(end_state) + 1) > MAX_DATA_BLOCK) {
- LOG_ERROR("BUG: JTAG scan request is too large to handle (%d bits)",
+ LOG_ERROR("BUG: JTAG scan request is too large to handle (%" PRIu32 " bits)",
total_bits);
/* Failing to run this scan mucks up debug on this target */
exit(-1);
}
xds110.txn_request_size += total_bytes;
xds110.txn_result_size += total_bytes;
-
- return;
}
static void xds110_queue_runtest(struct jtag_command *cmd)
xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 16) & 0xff;
xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 24) & 0xff;
xds110.txn_requests[xds110.txn_request_size++] = end_state;
-
- return;
}
static void xds110_queue_stableclocks(struct jtag_command *cmd)
xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 8) & 0xff;
xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 16) & 0xff;
xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 24) & 0xff;
-
- return;
}
static void xds110_execute_command(struct jtag_command *cmd)
uint32_t voltage = 0;
if (CMD_ARGC == 1) {
- COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], voltage);
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], voltage);
if (voltage == 0 || (voltage >= XDS110_MIN_VOLTAGE && voltage
<= XDS110_MAX_VOLTAGE)) {
/* Requested voltage is in range */