From e11b077da3aba4470f0a66815d262100e2ff630c Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Thu, 7 May 2020 18:16:07 +0800 Subject: [PATCH 1/4] Fix https://github.com/stlink-org/stlink/issues/893 * Add --freq argument for st-flash --- include/stlink.h | 2 ++ include/stlink/tools/flash.h | 3 +- src/st-util/gdb-server.c | 4 +-- src/stlink-gui/gui.c | 2 +- src/tools/flash.c | 8 +++--- src/tools/flash_opts.c | 50 +++++++++++++++++++++++++++++++++ src/tools/info.c | 2 +- src/usb.c | 47 +++++++++++++++++++++++++++++-- src/usb.h | 2 +- tests/flash.c | 54 ++++++++++++++++++++++++++++++++++++ tests/usb.c | 2 +- 11 files changed, 162 insertions(+), 14 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index 74c366d..ffa65b3 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -159,6 +159,8 @@ typedef struct flash_loader { char serial[STLINK_SERIAL_MAX_SIZE]; int serial_size; + int freq; // set by stlink_open_usb(), values: STLINK_SWDCLK_xxx_DIVISOR + enum stlink_flash_type flash_type; // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STLINK_FLASH_TYPE_xxx bool has_dual_bank; diff --git a/include/stlink/tools/flash.h b/include/stlink/tools/flash.h index 8c3f7d7..b8954af 100644 --- a/include/stlink/tools/flash.h +++ b/include/stlink/tools/flash.h @@ -26,9 +26,10 @@ struct flash_opts uint32_t val; size_t flash_size; /* --flash=n[k][m] */ int opt; + int freq; }; -#define FLASH_OPTS_INITIALIZER {0, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0} +#define FLASH_OPTS_INITIALIZER {0, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} int flash_get_opts(struct flash_opts* o, int ac, char** av); diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index a3839cf..2095482 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -87,9 +87,9 @@ static void cleanup(int signum) { static stlink_t* do_connect(st_state_t *st) { stlink_t *sl = NULL; if (serial_specified) { - sl = stlink_open_usb(st->logging_level, st->reset, serialnumber); + sl = stlink_open_usb(st->logging_level, st->reset, serialnumber, 0); } else { - sl = stlink_open_usb(st->logging_level, st->reset, NULL); + sl = stlink_open_usb(st->logging_level, st->reset, NULL, 0); } return sl; } diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index 5d5a422..6e9d59b 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -490,7 +490,7 @@ static void connect_button_cb (GtkWidget *widget, gpointer data) { /* try version 1 then version 2 */ gui->sl = stlink_v1_open(0, 1); if (gui->sl == NULL) - gui->sl = stlink_open_usb(0, 1, NULL); + gui->sl = stlink_open_usb(0, 1, NULL, 0); if (gui->sl == NULL) { stlink_gui_set_info_error_message (gui, "Failed to connect to STLink."); return; diff --git a/src/tools/flash.c b/src/tools/flash.c index 841b93c..3a83daf 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -28,9 +28,9 @@ static void cleanup(int signum) { static void usage(void) { - puts("command line: ./st-flash [--debug] [--reset] [--opt] [--serial ] [--format ] [--flash=] {read|write} [addr] [size]"); - puts("command line: ./st-flash [--debug] [--serial ] erase"); - puts("command line: ./st-flash [--debug] [--serial ] reset"); + puts("command line: ./st-flash [--debug] [--reset] [--opt] [--serial ] [--format ] [--flash=] [--freq=] {read|write} [addr] [size]"); + puts("command line: ./st-flash [--debug] [--freq=] [--serial ] erase"); + puts("command line: ./st-flash [--debug] [--freq=] [--serial ] reset"); puts(" , and : Use hex format."); puts(" : Use decimal, octal or hex (prefix 0xXXX) format, optionally followed by k=KB, or m=MB (eg. --flash=128k)"); puts(" : Can be 'binary' (default) or 'ihex', although must be specified for binary format only."); @@ -56,7 +56,7 @@ int main(int ac, char** av) printf("st-flash %s\n", STLINK_VERSION); - sl = stlink_open_usb(o.log_level, 1, (char *)o.serial); + sl = stlink_open_usb(o.log_level, 1, (char *)o.serial, o.freq); if (sl == NULL) { return -1; diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index 044527a..a5c9d28 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -149,6 +149,56 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { return -1; } + else if (strcmp(av[0], "--freq") == 0 || starts_with(av[0], "--freq=")) { + const char* freq; + if (strcmp(av[0], "--freq") == 0) { + ac--; + av++; + if (ac < 1) return -1; + freq = av[0]; + } + else { + freq = av[0] + strlen("--freq="); + } + if (strcmp(freq, "5K") == 0 || strcmp(freq, "5k") == 0) { + o->freq = 5; + } + else if (strcmp(freq, "15K") == 0 || strcmp(freq, "15k") == 0) { + o->freq = 15; + } + else if (strcmp(freq, "25K") == 0 || strcmp(freq, "25k") == 0) { + o->freq = 25; + } + else if (strcmp(freq, "50K") == 0 || strcmp(freq, "50k") == 0) { + o->freq = 50; + } + else if (strcmp(freq, "100K") == 0 || strcmp(freq, "100k") == 0) { + o->freq = 100; + } + else if (strcmp(freq, "125K") == 0 || strcmp(freq, "125k") == 0) { + o->freq = 125; + } + else if (strcmp(freq, "240K") == 0 || strcmp(freq, "240k") == 0) { + o->freq = 240; + } + else if (strcmp(freq, "480K") == 0 || strcmp(freq, "480k") == 0) { + o->freq = 480; + } + else if (strcmp(freq, "950K") == 0 || strcmp(freq, "950k") == 0) { + o->freq = 950; + } + else if (strcmp(freq, "1200K") == 0 || strcmp(freq, "1200k") == 0 || strcmp(freq, "1.2M") == 0 || strcmp(freq, "1.2m") == 0) { + o->freq = 1200; + } + else if (strcmp(freq, "1800K") == 0 || strcmp(freq, "1800k") == 0 || strcmp(freq, "1.8M") == 0 || strcmp(freq, "1.8m") == 0) { + o->freq = 1800; + } + else if (strcmp(freq, "4000K") == 0 || strcmp(freq, "4000k") == 0 || strcmp(freq, "4M") == 0 || strcmp(freq, "4m") == 0) { + o->freq = 4000; + } + else + return -1; + } else if (strcmp(av[0], "--format") == 0 || starts_with(av[0], "--format=")) { const char * format; if (strcmp(av[0], "--format") == 0) { diff --git a/src/tools/info.c b/src/tools/info.c index 3ebbba8..45d4842 100644 --- a/src/tools/info.c +++ b/src/tools/info.c @@ -81,7 +81,7 @@ static stlink_t *stlink_open_first(void) stlink_t* sl = NULL; sl = stlink_v1_open(0, 1); if (sl == NULL) - sl = stlink_open_usb(0, 1, NULL); + sl = stlink_open_usb(0, 1, NULL, 0); return sl; } diff --git a/src/usb.c b/src/usb.c index 4e7a298..ef3743c 100644 --- a/src/usb.c +++ b/src/usb.c @@ -873,7 +873,7 @@ static stlink_backend_t _stlink_usb_backend = { _stlink_usb_set_swdclk }; -stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE]) +stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq) { stlink_t* sl = NULL; struct stlink_libusb* slu = NULL; @@ -1041,10 +1041,51 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST stlink_exit_dfu_mode(sl); } + + sl->opt = freq; // set the speed before entering the mode // as the chip discovery phase should be done at this speed too // Set the stlink clock speed (default is 1800kHz) - stlink_set_swdclk(sl, STLINK_SWDCLK_1P8MHZ_DIVISOR); + DLOG("JTAG/SWD freq set to %d\n", freq); + switch (freq) { + case 5: + stlink_set_swdclk(sl, STLINK_SWDCLK_5KHZ_DIVISOR); + break; + case 15: + stlink_set_swdclk(sl, STLINK_SWDCLK_15KHZ_DIVISOR); + break; + case 25: + stlink_set_swdclk(sl, STLINK_SWDCLK_25KHZ_DIVISOR); + break; + case 50: + stlink_set_swdclk(sl, STLINK_SWDCLK_50KHZ_DIVISOR); + break; + case 100: + stlink_set_swdclk(sl, STLINK_SWDCLK_100KHZ_DIVISOR); + break; + case 125: + stlink_set_swdclk(sl, STLINK_SWDCLK_125KHZ_DIVISOR); + break; + case 240: + stlink_set_swdclk(sl, STLINK_SWDCLK_240KHZ_DIVISOR); + break; + case 480: + stlink_set_swdclk(sl, STLINK_SWDCLK_480KHZ_DIVISOR); + break; + case 950: + stlink_set_swdclk(sl, STLINK_SWDCLK_950KHZ_DIVISOR); + break; + case 1200: + stlink_set_swdclk(sl, STLINK_SWDCLK_1P2MHZ_DIVISOR); + break; + case 0: case 1800: + stlink_set_swdclk(sl, STLINK_SWDCLK_1P8MHZ_DIVISOR); + break; + case 4000: + stlink_set_swdclk(sl, STLINK_SWDCLK_4MHZ_DIVISOR); + break; + } + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); @@ -1147,7 +1188,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { continue; } - stlink_t *sl = stlink_open_usb(0, 1, serial); + stlink_t *sl = stlink_open_usb(0, 1, serial, 0); if (!sl) { ELOG("Failed to open USB device %#06x:%#06x\n", desc.idVendor, desc.idProduct); continue; diff --git a/src/usb.h b/src/usb.h index 968f38b..061042e 100644 --- a/src/usb.h +++ b/src/usb.h @@ -68,7 +68,7 @@ extern "C" { * @retval NULL Error while opening the stlink * @retval !NULL Stlink found and ready to use */ - stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE]); + stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq); size_t stlink_probe_usb(stlink_t **stdevs[]); void stlink_probe_usb_free(stlink_t **stdevs[], size_t size); diff --git a/tests/flash.c b/tests/flash.c index 96a43a2..3166e72 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -83,6 +83,7 @@ static struct Test tests[] = { .size = 0x1000, .reset = 1, .log_level = DEBUG_LOG_LEVEL, + .freq = 0, .format = FLASH_FORMAT_BINARY } }, { "--debug --reset write test.bin 0x80000000", 0, @@ -93,6 +94,51 @@ static struct Test tests[] = { .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, + .freq = 0, + .format = FLASH_FORMAT_BINARY } + }, + { "--debug --freq 5k --reset write test.bin 0x80000000", 0, + { .cmd = FLASH_CMD_WRITE, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 5, + .format = FLASH_FORMAT_BINARY } + }, + { "--debug --freq 15K --reset write test.bin 0x80000000", 0, + { .cmd = FLASH_CMD_WRITE, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 15, + .format = FLASH_FORMAT_BINARY } + }, + { "--debug --freq=5k --reset write test.bin 0x80000000", 0, + { .cmd = FLASH_CMD_WRITE, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 0, + .format = FLASH_FORMAT_BINARY } + }, + { "--debug --freq=6k --reset write test.bin 0x80000000", -1, + { .cmd = FLASH_CMD_WRITE, + .serial = { 0 }, + .filename = "test.bin", + .addr = 0x80000000, + .size = 0, + .reset = 1, + .log_level = DEBUG_LOG_LEVEL, + .freq = 6, .format = FLASH_FORMAT_BINARY } }, { "--debug --reset read test.bin 0x80000000 1000", 0, @@ -103,6 +149,7 @@ static struct Test tests[] = { .size = 1000, .reset = 1, .log_level = DEBUG_LOG_LEVEL, + .freq = 0, .format = FLASH_FORMAT_BINARY } }, { "--debug --reset read test.bin 0x80000000 1k", 0, @@ -113,6 +160,7 @@ static struct Test tests[] = { .size = 1024, .reset = 1, .log_level = DEBUG_LOG_LEVEL, + .freq = 0, .format = FLASH_FORMAT_BINARY } }, { "--debug --reset read test.bin 0x80000000 1M", 0, @@ -123,6 +171,7 @@ static struct Test tests[] = { .size = 1048576, .reset = 1, .log_level = DEBUG_LOG_LEVEL, + .freq = 0, .format = FLASH_FORMAT_BINARY } }, { "--debug --reset write test.bin 0x80000000", 0, @@ -133,6 +182,7 @@ static struct Test tests[] = { .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, + .freq = 0, .format = FLASH_FORMAT_BINARY } }, { "erase", 0, @@ -143,6 +193,7 @@ static struct Test tests[] = { .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, + .freq = 0, .format = FLASH_FORMAT_BINARY } }, { "--debug --reset --format=ihex write test.hex", 0, @@ -153,6 +204,7 @@ static struct Test tests[] = { .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, + .freq = 0, .format = FLASH_FORMAT_IHEX } }, { "--debug --reset --format=binary write test.hex", -1, FLASH_OPTS_INITIALIZER }, @@ -167,6 +219,7 @@ static struct Test tests[] = { .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, + .freq = 0, .format = FLASH_FORMAT_BINARY } }, { "--serial=A1020304 erase", 0, @@ -177,6 +230,7 @@ static struct Test tests[] = { .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, + .freq = 0, .format = FLASH_FORMAT_BINARY } }, }; diff --git a/tests/usb.c b/tests/usb.c index d409883..5165ea5 100644 --- a/tests/usb.c +++ b/tests/usb.c @@ -9,7 +9,7 @@ int main(int ac, char** av) { stlink_t* sl; struct stlink_reg regs; - sl = stlink_open_usb(10, 1, NULL); + sl = stlink_open_usb(10, 1, NULL, 0); if (sl != NULL) { printf("-- version\n"); stlink_version(sl); From 931141869e17f72a01dc14ebd27cca8f86348c32 Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Thu, 7 May 2020 18:52:34 +0800 Subject: [PATCH 2/4] Fix missing cmp and wrong expected value for freq --- tests/flash.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/flash.c b/tests/flash.c index 3166e72..d47b356 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -66,6 +66,7 @@ static bool execute_test(const struct Test * test) { ret &= (opts.size == test->opts.size); ret &= (opts.reset == test->opts.reset); ret &= (opts.log_level == test->opts.log_level); + ret &= (opts.freq == test->opts.freq); ret &= (opts.format == test->opts.format); } @@ -127,7 +128,7 @@ static struct Test tests[] = { .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, - .freq = 0, + .freq = 5, .format = FLASH_FORMAT_BINARY } }, { "--debug --freq=6k --reset write test.bin 0x80000000", -1, From 6c6f27b0f55fdd482ece7d223293ddc3e9a7a90b Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Fri, 8 May 2020 15:40:29 +0800 Subject: [PATCH 3/4] Add documentation of --freq and --opt --- doc/tutorial.md | 11 +++++++++++ include/stlink.h | 2 +- include/stlink/tools/flash.h | 4 ++-- src/usb.c | 2 +- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 929aa32..ad64a8d 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -19,6 +19,17 @@ The size may be followed by an optional "k" or "m" to multiply the given value b When flashing a file, a checksum is calculated for the binary file, both in md5 and the sum algorithm. The latter is also used by the official ST-Link utility tool from STMicroelectronics as described in the document: [`UM0892 - User manual - STM32 ST-LINK utility software description`](https://www.st.com/resource/en/user_manual/cd00262073-stm32-stlink-utility-software-description-stmicroelectronics.pdf). +#### --freq=n[k][m] + +(since v1.6.1) + +You can specify the frequency of SWD/JTAG interface, to override the default 1800KHz configuration. This option accpets decimal only (5K or 1.8M). `Hz` is left out in this option. Valid frequencies are `5K, 15K, 25K, 50K, 100K, 125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)` + +#### --opt + +(since v1.6.1, optional; enabled by default from v1.0.0 to v1.6.0) + +You can enable the optimization to skip flashing empty (0x00 or 0xff) bytes at the end of binary file. May cause some garbage data left after a flash. ## Solutions to common problems ### a) STLINK/v1 driver: Issue with Kernel Extension (kext) (macOS 10.11 and later only) diff --git a/include/stlink.h b/include/stlink.h index ffa65b3..b8080fd 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -151,7 +151,7 @@ typedef struct flash_loader { // transport layer verboseness: 0 for no debug info, 10 for lots int verbose; - int opt; + int opt; // set by main() in tools/flash.c, empty tail bytes drop optimization uint32_t core_id; // set by stlink_core_id(), result from STLINK_DEBUGREADCOREID uint32_t chip_id; // set by stlink_load_device_params(), used to identify flash and sram int core_stat; // set by stlink_status(), values STLINK_CORE_xxxxx diff --git a/include/stlink/tools/flash.h b/include/stlink/tools/flash.h index b8954af..a912a14 100644 --- a/include/stlink/tools/flash.h +++ b/include/stlink/tools/flash.h @@ -25,8 +25,8 @@ struct flash_opts enum flash_area area; uint32_t val; size_t flash_size; /* --flash=n[k][m] */ - int opt; - int freq; + int opt; /* enable empty tail data drop optimization */ + int freq; /* --freq=n[k][m] frequency of JTAG/SWD */ }; #define FLASH_OPTS_INITIALIZER {0, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} diff --git a/src/usb.c b/src/usb.c index ef3743c..148ad76 100644 --- a/src/usb.c +++ b/src/usb.c @@ -1042,7 +1042,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST } - sl->opt = freq; + sl->freq = freq; // set the speed before entering the mode // as the chip discovery phase should be done at this speed too // Set the stlink clock speed (default is 1800kHz) From 7a5b6ef2f707660e79d2ff7fde4aa84390da19be Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 9 May 2020 22:20:17 +0200 Subject: [PATCH 4/4] Whitespace cleanup --- include/stlink.h | 291 ++++++++++++++++++++++++----------------------- 1 file changed, 146 insertions(+), 145 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index b8080fd..68ca0ab 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -1,9 +1,10 @@ /* * File: stlink.h * - * This should contain all the common top level stlink interfaces, regardless - * of how the backend does the work.... + * This should contain all the common top level stlink interfaces, + * regardless of how the backend does the work.... */ + #ifndef STLINK_H #define STLINK_H @@ -19,12 +20,12 @@ extern "C" { #define STLINK_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) - // Max data transfer size. - // 6kB = max mem32_read block, 8kB sram - //#define Q_BUF_LEN 96 +// Max data transfer size. +// 6kB = max mem32_read block, 8kB sram +//#define Q_BUF_LEN 96 #define Q_BUF_LEN (1024 * 100) - // STLINK_DEBUG_RESETSYS, etc: +// STLINK_DEBUG_RESETSYS, etc: #define STLINK_CORE_RUNNING 0x80 #define STLINK_CORE_HALTED 0x81 #define STLINK_CORE_STAT_UNKNOWN -1 @@ -37,13 +38,13 @@ extern "C" { #define STLINK_DFU_COMMAND 0xF3 #define STLINK_DFU_EXIT 0x07 - // STLINK_GET_CURRENT_MODE +// STLINK_GET_CURRENT_MODE #define STLINK_DEV_DFU_MODE 0x00 #define STLINK_DEV_MASS_MODE 0x01 #define STLINK_DEV_DEBUG_MODE 0x02 #define STLINK_DEV_UNKNOWN_MODE -1 - // TODO - possible poor names... +// TODO - possible poor names... #define STLINK_SWD_ENTER 0x30 #define STLINK_SWD_READCOREID 0x32 // TBD #define STLINK_JTAG_WRITEDEBUG_32BIT 0x35 @@ -76,176 +77,176 @@ extern "C" { #define STLINK_V3_MAX_FREQ_NB 10 - /* Enough space to hold both a V2 command or a V1 command packaged as generic scsi*/ +/* 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 { - STLINK_FLASH_TYPE_UNKNOWN = 0, - STLINK_FLASH_TYPE_F0, /* used by f0, f1 (except f1xl),f3. */ - STLINK_FLASH_TYPE_F1_XL, /* f0 flash with dual bank, apparently */ - STLINK_FLASH_TYPE_F4, /* used by f2, f4, f7 */ - STLINK_FLASH_TYPE_L0, /* l0, l1 */ - STLINK_FLASH_TYPE_L4, /* l4, l4+ */ - STLINK_FLASH_TYPE_G0, - STLINK_FLASH_TYPE_G4, - STLINK_FLASH_TYPE_WB - }; +enum stlink_flash_type { + STLINK_FLASH_TYPE_UNKNOWN = 0, + STLINK_FLASH_TYPE_F0, /* used by f0, f1 (except f1xl),f3. */ + STLINK_FLASH_TYPE_F1_XL, /* f0 flash with dual bank, apparently */ + STLINK_FLASH_TYPE_F4, /* used by f2, f4, f7 */ + STLINK_FLASH_TYPE_L0, /* l0, l1 */ + STLINK_FLASH_TYPE_L4, /* l4, l4+ */ + STLINK_FLASH_TYPE_G0, + STLINK_FLASH_TYPE_G4, + STLINK_FLASH_TYPE_WB +}; - struct stlink_reg { - uint32_t r[16]; - uint32_t s[32]; - uint32_t xpsr; - uint32_t main_sp; - uint32_t process_sp; - uint32_t rw; - uint32_t rw2; - uint8_t control; - uint8_t faultmask; - uint8_t basepri; - uint8_t primask; - uint32_t fpscr; - }; +struct stlink_reg { + uint32_t r[16]; + uint32_t s[32]; + uint32_t xpsr; + uint32_t main_sp; + uint32_t process_sp; + uint32_t rw; + uint32_t rw2; + uint8_t control; + uint8_t faultmask; + uint8_t basepri; + uint8_t primask; + uint32_t fpscr; +}; - typedef uint32_t stm32_addr_t; +typedef uint32_t stm32_addr_t; typedef struct flash_loader { stm32_addr_t loader_addr; /* loader sram adddr */ stm32_addr_t buf_addr; /* buffer sram address */ } flash_loader_t; - typedef struct _cortex_m3_cpuid_ { - uint16_t implementer_id; - uint16_t variant; - uint16_t part; - uint8_t revision; - } cortex_m3_cpuid_t; +typedef struct _cortex_m3_cpuid_ { + uint16_t implementer_id; + uint16_t variant; + uint16_t part; + uint8_t revision; +} cortex_m3_cpuid_t; - typedef struct stlink_version_ { - uint32_t stlink_v; - uint32_t jtag_v; - uint32_t swim_v; - uint32_t st_vid; - uint32_t stlink_pid; - } stlink_version_t; +typedef struct stlink_version_ { + uint32_t stlink_v; + uint32_t jtag_v; + uint32_t swim_v; + uint32_t st_vid; + uint32_t stlink_pid; +} stlink_version_t; - enum transport_type { - TRANSPORT_TYPE_ZERO = 0, - TRANSPORT_TYPE_LIBSG, - TRANSPORT_TYPE_LIBUSB, - TRANSPORT_TYPE_INVALID - }; +enum transport_type { + TRANSPORT_TYPE_ZERO = 0, + TRANSPORT_TYPE_LIBSG, + TRANSPORT_TYPE_LIBUSB, + TRANSPORT_TYPE_INVALID +}; typedef struct _stlink stlink_t; #include - struct _stlink { - struct _stlink_backend *backend; - void *backend_data; +struct _stlink { + struct _stlink_backend *backend; + void *backend_data; - // Room for the command header - unsigned char c_buf[C_BUF_LEN]; - // Data transferred from or to device - unsigned char q_buf[Q_BUF_LEN]; - int q_len; + // Room for the command header + unsigned char c_buf[C_BUF_LEN]; + // Data transferred from or to device + unsigned char q_buf[Q_BUF_LEN]; + int q_len; - // transport layer verboseness: 0 for no debug info, 10 for lots - int verbose; - int opt; // set by main() in tools/flash.c, empty tail bytes drop optimization - uint32_t core_id; // set by stlink_core_id(), result from STLINK_DEBUGREADCOREID - uint32_t chip_id; // set by stlink_load_device_params(), used to identify flash and sram - int core_stat; // set by stlink_status(), values STLINK_CORE_xxxxx + // transport layer verboseness: 0 for no debug info, 10 for lots + int verbose; + int opt; // set by main() in tools/flash.c, empty tail bytes drop optimization + uint32_t core_id; // set by stlink_core_id(), result from STLINK_DEBUGREADCOREID + uint32_t chip_id; // set by stlink_load_device_params(), used to identify flash and sram + int core_stat; // set by stlink_status(), values STLINK_CORE_xxxxx - char serial[STLINK_SERIAL_MAX_SIZE]; - int serial_size; + char serial[STLINK_SERIAL_MAX_SIZE]; + int serial_size; - int freq; // set by stlink_open_usb(), values: STLINK_SWDCLK_xxx_DIVISOR + int freq; // set by stlink_open_usb(), values: STLINK_SWDCLK_xxx_DIVISOR - enum stlink_flash_type flash_type; // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STLINK_FLASH_TYPE_xxx - bool has_dual_bank; + enum stlink_flash_type flash_type; // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STLINK_FLASH_TYPE_xxx + bool has_dual_bank; - stm32_addr_t flash_base; // STM32_FLASH_BASE, set by stlink_load_device_params() - size_t flash_size; // calculated by stlink_load_device_params() - size_t flash_pgsz; // stlink_chipid_params.flash_pagesize, set by stlink_load_device_params() + stm32_addr_t flash_base; // STM32_FLASH_BASE, set by stlink_load_device_params() + size_t flash_size; // calculated by stlink_load_device_params() + size_t flash_pgsz; // stlink_chipid_params.flash_pagesize, set by stlink_load_device_params() - /* sram settings */ - stm32_addr_t sram_base; // STM32_SRAM_BASE, set by stlink_load_device_params() - size_t sram_size; // stlink_chipid_params.sram_size, set by stlink_load_device_params() + /* sram settings */ + stm32_addr_t sram_base; // STM32_SRAM_BASE, set by stlink_load_device_params() + size_t sram_size; // stlink_chipid_params.sram_size, set by stlink_load_device_params() - /* option settings */ - stm32_addr_t option_base; - size_t option_size; + /* option settings */ + stm32_addr_t option_base; + size_t option_size; - // bootloader - // sys_base and sys_size are not used by the tools, but are only there to - // download the bootloader code (see tests/sg.c) - stm32_addr_t sys_base; // stlink_chipid_params.bootrom_base, set by stlink_load_device_params() - size_t sys_size; // stlink_chipid_params.bootrom_size, set by stlink_load_device_params() + // bootloader + // sys_base and sys_size are not used by the tools, but are only there to + // download the bootloader code (see tests/sg.c) + stm32_addr_t sys_base; // stlink_chipid_params.bootrom_base, set by stlink_load_device_params() + size_t sys_size; // stlink_chipid_params.bootrom_size, set by stlink_load_device_params() - struct stlink_version_ version; - }; + struct stlink_version_ version; +}; - int stlink_enter_swd_mode(stlink_t *sl); - int stlink_enter_jtag_mode(stlink_t *sl); - int stlink_exit_debug_mode(stlink_t *sl); - int stlink_exit_dfu_mode(stlink_t *sl); - void stlink_close(stlink_t *sl); - int stlink_core_id(stlink_t *sl); - int stlink_reset(stlink_t *sl); - int stlink_jtag_reset(stlink_t *sl, int value); - int stlink_run(stlink_t *sl); - int stlink_status(stlink_t *sl); - int stlink_version(stlink_t *sl); - int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data); - int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len); - int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data); - int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len); - int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len); - int stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp); - int stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp); - int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); - int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); - int stlink_write_unsupported_reg(stlink_t *sl, uint32_t value, int r_idx, struct stlink_reg *regp); - int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx); - int stlink_step(stlink_t *sl); - int stlink_current_mode(stlink_t *sl); - int stlink_force_debug(stlink_t *sl); - int stlink_target_voltage(stlink_t *sl); - int stlink_set_swdclk(stlink_t *sl, uint16_t divisor); +int stlink_enter_swd_mode(stlink_t *sl); +int stlink_enter_jtag_mode(stlink_t *sl); +int stlink_exit_debug_mode(stlink_t *sl); +int stlink_exit_dfu_mode(stlink_t *sl); +void stlink_close(stlink_t *sl); +int stlink_core_id(stlink_t *sl); +int stlink_reset(stlink_t *sl); +int stlink_jtag_reset(stlink_t *sl, int value); +int stlink_run(stlink_t *sl); +int stlink_status(stlink_t *sl); +int stlink_version(stlink_t *sl); +int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data); +int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len); +int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data); +int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len); +int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len); +int stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp); +int stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp); +int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); +int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp); +int stlink_write_unsupported_reg(stlink_t *sl, uint32_t value, int r_idx, struct stlink_reg *regp); +int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx); +int stlink_step(stlink_t *sl); +int stlink_current_mode(stlink_t *sl); +int stlink_force_debug(stlink_t *sl); +int stlink_target_voltage(stlink_t *sl); +int stlink_set_swdclk(stlink_t *sl, uint16_t divisor); - int stlink_erase_flash_mass(stlink_t* sl); - int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); - int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, uint32_t * begin); - uint8_t stlink_get_erased_pattern(stlink_t *sl); - int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); - int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr); - int stlink_mwrite_sram(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); - int stlink_fwrite_sram(stlink_t *sl, const char* path, stm32_addr_t addr); - int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, uint32_t length); +int stlink_erase_flash_mass(stlink_t* sl); +int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); +int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, uint32_t * begin); +uint8_t stlink_get_erased_pattern(stlink_t *sl); +int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); +int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr); +int stlink_mwrite_sram(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr); +int stlink_fwrite_sram(stlink_t *sl, const char* path, stm32_addr_t addr); +int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, uint32_t length); - int stlink_chip_id(stlink_t *sl, uint32_t *chip_id); - int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid); +int stlink_chip_id(stlink_t *sl, uint32_t *chip_id); +int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid); - int stlink_erase_flash_page(stlink_t* sl, stm32_addr_t flashaddr); - uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr); - uint16_t read_uint16(const unsigned char *c, const int pt); - void stlink_core_stat(stlink_t *sl); - void stlink_print_data(stlink_t *sl); - unsigned int is_bigendian(void); - uint32_t read_uint32(const unsigned char *c, const int pt); - void write_uint32(unsigned char* buf, uint32_t ui); - void write_uint16(unsigned char* buf, uint16_t ui); - bool stlink_is_core_halted(stlink_t *sl); - int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, size_t size); - int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); - int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); - int stlink_load_device_params(stlink_t *sl); +int stlink_erase_flash_page(stlink_t* sl, stm32_addr_t flashaddr); +uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr); +uint16_t read_uint16(const unsigned char *c, const int pt); +void stlink_core_stat(stlink_t *sl); +void stlink_print_data(stlink_t *sl); +unsigned int is_bigendian(void); +uint32_t read_uint32(const unsigned char *c, const int pt); +void write_uint32(unsigned char* buf, uint32_t ui); +void write_uint16(unsigned char* buf, uint16_t ui); +bool stlink_is_core_halted(stlink_t *sl); +int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, size_t size); +int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); +int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); +int stlink_load_device_params(stlink_t *sl); - int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte); - int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte); +int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte); +int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte); - int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len); - int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); +int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len); +int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); #include #include