Skip to content

Commit 13c3351

Browse files
committed
stlink.c: Handle STLINKV3
Thanks to https://github.com/suglover/stlink-tool!
1 parent 9b93305 commit 13c3351

File tree

1 file changed

+62
-26
lines changed

1 file changed

+62
-26
lines changed

src/stlink.c

+62-26
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,48 @@ int stlink_read_info(struct STLinkInfo *info) {
124124
}
125125

126126
info->stlink_version = data[0] >> 4;
127-
info->jtag_version = (data[0] & 0x0F) << 2 | (data[1] & 0xC0) >> 6;
128-
info->swim_version = data[1] & 0x3F;
129-
info->loader_version = data[5] << 8 | data[4];
127+
128+
if (info->stlink_version < 3) {
129+
info->jtag_version = (data[0] & 0x0F) << 2 | (data[1] & 0xC0) >> 6;
130+
info->swim_version = data[1] & 0x3F;
131+
info->loader_version = data[5] << 8 | data[4];
132+
133+
} else {
134+
//info->product_id = data[3] << 8 | data[2];
135+
136+
memset(data, 0, sizeof(data));
137+
138+
data[0] = 0xFB;
139+
data[1] = 0x80;
140+
141+
/* Write */
142+
res = libusb_bulk_transfer(info->stinfo_dev_handle,
143+
info->stinfo_ep_out,
144+
data,
145+
16,
146+
&rw_bytes,
147+
USB_TIMEOUT);
148+
if (res) {
149+
fprintf(stderr, "USB transfer failure\n");
150+
return -1;
151+
}
152+
153+
/* Read */
154+
res = libusb_bulk_transfer(info->stinfo_dev_handle,
155+
info->stinfo_ep_in,
156+
data,
157+
12,
158+
&rw_bytes,
159+
USB_TIMEOUT);
160+
if (res) {
161+
fprintf(stderr, "USB transfer failure\n");
162+
return -1;
163+
}
164+
165+
info->jtag_version = data[2];
166+
info->swim_version = data[1];
167+
info->loader_version = data[11] << 8 | data[10];
168+
}
130169

131170
memset(data, 0, sizeof(data));
132171

@@ -162,8 +201,11 @@ int stlink_read_info(struct STLinkInfo *info) {
162201
/* Firmware encryption key generation */
163202
memcpy(info->firmware_key, data, 4);
164203
memcpy(info->firmware_key+4, data+8, 12);
165-
my_encrypt((unsigned char*)"I am key, wawawa", info->firmware_key, 16);
166-
204+
if (info->stlink_version < 3) {
205+
my_encrypt((unsigned char*)"I am key, wawawa", info->firmware_key, 16);
206+
} else {
207+
my_encrypt((unsigned char*)" found...STlink ", info->firmware_key, 16);
208+
}
167209
return 0;
168210
}
169211

@@ -223,6 +265,10 @@ int stlink_dfu_download(struct STLinkInfo *info,
223265
int rw_bytes, res;
224266
memset(download_request, 0, sizeof(download_request));
225267

268+
if (wBlockNum >= 2 && info->stlink_version == 3) {
269+
my_encrypt((uint8_t*)" .ST-Link.ver.3.", data, data_len);
270+
}
271+
226272
download_request[0] = ST_DFU_MAGIC;
227273
download_request[1] = DFU_DNLOAD;
228274
*(uint16_t*)(download_request+2) = wBlockNum; /* wValue */
@@ -411,30 +457,24 @@ int stlink_flash(struct STLinkInfo *info, const char *filename) {
411457
}
412458
int wdl = 2;
413459
if (info->stinfo_bl_type == STLINK_BL_V3) {
414-
if (((base_offset + flashed_bytes) & ((1 << 14) - 1)) == 0) {
415-
uint32_t sector_start[8] = {0x08000000, 0x08004000, 0x08008000, 0x0800C000,
416-
0x08010000, 0x08020000, 0x08040000, 0x08060000};
417-
int sector = -1;
418-
int i = 0;
419-
for (; i < 8; i++) {
420-
if (sector_start[i] == base_offset + flashed_bytes) {
421-
sector = i;
422-
break;
423-
}
424-
}
425-
if (i < 0) {
426-
fprintf(stderr, "No sector match for address %08x\n", base_offset + flashed_bytes);
427-
return i;
460+
uint32_t address = base_offset + flashed_bytes;
461+
uint32_t sector_start[8] = {0x08000000, 0x08004000, 0x08008000, 0x0800C000,
462+
0x08010000, 0x08020000, 0x08040000, 0x08060000};
463+
int sector;
464+
int i;
465+
for (i = 0; i < 8; i++) {
466+
if (sector_start[i] == address) {
467+
sector = i;
468+
break;
428469
}
429-
printf("Erase sector %d\n", sector);
470+
}
471+
if (i < 8) {
430472
res = stlink_sector_erase(info, sector);
431473
if (res) {
432474
fprintf(stderr, "Erase sector %d failed\n", sector);
433475
return res;
434476
}
435477
printf("Erase sector %d done\n", sector);
436-
} else {
437-
wdl = 3;
438478
}
439479
} else {
440480
res = stlink_erase(info, base_offset + flashed_bytes);
@@ -447,15 +487,11 @@ int stlink_flash(struct STLinkInfo *info, const char *filename) {
447487
if (res) {
448488
fprintf(stderr, "set address error at 0x%08x\n", base_offset + flashed_bytes);
449489
return res;
450-
} else {
451-
printf("set address to 0x%08x done\n", base_offset + flashed_bytes);
452490
}
453491
res = stlink_dfu_download(info, firmware + flashed_bytes, chunk_size, wdl);
454492
if (res) {
455493
fprintf(stderr, "Download error at 0x%08x\n", base_offset + flashed_bytes);
456494
return res;
457-
} else {
458-
printf("Download at 0x%08x done\n", base_offset + flashed_bytes);
459495
}
460496

461497
printf(".");

0 commit comments

Comments
 (0)