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

Handle Stlink V21. #11

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
CFLAGS := -Wall -Wextra -Werror $(shell pkg-config --cflags libusb-1.0)
ifeq ($(ASAN), 1)
CFLAGS += -fsanitize=address -Wno-format-truncation
LDFLAGS += -lasan
endif

CFLAGS := -Wall -Wextra -Werror $(shell pkg-config --cflags libusb-1.0) -g -Og
LDFLAGS := $(shell pkg-config --libs libusb-1.0)

OBJS := src/main.o src/stlink.o src/crypto.o tiny-AES-c/aes.o
Expand Down
181 changes: 144 additions & 37 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@

#define STLINK_VID 0x0483
#define STLINK_PID 0x3748
#define STLINK_PIDV21 0x374b
#define STLINK_PIDV21_MSD 0x3752
#define STLINK_V3EC 0x3754
#define STLINK_PIDV3_MSD 0x374e
#define STLINK_PIDV3 0x374f
#define STLINK_PIDV3_BL 0x374d

#define OPENMOKO_VID 0x1d50
#define BMP_APPL_PID 0x6018
#define BMP_DFU_IF 4

void print_help(char *argv[]) {
printf("Usage: %s [options] [firmware.bin]\n", argv[0]);
Expand All @@ -37,11 +47,10 @@ void print_help(char *argv[]) {
printf("\tApplication is started when called without argument or after firmware load\n\n");
}

#include <string.h>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Header should be at the beginning of the file

int main(int argc, char *argv[]) {
libusb_context *usb_ctx;
libusb_device_handle *dev_handle;
struct STLinkInfos infos;
int res, i, opt, probe = 0;
struct STLinkInfo info;
int res = EXIT_FAILURE, i, opt, probe = 0;

while ((opt = getopt(argc, argv, "hp")) != -1) {
switch (opt) {
Expand All @@ -61,63 +70,161 @@ int main(int argc, char *argv[]) {

int do_load = (optind < argc);

res = libusb_init(&usb_ctx);
(void)res;

dev_handle = libusb_open_device_with_vid_pid(usb_ctx,
STLINK_VID,
STLINK_PID);
if (!dev_handle) {
fprintf(stderr, "No ST-Link in DFU mode found. Replug ST-Link to flash!\n");
return EXIT_FAILURE;
}
res = libusb_init(&info.stinfo_usb_ctx);
rescan:
info.stinfo_dev_handle = NULL;
libusb_device **devs;
int n_devs = libusb_get_device_list(info.stinfo_usb_ctx, &devs);
if (n_devs < 0)
goto exit_libusb;
for (int i = 0; devs[i]; i++) {
libusb_device *dev = devs[i];
struct libusb_device_descriptor desc;
int res = libusb_get_device_descriptor(dev, &desc);
if (res < 0)
continue;
if ((desc.idVendor == OPENMOKO_VID) && (desc.idProduct == BMP_APPL_PID)) {
fprintf(stderr, "Trying to switch BMP/Application to bootloader\n");
res = libusb_open(dev, &info.stinfo_dev_handle);
if (res < 0) {
fprintf(stderr, "Can not open BMP/Application!\n");
continue;
}
libusb_claim_interface(info.stinfo_dev_handle, BMP_DFU_IF);
res = libusb_control_transfer(
info.stinfo_dev_handle,
/* bmRequestType */ LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE,
/* bRequest */ 0, /*DFU_DETACH,*/
/* wValue */ 1000,
/* wIndex */ BMP_DFU_IF,
/* Data */ NULL,
/* wLength */ 0,
5000 );
libusb_release_interface(info.stinfo_dev_handle, 0);
if (res < 0) {
fprintf(stderr, "BMP Switch failed\n");
continue;
}
libusb_free_device_list(devs, 1);
usleep(2000000);
goto rescan;
break;
}
if (desc.idVendor != STLINK_VID)
continue;
switch (desc.idProduct) {
case STLINK_PID:
res = libusb_open(dev, &info.stinfo_dev_handle);
if (res < 0) {
fprintf(stderr, "Can not open STLINK/Bootloader!\n");
continue;
}
info.stinfo_ep_in = 1 | LIBUSB_ENDPOINT_IN;
info.stinfo_ep_out = 2 | LIBUSB_ENDPOINT_OUT;
info.stinfo_bl_type = STLINK_BL_V2;
fprintf(stderr, "StlinkV21 Bootloader found\n");
break;
case STLINK_PIDV3_BL:
res = libusb_open(dev, &info.stinfo_dev_handle);
if (res < 0) {
fprintf(stderr, "Can not open STLINK-V3/Bootloader!\n");
continue;
}
info.stinfo_ep_in = 1 | LIBUSB_ENDPOINT_IN;
info.stinfo_ep_out = 1 | LIBUSB_ENDPOINT_OUT;
info.stinfo_bl_type = STLINK_BL_V3;
fprintf(stderr, "StlinkV3 Bootloader found\n");
break;
case STLINK_PIDV21:
case STLINK_V3EC:
case STLINK_PIDV21_MSD:
case STLINK_PIDV3_MSD:
case STLINK_PIDV3:
fprintf(stderr,
"Trying to switch STLINK/Application to bootloader\n");
res = libusb_open(dev, &info.stinfo_dev_handle);
if (res < 0) {
fprintf(stderr, "Can not open STLINK/Application!\n");
continue;
}
if (libusb_claim_interface(info.stinfo_dev_handle, 0)) {
fprintf(stderr,"Unable to claim USB interface ! "
"Please close all programs that "
"may communicate with an ST-Link dongle.\n");
continue;
}
res = stlink_dfu_mode(info.stinfo_dev_handle, 0);
if (res != 0x8000) {
libusb_release_interface(info.stinfo_dev_handle, 0);
return 0;
}
stlink_dfu_mode(info.stinfo_dev_handle, 1);
libusb_release_interface(info.stinfo_dev_handle, 0);
libusb_free_device_list(devs, 1);
usleep(2000000);
goto rescan;
break;
default:
fprintf(stderr, "Unknown STM PID %x, please report\n",
desc.idProduct);
}
if (info.stinfo_dev_handle)
break;}
libusb_free_device_list(devs, 1);
if (!info.stinfo_dev_handle) {
fprintf(stderr, "No ST-Link in DFU mode found. Replug ST-Link to flash!\n");
return EXIT_FAILURE;
}

if (libusb_claim_interface(dev_handle, 0)) {
fprintf(stderr, "Unable to claim USB interface ! Please close all programs that may communicate with an ST-Link dongle.\n");
if (libusb_claim_interface(info.stinfo_dev_handle, 0)) {
fprintf(stderr, "Unable to claim USB interface ! Please close all programs that "
"may communicate with an ST-Link dongle.\n");
return EXIT_FAILURE;
}

if (stlink_read_infos(dev_handle, &infos)) {
libusb_release_interface(dev_handle, 0);
if (stlink_read_info(&info)) {
libusb_release_interface(info.stinfo_dev_handle, 0);
return EXIT_FAILURE;
}

printf("Firmware version : V%dJ%dS%d\n", infos.stlink_version,
infos.jtag_version, infos.swim_version);
printf("Loader version : %d\n", infos.loader_version);
printf("Firmware version : V%dJ%dS%d\n", info.stlink_version,
info.jtag_version, info.swim_version);
printf("Loader version : %d\n", info.loader_version);
printf("ST-Link ID : ");
for (i = 0; i < 12; i++) {
printf("%02X", infos.id[i]);
for (i = 0; i < 12; i += 4) {
printf("%02X", info.id[i + 3]);
printf("%02X", info.id[i + 2]);
printf("%02X", info.id[i + 1]);
printf("%02X", info.id[i + 0]);
}
printf("\n");
printf("Firmware encryption key : ");
for (i = 0; i < 16; i++) {
printf("%02X", infos.firmware_key[i]);
printf("%02X", info.firmware_key[i]);
}
printf("\n");

res = stlink_current_mode(dev_handle);
res = stlink_current_mode(&info);
if (res < 0) {
libusb_release_interface(dev_handle, 0);
libusb_release_interface(info.stinfo_dev_handle, 0);
return EXIT_FAILURE;
}
printf("Current mode : %d\n", res);

if (res != 1) {
printf("ST-Link dongle is not in the correct mode. Please unplug and plug the dongle again.\n");
libusb_release_interface(dev_handle, 0);
if (res & 0xfffc) {
UweBonnes marked this conversation as resolved.
Show resolved Hide resolved
printf("ST-Link dongle has crypto bootloader. Restarting ST application.\n");
stlink_exit_dfu(&info);
libusb_release_interface(info.stinfo_dev_handle, 0);
return EXIT_SUCCESS;
}

if (!probe) {
if (do_load) {
stlink_flash(dev_handle, argv[optind], 0x8004000, 1024, &infos);
if (do_load)
stlink_flash(&info, argv[optind]);
stlink_exit_dfu(&info);
}
stlink_exit_dfu(dev_handle);
}

libusb_release_interface(dev_handle, 0);
libusb_exit(usb_ctx);
libusb_release_interface(info.stinfo_dev_handle, 0);
exit_libusb:
libusb_exit(info.stinfo_usb_ctx);

return EXIT_SUCCESS;
}
Loading