Skip to content

Commit d981002

Browse files
committed
Handle Stlink V21 and start handling Stlink v3. Allow to detach BMP.
1 parent a8e5dbb commit d981002

File tree

4 files changed

+321
-157
lines changed

4 files changed

+321
-157
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CFLAGS := -Wall -Wextra -Werror $(shell pkg-config --cflags libusb-1.0)
1+
CFLAGS := -Wall -Wextra -Werror $(shell pkg-config --cflags libusb-1.0) -g -Og
22
LDFLAGS := $(shell pkg-config --libs libusb-1.0)
33

44
OBJS := src/main.o src/stlink.o src/crypto.o tiny-AES-c/aes.o

src/main.c

+127-36
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@
2828

2929
#define STLINK_VID 0x0483
3030
#define STLINK_PID 0x3748
31+
#define STLINK_PIDV21 0x374b
32+
#define STLINK_PIDV21_MSD 0x3752
33+
#define STLINK_PIDV3 0x374f
34+
#define STLINK_PIDV3_BL 0x374d
35+
36+
#define OPENMOKO_VID 0x1d50
37+
#define BMP_APPL_PID 0x6018
38+
#define BMP_DFU_IF 4
3139

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

48+
#include <string.h>
4049
int main(int argc, char *argv[]) {
41-
libusb_context *usb_ctx;
42-
libusb_device_handle *dev_handle;
43-
struct STLinkInfos infos;
44-
int res, i, opt, probe = 0;
50+
struct STLinkInfo info;
51+
int res = EXIT_FAILURE, i, opt, probe = 0;
4552

4653
while ((opt = getopt(argc, argv, "hp")) != -1) {
4754
switch (opt) {
@@ -61,63 +68,147 @@ int main(int argc, char *argv[]) {
6168

6269
int do_load = (optind < argc);
6370

64-
res = libusb_init(&usb_ctx);
65-
(void)res;
66-
67-
dev_handle = libusb_open_device_with_vid_pid(usb_ctx,
68-
STLINK_VID,
69-
STLINK_PID);
70-
if (!dev_handle) {
71-
fprintf(stderr, "No ST-Link in DFU mode found. Replug ST-Link to flash!\n");
72-
return EXIT_FAILURE;
73-
}
71+
res = libusb_init(&info.stinfo_usb_ctx);
72+
rescan:
73+
info.stinfo_dev_handle = NULL;
74+
libusb_device **devs;
75+
int n_devs = libusb_get_device_list(info.stinfo_usb_ctx, &devs);
76+
if (n_devs < 0)
77+
goto exit_libusb;
78+
for (int i = 0; devs[i]; i++) {
79+
libusb_device *dev = devs[i];
80+
struct libusb_device_descriptor desc;
81+
int res = libusb_get_device_descriptor(dev, &desc);
82+
if (res < 0)
83+
continue;
84+
if ((desc.idVendor == OPENMOKO_VID) && (desc.idProduct == BMP_APPL_PID)) {
85+
res = libusb_open(dev, &info.stinfo_dev_handle);
86+
if (res < 0) {
87+
fprintf(stderr, "Can not open BMP/Application!\n");
88+
continue;
89+
}
90+
libusb_claim_interface(info.stinfo_dev_handle, BMP_DFU_IF);
91+
res = libusb_control_transfer(
92+
info.stinfo_dev_handle,
93+
/* bmRequestType */ LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE,
94+
/* bRequest */ 0, /*DFU_DETACH,*/
95+
/* wValue */ 1000,
96+
/* wIndex */ BMP_DFU_IF,
97+
/* Data */ NULL,
98+
/* wLength */ 0,
99+
5000 );
100+
libusb_release_interface(info.stinfo_dev_handle, 0);
101+
if (res < 0) {
102+
fprintf(stderr, "BMP Switch failed\n");
103+
continue;
104+
}
105+
libusb_free_device_list(devs, 1);
106+
usleep(2000000);
107+
goto rescan;
108+
break;
109+
}
110+
if (desc.idVendor != STLINK_VID)
111+
continue;
112+
switch (desc.idProduct) {
113+
case STLINK_PID:
114+
res = libusb_open(dev, &info.stinfo_dev_handle);
115+
if (res < 0) {
116+
fprintf(stderr, "Can not open STLINK/Bootloader!\n");
117+
continue;
118+
}
119+
info.stinfo_ep_in = 1 | LIBUSB_ENDPOINT_IN;
120+
info.stinfo_ep_out = 2 | LIBUSB_ENDPOINT_OUT;
121+
info.stinfo_bl_type = STLINK_BL_V2;
122+
fprintf(stderr, "StlinkV21 Bootloader found\n");
123+
break;
124+
case STLINK_PIDV3_BL:
125+
res = libusb_open(dev, &info.stinfo_dev_handle);
126+
if (res < 0) {
127+
fprintf(stderr, "Can not open STLINK-V3/Bootloader!\n");
128+
continue;
129+
}
130+
info.stinfo_ep_in = 1 | LIBUSB_ENDPOINT_IN;
131+
info.stinfo_ep_out = 1 | LIBUSB_ENDPOINT_OUT;
132+
info.stinfo_bl_type = STLINK_BL_V3;
133+
fprintf(stderr, "StlinkV3 Bootloader found\n");
134+
break;
135+
case STLINK_PIDV21:
136+
case STLINK_PIDV21_MSD:
137+
case STLINK_PIDV3:
138+
res = libusb_open(dev, &info.stinfo_dev_handle);
139+
if (res < 0) {
140+
fprintf(stderr, "Can not open STLINK/Application!\n");
141+
continue;
142+
}
143+
res = stlink_dfu_mode(info.stinfo_dev_handle, 0);
144+
if (res != 0x8000) {
145+
libusb_release_interface(info.stinfo_dev_handle, 0);
146+
return 0;
147+
}
148+
stlink_dfu_mode(info.stinfo_dev_handle, 1);
149+
libusb_release_interface(info.stinfo_dev_handle, 0);
150+
libusb_free_device_list(devs, 1);
151+
fprintf(stderr, "Trying to switch STLINK/Application to bootloader\n");
152+
usleep(2000000);
153+
goto rescan;
154+
break;
155+
}
156+
if (info.stinfo_dev_handle)
157+
break;}
158+
libusb_free_device_list(devs, 1);
159+
if (!info.stinfo_dev_handle) {
160+
fprintf(stderr, "No ST-Link in DFU mode found. Replug ST-Link to flash!\n");
161+
return EXIT_FAILURE;
162+
}
74163

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

80-
if (stlink_read_infos(dev_handle, &infos)) {
81-
libusb_release_interface(dev_handle, 0);
170+
if (stlink_read_info(&info)) {
171+
libusb_release_interface(info.stinfo_dev_handle, 0);
82172
return EXIT_FAILURE;
83173
}
84-
85-
printf("Firmware version : V%dJ%dS%d\n", infos.stlink_version,
86-
infos.jtag_version, infos.swim_version);
87-
printf("Loader version : %d\n", infos.loader_version);
174+
printf("Firmware version : V%dJ%dS%d\n", info.stlink_version,
175+
info.jtag_version, info.swim_version);
176+
printf("Loader version : %d\n", info.loader_version);
88177
printf("ST-Link ID : ");
89-
for (i = 0; i < 12; i++) {
90-
printf("%02X", infos.id[i]);
178+
for (i = 0; i < 12; i += 4) {
179+
printf("%02X", info.id[i + 3]);
180+
printf("%02X", info.id[i + 2]);
181+
printf("%02X", info.id[i + 1]);
182+
printf("%02X", info.id[i + 0]);
91183
}
92184
printf("\n");
93185
printf("Firmware encryption key : ");
94186
for (i = 0; i < 16; i++) {
95-
printf("%02X", infos.firmware_key[i]);
187+
printf("%02X", info.firmware_key[i]);
96188
}
97189
printf("\n");
98190

99-
res = stlink_current_mode(dev_handle);
191+
res = stlink_current_mode(&info);
100192
if (res < 0) {
101-
libusb_release_interface(dev_handle, 0);
193+
libusb_release_interface(info.stinfo_dev_handle, 0);
102194
return EXIT_FAILURE;
103195
}
104196
printf("Current mode : %d\n", res);
105197

106-
if (res != 1) {
198+
if (res & 0xfffc) {
107199
printf("ST-Link dongle is not in the correct mode. Please unplug and plug the dongle again.\n");
108-
libusb_release_interface(dev_handle, 0);
200+
libusb_release_interface(info.stinfo_dev_handle, 0);
109201
return EXIT_SUCCESS;
110202
}
111203

112204
if (!probe) {
113-
if (do_load) {
114-
stlink_flash(dev_handle, argv[optind], 0x8004000, 1024, &infos);
205+
if (do_load)
206+
stlink_flash(&info, argv[optind]);
207+
stlink_exit_dfu(&info);
115208
}
116-
stlink_exit_dfu(dev_handle);
117-
}
118-
119-
libusb_release_interface(dev_handle, 0);
120-
libusb_exit(usb_ctx);
209+
libusb_release_interface(info.stinfo_dev_handle, 0);
210+
exit_libusb:
211+
libusb_exit(info.stinfo_usb_ctx);
121212

122213
return EXIT_SUCCESS;
123214
}

0 commit comments

Comments
 (0)