X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Fdrivers%2Fstlink_usb.c;h=ce7ff413277282bda881dccf5b2fac7f7fae05ca;hb=30fde70c0321fd70d9330d5c6b56ed4e86653dd9;hp=7e31fe0429c6b7df232b74b880104cf70a48e73b;hpb=1bba393e3cf6ae36bf056f99761a0571811dc28a;p=openocd.git diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 7e31fe0429..ce7ff41327 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -30,9 +30,9 @@ /* project specific includes */ #include #include -#include -#include -#include +#include +#include +#include #include #include @@ -82,7 +82,7 @@ struct stlink_usb_handle_s { /** */ uint8_t databuf[STLINK_DATA_SIZE]; /** */ - enum stlink_transports transport; + enum hl_transports transport; /** */ struct stlink_usb_version version; /** */ @@ -107,6 +107,7 @@ struct stlink_usb_handle_s { #define STLINK_DFU_COMMAND 0xF3 #define STLINK_SWIM_COMMAND 0xF4 #define STLINK_GET_CURRENT_MODE 0xF5 +#define STLINK_GET_TARGET_VOLTAGE 0xF7 #define STLINK_DEV_DFU_MODE 0x00 #define STLINK_DEV_MASS_MODE 0x01 @@ -424,6 +425,40 @@ static int stlink_usb_version(void *handle) return ERROR_OK; } +static int stlink_usb_check_voltage(void *handle, float *target_voltage) +{ + struct stlink_usb_handle_s *h; + uint32_t adc_results[2]; + + h = (struct stlink_usb_handle_s *)handle; + + /* only supported by stlink/v2 and for firmware >= 13 */ + if (h->version.stlink == 1 || h->version.jtag < 13) + return ERROR_COMMAND_NOTFOUND; + + stlink_usb_init_buffer(handle, STLINK_RX_EP, 8); + + h->cmdbuf[h->cmdidx++] = STLINK_GET_TARGET_VOLTAGE; + + int result = stlink_usb_xfer(handle, h->databuf, 8); + + if (result != ERROR_OK) + return result; + + /* convert result */ + adc_results[0] = le_to_h_u32(h->databuf); + adc_results[1] = le_to_h_u32(h->databuf + 4); + + *target_voltage = 0; + + if (adc_results[0]) + *target_voltage = 2 * ((float)adc_results[1]) * (float)(1.2 / adc_results[0]); + + LOG_INFO("Target voltage: %f", (double)*target_voltage); + + return ERROR_OK; +} + /** */ static int stlink_usb_current_mode(void *handle, uint8_t *mode) { @@ -593,17 +628,40 @@ static int stlink_usb_init_mode(void *handle) if (res != ERROR_OK) return res; + /* we check the target voltage here as an aid to debugging connection problems. + * the stlink requires the target Vdd to be connected for reliable debugging. + * this cmd is supported in all modes except DFU + */ + if (mode != STLINK_DEV_DFU_MODE) { + + float target_voltage; + + /* check target voltage (if supported) */ + res = stlink_usb_check_voltage(h, &target_voltage); + + if (res != ERROR_OK) { + if (res != ERROR_COMMAND_NOTFOUND) + LOG_ERROR("voltage check failed"); + /* attempt to continue as it is not a catastrophic failure */ + } else { + /* check for a sensible target voltage, operating range is 1.65-5.5v + * according to datasheet */ + if (target_voltage < 1.5) + LOG_ERROR("target voltage may be too low for reliable debugging"); + } + } + LOG_DEBUG("MODE: 0x%02X", mode); /* set selected mode */ switch (h->transport) { - case STLINK_TRANSPORT_SWD: + case HL_TRANSPORT_SWD: emode = STLINK_MODE_DEBUG_SWD; break; - case STLINK_TRANSPORT_JTAG: + case HL_TRANSPORT_JTAG: emode = STLINK_MODE_DEBUG_JTAG; break; - case STLINK_TRANSPORT_SWIM: + case HL_TRANSPORT_SWIM: emode = STLINK_MODE_DEBUG_SWIM; break; default: @@ -1143,7 +1201,22 @@ static int stlink_usb_write_mem32(void *handle, uint32_t addr, uint16_t len, } /** */ -static int stlink_usb_open(struct stlink_interface_param_s *param, void **fd) +static int stlink_usb_close(void *fd) +{ + struct stlink_usb_handle_s *h; + + h = (struct stlink_usb_handle_s *)fd; + + if (h->fd) + jtag_libusb_close(h->fd); + + free(fd); + + return ERROR_OK; +} + +/** */ +static int stlink_usb_open(struct hl_interface_param_s *param, void **fd) { int err; struct stlink_usb_handle_s *h; @@ -1151,7 +1224,7 @@ static int stlink_usb_open(struct stlink_interface_param_s *param, void **fd) LOG_DEBUG("stlink_usb_open"); - h = malloc(sizeof(struct stlink_usb_handle_s)); + h = calloc(1, sizeof(struct stlink_usb_handle_s)); if (h == 0) { LOG_DEBUG("malloc failed"); @@ -1160,6 +1233,9 @@ static int stlink_usb_open(struct stlink_interface_param_s *param, void **fd) h->transport = param->transport; + /* set max read/write buffer size in bytes */ + param->max_buffer = 512; + const uint16_t vids[] = { param->vid, 0 }; const uint16_t pids[] = { param->pid, 0 }; @@ -1168,14 +1244,14 @@ static int stlink_usb_open(struct stlink_interface_param_s *param, void **fd) if (jtag_libusb_open(vids, pids, &h->fd) != ERROR_OK) { LOG_ERROR("open failed"); - return ERROR_FAIL; + goto error_open; } jtag_libusb_set_configuration(h->fd, 0); if (jtag_libusb_claim_interface(h->fd, 0) != ERROR_OK) { LOG_DEBUG("claim interface failed"); - return ERROR_FAIL; + goto error_open; } /* wrap version for first read */ @@ -1193,9 +1269,7 @@ static int stlink_usb_open(struct stlink_interface_param_s *param, void **fd) if (err != ERROR_OK) { LOG_ERROR("read version failed"); - jtag_libusb_close(h->fd); - free(h); - return err; + goto error_open; } /* compare usb vid/pid */ @@ -1208,12 +1282,12 @@ static int stlink_usb_open(struct stlink_interface_param_s *param, void **fd) err = ERROR_OK; switch (h->transport) { - case STLINK_TRANSPORT_SWD: - case STLINK_TRANSPORT_JTAG: + case HL_TRANSPORT_SWD: + case HL_TRANSPORT_JTAG: if (h->version.jtag == 0) err = ERROR_FAIL; break; - case STLINK_TRANSPORT_SWIM: + case HL_TRANSPORT_SWIM: if (h->version.swim == 0) err = ERROR_FAIL; break; @@ -1224,9 +1298,7 @@ static int stlink_usb_open(struct stlink_interface_param_s *param, void **fd) if (err != ERROR_OK) { LOG_ERROR("mode (transport) not supported by device"); - jtag_libusb_close(h->fd); - free(h); - return err; + goto error_open; } api = h->version.jtag_api_max; @@ -1246,24 +1318,21 @@ static int stlink_usb_open(struct stlink_interface_param_s *param, void **fd) if (err != ERROR_OK) { LOG_ERROR("init mode failed"); - jtag_libusb_close(h->fd); - free(h); - return err; + goto error_open; } *fd = h; return ERROR_OK; -} -/** */ -static int stlink_usb_close(void *fd) -{ - return ERROR_OK; +error_open: + stlink_usb_close(h); + + return ERROR_FAIL; } /** */ -struct stlink_layout_api_s stlink_usb_layout_api = { +struct hl_layout_api_s stlink_usb_layout_api = { /** */ .open = stlink_usb_open, /** */