Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic compatibility for STLink-v3 programmer #954

Merged
merged 8 commits into from
May 17, 2020
1 change: 0 additions & 1 deletion include/stlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ enum target_state {
#define STLINK_F_HAS_RW8_512BYTES (1<<9)


/* Enough space to hold both a V2 command or a V1 command packaged as generic scsi*/
#define C_BUF_LEN 32

enum stlink_flash_type {
Expand Down
3 changes: 2 additions & 1 deletion include/stlink/tools/flash.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
#include <stlink.h>

#define DEBUG_LOG_LEVEL 100
#define STND_LOG_LEVEL 100
#define STND_LOG_LEVEL 50
#define ENABLE_OPT 1

enum flash_cmd {FLASH_CMD_NONE = 0, FLASH_CMD_WRITE = 1, FLASH_CMD_READ = 2, FLASH_CMD_ERASE = 3, CMD_RESET = 4};
enum flash_format {FLASH_FORMAT_BINARY = 0, FLASH_FORMAT_IHEX = 1};
Expand Down
35 changes: 27 additions & 8 deletions include/stlink/usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,33 @@ extern "C" {
#endif

#define STLINK_USB_VID_ST 0x0483
#define STLINK_USB_PID_STLINK 0x3744
#define STLINK_USB_PID_STLINK_32L 0x3748
#define STLINK_USB_PID_STLINK_32L_AUDIO 0x374a
#define STLINK_USB_PID_STLINK_NUCLEO 0x374b
#define STLINK_USB_PID_STLINK_V3_USBLOADER 0x374d
#define STLINK_USB_PID_STLINK_V3E_PID 0x374e
#define STLINK_USB_PID_STLINK_V3S_PID 0x374f
#define STLINK_USB_PID_STLINK_V3_2VCP_PID 0x3753
#define STLINK_USB_PID_STLINK 0x3744
#define STLINK_USB_PID_STLINK_32L 0x3748
#define STLINK_USB_PID_STLINK_32L_AUDIO 0x374a
#define STLINK_USB_PID_STLINK_NUCLEO 0x374b
#define STLINK_USB_PID_STLINK_V2_1 0x3752
#define STLINK_USB_PID_STLINK_V3_USBLOADER 0x374d
#define STLINK_USB_PID_STLINK_V3E_PID 0x374e
#define STLINK_USB_PID_STLINK_V3S_PID 0x374f
#define STLINK_USB_PID_STLINK_V3_2VCP_PID 0x3753

#define STLINK_V1_USB_PID(pid) ((pid) == STLINK_USB_PID_STLINK )

#define STLINK_V2_USB_PID(pid) ((pid) == STLINK_USB_PID_STLINK_32L || \
(pid) == STLINK_USB_PID_STLINK_32L_AUDIO || \
(pid) == STLINK_USB_PID_STLINK_NUCLEO)

#define STLINK_V2_1_USB_PID(pid) ( (pid) == STLINK_USB_PID_STLINK_V2_1 )

#define STLINK_V3_USB_PID(pid) ((pid) == STLINK_USB_PID_STLINK_V3_USBLOADER || \
(pid) == STLINK_USB_PID_STLINK_V3E_PID || \
(pid) == STLINK_USB_PID_STLINK_V3S_PID || \
(pid) == STLINK_USB_PID_STLINK_V3_2VCP_PID )

#define STLINK_SUPPORTED_USB_PID(pid) ( STLINK_V1_USB_PID(pid) || \
STLINK_V2_USB_PID(pid) || \
STLINK_V2_1_USB_PID(pid) || \
STLINK_V3_USB_PID(pid))

