X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fjtag%2Fdrivers%2Fstlink_usb.c;h=a0ee44c44ac7cc369bc3479f56e64dc1d3cabb21;hp=49d7391fc7a9d1e2bc50e5e46c69e5c63a7da21c;hb=ab9221f80592bd99c017c3689ae3b805c01a0743;hpb=1822c2fb9487d56b2787d114275dadf42cb55053 diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 49d7391fc7..a0ee44c44a 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -89,6 +89,8 @@ struct stlink_usb_version { int swim; /** highest supported jtag api version */ enum stlink_jtag_api_version jtag_api_max; + /** one bit for each feature supported. See macros STLINK_F_* */ + uint32_t flags; }; /** */ @@ -257,7 +259,6 @@ struct stlink_usb_handle_s { #define STLINK_TRACE_SIZE 4096 #define STLINK_TRACE_MAX_HZ 2000000 -#define STLINK_TRACE_MIN_VERSION 13 /** */ enum stlink_mode { @@ -272,6 +273,15 @@ enum stlink_mode { #define REQUEST_SENSE 0x03 #define REQUEST_SENSE_LENGTH 18 +/* + * Map the relevant features, quirks and workaround for specific firmware + * version of stlink + */ +#define STLINK_F_HAS_TRACE (1UL << 0) + +/* aliases */ +#define STLINK_F_HAS_TARGET_VOLT STLINK_F_HAS_TRACE + struct speed_map { int speed; int speed_divisor; @@ -560,7 +570,7 @@ static int stlink_usb_read_trace(void *handle, const uint8_t *buf, int size) assert(handle != NULL); - assert(h->version.stlink >= 2); + assert(h->version.flags & STLINK_F_HAS_TRACE); if (jtag_libusb_bulk_read(h->fd, h->trace_ep, (char *)buf, size, STLINK_READ_TIMEOUT) != size) { @@ -622,6 +632,7 @@ static void stlink_usb_init_buffer(void *handle, uint8_t direction, uint32_t siz static int stlink_usb_version(void *handle) { int res; + uint32_t flags; uint16_t v; struct stlink_usb_handle_s *h = handle; @@ -644,13 +655,30 @@ static int stlink_usb_version(void *handle) h->vid = buf_get_u32(h->databuf, 16, 16); h->pid = buf_get_u32(h->databuf, 32, 16); - /* set the supported jtag api version - * API V2 is supported since JTAG V11 - */ - if (h->version.jtag >= 11) + flags = 0; + switch (h->version.stlink) { + case 1: + /* ST-LINK/V1 from J11 switch to api-v2 (and support SWD) */ + if (h->version.jtag >= 11) + h->version.jtag_api_max = STLINK_JTAG_API_V2; + else + h->version.jtag_api_max = STLINK_JTAG_API_V1; + + break; + case 2: + /* all ST-LINK/V2 and ST-Link/V2.1 use api-v2 */ h->version.jtag_api_max = STLINK_JTAG_API_V2; - else - h->version.jtag_api_max = STLINK_JTAG_API_V1; + + /* API for trace from J13 */ + /* API for target voltage from J13 */ + if (h->version.jtag >= 13) + flags |= STLINK_F_HAS_TRACE; + + break; + default: + break; + } + h->version.flags = flags; LOG_INFO("STLINK v%d JTAG v%d API v%d SWIM v%d VID 0x%04X PID 0x%04X", h->version.stlink, @@ -668,8 +696,8 @@ static int stlink_usb_check_voltage(void *handle, float *target_voltage) struct stlink_usb_handle_s *h = handle; uint32_t adc_results[2]; - /* only supported by stlink/v2 and for firmware >= 13 */ - if (h->version.stlink == 1 || h->version.jtag < 13) + /* no error message, simply quit with error */ + if (!(h->version.flags & STLINK_F_HAS_TARGET_VOLT)) return ERROR_COMMAND_NOTFOUND; stlink_usb_init_buffer(handle, h->rx_ep, 8); @@ -1256,7 +1284,7 @@ static int stlink_usb_trace_read(void *handle, uint8_t *buf, size_t *size) assert(handle != NULL); - if (h->trace.enabled && h->version.jtag >= STLINK_TRACE_MIN_VERSION) { + if (h->trace.enabled && (h->version.flags & STLINK_F_HAS_TRACE)) { int res; stlink_usb_init_buffer(handle, h->rx_ep, 10); @@ -1385,7 +1413,7 @@ static void stlink_usb_trace_disable(void *handle) assert(handle != NULL); - assert(h->version.jtag >= STLINK_TRACE_MIN_VERSION); + assert(h->version.flags & STLINK_F_HAS_TRACE); LOG_DEBUG("Tracing: disable"); @@ -1407,7 +1435,7 @@ static int stlink_usb_trace_enable(void *handle) assert(handle != NULL); - if (h->version.jtag >= STLINK_TRACE_MIN_VERSION) { + if (h->version.flags & STLINK_F_HAS_TRACE) { stlink_usb_init_buffer(handle, h->rx_ep, 10); h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; @@ -2262,7 +2290,6 @@ static int stlink_usb_open(struct hl_interface_param_s *param, void **fd) case STLINK_V1_PID: h->version.stlink = 1; h->tx_ep = STLINK_TX_EP; - h->trace_ep = STLINK_TRACE_EP; break; case STLINK_V2_1_PID: case STLINK_V2_1_NO_MSD_PID: @@ -2409,7 +2436,7 @@ int stlink_config_trace(void *handle, bool enabled, enum tpiu_pin_protocol pin_p { struct stlink_usb_handle_s *h = handle; - if (enabled && (h->jtag_api < 2 || + if (enabled && (!(h->version.flags & STLINK_F_HAS_TRACE) || pin_protocol != TPIU_PIN_PROTOCOL_ASYNC_UART)) { LOG_ERROR("The attached ST-LINK version doesn't support this trace mode"); return ERROR_FAIL;