X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Fdrivers%2Fxds110.c;h=8a832adf0ab3d68ab8fb6873dce8676665255336;hb=d35c44c743d6f471697ed1d204fe5447fd47cefd;hp=085d85f4c3c76807dfce92be28b258fca8de7fc2;hpb=c9ebd488eadfaec6154db5747f376323f587766d;p=openocd.git diff --git a/src/jtag/drivers/xds110.c b/src/jtag/drivers/xds110.c index 085d85f4c3..8a832adf0a 100644 --- a/src/jtag/drivers/xds110.c +++ b/src/jtag/drivers/xds110.c @@ -66,15 +66,6 @@ #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 * ***************************************************************************/ @@ -227,6 +218,13 @@ struct xds110_info { 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; @@ -259,6 +257,11 @@ struct xds110_info { 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, @@ -320,12 +323,20 @@ static bool usb_connect(void) 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); @@ -342,13 +353,21 @@ static bool usb_connect(void) 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 < sizeof(vids)/sizeof(vids[0]); 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 */ @@ -359,7 +378,7 @@ static bool usb_connect(void) } else { /* Get the device's serial number string */ result = libusb_get_string_descriptor_ascii(dev, - desc.iSerialNumber, data, MAX_DATA); + desc.iSerialNumber, data, max_data); if (0 < result && 0 == strcmp((char *)data, (char *)xds110.serial)) { found = true; @@ -387,6 +406,15 @@ static bool usb_connect(void) } 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; @@ -395,7 +423,7 @@ static bool usb_connect(void) (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; @@ -405,7 +433,7 @@ static bool usb_connect(void) 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) @@ -427,7 +455,7 @@ static void usb_disconnect(void) { 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; } @@ -451,7 +479,7 @@ static bool usb_read(unsigned char *buffer, int size, int *bytes_read, 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; @@ -466,13 +494,13 @@ static bool usb_write(unsigned char *buffer, int size, int *written) 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) { /* 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++; } @@ -1360,6 +1388,7 @@ static void xds110_show_info(void) { uint32_t firmware = xds110.firmware; + LOG_INFO("XDS110: vid/pid = %04x/%04x", xds110.vid, xds110.pid); LOG_INFO("XDS110: firmware version = %d.%d.%d.%d", (((firmware >> 28) & 0xf) * 10) + ((firmware >> 24) & 0xf), (((firmware >> 20) & 0xf) * 10) + ((firmware >> 16) & 0xf), @@ -2028,11 +2057,8 @@ COMMAND_HANDLER(xds110_handle_serial_command) xds110.serial[i] = (char)serial[i]; xds110.serial[len] = 0; - } else { - LOG_ERROR("XDS110: expected exactly one argument to xds110_serial " - ""); - return ERROR_FAIL; - } + } else + return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_OK; } @@ -2053,11 +2079,8 @@ COMMAND_HANDLER(xds110_handle_supply_voltage_command) return ERROR_FAIL; } xds110.voltage = voltage; - } else { - LOG_ERROR("XDS110: expected one argument to xds110_supply_voltage " - ""); - return ERROR_FAIL; - } + } else + return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_OK; } @@ -2067,33 +2090,33 @@ static const struct command_registration xds110_subcommand_handlers[] = { .name = "info", .handler = &xds110_handle_info_command, .mode = COMMAND_EXEC, - .usage = "", .help = "show XDS110 info", - }, - COMMAND_REGISTRATION_DONE -}; - -static const struct command_registration xds110_command_handlers[] = { - { - .name = "xds110", - .mode = COMMAND_ANY, - .help = "perform XDS110 management", - .usage = "", - .chain = xds110_subcommand_handlers, + .usage = "", }, { - .name = "xds110_serial", + .name = "serial", .handler = &xds110_handle_serial_command, .mode = COMMAND_CONFIG, .help = "set the XDS110 probe serial number", .usage = "serial_string", }, { - .name = "xds110_supply_voltage", + .name = "supply", .handler = &xds110_handle_supply_voltage_command, .mode = COMMAND_CONFIG, .help = "set the XDS110 probe supply voltage", - .usage = "supply_voltage (millivolts)", + .usage = "voltage_in_millivolts", + }, + COMMAND_REGISTRATION_DONE +}; + +static const struct command_registration xds110_command_handlers[] = { + { + .name = "xds110", + .mode = COMMAND_ANY, + .help = "perform XDS110 management", + .usage = "", + .chain = xds110_subcommand_handlers, }, COMMAND_REGISTRATION_DONE };