drivers: xds110: Add support for XDS110 stand-alone probe

The XDS110 stand-alone version has the ability to supply
voltage to the target board via it's AUX FUNCTIONS port.
Added command to enable setting the voltage on the XDS110
stand-alone.

Change-Id: I2f21c4a3d15ed99e649f3a83973c5e724c4bfeb6
Signed-off-by: Edward Fewell <efewell@ti.com>
Reviewed-on: http://openocd.zylin.com/4793
Tested-by: jenkins
Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
log_output
Edward Fewell 2018-12-06 14:47:29 -06:00 committed by Tomas Vanek
parent 9388915dc6
commit 615a066629
2 changed files with 90 additions and 1 deletions

View File

@ -538,6 +538,12 @@ debuggers to ARM Cortex based targets @url{http://www.keil.com/support/man/docs/
@item @b{TI XDS110 Debug Probe} @item @b{TI XDS110 Debug Probe}
@* The XDS110 is included as the embedded debug probe on many Texas Instruments @* The XDS110 is included as the embedded debug probe on many Texas Instruments
LaunchPad evaluation boards. LaunchPad evaluation boards.
@* The XDS110 is also available as a stand-alone USB debug probe. The XDS110
stand-alone probe has the additional ability to supply voltage to the target
board via its AUX FUNCTIONS port. Use the
@command{xds110_supply_voltage <millivolts>} command to set the voltage. 0 turns
off the supply. Otherwise, the supply can be set to any value in the range 1800
to 3600 millivolts.
@* Link: @url{http://processors.wiki.ti.com/index.php/XDS110} @* Link: @url{http://processors.wiki.ti.com/index.php/XDS110}
@* Link: @url{http://processors.wiki.ti.com/index.php/XDS_Emulation_Software_Package#XDS110_Support_Utilities} @* Link: @url{http://processors.wiki.ti.com/index.php/XDS_Emulation_Software_Package#XDS110_Support_Utilities}
@end itemize @end itemize

View File

@ -29,6 +29,13 @@
/* XDS110 USB serial number length */ /* XDS110 USB serial number length */
#define XDS110_SERIAL_LEN 8 #define XDS110_SERIAL_LEN 8
/* XDS110 stand-alone probe voltage supply limits */
#define XDS110_MIN_VOLTAGE 1800
#define XDS110_MAX_VOLTAGE 3600
/* XDS110 stand-alone probe hardware ID */
#define XDS110_STAND_ALONE_ID 0x21
/* Firmware version that introduced OpenOCD support via block accesses */ /* Firmware version that introduced OpenOCD support via block accesses */
#define OCD_FIRMWARE_VERSION 0x02030011 #define OCD_FIRMWARE_VERSION 0x02030011
#define OCD_FIRMWARE_UPGRADE \ #define OCD_FIRMWARE_UPGRADE \
@ -162,6 +169,7 @@
#define SWD_DISCONNECT 0x18 /* Switch from SWD to JTAG connection */ #define SWD_DISCONNECT 0x18 /* Switch from SWD to JTAG connection */
#define CJTAG_CONNECT 0x2b /* Switch from JTAG to cJTAG connection */ #define CJTAG_CONNECT 0x2b /* Switch from JTAG to cJTAG connection */
#define CJTAG_DISCONNECT 0x2c /* Switch from cJTAG to JTAG connection */ #define CJTAG_DISCONNECT 0x2c /* Switch from cJTAG to JTAG connection */
#define XDS_SET_SUPPLY 0x32 /* Set up stand-alone probe upply voltage */
#define OCD_DAP_REQUEST 0x3a /* Handle block of DAP requests */ #define OCD_DAP_REQUEST 0x3a /* Handle block of DAP requests */
#define OCD_SCAN_REQUEST 0x3b /* Handle block of JTAG scan requests */ #define OCD_SCAN_REQUEST 0x3b /* Handle block of JTAG scan requests */
#define OCD_PATHMOVE 0x3c /* Handle PATHMOVE to navigate JTAG states */ #define OCD_PATHMOVE 0x3c /* Handle PATHMOVE to navigate JTAG states */
@ -219,6 +227,8 @@ struct xds110_info {
uint32_t delay_count; uint32_t delay_count;
/* XDS110 serial number */ /* XDS110 serial number */
char serial[XDS110_SERIAL_LEN + 1]; char serial[XDS110_SERIAL_LEN + 1];
/* XDS110 voltage supply setting */
uint32_t voltage;
/* XDS110 firmware and hardware version */ /* XDS110 firmware and hardware version */
uint32_t firmware; uint32_t firmware;
uint16_t hardware; uint16_t hardware;
@ -242,6 +252,7 @@ static struct xds110_info xds110 = {
.speed = XDS110_MAX_TCK_SPEED, .speed = XDS110_MAX_TCK_SPEED,
.delay_count = 0, .delay_count = 0,
.serial = {0}, .serial = {0},
.voltage = 0,
.firmware = 0, .firmware = 0,
.hardware = 0, .hardware = 0,
.txn_request_size = 0, .txn_request_size = 0,
@ -601,10 +612,15 @@ static bool xds_execute(uint32_t out_length, uint32_t in_length,
if (bytes_read != in_length) { if (bytes_read != in_length) {
/* Unexpected amount of data returned */ /* Unexpected amount of data returned */
success = false; success = false;
LOG_DEBUG("XDS110: command 0x%02x return %d bytes, expected %d",
xds110.write_payload[0], bytes_read, in_length);
} else { } else {
/* Extract error code from return packet */ /* Extract error code from return packet */
error = (int)xds110_get_u32(&xds110.read_payload[0]); error = (int)xds110_get_u32(&xds110.read_payload[0]);
done = true; done = true;
if (SC_ERR_NONE != error)
LOG_DEBUG("XDS110: command 0x%02x returned error %d",
xds110.write_payload[0], error);
} }
} }
} }
@ -952,6 +968,24 @@ static bool cjtag_disconnect(void)
return success; return success;
} }
static bool xds_set_supply(uint32_t voltage)
{
uint8_t *volts_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 32-bits */
uint8_t *source_pntr = &xds110.write_payload[XDS_OUT_LEN + 4]; /* 8-bits */
bool success;
xds110.write_payload[0] = XDS_SET_SUPPLY;
xds110_set_u32(volts_pntr, voltage);
*source_pntr = (uint8_t)(0 != voltage ? 1 : 0);
success = xds_execute(XDS_OUT_LEN + 5, XDS_IN_LEN, DEFAULT_ATTEMPTS,
DEFAULT_TIMEOUT);
return success;
}
static bool ocd_dap_request(uint8_t *dap_requests, uint32_t request_size, static bool ocd_dap_request(uint8_t *dap_requests, uint32_t request_size,
uint32_t *dap_results, uint32_t result_count) uint32_t *dap_results, uint32_t result_count)
{ {
@ -1318,7 +1352,7 @@ static void xds110_show_info(void)
(((firmware >> 4) & 0xf) * 10) + ((firmware >> 0) & 0xf)); (((firmware >> 4) & 0xf) * 10) + ((firmware >> 0) & 0xf));
LOG_INFO("XDS110: hardware version = 0x%04x", xds110.hardware); LOG_INFO("XDS110: hardware version = 0x%04x", xds110.hardware);
if (0 != xds110.serial[0]) if (0 != xds110.serial[0])
LOG_INFO("XDS110: serial number = %s)", xds110.serial); LOG_INFO("XDS110: serial number = %s", xds110.serial);
if (xds110.is_swd_mode) { if (xds110.is_swd_mode) {
LOG_INFO("XDS110: connected to target via SWD"); LOG_INFO("XDS110: connected to target via SWD");
LOG_INFO("XDS110: SWCLK set to %d kHz", xds110.speed); LOG_INFO("XDS110: SWCLK set to %d kHz", xds110.speed);
@ -1390,6 +1424,20 @@ static int xds110_init(void)
} }
} }
if (success) {
/* Set supply voltage for stand-alone probes */
if (XDS110_STAND_ALONE_ID == xds110.hardware) {
success = xds_set_supply(xds110.voltage);
/* Allow time for target device to power up */
/* (CC32xx takes up to 1300 ms before debug is enabled) */
alive_sleep(1500);
} else if (0 != xds110.voltage) {
/* Voltage supply not a feature of embedded probes */
LOG_WARNING(
"XDS110: ignoring supply voltage, not supported on this probe");
}
}
if (success) { if (success) {
success = xds_set_trst(0); success = xds_set_trst(0);
if (success) if (success)
@ -1569,6 +1617,9 @@ static void xds110_execute_reset(struct jtag_command *cmd)
srst = 0; srst = 0;
} }
(void)xds_set_srst(srst); (void)xds_set_srst(srst);
/* Toggle TCK to trigger HIB on CC13x/CC26x devices */
(void)xds_cycle_tck(60000);
} }
} }
@ -1918,6 +1969,31 @@ COMMAND_HANDLER(xds110_handle_serial_command)
return ERROR_OK; return ERROR_OK;
} }
COMMAND_HANDLER(xds110_handle_supply_voltage_command)
{
uint32_t voltage = 0;
if (CMD_ARGC == 1) {
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], voltage);
if (voltage == 0 || (voltage >= XDS110_MIN_VOLTAGE && voltage
<= XDS110_MAX_VOLTAGE)) {
/* Requested voltage is in range */
xds110.voltage = voltage;
} else {
LOG_ERROR("XDS110: voltage must be 0 or between %d and %d "
"millivolts", XDS110_MIN_VOLTAGE, XDS110_MAX_VOLTAGE);
return ERROR_FAIL;
}
xds110.voltage = voltage;
} else {
LOG_ERROR("XDS110: expected one argument to xds110_supply_voltage "
"<millivolts>");
return ERROR_FAIL;
}
return ERROR_OK;
}
static const struct command_registration xds110_subcommand_handlers[] = { static const struct command_registration xds110_subcommand_handlers[] = {
{ {
.name = "info", .name = "info",
@ -1944,6 +2020,13 @@ static const struct command_registration xds110_command_handlers[] = {
.help = "set the XDS110 probe serial number", .help = "set the XDS110 probe serial number",
.usage = "serial_string", .usage = "serial_string",
}, },
{
.name = "xds110_supply_voltage",
.handler = &xds110_handle_supply_voltage_command,
.mode = COMMAND_CONFIG,
.help = "set the XDS110 probe supply voltage",
.usage = "supply_voltage (millivolts)",
},
COMMAND_REGISTRATION_DONE COMMAND_REGISTRATION_DONE
}; };