#define STLINK_SG_SIZE 31
#define STLINK_CMD_SIZE 16
Expand Down
3 changes: 1 addition & 2 deletions src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -992,8 +992,7 @@ int stlink_status(stlink_t *sl) {
* @param sl stlink context, assumed to contain valid data in the buffer
* @param slv output parsed version object
*/
void _parse_version(stlink_t *sl, stlink_version_t *slv)
{
void _parse_version(stlink_t *sl, stlink_version_t *slv) {
sl->version.flags = 0;
if (sl->version.stlink_v < 3) {
uint32_t b0 = sl->q_buf[0]; //lsb
Expand Down
5 changes: 4 additions & 1 deletion src/gdbserver/gdb-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -1439,7 +1439,10 @@ int serve(stlink_t *sl, st_state_t *st) {
break;
}

stlink_status(sl);
ret = stlink_status(sl);
if (ret) {
DLOG("Semihost: status failed\n");
}
if(sl->core_stat == TARGET_HALTED) {
struct stlink_reg reg;
stm32_addr_t pc;
Expand Down
16 changes: 7 additions & 9 deletions src/tools/flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,13 @@ static void cleanup(int signum) {

static void usage(void)
{
puts("stlinkv1 command line: ./st-flash [--debug] [--reset] [--format <format>] [--flash=<fsize>] {read|write} /dev/sgX <path> <addr> <size>");
puts("stlinkv1 command line: ./st-flash [--debug] /dev/sgX erase");
puts("stlinkv2/3 command line: ./st-flash [--debug] [--reset] [--serial <serial>] [--format <format>] [--flash=<fsize>] {read|write} <path> <addr> <size>");
puts("stlinkv2/3 command line: ./st-flash [--debug] [--serial <serial>] erase");
puts("stlinkv2/3 command line: ./st-flash [--debug] [--serial <serial>] reset");
puts(" Use hex format for addr, <serial> and <size>.");
puts(" fsize: Use decimal, octal or hex by prefix 0xXXX for hex, optionally followed by k=KB, or m=MB (eg. --flash=128k)");
puts(" Format may be 'binary' (default) or 'ihex', although <addr> must be specified for binary format only.");
puts(" ./st-flash [--version]");
puts("command line: ./st-flash [--debug] [--reset] [--opt] [--serial <serial>] [--format <format>] [--flash=<fsize>] {read|write} <path> [addr] [size]");
puts("command line: ./st-flash [--debug] [--serial <serial>] erase");
puts("command line: ./st-flash [--debug] [--serial <serial>] reset");
puts(" <addr>, <serial> and <size>: Use hex format.");
puts(" <fsize>: Use decimal, octal or hex (prefix 0xXXX) format, optionally followed by k=KB, or m=MB (eg. --flash=128k)");
puts(" <format>: Can be 'binary' (default) or 'ihex', although <addr> must be specified for binary format only.");
puts("print tool version info: ./st-flash [--version]");
puts("example write option byte: ./st-flash --debug --reset --area=option write 0xXXXXXXXX");
puts("example read option byte: ./st-flash --debug --reset --area=option read > option_byte");
}
Expand Down
146 changes: 67 additions & 79 deletions src/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,34 +29,34 @@ static int _stlink_match_speed_map(const uint32_t *map, unsigned int map_size, u
bool match = true;

for (i = 0; i < map_size; i++) {
if (!map[i])
continue;
last_valid_speed = i;
if (khz == map[i]) {
speed_index = i;
break;
} else {
int current_diff = khz - map[i];
/* get abs value for comparison */
current_diff = (current_diff > 0) ? current_diff : -current_diff;
if ((current_diff < speed_diff) && khz >= map[i]) {
speed_diff = current_diff;
speed_index = i;
}
}
if (!map[i])
continue;
last_valid_speed = i;
if (khz == map[i]) {
speed_index = i;
break;
} else {
int current_diff = khz - map[i];
/* get abs value for comparison */
current_diff = (current_diff > 0) ? current_diff : -current_diff;
if ((current_diff < speed_diff) && khz >= map[i]) {
speed_diff = current_diff;
speed_index = i;
}
}
}

if (speed_index == -1) {
/* this will only be here if we cannot match the slow speed.
* use the slowest speed we support.*/
speed_index = last_valid_speed;
match = false;
/* this will only be here if we cannot match the slow speed.
* use the slowest speed we support.*/
speed_index = last_valid_speed;
match = false;
} else if (i == map_size)
match = false;
match = false;

if (!match) {
ILOG("Unable to match requested speed %d kHz, using %d kHz\n", \
khz, map[speed_index]);
ILOG("Unable to match requested speed %d kHz, using %d kHz\n", \
khz, map[speed_index]);
}

return speed_index;
Expand Down Expand Up @@ -182,7 +182,7 @@ int _stlink_usb_version(stlink_t *sl) {
cmd[i++] = STLINK_APIV3_GET_VERSION_EX;

size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len);
if (size != rep_len) {
if (size != (ssize_t)rep_len) {
printf("[!] send_recv STLINK_APIV3_GET_VERSION_EX\n");
return (int) size;
}
Expand Down Expand Up @@ -1025,50 +1025,44 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST
}
}

if ((desc.idProduct == STLINK_USB_PID_STLINK_32L)
|| (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO)
|| (desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO)
|| (desc.idProduct == STLINK_USB_PID_STLINK_V3_USBLOADER)
|| (desc.idProduct == STLINK_USB_PID_STLINK_V3E_PID)
|| (desc.idProduct == STLINK_USB_PID_STLINK_V3S_PID)
|| (desc.idProduct == STLINK_USB_PID_STLINK_V3_2VCP_PID)) {
struct libusb_device_handle *handle;

ret = libusb_open(list[cnt], &handle);
if (ret)
continue;
ret = libusb_open(list[cnt], &handle);

/* could not open device, continue */
if (ret)
continue;


sl->serial_size = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber,
(unsigned char *)sl->serial, sizeof(sl->serial));

if ((desc.idProduct == STLINK_USB_PID_STLINK_32L)
|| (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO)
|| (desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO)) {
sl->version.stlink_v = 2;
} else if ((desc.idProduct == STLINK_USB_PID_STLINK_V3_USBLOADER)
|| (desc.idProduct == STLINK_USB_PID_STLINK_V3E_PID)
|| (desc.idProduct == STLINK_USB_PID_STLINK_V3S_PID)
|| (desc.idProduct == STLINK_USB_PID_STLINK_V3_2VCP_PID)) {
sl->version.stlink_v = 3;
}
if ((serial == NULL) || (*serial == 0))
break;

if ((serial == NULL) || (*serial == 0))
break;
if (sl->serial_size < 0)
continue;

if (sl->serial_size < 0)
continue;
if (memcmp(serial, &sl->serial, sl->serial_size) == 0)
break;

if (memcmp(serial, &sl->serial, sl->serial_size) == 0)
break;
libusb_close(handle);
chenguokai marked this conversation as resolved.
Show resolved Hide resolved

continue;
}
/* could not read serial, continue */
if (sl->serial_size < 0)
continue;

if (desc.idProduct == STLINK_USB_PID_STLINK) {
slu->protocoll = 1;
sl->version.stlink_v = 1;
break;
}
/* if no serial provided, or if serial match device, fixup version and protocol */
if (((serial == NULL) || (*serial == 0)) || (memcmp(serial, &sl->serial, sl->serial_size) == 0)) {
if (STLINK_V1_USB_PID(desc.idProduct)) {
slu->protocoll = 1;
sl->version.stlink_v = 1;
} else if (STLINK_V2_USB_PID(desc.idProduct) || STLINK_V2_1_USB_PID(desc.idProduct)) {
sl->version.stlink_v = 2;
} else if (STLINK_V3_USB_PID(desc.idProduct)) {
sl->version.stlink_v = 3;
}

break;
}
}

if (cnt < 0) {
Expand Down Expand Up @@ -1116,12 +1110,13 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST

// TODO - could use the scanning techniq from stm8 code here...
slu->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN;
if (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO
|| desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO
|| desc.idProduct == STLINK_USB_PID_STLINK_V3_USBLOADER
|| desc.idProduct == STLINK_USB_PID_STLINK_V3E_PID
|| desc.idProduct == STLINK_USB_PID_STLINK_V3S_PID
|| desc.idProduct == STLINK_USB_PID_STLINK_V3_2VCP_PID) {
if (desc.idProduct == STLINK_USB_PID_STLINK_NUCLEO ||
desc.idProduct == STLINK_USB_PID_STLINK_32L_AUDIO ||
desc.idProduct == STLINK_USB_PID_STLINK_V2_1 ||
desc.idProduct == STLINK_USB_PID_STLINK_V3_USBLOADER ||
desc.idProduct == STLINK_USB_PID_STLINK_V3E_PID ||
desc.idProduct == STLINK_USB_PID_STLINK_V3S_PID ||
desc.idProduct == STLINK_USB_PID_STLINK_V3_2VCP_PID) {
slu->ep_req = 1 /* ep req */ | LIBUSB_ENDPOINT_OUT;
} else {
slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT;
Expand Down Expand Up @@ -1196,15 +1191,13 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) {
break;
}

if (desc.idProduct != STLINK_USB_PID_STLINK_32L
&& desc.idProduct != STLINK_USB_PID_STLINK_32L_AUDIO
&& desc.idProduct != STLINK_USB_PID_STLINK_NUCLEO
&& desc.idProduct != STLINK_USB_PID_STLINK_V3_USBLOADER
&& desc.idProduct != STLINK_USB_PID_STLINK_V3E_PID
&& desc.idProduct != STLINK_USB_PID_STLINK_V3S_PID
&& desc.idProduct != STLINK_USB_PID_STLINK_V3_2VCP_PID)
continue;
if (desc.idVendor != STLINK_USB_VID_ST)
continue;

if (!STLINK_SUPPORTED_USB_PID(desc.idProduct)) {
WLOG("skipping ST device : %#04x:%#04x)\n", desc.idVendor, desc.idProduct);
continue;
}
slcnt++;
}

Expand All @@ -1225,9 +1218,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) {
break;
}

if (desc.idProduct != STLINK_USB_PID_STLINK_32L &&
desc.idProduct != STLINK_USB_PID_STLINK_32L_AUDIO &&
desc.idProduct != STLINK_USB_PID_STLINK_NUCLEO)
if (!STLINK_SUPPORTED_USB_PID(desc.idProduct)) {
continue;
}

Expand All @@ -1243,10 +1234,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) {
}
break;
}

ret = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)&serial, sizeof(serial));
if (ret < 0)
*serial = 0;
ret = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, (unsigned char *)&serial, sizeof(serial));

libusb_close(handle);

Expand Down
You are viewing a condensed version of this merge commit. You can view the full changes here.