From c0236dd12c9f07e78b73f774bf028dc102d8f04b Mon Sep 17 00:00:00 2001 From: Michael Nolan Date: Thu, 11 Mar 2021 13:22:00 -0500 Subject: [PATCH 01/65] Hopefully fix reading an invalid chip ID on STM32WB55 --- src/common.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/common.c b/src/common.c index 99049196d..242b690af 100644 --- a/src/common.c +++ b/src/common.c @@ -1222,8 +1222,34 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { int ret; if (sl->core_id == STM32H7_CORE_ID) { - // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) - ret = stlink_read_debug32(sl, 0x5c001000, chip_id); + /* STM32H7 chipid in 0x5c001000 (RM0433 pg3189) + * However, the STM32H7 is not the only chip with a JTAG + * IDCODE of 0x6ba02477, so we cannot rely solely on this info + * to select the address to read the chip id */ + + uint32_t chip_id_tmp; + // try reading from 0x5c001000 + ret = stlink_read_debug32(sl, 0x5c001000, &chip_id_tmp); + + // Extract the DEV_ID/CHIPID + uint32_t h7_chip_id = chip_id_tmp & 0xfff; + + if(ret != -1){ + // If we successfully read a H7 chip ID, return that + if((h7_chip_id == STLINK_CHIPID_STM32_H74XXX) || + (h7_chip_id == STLINK_CHIPID_STM32_H7AX) || + (h7_chip_id == STLINK_CHIPID_STM32_H72X)) { + *chip_id = chip_id_tmp; + return(ret); + } + } + + // If we had an error or were unsuccessful at reading an H7 + // series chip ID, try reading the chip ID from the default + // address + ret = stlink_read_debug32(sl, 0xE0042000, chip_id); + + } else { // default chipid address ret = stlink_read_debug32(sl, 0xE0042000, chip_id); From eff18d81d9c64ef9eaf4972d800de09be13ff141 Mon Sep 17 00:00:00 2001 From: 2a17 Date: Thu, 11 Mar 2021 23:04:14 +0000 Subject: [PATCH 02/65] option byte support improved --- src/st-flash/flash_opts.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index e74ecc1ce..2ef72c12a 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -337,12 +337,27 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { if (ac == 2) { uint32_t addr; - result = get_integer_from_char_array(av[1], &addr); + result = get_integer_from_char_array(av[0], &addr); if (result != 0) { return bad_arg ("addr"); } else { o->addr = (stm32_addr_t) addr; } + uint32_t val; + result = get_integer_from_char_array(av[1], &val); + if (result != 0) { + return bad_arg ("val"); + } else { + o->val = (uint32_t) val; + } + } else { + uint32_t val; + result = get_integer_from_char_array(av[0], &val); + if (result != 0) { + return bad_arg ("val"); + } else { + o->val = (uint32_t) val; + } } } else if (o->area == FLASH_OPTION_BYTES_BOOT_ADD) { // expect option bytes boot address if (ac != 1) { return invalid_args("option bytes boot_add write "); } From 93c59cc5c2bacf5901ad4550bf7a9a4041369dac Mon Sep 17 00:00:00 2001 From: 2a17 Date: Thu, 11 Mar 2021 23:49:51 +0000 Subject: [PATCH 03/65] spelling mistake 'feature request' changed to 'bug report' in bug report template --- .github/ISSUE_TEMPLATE/bug-report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index a1b9d65a0..0e22c2ce9 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -8,7 +8,7 @@ labels: '' Thank you for giving feedback to the stlink project. **NOTICE: Please read and follow instructions in #906 before submitting a ticket. -This feature request will be deleted without notice when not enough information is provided! So please ensure that all fields are filled out.** +This bug report will be deleted without notice when not enough information is provided! So please ensure that all fields are filled out.** - [ ] I made serious effort to avoid creating duplicate or nearly similar issue From 7729fea5ed2bc743c64578f9690c40fff58a9821 Mon Sep 17 00:00:00 2001 From: 2a17 Date: Fri, 12 Mar 2021 12:22:58 +0000 Subject: [PATCH 04/65] unused parameter removed, comment and return message updated --- src/st-flash/flash_opts.c | 36 +++++++----------------------------- 1 file changed, 7 insertions(+), 29 deletions(-) diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index 2ef72c12a..2ee19bd48 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -328,36 +328,14 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { case FLASH_CMD_WRITE: // TODO: should be boot add 0 and boot add 1 uint32 - if (o->area == FLASH_OPTION_BYTES) { // expect filename and optional address - if (ac >=1 && ac <= 2) { - o->filename = av[0]; - } else { - return invalid_args("write [addr]"); - } - - if (ac == 2) { - uint32_t addr; - result = get_integer_from_char_array(av[0], &addr); - if (result != 0) { - return bad_arg ("addr"); - } else { - o->addr = (stm32_addr_t) addr; - } - uint32_t val; - result = get_integer_from_char_array(av[1], &val); - if (result != 0) { - return bad_arg ("val"); - } else { - o->val = (uint32_t) val; - } + if (o->area == FLASH_OPTION_BYTES) { // expect option byte value + if (ac != 1) { return invalid_args("option byte write "); } + uint32_t val; + result = get_integer_from_char_array(av[0], &val); + if (result != 0) { + return bad_arg ("val"); } else { - uint32_t val; - result = get_integer_from_char_array(av[0], &val); - if (result != 0) { - return bad_arg ("val"); - } else { - o->val = (uint32_t) val; - } + o->val = (uint32_t) val; } } else if (o->area == FLASH_OPTION_BYTES_BOOT_ADD) { // expect option bytes boot address if (ac != 1) { return invalid_args("option bytes boot_add write "); } From e5767681f14de9851aa970a9299930ca68b2ed92 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 12 Mar 2021 18:39:08 +0100 Subject: [PATCH 05/65] [doc] Corrected tutorial.md Corrected info on --freq argument (Closes #1055) --- doc/tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index f13c4c6f1..3a0f16fd9 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -5,7 +5,7 @@ | Option | Tool | Description | Available
since | | --------------- | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | | --flash=n[k][m] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k
for the STM32F103C8T6 to assume 128k of flash being present. This option accepts
decimal (128k), octal 0200k, or hex 0x80k values. Leaving the multiplier out is
equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional "k"
or "m" to multiply the given value by 1k (1024) or 1M respectively. | v1.4.0 | -| --freq=n[k][m] | st-flash,
st-util | The frequency of the SWD/JTAG interface can be specified, to override the default
1800 kHz configuration. This option solely accepts decimal values (5K or 1.8M) with
the unit `Hz` being left out. Valid frequencies are `5K, 15K, 25K, 50K, 100K,`
`125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)`. | v1.6.1 | +| --freq=n[k][m] | st-flash | The frequency of the SWD/JTAG interface can be specified, to override the default
1800 kHz configuration. This option solely accepts decimal values (5K or 1.8M) with
the unit `Hz` being left out. Valid frequencies are: `5K, 15K, 25K, 50K, 100K,`
`125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)`. | v1.6.1 | | --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at
the end of binary file. This may cause some garbage data left after a flash operation.
This option was enabled by default in earlier releases. | v1.6.1 | | --reset | st-flash | Trigger a reset both before and after flashing. | v1.0.0 | | --version | st-info,
st-flash,
st-util | Print version information. | | From dd877b1883b94f4529f3765883f1ce1fe4744fa1 Mon Sep 17 00:00:00 2001 From: anton Date: Sun, 14 Mar 2021 21:09:40 +0500 Subject: [PATCH 06/65] Fixing support of stlink v1 --- src/stlink-lib/usb.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 0168834ca..d2b17fad6 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -301,7 +301,7 @@ int _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { if (ret == -1) { return(ret); } - ret = send_only(slu, 0, data, len); + ret = send_only(slu, 1, data, len); if (ret == -1) { return(ret); } @@ -431,6 +431,8 @@ int _stlink_usb_status(stlink_t * sl) { } else { sl->core_stat = TARGET_UNKNOWN; } + } else { + sl->core_stat = TARGET_UNKNOWN; } return(0); @@ -469,19 +471,14 @@ int _stlink_usb_enter_swd_mode(stlink_t * sl) { unsigned char* const cmd = sl->c_buf; ssize_t size; unsigned char* const data = sl->q_buf; - const uint32_t rep_len = sl->version.stlink_v > 1 ? 2 : 0; + const uint32_t rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 0 : 2; int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; // select correct API-Version for entering SWD mode: V1 API (0x20) or V2 API (0x30). cmd[i++] = sl->version.jtag_api == STLINK_JTAG_API_V1 ? STLINK_DEBUG_APIV1_ENTER : STLINK_DEBUG_APIV2_ENTER; cmd[i++] = STLINK_DEBUG_ENTER_SWD; - - if (rep_len == 0) { - size = send_only(slu, 1, cmd, slu->cmd_len); - } else { - size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); - } + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { printf("[!] send_recv STLINK_DEBUG_ENTER\n"); From c39ed921e39519eb30084b22b8539d19ae5df741 Mon Sep 17 00:00:00 2001 From: Michael Nolan Date: Sun, 14 Mar 2021 20:53:00 -0400 Subject: [PATCH 07/65] Implement changes suggested by Ant-ON to select the chipid register --- src/common.c | 36 ++++++++++++++++-------------------- src/stlink-lib/reg.h | 5 +++++ 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/common.c b/src/common.c index 242b690af..a064254d3 100644 --- a/src/common.c +++ b/src/common.c @@ -1227,28 +1227,24 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { * IDCODE of 0x6ba02477, so we cannot rely solely on this info * to select the address to read the chip id */ - uint32_t chip_id_tmp; - // try reading from 0x5c001000 - ret = stlink_read_debug32(sl, 0x5c001000, &chip_id_tmp); - - // Extract the DEV_ID/CHIPID - uint32_t h7_chip_id = chip_id_tmp & 0xfff; - - if(ret != -1){ - // If we successfully read a H7 chip ID, return that - if((h7_chip_id == STLINK_CHIPID_STM32_H74XXX) || - (h7_chip_id == STLINK_CHIPID_STM32_H7AX) || - (h7_chip_id == STLINK_CHIPID_STM32_H72X)) { - *chip_id = chip_id_tmp; - return(ret); - } + uint32_t cpu_id; + *chip_id = 0; + ret = -1; + + // Read the CPU ID as well to determine if this really is an H7 part + if (stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &cpu_id)) + cpu_id = 0; + + // If it is, read the chipid from the new address + if (sl->core_id == STM32H7_CORE_ID && cpu_id == STLINK_REG_CMx_CPUID_CM7) { + // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) + ret = stlink_read_debug32(sl, 0x5c001000, chip_id); } - // If we had an error or were unsuccessful at reading an H7 - // series chip ID, try reading the chip ID from the default - // address - ret = stlink_read_debug32(sl, 0xE0042000, chip_id); - + if (*chip_id == 0) { + // default chipid address + ret = stlink_read_debug32(sl, 0xE0042000, chip_id); + } } else { // default chipid address diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index 6d2c9f1af..5a796d7e1 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -3,6 +3,11 @@ #define STLINK_REG_CM3_CPUID 0xE000ED00 +#define STLINK_REG_CMx_CPUID_CM0 0x410CC200 +#define STLINK_REG_CMx_CPUID_CM3 0x412FC230 +#define STLINK_REG_CMx_CPUID_CM7 0x411FC272 + + #define STLINK_REG_CM3_FP_CTRL 0xE0002000 // Flash Patch Control Register #define STLINK_REG_CM3_FP_COMPn(n) (0xE0002008 + n*4) #define STLINK_REG_CM3_FP_CTRL_KEY (1 << 1) From 125cb2d7634d5cbc916e9c4bac6ddf80407ab605 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 17 Mar 2021 23:26:48 +0100 Subject: [PATCH 08/65] General Project Update - Updated CHANGELOG.md - Updated README.md - Formatting fixes -[doc] Updated tested devices & boards --- CHANGELOG.md | 10 +- README.md | 61 +++++----- doc/devices_boards.md | 253 +++++++++++++++++++++-------------------- doc/version_support.md | 112 +++++++++--------- 4 files changed, 217 insertions(+), 219 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 912092b65..cacd79eef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,7 @@ Features: Updates & changes: -- [doc] Added note on `(gdb) run` command (commit [#03793d4](https://github.com/stlink-org/stlink/commit/03793d42b6078344a9ef8ad55f1d5d0fc19e486e), [#276](https://github.com/stlink-org/stlink/pull/276)) +- [doc] Added note on `(gdb) run` command (commit [#03793d4](https://github.com/stlink-org/stlink/commit/03793d42b6078344a9ef8ad55f1d5d0fc19e486e), [#267](https://github.com/stlink-org/stlink/pull/267)) - [doc] `st-flash --reset` parameter (one solution for #356) ([#642](https://github.com/stlink-org/stlink/pull/642)) - [refactoring] General maintenance ([#864](https://github.com/stlink-org/stlink/pull/864), [#976](https://github.com/stlink-org/stlink/pull/976), [#978](https://github.com/stlink-org/stlink/pull/978)) - Imported debian pkg-settings ([#986](https://github.com/stlink-org/stlink/pull/986)) @@ -42,13 +42,17 @@ Fixes: - Fixed `connect under reset` for `st-flash` and `st-util` ([#983](https://github.com/stlink-org/stlink/pull/983)) - Fix for `mmap() size_t overflow` in `st-flash` ([#988](https://github.com/stlink-org/stlink/pull/988), [#989](https://github.com/stlink-org/stlink/pull/989)) - [regression] `stlink-gui` installation issue on Ubuntu-18.04 ([#1001](https://github.com/stlink-org/stlink/pull/1001), [#1004](https://github.com/stlink-org/stlink/pull/1004), [#1006](https://github.com/stlink-org/stlink/pull/1006)) -- `st-util`: wrong register values passed to `gdb` (STLink/V2) ([#1002](https://github.com/stlink-org/stlink/pull/1002), [#1011](https://github.com/stlink-org/stlink/pull/1011), [#1026](https://github.com/stlink-org/stlink/pull/1026), [#1027](https://github.com/stlink-org/stlink/pull/1027)) +- `st-util`: wrong register values passed to `gdb` (STLink/V2) ([#1002](https://github.com/stlink-org/stlink/pull/1002), [#1011](https://github.com/stlink-org/stlink/pull/1011), [#1026](https://github.com/stlink-org/stlink/pull/1026), [#1027](https://github.com/stlink-org/stlink/pull/1027), [#1064](https://github.com/stlink-org/stlink/pull/1064), [#1065](https://github.com/stlink-org/stlink/pull/1065)) - [doc] Fixed wrong path for `rules.d` folder ([#1020](https://github.com/stlink-org/stlink/pull/1020)) - Use vl flashloader for all STM32F1 series ([#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) +- st-util v1.6.1 does not recognize option --freq (commit [#e576768](https://github.com/stlink-org/stlink/commit/e5767681f14de9851aa970a9299930ca68b2ed92), [#1055](https://github.com/stlink-org/stlink/pull/1055)) - Fixed `gettimeofday` for MSVC ([#1074](https://github.com/stlink-org/stlink/pull/1074)) - Bugfixes for compilation with clang ([#1076](https://github.com/stlink-org/stlink/pull/1076), [#1078](https://github.com/stlink-org/stlink/pull/1078)) - Fixed compilation with GCC 11 ([#1077](https://github.com/stlink-org/stlink/pull/1077)) - [regression] Flash_loader: increased wait rounds for slow boards ([#1085](https://github.com/stlink-org/stlink/pull/1085)) +- Fixed support for writing option bytes ([#1102](https://github.com/stlink-org/stlink/pull/1102)) +- [doc] Corrected spelling mistake in bug report template ([#1103](https://github.com/stlink-org/stlink/pull/1103)) +- Fixed support for STLINK/V1 programmer ([#1045](https://github.com/stlink-org/stlink/pull/1045), [#1105](https://github.com/stlink-org/stlink/pull/1105)) # v1.6.1 @@ -380,8 +384,10 @@ Updates and fixes: - Stm32l0x flash loader (Robin Kreis) - Use libusb synchronous api ([#194](https://github.com/stlink-org/stlink/pull/194), [#374](https://github.com/stlink-org/stlink/pull/374)) - Fixed segfault when programmer is already busy and `NULL` pointers are in the list ([#256](https://github.com/stlink-org/stlink/pull/256), [#394](https://github.com/stlink-org/stlink/pull/394)) +- Fixed issue where "unknown chip id!" was seen every other time ([#352](https://github.com/stlink-org/stlink/pull/352), [#367](https://github.com/stlink-org/stlink/pull/367), [#381](https://github.com/stlink-org/stlink/pull/381)) - Send F4 memory-map and features for STM32F429 ([#188](https://github.com/stlink-org/stlink/pull/188), [#196](https://github.com/stlink-org/stlink/pull/196), [#250](https://github.com/stlink-org/stlink/pull/250), [#251](https://github.com/stlink-org/stlink/pull/251)) (Release v1.1.0) - Added AHB3 Peripherals definition for STM32F4 ([#218](https://github.com/stlink-org/stlink/pull/218), [#288](https://github.com/stlink-org/stlink/pull/288)) (Release v1.1.0) +- Reset: st-flash does not work when CPU is in sleep mode ([#62](https://github.com/stlink-org/stlink/pull/62)) (Release v1.0.0) - Corrected flash size register address for STM32F2 devices ([#278](https://github.com/stlink-org/stlink/pull/278)) (Release v1.0.0) Chip support added for: diff --git a/README.md b/README.md index 3799f46d2..8a8600947 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -Open source version of the STMicroelectronics STlink Tools -========================================================== +# Open source version of the STMicroelectronics STlink Tools [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/stlink-org/stlink.svg)](https://github.com/stlink-org/stlink/releases/latest) @@ -12,42 +11,40 @@ Open source version of the STMicroelectronics STlink Tools Recent new features and bugfixes can be found in the [Changelog](CHANGELOG.md) of this software project. - #### License The stlink library and tools are licensed under the **[BSD-3 License](LICENSE.md)**. - ## Introduction STLink is an open source toolset to program and debug STM32 devices and boards manufactured by STMicroelectronics. It supports several so called STLINK programmer boards (and clones thereof) which use a microcontroller chip to translate commands from USB to JTAG/SWD. There are four generations available on the market which are _all_ supported by this toolset: -* **STLINK/v1** _[obsolete as of 21-11-2019, continued support by this toolset] *)_ +- **STLINK/V1** _[obsolete as of 21-11-2019, continued support by this toolset] \*)_ - transport layer: SCSI passthru commands over USB - stand-alone programmer and present on STM32VL Discovery boards -* **STLINK/v2** +- **STLINK/V2** - transport layer: raw USB commands - stand-alone programmer and present on STM32L Discovery and Nucleo boards -* **STLINK/v2-1** +- **STLINK/V2-1** - transport layer: raw USB commands - present on some STM32 Nucleo boards -* **STLINK/v3** +- **STLINK/V3** - transport layer: raw USB commands - stand-alone programmer -_*)_ **Note: Support on macOS is limited to 10.14 - 10.15. Any later versions are no longer compatible with the STLINK/v1 due to technical reasons.** +_\*)_ **Note: Support for the STLINK/V1 on macOS is limited to 10.14 - 10.15. Due to the deprecation and removal of macOS Kernel Extensions (KEXT) there will be no support for this programmer on macOS 11 or any later version.** On the user level there is no difference in handling or operation between these different revisions. The STlink toolset includes: -* `st-info` - a programmer and chip information tool -* `st-flash` - a flash manipulation tool -* `st-util` - a GDB server (supported in Visual Studio Code / VSCodium via the [Cortex-Debug](https://github.com/Marus/cortex-debug) plugin) -* `stlink-lib` - a communication library -* `stlink-gui` - a GUI-Interface _[optional]_ - +- `st-info` - a programmer and chip information tool +- `st-flash` - a flash manipulation tool +- `st-trace` - a logging tool to record information on execution +- `st-util` - a GDB server (supported in Visual Studio Code / VSCodium via the [Cortex-Debug](https://github.com/Marus/cortex-debug) plugin) +- `stlink-lib` - a communication library +- `stlink-gui` - a GUI-Interface _[optional]_ ## Supported operating systems and hardware combinations @@ -58,12 +55,10 @@ Supported operating systems are listed in [version_support.md](doc/version_suppo The `stlink` toolset continues to maintain backwards compatibility with the **STLINK/v1** programmer.
Please note that on macOS this support is limited to versions 10.13 - 10.15. - ## Tutorial & HOWTO Our [tutorial](doc/tutorial.md) may help you along with some advanced tasks and additional info. - ## Installation **Windows**: @@ -77,8 +72,8 @@ Alternatively one may compile and install from source as described in our [compi We recommend to install from: -* [homebrew](https://formulae.brew.sh/formula/stlink) or -* [MacPorts](https://ports.macports.org/port/stlink) +- [homebrew](https://formulae.brew.sh/formula/stlink) or +- [MacPorts](https://ports.macports.org/port/stlink) Alternatively one can compile and install from source as described in our [compiling manual](doc/compiling.md#macOS). @@ -88,30 +83,28 @@ We recommend to install `stlink-tools` from the package repository of the used d **Note:** As packages distributed via the [Debian](https://packages.debian.org/buster/stlink-tools) and [Ubuntu](https://packages.ubuntu.com/stlink-tools) repositories differ from our self-maintained deb-package, we recommend to use the latter instead (see link below). It provides the opportunity to handle and fix user-reported package issues directly within the project and is not redundant to any limitations deriving from external maintenance guidelines. -* Debian Linux: [(Link)](https://github.com/stlink-org/stlink/releases) -* Ubuntu Linux: [(Link)](https://github.com/stlink-org/stlink/releases) -* Arch Linux: [(Link)](https://www.archlinux.org/packages/community/x86_64/stlink) -* Alpine Linux: [(Link)](https://pkgs.alpinelinux.org/packages?name=stlink) -* Fedora: [(Link)](https://src.fedoraproject.org/rpms/stlink) -* Gentoo Linux: [(Link)](https://packages.gentoo.org/packages/dev-embedded/stlink) +- Debian Linux: [(Link)](https://github.com/stlink-org/stlink/releases) +- Ubuntu Linux: [(Link)](https://github.com/stlink-org/stlink/releases) +- Arch Linux: [(Link)](https://www.archlinux.org/packages/community/x86_64/stlink) +- Alpine Linux: [(Link)](https://pkgs.alpinelinux.org/packages?name=stlink) +- Fedora: [(Link)](https://src.fedoraproject.org/rpms/stlink) +- Gentoo Linux: [(Link)](https://packages.gentoo.org/packages/dev-embedded/stlink) **Other Operating Systems**: -* RedHat/CentOS 8: Users can install from [EPEL repository](https://src.fedoraproject.org/rpms/stlink/branch/epel8) -* FreeBSD: Users can install from [freshports](https://www.freshports.org/devel/stlink) - +- RedHat/CentOS 8: Users can install from [EPEL repository](https://src.fedoraproject.org/rpms/stlink/branch/epel8) +- FreeBSD: Users can install from [freshports](https://www.freshports.org/devel/stlink) ## Installation from source (advanced users) When there is no executable available for your platform or you need the latest (possible unstable) version you need to compile the toolset yourself. This procedure is explained in the [compiling manual](doc/compiling.md). - ## Contributing and versioning -* The semantic versioning scheme is used. Read more at [semver.org](http://semver.org) -* Before creating a pull request, please _ALWAYS_ open a new issue for the discussion of the intended new features. Bugfixes don't require a discussion via a ticket-issue. However they should always be described in a few words as soon as they appear to help others as well. -* Contributors and/or maintainers may submit comments or request changes to patch-proposals and/or pull-requests. -* **ATTENTION: _NEVER EVER_ use the '#' character to count-up single points within a listing as '#' is _exclusively_ reserved for referencing GitHub issues and pull-requests. Otherwise you accidentally introduce false cross references within the project.** -* Please start new forks from the develop branch, as pull requests will go into this branch as well. +- The semantic versioning scheme is used. Read more at [semver.org](http://semver.org) +- Before creating a pull request, please _ALWAYS_ open a new issue for the discussion of the intended new features. Bugfixes don't require a discussion via a ticket-issue. However they should always be described in a few words as soon as they appear to help others as well. +- Contributors and/or maintainers may submit comments or request changes to patch-proposals and/or pull-requests. +- **ATTENTION: _NEVER EVER_ use the '#' character to count-up single points within a listing as '#' is _exclusively_ reserved for referencing GitHub issues and pull-requests. Otherwise you accidentally introduce false cross references within the project.** +- Please start new forks from the develop branch, as pull requests will go into this branch as well. Please also refer to our [Contribution Guidelines](CONTRIBUTING.md). diff --git a/doc/devices_boards.md b/doc/devices_boards.md index 97094b972..6396738c4 100644 --- a/doc/devices_boards.md +++ b/doc/devices_boards.md @@ -1,15 +1,13 @@ -Boards supported by the STlink toolset -====================================== +# Boards supported by the STlink toolset -The following devices are supported by the STlink tools. - -All Boards are expected to work with ST-Link-v2 programmers. +The following devices are supported by the stlink toolset. +All Boards are expected to work with ST-LINK/V2 programmers. **STM32F0 / ARM Cortex M0 / Core-ID: 0x0bb11477 (STM32F0_CORE_ID)** | Chip-ID | Product-Code | -| --- | --- | +| ------- | ------------------- | | 0x440 | STM32F0**30**x**8** | | 0x442 | STM32F0**30**x**C** | | 0x444 | STM32F0**3**xx**4** | @@ -22,19 +20,19 @@ All Boards are expected to work with ST-Link-v2 programmers. | 0x448 | STM32F0**72**xx | | 0x442 | STM32F0**9**xxx | -Tested boards [incl. STLink programmers]: -* Nucleo-F030R8 [v2-1] -* Nucleo-32 [v2-1] -* STM32F0-Discovery [v2] -* STM320518-EVAL -* Nucleo-F072RB [v2-1] -* Nucleo-F091RC [v2-1] +Tested boards [incl. STLINK programmers]: +- Nucleo-F030R8 [v2-1] +- Nucleo-F072RB [v2-1] +- Nucleo-F091RC [v2-1] +- Nucleo-32 [v2-1] +- STM32F0-Discovery [v2] +- STM320518-EVAL **STM32F1 / ARM Cortex M3 / Core-ID: 0x1ba01477 (STM32F1_CORE_ID)** | Product-Code | Product Line | -| --- | --- | +| ----------------- | ----------------------- | | STM32F10**0**yyxx | Value line (V) | | STM32F10**1**yyxx | Access line (A) | | STM32F10**2**yyxx | USB Access line (USB-A) | @@ -42,86 +40,83 @@ Tested boards [incl. STLink programmers]: | STM32F10**5**yyxx | Connectivity line (C) | | STM32F10**7**yyxx | Connectivity line (C) | -| Chip-ID | Product Line | Code (yy) | V | A | USB-A | P | C | -| --- | --- | --- | --- | --- | --- | --- | --- | -| 0x412 | Low-Density | x4 x6 | F100 | F101 | F102 | F103 | | -| 0x410 | Medium Density | x8 xB | | F101 | F102 | F103 | | -| 0x414 | High density | xC xD xE | | F101 | F103 | | | +| Chip-ID | Product Line | Code (yy) | V | A | USB-A | P | C | +| ------- | -------------------- | --------- | ---- | ---- | ----- | ---- | -------------- | +| 0x412 | Low-Density | x4 x6 | F100 | F101 | F102 | F103 | | +| 0x410 | Medium Density | x8 xB | | F101 | F102 | F103 | | +| 0x414 | High density | xC xD xE | | F101 | F103 | | | | 0x418 | STM32F105xx/107xx | x8 xB xC | | | | | F105
F107 | -| 0x420 | Medium density value | x8 xB | F100 | | | | | -| 0x428 | High density Value | xC xD xE | F100 | | | | | -| 0x430 | XL-Density | xF xG | | F101 | | F103 | | +| 0x420 | Medium density value | x8 xB | F100 | | | | | +| 0x428 | High density Value | xC xD xE | F100 | | | | | +| 0x430 | XL-Density | xF xG | | F101 | | F103 | | -Tested boards [incl. STLink programmers]: -* STM32VL-Discovery (STM32F100RBT6) with STLink-v1 [v1], [v2] -* STM32F103-Bluepill: C8Tx & R8xx [v2] -* Nucleo-F103RB [v2-1] -* HY-STM32 (STM32F103VETx) [v1, v2] -* DecaWave EVB1000 (STM32F105RCTx) [v1, v2] +Tested boards [incl. STLINK programmers]: +- STM32VL-Discovery (STM32F100RBT6) with STLINK/V1 [v1], [v2] +- STM32F103-Bluepill: C8Tx & R8xx [v2] +- Nucleo-F103RB [v2-1] +- HY-STM32 (STM32F103VETx) [v1, v2] +- DecaWave EVB1000 (STM32F105RCTx) [v1, v2] **STM32F2 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32F2_CORE_ID)** -| Chip-ID | Product-Code | Product Line | -| --- | --- | --- | -| 0x411 | STM32F2yyxx | (all devices) | - +| Chip-ID | Product-Code | Product Line | +| ------- | ------------ | ------------- | +| 0x411 | STM32F2yyxx | (all devices) | **STM32F1 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM3F1c_CORE_ID)** -| Product-Code | Chip-ID | STLink
Programmer | Boards | -| --- | --- | --- | --- | -| CKS32F103C8Tx | 0x410 | v2 | "STM32"-Bluepill ( _**Fake-Marking !**_ )
STM32F103C8T6 clone from China Key Systems (CKS) | -| CKS32F103C8Tx | 0x410 | v2 | CKS32-Bluepill (Clone)
STM32F103C8T6 clone from China Key Systems (CKS) | - +| Product-Code | Chip-ID | STLink
Programmer | Boards | +| ------------- | ------- | ---------------------- | ----------------------------------------------------------------------------------------------- | +| CKS32F103C8Tx | 0x410 | v2 | "STM32"-Bluepill ( _**Fake-Marking !**_ )
STM32F103C8T6 clone from China Key Systems (CKS) | +| CKS32F103C8Tx | 0x410 | v2 | CKS32-Bluepill (Clone)
STM32F103C8T6 clone from China Key Systems (CKS) | **STM32F3 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F3_CORE_ID)** -| Product-Code | Product Line | -| --- | --- | -| STM32F3**01**yyxx | Access line (A) | -| STM32F3**02**yyxx | USB & CAN line (USB/CAN) | -| STM32F3**03**yyxx | Performance line (P) | -| STM32F3**34**yy | Digital Power line (DP) | -| STM32F3**73**yy | Precision Measurement line (PM) 64k/16k / 128k/24k / 265k/32k | -| STM32F3**18**yy | General Purpose line (GP) 64k/16k | -| STM32F3**28**yy | General Purpose line (GP) 64k/16k | -| STM32F3**58**yy | General Purpose line (GP) 265k/48k | -| STM32F3**78**yy | Precision Measurement line (PM) 265k/32k | -| STM32F3**98**yy | General Purpose line (GP) 512k/80k | - -| Chip-ID | Product Line | Code (yy) | A | USB/CAN | P | others | -| --- | --- | --- | --- | --- | --- | --- | -| 0x422 | _N/A_ | xB xC | | F302 | F303 | | -| 0x422 | _N/A_ | - | | | | F358 | +| Product-Code | Product Line | +| ----------------- | ------------------------------------------------------------- | +| STM32F3**01**yyxx | Access line (A) | +| STM32F3**02**yyxx | USB & CAN line (USB/CAN) | +| STM32F3**03**yyxx | Performance line (P) | +| STM32F3**34**yy | Digital Power line (DP) | +| STM32F3**73**yy | Precision Measurement line (PM) 64k/16k / 128k/24k / 265k/32k | +| STM32F3**18**yy | General Purpose line (GP) 64k/16k | +| STM32F3**28**yy | General Purpose line (GP) 64k/16k | +| STM32F3**58**yy | General Purpose line (GP) 265k/48k | +| STM32F3**78**yy | Precision Measurement line (PM) 265k/32k | +| STM32F3**98**yy | General Purpose line (GP) 512k/80k | + +| Chip-ID | Product Line | Code (yy) | A | USB/CAN | P | others | +| ------- | ------------ | --------- | ---- | ------- | ---- | -------------- | +| 0x422 | _N/A_ | xB xC | | F302 | F303 | | +| 0x422 | _N/A_ | - | | | | F358 | | 0x432 | _N/A_ | - | | | | F373
F378 | -| 0x438 | _N/A_ | x4 x6 x8 | | | F303 | | +| 0x438 | _N/A_ | x4 x6 x8 | | | F303 | | | 0x438 | _N/A_ | - | | | | F334
F328 | -| 0x439 | _N/A_ | x4 x6 x8 | F301 | F302 | | | -| 0x439 | _N/A_ | - | | | | F318 | -| 0x446 | _N/A_ | xD xE | | F302 | F303 | | -| 0x446 | _N/A_ | - | | | | F398 | +| 0x439 | _N/A_ | x4 x6 x8 | F301 | F302 | | | +| 0x439 | _N/A_ | - | | | | F318 | +| 0x446 | _N/A_ | xD xE | | F302 | F303 | | +| 0x446 | _N/A_ | - | | | | F398 | -Tested boards [incl. STLink programmers]: -* Nucleo-F302K8 [v2-1] -* Nucleo-F303K8 [v2-1] -* STM32F3348-Discovery [v2-1] -* Nucleo-F334R8 [v2-1] -* STM32F303-Discovery [v2] -* Nucleo-F303RE [v2-1] +Tested boards [incl. STLINK programmers]: +- Nucleo-F302K8 [v2-1] +- Nucleo-F303K8 [v2-1] +- Nucleo-F303RE [v2-1] +- Nucleo-F334R8 [v2-1] +- STM32F303-Discovery [v2] +- STM32F3348-Discovery [v2-1] **STM32F3 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F3c_CORE_ID)** -| Product-Code | Chip-ID | STLink
Programmer | Boards | -| --- | --- | --- | --- | -| GD32F303VGT6 | 0x430 | _N/A_ | STM32F303 clone from GigaDevice GD)
_unsupported_ | - +| Product-Code | Chip-ID | STLink
Programmer | Boards | +| ------------ | ------- | ---------------------- | ------------------------------------------------------ | +| GD32F303VGT6 | 0x430 | _N/A_ | STM32F303 clone from GigaDevice GD)
_unsupported_ | **STM32F4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F4_CORE_ID)** | Chip-ID | Product-Code | -| --- | --- | +| ------- | ------------------- | | 0x413 | STM32F4**0**xxx | | 0x413 | STM32F4**1**xxx | | 0x419 | STM32F4**2**xxx | @@ -139,20 +134,20 @@ Tested boards [incl. STLink programmers]: | 0x463 | STM32F4**13**xx | | 0x463 | STM32F4**23**xx | -Tested boards [incl. STLink programmers]: -* STM32F407-Discovery [v2] -* 32F411E-Discovery with gyro, audio [v2] -* 32F429I-Discovery with LCD [v2] -* 32F439VIT6-Discovery [v2] (reseated MCU) -* Nucleo-F401RE [v2-1] -* Nucleo-F411RE [v2-1] -* 32F413H-Discovery [v2-1] +Tested boards [incl. STLINK programmers]: +- Nucleo-F401RE [v2-1] +- Nucleo-F411RE [v2-1] +- STM32F407-Discovery [v2] +- STM32F411E-Discovery with gyro, audio [v2] +- STM32F413H-Discovery [v2-1] +- STM32F429I-Discovery with LCD [v2] +- STM32F439VIT6-Discovery [v2] (reseated MCU) **STM32F7 / ARM Cortex M7F / Core-ID: 0x5ba02477 (STM32F7_CORE_ID)** | Chip-ID | Product-Code | -| --- | --- | +| ------- | --------------- | | 0x452 | STM32F7**2**xxx | | 0x452 | STM32F7**3**xxx | | 0x449 | STM32F7**4**xxx | @@ -160,37 +155,45 @@ Tested boards [incl. STLink programmers]: | 0x451 | STM32F7**6**xxx | | 0x451 | STM32F7**7**xxx | -Tested boards [incl. STLink programmers]: -* STM32F756NGHx evaluation board [v2-1] -* 32F769I-Discovery [v2-1] -* Nucleo-F722ZE [v2-1] -* Nucleo-F746ZG [v2-1] +Tested boards [incl. STLINK programmers]: + +- Nucleo-F722ZE [v2-1] +- Nucleo-F746ZG [v2-1] +- STM32F756NGHx evaluation board [v2-1] +- STM32F769I-Discovery [v2-1] + +**STM32H7 / ARM Cortex M7F / Core-ID: 0x6ba02477 (STM32H7_CORE_ID)** + +| Chip-ID | Product-Code | +| ------- | -------------- | +| 0x450 | STM32H74x/H75x | + +Tested boards [incl. STLINK programmers]: +- Nucleo-H745I-Q [v3] **STM32G0 / ARM Cortex M0+ / Core-ID: 0x0bc11477 (STM32G0_CORE_ID)** | Chip-ID | Product-Code | -| --- | --- | +| ------- | --------------- | | 0x466 | STM32G0**3**xxx | | 0x466 | STM32G0**4**xxx | | 0x460 | STM32G0**7**xxx | | 0x460 | STM32G0**8**xxx | - **STM32G4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32G4_CORE_ID)** | Chip-ID | Product-Code | -| --- | --- | +| ------- | --------------- | | 0x468 | STM32G4**31**xx | | 0x468 | STM32G4**41**xx | | 0x469 | STM32G4**7**xxx | | 0x469 | STM32G4**8**xxx | - **STM32L0 / ARM Cortex M0+ / Core-ID: 0x0bc11477 (STM32L0_CORE_ID)** | Chip-ID | Product-Code | -| --- | --- | +| ------- | --------------- | | 0x457 | STM32L0**1**xxx | | 0x457 | STM32L0**2**xxx | | 0x425 | STM32L0**31**xx | @@ -200,14 +203,14 @@ Tested boards [incl. STLink programmers]: | 0x447 | STM32L0**7**xxx | | 0x447 | STM32L0**8**xxx | -Tested boards [incl. STLink programmers]: -* Nucleo-L053R8 [v2-1] +Tested boards [incl. STLINK programmers]: +- Nucleo-L053R8 [v2-1] **STM32L1 / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32L1_CORE_ID)** | Chip-ID | Product-Code | -| --- | --- | +| ------- | ---------------- | | 0x416 | STM32L1xxx**6** | | 0x416 | STM32L1xxx**8** | | 0x416 | STM32L1xxx**B** | @@ -218,42 +221,42 @@ Tested boards [incl. STLink programmers]: | 0x436 | STM32L1xxx**D** | | 0x437 | STM32L1xxx**E** | -Tested boards [incl. STLink programmers]: -* Nucleo-L152RE [v2-1] -* 32L152C-Discovery [v2] +Tested boards [incl. STLINK programmers]: +- Nucleo-L152RE [v2-1] +- STM32L152C-Discovery [v2] **STM32L4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32L4_CORE_ID)** -| Chip-ID | Product-Code | -| --- | --- | -| 0x464 | STM32L4**12**xx | -| 0x464 | STM32L4**22**xx | -| 0x435 | STM32L4**3**xxx | -| 0x435 | STM32L4**4**xxx | -| 0x462 | STM32L4**5**xxx | -| 0x462 | STM32L4**6**xxx | -| 0x415 | STM32L4**7**xxx | -| 0x415 | STM32L4**8**xxx | -| 0x461 | STM32L4**96**xx | -| 0x461 | STM32L4**A6**xx | -| 0x470 | STM32L4**R**xx | -| 0x470 | STM32L4**S**xx | -| 0x471 | STM32L4**P5**xx | -| 0x471 | STM32L4**Q5**xx | - -Tested boards [incl. STLink programmers]: -* Nucleo-L432KC [v2-1] -* Nucleo-L452RE [v2-1] -* Nucleo-L476RG [v2-1] -* Nucleo-L496ZG [v2-1] -* 32L4R9I-Discovery [v2-1] - +| Chip-ID | Product-Code | +| ------- | --------------- | +| 0x464 | STM32L4**12**xx | +| 0x464 | STM32L4**22**xx | +| 0x435 | STM32L4**3**xxx | +| 0x435 | STM32L4**4**xxx | +| 0x462 | STM32L4**5**xxx | +| 0x462 | STM32L4**6**xxx | +| 0x415 | STM32L4**7**xxx | +| 0x415 | STM32L4**8**xxx | +| 0x461 | STM32L4**96**xx | +| 0x461 | STM32L4**A6**xx | +| 0x470 | STM32L4**R**xx | +| 0x470 | STM32L4**S**xx | +| 0x471 | STM32L4**P5**xx | +| 0x471 | STM32L4**Q5**xx | + +Tested boards [incl. STLINK programmers]: + +- Nucleo-L432KC [v2-1] +- Nucleo-L452RE [v2-1] +- Nucleo-L476RG [v2-1] +- Nucleo-L496ZG [v2-1] +- STM32L4R9I-Discovery [v2-1] **STM32W / ARM Cortex M3 / Core-ID: 0x2ba01477 (STM32W_CORE_ID)** -| Chip-ID | Product-Code | -| --- | --- | -| 0x495 | STM32WB**50**xx | -| 0x495 | STM32WB**55**xx | -| 0x497 | STM32WLE**5**xx | +| Chip-ID | Product-Code | +| ------- | --------------- | +| 0x495 | STM32WB**50**xx | +| 0x495 | STM32WB**55**xx | +| 0x497 | STM32WLE**5**xx | diff --git a/doc/version_support.md b/doc/version_support.md index afa2d2bd7..eca491b79 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -1,8 +1,7 @@ - _Source:_ pkgs.org - [libusb](https://pkgs.org/search/?q=libusb); [cmake](https://pkgs.org/search/?q=cmake); [gtk](https://pkgs.org/search/?q=gtk) (as of Apr 2020) - ## Supported Operating Systems + ### Microsoft Windows On Windows users should ensure that cmake 3.17.0 is installed.
@@ -10,72 +9,69 @@ Up on compiling c-make will check **automatically**, whether `libusb` 1.0.20 or If this is not the case, the installation routine will download the latest version (1.0.23 at the time of writing).
Thus no user interaction regarding libusb is necessary. -* Windows 10 -* Windows 8.1 - +- Windows 10 +- Windows 8.1 ### Apple macOS -| Package Repository | libusb
version | cmake
version | gtk-3
version | Supported macOS versions | -| --- | --- | --- | --- | --- | -| homebrew | 1.0.23 | 3.17.0 | 3.24.18
gtk+3 | 10.12 (Sierra)- 10.15 (Catalina) | -| MacPorts | 1.0.23 | 3.17.0 | 3.24.18
gtk3 | 10.6 (Snow Leopard) - 10.15 (Catalina) | - -NOTE: In order to use a STLINK/v1 programmer on macOS, versions 10.14 or 10.15 are required. +| Package Repository | libusb
version | cmake
version | gtk-3
version | Supported macOS versions | +| ------------------ | ------------------- | ------------------ | ------------------ | -------------------------------------- | +| homebrew | 1.0.23 | 3.17.0 | 3.24.18
gtk+3 | 10.12 (Sierra)- 10.15 (Catalina) | +| MacPorts | 1.0.23 | 3.17.0 | 3.24.18
gtk3 | 10.6 (Snow Leopard) - 10.15 (Catalina) | +NOTE: In order to use a STLINK/V1 programmer on macOS, versions 10.14 or 10.15 are required. ### Linux-/Unix-based: -| Operating System | libusb
version | cmake
version | gtk-3
version | Notes | -| --- | --- | --- | --- | --- | -| Alpine Edge | 1.0.23 | 3.17.0 | 3.99.0
gtk+3.0 | | -| ALT Linux Sisyphus | 1.0.23 | 3.17.0 | 3.24.18
libgtk+3 | | -| Arch Linux | 1.0.23 | 3.17.0 | 3.24.18
gtk3 | | -| Fedora Rawhide | 1.0.23 | 3.17.0 | 3.24.18
gtk3 | | named `libusbx`, but
`libusb`-codebase is used | -| KaOS | 1.0.23 | 3.17.0 | 3.24.18
gtk3 | | -| OpenMandriva Cooker | 1.0.23 | 3.17.0 | 3.24.18
libgtk+3.0
lib64gtk+3.0 | | -| PCLinuxOS | 1.0.23
lib64usb1.0 | 3.17.0 | 3.24.18
lib64gtk+3.0 | | -| Slackware Current | 1.0.23 | 3.17.0 | 3.24.18
gtk+3 | | -| Solus | 1.0.23 | 3.16.5 | 3.24.16
libgtk-3 | | -| Debian Sid | 1.0.23 | 3.16.3 | 3.24.18
libgtk-3 | | -| OpenMandriva Lx 4.1 | 1.0.23 | 3.16.3 | 3.24.13
libgtk+3.0
lib64gtk+3.0 | | -| Ubuntu 20.04 LTS (Focal Fossa) | 1.0.23 | 3.16.3 | 3.24.17
libgtk-3 | | -| openSUSE Tumbleweed | 1.0.23 | 3.16.2 | 3.24.16
gtk3 | | -| Alpine 3.11 | 1.0.23 | 3.15.5 | 3.24.13
gtk+3.0 | | -| Ubuntu 19.10 (Eoan Ermine) | 1.0.23 | 3.13.4 | 3.24.12
libgtk-3 | | -| Mageia Cauldron | 1.0.22 | 3.17.0 | 3.24.18
libgtk+3.0
lib64gtk+3.0 | | -| NetBSD 9.0 | 1.0.22 | 3.16.1 | 3.24.12
gtk+3 | | -| NetBSD 8.1 | 1.0.22 | 3.16.1 | 3.24.12
gtk+3 | | -| NetBSD 7.2 | 1.0.22 | 3.16.1 | _N/A_ | | -| Alpine 3.10 | 1.0.22 | 3.14.5 | 3.24.8
gtk+3.0 | | -| Fedora 31 | 1.0.22 | 3.14.5 | 3.24.12
gtk3 | named `libusbx`, but
`libusb`-codebase is used | -| Mageia 7.1 | 1.0.22 | 3.14.3 | 3.24.8
libgtk+3.0
lib64gtk+3.0 | | -| Fedora 30 | 1.0.22 | 3.14.2 | 3.24.8
gtk3 | named `libusbx`, but
`libusb`-codebase is used | -| Debian 10 (Buster) | 1.0.22 | 3.13.4 | 3.24.5
libgtk-3 | | -| Alpine 3.9 | 1.0.22 | 3.13.0 | 3.24.1
gtk+3.0 | | -| CentOS 8 | 1.0.22 | 3.11.4 | 3.22.30
gtk3 | named `libusbx`, but
`libusb`-codebase is used | -| openSUSE Leap 15.2 | 1.0.21 | 3.15.5 | 3.24.14
gtk3 | | -| openSUSE Leap 15.1 | 1.0.21 | 3.10.2 | 3.22.30
gtk3 | | -| Ubuntu 18.04 LTS (Bionic Beaver) | 1.0.21 | 3.10.2 | 3.22.30
libgtk-3 | | -| Debian 9 (Stretch) | 1.0.21 | 3.7.2 | 3.22.11
libgtk-3 | | -| Slackware 14.2 | **1.0.20** | 3.5.2 | 3.18.9
gtk+3 | | -| Ubuntu 16.04 LTS (Xenial Xerus) | **1.0.20** | 3.5.1 | 3.18.9
libgtk-3 | | -| OpenMandriva Lx 3.0 | **1.0.20** | **3.4.2** | 3.18.9
libgtk+3.0
lib64gtk+3.0 | | -| FreeBSD 13 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
gtk3 | linux_libusb-13.0r358841
(integrated) | -| FreeBSD 12 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
gtk3 | linux_libusb-11.0r261448_4
(integrated) | -| FreeBSD 11 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
gtk3 | linux_libusb-11.0r261448_4
(integrated) | - +| Operating System | libusb
version | cmake
version | gtk-3
version | Notes | +| -------------------------------- | ----------------------- | ------------------ | ----------------------------------------- | --------------------------------------------------- | --------------------------------------------------- | +| Alpine Edge | 1.0.23 | 3.17.0 | 3.99.0
gtk+3.0 | | +| ALT Linux Sisyphus | 1.0.23 | 3.17.0 | 3.24.18
libgtk+3 | | +| Arch Linux | 1.0.23 | 3.17.0 | 3.24.18
gtk3 | | +| Fedora Rawhide | 1.0.23 | 3.17.0 | 3.24.18
gtk3 | | named `libusbx`, but
`libusb`-codebase is used | +| KaOS | 1.0.23 | 3.17.0 | 3.24.18
gtk3 | | +| OpenMandriva Cooker | 1.0.23 | 3.17.0 | 3.24.18
libgtk+3.0
lib64gtk+3.0 | | +| PCLinuxOS | 1.0.23
lib64usb1.0 | 3.17.0 | 3.24.18
lib64gtk+3.0 | | +| Slackware Current | 1.0.23 | 3.17.0 | 3.24.18
gtk+3 | | +| Solus | 1.0.23 | 3.16.5 | 3.24.16
libgtk-3 | | +| Debian Sid | 1.0.23 | 3.16.3 | 3.24.18
libgtk-3 | | +| OpenMandriva Lx 4.1 | 1.0.23 | 3.16.3 | 3.24.13
libgtk+3.0
lib64gtk+3.0 | | +| Ubuntu 20.04 LTS (Focal Fossa) | 1.0.23 | 3.16.3 | 3.24.17
libgtk-3 | | +| openSUSE Tumbleweed | 1.0.23 | 3.16.2 | 3.24.16
gtk3 | | +| Alpine 3.11 | 1.0.23 | 3.15.5 | 3.24.13
gtk+3.0 | | +| Ubuntu 19.10 (Eoan Ermine) | 1.0.23 | 3.13.4 | 3.24.12
libgtk-3 | | +| Mageia Cauldron | 1.0.22 | 3.17.0 | 3.24.18
libgtk+3.0
lib64gtk+3.0 | | +| NetBSD 9.0 | 1.0.22 | 3.16.1 | 3.24.12
gtk+3 | | +| NetBSD 8.1 | 1.0.22 | 3.16.1 | 3.24.12
gtk+3 | | +| NetBSD 7.2 | 1.0.22 | 3.16.1 | _N/A_ | | +| Alpine 3.10 | 1.0.22 | 3.14.5 | 3.24.8
gtk+3.0 | | +| Fedora 31 | 1.0.22 | 3.14.5 | 3.24.12
gtk3 | named `libusbx`, but
`libusb`-codebase is used | +| Mageia 7.1 | 1.0.22 | 3.14.3 | 3.24.8
libgtk+3.0
lib64gtk+3.0 | | +| Fedora 30 | 1.0.22 | 3.14.2 | 3.24.8
gtk3 | named `libusbx`, but
`libusb`-codebase is used | +| Debian 10 (Buster) | 1.0.22 | 3.13.4 | 3.24.5
libgtk-3 | | +| Alpine 3.9 | 1.0.22 | 3.13.0 | 3.24.1
gtk+3.0 | | +| CentOS 8 | 1.0.22 | 3.11.4 | 3.22.30
gtk3 | named `libusbx`, but
`libusb`-codebase is used | +| openSUSE Leap 15.2 | 1.0.21 | 3.15.5 | 3.24.14
gtk3 | | +| openSUSE Leap 15.1 | 1.0.21 | 3.10.2 | 3.22.30
gtk3 | | +| Ubuntu 18.04 LTS (Bionic Beaver) | 1.0.21 | 3.10.2 | 3.22.30
libgtk-3 | | +| Debian 9 (Stretch) | 1.0.21 | 3.7.2 | 3.22.11
libgtk-3 | | +| Slackware 14.2 | **1.0.20** | 3.5.2 | 3.18.9
gtk+3 | | +| Ubuntu 16.04 LTS (Xenial Xerus) | **1.0.20** | 3.5.1 | 3.18.9
libgtk-3 | | +| OpenMandriva Lx 3.0 | **1.0.20** | **3.4.2** | 3.18.9
libgtk+3.0
lib64gtk+3.0 | | +| FreeBSD 13 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
gtk3 | linux_libusb-13.0r358841
(integrated) | +| FreeBSD 12 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
gtk3 | linux_libusb-11.0r261448_4
(integrated) | +| FreeBSD 11 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
gtk3 | linux_libusb-11.0r261448_4
(integrated) | ## Unsupported Operating Systems (as of Release v1.6.1) -| Operating System | libusb
version | cmake
version | End of
OS-Support | Notes | -| --- | --- | --- | --- | --- | -| CentOS 7 | 1.0.21 | **2.8.12.2** | | named `libusbx`, but
`libusb`-codebase is used | -| Debian 8 (Jessie) | 1.0.**19** | 3.**0.2** | Jun 2020 | -| Ubuntu 14.04 LTS (Trusty Tahr) | 1.0.**17** | **2.8.12.2** | Apr 2019 | -| CentOS 6 | 1.0.**9** | **2.8.12.2** | Dec 2020 | named `libusbx`, but
`libusb`-codebase is used | -| Slackware 14.1 | 1.0.**9** | **2.8.12** | | -| Slackware 14.0 | 1.0.**9** | **2.8.8** | | +| Operating System | libusb
version | cmake
version | End of
OS-Support | Notes | +| ------------------------------ | ------------------- | ------------------ | ---------------------- | --------------------------------------------------- | +| CentOS 7 | 1.0.21 | **2.8.12.2** | | named `libusbx`, but
`libusb`-codebase is used | +| Debian 8 (Jessie) | 1.0.**19** | 3.**0.2** | Jun 2020 | +| Ubuntu 14.04 LTS (Trusty Tahr) | 1.0.**17** | **2.8.12.2** | Apr 2019 | +| CentOS 6 | 1.0.**9** | **2.8.12.2** | Dec 2020 | named `libusbx`, but
`libusb`-codebase is used | +| Slackware 14.1 | 1.0.**9** | **2.8.12** | | +| Slackware 14.0 | 1.0.**9** | **2.8.8** | | _All other operating systems which are not listed are unsupported._ From dcdbd61fda443c34d416d44237799a1c6e08d018 Mon Sep 17 00:00:00 2001 From: Michael Nolan Date: Wed, 17 Mar 2021 20:02:41 -0400 Subject: [PATCH 09/65] Consolidate core id read code --- src/common.c | 44 ++++++++++++-------------------------------- 1 file changed, 12 insertions(+), 32 deletions(-) diff --git a/src/common.c b/src/common.c index a064254d3..5f2746e3d 100644 --- a/src/common.c +++ b/src/common.c @@ -1221,43 +1221,23 @@ int stlink_core_id(stlink_t *sl) { int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { int ret; - if (sl->core_id == STM32H7_CORE_ID) { - /* STM32H7 chipid in 0x5c001000 (RM0433 pg3189) - * However, the STM32H7 is not the only chip with a JTAG - * IDCODE of 0x6ba02477, so we cannot rely solely on this info - * to select the address to read the chip id */ - - uint32_t cpu_id; - *chip_id = 0; - ret = -1; - - // Read the CPU ID as well to determine if this really is an H7 part - if (stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &cpu_id)) - cpu_id = 0; - - // If it is, read the chipid from the new address - if (sl->core_id == STM32H7_CORE_ID && cpu_id == STLINK_REG_CMx_CPUID_CM7) { - // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) - ret = stlink_read_debug32(sl, 0x5c001000, chip_id); - } - - if (*chip_id == 0) { - // default chipid address - ret = stlink_read_debug32(sl, 0xE0042000, chip_id); - } + uint32_t cpu_id; + *chip_id = 0; + ret = -1; - } else { - // default chipid address - ret = stlink_read_debug32(sl, 0xE0042000, chip_id); - } + // Read the CPU ID to determine where to read the core id from + if (stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &cpu_id)) + cpu_id = 0; - if (ret == -1) { - return(ret); + // If the chip is an H7, read the chipid from the new address + if (sl->core_id == STM32H7_CORE_ID && cpu_id == STLINK_REG_CMx_CPUID_CM7) { + // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) + ret = stlink_read_debug32(sl, 0x5c001000, chip_id); } if (*chip_id == 0) { - // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) - ret = stlink_read_debug32(sl, 0x5c001000, chip_id); + // default chipid address + ret = stlink_read_debug32(sl, 0xE0042000, chip_id); } if (*chip_id == 0) { From 9ed3d46c24c2a78d1e49474ec7529e7cd4c46d3b Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Tue, 16 Mar 2021 21:04:31 +0100 Subject: [PATCH 10/65] fix for stlink old DFU serial number omit the hla serial aka 'openocd serial' Only one valid serial is used which matches the serial as displayed in STM32CubeProgrammer and official ST tools. Signed-off-by: Tarek BOCHKATI --- doc/man/st-info.1 | 3 --- doc/man/st-info.md | 8 ++---- inc/stlink.h | 6 ++--- src/st-flash/flash.h | 2 +- src/st-flash/flash_opts.c | 12 +-------- src/st-info/info.c | 28 ++------------------- src/st-trace/trace.c | 19 +------------- src/st-util/gdb-server.c | 17 ++----------- src/stlink-lib/usb.c | 52 +++++++++++++++++++++++++++++++++------ src/stlink-lib/usb.h | 2 +- 10 files changed, 57 insertions(+), 92 deletions(-) diff --git a/doc/man/st-info.1 b/doc/man/st-info.1 index a0380f851..776ec7a3f 100644 --- a/doc/man/st-info.1 +++ b/doc/man/st-info.1 @@ -37,9 +37,6 @@ Display the chip ID of the device .B \-\-serial Display the serial code of the device .TP -.B \-\-hla\-serial -Display the hex escaped serial code of the device -.TP .B \-\-probe Display the summarized information of the connected programmers and devices diff --git a/doc/man/st-info.md b/doc/man/st-info.md index 9164642f2..91f9ea0b0 100644 --- a/doc/man/st-info.md +++ b/doc/man/st-info.md @@ -13,7 +13,7 @@ st-info - Provides information about connected STLink and STM32 devices # DESCRIPTION Provides information about connected STLink programmers and STM32 devices: -Serial code, OpenOCD hla-serial, flash, page size, sram, chipid, description. +Serial code, flash, page size, sram, chipid, description. The STLink device to probe can be specified via the environment variable STLINK_DEVICE on the format :. @@ -29,9 +29,6 @@ STLINK_DEVICE on the format :. \--serial : Display the serial code of the device -\--hla-serial -: Display the hex escaped serial code of the device - \--flash : Display amount of flash memory available in the device @@ -53,8 +50,7 @@ Display information about connected programmers and devices $ st-info --probe Found 1 stlink programmers - serial: 303033413030323233343338353130323334333133393339 - hla-serial: "\x30\x30\x33\x41\x30\x30\x32\x32\x33\x34\x33\x38\x35\x31\x30\x32\x33\x34\x33\x31\x33\x39\x33\x39" + serial: 57FF72067265575742132067 flash: 131072 (pagesize: 128) sram: 20480 chipid: 0x0447 diff --git a/inc/stlink.h b/inc/stlink.h index 9b5e56594..7bb1bc51e 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -79,7 +79,8 @@ enum target_state { #define STLINK_SWDCLK_15KHZ_DIVISOR 265 #define STLINK_SWDCLK_5KHZ_DIVISOR 798 -#define STLINK_SERIAL_MAX_SIZE 64 +#define STLINK_SERIAL_LENGTH 24 +#define STLINK_SERIAL_BUFFER_SIZE (STLINK_SERIAL_LENGTH + 1) #define STLINK_V3_MAX_FREQ_NB 10 @@ -191,8 +192,7 @@ struct _stlink { uint32_t chip_id; // set by stlink_load_device_params(), used to identify flash and sram enum target_state core_stat; // set by stlink_status() - char serial[STLINK_SERIAL_MAX_SIZE]; - int serial_size; + char serial[STLINK_SERIAL_BUFFER_SIZE]; int freq; // set by stlink_open_usb(), values: STLINK_SWDCLK_xxx_DIVISOR enum stlink_flash_type flash_type; diff --git a/src/st-flash/flash.h b/src/st-flash/flash.h index ca0ca2839..8a5c2ad29 100644 --- a/src/st-flash/flash.h +++ b/src/st-flash/flash.h @@ -14,7 +14,7 @@ enum flash_format {FLASH_FORMAT_BINARY = 0, FLASH_FORMAT_IHEX = 1}; enum flash_area {FLASH_MAIN_MEMORY = 0, FLASH_SYSTEM_MEMORY = 1, FLASH_OTP = 2, FLASH_OPTION_BYTES = 3, FLASH_OPTION_BYTES_BOOT_ADD = 4, FLASH_OPTCR = 5, FLASH_OPTCR1 = 6}; struct flash_opts { enum flash_cmd cmd; - uint8_t serial[STLINK_SERIAL_MAX_SIZE]; + uint8_t serial[STLINK_SERIAL_BUFFER_SIZE]; const char* filename; stm32_addr_t addr; size_t size; diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index 2ee19bd48..7d846e425 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -106,18 +106,8 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { serial = av[0] + strlen("--serial="); } - /** @todo This is not really portable, as strlen really returns size_t we need to obey - and not cast it to a signed type. */ - int j = (int)strlen(serial); - int length = j / 2; // the length of the destination-array + memcpy(o->serial, serial, STLINK_SERIAL_BUFFER_SIZE); - if (j % 2 != 0) { return(-1); } - - for (size_t k = 0; j >= 0 && k < sizeof(o->serial); ++k, j -= 2) { - char buffer[3] = {0}; - memcpy(buffer, serial + j, 2); - o->serial[length - k] = (uint8_t)strtol(buffer, NULL, 16); - } } else if (strcmp(av[0], "--area") == 0 || starts_with(av[0], "--area=")) { const char * area; diff --git a/src/st-info/info.c b/src/st-info/info.c index 0fc4d4d8a..c1ac86373 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -9,7 +9,6 @@ static void usage(void) { puts("st-info --version"); puts("st-info --probe"); puts("st-info --serial"); - puts("st-info --hla-serial"); puts("st-info --flash [--connect-under-reset]"); puts("st-info --pagesize [--connect-under-reset]"); puts("st-info --sram [--connect-under-reset]"); @@ -17,24 +16,6 @@ static void usage(void) { puts("st-info --descr [--connect-under-reset]"); } -/* Print normal or OpenOCD hla_serial with newline */ -static void stlink_print_serial(stlink_t *sl, bool openocd) { - const char *fmt; - - if (openocd) { - printf("\""); - fmt = "\\x%02x"; - } else { - fmt = "%02x"; - } - - for (int n = 0; n < sl->serial_size; n++) { printf(fmt, sl->serial[n]); } - - if (openocd) { printf("\""); } - - printf("\n"); -} - static void stlink_print_version(stlink_t *sl) { // Implementation of version printing is minimalistic // but contains all available information from sl->version @@ -53,10 +34,7 @@ static void stlink_print_info(stlink_t *sl) { printf(" version: "); stlink_print_version(sl); - printf(" serial: "); - stlink_print_serial(sl, false); - printf(" hla-serial: "); - stlink_print_serial(sl, true); + printf(" serial: %s\n", sl->serial); printf(" flash: %u (pagesize: %u)\n", (uint32_t)sl->flash_size, (uint32_t)sl->flash_pgsz); printf(" sram: %u\n", (uint32_t)sl->sram_size); @@ -131,9 +109,7 @@ static int print_data(int ac, char **av) { if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } if (strcmp(av[1], "--serial") == 0) { - stlink_print_serial(sl, false); - } else if (strcmp(av[1], "--hla-serial") == 0) { - stlink_print_serial(sl, true); + printf("%s\n", sl->serial); } else if (strcmp(av[1], "--flash") == 0) { printf("0x%x\n", (uint32_t)sl->flash_size); } else if (strcmp(av[1], "--pagesize") == 0) { diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 71ba6b360..3180335a0 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -191,25 +191,8 @@ bool parse_options(int argc, char** argv, st_settings_t *settings) { return true; } -static void convert_serial_number_text_to_binary(const char* text, char binary_out[STLINK_SERIAL_MAX_SIZE]) { - size_t length = 0; - for (uint32_t n = 0; n < strlen(text) && length < STLINK_SERIAL_MAX_SIZE; n += 2) { - char buffer[3] = { 0 }; - memcpy(buffer, text + n, 2); - binary_out[length++] = (uint8_t)strtol(buffer, NULL, 16); - } -} - static stlink_t* stlink_connect(const st_settings_t* settings) { - if (settings->serial_number) { - // Open this specific stlink. - char binary_serial_number[STLINK_SERIAL_MAX_SIZE] = { 0 }; - convert_serial_number_text_to_binary(settings->serial_number, binary_serial_number); - return stlink_open_usb(settings->logging_level, false, binary_serial_number, 0); - } else { - // Otherwise, open any stlink. - return stlink_open_usb(settings->logging_level, false, NULL, 0); - } + return stlink_open_usb(settings->logging_level, false, settings->serial_number, 0); } static bool enable_trace(stlink_t* stlink, const st_settings_t* settings, uint32_t trace_frequency) { diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 4177cef11..0f30c688a 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -43,7 +43,7 @@ static stlink_t *connected_stlink = NULL; static bool semihosting = false; static bool serial_specified = false; -static char serialnumber[STLINK_SERIAL_MAX_SIZE] = {0}; +static char serialnumber[STLINK_SERIAL_BUFFER_SIZE] = {0}; #if defined(_WIN32) #define close_socket win32_close_socket @@ -192,20 +192,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { break; case SERIAL_OPTION: printf("use serial %s\n", optarg); - /* TODO: This is not really portable, as strlen really returns size_t, - * we need to obey and not cast it to a signed type. - */ - int j = (int)strlen(optarg); - int length = j / 2; // the length of the destination-array - - if (j % 2 != 0) { return(-1); } - - for (size_t k = 0; j >= 0 && k < sizeof(serialnumber); ++k, j -= 2) { - char buffer[3] = {0}; - memcpy(buffer, optarg + j, 2); - serialnumber[length - k] = (uint8_t)strtol(buffer, NULL, 16); - } - + memcpy(serialnumber, optarg, STLINK_SERIAL_BUFFER_SIZE); serial_specified = true; break; } diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index d2b17fad6..569815665 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -1159,7 +1159,44 @@ static stlink_backend_t _stlink_usb_backend = { _stlink_usb_read_trace }; -stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq) { +/* return the length of serial or (0) in case of errors */ +size_t stlink_serial(struct libusb_device_handle *handle, struct libusb_device_descriptor *desc, char *serial) { + unsigned char desc_serial[(STLINK_SERIAL_LENGTH) * 2]; + + /* truncate the string in the serial buffer */ + serial[0] = '\0'; + + /* get the LANGID from String Descriptor Zero */ + int ret = libusb_get_string_descriptor(handle, 0, 0, desc_serial, sizeof(desc_serial)); + if (ret < 4) return 0; + + uint32_t langid = desc_serial[2] | (desc_serial[3] << 8); + + /* get the serial */ + ret = libusb_get_string_descriptor(handle, desc->iSerialNumber, langid, desc_serial, + sizeof(desc_serial)); + if (ret < 0) return 0; // could not read serial + + unsigned char len = desc_serial[0]; + + if (len == ((STLINK_SERIAL_LENGTH + 1) * 2)) { /* len == 50 */ + /* good ST-Link adapter */ + ret = libusb_get_string_descriptor_ascii( + handle, desc->iSerialNumber, (unsigned char *)serial, STLINK_SERIAL_BUFFER_SIZE); + if (ret < 0) return 0; + } else if (len == ((STLINK_SERIAL_LENGTH / 2 + 1) * 2)) { /* len == 26 */ + /* fix-up the buggy serial */ + for (unsigned int i = 0; i < STLINK_SERIAL_LENGTH; i += 2) + sprintf(serial + i, "%02X", desc_serial[i + 2]); + serial[STLINK_SERIAL_LENGTH] = '\0'; + } else { + return 0; + } + + return strlen(serial); +} + +stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STLINK_SERIAL_BUFFER_SIZE], int freq) { stlink_t* sl = NULL; struct stlink_libusb* slu = NULL; int ret = -1; @@ -1236,15 +1273,14 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STL if (ret) { continue; } // could not open device - sl->serial_size = libusb_get_string_descriptor_ascii( - handle, desc.iSerialNumber, (unsigned char *)sl->serial, sizeof(sl->serial)); + size_t serial_len = stlink_serial(handle, &desc, sl->serial); libusb_close(handle); - if (sl->serial_size < 0) { continue; } // could not read serial + if (serial_len != STLINK_SERIAL_LENGTH) { continue; } // could not read the serial // 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 (((serial == NULL) || (*serial == 0)) || (memcmp(serial, &sl->serial, STLINK_SERIAL_LENGTH) == 0)) { if (STLINK_V1_USB_PID(desc.idProduct)) { slu->protocoll = 1; sl->version.stlink_v = 1; @@ -1433,7 +1469,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { if (!STLINK_SUPPORTED_USB_PID(desc.idProduct)) { continue; } struct libusb_device_handle* handle; - char serial[STLINK_SERIAL_MAX_SIZE] = {0, }; + char serial[STLINK_SERIAL_BUFFER_SIZE] = {0, }; ret = libusb_open(dev, &handle); @@ -1447,11 +1483,11 @@ 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)); + size_t serial_len = stlink_serial(handle, &desc, serial); libusb_close(handle); - if (ret < 0) { continue; } + if (serial_len != STLINK_SERIAL_LENGTH) { continue; } stlink_t *sl = stlink_open_usb(0, 1, serial, 0); diff --git a/src/stlink-lib/usb.h b/src/stlink-lib/usb.h index 717a82f6d..512370a10 100644 --- a/src/stlink-lib/usb.h +++ b/src/stlink-lib/usb.h @@ -67,7 +67,7 @@ struct stlink_libusb { * @retval NULL Error while opening the stlink * @retval !NULL Stlink found and ready to use */ -stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq); +stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STLINK_SERIAL_BUFFER_SIZE], int freq); size_t stlink_probe_usb(stlink_t **stdevs[]); void stlink_probe_usb_free(stlink_t **stdevs[], size_t size); From d9726fa86da888f54e463b21f624ee27e208e3a0 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Wed, 17 Mar 2021 12:38:38 +0500 Subject: [PATCH 11/65] Updated a target resetting documentation --- doc/man/st-flash.1 | 2 +- doc/man/st-flash.md | 2 +- doc/tutorial.md | 19 ++++++++++--------- src/st-flash/flash.c | 4 ++-- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/doc/man/st-flash.1 b/doc/man/st-flash.1 index c2654f280..086046d2c 100644 --- a/doc/man/st-flash.1 +++ b/doc/man/st-flash.1 @@ -41,7 +41,7 @@ Print version information TODO .TP --reset -TODO +Trigger a reset both before and after flashing .TP --opt Enable ignore ending empty bytes optimization diff --git a/doc/man/st-flash.md b/doc/man/st-flash.md index d5565e923..80130c8f1 100644 --- a/doc/man/st-flash.md +++ b/doc/man/st-flash.md @@ -46,7 +46,7 @@ reset : TODO \--reset -: TODO +: Trigger a reset both before and after flashing \--opt : Enable ignore ending empty bytes optimization diff --git a/doc/tutorial.md b/doc/tutorial.md index 3a0f16fd9..d4cf89ce2 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -2,14 +2,15 @@ ## Available tools and options -| Option | Tool | Description | Available
since | -| --------------- | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| --flash=n[k][m] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k
for the STM32F103C8T6 to assume 128k of flash being present. This option accepts
decimal (128k), octal 0200k, or hex 0x80k values. Leaving the multiplier out is
equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional "k"
or "m" to multiply the given value by 1k (1024) or 1M respectively. | v1.4.0 | -| --freq=n[k][m] | st-flash | The frequency of the SWD/JTAG interface can be specified, to override the default
1800 kHz configuration. This option solely accepts decimal values (5K or 1.8M) with
the unit `Hz` being left out. Valid frequencies are: `5K, 15K, 25K, 50K, 100K,`
`125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)`. | v1.6.1 | -| --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at
the end of binary file. This may cause some garbage data left after a flash operation.
This option was enabled by default in earlier releases. | v1.6.1 | -| --reset | st-flash | Trigger a reset both before and after flashing. | v1.0.0 | -| --version | st-info,
st-flash,
st-util | Print version information. | | -| --help | st-flash,
st-util | Print list of available commands. _(To be added to this table.)_ | | +| Option | Tool | Description | Available
since | +| --------------------- | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | +| --flash=n[k][m] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k
for the STM32F103C8T6 to assume 128k of flash being present. This option accepts
decimal (128k), octal 0200k, or hex 0x80k values. Leaving the multiplier out is
equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional "k"
or "m" to multiply the given value by 1k (1024) or 1M respectively. | v1.4.0 | +| --freq=n[k][m] | st-flash | The frequency of the SWD/JTAG interface can be specified, to override the default
1800 kHz configuration. This option solely accepts decimal values (5K or 1.8M) with
the unit `Hz` being left out. Valid frequencies are: `5K, 15K, 25K, 50K, 100K,`
`125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)`. | v1.6.1 | +| --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at
the end of binary file. This may cause some garbage data left after a flash operation.
This option was enabled by default in earlier releases. | v1.6.1 | +| --reset | st-flash | Trigger a reset both before and after flashing. The default use the hardware reset
through `NRST` pin. The software system reset is used if the hardware reset failed
(`NRST` pin not connected). | v1.0.0 | +| --connect-under-reset | st-flash | Connect under reset. Option makes it possible to connect to the device before code
executing. This is useful when the target contains a code that go device to sleep,
disables of debug pins or other special code. | v1.6.1 | +| --version | st-info
st-flash
st-util | Print version information. | | +| --help | st-flash
st-util | Print list of available commands. _(To be added to this table.)_ | | ### st-flash: Checksum for binary files @@ -272,7 +273,7 @@ In order to continue, one can use 'monitor reset' to reset the MCU. Remember that you can shorten the commands. `tar ext :4242` is good enough for GDB. -If you need to send a hard reset signal through `NRST` pin, you can use the following command: +If you need to send a reset signal, you can use the following command: ``` (gdb) monitor jtag_reset diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index d8bd8772c..447daa158 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -26,8 +26,8 @@ static void cleanup(int signum) { } static void usage(void) { - puts("command line: ./st-flash [--debug] [--reset] [--opt] [--serial ] [--format ] [--flash=] [--freq=] [--area=] {read|write} [path] [addr] [size]"); - puts("command line: ./st-flash [--debug] [--freq=] [--serial ] erase"); + puts("command line: ./st-flash [--debug] [--reset] [--connect-under-reset] [--opt] [--serial ] [--format ] [--flash=] [--freq=] [--area=] {read|write} [path] [addr] [size]"); + puts("command line: ./st-flash [--debug] [--connect-under-reset] [--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)"); From ebcf04f02bcb47f0d34d0b0a4992007ee19bfe5c Mon Sep 17 00:00:00 2001 From: anton Date: Wed, 17 Mar 2021 20:32:20 +0500 Subject: [PATCH 12/65] flash_loader: used timeout in ms --- src/stlink-lib/flash_loader.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index b55953406..1224215e5 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -3,6 +3,7 @@ #include #include +#include #include "flash_loader.h" #define FLASH_REGS_BANK2_OFS 0x40 @@ -313,7 +314,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) { struct stlink_reg rr; - int i = 0; + unsigned timeout; size_t count = 0; uint32_t flash_base = 0; const char *error = NULL; @@ -368,16 +369,19 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe * the OS uses, the wait until the error message is reduced to the same order of magnitude * as what was intended. -- REW. */ -#define WAIT_ROUNDS 40 // wait until done (reaches breakpoint) - for (i = 0; i < WAIT_ROUNDS; i++) { + timeout = time_ms() + 500; + while (time_ms() < timeout) { usleep(10000); - if (stlink_is_core_halted(sl)) { break; } + if (stlink_is_core_halted(sl)) { + timeout = 0; + break; + } } - if (i >= WAIT_ROUNDS) { + if (timeout) { error = "Flash loader run error"; goto error; } From 41bbbc2e9650f873fa562977ac89242fd4ac19fe Mon Sep 17 00:00:00 2001 From: anton Date: Thu, 18 Mar 2021 19:28:40 +0500 Subject: [PATCH 13/65] flash_loader: fix check BUSY flag, code simplified --- flashloaders/Makefile | 75 ++++++++---- flashloaders/cleanroom.md | 38 +++---- flashloaders/stm32f0.s | 78 +++++++------ flashloaders/stm32f4.s | 32 ++++-- flashloaders/stm32f4lv.s | 38 ++++--- flashloaders/stm32f7.s | 32 ++++-- flashloaders/stm32f7lv.s | 38 ++++--- flashloaders/stm32l0x.s | 22 ---- flashloaders/stm32l4.s | 32 ++++-- flashloaders/stm32lx.s | 26 +++-- src/stlink-lib/flash_loader.c | 207 ++++++++++++++-------------------- src/stlink-lib/reg.h | 6 + 12 files changed, 320 insertions(+), 304 deletions(-) delete mode 100644 flashloaders/stm32l0x.s diff --git a/flashloaders/Makefile b/flashloaders/Makefile index 7b17cb2a0..3517e1499 100644 --- a/flashloaders/Makefile +++ b/flashloaders/Makefile @@ -4,35 +4,60 @@ # This makefile will save your time from dealing with compile errors # Adjust CC if needed -CC = /opt/local/gcc-arm-none-eabi-8-2018-q4-major/bin/arm-none-eabi-gcc - -CFLAGS_thumb1 = -mcpu=Cortex-M0 -Tlinker.ld -ffreestanding -nostdlib -CFLAGS_thumb2 = -mcpu=Cortex-M3 -Tlinker.ld -ffreestanding -nostdlib - -all: stm32vl.o stm32f0.o stm32l.o stm32f4.o stm32f4_lv.o stm32l4.o stm32f7.o stm32f7_lv.o - -stm32vl.o: stm32f0.s - $(CC) stm32f0.s $(CFLAGS_thumb2) -o stm32vl.o -stm32f0.o: stm32f0.s - $(CC) stm32f0.s $(CFLAGS_thumb1) -o stm32f0.o -stm32l.o: stm32lx.s - $(CC) stm32lx.s $(CFLAGS_thumb2) -o stm32l.o -stm32f4.o: stm32f4.s - $(CC) stm32f4.s $(CFLAGS_thumb2) -o stm32f4.o -stm32f4_lv.o: stm32f4lv.s - $(CC) stm32f4lv.s $(CFLAGS_thumb2) -o stm32f4_lv.o -stm32l4.o: stm32l4.s - $(CC) stm32l4.s $(CFLAGS_thumb2) -o stm32l4.o -stm32f7.o: stm32f7.s - $(CC) stm32f7.s $(CFLAGS_thumb2) -o stm32f7.o -stm32f7_lv.o: stm32f7lv.s - $(CC) stm32f7lv.s $(CFLAGS_thumb2) -o stm32f7_lv.o +CROSS_COMPILE ?= /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi- -clean: - rm *.o +CC = $(CROSS_COMPILE)gcc +OBJCOPY = $(CROSS_COMPILE)objcopy + +XXD = xxd +XXDFLAGS = -i -c 4 + +CFLAGS_THUMB1 = -mcpu=Cortex-M0 -Tlinker.ld -ffreestanding -nostdlib +CFLAGS_THUMB2 = -mcpu=Cortex-M3 -Tlinker.ld -ffreestanding -nostdlib + +all: stm32vl.h stm32f0.h stm32lx.h stm32f4.h stm32f4lv.h stm32l4.h stm32f7.h stm32f7lv.h +stm32f0.h: stm32f0.s + $(CC) stm32f0.s $(CFLAGS_THUMB1) -o stm32f0.o + $(OBJCOPY) -O binary stm32f0.o stm32f0.bin + $(XXD) $(XXDFLAGS) stm32f0.bin stm32f0.h +stm32vl.h: stm32f0.s + $(CC) stm32f0.s $(CFLAGS_THUMB2) -o stm32vl.o + $(OBJCOPY) -O binary stm32vl.o stm32vl.bin + $(XXD) $(XXDFLAGS) stm32vl.bin stm32vl.h +stm32lx.h: stm32lx.s + $(CC) stm32lx.s $(CFLAGS_THUMB2) -o stm32lx.o + $(OBJCOPY) -O binary stm32lx.o stm32lx.bin + $(XXD) $(XXDFLAGS) stm32lx.bin stm32lx.h +stm32f4.h: stm32f4.s + $(CC) stm32f4.s $(CFLAGS_THUMB2) -o stm32f4.o + $(OBJCOPY) -O binary stm32f4.o stm32f4.bin + $(XXD) $(XXDFLAGS) stm32f4.bin stm32f4.h +stm32f4lv.h: stm32f4lv.s + $(CC) stm32f4lv.s $(CFLAGS_THUMB2) -o stm32f4lv.o + $(OBJCOPY) -O binary stm32f4lv.o stm32f4lv.bin + $(XXD) $(XXDFLAGS) stm32f4lv.bin stm32f4lv.h +stm32l4.h: stm32l4.s + $(CC) stm32l4.s $(CFLAGS_THUMB2) -o stm32l4.o + $(OBJCOPY) -O binary stm32l4.o stm32l4.bin + $(XXD) $(XXDFLAGS) stm32l4.bin stm32l4.h + +stm32f7.h: stm32f7.s + $(CC) stm32f7.s $(CFLAGS_THUMB2) -o stm32f7.o + $(OBJCOPY) -O binary stm32f7.o stm32f7.bin + $(XXD) $(XXDFLAGS) stm32f7.bin stm32f7.h + +stm32f7lv.h: stm32f7lv.s + $(CC) stm32f7lv.s $(CFLAGS_THUMB2) -o stm32f7lv.o + $(OBJCOPY) -O binary stm32f7lv.o stm32f7lv.bin + $(XXD) $(XXDFLAGS) stm32f7lv.bin stm32f7lv.h + +clean: + rm *.o + rm *.bin + rm *.h diff --git a/flashloaders/cleanroom.md b/flashloaders/cleanroom.md index a468efe49..b2cb9f00d 100644 --- a/flashloaders/cleanroom.md +++ b/flashloaders/cleanroom.md @@ -1,6 +1,4 @@ -Original Chinese version can be found below. - -# Clean Room Documentation English Version +# Flash Loader Documentation Code is situated in section `.text` @@ -12,11 +10,12 @@ All parameters would be passed over registers `r0`: the base address of the copy source `r1`: the base address of the copy destination -`r2`: the total word (4 bytes) count to be copied (with expeptions) +`r2`: the count of byte to be copied +`r3`: flash register offset (used to support two banks) **What the program is expected to do**: -Copy data from source to destination, after which trigger a breakpint to exit. Before exit, `r2` must be cleared to zero to indicate that the copy is done. +Copy data from source to destination, after which trigger a breakpint to exit. Before exit, `r2` must be less or equal to zero to indicate that the copy is done. **Limitation**: No stack operations are permitted. Registers ranging from `r3` to `r12` are free to use. Note that `r13` is `sp`(stack pointer), `r14` is `lr`(commonly used to store jump address), `r15` is `pc`(program counter). @@ -24,8 +23,6 @@ Copy data from source to destination, after which trigger a breakpint to exit. B ## stm32f0.s -**Exception**: `r2` stores the total half word (2 bytes) count to be copied - `flash_base`: 0x40022000 `FLASH_CR`: offset from `flash_base` is 16 @@ -37,11 +34,11 @@ Copy data from source to destination, after which trigger a breakpint to exit. B **Special requirements**: -Before every copy, read a word from FLASH_CR, set the lowest bit to 1 and write back. Copy one half word each time. +Before every copy, read a word from FLASH_CR, set the PG bit to 1 and write back. Copy one half word each time. -How to wait for the write process: read a word from FLASH_SR, loop until the content is not 1. After that, check FLASH_SR, proceed if the content is 4, otherwise exit. +How to wait for the write process: read a word from FLASH_SR, loop until the busy bit is reset. After that, FLASH_SR is check. The process is interrupted if the error bit (0x04) is set. -Exit: after the copying process and before triggering the breakpoint, clear the lowest bit in FLASH_CR. +Exit: after the copying process and before triggering the breakpoint, clear the PG bit in FLASH_CR. ## stm32f4.s @@ -56,7 +53,8 @@ Exit: after the copying process and before triggering the breakpoint, clear the **Special requirements**: Copy one word each time. -How to wait for the write process: read a half word from FLASH_SR, loop until the content is not 1. + +How to wait for the write process: read a word from FLASH_SR, loop until the busy bit is reset. ## stm32f4lv.s @@ -71,7 +69,7 @@ How to wait for the write process: read a half word from FLASH_SR, loop until th Copy one byte each time. -How to wait from the write process: read a half word from FLASH_SR, loop until the content is not 1. +How to wait from the write process: read a half word from FLASH_SR, loop until the busy bit is reset. ## stm32f7.s @@ -89,7 +87,7 @@ Mostly same with `stm32f4.s`. Require establishing a memory barrier after every Mostly same with `stm32f7.s`. Copy one byte each time. -## stm32l0x.s +## stm32lx.s **Special Requirements**: @@ -97,8 +95,6 @@ Copy one word each time. No wait for write. ## stm32l4.s -**Exception**: r2 stores the double word count to be copied. - `flash_base`: 0x40022000 `FLASH_BSY`: offset from `flash_base` is 0x12 @@ -109,14 +105,10 @@ Copy one word each time. No wait for write. Copy one double word each time (More than one registers are allowed). -How to wait for the write process: read a half word from `FLASH_BSY`, loop until the lowest bit turns non-1. - -## stm32lx.s +How to wait for the write process: read a half word from `FLASH_BSY`, loop until the busy bit is reset. -Same with stm32l0x.s. - -# 净室工程文档-原始中文版 +# 净室工程文档-原始中文版 (out of date) 代码位于的section:`.text` 编译制导添加`.syntax unified` @@ -139,8 +131,6 @@ Same with stm32l0x.s. ## stm32f0.s -例外:`r2`:拷贝half word(2字节)数 - 特殊地址定义:`flash_base`:定义为0x40022000 `FLASH_CR`: 相对`flash_base`的offset为16 @@ -230,4 +220,4 @@ Same with stm32l0x.s. ## stm32lx.s -要求与stm32l0x.s相同 \ No newline at end of file +要求与stm32l0x.s相同 diff --git a/flashloaders/stm32f0.s b/flashloaders/stm32f0.s index f30e4bfc6..e2a4b0f00 100644 --- a/flashloaders/stm32f0.s +++ b/flashloaders/stm32f0.s @@ -1,6 +1,14 @@ .syntax unified .text + /* + * Arguments: + * r0 - source memory ptr + * r1 - target memory ptr + * r2 - count of bytes + * r3 - flash register offset + */ + .global copy copy: /* @@ -17,54 +25,56 @@ copy: */ nop nop - ldr r7, =flash_base - ldr r4, [r7] - ldr r7, =flash_off_cr - ldr r6, [r7] - adds r6, r6, r4 - ldr r7, =flash_off_sr - ldr r5, [r7] - adds r5, r5, r4 -loop: - # FLASH_CR ^= 1 + # load flash control register address + # add r3 to flash_base for support dual bank (see flash_loader.c) + ldr r7, flash_base + add r7, r7, r3 + ldr r6, flash_off_cr + add r6, r6, r7 + ldr r5, flash_off_sr + add r5, r5, r7 + + # FLASH_CR |= 0x01 (set PG) ldr r7, =0x1 - ldr r3, [r6] - orrs r3, r3, r7 - str r3, [r6] + ldr r4, [r6] + orrs r4, r4, r7 + str r4, [r6] +loop: # copy 2 bytes - ldrh r3, [r0] - strh r3, [r1] + ldrh r4, [r0] + strh r4, [r1] - ldr r7, =2 - adds r0, r0, r7 - adds r1, r1, r7 + # increment address + adds r0, r0, #0x2 + adds r1, r1, #0x2 - # wait if FLASH_SR == 1 + # BUSY flag + ldr r7, =0x01 wait: - ldr r7, =0x1 - ldr r3, [r5] - tst r3, r7 - beq wait + # get FLASH_SR + ldr r4, [r5] - # exit if FLASH_SR != 4 - ldr r7, =0x4 - tst r3, r7 + # wait until BUSY flag is reset + tst r4, r7 + bne wait + + # test PGERR or WRPRTERR flag is reset + ldr r7, =0x14 + tst r4, r7 bne exit - # loop if r2 != 0 - ldr r7, =0x1 - subs r2, r2, r7 - cmp r2, #0 - bne loop + # loop if count > 0 + subs r2, r2, #0x2 + bgt loop exit: # FLASH_CR &= ~1 ldr r7, =0x1 - ldr r3, [r6] - bics r3, r3, r7 - str r3, [r6] + ldr r4, [r6] + bics r4, r4, r7 + str r4, [r6] bkpt diff --git a/flashloaders/stm32f4.s b/flashloaders/stm32f4.s index a88ad9e02..a66c70dac 100644 --- a/flashloaders/stm32f4.s +++ b/flashloaders/stm32f4.s @@ -1,6 +1,14 @@ .syntax unified .text + /* + * Arguments: + * r0 - source memory ptr + * r1 - target memory ptr + * r2 - count of bytes + * r3 - flash register offset + */ + .global copy copy: ldr r12, flash_base @@ -9,22 +17,24 @@ copy: loop: # copy 4 bytes - ldr r3, [r0] - str r3, [r1] + ldr r4, [r0] + str r4, [r1] + # increment address add r0, r0, #4 add r1, r1, #4 - # wait if FLASH_SR == 1 wait: - ldrh r3, [r10] - tst r3, #0x1 - beq wait - - # loop if r2 != 0 - sub r2, r2, #1 - cmp r2, #0 - bne loop + # get FLASH_SR + ldrh r4, [r10] + + # wait until BUSY flag is reset + tst r4, #0x1 + bne wait + + # loop if count > 0 + subs r2, r2, #4 + bgt loop exit: bkpt diff --git a/flashloaders/stm32f4lv.s b/flashloaders/stm32f4lv.s index 41467a9ef..b8fcfa048 100644 --- a/flashloaders/stm32f4lv.s +++ b/flashloaders/stm32f4lv.s @@ -1,36 +1,40 @@ .syntax unified .text + /* + * Arguments: + * r0 - source memory ptr + * r1 - target memory ptr + * r2 - count of bytes + * r3 - flash register offset + */ + .global copy copy: ldr r12, flash_base ldr r10, flash_off_sr add r10, r10, r12 - # tip 1: original r2 indicates the count of 4 bytes need to copy, - # but we can only copy one byte each time. - # as we have no flash larger than 1GB, we do a little trick here. - # tip 2: r2 is always a power of 2 - mov r2, r2, lsl#2 - loop: # copy 1 byte - ldrb r3, [r0] - strb r3, [r1] + ldrb r4, [r0] + strb r4, [r1] + # increment address add r0, r0, #1 add r1, r1, #1 - # wait if FLASH_SR == 1 wait: - ldrh r3, [r10] - tst r3, #0x1 - beq wait - - # loop if r2 != 0 - sub r2, r2, #1 - cmp r2, #0 - bne loop + # get FLASH_SR + ldrh r4, [r10] + + # wait until BUSY flag is reset + tst r4, #0x1 + bne wait + + # loop if count > 0 + subs r2, r2, #1 + bgt loop exit: bkpt diff --git a/flashloaders/stm32f7.s b/flashloaders/stm32f7.s index 3779a5ea6..4b43cebdc 100644 --- a/flashloaders/stm32f7.s +++ b/flashloaders/stm32f7.s @@ -1,6 +1,14 @@ .syntax unified .text + /* + * Arguments: + * r0 - source memory ptr + * r1 - target memory ptr + * r2 - count of bytes + * r3 - flash register offset + */ + .global copy copy: ldr r12, flash_base @@ -9,25 +17,27 @@ copy: loop: # copy 4 bytes - ldr r3, [r0] - str r3, [r1] + ldr r4, [r0] + str r4, [r1] + # increment address add r0, r0, #4 add r1, r1, #4 # memory barrier dsb sy - # wait if FLASH_SR == 1 wait: - ldrh r3, [r10] - tst r3, #0x1 - beq wait - - # loop if r2 != 0 - sub r2, r2, #1 - cmp r2, #0 - bne loop + # get FLASH_SR + ldrh r4, [r10] + + # wait until BUSY flag is reset + tst r4, #0x1 + bne wait + + # loop if count > 0 + subs r2, r2, #4 + bgt loop exit: bkpt diff --git a/flashloaders/stm32f7lv.s b/flashloaders/stm32f7lv.s index e7b66cc2c..78ff35dbc 100644 --- a/flashloaders/stm32f7lv.s +++ b/flashloaders/stm32f7lv.s @@ -1,39 +1,43 @@ .syntax unified .text + /* + * Arguments: + * r0 - source memory ptr + * r1 - target memory ptr + * r2 - count of bytes + * r3 - flash register offset + */ + .global copy copy: ldr r12, flash_base ldr r10, flash_off_sr add r10, r10, r12 - # tip 1: original r2 indicates the count in 4 bytes need to copy, - # but we can only copy one byte each time. - # as we have no flash larger than 1GB, we do a little trick here. - # tip 2: r2 is always a power of 2 - mov r2, r2, lsl#2 - loop: # copy 1 byte - ldrb r3, [r0] - strb r3, [r1] + ldrb r4, [r0] + strb r4, [r1] + # increment address add r0, r0, #1 add r1, r1, #1 # memory barrier dsb sy - # wait if FLASH_SR == 1 wait: - ldrh r3, [r10] - tst r3, #0x1 - beq wait - - # loop if r2 != 0 - sub r2, r2, #1 - cmp r2, #0 - bne loop + # get FLASH_SR + ldrh r4, [r10] + + # wait until BUSY flag is reset + tst r4, #0x1 + bne wait + + # loop if count > 0 + subs r2, r2, #1 + bgt loop exit: bkpt diff --git a/flashloaders/stm32l0x.s b/flashloaders/stm32l0x.s deleted file mode 100644 index f9c257e2e..000000000 --- a/flashloaders/stm32l0x.s +++ /dev/null @@ -1,22 +0,0 @@ - .syntax unified - .text - - .global copy -copy: -loop: - # copy 4 bytes - ldr r3, [r0] - str r3, [r1] - - ldr r7, =4 - add r0, r0, r7 - add r1, r1, r7 - - # loop if r2 != 0 - ldr r7, =1 - subs r2, r2, r7 - cmp r2, #0 - bne loop - -exit: - bkpt diff --git a/flashloaders/stm32l4.s b/flashloaders/stm32l4.s index 32c27a057..21e926f49 100644 --- a/flashloaders/stm32l4.s +++ b/flashloaders/stm32l4.s @@ -1,6 +1,14 @@ .syntax unified .text + /* + * Arguments: + * r0 - source memory ptr + * r1 - target memory ptr + * r2 - count of bytes + * r3 - flash register offset + */ + .global copy copy: ldr r12, flash_base @@ -9,24 +17,26 @@ copy: loop: # copy 8 bytes - ldr r3, [r0] + ldr r5, [r0] ldr r4, [r0, #4] - str r3, [r1] + str r5, [r1] str r4, [r1, #4] + # increment address add r0, r0, #8 add r1, r1, #8 - # wait if FLASH_BSY[0b] == 1 wait: - ldrh r3, [r10] - tst r3, #0x1 - beq wait - - # loop if r2 != 0 - sub r2, r2, #1 - cmp r2, #0 - bne loop + # get FLASH_SR + ldr r4, [r10] + + # wait until BUSY flag is reset + tst r4, #0x10000 + bne wait + + # loop if count > 0 + subs r2, r2, #8 + bgt loop exit: bkpt diff --git a/flashloaders/stm32lx.s b/flashloaders/stm32lx.s index f9c257e2e..69acdea7b 100644 --- a/flashloaders/stm32lx.s +++ b/flashloaders/stm32lx.s @@ -1,22 +1,28 @@ .syntax unified .text + /* + * Arguments: + * r0 - source memory ptr + * r1 - target memory ptr + * r2 - count of bytes + * r3 - flash register offset + */ + .global copy copy: loop: # copy 4 bytes - ldr r3, [r0] - str r3, [r1] + ldr r4, [r0] + str r4, [r1] - ldr r7, =4 - add r0, r0, r7 - add r1, r1, r7 + # increment address + add r0, r0, #4 + add r1, r1, #4 - # loop if r2 != 0 - ldr r7, =1 - subs r2, r2, r7 - cmp r2, #0 - bne loop + # loop if count > 0 + subs r2, r2, #4 + bgt loop exit: bkpt diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 1224215e5..5bc314b07 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -13,89 +13,72 @@ /* flashloaders/stm32f0.s -- compiled with thumb2 */ static const uint8_t loader_code_stm32vl[] = { - 0x16, 0x4f, 0x3c, 0x68, - 0x16, 0x4f, 0x3e, 0x68, - 0x36, 0x19, 0x16, 0x4f, - 0x3d, 0x68, 0x2d, 0x19, + 0x00, 0xbf, 0x00, 0xbf, + 0x0f, 0x4f, 0x1f, 0x44, + 0x0f, 0x4e, 0x3e, 0x44, + 0x0f, 0x4d, 0x3d, 0x44, 0x4f, 0xf0, 0x01, 0x07, - 0x33, 0x68, 0x3b, 0x43, - 0x33, 0x60, 0x03, 0x88, - 0x0b, 0x80, 0x4f, 0xf0, - 0x02, 0x07, 0xc0, 0x19, - 0xc9, 0x19, 0x4f, 0xf0, - 0x01, 0x07, 0x2b, 0x68, - 0x3b, 0x42, 0xfa, 0xd0, - 0x4f, 0xf0, 0x04, 0x07, - 0x3b, 0x42, 0x04, 0xd1, + 0x34, 0x68, 0x3c, 0x43, + 0x34, 0x60, 0x04, 0x88, + 0x0c, 0x80, 0x02, 0x30, + 0x02, 0x31, 0x4f, 0xf0, + 0x01, 0x07, 0x2c, 0x68, + 0x3c, 0x42, 0xfc, 0xd1, + 0x4f, 0xf0, 0x14, 0x07, + 0x3c, 0x42, 0x01, 0xd1, + 0x02, 0x3a, 0xf0, 0xdc, 0x4f, 0xf0, 0x01, 0x07, - 0xd2, 0x1b, 0x00, 0x2a, - 0xe6, 0xd1, 0x4f, 0xf0, - 0x01, 0x07, 0x33, 0x68, - 0xbb, 0x43, 0x33, 0x60, - 0x00, 0xbe, 0x00, 0xbf, + 0x34, 0x68, 0xbc, 0x43, + 0x34, 0x60, 0x00, 0xbe, 0x00, 0x20, 0x02, 0x40, 0x10, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, - 0x50, 0x00, 0x00, 0x20, - 0x54, 0x00, 0x00, 0x20, - 0x58, 0x00, 0x00, 0x20 + 0x0c, 0x00, 0x00, 0x00 }; /* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ static const uint8_t loader_code_stm32f0[] = { 0xc0, 0x46, 0xc0, 0x46, - 0x13, 0x4f, 0x3c, 0x68, - 0x13, 0x4f, 0x3e, 0x68, - 0x36, 0x19, 0x13, 0x4f, - 0x3d, 0x68, 0x2d, 0x19, - 0x12, 0x4f, 0x33, 0x68, - 0x3b, 0x43, 0x33, 0x60, - 0x03, 0x88, 0x0b, 0x80, - 0x10, 0x4f, 0xc0, 0x19, - 0xc9, 0x19, 0x0e, 0x4f, - 0x2b, 0x68, 0x3b, 0x42, - 0xfb, 0xd0, 0x0e, 0x4f, - 0x3b, 0x42, 0x03, 0xd1, - 0x0a, 0x4f, 0xd2, 0x1b, - 0x00, 0x2a, 0xeb, 0xd1, - 0x08, 0x4f, 0x33, 0x68, - 0xbb, 0x43, 0x33, 0x60, - 0x00, 0xbe, 0xc0, 0x46, + 0x0d, 0x4f, 0x1f, 0x44, + 0x0d, 0x4e, 0x3e, 0x44, + 0x0d, 0x4d, 0x3d, 0x44, + 0x0d, 0x4f, 0x34, 0x68, + 0x3c, 0x43, 0x34, 0x60, + 0x04, 0x88, 0x0c, 0x80, + 0x02, 0x30, 0x02, 0x31, + 0x09, 0x4f, 0x2c, 0x68, + 0x3c, 0x42, 0xfc, 0xd1, + 0x08, 0x4f, 0x3c, 0x42, + 0x01, 0xd1, 0x02, 0x3a, + 0xf2, 0xdc, 0x05, 0x4f, + 0x34, 0x68, 0xbc, 0x43, + 0x34, 0x60, 0x00, 0xbe, 0x00, 0x20, 0x02, 0x40, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x20, - 0x4c, 0x00, 0x00, 0x20, - 0x50, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00 + 0x14, 0x00, 0x00, 0x00 }; -static const uint8_t loader_code_stm32l[] = { +static const uint8_t loader_code_stm32lx[] = { // flashloaders/stm32lx.s - - 0x03, 0x68, 0x0b, 0x60, - 0x4f, 0xf0, 0x04, 0x07, - 0x38, 0x44, 0x39, 0x44, - 0x4f, 0xf0, 0x01, 0x07, - 0xd2, 0x1b, 0x00, 0x2a, - 0xf4, 0xd1, 0x00, 0xbe, + 0x04, 0x68, 0x0c, 0x60, + 0x00, 0xf1, 0x04, 0x00, + 0x01, 0xf1, 0x04, 0x01, + 0x04, 0x3a, 0xf7, 0xdc, + 0x00, 0xbe }; static const uint8_t loader_code_stm32f4[] = { // flashloaders/stm32f4.s - - 0xdf, 0xf8, 0x28, 0xc0, - 0xdf, 0xf8, 0x28, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x0b, 0x60, 0x00, 0xf1, + 0xdf, 0xf8, 0x24, 0xc0, + 0xdf, 0xf8, 0x24, 0xa0, + 0xe2, 0x44, 0x04, 0x68, + 0x0c, 0x60, 0x00, 0xf1, 0x04, 0x00, 0x01, 0xf1, 0x04, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xf0, 0xd1, + 0x00, 0x40, 0x14, 0xf0, + 0x01, 0x0f, 0xfa, 0xd1, + 0x04, 0x3a, 0xf2, 0xdc, 0x00, 0xbe, 0x00, 0xbf, 0x00, 0x3c, 0x02, 0x40, 0x0e, 0x00, 0x00, 0x00 @@ -103,17 +86,15 @@ static const uint8_t loader_code_stm32f4[] = { static const uint8_t loader_code_stm32f4_lv[] = { // flashloaders/stm32f4lv.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x4f, 0xea, - 0x82, 0x02, 0x03, 0x78, - 0x0b, 0x70, 0x00, 0xf1, + 0xdf, 0xf8, 0x24, 0xc0, + 0xdf, 0xf8, 0x24, 0xa0, + 0xe2, 0x44, 0x04, 0x78, + 0x0c, 0x70, 0x00, 0xf1, 0x01, 0x00, 0x01, 0xf1, 0x01, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xf0, 0xd1, + 0x00, 0x40, 0x14, 0xf0, + 0x01, 0x0f, 0xfa, 0xd1, + 0x01, 0x3a, 0xf2, 0xdc, 0x00, 0xbe, 0x00, 0xbf, 0x00, 0x3c, 0x02, 0x40, 0x0e, 0x00, 0x00, 0x00 @@ -121,17 +102,16 @@ static const uint8_t loader_code_stm32f4_lv[] = { static const uint8_t loader_code_stm32l4[] = { // flashloaders/stm32l4.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x44, 0x68, 0x0b, 0x60, + 0xdf, 0xf8, 0x28, 0xc0, + 0xdf, 0xf8, 0x28, 0xa0, + 0xe2, 0x44, 0x05, 0x68, + 0x44, 0x68, 0x0d, 0x60, 0x4c, 0x60, 0x00, 0xf1, 0x08, 0x00, 0x01, 0xf1, - 0x08, 0x01, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, + 0x08, 0x01, 0xda, 0xf8, + 0x00, 0x40, 0x14, 0xf4, + 0x80, 0x3f, 0xfa, 0xd1, + 0x08, 0x3a, 0xf0, 0xdc, 0x00, 0xbe, 0x00, 0xbf, 0x00, 0x20, 0x02, 0x40, 0x12, 0x00, 0x00, 0x00 @@ -139,17 +119,16 @@ static const uint8_t loader_code_stm32l4[] = { static const uint8_t loader_code_stm32f7[] = { // flashloaders/stm32f7.s - 0xdf, 0xf8, 0x2c, 0xc0, - 0xdf, 0xf8, 0x2c, 0xa0, - 0xe2, 0x44, 0x03, 0x68, - 0x0b, 0x60, 0x00, 0xf1, + 0xdf, 0xf8, 0x28, 0xc0, + 0xdf, 0xf8, 0x28, 0xa0, + 0xe2, 0x44, 0x04, 0x68, + 0x0c, 0x60, 0x00, 0xf1, 0x04, 0x00, 0x01, 0xf1, 0x04, 0x01, 0xbf, 0xf3, 0x4f, 0x8f, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0x40, 0x14, 0xf0, + 0x01, 0x0f, 0xfa, 0xd1, + 0x04, 0x3a, 0xf0, 0xdc, 0x00, 0xbe, 0x00, 0xbf, 0x00, 0x3c, 0x02, 0x40, 0x0e, 0x00, 0x00, 0x00 @@ -157,18 +136,16 @@ static const uint8_t loader_code_stm32f7[] = { static const uint8_t loader_code_stm32f7_lv[] = { // flashloaders/stm32f7lv.s - 0xdf, 0xf8, 0x30, 0xc0, - 0xdf, 0xf8, 0x30, 0xa0, - 0xe2, 0x44, 0x4f, 0xea, - 0x82, 0x02, 0x03, 0x78, - 0x0b, 0x70, 0x00, 0xf1, + 0xdf, 0xf8, 0x28, 0xc0, + 0xdf, 0xf8, 0x28, 0xa0, + 0xe2, 0x44, 0x04, 0x78, + 0x0c, 0x70, 0x00, 0xf1, 0x01, 0x00, 0x01, 0xf1, 0x01, 0x01, 0xbf, 0xf3, 0x4f, 0x8f, 0xba, 0xf8, - 0x00, 0x30, 0x13, 0xf0, - 0x01, 0x0f, 0xfa, 0xd0, - 0xa2, 0xf1, 0x01, 0x02, - 0x00, 0x2a, 0xee, 0xd1, + 0x00, 0x40, 0x14, 0xf0, + 0x01, 0x0f, 0xfa, 0xd1, + 0x01, 0x3a, 0xf0, 0xdc, 0x00, 0xbe, 0x00, 0xbf, 0x00, 0x3c, 0x02, 0x40, 0x0e, 0x00, 0x00, 0x00 @@ -234,8 +211,8 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { // STM32l - loader_code = loader_code_stm32l; - loader_size = sizeof(loader_code_stm32l); + loader_code = loader_code_stm32lx; + loader_size = sizeof(loader_code_stm32lx); } else if (sl->core_id == STM32VL_CORE_ID || sl->chip_id == STLINK_CHIPID_STM32_F1_MEDIUM || sl->chip_id == STLINK_CHIPID_STM32_F1_HIGH || @@ -315,10 +292,9 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) { struct stlink_reg rr; unsigned timeout; - size_t count = 0; uint32_t flash_base = 0; const char *error = NULL; - uint32_t dhcsr, dfsr; + uint32_t dhcsr, dfsr, cfsr, hfsr; DLOG("Running flash loader, write address:%#x, size: %u\n", target, (unsigned int)size); @@ -329,22 +305,6 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe return(-1); } - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { - count = size / sizeof(uint16_t); - - if (size % sizeof(uint16_t)) { ++count; } - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4 || - sl->flash_type == STLINK_FLASH_TYPE_L0) { - count = size / sizeof(uint32_t); - - if (size % sizeof(uint32_t)) { ++count; } - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - count = size / sizeof(uint64_t); - - if (size % sizeof(uint64_t)) { ++count; } - } - if ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (target >= FLASH_BANK2_START_ADDR)) { flash_base = FLASH_REGS_BANK2_OFS; } @@ -352,7 +312,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe /* Setup core */ stlink_write_reg(sl, fl->buf_addr, 0); // source stlink_write_reg(sl, target, 1); // target - stlink_write_reg(sl, (uint32_t)count, 2); // count + stlink_write_reg(sl, (uint32_t)size, 2); // count stlink_write_reg(sl, flash_base, 3); // flash register base // only used on VL/F1_XL, but harmless for others stlink_write_reg(sl, fl->loader_addr, 15); // pc register @@ -376,9 +336,9 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe usleep(10000); if (stlink_is_core_halted(sl)) { - timeout = 0; - break; - } + timeout = 0; + break; + } } if (timeout) { @@ -397,11 +357,14 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe return(0); error: - dhcsr = dfsr = 0; + dhcsr = dfsr = cfsr = hfsr = 0; stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); stlink_read_debug32(sl, STLINK_REG_DFSR, &dfsr); + stlink_read_debug32(sl, STLINK_REG_CFSR, &cfsr); + stlink_read_debug32(sl, STLINK_REG_HFSR, &hfsr); stlink_read_all_regs(sl, &rr); - ELOG("%s (R2 0x%08X R15 0x%08X DHCSR 0x%08X DFSR 0x%08X)\n", error, rr.r[2], rr.r[15], dhcsr, dfsr); + ELOG("%s (R2 0x%X R15 0x%X DHCSR 0x%X DFSR 0x%X CFSR 0x%X HFSR 0x%X)\n", error, rr.r[2], rr.r[15], dhcsr, dfsr, cfsr, hfsr); + ELOG("(R0 0x%X R1 0x%X)\n", rr.r[0], rr.r[1]); return(-1); } diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index 6d2c9f1af..473231117 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -19,6 +19,12 @@ #define STLINK_REG_CM3_DWT_FUNn(n) (0xE0001028 + n*16) /* Cortex™-M3 Technical Reference Manual */ +/* Configurable Fault Status Register */ +#define STLINK_REG_CFSR 0xE000ED28 + +/* Hard Fault Status Register */ +#define STLINK_REG_HFSR 0xE000ED2C + /* Debug Halting Control and Status Register */ #define STLINK_REG_DFSR 0xE000ED30 #define STLINK_REG_DFSR_HALT (1 << 0) From 76f153035a90fc72dc075a75c3d0523c0e0f0ddb Mon Sep 17 00:00:00 2001 From: anton Date: Thu, 18 Mar 2021 23:03:10 +0500 Subject: [PATCH 14/65] flash_loader: disable interrupt before start --- src/common.c | 16 ++++++++++++++++ src/stlink-lib/flash_loader.c | 13 ++++++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/common.c b/src/common.c index 99049196d..eeccd5f5b 100644 --- a/src/common.c +++ b/src/common.c @@ -2730,6 +2730,13 @@ int stm32l1_write_half_pages( } int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { + + // force halt and disable interrupt + stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | + STLINK_REG_DHCSR_C_DEBUGEN | + STLINK_REG_DHCSR_C_HALT | + STLINK_REG_DHCSR_C_MASKINTS); + if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || (sl->flash_type == STLINK_FLASH_TYPE_F7) || (sl->flash_type == STLINK_FLASH_TYPE_L4)) { @@ -2998,6 +3005,8 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr } int stlink_flashloader_stop(stlink_t *sl) { + uint32_t dhcsr; + if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || (sl->flash_type == STLINK_FLASH_TYPE_F7) || (sl->flash_type == STLINK_FLASH_TYPE_L4) || @@ -3028,6 +3037,13 @@ int stlink_flashloader_stop(stlink_t *sl) { stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); } + // enable interrupt + if (!stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr)) { + stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | + STLINK_REG_DHCSR_C_DEBUGEN | + (dhcsr&(~STLINK_REG_DHCSR_C_MASKINTS))); + } + return(0); } diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 5bc314b07..9fa897ccc 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -293,7 +293,6 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe struct stlink_reg rr; unsigned timeout; uint32_t flash_base = 0; - const char *error = NULL; uint32_t dhcsr, dfsr, cfsr, hfsr; DLOG("Running flash loader, write address:%#x, size: %u\n", target, (unsigned int)size); @@ -342,7 +341,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe } if (timeout) { - error = "Flash loader run error"; + ELOG("Flash loader run error\n"); goto error; } @@ -350,7 +349,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe stlink_read_reg(sl, 2, &rr); if (rr.r[2] != 0) { - error = "Write error"; + ELOG("Write error\n"); goto error; } @@ -363,8 +362,12 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe stlink_read_debug32(sl, STLINK_REG_CFSR, &cfsr); stlink_read_debug32(sl, STLINK_REG_HFSR, &hfsr); stlink_read_all_regs(sl, &rr); - ELOG("%s (R2 0x%X R15 0x%X DHCSR 0x%X DFSR 0x%X CFSR 0x%X HFSR 0x%X)\n", error, rr.r[2], rr.r[15], dhcsr, dfsr, cfsr, hfsr); - ELOG("(R0 0x%X R1 0x%X)\n", rr.r[0], rr.r[1]); + + WLOG("Loader state: R2 0x%X R15 0x%X\n", rr.r[2], rr.r[15]); + if (dhcsr != 0x3000B || dfsr != 0x3 || cfsr || hfsr) { + WLOG("MCU state: DHCSR 0x%X DFSR 0x%X CFSR 0x%X HFSR 0x%X\n", + dhcsr, dfsr, cfsr, hfsr); + } return(-1); } From bc9062c6c590e603e203567b6bfe14baf4c6a0af Mon Sep 17 00:00:00 2001 From: anton Date: Fri, 19 Mar 2021 18:59:09 +0500 Subject: [PATCH 15/65] flash_loader: preventing unpredictable behavior when disabling interrupts --- src/common.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index eeccd5f5b..1fd023962 100644 --- a/src/common.c +++ b/src/common.c @@ -2731,7 +2731,11 @@ int stm32l1_write_half_pages( int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { - // force halt and disable interrupt + // According to DDI0419C, Table C1-7 firstly force halt + stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | + STLINK_REG_DHCSR_C_DEBUGEN | + STLINK_REG_DHCSR_C_HALT); + // and only then disable interrupts stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | STLINK_REG_DHCSR_C_HALT | From de89563057fca8d0aaa6b6dfa8655557523507e6 Mon Sep 17 00:00:00 2001 From: anton Date: Sat, 20 Mar 2021 14:09:52 +0500 Subject: [PATCH 16/65] gdb-server: added target description for all mcu --- src/st-util/gdb-server.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 4177cef11..e35e5c2e8 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -288,7 +288,7 @@ int main(int argc, char** argv) { return(0); } -static const char* const target_description_F4 = +static const char* const target_description = "" "" "" @@ -1178,13 +1178,7 @@ int serve(stlink_t *sl, st_state_t *st) { DLOG("query: %s;%s\n", queryName, params); if (!strcmp(queryName, "Supported")) { - if (sl->chip_id == STLINK_CHIPID_STM32_F4 || - sl->chip_id == STLINK_CHIPID_STM32_F4_HD || - sl->core_id == STM32F7_CORE_ID) { - reply = strdup("PacketSize=3fff;qXfer:memory-map:read+;qXfer:features:read+"); - } else { - reply = strdup("PacketSize=3fff;qXfer:memory-map:read+"); - } + reply = strdup("PacketSize=3fff;qXfer:memory-map:read+;qXfer:features:read+"); } else if (!strcmp(queryName, "Xfer")) { char *type, *op, *__s_addr, *s_length; char *tok = params; @@ -1202,14 +1196,15 @@ int serve(stlink_t *sl, st_state_t *st) { DLOG("Xfer: type:%s;op:%s;annex:%s;addr:%d;length:%d\n", type, op, annex, addr, length); - const char* data = NULL; - - if (!strcmp(type, "memory-map") && !strcmp(op, "read")) { + const char* data; + if (strcmp(op, "read")) { + data = NULL; + } else if (!strcmp(type, "memory-map")) { data = current_memory_map; - } - - if (!strcmp(type, "features") && !strcmp(op, "read")) { - data = target_description_F4; + } else if (!strcmp(type, "features")) { + data = target_description; + } else { + data = NULL; } if (data) { @@ -1592,7 +1587,7 @@ int serve(stlink_t *sl, st_state_t *st) { reply = strdup("E00"); } - if (ret) { DLOG("p packet: stlink_read_unsupported_reg failed with id %u\n", id); } + if (ret) { DLOG("p packet: could not read register with id %u\n", id); } if (reply == NULL) { // if reply is set to "E00", skip From 9083d43d15ed53c575d48c71f6dbf31c8882b4f1 Mon Sep 17 00:00:00 2001 From: anton Date: Sat, 20 Mar 2021 14:48:52 +0500 Subject: [PATCH 17/65] gdb-server: fixed initialization of flash segments --- src/st-util/gdb-server.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index e35e5c2e8..080d434b3 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -817,10 +817,11 @@ static int flash_add_block(stm32_addr_t addr, unsigned length, stlink_t *sl) { } struct flash_block* new = malloc(sizeof(struct flash_block)); - new->next = flash_root; + new->next = flash_root; new->addr = addr; new->length = length; - new->data = calloc(length, 1); + new->data = malloc(length); + memset(new->data, stlink_get_erased_pattern(sl), length); flash_root = new; return(0); From 7c5ac5908cf16d1b1b8c7d355ac6856461aab3c4 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 20 Mar 2021 12:18:56 +0100 Subject: [PATCH 18/65] Updated travis CI config for macOS --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index fefafbaf1..5d2e5fbdf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -129,6 +129,8 @@ jobs: ### macOS ### - os: osx env: BADGE=osx + osx_image: xcode12.2 + name: macOS 10.15.7 compiler: gcc addons: homebrew: @@ -138,6 +140,8 @@ jobs: - gtk+3 - os: osx env: BADGE=osx + osx_image: xcode12.2 + name: macOS 10.15.7 compiler: clang addons: homebrew: From 5e0a502df812495bfa96fa9116a19f1306152b17 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 20 Mar 2021 15:44:09 +0100 Subject: [PATCH 19/65] General Project Update - Updated CHANGELOG.md - Updated README.md - [doc] Official STLINK-V3 support (Closes #820, Closes #1022, Closes #1025) - Updated list of contributors - Updated info on version support - Minor formatting fixes --- CHANGELOG.md | 3 ++ README.md | 18 +++---- contributors.txt | 1 + doc/compiling.md | 113 ++++++++++++++++++++--------------------- doc/version_support.md | 80 ++++++++++++++--------------- 5 files changed, 109 insertions(+), 106 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cacd79eef..7ca94dbc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Release date: (TBD) Features: - Added support for STM32H742/743/753 ([#671](https://github.com/stlink-org/stlink/pull/671), [#793](https://github.com/stlink-org/stlink/pull/793), [#823](https://github.com/stlink-org/stlink/pull/823), [#998](https://github.com/stlink-org/stlink/pull/998), [#1052](https://github.com/stlink-org/stlink/pull/1052)) +- Official support for STLINK-V3 programmers ([#820](https://github.com/stlink-org/stlink/pull/820), [#1022](https://github.com/stlink-org/stlink/pull/1022), [#1025](https://github.com/stlink-org/stlink/pull/1025)) - Added preliminary support for STM32L5x2 ([#904](https://github.com/stlink-org/stlink/pull/904), [#999](https://github.com/stlink-org/stlink/pull/999)) - Option bytes on the STM32F767 ZIT6 Nucleo-144 ([#968](https://github.com/stlink-org/stlink/pull/968), [#997](https://github.com/stlink-org/stlink/pull/997)) - Use SetConsoleCtrlHandler for Windows ([#1021](https://github.com/stlink-org/stlink/pull/1021)) @@ -32,6 +33,7 @@ Updates & changes: Fixes: +- Fixed old DFU serial number for STLINK programmers ([#417](https://github.com/stlink-org/stlink/pull/417), [#494](https://github.com/stlink-org/stlink/pull/494), [#1106](https://github.com/stlink-org/stlink/pull/1106)) - [regression] Changed timeout on flash write ([#787](https://github.com/stlink-org/stlink/pull/787), [#981](https://github.com/stlink-org/stlink/pull/981), [#987](https://github.com/stlink-org/stlink/pull/987)) - cmake compile failure with external `CMAKE_MODULE_PATH` set ([#962](https://github.com/stlink-org/stlink/pull/962)) - doc/man: Fixed installation directory ([#970](https://github.com/stlink-org/stlink/pull/970)) @@ -53,6 +55,7 @@ Fixes: - Fixed support for writing option bytes ([#1102](https://github.com/stlink-org/stlink/pull/1102)) - [doc] Corrected spelling mistake in bug report template ([#1103](https://github.com/stlink-org/stlink/pull/1103)) - Fixed support for STLINK/V1 programmer ([#1045](https://github.com/stlink-org/stlink/pull/1045), [#1105](https://github.com/stlink-org/stlink/pull/1105)) +- Fixed STM32WB55 reading DEBUG IDCODE from the wrong address ([#1100](https://github.com/stlink-org/stlink/pull/1100), [#1101](https://github.com/stlink-org/stlink/pull/1101)) # v1.6.1 diff --git a/README.md b/README.md index 8a8600947..7ddc78005 100644 --- a/README.md +++ b/README.md @@ -17,21 +17,24 @@ The stlink library and tools are licensed under the **[BSD-3 License](LICENSE.md ## Introduction -STLink is an open source toolset to program and debug STM32 devices and boards manufactured by STMicroelectronics. +stlink is an open source toolset to program and debug STM32 devices and boards manufactured by STMicroelectronics. It supports several so called STLINK programmer boards (and clones thereof) which use a microcontroller chip to translate commands from USB to JTAG/SWD. There are four generations available on the market which are _all_ supported by this toolset: - **STLINK/V1** _[obsolete as of 21-11-2019, continued support by this toolset] \*)_ - transport layer: SCSI passthru commands over USB - - stand-alone programmer and present on STM32VL Discovery boards + - stand-alone programmer + - on-board on STM32VL Discovery boards - **STLINK/V2** - transport layer: raw USB commands - - stand-alone programmer and present on STM32L Discovery and Nucleo boards + - stand-alone programmer + - on-board on STM32L Discovery and STM32 Nucleo boards - **STLINK/V2-1** - transport layer: raw USB commands - - present on some STM32 Nucleo boards -- **STLINK/V3** + - on-board on some STM32 Nucleo boards +- **STLINK-V3** - transport layer: raw USB commands - - stand-alone programmer + - stand-alone programmer (STLINK-V3SET, STLINK-V3MINI, STLINK-V3MODS) + - on-board on some STM32 Nucleo boards _\*)_ **Note: Support for the STLINK/V1 on macOS is limited to 10.14 - 10.15. Due to the deprecation and removal of macOS Kernel Extensions (KEXT) there will be no support for this programmer on macOS 11 or any later version.** @@ -52,9 +55,6 @@ Currently known working combinations of programmers and targets are listed in [d Supported operating systems are listed in [version_support.md](doc/version_support.md). -The `stlink` toolset continues to maintain backwards compatibility with the **STLINK/v1** programmer.
-Please note that on macOS this support is limited to versions 10.13 - 10.15. - ## Tutorial & HOWTO Our [tutorial](doc/tutorial.md) may help you along with some advanced tasks and additional info. diff --git a/contributors.txt b/contributors.txt index 38cc9cd42..88f1f0c89 100644 --- a/contributors.txt +++ b/contributors.txt @@ -113,6 +113,7 @@ Simon Wright Stany Marcel Stefan Misik Sven Wegener +Tarek Bochkati [tarek-bochkati] (STMicroelectronics) Timothy Lee [timothytylee] Tuomo Kaikkonen Theodore A. Roth diff --git a/doc/compiling.md b/doc/compiling.md index 07193f357..eef207f95 100644 --- a/doc/compiling.md +++ b/doc/compiling.md @@ -1,14 +1,14 @@ # Compiling from sources ## Microsoft Windows (10, 8.1) + ### Common Requirements On Windows users should ensure that the following software is installed: -* `git` (_optional, but recommended_) -* `cmake` (3.17.0 or later) -* `MinGW-w64` (7.0.0 or later) with GCC toolchain 8.1.0 - +- `git` (_optional, but recommended_) +- `cmake` (3.17.0 or later) +- `MinGW-w64` (7.0.0 or later) with GCC toolchain 8.1.0 ### Installation @@ -16,12 +16,14 @@ On Windows users should ensure that the following software is installed: 2. Install `cmake` from
Ensure that you add cmake to the $PATH system variable when following the instructions by the setup assistant. 3. Install - - _EITHER_: **MinGW-w64** from (mingw-w64-install.exe)
- - _OR_: **MSVC toolchain** from Visual Studio Build Tools 2019 + +- _EITHER_: **MinGW-w64** from (mingw-w64-install.exe)
+- _OR_: **MSVC toolchain** from Visual Studio Build Tools 2019 + 4. Create a new destination folder at a place of your choice 5. Open the command-line (cmd.exe) and execute `cd C:\$Path-to-your-destination-folder$\` 6. Fetch the project sourcefiles by running `git clone https://github.com/stlink-org/stlink.git`from the command-line (cmd.exe)
- or download the stlink zip-sourcefolder from the Release page on GitHub + or download the stlink zip-sourcefolder from the Release page on GitHub #### MSVC toolchain - minimal installation @@ -31,15 +33,19 @@ Visual Studio IDE is not necessary, only Windows SDK & build tools are required 2. Navigate through menus as follows (might change overtime) `All downloads > Tools for Visual Studio 2019 > Build Tools for Visual Studio 2019 > Download` + 3. Start downloaded executable. After Visual Studio Installer bootstraps and main window pops up, open `Individual Components` tab, and pick - - latest build tools (eg. `MSVC v142 - VS 2019 C++ x64/x86 build tools (v14.25)`) - - latest Windows SDK (eg. `Windows 10 SDK (10.0.18362.0)`) + +- latest build tools (eg. `MSVC v142 - VS 2019 C++ x64/x86 build tools (v14.25)`) +- latest Windows SDK (eg. `Windows 10 SDK (10.0.18362.0)`) + 4. After installation finishes, you can press `Launch` button in Visual Studio Installer's main menu. - Thus you can open `Developer Command Prompt for VS 2019`. It is `cmd.exe` instance with adjusted PATHs including eg. `msbuild`. - Alternatively, you can use `Developer Powershell for VS 2019` which is the same thing for `powershell.exe`. Both are available from Start menu. - Another option is to add `msbuild` to PATH manually. Its location should be `C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin`. Then, it should be available from any `powershell.exe` or `cmd.exe` session. ### Building + #### MinGW-w64 1. Use the command-line to move to the `scripts` directory within the source-folder: `cd stlink\scripts\` @@ -50,7 +56,6 @@ Per default the build script (currently) uses `C:\Program Files\mingw-w64\x86_64 When installing different toolchains make sure to update the path in the `mingw64-build.bat`.
This can be achieved by opening the .bat file with a common text editor. - #### MSVC toolchain 1. In a command prompt, change the directory to the folder where the stlink files were cloned (or unzipped) to. @@ -59,12 +64,15 @@ This can be achieved by opening the .bat file with a common text editor. This will create a solution file `stlink.sln` in the build folder. Now, you can build whole `stlink` suite using following command: + ``` msbuild /m /p:Configuration=Release stlink.sln ``` + Options: + - `/m` - compilation runs in parallel utilizing multiple cores -- `/p:Configuration=Release` - generates *Release*, optimized build. +- `/p:Configuration=Release` - generates _Release_, optimized build. Directory `\build\Release` contains final executables. (`st-util.exe` is located in `\build\src\gdbserver\Release`). @@ -79,25 +87,25 @@ It can be copied from: `\build\3rdparty\libusb-{version}\MS{arch}\ [ST-LINK drivers](https://www.st.com/en/development-tools/stsw-link009.html) are required for `stlink` to work. ## Linux + ### Common requirements Install the following packages from your package repository: -* `git` -* `gcc` or `clang` or `mingw32-gcc` or `mingw64-gcc` (C-compiler; very likely gcc is already present) -* `build-essential` (on Debian based distros (Debian, Ubuntu)) -* `cmake` (3.4.2 or later, use the latest version available from the repository) -* `rpm` (on Debian based distros (Debian, Ubuntu), needed for package build with `make package`) -* `libusb-1.0` -* `libusb-1.0-0-dev` (development headers for building) -* `libgtk-3-dev` (_optional_, needed for `stlink-gui`) -* `pandoc` (_optional_, needed for generating manpages from markdown) +- `git` +- `gcc` or `clang` or `mingw32-gcc` or `mingw64-gcc` (C-compiler; very likely gcc is already present) +- `build-essential` (on Debian based distros (Debian, Ubuntu)) +- `cmake` (3.4.2 or later, use the latest version available from the repository) +- `rpm` (on Debian based distros (Debian, Ubuntu), needed for package build with `make package`) +- `libusb-1.0` +- `libusb-1.0-0-dev` (development headers for building) +- `libgtk-3-dev` (_optional_, needed for `stlink-gui`) +- `pandoc` (_optional_, needed for generating manpages from markdown) or execute (Debian-based systems only): `apt-get install gcc build-essential cmake libusb-1.0 libusb-1.0-0-dev libgtk-3-dev pandoc` (Replace gcc with the intended C-compiler if necessary or leave out any optional package not needed.) - ### Installation 1. Open a new terminal console @@ -105,7 +113,6 @@ or execute (Debian-based systems only): `apt-get install gcc build-essential cma 3. Change to this directory: `cd ~/git` 4. Fetch the project sourcefiles by running `git clone https://github.com/stlink-org/stlink.git` - ### Building #### Installation: @@ -120,21 +127,19 @@ or execute (Debian-based systems only): `apt-get install gcc build-essential cma As an option you may also install to an individual user-defined folder e.g `$HOME` with `make install DESTDIR=$HOME`. - -#### Removal: +#### Removal: 1. Run `make uninstall` to perform a clean uninstall of the package from the system. 2. Run `make clean` to clean the build-folder within the project source and remove all compiled and linked files and libraries. - ### Cross-Building for Windows Install the following packages from your package repository: -* `mingw-w64` -* `mingw-w64-common` -* `mingw-w64-i686-dev` -* `mingw-w64-x86-64-dev` +- `mingw-w64` +- `mingw-w64-common` +- `mingw-w64-i686-dev` +- `mingw-w64-x86-64-dev` After following the steps for installation above, proceed with from the build dircetory itself: @@ -144,7 +149,6 @@ $ sudo sh ./cmake/packaging/windows/generate_binaries.sh The generated zip-packages can be found in the subdirectory `./build/dist`. - ### Set device access permissions and the role of udev By default most distributions don't allow access to USB devices. @@ -162,22 +166,21 @@ $ sudo udevadm trigger udev will now create device node files, e.g. `/dev/stlinkv3_XX`, `/dev/stlinkv2_XX`, `/dev/stlinkv1_XX`. - ### Special note on the use of STLink/V1 programmers (legacy): As the STLINKV1's SCSI emulation is somehow broken, the best advice possibly is to tell your operating system to completely ignore it.
Choose one of the following options _before_ connecting the device to your computer: -* `modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i` -* _OR_ - 1. `echo "options usb-storage quirks=483:3744:i" >> /etc/modprobe.conf` - 2. `modprobe -r usb-storage && modprobe usb-storage` -* _OR_ - 1. `cp stlink_v1.modprobe.conf /etc/modprobe.d` - 2. `modprobe -r usb-storage && modprobe usb-storage` - +- `modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i` +- _OR_ + 1. `echo "options usb-storage quirks=483:3744:i" >> /etc/modprobe.conf` + 2. `modprobe -r usb-storage && modprobe usb-storage` +- _OR_ + 1. `cp stlink_v1.modprobe.conf /etc/modprobe.d` + 2. `modprobe -r usb-storage && modprobe usb-storage` ## macOS + ### Common requirements The best and recommended way is to install a package manager for open source software, @@ -185,21 +188,20 @@ either [homebrew](https://brew.sh) or [MacPorts](https://www.macports.org/). Then install the following dependencies from the package repository: -* `git` -* `gcc` or `llvm` (for clang) (C-compiler) -* `cmake` -* `libusb` -* `gtk+3` or `gtk3` (_optional_, needed for `stlink-gui`) +- `git` +- `gcc` or `llvm` (for clang) (C-compiler) +- `cmake` +- `libusb` +- `gtk+3` or `gtk3` (_optional_, needed for `stlink-gui`) To do this with only one simple command, type: -* for homebrew: - - with gcc: `sudo brew install git gcc cmake libusb gtk+3` or - - with clang: `sudo brew install git llvm cmake libusb gtk+3` or -* for MacPorts: - - with gcc: `sudo port install git gcc10 cmake libusb gtk3` or - - with clang: `sudo port install git llvm-10 cmake libusb gtk3` - +- for homebrew: + - with gcc: `sudo brew install git gcc cmake libusb gtk+3` or + - with clang: `sudo brew install git llvm cmake libusb gtk+3` or +- for MacPorts: + - with gcc: `sudo port install git gcc10 cmake libusb gtk3` or + - with clang: `sudo port install git llvm-10 cmake libusb gtk3` ### Installation @@ -208,7 +210,6 @@ To do this with only one simple command, type: 3. Change to this directory: `cd ~/git` 4. Fetch the project sourcefiles by running `git clone https://github.com/stlink-org/stlink.git` - ### Building 1. Change into the project source directory: `cd stlink` @@ -217,14 +218,13 @@ To do this with only one simple command, type: 4. Run `make debug` to create the _Debug_ target (_optional_)
The debug target is only necessary in order to modify the sources and to run under a debugger. - ## Build options + ### Build using a different directory for shared libs To put the compiled shared libs into a different directory during installation, you can use the cmake option `cmake -DLIB_INSTALL_DIR:PATH="/usr/lib64" ..`. - ### Standard installation directories The cmake build system of this toolset includes `GNUInstallDirs` to define GNU standard installation directories. @@ -232,8 +232,7 @@ This module provides install directory variables as defined by the GNU Coding St Below are the preset default cmake options, which apply if none of these options are redefined: -* `-DCMAKE_INSTALL_SYSCONFDIR=/etc` -* `-DCMAKE_INSTALL_PREFIX=/usr/local` - +- `-DCMAKE_INSTALL_SYSCONFDIR=/etc` +- `-DCMAKE_INSTALL_PREFIX=/usr/local` Author: nightwalker-87 diff --git a/doc/version_support.md b/doc/version_support.md index eca491b79..1edf2e19c 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -23,52 +23,52 @@ NOTE: In order to use a STLINK/V1 programmer on macOS, versions 10.14 or 10.15 a ### Linux-/Unix-based: -| Operating System | libusb
version | cmake
version | gtk-3
version | Notes | -| -------------------------------- | ----------------------- | ------------------ | ----------------------------------------- | --------------------------------------------------- | --------------------------------------------------- | -| Alpine Edge | 1.0.23 | 3.17.0 | 3.99.0
gtk+3.0 | | -| ALT Linux Sisyphus | 1.0.23 | 3.17.0 | 3.24.18
libgtk+3 | | -| Arch Linux | 1.0.23 | 3.17.0 | 3.24.18
gtk3 | | -| Fedora Rawhide | 1.0.23 | 3.17.0 | 3.24.18
gtk3 | | named `libusbx`, but
`libusb`-codebase is used | -| KaOS | 1.0.23 | 3.17.0 | 3.24.18
gtk3 | | -| OpenMandriva Cooker | 1.0.23 | 3.17.0 | 3.24.18
libgtk+3.0
lib64gtk+3.0 | | -| PCLinuxOS | 1.0.23
lib64usb1.0 | 3.17.0 | 3.24.18
lib64gtk+3.0 | | -| Slackware Current | 1.0.23 | 3.17.0 | 3.24.18
gtk+3 | | -| Solus | 1.0.23 | 3.16.5 | 3.24.16
libgtk-3 | | -| Debian Sid | 1.0.23 | 3.16.3 | 3.24.18
libgtk-3 | | -| OpenMandriva Lx 4.1 | 1.0.23 | 3.16.3 | 3.24.13
libgtk+3.0
lib64gtk+3.0 | | -| Ubuntu 20.04 LTS (Focal Fossa) | 1.0.23 | 3.16.3 | 3.24.17
libgtk-3 | | -| openSUSE Tumbleweed | 1.0.23 | 3.16.2 | 3.24.16
gtk3 | | -| Alpine 3.11 | 1.0.23 | 3.15.5 | 3.24.13
gtk+3.0 | | -| Ubuntu 19.10 (Eoan Ermine) | 1.0.23 | 3.13.4 | 3.24.12
libgtk-3 | | -| Mageia Cauldron | 1.0.22 | 3.17.0 | 3.24.18
libgtk+3.0
lib64gtk+3.0 | | -| NetBSD 9.0 | 1.0.22 | 3.16.1 | 3.24.12
gtk+3 | | -| NetBSD 8.1 | 1.0.22 | 3.16.1 | 3.24.12
gtk+3 | | -| NetBSD 7.2 | 1.0.22 | 3.16.1 | _N/A_ | | -| Alpine 3.10 | 1.0.22 | 3.14.5 | 3.24.8
gtk+3.0 | | -| Fedora 31 | 1.0.22 | 3.14.5 | 3.24.12
gtk3 | named `libusbx`, but
`libusb`-codebase is used | -| Mageia 7.1 | 1.0.22 | 3.14.3 | 3.24.8
libgtk+3.0
lib64gtk+3.0 | | -| Fedora 30 | 1.0.22 | 3.14.2 | 3.24.8
gtk3 | named `libusbx`, but
`libusb`-codebase is used | -| Debian 10 (Buster) | 1.0.22 | 3.13.4 | 3.24.5
libgtk-3 | | -| Alpine 3.9 | 1.0.22 | 3.13.0 | 3.24.1
gtk+3.0 | | -| CentOS 8 | 1.0.22 | 3.11.4 | 3.22.30
gtk3 | named `libusbx`, but
`libusb`-codebase is used | -| openSUSE Leap 15.2 | 1.0.21 | 3.15.5 | 3.24.14
gtk3 | | -| openSUSE Leap 15.1 | 1.0.21 | 3.10.2 | 3.22.30
gtk3 | | -| Ubuntu 18.04 LTS (Bionic Beaver) | 1.0.21 | 3.10.2 | 3.22.30
libgtk-3 | | -| Debian 9 (Stretch) | 1.0.21 | 3.7.2 | 3.22.11
libgtk-3 | | -| Slackware 14.2 | **1.0.20** | 3.5.2 | 3.18.9
gtk+3 | | -| Ubuntu 16.04 LTS (Xenial Xerus) | **1.0.20** | 3.5.1 | 3.18.9
libgtk-3 | | -| OpenMandriva Lx 3.0 | **1.0.20** | **3.4.2** | 3.18.9
libgtk+3.0
lib64gtk+3.0 | | -| FreeBSD 13 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
gtk3 | linux_libusb-13.0r358841
(integrated) | -| FreeBSD 12 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
gtk3 | linux_libusb-11.0r261448_4
(integrated) | -| FreeBSD 11 | **1.0.16** - 1.0.18 | 3.15.5 | 3.24.10
gtk3 | linux_libusb-11.0r261448_4
(integrated) | +| Operating System | libusb
version | cmake
version | gtk-3
version | Notes | +| -------------------------------- | ----------------------- | ------------------ | ----------------------------------------- | ----------------------------------------------------------------------------- | +| Alpine Edge | 1.0.23 | 3.17.0 | 3.99.0
gtk+3.0 | | +| ALT Linux Sisyphus | 1.0.23 | 3.17.0 | 3.24.18
libgtk+3 | | +| Arch Linux | 1.0.23 | 3.17.0 | 3.24.18
gtk3 | | +| Fedora Rawhide | 1.0.23 | 3.17.0 | 3.24.18
gtk3 | named `libusbx`, but
`libusb`-codebase is used | +| KaOS | 1.0.23 | 3.17.0 | 3.24.18
gtk3 | | +| OpenMandriva Cooker | 1.0.23 | 3.17.0 | 3.24.18
libgtk+3.0
lib64gtk+3.0 | | +| PCLinuxOS | 1.0.23
lib64usb1.0 | 3.17.0 | 3.24.18
lib64gtk+3.0 | | +| Slackware Current | 1.0.23 | 3.17.0 | 3.24.18
gtk+3 | | +| Solus | 1.0.23 | 3.16.5 | 3.24.16
libgtk-3 | | +| Debian Sid | 1.0.23 | 3.16.3 | 3.24.18
libgtk-3 | | +| OpenMandriva Lx 4.1 | 1.0.23 | 3.16.3 | 3.24.13
libgtk+3.0
lib64gtk+3.0 | | +| Ubuntu 20.04 LTS (Focal Fossa) | 1.0.23 | 3.16.3 | 3.24.17
libgtk-3 | | +| openSUSE Tumbleweed | 1.0.23 | 3.16.2 | 3.24.16
gtk3 | | +| Alpine 3.11 | 1.0.23 | 3.15.5 | 3.24.13
gtk+3.0 | | +| Ubuntu 19.10 (Eoan Ermine) | 1.0.23 | 3.13.4 | 3.24.12
libgtk-3 | | +| Mageia Cauldron | 1.0.22 | 3.17.0 | 3.24.18
libgtk+3.0
lib64gtk+3.0 | | +| NetBSD 9.0 | 1.0.22 | 3.16.1 | 3.24.12
gtk+3 | | +| NetBSD 8.1 | 1.0.22 | 3.16.1 | 3.24.12
gtk+3 | | +| NetBSD 7.2 | 1.0.22 | 3.16.1 | _N/A_ | | +| Alpine 3.10 | 1.0.22 | 3.14.5 | 3.24.8
gtk+3.0 | | +| Fedora 31 | 1.0.22 | 3.14.5 | 3.24.12
gtk3 | named `libusbx`, but
`libusb`-codebase is used | +| Mageia 7.1 | 1.0.22 | 3.14.3 | 3.24.8
libgtk+3.0
lib64gtk+3.0 | | +| Fedora 30 | 1.0.22 | 3.14.2 | 3.24.8
gtk3 | named `libusbx`, but
`libusb`-codebase is used | +| Debian 10 (Buster) | 1.0.22 | 3.13.4 | 3.24.5
libgtk-3 | | +| Alpine 3.9 | 1.0.22 | 3.13.0 | 3.24.1
gtk+3.0 | | +| CentOS 8 | 1.0.22 | 3.11.4 | 3.22.30
gtk3 | named `libusbx`, but
`libusb`-codebase is used | +| openSUSE Leap 15.2 | 1.0.21 | 3.15.5 | 3.24.14
gtk3 | | +| openSUSE Leap 15.1 | 1.0.21 | 3.10.2 | 3.22.30
gtk3 | | +| Ubuntu 18.04 LTS (Bionic Beaver) | 1.0.21 | 3.10.2 | 3.22.30
libgtk-3 | | +| Debian 9 (Stretch) | 1.0.21 | 3.7.2 | 3.22.11
libgtk-3 | | +| Slackware 14.2 | 1.0.20 | 3.5.2 | 3.18.9
gtk+3 | | +| Ubuntu 16.04 LTS (Xenial Xerus) | 1.0.20 | 3.5.1 | 3.18.9
libgtk-3 | | +| OpenMandriva Lx 3.0x | 1.0.20 | **3.4.2** | 3.18.9
libgtk+3.0
lib64gtk+3.0 | | +| FreeBSD 13 | **1.0.16 - 1.0.18** | 3.15.5 | 3.24.10
gtk3 | linux_libusb-13.0r358841
LIBUSB_API_VERSION 0x01000102
(integrated) | +| FreeBSD 12 | **1.0.16 - 1.0.18** | 3.15.5 | 3.24.10
gtk3 | linux_libusb-13.0r358841
LIBUSB_API_VERSION 0x01000102
(integrated) | +| FreeBSD 11 | **1.0.16 - 1.0.18** | 3.15.5 | 3.24.10
gtk3 | linux_libusb-13.0r358841
LIBUSB_API_VERSION 0x01000102
(integrated) | ## Unsupported Operating Systems (as of Release v1.6.1) | Operating System | libusb
version | cmake
version | End of
OS-Support | Notes | | ------------------------------ | ------------------- | ------------------ | ---------------------- | --------------------------------------------------- | | CentOS 7 | 1.0.21 | **2.8.12.2** | | named `libusbx`, but
`libusb`-codebase is used | -| Debian 8 (Jessie) | 1.0.**19** | 3.**0.2** | Jun 2020 | -| Ubuntu 14.04 LTS (Trusty Tahr) | 1.0.**17** | **2.8.12.2** | Apr 2019 | +| Debian 8 (Jessie) | 1.0.19 | **3.0.2** | Jun 2020 | +| Ubuntu 14.04 LTS (Trusty Tahr) | 1.0.17 | **2.8.12.2** | Apr 2019 | | CentOS 6 | 1.0.**9** | **2.8.12.2** | Dec 2020 | named `libusbx`, but
`libusb`-codebase is used | | Slackware 14.1 | 1.0.**9** | **2.8.12** | | | Slackware 14.0 | 1.0.**9** | **2.8.8** | | From 7c7ce954045d9734198d7345477b94bcf58f770e Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 21 Mar 2021 14:17:35 +0100 Subject: [PATCH 20/65] Create codeql-analysis.yml Setup for code scanning alerts --- .github/workflows/codeql-analysis.yml | 67 +++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 000000000..202867cfc --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,67 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ develop, master ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ develop ] + schedule: + - cron: '23 20 * * 2' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + language: [ 'cpp' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] + # Learn more: + # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From ab6094a615f31653c1f0b355e05c5a29a338aa39 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 21 Mar 2021 14:26:10 +0100 Subject: [PATCH 21/65] Create cmake.yml Added Github Action - CMake Workflow Build and test a CMake based project. --- .github/workflows/cmake.yml | 46 +++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .github/workflows/cmake.yml diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml new file mode 100644 index 000000000..005915e6e --- /dev/null +++ b/.github/workflows/cmake.yml @@ -0,0 +1,46 @@ +name: CMake + +on: [push] + +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: Release + +jobs: + build: + # The CMake configure and build commands are platform agnostic and should work equally + # well on Windows or Mac. You can convert this to a matrix build if you need + # cross-platform coverage. + # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Create Build Environment + # Some projects don't allow in-source building, so create a separate build directory + # We'll use this as our working directory for all subsequent commands + run: cmake -E make_directory ${{github.workspace}}/build + + - name: Configure CMake + # Use a bash shell so we can use the same syntax for environment variable + # access regardless of the host operating system + shell: bash + working-directory: ${{github.workspace}}/build + # Note the current convention is to use the -S and -B options here to specify source + # and build directories, but this is only available with CMake 3.13 and higher. + # The CMake binaries on the Github Actions machines are (as of this writing) 3.12 + run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE + + - name: Build + working-directory: ${{github.workspace}}/build + shell: bash + # Execute the build. You can specify a specific target with "--target " + run: cmake --build . --config $BUILD_TYPE + + - name: Test + working-directory: ${{github.workspace}}/build + shell: bash + # Execute tests defined by the CMake configuration. + # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail + run: ctest -C $BUILD_TYPE From 812bc6ed4fae1078f00616d217a7b91e3480fa0f Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 21 Mar 2021 14:58:45 +0100 Subject: [PATCH 22/65] Create c-cpp.yml Added Github Action - Make Workflow Build and test a C/C++ project using Make. --- .github/workflows/c-cpp.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/c-cpp.yml diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml new file mode 100644 index 000000000..e211e4e54 --- /dev/null +++ b/.github/workflows/c-cpp.yml @@ -0,0 +1,23 @@ +name: C/C++ CI + +on: + push: + branches: [ testing ] + pull_request: + branches: [ testing ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: configure + run: ./configure + - name: make + run: make + - name: make check + run: make check + - name: make distcheck + run: make distcheck From c677eb2f4dfd669bec7c73f1a324e0624908968a Mon Sep 17 00:00:00 2001 From: anton Date: Tue, 23 Mar 2021 20:06:47 +0500 Subject: [PATCH 23/65] flash_loader: makefile simplification --- flashloaders/Makefile | 75 +++++++++++++++---------------------------- 1 file changed, 25 insertions(+), 50 deletions(-) diff --git a/flashloaders/Makefile b/flashloaders/Makefile index 3517e1499..d4ca4d22a 100644 --- a/flashloaders/Makefile +++ b/flashloaders/Makefile @@ -1,10 +1,7 @@ -# Note that according to the original GPLed code, compiling is noted to be -# as simple as gcc -c, this fails with my tests where this will lead to a wrong -# address read by the program. -# This makefile will save your time from dealing with compile errors -# Adjust CC if needed +# The flash loader code cannot be compiled by the system gcc. This +# makefile use arm-none-eabi-gcc for this purpose -CROSS_COMPILE ?= /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi- +CROSS_COMPILE ?= arm-none-eabi- CC = $(CROSS_COMPILE)gcc OBJCOPY = $(CROSS_COMPILE)objcopy @@ -12,52 +9,30 @@ OBJCOPY = $(CROSS_COMPILE)objcopy XXD = xxd XXDFLAGS = -i -c 4 -CFLAGS_THUMB1 = -mcpu=Cortex-M0 -Tlinker.ld -ffreestanding -nostdlib -CFLAGS_THUMB2 = -mcpu=Cortex-M3 -Tlinker.ld -ffreestanding -nostdlib +CFLAGS_ARMV6_M = -mcpu=Cortex-M0 -Tlinker.ld -ffreestanding -nostdlib +CFLAGS_ARMV7_M = -mcpu=Cortex-M3 -Tlinker.ld -ffreestanding -nostdlib all: stm32vl.h stm32f0.h stm32lx.h stm32f4.h stm32f4lv.h stm32l4.h stm32f7.h stm32f7lv.h + -stm32f0.h: stm32f0.s - $(CC) stm32f0.s $(CFLAGS_THUMB1) -o stm32f0.o - $(OBJCOPY) -O binary stm32f0.o stm32f0.bin - $(XXD) $(XXDFLAGS) stm32f0.bin stm32f0.h - -stm32vl.h: stm32f0.s - $(CC) stm32f0.s $(CFLAGS_THUMB2) -o stm32vl.o - $(OBJCOPY) -O binary stm32vl.o stm32vl.bin - $(XXD) $(XXDFLAGS) stm32vl.bin stm32vl.h - -stm32lx.h: stm32lx.s - $(CC) stm32lx.s $(CFLAGS_THUMB2) -o stm32lx.o - $(OBJCOPY) -O binary stm32lx.o stm32lx.bin - $(XXD) $(XXDFLAGS) stm32lx.bin stm32lx.h - -stm32f4.h: stm32f4.s - $(CC) stm32f4.s $(CFLAGS_THUMB2) -o stm32f4.o - $(OBJCOPY) -O binary stm32f4.o stm32f4.bin - $(XXD) $(XXDFLAGS) stm32f4.bin stm32f4.h - -stm32f4lv.h: stm32f4lv.s - $(CC) stm32f4lv.s $(CFLAGS_THUMB2) -o stm32f4lv.o - $(OBJCOPY) -O binary stm32f4lv.o stm32f4lv.bin - $(XXD) $(XXDFLAGS) stm32f4lv.bin stm32f4lv.h - -stm32l4.h: stm32l4.s - $(CC) stm32l4.s $(CFLAGS_THUMB2) -o stm32l4.o - $(OBJCOPY) -O binary stm32l4.o stm32l4.bin - $(XXD) $(XXDFLAGS) stm32l4.bin stm32l4.h - -stm32f7.h: stm32f7.s - $(CC) stm32f7.s $(CFLAGS_THUMB2) -o stm32f7.o - $(OBJCOPY) -O binary stm32f7.o stm32f7.bin - $(XXD) $(XXDFLAGS) stm32f7.bin stm32f7.h - -stm32f7lv.h: stm32f7lv.s - $(CC) stm32f7lv.s $(CFLAGS_THUMB2) -o stm32f7lv.o - $(OBJCOPY) -O binary stm32f7lv.o stm32f7lv.bin - $(XXD) $(XXDFLAGS) stm32f7lv.bin stm32f7lv.h +%.h: %.bin + $(XXD) $(XXDFLAGS) $< $@ + +%.bin: %.o + $(OBJCOPY) -O binary $< $@ + rm $< + +# separate rule for STM32F0 +stm32f0.o: stm32f0.s + $(CC) stm32f0.s $(CFLAGS_ARMV6_M) -o stm32f0.o + +# separate rule for STM32F1/F3 +stm32vl.o: stm32f0.s + $(CC) stm32f0.s $(CFLAGS_ARMV7_M) -o stm32vl.o + +# generic rule for all other ARMv7-M +%.o: *.s + $(CC) $< $(CFLAGS_ARMV7_M) -o $@ clean: - rm *.o - rm *.bin - rm *.h + rm -f *.h From ee2c9f508e3eaa39d72dd8d41dfe642800a4946e Mon Sep 17 00:00:00 2001 From: anton Date: Tue, 23 Mar 2021 22:33:00 +0500 Subject: [PATCH 24/65] Core ID reading rework --- inc/stm32.h | 7 ++++--- src/common.c | 41 ++++++++++++++++++++++++++++++++--------- src/stlink-lib/reg.h | 9 ++++++--- 3 files changed, 42 insertions(+), 15 deletions(-) diff --git a/inc/stm32.h b/inc/stm32.h index ca56a12f5..7d60ab5de 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -8,9 +8,10 @@ #define STM32_H /* Cortex core ids */ -#define STM32VL_CORE_ID 0x1ba01477 -#define STM32F7_CORE_ID 0x5ba02477 -#define STM32H7_CORE_ID 0x6ba02477 // STM32H7 JTAG ID Code (RM0433 pg3065) +#define STM32VL_CORE_ID 0x1ba01477 +#define STM32F7_CORE_ID 0x5ba02477 +#define STM32H7_CORE_ID 0x6ba02477 // STM32H7 SWD ID Code +#define STM32H7_CORE_ID_JTAG 0x6ba00477 // STM32H7 JTAG ID Code (RM0433 pg3065) /* Constant STM32 memory map figures */ #define STM32_FLASH_BASE ((uint32_t)0x08000000) diff --git a/src/common.c b/src/common.c index 5f2746e3d..b5bb67e9e 100644 --- a/src/common.c +++ b/src/common.c @@ -1229,20 +1229,43 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { if (stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &cpu_id)) cpu_id = 0; - // If the chip is an H7, read the chipid from the new address - if (sl->core_id == STM32H7_CORE_ID && cpu_id == STLINK_REG_CMx_CPUID_CM7) { + /* + * the chip_id register in the reference manual have + * DBGMCU_IDCODE / DBG_IDCODE name + * + */ + + uint32_t part_no = STLINK_REG_CM3_CPUID_PARTNO(cpu_id); + if ((sl->core_id == STM32H7_CORE_ID || + sl->core_id == STM32H7_CORE_ID_JTAG) && + part_no == STLINK_REG_CMx_CPUID_PARTNO_CM7) { // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) ret = stlink_read_debug32(sl, 0x5c001000, chip_id); - } - - if (*chip_id == 0) { + } else if (part_no == STLINK_REG_CMx_CPUID_PARTNO_CM0) { + // STM32F0 (RM0091, pg914; RM0360, pg713) + // STM32L0 (RM0377, pg813; RM0367, pg915; RM0376, pg917) + // STM32G0 (RM0444, pg1367) + ret = stlink_read_debug32(sl, 0x40015800, chip_id); + } else if (part_no == STLINK_REG_CMx_CPUID_PARTNO_CM33) { + // STM32L5 (RM0438, pg2157) + ret = stlink_read_debug32(sl, 0xE0044000, chip_id); + } else /* СM3, СM4, CM7 */ { // default chipid address + + // STM32F1 (RM0008, pg1087; RM0041, pg681) + // STM32F2 (RM0033, pg1326) + // STM32F3 (RM0316, pg1095; RM0313, pg874) + // STM32F7 (RM0385, pg1676; RM0410, pg1912) + // STM32L1 (RM0038, pg861) + // STM32L4 (RM0351, pg1840; RM0394, pg1560) + // STM32G4 (RM0440, pg2086) + // STM32WB (RM0434, pg1406) ret = stlink_read_debug32(sl, 0xE0042000, chip_id); - } - if (*chip_id == 0) { - // Try Corex M0 DBGMCU_IDCODE register address - ret = stlink_read_debug32(sl, 0x40015800, chip_id); + // Fix chip_id for F4 rev A errata, read CPU ID, as CoreID is the same for F2/F4 + if (*chip_id == 0x411 && (cpu_id & 0xfff0) == 0xc240) { + *chip_id = 0x413; + } } return(ret); diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index 5a796d7e1..73f608cb6 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -3,9 +3,12 @@ #define STLINK_REG_CM3_CPUID 0xE000ED00 -#define STLINK_REG_CMx_CPUID_CM0 0x410CC200 -#define STLINK_REG_CMx_CPUID_CM3 0x412FC230 -#define STLINK_REG_CMx_CPUID_CM7 0x411FC272 +#define STLINK_REG_CM3_CPUID_PARTNO(cpuid) ((cpuid)&STLINK_REG_CMx_CPUID_PARTNO_MASK) +#define STLINK_REG_CMx_CPUID_PARTNO_MASK 0xFFF0 +#define STLINK_REG_CMx_CPUID_PARTNO_CM0 0xC200 +#define STLINK_REG_CMx_CPUID_PARTNO_CM3 0xC230 +#define STLINK_REG_CMx_CPUID_PARTNO_CM7 0xC270 +#define STLINK_REG_CMx_CPUID_PARTNO_CM33 0xD210 #define STLINK_REG_CM3_FP_CTRL 0xE0002000 // Flash Patch Control Register From 229c721189587760db5509c59b3c02e93e7035c8 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 24 Mar 2021 23:26:38 +0100 Subject: [PATCH 25/65] General Project Update - Added basic security policy - Updated info on version support for macOS - Updated tutorial.md > Added reference for st-info --probe command > Added section on unknown chip id error (Closes #107, Closes #568, Closes #669) > Added information on HW reset pin issue (Closes #220, Closes #238) --- CHANGELOG.md | 18 ++++++++---- SECURITY.md | 20 +++++++++++++ doc/tutorial.md | 67 ++++++++++++++++++++++++++++++++---------- doc/version_support.md | 8 ++--- 4 files changed, 87 insertions(+), 26 deletions(-) create mode 100644 SECURITY.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ca94dbc8..e3f8e13b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,13 @@ # v1.6.2 -Release date: (TBD) +Release date: (planned H1/2021) Features: +- Extended support for STM32H7 & rework of software reset ([#532](https://github.com/stlink-org/stlink/pull/532), [#1059](https://github.com/stlink-org/stlink/pull/1059), [#1063](https://github.com/stlink-org/stlink/pull/1063), [#1071](https://github.com/stlink-org/stlink/pull/1071)) - Added support for STM32H742/743/753 ([#671](https://github.com/stlink-org/stlink/pull/671), [#793](https://github.com/stlink-org/stlink/pull/793), [#823](https://github.com/stlink-org/stlink/pull/823), [#998](https://github.com/stlink-org/stlink/pull/998), [#1052](https://github.com/stlink-org/stlink/pull/1052)) -- Official support for STLINK-V3 programmers ([#820](https://github.com/stlink-org/stlink/pull/820), [#1022](https://github.com/stlink-org/stlink/pull/1022), [#1025](https://github.com/stlink-org/stlink/pull/1025)) +- Official support for STLINK-V3 programmers (commit [#5e0a502](https://github.com/stlink-org/stlink/commit/5e0a502df812495bfa96fa9116a19f1306152b17), [#820](https://github.com/stlink-org/stlink/pull/820), [#1022](https://github.com/stlink-org/stlink/pull/1022), [#1025](https://github.com/stlink-org/stlink/pull/1025)) - Added preliminary support for STM32L5x2 ([#904](https://github.com/stlink-org/stlink/pull/904), [#999](https://github.com/stlink-org/stlink/pull/999)) - Option bytes on the STM32F767 ZIT6 Nucleo-144 ([#968](https://github.com/stlink-org/stlink/pull/968), [#997](https://github.com/stlink-org/stlink/pull/997)) - Use SetConsoleCtrlHandler for Windows ([#1021](https://github.com/stlink-org/stlink/pull/1021)) @@ -15,12 +16,13 @@ Features: - `st-util`: Add specialized memory map for STM32H7 devices ([#1060](https://github.com/stlink-org/stlink/pull/1060)) - Support for STM32F4 option bytes ([#1062](https://github.com/stlink-org/stlink/pull/1062)) - Link for WIN32 & APPLE with stlink-static ([#1069](https://github.com/stlink-org/stlink/pull/1069)) -- Extended support for STM32H7 ([#1059](https://github.com/stlink-org/stlink/pull/1059), [#1063](https://github.com/stlink-org/stlink/pull/1063), [#1071](https://github.com/stlink-org/stlink/pull/1071)) - ITM functionality for STLink/V2 and STM32Fxx chipsets ([#136](https://github.com/stlink-org/stlink/pull/136), [#179](https://github.com/stlink-org/stlink/pull/179), [#815](https://github.com/stlink-org/stlink/pull/815), [#1072](https://github.com/stlink-org/stlink/pull/1072)) - Included ITM functionality for building with MSVC ([#1080](https://github.com/stlink-org/stlink/pull/1080)) Updates & changes: +- [doc] Added tutorial section on unknown chip id error ([#107](https://github.com/stlink-org/stlink/pull/107), [#568](https://github.com/stlink-org/stlink/pull/568), +- [doc] Updated documentation on target resetting ([#261](https://github.com/stlink-org/stlink/pull/261), [#533](https://github.com/stlink-org/stlink/pull/533), [#1107](https://github.com/stlink-org/stlink/pull/1107)) - [doc] Added note on `(gdb) run` command (commit [#03793d4](https://github.com/stlink-org/stlink/commit/03793d42b6078344a9ef8ad55f1d5d0fc19e486e), [#267](https://github.com/stlink-org/stlink/pull/267)) - [doc] `st-flash --reset` parameter (one solution for #356) ([#642](https://github.com/stlink-org/stlink/pull/642)) - [refactoring] General maintenance ([#864](https://github.com/stlink-org/stlink/pull/864), [#976](https://github.com/stlink-org/stlink/pull/976), [#978](https://github.com/stlink-org/stlink/pull/978)) @@ -33,6 +35,7 @@ Updates & changes: Fixes: +- Flash loader rework ([#356](https://github.com/stlink-org/stlink/pull/356), [#556](https://github.com/stlink-org/stlink/pull/556), [#593](https://github.com/stlink-org/stlink/pull/593), [#607](https://github.com/stlink-org/stlink/pull/607), [#612](https://github.com/stlink-org/stlink/pull/612), [#638](https://github.com/stlink-org/stlink/pull/638), [#661](https://github.com/stlink-org/stlink/pull/661), [#690](https://github.com/stlink-org/stlink/pull/690), [#979](https://github.com/stlink-org/stlink/pull/979), [#1043](https://github.com/stlink-org/stlink/pull/1043), [#1054](https://github.com/stlink-org/stlink/pull/1054), [#1105](https://github.com/stlink-org/stlink/pull/1105), [#1113](https://github.com/stlink-org/stlink/pull/1113)) - Fixed old DFU serial number for STLINK programmers ([#417](https://github.com/stlink-org/stlink/pull/417), [#494](https://github.com/stlink-org/stlink/pull/494), [#1106](https://github.com/stlink-org/stlink/pull/1106)) - [regression] Changed timeout on flash write ([#787](https://github.com/stlink-org/stlink/pull/787), [#981](https://github.com/stlink-org/stlink/pull/981), [#987](https://github.com/stlink-org/stlink/pull/987)) - cmake compile failure with external `CMAKE_MODULE_PATH` set ([#962](https://github.com/stlink-org/stlink/pull/962)) @@ -45,8 +48,10 @@ Fixes: - Fix for `mmap() size_t overflow` in `st-flash` ([#988](https://github.com/stlink-org/stlink/pull/988), [#989](https://github.com/stlink-org/stlink/pull/989)) - [regression] `stlink-gui` installation issue on Ubuntu-18.04 ([#1001](https://github.com/stlink-org/stlink/pull/1001), [#1004](https://github.com/stlink-org/stlink/pull/1004), [#1006](https://github.com/stlink-org/stlink/pull/1006)) - `st-util`: wrong register values passed to `gdb` (STLink/V2) ([#1002](https://github.com/stlink-org/stlink/pull/1002), [#1011](https://github.com/stlink-org/stlink/pull/1011), [#1026](https://github.com/stlink-org/stlink/pull/1026), [#1027](https://github.com/stlink-org/stlink/pull/1027), [#1064](https://github.com/stlink-org/stlink/pull/1064), [#1065](https://github.com/stlink-org/stlink/pull/1065)) +- GDB: Fixed problems with target description ([#1013](https://github.com/stlink-org/stlink/pull/1013), [#1088](https://github.com/stlink-org/stlink/pull/1088), [#1109](https://github.com/stlink-org/stlink/pull/1109)) - [doc] Fixed wrong path for `rules.d` folder ([#1020](https://github.com/stlink-org/stlink/pull/1020)) - Use vl flashloader for all STM32F1 series ([#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) +- Fixed support for STLINK/V1 programmer ([#1045](https://github.com/stlink-org/stlink/pull/1045), [#1105](https://github.com/stlink-org/stlink/pull/1105)) - st-util v1.6.1 does not recognize option --freq (commit [#e576768](https://github.com/stlink-org/stlink/commit/e5767681f14de9851aa970a9299930ca68b2ed92), [#1055](https://github.com/stlink-org/stlink/pull/1055)) - Fixed `gettimeofday` for MSVC ([#1074](https://github.com/stlink-org/stlink/pull/1074)) - Bugfixes for compilation with clang ([#1076](https://github.com/stlink-org/stlink/pull/1076), [#1078](https://github.com/stlink-org/stlink/pull/1078)) @@ -54,7 +59,6 @@ Fixes: - [regression] Flash_loader: increased wait rounds for slow boards ([#1085](https://github.com/stlink-org/stlink/pull/1085)) - Fixed support for writing option bytes ([#1102](https://github.com/stlink-org/stlink/pull/1102)) - [doc] Corrected spelling mistake in bug report template ([#1103](https://github.com/stlink-org/stlink/pull/1103)) -- Fixed support for STLINK/V1 programmer ([#1045](https://github.com/stlink-org/stlink/pull/1045), [#1105](https://github.com/stlink-org/stlink/pull/1105)) - Fixed STM32WB55 reading DEBUG IDCODE from the wrong address ([#1100](https://github.com/stlink-org/stlink/pull/1100), [#1101](https://github.com/stlink-org/stlink/pull/1101)) # v1.6.1 @@ -179,8 +183,8 @@ Major changes and added features: Updates and fixes: -- Fixed `unkown chip id`, piped output and `st-util -v` ([#107](https://github.com/stlink-org/stlink/pull/107), [#665](https://github.com/stlink-org/stlink/pull/665), [#763](https://github.com/stlink-org/stlink/pull/763)) - Fixed an issue with versioning stuck at 1.4.0 for versions cloned with git ([#563](https://github.com/stlink-org/stlink/pull/563), [#762](https://github.com/stlink-org/stlink/pull/762), [#772](https://github.com/stlink-org/stlink/pull/772)) +- Fixed `unkown chip id`, piped output and `st-util -v` ([#665](https://github.com/stlink-org/stlink/pull/665), [#763](https://github.com/stlink-org/stlink/pull/763)) - Updated STM32F3xx chip ID that covers a few different devices ([#685](https://github.com/stlink-org/stlink/pull/685), [#758](https://github.com/stlink-org/stlink/pull/758)) - Made udev rules and modprobe conf installation optional ([#741](https://github.com/stlink-org/stlink/pull/741)) - Fixed case when `__FILE__` doesn't contain either `/` nor `\\` ([#745](https://github.com/stlink-org/stlink/pull/745)) @@ -385,12 +389,14 @@ Updates and fixes: - Fixed STM32F2xx memory map (Nicolas Schodet) - Memory map for STM32F42xxx and STM32F43xxx devices (Craig Lilley) - Stm32l0x flash loader (Robin Kreis) -- Use libusb synchronous api ([#194](https://github.com/stlink-org/stlink/pull/194), [#374](https://github.com/stlink-org/stlink/pull/374)) +- Modified determination of erased byte pattern when flashing ([#193](https://github.com/stlink-org/stlink/pull/193), [#377](https://github.com/stlink-org/stlink/pull/377)) +- Use libusb synchronous api ([#194](https://github.com/stlink-org/stlink/pull/194), [#225](https://github.com/stlink-org/stlink/pull/225), [#374](https://github.com/stlink-org/stlink/pull/374)) - Fixed segfault when programmer is already busy and `NULL` pointers are in the list ([#256](https://github.com/stlink-org/stlink/pull/256), [#394](https://github.com/stlink-org/stlink/pull/394)) - Fixed issue where "unknown chip id!" was seen every other time ([#352](https://github.com/stlink-org/stlink/pull/352), [#367](https://github.com/stlink-org/stlink/pull/367), [#381](https://github.com/stlink-org/stlink/pull/381)) - Send F4 memory-map and features for STM32F429 ([#188](https://github.com/stlink-org/stlink/pull/188), [#196](https://github.com/stlink-org/stlink/pull/196), [#250](https://github.com/stlink-org/stlink/pull/250), [#251](https://github.com/stlink-org/stlink/pull/251)) (Release v1.1.0) - Added AHB3 Peripherals definition for STM32F4 ([#218](https://github.com/stlink-org/stlink/pull/218), [#288](https://github.com/stlink-org/stlink/pull/288)) (Release v1.1.0) - Reset: st-flash does not work when CPU is in sleep mode ([#62](https://github.com/stlink-org/stlink/pull/62)) (Release v1.0.0) +- Ensure USB device search succeeds if the matched device is at index 0 ([#126](https://github.com/stlink-org/stlink/pull/126), [#151](https://github.com/stlink-org/stlink/pull/151)) (Release v1.0.0) - Corrected flash size register address for STM32F2 devices ([#278](https://github.com/stlink-org/stlink/pull/278)) (Release v1.0.0) Chip support added for: diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..caa2740db --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,20 @@ +# Security Policy + +## Supported Versions + +The following versions of the stlink toolset are currently being supported.
As this is a development toolset, please note that bugfixes will only be applied to the latest version. + +| Version | Supported | +| ------- | ------------------ | +| develop | :white_check_mark: | +| 1.6.x | :white_check_mark: | +| 1.5.x | :x: | +| 1.4.0 | :x: | +| 1.3.x | :x: | +| 1.2.0 | :x: | +| 1.1.0 | :x: | +| 1.0.0 | :x: | + +## Reporting a Vulnerability + +Detected vulnerabilities in the toolset should be reported by opening a regular bugreport issue. diff --git a/doc/tutorial.md b/doc/tutorial.md index d4cf89ce2..8b1220747 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -2,15 +2,16 @@ ## Available tools and options -| Option | Tool | Description | Available
since | -| --------------------- | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -| --flash=n[k][m] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k
for the STM32F103C8T6 to assume 128k of flash being present. This option accepts
decimal (128k), octal 0200k, or hex 0x80k values. Leaving the multiplier out is
equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional "k"
or "m" to multiply the given value by 1k (1024) or 1M respectively. | v1.4.0 | -| --freq=n[k][m] | st-flash | The frequency of the SWD/JTAG interface can be specified, to override the default
1800 kHz configuration. This option solely accepts decimal values (5K or 1.8M) with
the unit `Hz` being left out. Valid frequencies are: `5K, 15K, 25K, 50K, 100K,`
`125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)`. | v1.6.1 | -| --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at
the end of binary file. This may cause some garbage data left after a flash operation.
This option was enabled by default in earlier releases. | v1.6.1 | -| --reset | st-flash | Trigger a reset both before and after flashing. The default use the hardware reset
through `NRST` pin. The software system reset is used if the hardware reset failed
(`NRST` pin not connected). | v1.0.0 | -| --connect-under-reset | st-flash | Connect under reset. Option makes it possible to connect to the device before code
executing. This is useful when the target contains a code that go device to sleep,
disables of debug pins or other special code. | v1.6.1 | -| --version | st-info
st-flash
st-util | Print version information. | | -| --help | st-flash
st-util | Print list of available commands. _(To be added to this table.)_ | | +| Option | Tool | Description | Available
since | +| --------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | +| --flash=n[k][m] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k for the STM32F103C8T6
to assume 128k of flash being present. This option accepts decimal (128k), octal 0200k, or hex 0x80k values.
Leaving the multiplier out is equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional
"k" or "m" to multiply the given value by 1k (1024) or 1M respectively. | v1.4.0 | +| --freq=n[k][m] | st-flash | The frequency of the SWD/JTAG interface can be specified, to override the default 1800 kHz configuration.
This option solely accepts decimal values (5K or 1.8M) with the unit `Hz` being left out. Valid frequencies are:
`5K, 15K, 25K, 50K, 100K, 125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)`. | v1.6.1 | +| --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at the end of binary file.
This may cause some garbage data left after a flash operation. This option was enabled by default in earlier releases. | v1.6.1 | +| --reset | st-flash | Trigger a reset both before and after flashing. The default uses the hardware reset through `NRST` pin.
The software reset is used if the hardware reset failed (`NRST` pin not connected). | v1.0.0 | +| --connect-under-reset | st-flash | Connect under reset. Option makes it possible to connect to the device before code execution. This is useful
when the target contains code that lets the device go to sleep, disables debug pins or other special code. | v1.6.1 | +| --probe | st-info | Display hardware information about the connected programmer and target MCU. | v1.2.0 | +| --version | st-info
st-flash
st-util | Print version information. | v1.3.0 | +| --help | st-flash
st-util | Print list of available commands. | | ### st-flash: Checksum for binary files @@ -102,17 +103,52 @@ Check your hardware and try to identify what you have in front of you before ass Please let us know, if you come across any further websites or tutorials that help to identify STM32 fake chips so we can list them here to help others. ---- +### c) Appearance of the warning message `WARN src/common.c: unknown chip id!` + +The chip ID is the main identifier for STM32 MCU and their specific type and provides primary information on flash and SRAM architecture. +This so called `DBGMCU_IDCODE` register is allocated either at memory address `0xE0042000` or `0x40015800`. + +A failure of chip identification results in the error `WARN src/common.c: unknown chip id!`. +There are different variants of this message that refer to different issues: + +- `unknown chip id! 0` --> _currently unknown_ +- `unknown chip id! 0x1a` --> _currently unknown_ +- `unknown chip id! 0x001f` --> _currently unknown_ +- `unknown chip id! 0x3e8` --> _currently unknown_ +- `unknown chip id! 0xa05f0000` --> _currently unknown_ +- `unknown chip id! 0x3748` --> A target chip / board cannot be detected. + 1. No target is connected --> In this case `st-info --probe` displays `chip id 0x0748` with STLINK/V2 and `chip id 0x03e8` with STLINK-V3. + 2. The chip is connected but has gone into an undefined state of operation where the SWD pins are unresponsive. --> Try to use `--connect-under-reset` while pressing the reset button on the target board. + 3. A firmware-issue prevents the programmer from normal operation. --> Ensure that your programmer runs the latest firmware version and consider to upgrade any older version by using the official firmware upgrade tool provided by STMicroelectronics. +- `unknown chip id! 0xe0042000` --> The memory register holding the information on the chip ID could not be read. The following problems may lead to this case: + 1. This problem is caused by the SWDIO and SWCLK being configured for other purpose (GPIO, etc) other than Serial Wire configuration or Jtag --> A possible solution to this is to short the `BOOT0` pin with `VDD` (1) and to reset the chip / board by the execuing `st-flash erase` in order to return the MCU back to normal operation. Afterwards `BOOT0` should be set back to `GND` (0). + 2. There is a hardware defect in the connection between the MCU and the used programmer (solder points, cables, connectors). + +### d) Understanding hardware and software reset functionality for `st-flash` and reset-related device recovery + +Typically a reset signal is sent via the reset pin `NRST`. Using `st-flash` for flashing results in the following behaviour: -( Content below is currently unrevised and may be outdated as of Apr 2020. ) +- without the `--reset` option: `st-flash write` results in one reset signal on the `NRST` line +- with the `--reset` option: `st-flash write --reset` results in two subsequent reset signals on the `NRST` line -# Using STM32 discovery kits with open source tools +Depending on the used programmer the hardware reset line is not always connected. +This is especially the case for low-cost STLINK/V2 clone programmers. +Here the SWD connector consists of only 4 pins: `VCC`, `SWCLK`, `GND` and `SWDATA`. -This guide details the use of STMicroelectronics STM32 discovery kits in an open source environment. +When the physical reset line `NRST` is not connected, a reset is initiated by software via `SWD_SWDIO/JTAG_TMS` (software reset). +Just as mentioned above, flashing is possible here eiher with and without the `--reset` option. -## Installing a GNU toolchain +Configuring the STM32 pin `JTAG_TMS/SWD_SWDIO` as an output now also prevents the SWD interface from flashing and resetting the device. +In consequence this constellation typically requires a _hard reset_ to allow for the ST-Link/V2 programmer to reconnect to the target at all. -Any toolchain supporting the cortex m3 should do. +As soon as the device is in DFU mode, the `JTAG_TMS/SWD_SWDIO` pin is left in the default state with all JTAG pins available. +Here flashing of the device is now possible with and without the `--reset` option. + +The debug command `(gdb) monitor jtag_reset` sends a _hard reset_ signal via the `NRST` pin to reset the device and allows for flashing it (again). + +--- + +( Content below is currently unrevised and may be outdated as of Mar 2021. ) ## Using the GDB server @@ -201,7 +237,6 @@ Of course, you can use this instead of the gdb server, if you prefer. Just remember to use the “.bin” image, rather than the .elf file. ``` - # write blink.bin into FLASH $> [sudo] ./st-flash write fancy_blink.bin 0x08000000 ``` diff --git a/doc/version_support.md b/doc/version_support.md index 1edf2e19c..5d2cdd375 100644 --- a/doc/version_support.md +++ b/doc/version_support.md @@ -14,10 +14,10 @@ Thus no user interaction regarding libusb is necessary. ### Apple macOS -| Package Repository | libusb
version | cmake
version | gtk-3
version | Supported macOS versions | -| ------------------ | ------------------- | ------------------ | ------------------ | -------------------------------------- | -| homebrew | 1.0.23 | 3.17.0 | 3.24.18
gtk+3 | 10.12 (Sierra)- 10.15 (Catalina) | -| MacPorts | 1.0.23 | 3.17.0 | 3.24.18
gtk3 | 10.6 (Snow Leopard) - 10.15 (Catalina) | +| Package Repository | libusb
version | cmake
version | gtk-3
version | Supported macOS versions | +| ------------------ | ------------------- | ------------------ | ------------------ | ------------------------ | +| homebrew | 1.0.23 | 3.17.0 | 3.24.18
gtk+3 | 10.9 - 10.15 | +| MacPorts | 1.0.23 | 3.17.0 | 3.24.18
gtk3 | 10.4 - 10.15 | NOTE: In order to use a STLINK/V1 programmer on macOS, versions 10.14 or 10.15 are required. From b387c93ee007a2bde37daba8198a2108ec9704e5 Mon Sep 17 00:00:00 2001 From: anton Date: Thu, 25 Mar 2021 19:25:33 +0500 Subject: [PATCH 26/65] Extended set of command line arguments st-info: added --freq, --hot-plug and --connect-under-reset to probe st-util: added --freq --- doc/tutorial.md | 7 ++-- src/st-flash/flash.c | 11 +++--- src/st-flash/flash.h | 2 +- src/st-flash/flash_opts.c | 57 ++++++++---------------------- src/st-info/info.c | 74 +++++++++++++++++++++------------------ src/st-util/gdb-server.c | 36 ++++++++++++------- src/stlink-lib/helper.c | 14 ++++++++ src/stlink-lib/helper.h | 2 ++ src/stlink-lib/usb.c | 19 +++++----- src/stlink-lib/usb.h | 12 +++++-- 10 files changed, 122 insertions(+), 112 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 8b1220747..2403590ac 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -5,10 +5,11 @@ | Option | Tool | Description | Available
since | | --------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | | --flash=n[k][m] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k for the STM32F103C8T6
to assume 128k of flash being present. This option accepts decimal (128k), octal 0200k, or hex 0x80k values.
Leaving the multiplier out is equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional
"k" or "m" to multiply the given value by 1k (1024) or 1M respectively. | v1.4.0 | -| --freq=n[k][m] | st-flash | The frequency of the SWD/JTAG interface can be specified, to override the default 1800 kHz configuration.
This option solely accepts decimal values (5K or 1.8M) with the unit `Hz` being left out. Valid frequencies are:
`5K, 15K, 25K, 50K, 100K, 125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)`. | v1.6.1 | +| --freq=n[k][m] | st-info
st-flash
st-util | The frequency of the SWD/JTAG interface can be specified, to override the default 1800 kHz configuration.
This option solely accepts decimal values (5K or 1.8M) with the unit `Hz` being left out. Valid frequencies are:
`5K, 15K, 25K, 50K, 100K, 125K, 240K, 480K, 950K, 1200K, 1800K, 4000K(4M)`. | v1.6.1 | | --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at the end of binary file.
This may cause some garbage data left after a flash operation. This option was enabled by default in earlier releases. | v1.6.1 | | --reset | st-flash | Trigger a reset both before and after flashing. The default uses the hardware reset through `NRST` pin.
The software reset is used if the hardware reset failed (`NRST` pin not connected). | v1.0.0 | -| --connect-under-reset | st-flash | Connect under reset. Option makes it possible to connect to the device before code execution. This is useful
when the target contains code that lets the device go to sleep, disables debug pins or other special code. | v1.6.1 | +| --connect-under-reset | st-info
st-flash | Connect under reset. Option makes it possible to connect to the device before code execution. This is useful
when the target contains code that lets the device go to sleep, disables debug pins or other special code. | v1.6.1 | +| --hot-plug | st-info
st-util | Connect to the target without reset. | v1.6.2 | | --probe | st-info | Display hardware information about the connected programmer and target MCU. | v1.2.0 | | --version | st-info
st-flash
st-util | Print version information. | v1.3.0 | | --help | st-flash
st-util | Print list of available commands. | | @@ -262,7 +263,7 @@ There are a few options: -m, --multi Set gdb server to extended mode. st-util will continue listening for connections after disconnect. - -n, --no-reset + -n, --no-reset, --hot-plug Do not reset board on connection. ``` diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 447daa158..5a226d57b 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -26,9 +26,9 @@ static void cleanup(int signum) { } static void usage(void) { - puts("command line: ./st-flash [--debug] [--reset] [--connect-under-reset] [--opt] [--serial ] [--format ] [--flash=] [--freq=] [--area=] {read|write} [path] [addr] [size]"); - puts("command line: ./st-flash [--debug] [--connect-under-reset] [--freq=] [--serial ] erase"); - puts("command line: ./st-flash [--debug] [--freq=] [--serial ] reset"); + puts("command line: ./st-flash [--debug] [--reset] [--connect-under-reset] [--opt] [--serial ] [--format ] [--flash=] [--freq=] [--area=] {read|write} [path] [addr] [size]"); + puts("command line: ./st-flash [--debug] [--connect-under-reset] [--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."); @@ -52,6 +52,7 @@ int main(int ac, char** av) { uint8_t * mem = NULL; o.size = 0; + o.connect = CONNECT_NORMAL; if (flash_get_opts(&o, ac - 1, av + 1) == -1) { printf("invalid command line\n"); @@ -61,9 +62,7 @@ int main(int ac, char** av) { printf("st-flash %s\n", STLINK_VERSION); - sl = stlink_open_usb(o.log_level, - o.connect_under_reset ? 2 : 1, - (char *)o.serial, o.freq); + sl = stlink_open_usb(o.log_level, o.connect, (char *)o.serial, o.freq); if (sl == NULL) { return(-1); } diff --git a/src/st-flash/flash.h b/src/st-flash/flash.h index 8a5c2ad29..cd08db70f 100644 --- a/src/st-flash/flash.h +++ b/src/st-flash/flash.h @@ -26,7 +26,7 @@ struct flash_opts { size_t flash_size; // --flash=n[k][m] int opt; // enable empty tail data drop optimization int freq; // --freq=n[k][m] frequency of JTAG/SWD - bool connect_under_reset; + enum connect_type connect; }; #define FLASH_OPTS_INITIALIZER {0, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index 7d846e425..63774ea25 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -2,6 +2,8 @@ #include #include +#include + #include "flash.h" static bool starts_with(const char * str, const char * prefix) { @@ -140,50 +142,21 @@ 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); - } + } else if (strcmp(av[0], "--freq") == 0) { + ac--; + av++; - freq = av[0]; - } else { - freq = av[0] + strlen("--freq="); + if (ac < 1) { + return(-1); } - 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 { + o->freq = arg_parse_freq(av[0]); + if (o->freq < 0) { + return(-1); + } + } else if (starts_with(av[0], "--freq=")) { + o->freq = arg_parse_freq(av[0] + strlen("--freq=")); + if (o->freq < 0) { return(-1); } } else if (strcmp(av[0], "--format") == 0 || starts_with(av[0], "--format=")) { @@ -219,7 +192,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { o->flash_size = (size_t)flash_size; } } else if (strcmp(av[0], "--connect-under-reset") == 0) { - o->connect_under_reset = true; + o->connect = CONNECT_UNDER_RESET; } else { break; // non-option found diff --git a/src/st-info/info.c b/src/st-info/info.c index c1ac86373..a6b4e85c6 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -4,16 +4,17 @@ #include #include +#include static void usage(void) { puts("st-info --version"); - puts("st-info --probe"); + puts("st-info --probe [--connect-under-reset] [--hot-plug] [--freq=]"); puts("st-info --serial"); - puts("st-info --flash [--connect-under-reset]"); - puts("st-info --pagesize [--connect-under-reset]"); - puts("st-info --sram [--connect-under-reset]"); - puts("st-info --chipid [--connect-under-reset]"); - puts("st-info --descr [--connect-under-reset]"); + puts("st-info --flash [--connect-under-reset] [--hot-plug] [--freq=]"); + puts("st-info --pagesize [--connect-under-reset] [--hot-plug] [--freq=]"); + puts("st-info --sram [--connect-under-reset] [--hot-plug] [--freq=]"); + puts("st-info --chipid [--connect-under-reset] [--hot-plug] [--freq=]"); + puts("st-info --descr [--connect-under-reset] [--hot-plug] [--freq=]"); } static void stlink_print_version(stlink_t *sl) { @@ -45,11 +46,11 @@ static void stlink_print_info(stlink_t *sl) { if (params) { printf(" descr: %s\n", params->description); } } -static void stlink_probe(void) { +static void stlink_probe(enum connect_type connect, int freq) { stlink_t **stdevs; size_t size; - size = stlink_probe_usb(&stdevs); + size = stlink_probe_usb(&stdevs, connect, freq); printf("Found %u stlink programmers\n", (unsigned int)size); @@ -61,44 +62,47 @@ static void stlink_probe(void) { stlink_probe_usb_free(&stdevs, size); } -static stlink_t *stlink_open_first(bool under_reset) { +static int print_data(int ac, char **av) { stlink_t* sl = NULL; - sl = stlink_v1_open(0, 1); + enum connect_type connect = CONNECT_NORMAL; + int freq = 0; - if (sl == NULL) { - if (under_reset) { - sl = stlink_open_usb(0, 2, NULL, 0); - } else { - sl = stlink_open_usb(0, 1, NULL, 0); - } + if (strcmp(av[1], "--version") == 0) { + printf("v%s\n", STLINK_VERSION); + return(0); } - return(sl); -} + for (int i=2; i= 0) { continue; } + } + } else if (strncmp(av[i], "--freq=", 7) == 0) { + freq = arg_parse_freq(av[i] + 7); + if (freq >= 0) { continue; } + } -static int print_data(int ac, char **av) { - stlink_t* sl = NULL; - bool under_reset = false; + printf("Incorrect argument: %s\n\n", av[i]); + usage(); + return(-1); + } // probe needs all devices unclaimed if (strcmp(av[1], "--probe") == 0) { - stlink_probe(); - return(0); - } else if (strcmp(av[1], "--version") == 0) { - printf("v%s\n", STLINK_VERSION); + stlink_probe(connect, freq); return(0); } - if (ac == 3) { - if (strcmp(av[2], "--connect-under-reset") == 0) { - under_reset = true; - } else { - usage(); - return(-1); - } - } - - sl = stlink_open_first(under_reset); + // open first st-link device + sl = stlink_open_usb(0, connect, NULL, freq); if (sl == NULL) { return(-1); } diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index d7ca6d008..3dc3073e5 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -26,6 +26,7 @@ #endif #include +#include #include #include "gdb-remote.h" #include "gdb-server.h" @@ -63,7 +64,8 @@ typedef struct _st_state_t { int logging_level; int listen_port; int persistent; - int reset; + enum connect_type connect_mode; + int freq; } st_state_t; @@ -100,9 +102,9 @@ 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, 0); + sl = stlink_open_usb(st->logging_level, st->connect_mode, serialnumber, st->freq); } else { - sl = stlink_open_usb(st->logging_level, st->reset, NULL, 0); + sl = stlink_open_usb(st->logging_level, st->connect_mode, NULL, st->freq); } return(sl); @@ -116,6 +118,8 @@ int parse_options(int argc, char** argv, st_state_t *st) { {"listen_port", required_argument, NULL, 'p'}, {"multi", optional_argument, NULL, 'm'}, {"no-reset", optional_argument, NULL, 'n'}, + {"hot-plug", optional_argument, NULL, 'n'}, + {"freq", optional_argument, NULL, 'F'}, {"version", no_argument, NULL, 'V'}, {"semihosting", no_argument, NULL, SEMIHOSTING_OPTION}, {"serial", required_argument, NULL, SERIAL_OPTION}, @@ -126,16 +130,16 @@ int parse_options(int argc, char** argv, st_state_t *st) { " -V, --version\t\tPrint the version\n" " -vXX, --verbose=XX\tSpecify a specific verbosity level (0..99)\n" " -v, --verbose\t\tSpecify generally verbose logging\n" - "\t\t\tChoose what version of stlink to use, (defaults to 2)\n" - " -1, --stlinkv1\tForce stlink version 1\n" " -p 4242, --listen_port=1234\n" "\t\t\tSet the gdb server listen port. " "(default port: " STRINGIFY(DEFAULT_GDB_LISTEN_PORT) ")\n" " -m, --multi\n" "\t\t\tSet gdb server to extended mode.\n" "\t\t\tst-util will continue listening for connections after disconnect.\n" - " -n, --no-reset\n" + " -n, --no-reset, --hot-plug\n" "\t\t\tDo not reset board on connection.\n" + " -F 1800K, --freq=1M\n" + "\t\t\tSet the frequency of the SWD/JTAG interface.\n" " --semihosting\n" "\t\t\tEnable semihosting support.\n" " --serial \n" @@ -160,7 +164,6 @@ int parse_options(int argc, char** argv, st_state_t *st) { exit(EXIT_SUCCESS); break; case 'v': - if (optarg) { st->logging_level = atoi(optarg); } else { @@ -170,7 +173,6 @@ int parse_options(int argc, char** argv, st_state_t *st) { break; case 'p': sscanf(optarg, "%i", &q); - if (q < 0) { fprintf(stderr, "Can't use a negative port to listen on: %d\n", q); exit(EXIT_FAILURE); @@ -178,11 +180,19 @@ int parse_options(int argc, char** argv, st_state_t *st) { st->listen_port = q; break; + case 'm': st->persistent = 1; break; case 'n': - st->reset = 0; + st->connect_mode = CONNECT_HOT_PLUG; + break; + case 'F': + st->freq = arg_parse_freq(optarg); + if (st->freq < 0) { + fprintf(stderr, "Can't parse a frequency: %s\n", optarg); + exit(EXIT_FAILURE); + } break; case 'V': printf("v%s\n", STLINK_VERSION); @@ -217,7 +227,7 @@ int main(int argc, char** argv) { // set defaults ... state.logging_level = DEFAULT_LOGGING_LEVEL; state.listen_port = DEFAULT_GDB_LISTEN_PORT; - state.reset = 1; // by default, reset board + state.connect_mode = CONNECT_NORMAL; // by default, reset board parse_options(argc, argv, &state); printf("st-util\n"); @@ -240,7 +250,7 @@ int main(int argc, char** argv) { signal(SIGSEGV, &cleanup); #endif - if (state.reset) { stlink_reset(sl); } + if (state.connect_mode != CONNECT_HOT_PLUG) { stlink_reset(sl); } DLOG("Chip ID is %#010x, Core ID is %#08x.\n", sl->chip_id, sl->core_id); @@ -1111,7 +1121,7 @@ int serve(stlink_t *sl, st_state_t *st) { stlink_force_debug(sl); - if (st->reset) { stlink_reset(sl); } + if (st->connect_mode != CONNECT_HOT_PLUG) { stlink_reset(sl); } init_code_breakpoints(sl); init_data_watchpoints(sl); @@ -1840,7 +1850,7 @@ int serve(stlink_t *sl, st_state_t *st) { connected_stlink = sl; - if (st->reset) { stlink_reset(sl); } + if (st->connect_mode != CONNECT_HOT_PLUG) { stlink_reset(sl); } ret = stlink_force_debug(sl); diff --git a/src/stlink-lib/helper.c b/src/stlink-lib/helper.c index 32d9b6c8d..1f0f71b8d 100644 --- a/src/stlink-lib/helper.c +++ b/src/stlink-lib/helper.c @@ -1,6 +1,7 @@ #include #include +#include #ifdef STLINK_HAVE_SYS_TIME_H #include @@ -13,3 +14,16 @@ unsigned time_ms() { gettimeofday(&tv, NULL); return (unsigned)(tv.tv_sec * 1000 + tv.tv_usec / 1000); } + +int arg_parse_freq(const char *str) { + char *tail; + int value = (int)strtol(str, &tail, 10); + + if ((tail[0] == 'm' || tail[0] == 'M') && tail[1] == '\0') { + value = value*1000; + } else if (((tail[0] != 'k' && tail[0] != 'K') || tail[1] != '\0') && tail[0] != '\0') { + return -1; + } + + return value; +} diff --git a/src/stlink-lib/helper.h b/src/stlink-lib/helper.h index 12c2ea2a7..96467377a 100644 --- a/src/stlink-lib/helper.h +++ b/src/stlink-lib/helper.h @@ -3,4 +3,6 @@ unsigned time_ms(); +int arg_parse_freq(const char *str); + #endif /* SYS_HELPER_H */ diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 569815665..ce0d672c8 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -46,7 +46,7 @@ static int _stlink_match_speed_map(const uint32_t *map, unsigned int map_size, u // get abs value for comparison current_diff = (current_diff > 0) ? current_diff : -current_diff; - if ((current_diff < speed_diff) && khz >= map[i]) { + if (current_diff < speed_diff) { speed_diff = current_diff; speed_index = i; } @@ -741,6 +741,8 @@ int _stlink_usb_set_swdclk(stlink_t* sl, int clk_freq) { } return(0); + } else if (clk_freq) { + WLOG("ST-Link firmware does not support frequency setup\n"); } return(-1); @@ -1196,7 +1198,7 @@ size_t stlink_serial(struct libusb_device_handle *handle, struct libusb_device_d return strlen(serial); } -stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STLINK_SERIAL_BUFFER_SIZE], int freq) { +stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, char serial[STLINK_SERIAL_BUFFER_SIZE], int freq) { stlink_t* sl = NULL; struct stlink_libusb* slu = NULL; int ret = -1; @@ -1380,7 +1382,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STL DLOG("JTAG/SWD freq set to %d\n", freq); stlink_set_swdclk(sl, freq); - if (reset == 2) { + if (connect == CONNECT_UNDER_RESET) { stlink_jtag_reset(sl, 0); if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } @@ -1390,10 +1392,9 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STL usleep(10000); } - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } - if (reset == 1) { + if (connect == CONNECT_NORMAL) { if ( sl->version.stlink_v > 1) { stlink_jtag_reset(sl, 2); } stlink_reset(sl); @@ -1420,7 +1421,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STL return(NULL); } -static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { +static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[], enum connect_type connect, int freq) { stlink_t **_sldevs; libusb_device *dev; int i = 0; @@ -1489,7 +1490,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { if (serial_len != STLINK_SERIAL_LENGTH) { continue; } - stlink_t *sl = stlink_open_usb(0, 1, serial, 0); + stlink_t *sl = stlink_open_usb(0, connect, serial, freq); if (!sl) { ELOG("Failed to open USB device %#06x:%#06x\n", desc.idVendor, desc.idProduct); @@ -1504,7 +1505,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) { return(slcur); } -size_t stlink_probe_usb(stlink_t **stdevs[]) { +size_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int freq) { libusb_device **devs; stlink_t **sldevs; @@ -1520,7 +1521,7 @@ size_t stlink_probe_usb(stlink_t **stdevs[]) { if (cnt < 0) { return(0); } - slcnt = stlink_probe_usb_devs(devs, &sldevs); + slcnt = stlink_probe_usb_devs(devs, &sldevs, connect, freq); libusb_free_device_list(devs, 1); libusb_exit(NULL); diff --git a/src/stlink-lib/usb.h b/src/stlink-lib/usb.h index 512370a10..f48ef225d 100644 --- a/src/stlink-lib/usb.h +++ b/src/stlink-lib/usb.h @@ -48,6 +48,12 @@ extern "C" { #define STLINK_SG_SIZE 31 #define STLINK_CMD_SIZE 16 +enum connect_type { + CONNECT_HOT_PLUG = 0, + CONNECT_NORMAL = 1, + CONNECT_UNDER_RESET = 2, +}; + struct stlink_libusb { libusb_context* libusb_ctx; libusb_device_handle* usb_handle; @@ -62,13 +68,13 @@ struct stlink_libusb { /** * Open a stlink * @param verbose Verbosity loglevel - * @param reset Reset stlink programmer + * @param connect Type of connect to target * @param serial Serial number to search for, when NULL the first stlink found is opened (binary format) * @retval NULL Error while opening the stlink * @retval !NULL Stlink found and ready to use */ -stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STLINK_SERIAL_BUFFER_SIZE], int freq); -size_t stlink_probe_usb(stlink_t **stdevs[]); +stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, char serial[STLINK_SERIAL_BUFFER_SIZE], int freq); +size_t stlink_probe_usb(stlink_t **stdevs[], enum connect_type connect, int freq); void stlink_probe_usb_free(stlink_t **stdevs[], size_t size); #ifdef __cplusplus From 5b8ee390eec6e83bfb67c026248f0cffc9e84ab0 Mon Sep 17 00:00:00 2001 From: Oleksiy Slyshyk Date: Sat, 27 Mar 2021 12:27:43 +0200 Subject: [PATCH 27/65] remove abort() from lib. related to #634 --- src/common.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/common.c b/src/common.c index 8fae08a09..72150953b 100644 --- a/src/common.c +++ b/src/common.c @@ -980,7 +980,7 @@ static inline uint32_t read_flash_sr(stlink_t *sl, unsigned bank) { } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { sr_reg = (bank==BANK_1)?FLASH_H7_SR1:FLASH_H7_SR2; } else { - ELOG("unsupported flash method, abort"); + ELOG("unsupported flash method, abort\n"); return(-1); } @@ -1010,7 +1010,7 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { sr_busy_shift = FLASH_H7_SR_QW; } else { - ELOG("unsupported flash method, abort"); + ELOG("unsupported flash method, abort\n"); return(-1); } @@ -1617,9 +1617,8 @@ int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { DLOG("*** stlink_write_mem32 %u bytes to %#x\n", len, addr); if (len % 4 != 0) { - fprintf(stderr, "Error: Data length doesn't have a 32 bit alignment: +%d byte.\n", - len % 4); - abort(); + ELOG("Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); + return(-1); } return(sl->backend->write_mem32(sl, addr, len)); @@ -1629,9 +1628,8 @@ int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { DLOG("*** stlink_read_mem32 ***\n"); if (len % 4 != 0) { // !!! never ever: fw gives just wrong values - fprintf(stderr, "Error: Data length doesn't have a 32 bit alignment: +%d byte.\n", - len % 4); - abort(); + ELOG("Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); + return(-1); } return(sl->backend->read_mem32(sl, addr, len)); @@ -1641,9 +1639,8 @@ int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { DLOG("*** stlink_write_mem8 ***\n"); if (len > 0x40) { // !!! never ever: Writing more then 0x40 bytes gives unexpected behaviour - fprintf(stderr, "Error: Data length > 64: +%d byte.\n", - len); - abort(); + ELOG("Data length > 64: +%d byte.\n", len); + return(-1); } return(sl->backend->write_mem8(sl, addr, len)); From 0b7221076a9b66cfb9647e4f06d55d66229e0799 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 27 Mar 2021 11:41:09 +0100 Subject: [PATCH 28/65] General Project Update - Updated CHANGELOG.md - [doc] Update for GD32F303VGT6 in device list - [doc] Updated tutorial.md > Added refs for unknown chip id! 0 > Minor update for tool option table --- CHANGELOG.md | 8 ++++---- doc/devices_boards.md | 6 +++--- doc/tutorial.md | 8 +++++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3f8e13b5..ee46901e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # v1.6.2 -Release date: (planned H1/2021) +Release date: (planned Q2/2021) Features: @@ -21,7 +21,7 @@ Features: Updates & changes: -- [doc] Added tutorial section on unknown chip id error ([#107](https://github.com/stlink-org/stlink/pull/107), [#568](https://github.com/stlink-org/stlink/pull/568), +- [doc] Added tutorial section on unknown chip id error (commit [#229c721](https://github.com/stlink-org/stlink/commit/229c721189587760db5509c59b3c02e93e7035c8), [#107](https://github.com/stlink-org/stlink/pull/107), [#568](https://github.com/stlink-org/stlink/pull/568)) - [doc] Updated documentation on target resetting ([#261](https://github.com/stlink-org/stlink/pull/261), [#533](https://github.com/stlink-org/stlink/pull/533), [#1107](https://github.com/stlink-org/stlink/pull/1107)) - [doc] Added note on `(gdb) run` command (commit [#03793d4](https://github.com/stlink-org/stlink/commit/03793d42b6078344a9ef8ad55f1d5d0fc19e486e), [#267](https://github.com/stlink-org/stlink/pull/267)) - [doc] `st-flash --reset` parameter (one solution for #356) ([#642](https://github.com/stlink-org/stlink/pull/642)) @@ -35,8 +35,9 @@ Updates & changes: Fixes: -- Flash loader rework ([#356](https://github.com/stlink-org/stlink/pull/356), [#556](https://github.com/stlink-org/stlink/pull/556), [#593](https://github.com/stlink-org/stlink/pull/593), [#607](https://github.com/stlink-org/stlink/pull/607), [#612](https://github.com/stlink-org/stlink/pull/612), [#638](https://github.com/stlink-org/stlink/pull/638), [#661](https://github.com/stlink-org/stlink/pull/661), [#690](https://github.com/stlink-org/stlink/pull/690), [#979](https://github.com/stlink-org/stlink/pull/979), [#1043](https://github.com/stlink-org/stlink/pull/1043), [#1054](https://github.com/stlink-org/stlink/pull/1054), [#1105](https://github.com/stlink-org/stlink/pull/1105), [#1113](https://github.com/stlink-org/stlink/pull/1113)) +- Flash loader rework ([#356](https://github.com/stlink-org/stlink/pull/356), [#556](https://github.com/stlink-org/stlink/pull/556), [#593](https://github.com/stlink-org/stlink/pull/593), [#597](https://github.com/stlink-org/stlink/pull/597), [#607](https://github.com/stlink-org/stlink/pull/607), [#612](https://github.com/stlink-org/stlink/pull/612), [#638](https://github.com/stlink-org/stlink/pull/638), [#661](https://github.com/stlink-org/stlink/pull/661), [#690](https://github.com/stlink-org/stlink/pull/690), [#818](https://github.com/stlink-org/stlink/pull/818), [#854](https://github.com/stlink-org/stlink/pull/854), [#967](https://github.com/stlink-org/stlink/pull/967), [#979](https://github.com/stlink-org/stlink/pull/979), [#1043](https://github.com/stlink-org/stlink/pull/1043), [#1054](https://github.com/stlink-org/stlink/pull/1054), [#1092](https://github.com/stlink-org/stlink/pull/1092), [#1105](https://github.com/stlink-org/stlink/pull/1105), [#1113](https://github.com/stlink-org/stlink/pull/1113)) - Fixed old DFU serial number for STLINK programmers ([#417](https://github.com/stlink-org/stlink/pull/417), [#494](https://github.com/stlink-org/stlink/pull/494), [#1106](https://github.com/stlink-org/stlink/pull/1106)) +- Use vl flashloader for all STM32F1 series ([#769](https://github.com/stlink-org/stlink/pull/769), [#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) - [regression] Changed timeout on flash write ([#787](https://github.com/stlink-org/stlink/pull/787), [#981](https://github.com/stlink-org/stlink/pull/981), [#987](https://github.com/stlink-org/stlink/pull/987)) - cmake compile failure with external `CMAKE_MODULE_PATH` set ([#962](https://github.com/stlink-org/stlink/pull/962)) - doc/man: Fixed installation directory ([#970](https://github.com/stlink-org/stlink/pull/970)) @@ -50,7 +51,6 @@ Fixes: - `st-util`: wrong register values passed to `gdb` (STLink/V2) ([#1002](https://github.com/stlink-org/stlink/pull/1002), [#1011](https://github.com/stlink-org/stlink/pull/1011), [#1026](https://github.com/stlink-org/stlink/pull/1026), [#1027](https://github.com/stlink-org/stlink/pull/1027), [#1064](https://github.com/stlink-org/stlink/pull/1064), [#1065](https://github.com/stlink-org/stlink/pull/1065)) - GDB: Fixed problems with target description ([#1013](https://github.com/stlink-org/stlink/pull/1013), [#1088](https://github.com/stlink-org/stlink/pull/1088), [#1109](https://github.com/stlink-org/stlink/pull/1109)) - [doc] Fixed wrong path for `rules.d` folder ([#1020](https://github.com/stlink-org/stlink/pull/1020)) -- Use vl flashloader for all STM32F1 series ([#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) - Fixed support for STLINK/V1 programmer ([#1045](https://github.com/stlink-org/stlink/pull/1045), [#1105](https://github.com/stlink-org/stlink/pull/1105)) - st-util v1.6.1 does not recognize option --freq (commit [#e576768](https://github.com/stlink-org/stlink/commit/e5767681f14de9851aa970a9299930ca68b2ed92), [#1055](https://github.com/stlink-org/stlink/pull/1055)) - Fixed `gettimeofday` for MSVC ([#1074](https://github.com/stlink-org/stlink/pull/1074)) diff --git a/doc/devices_boards.md b/doc/devices_boards.md index 6396738c4..df4b5ed29 100644 --- a/doc/devices_boards.md +++ b/doc/devices_boards.md @@ -109,9 +109,9 @@ Tested boards [incl. STLINK programmers]: **STM32F3 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F3c_CORE_ID)** -| Product-Code | Chip-ID | STLink
Programmer | Boards | -| ------------ | ------- | ---------------------- | ------------------------------------------------------ | -| GD32F303VGT6 | 0x430 | _N/A_ | STM32F303 clone from GigaDevice GD)
_unsupported_ | +| Product-Code | Chip-ID | STLINK
Programmer | Boards | +| ------------ | ------- | ---------------------- | ---------------------------------- | +| GD32F303VGT6 | 0x430 | [v2] | STM32F303 clone from GigaDevice GD | **STM32F4 / ARM Cortex M4F / Core-ID: 0x2ba01477 (STM32F4_CORE_ID)** diff --git a/doc/tutorial.md b/doc/tutorial.md index 2403590ac..37c29ab6a 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -7,7 +7,7 @@ | --flash=n[k][m] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k for the STM32F103C8T6
to assume 128k of flash being present. This option accepts decimal (128k), octal 0200k, or hex 0x80k values.
Leaving the multiplier out is equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional
"k" or "m" to multiply the given value by 1k (1024) or 1M respectively. | v1.4.0 | | --freq=n[k][m] | st-info
st-flash
st-util | The frequency of the SWD/JTAG interface can be specified, to override the default 1800 kHz configuration.
This option solely accepts decimal values (5K or 1.8M) with the unit `Hz` being left out. Valid frequencies are:
`5K, 15K, 25K, 50K, 100K, 125K, 240K, 480K, 950K, 1200K, 1800K, 4000K(4M)`. | v1.6.1 | | --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at the end of binary file.
This may cause some garbage data left after a flash operation. This option was enabled by default in earlier releases. | v1.6.1 | -| --reset | st-flash | Trigger a reset both before and after flashing. The default uses the hardware reset through `NRST` pin.
The software reset is used if the hardware reset failed (`NRST` pin not connected). | v1.0.0 | +| --reset | st-flash | Trigger a reset both before and after flashing. The default uses the hardware reset through `NRST` pin.
A software reset (via `AIRCR`; since v1.5.1) is used, if the hardware reset failed (`NRST` pin not connected). | v1.0.0 | | --connect-under-reset | st-info
st-flash | Connect under reset. Option makes it possible to connect to the device before code execution. This is useful
when the target contains code that lets the device go to sleep, disables debug pins or other special code. | v1.6.1 | | --hot-plug | st-info
st-util | Connect to the target without reset. | v1.6.2 | | --probe | st-info | Display hardware information about the connected programmer and target MCU. | v1.2.0 | @@ -112,12 +112,14 @@ This so called `DBGMCU_IDCODE` register is allocated either at memory address `0 A failure of chip identification results in the error `WARN src/common.c: unknown chip id!`. There are different variants of this message that refer to different issues: -- `unknown chip id! 0` --> _currently unknown_ +- `unknown chip id! 0` --> Target chip (board) is unknown. + 1. Microcontroller is in stop/standby mode. + 2. The signals `DIO` and `CLK` are reversed on the SWD-Interface. - `unknown chip id! 0x1a` --> _currently unknown_ - `unknown chip id! 0x001f` --> _currently unknown_ - `unknown chip id! 0x3e8` --> _currently unknown_ - `unknown chip id! 0xa05f0000` --> _currently unknown_ -- `unknown chip id! 0x3748` --> A target chip / board cannot be detected. +- `unknown chip id! 0x3748` --> A target chip (board) cannot be detected. 1. No target is connected --> In this case `st-info --probe` displays `chip id 0x0748` with STLINK/V2 and `chip id 0x03e8` with STLINK-V3. 2. The chip is connected but has gone into an undefined state of operation where the SWD pins are unresponsive. --> Try to use `--connect-under-reset` while pressing the reset button on the target board. 3. A firmware-issue prevents the programmer from normal operation. --> Ensure that your programmer runs the latest firmware version and consider to upgrade any older version by using the official firmware upgrade tool provided by STMicroelectronics. From 36434d5785bc752465b47b5b058e33da1df90794 Mon Sep 17 00:00:00 2001 From: anton Date: Sat, 27 Mar 2021 15:54:54 +0500 Subject: [PATCH 29/65] Added addition check of connected target --- src/common.c | 58 ++++++++++++++++++-------------------------- src/stlink-lib/reg.h | 12 ++++----- 2 files changed, 29 insertions(+), 41 deletions(-) diff --git a/src/common.c b/src/common.c index b5bb67e9e..f621a4b6d 100644 --- a/src/common.c +++ b/src/common.c @@ -1220,14 +1220,14 @@ int stlink_core_id(stlink_t *sl) { // do not call this procedure directly. int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { int ret; + cortex_m3_cpuid_t cpu_id; - uint32_t cpu_id; - *chip_id = 0; - ret = -1; - - // Read the CPU ID to determine where to read the core id from - if (stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &cpu_id)) - cpu_id = 0; + // Read the CPU ID to determine where to read the core id + if (stlink_cpu_id(sl, &cpu_id) || + cpu_id.implementer_id != STLINK_REG_CMx_CPUID_IMPL_ARM) { + ELOG("Can not connect to target. Please use \'connect under reset\' and try again\n"); + return -1; + } /* * the chip_id register in the reference manual have @@ -1235,18 +1235,17 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { * */ - uint32_t part_no = STLINK_REG_CM3_CPUID_PARTNO(cpu_id); if ((sl->core_id == STM32H7_CORE_ID || sl->core_id == STM32H7_CORE_ID_JTAG) && - part_no == STLINK_REG_CMx_CPUID_PARTNO_CM7) { + cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM7) { // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) ret = stlink_read_debug32(sl, 0x5c001000, chip_id); - } else if (part_no == STLINK_REG_CMx_CPUID_PARTNO_CM0) { + } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0) { // STM32F0 (RM0091, pg914; RM0360, pg713) // STM32L0 (RM0377, pg813; RM0367, pg915; RM0376, pg917) // STM32G0 (RM0444, pg1367) ret = stlink_read_debug32(sl, 0x40015800, chip_id); - } else if (part_no == STLINK_REG_CMx_CPUID_PARTNO_CM33) { + } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM33) { // STM32L5 (RM0438, pg2157) ret = stlink_read_debug32(sl, 0xE0044000, chip_id); } else /* СM3, СM4, CM7 */ { @@ -1261,9 +1260,16 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { // STM32G4 (RM0440, pg2086) // STM32WB (RM0434, pg1406) ret = stlink_read_debug32(sl, 0xE0042000, chip_id); + } + + if (ret || !(*chip_id)) { + *chip_id = 0; + ELOG("Could not find chip id!\n"); + } else { + *chip_id = (*chip_id) & 0xfff; // Fix chip_id for F4 rev A errata, read CPU ID, as CoreID is the same for F2/F4 - if (*chip_id == 0x411 && (cpu_id & 0xfff0) == 0xc240) { + if (*chip_id == 0x411 && cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM4) { *chip_id = 0x413; } } @@ -1272,7 +1278,7 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { } /** - * Cortex m3 tech ref manual, CPUID register description + * Cortex M tech ref manual, CPUID register description * @param sl stlink context * @param cpuid pointer to the result object */ @@ -1305,26 +1311,16 @@ int stlink_load_device_params(stlink_t *sl) { DLOG("Loading device parameters....\n"); const struct stlink_chipid_params *params = NULL; stlink_core_id(sl); - uint32_t chip_id = 0; uint32_t flash_size; - stlink_chip_id(sl, &chip_id); - sl->chip_id = chip_id & 0xfff; - - // Fix chip_id for F4 rev A errata , Read CPU ID, as CoreID is the same for F2/F4 - if (sl->chip_id == 0x411) { - uint32_t cpuid; - stlink_read_debug32(sl, 0xE000ED00, &cpuid); - - if ((cpuid & 0xfff0) == 0xc240) { - sl->chip_id = 0x413; - } + if (stlink_chip_id(sl, &sl->chip_id)) { + return(-1); } params = stlink_chipid_get_params(sl->chip_id); if (params == NULL) { - WLOG("unknown chip id! %#x\n", chip_id); + WLOG("unknown chip id! %#x\n", sl->chip_id); return(-1); } @@ -1390,19 +1386,11 @@ int stlink_load_device_params(stlink_t *sl) { sl->chip_flags &= ~CHIP_F_HAS_DUAL_BANK; } -#if 0 - // Old code -- REW - ILOG("Device connected is: %s, id %#x\n", params->description, chip_id); - // TODO: make note of variable page size here..... - ILOG("SRAM size: %#x bytes (%d KiB), Flash: %#x bytes (%d KiB) in pages of %u bytes\n", - sl->sram_size, sl->sram_size / 1024, sl->flash_size, sl->flash_size / 1024, - (unsigned int)sl->flash_pgsz); -#else ILOG("%s: %u KiB SRAM, %u KiB flash in at least %u %s pages.\n", params->description, (unsigned)(sl->sram_size / 1024), (unsigned)(sl->flash_size / 1024), (sl->flash_pgsz < 1024) ? (unsigned)(sl->flash_pgsz) : (unsigned)(sl->flash_pgsz / 1024), (sl->flash_pgsz < 1024) ? "byte" : "KiB"); -#endif + return(0); } diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index 73f608cb6..79570aa34 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -3,12 +3,12 @@ #define STLINK_REG_CM3_CPUID 0xE000ED00 -#define STLINK_REG_CM3_CPUID_PARTNO(cpuid) ((cpuid)&STLINK_REG_CMx_CPUID_PARTNO_MASK) -#define STLINK_REG_CMx_CPUID_PARTNO_MASK 0xFFF0 -#define STLINK_REG_CMx_CPUID_PARTNO_CM0 0xC200 -#define STLINK_REG_CMx_CPUID_PARTNO_CM3 0xC230 -#define STLINK_REG_CMx_CPUID_PARTNO_CM7 0xC270 -#define STLINK_REG_CMx_CPUID_PARTNO_CM33 0xD210 +#define STLINK_REG_CMx_CPUID_PARTNO_CM0 0xC20 +#define STLINK_REG_CMx_CPUID_PARTNO_CM3 0xC23 +#define STLINK_REG_CMx_CPUID_PARTNO_CM4 0xC24 +#define STLINK_REG_CMx_CPUID_PARTNO_CM7 0xC27 +#define STLINK_REG_CMx_CPUID_PARTNO_CM33 0xD21 +#define STLINK_REG_CMx_CPUID_IMPL_ARM 0x41 #define STLINK_REG_CM3_FP_CTRL 0xE0002000 // Flash Patch Control Register From da37fec19ee378d076fae2d615ea7082d99e110e Mon Sep 17 00:00:00 2001 From: anton Date: Sat, 27 Mar 2021 21:12:00 +0500 Subject: [PATCH 30/65] Applied missing changes to tests --- tests/flash.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/tests/flash.c b/tests/flash.c index a8d479b2d..132066aba 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -131,17 +131,6 @@ static struct Test tests[] = { .freq = 5, .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, { .cmd = FLASH_CMD_READ, .serial = { 0 }, @@ -211,10 +200,10 @@ static struct Test tests[] = { { "--debug --reset --format=binary write test.hex", -1, FLASH_OPTS_INITIALIZER }, { "--debug --reset --format=ihex write test.hex 0x80000000", -1, FLASH_OPTS_INITIALIZER }, { "--debug --reset write test.hex sometext", -1, FLASH_OPTS_INITIALIZER }, - { "--serial A1020304 erase sometext", -1, FLASH_OPTS_INITIALIZER }, - { "--serial A1020304 erase", 0, + { "--serial ABCEFF544851717867216044 erase sometext", -1, FLASH_OPTS_INITIALIZER }, + { "--serial ABCEFF544851717867216044 erase", 0, { .cmd = FLASH_CMD_ERASE, - .serial = "\xA1\x02\x03\x04", + .serial = "ABCEFF544851717867216044", .filename = NULL, .addr = 0, .size = 0, @@ -223,9 +212,9 @@ static struct Test tests[] = { .freq = 0, .format = FLASH_FORMAT_BINARY } }, - { "--serial=A1020304 erase", 0, + { "--serial=ABCEFF544851717867216044 erase", 0, { .cmd = FLASH_CMD_ERASE, - .serial = "\xA1\x02\x03\x04", + .serial = "ABCEFF544851717867216044", .filename = NULL, .addr = 0, .size = 0, From 878df31761f449e5846bb841085a320420c77c15 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 27 Mar 2021 17:46:22 +0100 Subject: [PATCH 31/65] Updated CI config & issue templates - Initial support for GitHub CI workflows - Cleanup for Travis CI config - Minor fixes for issue templates --- .github/ISSUE_TEMPLATE/bug-report.md | 18 +- .github/ISSUE_TEMPLATE/feature-request.md | 16 +- .github/workflows/c-cpp.yml | 334 +++++++++++++++++++++- .github/workflows/cmake.yml | 46 --- .travis.sh | 13 - .travis.yml | 2 +- README.md | 1 + 7 files changed, 338 insertions(+), 92 deletions(-) delete mode 100644 .github/workflows/cmake.yml diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index 0e22c2ce9..16e0477f0 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -1,8 +1,8 @@ --- name: "Bug Report" about: "Report a bug" -title: "[STM32 device name]: [_$YourTitle_]" -labels: '' +title: "[STM32 device name]: $YourTitle" +labels: "" --- Thank you for giving feedback to the stlink project. @@ -12,18 +12,17 @@ This bug report will be deleted without notice when not enough information is pr - [ ] I made serious effort to avoid creating duplicate or nearly similar issue -In order to allow developers and other contributors to isolate and target your respective issue, please take some time to select the check boxes below -and fill out each of the following items appropriate to your specific problem. +In order to allow developers and other contributors to isolate and target your respective issue, please take some time to select the check boxes below and fill out each of the following items appropriate to your specific problem. -- [ ] Programmer/board type: [enter here] (e.g STLink /V1, /V2, /V2-onboard, /V2-clone, /V3) +- [ ] Programmer/board type: [enter here] (e.g STLINK /V1, /V2, /V2-onboard, /V2-clone, /V3) - [ ] Operating system an version: [enter here] (e.g Linux, macOS, Windows) -- [ ] **Stlink tools version** and/or git commit hash: [enter here] (e.g v1.6.1/git-d0416149) -- [ ] Stlink commandline tool name: [enter here] (e.g `st-info`, `st-flash`, `st-util`) +- [ ] **stlink tools version** and/or git commit hash: [enter here] (e.g v1.6.1/git-d0416149) +- [ ] stlink commandline tool name: [enter here] (e.g `st-info`, `st-flash`, `st-trace`, `st-util`) - [ ] Target chip (and board, if applicable): [enter here] (e.g STM32F103C8T6 (NUCLEO-F103RB)) -Futher we kindly ask you to describe the detected problem as detailed as possible and to add debug output if available, by using the following template: +Further we kindly ask you to describe the detected problem as detailed as possible and to add debug output if available, by using the following template: -Commandline-Output: +Commandline output: ``` OUTPUT/ERROR of the commandline tool(s) @@ -33,7 +32,6 @@ Expected/description: `short description of the expected value` - Thank you for your support. The stlink project maintainers diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md index 3de593aa6..ddeb79357 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.md +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -1,7 +1,7 @@ --- name: "Feature Request" about: "Suggest an idea for this project" -title: "[feature] [_$YourTitle_]" +title: "[feature] $YourTitle" labels: code/feature-request --- @@ -12,18 +12,17 @@ This feature request will be deleted without notice when not enough information - [ ] I made serious effort to avoid creating duplicate or nearly similar issue -In order to allow developers and other contributors to isolate and target your respective issue, please take some time to select the check boxes below -and fill out each of the following items appropriate to your specific request. +In order to allow developers and other contributors to isolate and target your respective issue, please take some time to select the check boxes below and fill out each of the following items appropriate to your specific request. -- [ ] Programmer/board type: [enter here] (e.g STLink /V1, /V2, /V2-onboard, /V2-clone, /V3) +- [ ] Programmer/board type: [enter here] (e.g STLINK /V1, /V2, /V2-onboard, /V2-clone, /V3) - [ ] Operating system an version: [enter here] (e.g Linux, macOS, Windows) -- [ ] **Stlink tools version** and/or git commit hash: [enter here] (e.g v1.6.1/git-d0416149) -- [ ] Stlink commandline tool name: [enter here] (e.g `st-info`, `st-flash`, `st-util`) +- [ ] **stlink tools version** and/or git commit hash: [enter here] (e.g v1.6.1/git-d0416149) +- [ ] stlink commandline tool name: [enter here] (e.g `st-info`, `st-flash`, `st-trace`, `st-util`) - [ ] Target chip (and board, if applicable): [enter here] (e.g STM32F103C8T6 (NUCLEO-F103RB)) -Futher we kindly ask you to describe the detected problem as detailed as possible and to add debug output if available, by using the following template: +Further we kindly ask you to describe the detected problem as detailed as possible and to add debug output if available, by using the following template: -Commandline-Output: +Commandline output: ``` OUTPUT/ERROR of the commandline tool(s) @@ -33,7 +32,6 @@ Expected/description: `short description of the expected value` - Thank you for your support. The stlink project maintainers diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index e211e4e54..c792612c2 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -2,22 +2,330 @@ name: C/C++ CI on: push: - branches: [ testing ] + branches: [develop, testing] pull_request: - branches: [ testing ] + branches: [develop, testing] jobs: - build: + job_linux_1a: + name: ubuntu-20.04 gcc + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean + + job_linux_2a: + name: ubuntu-18.04 gcc + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - name: install dependencies + run: sudo apt-get install gcc-6 libusb-1.0.0-dev libgtk-3-dev rpm + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean + + job_linux_3a: + name: ubuntu-16.04 gcc + runs-on: ubuntu-16.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean + + job_linux_1b: + name: ubuntu-20.04 clang + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean + + job_linux_2b: + name: ubuntu-18.04 clang + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - name: install dependencies + run: sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean + + job_linux_3b: + name: ubuntu-16.04 clang + runs-on: ubuntu-16.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get install clang libusb-1.0.0-dev libgtk-3-dev rpm + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean + + job_linux_1c: + name: ubuntu-20.04 gcc 32-bit + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm + - name: Set compiler flags + run: | + CFLAGS="$CFLAGS -m32" + CXXFLAGS="$CXXFLAGS -m32" + LDFLAGS="$LDFLAGS -m32" + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean + + job_linux_2c: + name: ubuntu-18.04 gcc 32-bit + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - name: install dependencies + run: sudo apt-get install gcc-6 libusb-1.0.0-dev libgtk-3-dev rpm + - name: Set compiler flags + run: | + CFLAGS="$CFLAGS -m32" + CXXFLAGS="$CXXFLAGS -m32" + LDFLAGS="$LDFLAGS -m32" + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean + + job_linux_3c: + name: ubuntu-16.04 gcc 32-bit + runs-on: ubuntu-16.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm + - name: Set compiler flags + run: | + CFLAGS="$CFLAGS -m32" + CXXFLAGS="$CXXFLAGS -m32" + LDFLAGS="$LDFLAGS -m32" + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean + + job_linux_4: + name: ubuntu-20.04 mingw64 + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm mingw-w64 + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean + + # job_macos_1a: + # name: macos-11.0 gcc + # runs-on: macos-11.0 + # steps: + # - uses: actions/checkout@v2 + # - name: Install dependencies + # run: brew install gcc libusb gtk+3 + # - name: make debug + # run: make debug + # - name: make test + # run: make test + # - name: make release + # run: make release + # - name: make install + # run: make install + # - name: make package + # run: make package + # - name: make uninstall + # run: make uninstall + # - name: make clean + # run: make clean + + job_macos_2a: + name: macos-10.15 gcc + runs-on: macos-10.15 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: brew install gcc libusb gtk+3 + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean - runs-on: ubuntu-latest + # job_macos_1b: + # name: macos-11.0 clang + # runs-on: macos-11.0 + # steps: + # - uses: actions/checkout@v2 + # - name: Install dependencies + # run: brew install llvm libusb gtk+3 + # - name: make debug + # run: make debug + # - name: make test + # run: make test + # - name: make release + # run: make release + # - name: make install + # run: make install + # - name: make package + # run: make package + # - name: make uninstall + # run: make uninstall + # - name: make clean + # run: make clean + job_macos_2b: + name: macos-10.15 clang + runs-on: macos-10.15 steps: - - uses: actions/checkout@v2 - - name: configure - run: ./configure - - name: make - run: make - - name: make check - run: make check - - name: make distcheck - run: make distcheck + - uses: actions/checkout@v2 + - name: Install dependencies + run: brew install llvm libusb gtk+3 + - name: make debug + run: make debug + - name: make test + run: make test + - name: make release + run: make release + - name: make install + run: make install + - name: make package + run: make package + - name: make uninstall + run: make uninstall + - name: make clean + run: make clean diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml deleted file mode 100644 index 005915e6e..000000000 --- a/.github/workflows/cmake.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: CMake - -on: [push] - -env: - # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) - BUILD_TYPE: Release - -jobs: - build: - # The CMake configure and build commands are platform agnostic and should work equally - # well on Windows or Mac. You can convert this to a matrix build if you need - # cross-platform coverage. - # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - name: Create Build Environment - # Some projects don't allow in-source building, so create a separate build directory - # We'll use this as our working directory for all subsequent commands - run: cmake -E make_directory ${{github.workspace}}/build - - - name: Configure CMake - # Use a bash shell so we can use the same syntax for environment variable - # access regardless of the host operating system - shell: bash - working-directory: ${{github.workspace}}/build - # Note the current convention is to use the -S and -B options here to specify source - # and build directories, but this is only available with CMake 3.13 and higher. - # The CMake binaries on the Github Actions machines are (as of this writing) 3.12 - run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE - - - name: Build - working-directory: ${{github.workspace}}/build - shell: bash - # Execute the build. You can specify a specific target with "--target " - run: cmake --build . --config $BUILD_TYPE - - - name: Test - working-directory: ${{github.workspace}}/build - shell: bash - # Execute tests defined by the CMake configuration. - # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail - run: ctest -C $BUILD_TYPE diff --git a/.travis.sh b/.travis.sh index cc0958bf5..7683af001 100755 --- a/.travis.sh +++ b/.travis.sh @@ -11,61 +11,48 @@ DIR=$PWD if [ "$TRAVIS_JOB_NAME" == "linux-mingw" ]; then echo "--> Building Release for Windows (x86-64) ..." mkdir -p build-mingw && cd build-mingw - echo "-DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ - -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR" cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make && rm -rf build-mingw && cd - echo "--> Building Release for Windows (i686) ..." mkdir -p build-mingw && cd build-mingw - echo "-DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ - -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR" cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make && rm -rf build-mingw && cd - elif [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq || true - sudo apt-get install -qq -y --no-install-recommends libgtk-3-dev echo "--> Building Debug..." mkdir -p build/Debug && cd build/Debug - echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install" cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make && cd - echo "--> Building Release with package..." mkdir -p build/Release && cd build/Release - echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install" cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make package && cd - elif [ "$TRAVIS_OS_NAME" == "osx" ]; then - brew install libusb - echo "--> Building Debug..." mkdir -p build/Debug && cd build/Debug - echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install" cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make && cd - echo "--> Building Release with package..." mkdir -p build/Release && cd build/Release - echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install" cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make package && cd - else # local test-build echo "--> Building Debug..." mkdir -p build/Debug && cd build/Debug - echo "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install" cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install ../../ make && cd - echo "--> Building Release with package..." mkdir -p build/Release && cd build/Release - echo "-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install" cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install ../../ make package && cd - fi diff --git a/.travis.yml b/.travis.yml index 5d2e5fbdf..e866cc6ab 100644 --- a/.travis.yml +++ b/.travis.yml @@ -146,7 +146,7 @@ jobs: addons: homebrew: packages: - - clang + - llvm - libusb - gtk+3 diff --git a/README.md b/README.md index 7ddc78005..aafba5988 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ ![GitHub commits](https://img.shields.io/github/commits-since/stlink-org/stlink/v1.6.1/develop) ![GitHub activity](https://img.shields.io/github/commit-activity/m/stlink-org/stlink) ![GitHub contributors](https://img.shields.io/github/contributors/stlink-org/stlink) +[![C/C++ CI](https://github.com/stlink-org/stlink/actions/workflows/c-cpp.yml/badge.svg?branch=testing)](https://github.com/stlink-org/stlink/actions/workflows/c-cpp.yml) [![Linux Status](https://img.shields.io/travis/stlink-org/stlink/master?env=BADGE=linux&label=linux)](https://travis-ci.org/stlink-org/stlink) [![macOS Status](https://img.shields.io/travis/stlink-org/stlink/master?env=BADGE=osx&label=osx)](https://travis-ci.org/stlink-org/stlink) From a5a4a687c42045a139d9950036c5adddaa317bf6 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 27 Mar 2021 21:01:31 +0100 Subject: [PATCH 32/65] Updated config for GitHub Actions CI workflow --- .github/workflows/c-cpp.yml | 228 ++++++++++++++++++------------------ 1 file changed, 114 insertions(+), 114 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index c792612c2..b42d001af 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -2,9 +2,9 @@ name: C/C++ CI on: push: - branches: [develop, testing] + branches: [master, develop, testing] pull_request: - branches: [develop, testing] + branches: [master, develop, testing] jobs: job_linux_1a: @@ -20,14 +20,14 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean job_linux_2a: name: ubuntu-18.04 gcc @@ -42,14 +42,14 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean job_linux_3a: name: ubuntu-16.04 gcc @@ -64,14 +64,14 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean job_linux_1b: name: ubuntu-20.04 clang @@ -86,14 +86,14 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean job_linux_2b: name: ubuntu-18.04 clang @@ -108,14 +108,14 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean job_linux_3b: name: ubuntu-16.04 clang @@ -130,14 +130,14 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean job_linux_1c: name: ubuntu-20.04 gcc 32-bit @@ -157,14 +157,14 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean job_linux_2c: name: ubuntu-18.04 gcc 32-bit @@ -184,14 +184,14 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean job_linux_3c: name: ubuntu-16.04 gcc 32-bit @@ -211,14 +211,14 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean job_linux_4: name: ubuntu-20.04 mingw64 @@ -233,14 +233,14 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean # job_macos_1a: # name: macos-11.0 gcc @@ -255,14 +255,14 @@ jobs: # run: make test # - name: make release # run: make release - # - name: make install - # run: make install - # - name: make package - # run: make package - # - name: make uninstall - # run: make uninstall - # - name: make clean - # run: make clean + # - name: sudo make install + # run: sudo make install + # - name: sudo make package + # run: sudo make package + # - name: sudo make uninstall + # run: sudo make uninstall + # - name: sudo make clean + # run: sudo make clean job_macos_2a: name: macos-10.15 gcc @@ -277,14 +277,14 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean # job_macos_1b: # name: macos-11.0 clang @@ -299,14 +299,14 @@ jobs: # run: make test # - name: make release # run: make release - # - name: make install - # run: make install - # - name: make package - # run: make package - # - name: make uninstall - # run: make uninstall - # - name: make clean - # run: make clean + # - name: sudo make install + # run: sudo make install + # - name: sudo make package + # run: sudo make package + # - name: sudo make uninstall + # run: sudo make uninstall + # - name: sudo make clean + # run: sudo make clean job_macos_2b: name: macos-10.15 clang @@ -321,11 +321,11 @@ jobs: run: make test - name: make release run: make release - - name: make install - run: make install - - name: make package - run: make package - - name: make uninstall - run: make uninstall - - name: make clean - run: make clean + - name: sudo make install + run: sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall + - name: sudo make clean + run: sudo make clean From face74262f879bba5a330c8326064a383cac2b42 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 28 Mar 2021 00:30:33 +0100 Subject: [PATCH 33/65] Updated config for GitHub code scanning alerts --- .github/workflows/codeql-analysis.yml | 60 ++++++++++++++------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 202867cfc..bab5fb048 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -13,12 +13,12 @@ name: "CodeQL" on: push: - branches: [ develop, master ] + branches: [develop, master] pull_request: # The branches below must be a subset of the branches above - branches: [ develop ] + branches: [develop] schedule: - - cron: '23 20 * * 2' + - cron: "23 20 * * 2" jobs: analyze: @@ -28,40 +28,42 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'cpp' ] + language: ["cpp"] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] # Learn more: # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed steps: - - name: Checkout repository - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm + - name: Checkout repository + uses: actions/checkout@v2 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v1 + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 - # ℹ️ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl - # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language - #- run: | - # make bootstrap - # make release + #- run: | + # make bootstrap + # make release - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From d10a4f8def8189d4b14fad20b25b75bcf010e563 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 28 Mar 2021 00:35:03 +0100 Subject: [PATCH 34/65] Updated libusb to v1.0.24 --- cmake/modules/Findlibusb.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index bc613779d..b3e5c7e2b 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -75,7 +75,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) if (NOT LIBUSB_FOUND) # Preparations for installing libusb library - set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version + set(LIBUSB_WIN_VERSION 1.0.24) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) if (WIN32 AND NOT EXISTS "/etc/debian_version") # ... on native Windows systems set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) @@ -92,7 +92,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) message(STATUS "downloading libusb ${LIBUSB_WIN_VERSION}") file(DOWNLOAD https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-${LIBUSB_WIN_VERSION}/libusb-${LIBUSB_WIN_VERSION}.7z/download - ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 cf3d38d2ff053ef343d10c0b8b0950c2 + ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 5c944b1c8aa9d43e026a94302d0f8ac4 ) endif () From 0496ecff48b7c122c243c4d449e44ad34e8ecba6 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 2 Apr 2021 16:43:54 +0200 Subject: [PATCH 35/65] Updated config for GitHub code scanning alerts --- .github/workflows/codeql-analysis.yml | 8 ++++---- README.md | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index bab5fb048..26313ecb5 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -13,12 +13,12 @@ name: "CodeQL" on: push: - branches: [develop, master] + branches: [ testing, develop, master ] pull_request: # The branches below must be a subset of the branches above - branches: [develop] + branches: [ testing, develop ] schedule: - - cron: "23 20 * * 2" + - cron: '00 20 * * 1' jobs: analyze: @@ -28,7 +28,7 @@ jobs: strategy: fail-fast: false matrix: - language: ["cpp"] + language: [ 'cpp' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] # Learn more: # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed diff --git a/README.md b/README.md index aafba5988..644c3fd86 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ ![GitHub commits](https://img.shields.io/github/commits-since/stlink-org/stlink/v1.6.1/develop) ![GitHub activity](https://img.shields.io/github/commit-activity/m/stlink-org/stlink) ![GitHub contributors](https://img.shields.io/github/contributors/stlink-org/stlink) +[![CodeQL](https://github.com/stlink-org/stlink/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/stlink-org/stlink/actions/workflows/codeql-analysis.yml) [![C/C++ CI](https://github.com/stlink-org/stlink/actions/workflows/c-cpp.yml/badge.svg?branch=testing)](https://github.com/stlink-org/stlink/actions/workflows/c-cpp.yml) [![Linux Status](https://img.shields.io/travis/stlink-org/stlink/master?env=BADGE=linux&label=linux)](https://travis-ci.org/stlink-org/stlink) [![macOS Status](https://img.shields.io/travis/stlink-org/stlink/master?env=BADGE=osx&label=osx)](https://travis-ci.org/stlink-org/stlink) From eebcb1acc8a29a156276852eb730e961883a9e71 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 2 Apr 2021 18:34:31 +0200 Subject: [PATCH 36/65] Revert "Updated libusb to v1.0.24" This reverts commit d10a4f8def8189d4b14fad20b25b75bcf010e563. --- cmake/modules/Findlibusb.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index b3e5c7e2b..bc613779d 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -75,7 +75,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) if (NOT LIBUSB_FOUND) # Preparations for installing libusb library - set(LIBUSB_WIN_VERSION 1.0.24) # set libusb version + set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) if (WIN32 AND NOT EXISTS "/etc/debian_version") # ... on native Windows systems set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) @@ -92,7 +92,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) message(STATUS "downloading libusb ${LIBUSB_WIN_VERSION}") file(DOWNLOAD https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-${LIBUSB_WIN_VERSION}/libusb-${LIBUSB_WIN_VERSION}.7z/download - ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 5c944b1c8aa9d43e026a94302d0f8ac4 + ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 cf3d38d2ff053ef343d10c0b8b0950c2 ) endif () From 32ba234b305a8fa3ffdd5cd825a72973ad94a512 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 2 Apr 2021 18:36:05 +0200 Subject: [PATCH 37/65] Revert "Updated libusb to v1.0.24" This reverts commit d10a4f8def8189d4b14fad20b25b75bcf010e563. --- cmake/modules/Findlibusb.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index b3e5c7e2b..bc613779d 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -75,7 +75,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) if (NOT LIBUSB_FOUND) # Preparations for installing libusb library - set(LIBUSB_WIN_VERSION 1.0.24) # set libusb version + set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) if (WIN32 AND NOT EXISTS "/etc/debian_version") # ... on native Windows systems set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) @@ -92,7 +92,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) message(STATUS "downloading libusb ${LIBUSB_WIN_VERSION}") file(DOWNLOAD https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-${LIBUSB_WIN_VERSION}/libusb-${LIBUSB_WIN_VERSION}.7z/download - ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 5c944b1c8aa9d43e026a94302d0f8ac4 + ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 cf3d38d2ff053ef343d10c0b8b0950c2 ) endif () From e0f7552fc1a13990f70da863c5fdaa1f64be649f Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 3 Apr 2021 14:53:16 +0200 Subject: [PATCH 38/65] Updated CI build configuration - Ensure clean build system for all build targets - Rearranged & renamed build jobs - Completed set of 32-bit & 64-bit builds - Updated notifications for MinGW cross build - Added macOS 10.14 build environment for Travis CI --- .github/workflows/c-cpp.yml | 387 +++++++++++++++++++-------------- .travis.sh | 4 +- .travis.yml | 177 +++++---------- cmake/modules/Findlibusb.cmake | 2 + 4 files changed, 281 insertions(+), 289 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index b42d001af..4769450ae 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -7,95 +7,145 @@ on: branches: [master, develop, testing] jobs: - job_linux_1a: - name: ubuntu-20.04 gcc - runs-on: ubuntu-20.04 + +# Linux + + job_linux_16_04_64_gcc: + name: ubuntu-16.04 gcc + runs-on: ubuntu-16.04 steps: - uses: actions/checkout@v2 - name: Install dependencies - run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm + run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm - name: make debug - run: make debug + run: sudo make clean && make debug - name: make test - run: make test + run: sudo make clean && make test - name: make release - run: make release + run: sudo make clean && make release - name: sudo make install - run: sudo make install + run: sudo make clean && sudo make install - name: sudo make package run: sudo make package - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean + run: sudo make uninstall && sudo make clean - job_linux_2a: - name: ubuntu-18.04 gcc - runs-on: ubuntu-18.04 + job_linux_16_04_32_gcc: + name: ubuntu-16.04 gcc 32-bit + runs-on: ubuntu-16.04 steps: - uses: actions/checkout@v2 - - name: install dependencies - run: sudo apt-get install gcc-6 libusb-1.0.0-dev libgtk-3-dev rpm + - name: Install dependencies + run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm + - name: Set compiler flags + run: | + CFLAGS="$CFLAGS -m32" + CXXFLAGS="$CXXFLAGS -m32" + LDFLAGS="$LDFLAGS -m32" - name: make debug - run: make debug + run: sudo make clean && make debug - name: make test - run: make test + run: sudo make clean && make test - name: make release - run: make release + run: sudo make clean && make release - name: sudo make install - run: sudo make install + run: sudo make clean && sudo make install - name: sudo make package run: sudo make package - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean + run: sudo make uninstall && sudo make clean - job_linux_3a: - name: ubuntu-16.04 gcc + job_linux_16_04_64_clang: + name: ubuntu-16.04 clang runs-on: ubuntu-16.04 steps: - uses: actions/checkout@v2 - name: Install dependencies - run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm + run: sudo apt-get install clang-3.5 libusb-1.0.0-dev libgtk-3-dev rpm - name: make debug - run: make debug + run: sudo make clean && make debug - name: make test - run: make test + run: sudo make clean && make test - name: make release - run: make release + run: sudo make clean && make release - name: sudo make install - run: sudo make install + run: sudo make clean && sudo make install - name: sudo make package run: sudo make package - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean + run: sudo make uninstall && sudo make clean - job_linux_1b: - name: ubuntu-20.04 clang - runs-on: ubuntu-20.04 + job_linux_16_04_32_clang: + name: ubuntu-16.04 clang 32-bit + runs-on: ubuntu-16.04 steps: - uses: actions/checkout@v2 - name: Install dependencies - run: sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm + run: sudo apt-get install clang-3.5 libusb-1.0.0-dev libgtk-3-dev rpm + - name: Set compiler flags + run: | + CFLAGS="$CFLAGS -m32" + CXXFLAGS="$CXXFLAGS -m32" + LDFLAGS="$LDFLAGS -m32" + - name: make debug + run: sudo make clean && make debug + - name: make test + run: sudo make clean && make test + - name: make release + run: sudo make clean && make release + - name: sudo make install + run: sudo make clean && sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall && sudo make clean + + job_linux_18_04_64_gcc: + name: ubuntu-18.04 gcc + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - name: install dependencies + run: sudo apt-get install gcc-6 libusb-1.0.0-dev libgtk-3-dev rpm - name: make debug - run: make debug + run: sudo make clean && make debug - name: make test - run: make test + run: sudo make clean && make test - name: make release - run: make release + run: sudo make clean && make release - name: sudo make install - run: sudo make install + run: sudo make clean && sudo make install - name: sudo make package run: sudo make package - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean + run: sudo make uninstall && sudo make clean - job_linux_2b: + job_linux_18_04_32_gcc: + name: ubuntu-18.04 gcc 32-bit + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - name: install dependencies + run: sudo apt-get install gcc-6 libusb-1.0.0-dev libgtk-3-dev rpm + - name: Set compiler flags + run: | + CFLAGS="$CFLAGS -m32" + CXXFLAGS="$CXXFLAGS -m32" + LDFLAGS="$LDFLAGS -m32" + - name: make debug + run: sudo make clean && make debug + - name: make test + run: sudo make clean && make test + - name: make release + run: sudo make clean && make release + - name: sudo make install + run: sudo make clean && sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall && sudo make clean + + job_linux_18_04_64_clang: name: ubuntu-18.04 clang runs-on: ubuntu-18.04 steps: @@ -103,43 +153,64 @@ jobs: - name: install dependencies run: sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm - name: make debug - run: make debug + run: sudo make clean && make debug - name: make test - run: make test + run: sudo make clean && make test - name: make release - run: make release + run: sudo make clean && make release - name: sudo make install - run: sudo make install + run: sudo make clean && sudo make install - name: sudo make package run: sudo make package - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean + run: sudo make uninstall && sudo make clean - job_linux_3b: - name: ubuntu-16.04 clang - runs-on: ubuntu-16.04 + job_linux_18_04_32_clang: + name: ubuntu-18.04 clang 32-bit + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm + - name: Set compiler flags + run: | + CFLAGS="$CFLAGS -m32" + CXXFLAGS="$CXXFLAGS -m32" + LDFLAGS="$LDFLAGS -m32" + - name: make debug + run: sudo make clean && make debug + - name: make test + run: sudo make clean && make test + - name: make release + run: sudo make clean && make release + - name: sudo make install + run: sudo make clean && sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall && sudo make clean + + job_linux_20_04_64_gcc: + name: ubuntu-20.04 gcc + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - name: Install dependencies - run: sudo apt-get install clang libusb-1.0.0-dev libgtk-3-dev rpm + run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm - name: make debug - run: make debug + run: sudo make clean && make debug - name: make test - run: make test + run: sudo make clean && make test - name: make release - run: make release + run: sudo make clean && make release - name: sudo make install - run: sudo make install + run: sudo make clean && sudo make install - name: sudo make package run: sudo make package - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean + run: sudo make uninstall && sudo make clean - job_linux_1c: + job_linux_20_04_32_gcc: name: ubuntu-20.04 gcc 32-bit runs-on: ubuntu-20.04 steps: @@ -152,97 +223,106 @@ jobs: CXXFLAGS="$CXXFLAGS -m32" LDFLAGS="$LDFLAGS -m32" - name: make debug - run: make debug + run: sudo make clean && make debug - name: make test - run: make test + run: sudo make clean && make test - name: make release - run: make release + run: sudo make clean && make release - name: sudo make install - run: sudo make install + run: sudo make clean && sudo make install - name: sudo make package run: sudo make package - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean + run: sudo make uninstall && sudo make clean - job_linux_2c: - name: ubuntu-18.04 gcc 32-bit - runs-on: ubuntu-18.04 + job_linux_20_04_64_clang: + name: ubuntu-20.04 clang + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - - name: install dependencies - run: sudo apt-get install gcc-6 libusb-1.0.0-dev libgtk-3-dev rpm - - name: Set compiler flags - run: | - CFLAGS="$CFLAGS -m32" - CXXFLAGS="$CXXFLAGS -m32" - LDFLAGS="$LDFLAGS -m32" + - name: Install dependencies + run: sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm - name: make debug - run: make debug + run: sudo make clean && make debug - name: make test - run: make test + run: sudo make clean && make test - name: make release - run: make release + run: sudo make clean && make release - name: sudo make install - run: sudo make install + run: sudo make clean && sudo make install - name: sudo make package run: sudo make package - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean + run: sudo make uninstall && sudo make clean - job_linux_3c: - name: ubuntu-16.04 gcc 32-bit - runs-on: ubuntu-16.04 + job_linux_20_04_32_clang: + name: ubuntu-20.04 clang 32-bit + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - name: Install dependencies - run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm + run: sudo apt-get install clang-10 libusb-1.0.0-dev libgtk-3-dev rpm - name: Set compiler flags run: | CFLAGS="$CFLAGS -m32" CXXFLAGS="$CXXFLAGS -m32" LDFLAGS="$LDFLAGS -m32" - name: make debug - run: make debug + run: sudo make clean && make debug - name: make test - run: make test + run: sudo make clean && make test - name: make release - run: make release + run: sudo make clean && make release - name: sudo make install - run: sudo make install + run: sudo make clean && sudo make install - name: sudo make package run: sudo make package - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean + run: sudo make uninstall && sudo make clean - job_linux_4: - name: ubuntu-20.04 mingw64 - runs-on: ubuntu-20.04 +# macOS + + job_macos_10_15_gcc: + name: macos-10.15 gcc + runs-on: macos-10.15 + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: brew install gcc libusb gtk+3 + - name: make debug + run: sudo make clean && make debug + - name: make test + run: sudo make clean && make test + - name: make release + run: sudo make clean && make release + - name: sudo make install + run: sudo make clean && sudo make install + - name: sudo make package + run: sudo make package + - name: sudo make uninstall + run: sudo make uninstall && sudo make clean + + job_macos_10_15_clang: + name: macos-10.15 clang + runs-on: macos-10.15 steps: - uses: actions/checkout@v2 - name: Install dependencies - run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm mingw-w64 + run: brew install llvm libusb gtk+3 - name: make debug - run: make debug + run: sudo make clean && make debug - name: make test - run: make test + run: sudo make clean && make test - name: make release - run: make release + run: sudo make clean && make release - name: sudo make install - run: sudo make install + run: sudo make clean && sudo make install - name: sudo make package run: sudo make package - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean + run: sudo make uninstall && sudo make clean - # job_macos_1a: + # job_macos_11_gcc: # name: macos-11.0 gcc # runs-on: macos-11.0 # steps: @@ -250,43 +330,19 @@ jobs: # - name: Install dependencies # run: brew install gcc libusb gtk+3 # - name: make debug - # run: make debug + # run: sudo make clean && make debug # - name: make test - # run: make test + # run: sudo make clean && make test # - name: make release - # run: make release + # run: sudo make clean && make release # - name: sudo make install - # run: sudo make install + # run: sudo make clean && sudo make install # - name: sudo make package # run: sudo make package # - name: sudo make uninstall - # run: sudo make uninstall - # - name: sudo make clean - # run: sudo make clean + # run: sudo make uninstall && sudo make clean - job_macos_2a: - name: macos-10.15 gcc - runs-on: macos-10.15 - steps: - - uses: actions/checkout@v2 - - name: Install dependencies - run: brew install gcc libusb gtk+3 - - name: make debug - run: make debug - - name: make test - run: make test - - name: make release - run: make release - - name: sudo make install - run: sudo make install - - name: sudo make package - run: sudo make package - - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean - - # job_macos_1b: + # job_macos_11_clang: # name: macos-11.0 clang # runs-on: macos-11.0 # steps: @@ -294,38 +350,31 @@ jobs: # - name: Install dependencies # run: brew install llvm libusb gtk+3 # - name: make debug - # run: make debug + # run: sudo make clean && make debug # - name: make test - # run: make test + # run: sudo make clean && make test # - name: make release - # run: make release + # run: sudo make clean && make release # - name: sudo make install - # run: sudo make install + # run: sudo make clean && sudo make install # - name: sudo make package # run: sudo make package # - name: sudo make uninstall - # run: sudo make uninstall - # - name: sudo make clean - # run: sudo make clean + # run: sudo make uninstall && sudo make clean - job_macos_2b: - name: macos-10.15 clang - runs-on: macos-10.15 - steps: - - uses: actions/checkout@v2 - - name: Install dependencies - run: brew install llvm libusb gtk+3 - - name: make debug - run: make debug - - name: make test - run: make test - - name: make release - run: make release - - name: sudo make install - run: sudo make install - - name: sudo make package - run: sudo make package - - name: sudo make uninstall - run: sudo make uninstall - - name: sudo make clean - run: sudo make clean +# Linux MinGW cross compliation + + # job_linux_20_04_cross: + # name: ubuntu-20.04 mingw64 + # runs-on: ubuntu-20.04 + # steps: + # - uses: actions/checkout@v2 + # - name: Install dependencies + # run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm mingw-w64 + # - name: Building Release for Windows (x86-64) ... + # run: sudo mkdir -p build-mingw && cd build-mingw && sudo cmake \ + # -DCMAKE_SYSTEM_NAME=Windows \ + # -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ + # -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake \ + # -DCMAKE_INSTALL_PREFIX=$PWD/install $PWD && \ + # sudo make && sudo rm -rf build-mingw && cd - diff --git a/.travis.sh b/.travis.sh index 7683af001..de2a42372 100755 --- a/.travis.sh +++ b/.travis.sh @@ -9,13 +9,13 @@ echo "WORK DIR:$DIR" DIR=$PWD if [ "$TRAVIS_JOB_NAME" == "linux-mingw" ]; then - echo "--> Building Release for Windows (x86-64) ..." + echo "--> Building for Windows (x86-64) ..." mkdir -p build-mingw && cd build-mingw cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make && rm -rf build-mingw && cd - - echo "--> Building Release for Windows (i686) ..." + echo "--> Building for Windows (i686) ..." mkdir -p build-mingw && cd build-mingw cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR diff --git a/.travis.yml b/.travis.yml index e866cc6ab..2a788fd69 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,23 +2,7 @@ language: c jobs: include: - ### 64-bit builds on AMD64 ### - - os: linux - dist: xenial - env: BADGE=linux - compiler: gcc-5 - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: ["gcc-5", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - - os: linux - dist: bionic - env: BADGE=linux - compiler: gcc-6 - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: ["gcc-6", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + ### 64-bit build on AMD64 ### - os: linux dist: focal env: BADGE=linux @@ -27,30 +11,18 @@ jobs: apt: sources: ["ubuntu-toolchain-r-test"] packages: ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - - os: linux - dist: xenial - env: BADGE=linux - compiler: clang - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: ["libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - - os: linux - dist: bionic - env: BADGE=linux - compiler: clang-10 - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: ["clang-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + + ### 32-bit build on AMD64 ### - os: linux dist: focal env: BADGE=linux - compiler: clang-10 + compiler: gcc-10 addons: apt: sources: ["ubuntu-toolchain-r-test"] - packages: ["clang-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + packages: ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + before_install: + - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; ### cross build on AMD64 ### - os: linux @@ -63,92 +35,61 @@ jobs: sources: ["ubuntu-toolchain-r-test"] packages: ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] - - ### 32-bit builds on AMD64 ### - - os: linux - dist: xenial - env: BADGE=linux - compiler: gcc-5 - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: ["gcc-5", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - before_install: - - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - - os: linux - dist: bionic - env: BADGE=linux - compiler: gcc-6 - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: ["gcc-6", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - before_install: - - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - - os: linux - dist: focal - env: BADGE=linux - compiler: gcc-10 - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - before_install: - - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - - os: linux - dist: xenial - env: BADGE=linux - compiler: clang - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: ["libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] before_install: - - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - - os: linux - dist: bionic - env: BADGE=linux - compiler: clang-10 - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: ["clang-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - before_install: - - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - - os: linux - dist: focal - env: BADGE=linux - compiler: clang-10 - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: ["clang-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - before_install: - - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; + - LDFLAGS="$LDFLAGS -NDEBUG"; ### macOS ### - - os: osx - env: BADGE=osx - osx_image: xcode12.2 - name: macOS 10.15.7 - compiler: gcc - addons: - homebrew: - packages: - - gcc - - libusb - - gtk+3 - - os: osx - env: BADGE=osx - osx_image: xcode12.2 - name: macOS 10.15.7 - compiler: clang - addons: - homebrew: - packages: - - llvm - - libusb - - gtk+3 + # - os: osx + # env: BADGE=osx + # osx_image: xcode11.3 + # name: macOS 10.14.6 gcc + # compiler: gcc + # addons: + # homebrew: + # packages: + # - gcc + # - libusb + # - gtk+3 + + # - os: osx + # env: BADGE=osx + # osx_image: xcode11.3 + # name: macOS 10.14.6 gcc 32-bit + # compiler: gcc + # addons: + # homebrew: + # packages: + # - gcc + # - libusb + # - gtk+3 + # before_install: + # - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; + + # - os: osx + # env: BADGE=osx + # osx_image: xcode11.3 + # name: macOS 10.14.6 clang + # compiler: clang + # addons: + # homebrew: + # packages: + # - llvm + # - libusb + # - gtk+3 + + # - os: osx + # env: BADGE=osx + # osx_image: xcode11.3 + # name: macOS 10.14.6 clang 32-bit + # compiler: clang + # addons: + # homebrew: + # packages: + # - llvm + # - libusb + # - gtk+3 + # before_install: + # - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; script: - git fetch --tags diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index bc613779d..3082a9509 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -46,8 +46,10 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-toolchain on Debian # for MinGW/MSYS/MSVC: 64-bit or 32-bit? if (CMAKE_SIZEOF_VOID_P EQUAL 8) + message(STATUS "=== Building for Windows (x86-64) ===") set(ARCH 64) else () + message(STATUS "=== Building for Windowsm (i686) ===") set(ARCH 32) endif () From 7cfab876e73f994c95697ba1b09a0a18c2602597 Mon Sep 17 00:00:00 2001 From: anton Date: Sat, 27 Mar 2021 19:14:37 +0500 Subject: [PATCH 39/65] flash_loader: fix typo in the stm32l4 loader --- flashloaders/stm32l4.s | 6 +++--- src/stlink-lib/flash_loader.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/flashloaders/stm32l4.s b/flashloaders/stm32l4.s index 21e926f49..50676be9a 100644 --- a/flashloaders/stm32l4.s +++ b/flashloaders/stm32l4.s @@ -12,7 +12,7 @@ .global copy copy: ldr r12, flash_base - ldr r10, flash_off_bsy + ldr r10, flash_off_sr add r10, r10, r12 loop: @@ -44,5 +44,5 @@ exit: .align 2 flash_base: .word 0x40022000 -flash_off_bsy: - .word 0x12 +flash_off_sr: + .word 0x10 diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 9fa897ccc..20fd6aeed 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -114,7 +114,7 @@ static const uint8_t loader_code_stm32l4[] = { 0x08, 0x3a, 0xf0, 0xdc, 0x00, 0xbe, 0x00, 0xbf, 0x00, 0x20, 0x02, 0x40, - 0x12, 0x00, 0x00, 0x00 + 0x10, 0x00, 0x00, 0x00 }; static const uint8_t loader_code_stm32f7[] = { From c0653f6595e1c564f5a762982ef0c23a00ff3dea Mon Sep 17 00:00:00 2001 From: anton Date: Sat, 27 Mar 2021 19:17:13 +0500 Subject: [PATCH 40/65] flash_loader: improved handling errors --- flashloaders/Makefile | 2 +- src/stlink-lib/flash_loader.c | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/flashloaders/Makefile b/flashloaders/Makefile index d4ca4d22a..8b01d5293 100644 --- a/flashloaders/Makefile +++ b/flashloaders/Makefile @@ -31,7 +31,7 @@ stm32vl.o: stm32f0.s $(CC) stm32f0.s $(CFLAGS_ARMV7_M) -o stm32vl.o # generic rule for all other ARMv7-M -%.o: *.s +%.o: %.s $(CC) $< $(CFLAGS_ARMV7_M) -o $@ clean: diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 20fd6aeed..aea60f258 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -154,6 +154,7 @@ static const uint8_t loader_code_stm32f7_lv[] = { int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { size_t size = 0; + uint32_t dfsr, cfsr, hfsr; // allocate the loader in SRAM if (stlink_flash_loader_write_to_sram(sl, &fl->loader_addr, &size) == -1) { @@ -165,6 +166,20 @@ int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { fl->buf_addr = fl->loader_addr + (uint32_t)size; ILOG("Successfully loaded flash loader in sram\n"); + /* Clear Fault Status Register for handling flash loader error */ + if (!stlink_read_debug32(sl, STLINK_REG_DFSR, &dfsr) && dfsr) { + ILOG("Clear DFSR\n"); + stlink_write_debug32(sl, STLINK_REG_DFSR, dfsr); + } + if (!stlink_read_debug32(sl, STLINK_REG_CFSR, &cfsr) && cfsr) { + ILOG("Clear CFSR\n"); + stlink_write_debug32(sl, STLINK_REG_CFSR, cfsr); + } + if (!stlink_read_debug32(sl, STLINK_REG_HFSR, &hfsr) && hfsr) { + ILOG("Clear HFSR\n"); + stlink_write_debug32(sl, STLINK_REG_HFSR, hfsr); + } + return(0); } @@ -348,7 +363,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe // check written byte count stlink_read_reg(sl, 2, &rr); - if (rr.r[2] != 0) { + if ((int32_t)rr.r[2] > 0) { ELOG("Write error\n"); goto error; } @@ -364,7 +379,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe stlink_read_all_regs(sl, &rr); WLOG("Loader state: R2 0x%X R15 0x%X\n", rr.r[2], rr.r[15]); - if (dhcsr != 0x3000B || dfsr != 0x3 || cfsr || hfsr) { + if (dhcsr != 0x3000B || dfsr || cfsr || hfsr) { WLOG("MCU state: DHCSR 0x%X DFSR 0x%X CFSR 0x%X HFSR 0x%X\n", dhcsr, dfsr, cfsr, hfsr); } From bb96d613dd78f34b112dcbc91af0363315b7d0ff Mon Sep 17 00:00:00 2001 From: anton Date: Sat, 27 Mar 2021 19:37:20 +0500 Subject: [PATCH 41/65] Fix is_flash_busy on STM32F1 XL device --- src/common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common.c b/src/common.c index a17392cf1..640f37799 100644 --- a/src/common.c +++ b/src/common.c @@ -993,7 +993,7 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { unsigned int res; if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) || (sl->flash_type == STLINK_FLASH_TYPE_L0)) { sr_busy_shift = FLASH_SR_BSY; } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { @@ -1010,7 +1010,7 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { sr_busy_shift = FLASH_H7_SR_QW; } else { - ELOG("unsupported flash method, abort\n"); + ELOG("unsupported flash method\n"); return(-1); } From be9c9dec7661f2b9e30fb26b85808bc132ee2c80 Mon Sep 17 00:00:00 2001 From: anton Date: Sun, 28 Mar 2021 21:36:12 +0500 Subject: [PATCH 42/65] flash_loader: fixed check of the flash loader results --- src/stlink-lib/flash_loader.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index aea60f258..992f0a827 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -363,7 +363,13 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe // check written byte count stlink_read_reg(sl, 2, &rr); - if ((int32_t)rr.r[2] > 0) { + /* The chunk size for loading is not rounded. The flash loader + * subtracts the size of the written block (1-8 bytes) from + * the remaining size each time. A negative value may mean that + * several bytes garbage has been written due to the unaligned + * firmware size. + */ + if ((int32_t)rr.r[2] > 0 || (int32_t)rr.r[2] < -7) { ELOG("Write error\n"); goto error; } From d0d52690d680d603264b90f6328e54aec4be793c Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 29 Mar 2021 19:51:55 +0500 Subject: [PATCH 43/65] Added error checking in the FLASH_SR register after write and erase operations --- src/common.c | 214 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 175 insertions(+), 39 deletions(-) diff --git a/src/common.c b/src/common.c index 640f37799..7ebbb8d11 100644 --- a/src/common.c +++ b/src/common.c @@ -159,6 +159,9 @@ // G0/G4 FLASH status register #define STM32Gx_FLASH_SR_ERROR_MASK (0x3fa) +#define STM32Gx_FLASH_SR_PROGERR (3) +#define STM32Gx_FLASH_SR_WRPERR (4) +#define STM32Gx_FLASH_SR_PGAERR (5) #define STM32Gx_FLASH_SR_BSY (16) /* FLASH_SR Busy */ #define STM32Gx_FLASH_SR_EOP (0) /* FLASH_EOP End of Operation */ @@ -188,11 +191,15 @@ #define STM32WB_FLASH_SRRVR (STM32WB_FLASH_REGS_ADDR + 0x84) // WB Flash control register. -#define STM32WB_FLASH_CR_STRT (16) /* FLASH_CR Start */ -#define STM32WB_FLASH_CR_OPTLOCK (30) /* FLASH_CR Option Lock */ -#define STM32WB_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ +#define STM32WB_FLASH_CR_STRT (16) /* Start */ +#define STM32WB_FLASH_CR_OPTLOCK (30) /* Option Lock */ +#define STM32WB_FLASH_CR_LOCK (31) /* Lock */ // WB Flash status register. -#define STM32WB_FLASH_SR_BSY (16) /* FLASH_SR Busy */ +#define STM32WB_FLASH_SR_ERROR_MASK (0x3f8) /* SR [9:3] */ +#define STM32WB_FLASH_SR_PROGERR (3) /* Programming alignment error */ +#define STM32WB_FLASH_SR_WRPERR (4) /* Write protection error */ +#define STM32WB_FLASH_SR_PGAERR (5) /* Programming error */ +#define STM32WB_FLASH_SR_BSY (16) /* Busy */ // 32L4 register base is at FLASH_REGS_ADDR (0x40022000) #define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) @@ -201,8 +208,11 @@ #define STM32L4_FLASH_CR (FLASH_REGS_ADDR + 0x14) #define STM32L4_FLASH_OPTR (FLASH_REGS_ADDR + 0x20) +#define STM32L4_FLASH_SR_ERROR_MASK 0x3f8 /* SR [9:3] */ +#define STM32L4_FLASH_SR_PROGERR 3 +#define STM32L4_FLASH_SR_WRPERR 4 +#define STM32L4_FLASH_SR_PGAERR 5 #define STM32L4_FLASH_SR_BSY 16 -#define STM32L4_FLASH_SR_ERRMASK 0x3f8 /* SR [9:3] */ #define STM32L4_FLASH_CR_LOCK 31 /* Lock control register */ #define STM32L4_FLASH_CR_OPTLOCK 30 /* Lock option bytes */ @@ -234,7 +244,10 @@ #define STM32L0_FLASH_OPTLOCK (2) #define STM32L0_FLASH_OBL_LAUNCH (18) -#define STM32L0_FLASH_SR_ERROR_MASK 0x00003F00 +#define STM32L0_FLASH_SR_ERROR_MASK 0x00013F00 +#define STM32L0_FLASH_SR_WRPERR 8 +#define STM32L0_FLASH_SR_PGAERR 9 +#define STM32L0_FLASH_SR_NOTZEROERR 16 #define FLASH_ACR_OFF ((uint32_t) 0x00) #define FLASH_PECR_OFF ((uint32_t) 0x04) @@ -287,7 +300,10 @@ #define FLASH_F4_CR_SER 1 #define FLASH_F4_CR_SNB 3 #define FLASH_F4_CR_SNB_MASK 0xf8 -#define FLASH_F4_SR_BSY 16 +#define FLASH_F4_SR_ERROR_MASK 0x000000F0 +#define FLASH_F4_SR_PGAERR 5 +#define FLASH_F4_SR_WRPERR 4 +#define FLASH_F4_SR_BSY 16 // STM32F2 #define FLASH_F2_REGS_ADDR ((uint32_t)0x40023c00) @@ -980,7 +996,7 @@ static inline uint32_t read_flash_sr(stlink_t *sl, unsigned bank) { } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { sr_reg = (bank==BANK_1)?FLASH_H7_SR1:FLASH_H7_SR2; } else { - ELOG("unsupported flash method, abort\n"); + ELOG("method 'read_flash_sr' is unsupported\n"); return(-1); } @@ -988,6 +1004,35 @@ static inline uint32_t read_flash_sr(stlink_t *sl, unsigned bank) { return(res); } +static inline int write_flash_sr(stlink_t *sl, unsigned bank, uint32_t val) { + uint32_t sr_reg; + + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + sr_reg = (bank==BANK_1)?FLASH_SR:FLASH_SR2; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + sr_reg = FLASH_F4_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + sr_reg = FLASH_F7_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + sr_reg = STM32L4_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + sr_reg = STM32Gx_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + sr_reg = STM32WB_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + sr_reg = (bank==BANK_1)?FLASH_H7_SR1:FLASH_H7_SR2; + } else { + ELOG("method 'write_flash_sr' is unsupported\n"); + return(-1); + } + + return stlink_write_debug32(sl, sr_reg, val); +} + static inline unsigned int is_flash_busy(stlink_t *sl) { uint32_t sr_busy_shift; unsigned int res; @@ -1010,7 +1055,7 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { sr_busy_shift = FLASH_H7_SR_QW; } else { - ELOG("unsupported flash method\n"); + ELOG("method 'is_flash_busy' is unsupported\n"); return(-1); } @@ -1048,43 +1093,120 @@ static void wait_flash_busy_progress(stlink_t *sl) { fprintf(stdout, "\n"); } +static void clear_flash_error(stlink_t *sl) +{ + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + write_flash_sr(sl, BANK_1, FLASH_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_F4: + write_flash_sr(sl, BANK_1, FLASH_F4_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_F7: + write_flash_sr(sl, BANK_1, FLASH_F7_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + write_flash_sr(sl, BANK_1, STM32Gx_FLASH_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_L0: + write_flash_sr(sl, BANK_1, STM32L0_FLASH_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_L4: + write_flash_sr(sl, BANK_1, STM32L4_FLASH_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_H7: + write_flash_sr(sl, BANK_1, FLASH_H7_SR_ERROR_MASK); + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + write_flash_sr(sl, BANK_2, FLASH_H7_SR_ERROR_MASK); + } + break; + case STLINK_FLASH_TYPE_WB: + write_flash_sr(sl, BANK_1, STM32WB_FLASH_SR_ERROR_MASK); + break; + default: + break; + } +} + static int check_flash_error(stlink_t *sl) { uint32_t res = 0; + uint32_t WRPERR, PROGERR, PGAERR; + + WRPERR = PROGERR = PGAERR = 0; switch (sl->flash_type) { case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: res = read_flash_sr(sl, BANK_1) & FLASH_SR_ERROR_MASK; + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + res |= read_flash_sr(sl, BANK_2) & FLASH_SR_ERROR_MASK; + } + WRPERR = (1 << FLASH_SR_WRPRT_ERR); + PROGERR = (1 << FLASH_SR_PG_ERR); + break; + case STLINK_FLASH_TYPE_F4: + res = read_flash_sr(sl, BANK_1) & FLASH_F4_SR_ERROR_MASK; + WRPERR = (1 << FLASH_F4_SR_WRPERR); + PGAERR = (1 << FLASH_F4_SR_PGAERR); break; case STLINK_FLASH_TYPE_F7: res = read_flash_sr(sl, BANK_1) & FLASH_F7_SR_ERROR_MASK; + WRPERR = (1 << FLASH_F7_SR_WRP_ERR); + PROGERR = (1 << FLASH_F7_SR_PGP_ERR); break; case STLINK_FLASH_TYPE_G0: case STLINK_FLASH_TYPE_G4: res = read_flash_sr(sl, BANK_1) & STM32Gx_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32Gx_FLASH_SR_WRPERR); + PROGERR = (1 << STM32Gx_FLASH_SR_PROGERR); + PGAERR = (1 << STM32Gx_FLASH_SR_PGAERR); break; case STLINK_FLASH_TYPE_L0: res = read_flash_sr(sl, BANK_1) & STM32L0_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32L0_FLASH_SR_WRPERR); + PROGERR = (1 << STM32L0_FLASH_SR_NOTZEROERR); + PGAERR = (1 << STM32L0_FLASH_SR_PGAERR); + break; + case STLINK_FLASH_TYPE_L4: + res = read_flash_sr(sl, BANK_1) & STM32L4_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32L4_FLASH_SR_WRPERR); + PROGERR = (1 << STM32L4_FLASH_SR_PROGERR); + PGAERR = (1 << STM32L4_FLASH_SR_PGAERR); break; case STLINK_FLASH_TYPE_H7: res = read_flash_sr(sl, BANK_1) & FLASH_H7_SR_ERROR_MASK; if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { res |= read_flash_sr(sl, BANK_2) & FLASH_H7_SR_ERROR_MASK; } - if (res) { - // Clear errors - stlink_write_debug32(sl, FLASH_H7_CCR1, res); - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - stlink_write_debug32(sl, FLASH_H7_CCR2, res); - } - } + WRPERR = (1 << FLASH_H7_SR_WRPERR); + break; + case STLINK_FLASH_TYPE_WB: + res = read_flash_sr(sl, BANK_1) & STM32WB_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32WB_FLASH_SR_WRPERR); + PROGERR = (1 << STM32WB_FLASH_SR_PROGERR); + PGAERR = (1 << STM32WB_FLASH_SR_PGAERR); break; default: break; } if (res) { - ELOG("Flash programming error : %#010x\n", res); + if (WRPERR && (WRPERR&res)==WRPERR) { + ELOG("Flash memory is write protected\n"); + res &= ~WRPERR; + } else if (PROGERR && (PROGERR&res)==PROGERR) { + ELOG("Flash memory contains a non-erased value\n"); + res &= ~PROGERR; + } else if (PGAERR && (PGAERR&res)==PGAERR) { + ELOG("Invalid flash address\n"); + res &= ~PGAERR; + } + + if (res) { + ELOG("Flash programming error: %#010x\n", res); + } return(-1); } @@ -2372,12 +2494,14 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { * @return 0 on success -ve on failure */ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { + // wait for ongoing op to finish + wait_flash_busy(sl); + // clear flash IO errors + clear_flash_error(sl); + if (sl->flash_type == STLINK_FLASH_TYPE_F4 || sl->flash_type == STLINK_FLASH_TYPE_F7 || sl->flash_type == STLINK_FLASH_TYPE_L4) { - // wait for ongoing op to finish - wait_flash_busy(sl); - // unlock if locked unlock_flash_if(sl); @@ -2498,7 +2622,6 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { uint32_t val; - wait_flash_busy(sl); // wait for any ongoing Flash operation to finish unlock_flash_if(sl); set_flash_cr_per(sl, BANK_1); // set the 'enable Flash erase' bit @@ -2535,7 +2658,6 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { } else if (sl->flash_type == STLINK_FLASH_TYPE_F0 || sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { unsigned bank = (flashaddr < STM32_F1_FLASH_BANK2_BASE)?BANK_1:BANK_2; - wait_flash_busy(sl); unlock_flash_if(sl); clear_flash_cr_pg(sl, bank); // clear the pg bit set_flash_cr_per(sl, bank); // set the page erase bit @@ -2545,7 +2667,6 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { lock_flash(sl); } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { unsigned bank = (flashaddr < STM32_H7_FLASH_BANK2_BASE)?BANK_1:BANK_2; - wait_flash_busy(sl); // wait for ongoing op to finish unlock_flash_if(sl); // unlock if locked uint32_t sector = calculate_H7_sectornum(sl, flashaddr, bank);// calculate the actual page from the address write_flash_cr_snb(sl, sector, bank); // select the page to erase @@ -2557,8 +2678,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { return(-1); } - // TODO: verify the erased page - return(0); + return check_flash_error(sl); } int stlink_erase_flash_mass(stlink_t *sl) { @@ -2574,7 +2694,7 @@ int stlink_erase_flash_mass(stlink_t *sl) { // addr must be an addr inside the page stm32_addr_t addr = (stm32_addr_t)sl->flash_base + i * (stm32_addr_t)sl->flash_pgsz; - if (stlink_erase_flash_page(sl, addr) == -1) { + if (stlink_erase_flash_page(sl, addr)) { WLOG("Failed to erase_flash_page(%#x) == -1\n", addr); return(-1); } @@ -2586,6 +2706,7 @@ int stlink_erase_flash_mass(stlink_t *sl) { fprintf(stdout, "\n"); } else { wait_flash_busy(sl); + clear_flash_error(sl); unlock_flash_if(sl); if (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->chip_id != STLINK_CHIPID_STM32_H7AX) { @@ -2596,7 +2717,7 @@ int stlink_erase_flash_mass(stlink_t *sl) { } } - set_flash_cr_mer(sl, 1, BANK_1); // set the mass erase bit + set_flash_cr_mer(sl, 1, BANK_1); // set the mass erase bit set_flash_cr_strt(sl, BANK_1); // start erase operation, reset by hw with busy bit if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || @@ -2606,7 +2727,6 @@ int stlink_erase_flash_mass(stlink_t *sl) { } wait_flash_busy_progress(sl); - err = check_flash_error(sl); lock_flash(sl); // reset the mass erase bit @@ -2616,7 +2736,7 @@ int stlink_erase_flash_mass(stlink_t *sl) { set_flash_cr_mer(sl, 0, BANK_2); } - // TODO: verify the erased memory + err = check_flash_error(sl); } return(err); @@ -2751,6 +2871,11 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { STLINK_REG_DHCSR_C_HALT | STLINK_REG_DHCSR_C_MASKINTS); + // wait for ongoing op to finish + wait_flash_busy(sl); + // Clear errors + clear_flash_error(sl); + if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || (sl->flash_type == STLINK_FLASH_TYPE_F7) || (sl->flash_type == STLINK_FLASH_TYPE_L4)) { @@ -2801,7 +2926,6 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { sl->flash_type == STLINK_FLASH_TYPE_G4) { ILOG("Starting Flash write for WB/G0/G4\n"); - wait_flash_busy(sl); unlock_flash_if(sl); // unlock flash if necessary set_flash_cr_pg(sl, BANK_1); // set PG 'allow programming' bit } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { @@ -2882,6 +3006,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr size_t size = len - off > buf_size ? buf_size : len - off; if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, size) == -1) { ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", (unsigned)(addr + off)); + check_flash_error(sl); return(-1); } @@ -2977,6 +3102,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, size) == -1) { ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", (unsigned)(addr + off)); + check_flash_error(sl); return(-1); } @@ -3015,7 +3141,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr return(-1); } - return(0); + return check_flash_error(sl); } int stlink_flashloader_stop(stlink_t *sl) { @@ -3405,6 +3531,8 @@ static int stlink_write_option_bytes_gx( (void)len; uint32_t data; + clear_flash_error(sl); + write_uint32((unsigned char*)&data, *(uint32_t*)(base)); WLOG("Writing option bytes %#10x to %#10x\n", data, addr); stlink_write_debug32(sl, STM32Gx_FLASH_OPTR, data); @@ -3441,7 +3569,7 @@ static int stlink_write_option_bytes_l0( int ret = 0; // Clear errors - stlink_write_debug32(sl, flash_base + FLASH_SR_OFF, STM32L0_FLASH_REGS_ADDR); + clear_flash_error(sl); while (len != 0) { write_uint32((unsigned char*)&data, *(uint32_t*)(base)); // write options bytes @@ -3480,6 +3608,9 @@ static int stlink_write_option_bytes_l4( (void)addr; (void)len; + // Clear errors + clear_flash_error(sl); + // write options bytes uint32_t data; write_uint32((unsigned char*)&data, *(uint32_t*)(base)); @@ -3516,6 +3647,9 @@ static int stlink_write_option_bytes_f4( (void)addr; (void)len; + // Clear errors + clear_flash_error(sl); + write_uint32((unsigned char*)&option_byte, *(uint32_t*)(base)); // write option byte, ensuring we dont lock opt, and set strt bit @@ -3539,8 +3673,8 @@ static int stlink_write_option_bytes_f7(stlink_t *sl, uint8_t* base, stm32_addr_ uint32_t option_byte; int ret = 0; - //(void) addr; - //(void) len; + // Clear errors + clear_flash_error(sl); ILOG("Asked to write option byte %#10x to %#010x.\n", *(uint32_t*) (base), addr); write_uint32((unsigned char*) &option_byte, *(uint32_t*) (base)); @@ -3999,9 +4133,10 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui static int stlink_write_option_control_register_f7(stlink_t *sl, uint32_t option_control_register) { int ret = 0; + // Clear errors + clear_flash_error(sl); + ILOG("Asked to write option control register 1 %#10x to %#010x.\n", option_control_register, FLASH_F7_OPTCR); - //write_uint32((unsigned char*) &option_byte, *(uint32_t*) (base)); - //ILOG("Write %d option bytes %#010x to %#010x!\n", len, option_byte, addr); /* write option byte, ensuring we dont lock opt, and set strt bit */ stlink_write_debug32(sl, FLASH_F7_OPTCR, (option_control_register & ~(1 << FLASH_F7_OPTCR_LOCK)) | (1 << FLASH_F7_OPTCR_START)); @@ -4010,7 +4145,7 @@ static int stlink_write_option_control_register_f7(stlink_t *sl, uint32_t option ret = check_flash_error(sl); if (!ret) - ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, FLASH_F7_OPTCR1); + ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, FLASH_F7_OPTCR); return ret; } @@ -4024,9 +4159,10 @@ static int stlink_write_option_control_register_f7(stlink_t *sl, uint32_t option static int stlink_write_option_control_register1_f7(stlink_t *sl, uint32_t option_control_register1) { int ret = 0; + // Clear errors + clear_flash_error(sl); + ILOG("Asked to write option control register 1 %#010x to %#010x.\n", option_control_register1, FLASH_F7_OPTCR1); - //write_uint32((unsigned char*) &option_byte, *(uint32_t*) (base)); - //ILOG("Write %d option bytes %#010x to %#010x!\n", len, option_byte, addr); /* write option byte, ensuring we dont lock opt, and set strt bit */ uint32_t current_control_register_value; From 817c8ad436eada97294fa93e6cc8e57fb1be9504 Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 29 Mar 2021 20:31:57 +0500 Subject: [PATCH 44/65] flash_loader: fixed setup PG flag in F0/VL flash loaders, code cleared --- flashloaders/stm32f0.s | 6 ++-- src/common.c | 58 ++++++++++------------------------- src/stlink-lib/flash_loader.c | 18 +++++------ 3 files changed, 26 insertions(+), 56 deletions(-) diff --git a/flashloaders/stm32f0.s b/flashloaders/stm32f0.s index e2a4b0f00..23f1c43fe 100644 --- a/flashloaders/stm32f0.s +++ b/flashloaders/stm32f0.s @@ -35,10 +35,8 @@ copy: ldr r5, flash_off_sr add r5, r5, r7 - # FLASH_CR |= 0x01 (set PG) - ldr r7, =0x1 - ldr r4, [r6] - orrs r4, r4, r7 + # FLASH_CR = 0x01 (set PG) + ldr r4, =0x1 str r4, [r6] loop: diff --git a/src/common.c b/src/common.c index 7ebbb8d11..8585ff881 100644 --- a/src/common.c +++ b/src/common.c @@ -394,13 +394,21 @@ uint16_t read_uint16(const unsigned char *c, const int pt) { static uint32_t get_stm32l0_flash_base(stlink_t *sl) { switch (sl->chip_id) { + case STLINK_CHIPID_STM32_L0: + case STLINK_CHIPID_STM32_L0_CAT5: + case STLINK_CHIPID_STM32_L0_CAT2: + case STLINK_CHIPID_STM32_L011: + return(STM32L0_FLASH_REGS_ADDR); + case STLINK_CHIPID_STM32_L1_CAT2: case STLINK_CHIPID_STM32_L1_MEDIUM: case STLINK_CHIPID_STM32_L1_MEDIUM_PLUS: case STLINK_CHIPID_STM32_L1_HIGH: return(STM32L1_FLASH_REGS_ADDR); + default: - return(STM32L0_FLASH_REGS_ADDR); + WLOG("Flash base use default L0 address"); + return(STM32L0_FLASH_REGS_ADDR); } } @@ -2549,16 +2557,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { uint32_t val; - uint32_t flash_regs_base; - - if (sl->chip_id == STLINK_CHIPID_STM32_L0 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || - sl->chip_id == STLINK_CHIPID_STM32_L011) { - flash_regs_base = STM32L0_FLASH_REGS_ADDR; - } else { - flash_regs_base = STM32L_FLASH_REGS_ADDR; - } + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); // check if the locks are set stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); @@ -2592,15 +2591,6 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { // set pecr.{erase,prog} val |= (1 << 9) | (1 << 3); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); -#if 0 - /* Wait for sr.busy to be cleared - * MP: Test shows that busy bit is not set here. Perhaps, PM0062 is wrong - * and we do not need to wait here for clearing the busy bit. - */ - do { - stlink_read_debug32(sl, STM32L_FLASH_SR, &val) - } while ((val & (1 << 0)) != 0); -#endif // write 0 to the first word of the page to be erased stlink_write_debug32(sl, flashaddr, 0); @@ -2610,9 +2600,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { * Test shows that a few iterations is performed in the following loop * before busy bit is cleared. */ - do - stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); - while ((val & (1 << 0)) != 0); + wait_flash_busy(sl); // reset lock bits stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); @@ -2652,7 +2640,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { } set_flash_cr_strt(sl, BANK_1); // set the 'start operation' bit - wait_flash_busy(sl); // wait for the 'busy' bit to clear + wait_flash_busy(sl); // wait for the 'busy' bit to clear clear_flash_cr_per(sl, BANK_1); // clear the 'enable page erase' bit lock_flash(sl); } else if (sl->flash_type == STLINK_FLASH_TYPE_F0 || @@ -2664,6 +2652,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { write_flash_ar(sl, flashaddr, bank); // select the page to erase set_flash_cr_strt(sl, bank); // start erase operation, reset by hw with busy bit wait_flash_busy(sl); + clear_flash_cr_per(sl, bank); // clear the page erase bit lock_flash(sl); } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { unsigned bank = (flashaddr < STM32_H7_FLASH_BANK2_BASE)?BANK_1:BANK_2; @@ -2796,18 +2785,9 @@ int stm32l1_write_half_pages( unsigned int count; unsigned int num_half_pages = len / pagesize; uint32_t val; - uint32_t flash_regs_base; + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); flash_loader_t fl; - if (sl->chip_id == STLINK_CHIPID_STM32_L0 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || - sl->chip_id == STLINK_CHIPID_STM32_L011) { - flash_regs_base = STM32L0_FLASH_REGS_ADDR; - } else { - flash_regs_base = STM32L_FLASH_REGS_ADDR; - } - ILOG("Starting Half page flash write for STM32L core id\n"); /* Flash loader initialisation */ @@ -2824,9 +2804,7 @@ int stm32l1_write_half_pages( val |= (1 << FLASH_L1_PROG); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - do { - stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); - } while ((val & (1 << 0)) != 0); + wait_flash_busy(sl); for (count = 0; count < num_half_pages; count++) { if (stlink_flash_loader_run( @@ -2845,9 +2823,7 @@ int stm32l1_write_half_pages( fflush(stdout); } - do { - stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); - } while ((val & (1 << 0)) != 0); + wait_flash_busy(sl); } stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); @@ -3096,8 +3072,6 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr // unlock and set programming mode unlock_flash_if(sl); - if (sl->flash_type != STLINK_FLASH_TYPE_F1_XL) { set_flash_cr_pg(sl, BANK_1); } - DLOG("Finished unlocking flash, running loader!\n"); if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, size) == -1) { diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 992f0a827..e3b1a12ea 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -14,11 +14,10 @@ /* flashloaders/stm32f0.s -- compiled with thumb2 */ static const uint8_t loader_code_stm32vl[] = { 0x00, 0xbf, 0x00, 0xbf, - 0x0f, 0x4f, 0x1f, 0x44, - 0x0f, 0x4e, 0x3e, 0x44, - 0x0f, 0x4d, 0x3d, 0x44, - 0x4f, 0xf0, 0x01, 0x07, - 0x34, 0x68, 0x3c, 0x43, + 0x0e, 0x4f, 0x1f, 0x44, + 0x0e, 0x4e, 0x3e, 0x44, + 0x0e, 0x4d, 0x3d, 0x44, + 0x4f, 0xf0, 0x01, 0x04, 0x34, 0x60, 0x04, 0x88, 0x0c, 0x80, 0x02, 0x30, 0x02, 0x31, 0x4f, 0xf0, @@ -38,11 +37,10 @@ static const uint8_t loader_code_stm32vl[] = { /* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ static const uint8_t loader_code_stm32f0[] = { 0xc0, 0x46, 0xc0, 0x46, - 0x0d, 0x4f, 0x1f, 0x44, - 0x0d, 0x4e, 0x3e, 0x44, - 0x0d, 0x4d, 0x3d, 0x44, - 0x0d, 0x4f, 0x34, 0x68, - 0x3c, 0x43, 0x34, 0x60, + 0x0c, 0x4f, 0x1f, 0x44, + 0x0c, 0x4e, 0x3e, 0x44, + 0x0c, 0x4d, 0x3d, 0x44, + 0x0c, 0x4c, 0x34, 0x60, 0x04, 0x88, 0x0c, 0x80, 0x02, 0x30, 0x02, 0x31, 0x09, 0x4f, 0x2c, 0x68, From b62cdcfab70e362b34b5875ad86b31c9e6fd6c73 Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 29 Mar 2021 20:40:22 +0500 Subject: [PATCH 45/65] Added disabling the IWDG and WWDG in halt state --- src/common.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index 8585ff881..26a3b3859 100644 --- a/src/common.c +++ b/src/common.c @@ -362,6 +362,25 @@ #define FLASH_H7_OPTSR_CUR (FLASH_H7_REGS_ADDR + 0x1c) #define FLASH_H7_OPTCCR (FLASH_H7_REGS_ADDR + 0x24) +#define STM32F0_DBGMCU_CR 0xE0042004 +#define STM32F0_DBGMCU_CR_IWDG_STOP 8 +#define STM32F0_DBGMCU_CR_WWDG_STOP 9 + +#define STM32F4_DBGMCU_APB1FZR1 0xE0042008 +#define STM32F4_DBGMCU_APB1FZR1_WWDG_STOP 11 +#define STM32F4_DBGMCU_APB1FZR1_IWDG_STOP 12 + +#define STM32L0_DBGMCU_APB1_FZ 0x40015808 +#define STM32L0_DBGMCU_APB1_FZ_WWDG_STOP 11 +#define STM32L0_DBGMCU_APB1_FZ_IWDG_STOP 12 + +#define STM32H7_DBGMCU_APB1HFZ 0x5C001054 +#define STM32H7_DBGMCU_APB1HFZ_IWDG_STOP 18 + +#define STM32WB_DBGMCU_APB1FZR1 0xE004203C +#define STM32WB_DBGMCU_APB1FZR1_WWDG_STOP 11 +#define STM32WB_DBGMCU_APB1FZR1_IWDG_STOP 12 + #define L1_WRITE_BLOCK_SIZE 0x80 #define L0_WRITE_BLOCK_SIZE 0x40 @@ -1221,6 +1240,50 @@ static int check_flash_error(stlink_t *sl) return(0); } +static void stop_wdg_in_debug(stlink_t *sl) { + uint32_t dbgmcu_cr; + uint32_t set; + uint32_t value; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + case STLINK_FLASH_TYPE_G4: + dbgmcu_cr = STM32F0_DBGMCU_CR; + set = (1< halted state. int stlink_force_debug(stlink_t *sl) { DLOG("*** stlink_force_debug_mode ***\n"); - return(sl->backend->force_debug(sl)); + int res = sl->backend->force_debug(sl); + // Stop the watchdogs in the halted state for suppress target reboot + stop_wdg_in_debug(sl); + return(res); } int stlink_exit_dfu_mode(stlink_t *sl) { From b0192478c8262476ead421890b1550d6a7b72ecc Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 29 Mar 2021 20:56:03 +0500 Subject: [PATCH 46/65] Added disabling the DMA channels --- inc/stlink.h | 3 +- src/common.c | 83 +++++++++++++++++++++++++++++++++++++++- src/st-flash/flash.c | 13 ------- src/st-util/gdb-server.c | 2 +- src/stlink-gui/gui.c | 12 ------ 5 files changed, 84 insertions(+), 29 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index 7bb1bc51e..61b8472f1 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -137,6 +137,7 @@ typedef uint32_t stm32_addr_t; typedef struct flash_loader { stm32_addr_t loader_addr; // loader sram addr stm32_addr_t buf_addr; // buffer sram address + uint32_t rcc_dma_bkp; // backup RCC DMA enable state } flash_loader_t; typedef struct _cortex_m3_cpuid_ { @@ -297,7 +298,7 @@ int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl); int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t* base, uint32_t len); -int stlink_flashloader_stop(stlink_t *sl); +int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl); #include #include diff --git a/src/common.c b/src/common.c index 26a3b3859..60d7ff145 100644 --- a/src/common.c +++ b/src/common.c @@ -381,6 +381,27 @@ #define STM32WB_DBGMCU_APB1FZR1_WWDG_STOP 11 #define STM32WB_DBGMCU_APB1FZR1_IWDG_STOP 12 +#define STM32F1_RCC_AHBENR 0x40021014 +#define STM32F1_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN + +#define STM32F4_RCC_AHB1ENR 0x40023830 +#define STM32F4_RCC_DMAEN 0x00600000 // DMA2EN | DMA1EN + +#define STM32G0_RCC_AHBENR 0x40021038 +#define STM32G0_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN + +#define STM32G4_RCC_AHB1ENR 0x40021048 +#define STM32G4_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN + +#define STM32L0_RCC_AHBENR 0x40021030 +#define STM32L0_RCC_DMAEN 0x00000001 // DMAEN + +#define STM32H7_RCC_AHB1ENR 0x58024538 +#define STM32H7_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN + +#define STM32WB_RCC_AHB1ENR 0x58000048 +#define STM32WB_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN + #define L1_WRITE_BLOCK_SIZE 0x80 #define L0_WRITE_BLOCK_SIZE 0x40 @@ -1284,6 +1305,58 @@ static void stop_wdg_in_debug(stlink_t *sl) { } } +static void set_dma_state(stlink_t *sl, flash_loader_t* fl, int bckpRstr) { + uint32_t rcc, rcc_dma_mask, value; + + rcc = rcc_dma_mask = value = 0; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + rcc = STM32F1_RCC_AHBENR; + rcc_dma_mask = STM32F1_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_F4: + case STLINK_FLASH_TYPE_F7: + rcc = STM32F4_RCC_AHB1ENR; + rcc_dma_mask = STM32F4_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_G0: + rcc = STM32G0_RCC_AHBENR; + rcc_dma_mask = STM32G0_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_G4: + case STLINK_FLASH_TYPE_L4: + rcc = STM32G4_RCC_AHB1ENR; + rcc_dma_mask = STM32G4_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_L0: + rcc = STM32L0_RCC_AHBENR; + rcc_dma_mask = STM32L0_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_H7: + rcc = STM32H7_RCC_AHB1ENR; + rcc_dma_mask = STM32H7_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_WB: + rcc = STM32WB_RCC_AHB1ENR; + rcc_dma_mask = STM32WB_RCC_DMAEN; + break; + default: + return; + } + + if (!stlink_read_debug32(sl, rcc, &value)) { + if (bckpRstr) { + value = (value&(~rcc_dma_mask)) | fl->rcc_dma_bkp; + } else { + fl->rcc_dma_bkp = value&rcc_dma_mask; + value &= ~rcc_dma_mask; + } + stlink_write_debug32(sl, rcc, value); + } +} + static inline void write_flash_ar(stlink_t *sl, uint32_t n, unsigned bank) { stlink_write_debug32(sl, (bank==BANK_1)?FLASH_AR:FLASH_AR2, n); } @@ -2913,6 +2986,9 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { STLINK_REG_DHCSR_C_HALT | STLINK_REG_DHCSR_C_MASKINTS); + // disable DMA + set_dma_state(sl, fl, 0); + // wait for ongoing op to finish wait_flash_busy(sl); // Clear errors @@ -3184,7 +3260,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr return check_flash_error(sl); } -int stlink_flashloader_stop(stlink_t *sl) { +int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { uint32_t dhcsr; if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || @@ -3224,6 +3300,9 @@ int stlink_flashloader_stop(stlink_t *sl) { (dhcsr&(~STLINK_REG_DHCSR_C_MASKINTS))); } + // restore DMA state + set_dma_state(sl, fl, 1); + return(0); } @@ -3286,7 +3365,7 @@ int stlink_write_flash( ret = stlink_flashloader_write(sl, &fl, addr, base, len); if (ret) return ret; - ret = stlink_flashloader_stop(sl); + ret = stlink_flashloader_stop(sl, &fl); if (ret) return ret; diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 5a226d57b..e870e116c 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -112,19 +112,6 @@ int main(int ac, char** av) { } } - // disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 - if (sl->chip_id == STLINK_CHIPID_STM32_F4) { - memset(sl->q_buf, 0, 4); - - for (int i = 0; i < 8; i++) { - stlink_write_mem32(sl, 0x40026000 + 0x10 + 0x18 * i, 4); - stlink_write_mem32(sl, 0x40026400 + 0x10 + 0x18 * i, 4); - stlink_write_mem32(sl, 0x40026000 + 0x24 + 0x18 * i, 4); - stlink_write_mem32(sl, 0x40026400 + 0x24 + 0x18 * i, 4); - - } - } - // core must be halted to use RAM based flashloaders if (stlink_force_debug(sl)) { printf("Failed to halt the core\n"); diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 3dc3073e5..8d63d9ee0 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -908,7 +908,7 @@ static int flash_go(stlink_t *sl) { } } - stlink_flashloader_stop(sl); + stlink_flashloader_stop(sl, &fl); stlink_soft_reset(sl, 1 /* halt on reset */); error = 0; diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index ed38fcc7c..d264cf9a5 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -514,18 +514,6 @@ static void connect_button_cb(GtkWidget *widget, gpointer data) { stlink_enter_swd_mode(gui->sl); } - // disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 - if (gui->sl->chip_id == STLINK_CHIPID_STM32_F4) { - memset(gui->sl->q_buf, 0, 4); - - for (i = 0; i < 8; i++) { - stlink_write_mem32(gui->sl, 0x40026000 + 0x10 + 0x18 * i, 4); - stlink_write_mem32(gui->sl, 0x40026400 + 0x10 + 0x18 * i, 4); - stlink_write_mem32(gui->sl, 0x40026000 + 0x24 + 0x18 * i, 4); - stlink_write_mem32(gui->sl, 0x40026400 + 0x24 + 0x18 * i, 4); - } - } - stlink_gui_set_connected(gui); } From c793ca348fab43711cc3d24e8b9956ba90ca03d3 Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 29 Mar 2021 22:19:48 +0500 Subject: [PATCH 47/65] Fixed GUI compilation --- src/stlink-gui/gui.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/stlink-gui/gui.c b/src/stlink-gui/gui.c index d264cf9a5..03e999b7f 100644 --- a/src/stlink-gui/gui.c +++ b/src/stlink-gui/gui.c @@ -489,7 +489,6 @@ static void stlink_gui_set_connected(STlinkGUI *gui) { static void connect_button_cb(GtkWidget *widget, gpointer data) { STlinkGUI *gui; - gint i; (void)widget; gui = STLINK_GUI(data); From 4334ce48b2c03497a6d415f8982fdb986409398c Mon Sep 17 00:00:00 2001 From: anton Date: Sun, 4 Apr 2021 11:45:21 +0500 Subject: [PATCH 48/65] flash_loader: added reset of IWDG If IWDG is enabled by hardware, then IWDG cannot be disabled by software --- inc/stlink.h | 1 + src/stlink-lib/flash_loader.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/inc/stlink.h b/inc/stlink.h index 61b8472f1..855e5126d 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -138,6 +138,7 @@ typedef struct flash_loader { stm32_addr_t loader_addr; // loader sram addr stm32_addr_t buf_addr; // buffer sram address uint32_t rcc_dma_bkp; // backup RCC DMA enable state + uint32_t iwdg_kr; // IWDG key register address } flash_loader_t; typedef struct _cortex_m3_cpuid_ { diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index e3b1a12ea..80262cf07 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -9,6 +9,11 @@ #define FLASH_REGS_BANK2_OFS 0x40 #define FLASH_BANK2_START_ADDR 0x08080000 +#define STM32F0_WDG_KR 0x40003000 +#define STM32H7_WDG_KR 0x58004800 + +#define STM32F0_WDG_KR_KEY_RELOAD 0xAAAA + /* DO NOT MODIFY SOURCECODE DIRECTLY, EDIT ASSEMBLY FILES INSTEAD */ /* flashloaders/stm32f0.s -- compiled with thumb2 */ @@ -164,6 +169,13 @@ int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { fl->buf_addr = fl->loader_addr + (uint32_t)size; ILOG("Successfully loaded flash loader in sram\n"); + // set address of IWDG key register for reset it + if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + fl->iwdg_kr = STM32H7_WDG_KR; + } else { + fl->iwdg_kr = STM32F0_WDG_KR; + } + /* Clear Fault Status Register for handling flash loader error */ if (!stlink_read_debug32(sl, STLINK_REG_DFSR, &dfsr) && dfsr) { ILOG("Clear DFSR\n"); @@ -329,6 +341,11 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe // only used on VL/F1_XL, but harmless for others stlink_write_reg(sl, fl->loader_addr, 15); // pc register + /* Reset IWDG */ + if (fl->iwdg_kr) { + stlink_write_debug32(sl, fl->iwdg_kr, STM32F0_WDG_KR_KEY_RELOAD); + } + /* Run loader */ stlink_run(sl); From a3b1247d141592bd87fdb1f0aeec879e1b061eef Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 4 Apr 2021 23:40:10 +0200 Subject: [PATCH 49/65] General Project Update - Updated CHANGELOG.md - Added STLINK-V3E to supported programmers --- CHANGELOG.md | 22 ++++++++++++++-------- README.md | 2 +- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee46901e7..57426342a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,14 @@ -# stlink ChangeLog +# stlink Changelog # v1.6.2 -Release date: (planned Q2/2021) +Release date: 2020-04-xx + +This release drops support for the STLINK/V1 programmer on macOS 10.13. Features: -- Extended support for STM32H7 & rework of software reset ([#532](https://github.com/stlink-org/stlink/pull/532), [#1059](https://github.com/stlink-org/stlink/pull/1059), [#1063](https://github.com/stlink-org/stlink/pull/1063), [#1071](https://github.com/stlink-org/stlink/pull/1071)) +- Extended support for STM32H7 & rework of software reset ([#532](https://github.com/stlink-org/stlink/pull/532), [#868](https://github.com/stlink-org/stlink/pull/868), [#1059](https://github.com/stlink-org/stlink/pull/1059), [#1063](https://github.com/stlink-org/stlink/pull/1063), [#1071](https://github.com/stlink-org/stlink/pull/1071)) - Added support for STM32H742/743/753 ([#671](https://github.com/stlink-org/stlink/pull/671), [#793](https://github.com/stlink-org/stlink/pull/793), [#823](https://github.com/stlink-org/stlink/pull/823), [#998](https://github.com/stlink-org/stlink/pull/998), [#1052](https://github.com/stlink-org/stlink/pull/1052)) - Official support for STLINK-V3 programmers (commit [#5e0a502](https://github.com/stlink-org/stlink/commit/5e0a502df812495bfa96fa9116a19f1306152b17), [#820](https://github.com/stlink-org/stlink/pull/820), [#1022](https://github.com/stlink-org/stlink/pull/1022), [#1025](https://github.com/stlink-org/stlink/pull/1025)) - Added preliminary support for STM32L5x2 ([#904](https://github.com/stlink-org/stlink/pull/904), [#999](https://github.com/stlink-org/stlink/pull/999)) @@ -18,6 +20,7 @@ Features: - Link for WIN32 & APPLE with stlink-static ([#1069](https://github.com/stlink-org/stlink/pull/1069)) - ITM functionality for STLink/V2 and STM32Fxx chipsets ([#136](https://github.com/stlink-org/stlink/pull/136), [#179](https://github.com/stlink-org/stlink/pull/179), [#815](https://github.com/stlink-org/stlink/pull/815), [#1072](https://github.com/stlink-org/stlink/pull/1072)) - Included ITM functionality for building with MSVC ([#1080](https://github.com/stlink-org/stlink/pull/1080)) +- Update for CI integration (commit [#0eebc9a](https://github.com/stlink-org/stlink/commit/0eebc9a74506e84d5c460ec325ae98064a81885e), [#1118](https://github.com/stlink-org/stlink/pull/1118)) Updates & changes: @@ -32,10 +35,11 @@ Updates & changes: - [doc] Added example for output of `st-info --probe` ([#1007](https://github.com/stlink-org/stlink/pull/1007), [#1049](https://github.com/stlink-org/stlink/pull/1049)) - [refactoring] Correctly handle endianness without reference to host platform ([#1081](https://github.com/stlink-org/stlink/pull/1081)) - Check format string for log messages ([#1093](https://github.com/stlink-org/stlink/pull/1093)) +- Removed abort() from stlink-lib ([#1116](https://github.com/stlink-org/stlink/pull/1116)) Fixes: -- Flash loader rework ([#356](https://github.com/stlink-org/stlink/pull/356), [#556](https://github.com/stlink-org/stlink/pull/556), [#593](https://github.com/stlink-org/stlink/pull/593), [#597](https://github.com/stlink-org/stlink/pull/597), [#607](https://github.com/stlink-org/stlink/pull/607), [#612](https://github.com/stlink-org/stlink/pull/612), [#638](https://github.com/stlink-org/stlink/pull/638), [#661](https://github.com/stlink-org/stlink/pull/661), [#690](https://github.com/stlink-org/stlink/pull/690), [#818](https://github.com/stlink-org/stlink/pull/818), [#854](https://github.com/stlink-org/stlink/pull/854), [#967](https://github.com/stlink-org/stlink/pull/967), [#979](https://github.com/stlink-org/stlink/pull/979), [#1043](https://github.com/stlink-org/stlink/pull/1043), [#1054](https://github.com/stlink-org/stlink/pull/1054), [#1092](https://github.com/stlink-org/stlink/pull/1092), [#1105](https://github.com/stlink-org/stlink/pull/1105), [#1113](https://github.com/stlink-org/stlink/pull/1113)) +- Flash loader rework ([#356](https://github.com/stlink-org/stlink/pull/356), [#556](https://github.com/stlink-org/stlink/pull/556), [#593](https://github.com/stlink-org/stlink/pull/593), [#597](https://github.com/stlink-org/stlink/pull/597), [#607](https://github.com/stlink-org/stlink/pull/607), [#612](https://github.com/stlink-org/stlink/pull/612), [#638](https://github.com/stlink-org/stlink/pull/638), [#661](https://github.com/stlink-org/stlink/pull/661), [#690](https://github.com/stlink-org/stlink/pull/690), [#818](https://github.com/stlink-org/stlink/pull/818), [#854](https://github.com/stlink-org/stlink/pull/854), [#868](https://github.com/stlink-org/stlink/pull/868), [#967](https://github.com/stlink-org/stlink/pull/967), [#979](https://github.com/stlink-org/stlink/pull/979), [#1043](https://github.com/stlink-org/stlink/pull/1043), [#1054](https://github.com/stlink-org/stlink/pull/1054), [#1092](https://github.com/stlink-org/stlink/pull/1092), [#1105](https://github.com/stlink-org/stlink/pull/1105), [#1113](https://github.com/stlink-org/stlink/pull/1113)) - Fixed old DFU serial number for STLINK programmers ([#417](https://github.com/stlink-org/stlink/pull/417), [#494](https://github.com/stlink-org/stlink/pull/494), [#1106](https://github.com/stlink-org/stlink/pull/1106)) - Use vl flashloader for all STM32F1 series ([#769](https://github.com/stlink-org/stlink/pull/769), [#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) - [regression] Changed timeout on flash write ([#787](https://github.com/stlink-org/stlink/pull/787), [#981](https://github.com/stlink-org/stlink/pull/981), [#987](https://github.com/stlink-org/stlink/pull/987)) @@ -60,6 +64,8 @@ Fixes: - Fixed support for writing option bytes ([#1102](https://github.com/stlink-org/stlink/pull/1102)) - [doc] Corrected spelling mistake in bug report template ([#1103](https://github.com/stlink-org/stlink/pull/1103)) - Fixed STM32WB55 reading DEBUG IDCODE from the wrong address ([#1100](https://github.com/stlink-org/stlink/pull/1100), [#1101](https://github.com/stlink-org/stlink/pull/1101)) +- Applied missing changes to tests ([#1119](https://github.com/stlink-org/stlink/pull/1119)) +- Improvements for Chip_ID read ([#1120](https://github.com/stlink-org/stlink/pull/1120)) # v1.6.1 @@ -216,7 +222,7 @@ Release date: 2018-09-13 Major changes and added features: -- Added reset through `AIRCR` ([#540](https://github.com/stlink-org/stlink/pull/540), [#712](https://github.com/stlink-org/stlink/pull/712)) +- Added reset through `AIRCR` ([#254](https://github.com/stlink-org/stlink/pull/254), [#540](https://github.com/stlink-org/stlink/pull/540), [#712](https://github.com/stlink-org/stlink/pull/712)) - Added creation of icons for `.desktop` file ([#684](https://github.com/stlink-org/stlink/pull/684), [#708](https://github.com/stlink-org/stlink/pull/708)) - Added desktop file for linux ([#688](https://github.com/stlink-org/stlink/pull/688)) - Added button to export STM32 flash memory to a file ([#691](https://github.com/stlink-org/stlink/pull/691)) @@ -279,7 +285,6 @@ Major changes and added features: Updates and fixes: -- Fixed gdb-server: STM32L0xx has no `FP_CTRL` register for breakpoints ([#273](https://github.com/stlink-org/stlink/pull/273)) - Added `--flash=n[k][m]` command line option to override device model ([#305](https://github.com/stlink-org/stlink/pull/305), [#516](https://github.com/stlink-org/stlink/pull/516), [#576](https://github.com/stlink-org/stlink/pull/576)) - Updated `libusb` to 1.0.21 for Windows ([#562](https://github.com/stlink-org/stlink/pull/562)) - Fixed low-voltage flashing on STM32F7 devices ([#566](https://github.com/stlink-org/stlink/pull/566), [#567](https://github.com/stlink-org/stlink/pull/567)) @@ -324,11 +329,11 @@ Major changes and added features: - Added manpages (generated with `pandoc` from Markdown) ([#208](https://github.com/stlink-org/stlink/pull/208), [#464](https://github.com/stlink-org/stlink/pull/464), [#466](https://github.com/stlink-org/stlink/pull/466), [#467](https://github.com/stlink-org/stlink/pull/467)) - Removal of undocumented `st-term` utility, which is now replaced by `st-util` ARM semihosting feature ([#228](https://github.com/stlink-org/stlink/pull/228), [#507](https://github.com/stlink-org/stlink/pull/507), commit [#3fd0f09](https://github.com/stlink-org/stlink/commit/3fd0f099782506532198473b24f643a3f68d5ff9)) - Support serial numbers argument for `st-util` and `st-flash` to probe and control multiple connected programmers ([#318](https://github.com/stlink-org/stlink/pull/318), [#398](https://github.com/stlink-org/stlink/pull/398), [#541](https://github.com/stlink-org/stlink/pull/541)) +- Added 'k' (kill) command to gdb-server, which resets the connection ([#358](https://github.com/stlink-org/stlink/pull/358), [#525](https://github.com/stlink-org/stlink/pull/525), [#527](https://github.com/stlink-org/stlink/pull/527), [#528](https://github.com/stlink-org/stlink/pull/528)) - Merge `st-probe` tool into `st-info` ([#398](https://github.com/stlink-org/stlink/pull/398)) - Added support for native debian packaging ([#444](https://github.com/stlink-org/stlink/pull/444), [#472](https://github.com/stlink-org/stlink/pull/472), [#473](https://github.com/stlink-org/stlink/pull/473), [#482](https://github.com/stlink-org/stlink/pull/482), [#483](https://github.com/stlink-org/stlink/pull/483), [#484](https://github.com/stlink-org/stlink/pull/484), [#485](https://github.com/stlink-org/stlink/pull/485)) - Rewritten commandline parsing for `st-flash` ([#459](https://github.com/stlink-org/stlink/pull/459)) - Added `--reset` command to `st-flash` ([#505](https://github.com/stlink-org/stlink/pull/505)) -- st-util should detect when USB commands fail ([#525](https://github.com/stlink-org/stlink/pull/525), [#527](https://github.com/stlink-org/stlink/pull/527), [#528](https://github.com/stlink-org/stlink/pull/528)) Chip support added for: @@ -344,12 +349,12 @@ Chip support added for: Updates and fixes: +- Do a JTAG reset prior to reading CPU information when processor is in deep sleep ([#291](https://github.com/stlink-org/stlink/pull/291), [#428](https://github.com/stlink-org/stlink/pull/428), [#430](https://github.com/stlink-org/stlink/pull/430), [#451](https://github.com/stlink-org/stlink/pull/451)) - Fixed `unaligned addr or size` when trying to write a program in RAM ([#323](https://github.com/stlink-org/stlink/pull/323)) - Fixed flashing on `STM32_F3_SMALL` ([#325](https://github.com/stlink-org/stlink/pull/325)) - Fixed STM32L-problem with flash loader ([#390](https://github.com/stlink-org/stlink/pull/390), [#407](https://github.com/stlink-org/stlink/pull/407), [#408](https://github.com/stlink-org/stlink/pull/408)) - Don't read the target voltage on startup, because it crashes STM32F100 ([#423](https://github.com/stlink-org/stlink/pull/423), [#424](https://github.com/stlink-org/stlink/pull/424)) - Added a useful error message instead of `[!] send_recv` ([#425](https://github.com/stlink-org/stlink/pull/425), [#426](https://github.com/stlink-org/stlink/pull/426)) -- Do a JTAG reset prior to reading CPU information when processor is in deep sleep ([#428](https://github.com/stlink-org/stlink/pull/428), [#430](https://github.com/stlink-org/stlink/pull/430), [#451](https://github.com/stlink-org/stlink/pull/451)) - Fixed STM32F030 erase error ([#442](https://github.com/stlink-org/stlink/pull/442)) - Fixed memory map for STM32F7xx ([#453](https://github.com/stlink-org/stlink/pull/453), [#456](https://github.com/stlink-org/stlink/pull/456)) - Redesign of `st-flash` commandline options parsing ([#459](https://github.com/stlink-org/stlink/pull/459)) @@ -392,6 +397,7 @@ Updates and fixes: - Modified determination of erased byte pattern when flashing ([#193](https://github.com/stlink-org/stlink/pull/193), [#377](https://github.com/stlink-org/stlink/pull/377)) - Use libusb synchronous api ([#194](https://github.com/stlink-org/stlink/pull/194), [#225](https://github.com/stlink-org/stlink/pull/225), [#374](https://github.com/stlink-org/stlink/pull/374)) - Fixed segfault when programmer is already busy and `NULL` pointers are in the list ([#256](https://github.com/stlink-org/stlink/pull/256), [#394](https://github.com/stlink-org/stlink/pull/394)) +- Fixed gdb-server: Cortex M0 chips have no `FP_CTRL` register for breakpoints ([#266](https://github.com/stlink-org/stlink/pull/266), [#273](https://github.com/stlink-org/stlink/pull/273), [#341](https://github.com/stlink-org/stlink/pull/341)) - Fixed issue where "unknown chip id!" was seen every other time ([#352](https://github.com/stlink-org/stlink/pull/352), [#367](https://github.com/stlink-org/stlink/pull/367), [#381](https://github.com/stlink-org/stlink/pull/381)) - Send F4 memory-map and features for STM32F429 ([#188](https://github.com/stlink-org/stlink/pull/188), [#196](https://github.com/stlink-org/stlink/pull/196), [#250](https://github.com/stlink-org/stlink/pull/250), [#251](https://github.com/stlink-org/stlink/pull/251)) (Release v1.1.0) - Added AHB3 Peripherals definition for STM32F4 ([#218](https://github.com/stlink-org/stlink/pull/218), [#288](https://github.com/stlink-org/stlink/pull/288)) (Release v1.1.0) diff --git a/README.md b/README.md index 644c3fd86..93994db49 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ It supports several so called STLINK programmer boards (and clones thereof) whic - **STLINK-V3** - transport layer: raw USB commands - stand-alone programmer (STLINK-V3SET, STLINK-V3MINI, STLINK-V3MODS) - - on-board on some STM32 Nucleo boards + - on-board on some STM32 Nucleo boards (STLINK-V3E) _\*)_ **Note: Support for the STLINK/V1 on macOS is limited to 10.14 - 10.15. Due to the deprecation and removal of macOS Kernel Extensions (KEXT) there will be no support for this programmer on macOS 11 or any later version.** From 9a8e0aa6457640e27a0dbee5d994c3f8249fddf6 Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 5 Apr 2021 21:15:18 +0500 Subject: [PATCH 50/65] Added the hot plug option to st-flash --- doc/tutorial.md | 2 +- src/st-flash/flash.c | 4 ++-- src/st-flash/flash_opts.c | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 37c29ab6a..256513bc4 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -9,7 +9,7 @@ | --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at the end of binary file.
This may cause some garbage data left after a flash operation. This option was enabled by default in earlier releases. | v1.6.1 | | --reset | st-flash | Trigger a reset both before and after flashing. The default uses the hardware reset through `NRST` pin.
A software reset (via `AIRCR`; since v1.5.1) is used, if the hardware reset failed (`NRST` pin not connected). | v1.0.0 | | --connect-under-reset | st-info
st-flash | Connect under reset. Option makes it possible to connect to the device before code execution. This is useful
when the target contains code that lets the device go to sleep, disables debug pins or other special code. | v1.6.1 | -| --hot-plug | st-info
st-util | Connect to the target without reset. | v1.6.2 | +| --hot-plug | st-info
st-flash
st-util | Connect to the target without reset. | v1.6.2 | | --probe | st-info | Display hardware information about the connected programmer and target MCU. | v1.2.0 | | --version | st-info
st-flash
st-util | Print version information. | v1.3.0 | | --help | st-flash
st-util | Print list of available commands. | | diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index e870e116c..356515ac4 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -26,8 +26,8 @@ static void cleanup(int signum) { } static void usage(void) { - puts("command line: ./st-flash [--debug] [--reset] [--connect-under-reset] [--opt] [--serial ] [--format ] [--flash=] [--freq=] [--area=] {read|write} [path] [addr] [size]"); - puts("command line: ./st-flash [--debug] [--connect-under-reset] [--freq=] [--serial ] erase"); + puts("command line: ./st-flash [--debug] [--reset] [--connect-under-reset] [--hot-plug] [--opt] [--serial ] [--format ] [--flash=] [--freq=] [--area=] {read|write} [path] [addr] [size]"); + puts("command line: ./st-flash [--debug] [--connect-under-reset] [--hot-plug] [--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)"); diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index 63774ea25..172a24468 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -193,6 +193,8 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { } } else if (strcmp(av[0], "--connect-under-reset") == 0) { o->connect = CONNECT_UNDER_RESET; + } else if (strcmp(av[0], "--hot-plug") == 0) { + o->connect = CONNECT_HOT_PLUG; } else { break; // non-option found From 696ea923ce7517a604d43adfe017c1cdda3b7339 Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 5 Apr 2021 21:23:16 +0500 Subject: [PATCH 51/65] Changed the behavior of the st-flash reset option. The reset option conflicted with the connection type options (connect under reset, hot plug). Now reset of target is performed only after the completion of the firmware if the reset options is used. --- src/st-flash/flash.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 356515ac4..edb54e195 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -98,20 +98,6 @@ int main(int ac, char** av) { } } - if (o.reset) { - if (sl->version.stlink_v > 1) { - if (stlink_jtag_reset(sl, 2)) { - printf("Failed to reset JTAG\n"); - goto on_error; - } - } - - if (stlink_reset(sl)) { - printf("Failed to reset device\n"); - goto on_error; - } - } - // core must be halted to use RAM based flashloaders if (stlink_force_debug(sl)) { printf("Failed to halt the core\n"); From d3bc853209a6785a1f87a2359839e80c15735563 Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 5 Apr 2021 21:53:57 +0500 Subject: [PATCH 52/65] Update tutorial --- doc/tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 256513bc4..21f1498ee 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -7,7 +7,7 @@ | --flash=n[k][m] | st-flash | One can specify `--flash=128k` for example, to override the default value of 64k for the STM32F103C8T6
to assume 128k of flash being present. This option accepts decimal (128k), octal 0200k, or hex 0x80k values.
Leaving the multiplier out is equally valid, e.g.: `--flash=0x20000`. The size may be followed by an optional
"k" or "m" to multiply the given value by 1k (1024) or 1M respectively. | v1.4.0 | | --freq=n[k][m] | st-info
st-flash
st-util | The frequency of the SWD/JTAG interface can be specified, to override the default 1800 kHz configuration.
This option solely accepts decimal values (5K or 1.8M) with the unit `Hz` being left out. Valid frequencies are:
`5K, 15K, 25K, 50K, 100K, 125K, 240K, 480K, 950K, 1200K, 1800K, 4000K(4M)`. | v1.6.1 | | --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at the end of binary file.
This may cause some garbage data left after a flash operation. This option was enabled by default in earlier releases. | v1.6.1 | -| --reset | st-flash | Trigger a reset both before and after flashing. The default uses the hardware reset through `NRST` pin.
A software reset (via `AIRCR`; since v1.5.1) is used, if the hardware reset failed (`NRST` pin not connected). | v1.0.0 | +| --reset | st-flash | Trigger a reset after flashing. The default uses the hardware reset through `NRST` pin.
A software reset (via `AIRCR`; since v1.5.1) is used, if the hardware reset failed (`NRST` pin not connected). | v1.0.0 | | --connect-under-reset | st-info
st-flash | Connect under reset. Option makes it possible to connect to the device before code execution. This is useful
when the target contains code that lets the device go to sleep, disables debug pins or other special code. | v1.6.1 | | --hot-plug | st-info
st-flash
st-util | Connect to the target without reset. | v1.6.2 | | --probe | st-info | Display hardware information about the connected programmer and target MCU. | v1.2.0 | From 4fc6344d44681a0add3bdce69ecf2d0e4e70db49 Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 5 Apr 2021 22:13:17 +0500 Subject: [PATCH 53/65] flash_loader: fixed alignment of size of the lx loader --- src/stlink-lib/flash_loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 80262cf07..cd7096490 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -68,7 +68,7 @@ static const uint8_t loader_code_stm32lx[] = { 0x00, 0xf1, 0x04, 0x00, 0x01, 0xf1, 0x04, 0x01, 0x04, 0x3a, 0xf7, 0xdc, - 0x00, 0xbe + 0x00, 0xbe, 0x00, 0x00 }; static const uint8_t loader_code_stm32f4[] = { From 5ce54824a5ca819a7ff630b880268febb07ff3e3 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Mon, 5 Apr 2021 21:55:54 +0200 Subject: [PATCH 54/65] Updated CI & MinGW64 cross build configuration - Moved config for macOS 10.14 to GitHub Actions (Note: preparation only, yet inactive) - Removed macOS 10.14 builds from Travis CI - Removed Linux build config from Travis CI - Split 32- & 64-bit cross builds to separate jobs - Minor fixes for MinGW64 cross build config --- .github/workflows/c-cpp.yml | 90 ++++++++++++++++++++ .travis.sh | 22 ++--- .travis.yml | 79 ++--------------- cmake/modules/Findlibusb.cmake | 18 ++-- cmake/modules/c_flags.cmake | 2 +- cmake/packaging/windows/generate_binaries.sh | 18 ++-- 6 files changed, 123 insertions(+), 106 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 4769450ae..97f48d88d 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -282,6 +282,96 @@ jobs: # macOS + # job_macos_10_14_64_gcc: + # name: macos-10.14 gcc + # runs-on: macos-10.14 + # steps: + # - uses: actions/checkout@v2 + # - name: Install dependencies + # run: brew install gcc libusb gtk+3 + # - name: make debug + # run: sudo make clean && make debug + # - name: make test + # run: sudo make clean && make test + # - name: make release + # run: sudo make clean && make release + # - name: sudo make install + # run: sudo make clean && sudo make install + # - name: sudo make package + # run: sudo make package + # - name: sudo make uninstall + # run: sudo make uninstall && sudo make clean + + # job_macos_10_14_32_gcc: + # name: macos-10.14 gcc 32-bit + # runs-on: macos-10.14 + # steps: + # - uses: actions/checkout@v2 + # - name: Install dependencies + # run: brew install gcc libusb gtk+3 + # - name: Set compiler flags + # run: | + # CFLAGS="$CFLAGS -m32" + # CXXFLAGS="$CXXFLAGS -m32" + # LDFLAGS="$LDFLAGS -m32" + # - name: make debug + # run: sudo make clean && make debug + # - name: make test + # run: sudo make clean && make test + # - name: make release + # run: sudo make clean && make release + # - name: sudo make install + # run: sudo make clean && sudo make install + # - name: sudo make package + # run: sudo make package + # - name: sudo make uninstall + # run: sudo make uninstall && sudo make clean + + # job_macos_10_14_64_clang: + # name: macos-10.14 clang + # runs-on: macos-10.14 + # steps: + # - uses: actions/checkout@v2 + # - name: Install dependencies + # run: brew install llvm libusb gtk+3 + # - name: make debug + # run: sudo make clean && make debug + # - name: make test + # run: sudo make clean && make test + # - name: make release + # run: sudo make clean && make release + # - name: sudo make install + # run: sudo make clean && sudo make install + # - name: sudo make package + # run: sudo make package + # - name: sudo make uninstall + # run: sudo make uninstall && sudo make clean + + # job_macos_10_14_32_clang: + # name: macos-10.14 clang 32-bit + # runs-on: macos-10.14 + # steps: + # - uses: actions/checkout@v2 + # - name: Install dependencies + # run: brew install llvm libusb gtk+3 + # - name: Set compiler flags + # run: | + # CFLAGS="$CFLAGS -m32" + # CXXFLAGS="$CXXFLAGS -m32" + # LDFLAGS="$LDFLAGS -m32" + # - name: make debug + # run: sudo make clean && make debug + # - name: make test + # run: sudo make clean && make test + # - name: make release + # run: sudo make clean && make release + # - name: sudo make install + # run: sudo make clean && sudo make install + # - name: sudo make package + # run: sudo make package + # - name: sudo make uninstall + # run: sudo make uninstall && sudo make clean + job_macos_10_15_gcc: name: macos-10.15 gcc runs-on: macos-10.15 diff --git a/.travis.sh b/.travis.sh index de2a42372..e45cd3609 100755 --- a/.travis.sh +++ b/.travis.sh @@ -8,18 +8,19 @@ echo "----" echo "WORK DIR:$DIR" DIR=$PWD -if [ "$TRAVIS_JOB_NAME" == "linux-mingw" ]; then +if [ "$TRAVIS_JOB_NAME" == "linux-mingw-64" ]; then echo "--> Building for Windows (x86-64) ..." - mkdir -p build-mingw && cd build-mingw + mkdir -p build-mingw && cd build-mingw-64 cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR - make && rm -rf build-mingw && cd - + make && rm -rf build-mingw-64 && cd - +elif [ "$TRAVIS_JOB_NAME" == "linux-mingw-32" ]; then echo "--> Building for Windows (i686) ..." - mkdir -p build-mingw && cd build-mingw + mkdir -p build-mingw && cd build-mingw-32 cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR - make && rm -rf build-mingw && cd - + make && rm -rf build-mingw-32 && cd - elif [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq || true @@ -34,17 +35,6 @@ elif [ "$TRAVIS_OS_NAME" == "linux" ]; then cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make package && cd - -elif [ "$TRAVIS_OS_NAME" == "osx" ]; then - echo "--> Building Debug..." - mkdir -p build/Debug && cd build/Debug - cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR - make && cd - - - echo "--> Building Release with package..." - mkdir -p build/Release && cd build/Release - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR - make package && cd - - else # local test-build echo "--> Building Debug..." mkdir -p build/Debug && cd build/Debug diff --git a/.travis.yml b/.travis.yml index 2a788fd69..a733019a1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,32 +2,22 @@ language: c jobs: include: - ### 64-bit build on AMD64 ### - - os: linux - dist: focal - env: BADGE=linux - compiler: gcc-10 - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] + ### cross builds on AMD64 ### - ### 32-bit build on AMD64 ### - os: linux dist: focal - env: BADGE=linux + env: BADGE=linux-mingw-64 + name: linux-mingw compiler: gcc-10 addons: apt: sources: ["ubuntu-toolchain-r-test"] - packages: ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm"] - before_install: - - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; + packages: + ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] - ### cross build on AMD64 ### - os: linux dist: focal - env: BADGE=linux-mingw + env: BADGE=linux-mingw-32 name: linux-mingw compiler: gcc-10 addons: @@ -35,64 +25,9 @@ jobs: sources: ["ubuntu-toolchain-r-test"] packages: ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] - before_install: - - LDFLAGS="$LDFLAGS -NDEBUG"; - - ### macOS ### - # - os: osx - # env: BADGE=osx - # osx_image: xcode11.3 - # name: macOS 10.14.6 gcc - # compiler: gcc - # addons: - # homebrew: - # packages: - # - gcc - # - libusb - # - gtk+3 - - # - os: osx - # env: BADGE=osx - # osx_image: xcode11.3 - # name: macOS 10.14.6 gcc 32-bit - # compiler: gcc - # addons: - # homebrew: - # packages: - # - gcc - # - libusb - # - gtk+3 - # before_install: - # - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; - - # - os: osx - # env: BADGE=osx - # osx_image: xcode11.3 - # name: macOS 10.14.6 clang - # compiler: clang - # addons: - # homebrew: - # packages: - # - llvm - # - libusb - # - gtk+3 - - # - os: osx - # env: BADGE=osx - # osx_image: xcode11.3 - # name: macOS 10.14.6 clang 32-bit - # compiler: clang - # addons: - # homebrew: - # packages: - # - llvm - # - libusb - # - gtk+3 - # before_install: - # - CFLAGS="$CFLAGS -m32"; CXXFLAGS="$CXXFLAGS -m32"; LDFLAGS="$LDFLAGS -m32"; script: - git fetch --tags - printenv - cmake --version - - if [[ "$TRAVIS_OS_NAME" == "linux" ]] || [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./.travis.sh; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./.travis.sh; fi diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index 3082a9509..257c682ce 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -10,7 +10,7 @@ include(FindPackageHandleStandardArgs) -if (APPLE) # macOS +if (APPLE) # macOS FIND_PATH( LIBUSB_INCLUDE_DIR NAMES libusb.h HINTS /usr /usr/local /opt @@ -27,7 +27,7 @@ if (APPLE) message(FATAL_ERROR "No libusb library found on your system! Install libusb-1.0 from Homebrew or MacPorts") endif () -elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD; libusb is integrated into the system +elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FreeBSD; libusb is integrated into the system FIND_PATH( LIBUSB_INCLUDE_DIR NAMES libusb.h HINTS /usr/include @@ -43,13 +43,13 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") message(FATAL_ERROR "Expected libusb library not found on your system! Verify your system integrity.") endif () -elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-toolchain on Debian - # for MinGW/MSYS/MSVC: 64-bit or 32-bit? +elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-toolchain on Debian + # MinGW/MSYS/MSVC: 64-bit or 32-bit? if (CMAKE_SIZEOF_VOID_P EQUAL 8) message(STATUS "=== Building for Windows (x86-64) ===") set(ARCH 64) else () - message(STATUS "=== Building for Windowsm (i686) ===") + message(STATUS "=== Building for Windows (i686) ===") set(ARCH 32) endif () @@ -77,14 +77,14 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) if (NOT LIBUSB_FOUND) # Preparations for installing libusb library - set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version + set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) if (WIN32 AND NOT EXISTS "/etc/debian_version") # ... on native Windows systems set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_BINARY_DIR}/3rdparty/libusb-${LIBUSB_WIN_VERSION}) - else (EXISTS "/etc/debian_version" AND MINGW) # ... only for cross-building on Debian - set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_SOURCE_DIR}/build-mingw/${LIBUSB_WIN_ARCHIVE}) - set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_SOURCE_DIR}/build-mingw/3rdparty/libusb-${LIBUSB_WIN_VERSION}) + else (EXISTS "/etc/debian_version" AND MINGW) # ... only for cross-building on Debian + set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_SOURCE_DIR}/build-mingw-${ARCH}/${LIBUSB_WIN_ARCHIVE}) + set(LIBUSB_WIN_OUTPUT_FOLDER ${CMAKE_SOURCE_DIR}/build-mingw-${ARCH}/3rdparty/libusb-${LIBUSB_WIN_VERSION}) endif () # Get libusb package diff --git a/cmake/modules/c_flags.cmake b/cmake/modules/c_flags.cmake index 8291ea0ee..5ed0c4d7d 100644 --- a/cmake/modules/c_flags.cmake +++ b/cmake/modules/c_flags.cmake @@ -41,7 +41,7 @@ if (NOT CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") add_cflag_if_supported("-Wredundant-decls") endif () -if (NOT WIN32) +if (NOT (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW))) add_cflag_if_supported("-fPIC") endif () diff --git a/cmake/packaging/windows/generate_binaries.sh b/cmake/packaging/windows/generate_binaries.sh index d38f8d62f..bf2453d10 100644 --- a/cmake/packaging/windows/generate_binaries.sh +++ b/cmake/packaging/windows/generate_binaries.sh @@ -6,23 +6,25 @@ #sudo apt-get install mingw-w64 # x86_64 -mkdir build-mingw -cd build-mingw +mkdir build-mingw-64 +cd build-mingw-64 cmake -DCMAKE_SYSTEM_NAME=Windows \ -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ - -DCMAKE_TOOLCHAIN_FILE=./cmake/modules/set_toolchain.cmake .. + -DCMAKE_TOOLCHAIN_FILE=./../cmake/modules/set_toolchain.cmake .. make package cp dist/*.zip ../build/Release/dist +make clean cd .. -rm -rf build-mingw +rm -rf build-mingw-64 # i686 -mkdir build-mingw -cd build-mingw +mkdir build-mingw-32 +cd build-mingw-32 cmake -DCMAKE_SYSTEM_NAME=Windows \ -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ - -DCMAKE_TOOLCHAIN_FILE=./cmake/modules/set_toolchain.cmake .. + -DCMAKE_TOOLCHAIN_FILE=./../cmake/modules/set_toolchain.cmake .. make package cp dist/*.zip ../build/Release/dist +make clean cd .. -rm -rf build-mingw +rm -rf build-mingw-32 From 89a495d169a15f42d8cfd1a68c6738c984d052f8 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Tue, 6 Apr 2021 00:46:44 +0200 Subject: [PATCH 55/65] Updated libusb to v1.0.24 Note: Due to a compilation bug in libusb v1.0.24, building of x86-64 windows binaries is currently not possible and has been deactivated. --- .gitignore | 1 + .travis.sh | 18 +++++++-------- .travis.yml | 24 ++++++++++---------- cmake/modules/Findlibusb.cmake | 6 ++--- cmake/packaging/windows/generate_binaries.sh | 24 ++++++++++---------- 5 files changed, 37 insertions(+), 36 deletions(-) diff --git a/.gitignore b/.gitignore index a07eed9ca..82c1195e4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ build build-mingw +build-mingw-* .project .cmake/ diff --git a/.travis.sh b/.travis.sh index e45cd3609..58cea5746 100755 --- a/.travis.sh +++ b/.travis.sh @@ -8,20 +8,20 @@ echo "----" echo "WORK DIR:$DIR" DIR=$PWD -if [ "$TRAVIS_JOB_NAME" == "linux-mingw-64" ]; then - echo "--> Building for Windows (x86-64) ..." - mkdir -p build-mingw && cd build-mingw-64 - cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ - -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR - make && rm -rf build-mingw-64 && cd - - -elif [ "$TRAVIS_JOB_NAME" == "linux-mingw-32" ]; then +if [ "$TRAVIS_JOB_NAME" == "linux-mingw-32" ]; then echo "--> Building for Windows (i686) ..." - mkdir -p build-mingw && cd build-mingw-32 + mkdir -p build-mingw-32 && cd build-mingw-32 cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make && rm -rf build-mingw-32 && cd - +# elif [ "$TRAVIS_JOB_NAME" == "linux-mingw-64" ]; then +# echo "--> Building for Windows (x86-64) ..." +# mkdir -p build-mingw-64 && cd build-mingw-64 +# cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ +# -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR +# make && rm -rf build-mingw-64 && cd - + elif [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq || true diff --git a/.travis.yml b/.travis.yml index a733019a1..307c0bfa0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,21 +4,10 @@ jobs: include: ### cross builds on AMD64 ### - - os: linux - dist: focal - env: BADGE=linux-mingw-64 - name: linux-mingw - compiler: gcc-10 - addons: - apt: - sources: ["ubuntu-toolchain-r-test"] - packages: - ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] - - os: linux dist: focal env: BADGE=linux-mingw-32 - name: linux-mingw + name: linux-mingw-32 compiler: gcc-10 addons: apt: @@ -26,6 +15,17 @@ jobs: packages: ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] + # - os: linux + # dist: focal + # env: BADGE=linux-mingw-64 + # name: linux-mingw-64 + # compiler: gcc-10 + # addons: + # apt: + # sources: ["ubuntu-toolchain-r-test"] + # packages: + # ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] + script: - git fetch --tags - printenv diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index 257c682ce..99f4d56ec 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -77,7 +77,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to if (NOT LIBUSB_FOUND) # Preparations for installing libusb library - set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version + set(LIBUSB_WIN_VERSION 1.0.24) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) if (WIN32 AND NOT EXISTS "/etc/debian_version") # ... on native Windows systems set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) @@ -94,7 +94,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to message(STATUS "downloading libusb ${LIBUSB_WIN_VERSION}") file(DOWNLOAD https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-${LIBUSB_WIN_VERSION}/libusb-${LIBUSB_WIN_VERSION}.7z/download - ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 cf3d38d2ff053ef343d10c0b8b0950c2 + ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 5c944b1c8aa9d43e026a94302d0f8ac4 ) endif () @@ -128,7 +128,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to set(LIBUSB_NAME libusb-1.0.lib) find_library( LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS${ARCH}/dll + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/**/MS${ARCH}/dll NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH ) diff --git a/cmake/packaging/windows/generate_binaries.sh b/cmake/packaging/windows/generate_binaries.sh index bf2453d10..5616ecb38 100644 --- a/cmake/packaging/windows/generate_binaries.sh +++ b/cmake/packaging/windows/generate_binaries.sh @@ -5,18 +5,6 @@ # Install this cross-compiler toolchain: #sudo apt-get install mingw-w64 -# x86_64 -mkdir build-mingw-64 -cd build-mingw-64 -cmake -DCMAKE_SYSTEM_NAME=Windows \ - -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ - -DCMAKE_TOOLCHAIN_FILE=./../cmake/modules/set_toolchain.cmake .. -make package -cp dist/*.zip ../build/Release/dist -make clean -cd .. -rm -rf build-mingw-64 - # i686 mkdir build-mingw-32 cd build-mingw-32 @@ -28,3 +16,15 @@ cp dist/*.zip ../build/Release/dist make clean cd .. rm -rf build-mingw-32 + +# x86_64 +# mkdir build-mingw-64 +# cd build-mingw-64 +# cmake -DCMAKE_SYSTEM_NAME=Windows \ +# -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ +# -DCMAKE_TOOLCHAIN_FILE=./../cmake/modules/set_toolchain.cmake .. +# make package +# cp dist/*.zip ../build/Release/dist +# make clean +# cd .. +# rm -rf build-mingw-64 From ee43e3b3571c8c7d253b158bbab2d330b3ef19cb Mon Sep 17 00:00:00 2001 From: anton Date: Tue, 6 Apr 2021 21:13:54 +0500 Subject: [PATCH 56/65] Unification of the reset function --- inc/stlink.h | 24 +++++++++-- src/common.c | 91 +++++++++++++++++++++++++++++++++++++-- src/st-flash/flash.c | 13 +----- src/st-trace/trace.c | 2 +- src/st-util/gdb-server.c | 92 +++++++++++++--------------------------- src/stlink-lib/sg.c | 2 +- src/stlink-lib/usb.c | 51 +--------------------- src/stlink-lib/usb.h | 6 --- tests/sg.c | 2 +- tests/usb.c | 2 +- 10 files changed, 145 insertions(+), 140 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index 855e5126d..8fe6033d6 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -58,6 +58,11 @@ enum target_state { #define STLINK_JTAG_READDEBUG_32BIT 0x36 #define STLINK_JTAG_DRIVE_NRST 0x3C +/* NRST pin states */ +#define STLINK_JTAG_DRIVE_NRST_LOW 0x00 +#define STLINK_JTAG_DRIVE_NRST_HIGH 0x01 +#define STLINK_JTAG_DRIVE_NRST_PULSE 0x02 + #define STLINK_DEBUG_APIV2_SWD_SET_FREQ 0x43 #define STLINK_APIV3_SET_COM_FREQ 0x61 @@ -173,6 +178,19 @@ enum transport_type { TRANSPORT_TYPE_INVALID }; +enum connect_type { + CONNECT_HOT_PLUG = 0, + CONNECT_NORMAL = 1, + CONNECT_UNDER_RESET = 2, +}; + +enum reset_type { + RESET_AUTO = 0, + RESET_HARD = 1, + RESET_SOFT = 2, + RESET_SOFT_AND_HALT = 3, +}; + typedef struct _stlink stlink_t; #include @@ -231,9 +249,7 @@ 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_soft_reset(stlink_t *sl, int halt_on_reset); +int stlink_reset(stlink_t *sl, enum reset_type type); int stlink_run(stlink_t *sl); int stlink_status(stlink_t *sl); int stlink_version(stlink_t *sl); @@ -301,6 +317,8 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl); int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, uint8_t* base, uint32_t len); int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl); +int stlink_target_connect(stlink_t *sl, enum connect_type connect); + #include #include #include diff --git a/src/common.c b/src/common.c index 60d7ff145..928091eb4 100644 --- a/src/common.c +++ b/src/common.c @@ -1663,10 +1663,6 @@ int stlink_load_device_params(stlink_t *sl) { return(0); } -int stlink_reset(stlink_t *sl) { - DLOG("*** stlink_reset ***\n"); - return(sl->backend->reset(sl)); -} int stlink_jtag_reset(stlink_t *sl, int value) { DLOG("*** stlink_jtag_reset ***\n"); @@ -1742,6 +1738,59 @@ int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { return(0); } +int stlink_reset(stlink_t *sl, enum reset_type type) { + uint32_t dhcsr; + unsigned timeout; + + DLOG("*** stlink_reset ***\n"); + + if (type == RESET_AUTO) { + // clear S_RESET_ST in DHCSR register for reset state detection + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + } + + if (type == RESET_HARD || type == RESET_AUTO) { + // hardware target reset + if (sl->version.stlink_v > 1) { stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_PULSE); } + if (sl->backend->reset(sl)) { return(-1); } + usleep(10000); + } + + if (type == RESET_AUTO) { + /* Check if the S_RESET_ST bit is set in DHCSR + * This means that a reset has occurred + * DDI0337E, p. 10-4, Debug Halting Control and Status Register */ + + dhcsr = 0; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { + // reset not done yet + // try reset through AIRCR so that NRST does not need to be connected + + WLOG("NRST is not connected\n"); + DLOG("Using reset through SYSRESETREQ\n"); + return stlink_soft_reset(sl, 0); + } + + // waiting for reset the S_RESET_ST bit within 500ms + timeout = time_ms() + 500; + while (time_ms() < timeout) { + dhcsr = STLINK_REG_DHCSR_S_RESET_ST; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr&STLINK_REG_DHCSR_S_RESET_ST) == 0) + return(0); + } + + return(-1); + } + + if (type == RESET_SOFT || type == RESET_SOFT_AND_HALT) { + return stlink_soft_reset(sl, (type==RESET_SOFT_AND_HALT)); + } + + return(0); +} + int stlink_run(stlink_t *sl) { struct stlink_reg rr; DLOG("*** stlink_run ***\n"); @@ -4467,3 +4516,37 @@ int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr return(err); } +int stlink_target_connect(stlink_t *sl, enum connect_type connect) { + uint32_t dhcsr; + + if (connect == CONNECT_UNDER_RESET) { + stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_LOW); + + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } + stlink_force_debug(sl); + + // clear S_RESET_ST in DHCSR register + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + + stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_HIGH); + usleep(10000); + + // check NRST connection + dhcsr = 0; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { + WLOG("NRST is not connected\n"); + } + + // addition soft reset for halt before the first instruction + stlink_soft_reset(sl, 1 /* halt on reset */); + } + + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } + + if (connect == CONNECT_NORMAL) { + stlink_reset(sl, RESET_AUTO); + } + + return stlink_load_device_params(sl); +} diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index edb54e195..5eb607758 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -188,14 +188,7 @@ int main(int ac, char** av) { goto on_error; } } else if (o.cmd == CMD_RESET) { - if (sl->version.stlink_v > 1) { - if (stlink_jtag_reset(sl, 2)) { - printf("Failed to reset JTAG\n"); - goto on_error; - } - } - - if (stlink_reset(sl)) { + if (stlink_reset(sl, RESET_AUTO)) { printf("Failed to reset device\n"); goto on_error; } @@ -263,9 +256,7 @@ int main(int ac, char** av) { } if (o.reset) { - if (sl->version.stlink_v > 1) { stlink_jtag_reset(sl, 2); } - - stlink_reset(sl); + stlink_reset(sl, RESET_AUTO); } err = 0; // success diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index 3180335a0..f40a9d683 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -203,7 +203,7 @@ static bool enable_trace(stlink_t* stlink, const st_settings_t* settings, uint32 return false; } - if (settings->reset_board && stlink_jtag_reset(stlink, 2)) { + if (settings->reset_board && stlink_reset(stlink, RESET_AUTO)) { ELOG("Unable to reset device\n"); if (!settings->force) return false; diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 8d63d9ee0..c2a220df3 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -42,9 +42,6 @@ #define FLASH_PAGE (sl->flash_pgsz) static stlink_t *connected_stlink = NULL; -static bool semihosting = false; -static bool serial_specified = false; -static char serialnumber[STLINK_SERIAL_BUFFER_SIZE] = {0}; #if defined(_WIN32) #define close_socket win32_close_socket @@ -57,8 +54,6 @@ static char serialnumber[STLINK_SERIAL_BUFFER_SIZE] = {0}; static const char hex[] = "0123456789abcdef"; -static const char* current_memory_map = NULL; - typedef struct _st_state_t { // things from command line, bleh int logging_level; @@ -66,6 +61,9 @@ typedef struct _st_state_t { int persistent; enum connect_type connect_mode; int freq; + char serialnumber[STLINK_SERIAL_BUFFER_SIZE]; + bool semihosting; + const char* current_memory_map; } st_state_t; @@ -97,20 +95,6 @@ BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) { } #endif - -static stlink_t* do_connect(st_state_t *st) { - stlink_t *sl = NULL; - - if (serial_specified) { - sl = stlink_open_usb(st->logging_level, st->connect_mode, serialnumber, st->freq); - } else { - sl = stlink_open_usb(st->logging_level, st->connect_mode, NULL, st->freq); - } - - return(sl); -} - - int parse_options(int argc, char** argv, st_state_t *st) { static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, @@ -119,6 +103,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { {"multi", optional_argument, NULL, 'm'}, {"no-reset", optional_argument, NULL, 'n'}, {"hot-plug", optional_argument, NULL, 'n'}, + {"connect-under-reset", optional_argument, NULL, 'u'}, {"freq", optional_argument, NULL, 'F'}, {"version", no_argument, NULL, 'V'}, {"semihosting", no_argument, NULL, SEMIHOSTING_OPTION}, @@ -138,6 +123,8 @@ int parse_options(int argc, char** argv, st_state_t *st) { "\t\t\tst-util will continue listening for connections after disconnect.\n" " -n, --no-reset, --hot-plug\n" "\t\t\tDo not reset board on connection.\n" + " -u, --connect-under-reset\n" + "\t\t\tConnect to the board before executing any instructions.\n" " -F 1800K, --freq=1M\n" "\t\t\tSet the frequency of the SWD/JTAG interface.\n" " --semihosting\n" @@ -182,11 +169,14 @@ int parse_options(int argc, char** argv, st_state_t *st) { break; case 'm': - st->persistent = 1; + st->persistent = true; break; case 'n': st->connect_mode = CONNECT_HOT_PLUG; break; + case 'u': + st->connect_mode = CONNECT_UNDER_RESET; + break; case 'F': st->freq = arg_parse_freq(optarg); if (st->freq < 0) { @@ -198,12 +188,11 @@ int parse_options(int argc, char** argv, st_state_t *st) { printf("v%s\n", STLINK_VERSION); exit(EXIT_SUCCESS); case SEMIHOSTING_OPTION: - semihosting = true; + st->semihosting = true; break; case SERIAL_OPTION: printf("use serial %s\n", optarg); - memcpy(serialnumber, optarg, STLINK_SERIAL_BUFFER_SIZE); - serial_specified = true; + memcpy(st->serialnumber, optarg, STLINK_SERIAL_BUFFER_SIZE); break; } @@ -232,8 +221,7 @@ int main(int argc, char** argv) { printf("st-util\n"); - sl = do_connect(&state); - + sl = stlink_open_usb(state.logging_level, state.connect_mode, state.serialnumber, state.freq); if (sl == NULL) { return(1); } if (sl->chip_id == STLINK_CHIPID_UNKNOWN) { @@ -241,7 +229,9 @@ int main(int argc, char** argv) { return(1); } + sl->verbose = 0; connected_stlink = sl; + #if defined(_WIN32) SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE); #else @@ -250,18 +240,14 @@ int main(int argc, char** argv) { signal(SIGSEGV, &cleanup); #endif - if (state.connect_mode != CONNECT_HOT_PLUG) { stlink_reset(sl); } - DLOG("Chip ID is %#010x, Core ID is %#08x.\n", sl->chip_id, sl->core_id); - sl->verbose = 0; - current_memory_map = make_memory_map(sl); + state.current_memory_map = make_memory_map(sl); #if defined(_WIN32) WSADATA wsadata; if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0) { goto winsock_error; } - #endif init_cache(sl); @@ -865,16 +851,13 @@ static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { return(0); } -static int flash_go(stlink_t *sl) { +static int flash_go(stlink_t *sl, st_state_t *st) { int error = -1; int ret; flash_loader_t fl; - // some kinds of clock settings do not allow writing to flash. - stlink_reset(sl); + stlink_target_connect(sl, st->connect_mode); stlink_force_debug(sl); - // delay to ensure that STM32 HSI clock and others have started up fully - usleep(10000); for (struct flash_block* fb = flash_root; fb; fb = fb->next) { ILOG("flash_erase: block %08x -> %04x\n", fb->addr, fb->length); @@ -909,7 +892,7 @@ static int flash_go(stlink_t *sl) { } stlink_flashloader_stop(sl, &fl); - stlink_soft_reset(sl, 1 /* halt on reset */); + stlink_reset(sl, RESET_SOFT_AND_HALT); error = 0; error: @@ -1119,10 +1102,9 @@ int serve(stlink_t *sl, st_state_t *st) { close_socket(sock); + stlink_target_connect(sl, st->connect_mode); stlink_force_debug(sl); - if (st->connect_mode != CONNECT_HOT_PLUG) { stlink_reset(sl); } - init_code_breakpoints(sl); init_data_watchpoints(sl); @@ -1198,7 +1180,7 @@ int serve(stlink_t *sl, st_state_t *st) { if (strcmp(op, "read")) { data = NULL; } else if (!strcmp(type, "memory-map")) { - data = current_memory_map; + data = st->current_memory_map; } else if (!strcmp(type, "features")) { data = target_description; } else { @@ -1269,22 +1251,14 @@ int serve(stlink_t *sl, st_state_t *st) { } else if (!strncmp(cmd, "jtag_reset", 10)) { // jtag_reset reply = strdup("OK"); - ret = stlink_jtag_reset(sl, 0); - - if (ret) { - DLOG("Rcmd: jtag_reset failed with jtag_reset\n"); - reply = strdup("E00"); - } - - ret = stlink_jtag_reset(sl, 1); + ret = stlink_reset(sl, RESET_HARD); if (ret) { DLOG("Rcmd: jtag_reset failed with jtag_reset\n"); reply = strdup("E00"); } ret = stlink_force_debug(sl); - if (ret) { DLOG("Rcmd: jtag_reset failed with force_debug\n"); reply = strdup("E00"); @@ -1297,14 +1271,12 @@ int serve(stlink_t *sl, st_state_t *st) { } else if (!strncmp(cmd, "reset", 5)) { // reset ret = stlink_force_debug(sl); - if (ret) { DLOG("Rcmd: reset failed with force_debug\n"); reply = strdup("E00"); } - ret = stlink_reset(sl); - + ret = stlink_reset(sl, RESET_AUTO); if (ret) { DLOG("Rcmd: reset failed with reset\n"); reply = strdup("E00"); @@ -1325,10 +1297,10 @@ int serve(stlink_t *sl, st_state_t *st) { while (isspace(*arg)) { arg++; } // skip whitespaces if (!strncmp(arg, "enable", 6) || !strncmp(arg, "1", 1)) { - semihosting = true; + st->semihosting = true; reply = strdup("OK"); } else if (!strncmp(arg, "disable", 7) || !strncmp(arg, "0", 1)) { - semihosting = false; + st->semihosting = false; reply = strdup("OK"); } else { DLOG("Rcmd: unknown semihosting arg: '%s'\n", arg); @@ -1407,7 +1379,7 @@ int serve(stlink_t *sl, st_state_t *st) { free(decoded); } else if (!strcmp(cmdName, "FlashDone")) { - if (flash_go(sl)) { + if (flash_go(sl, st)) { reply = strdup("E08"); } else { reply = strdup("OK"); @@ -1453,7 +1425,7 @@ int serve(stlink_t *sl, st_state_t *st) { int offset = 0; uint16_t insn; - if (!semihosting) { break; } + if (!st->semihosting) { break; } ret = stlink_read_all_regs (sl, ®); @@ -1821,7 +1793,7 @@ int serve(stlink_t *sl, st_state_t *st) { case 'R': { // reset the core. - ret = stlink_reset(sl); + ret = stlink_reset(sl, RESET_AUTO); if (ret) { DLOG("R packet : stlink_reset failed\n"); } init_code_breakpoints(sl); @@ -1835,25 +1807,19 @@ int serve(stlink_t *sl, st_state_t *st) { case 'k': // kill request - reset the connection itself ret = stlink_run(sl); - if (ret) { DLOG("Kill: stlink_run failed\n"); } ret = stlink_exit_debug_mode(sl); - if (ret) { DLOG("Kill: stlink_exit_debug_mode failed\n"); } stlink_close(sl); - sl = do_connect(st); - + sl = stlink_open_usb(st->logging_level, st->connect_mode, st->serialnumber, st->freq); if (sl == NULL || sl->chip_id == STLINK_CHIPID_UNKNOWN) { cleanup(0); } connected_stlink = sl; - if (st->connect_mode != CONNECT_HOT_PLUG) { stlink_reset(sl); } - ret = stlink_force_debug(sl); - if (ret) { DLOG("Kill: stlink_force_debug failed\n"); } init_cache(sl); diff --git a/src/stlink-lib/sg.c b/src/stlink-lib/sg.c index 840466e75..c5946ed19 100644 --- a/src/stlink-lib/sg.c +++ b/src/stlink-lib/sg.c @@ -1114,7 +1114,7 @@ stlink_t* stlink_v1_open(const int verbose, int reset) { stlink_enter_swd_mode(sl); // now we are ready to read the parameters - if (reset) { stlink_reset(sl); } + if (reset) { stlink_reset(sl, RESET_AUTO); } stlink_load_device_params(sl); ILOG("Successfully opened a stlink v1 debugger\n"); diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index ce0d672c8..99b5f51ef 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -512,13 +512,8 @@ int _stlink_usb_reset(stlink_t * sl) { unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; ssize_t size; - uint32_t dhcsr; - unsigned timeout; int i, rep_len = 2; - // clear S_RESET_ST in DHCSR registr - _stlink_usb_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - // send reset command i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; @@ -536,30 +531,7 @@ int _stlink_usb_reset(stlink_t * sl) { return((int)size); } - usleep(10000); - - dhcsr = 0; - _stlink_usb_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { - // reset not done yet - // try reset through AIRCR so that NRST does not need to be connected - - WLOG("NRST is not connected\n"); - DLOG("Using reset through SYSRESETREQ\n"); - return stlink_soft_reset(sl, 0); - } - - // waiting for a reset within 500ms - timeout = time_ms() + 500; - while (time_ms() < timeout) { - // DDI0337E, p. 10-4, Debug Halting Control and Status Register - dhcsr = STLINK_REG_DHCSR_S_RESET_ST; - _stlink_usb_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr&STLINK_REG_DHCSR_S_RESET_ST) == 0) - return(0); - } - - return(-1); + return(0); } int _stlink_usb_jtag_reset(stlink_t * sl, int value) { @@ -1382,26 +1354,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, enum connect_type connect, DLOG("JTAG/SWD freq set to %d\n", freq); stlink_set_swdclk(sl, freq); - if (connect == CONNECT_UNDER_RESET) { - stlink_jtag_reset(sl, 0); - - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } - - stlink_force_debug(sl); - stlink_jtag_reset(sl, 1); - usleep(10000); - } - - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } - - if (connect == CONNECT_NORMAL) { - if ( sl->version.stlink_v > 1) { stlink_jtag_reset(sl, 2); } - - stlink_reset(sl); - usleep(10000); - } - - stlink_load_device_params(sl); + stlink_target_connect(sl, connect); return(sl); on_libusb_error: diff --git a/src/stlink-lib/usb.h b/src/stlink-lib/usb.h index f48ef225d..27de32700 100644 --- a/src/stlink-lib/usb.h +++ b/src/stlink-lib/usb.h @@ -48,12 +48,6 @@ extern "C" { #define STLINK_SG_SIZE 31 #define STLINK_CMD_SIZE 16 -enum connect_type { - CONNECT_HOT_PLUG = 0, - CONNECT_NORMAL = 1, - CONNECT_UNDER_RESET = 2, -}; - struct stlink_libusb { libusb_context* libusb_ctx; libusb_device_handle* usb_handle; diff --git a/tests/sg.c b/tests/sg.c index 745df845f..7584ab5d4 100644 --- a/tests/sg.c +++ b/tests/sg.c @@ -46,7 +46,7 @@ int main(void) { // main() ripped out of old stlink-hw.c stlink_core_id(sl); stlink_status(sl); // stlink_force_debug(sl); - stlink_reset(sl); + stlink_reset(sl, RESET_AUTO); stlink_status(sl); // core system control block stlink_read_mem32(sl, 0xe000ed00, 4); diff --git a/tests/usb.c b/tests/usb.c index 03c135f00..5c5c2077d 100644 --- a/tests/usb.c +++ b/tests/usb.c @@ -93,7 +93,7 @@ int main(int ac, char** av) { stlink_status(sl); printf("-- reset\n"); - stlink_reset(sl); + stlink_reset(sl, RESET_AUTO); stlink_force_debug(sl); /* Test reg write */ stlink_write_reg(sl, 0x01234567, 3); From 6bd99d4b55cd33c7f3773eda8aadea10e1288b5e Mon Sep 17 00:00:00 2001 From: anton Date: Tue, 6 Apr 2021 22:03:52 +0500 Subject: [PATCH 57/65] flash_loader: fixed interrupt masking --- doc/dev/developer.txt | 7 ++++--- doc/tutorial.md | 2 +- inc/backend.h | 2 +- inc/stlink.h | 8 +++++++- src/common.c | 8 ++++---- src/st-flash/flash.c | 2 +- src/st-trace/trace.c | 2 +- src/st-util/gdb-server.c | 16 ++++++++-------- src/stlink-lib/flash_loader.c | 2 +- src/stlink-lib/sg.c | 3 ++- src/stlink-lib/usb.c | 7 +++++-- tests/sg.c | 4 ++-- tests/usb.c | 2 +- 13 files changed, 38 insertions(+), 27 deletions(-) diff --git a/doc/dev/developer.txt b/doc/dev/developer.txt index 9c4da22f7..e3091c003 100644 --- a/doc/dev/developer.txt +++ b/doc/dev/developer.txt @@ -244,18 +244,19 @@ Description: Backend: "jtag_reset" Arguments: sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() - value: 0: drive low, 1: drive high, 2: ???? + value: 0: drive low, 1: drive high, 2: pulse Return: -1 for error. 0 for success. Include: inc/stlink.h -Prototype: int stlink_run(stlink_t *sl); +Prototype: int stlink_run(stlink_t *sl, enum run_type type); Definition: src/common.c Description: Just calls the backend "run" procedure. Backend: "run" Arguments: - sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() + sl: Pointer to the stlink data structure, returned by stlink_v1_open() or stlink_open_usb() + type: RUN_NORMAL - run target, RUN_FLASH_LOADER - run target with masking interrupts Return: -1 for error. 0 for success. Include: inc/stlink.h diff --git a/doc/tutorial.md b/doc/tutorial.md index 21f1498ee..71af3d45e 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -8,7 +8,7 @@ | --freq=n[k][m] | st-info
st-flash
st-util | The frequency of the SWD/JTAG interface can be specified, to override the default 1800 kHz configuration.
This option solely accepts decimal values (5K or 1.8M) with the unit `Hz` being left out. Valid frequencies are:
`5K, 15K, 25K, 50K, 100K, 125K, 240K, 480K, 950K, 1200K, 1800K, 4000K(4M)`. | v1.6.1 | | --opt | st-flash | Optimisation can be enabled in order to skip flashing empty (0x00 or 0xff) bytes at the end of binary file.
This may cause some garbage data left after a flash operation. This option was enabled by default in earlier releases. | v1.6.1 | | --reset | st-flash | Trigger a reset after flashing. The default uses the hardware reset through `NRST` pin.
A software reset (via `AIRCR`; since v1.5.1) is used, if the hardware reset failed (`NRST` pin not connected). | v1.0.0 | -| --connect-under-reset | st-info
st-flash | Connect under reset. Option makes it possible to connect to the device before code execution. This is useful
when the target contains code that lets the device go to sleep, disables debug pins or other special code. | v1.6.1 | +| --connect-under-reset | st-info
st-flash
st-util | Connect under reset. Option makes it possible to connect to the device before code execution. This is useful
when the target contains code that lets the device go to sleep, disables debug pins or other special code. | v1.6.1 | | --hot-plug | st-info
st-flash
st-util | Connect to the target without reset. | v1.6.2 | | --probe | st-info | Display hardware information about the connected programmer and target MCU. | v1.2.0 | | --version | st-info
st-flash
st-util | Print version information. | v1.3.0 | diff --git a/inc/backend.h b/inc/backend.h index ebd438127..a45dccd82 100644 --- a/inc/backend.h +++ b/inc/backend.h @@ -10,7 +10,7 @@ int (*core_id) (stlink_t * stl); int (*reset) (stlink_t * stl); int (*jtag_reset) (stlink_t * stl, int value); - int (*run) (stlink_t * stl); + int (*run) (stlink_t * stl, enum run_type type); int (*status) (stlink_t * stl); int (*version) (stlink_t *sl); int (*read_debug32) (stlink_t *sl, uint32_t addr, uint32_t *data); diff --git a/inc/stlink.h b/inc/stlink.h index 8fe6033d6..ec119c145 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -191,6 +191,12 @@ enum reset_type { RESET_SOFT_AND_HALT = 3, }; +enum run_type { + RUN_NORMAL = 0, + RUN_FLASH_LOADER = 1, +}; + + typedef struct _stlink stlink_t; #include @@ -250,7 +256,7 @@ 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, enum reset_type type); -int stlink_run(stlink_t *sl); +int stlink_run(stlink_t *sl, enum run_type type); 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); diff --git a/src/common.c b/src/common.c index 928091eb4..63086ab22 100644 --- a/src/common.c +++ b/src/common.c @@ -1791,7 +1791,7 @@ int stlink_reset(stlink_t *sl, enum reset_type type) { return(0); } -int stlink_run(stlink_t *sl) { +int stlink_run(stlink_t *sl, enum run_type type) { struct stlink_reg rr; DLOG("*** stlink_run ***\n"); @@ -1804,7 +1804,7 @@ int stlink_run(stlink_t *sl) { stlink_write_reg(sl, rr.xpsr | (1 << 24), 16); } - return(sl->backend->run(sl)); + return(sl->backend->run(sl, type)); } int stlink_set_swdclk(stlink_t *sl, int freq_khz) { @@ -2096,7 +2096,7 @@ int stlink_trace_read(stlink_t* sl, uint8_t* buf, size_t size) { void stlink_run_at(stlink_t *sl, stm32_addr_t addr) { stlink_write_reg(sl, addr, 15); /* pc register */ - stlink_run(sl); + stlink_run(sl, RUN_NORMAL); while (stlink_is_core_halted(sl)) { usleep(3000000); } } @@ -2258,7 +2258,7 @@ static void stlink_fwrite_finalize(stlink_t *sl, stm32_addr_t addr) { // set PC to the reset routine stlink_read_debug32(sl, addr + 4, &val); stlink_write_reg(sl, val, 15); - stlink_run(sl); + stlink_run(sl, RUN_NORMAL); } int stlink_mwrite_sram(stlink_t * sl, uint8_t* data, uint32_t length, stm32_addr_t addr) { diff --git a/src/st-flash/flash.c b/src/st-flash/flash.c index 5eb607758..ede0f1179 100644 --- a/src/st-flash/flash.c +++ b/src/st-flash/flash.c @@ -17,7 +17,7 @@ static void cleanup(int signum) { (void)signum; if (connected_stlink) { // switch back to mass storage mode before closing - stlink_run(connected_stlink); + stlink_run(connected_stlink, RUN_NORMAL); stlink_exit_debug_mode(connected_stlink); stlink_close(connected_stlink); } diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index f40a9d683..f28624475 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -539,7 +539,7 @@ int main(int argc, char** argv) memset(&trace, 0, sizeof(trace)); trace.start_time = time(NULL); - if (stlink_run(stlink)) { + if (stlink_run(stlink, RUN_NORMAL)) { ELOG("Unable to run device\n"); if (!settings.force) return APP_RESULT_STLINK_STATE_ERROR; diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index c2a220df3..c6d329456 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -74,7 +74,7 @@ static void init_cache(stlink_t *sl); static void _cleanup() { if (connected_stlink) { // Switch back to mass storage mode before closing - stlink_run(connected_stlink); + stlink_run(connected_stlink, RUN_NORMAL); stlink_exit_debug_mode(connected_stlink); stlink_close(connected_stlink); } @@ -252,11 +252,11 @@ int main(int argc, char** argv) { init_cache(sl); - do { // don't go beserk if serve() returns with error + do { // don't go beserk if serve() returns with error if (serve(sl, &state)) { usleep (1 * 1000); } - sl = connected_stlink; // in case serve() changed the connection - stlink_run(sl); // continue + sl = connected_stlink; // in case serve() changed the connection + stlink_run(sl, RUN_NORMAL); // continue } while (state.persistent); #if defined(_WIN32) @@ -1229,7 +1229,7 @@ int serve(stlink_t *sl, st_state_t *st) { if (!strncmp(cmd, "resume", 6)) { // resume DLOG("Rcmd: resume\n"); cache_sync(sl); - ret = stlink_run(sl); + ret = stlink_run(sl, RUN_NORMAL); if (ret) { DLOG("Rcmd: resume failed\n"); @@ -1396,7 +1396,7 @@ int serve(stlink_t *sl, st_state_t *st) { case 'c': cache_sync(sl); - ret = stlink_run(sl); + ret = stlink_run(sl, RUN_NORMAL); if (ret) { DLOG("Semihost: run failed\n"); } @@ -1466,7 +1466,7 @@ int serve(stlink_t *sl, st_state_t *st) { // continue execution cache_sync(sl); - ret = stlink_run(sl); + ret = stlink_run(sl, RUN_NORMAL); if (ret) { DLOG("Semihost: continue execution failed with stlink_run\n"); } } else { @@ -1806,7 +1806,7 @@ int serve(stlink_t *sl, st_state_t *st) { } case 'k': // kill request - reset the connection itself - ret = stlink_run(sl); + ret = stlink_run(sl, RUN_NORMAL); if (ret) { DLOG("Kill: stlink_run failed\n"); } ret = stlink_exit_debug_mode(sl); diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index cd7096490..ba5efdb8e 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -347,7 +347,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe } /* Run loader */ - stlink_run(sl); + stlink_run(sl, RUN_FLASH_LOADER); /* This piece of code used to try to spin for .1 second by waiting doing 10000 rounds of 10 µs. * But because this usually runs on Unix-like OSes, the 10 µs get rounded up to the "tick" diff --git a/src/stlink-lib/sg.c b/src/stlink-lib/sg.c index c5946ed19..07971284f 100644 --- a/src/stlink-lib/sg.c +++ b/src/stlink-lib/sg.c @@ -731,8 +731,9 @@ void stlink_write_dreg(stlink_t *sl, uint32_t reg, uint32_t addr) { } // force the core exit the debug mode. -int _stlink_sg_run(stlink_t *sl) { +int _stlink_sg_run(stlink_t *sl, enum run_type type) { struct stlink_libsg *sg = sl->backend_data; + (void)(type); //unused clear_cdb(sg); sg->cdb_cmd_blk[1] = STLINK_DEBUG_RUNCORE; sl->q_len = 2; diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 99b5f51ef..2754db06f 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -590,14 +590,17 @@ int _stlink_usb_step(stlink_t* sl) { /** * This seems to do a good job of restarting things from the beginning? * @param sl + * @param type */ -int _stlink_usb_run(stlink_t* sl) { +int _stlink_usb_run(stlink_t* sl, enum run_type type) { struct stlink_libusb * const slu = sl->backend_data; int res; if (sl->version.jtag_api != STLINK_JTAG_API_V1) { - res = _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN); + res = _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, + STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | + ((type==RUN_FLASH_LOADER)?STLINK_REG_DHCSR_C_MASKINTS:0)); return(res); } diff --git a/tests/sg.c b/tests/sg.c index 7584ab5d4..d88fbe760 100644 --- a/tests/sg.c +++ b/tests/sg.c @@ -159,7 +159,7 @@ int main(void) { // main() ripped out of old stlink-hw.c #endif #if 0 - stlink_run(sl); + stlink_run(sl, RUN_NORMAL); stlink_status(sl); stlink_force_debug(sl); stlink_status(sl); @@ -196,7 +196,7 @@ int main(void) { // main() ripped out of old stlink-hw.c #endif #if 0 - stlink_run(sl); + stlink_run(sl, RUN_NORMAL); stlink_status(sl); // back to mass mode, just in case ... stlink_exit_debug_mode(sl); diff --git a/tests/usb.c b/tests/usb.c index 5c5c2077d..742f5c578 100644 --- a/tests/usb.c +++ b/tests/usb.c @@ -111,7 +111,7 @@ int main(int ac, char** av) { stlink_step(sl); printf("-- run\n"); - stlink_run(sl); + stlink_run(sl, RUN_NORMAL); printf("-- exit_debug_mode\n"); stlink_exit_debug_mode(sl); From c2e898c9228e2b13378987354f602745e1ca7b1c Mon Sep 17 00:00:00 2001 From: anton Date: Tue, 6 Apr 2021 22:43:15 +0500 Subject: [PATCH 58/65] Manual NRST pulse shaping Automatic generation via argument two of the jtag_reset function seem doesn't to work --- src/common.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index 63086ab22..1cb5c6db0 100644 --- a/src/common.c +++ b/src/common.c @@ -1751,7 +1751,12 @@ int stlink_reset(stlink_t *sl, enum reset_type type) { if (type == RESET_HARD || type == RESET_AUTO) { // hardware target reset - if (sl->version.stlink_v > 1) { stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_PULSE); } + if (sl->version.stlink_v > 1) { + stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_LOW); + // minimum reset pulse duration of 20 us (RM0008, 8.1.2 Power reset) + usleep(100); + stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_HIGH); + } if (sl->backend->reset(sl)) { return(-1); } usleep(10000); } @@ -4522,6 +4527,9 @@ int stlink_target_connect(stlink_t *sl, enum connect_type connect) { if (connect == CONNECT_UNDER_RESET) { stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_LOW); + // minimum reset pulse duration of 20 us (RM0008, 8.1.2 Power reset) + usleep(20); + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } stlink_force_debug(sl); From 31738583967b89cf6416fd45a17ca8a7adfe12e2 Mon Sep 17 00:00:00 2001 From: anton Date: Wed, 7 Apr 2021 20:57:17 +0500 Subject: [PATCH 59/65] gdb-server: set target configuration after client connects --- src/st-util/gdb-server.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index c6d329456..006a0e3aa 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -242,16 +242,12 @@ int main(int argc, char** argv) { DLOG("Chip ID is %#010x, Core ID is %#08x.\n", sl->chip_id, sl->core_id); - state.current_memory_map = make_memory_map(sl); - #if defined(_WIN32) WSADATA wsadata; if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0) { goto winsock_error; } #endif - init_cache(sl); - do { // don't go beserk if serve() returns with error if (serve(sl, &state)) { usleep (1 * 1000); } @@ -1102,12 +1098,22 @@ int serve(stlink_t *sl, st_state_t *st) { close_socket(sock); + uint32_t chip_id = sl->chip_id; + stlink_target_connect(sl, st->connect_mode); stlink_force_debug(sl); + if (sl->chip_id != chip_id) { + WLOG("Target has changed!\n"); + } + init_code_breakpoints(sl); init_data_watchpoints(sl); + init_cache(sl); + + st->current_memory_map = make_memory_map(sl); + ILOG("GDB connected.\n"); /* From d2a2c9825a739d92f2c4b7604ca732a2c1e3161e Mon Sep 17 00:00:00 2001 From: anton Date: Mon, 12 Apr 2021 22:34:44 +0500 Subject: [PATCH 60/65] Fixed chipid detection on Cortex-MO+ core --- src/common.c | 3 ++- src/stlink-lib/reg.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index a17392cf1..f230bee64 100644 --- a/src/common.c +++ b/src/common.c @@ -1240,7 +1240,8 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM7) { // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) ret = stlink_read_debug32(sl, 0x5c001000, chip_id); - } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0) { + } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0 || + cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0P) { // STM32F0 (RM0091, pg914; RM0360, pg713) // STM32L0 (RM0377, pg813; RM0367, pg915; RM0376, pg917) // STM32G0 (RM0444, pg1367) diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index 4849806d7..b581a269c 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -4,6 +4,7 @@ #define STLINK_REG_CM3_CPUID 0xE000ED00 #define STLINK_REG_CMx_CPUID_PARTNO_CM0 0xC20 +#define STLINK_REG_CMx_CPUID_PARTNO_CM0P 0xC60 #define STLINK_REG_CMx_CPUID_PARTNO_CM3 0xC23 #define STLINK_REG_CMx_CPUID_PARTNO_CM4 0xC24 #define STLINK_REG_CMx_CPUID_PARTNO_CM7 0xC27 From dfb00775a3e332c8575d8d5dfc86365de04ed2e3 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Thu, 15 Apr 2021 22:39:24 +0200 Subject: [PATCH 61/65] Updated changelog --- CHANGELOG.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57426342a..0ac52da73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # stlink Changelog -# v1.6.2 +# v1.7.0 Release date: 2020-04-xx @@ -8,7 +8,8 @@ This release drops support for the STLINK/V1 programmer on macOS 10.13. Features: -- Extended support for STM32H7 & rework of software reset ([#532](https://github.com/stlink-org/stlink/pull/532), [#868](https://github.com/stlink-org/stlink/pull/868), [#1059](https://github.com/stlink-org/stlink/pull/1059), [#1063](https://github.com/stlink-org/stlink/pull/1063), [#1071](https://github.com/stlink-org/stlink/pull/1071)) +- Extended set of cmd line arguments for st-info and st-util ([#332](https://github.com/stlink-org/stlink/pull/332), [#990](https://github.com/stlink-org/stlink/pull/990), [#1091](https://github.com/stlink-org/stlink/pull/1091), [#1114](https://github.com/stlink-org/stlink/pull/1114)) +- Extended support for STM32H7 & rework of software reset ([#532](https://github.com/stlink-org/stlink/pull/532), [#801](https://github.com/stlink-org/stlink/pull/801), [#868](https://github.com/stlink-org/stlink/pull/868), [#1059](https://github.com/stlink-org/stlink/pull/1059), [#1063](https://github.com/stlink-org/stlink/pull/1063), [#1071](https://github.com/stlink-org/stlink/pull/1071)) - Added support for STM32H742/743/753 ([#671](https://github.com/stlink-org/stlink/pull/671), [#793](https://github.com/stlink-org/stlink/pull/793), [#823](https://github.com/stlink-org/stlink/pull/823), [#998](https://github.com/stlink-org/stlink/pull/998), [#1052](https://github.com/stlink-org/stlink/pull/1052)) - Official support for STLINK-V3 programmers (commit [#5e0a502](https://github.com/stlink-org/stlink/commit/5e0a502df812495bfa96fa9116a19f1306152b17), [#820](https://github.com/stlink-org/stlink/pull/820), [#1022](https://github.com/stlink-org/stlink/pull/1022), [#1025](https://github.com/stlink-org/stlink/pull/1025)) - Added preliminary support for STM32L5x2 ([#904](https://github.com/stlink-org/stlink/pull/904), [#999](https://github.com/stlink-org/stlink/pull/999)) @@ -39,7 +40,7 @@ Updates & changes: Fixes: -- Flash loader rework ([#356](https://github.com/stlink-org/stlink/pull/356), [#556](https://github.com/stlink-org/stlink/pull/556), [#593](https://github.com/stlink-org/stlink/pull/593), [#597](https://github.com/stlink-org/stlink/pull/597), [#607](https://github.com/stlink-org/stlink/pull/607), [#612](https://github.com/stlink-org/stlink/pull/612), [#638](https://github.com/stlink-org/stlink/pull/638), [#661](https://github.com/stlink-org/stlink/pull/661), [#690](https://github.com/stlink-org/stlink/pull/690), [#818](https://github.com/stlink-org/stlink/pull/818), [#854](https://github.com/stlink-org/stlink/pull/854), [#868](https://github.com/stlink-org/stlink/pull/868), [#967](https://github.com/stlink-org/stlink/pull/967), [#979](https://github.com/stlink-org/stlink/pull/979), [#1043](https://github.com/stlink-org/stlink/pull/1043), [#1054](https://github.com/stlink-org/stlink/pull/1054), [#1092](https://github.com/stlink-org/stlink/pull/1092), [#1105](https://github.com/stlink-org/stlink/pull/1105), [#1113](https://github.com/stlink-org/stlink/pull/1113)) +- Flash loader rework ([#356](https://github.com/stlink-org/stlink/pull/356), [#556](https://github.com/stlink-org/stlink/pull/556), [#593](https://github.com/stlink-org/stlink/pull/593), [#597](https://github.com/stlink-org/stlink/pull/597), [#607](https://github.com/stlink-org/stlink/pull/607), [#612](https://github.com/stlink-org/stlink/pull/612), [#638](https://github.com/stlink-org/stlink/pull/638), [#661](https://github.com/stlink-org/stlink/pull/661), [#690](https://github.com/stlink-org/stlink/pull/690), [#807](https://github.com/stlink-org/stlink/pull/807), [#817](https://github.com/stlink-org/stlink/pull/817), [#818](https://github.com/stlink-org/stlink/pull/818), [#854](https://github.com/stlink-org/stlink/pull/854), [#868](https://github.com/stlink-org/stlink/pull/868), [#967](https://github.com/stlink-org/stlink/pull/967), [#979](https://github.com/stlink-org/stlink/pull/979), [#1043](https://github.com/stlink-org/stlink/pull/1043), [#1054](https://github.com/stlink-org/stlink/pull/1054), [#1092](https://github.com/stlink-org/stlink/pull/1092), [#1105](https://github.com/stlink-org/stlink/pull/1105), [#1113](https://github.com/stlink-org/stlink/pull/1113)) - Fixed old DFU serial number for STLINK programmers ([#417](https://github.com/stlink-org/stlink/pull/417), [#494](https://github.com/stlink-org/stlink/pull/494), [#1106](https://github.com/stlink-org/stlink/pull/1106)) - Use vl flashloader for all STM32F1 series ([#769](https://github.com/stlink-org/stlink/pull/769), [#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) - [regression] Changed timeout on flash write ([#787](https://github.com/stlink-org/stlink/pull/787), [#981](https://github.com/stlink-org/stlink/pull/981), [#987](https://github.com/stlink-org/stlink/pull/987)) @@ -52,7 +53,7 @@ Fixes: - Fixed `connect under reset` for `st-flash` and `st-util` ([#983](https://github.com/stlink-org/stlink/pull/983)) - Fix for `mmap() size_t overflow` in `st-flash` ([#988](https://github.com/stlink-org/stlink/pull/988), [#989](https://github.com/stlink-org/stlink/pull/989)) - [regression] `stlink-gui` installation issue on Ubuntu-18.04 ([#1001](https://github.com/stlink-org/stlink/pull/1001), [#1004](https://github.com/stlink-org/stlink/pull/1004), [#1006](https://github.com/stlink-org/stlink/pull/1006)) -- `st-util`: wrong register values passed to `gdb` (STLink/V2) ([#1002](https://github.com/stlink-org/stlink/pull/1002), [#1011](https://github.com/stlink-org/stlink/pull/1011), [#1026](https://github.com/stlink-org/stlink/pull/1026), [#1027](https://github.com/stlink-org/stlink/pull/1027), [#1064](https://github.com/stlink-org/stlink/pull/1064), [#1065](https://github.com/stlink-org/stlink/pull/1065)) +- `st-util`: wrong register values passed to `gdb` (STLink/V2) ([#1002](https://github.com/stlink-org/stlink/pull/1002), [#1011](https://github.com/stlink-org/stlink/pull/1011), [#1026](https://github.com/stlink-org/stlink/pull/1026), [#1027](https://github.com/stlink-org/stlink/pull/1027), [#1038](https://github.com/stlink-org/stlink/pull/1038),[#1064](https://github.com/stlink-org/stlink/pull/1064), [#1065](https://github.com/stlink-org/stlink/pull/1065)) - GDB: Fixed problems with target description ([#1013](https://github.com/stlink-org/stlink/pull/1013), [#1088](https://github.com/stlink-org/stlink/pull/1088), [#1109](https://github.com/stlink-org/stlink/pull/1109)) - [doc] Fixed wrong path for `rules.d` folder ([#1020](https://github.com/stlink-org/stlink/pull/1020)) - Fixed support for STLINK/V1 programmer ([#1045](https://github.com/stlink-org/stlink/pull/1045), [#1105](https://github.com/stlink-org/stlink/pull/1105)) @@ -61,7 +62,7 @@ Fixes: - Bugfixes for compilation with clang ([#1076](https://github.com/stlink-org/stlink/pull/1076), [#1078](https://github.com/stlink-org/stlink/pull/1078)) - Fixed compilation with GCC 11 ([#1077](https://github.com/stlink-org/stlink/pull/1077)) - [regression] Flash_loader: increased wait rounds for slow boards ([#1085](https://github.com/stlink-org/stlink/pull/1085)) -- Fixed support for writing option bytes ([#1102](https://github.com/stlink-org/stlink/pull/1102)) +- Fixed support for writing option bytes ([#1102](https://github.com/stlink-org/stlink/pull/1102), [#1128](https://github.com/stlink-org/stlink/pull/1128)) - [doc] Corrected spelling mistake in bug report template ([#1103](https://github.com/stlink-org/stlink/pull/1103)) - Fixed STM32WB55 reading DEBUG IDCODE from the wrong address ([#1100](https://github.com/stlink-org/stlink/pull/1100), [#1101](https://github.com/stlink-org/stlink/pull/1101)) - Applied missing changes to tests ([#1119](https://github.com/stlink-org/stlink/pull/1119)) @@ -75,7 +76,7 @@ This release drops support for some older operating systems. Check project READM Features: -- Basic compatibility for STLink/V3 programmer ([#271](https://github.com/stlink-org/stlink/pull/271), [#863](https://github.com/stlink-org/stlink/pull/863), [#954](https://github.com/stlink-org/stlink/pull/954)) +- Basic compatibility for STLink/V3 programmer ([#271](https://github.com/stlink-org/stlink/pull/271), [#863](https://github.com/stlink-org/stlink/pull/863), [#954](https://github.com/stlink-org/stlink/pull/954), [#1023](https://github.com/stlink-org/stlink/pull/1023)) - Added support for JTAG command API v2 & distinguish protocol versions v1 and v2 - Compatibility with the STLink/V3 firmware which dropped support for the previous API v1 - As of firmware version J11 the STLink/V1 programmer supports API v2 commands as well @@ -142,6 +143,7 @@ Updates & changes: Fixes: +- Improvements and fixes of the flash loaders, unification of the reset function ([#244](https://github.com/stlink-org/stlink/pull/244), [#382](https://github.com/stlink-org/stlink/pull/382), [#705](https://github.com/stlink-org/stlink/pull/705), [#980](https://github.com/stlink-org/stlink/pull/980), [#995](https://github.com/stlink-org/stlink/pull/995), [#1115](https://github.com/stlink-org/stlink/pull/1115), [#1117](https://github.com/stlink-org/stlink/pull/1117), [#1122](https://github.com/stlink-org/stlink/pull/1122), [#1124](https://github.com/stlink-org/stlink/pull/1124)) - Fixed wait-loop for `flash_loader_run()` ([#290](https://github.com/stlink-org/stlink/pull/290)) - Better argument parsing for CLI tools: `stlink_open_usb` can address v1, v2, v3 ([#378](https://github.com/stlink-org/stlink/pull/378), [#922](https://github.com/stlink-org/stlink/pull/922)) - Clear the PG bit before setting the `PER` bit ([#579](https://github.com/stlink-org/stlink/pull/579), [#876](https://github.com/stlink-org/stlink/pull/876)) @@ -163,6 +165,7 @@ Fixes: - Set static link for `libssp` (stack-smashing protection) ([#960](https://github.com/stlink-org/stlink/pull/960), [#961](https://github.com/stlink-org/stlink/pull/961)) - Fixed udev rules installing to wrong directory ([#966](https://github.com/stlink-org/stlink/pull/966)) - Fixed formatting for options display in `st-flash` & `st-info` (commits [#c783d0e](https://github.com/stlink-org/stlink/commit/c783d0e777ccc83a7a8be26a4f4d3414e0478560) and [#562cd24](https://github.com/stlink-org/stlink/commit/562cd2496e696dbd22950925866aac662d81ee5f)) +- Fixed reading of chip ID on Cortex-M0+ core ([#1125](https://github.com/stlink-org/stlink/pull/1125), [#1126](https://github.com/stlink-org/stlink/pull/1126)) # v1.6.0 From 9c1315a73296841ed3c25b4ea9500c187ab8236d Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Fri, 16 Apr 2021 00:10:20 +0200 Subject: [PATCH 62/65] Fixed GitHub Actions code scanning alerts --- src/common.c | 6800 ++++++++++++++++++++------------------ src/st-trace/trace.c | 990 +++--- src/stlink-lib/logging.c | 127 +- 3 files changed, 4089 insertions(+), 3828 deletions(-) diff --git a/src/common.c b/src/common.c index 57322cefd..4541aa31c 100644 --- a/src/common.c +++ b/src/common.c @@ -1,20 +1,20 @@ #define DEBUG_FLASH 0 #include +#include #include #include #include -#include #include -#include #include -#include #include +#include +#include -#include +#include #include #include -#include +#include #ifdef STLINK_HAVE_SYS_MMAN_H #include @@ -35,7 +35,8 @@ /* stm32f FPEC flash controller interface, pm0063 manual */ // TODO - all of this needs to be abstracted out.... -// STM32F05x is identical, based on RM0091 (DM00031936, Doc ID 018940 Rev 2, August 2012) +// STM32F05x is identical, based on RM0091 (DM00031936, Doc ID 018940 Rev 2, +// August 2012) #define FLASH_REGS_ADDR 0x40022000 #define FLASH_REGS_SIZE 0x28 @@ -48,7 +49,8 @@ #define FLASH_OBR (FLASH_REGS_ADDR + 0x1c) #define FLASH_WRPR (FLASH_REGS_ADDR + 0x20) -// STM32F10x_XL has two flash memory banks with separate registers to control the second bank. +// STM32F10x_XL has two flash memory banks with separate registers to control +// the second bank. #define FLASH_KEYR2 (FLASH_REGS_ADDR + 0x44) #define FLASH_SR2 (FLASH_REGS_ADDR + 0x4c) #define FLASH_CR2 (FLASH_REGS_ADDR + 0x50) @@ -128,113 +130,112 @@ // Mostly the same as STM32G0 chips, but there are a few extra // registers because 'cat 3' devices can have two Flash banks. #define STM32G4_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR) -#define STM32G4_FLASH_PDKEYR (STM32G4_FLASH_REGS_ADDR + 0x04) -#define STM32G4_FLASH_PCROP1SR (STM32G4_FLASH_REGS_ADDR + 0x24) -#define STM32G4_FLASH_PCROP1ER (STM32G4_FLASH_REGS_ADDR + 0x28) -#define STM32G4_FLASH_WRP1AR (STM32G4_FLASH_REGS_ADDR + 0x2C) -#define STM32G4_FLASH_WRP1BR (STM32G4_FLASH_REGS_ADDR + 0x30) -#define STM32G4_FLASH_PCROP2SR (STM32G4_FLASH_REGS_ADDR + 0x44) -#define STM32G4_FLASH_PCROP2ER (STM32G4_FLASH_REGS_ADDR + 0x48) -#define STM32G4_FLASH_WRP2AR (STM32G4_FLASH_REGS_ADDR + 0x4C) -#define STM32G4_FLASH_WRP2BR (STM32G4_FLASH_REGS_ADDR + 0x50) -#define STM32G4_FLASH_SEC1R (STM32G4_FLASH_REGS_ADDR + 0x70) -#define STM32G4_FLASH_SEC2R (STM32G4_FLASH_REGS_ADDR + 0x74) +#define STM32G4_FLASH_PDKEYR (STM32G4_FLASH_REGS_ADDR + 0x04) +#define STM32G4_FLASH_PCROP1SR (STM32G4_FLASH_REGS_ADDR + 0x24) +#define STM32G4_FLASH_PCROP1ER (STM32G4_FLASH_REGS_ADDR + 0x28) +#define STM32G4_FLASH_WRP1AR (STM32G4_FLASH_REGS_ADDR + 0x2C) +#define STM32G4_FLASH_WRP1BR (STM32G4_FLASH_REGS_ADDR + 0x30) +#define STM32G4_FLASH_PCROP2SR (STM32G4_FLASH_REGS_ADDR + 0x44) +#define STM32G4_FLASH_PCROP2ER (STM32G4_FLASH_REGS_ADDR + 0x48) +#define STM32G4_FLASH_WRP2AR (STM32G4_FLASH_REGS_ADDR + 0x4C) +#define STM32G4_FLASH_WRP2BR (STM32G4_FLASH_REGS_ADDR + 0x50) +#define STM32G4_FLASH_SEC1R (STM32G4_FLASH_REGS_ADDR + 0x70) +#define STM32G4_FLASH_SEC2R (STM32G4_FLASH_REGS_ADDR + 0x74) // G0/G4 FLASH control register -#define STM32Gx_FLASH_CR_PG (0) /* Program */ -#define STM32Gx_FLASH_CR_PER (1) /* Page erase */ -#define STM32Gx_FLASH_CR_MER1 (2) /* Mass erase */ -#define STM32Gx_FLASH_CR_PNB (3) /* Page number */ -#define STM32G0_FLASH_CR_PNG_LEN (5) /* STM32G0: 5 page number bits */ -#define STM32G4_FLASH_CR_PNG_LEN (7) /* STM32G4: 7 page number bits */ -#define STM32Gx_FLASH_CR_MER2 (15) /* Mass erase (2nd bank)*/ -#define STM32Gx_FLASH_CR_STRT (16) /* Start */ -#define STM32Gx_FLASH_CR_OPTSTRT (17) /* Start of modification of option bytes */ -#define STM32Gx_FLASH_CR_FSTPG (18) /* Fast programming */ -#define STM32Gx_FLASH_CR_EOPIE (24) /* End of operation interrupt enable */ -#define STM32Gx_FLASH_CR_ERRIE (25) /* Error interrupt enable */ -#define STM32Gx_FLASH_CR_OBL_LAUNCH (27) /* Forces the option byte loading */ -#define STM32Gx_FLASH_CR_OPTLOCK (30) /* Options Lock */ -#define STM32Gx_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ +#define STM32Gx_FLASH_CR_PG (0) /* Program */ +#define STM32Gx_FLASH_CR_PER (1) /* Page erase */ +#define STM32Gx_FLASH_CR_MER1 (2) /* Mass erase */ +#define STM32Gx_FLASH_CR_PNB (3) /* Page number */ +#define STM32G0_FLASH_CR_PNG_LEN (5) /* STM32G0: 5 page number bits */ +#define STM32G4_FLASH_CR_PNG_LEN (7) /* STM32G4: 7 page number bits */ +#define STM32Gx_FLASH_CR_MER2 (15) /* Mass erase (2nd bank)*/ +#define STM32Gx_FLASH_CR_STRT (16) /* Start */ +#define STM32Gx_FLASH_CR_OPTSTRT \ + (17) /* Start of modification of option bytes */ +#define STM32Gx_FLASH_CR_FSTPG (18) /* Fast programming */ +#define STM32Gx_FLASH_CR_EOPIE (24) /* End of operation interrupt enable */ +#define STM32Gx_FLASH_CR_ERRIE (25) /* Error interrupt enable */ +#define STM32Gx_FLASH_CR_OBL_LAUNCH (27) /* Forces the option byte loading */ +#define STM32Gx_FLASH_CR_OPTLOCK (30) /* Options Lock */ +#define STM32Gx_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ // G0/G4 FLASH status register #define STM32Gx_FLASH_SR_ERROR_MASK (0x3fa) -#define STM32Gx_FLASH_SR_PROGERR (3) -#define STM32Gx_FLASH_SR_WRPERR (4) -#define STM32Gx_FLASH_SR_PGAERR (5) -#define STM32Gx_FLASH_SR_BSY (16) /* FLASH_SR Busy */ -#define STM32Gx_FLASH_SR_EOP (0) /* FLASH_EOP End of Operation */ +#define STM32Gx_FLASH_SR_PROGERR (3) +#define STM32Gx_FLASH_SR_WRPERR (4) +#define STM32Gx_FLASH_SR_PGAERR (5) +#define STM32Gx_FLASH_SR_BSY (16) /* FLASH_SR Busy */ +#define STM32Gx_FLASH_SR_EOP (0) /* FLASH_EOP End of Operation */ // G4 FLASH option register -#define STM32G4_FLASH_OPTR_DBANK (22) /* FLASH_OPTR Dual Bank Mode */ +#define STM32G4_FLASH_OPTR_DBANK (22) /* FLASH_OPTR Dual Bank Mode */ // WB (RM0434) #define STM32WB_FLASH_REGS_ADDR ((uint32_t)0x58004000) -#define STM32WB_FLASH_ACR (STM32WB_FLASH_REGS_ADDR + 0x00) -#define STM32WB_FLASH_KEYR (STM32WB_FLASH_REGS_ADDR + 0x08) -#define STM32WB_FLASH_OPT_KEYR (STM32WB_FLASH_REGS_ADDR + 0x0C) -#define STM32WB_FLASH_SR (STM32WB_FLASH_REGS_ADDR + 0x10) -#define STM32WB_FLASH_CR (STM32WB_FLASH_REGS_ADDR + 0x14) -#define STM32WB_FLASH_ECCR (STM32WB_FLASH_REGS_ADDR + 0x18) -#define STM32WB_FLASH_OPTR (STM32WB_FLASH_REGS_ADDR + 0x20) +#define STM32WB_FLASH_ACR (STM32WB_FLASH_REGS_ADDR + 0x00) +#define STM32WB_FLASH_KEYR (STM32WB_FLASH_REGS_ADDR + 0x08) +#define STM32WB_FLASH_OPT_KEYR (STM32WB_FLASH_REGS_ADDR + 0x0C) +#define STM32WB_FLASH_SR (STM32WB_FLASH_REGS_ADDR + 0x10) +#define STM32WB_FLASH_CR (STM32WB_FLASH_REGS_ADDR + 0x14) +#define STM32WB_FLASH_ECCR (STM32WB_FLASH_REGS_ADDR + 0x18) +#define STM32WB_FLASH_OPTR (STM32WB_FLASH_REGS_ADDR + 0x20) #define STM32WB_FLASH_PCROP1ASR (STM32WB_FLASH_REGS_ADDR + 0x24) #define STM32WB_FLASH_PCROP1AER (STM32WB_FLASH_REGS_ADDR + 0x28) -#define STM32WB_FLASH_WRP1AR (STM32WB_FLASH_REGS_ADDR + 0x2C) -#define STM32WB_FLASH_WRP1BR (STM32WB_FLASH_REGS_ADDR + 0x30) +#define STM32WB_FLASH_WRP1AR (STM32WB_FLASH_REGS_ADDR + 0x2C) +#define STM32WB_FLASH_WRP1BR (STM32WB_FLASH_REGS_ADDR + 0x30) #define STM32WB_FLASH_PCROP1BSR (STM32WB_FLASH_REGS_ADDR + 0x34) #define STM32WB_FLASH_PCROP1BER (STM32WB_FLASH_REGS_ADDR + 0x38) -#define STM32WB_FLASH_IPCCBR (STM32WB_FLASH_REGS_ADDR + 0x3C) -#define STM32WB_FLASH_C2ACR (STM32WB_FLASH_REGS_ADDR + 0x5C) -#define STM32WB_FLASH_C2SR (STM32WB_FLASH_REGS_ADDR + 0x60) -#define STM32WB_FLASH_C2CR (STM32WB_FLASH_REGS_ADDR + 0x64) -#define STM32WB_FLASH_SFR (STM32WB_FLASH_REGS_ADDR + 0x80) -#define STM32WB_FLASH_SRRVR (STM32WB_FLASH_REGS_ADDR + 0x84) +#define STM32WB_FLASH_IPCCBR (STM32WB_FLASH_REGS_ADDR + 0x3C) +#define STM32WB_FLASH_C2ACR (STM32WB_FLASH_REGS_ADDR + 0x5C) +#define STM32WB_FLASH_C2SR (STM32WB_FLASH_REGS_ADDR + 0x60) +#define STM32WB_FLASH_C2CR (STM32WB_FLASH_REGS_ADDR + 0x64) +#define STM32WB_FLASH_SFR (STM32WB_FLASH_REGS_ADDR + 0x80) +#define STM32WB_FLASH_SRRVR (STM32WB_FLASH_REGS_ADDR + 0x84) // WB Flash control register. -#define STM32WB_FLASH_CR_STRT (16) /* Start */ -#define STM32WB_FLASH_CR_OPTLOCK (30) /* Option Lock */ -#define STM32WB_FLASH_CR_LOCK (31) /* Lock */ +#define STM32WB_FLASH_CR_STRT (16) /* Start */ +#define STM32WB_FLASH_CR_OPTLOCK (30) /* Option Lock */ +#define STM32WB_FLASH_CR_LOCK (31) /* Lock */ // WB Flash status register. #define STM32WB_FLASH_SR_ERROR_MASK (0x3f8) /* SR [9:3] */ -#define STM32WB_FLASH_SR_PROGERR (3) /* Programming alignment error */ -#define STM32WB_FLASH_SR_WRPERR (4) /* Write protection error */ -#define STM32WB_FLASH_SR_PGAERR (5) /* Programming error */ -#define STM32WB_FLASH_SR_BSY (16) /* Busy */ +#define STM32WB_FLASH_SR_PROGERR (3) /* Programming alignment error */ +#define STM32WB_FLASH_SR_WRPERR (4) /* Write protection error */ +#define STM32WB_FLASH_SR_PGAERR (5) /* Programming error */ +#define STM32WB_FLASH_SR_BSY (16) /* Busy */ // 32L4 register base is at FLASH_REGS_ADDR (0x40022000) -#define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) -#define STM32L4_FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x0C) -#define STM32L4_FLASH_SR (FLASH_REGS_ADDR + 0x10) -#define STM32L4_FLASH_CR (FLASH_REGS_ADDR + 0x14) -#define STM32L4_FLASH_OPTR (FLASH_REGS_ADDR + 0x20) +#define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) +#define STM32L4_FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x0C) +#define STM32L4_FLASH_SR (FLASH_REGS_ADDR + 0x10) +#define STM32L4_FLASH_CR (FLASH_REGS_ADDR + 0x14) +#define STM32L4_FLASH_OPTR (FLASH_REGS_ADDR + 0x20) #define STM32L4_FLASH_SR_ERROR_MASK 0x3f8 /* SR [9:3] */ -#define STM32L4_FLASH_SR_PROGERR 3 -#define STM32L4_FLASH_SR_WRPERR 4 -#define STM32L4_FLASH_SR_PGAERR 5 -#define STM32L4_FLASH_SR_BSY 16 - -#define STM32L4_FLASH_CR_LOCK 31 /* Lock control register */ -#define STM32L4_FLASH_CR_OPTLOCK 30 /* Lock option bytes */ -#define STM32L4_FLASH_CR_PG 0 /* Program */ -#define STM32L4_FLASH_CR_PER 1 /* Page erase */ -#define STM32L4_FLASH_CR_MER1 2 /* Bank 1 erase */ -#define STM32L4_FLASH_CR_MER2 15 /* Bank 2 erase */ -#define STM32L4_FLASH_CR_STRT 16 /* Start command */ -#define STM32L4_FLASH_CR_OPTSTRT 17 /* Start writing option bytes */ -#define STM32L4_FLASH_CR_BKER 11 /* Bank select for page erase */ -#define STM32L4_FLASH_CR_PNB 3 /* Page number (8 bits) */ +#define STM32L4_FLASH_SR_PROGERR 3 +#define STM32L4_FLASH_SR_WRPERR 4 +#define STM32L4_FLASH_SR_PGAERR 5 +#define STM32L4_FLASH_SR_BSY 16 + +#define STM32L4_FLASH_CR_LOCK 31 /* Lock control register */ +#define STM32L4_FLASH_CR_OPTLOCK 30 /* Lock option bytes */ +#define STM32L4_FLASH_CR_PG 0 /* Program */ +#define STM32L4_FLASH_CR_PER 1 /* Page erase */ +#define STM32L4_FLASH_CR_MER1 2 /* Bank 1 erase */ +#define STM32L4_FLASH_CR_MER2 15 /* Bank 2 erase */ +#define STM32L4_FLASH_CR_STRT 16 /* Start command */ +#define STM32L4_FLASH_CR_OPTSTRT 17 /* Start writing option bytes */ +#define STM32L4_FLASH_CR_BKER 11 /* Bank select for page erase */ +#define STM32L4_FLASH_CR_PNB 3 /* Page number (8 bits) */ #define STM32L4_FLASH_CR_OBL_LAUNCH 27 /* Option bytes reload */ // Bits requesting flash operations (useful when we want to clear them) -#define STM32L4_FLASH_CR_OPBITS \ - (uint32_t)((1lu << STM32L4_FLASH_CR_PG) | \ - (1lu << STM32L4_FLASH_CR_PER) | \ - (1lu << STM32L4_FLASH_CR_MER1) | \ - (1lu << STM32L4_FLASH_CR_MER1)) +#define STM32L4_FLASH_CR_OPBITS \ + (uint32_t)((1lu << STM32L4_FLASH_CR_PG) | (1lu << STM32L4_FLASH_CR_PER) | \ + (1lu << STM32L4_FLASH_CR_MER1) | (1lu << STM32L4_FLASH_CR_MER1)) // Page is fully specified by BKER and PNB #define STM32L4_FLASH_CR_PAGEMASK (uint32_t)(0x1fflu << STM32L4_FLASH_CR_PNB) -#define STM32L4_FLASH_OPTR_DUALBANK 21 +#define STM32L4_FLASH_OPTR_DUALBANK 21 // STM32L0x flash register base and offsets RM0090 - DM00031020.pdf #define STM32L0_FLASH_REGS_ADDR ((uint32_t)0x40022000) @@ -245,21 +246,21 @@ #define STM32L0_FLASH_OBL_LAUNCH (18) #define STM32L0_FLASH_SR_ERROR_MASK 0x00013F00 -#define STM32L0_FLASH_SR_WRPERR 8 -#define STM32L0_FLASH_SR_PGAERR 9 +#define STM32L0_FLASH_SR_WRPERR 8 +#define STM32L0_FLASH_SR_PGAERR 9 #define STM32L0_FLASH_SR_NOTZEROERR 16 -#define FLASH_ACR_OFF ((uint32_t) 0x00) -#define FLASH_PECR_OFF ((uint32_t) 0x04) -#define FLASH_PDKEYR_OFF ((uint32_t) 0x08) -#define FLASH_PEKEYR_OFF ((uint32_t) 0x0c) -#define FLASH_PRGKEYR_OFF ((uint32_t) 0x10) -#define FLASH_OPTKEYR_OFF ((uint32_t) 0x14) -#define FLASH_SR_OFF ((uint32_t) 0x18) -#define FLASH_OBR_OFF ((uint32_t) 0x1c) -#define FLASH_WRPR_OFF ((uint32_t) 0x20) - -//STM32F7 +#define FLASH_ACR_OFF ((uint32_t)0x00) +#define FLASH_PECR_OFF ((uint32_t)0x04) +#define FLASH_PDKEYR_OFF ((uint32_t)0x08) +#define FLASH_PEKEYR_OFF ((uint32_t)0x0c) +#define FLASH_PRGKEYR_OFF ((uint32_t)0x10) +#define FLASH_OPTKEYR_OFF ((uint32_t)0x14) +#define FLASH_SR_OFF ((uint32_t)0x18) +#define FLASH_OBR_OFF ((uint32_t)0x1c) +#define FLASH_WRPR_OFF ((uint32_t)0x20) + +// STM32F7 #define FLASH_F7_REGS_ADDR ((uint32_t)0x40023c00) #define FLASH_F7_KEYR (FLASH_F7_REGS_ADDR + 0x04) #define FLASH_F7_OPT_KEYR (FLASH_F7_REGS_ADDR + 0x08) @@ -279,14 +280,17 @@ #define FLASH_F7_SR_PGP_ERR 6 /* Programming parallelism error */ #define FLASH_F7_SR_PGA_ERR 5 /* Programming alignment error */ #define FLASH_F7_SR_WRP_ERR 4 /* Write protection error */ -#define FLASH_F7_SR_OP_ERR 1 /* Operation error */ -#define FLASH_F7_SR_EOP 0 /* End of operation */ +#define FLASH_F7_SR_OP_ERR 1 /* Operation error */ +#define FLASH_F7_SR_EOP 0 /* End of operation */ #define FLASH_F7_OPTCR1_BOOT_ADD0 0 #define FLASH_F7_OPTCR1_BOOT_ADD1 16 -#define FLASH_F7_SR_ERROR_MASK ((1 << FLASH_F7_SR_ERS_ERR) | (1 << FLASH_F7_SR_PGP_ERR) | (1 << FLASH_F7_SR_PGA_ERR) | (1 << FLASH_F7_SR_WRP_ERR) | (1 << FLASH_F7_SR_OP_ERR)) +#define FLASH_F7_SR_ERROR_MASK \ + ((1 << FLASH_F7_SR_ERS_ERR) | (1 << FLASH_F7_SR_PGP_ERR) | \ + (1 << FLASH_F7_SR_PGA_ERR) | (1 << FLASH_F7_SR_WRP_ERR) | \ + (1 << FLASH_F7_SR_OP_ERR)) -//STM32F4 +// STM32F4 #define FLASH_F4_REGS_ADDR ((uint32_t)0x40023c00) #define FLASH_F4_KEYR (FLASH_F4_REGS_ADDR + 0x04) #define FLASH_F4_OPT_KEYR (FLASH_F4_REGS_ADDR + 0x08) @@ -301,9 +305,9 @@ #define FLASH_F4_CR_SNB 3 #define FLASH_F4_CR_SNB_MASK 0xf8 #define FLASH_F4_SR_ERROR_MASK 0x000000F0 -#define FLASH_F4_SR_PGAERR 5 -#define FLASH_F4_SR_WRPERR 4 -#define FLASH_F4_SR_BSY 16 +#define FLASH_F4_SR_PGAERR 5 +#define FLASH_F4_SR_WRPERR 4 +#define FLASH_F4_SR_BSY 16 // STM32F2 #define FLASH_F2_REGS_ADDR ((uint32_t)0x40023c00) @@ -327,15 +331,17 @@ #define FLASH_H7_CR_SER 2 #define FLASH_H7_CR_BER 3 #define FLASH_H7_CR_PSIZE 4 -#define FLASH_H7_CR_START(chipid) (chipid==STLINK_CHIPID_STM32_H7AX?5:7) +#define FLASH_H7_CR_START(chipid) (chipid == STLINK_CHIPID_STM32_H7AX ? 5 : 7) #define FLASH_H7_CR_SNB 8 #define FLASH_H7_CR_SNB_MASK 0x700 -#define FLASH_H7_SR_QW 2 +#define FLASH_H7_SR_QW 2 #define FLASH_H7_SR_WRPERR 17 #define FLASH_H7_SR_PGSERR 18 #define FLASH_H7_SR_STRBERR 19 -#define FLASH_H7_SR_ERROR_MASK ((1 << FLASH_H7_SR_PGSERR) | (1 << FLASH_H7_SR_STRBERR) | (1 << FLASH_H7_SR_WRPERR)) +#define FLASH_H7_SR_ERROR_MASK \ + ((1 << FLASH_H7_SR_PGSERR) | (1 << FLASH_H7_SR_STRBERR) | \ + (1 << FLASH_H7_SR_WRPERR)) #define FLASH_H7_OPTCR_OPTLOCK 0 #define FLASH_H7_OPTCR_OPTSTART 1 @@ -362,1189 +368,1188 @@ #define FLASH_H7_OPTSR_CUR (FLASH_H7_REGS_ADDR + 0x1c) #define FLASH_H7_OPTCCR (FLASH_H7_REGS_ADDR + 0x24) -#define STM32F0_DBGMCU_CR 0xE0042004 -#define STM32F0_DBGMCU_CR_IWDG_STOP 8 -#define STM32F0_DBGMCU_CR_WWDG_STOP 9 +#define STM32F0_DBGMCU_CR 0xE0042004 +#define STM32F0_DBGMCU_CR_IWDG_STOP 8 +#define STM32F0_DBGMCU_CR_WWDG_STOP 9 -#define STM32F4_DBGMCU_APB1FZR1 0xE0042008 +#define STM32F4_DBGMCU_APB1FZR1 0xE0042008 #define STM32F4_DBGMCU_APB1FZR1_WWDG_STOP 11 #define STM32F4_DBGMCU_APB1FZR1_IWDG_STOP 12 -#define STM32L0_DBGMCU_APB1_FZ 0x40015808 -#define STM32L0_DBGMCU_APB1_FZ_WWDG_STOP 11 -#define STM32L0_DBGMCU_APB1_FZ_IWDG_STOP 12 +#define STM32L0_DBGMCU_APB1_FZ 0x40015808 +#define STM32L0_DBGMCU_APB1_FZ_WWDG_STOP 11 +#define STM32L0_DBGMCU_APB1_FZ_IWDG_STOP 12 -#define STM32H7_DBGMCU_APB1HFZ 0x5C001054 -#define STM32H7_DBGMCU_APB1HFZ_IWDG_STOP 18 +#define STM32H7_DBGMCU_APB1HFZ 0x5C001054 +#define STM32H7_DBGMCU_APB1HFZ_IWDG_STOP 18 -#define STM32WB_DBGMCU_APB1FZR1 0xE004203C +#define STM32WB_DBGMCU_APB1FZR1 0xE004203C #define STM32WB_DBGMCU_APB1FZR1_WWDG_STOP 11 #define STM32WB_DBGMCU_APB1FZR1_IWDG_STOP 12 -#define STM32F1_RCC_AHBENR 0x40021014 -#define STM32F1_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN +#define STM32F1_RCC_AHBENR 0x40021014 +#define STM32F1_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN -#define STM32F4_RCC_AHB1ENR 0x40023830 -#define STM32F4_RCC_DMAEN 0x00600000 // DMA2EN | DMA1EN +#define STM32F4_RCC_AHB1ENR 0x40023830 +#define STM32F4_RCC_DMAEN 0x00600000 // DMA2EN | DMA1EN -#define STM32G0_RCC_AHBENR 0x40021038 -#define STM32G0_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN +#define STM32G0_RCC_AHBENR 0x40021038 +#define STM32G0_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN -#define STM32G4_RCC_AHB1ENR 0x40021048 -#define STM32G4_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN +#define STM32G4_RCC_AHB1ENR 0x40021048 +#define STM32G4_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN -#define STM32L0_RCC_AHBENR 0x40021030 -#define STM32L0_RCC_DMAEN 0x00000001 // DMAEN +#define STM32L0_RCC_AHBENR 0x40021030 +#define STM32L0_RCC_DMAEN 0x00000001 // DMAEN -#define STM32H7_RCC_AHB1ENR 0x58024538 -#define STM32H7_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN +#define STM32H7_RCC_AHB1ENR 0x58024538 +#define STM32H7_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN -#define STM32WB_RCC_AHB1ENR 0x58000048 -#define STM32WB_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN +#define STM32WB_RCC_AHB1ENR 0x58000048 +#define STM32WB_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN #define L1_WRITE_BLOCK_SIZE 0x80 #define L0_WRITE_BLOCK_SIZE 0x40 - // Endianness // https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html // These functions encode and decode little endian uint16 and uint32 values. -void write_uint32(unsigned char* buf, uint32_t ui) { - buf[0] = ui; - buf[1] = ui >> 8; - buf[2] = ui >> 16; - buf[3] = ui >> 24; +void write_uint32(unsigned char *buf, uint32_t ui) { + buf[0] = ui; + buf[1] = ui >> 8; + buf[2] = ui >> 16; + buf[3] = ui >> 24; } -void write_uint16(unsigned char* buf, uint16_t ui) { - buf[0] = ui ; - buf[1] = ui >> 8; +void write_uint16(unsigned char *buf, uint16_t ui) { + buf[0] = ui; + buf[1] = ui >> 8; } uint32_t read_uint32(const unsigned char *c, const int pt) { - return ((uint32_t)c[pt]) | ((uint32_t)c[pt+1] << 8) | ((uint32_t)c[pt+2] << 16) | ((uint32_t)c[pt+3] << 24) ; + return ((uint32_t)c[pt]) | ((uint32_t)c[pt + 1] << 8) | + ((uint32_t)c[pt + 2] << 16) | ((uint32_t)c[pt + 3] << 24); } uint16_t read_uint16(const unsigned char *c, const int pt) { - return ((uint16_t)c[pt]) | ((uint16_t)c[pt+1] << 8); + return ((uint16_t)c[pt]) | ((uint16_t)c[pt + 1] << 8); } +static uint32_t get_stm32l0_flash_base(stlink_t *sl) { + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_L0: + case STLINK_CHIPID_STM32_L0_CAT5: + case STLINK_CHIPID_STM32_L0_CAT2: + case STLINK_CHIPID_STM32_L011: + return (STM32L0_FLASH_REGS_ADDR); -static uint32_t get_stm32l0_flash_base(stlink_t *sl) -{ - switch (sl->chip_id) { - case STLINK_CHIPID_STM32_L0: - case STLINK_CHIPID_STM32_L0_CAT5: - case STLINK_CHIPID_STM32_L0_CAT2: - case STLINK_CHIPID_STM32_L011: - return(STM32L0_FLASH_REGS_ADDR); - - case STLINK_CHIPID_STM32_L1_CAT2: - case STLINK_CHIPID_STM32_L1_MEDIUM: - case STLINK_CHIPID_STM32_L1_MEDIUM_PLUS: - case STLINK_CHIPID_STM32_L1_HIGH: - return(STM32L1_FLASH_REGS_ADDR); + case STLINK_CHIPID_STM32_L1_CAT2: + case STLINK_CHIPID_STM32_L1_MEDIUM: + case STLINK_CHIPID_STM32_L1_MEDIUM_PLUS: + case STLINK_CHIPID_STM32_L1_HIGH: + return (STM32L1_FLASH_REGS_ADDR); - default: - WLOG("Flash base use default L0 address"); - return(STM32L0_FLASH_REGS_ADDR); - } + default: + WLOG("Flash base use default L0 address"); + return (STM32L0_FLASH_REGS_ADDR); + } } static uint32_t __attribute__((unused)) read_flash_rdp(stlink_t *sl) { - uint32_t rdp; - stlink_read_debug32(sl, FLASH_WRPR, &rdp); - return(rdp & 0xff); + uint32_t rdp; + stlink_read_debug32(sl, FLASH_WRPR, &rdp); + return (rdp & 0xff); } static inline uint32_t read_flash_cr(stlink_t *sl, unsigned bank) { - uint32_t reg, res; - - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - reg = FLASH_F4_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - reg = FLASH_F7_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - reg = STM32L4_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - reg = STM32WB_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - reg = (bank == BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; - } else { - reg = (bank == BANK_1)?FLASH_CR:FLASH_CR2; - } - - stlink_read_debug32(sl, reg, &res); + uint32_t reg, res; + + if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + reg = FLASH_F4_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + reg = FLASH_F7_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + reg = STM32L4_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + reg = STM32Gx_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + reg = STM32WB_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + } else { + reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + } + + stlink_read_debug32(sl, reg, &res); #if DEBUG_FLASH - fprintf(stdout, "CR:0x%x\n", res); + fprintf(stdout, "CR:0x%x\n", res); #endif - return(res); + return (res); } static inline unsigned int is_flash_locked(stlink_t *sl) { - /* return non zero for true */ - uint32_t cr_lock_shift; - uint32_t cr_reg; - uint32_t n; - - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { - cr_reg = FLASH_CR; - cr_lock_shift = FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - cr_reg = FLASH_F4_CR; - cr_lock_shift = FLASH_F4_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - cr_lock_shift = FLASH_F7_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; - cr_lock_shift = STM32L0_FLASH_PELOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - cr_lock_shift = STM32L4_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_lock_shift = STM32Gx_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - cr_lock_shift = STM32WB_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = FLASH_H7_CR1; - cr_lock_shift = FLASH_H7_CR_LOCK; - } else { - ELOG("unsupported flash method, abort\n"); - return(-1); - } - - stlink_read_debug32(sl, cr_reg, &n); - return(n & (1u << cr_lock_shift)); + /* return non zero for true */ + uint32_t cr_lock_shift; + uint32_t cr_reg; + uint32_t n; + + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + cr_reg = FLASH_CR; + cr_lock_shift = FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; + cr_lock_shift = FLASH_F4_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_lock_shift = FLASH_F7_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + cr_lock_shift = STM32L0_FLASH_PELOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + cr_lock_shift = STM32L4_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + cr_lock_shift = STM32Gx_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + cr_lock_shift = STM32WB_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; + cr_lock_shift = FLASH_H7_CR_LOCK; + } else { + ELOG("unsupported flash method, abort\n"); + return (-1); + } + + stlink_read_debug32(sl, cr_reg, &n); + return (n & (1u << cr_lock_shift)); } static void unlock_flash(stlink_t *sl) { - uint32_t key_reg, key2_reg = 0; - uint32_t flash_key1 = FLASH_KEY1; - uint32_t flash_key2 = FLASH_KEY2; - /* The unlock sequence consists of 2 write cycles where 2 key values are written - * to the FLASH_KEYR register. - * An invalid sequence results in a definitive lock of the FPEC block until next reset. - */ - - if (sl->flash_type == STLINK_FLASH_TYPE_F0) { - key_reg = FLASH_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - key_reg = FLASH_KEYR; - key2_reg = FLASH_KEYR2; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - key_reg = FLASH_F4_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - key_reg = FLASH_F7_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - key_reg = get_stm32l0_flash_base(sl) + FLASH_PEKEYR_OFF; - flash_key1 = FLASH_L0_PEKEY1; - flash_key2 = FLASH_L0_PEKEY2; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - key_reg = STM32L4_FLASH_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - key_reg = STM32Gx_FLASH_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - key_reg = STM32WB_FLASH_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - key_reg = FLASH_H7_KEYR1; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - key2_reg = FLASH_H7_KEYR2; - } - } else { - ELOG("unsupported flash method, abort\n"); - return; - } + uint32_t key_reg, key2_reg = 0; + uint32_t flash_key1 = FLASH_KEY1; + uint32_t flash_key2 = FLASH_KEY2; + /* The unlock sequence consists of 2 write cycles where 2 key values are + * written to the FLASH_KEYR register. An invalid sequence results in a + * definitive lock of the FPEC block until next reset. + */ + + if (sl->flash_type == STLINK_FLASH_TYPE_F0) { + key_reg = FLASH_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + key_reg = FLASH_KEYR; + key2_reg = FLASH_KEYR2; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + key_reg = FLASH_F4_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + key_reg = FLASH_F7_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + key_reg = get_stm32l0_flash_base(sl) + FLASH_PEKEYR_OFF; + flash_key1 = FLASH_L0_PEKEY1; + flash_key2 = FLASH_L0_PEKEY2; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + key_reg = STM32L4_FLASH_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + key_reg = STM32Gx_FLASH_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + key_reg = STM32WB_FLASH_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + key_reg = FLASH_H7_KEYR1; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + key2_reg = FLASH_H7_KEYR2; + } + } else { + ELOG("unsupported flash method, abort\n"); + return; + } - stlink_write_debug32(sl, key_reg, flash_key1); - stlink_write_debug32(sl, key_reg, flash_key2); + stlink_write_debug32(sl, key_reg, flash_key1); + stlink_write_debug32(sl, key_reg, flash_key2); - if (key2_reg) { - stlink_write_debug32(sl, key2_reg, flash_key1); - stlink_write_debug32(sl, key2_reg, flash_key2); - } + if (key2_reg) { + stlink_write_debug32(sl, key2_reg, flash_key1); + stlink_write_debug32(sl, key2_reg, flash_key2); + } } /* unlock flash if already locked */ static int unlock_flash_if(stlink_t *sl) { - if (is_flash_locked(sl)) { - unlock_flash(sl); + if (is_flash_locked(sl)) { + unlock_flash(sl); - if (is_flash_locked(sl)) { - WLOG("Failed to unlock flash!\n"); - return(-1); - } + if (is_flash_locked(sl)) { + WLOG("Failed to unlock flash!\n"); + return (-1); } + } - DLOG("Successfully unlocked flash\n"); - return(0); + DLOG("Successfully unlocked flash\n"); + return (0); } static void lock_flash(stlink_t *sl) { - uint32_t cr_lock_shift, cr_reg, n, cr2_reg = 0; - uint32_t cr_mask = 0xffffffffu; - - if (sl->flash_type == STLINK_FLASH_TYPE_F0) { - cr_reg = FLASH_CR; - cr_lock_shift = FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - cr_reg = FLASH_CR; - cr2_reg = FLASH_CR2; - cr_lock_shift = FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - cr_reg = FLASH_F4_CR; - cr_lock_shift = FLASH_F4_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - cr_lock_shift = FLASH_F7_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; - cr_lock_shift = STM32L0_FLASH_PELOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - cr_lock_shift = STM32L4_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_lock_shift = STM32Gx_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - cr_lock_shift = STM32WB_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = FLASH_H7_CR1; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - cr2_reg = FLASH_H7_CR2; - } - cr_lock_shift = FLASH_H7_CR_LOCK; - cr_mask = ~(1u << FLASH_H7_CR_SER); - } else { - ELOG("unsupported flash method, abort\n"); - return; - } + uint32_t cr_lock_shift, cr_reg, n, cr2_reg = 0; + uint32_t cr_mask = 0xffffffffu; + + if (sl->flash_type == STLINK_FLASH_TYPE_F0) { + cr_reg = FLASH_CR; + cr_lock_shift = FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + cr_reg = FLASH_CR; + cr2_reg = FLASH_CR2; + cr_lock_shift = FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; + cr_lock_shift = FLASH_F4_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_lock_shift = FLASH_F7_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + cr_lock_shift = STM32L0_FLASH_PELOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + cr_lock_shift = STM32L4_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + cr_lock_shift = STM32Gx_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + cr_lock_shift = STM32WB_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + cr2_reg = FLASH_H7_CR2; + } + cr_lock_shift = FLASH_H7_CR_LOCK; + cr_mask = ~(1u << FLASH_H7_CR_SER); + } else { + ELOG("unsupported flash method, abort\n"); + return; + } - stlink_read_debug32(sl, cr_reg, &n); - n &= cr_mask; - n |= (1u << cr_lock_shift); - stlink_write_debug32(sl, cr_reg, n); + stlink_read_debug32(sl, cr_reg, &n); + n &= cr_mask; + n |= (1u << cr_lock_shift); + stlink_write_debug32(sl, cr_reg, n); - if (cr2_reg) { - n = read_flash_cr(sl, BANK_2) | (1u << cr_lock_shift); - stlink_write_debug32(sl, cr2_reg, n); - } + if (cr2_reg) { + n = read_flash_cr(sl, BANK_2) | (1u << cr_lock_shift); + stlink_write_debug32(sl, cr2_reg, n); + } } static bool is_flash_option_locked(stlink_t *sl) { - uint32_t optlock_shift, optcr_reg; - int active_bit_level = 1; - uint32_t n; - - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - optcr_reg = FLASH_CR; - optlock_shift = FLASH_CR_OPTWRE; - active_bit_level = 0; /* bit is "option write enable", not lock */ - break; - case STLINK_FLASH_TYPE_F4: - optcr_reg = FLASH_F4_OPTCR; - optlock_shift = FLASH_F4_OPTCR_LOCK; - break; - case STLINK_FLASH_TYPE_F7: - optcr_reg = FLASH_F7_OPTCR; - optlock_shift = FLASH_F7_OPTCR_LOCK; - break; - case STLINK_FLASH_TYPE_L0: - optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; - optlock_shift = STM32L0_FLASH_OPTLOCK; - break; - case STLINK_FLASH_TYPE_L4: - optcr_reg = STM32L4_FLASH_CR; - optlock_shift = STM32L4_FLASH_CR_OPTLOCK; - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - optcr_reg = STM32Gx_FLASH_CR; - optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; - break; - case STLINK_FLASH_TYPE_WB: - optcr_reg = STM32WB_FLASH_CR; - optlock_shift = STM32WB_FLASH_CR_OPTLOCK; - break; - case STLINK_FLASH_TYPE_H7: - optcr_reg = FLASH_H7_OPTCR; - optlock_shift = FLASH_H7_OPTCR_OPTLOCK; - break; - default: - ELOG("unsupported flash method, abort\n"); - return -1; - } - - stlink_read_debug32(sl, optcr_reg, &n); - - if (active_bit_level == 0) { - return(!(n & (1u << optlock_shift))); - } - - return(n & (1u << optlock_shift)); - + uint32_t optlock_shift, optcr_reg; + int active_bit_level = 1; + uint32_t n; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + optcr_reg = FLASH_CR; + optlock_shift = FLASH_CR_OPTWRE; + active_bit_level = 0; /* bit is "option write enable", not lock */ + break; + case STLINK_FLASH_TYPE_F4: + optcr_reg = FLASH_F4_OPTCR; + optlock_shift = FLASH_F4_OPTCR_LOCK; + break; + case STLINK_FLASH_TYPE_F7: + optcr_reg = FLASH_F7_OPTCR; + optlock_shift = FLASH_F7_OPTCR_LOCK; + break; + case STLINK_FLASH_TYPE_L0: + optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + optlock_shift = STM32L0_FLASH_OPTLOCK; + break; + case STLINK_FLASH_TYPE_L4: + optcr_reg = STM32L4_FLASH_CR; + optlock_shift = STM32L4_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + optcr_reg = STM32Gx_FLASH_CR; + optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_WB: + optcr_reg = STM32WB_FLASH_CR; + optlock_shift = STM32WB_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_H7: + optcr_reg = FLASH_H7_OPTCR; + optlock_shift = FLASH_H7_OPTCR_OPTLOCK; + break; + default: + ELOG("unsupported flash method, abort\n"); + return -1; + } + + stlink_read_debug32(sl, optcr_reg, &n); + + if (active_bit_level == 0) { + return (!(n & (1u << optlock_shift))); + } + + return (n & (1u << optlock_shift)); } static int lock_flash_option(stlink_t *sl) { - uint32_t optlock_shift, optcr_reg, n, optcr2_reg = 0; - int active_bit_level = 1; - - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - optcr_reg = FLASH_CR; - optlock_shift = FLASH_CR_OPTWRE; - active_bit_level = 0; - break; - case STLINK_FLASH_TYPE_F4: - optcr_reg = FLASH_F4_OPTCR; - optlock_shift = FLASH_F4_OPTCR_LOCK; - break; - case STLINK_FLASH_TYPE_F7: - optcr_reg = FLASH_F7_OPTCR; - optlock_shift = FLASH_F7_OPTCR_LOCK; - break; - case STLINK_FLASH_TYPE_L0: - optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; - optlock_shift = STM32L0_FLASH_OPTLOCK; - break; - case STLINK_FLASH_TYPE_L4: - optcr_reg = STM32L4_FLASH_CR; - optlock_shift = STM32L4_FLASH_CR_OPTLOCK; - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - optcr_reg = STM32Gx_FLASH_CR; - optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; - break; - case STLINK_FLASH_TYPE_WB: - optcr_reg = STM32WB_FLASH_CR; - optlock_shift = STM32WB_FLASH_CR_OPTLOCK; - break; - case STLINK_FLASH_TYPE_H7: - optcr_reg = FLASH_H7_OPTCR; - optlock_shift = FLASH_H7_OPTCR_OPTLOCK; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) - optcr2_reg = FLASH_H7_OPTCR2; - break; - default: - ELOG("unsupported flash method, abort\n"); - return -1; - } - - stlink_read_debug32(sl, optcr_reg, &n); + uint32_t optlock_shift, optcr_reg, n, optcr2_reg = 0; + int active_bit_level = 1; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + optcr_reg = FLASH_CR; + optlock_shift = FLASH_CR_OPTWRE; + active_bit_level = 0; + break; + case STLINK_FLASH_TYPE_F4: + optcr_reg = FLASH_F4_OPTCR; + optlock_shift = FLASH_F4_OPTCR_LOCK; + break; + case STLINK_FLASH_TYPE_F7: + optcr_reg = FLASH_F7_OPTCR; + optlock_shift = FLASH_F7_OPTCR_LOCK; + break; + case STLINK_FLASH_TYPE_L0: + optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; + optlock_shift = STM32L0_FLASH_OPTLOCK; + break; + case STLINK_FLASH_TYPE_L4: + optcr_reg = STM32L4_FLASH_CR; + optlock_shift = STM32L4_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + optcr_reg = STM32Gx_FLASH_CR; + optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_WB: + optcr_reg = STM32WB_FLASH_CR; + optlock_shift = STM32WB_FLASH_CR_OPTLOCK; + break; + case STLINK_FLASH_TYPE_H7: + optcr_reg = FLASH_H7_OPTCR; + optlock_shift = FLASH_H7_OPTCR_OPTLOCK; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) + optcr2_reg = FLASH_H7_OPTCR2; + break; + default: + ELOG("unsupported flash method, abort\n"); + return -1; + } + + stlink_read_debug32(sl, optcr_reg, &n); + + if (active_bit_level == 0) { + n &= ~(1u << optlock_shift); + } else { + n |= (1u << optlock_shift); + } + + stlink_write_debug32(sl, optcr_reg, n); + + if (optcr2_reg) { + stlink_read_debug32(sl, optcr2_reg, &n); if (active_bit_level == 0) { - n &= ~(1u << optlock_shift); + n &= ~(1u << optlock_shift); } else { - n |= (1u << optlock_shift); + n |= (1u << optlock_shift); } - stlink_write_debug32(sl, optcr_reg, n); + stlink_write_debug32(sl, optcr2_reg, n); + } - if (optcr2_reg) { - stlink_read_debug32(sl, optcr2_reg, &n); - - if (active_bit_level == 0) { - n &= ~(1u << optlock_shift); - } else { - n |= (1u << optlock_shift); - } - - stlink_write_debug32(sl, optcr2_reg, n); - } - - return(0); + return (0); } static int unlock_flash_option(stlink_t *sl) { - uint32_t optkey_reg, optkey2_reg = 0; - uint32_t optkey1 = FLASH_OPTKEY1; - uint32_t optkey2 = FLASH_OPTKEY2; - - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - optkey_reg = FLASH_OPTKEYR; - optkey1 = FLASH_F0_OPTKEY1; - optkey2 = FLASH_F0_OPTKEY2; - break; - case STLINK_FLASH_TYPE_F4: - optkey_reg = FLASH_F4_OPT_KEYR; - break; - case STLINK_FLASH_TYPE_F7: - optkey_reg = FLASH_F7_OPT_KEYR; - break; - case STLINK_FLASH_TYPE_L0: - optkey_reg = get_stm32l0_flash_base(sl) + FLASH_OPTKEYR_OFF; - optkey1 = FLASH_L0_OPTKEY1; - optkey2 = FLASH_L0_OPTKEY2; - break; - case STLINK_FLASH_TYPE_L4: - optkey_reg = STM32L4_FLASH_OPTKEYR; - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - optkey_reg = STM32Gx_FLASH_OPTKEYR; - break; - case STLINK_FLASH_TYPE_WB: - optkey_reg = STM32WB_FLASH_OPT_KEYR; - break; - case STLINK_FLASH_TYPE_H7: - optkey_reg = FLASH_H7_OPT_KEYR; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) - optkey2_reg = FLASH_H7_OPT_KEYR2; - break; - default: - ELOG("unsupported flash method, abort\n"); - return(-1); - } - - stlink_write_debug32(sl, optkey_reg, optkey1); - stlink_write_debug32(sl, optkey_reg, optkey2); - - if (optkey2_reg) { - stlink_write_debug32(sl, optkey2_reg, optkey1); - stlink_write_debug32(sl, optkey2_reg, optkey2); - } - - return(0); + uint32_t optkey_reg, optkey2_reg = 0; + uint32_t optkey1 = FLASH_OPTKEY1; + uint32_t optkey2 = FLASH_OPTKEY2; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + optkey_reg = FLASH_OPTKEYR; + optkey1 = FLASH_F0_OPTKEY1; + optkey2 = FLASH_F0_OPTKEY2; + break; + case STLINK_FLASH_TYPE_F4: + optkey_reg = FLASH_F4_OPT_KEYR; + break; + case STLINK_FLASH_TYPE_F7: + optkey_reg = FLASH_F7_OPT_KEYR; + break; + case STLINK_FLASH_TYPE_L0: + optkey_reg = get_stm32l0_flash_base(sl) + FLASH_OPTKEYR_OFF; + optkey1 = FLASH_L0_OPTKEY1; + optkey2 = FLASH_L0_OPTKEY2; + break; + case STLINK_FLASH_TYPE_L4: + optkey_reg = STM32L4_FLASH_OPTKEYR; + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + optkey_reg = STM32Gx_FLASH_OPTKEYR; + break; + case STLINK_FLASH_TYPE_WB: + optkey_reg = STM32WB_FLASH_OPT_KEYR; + break; + case STLINK_FLASH_TYPE_H7: + optkey_reg = FLASH_H7_OPT_KEYR; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) + optkey2_reg = FLASH_H7_OPT_KEYR2; + break; + default: + ELOG("unsupported flash method, abort\n"); + return (-1); + } + + stlink_write_debug32(sl, optkey_reg, optkey1); + stlink_write_debug32(sl, optkey_reg, optkey2); + + if (optkey2_reg) { + stlink_write_debug32(sl, optkey2_reg, optkey1); + stlink_write_debug32(sl, optkey2_reg, optkey2); + } + + return (0); } static int unlock_flash_option_if(stlink_t *sl) { - if (is_flash_option_locked(sl)) { - if (unlock_flash_option(sl)) { - ELOG("Could not unlock flash option!\n"); - return(-1); - } + if (is_flash_option_locked(sl)) { + if (unlock_flash_option(sl)) { + ELOG("Could not unlock flash option!\n"); + return (-1); + } - if (is_flash_option_locked(sl)) { - ELOG("Failed to unlock flash option!\n"); - return(-1); - } + if (is_flash_option_locked(sl)) { + ELOG("Failed to unlock flash option!\n"); + return (-1); } + } - DLOG("Successfully unlocked flash option\n"); - return(0); + DLOG("Successfully unlocked flash option\n"); + return (0); } static void set_flash_cr_pg(stlink_t *sl, unsigned bank) { - uint32_t cr_reg, x; - - x = read_flash_cr(sl, bank); - - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - cr_reg = FLASH_F4_CR; - x |= 1 << FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - x |= 1 << FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - x &= ~STM32L4_FLASH_CR_OPBITS; - x |= (1 << STM32L4_FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - x |= (1 << FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - x |= (1 << FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = (bank == BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; - x |= (1 << FLASH_H7_CR_PG); - } else { - cr_reg = FLASH_CR; - x = (1 << FLASH_CR_PG); - } - - stlink_write_debug32(sl, cr_reg, x); + uint32_t cr_reg, x; + + x = read_flash_cr(sl, bank); + + if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; + x |= 1 << FLASH_CR_PG; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + x |= 1 << FLASH_CR_PG; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + x &= ~STM32L4_FLASH_CR_OPBITS; + x |= (1 << STM32L4_FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + x |= (1 << FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + x |= (1 << FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + x |= (1 << FLASH_H7_CR_PG); + } else { + cr_reg = FLASH_CR; + x = (1 << FLASH_CR_PG); + } + + stlink_write_debug32(sl, cr_reg, x); } static void clear_flash_cr_pg(stlink_t *sl, unsigned bank) { - uint32_t cr_reg, n; - uint32_t bit = FLASH_CR_PG; - - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - cr_reg = FLASH_F4_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = (bank == BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; - bit = FLASH_H7_CR_PG; - } else { - cr_reg = FLASH_CR; - } - - n = read_flash_cr(sl, bank) & ~(1 << bit); - stlink_write_debug32(sl, cr_reg, n); + uint32_t cr_reg, n; + uint32_t bit = FLASH_CR_PG; + + if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + bit = FLASH_H7_CR_PG; + } else { + cr_reg = FLASH_CR; + } + + n = read_flash_cr(sl, bank) & ~(1 << bit); + stlink_write_debug32(sl, cr_reg, n); } static void set_flash_cr_per(stlink_t *sl, unsigned bank) { - uint32_t cr_reg, val; + uint32_t cr_reg, val; - if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - } else { - cr_reg = (bank==BANK_1)?FLASH_CR:FLASH_CR2; - } + if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + } else { + cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + } - stlink_read_debug32(sl, cr_reg, &val); - val |= (1 << FLASH_CR_PER); - stlink_write_debug32(sl, cr_reg, val); + stlink_read_debug32(sl, cr_reg, &val); + val |= (1 << FLASH_CR_PER); + stlink_write_debug32(sl, cr_reg, val); } static void clear_flash_cr_per(stlink_t *sl, unsigned bank) { - uint32_t cr_reg; + uint32_t cr_reg; - if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - } else { - cr_reg = (bank==BANK_1)?FLASH_CR:FLASH_CR2; - } + if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + } else { + cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + } - const uint32_t n = read_flash_cr(sl, bank) & ~(1 << FLASH_CR_PER); - stlink_write_debug32(sl, cr_reg, n); + const uint32_t n = read_flash_cr(sl, bank) & ~(1 << FLASH_CR_PER); + stlink_write_debug32(sl, cr_reg, n); } static void set_flash_cr_mer(stlink_t *sl, bool v, unsigned bank) { - uint32_t val, cr_reg, cr_mer, cr_pg; - - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - cr_reg = FLASH_F4_CR; - cr_mer = 1 << FLASH_CR_MER; - cr_pg = 1 << FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - cr_mer = 1 << FLASH_CR_MER; - cr_pg = 1 << FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); - cr_pg = (1 << STM32L4_FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_mer = (1 << STM32Gx_FLASH_CR_MER1); - - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - cr_mer |= (1 << STM32Gx_FLASH_CR_MER2); - } - - cr_pg = (1 << FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - cr_mer = (1 << FLASH_CR_MER); - cr_pg = (1 << FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = (bank==BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; - cr_mer = (1 << FLASH_H7_CR_BER); - cr_pg = (1 << FLASH_H7_CR_PG); - } else { - cr_reg = (bank==BANK_1)?FLASH_CR:FLASH_CR2; - cr_mer = (1 << FLASH_CR_MER); - cr_pg = (1 << FLASH_CR_PG); - } - - stlink_read_debug32(sl, cr_reg, &val); - - if (val & cr_pg) { - // STM32F030 will drop MER bit if PG was set - val &= ~cr_pg; - stlink_write_debug32(sl, cr_reg, val); - } + uint32_t val, cr_reg, cr_mer, cr_pg; + + if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; + cr_mer = 1 << FLASH_CR_MER; + cr_pg = 1 << FLASH_CR_PG; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_mer = 1 << FLASH_CR_MER; + cr_pg = 1 << FLASH_CR_PG; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); + cr_pg = (1 << STM32L4_FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + cr_mer = (1 << STM32Gx_FLASH_CR_MER1); + + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + cr_mer |= (1 << STM32Gx_FLASH_CR_MER2); + } + + cr_pg = (1 << FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + cr_mer = (1 << FLASH_CR_MER); + cr_pg = (1 << FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + cr_mer = (1 << FLASH_H7_CR_BER); + cr_pg = (1 << FLASH_H7_CR_PG); + } else { + cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + cr_mer = (1 << FLASH_CR_MER); + cr_pg = (1 << FLASH_CR_PG); + } + + stlink_read_debug32(sl, cr_reg, &val); + + if (val & cr_pg) { + // STM32F030 will drop MER bit if PG was set + val &= ~cr_pg; + stlink_write_debug32(sl, cr_reg, val); + } - if (v) { - val |= cr_mer; - } else { - val &= ~cr_mer; - } + if (v) { + val |= cr_mer; + } else { + val &= ~cr_mer; + } - stlink_write_debug32(sl, cr_reg, val); + stlink_write_debug32(sl, cr_reg, val); } static void set_flash_cr_strt(stlink_t *sl, unsigned bank) { - uint32_t val, cr_reg, cr_strt; - - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - cr_reg = FLASH_F4_CR; - cr_strt = 1 << FLASH_F4_CR_STRT; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - cr_strt = 1 << FLASH_F7_CR_STRT; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - cr_strt = (1 << STM32L4_FLASH_CR_STRT); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_strt = (1 << STM32Gx_FLASH_CR_STRT); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - cr_reg = STM32WB_FLASH_CR; - cr_strt = (1 << STM32WB_FLASH_CR_STRT); - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = (bank==BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; - cr_strt = 1 << FLASH_H7_CR_START(sl->chip_id); - } else { - cr_reg = (bank==BANK_1)?FLASH_CR:FLASH_CR2; - cr_strt = (1 << FLASH_CR_STRT); - } - - stlink_read_debug32(sl, cr_reg, &val); - val |= cr_strt; - stlink_write_debug32(sl, cr_reg, val); + uint32_t val, cr_reg, cr_strt; + + if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + cr_reg = FLASH_F4_CR; + cr_strt = 1 << FLASH_F4_CR_STRT; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + cr_reg = FLASH_F7_CR; + cr_strt = 1 << FLASH_F7_CR_STRT; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + cr_strt = (1 << STM32L4_FLASH_CR_STRT); + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + cr_strt = (1 << STM32Gx_FLASH_CR_STRT); + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + cr_reg = STM32WB_FLASH_CR; + cr_strt = (1 << STM32WB_FLASH_CR_STRT); + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + cr_strt = 1 << FLASH_H7_CR_START(sl->chip_id); + } else { + cr_reg = (bank == BANK_1) ? FLASH_CR : FLASH_CR2; + cr_strt = (1 << FLASH_CR_STRT); + } + + stlink_read_debug32(sl, cr_reg, &val); + val |= cr_strt; + stlink_write_debug32(sl, cr_reg, val); } static inline uint32_t read_flash_sr(stlink_t *sl, unsigned bank) { - uint32_t res, sr_reg; - - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { - sr_reg = (bank==BANK_1)?FLASH_SR:FLASH_SR2; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - sr_reg = FLASH_F4_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - sr_reg = FLASH_F7_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - sr_reg = STM32L4_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - sr_reg = STM32Gx_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - sr_reg = STM32WB_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - sr_reg = (bank==BANK_1)?FLASH_H7_SR1:FLASH_H7_SR2; - } else { - ELOG("method 'read_flash_sr' is unsupported\n"); - return(-1); - } - - stlink_read_debug32(sl, sr_reg, &res); - return(res); + uint32_t res, sr_reg; + + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + sr_reg = FLASH_F4_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + sr_reg = FLASH_F7_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + sr_reg = STM32L4_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + sr_reg = STM32Gx_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + sr_reg = STM32WB_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + sr_reg = (bank == BANK_1) ? FLASH_H7_SR1 : FLASH_H7_SR2; + } else { + ELOG("method 'read_flash_sr' is unsupported\n"); + return (-1); + } + + stlink_read_debug32(sl, sr_reg, &res); + return (res); } static inline int write_flash_sr(stlink_t *sl, unsigned bank, uint32_t val) { - uint32_t sr_reg; - - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { - sr_reg = (bank==BANK_1)?FLASH_SR:FLASH_SR2; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - sr_reg = FLASH_F4_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - sr_reg = FLASH_F7_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - sr_reg = STM32L4_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - sr_reg = STM32Gx_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - sr_reg = STM32WB_FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - sr_reg = (bank==BANK_1)?FLASH_H7_SR1:FLASH_H7_SR2; - } else { - ELOG("method 'write_flash_sr' is unsupported\n"); - return(-1); - } - - return stlink_write_debug32(sl, sr_reg, val); + uint32_t sr_reg; + + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + sr_reg = (bank == BANK_1) ? FLASH_SR : FLASH_SR2; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + sr_reg = FLASH_F4_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + sr_reg = FLASH_F7_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + sr_reg = STM32L4_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + sr_reg = STM32Gx_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + sr_reg = STM32WB_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + sr_reg = (bank == BANK_1) ? FLASH_H7_SR1 : FLASH_H7_SR2; + } else { + ELOG("method 'write_flash_sr' is unsupported\n"); + return (-1); + } + + return stlink_write_debug32(sl, sr_reg, val); } static inline unsigned int is_flash_busy(stlink_t *sl) { - uint32_t sr_busy_shift; - unsigned int res; - - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) || - (sl->flash_type == STLINK_FLASH_TYPE_L0)) { - sr_busy_shift = FLASH_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - sr_busy_shift = FLASH_F4_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - sr_busy_shift = FLASH_F7_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - sr_busy_shift = STM32L4_FLASH_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - sr_busy_shift = STM32Gx_FLASH_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - sr_busy_shift = STM32WB_FLASH_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - sr_busy_shift = FLASH_H7_SR_QW; - } else { - ELOG("method 'is_flash_busy' is unsupported\n"); - return(-1); - } - - res = read_flash_sr(sl, BANK_1) & (1 << sr_busy_shift); - - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || - (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { - res |= read_flash_sr(sl, BANK_2) & (1 << sr_busy_shift); - } - - return(res); + uint32_t sr_busy_shift; + unsigned int res; + + if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) || + (sl->flash_type == STLINK_FLASH_TYPE_L0)) { + sr_busy_shift = FLASH_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { + sr_busy_shift = FLASH_F4_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { + sr_busy_shift = FLASH_F7_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + sr_busy_shift = STM32L4_FLASH_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + sr_busy_shift = STM32Gx_FLASH_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + sr_busy_shift = STM32WB_FLASH_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + sr_busy_shift = FLASH_H7_SR_QW; + } else { + ELOG("method 'is_flash_busy' is unsupported\n"); + return (-1); + } + + res = read_flash_sr(sl, BANK_1) & (1 << sr_busy_shift); + + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || + (sl->flash_type == STLINK_FLASH_TYPE_H7 && + sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { + res |= read_flash_sr(sl, BANK_2) & (1 << sr_busy_shift); + } + + return (res); } static void wait_flash_busy(stlink_t *sl) { - // TODO: add some delays here - while (is_flash_busy(sl)) - ; + // TODO: add some delays here + while (is_flash_busy(sl)) + ; } static void wait_flash_busy_progress(stlink_t *sl) { - int i = 0; - fprintf(stdout, "Mass erasing"); - fflush(stdout); - - while (is_flash_busy(sl)) { - usleep(10000); - i++; - - if (i % 100 == 0) { - fprintf(stdout, "."); - fflush(stdout); - } - } - - fprintf(stdout, "\n"); -} - -static void clear_flash_error(stlink_t *sl) -{ - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - write_flash_sr(sl, BANK_1, FLASH_SR_ERROR_MASK); - break; - case STLINK_FLASH_TYPE_F4: - write_flash_sr(sl, BANK_1, FLASH_F4_SR_ERROR_MASK); - break; - case STLINK_FLASH_TYPE_F7: - write_flash_sr(sl, BANK_1, FLASH_F7_SR_ERROR_MASK); - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - write_flash_sr(sl, BANK_1, STM32Gx_FLASH_SR_ERROR_MASK); - break; - case STLINK_FLASH_TYPE_L0: - write_flash_sr(sl, BANK_1, STM32L0_FLASH_SR_ERROR_MASK); - break; - case STLINK_FLASH_TYPE_L4: - write_flash_sr(sl, BANK_1, STM32L4_FLASH_SR_ERROR_MASK); - break; - case STLINK_FLASH_TYPE_H7: - write_flash_sr(sl, BANK_1, FLASH_H7_SR_ERROR_MASK); - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - write_flash_sr(sl, BANK_2, FLASH_H7_SR_ERROR_MASK); - } - break; - case STLINK_FLASH_TYPE_WB: - write_flash_sr(sl, BANK_1, STM32WB_FLASH_SR_ERROR_MASK); - break; - default: - break; - } -} - -static int check_flash_error(stlink_t *sl) -{ - uint32_t res = 0; - uint32_t WRPERR, PROGERR, PGAERR; - - WRPERR = PROGERR = PGAERR = 0; - - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - res = read_flash_sr(sl, BANK_1) & FLASH_SR_ERROR_MASK; - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - res |= read_flash_sr(sl, BANK_2) & FLASH_SR_ERROR_MASK; - } - WRPERR = (1 << FLASH_SR_WRPRT_ERR); - PROGERR = (1 << FLASH_SR_PG_ERR); - break; - case STLINK_FLASH_TYPE_F4: - res = read_flash_sr(sl, BANK_1) & FLASH_F4_SR_ERROR_MASK; - WRPERR = (1 << FLASH_F4_SR_WRPERR); - PGAERR = (1 << FLASH_F4_SR_PGAERR); - break; - case STLINK_FLASH_TYPE_F7: - res = read_flash_sr(sl, BANK_1) & FLASH_F7_SR_ERROR_MASK; - WRPERR = (1 << FLASH_F7_SR_WRP_ERR); - PROGERR = (1 << FLASH_F7_SR_PGP_ERR); - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - res = read_flash_sr(sl, BANK_1) & STM32Gx_FLASH_SR_ERROR_MASK; - WRPERR = (1 << STM32Gx_FLASH_SR_WRPERR); - PROGERR = (1 << STM32Gx_FLASH_SR_PROGERR); - PGAERR = (1 << STM32Gx_FLASH_SR_PGAERR); - break; - case STLINK_FLASH_TYPE_L0: - res = read_flash_sr(sl, BANK_1) & STM32L0_FLASH_SR_ERROR_MASK; - WRPERR = (1 << STM32L0_FLASH_SR_WRPERR); - PROGERR = (1 << STM32L0_FLASH_SR_NOTZEROERR); - PGAERR = (1 << STM32L0_FLASH_SR_PGAERR); - break; - case STLINK_FLASH_TYPE_L4: - res = read_flash_sr(sl, BANK_1) & STM32L4_FLASH_SR_ERROR_MASK; - WRPERR = (1 << STM32L4_FLASH_SR_WRPERR); - PROGERR = (1 << STM32L4_FLASH_SR_PROGERR); - PGAERR = (1 << STM32L4_FLASH_SR_PGAERR); - break; - case STLINK_FLASH_TYPE_H7: - res = read_flash_sr(sl, BANK_1) & FLASH_H7_SR_ERROR_MASK; - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - res |= read_flash_sr(sl, BANK_2) & FLASH_H7_SR_ERROR_MASK; - } - WRPERR = (1 << FLASH_H7_SR_WRPERR); - break; - case STLINK_FLASH_TYPE_WB: - res = read_flash_sr(sl, BANK_1) & STM32WB_FLASH_SR_ERROR_MASK; - WRPERR = (1 << STM32WB_FLASH_SR_WRPERR); - PROGERR = (1 << STM32WB_FLASH_SR_PROGERR); - PGAERR = (1 << STM32WB_FLASH_SR_PGAERR); - break; - default: - break; + int i = 0; + fprintf(stdout, "Mass erasing"); + fflush(stdout); + + while (is_flash_busy(sl)) { + usleep(10000); + i++; + + if (i % 100 == 0) { + fprintf(stdout, "."); + fflush(stdout); + } + } + + fprintf(stdout, "\n"); +} + +static void clear_flash_error(stlink_t *sl) { + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + write_flash_sr(sl, BANK_1, FLASH_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_F4: + write_flash_sr(sl, BANK_1, FLASH_F4_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_F7: + write_flash_sr(sl, BANK_1, FLASH_F7_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + write_flash_sr(sl, BANK_1, STM32Gx_FLASH_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_L0: + write_flash_sr(sl, BANK_1, STM32L0_FLASH_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_L4: + write_flash_sr(sl, BANK_1, STM32L4_FLASH_SR_ERROR_MASK); + break; + case STLINK_FLASH_TYPE_H7: + write_flash_sr(sl, BANK_1, FLASH_H7_SR_ERROR_MASK); + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + write_flash_sr(sl, BANK_2, FLASH_H7_SR_ERROR_MASK); + } + break; + case STLINK_FLASH_TYPE_WB: + write_flash_sr(sl, BANK_1, STM32WB_FLASH_SR_ERROR_MASK); + break; + default: + break; + } +} + +static int check_flash_error(stlink_t *sl) { + uint32_t res = 0; + uint32_t WRPERR, PROGERR, PGAERR; + + WRPERR = PROGERR = PGAERR = 0; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + res = read_flash_sr(sl, BANK_1) & FLASH_SR_ERROR_MASK; + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + res |= read_flash_sr(sl, BANK_2) & FLASH_SR_ERROR_MASK; + } + WRPERR = (1 << FLASH_SR_WRPRT_ERR); + PROGERR = (1 << FLASH_SR_PG_ERR); + break; + case STLINK_FLASH_TYPE_F4: + res = read_flash_sr(sl, BANK_1) & FLASH_F4_SR_ERROR_MASK; + WRPERR = (1 << FLASH_F4_SR_WRPERR); + PGAERR = (1 << FLASH_F4_SR_PGAERR); + break; + case STLINK_FLASH_TYPE_F7: + res = read_flash_sr(sl, BANK_1) & FLASH_F7_SR_ERROR_MASK; + WRPERR = (1 << FLASH_F7_SR_WRP_ERR); + PROGERR = (1 << FLASH_F7_SR_PGP_ERR); + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + res = read_flash_sr(sl, BANK_1) & STM32Gx_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32Gx_FLASH_SR_WRPERR); + PROGERR = (1 << STM32Gx_FLASH_SR_PROGERR); + PGAERR = (1 << STM32Gx_FLASH_SR_PGAERR); + break; + case STLINK_FLASH_TYPE_L0: + res = read_flash_sr(sl, BANK_1) & STM32L0_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32L0_FLASH_SR_WRPERR); + PROGERR = (1 << STM32L0_FLASH_SR_NOTZEROERR); + PGAERR = (1 << STM32L0_FLASH_SR_PGAERR); + break; + case STLINK_FLASH_TYPE_L4: + res = read_flash_sr(sl, BANK_1) & STM32L4_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32L4_FLASH_SR_WRPERR); + PROGERR = (1 << STM32L4_FLASH_SR_PROGERR); + PGAERR = (1 << STM32L4_FLASH_SR_PGAERR); + break; + case STLINK_FLASH_TYPE_H7: + res = read_flash_sr(sl, BANK_1) & FLASH_H7_SR_ERROR_MASK; + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + res |= read_flash_sr(sl, BANK_2) & FLASH_H7_SR_ERROR_MASK; + } + WRPERR = (1 << FLASH_H7_SR_WRPERR); + break; + case STLINK_FLASH_TYPE_WB: + res = read_flash_sr(sl, BANK_1) & STM32WB_FLASH_SR_ERROR_MASK; + WRPERR = (1 << STM32WB_FLASH_SR_WRPERR); + PROGERR = (1 << STM32WB_FLASH_SR_PROGERR); + PGAERR = (1 << STM32WB_FLASH_SR_PGAERR); + break; + default: + break; + } + + if (res) { + if (WRPERR && (WRPERR & res) == WRPERR) { + ELOG("Flash memory is write protected\n"); + res &= ~WRPERR; + } else if (PROGERR && (PROGERR & res) == PROGERR) { + ELOG("Flash memory contains a non-erased value\n"); + res &= ~PROGERR; + } else if (PGAERR && (PGAERR & res) == PGAERR) { + ELOG("Invalid flash address\n"); + res &= ~PGAERR; } if (res) { - if (WRPERR && (WRPERR&res)==WRPERR) { - ELOG("Flash memory is write protected\n"); - res &= ~WRPERR; - } else if (PROGERR && (PROGERR&res)==PROGERR) { - ELOG("Flash memory contains a non-erased value\n"); - res &= ~PROGERR; - } else if (PGAERR && (PGAERR&res)==PGAERR) { - ELOG("Invalid flash address\n"); - res &= ~PGAERR; - } - - if (res) { - ELOG("Flash programming error: %#010x\n", res); - } - return(-1); + ELOG("Flash programming error: %#010x\n", res); } + return (-1); + } - return(0); + return (0); } static void stop_wdg_in_debug(stlink_t *sl) { - uint32_t dbgmcu_cr; - uint32_t set; - uint32_t value; - - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - case STLINK_FLASH_TYPE_G4: - dbgmcu_cr = STM32F0_DBGMCU_CR; - set = (1<flash_type) { - case STLINK_FLASH_TYPE_F0: - case STLINK_FLASH_TYPE_F1_XL: - rcc = STM32F1_RCC_AHBENR; - rcc_dma_mask = STM32F1_RCC_DMAEN; - break; - case STLINK_FLASH_TYPE_F4: - case STLINK_FLASH_TYPE_F7: - rcc = STM32F4_RCC_AHB1ENR; - rcc_dma_mask = STM32F4_RCC_DMAEN; - break; - case STLINK_FLASH_TYPE_G0: - rcc = STM32G0_RCC_AHBENR; - rcc_dma_mask = STM32G0_RCC_DMAEN; - break; - case STLINK_FLASH_TYPE_G4: - case STLINK_FLASH_TYPE_L4: - rcc = STM32G4_RCC_AHB1ENR; - rcc_dma_mask = STM32G4_RCC_DMAEN; - break; - case STLINK_FLASH_TYPE_L0: - rcc = STM32L0_RCC_AHBENR; - rcc_dma_mask = STM32L0_RCC_DMAEN; - break; - case STLINK_FLASH_TYPE_H7: - rcc = STM32H7_RCC_AHB1ENR; - rcc_dma_mask = STM32H7_RCC_DMAEN; - break; - case STLINK_FLASH_TYPE_WB: - rcc = STM32WB_RCC_AHB1ENR; - rcc_dma_mask = STM32WB_RCC_DMAEN; - break; - default: - return; - } + uint32_t dbgmcu_cr; + uint32_t set; + uint32_t value; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + case STLINK_FLASH_TYPE_G4: + dbgmcu_cr = STM32F0_DBGMCU_CR; + set = + (1 << STM32F0_DBGMCU_CR_IWDG_STOP) | (1 << STM32F0_DBGMCU_CR_WWDG_STOP); + break; + case STLINK_FLASH_TYPE_F4: + case STLINK_FLASH_TYPE_F7: + case STLINK_FLASH_TYPE_L4: + dbgmcu_cr = STM32F4_DBGMCU_APB1FZR1; + set = (1 << STM32F4_DBGMCU_APB1FZR1_IWDG_STOP) | + (1 << STM32F4_DBGMCU_APB1FZR1_WWDG_STOP); + break; + case STLINK_FLASH_TYPE_L0: + case STLINK_FLASH_TYPE_G0: + dbgmcu_cr = STM32L0_DBGMCU_APB1_FZ; + set = (1 << STM32L0_DBGMCU_APB1_FZ_IWDG_STOP) | + (1 << STM32L0_DBGMCU_APB1_FZ_WWDG_STOP); + break; + case STLINK_FLASH_TYPE_H7: + dbgmcu_cr = STM32H7_DBGMCU_APB1HFZ; + set = (1 << STM32H7_DBGMCU_APB1HFZ_IWDG_STOP); + break; + case STLINK_FLASH_TYPE_WB: + dbgmcu_cr = STM32WB_DBGMCU_APB1FZR1; + set = (1 << STM32WB_DBGMCU_APB1FZR1_IWDG_STOP) | + (1 << STM32WB_DBGMCU_APB1FZR1_WWDG_STOP); + break; + default: + return; + } + + if (!stlink_read_debug32(sl, dbgmcu_cr, &value)) { + stlink_write_debug32(sl, dbgmcu_cr, value | set); + } +} + +static void set_dma_state(stlink_t *sl, flash_loader_t *fl, int bckpRstr) { + uint32_t rcc, rcc_dma_mask, value; + + rcc = rcc_dma_mask = value = 0; + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F0: + case STLINK_FLASH_TYPE_F1_XL: + rcc = STM32F1_RCC_AHBENR; + rcc_dma_mask = STM32F1_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_F4: + case STLINK_FLASH_TYPE_F7: + rcc = STM32F4_RCC_AHB1ENR; + rcc_dma_mask = STM32F4_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_G0: + rcc = STM32G0_RCC_AHBENR; + rcc_dma_mask = STM32G0_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_G4: + case STLINK_FLASH_TYPE_L4: + rcc = STM32G4_RCC_AHB1ENR; + rcc_dma_mask = STM32G4_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_L0: + rcc = STM32L0_RCC_AHBENR; + rcc_dma_mask = STM32L0_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_H7: + rcc = STM32H7_RCC_AHB1ENR; + rcc_dma_mask = STM32H7_RCC_DMAEN; + break; + case STLINK_FLASH_TYPE_WB: + rcc = STM32WB_RCC_AHB1ENR; + rcc_dma_mask = STM32WB_RCC_DMAEN; + break; + default: + return; + } - if (!stlink_read_debug32(sl, rcc, &value)) { - if (bckpRstr) { - value = (value&(~rcc_dma_mask)) | fl->rcc_dma_bkp; - } else { - fl->rcc_dma_bkp = value&rcc_dma_mask; - value &= ~rcc_dma_mask; - } - stlink_write_debug32(sl, rcc, value); + if (!stlink_read_debug32(sl, rcc, &value)) { + if (bckpRstr) { + value = (value & (~rcc_dma_mask)) | fl->rcc_dma_bkp; + } else { + fl->rcc_dma_bkp = value & rcc_dma_mask; + value &= ~rcc_dma_mask; } + stlink_write_debug32(sl, rcc, value); + } } static inline void write_flash_ar(stlink_t *sl, uint32_t n, unsigned bank) { - stlink_write_debug32(sl, (bank==BANK_1)?FLASH_AR:FLASH_AR2, n); + stlink_write_debug32(sl, (bank == BANK_1) ? FLASH_AR : FLASH_AR2, n); } -static inline void write_flash_cr_psiz(stlink_t *sl, uint32_t n, unsigned bank) { - uint32_t cr_reg, psize_shift; - uint32_t x = read_flash_cr(sl, bank); +static inline void write_flash_cr_psiz(stlink_t *sl, uint32_t n, + unsigned bank) { + uint32_t cr_reg, psize_shift; + uint32_t x = read_flash_cr(sl, bank); - if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = (bank==BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; - psize_shift = FLASH_H7_CR_PSIZE; - } else { - cr_reg = FLASH_F4_CR; - psize_shift = 8; - } + if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + psize_shift = FLASH_H7_CR_PSIZE; + } else { + cr_reg = FLASH_F4_CR; + psize_shift = 8; + } - x &= ~(0x03 << psize_shift); - x |= (n << psize_shift); + x &= ~(0x03 << psize_shift); + x |= (n << psize_shift); #if DEBUG_FLASH - fprintf(stdout, "PSIZ:0x%x 0x%x\n", x, n); + fprintf(stdout, "PSIZ:0x%x 0x%x\n", x, n); #endif - stlink_write_debug32(sl, cr_reg, x); + stlink_write_debug32(sl, cr_reg, x); } static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n, unsigned bank) { - uint32_t cr_reg, snb_mask, snb_shift, ser_shift; - uint32_t x = read_flash_cr(sl, bank); - - if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = (bank==BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; - snb_mask = FLASH_H7_CR_SNB_MASK; - snb_shift = FLASH_H7_CR_SNB; - ser_shift = FLASH_H7_CR_SER; - } else { - cr_reg = FLASH_F4_CR; - snb_mask = FLASH_F4_CR_SNB_MASK; - snb_shift = FLASH_F4_CR_SNB; - ser_shift = FLASH_F4_CR_SER; - } - - x &= ~snb_mask; - x |= (n << snb_shift); - x |= (1 << ser_shift); + uint32_t cr_reg, snb_mask, snb_shift, ser_shift; + uint32_t x = read_flash_cr(sl, bank); + + if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = (bank == BANK_1) ? FLASH_H7_CR1 : FLASH_H7_CR2; + snb_mask = FLASH_H7_CR_SNB_MASK; + snb_shift = FLASH_H7_CR_SNB; + ser_shift = FLASH_H7_CR_SER; + } else { + cr_reg = FLASH_F4_CR; + snb_mask = FLASH_F4_CR_SNB_MASK; + snb_shift = FLASH_F4_CR_SNB; + ser_shift = FLASH_F4_CR_SER; + } + + x &= ~snb_mask; + x |= (n << snb_shift); + x |= (1 << ser_shift); #if DEBUG_FLASH - fprintf(stdout, "SNB:0x%x 0x%x\n", x, n); + fprintf(stdout, "SNB:0x%x 0x%x\n", x, n); #endif - stlink_write_debug32(sl, cr_reg, x); + stlink_write_debug32(sl, cr_reg, x); } static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) { - stlink_write_debug32(sl, STM32L4_FLASH_SR, 0xFFFFFFFF & ~(1 << STM32L4_FLASH_SR_BSY)); - uint32_t x = read_flash_cr(sl, BANK_1); - x &= ~STM32L4_FLASH_CR_OPBITS; - x &= ~STM32L4_FLASH_CR_PAGEMASK; - x &= ~(1 << STM32L4_FLASH_CR_MER1); - x &= ~(1 << STM32L4_FLASH_CR_MER2); - x |= (n << STM32L4_FLASH_CR_PNB); - x |= (uint32_t)(1lu << STM32L4_FLASH_CR_PER); + stlink_write_debug32(sl, STM32L4_FLASH_SR, + 0xFFFFFFFF & ~(1 << STM32L4_FLASH_SR_BSY)); + uint32_t x = read_flash_cr(sl, BANK_1); + x &= ~STM32L4_FLASH_CR_OPBITS; + x &= ~STM32L4_FLASH_CR_PAGEMASK; + x &= ~(1 << STM32L4_FLASH_CR_MER1); + x &= ~(1 << STM32L4_FLASH_CR_MER2); + x |= (n << STM32L4_FLASH_CR_PNB); + x |= (uint32_t)(1lu << STM32L4_FLASH_CR_PER); #if DEBUG_FLASH - fprintf(stdout, "BKER:PNB:0x%x 0x%x\n", x, n); + fprintf(stdout, "BKER:PNB:0x%x 0x%x\n", x, n); #endif - stlink_write_debug32(sl, STM32L4_FLASH_CR, x); + stlink_write_debug32(sl, STM32L4_FLASH_CR, x); } // Delegates to the backends... void stlink_close(stlink_t *sl) { - DLOG("*** stlink_close ***\n"); + DLOG("*** stlink_close ***\n"); - if (!sl) { - return; - } + if (!sl) { + return; + } - sl->backend->close(sl); - free(sl); + sl->backend->close(sl); + free(sl); } int stlink_exit_debug_mode(stlink_t *sl) { - int ret; + int ret; - DLOG("*** stlink_exit_debug_mode ***\n"); - ret = stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY); + DLOG("*** stlink_exit_debug_mode ***\n"); + ret = stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY); - if (ret == -1) { - return(ret); - } + if (ret == -1) { + return (ret); + } - return(sl->backend->exit_debug_mode(sl)); + return (sl->backend->exit_debug_mode(sl)); } int stlink_enter_swd_mode(stlink_t *sl) { - DLOG("*** stlink_enter_swd_mode ***\n"); - return(sl->backend->enter_swd_mode(sl)); + DLOG("*** stlink_enter_swd_mode ***\n"); + return (sl->backend->enter_swd_mode(sl)); } // Force the core into the debug mode -> halted state. int stlink_force_debug(stlink_t *sl) { - DLOG("*** stlink_force_debug_mode ***\n"); - int res = sl->backend->force_debug(sl); - // Stop the watchdogs in the halted state for suppress target reboot - stop_wdg_in_debug(sl); - return(res); + DLOG("*** stlink_force_debug_mode ***\n"); + int res = sl->backend->force_debug(sl); + // Stop the watchdogs in the halted state for suppress target reboot + stop_wdg_in_debug(sl); + return (res); } int stlink_exit_dfu_mode(stlink_t *sl) { - DLOG("*** stlink_exit_dfu_mode ***\n"); - return(sl->backend->exit_dfu_mode(sl)); + DLOG("*** stlink_exit_dfu_mode ***\n"); + return (sl->backend->exit_dfu_mode(sl)); } int stlink_core_id(stlink_t *sl) { - int ret; + int ret; - DLOG("*** stlink_core_id ***\n"); - ret = sl->backend->core_id(sl); + DLOG("*** stlink_core_id ***\n"); + ret = sl->backend->core_id(sl); - if (ret == -1) { - ELOG("Failed to read core_id\n"); - return(ret); - } + if (ret == -1) { + ELOG("Failed to read core_id\n"); + return (ret); + } - if (sl->verbose > 2) { - stlink_print_data(sl); - } + if (sl->verbose > 2) { + stlink_print_data(sl); + } - DLOG("core_id = 0x%08x\n", sl->core_id); - return(ret); + DLOG("core_id = 0x%08x\n", sl->core_id); + return (ret); } // stlink_chip_id() is called by stlink_load_device_params() // do not call this procedure directly. int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { - int ret; - cortex_m3_cpuid_t cpu_id; - - // Read the CPU ID to determine where to read the core id - if (stlink_cpu_id(sl, &cpu_id) || - cpu_id.implementer_id != STLINK_REG_CMx_CPUID_IMPL_ARM) { - ELOG("Can not connect to target. Please use \'connect under reset\' and try again\n"); - return -1; - } - - /* - * the chip_id register in the reference manual have - * DBGMCU_IDCODE / DBG_IDCODE name - * - */ - - if ((sl->core_id == STM32H7_CORE_ID || - sl->core_id == STM32H7_CORE_ID_JTAG) && - cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM7) { - // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) - ret = stlink_read_debug32(sl, 0x5c001000, chip_id); - } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0 || - cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0P) { - // STM32F0 (RM0091, pg914; RM0360, pg713) - // STM32L0 (RM0377, pg813; RM0367, pg915; RM0376, pg917) - // STM32G0 (RM0444, pg1367) - ret = stlink_read_debug32(sl, 0x40015800, chip_id); - } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM33) { - // STM32L5 (RM0438, pg2157) - ret = stlink_read_debug32(sl, 0xE0044000, chip_id); - } else /* СM3, СM4, CM7 */ { - // default chipid address - - // STM32F1 (RM0008, pg1087; RM0041, pg681) - // STM32F2 (RM0033, pg1326) - // STM32F3 (RM0316, pg1095; RM0313, pg874) - // STM32F7 (RM0385, pg1676; RM0410, pg1912) - // STM32L1 (RM0038, pg861) - // STM32L4 (RM0351, pg1840; RM0394, pg1560) - // STM32G4 (RM0440, pg2086) - // STM32WB (RM0434, pg1406) - ret = stlink_read_debug32(sl, 0xE0042000, chip_id); - } - - if (ret || !(*chip_id)) { - *chip_id = 0; - ELOG("Could not find chip id!\n"); - } else { - *chip_id = (*chip_id) & 0xfff; - - // Fix chip_id for F4 rev A errata, read CPU ID, as CoreID is the same for F2/F4 - if (*chip_id == 0x411 && cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM4) { - *chip_id = 0x413; - } - } - - return(ret); + int ret; + cortex_m3_cpuid_t cpu_id; + + // Read the CPU ID to determine where to read the core id + if (stlink_cpu_id(sl, &cpu_id) || + cpu_id.implementer_id != STLINK_REG_CMx_CPUID_IMPL_ARM) { + ELOG("Can not connect to target. Please use \'connect under reset\' and " + "try again\n"); + return -1; + } + + /* + * the chip_id register in the reference manual have + * DBGMCU_IDCODE / DBG_IDCODE name + * + */ + + if ((sl->core_id == STM32H7_CORE_ID || sl->core_id == STM32H7_CORE_ID_JTAG) && + cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM7) { + // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) + ret = stlink_read_debug32(sl, 0x5c001000, chip_id); + } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0 || + cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM0P) { + // STM32F0 (RM0091, pg914; RM0360, pg713) + // STM32L0 (RM0377, pg813; RM0367, pg915; RM0376, pg917) + // STM32G0 (RM0444, pg1367) + ret = stlink_read_debug32(sl, 0x40015800, chip_id); + } else if (cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM33) { + // STM32L5 (RM0438, pg2157) + ret = stlink_read_debug32(sl, 0xE0044000, chip_id); + } else /* СM3, СM4, CM7 */ { + // default chipid address + + // STM32F1 (RM0008, pg1087; RM0041, pg681) + // STM32F2 (RM0033, pg1326) + // STM32F3 (RM0316, pg1095; RM0313, pg874) + // STM32F7 (RM0385, pg1676; RM0410, pg1912) + // STM32L1 (RM0038, pg861) + // STM32L4 (RM0351, pg1840; RM0394, pg1560) + // STM32G4 (RM0440, pg2086) + // STM32WB (RM0434, pg1406) + ret = stlink_read_debug32(sl, 0xE0042000, chip_id); + } + + if (ret || !(*chip_id)) { + *chip_id = 0; + ELOG("Could not find chip id!\n"); + } else { + *chip_id = (*chip_id) & 0xfff; + + // Fix chip_id for F4 rev A errata, read CPU ID, as CoreID is the same for + // F2/F4 + if (*chip_id == 0x411 && cpu_id.part == STLINK_REG_CMx_CPUID_PARTNO_CM4) { + *chip_id = 0x413; + } + } + + return (ret); } /** @@ -1553,21 +1558,21 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { * @param cpuid pointer to the result object */ int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { - uint32_t raw; - - if (stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &raw)) { - cpuid->implementer_id = 0; - cpuid->variant = 0; - cpuid->part = 0; - cpuid->revision = 0; - return(-1); - } + uint32_t raw; - cpuid->implementer_id = (raw >> 24) & 0x7f; - cpuid->variant = (raw >> 20) & 0xf; - cpuid->part = (raw >> 4) & 0xfff; - cpuid->revision = raw & 0xf; - return(0); + if (stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &raw)) { + cpuid->implementer_id = 0; + cpuid->variant = 0; + cpuid->part = 0; + cpuid->revision = 0; + return (-1); + } + + cpuid->implementer_id = (raw >> 24) & 0x7f; + cpuid->variant = (raw >> 20) & 0xf; + cpuid->part = (raw >> 4) & 0xfff; + cpuid->revision = raw & 0xf; + return (0); } /** @@ -1576,256 +1581,269 @@ int stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) { * @return 0 for success, or -1 for unsupported core type. */ int stlink_load_device_params(stlink_t *sl) { - // This seems to normally work so is unnecessary info for a normal user. - // Demoted to debug. -- REW - DLOG("Loading device parameters....\n"); - const struct stlink_chipid_params *params = NULL; - stlink_core_id(sl); - uint32_t flash_size; - - if (stlink_chip_id(sl, &sl->chip_id)) { - return(-1); - } + // This seems to normally work so is unnecessary info for a normal user. + // Demoted to debug. -- REW + DLOG("Loading device parameters....\n"); + const struct stlink_chipid_params *params = NULL; + stlink_core_id(sl); + uint32_t flash_size; + + if (stlink_chip_id(sl, &sl->chip_id)) { + return (-1); + } + + params = stlink_chipid_get_params(sl->chip_id); + + if (params == NULL) { + WLOG("unknown chip id! %#x\n", sl->chip_id); + return (-1); + } + + if (params->flash_type == STLINK_FLASH_TYPE_UNKNOWN) { + WLOG("Invalid flash type, please check device declaration\n"); + sl->flash_size = 0; + return (0); + } + + // These are fixed... + sl->flash_base = STM32_FLASH_BASE; + sl->sram_base = STM32_SRAM_BASE; + stlink_read_debug32(sl, (params->flash_size_reg) & ~3, &flash_size); + + if (params->flash_size_reg & 2) { + flash_size = flash_size >> 16; + } + + flash_size = flash_size & 0xffff; + + if ((sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM || + sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW || + sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM_PLUS) && + (flash_size == 0)) { + sl->flash_size = 128 * 1024; + } else if (sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2) { + sl->flash_size = (flash_size & 0xff) * 1024; + } else if ((sl->chip_id & 0xFFF) == STLINK_CHIPID_STM32_L1_HIGH) { + // 0 is 384k and 1 is 256k + if (flash_size == 0) { + sl->flash_size = 384 * 1024; + } else { + sl->flash_size = 256 * 1024; + } + } else { + sl->flash_size = flash_size * 1024; + } + + sl->flash_type = params->flash_type; + sl->flash_pgsz = params->flash_pagesize; + sl->sram_size = params->sram_size; + sl->sys_base = params->bootrom_base; + sl->sys_size = params->bootrom_size; + sl->option_base = params->option_base; + sl->option_size = params->option_size; + sl->chip_flags = params->flags; + + // medium and low devices have the same chipid. ram size depends on flash + // size. STM32F100xx datasheet Doc ID 16455 Table 2 + if (sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW && + sl->flash_size < 64 * 1024) { + sl->sram_size = 0x1000; + } + + if (sl->chip_id == STLINK_CHIPID_STM32_G4_CAT3) { + uint32_t flash_optr; + stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, &flash_optr); + + if (!(flash_optr & (1 << STM32G4_FLASH_OPTR_DBANK))) { + sl->flash_pgsz <<= 1; + } + } + + // H7 devices with small flash has one bank + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK && + sl->flash_type == STLINK_FLASH_TYPE_H7) { + if ((flash_size / sl->flash_pgsz) <= 1) + sl->chip_flags &= ~CHIP_F_HAS_DUAL_BANK; + } + + ILOG("%s: %u KiB SRAM, %u KiB flash in at least %u %s pages.\n", + params->description, (unsigned)(sl->sram_size / 1024), + (unsigned)(sl->flash_size / 1024), + (sl->flash_pgsz < 1024) ? (unsigned)(sl->flash_pgsz) + : (unsigned)(sl->flash_pgsz / 1024), + (sl->flash_pgsz < 1024) ? "byte" : "KiB"); + + return (0); +} - params = stlink_chipid_get_params(sl->chip_id); +int stlink_jtag_reset(stlink_t *sl, int value) { + DLOG("*** stlink_jtag_reset ***\n"); + return (sl->backend->jtag_reset(sl, value)); +} - if (params == NULL) { - WLOG("unknown chip id! %#x\n", sl->chip_id); - return(-1); +int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { + int ret; + unsigned timeout; + uint32_t dhcsr, dfsr; + + DLOG("*** stlink_soft_reset %s***\n", halt_on_reset ? "(halt) " : ""); + + // halt core and enable debugging (if not already done) + // C_DEBUGEN is required to Halt on reset (DDI0337E, p. 10-6) + stlink_write_debug32(sl, STLINK_REG_DHCSR, + STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | + STLINK_REG_DHCSR_C_DEBUGEN); + + // enable Halt on reset by set VC_CORERESET and TRCENA (DDI0337E, p. 10-10) + if (halt_on_reset) { + stlink_write_debug32( + sl, STLINK_REG_CM3_DEMCR, + STLINK_REG_CM3_DEMCR_TRCENA | STLINK_REG_CM3_DEMCR_VC_HARDERR | + STLINK_REG_CM3_DEMCR_VC_BUSERR | STLINK_REG_CM3_DEMCR_VC_CORERESET); + + // clear VCATCH in the DFSR register + stlink_write_debug32(sl, STLINK_REG_DFSR, STLINK_REG_DFSR_VCATCH); + } else { + stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, + STLINK_REG_CM3_DEMCR_TRCENA | + STLINK_REG_CM3_DEMCR_VC_HARDERR | + STLINK_REG_CM3_DEMCR_VC_BUSERR); + } + + // clear S_RESET_ST in the DHCSR register + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + + // soft reset (core reset) by SYSRESETREQ (DDI0337E, p. 8-23) + ret = stlink_write_debug32(sl, STLINK_REG_AIRCR, + STLINK_REG_AIRCR_VECTKEY | + STLINK_REG_AIRCR_SYSRESETREQ); + if (ret) { + ELOG("Soft reset failed: error write to AIRCR\n"); + return (ret); + } + + // waiting for a reset within 500ms + // DDI0337E, p. 10-4, Debug Halting Control and Status Register + timeout = time_ms() + 500; + while (time_ms() < timeout) { + // DDI0337E, p. 10-4, Debug Halting Control and Status Register + dhcsr = STLINK_REG_DHCSR_S_RESET_ST; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { + if (halt_on_reset) { + // waiting halt by the SYSRESETREQ exception + // DDI0403E, p. C1-699, Debug Fault Status Register + dfsr = 0; + stlink_read_debug32(sl, STLINK_REG_DFSR, &dfsr); + if ((dfsr & STLINK_REG_DFSR_VCATCH) == 0) { + continue; + } + } + timeout = 0; + break; } + } - if (params->flash_type == STLINK_FLASH_TYPE_UNKNOWN) { - WLOG("Invalid flash type, please check device declaration\n"); - sl->flash_size = 0; - return(0); - } + // reset DFSR register. DFSR is power-on reset only (DDI0337H, p. 7-5) + stlink_write_debug32(sl, STLINK_REG_DFSR, STLINK_REG_DFSR_CLEAR); - // These are fixed... - sl->flash_base = STM32_FLASH_BASE; - sl->sram_base = STM32_SRAM_BASE; - stlink_read_debug32(sl, (params->flash_size_reg) & ~3, &flash_size); + if (timeout) { + ELOG("Soft reset failed: timeout\n"); + return (-1); + } - if (params->flash_size_reg & 2) { - flash_size = flash_size >> 16; - } + return (0); +} - flash_size = flash_size & 0xffff; - - if ((sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM || - sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW || - sl->chip_id == STLINK_CHIPID_STM32_L1_MEDIUM_PLUS) && (flash_size == 0)) { - sl->flash_size = 128 * 1024; - } else if (sl->chip_id == STLINK_CHIPID_STM32_L1_CAT2) { - sl->flash_size = (flash_size & 0xff) * 1024; - } else if ((sl->chip_id & 0xFFF) == STLINK_CHIPID_STM32_L1_HIGH) { - // 0 is 384k and 1 is 256k - if (flash_size == 0) { - sl->flash_size = 384 * 1024; - } else { - sl->flash_size = 256 * 1024; - } - } else { - sl->flash_size = flash_size * 1024; - } +int stlink_reset(stlink_t *sl, enum reset_type type) { + uint32_t dhcsr; + unsigned timeout; + + DLOG("*** stlink_reset ***\n"); + + if (type == RESET_AUTO) { + // clear S_RESET_ST in DHCSR register for reset state detection + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + } - sl->flash_type = params->flash_type; - sl->flash_pgsz = params->flash_pagesize; - sl->sram_size = params->sram_size; - sl->sys_base = params->bootrom_base; - sl->sys_size = params->bootrom_size; - sl->option_base = params->option_base; - sl->option_size = params->option_size; - sl->chip_flags = params->flags; - - // medium and low devices have the same chipid. ram size depends on flash size. - // STM32F100xx datasheet Doc ID 16455 Table 2 - if (sl->chip_id == STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW && sl->flash_size < 64 * 1024) { - sl->sram_size = 0x1000; + if (type == RESET_HARD || type == RESET_AUTO) { + // hardware target reset + if (sl->version.stlink_v > 1) { + stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_LOW); + // minimum reset pulse duration of 20 us (RM0008, 8.1.2 Power reset) + usleep(100); + stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_HIGH); + } + if (sl->backend->reset(sl)) { + return (-1); } + usleep(10000); + } - if (sl->chip_id == STLINK_CHIPID_STM32_G4_CAT3) { - uint32_t flash_optr; - stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, &flash_optr); + if (type == RESET_AUTO) { + /* Check if the S_RESET_ST bit is set in DHCSR + * This means that a reset has occurred + * DDI0337E, p. 10-4, Debug Halting Control and Status Register */ + + dhcsr = 0; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { + // reset not done yet + // try reset through AIRCR so that NRST does not need to be connected - if (!(flash_optr & (1 << STM32G4_FLASH_OPTR_DBANK))) { sl->flash_pgsz <<= 1; } + WLOG("NRST is not connected\n"); + DLOG("Using reset through SYSRESETREQ\n"); + return stlink_soft_reset(sl, 0); } - // H7 devices with small flash has one bank - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK && sl->flash_type == STLINK_FLASH_TYPE_H7) { - if ((flash_size/sl->flash_pgsz) <= 1) - sl->chip_flags &= ~CHIP_F_HAS_DUAL_BANK; + // waiting for reset the S_RESET_ST bit within 500ms + timeout = time_ms() + 500; + while (time_ms() < timeout) { + dhcsr = STLINK_REG_DHCSR_S_RESET_ST; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) + return (0); } - ILOG("%s: %u KiB SRAM, %u KiB flash in at least %u %s pages.\n", - params->description, (unsigned)(sl->sram_size / 1024), (unsigned)(sl->flash_size / 1024), - (sl->flash_pgsz < 1024) ? (unsigned)(sl->flash_pgsz) : (unsigned)(sl->flash_pgsz / 1024), - (sl->flash_pgsz < 1024) ? "byte" : "KiB"); + return (-1); + } - return(0); + if (type == RESET_SOFT || type == RESET_SOFT_AND_HALT) { + return stlink_soft_reset(sl, (type == RESET_SOFT_AND_HALT)); + } + + return (0); } +int stlink_run(stlink_t *sl, enum run_type type) { + struct stlink_reg rr; + DLOG("*** stlink_run ***\n"); + + /* Make sure we are in Thumb mode + * Cortex-M chips don't support ARM mode instructions + * xPSR may be incorrect if the vector table has invalid data */ + stlink_read_reg(sl, 16, &rr); + if ((rr.xpsr & (1 << 24)) == 0) { + ILOG("Go to Thumb mode\n"); + stlink_write_reg(sl, rr.xpsr | (1 << 24), 16); + } -int stlink_jtag_reset(stlink_t *sl, int value) { - DLOG("*** stlink_jtag_reset ***\n"); - return(sl->backend->jtag_reset(sl, value)); + return (sl->backend->run(sl, type)); } -int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { - int ret; - unsigned timeout; - uint32_t dhcsr, dfsr; - - DLOG("*** stlink_soft_reset %s***\n", halt_on_reset?"(halt) ":""); +int stlink_set_swdclk(stlink_t *sl, int freq_khz) { + DLOG("*** set_swdclk ***\n"); + return (sl->backend->set_swdclk(sl, freq_khz)); +} - // halt core and enable debugging (if not already done) - // C_DEBUGEN is required to Halt on reset (DDI0337E, p. 10-6) - stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | - STLINK_REG_DHCSR_C_HALT | STLINK_REG_DHCSR_C_DEBUGEN); +int stlink_status(stlink_t *sl) { + int ret; - // enable Halt on reset by set VC_CORERESET and TRCENA (DDI0337E, p. 10-10) - if (halt_on_reset) { - stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, STLINK_REG_CM3_DEMCR_TRCENA | - STLINK_REG_CM3_DEMCR_VC_HARDERR | STLINK_REG_CM3_DEMCR_VC_BUSERR | - STLINK_REG_CM3_DEMCR_VC_CORERESET); - - // clear VCATCH in the DFSR register - stlink_write_debug32(sl, STLINK_REG_DFSR, STLINK_REG_DFSR_VCATCH); - } else { - stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, STLINK_REG_CM3_DEMCR_TRCENA | - STLINK_REG_CM3_DEMCR_VC_HARDERR | STLINK_REG_CM3_DEMCR_VC_BUSERR); - } - - // clear S_RESET_ST in the DHCSR register - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - - // soft reset (core reset) by SYSRESETREQ (DDI0337E, p. 8-23) - ret = stlink_write_debug32(sl, STLINK_REG_AIRCR, STLINK_REG_AIRCR_VECTKEY | - STLINK_REG_AIRCR_SYSRESETREQ); - if (ret) { - ELOG("Soft reset failed: error write to AIRCR\n"); - return(ret); - } - - // waiting for a reset within 500ms - // DDI0337E, p. 10-4, Debug Halting Control and Status Register - timeout = time_ms() + 500; - while (time_ms() < timeout) { - // DDI0337E, p. 10-4, Debug Halting Control and Status Register - dhcsr = STLINK_REG_DHCSR_S_RESET_ST; - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr&STLINK_REG_DHCSR_S_RESET_ST) == 0) { - if (halt_on_reset) { - // waiting halt by the SYSRESETREQ exception - // DDI0403E, p. C1-699, Debug Fault Status Register - dfsr = 0; - stlink_read_debug32(sl, STLINK_REG_DFSR, &dfsr); - if ((dfsr&STLINK_REG_DFSR_VCATCH) == 0) { - continue; - } - } - timeout = 0; - break; - } - } - - // reset DFSR register. DFSR is power-on reset only (DDI0337H, p. 7-5) - stlink_write_debug32(sl, STLINK_REG_DFSR, STLINK_REG_DFSR_CLEAR); - - if (timeout) { - ELOG("Soft reset failed: timeout\n"); - return(-1); - } - - return(0); -} - -int stlink_reset(stlink_t *sl, enum reset_type type) { - uint32_t dhcsr; - unsigned timeout; - - DLOG("*** stlink_reset ***\n"); - - if (type == RESET_AUTO) { - // clear S_RESET_ST in DHCSR register for reset state detection - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - } - - if (type == RESET_HARD || type == RESET_AUTO) { - // hardware target reset - if (sl->version.stlink_v > 1) { - stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_LOW); - // minimum reset pulse duration of 20 us (RM0008, 8.1.2 Power reset) - usleep(100); - stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_HIGH); - } - if (sl->backend->reset(sl)) { return(-1); } - usleep(10000); - } - - if (type == RESET_AUTO) { - /* Check if the S_RESET_ST bit is set in DHCSR - * This means that a reset has occurred - * DDI0337E, p. 10-4, Debug Halting Control and Status Register */ - - dhcsr = 0; - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { - // reset not done yet - // try reset through AIRCR so that NRST does not need to be connected - - WLOG("NRST is not connected\n"); - DLOG("Using reset through SYSRESETREQ\n"); - return stlink_soft_reset(sl, 0); - } - - // waiting for reset the S_RESET_ST bit within 500ms - timeout = time_ms() + 500; - while (time_ms() < timeout) { - dhcsr = STLINK_REG_DHCSR_S_RESET_ST; - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr&STLINK_REG_DHCSR_S_RESET_ST) == 0) - return(0); - } - - return(-1); - } - - if (type == RESET_SOFT || type == RESET_SOFT_AND_HALT) { - return stlink_soft_reset(sl, (type==RESET_SOFT_AND_HALT)); - } - - return(0); -} - -int stlink_run(stlink_t *sl, enum run_type type) { - struct stlink_reg rr; - DLOG("*** stlink_run ***\n"); - - /* Make sure we are in Thumb mode - * Cortex-M chips don't support ARM mode instructions - * xPSR may be incorrect if the vector table has invalid data */ - stlink_read_reg(sl, 16, &rr); - if ((rr.xpsr & (1 << 24)) == 0) { - ILOG("Go to Thumb mode\n"); - stlink_write_reg(sl, rr.xpsr | (1 << 24), 16); - } - - return(sl->backend->run(sl, type)); -} - -int stlink_set_swdclk(stlink_t *sl, int freq_khz) { - DLOG("*** set_swdclk ***\n"); - return(sl->backend->set_swdclk(sl, freq_khz)); -} - -int stlink_status(stlink_t *sl) { - int ret; - - DLOG("*** stlink_status ***\n"); - ret = sl->backend->status(sl); - stlink_core_stat(sl); - return(ret); -} + DLOG("*** stlink_status ***\n"); + ret = sl->backend->status(sl); + stlink_core_stat(sl); + return (ret); +} /** * Decode the version bits, originally from -sg, verified with usb @@ -1833,1109 +1851,1192 @@ int stlink_status(stlink_t *sl) { * @param slv output parsed version object */ 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 - uint32_t b1 = sl->q_buf[1]; - uint32_t b2 = sl->q_buf[2]; - uint32_t b3 = sl->q_buf[3]; - uint32_t b4 = sl->q_buf[4]; - uint32_t b5 = sl->q_buf[5]; // msb - - // b0 b1 || b2 b3 | b4 b5 - // 4b | 6b | 6b || 2B | 2B - // stlink_v | jtag_v | swim_v || st_vid | stlink_pid - - slv->stlink_v = (b0 & 0xf0) >> 4; - slv->jtag_v = ((b0 & 0x0f) << 2) | ((b1 & 0xc0) >> 6); - slv->swim_v = b1 & 0x3f; - slv->st_vid = (b3 << 8) | b2; - slv->stlink_pid = (b5 << 8) | b4; - - // ST-LINK/V1 from J11 switch to api-v2 (and support SWD) - if (slv->stlink_v == 1) { - slv->jtag_api = slv->jtag_v > 11 ? STLINK_JTAG_API_V2 : STLINK_JTAG_API_V1; - } else { - slv->jtag_api = STLINK_JTAG_API_V2; - - // preferred API to get last R/W status from J15 - if (sl->version.jtag_v >= 15) { - sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; - } - - if (sl->version.jtag_v >= 13) { - sl->version.flags |= STLINK_F_HAS_TRACE; - sl->max_trace_freq = STLINK_V2_MAX_TRACE_FREQUENCY; - } - } + sl->version.flags = 0; + + if (sl->version.stlink_v < 3) { + uint32_t b0 = sl->q_buf[0]; // lsb + uint32_t b1 = sl->q_buf[1]; + uint32_t b2 = sl->q_buf[2]; + uint32_t b3 = sl->q_buf[3]; + uint32_t b4 = sl->q_buf[4]; + uint32_t b5 = sl->q_buf[5]; // msb + + // b0 b1 || b2 b3 | b4 b5 + // 4b | 6b | 6b || 2B | 2B + // stlink_v | jtag_v | swim_v || st_vid | stlink_pid + + slv->stlink_v = (b0 & 0xf0) >> 4; + slv->jtag_v = ((b0 & 0x0f) << 2) | ((b1 & 0xc0) >> 6); + slv->swim_v = b1 & 0x3f; + slv->st_vid = (b3 << 8) | b2; + slv->stlink_pid = (b5 << 8) | b4; + + // ST-LINK/V1 from J11 switch to api-v2 (and support SWD) + if (slv->stlink_v == 1) { + slv->jtag_api = + slv->jtag_v > 11 ? STLINK_JTAG_API_V2 : STLINK_JTAG_API_V1; } else { - // V3 uses different version format, for reference see OpenOCD source - // (that was written from docs available from ST under NDA): - // https://github.com/ntfreak/openocd/blob/a6dacdff58ef36fcdac00c53ec27f19de1fbce0d/src/jtag/drivers/stlink_usb.c#L965 - slv->stlink_v = sl->q_buf[0]; - slv->swim_v = sl->q_buf[1]; - slv->jtag_v = sl->q_buf[2]; - slv->st_vid = (uint32_t)((sl->q_buf[9] << 8) | sl->q_buf[8]); - slv->stlink_pid = (uint32_t)((sl->q_buf[11] << 8) | sl->q_buf[10]); - slv->jtag_api = STLINK_JTAG_API_V3; - /* preferred API to get last R/W status */ + slv->jtag_api = STLINK_JTAG_API_V2; + + // preferred API to get last R/W status from J15 + if (sl->version.jtag_v >= 15) { sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; - sl->version.flags |= STLINK_F_HAS_TRACE; - sl->max_trace_freq = STLINK_V3_MAX_TRACE_FREQUENCY; - } + } - return; + if (sl->version.jtag_v >= 13) { + sl->version.flags |= STLINK_F_HAS_TRACE; + sl->max_trace_freq = STLINK_V2_MAX_TRACE_FREQUENCY; + } + } + } else { + // V3 uses different version format, for reference see OpenOCD source + // (that was written from docs available from ST under NDA): + // https://github.com/ntfreak/openocd/blob/a6dacdff58ef36fcdac00c53ec27f19de1fbce0d/src/jtag/drivers/stlink_usb.c#L965 + slv->stlink_v = sl->q_buf[0]; + slv->swim_v = sl->q_buf[1]; + slv->jtag_v = sl->q_buf[2]; + slv->st_vid = (uint32_t)((sl->q_buf[9] << 8) | sl->q_buf[8]); + slv->stlink_pid = (uint32_t)((sl->q_buf[11] << 8) | sl->q_buf[10]); + slv->jtag_api = STLINK_JTAG_API_V3; + /* preferred API to get last R/W status */ + sl->version.flags |= STLINK_F_HAS_GETLASTRWSTATUS2; + sl->version.flags |= STLINK_F_HAS_TRACE; + sl->max_trace_freq = STLINK_V3_MAX_TRACE_FREQUENCY; + } + + return; } int stlink_version(stlink_t *sl) { - DLOG("*** looking up stlink version\n"); + DLOG("*** looking up stlink version\n"); - if (sl->backend->version(sl)) { - return(-1); - } + if (sl->backend->version(sl)) { + return (-1); + } - _parse_version(sl, &sl->version); + _parse_version(sl, &sl->version); - DLOG("st vid = 0x%04x (expect 0x%04x)\n", sl->version.st_vid, STLINK_USB_VID_ST); - DLOG("stlink pid = 0x%04x\n", sl->version.stlink_pid); - DLOG("stlink version = 0x%x\n", sl->version.stlink_v); - DLOG("jtag version = 0x%x\n", sl->version.jtag_v); - DLOG("swim version = 0x%x\n", sl->version.swim_v); + DLOG("st vid = 0x%04x (expect 0x%04x)\n", sl->version.st_vid, + STLINK_USB_VID_ST); + DLOG("stlink pid = 0x%04x\n", sl->version.stlink_pid); + DLOG("stlink version = 0x%x\n", sl->version.stlink_v); + DLOG("jtag version = 0x%x\n", sl->version.jtag_v); + DLOG("swim version = 0x%x\n", sl->version.swim_v); - if (sl->version.jtag_v == 0) { - DLOG(" notice: the firmware doesn't support a jtag/swd interface\n"); - } + if (sl->version.jtag_v == 0) { + DLOG(" notice: the firmware doesn't support a jtag/swd interface\n"); + } - if (sl->version.swim_v == 0) { - DLOG(" notice: the firmware doesn't support a swim interface\n"); - } + if (sl->version.swim_v == 0) { + DLOG(" notice: the firmware doesn't support a swim interface\n"); + } - return(0); + return (0); } int stlink_target_voltage(stlink_t *sl) { - int voltage = -1; - DLOG("*** reading target voltage\n"); + int voltage = -1; + DLOG("*** reading target voltage\n"); - if (sl->backend->target_voltage != NULL) { - voltage = sl->backend->target_voltage(sl); + if (sl->backend->target_voltage != NULL) { + voltage = sl->backend->target_voltage(sl); - if (voltage != -1) { - DLOG("target voltage = %imV\n", voltage); - } else { - DLOG("error reading target voltage\n"); - } + if (voltage != -1) { + DLOG("target voltage = %imV\n", voltage); } else { - DLOG("reading voltage not supported by backend\n"); + DLOG("error reading target voltage\n"); } + } else { + DLOG("reading voltage not supported by backend\n"); + } - return(voltage); + return (voltage); } int stlink_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { - int ret; + int ret; - ret = sl->backend->read_debug32(sl, addr, data); - if (!ret) - DLOG("*** stlink_read_debug32 %#010x at %#010x\n", *data, addr); + ret = sl->backend->read_debug32(sl, addr, data); + if (!ret) + DLOG("*** stlink_read_debug32 %#010x at %#010x\n", *data, addr); - return(ret); + return (ret); } int stlink_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { - DLOG("*** stlink_write_debug32 %#010x to %#010x\n", data, addr); - return sl->backend->write_debug32(sl, addr, data); + DLOG("*** stlink_write_debug32 %#010x to %#010x\n", data, addr); + return sl->backend->write_debug32(sl, addr, data); } int stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { - DLOG("*** stlink_write_mem32 %u bytes to %#x\n", len, addr); + DLOG("*** stlink_write_mem32 %u bytes to %#x\n", len, addr); - if (len % 4 != 0) { - ELOG("Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); - return(-1); - } + if (len % 4 != 0) { + ELOG("Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); + return (-1); + } - return(sl->backend->write_mem32(sl, addr, len)); + return (sl->backend->write_mem32(sl, addr, len)); } int stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { - DLOG("*** stlink_read_mem32 ***\n"); + DLOG("*** stlink_read_mem32 ***\n"); - if (len % 4 != 0) { // !!! never ever: fw gives just wrong values - ELOG("Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); - return(-1); - } + if (len % 4 != 0) { // !!! never ever: fw gives just wrong values + ELOG("Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4); + return (-1); + } - return(sl->backend->read_mem32(sl, addr, len)); + return (sl->backend->read_mem32(sl, addr, len)); } int stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { - DLOG("*** stlink_write_mem8 ***\n"); + DLOG("*** stlink_write_mem8 ***\n"); - if (len > 0x40) { // !!! never ever: Writing more then 0x40 bytes gives unexpected behaviour - ELOG("Data length > 64: +%d byte.\n", len); - return(-1); - } + if (len > 0x40) { // !!! never ever: Writing more then 0x40 bytes gives + // unexpected behaviour + ELOG("Data length > 64: +%d byte.\n", len); + return (-1); + } - return(sl->backend->write_mem8(sl, addr, len)); + return (sl->backend->write_mem8(sl, addr, len)); } int stlink_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { - DLOG("*** stlink_read_all_regs ***\n"); - return(sl->backend->read_all_regs(sl, regp)); + DLOG("*** stlink_read_all_regs ***\n"); + return (sl->backend->read_all_regs(sl, regp)); } int stlink_read_all_unsupported_regs(stlink_t *sl, struct stlink_reg *regp) { - DLOG("*** stlink_read_all_unsupported_regs ***\n"); - return(sl->backend->read_all_unsupported_regs(sl, regp)); + DLOG("*** stlink_read_all_unsupported_regs ***\n"); + return (sl->backend->read_all_unsupported_regs(sl, regp)); } int stlink_write_reg(stlink_t *sl, uint32_t reg, int idx) { - DLOG("*** stlink_write_reg\n"); - return(sl->backend->write_reg(sl, reg, idx)); + DLOG("*** stlink_write_reg\n"); + return (sl->backend->write_reg(sl, reg, idx)); } int stlink_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { - DLOG("*** stlink_read_reg\n"); - DLOG(" (%d) ***\n", r_idx); + DLOG("*** stlink_read_reg\n"); + DLOG(" (%d) ***\n", r_idx); - if (r_idx > 20 || r_idx < 0) { - fprintf(stderr, "Error: register index must be in [0..20]\n"); - return(-1); - } + if (r_idx > 20 || r_idx < 0) { + fprintf(stderr, "Error: register index must be in [0..20]\n"); + return (-1); + } - return(sl->backend->read_reg(sl, r_idx, regp)); + return (sl->backend->read_reg(sl, r_idx, regp)); } -int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { - int r_convert; +int stlink_read_unsupported_reg(stlink_t *sl, int r_idx, + struct stlink_reg *regp) { + int r_convert; - DLOG("*** stlink_read_unsupported_reg\n"); - DLOG(" (%d) ***\n", r_idx); + DLOG("*** stlink_read_unsupported_reg\n"); + DLOG(" (%d) ***\n", r_idx); - /* Convert to values used by STLINK_REG_DCRSR */ - if (r_idx >= 0x1C && r_idx <= 0x1F) { // primask, basepri, faultmask, or control - r_convert = 0x14; - } else if (r_idx == 0x40) { // FPSCR - r_convert = 0x21; - } else if (r_idx >= 0x20 && r_idx < 0x40) { - r_convert = 0x40 + (r_idx - 0x20); - } else { - fprintf(stderr, "Error: register address must be in [0x1C..0x40]\n"); - return(-1); - } + /* Convert to values used by STLINK_REG_DCRSR */ + if (r_idx >= 0x1C && + r_idx <= 0x1F) { // primask, basepri, faultmask, or control + r_convert = 0x14; + } else if (r_idx == 0x40) { // FPSCR + r_convert = 0x21; + } else if (r_idx >= 0x20 && r_idx < 0x40) { + r_convert = 0x40 + (r_idx - 0x20); + } else { + fprintf(stderr, "Error: register address must be in [0x1C..0x40]\n"); + return (-1); + } - return(sl->backend->read_unsupported_reg(sl, r_convert, regp)); + return (sl->backend->read_unsupported_reg(sl, r_convert, regp)); } -int stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, struct stlink_reg *regp) { - int r_convert; +int stlink_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, + struct stlink_reg *regp) { + int r_convert; - DLOG("*** stlink_write_unsupported_reg\n"); - DLOG(" (%d) ***\n", r_idx); + DLOG("*** stlink_write_unsupported_reg\n"); + DLOG(" (%d) ***\n", r_idx); - /* Convert to values used by STLINK_REG_DCRSR */ - if (r_idx >= 0x1C && r_idx <= 0x1F) { /* primask, basepri, faultmask, or control */ - r_convert = r_idx; // the backend function handles this - } else if (r_idx == 0x40) { // FPSCR - r_convert = 0x21; - } else if (r_idx >= 0x20 && r_idx < 0x40) { - r_convert = 0x40 + (r_idx - 0x20); - } else { - fprintf(stderr, "Error: register address must be in [0x1C..0x40]\n"); - return(-1); - } + /* Convert to values used by STLINK_REG_DCRSR */ + if (r_idx >= 0x1C && + r_idx <= 0x1F) { /* primask, basepri, faultmask, or control */ + r_convert = r_idx; // the backend function handles this + } else if (r_idx == 0x40) { // FPSCR + r_convert = 0x21; + } else if (r_idx >= 0x20 && r_idx < 0x40) { + r_convert = 0x40 + (r_idx - 0x20); + } else { + fprintf(stderr, "Error: register address must be in [0x1C..0x40]\n"); + return (-1); + } - return(sl->backend->write_unsupported_reg(sl, val, r_convert, regp)); + return (sl->backend->write_unsupported_reg(sl, val, r_convert, regp)); } bool stlink_is_core_halted(stlink_t *sl) { - stlink_status(sl); - return(sl->core_stat == TARGET_HALTED); + stlink_status(sl); + return (sl->core_stat == TARGET_HALTED); } int stlink_step(stlink_t *sl) { - DLOG("*** stlink_step ***\n"); - return(sl->backend->step(sl)); + DLOG("*** stlink_step ***\n"); + return (sl->backend->step(sl)); } int stlink_current_mode(stlink_t *sl) { - int mode = sl->backend->current_mode(sl); - - switch (mode) { - case STLINK_DEV_DFU_MODE: - DLOG("stlink current mode: dfu\n"); - return(mode); - case STLINK_DEV_DEBUG_MODE: - DLOG("stlink current mode: debug (jtag or swd)\n"); - return(mode); - case STLINK_DEV_MASS_MODE: - DLOG("stlink current mode: mass\n"); - return(mode); - } + int mode = sl->backend->current_mode(sl); - DLOG("stlink mode: unknown!\n"); - return(STLINK_DEV_UNKNOWN_MODE); -} + switch (mode) { + case STLINK_DEV_DFU_MODE: + DLOG("stlink current mode: dfu\n"); + return (mode); + case STLINK_DEV_DEBUG_MODE: + DLOG("stlink current mode: debug (jtag or swd)\n"); + return (mode); + case STLINK_DEV_MASS_MODE: + DLOG("stlink current mode: mass\n"); + return (mode); + } -int stlink_trace_enable(stlink_t* sl, uint32_t frequency) { - DLOG("*** stlink_trace_enable ***\n"); - return(sl->backend->trace_enable(sl, frequency)); + DLOG("stlink mode: unknown!\n"); + return (STLINK_DEV_UNKNOWN_MODE); } -int stlink_trace_disable(stlink_t* sl) { - DLOG("*** stlink_trace_disable ***\n"); - return(sl->backend->trace_disable(sl)); +int stlink_trace_enable(stlink_t *sl, uint32_t frequency) { + DLOG("*** stlink_trace_enable ***\n"); + return (sl->backend->trace_enable(sl, frequency)); } -int stlink_trace_read(stlink_t* sl, uint8_t* buf, size_t size) { - return(sl->backend->trace_read(sl, buf, size)); +int stlink_trace_disable(stlink_t *sl) { + DLOG("*** stlink_trace_disable ***\n"); + return (sl->backend->trace_disable(sl)); } +int stlink_trace_read(stlink_t *sl, uint8_t *buf, size_t size) { + return (sl->backend->trace_read(sl, buf, size)); +} // End of delegates.... Common code below here... - - // same as above with entrypoint. void stlink_run_at(stlink_t *sl, stm32_addr_t addr) { - stlink_write_reg(sl, addr, 15); /* pc register */ - stlink_run(sl, RUN_NORMAL); + stlink_write_reg(sl, addr, 15); /* pc register */ + stlink_run(sl, RUN_NORMAL); - while (stlink_is_core_halted(sl)) { usleep(3000000); } + while (stlink_is_core_halted(sl)) { + usleep(3000000); + } } - // this function is called by stlink_status() // do not call stlink_core_stat() directly, always use stlink_status() void stlink_core_stat(stlink_t *sl) { - switch (sl->core_stat ) { - case TARGET_RUNNING: - DLOG(" core status: running\n"); - return; - case TARGET_HALTED: - DLOG(" core status: halted\n"); - return; - case TARGET_RESET: - DLOG(" core status: reset\n"); - return; - case TARGET_DEBUG_RUNNING: - DLOG(" core status: debug running\n"); - return; - default: - DLOG(" core status: unknown\n"); - } + switch (sl->core_stat) { + case TARGET_RUNNING: + DLOG(" core status: running\n"); + return; + case TARGET_HALTED: + DLOG(" core status: halted\n"); + return; + case TARGET_RESET: + DLOG(" core status: reset\n"); + return; + case TARGET_DEBUG_RUNNING: + DLOG(" core status: debug running\n"); + return; + default: + DLOG(" core status: unknown\n"); + } } -void stlink_print_data(stlink_t * sl) { - if (sl->q_len <= 0 || sl->verbose < UDEBUG) { return; } +void stlink_print_data(stlink_t *sl) { + if (sl->q_len <= 0 || sl->verbose < UDEBUG) { + return; + } - if (sl->verbose > 2) { DLOG("data_len = %d 0x%x\n", sl->q_len, sl->q_len); } + if (sl->verbose > 2) { + DLOG("data_len = %d 0x%x\n", sl->q_len, sl->q_len); + } - for (int i = 0; i < sl->q_len; i++) { - if (i % 16 == 0) { - /* - if (sl->q_data_dir == Q_DATA_OUT) { - fprintf(stdout, "\n<- 0x%08x ", sl->q_addr + i); - } else { - fprintf(stdout, "\n-> 0x%08x ", sl->q_addr + i); - } - */ - } - //DLOG(" %02x", (unsigned int) sl->q_buf[i]); - fprintf(stderr, " %02x", (unsigned int) sl->q_buf[i]); + for (int i = 0; i < sl->q_len; i++) { + if (i % 16 == 0) { + /* + if (sl->q_data_dir == Q_DATA_OUT) { + fprintf(stdout, "\n<- 0x%08x ", sl->q_addr + i); + } else { + fprintf(stdout, "\n-> 0x%08x ", sl->q_addr + i); + } + */ } - //DLOG("\n\n"); - fprintf(stderr, "\n"); + // DLOG(" %02x", (unsigned int) sl->q_buf[i]); + fprintf(stderr, " %02x", (unsigned int)sl->q_buf[i]); + } + // DLOG("\n\n"); + fprintf(stderr, "\n"); } /* Memory mapped file */ typedef struct mapped_file { - uint8_t* base; - size_t len; + uint8_t *base; + size_t len; } mapped_file_t; -#define MAPPED_FILE_INITIALIZER { NULL, 0 } +#define MAPPED_FILE_INITIALIZER \ + { NULL, 0 } -static int map_file(mapped_file_t* mf, const char* path) { - int error = -1; - struct stat st; +static int map_file(mapped_file_t *mf, const char *path) { + int error = -1; + struct stat st; - const int fd = open(path, O_RDONLY | O_BINARY); + const int fd = open(path, O_RDONLY | O_BINARY); - if (fd == -1) { - fprintf(stderr, "open(%s) == -1\n", path); - return(-1); - } + if (fd == -1) { + fprintf(stderr, "open(%s) == -1\n", path); + return (-1); + } - if (fstat(fd, &st) == -1) { - fprintf(stderr, "fstat(%s) == -1\n", path); - goto on_error; - } + if (fstat(fd, &st) == -1) { + fprintf(stderr, "fstat(%s) == -1\n", path); + goto on_error; + } - if (sizeof(st.st_size) != sizeof(size_t)) { - // on 32 bit systems, check if there is an overflow - if (st.st_size > (off_t)INT32_MAX) { - fprintf(stderr, "mmap() size_t overflow for file %s\n", path); - goto on_error; - } + if (sizeof(st.st_size) != sizeof(size_t)) { + // on 32 bit systems, check if there is an overflow + if (st.st_size > (off_t)INT32_MAX) { + fprintf(stderr, "mmap() size_t overflow for file %s\n", path); + goto on_error; } + } - mf->base = (uint8_t*)mmap(NULL, (size_t)(st.st_size), PROT_READ, MAP_SHARED, fd, 0); + mf->base = + (uint8_t *)mmap(NULL, (size_t)(st.st_size), PROT_READ, MAP_SHARED, fd, 0); - if (mf->base == MAP_FAILED) { - fprintf(stderr, "mmap() == MAP_FAILED for file %s\n", path); - goto on_error; - } + if (mf->base == MAP_FAILED) { + fprintf(stderr, "mmap() == MAP_FAILED for file %s\n", path); + goto on_error; + } - mf->len = st.st_size; - error = 0; // success + mf->len = st.st_size; + error = 0; // success on_error: - close(fd); - return(error); + close(fd); + return (error); } -static void unmap_file(mapped_file_t * mf) { - munmap((void*)mf->base, mf->len); - mf->base = (unsigned char*)MAP_FAILED; - mf->len = 0; +static void unmap_file(mapped_file_t *mf) { + munmap((void *)mf->base, mf->len); + mf->base = (unsigned char *)MAP_FAILED; + mf->len = 0; } -/* Limit the block size to compare to 0x1800 as anything larger will stall the STLINK2 - * Maybe STLINK V1 needs smaller value! +/* Limit the block size to compare to 0x1800 as anything larger will stall the + * STLINK2 Maybe STLINK V1 needs smaller value! */ -static int check_file(stlink_t* sl, mapped_file_t* mf, stm32_addr_t addr) { - size_t off; - size_t n_cmp = sl->flash_pgsz; +static int check_file(stlink_t *sl, mapped_file_t *mf, stm32_addr_t addr) { + size_t off; + size_t n_cmp = sl->flash_pgsz; - if ( n_cmp > 0x1800) { n_cmp = 0x1800; } + if (n_cmp > 0x1800) { + n_cmp = 0x1800; + } - for (off = 0; off < mf->len; off += n_cmp) { - size_t aligned_size; + for (off = 0; off < mf->len; off += n_cmp) { + size_t aligned_size; - size_t cmp_size = n_cmp; // adjust last page size + size_t cmp_size = n_cmp; // adjust last page size - if ((off + n_cmp) > mf->len) { cmp_size = mf->len - off; } + if ((off + n_cmp) > mf->len) { + cmp_size = mf->len - off; + } - aligned_size = cmp_size; + aligned_size = cmp_size; - if (aligned_size & (4 - 1)) { aligned_size = (cmp_size + 4) & ~(4 - 1); } + if (aligned_size & (4 - 1)) { + aligned_size = (cmp_size + 4) & ~(4 - 1); + } - stlink_read_mem32(sl, addr + (uint32_t)off, aligned_size); + stlink_read_mem32(sl, addr + (uint32_t)off, aligned_size); - if (memcmp(sl->q_buf, mf->base + off, cmp_size)) { return(-1); } + if (memcmp(sl->q_buf, mf->base + off, cmp_size)) { + return (-1); } + } - return(0); + return (0); } static void md5_calculate(mapped_file_t *mf) { - // calculate md5 checksum of given binary file - Md5Context md5Context; - MD5_HASH md5Hash; - Md5Initialise(&md5Context); - Md5Update(&md5Context, mf->base, (uint32_t)mf->len); - Md5Finalise(&md5Context, &md5Hash); - printf("md5 checksum: "); + // calculate md5 checksum of given binary file + Md5Context md5Context; + MD5_HASH md5Hash; + Md5Initialise(&md5Context); + Md5Update(&md5Context, mf->base, (uint32_t)mf->len); + Md5Finalise(&md5Context, &md5Hash); + printf("md5 checksum: "); - for (int i = 0; i < (int)sizeof(md5Hash); i++) { printf("%x", md5Hash.bytes[i]); } + for (int i = 0; i < (int)sizeof(md5Hash); i++) { + printf("%x", md5Hash.bytes[i]); + } - printf(", "); + printf(", "); } static void stlink_checksum(mapped_file_t *mp) { - /* checksum that backward compatible with official ST tools */ - uint32_t sum = 0; - uint8_t *mp_byte = (uint8_t *)mp->base; + /* checksum that backward compatible with official ST tools */ + uint32_t sum = 0; + uint8_t *mp_byte = (uint8_t *)mp->base; - for (size_t i = 0; i < mp->len; ++i) { sum += mp_byte[i]; } + for (size_t i = 0; i < mp->len; ++i) { + sum += mp_byte[i]; + } - printf("stlink checksum: 0x%08x\n", sum); + printf("stlink checksum: 0x%08x\n", sum); } static void stlink_fwrite_finalize(stlink_t *sl, stm32_addr_t addr) { - unsigned int val; - // set stack - stlink_read_debug32(sl, addr, &val); - stlink_write_reg(sl, val, 13); - // set PC to the reset routine - stlink_read_debug32(sl, addr + 4, &val); - stlink_write_reg(sl, val, 15); - stlink_run(sl, RUN_NORMAL); -} - -int stlink_mwrite_sram(stlink_t * sl, uint8_t* data, uint32_t length, stm32_addr_t addr) { - // write the file in sram at addr - - int error = -1; - size_t off; - size_t len; - - // check addr range is inside the sram - if (addr < sl->sram_base) { - fprintf(stderr, "addr too low\n"); - goto on_error; - } else if ((addr + length) < addr) { - fprintf(stderr, "addr overruns\n"); - goto on_error; - } else if ((addr + length) > (sl->sram_base + sl->sram_size)) { - fprintf(stderr, "addr too high\n"); - goto on_error; - } else if (addr & 3) { - fprintf(stderr, "unaligned addr\n"); - goto on_error; - } - - len = length; - - if (len & 3) { len -= len & 3; } - - // do the copy by 1kB blocks - for (off = 0; off < len; off += 1024) { - size_t size = 1024; - - if ((off + size) > len) { size = len - off; } - - memcpy(sl->q_buf, data + off, size); - - if (size & 3) { size += 2; } // round size if needed - - stlink_write_mem32(sl, addr + (uint32_t)off, size); - } - - if (length > len) { - memcpy(sl->q_buf, data + len, length - len); - stlink_write_mem8(sl, addr + (uint32_t)len, length - len); - } - - - error = 0; // success - stlink_fwrite_finalize(sl, addr); + unsigned int val; + // set stack + stlink_read_debug32(sl, addr, &val); + stlink_write_reg(sl, val, 13); + // set PC to the reset routine + stlink_read_debug32(sl, addr + 4, &val); + stlink_write_reg(sl, val, 15); + stlink_run(sl, RUN_NORMAL); +} + +int stlink_mwrite_sram(stlink_t *sl, uint8_t *data, uint32_t length, + stm32_addr_t addr) { + // write the file in sram at addr + + int error = -1; + size_t off; + size_t len; + + // check addr range is inside the sram + if (addr < sl->sram_base) { + fprintf(stderr, "addr too low\n"); + goto on_error; + } else if ((addr + length) < addr) { + fprintf(stderr, "addr overruns\n"); + goto on_error; + } else if ((addr + length) > (sl->sram_base + sl->sram_size)) { + fprintf(stderr, "addr too high\n"); + goto on_error; + } else if (addr & 3) { + fprintf(stderr, "unaligned addr\n"); + goto on_error; + } + + len = length; + + if (len & 3) { + len -= len & 3; + } + + // do the copy by 1kB blocks + for (off = 0; off < len; off += 1024) { + size_t size = 1024; + + if ((off + size) > len) { + size = len - off; + } + + memcpy(sl->q_buf, data + off, size); + + if (size & 3) { + size += 2; + } // round size if needed + + stlink_write_mem32(sl, addr + (uint32_t)off, size); + } + + if (length > len) { + memcpy(sl->q_buf, data + len, length - len); + stlink_write_mem8(sl, addr + (uint32_t)len, length - len); + } + + error = 0; // success + stlink_fwrite_finalize(sl, addr); on_error: - return(error); + return (error); } -int stlink_fwrite_sram(stlink_t * sl, const char* path, stm32_addr_t addr) { - // write the file in sram at addr +int stlink_fwrite_sram(stlink_t *sl, const char *path, stm32_addr_t addr) { + // write the file in sram at addr - int error = -1; - size_t off; - size_t len; - mapped_file_t mf = MAPPED_FILE_INITIALIZER; + int error = -1; + size_t off; + size_t len; + mapped_file_t mf = MAPPED_FILE_INITIALIZER; - if (map_file(&mf, path) == -1) { - fprintf(stderr, "map_file() == -1\n"); - return(-1); - } + if (map_file(&mf, path) == -1) { + fprintf(stderr, "map_file() == -1\n"); + return (-1); + } - printf("file %s ", path); - md5_calculate(&mf); - stlink_checksum(&mf); - - // check if addr range is inside the SRAM - if (addr < sl->sram_base) { - fprintf(stderr, "addr too low\n"); - goto on_error; - } else if ((addr + mf.len) < addr) { - fprintf(stderr, "addr overruns\n"); - goto on_error; - } else if ((addr + mf.len) > (sl->sram_base + sl->sram_size)) { - fprintf(stderr, "addr too high\n"); - goto on_error; - } else if (addr & 3) { - fprintf(stderr, "unaligned addr\n"); - goto on_error; - } + printf("file %s ", path); + md5_calculate(&mf); + stlink_checksum(&mf); - len = mf.len; + // check if addr range is inside the SRAM + if (addr < sl->sram_base) { + fprintf(stderr, "addr too low\n"); + goto on_error; + } else if ((addr + mf.len) < addr) { + fprintf(stderr, "addr overruns\n"); + goto on_error; + } else if ((addr + mf.len) > (sl->sram_base + sl->sram_size)) { + fprintf(stderr, "addr too high\n"); + goto on_error; + } else if (addr & 3) { + fprintf(stderr, "unaligned addr\n"); + goto on_error; + } - if (len & 3) { len -= len & 3; } + len = mf.len; - // do the copy by 1kB blocks - for (off = 0; off < len; off += 1024) { - size_t size = 1024; + if (len & 3) { + len -= len & 3; + } - if ((off + size) > len) { size = len - off; } + // do the copy by 1kB blocks + for (off = 0; off < len; off += 1024) { + size_t size = 1024; - memcpy(sl->q_buf, mf.base + off, size); + if ((off + size) > len) { + size = len - off; + } - if (size & 3) { size += 2; } // round size if needed + memcpy(sl->q_buf, mf.base + off, size); - stlink_write_mem32(sl, addr + (uint32_t)off, size); - } + if (size & 3) { + size += 2; + } // round size if needed - if (mf.len > len) { - memcpy(sl->q_buf, mf.base + len, mf.len - len); - stlink_write_mem8(sl, addr + (uint32_t)len, mf.len - len); - } + stlink_write_mem32(sl, addr + (uint32_t)off, size); + } - // check the file has been written - if (check_file(sl, &mf, addr) == -1) { - fprintf(stderr, "check_file() == -1\n"); - goto on_error; - } + if (mf.len > len) { + memcpy(sl->q_buf, mf.base + len, mf.len - len); + stlink_write_mem8(sl, addr + (uint32_t)len, mf.len - len); + } - error = 0; // success - stlink_fwrite_finalize(sl, addr); + // check the file has been written + if (check_file(sl, &mf, addr) == -1) { + fprintf(stderr, "check_file() == -1\n"); + goto on_error; + } + + error = 0; // success + stlink_fwrite_finalize(sl, addr); on_error: - unmap_file(&mf); - return(error); + unmap_file(&mf); + return (error); } -typedef bool (*save_block_fn)(void* arg, uint8_t* block, ssize_t len); +typedef bool (*save_block_fn)(void *arg, uint8_t *block, ssize_t len); -static int stlink_read( - stlink_t* sl, stm32_addr_t addr, size_t size, save_block_fn fn, void* fn_arg) { +static int stlink_read(stlink_t *sl, stm32_addr_t addr, size_t size, + save_block_fn fn, void *fn_arg) { - int error = -1; + int error = -1; - if (size < 1) { size = sl->flash_size; } + if (size < 1) { + size = sl->flash_size; + } - if (size > sl->flash_size) { - size = sl->flash_size; - } + if (size > sl->flash_size) { + size = sl->flash_size; + } - size_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; + size_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; - for (size_t off = 0; off < size; off += cmp_size) { - size_t aligned_size; + for (size_t off = 0; off < size; off += cmp_size) { + size_t aligned_size; - // adjust last page size - if ((off + cmp_size) > size) { cmp_size = size - off; } + // adjust last page size + if ((off + cmp_size) > size) { + cmp_size = size - off; + } - aligned_size = cmp_size; + aligned_size = cmp_size; - if (aligned_size & (4 - 1)) { aligned_size = (cmp_size + 4) & ~(4 - 1); } + if (aligned_size & (4 - 1)) { + aligned_size = (cmp_size + 4) & ~(4 - 1); + } - stlink_read_mem32(sl, addr + (uint32_t)off, aligned_size); + stlink_read_mem32(sl, addr + (uint32_t)off, aligned_size); - if (!fn(fn_arg, sl->q_buf, aligned_size)) { goto on_error; } + if (!fn(fn_arg, sl->q_buf, aligned_size)) { + goto on_error; } + } - error = 0; // success + error = 0; // success on_error: - return(error); + return (error); } struct stlink_fread_worker_arg { - int fd; + int fd; }; -static bool stlink_fread_worker(void* arg, uint8_t* block, ssize_t len) { - struct stlink_fread_worker_arg* the_arg = (struct stlink_fread_worker_arg*)arg; +static bool stlink_fread_worker(void *arg, uint8_t *block, ssize_t len) { + struct stlink_fread_worker_arg *the_arg = + (struct stlink_fread_worker_arg *)arg; - if (write(the_arg->fd, block, len) != len) { - fprintf(stderr, "write() != aligned_size\n"); - return(false); - } else { - return(true); - } + if (write(the_arg->fd, block, len) != len) { + fprintf(stderr, "write() != aligned_size\n"); + return (false); + } else { + return (true); + } } struct stlink_fread_ihex_worker_arg { - FILE* file; - uint32_t addr; - uint32_t lba; - uint8_t buf[16]; - uint8_t buf_pos; + FILE *file; + uint32_t addr; + uint32_t lba; + uint8_t buf[16]; + uint8_t buf_pos; }; -static bool stlink_fread_ihex_newsegment(struct stlink_fread_ihex_worker_arg* the_arg) { - uint32_t addr = the_arg->addr; - uint8_t sum = 2 + 4 + (uint8_t)((addr & 0xFF000000) >> 24) + (uint8_t)((addr & 0x00FF0000) >> 16); +static bool +stlink_fread_ihex_newsegment(struct stlink_fread_ihex_worker_arg *the_arg) { + uint32_t addr = the_arg->addr; + uint8_t sum = 2 + 4 + (uint8_t)((addr & 0xFF000000) >> 24) + + (uint8_t)((addr & 0x00FF0000) >> 16); - if (17 != fprintf(the_arg->file, ":02000004%04X%02X\r\n", (addr & 0xFFFF0000) >> 16, - (uint8_t)(0x100 - sum))) { - return(false); - } + if (17 != fprintf(the_arg->file, ":02000004%04X%02X\r\n", + (addr & 0xFFFF0000) >> 16, (uint8_t)(0x100 - sum))) { + return (false); + } - the_arg->lba = (addr & 0xFFFF0000); - return(true); + the_arg->lba = (addr & 0xFFFF0000); + return (true); } -static bool stlink_fread_ihex_writeline(struct stlink_fread_ihex_worker_arg* the_arg) { - uint8_t count = the_arg->buf_pos; +static bool +stlink_fread_ihex_writeline(struct stlink_fread_ihex_worker_arg *the_arg) { + uint8_t count = the_arg->buf_pos; - if (count == 0) { return(true); } + if (count == 0) { + return (true); + } - uint32_t addr = the_arg->addr; + uint32_t addr = the_arg->addr; - if (the_arg->lba != (addr & 0xFFFF0000)) { // segment changed - if (!stlink_fread_ihex_newsegment(the_arg)) { - return(false); - } + if (the_arg->lba != (addr & 0xFFFF0000)) { // segment changed + if (!stlink_fread_ihex_newsegment(the_arg)) { + return (false); } + } - uint8_t sum = count + (uint8_t)((addr & 0x0000FF00) >> 8) + (uint8_t)(addr & 0x000000FF); + uint8_t sum = count + (uint8_t)((addr & 0x0000FF00) >> 8) + + (uint8_t)(addr & 0x000000FF); - if (9 != fprintf(the_arg->file, ":%02X%04X00", count, (addr & 0x0000FFFF))) { - return(false); - } + if (9 != fprintf(the_arg->file, ":%02X%04X00", count, (addr & 0x0000FFFF))) { + return (false); + } - for (uint8_t i = 0; i < count; ++i) { - uint8_t b = the_arg->buf[i]; - sum += b; + for (uint8_t i = 0; i < count; ++i) { + uint8_t b = the_arg->buf[i]; + sum += b; - if (2 != fprintf(the_arg->file, "%02X", b)) { - return(false); - } + if (2 != fprintf(the_arg->file, "%02X", b)) { + return (false); } + } - if (4 != fprintf(the_arg->file, "%02X\r\n", (uint8_t)(0x100 - sum))) { - return(false); - } + if (4 != fprintf(the_arg->file, "%02X\r\n", (uint8_t)(0x100 - sum))) { + return (false); + } - the_arg->addr += count; - the_arg->buf_pos = 0; + the_arg->addr += count; + the_arg->buf_pos = 0; - return(true); + return (true); } -static bool stlink_fread_ihex_init( - struct stlink_fread_ihex_worker_arg* the_arg, int fd, stm32_addr_t addr) { - the_arg->file = fdopen(fd, "w"); - the_arg->addr = addr; - the_arg->lba = 0; - the_arg->buf_pos = 0; +static bool stlink_fread_ihex_init(struct stlink_fread_ihex_worker_arg *the_arg, + int fd, stm32_addr_t addr) { + the_arg->file = fdopen(fd, "w"); + the_arg->addr = addr; + the_arg->lba = 0; + the_arg->buf_pos = 0; - return (the_arg->file != NULL); + return (the_arg->file != NULL); } -static bool stlink_fread_ihex_worker(void* arg, uint8_t* block, ssize_t len) { - struct stlink_fread_ihex_worker_arg* the_arg = (struct stlink_fread_ihex_worker_arg*)arg; - - for (ssize_t i = 0; i < len; ++i) { - if (the_arg->buf_pos == sizeof(the_arg->buf)) { // line is full - if (!stlink_fread_ihex_writeline(the_arg)) { return(false); } - } +static bool stlink_fread_ihex_worker(void *arg, uint8_t *block, ssize_t len) { + struct stlink_fread_ihex_worker_arg *the_arg = + (struct stlink_fread_ihex_worker_arg *)arg; - the_arg->buf[the_arg->buf_pos++] = block[i]; + for (ssize_t i = 0; i < len; ++i) { + if (the_arg->buf_pos == sizeof(the_arg->buf)) { // line is full + if (!stlink_fread_ihex_writeline(the_arg)) { + return (false); + } } - return(true); + the_arg->buf[the_arg->buf_pos++] = block[i]; + } + + return (true); } -static bool stlink_fread_ihex_finalize(struct stlink_fread_ihex_worker_arg* the_arg) { - if (!stlink_fread_ihex_writeline(the_arg)) { return(false); } +static bool +stlink_fread_ihex_finalize(struct stlink_fread_ihex_worker_arg *the_arg) { + if (!stlink_fread_ihex_writeline(the_arg)) { + return (false); + } - // FIXME: do we need the Start Linear Address? + // FIXME: do we need the Start Linear Address? - if (13 != fprintf(the_arg->file, ":00000001FF\r\n")) { // EoF - return(false); - } + if (13 != fprintf(the_arg->file, ":00000001FF\r\n")) { // EoF + return (false); + } - return (0 == fclose(the_arg->file)); + return (0 == fclose(the_arg->file)); } -int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size) { - // read size bytes from addr to file - ILOG("read from address %#010x size %u\n", addr, (unsigned)size); +int stlink_fread(stlink_t *sl, const char *path, bool is_ihex, + stm32_addr_t addr, size_t size) { + // read size bytes from addr to file + ILOG("read from address %#010x size %u\n", addr, (unsigned)size); - int error; - int fd = open(path, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 00700); + int error; + int fd = open(path, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 00700); - if (fd == -1) { - fprintf(stderr, "open(%s) == -1\n", path); - return(-1); - } + if (fd == -1) { + fprintf(stderr, "open(%s) == -1\n", path); + return (-1); + } - if (is_ihex) { - struct stlink_fread_ihex_worker_arg arg; + if (is_ihex) { + struct stlink_fread_ihex_worker_arg arg; - if (stlink_fread_ihex_init(&arg, fd, addr)) { - error = stlink_read(sl, addr, size, &stlink_fread_ihex_worker, &arg); + if (stlink_fread_ihex_init(&arg, fd, addr)) { + error = stlink_read(sl, addr, size, &stlink_fread_ihex_worker, &arg); - if (!stlink_fread_ihex_finalize(&arg)) { error = -1; } - } else { - error = -1; - } + if (!stlink_fread_ihex_finalize(&arg)) { + error = -1; + } } else { - struct stlink_fread_worker_arg arg = { fd }; - error = stlink_read(sl, addr, size, &stlink_fread_worker, &arg); + error = -1; } + } else { + struct stlink_fread_worker_arg arg = {fd}; + error = stlink_read(sl, addr, size, &stlink_fread_worker, &arg); + } - close(fd); - return(error); + close(fd); + return (error); } -int write_buffer_to_sram(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, size_t size) { - // write the buffer right after the loader - size_t chunk = size & ~0x3; - size_t rem = size & 0x3; +int write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *buf, + size_t size) { + // write the buffer right after the loader + size_t chunk = size & ~0x3; + size_t rem = size & 0x3; - if (chunk) { - memcpy(sl->q_buf, buf, chunk); - stlink_write_mem32(sl, fl->buf_addr, chunk); - } + if (chunk) { + memcpy(sl->q_buf, buf, chunk); + stlink_write_mem32(sl, fl->buf_addr, chunk); + } - if (rem) { - memcpy(sl->q_buf, buf + chunk, rem); - stlink_write_mem8(sl, (fl->buf_addr) + (uint32_t)chunk, rem); - } + if (rem) { + memcpy(sl->q_buf, buf + chunk, rem); + stlink_write_mem8(sl, (fl->buf_addr) + (uint32_t)chunk, rem); + } - return(0); + return (0); } uint32_t calculate_F4_sectornum(uint32_t flashaddr) { - uint32_t offset = 0; - flashaddr &= ~STM32_FLASH_BASE; // page now holding the actual flash address - - if (flashaddr >= 0x100000) { - offset = 12; - flashaddr -= 0x100000; - } - - if (flashaddr < 0x4000) { - return (offset + 0); - } else if (flashaddr < 0x8000) { - return(offset + 1); - } else if (flashaddr < 0xc000) { - return(offset + 2); - } else if (flashaddr < 0x10000) { - return(offset + 3); - } else if (flashaddr < 0x20000) { - return(offset + 4); - } else { - return(offset + (flashaddr / 0x20000) + 4); - } - + uint32_t offset = 0; + flashaddr &= ~STM32_FLASH_BASE; // page now holding the actual flash address + + if (flashaddr >= 0x100000) { + offset = 12; + flashaddr -= 0x100000; + } + + if (flashaddr < 0x4000) { + return (offset + 0); + } else if (flashaddr < 0x8000) { + return (offset + 1); + } else if (flashaddr < 0xc000) { + return (offset + 2); + } else if (flashaddr < 0x10000) { + return (offset + 3); + } else if (flashaddr < 0x20000) { + return (offset + 4); + } else { + return (offset + (flashaddr / 0x20000) + 4); + } } uint32_t calculate_F7_sectornum(uint32_t flashaddr) { - flashaddr &= ~STM32_FLASH_BASE; // Page now holding the actual flash address - - if (flashaddr < 0x20000) { - return(flashaddr / 0x8000); - } else if (flashaddr < 0x40000) { - return(4); - } else { - return((flashaddr / 0x40000) + 4); - } + flashaddr &= ~STM32_FLASH_BASE; // Page now holding the actual flash address + if (flashaddr < 0x20000) { + return (flashaddr / 0x8000); + } else if (flashaddr < 0x40000) { + return (4); + } else { + return ((flashaddr / 0x40000) + 4); + } } -uint32_t calculate_H7_sectornum(stlink_t *sl, uint32_t flashaddr, unsigned bank) { - flashaddr &= ~((bank==BANK_1)?STM32_FLASH_BASE:STM32_H7_FLASH_BANK2_BASE); // sector holding the flash address - return(flashaddr / sl->flash_pgsz); +uint32_t calculate_H7_sectornum(stlink_t *sl, uint32_t flashaddr, + unsigned bank) { + flashaddr &= + ~((bank == BANK_1) + ? STM32_FLASH_BASE + : STM32_H7_FLASH_BANK2_BASE); // sector holding the flash address + return (flashaddr / sl->flash_pgsz); } // returns BKER:PNB for the given page address uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { - uint32_t bker = 0; - uint32_t flashopt; - stlink_read_debug32(sl, STM32L4_FLASH_OPTR, &flashopt); - flashaddr -= STM32_FLASH_BASE; - - if (sl->chip_id == STLINK_CHIPID_STM32_L4 || - sl->chip_id == STLINK_CHIPID_STM32_L496X || - sl->chip_id == STLINK_CHIPID_STM32_L4RX) { - // this chip use dual banked flash - if (flashopt & (uint32_t)(1lu << STM32L4_FLASH_OPTR_DUALBANK)) { - uint32_t banksize = (uint32_t)sl->flash_size / 2; - - if (flashaddr >= banksize) { - flashaddr -= banksize; - bker = 0x100; - } - } + uint32_t bker = 0; + uint32_t flashopt; + stlink_read_debug32(sl, STM32L4_FLASH_OPTR, &flashopt); + flashaddr -= STM32_FLASH_BASE; + + if (sl->chip_id == STLINK_CHIPID_STM32_L4 || + sl->chip_id == STLINK_CHIPID_STM32_L496X || + sl->chip_id == STLINK_CHIPID_STM32_L4RX) { + // this chip use dual banked flash + if (flashopt & (uint32_t)(1lu << STM32L4_FLASH_OPTR_DUALBANK)) { + uint32_t banksize = (uint32_t)sl->flash_size / 2; + + if (flashaddr >= banksize) { + flashaddr -= banksize; + bker = 0x100; + } } + } - // For 1MB chips without the dual-bank option set, the page address will overflow - // into the BKER bit, which gives us the correct bank:page value. - return(bker | flashaddr / (uint32_t)sl->flash_pgsz); + // For 1MB chips without the dual-bank option set, the page address will + // overflow into the BKER bit, which gives us the correct bank:page value. + return (bker | flashaddr / (uint32_t)sl->flash_pgsz); } uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { - if ((sl->chip_id == STLINK_CHIPID_STM32_F2) || - (sl->chip_id == STLINK_CHIPID_STM32_F4) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_LP) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_HD) || - (sl->chip_id == STLINK_CHIPID_STM32_F411RE) || - (sl->chip_id == STLINK_CHIPID_STM32_F446) || - (sl->chip_id == STLINK_CHIPID_STM32_F4_DSI) || - (sl->chip_id == STLINK_CHIPID_STM32_F72XXX) || - (sl->chip_id == STLINK_CHIPID_STM32_F412)) { - uint32_t sector = calculate_F4_sectornum(flashaddr); - - if (sector >= 12) { sector -= 12; } - - if (sector < 4) { - sl->flash_pgsz = 0x4000; - } else if (sector < 5) { - sl->flash_pgsz = 0x10000; - } else { - sl->flash_pgsz = 0x20000; - } - } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || - sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { - uint32_t sector = calculate_F7_sectornum(flashaddr); + if ((sl->chip_id == STLINK_CHIPID_STM32_F2) || + (sl->chip_id == STLINK_CHIPID_STM32_F4) || + (sl->chip_id == STLINK_CHIPID_STM32_F4_DE) || + (sl->chip_id == STLINK_CHIPID_STM32_F4_LP) || + (sl->chip_id == STLINK_CHIPID_STM32_F4_HD) || + (sl->chip_id == STLINK_CHIPID_STM32_F411RE) || + (sl->chip_id == STLINK_CHIPID_STM32_F446) || + (sl->chip_id == STLINK_CHIPID_STM32_F4_DSI) || + (sl->chip_id == STLINK_CHIPID_STM32_F72XXX) || + (sl->chip_id == STLINK_CHIPID_STM32_F412)) { + uint32_t sector = calculate_F4_sectornum(flashaddr); + + if (sector >= 12) { + sector -= 12; + } + + if (sector < 4) { + sl->flash_pgsz = 0x4000; + } else if (sector < 5) { + sl->flash_pgsz = 0x10000; + } else { + sl->flash_pgsz = 0x20000; + } + } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || + sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { + uint32_t sector = calculate_F7_sectornum(flashaddr); - if (sector < 4) { - sl->flash_pgsz = 0x8000; - } else if (sector < 5) { - sl->flash_pgsz = 0x20000; - } else { - sl->flash_pgsz = 0x40000; - } + if (sector < 4) { + sl->flash_pgsz = 0x8000; + } else if (sector < 5) { + sl->flash_pgsz = 0x20000; + } else { + sl->flash_pgsz = 0x40000; } + } - return((uint32_t)sl->flash_pgsz); + return ((uint32_t)sl->flash_pgsz); } /** - * Erase a page of flash, assumes sl is fully populated with things like chip/core ids + * Erase a page of flash, assumes sl is fully populated with things like + * chip/core ids * @param sl stlink context * @param flashaddr an address in the flash page to erase * @return 0 on success -ve on failure */ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { - // wait for ongoing op to finish - wait_flash_busy(sl); - // clear flash IO errors - clear_flash_error(sl); + // wait for ongoing op to finish + wait_flash_busy(sl); + // clear flash IO errors + clear_flash_error(sl); + + if (sl->flash_type == STLINK_FLASH_TYPE_F4 || + sl->flash_type == STLINK_FLASH_TYPE_F7 || + sl->flash_type == STLINK_FLASH_TYPE_L4) { + // unlock if locked + unlock_flash_if(sl); + + // select the page to erase + if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || + (sl->chip_id == STLINK_CHIPID_STM32_L43X) || + (sl->chip_id == STLINK_CHIPID_STM32_L46X) || + (sl->chip_id == STLINK_CHIPID_STM32_L496X) || + (sl->chip_id == STLINK_CHIPID_STM32_L4RX)) { + // calculate the actual bank+page from the address + uint32_t page = calculate_L4_page(sl, flashaddr); + + fprintf(stderr, "EraseFlash - Page:0x%x Size:0x%x ", page, + stlink_calculate_pagesize(sl, flashaddr)); + + write_flash_cr_bker_pnb(sl, page); + } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || + sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { + // calculate the actual page from the address + uint32_t sector = calculate_F7_sectornum(flashaddr); - if (sl->flash_type == STLINK_FLASH_TYPE_F4 || - sl->flash_type == STLINK_FLASH_TYPE_F7 || - sl->flash_type == STLINK_FLASH_TYPE_L4) { - // unlock if locked - unlock_flash_if(sl); - - // select the page to erase - if ((sl->chip_id == STLINK_CHIPID_STM32_L4) || - (sl->chip_id == STLINK_CHIPID_STM32_L43X) || - (sl->chip_id == STLINK_CHIPID_STM32_L46X) || - (sl->chip_id == STLINK_CHIPID_STM32_L496X) || - (sl->chip_id == STLINK_CHIPID_STM32_L4RX)) { - // calculate the actual bank+page from the address - uint32_t page = calculate_L4_page(sl, flashaddr); - - fprintf(stderr, "EraseFlash - Page:0x%x Size:0x%x ", - page, stlink_calculate_pagesize(sl, flashaddr)); - - write_flash_cr_bker_pnb(sl, page); - } else if (sl->chip_id == STLINK_CHIPID_STM32_F7 || - sl->chip_id == STLINK_CHIPID_STM32_F7XXXX) { - // calculate the actual page from the address - uint32_t sector = calculate_F7_sectornum(flashaddr); - - fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", - sector, stlink_calculate_pagesize(sl, flashaddr)); - write_flash_cr_snb(sl, sector, BANK_1); - } else { - // calculate the actual page from the address - uint32_t sector = calculate_F4_sectornum(flashaddr); + fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, + stlink_calculate_pagesize(sl, flashaddr)); + write_flash_cr_snb(sl, sector, BANK_1); + } else { + // calculate the actual page from the address + uint32_t sector = calculate_F4_sectornum(flashaddr); - fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", - sector, stlink_calculate_pagesize(sl, flashaddr)); + fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, + stlink_calculate_pagesize(sl, flashaddr)); - // the SNB values for flash sectors in the second bank do not directly - // follow the values for the first bank on 2mb devices... - if (sector >= 12) { sector += 4; } + // the SNB values for flash sectors in the second bank do not directly + // follow the values for the first bank on 2mb devices... + if (sector >= 12) { + sector += 4; + } - write_flash_cr_snb(sl, sector, BANK_1); - } + write_flash_cr_snb(sl, sector, BANK_1); + } - set_flash_cr_strt(sl, BANK_1); // start erase operation - wait_flash_busy(sl); // wait for completion - lock_flash(sl); // TODO: fails to program if this is in + set_flash_cr_strt(sl, BANK_1); // start erase operation + wait_flash_busy(sl); // wait for completion + lock_flash(sl); // TODO: fails to program if this is in #if DEBUG_FLASH - fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl, BANK_1)); + fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl, BANK_1)); #endif - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - uint32_t val; - uint32_t flash_regs_base = get_stm32l0_flash_base(sl); + uint32_t val; + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); - // check if the locks are set - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + // check if the locks are set + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - if ((val & (1 << 0)) || (val & (1 << 1))) { - // disable pecr protection - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY2); + if ((val & (1 << 0)) || (val & (1 << 1))) { + // disable pecr protection + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, + FLASH_L0_PEKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, + FLASH_L0_PEKEY2); - // check pecr.pelock is cleared - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + // check pecr.pelock is cleared + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - if (val & (1 << 0)) { - WLOG("pecr.pelock not clear (%#x)\n", val); - return(-1); - } + if (val & (1 << 0)) { + WLOG("pecr.pelock not clear (%#x)\n", val); + return (-1); + } - // unlock program memory - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY2); + // unlock program memory + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, + FLASH_L0_PRGKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, + FLASH_L0_PRGKEY2); - // check pecr.prglock is cleared - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + // check pecr.prglock is cleared + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - if (val & (1 << 1)) { - WLOG("pecr.prglock not clear (%#x)\n", val); - return(-1); - } - } + if (val & (1 << 1)) { + WLOG("pecr.prglock not clear (%#x)\n", val); + return (-1); + } + } - // set pecr.{erase,prog} - val |= (1 << 9) | (1 << 3); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - - // write 0 to the first word of the page to be erased - stlink_write_debug32(sl, flashaddr, 0); - - /* MP: It is better to wait for clearing the busy bit after issuing page - * erase command, even though PM0062 recommends to wait before it. - * Test shows that a few iterations is performed in the following loop - * before busy bit is cleared. - */ - wait_flash_busy(sl); - - // reset lock bits - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val |= (1 << 0) | (1 << 1) | (1 << 2); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || - sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - uint32_t val; - unlock_flash_if(sl); - set_flash_cr_per(sl, BANK_1); // set the 'enable Flash erase' bit - - // set the page to erase - if (sl->flash_type == STLINK_FLASH_TYPE_WB) { - uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); - stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); - - // sec 3.10.5 - PNB[7:0] is offset by 3. - val &= ~(0xFF << 3); // Clear previously set page number (if any) - val |= ((flash_page & 0xFF) << 3); - - stlink_write_debug32(sl, STM32WB_FLASH_CR, val); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { - uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - // sec 3.7.5 - PNB[5:0] is offset by 3. PER is 0x2. - val &= ~(0x3F << 3); - val |= ((flash_page & 0x3F) << 3) | (1 << FLASH_CR_PER); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G4) { - uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - // sec 3.7.5 - PNB[6:0] is offset by 3. PER is 0x2. - val &= ~(0x7F << 3); - val |= ((flash_page & 0x7F) << 3) | (1 << FLASH_CR_PER); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - } + // set pecr.{erase,prog} + val |= (1 << 9) | (1 << 3); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - set_flash_cr_strt(sl, BANK_1); // set the 'start operation' bit - wait_flash_busy(sl); // wait for the 'busy' bit to clear - clear_flash_cr_per(sl, BANK_1); // clear the 'enable page erase' bit - lock_flash(sl); - } else if (sl->flash_type == STLINK_FLASH_TYPE_F0 || - sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - unsigned bank = (flashaddr < STM32_F1_FLASH_BANK2_BASE)?BANK_1:BANK_2; - unlock_flash_if(sl); - clear_flash_cr_pg(sl, bank); // clear the pg bit - set_flash_cr_per(sl, bank); // set the page erase bit - write_flash_ar(sl, flashaddr, bank); // select the page to erase - set_flash_cr_strt(sl, bank); // start erase operation, reset by hw with busy bit - wait_flash_busy(sl); - clear_flash_cr_per(sl, bank); // clear the page erase bit - lock_flash(sl); - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - unsigned bank = (flashaddr < STM32_H7_FLASH_BANK2_BASE)?BANK_1:BANK_2; - unlock_flash_if(sl); // unlock if locked - uint32_t sector = calculate_H7_sectornum(sl, flashaddr, bank);// calculate the actual page from the address - write_flash_cr_snb(sl, sector, bank); // select the page to erase - set_flash_cr_strt(sl, bank); // start erase operation - wait_flash_busy(sl); // wait for completion - lock_flash(sl); - } else { - WLOG("unknown coreid %x, page erase failed\n", sl->core_id); - return(-1); - } + // write 0 to the first word of the page to be erased + stlink_write_debug32(sl, flashaddr, 0); + + /* MP: It is better to wait for clearing the busy bit after issuing page + * erase command, even though PM0062 recommends to wait before it. + * Test shows that a few iterations is performed in the following loop + * before busy bit is cleared. + */ + wait_flash_busy(sl); + + // reset lock bits + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val |= (1 << 0) | (1 << 1) | (1 << 2); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || + sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + uint32_t val; + unlock_flash_if(sl); + set_flash_cr_per(sl, BANK_1); // set the 'enable Flash erase' bit + + // set the page to erase + if (sl->flash_type == STLINK_FLASH_TYPE_WB) { + uint32_t flash_page = + ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); + stlink_read_debug32(sl, STM32WB_FLASH_CR, &val); + + // sec 3.10.5 - PNB[7:0] is offset by 3. + val &= ~(0xFF << 3); // Clear previously set page number (if any) + val |= ((flash_page & 0xFF) << 3); + + stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { + uint32_t flash_page = + ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + // sec 3.7.5 - PNB[5:0] is offset by 3. PER is 0x2. + val &= ~(0x3F << 3); + val |= ((flash_page & 0x3F) << 3) | (1 << FLASH_CR_PER); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + } else if (sl->flash_type == STLINK_FLASH_TYPE_G4) { + uint32_t flash_page = + ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + // sec 3.7.5 - PNB[6:0] is offset by 3. PER is 0x2. + val &= ~(0x7F << 3); + val |= ((flash_page & 0x7F) << 3) | (1 << FLASH_CR_PER); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + } + + set_flash_cr_strt(sl, BANK_1); // set the 'start operation' bit + wait_flash_busy(sl); // wait for the 'busy' bit to clear + clear_flash_cr_per(sl, BANK_1); // clear the 'enable page erase' bit + lock_flash(sl); + } else if (sl->flash_type == STLINK_FLASH_TYPE_F0 || + sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + unsigned bank = (flashaddr < STM32_F1_FLASH_BANK2_BASE) ? BANK_1 : BANK_2; + unlock_flash_if(sl); + clear_flash_cr_pg(sl, bank); // clear the pg bit + set_flash_cr_per(sl, bank); // set the page erase bit + write_flash_ar(sl, flashaddr, bank); // select the page to erase + set_flash_cr_strt(sl, + bank); // start erase operation, reset by hw with busy bit + wait_flash_busy(sl); + clear_flash_cr_per(sl, bank); // clear the page erase bit + lock_flash(sl); + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + unsigned bank = (flashaddr < STM32_H7_FLASH_BANK2_BASE) ? BANK_1 : BANK_2; + unlock_flash_if(sl); // unlock if locked + uint32_t sector = calculate_H7_sectornum( + sl, flashaddr, bank); // calculate the actual page from the address + write_flash_cr_snb(sl, sector, bank); // select the page to erase + set_flash_cr_strt(sl, bank); // start erase operation + wait_flash_busy(sl); // wait for completion + lock_flash(sl); + } else { + WLOG("unknown coreid %x, page erase failed\n", sl->core_id); + return (-1); + } - return check_flash_error(sl); + return check_flash_error(sl); } int stlink_erase_flash_mass(stlink_t *sl) { - int err = 0; + int err = 0; - // TODO: User MER bit to mass-erase WB series. - if (sl->flash_type == STLINK_FLASH_TYPE_L0 || - sl->flash_type == STLINK_FLASH_TYPE_WB) { - // erase each page - int i = 0, num_pages = (int)(sl->flash_size / sl->flash_pgsz); + // TODO: User MER bit to mass-erase WB series. + if (sl->flash_type == STLINK_FLASH_TYPE_L0 || + sl->flash_type == STLINK_FLASH_TYPE_WB) { + // erase each page + int i = 0, num_pages = (int)(sl->flash_size / sl->flash_pgsz); - for (i = 0; i < num_pages; i++) { - // addr must be an addr inside the page - stm32_addr_t addr = (stm32_addr_t)sl->flash_base + i * (stm32_addr_t)sl->flash_pgsz; + for (i = 0; i < num_pages; i++) { + // addr must be an addr inside the page + stm32_addr_t addr = + (stm32_addr_t)sl->flash_base + i * (stm32_addr_t)sl->flash_pgsz; - if (stlink_erase_flash_page(sl, addr)) { - WLOG("Failed to erase_flash_page(%#x) == -1\n", addr); - return(-1); - } + if (stlink_erase_flash_page(sl, addr)) { + WLOG("Failed to erase_flash_page(%#x) == -1\n", addr); + return (-1); + } - fprintf(stdout, "-> Flash page at %5d/%5d erased\n", i, num_pages); - fflush(stdout); - } + fprintf(stdout, "-> Flash page at %5d/%5d erased\n", i, num_pages); + fflush(stdout); + } - fprintf(stdout, "\n"); - } else { - wait_flash_busy(sl); - clear_flash_error(sl); - unlock_flash_if(sl); - - if (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->chip_id != STLINK_CHIPID_STM32_H7AX) { - // set parallelism - write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); - } - } + fprintf(stdout, "\n"); + } else { + wait_flash_busy(sl); + clear_flash_error(sl); + unlock_flash_if(sl); - set_flash_cr_mer(sl, 1, BANK_1); // set the mass erase bit - set_flash_cr_strt(sl, BANK_1); // start erase operation, reset by hw with busy bit + if (sl->flash_type == STLINK_FLASH_TYPE_H7 && + sl->chip_id != STLINK_CHIPID_STM32_H7AX) { + // set parallelism + write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); + } + } - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || - (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { - set_flash_cr_mer(sl, 1, BANK_2); // set the mass erase bit in bank 2 - set_flash_cr_strt(sl, BANK_2); // start erase operation in bank 2 - } + set_flash_cr_mer(sl, 1, BANK_1); // set the mass erase bit + set_flash_cr_strt( + sl, BANK_1); // start erase operation, reset by hw with busy bit - wait_flash_busy_progress(sl); - lock_flash(sl); + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || + (sl->flash_type == STLINK_FLASH_TYPE_H7 && + sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { + set_flash_cr_mer(sl, 1, BANK_2); // set the mass erase bit in bank 2 + set_flash_cr_strt(sl, BANK_2); // start erase operation in bank 2 + } - // reset the mass erase bit - set_flash_cr_mer(sl, 0, BANK_1); - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || - (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { - set_flash_cr_mer(sl, 0, BANK_2); - } + wait_flash_busy_progress(sl); + lock_flash(sl); - err = check_flash_error(sl); + // reset the mass erase bit + set_flash_cr_mer(sl, 0, BANK_1); + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || + (sl->flash_type == STLINK_FLASH_TYPE_H7 && + sl->chip_flags & CHIP_F_HAS_DUAL_BANK)) { + set_flash_cr_mer(sl, 0, BANK_2); } - return(err); + err = check_flash_error(sl); + } + + return (err); } -int stlink_fcheck_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { - // check the contents of path are at addr +int stlink_fcheck_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { + // check the contents of path are at addr - int res; - mapped_file_t mf = MAPPED_FILE_INITIALIZER; + int res; + mapped_file_t mf = MAPPED_FILE_INITIALIZER; - if (map_file(&mf, path) == -1) { return(-1); } + if (map_file(&mf, path) == -1) { + return (-1); + } - res = check_file(sl, &mf, addr); - unmap_file(&mf); - return(res); + res = check_file(sl, &mf, addr); + unmap_file(&mf); + return (res); } /** @@ -2946,696 +3047,741 @@ int stlink_fcheck_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { * @param length how much * @return 0 for success, -ve for failure */ -int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, unsigned length) { - size_t off; - size_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; - ILOG("Starting verification of write complete\n"); +int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, + unsigned length) { + size_t off; + size_t cmp_size = (sl->flash_pgsz > 0x1800) ? 0x1800 : sl->flash_pgsz; + ILOG("Starting verification of write complete\n"); - for (off = 0; off < length; off += cmp_size) { - size_t aligned_size; + for (off = 0; off < length; off += cmp_size) { + size_t aligned_size; - // adjust last page size - if ((off + cmp_size) > length) { cmp_size = length - off; } - - aligned_size = cmp_size; - - if (aligned_size & (4 - 1)) { aligned_size = (cmp_size + 4) & ~(4 - 1); } - - stlink_read_mem32(sl, address + (uint32_t)off, aligned_size); - - if (memcmp(sl->q_buf, data + off, cmp_size)) { - ELOG("Verification of flash failed at offset: %u\n", (unsigned int)off); - return(-1); - } + // adjust last page size + if ((off + cmp_size) > length) { + cmp_size = length - off; } - ILOG("Flash written and verified! jolly good!\n"); - return(0); + aligned_size = cmp_size; -} - -int stm32l1_write_half_pages( - stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len, uint32_t pagesize) { - unsigned int count; - unsigned int num_half_pages = len / pagesize; - uint32_t val; - uint32_t flash_regs_base = get_stm32l0_flash_base(sl); - flash_loader_t fl; - - ILOG("Starting Half page flash write for STM32L core id\n"); - - /* Flash loader initialisation */ - if (stlink_flash_loader_init(sl, &fl) == -1) { - WLOG("stlink_flash_loader_init() == -1\n"); - return(-1); + if (aligned_size & (4 - 1)) { + aligned_size = (cmp_size + 4) & ~(4 - 1); } - // unlock already done - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val |= (1 << FLASH_L1_FPRG); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - - val |= (1 << FLASH_L1_PROG); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - - wait_flash_busy(sl); - - for (count = 0; count < num_half_pages; count++) { - if (stlink_flash_loader_run( - sl, &fl, addr + count * pagesize, base + count * pagesize, pagesize) == -1) { - WLOG("l1_stlink_flash_loader_run(%#x) failed! == -1\n", addr + count * pagesize); - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val &= ~((1 << FLASH_L1_FPRG) | (1 << FLASH_L1_PROG)); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - return(-1); - } + stlink_read_mem32(sl, address + (uint32_t)off, aligned_size); - // wait for sr.busy to be cleared - if (sl->verbose >= 1) { - // show progress; writing procedure is slow and previous errors are misleading - fprintf(stdout, "\r%3u/%u halfpages written", count + 1, num_half_pages); - fflush(stdout); - } - - wait_flash_busy(sl); + if (memcmp(sl->q_buf, data + off, cmp_size)) { + ELOG("Verification of flash failed at offset: %u\n", (unsigned int)off); + return (-1); } + } - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val &= ~(1 << FLASH_L1_PROG); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val &= ~(1 << FLASH_L1_FPRG); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - return(0); + ILOG("Flash written and verified! jolly good!\n"); + return (0); } -int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { - - // According to DDI0419C, Table C1-7 firstly force halt - stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | - STLINK_REG_DHCSR_C_DEBUGEN | - STLINK_REG_DHCSR_C_HALT); - // and only then disable interrupts - stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | - STLINK_REG_DHCSR_C_DEBUGEN | - STLINK_REG_DHCSR_C_HALT | - STLINK_REG_DHCSR_C_MASKINTS); - - // disable DMA - set_dma_state(sl, fl, 0); - - // wait for ongoing op to finish - wait_flash_busy(sl); - // Clear errors - clear_flash_error(sl); - - if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || - (sl->flash_type == STLINK_FLASH_TYPE_F7) || - (sl->flash_type == STLINK_FLASH_TYPE_L4)) { - ILOG("Starting Flash write for F2/F4/F7/L4\n"); - - // Flash loader initialisation - if (stlink_flash_loader_init(sl, fl) == -1) { - ELOG("stlink_flash_loader_init() == -1\n"); - return(-1); - } - - unlock_flash_if(sl); // first unlock the cr - - int voltage; - if (sl->version.stlink_v == 1) { - WLOG("STLINK V1 cannot read voltage, use default voltage 3.2V\n"); - voltage = 3200; - } else { - voltage = stlink_target_voltage(sl); - } - - if (voltage == -1) { - ELOG("Failed to read Target voltage\n"); - return(-1); - } - - if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - // L4 does not have a byte-write mode - if (voltage < 1710) { - ELOG("Target voltage (%d mV) too low for flash writes!\n", voltage); - return(-1); - } - } else { - if (voltage > 2700) { - ILOG("enabling 32-bit flash writes\n"); - write_flash_cr_psiz(sl, 2, BANK_1); - } else { - ILOG("Target voltage (%d mV) too low for 32-bit flash, " - "using 8-bit flash writes\n", voltage); - write_flash_cr_psiz(sl, 0, BANK_1); - } - } - - // set programming mode - set_flash_cr_pg(sl, BANK_1); - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || - sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - ILOG("Starting Flash write for WB/G0/G4\n"); - - unlock_flash_if(sl); // unlock flash if necessary - set_flash_cr_pg(sl, BANK_1); // set PG 'allow programming' bit - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - ILOG("Starting Flash write for L0\n"); - - uint32_t val; - uint32_t flash_regs_base; - if (sl->chip_id == STLINK_CHIPID_STM32_L0 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || - sl->chip_id == STLINK_CHIPID_STM32_L011) { - flash_regs_base = STM32L0_FLASH_REGS_ADDR; - } else { - flash_regs_base = STM32L_FLASH_REGS_ADDR; - } - - // disable pecr protection - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, FLASH_L0_PEKEY2); - - // check pecr.pelock is cleared - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - if (val & (1 << 0)) { - ELOG("pecr.pelock not clear\n"); - return(-1); - } - - // unlock program memory - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY1); - stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, FLASH_L0_PRGKEY2); +int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, + uint32_t len, uint32_t pagesize) { + unsigned int count; + unsigned int num_half_pages = len / pagesize; + uint32_t val; + uint32_t flash_regs_base = get_stm32l0_flash_base(sl); + flash_loader_t fl; - // check pecr.prglock is cleared - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - if (val & (1 << 1)) { - ELOG("pecr.prglock not clear\n"); - return(-1); - } - } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { - ILOG("Starting Flash write for VL/F0/F3/F1_XL\n"); - - // flash loader initialisation - if (stlink_flash_loader_init(sl, fl) == -1) { - ELOG("stlink_flash_loader_init() == -1\n"); - return(-1); - } - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - ILOG("Starting Flash write for H7\n"); + ILOG("Starting Half page flash write for STM32L core id\n"); - unlock_flash_if(sl); // unlock the cr - set_flash_cr_pg(sl, BANK_1); // set programming mode - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - set_flash_cr_pg(sl, BANK_2); - } - if (sl->chip_id != STLINK_CHIPID_STM32_H7AX) { - // set parallelism - write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); - if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); - } - } - } else { - ELOG("unknown coreid, not sure how to write: %x\n", sl->core_id); - return(-1); - } + /* Flash loader initialisation */ + if (stlink_flash_loader_init(sl, &fl) == -1) { + WLOG("stlink_flash_loader_init() == -1\n"); + return (-1); + } - return(0); -} - -int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr, - uint8_t* base, uint32_t len) { - size_t off; - if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || - (sl->flash_type == STLINK_FLASH_TYPE_F7) || - (sl->flash_type == STLINK_FLASH_TYPE_L4)) { - size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; - for (off = 0; off < len;) { - size_t size = len - off > buf_size ? buf_size : len - off; - if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, size) == -1) { - ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", (unsigned)(addr + off)); - check_flash_error(sl); - return(-1); - } + // unlock already done + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val |= (1 << FLASH_L1_FPRG); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - off += size; - } - } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || - sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); - for (off = 0; off < len; off += sizeof(uint32_t)) { - uint32_t data; - - if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { - fprintf(stdout, "\r%3u/%3u pages written", - (unsigned int)(off / sl->flash_pgsz), - (unsigned int)(len / sl->flash_pgsz)); - fflush(stdout); - } - - write_uint32((unsigned char*)&data, *(uint32_t*)(base + off)); - stlink_write_debug32(sl, addr + (uint32_t)off, data); - wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear - } - fprintf(stdout, "\n"); - - // flash writes happen as 2 words at a time - if ((off / sizeof(uint32_t)) % 2 != 0) { - stlink_write_debug32(sl, addr + (uint32_t)off, 0); // write a single word of zeros - wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear - } - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - uint32_t val; - uint32_t flash_regs_base; - uint32_t pagesize; - - if (sl->chip_id == STLINK_CHIPID_STM32_L0 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || - sl->chip_id == STLINK_CHIPID_STM32_L011) { - flash_regs_base = STM32L0_FLASH_REGS_ADDR; - pagesize = L0_WRITE_BLOCK_SIZE; - } else { - flash_regs_base = STM32L_FLASH_REGS_ADDR; - pagesize = L1_WRITE_BLOCK_SIZE; - } + val |= (1 << FLASH_L1_PROG); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); - off = 0; + wait_flash_busy(sl); - if (len > pagesize) { - if (stm32l1_write_half_pages(sl, addr, base, len, pagesize) == -1) { - // this may happen on a blank device! - WLOG("\nwrite_half_pages failed == -1\n"); - } else { - off = (len / pagesize) * pagesize; - } - } + for (count = 0; count < num_half_pages; count++) { + if (stlink_flash_loader_run(sl, &fl, addr + count * pagesize, + base + count * pagesize, pagesize) == -1) { + WLOG("l1_stlink_flash_loader_run(%#x) failed! == -1\n", + addr + count * pagesize); + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val &= ~((1 << FLASH_L1_FPRG) | (1 << FLASH_L1_PROG)); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + return (-1); + } - // write remaining word in program memory - for ( ; off < len; off += sizeof(uint32_t)) { - uint32_t data; + // wait for sr.busy to be cleared + if (sl->verbose >= 1) { + // show progress; writing procedure is slow and previous errors are + // misleading + fprintf(stdout, "\r%3u/%u halfpages written", count + 1, num_half_pages); + fflush(stdout); + } - if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { - fprintf(stdout, "\r%3u/%3u pages written", - (unsigned int)(off / sl->flash_pgsz), - (unsigned int)(len / sl->flash_pgsz)); - fflush(stdout); - } + wait_flash_busy(sl); + } - write_uint32((unsigned char*)&data, *(uint32_t*)(base + off)); - stlink_write_debug32(sl, addr + (uint32_t)off, data); + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val &= ~(1 << FLASH_L1_PROG); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val &= ~(1 << FLASH_L1_FPRG); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + return (0); +} - // wait for sr.busy to be cleared - do { - stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); - } while ((val & (1 << 0)) != 0); +int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { - // TODO: check redo write operation - } - fprintf(stdout, "\n"); - } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { - int write_block_count = 0; - for (off = 0; off < len; off += sl->flash_pgsz) { - // adjust last write size - size_t size = len - off > sl->flash_pgsz ? sl->flash_pgsz : len - off; - - // unlock and set programming mode - unlock_flash_if(sl); - - DLOG("Finished unlocking flash, running loader!\n"); - - if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, size) == -1) { - ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", (unsigned)(addr + off)); - check_flash_error(sl); - return(-1); - } + // According to DDI0419C, Table C1-7 firstly force halt + stlink_write_debug32(sl, STLINK_REG_DHCSR, + STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | + STLINK_REG_DHCSR_C_HALT); + // and only then disable interrupts + stlink_write_debug32(sl, STLINK_REG_DHCSR, + STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | + STLINK_REG_DHCSR_C_HALT | + STLINK_REG_DHCSR_C_MASKINTS); + + // disable DMA + set_dma_state(sl, fl, 0); + + // wait for ongoing op to finish + wait_flash_busy(sl); + // Clear errors + clear_flash_error(sl); + + if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || + (sl->flash_type == STLINK_FLASH_TYPE_F7) || + (sl->flash_type == STLINK_FLASH_TYPE_L4)) { + ILOG("Starting Flash write for F2/F4/F7/L4\n"); + + // Flash loader initialisation + if (stlink_flash_loader_init(sl, fl) == -1) { + ELOG("stlink_flash_loader_init() == -1\n"); + return (-1); + } + + unlock_flash_if(sl); // first unlock the cr + + int voltage; + if (sl->version.stlink_v == 1) { + WLOG("STLINK V1 cannot read voltage, use default voltage 3.2V\n"); + voltage = 3200; + } else { + voltage = stlink_target_voltage(sl); + } - lock_flash(sl); + if (voltage == -1) { + ELOG("Failed to read Target voltage\n"); + return (-1); + } - if (sl->verbose >= 1) { - // show progress; writing procedure is slow and previous errors are misleading - fprintf(stdout, "\r%3u/%3u pages written", ++write_block_count, - (unsigned int)((len + sl->flash_pgsz - 1) / sl->flash_pgsz)); - fflush(stdout); - } - } - if (sl->verbose >= 1) { - fprintf(stdout, "\n"); - } - } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - for (off = 0; off < len;) { - // Program STM32H7x with 64-byte Flash words - size_t chunk = (len - off > 64) ? 64 : len - off; - memcpy(sl->q_buf, base + off, chunk); - stlink_write_mem32(sl, addr + (uint32_t)off, 64); - wait_flash_busy(sl); - - off += chunk; - - if (sl->verbose >= 1) { - // show progress - fprintf(stdout, "\r%u/%u bytes written", (unsigned int)off, (unsigned int)len); - fflush(stdout); - } - } - if (sl->verbose >= 1) { - fprintf(stdout, "\n"); - } + if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + // L4 does not have a byte-write mode + if (voltage < 1710) { + ELOG("Target voltage (%d mV) too low for flash writes!\n", voltage); + return (-1); + } + } else { + if (voltage > 2700) { + ILOG("enabling 32-bit flash writes\n"); + write_flash_cr_psiz(sl, 2, BANK_1); + } else { + ILOG("Target voltage (%d mV) too low for 32-bit flash, " + "using 8-bit flash writes\n", + voltage); + write_flash_cr_psiz(sl, 0, BANK_1); + } + } + + // set programming mode + set_flash_cr_pg(sl, BANK_1); + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || + sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + ILOG("Starting Flash write for WB/G0/G4\n"); + + unlock_flash_if(sl); // unlock flash if necessary + set_flash_cr_pg(sl, BANK_1); // set PG 'allow programming' bit + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + ILOG("Starting Flash write for L0\n"); + + uint32_t val; + uint32_t flash_regs_base; + if (sl->chip_id == STLINK_CHIPID_STM32_L0 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || + sl->chip_id == STLINK_CHIPID_STM32_L011) { + flash_regs_base = STM32L0_FLASH_REGS_ADDR; } else { - return(-1); + flash_regs_base = STM32L_FLASH_REGS_ADDR; } - return check_flash_error(sl); -} + // disable pecr protection + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, + FLASH_L0_PEKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PEKEYR_OFF, + FLASH_L0_PEKEY2); -int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { - uint32_t dhcsr; - - if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || - (sl->flash_type == STLINK_FLASH_TYPE_F7) || - (sl->flash_type == STLINK_FLASH_TYPE_L4) || - (sl->flash_type == STLINK_FLASH_TYPE_WB) || - (sl->flash_type == STLINK_FLASH_TYPE_G0) || - (sl->flash_type == STLINK_FLASH_TYPE_G4) || - (sl->flash_type == STLINK_FLASH_TYPE_H7)) { - - clear_flash_cr_pg(sl, BANK_1); - if (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { - clear_flash_cr_pg(sl, BANK_2); - } - lock_flash(sl); - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - uint32_t val; - uint32_t flash_regs_base; - if (sl->chip_id == STLINK_CHIPID_STM32_L0 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || - sl->chip_id == STLINK_CHIPID_STM32_L011) { - flash_regs_base = STM32L0_FLASH_REGS_ADDR; - } else { - flash_regs_base = STM32L_FLASH_REGS_ADDR; - } - // reset lock bits - stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); - val |= (1 << 0) | (1 << 1) | (1 << 2); - stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + // check pecr.pelock is cleared + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + if (val & (1 << 0)) { + ELOG("pecr.pelock not clear\n"); + return (-1); + } + + // unlock program memory + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, + FLASH_L0_PRGKEY1); + stlink_write_debug32(sl, flash_regs_base + FLASH_PRGKEYR_OFF, + FLASH_L0_PRGKEY2); + + // check pecr.prglock is cleared + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + if (val & (1 << 1)) { + ELOG("pecr.prglock not clear\n"); + return (-1); + } + } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + ILOG("Starting Flash write for VL/F0/F3/F1_XL\n"); + + // flash loader initialisation + if (stlink_flash_loader_init(sl, fl) == -1) { + ELOG("stlink_flash_loader_init() == -1\n"); + return (-1); + } + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + ILOG("Starting Flash write for H7\n"); + + unlock_flash_if(sl); // unlock the cr + set_flash_cr_pg(sl, BANK_1); // set programming mode + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + set_flash_cr_pg(sl, BANK_2); + } + if (sl->chip_id != STLINK_CHIPID_STM32_H7AX) { + // set parallelism + write_flash_cr_psiz(sl, 3 /*64it*/, BANK_1); + if (sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + write_flash_cr_psiz(sl, 3 /*64bit*/, BANK_2); + } + } + } else { + ELOG("unknown coreid, not sure how to write: %x\n", sl->core_id); + return (-1); + } + + return (0); +} + +int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, + stm32_addr_t addr, uint8_t *base, uint32_t len) { + size_t off; + if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || + (sl->flash_type == STLINK_FLASH_TYPE_F7) || + (sl->flash_type == STLINK_FLASH_TYPE_L4)) { + size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; + for (off = 0; off < len;) { + size_t size = len - off > buf_size ? buf_size : len - off; + if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, + size) == -1) { + ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", + (unsigned)(addr + off)); + check_flash_error(sl); + return (-1); + } + + off += size; + } + } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || + sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + DLOG("Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); + for (off = 0; off < len; off += sizeof(uint32_t)) { + uint32_t data; + + if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { + fprintf(stdout, "\r%3u/%3u pages written", + (unsigned int)(off / sl->flash_pgsz), + (unsigned int)(len / sl->flash_pgsz)); + fflush(stdout); + } + + write_uint32((unsigned char *)&data, *(uint32_t *)(base + off)); + stlink_write_debug32(sl, addr + (uint32_t)off, data); + wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear } + fprintf(stdout, "\n"); - // enable interrupt - if (!stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr)) { - stlink_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | - STLINK_REG_DHCSR_C_DEBUGEN | - (dhcsr&(~STLINK_REG_DHCSR_C_MASKINTS))); + // flash writes happen as 2 words at a time + if ((off / sizeof(uint32_t)) % 2 != 0) { + stlink_write_debug32(sl, addr + (uint32_t)off, + 0); // write a single word of zeros + wait_flash_busy(sl); // wait for 'busy' bit in FLASH_SR to clear + } + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + uint32_t val; + uint32_t flash_regs_base; + uint32_t pagesize; + + if (sl->chip_id == STLINK_CHIPID_STM32_L0 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || + sl->chip_id == STLINK_CHIPID_STM32_L011) { + flash_regs_base = STM32L0_FLASH_REGS_ADDR; + pagesize = L0_WRITE_BLOCK_SIZE; + } else { + flash_regs_base = STM32L_FLASH_REGS_ADDR; + pagesize = L1_WRITE_BLOCK_SIZE; } - // restore DMA state - set_dma_state(sl, fl, 1); - - return(0); -} - -int stlink_write_flash( - stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len, uint8_t eraseonly) { - size_t off; - int ret; - flash_loader_t fl; - ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", len, len, addr, addr); - // check addr range is inside the flash - stlink_calculate_pagesize(sl, addr); - - if (addr < sl->flash_base) { - ELOG("addr too low %#x < %#x\n", addr, sl->flash_base); - return(-1); - } else if ((addr + len) < addr) { - ELOG("addr overruns\n"); - return(-1); - } else if ((addr + len) > (sl->flash_base + sl->flash_size)) { - ELOG("addr too high\n"); - return(-1); - } else if (addr & 1) { - ELOG("unaligned addr 0x%x\n", addr); - return(-1); - } else if (len & 1) { - WLOG("unaligned len 0x%x -- padding with zero\n", len); - len += 1; - } else if (addr & (sl->flash_pgsz - 1)) { - ELOG("addr not a multiple of current pagesize (%u bytes), not supported, " - "check page start address and compare with flash module organisation " - "in related ST reference manual of your device.\n", (unsigned)(sl->flash_pgsz)); - return(-1); + off = 0; + + if (len > pagesize) { + if (stm32l1_write_half_pages(sl, addr, base, len, pagesize) == -1) { + // this may happen on a blank device! + WLOG("\nwrite_half_pages failed == -1\n"); + } else { + off = (size_t)(len / pagesize) * pagesize; + } } - // make sure we've loaded the context with the chip details - stlink_core_id(sl); + // write remaining word in program memory + for (; off < len; off += sizeof(uint32_t)) { + uint32_t data; - // Erase each page - int page_count = 0; + if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { + fprintf(stdout, "\r%3u/%3u pages written", + (unsigned int)(off / sl->flash_pgsz), + (unsigned int)(len / sl->flash_pgsz)); + fflush(stdout); + } - for (off = 0; off < len; off += stlink_calculate_pagesize(sl, addr + (uint32_t)off)) { - // addr must be an addr inside the page - if (stlink_erase_flash_page(sl, addr + (uint32_t)off) == -1) { - ELOG("Failed to erase_flash_page(%#x) == -1\n", (unsigned)(addr + off)); - return(-1); - } + write_uint32((unsigned char *)&data, *(uint32_t *)(base + off)); + stlink_write_debug32(sl, addr + (uint32_t)off, data); - ILOG("Flash page at addr: 0x%08lx erased\n", (unsigned long)(addr + off)); - page_count++; + // wait for sr.busy to be cleared + do { + stlink_read_debug32(sl, flash_regs_base + FLASH_SR_OFF, &val); + } while ((val & (1 << 0)) != 0); + + // TODO: check redo write operation } + fprintf(stdout, "\n"); + } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || + (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + int write_block_count = 0; + for (off = 0; off < len; off += sl->flash_pgsz) { + // adjust last write size + size_t size = len - off > sl->flash_pgsz ? sl->flash_pgsz : len - off; + + // unlock and set programming mode + unlock_flash_if(sl); + + DLOG("Finished unlocking flash, running loader!\n"); + + if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, + size) == -1) { + ELOG("stlink_flash_loader_run(%#x) failed! == -1\n", + (unsigned)(addr + off)); + check_flash_error(sl); + return (-1); + } + + lock_flash(sl); + + if (sl->verbose >= 1) { + // show progress; writing procedure is slow and previous errors are + // misleading + fprintf(stdout, "\r%3u/%3u pages written", ++write_block_count, + (unsigned int)((len + sl->flash_pgsz - 1) / sl->flash_pgsz)); + fflush(stdout); + } + } + if (sl->verbose >= 1) { + fprintf(stdout, "\n"); + } + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + for (off = 0; off < len;) { + // Program STM32H7x with 64-byte Flash words + size_t chunk = (len - off > 64) ? 64 : len - off; + memcpy(sl->q_buf, base + off, chunk); + stlink_write_mem32(sl, addr + (uint32_t)off, 64); + wait_flash_busy(sl); + + off += chunk; + + if (sl->verbose >= 1) { + // show progress + fprintf(stdout, "\r%u/%u bytes written", (unsigned int)off, + (unsigned int)len); + fflush(stdout); + } + } + if (sl->verbose >= 1) { + fprintf(stdout, "\n"); + } + } else { + return (-1); + } + + return check_flash_error(sl); +} - ILOG("Finished erasing %d pages of %u (%#x) bytes\n", - page_count, (unsigned)(sl->flash_pgsz), (unsigned)(sl->flash_pgsz)); +int stlink_flashloader_stop(stlink_t *sl, flash_loader_t *fl) { + uint32_t dhcsr; - if (eraseonly) { return(0); } + if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || + (sl->flash_type == STLINK_FLASH_TYPE_F7) || + (sl->flash_type == STLINK_FLASH_TYPE_L4) || + (sl->flash_type == STLINK_FLASH_TYPE_WB) || + (sl->flash_type == STLINK_FLASH_TYPE_G0) || + (sl->flash_type == STLINK_FLASH_TYPE_G4) || + (sl->flash_type == STLINK_FLASH_TYPE_H7)) { - ret = stlink_flashloader_start(sl, &fl); - if (ret) - return ret; - ret = stlink_flashloader_write(sl, &fl, addr, base, len); - if (ret) - return ret; - ret = stlink_flashloader_stop(sl, &fl); - if (ret) - return ret; + clear_flash_cr_pg(sl, BANK_1); + if (sl->flash_type == STLINK_FLASH_TYPE_H7 && + sl->chip_flags & CHIP_F_HAS_DUAL_BANK) { + clear_flash_cr_pg(sl, BANK_2); + } + lock_flash(sl); + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + uint32_t val; + uint32_t flash_regs_base; + if (sl->chip_id == STLINK_CHIPID_STM32_L0 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2 || + sl->chip_id == STLINK_CHIPID_STM32_L011) { + flash_regs_base = STM32L0_FLASH_REGS_ADDR; + } else { + flash_regs_base = STM32L_FLASH_REGS_ADDR; + } + // reset lock bits + stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val); + val |= (1 << 0) | (1 << 1) | (1 << 2); + stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); + } + + // enable interrupt + if (!stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr)) { + stlink_write_debug32(sl, STLINK_REG_DHCSR, + STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | + (dhcsr & (~STLINK_REG_DHCSR_C_MASKINTS))); + } + + // restore DMA state + set_dma_state(sl, fl, 1); + + return (0); +} + +int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t *base, + uint32_t len, uint8_t eraseonly) { + size_t off; + int ret; + flash_loader_t fl; + ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", len, + len, addr, addr); + // check addr range is inside the flash + stlink_calculate_pagesize(sl, addr); + + if (addr < sl->flash_base) { + ELOG("addr too low %#x < %#x\n", addr, sl->flash_base); + return (-1); + } else if ((addr + len) < addr) { + ELOG("addr overruns\n"); + return (-1); + } else if ((addr + len) > (sl->flash_base + sl->flash_size)) { + ELOG("addr too high\n"); + return (-1); + } else if (addr & 1) { + ELOG("unaligned addr 0x%x\n", addr); + return (-1); + } else if (len & 1) { + WLOG("unaligned len 0x%x -- padding with zero\n", len); + len += 1; + } else if (addr & (sl->flash_pgsz - 1)) { + ELOG("addr not a multiple of current pagesize (%u bytes), not supported, " + "check page start address and compare with flash module organisation " + "in related ST reference manual of your device.\n", + (unsigned)(sl->flash_pgsz)); + return (-1); + } + + // make sure we've loaded the context with the chip details + stlink_core_id(sl); + + // Erase each page + int page_count = 0; + + for (off = 0; off < len; + off += stlink_calculate_pagesize(sl, addr + (uint32_t)off)) { + // addr must be an addr inside the page + if (stlink_erase_flash_page(sl, addr + (uint32_t)off) == -1) { + ELOG("Failed to erase_flash_page(%#x) == -1\n", (unsigned)(addr + off)); + return (-1); + } + + ILOG("Flash page at addr: 0x%08lx erased\n", (unsigned long)(addr + off)); + page_count++; + } + + ILOG("Finished erasing %d pages of %u (%#x) bytes\n", page_count, + (unsigned)(sl->flash_pgsz), (unsigned)(sl->flash_pgsz)); + + if (eraseonly) { + return (0); + } + + ret = stlink_flashloader_start(sl, &fl); + if (ret) + return ret; + ret = stlink_flashloader_write(sl, &fl, addr, base, len); + if (ret) + return ret; + ret = stlink_flashloader_stop(sl, &fl); + if (ret) + return ret; - return(stlink_verify_write_flash(sl, addr, base, len)); + return (stlink_verify_write_flash(sl, addr, base, len)); } // TODO: length not checked -static uint8_t stlink_parse_hex(const char* hex) { - uint8_t d[2]; - - for (int i = 0; i < 2; ++i) { - char c = *(hex + i); - - if (c >= '0' && c <= '9') { - d[i] = c - '0'; - } else if (c >= 'A' && c <= 'F') { - d[i] = c - 'A' + 10; - } else if (c >= 'a' && c <= 'f') { - d[i] = c - 'a' + 10; - } else { - return(0); // error - } +static uint8_t stlink_parse_hex(const char *hex) { + uint8_t d[2]; + + for (int i = 0; i < 2; ++i) { + char c = *(hex + i); + + if (c >= '0' && c <= '9') { + d[i] = c - '0'; + } else if (c >= 'A' && c <= 'F') { + d[i] = c - 'A' + 10; + } else if (c >= 'a' && c <= 'f') { + d[i] = c - 'a' + 10; + } else { + return (0); // error } + } - return((d[0] << 4) | (d[1])); + return ((d[0] << 4) | (d[1])); } -int stlink_parse_ihex(const char* path, uint8_t erased_pattern, uint8_t * * mem, size_t * size, - uint32_t * begin) { - int res = 0; - *begin = UINT32_MAX; - uint8_t* data = NULL; - uint32_t end = 0; - bool eof_found = false; +int stlink_parse_ihex(const char *path, uint8_t erased_pattern, uint8_t **mem, + size_t *size, uint32_t *begin) { + int res = 0; + *begin = UINT32_MAX; + uint8_t *data = NULL; + uint32_t end = 0; + bool eof_found = false; - for (int scan = 0; (res == 0) && (scan < 2); ++scan) { - // parse file two times - first to find memory range, second - to fill it - if (scan == 1) { - if (!eof_found) { - ELOG("No EoF recond\n"); - res = -1; - break; - } + for (int scan = 0; (res == 0) && (scan < 2); ++scan) { + // parse file two times - first to find memory range, second - to fill it + if (scan == 1) { + if (!eof_found) { + ELOG("No EoF recond\n"); + res = -1; + break; + } - if (*begin >= end) { - ELOG("No data found in file\n"); - res = -1; - break; - } + if (*begin >= end) { + ELOG("No data found in file\n"); + res = -1; + break; + } - *size = (end - *begin) + 1; - data = calloc(*size, 1); // use calloc to get NULL if out of memory + *size = (end - *begin) + 1; + data = calloc(*size, 1); // use calloc to get NULL if out of memory - if (!data) { - ELOG("Cannot allocate %u bytes\n", (unsigned)(*size)); - res = -1; - break; - } + if (!data) { + ELOG("Cannot allocate %u bytes\n", (unsigned)(*size)); + res = -1; + break; + } - memset(data, erased_pattern, *size); - } + memset(data, erased_pattern, *size); + } - FILE* file = fopen(path, "r"); + FILE *file = fopen(path, "r"); - if (!file) { - ELOG("Cannot open file\n"); - res = -1; - break; - } + if (!file) { + ELOG("Cannot open file\n"); + res = -1; + break; + } - uint32_t lba = 0; - char line[1 + 5 * 2 + 255 * 2 + 2]; + uint32_t lba = 0; + char line[1 + 5 * 2 + 255 * 2 + 2]; - while (fgets(line, sizeof(line), file)) { - if (line[0] == '\n' || line[0] == '\r') { continue; } // skip empty lines + while (fgets(line, sizeof(line), file)) { + if (line[0] == '\n' || line[0] == '\r') { + continue; + } // skip empty lines - if (line[0] != ':') { // no marker - wrong file format - ELOG("Wrong file format - no marker\n"); - res = -1; - break; - } + if (line[0] != ':') { // no marker - wrong file format + ELOG("Wrong file format - no marker\n"); + res = -1; + break; + } - size_t l = strlen(line); + size_t l = strlen(line); - while (l > 0 && (line[l - 1] == '\n' || line[l - 1] == '\r')) { --l; } // trim EoL + while (l > 0 && (line[l - 1] == '\n' || line[l - 1] == '\r')) { + --l; + } // trim EoL - if ((l < 11) || (l == (sizeof(line) - 1))) { // line too short or long - wrong file format - ELOG("Wrong file format - wrong line length\n"); - res = -1; - break; - } + if ((l < 11) || + (l == + (sizeof(line) - 1))) { // line too short or long - wrong file format + ELOG("Wrong file format - wrong line length\n"); + res = -1; + break; + } - uint8_t chksum = 0; // check sum + uint8_t chksum = 0; // check sum - for (size_t i = 1; i < l; i += 2) { chksum += stlink_parse_hex(line + i); } + for (size_t i = 1; i < l; i += 2) { + chksum += stlink_parse_hex(line + i); + } - if (chksum != 0) { - ELOG("Wrong file format - checksum mismatch\n"); - res = -1; - break; - } + if (chksum != 0) { + ELOG("Wrong file format - checksum mismatch\n"); + res = -1; + break; + } - uint8_t reclen = stlink_parse_hex(line + 1); + uint8_t reclen = stlink_parse_hex(line + 1); - if (((uint32_t)reclen + 5) * 2 + 1 != l) { - ELOG("Wrong file format - record length mismatch\n"); - res = -1; - break; - } + if (((uint32_t)reclen + 5) * 2 + 1 != l) { + ELOG("Wrong file format - record length mismatch\n"); + res = -1; + break; + } - uint16_t offset = ((uint16_t)stlink_parse_hex(line + 3) << 8) | - ((uint16_t)stlink_parse_hex(line + 5)); - uint8_t rectype = stlink_parse_hex(line + 7); - - switch (rectype) { - case 0: /* Data */ - if (scan == 0) { - uint32_t b = lba + offset; - uint32_t e = b + reclen - 1; - - if (b < *begin) { *begin = b; } - - if (e > end) { end = e; } - } else { - for (uint8_t i = 0; i < reclen; ++i) { - uint8_t b = stlink_parse_hex(line + 9 + i * 2); - uint32_t addr = lba + offset + i; - - if (addr >= *begin && addr <= end) { data[addr - *begin] = b; } - } - } - break; - case 1: /* EoF */ - eof_found = true; - break; - case 2: /* Extended Segment Address, unexpected */ - res = -1; - break; - case 3: /* Start Segment Address, unexpected */ - res = -1; - break; - case 4: /* Extended Linear Address */ - if (reclen == 2) { - lba = ((uint32_t)stlink_parse_hex(line + 9) << 24) | - ((uint32_t)stlink_parse_hex(line + 11) << 16); - } else { - ELOG("Wrong file format - wrong LBA length\n"); - res = -1; - } - break; - case 5: /* Start Linear Address - expected, but ignore */ - break; - default: - ELOG("Wrong file format - unexpected record type %d\n", rectype); - res = -1; - } + uint16_t offset = ((uint16_t)stlink_parse_hex(line + 3) << 8) | + ((uint16_t)stlink_parse_hex(line + 5)); + uint8_t rectype = stlink_parse_hex(line + 7); - if (res != 0) { break; } - } + switch (rectype) { + case 0: /* Data */ + if (scan == 0) { + uint32_t b = lba + offset; + uint32_t e = b + reclen - 1; - fclose(file); - } + if (b < *begin) { + *begin = b; + } - if (res == 0) { - *mem = data; - } else { - free(data); - } + if (e > end) { + end = e; + } + } else { + for (uint8_t i = 0; i < reclen; ++i) { + uint8_t b = stlink_parse_hex(line + 9 + i * 2); + uint32_t addr = lba + offset + i; - return(res); -} + if (addr >= *begin && addr <= end) { + data[addr - *begin] = b; + } + } + } + break; + case 1: /* EoF */ + eof_found = true; + break; + case 2: /* Extended Segment Address, unexpected */ + res = -1; + break; + case 3: /* Start Segment Address, unexpected */ + res = -1; + break; + case 4: /* Extended Linear Address */ + if (reclen == 2) { + lba = ((uint32_t)stlink_parse_hex(line + 9) << 24) | + ((uint32_t)stlink_parse_hex(line + 11) << 16); + } else { + ELOG("Wrong file format - wrong LBA length\n"); + res = -1; + } + break; + case 5: /* Start Linear Address - expected, but ignore */ + break; + default: + ELOG("Wrong file format - unexpected record type %d\n", rectype); + res = -1; + } -uint8_t stlink_get_erased_pattern(stlink_t *sl) { - if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - return(0x00); - } else { - return(0xff); + if (res != 0) { + break; + } } -} -int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr_t addr) { - /* Write the block in flash at addr */ - int err; - unsigned int num_empty, idx; - uint8_t erased_pattern = stlink_get_erased_pattern(sl); + fclose(file); + } - /* - * This optimisation may cause unexpected garbage data remaining. - * Therfore it is turned off by default. - */ - if (sl->opt) { - idx = (unsigned int)length; + if (res == 0) { + *mem = data; + } else { + free(data); + } + + return (res); +} - for (num_empty = 0; num_empty != length; ++num_empty) - if (data[--idx] != erased_pattern) { break; } +uint8_t stlink_get_erased_pattern(stlink_t *sl) { + if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + return (0x00); + } else { + return (0xff); + } +} + +int stlink_mwrite_flash(stlink_t *sl, uint8_t *data, uint32_t length, + stm32_addr_t addr) { + /* Write the block in flash at addr */ + int err; + unsigned int num_empty, idx; + uint8_t erased_pattern = stlink_get_erased_pattern(sl); + + /* + * This optimisation may cause unexpected garbage data remaining. + * Therfore it is turned off by default. + */ + if (sl->opt) { + idx = (unsigned int)length; + + for (num_empty = 0; num_empty != length; ++num_empty) + if (data[--idx] != erased_pattern) { + break; + } - num_empty -= (num_empty & 3); // Round down to words + num_empty -= (num_empty & 3); // Round down to words - if (num_empty != 0) { - ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); - } - } else { - num_empty = 0; + if (num_empty != 0) { + ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, + erased_pattern); } + } else { + num_empty = 0; + } - /* - * TODO: investigate a kind of weird behaviour here: - * If the file is identified to be all-empty and four-bytes aligned, - * still flash the whole file even if ignoring message is printed. - */ - err = stlink_write_flash(sl, addr, data, - (num_empty == length) ? (uint32_t)length : (uint32_t)length - num_empty, - num_empty == length); - stlink_fwrite_finalize(sl, addr); - return(err); + /* + * TODO: investigate a kind of weird behaviour here: + * If the file is identified to be all-empty and four-bytes aligned, + * still flash the whole file even if ignoring message is printed. + */ + err = stlink_write_flash(sl, addr, data, + (num_empty == length) ? (uint32_t)length + : (uint32_t)length - num_empty, + num_empty == length); + stlink_fwrite_finalize(sl, addr); + return (err); } /** @@ -3645,49 +3791,53 @@ int stlink_mwrite_flash(stlink_t *sl, uint8_t* data, uint32_t length, stm32_addr * @param addr where to start writing * @return 0 on success, -ve on failure. */ -int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { - /* Write the file in flash at addr */ - int err; - unsigned int num_empty, idx; - uint8_t erased_pattern = stlink_get_erased_pattern(sl); - mapped_file_t mf = MAPPED_FILE_INITIALIZER; - - if (map_file(&mf, path) == -1) { - ELOG("map_file() == -1\n"); - return(-1); +int stlink_fwrite_flash(stlink_t *sl, const char *path, stm32_addr_t addr) { + /* Write the file in flash at addr */ + int err; + unsigned int num_empty, idx; + uint8_t erased_pattern = stlink_get_erased_pattern(sl); + mapped_file_t mf = MAPPED_FILE_INITIALIZER; + + if (map_file(&mf, path) == -1) { + ELOG("map_file() == -1\n"); + return (-1); + } + + printf("file %s ", path); + md5_calculate(&mf); + stlink_checksum(&mf); + + if (sl->opt) { + idx = (unsigned int)mf.len; + + for (num_empty = 0; num_empty != mf.len; ++num_empty) { + if (mf.base[--idx] != erased_pattern) { + break; + } } - printf("file %s ", path); - md5_calculate(&mf); - stlink_checksum(&mf); - - if (sl->opt) { - idx = (unsigned int)mf.len; + num_empty -= (num_empty & 3); // round down to words - for (num_empty = 0; num_empty != mf.len; ++num_empty) { - if (mf.base[--idx] != erased_pattern) { break; } - } - - num_empty -= (num_empty & 3); // round down to words - - if (num_empty != 0) { - ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); - } - } else { - num_empty = 0; + if (num_empty != 0) { + ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, + erased_pattern); } + } else { + num_empty = 0; + } - /* - * TODO: investigate a kind of weird behaviour here: - * If the file is identified to be all-empty and four-bytes aligned, - * still flash the whole file even if ignoring message is printed. - */ - err = stlink_write_flash(sl, addr, mf.base, - (num_empty == mf.len) ? (uint32_t)mf.len : (uint32_t)mf.len - num_empty, - num_empty == mf.len); - stlink_fwrite_finalize(sl, addr); - unmap_file(&mf); - return(err); + /* + * TODO: investigate a kind of weird behaviour here: + * If the file is identified to be all-empty and four-bytes aligned, + * still flash the whole file even if ignoring message is printed. + */ + err = stlink_write_flash(sl, addr, mf.base, + (num_empty == mf.len) ? (uint32_t)mf.len + : (uint32_t)mf.len - num_empty, + num_empty == mf.len); + stlink_fwrite_finalize(sl, addr); + unmap_file(&mf); + return (err); } /** @@ -3697,35 +3847,35 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { * @param base option bytes to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_gx( - stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { - /* Write options bytes */ - uint32_t val; - int ret = 0; - (void)len; - uint32_t data; +static int stlink_write_option_bytes_gx(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { + /* Write options bytes */ + uint32_t val; + int ret = 0; + (void)len; + uint32_t data; - clear_flash_error(sl); + clear_flash_error(sl); - write_uint32((unsigned char*)&data, *(uint32_t*)(base)); - WLOG("Writing option bytes %#10x to %#10x\n", data, addr); - stlink_write_debug32(sl, STM32Gx_FLASH_OPTR, data); + write_uint32((unsigned char *)&data, *(uint32_t *)(base)); + WLOG("Writing option bytes %#10x to %#10x\n", data, addr); + stlink_write_debug32(sl, STM32Gx_FLASH_OPTR, data); - // Set Options Start bit - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - val |= (1 << STM32Gx_FLASH_CR_OPTSTRT); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + // Set Options Start bit + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + val |= (1 << STM32Gx_FLASH_CR_OPTSTRT); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - wait_flash_busy(sl); + wait_flash_busy(sl); - ret = check_flash_error(sl); + ret = check_flash_error(sl); - // Reload options - stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); - val |= (1 << STM32Gx_FLASH_CR_OBL_LAUNCH); - stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); + // Reload options + stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); + val |= (1 << STM32Gx_FLASH_CR_OBL_LAUNCH); + stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); - return(ret); + return (ret); } /** @@ -3735,36 +3885,39 @@ static int stlink_write_option_bytes_gx( * @param base option bytes to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_l0( - stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { - uint32_t flash_base = get_stm32l0_flash_base(sl); - uint32_t val; - uint32_t data; - int ret = 0; - - // Clear errors - clear_flash_error(sl); +static int stlink_write_option_bytes_l0(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { + uint32_t flash_base = get_stm32l0_flash_base(sl); + uint32_t val; + uint32_t data; + int ret = 0; - while (len != 0) { - write_uint32((unsigned char*)&data, *(uint32_t*)(base)); // write options bytes + // Clear errors + clear_flash_error(sl); - WLOG("Writing option bytes %#10x to %#10x\n", data, addr); - stlink_write_debug32(sl, addr, data); - wait_flash_busy(sl); + while (len != 0) { + write_uint32((unsigned char *)&data, + *(uint32_t *)(base)); // write options bytes - if ((ret = check_flash_error(sl))) { break; } + WLOG("Writing option bytes %#10x to %#10x\n", data, addr); + stlink_write_debug32(sl, addr, data); + wait_flash_busy(sl); - len -= 4; - addr += 4; - base += 4; + if ((ret = check_flash_error(sl))) { + break; } - // Reload options - stlink_read_debug32(sl, flash_base + FLASH_PECR_OFF, &val); - val |= (1 << STM32L0_FLASH_OBL_LAUNCH); - stlink_write_debug32(sl, flash_base + FLASH_PECR_OFF, val); + len -= 4; + addr += 4; + base += 4; + } + + // Reload options + stlink_read_debug32(sl, flash_base + FLASH_PECR_OFF, &val); + val |= (1 << STM32L0_FLASH_OBL_LAUNCH); + stlink_write_debug32(sl, flash_base + FLASH_PECR_OFF, val); - return(ret); + return (ret); } /** @@ -3774,67 +3927,67 @@ static int stlink_write_option_bytes_l0( * @param base option bytes to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_l4( - stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { +static int stlink_write_option_bytes_l4(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { - uint32_t val; - int ret = 0; - (void)addr; - (void)len; + uint32_t val; + int ret = 0; + (void)addr; + (void)len; - // Clear errors - clear_flash_error(sl); + // Clear errors + clear_flash_error(sl); - // write options bytes - uint32_t data; - write_uint32((unsigned char*)&data, *(uint32_t*)(base)); - WLOG("Writing option bytes 0x%04x\n", data); - stlink_write_debug32(sl, STM32L4_FLASH_OPTR, data); + // write options bytes + uint32_t data; + write_uint32((unsigned char *)&data, *(uint32_t *)(base)); + WLOG("Writing option bytes 0x%04x\n", data); + stlink_write_debug32(sl, STM32L4_FLASH_OPTR, data); - // set options start bit - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - val |= (1 << STM32L4_FLASH_CR_OPTSTRT); - stlink_write_debug32(sl, STM32L4_FLASH_CR, val); + // set options start bit + stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); + val |= (1 << STM32L4_FLASH_CR_OPTSTRT); + stlink_write_debug32(sl, STM32L4_FLASH_CR, val); - wait_flash_busy(sl); - ret = check_flash_error(sl); + wait_flash_busy(sl); + ret = check_flash_error(sl); - // apply options bytes immediate - stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); - val |= (1 << STM32L4_FLASH_CR_OBL_LAUNCH); - stlink_write_debug32(sl, STM32L4_FLASH_CR, val); + // apply options bytes immediate + stlink_read_debug32(sl, STM32L4_FLASH_CR, &val); + val |= (1 << STM32L4_FLASH_CR_OBL_LAUNCH); + stlink_write_debug32(sl, STM32L4_FLASH_CR, val); - return(ret); + return (ret); } - /** * Write option bytes * @param sl * @param option_byte value to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_f4( - stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { - uint32_t option_byte; - int ret = 0; - (void)addr; - (void)len; - - // Clear errors - clear_flash_error(sl); +static int stlink_write_option_bytes_f4(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { + uint32_t option_byte; + int ret = 0; + (void)addr; + (void)len; - write_uint32((unsigned char*)&option_byte, *(uint32_t*)(base)); + // Clear errors + clear_flash_error(sl); - // write option byte, ensuring we dont lock opt, and set strt bit - stlink_write_debug32(sl, FLASH_F4_OPTCR, - (option_byte & ~(1 << FLASH_F4_OPTCR_LOCK)) | (1 << FLASH_F4_OPTCR_START)); + write_uint32((unsigned char *)&option_byte, *(uint32_t *)(base)); - wait_flash_busy(sl); - ret = check_flash_error(sl); + // write option byte, ensuring we dont lock opt, and set strt bit + stlink_write_debug32(sl, FLASH_F4_OPTCR, + (option_byte & ~(1 << FLASH_F4_OPTCR_LOCK)) | + (1 << FLASH_F4_OPTCR_START)); - // option bytes are reloaded at reset only, no obl. */ - return(ret); + wait_flash_busy(sl); + ret = check_flash_error(sl); + + // option bytes are reloaded at reset only, no obl. */ + return (ret); } /** @@ -3843,47 +3996,54 @@ static int stlink_write_option_bytes_f4( * @param option_byte value to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_f7(stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { - uint32_t option_byte; - int ret = 0; +static int stlink_write_option_bytes_f7(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { + uint32_t option_byte; + int ret = 0; - // Clear errors - clear_flash_error(sl); + // Clear errors + clear_flash_error(sl); - ILOG("Asked to write option byte %#10x to %#010x.\n", *(uint32_t*) (base), addr); - write_uint32((unsigned char*) &option_byte, *(uint32_t*) (base)); - ILOG("Write %d option bytes %#010x to %#010x!\n", len, option_byte, addr); + ILOG("Asked to write option byte %#10x to %#010x.\n", *(uint32_t *)(base), + addr); + write_uint32((unsigned char *)&option_byte, *(uint32_t *)(base)); + ILOG("Write %d option bytes %#010x to %#010x!\n", len, option_byte, addr); - if ( addr == 0 ) { - addr = FLASH_F7_OPTCR; - ILOG("No address provided, using %#10x\n", addr); - } + if (addr == 0) { + addr = FLASH_F7_OPTCR; + ILOG("No address provided, using %#10x\n", addr); + } - if ( addr == FLASH_F7_OPTCR ) { - /* write option byte, ensuring we dont lock opt, and set strt bit */ - stlink_write_debug32(sl, FLASH_F7_OPTCR, (option_byte & ~(1 << FLASH_F7_OPTCR_LOCK)) | (1 << FLASH_F7_OPTCR_START)); - } else if ( addr == FLASH_F7_OPTCR1 ) { - // Read FLASH_F7_OPTCR - uint32_t oldvalue; - stlink_read_debug32(sl, FLASH_F7_OPTCR, &oldvalue); - /* write option byte */ - stlink_write_debug32(sl, FLASH_F7_OPTCR1, option_byte); - // Write FLASH_F7_OPTCR lock and start address - stlink_write_debug32(sl, FLASH_F7_OPTCR, (oldvalue & ~(1 << FLASH_F7_OPTCR_LOCK)) | (1 << FLASH_F7_OPTCR_START)); - } else { - WLOG("WIP: write %#010x to address %#010x\n", option_byte, addr); - stlink_write_debug32(sl, addr, option_byte); - } + if (addr == FLASH_F7_OPTCR) { + /* write option byte, ensuring we dont lock opt, and set strt bit */ + stlink_write_debug32(sl, FLASH_F7_OPTCR, + (option_byte & ~(1 << FLASH_F7_OPTCR_LOCK)) | + (1 << FLASH_F7_OPTCR_START)); + } else if (addr == FLASH_F7_OPTCR1) { + // Read FLASH_F7_OPTCR + uint32_t oldvalue; + stlink_read_debug32(sl, FLASH_F7_OPTCR, &oldvalue); + /* write option byte */ + stlink_write_debug32(sl, FLASH_F7_OPTCR1, option_byte); + // Write FLASH_F7_OPTCR lock and start address + stlink_write_debug32(sl, FLASH_F7_OPTCR, + (oldvalue & ~(1 << FLASH_F7_OPTCR_LOCK)) | + (1 << FLASH_F7_OPTCR_START)); + } else { + WLOG("WIP: write %#010x to address %#010x\n", option_byte, addr); + stlink_write_debug32(sl, addr, option_byte); + } - wait_flash_busy(sl); + wait_flash_busy(sl); - ret = check_flash_error(sl); - if (!ret) - ILOG("Wrote %d option bytes %#010x to %#010x!\n", len, *(uint32_t*) base, addr); + ret = check_flash_error(sl); + if (!ret) + ILOG("Wrote %d option bytes %#010x to %#010x!\n", len, *(uint32_t *)base, + addr); - /* option bytes are reloaded at reset only, no obl. */ + /* option bytes are reloaded at reset only, no obl. */ - return ret; + return ret; } /** @@ -3894,64 +4054,67 @@ static int stlink_write_option_bytes_f7(stlink_t *sl, uint8_t* base, stm32_addr_ * @param len number of bytes to write (must be multiple of 4) * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_h7( - stlink_t *sl, uint8_t* base, stm32_addr_t addr, uint32_t len) { - uint32_t val; - uint32_t data; - - // Wait until previous flash option has completed - wait_flash_busy(sl); - - // Clear previous error - stlink_write_debug32(sl, FLASH_H7_OPTCCR, 1 << FLASH_H7_OPTCCR_CLR_OPTCHANGEERR); - - while (len != 0) { - switch (addr) { - case FLASH_H7_REGS_ADDR + 0x20: // FLASH_OPTSR_PRG - case FLASH_H7_REGS_ADDR + 0x2c: // FLASH_PRAR_PRG1 - case FLASH_H7_REGS_ADDR + 0x34: // FLASH_SCAR_PRG1 - case FLASH_H7_REGS_ADDR + 0x3c: // FLASH_WPSN_PRG1 - case FLASH_H7_REGS_ADDR + 0x44: // FLASH_BOOT_PRG - /* Write to FLASH_xxx_PRG registers */ - write_uint32((unsigned char*)&data, *(uint32_t*)(base)); // write options bytes - - WLOG("Writing option bytes %#10x to %#10x\n", data, addr); - - /* Skip if the value in the CUR register is identical */ - stlink_read_debug32(sl, addr - 4, &val); - if (val == data) { - break; - } - - /* Write new option byte values and start modification */ - stlink_write_debug32(sl, addr, data); - stlink_read_debug32(sl, FLASH_H7_OPTCR, &val); - val |= (1 << FLASH_H7_OPTCR_OPTSTART); - stlink_write_debug32(sl, FLASH_H7_OPTCR, val); - - /* Wait for the option bytes modification to complete */ - do { - stlink_read_debug32(sl, FLASH_H7_OPTSR_CUR, &val); - } while ((val & (1 << FLASH_H7_OPTSR_OPT_BUSY)) != 0); - - /* Check for errors */ - if ((val & (1 << FLASH_H7_OPTSR_OPTCHANGEERR)) != 0) { - stlink_write_debug32(sl, FLASH_H7_OPTCCR, 1 << FLASH_H7_OPTCCR_CLR_OPTCHANGEERR); - return -1; - } - break; - - default: - /* Skip non-programmable registers */ - break; - } +static int stlink_write_option_bytes_h7(stlink_t *sl, uint8_t *base, + stm32_addr_t addr, uint32_t len) { + uint32_t val; + uint32_t data; + + // Wait until previous flash option has completed + wait_flash_busy(sl); + + // Clear previous error + stlink_write_debug32(sl, FLASH_H7_OPTCCR, + 1 << FLASH_H7_OPTCCR_CLR_OPTCHANGEERR); + + while (len != 0) { + switch (addr) { + case FLASH_H7_REGS_ADDR + 0x20: // FLASH_OPTSR_PRG + case FLASH_H7_REGS_ADDR + 0x2c: // FLASH_PRAR_PRG1 + case FLASH_H7_REGS_ADDR + 0x34: // FLASH_SCAR_PRG1 + case FLASH_H7_REGS_ADDR + 0x3c: // FLASH_WPSN_PRG1 + case FLASH_H7_REGS_ADDR + 0x44: // FLASH_BOOT_PRG + /* Write to FLASH_xxx_PRG registers */ + write_uint32((unsigned char *)&data, + *(uint32_t *)(base)); // write options bytes + + WLOG("Writing option bytes %#10x to %#10x\n", data, addr); + + /* Skip if the value in the CUR register is identical */ + stlink_read_debug32(sl, addr - 4, &val); + if (val == data) { + break; + } + + /* Write new option byte values and start modification */ + stlink_write_debug32(sl, addr, data); + stlink_read_debug32(sl, FLASH_H7_OPTCR, &val); + val |= (1 << FLASH_H7_OPTCR_OPTSTART); + stlink_write_debug32(sl, FLASH_H7_OPTCR, val); + + /* Wait for the option bytes modification to complete */ + do { + stlink_read_debug32(sl, FLASH_H7_OPTSR_CUR, &val); + } while ((val & (1 << FLASH_H7_OPTSR_OPT_BUSY)) != 0); + + /* Check for errors */ + if ((val & (1 << FLASH_H7_OPTSR_OPTCHANGEERR)) != 0) { + stlink_write_debug32(sl, FLASH_H7_OPTCCR, + 1 << FLASH_H7_OPTCCR_CLR_OPTCHANGEERR); + return -1; + } + break; - len -= 4; - addr += 4; - base += 4; + default: + /* Skip non-programmable registers */ + break; } - return 0; + len -= 4; + addr += 4; + base += 4; + } + + return 0; } /** @@ -3960,8 +4123,9 @@ static int stlink_write_option_bytes_h7( * @param option_byte value to write * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register_Gx(stlink_t *sl, uint32_t* option_byte) { - return stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, option_byte); +int stlink_read_option_control_register_Gx(stlink_t *sl, + uint32_t *option_byte) { + return stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, option_byte); } /** @@ -3970,8 +4134,8 @@ int stlink_read_option_control_register_Gx(stlink_t *sl, uint32_t* option_byte) * @param option_byte value to write * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t* option_byte) { - return stlink_read_option_control_register_Gx(sl, option_byte); +int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t *option_byte) { + return stlink_read_option_control_register_Gx(sl, option_byte); } /** @@ -3980,8 +4144,9 @@ int stlink_read_option_bytes_Gx(stlink_t *sl, uint32_t* option_byte) { * @param option_byte value to write * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register_f2(stlink_t *sl, uint32_t* option_byte) { - return stlink_read_debug32(sl, FLASH_F2_OPT_CR, option_byte); +int stlink_read_option_control_register_f2(stlink_t *sl, + uint32_t *option_byte) { + return stlink_read_debug32(sl, FLASH_F2_OPT_CR, option_byte); } /** @@ -3990,8 +4155,8 @@ int stlink_read_option_control_register_f2(stlink_t *sl, uint32_t* option_byte) * @param option_byte value to write * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte) { - return stlink_read_option_control_register_f2(sl, option_byte); +int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t *option_byte) { + return stlink_read_option_control_register_f2(sl, option_byte); } /** @@ -4000,8 +4165,9 @@ int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte) { * @param option_byte value to read * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register_f4(stlink_t *sl, uint32_t* option_byte) { - return stlink_read_debug32(sl, FLASH_F4_OPTCR, option_byte); +int stlink_read_option_control_register_f4(stlink_t *sl, + uint32_t *option_byte) { + return stlink_read_debug32(sl, FLASH_F4_OPTCR, option_byte); } /** @@ -4010,8 +4176,8 @@ int stlink_read_option_control_register_f4(stlink_t *sl, uint32_t* option_byte) * @param option_byte value to read * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte) { - return stlink_read_option_control_register_f4(sl, option_byte); +int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t *option_byte) { + return stlink_read_option_control_register_f4(sl, option_byte); } /** @@ -4020,9 +4186,10 @@ int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte) { * @param option_byte value to read * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register_f7(stlink_t *sl, uint32_t* option_byte) { - DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_F7_OPTCR); - return stlink_read_debug32(sl, FLASH_F7_OPTCR, option_byte); +int stlink_read_option_control_register_f7(stlink_t *sl, + uint32_t *option_byte) { + DLOG("@@@@ Read option control register byte from %#10x\n", FLASH_F7_OPTCR); + return stlink_read_debug32(sl, FLASH_F7_OPTCR, option_byte); } /** @@ -4031,9 +4198,11 @@ int stlink_read_option_control_register_f7(stlink_t *sl, uint32_t* option_byte) * @param option_byte value to read * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register1_f7(stlink_t *sl, uint32_t* option_byte) { - DLOG("@@@@ Read option control register 1 byte from %#10x\n", FLASH_F7_OPTCR1); - return stlink_read_debug32(sl, FLASH_F7_OPTCR1, option_byte); +int stlink_read_option_control_register1_f7(stlink_t *sl, + uint32_t *option_byte) { + DLOG("@@@@ Read option control register 1 byte from %#10x\n", + FLASH_F7_OPTCR1); + return stlink_read_debug32(sl, FLASH_F7_OPTCR1, option_byte); } /** @@ -4042,9 +4211,9 @@ int stlink_read_option_control_register1_f7(stlink_t *sl, uint32_t* option_byte) * @param option_byte value to read * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_boot_add_f7(stlink_t *sl, uint32_t* option_byte) { - DLOG("@@@@ Read option byte boot address\n"); - return stlink_read_option_control_register1_f7(sl, option_byte); +int stlink_read_option_bytes_boot_add_f7(stlink_t *sl, uint32_t *option_byte) { + DLOG("@@@@ Read option byte boot address\n"); + return stlink_read_option_control_register1_f7(sl, option_byte); } /** @@ -4056,18 +4225,22 @@ int stlink_read_option_bytes_boot_add_f7(stlink_t *sl, uint32_t* option_byte) { * Since multiple bytes can be read, we read and print all but one here * and then return the last one just like other devices */ -int stlink_read_option_bytes_f7(stlink_t *sl, uint32_t* option_byte) { - int err = -1; - for (uint8_t counter = 0; counter < (sl->option_size / 4 - 1); counter++) { - err = stlink_read_debug32(sl, sl->option_base + counter * sizeof(uint32_t), option_byte); - if (err == -1) { - return err; - } else { - printf("%08x\n", *option_byte); - } +int stlink_read_option_bytes_f7(stlink_t *sl, uint32_t *option_byte) { + int err = -1; + for (uint32_t counter = 0; counter < (sl->option_size / 4 - 1); counter++) { + err = stlink_read_debug32(sl, sl->option_base + counter * sizeof(uint32_t), + option_byte); + if (err == -1) { + return err; + } else { + printf("%08x\n", *option_byte); } + } - return stlink_read_debug32(sl, sl->option_base + (uint32_t) (sl->option_size / 4 - 1) * sizeof(uint32_t), option_byte); + return stlink_read_debug32( + sl, + sl->option_base + (uint32_t)(sl->option_size / 4 - 1) * sizeof(uint32_t), + option_byte); } /** @@ -4076,9 +4249,9 @@ int stlink_read_option_bytes_f7(stlink_t *sl, uint32_t* option_byte) { * @param option_byte option value * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t* option_byte) { - DLOG("@@@@ Read option bytes boot address from %#10x\n", sl->option_base); - return stlink_read_debug32(sl, sl->option_base, option_byte); +int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t *option_byte) { + DLOG("@@@@ Read option bytes boot address from %#10x\n", sl->option_base); + return stlink_read_debug32(sl, sl->option_base, option_byte); } /** @@ -4087,7 +4260,8 @@ int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t* option_byte) { * @param option_byte value to read * @return 0 on success, -ve on failure. */ -//int stlink_read_option_bytes_boot_add_generic(stlink_t *sl, uint32_t* option_byte) { +// int stlink_read_option_bytes_boot_add_generic(stlink_t *sl, uint32_t* +// option_byte) { // DLOG("@@@@ Read option bytes boot address from %#10x\n", sl->option_base); // return stlink_read_debug32(sl, sl->option_base, option_byte); //} @@ -4098,9 +4272,11 @@ int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t* option_byte) { * @param option_byte value to read * @return 0 on success, -ve on failure. */ -//int stlink_read_option_control_register_generic(stlink_t *sl, uint32_t* option_byte) { -// DLOG("@@@@ Read option control register byte from %#10x\n", sl->option_base); -// return stlink_read_debug32(sl, sl->option_base, option_byte); +// int stlink_read_option_control_register_generic(stlink_t *sl, uint32_t* +// option_byte) { +// DLOG("@@@@ Read option control register byte from %#10x\n", +// sl->option_base); return stlink_read_debug32(sl, sl->option_base, +// option_byte); //} /** @@ -4109,9 +4285,11 @@ int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t* option_byte) { * @param option_byte value to read * @return 0 on success, -ve on failure. */ -//int stlink_read_option_control_register1_generic(stlink_t *sl, uint32_t* option_byte) { -// DLOG("@@@@ Read option control register 1 byte from %#10x\n", sl->option_base); -// return stlink_read_debug32(sl, sl->option_base, option_byte); +// int stlink_read_option_control_register1_generic(stlink_t *sl, uint32_t* +// option_byte) { +// DLOG("@@@@ Read option control register 1 byte from %#10x\n", +// sl->option_base); return stlink_read_debug32(sl, sl->option_base, +// option_byte); //} /** @@ -4120,28 +4298,28 @@ int stlink_read_option_bytes_generic(stlink_t *sl, uint32_t* option_byte) { * @param option_byte option value * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte) { - if (sl->option_base == 0) { - ELOG("Option bytes read is currently not supported for connected chip\n"); - return(-1); - } - - switch (sl->chip_id) { - case STLINK_CHIPID_STM32_F2: - return stlink_read_option_bytes_f2(sl, option_byte); - case STLINK_CHIPID_STM32_F4: - case STLINK_CHIPID_STM32_F446: - return stlink_read_option_bytes_f4(sl, option_byte); - case STLINK_CHIPID_STM32_F7XXXX: - return stlink_read_option_bytes_f7(sl, option_byte); - case STLINK_CHIPID_STM32_G0_CAT1: - case STLINK_CHIPID_STM32_G0_CAT2: - case STLINK_CHIPID_STM32_G4_CAT2: - case STLINK_CHIPID_STM32_G4_CAT3: - return stlink_read_option_bytes_Gx(sl, option_byte); - default: - return stlink_read_option_bytes_generic(sl, option_byte); - } +int stlink_read_option_bytes32(stlink_t *sl, uint32_t *option_byte) { + if (sl->option_base == 0) { + ELOG("Option bytes read is currently not supported for connected chip\n"); + return (-1); + } + + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_F2: + return stlink_read_option_bytes_f2(sl, option_byte); + case STLINK_CHIPID_STM32_F4: + case STLINK_CHIPID_STM32_F446: + return stlink_read_option_bytes_f4(sl, option_byte); + case STLINK_CHIPID_STM32_F7XXXX: + return stlink_read_option_bytes_f7(sl, option_byte); + case STLINK_CHIPID_STM32_G0_CAT1: + case STLINK_CHIPID_STM32_G0_CAT2: + case STLINK_CHIPID_STM32_G4_CAT2: + case STLINK_CHIPID_STM32_G4_CAT3: + return stlink_read_option_bytes_Gx(sl, option_byte); + default: + return stlink_read_option_bytes_generic(sl, option_byte); + } } /** @@ -4150,20 +4328,20 @@ int stlink_read_option_bytes32(stlink_t *sl, uint32_t* option_byte) { * @param option_byte option value * @return 0 on success, -ve on failure. */ -int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t* option_byte) -{ - if (sl->option_base == 0) { - ELOG("Option bytes boot address read is currently not supported for connected chip\n"); - return -1; - } - - switch (sl->chip_id) { - case STLINK_CHIPID_STM32_F7XXXX: - return stlink_read_option_bytes_boot_add_f7(sl, option_byte); - default: - return -1; - //return stlink_read_option_bytes_boot_add_generic(sl, option_byte); - } +int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t *option_byte) { + if (sl->option_base == 0) { + ELOG("Option bytes boot address read is currently not supported for " + "connected chip\n"); + return -1; + } + + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_F7XXXX: + return stlink_read_option_bytes_boot_add_f7(sl, option_byte); + default: + return -1; + // return stlink_read_option_bytes_boot_add_generic(sl, option_byte); + } } /** @@ -4172,20 +4350,19 @@ int stlink_read_option_bytes_boot_add32(stlink_t *sl, uint32_t* option_byte) * @param option_byte option value * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register32(stlink_t *sl, uint32_t* option_byte) -{ - if (sl->option_base == 0) { - ELOG("Option bytes read is currently not supported for connected chip\n"); - return -1; - } +int stlink_read_option_control_register32(stlink_t *sl, uint32_t *option_byte) { + if (sl->option_base == 0) { + ELOG("Option bytes read is currently not supported for connected chip\n"); + return -1; + } - switch (sl->chip_id) { - case STLINK_CHIPID_STM32_F7XXXX: - return stlink_read_option_control_register_f7(sl, option_byte); - default: - return -1; - //return stlink_read_option_control_register_generic(sl, option_byte); - } + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_F7XXXX: + return stlink_read_option_control_register_f7(sl, option_byte); + default: + return -1; + // return stlink_read_option_control_register_generic(sl, option_byte); + } } /** @@ -4194,20 +4371,20 @@ int stlink_read_option_control_register32(stlink_t *sl, uint32_t* option_byte) * @param option_byte option value * @return 0 on success, -ve on failure. */ -int stlink_read_option_control_register1_32(stlink_t *sl, uint32_t* option_byte) -{ - if (sl->option_base == 0) { - ELOG("Option bytes read is currently not supported for connected chip\n"); - return -1; - } - - switch (sl->chip_id) { - case STLINK_CHIPID_STM32_F7XXXX: - return stlink_read_option_control_register1_f7(sl, option_byte); - default: - return -1; - //return stlink_read_option_control_register1_generic(sl, option_byte); - } +int stlink_read_option_control_register1_32(stlink_t *sl, + uint32_t *option_byte) { + if (sl->option_base == 0) { + ELOG("Option bytes read is currently not supported for connected chip\n"); + return -1; + } + + switch (sl->chip_id) { + case STLINK_CHIPID_STM32_F7XXXX: + return stlink_read_option_control_register1_f7(sl, option_byte); + default: + return -1; + // return stlink_read_option_control_register1_generic(sl, option_byte); + } } /** @@ -4216,10 +4393,11 @@ int stlink_read_option_control_register1_32(stlink_t *sl, uint32_t* option_byte) * @param option_byte value to write * @return 0 on success, -ve on failure. */ -int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) -{ - WLOG("About to write option byte %#10x to %#10x.\n", option_byte, sl->option_base); - return stlink_write_option_bytes(sl, sl->option_base, (uint8_t *) &option_byte, 4); +int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) { + WLOG("About to write option byte %#10x to %#10x.\n", option_byte, + sl->option_base); + return stlink_write_option_bytes(sl, sl->option_base, (uint8_t *)&option_byte, + 4); } /** @@ -4229,73 +4407,76 @@ int stlink_write_option_bytes32(stlink_t *sl, uint32_t option_byte) * @param base option bytes to write * @return 0 on success, -ve on failure. */ -int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len) { - int ret = -1; - - if (sl->option_base == 0) { - ELOG("Option bytes writing is currently not supported for connected chip\n"); - return(-1); - } - - - if ((addr < sl->option_base) || addr > sl->option_base + sl->option_size) { - ELOG("Option bytes start address out of Option bytes range\n"); - return(-1); - } - - if (addr + len > sl->option_base + sl->option_size) { - ELOG("Option bytes data too long\n"); - return(-1); - } - - wait_flash_busy(sl); - - if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); - return(-1); - } - - if (unlock_flash_option_if(sl)) { - ELOG("Flash option unlock failed!\n"); - return(-1); - } - - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F4: - ret = stlink_write_option_bytes_f4(sl, base, addr, len); - break; - case STLINK_FLASH_TYPE_F7: - ret = stlink_write_option_bytes_f7(sl, base, addr, len); - break; - case STLINK_FLASH_TYPE_L0: - ret = stlink_write_option_bytes_l0(sl, base, addr, len); - break; - case STLINK_FLASH_TYPE_L4: - ret = stlink_write_option_bytes_l4(sl, base, addr, len); - break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - ret = stlink_write_option_bytes_gx(sl, base, addr, len); - break; - case STLINK_FLASH_TYPE_H7: - ret = stlink_write_option_bytes_h7(sl, base, addr, len); - break; - default: - ELOG("Option bytes writing is currently not implemented for connected chip\n"); - break; - } - - if (ret) { - ELOG("Flash option write failed!\n"); - } else { - ILOG("Wrote %d option bytes to %#010x!\n", len, addr); - } - - /* Re-lock flash. */ - lock_flash_option(sl); - lock_flash(sl); - - return ret; +int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t *base, + uint32_t len) { + int ret = -1; + + if (sl->option_base == 0) { + ELOG( + "Option bytes writing is currently not supported for connected chip\n"); + return (-1); + } + + if ((addr < sl->option_base) || addr > sl->option_base + sl->option_size) { + ELOG("Option bytes start address out of Option bytes range\n"); + return (-1); + } + + if (addr + len > sl->option_base + sl->option_size) { + ELOG("Option bytes data too long\n"); + return (-1); + } + + wait_flash_busy(sl); + + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it " + "again!\n"); + return (-1); + } + + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return (-1); + } + + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F4: + ret = stlink_write_option_bytes_f4(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_F7: + ret = stlink_write_option_bytes_f7(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_L0: + ret = stlink_write_option_bytes_l0(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_L4: + ret = stlink_write_option_bytes_l4(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + ret = stlink_write_option_bytes_gx(sl, base, addr, len); + break; + case STLINK_FLASH_TYPE_H7: + ret = stlink_write_option_bytes_h7(sl, base, addr, len); + break; + default: + ELOG("Option bytes writing is currently not implemented for connected " + "chip\n"); + break; + } + + if (ret) { + ELOG("Flash option write failed!\n"); + } else { + ILOG("Wrote %d option bytes to %#010x!\n", len, addr); + } + + /* Re-lock flash. */ + lock_flash_option(sl); + lock_flash(sl); + + return ret; } /** @@ -4304,24 +4485,30 @@ int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, ui * @param option_byte value to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_control_register_f7(stlink_t *sl, uint32_t option_control_register) { - int ret = 0; +static int +stlink_write_option_control_register_f7(stlink_t *sl, + uint32_t option_control_register) { + int ret = 0; - // Clear errors - clear_flash_error(sl); + // Clear errors + clear_flash_error(sl); - ILOG("Asked to write option control register 1 %#10x to %#010x.\n", option_control_register, FLASH_F7_OPTCR); + ILOG("Asked to write option control register 1 %#10x to %#010x.\n", + option_control_register, FLASH_F7_OPTCR); - /* write option byte, ensuring we dont lock opt, and set strt bit */ - stlink_write_debug32(sl, FLASH_F7_OPTCR, (option_control_register & ~(1 << FLASH_F7_OPTCR_LOCK)) | (1 << FLASH_F7_OPTCR_START)); + /* write option byte, ensuring we dont lock opt, and set strt bit */ + stlink_write_debug32(sl, FLASH_F7_OPTCR, + (option_control_register & ~(1 << FLASH_F7_OPTCR_LOCK)) | + (1 << FLASH_F7_OPTCR_START)); - wait_flash_busy(sl); + wait_flash_busy(sl); - ret = check_flash_error(sl); - if (!ret) - ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, FLASH_F7_OPTCR); + ret = check_flash_error(sl); + if (!ret) + ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register, + FLASH_F7_OPTCR); - return ret; + return ret; } /** @@ -4330,29 +4517,36 @@ static int stlink_write_option_control_register_f7(stlink_t *sl, uint32_t option * @param option_byte value to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_control_register1_f7(stlink_t *sl, uint32_t option_control_register1) { - int ret = 0; +static int +stlink_write_option_control_register1_f7(stlink_t *sl, + uint32_t option_control_register1) { + int ret = 0; - // Clear errors - clear_flash_error(sl); + // Clear errors + clear_flash_error(sl); - ILOG("Asked to write option control register 1 %#010x to %#010x.\n", option_control_register1, FLASH_F7_OPTCR1); + ILOG("Asked to write option control register 1 %#010x to %#010x.\n", + option_control_register1, FLASH_F7_OPTCR1); - /* write option byte, ensuring we dont lock opt, and set strt bit */ - uint32_t current_control_register_value; - stlink_read_debug32(sl, FLASH_F7_OPTCR, ¤t_control_register_value); + /* write option byte, ensuring we dont lock opt, and set strt bit */ + uint32_t current_control_register_value; + stlink_read_debug32(sl, FLASH_F7_OPTCR, ¤t_control_register_value); - /* write option byte */ - stlink_write_debug32(sl, FLASH_F7_OPTCR1, option_control_register1); - stlink_write_debug32(sl, FLASH_F7_OPTCR, (current_control_register_value & ~(1 << FLASH_F7_OPTCR_LOCK)) | (1 << FLASH_F7_OPTCR_START)); + /* write option byte */ + stlink_write_debug32(sl, FLASH_F7_OPTCR1, option_control_register1); + stlink_write_debug32( + sl, FLASH_F7_OPTCR, + (current_control_register_value & ~(1 << FLASH_F7_OPTCR_LOCK)) | + (1 << FLASH_F7_OPTCR_START)); - wait_flash_busy(sl); + wait_flash_busy(sl); - ret = check_flash_error(sl); - if (!ret) - ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register1, FLASH_F7_OPTCR1); + ret = check_flash_error(sl); + if (!ret) + ILOG("Wrote option bytes %#010x to %#010x!\n", option_control_register1, + FLASH_F7_OPTCR1); - return ret; + return ret; } /** @@ -4361,9 +4555,11 @@ static int stlink_write_option_control_register1_f7(stlink_t *sl, uint32_t optio * @param option_byte value to write * @return 0 on success, -ve on failure. */ -static int stlink_write_option_bytes_boot_add_f7(stlink_t *sl, uint32_t option_byte_boot_add) { - ILOG("Asked to write option byte boot add %#010x.\n", option_byte_boot_add); - return stlink_write_option_control_register1_f7(sl, option_byte_boot_add); +static int +stlink_write_option_bytes_boot_add_f7(stlink_t *sl, + uint32_t option_byte_boot_add) { + ILOG("Asked to write option byte boot add %#010x.\n", option_byte_boot_add); + return stlink_write_option_control_register1_f7(sl, option_byte_boot_add); } /** @@ -4372,41 +4568,43 @@ static int stlink_write_option_bytes_boot_add_f7(stlink_t *sl, uint32_t option_b * @param option bytes boot address to write * @return 0 on success, -ve on failure. */ -int stlink_write_option_bytes_boot_add32(stlink_t *sl, uint32_t option_bytes_boot_add) -{ - int ret = -1; +int stlink_write_option_bytes_boot_add32(stlink_t *sl, + uint32_t option_bytes_boot_add) { + int ret = -1; - wait_flash_busy(sl); + wait_flash_busy(sl); - if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it " + "again!\n"); + return -1; + } - if (unlock_flash_option_if(sl)) { - ELOG("Flash option unlock failed!\n"); - return -1; - } + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return -1; + } - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F7: - ret = stlink_write_option_bytes_boot_add_f7(sl, option_bytes_boot_add); - break; - default: - ELOG("Option bytes boot address writing is currently not implemented for connected chip\n"); - break; - } + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F7: + ret = stlink_write_option_bytes_boot_add_f7(sl, option_bytes_boot_add); + break; + default: + ELOG("Option bytes boot address writing is currently not implemented for " + "connected chip\n"); + break; + } - if (ret) - ELOG("Flash option write failed!\n"); - else - ILOG("Wrote option bytes boot address %#010x!\n", option_bytes_boot_add); + if (ret) + ELOG("Flash option write failed!\n"); + else + ILOG("Wrote option bytes boot address %#010x!\n", option_bytes_boot_add); - /* Re-lock flash. */ - lock_flash_option(sl); - lock_flash(sl); + /* Re-lock flash. */ + lock_flash_option(sl); + lock_flash(sl); - return ret; + return ret; } /** @@ -4415,41 +4613,43 @@ int stlink_write_option_bytes_boot_add32(stlink_t *sl, uint32_t option_bytes_boo * @param option bytes boot address to write * @return 0 on success, -ve on failure. */ -int stlink_write_option_control_register32(stlink_t *sl, uint32_t option_control_register) -{ - int ret = -1; +int stlink_write_option_control_register32(stlink_t *sl, + uint32_t option_control_register) { + int ret = -1; - wait_flash_busy(sl); + wait_flash_busy(sl); - if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it " + "again!\n"); + return -1; + } - if (unlock_flash_option_if(sl)) { - ELOG("Flash option unlock failed!\n"); - return -1; - } + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return -1; + } - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F7: - ret = stlink_write_option_control_register_f7(sl, option_control_register); - break; - default: - ELOG("Option control register writing is currently not implemented for connected chip\n"); - break; - } + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F7: + ret = stlink_write_option_control_register_f7(sl, option_control_register); + break; + default: + ELOG("Option control register writing is currently not implemented for " + "connected chip\n"); + break; + } - if (ret) - ELOG("Flash option write failed!\n"); - else - ILOG("Wrote option control register %#010x!\n", option_control_register); + if (ret) + ELOG("Flash option write failed!\n"); + else + ILOG("Wrote option control register %#010x!\n", option_control_register); - /* Re-lock flash. */ - lock_flash_option(sl); - lock_flash(sl); + /* Re-lock flash. */ + lock_flash_option(sl); + lock_flash(sl); - return ret; + return ret; } /** @@ -4458,40 +4658,43 @@ int stlink_write_option_control_register32(stlink_t *sl, uint32_t option_control * @param option bytes boot address to write * @return 0 on success, -ve on failure. */ -int stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_control_register1) -{ - int ret = -1; +int stlink_write_option_control_register1_32( + stlink_t *sl, uint32_t option_control_register1) { + int ret = -1; - wait_flash_busy(sl); + wait_flash_busy(sl); - if (unlock_flash_if(sl)) { - ELOG("Flash unlock failed! System reset required to be able to unlock it again!\n"); - return -1; - } + if (unlock_flash_if(sl)) { + ELOG("Flash unlock failed! System reset required to be able to unlock it " + "again!\n"); + return -1; + } - if (unlock_flash_option_if(sl)) { - ELOG("Flash option unlock failed!\n"); - return -1; - } + if (unlock_flash_option_if(sl)) { + ELOG("Flash option unlock failed!\n"); + return -1; + } - switch (sl->flash_type) { - case STLINK_FLASH_TYPE_F7: - ret = stlink_write_option_control_register1_f7(sl, option_control_register1); - break; - default: - ELOG("Option control register 1 writing is currently not implemented for connected chip\n"); - break; - } + switch (sl->flash_type) { + case STLINK_FLASH_TYPE_F7: + ret = + stlink_write_option_control_register1_f7(sl, option_control_register1); + break; + default: + ELOG("Option control register 1 writing is currently not implemented for " + "connected chip\n"); + break; + } - if (ret) - ELOG("Flash option write failed!\n"); - else - ILOG("Wrote option control register 1 %#010x!\n", option_control_register1); + if (ret) + ELOG("Flash option write failed!\n"); + else + ILOG("Wrote option control register 1 %#010x!\n", option_control_register1); - lock_flash_option(sl); - lock_flash(sl); + lock_flash_option(sl); + lock_flash(sl); - return(ret); + return (ret); } /** @@ -4501,61 +4704,66 @@ int stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_contr * @param addr of the memory mapped option bytes * @return 0 on success, -ve on failure. */ -int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr) { - /* Write the file in flash at addr */ - int err; - mapped_file_t mf = MAPPED_FILE_INITIALIZER; - - if (map_file(&mf, path) == -1) { - ELOG("map_file() == -1\n"); - return(-1); - } +int stlink_fwrite_option_bytes(stlink_t *sl, const char *path, + stm32_addr_t addr) { + /* Write the file in flash at addr */ + int err; + mapped_file_t mf = MAPPED_FILE_INITIALIZER; - printf("file %s ", path); - md5_calculate(&mf); - stlink_checksum(&mf); + if (map_file(&mf, path) == -1) { + ELOG("map_file() == -1\n"); + return (-1); + } - err = stlink_write_option_bytes(sl, addr, mf.base, (uint32_t)mf.len); - stlink_fwrite_finalize(sl, addr); - unmap_file(&mf); + printf("file %s ", path); + md5_calculate(&mf); + stlink_checksum(&mf); - return(err); + err = stlink_write_option_bytes(sl, addr, mf.base, (uint32_t)mf.len); + stlink_fwrite_finalize(sl, addr); + unmap_file(&mf); + + return (err); } int stlink_target_connect(stlink_t *sl, enum connect_type connect) { - uint32_t dhcsr; - - if (connect == CONNECT_UNDER_RESET) { - stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_LOW); + uint32_t dhcsr; - // minimum reset pulse duration of 20 us (RM0008, 8.1.2 Power reset) - usleep(20); + if (connect == CONNECT_UNDER_RESET) { + stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_LOW); - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } - stlink_force_debug(sl); + // minimum reset pulse duration of 20 us (RM0008, 8.1.2 Power reset) + usleep(20); - // clear S_RESET_ST in DHCSR register - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { + stlink_enter_swd_mode(sl); + } + stlink_force_debug(sl); - stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_HIGH); - usleep(10000); + // clear S_RESET_ST in DHCSR register + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - // check NRST connection - dhcsr = 0; - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); - if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { - WLOG("NRST is not connected\n"); - } + stlink_jtag_reset(sl, STLINK_JTAG_DRIVE_NRST_HIGH); + usleep(10000); - // addition soft reset for halt before the first instruction - stlink_soft_reset(sl, 1 /* halt on reset */); + // check NRST connection + dhcsr = 0; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr & STLINK_REG_DHCSR_S_RESET_ST) == 0) { + WLOG("NRST is not connected\n"); } - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { stlink_enter_swd_mode(sl); } + // addition soft reset for halt before the first instruction + stlink_soft_reset(sl, 1 /* halt on reset */); + } - if (connect == CONNECT_NORMAL) { - stlink_reset(sl, RESET_AUTO); - } + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { + stlink_enter_swd_mode(sl); + } + + if (connect == CONNECT_NORMAL) { + stlink_reset(sl, RESET_AUTO); + } - return stlink_load_device_params(sl); + return stlink_load_device_params(sl); } diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index f28624475..a02c64701 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -1,556 +1,596 @@ +#include +#include +#include +#include #include #include #include #include -#include -#include -#include -#include -#include #include +#include -#include -#include #include - +#include +#include #define DEFAULT_LOGGING_LEVEL 50 #define DEBUG_LOGGING_LEVEL 100 -#define APP_RESULT_SUCCESS 0 -#define APP_RESULT_INVALID_PARAMS 1 -#define APP_RESULT_STLINK_NOT_FOUND 2 -#define APP_RESULT_STLINK_MISSING_DEVICE 3 -#define APP_RESULT_STLINK_UNSUPPORTED_DEVICE 4 -#define APP_RESULT_STLINK_UNSUPPORTED_LINK 5 -#define APP_RESULT_UNSUPPORTED_TRACE_FREQUENCY 6 -#define APP_RESULT_STLINK_STATE_ERROR 7 +#define APP_RESULT_SUCCESS 0 +#define APP_RESULT_INVALID_PARAMS 1 +#define APP_RESULT_STLINK_NOT_FOUND 2 +#define APP_RESULT_STLINK_MISSING_DEVICE 3 +#define APP_RESULT_STLINK_UNSUPPORTED_DEVICE 4 +#define APP_RESULT_STLINK_UNSUPPORTED_LINK 5 +#define APP_RESULT_UNSUPPORTED_TRACE_FREQUENCY 6 +#define APP_RESULT_STLINK_STATE_ERROR 7 // See D4.2 of https://developer.arm.com/documentation/ddi0403/ed/ -#define TRACE_OP_IS_OVERFLOW(c) ((c) == 0x70) -#define TRACE_OP_IS_LOCAL_TIME(c) (((c) & 0x0f) == 0x00 && ((c) & 0x70) != 0x00) -#define TRACE_OP_IS_EXTENSION(c) (((c) & 0x0b) == 0x08) -#define TRACE_OP_IS_GLOBAL_TIME(c) (((c) & 0xdf) == 0x94) -#define TRACE_OP_IS_SOURCE(c) (((c) & 0x03) != 0x00) -#define TRACE_OP_IS_SW_SOURCE(c) (((c) & 0x03) != 0x00 && ((c) & 0x04) == 0x00) -#define TRACE_OP_IS_HW_SOURCE(c) (((c) & 0x03) != 0x00 && ((c) & 0x04) == 0x04) -#define TRACE_OP_IS_TARGET_SOURCE(c) ((c) == 0x01) -#define TRACE_OP_GET_CONTINUATION(c) ((c) & 0x80) -#define TRACE_OP_GET_SOURCE_SIZE(c) ((c) & 0x03) -#define TRACE_OP_GET_SW_SOURCE_ADDR(c) ((c) >> 3) - +#define TRACE_OP_IS_OVERFLOW(c) ((c) == 0x70) +#define TRACE_OP_IS_LOCAL_TIME(c) (((c)&0x0f) == 0x00 && ((c)&0x70) != 0x00) +#define TRACE_OP_IS_EXTENSION(c) (((c)&0x0b) == 0x08) +#define TRACE_OP_IS_GLOBAL_TIME(c) (((c)&0xdf) == 0x94) +#define TRACE_OP_IS_SOURCE(c) (((c)&0x03) != 0x00) +#define TRACE_OP_IS_SW_SOURCE(c) (((c)&0x03) != 0x00 && ((c)&0x04) == 0x00) +#define TRACE_OP_IS_HW_SOURCE(c) (((c)&0x03) != 0x00 && ((c)&0x04) == 0x04) +#define TRACE_OP_IS_TARGET_SOURCE(c) ((c) == 0x01) +#define TRACE_OP_GET_CONTINUATION(c) ((c)&0x80) +#define TRACE_OP_GET_SOURCE_SIZE(c) ((c)&0x03) +#define TRACE_OP_GET_SW_SOURCE_ADDR(c) ((c) >> 3) typedef struct { - bool show_help; - bool show_version; - int logging_level; - uint32_t core_frequency; - uint32_t trace_frequency; - bool reset_board; - bool force; - char* serial_number; + bool show_help; + bool show_version; + int logging_level; + uint32_t core_frequency; + uint32_t trace_frequency; + bool reset_board; + bool force; + char *serial_number; } st_settings_t; - // We use a simple state machine to parse the trace data. typedef enum { - TRACE_STATE_UNKNOWN, - TRACE_STATE_IDLE, - TRACE_STATE_TARGET_SOURCE, - TRACE_STATE_SKIP_FRAME, - TRACE_STATE_SKIP_4, - TRACE_STATE_SKIP_3, - TRACE_STATE_SKIP_2, - TRACE_STATE_SKIP_1, + TRACE_STATE_UNKNOWN, + TRACE_STATE_IDLE, + TRACE_STATE_TARGET_SOURCE, + TRACE_STATE_SKIP_FRAME, + TRACE_STATE_SKIP_4, + TRACE_STATE_SKIP_3, + TRACE_STATE_SKIP_2, + TRACE_STATE_SKIP_1, } trace_state; typedef struct { - time_t start_time; - bool configuration_checked; + time_t start_time; + bool configuration_checked; - trace_state state; + trace_state state; - uint32_t count_raw_bytes; - uint32_t count_target_data; - uint32_t count_time_packets; - uint32_t count_hw_overflow; - uint32_t count_sw_overflow; - uint32_t count_error; + uint32_t count_raw_bytes; + uint32_t count_target_data; + uint32_t count_time_packets; + uint32_t count_hw_overflow; + uint32_t count_sw_overflow; + uint32_t count_error; - uint8_t unknown_opcodes[256 / 8]; - uint32_t unknown_sources; + uint8_t unknown_opcodes[256 / 8]; + uint32_t unknown_sources; } st_trace_t; - -// We use a global flag to allow communicating to the main thread from the signal handler. +// We use a global flag to allow communicating to the main thread from the +// signal handler. static bool g_abort_trace = false; -static void abort_trace() { - g_abort_trace = true; -} +static void abort_trace() { g_abort_trace = true; } #if defined(_WIN32) BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) { - (void)fdwCtrlType; - abort_trace(); - return FALSE; + (void)fdwCtrlType; + abort_trace(); + return FALSE; } #endif static void usage(void) { - puts("st-trace - usage:"); - puts(" -h, --help Print this help"); - puts(" -V, --version Print this version"); - puts(" -vXX, --verbose=XX Specify a specific verbosity level (0..99)"); - puts(" -v, --verbose Specify a generally verbose logging"); - puts(" -cXX, --clock=XX Specify the core frequency in MHz"); - puts(" -tXX, --trace=XX Specify the trace frequency in Hz"); - puts(" -n, --no-reset Do not reset board on connection"); - puts(" -sXX, --serial=XX Use a specific serial number"); - puts(" -f, --force Ignore most initialization errors"); + puts("st-trace - usage:"); + puts(" -h, --help Print this help"); + puts(" -V, --version Print this version"); + puts(" -vXX, --verbose=XX Specify a specific verbosity level (0..99)"); + puts(" -v, --verbose Specify a generally verbose logging"); + puts(" -cXX, --clock=XX Specify the core frequency in MHz"); + puts(" -tXX, --trace=XX Specify the trace frequency in Hz"); + puts(" -n, --no-reset Do not reset board on connection"); + puts(" -sXX, --serial=XX Use a specific serial number"); + puts(" -f, --force Ignore most initialization errors"); } -bool parse_options(int argc, char** argv, st_settings_t *settings) { - - static struct option long_options[] = { - {"help", no_argument, NULL, 'h'}, - {"version", no_argument, NULL, 'V'}, - {"verbose", optional_argument, NULL, 'v'}, - {"clock", required_argument, NULL, 'c'}, - {"trace", required_argument, NULL, 't'}, - {"no-reset", no_argument, NULL, 'n'}, - {"serial", required_argument, NULL, 's'}, - {"force", no_argument, NULL, 'f'}, - {0, 0, 0, 0}, - }; - int option_index = 0; - int c; - bool error = false; - - settings->show_help = false; - settings->show_version = false; - settings->logging_level = DEFAULT_LOGGING_LEVEL; - settings->core_frequency = 0; - settings->trace_frequency = 0; - settings->reset_board = true; - settings->force = false; - settings->serial_number = NULL; - ugly_init(settings->logging_level); - - while ((c = getopt_long(argc, argv, "hVv::c:ns:f", long_options, &option_index)) != -1) { - switch (c) { - case 'h': - settings->show_help = true; - break; - case 'V': - settings->show_version = true; - break; - case 'v': - if (optarg) { - settings->logging_level = atoi(optarg); - } else { - settings->logging_level = DEBUG_LOGGING_LEVEL; - } - ugly_init(settings->logging_level); - break; - case 'c': - settings->core_frequency = atoi(optarg) * 1000000; - break; - case 't': - settings->trace_frequency = atoi(optarg); - break; - case 'n': - settings->reset_board = false; - break; - case 'f': - settings->force = true; - break; - case 's': - settings->serial_number = optarg; - break; - case '?': - error = true; - break; - default: - ELOG("Unknown command line option: '%c' (0x%02x)\n", c, c); - error = true; - break; - } +bool parse_options(int argc, char **argv, st_settings_t *settings) { + + static struct option long_options[] = { + {"help", no_argument, NULL, 'h'}, + {"version", no_argument, NULL, 'V'}, + {"verbose", optional_argument, NULL, 'v'}, + {"clock", required_argument, NULL, 'c'}, + {"trace", required_argument, NULL, 't'}, + {"no-reset", no_argument, NULL, 'n'}, + {"serial", required_argument, NULL, 's'}, + {"force", no_argument, NULL, 'f'}, + {0, 0, 0, 0}, + }; + int option_index = 0; + int c; + bool error = false; + + settings->show_help = false; + settings->show_version = false; + settings->logging_level = DEFAULT_LOGGING_LEVEL; + settings->core_frequency = 0; + settings->trace_frequency = 0; + settings->reset_board = true; + settings->force = false; + settings->serial_number = NULL; + ugly_init(settings->logging_level); + + while ((c = getopt_long(argc, argv, "hVv::c:ns:f", long_options, + &option_index)) != -1) { + switch (c) { + case 'h': + settings->show_help = true; + break; + case 'V': + settings->show_version = true; + break; + case 'v': + if (optarg) { + settings->logging_level = atoi(optarg); + } else { + settings->logging_level = DEBUG_LOGGING_LEVEL; + } + ugly_init(settings->logging_level); + break; + case 'c': + settings->core_frequency = atoi(optarg) * 1000000; + break; + case 't': + settings->trace_frequency = atoi(optarg); + break; + case 'n': + settings->reset_board = false; + break; + case 'f': + settings->force = true; + break; + case 's': + settings->serial_number = optarg; + break; + case '?': + error = true; + break; + default: + ELOG("Unknown command line option: '%c' (0x%02x)\n", c, c); + error = true; + break; } + } - if (optind < argc) { - while (optind < argc) { - ELOG("Unknown command line argument: '%s'\n", argv[optind++]); - } - error = true; + if (optind < argc) { + while (optind < argc) { + ELOG("Unknown command line argument: '%s'\n", argv[optind++]); } + error = true; + } - if (error && !settings->force) - return false; + if (error && !settings->force) + return false; - return true; + return true; } -static stlink_t* stlink_connect(const st_settings_t* settings) { - return stlink_open_usb(settings->logging_level, false, settings->serial_number, 0); +static stlink_t *stlink_connect(const st_settings_t *settings) { + return stlink_open_usb(settings->logging_level, false, + settings->serial_number, 0); } -static bool enable_trace(stlink_t* stlink, const st_settings_t* settings, uint32_t trace_frequency) { - - if (stlink_force_debug(stlink)) { - ELOG("Unable to debug device\n"); - if (!settings->force) - return false; - } - - if (settings->reset_board && stlink_reset(stlink, RESET_AUTO)) { - ELOG("Unable to reset device\n"); - if (!settings->force) - return false; - } - - - stlink_write_debug32(stlink, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | - STLINK_REG_DHCSR_C_DEBUGEN | - STLINK_REG_DHCSR_C_HALT); - stlink_write_debug32(stlink, STLINK_REG_DEMCR, STLINK_REG_DEMCR_TRCENA); - stlink_write_debug32(stlink, STLINK_REG_CM3_FP_CTRL, STLINK_REG_CM3_FP_CTRL_KEY); - stlink_write_debug32(stlink, STLINK_REG_DWT_FUNCTION0, 0); - stlink_write_debug32(stlink, STLINK_REG_DWT_FUNCTION1, 0); - stlink_write_debug32(stlink, STLINK_REG_DWT_FUNCTION2, 0); - stlink_write_debug32(stlink, STLINK_REG_DWT_FUNCTION3, 0); - stlink_write_debug32(stlink, STLINK_REG_DWT_CTRL, 0); - stlink_write_debug32(stlink, STLINK_REG_DBGMCU_CR, STLINK_REG_DBGMCU_CR_DBG_SLEEP | - STLINK_REG_DBGMCU_CR_DBG_STOP | - STLINK_REG_DBGMCU_CR_DBG_STANDBY | - STLINK_REG_DBGMCU_CR_TRACE_IOEN | - STLINK_REG_DBGMCU_CR_TRACE_MODE_ASYNC); - - if (stlink_trace_enable(stlink, trace_frequency)) { - ELOG("Unable to turn on tracing in stlink\n"); - if (!settings->force) - return false; - } - - stlink_write_debug32(stlink, STLINK_REG_TPI_CSPSR, STLINK_REG_TPI_CSPSR_PORT_SIZE_1); - - if (settings->core_frequency) { - uint32_t prescaler = settings->core_frequency / trace_frequency - 1; - if (prescaler > STLINK_REG_TPI_ACPR_MAX) { - ELOG("Trace frequency prescaler %d out of range. Try setting a faster trace frequency.\n", prescaler); - if (!settings->force) - return false; - } - stlink_write_debug32(stlink, STLINK_REG_TPI_ACPR, prescaler); // Set TPIU_ACPR clock divisor - } - stlink_write_debug32(stlink, STLINK_REG_TPI_FFCR, STLINK_REG_TPI_FFCR_TRIG_IN); - stlink_write_debug32(stlink, STLINK_REG_TPI_SPPR, STLINK_REG_TPI_SPPR_SWO_NRZ); - stlink_write_debug32(stlink, STLINK_REG_ITM_LAR, STLINK_REG_ITM_LAR_KEY); - stlink_write_debug32(stlink, STLINK_REG_ITM_TCC, 0x00000400); // Set sync counter - stlink_write_debug32(stlink, STLINK_REG_ITM_TCR, STLINK_REG_ITM_TCR_TRACE_BUS_ID_1 | - STLINK_REG_ITM_TCR_TS_ENA | - STLINK_REG_ITM_TCR_ITM_ENA); - stlink_write_debug32(stlink, STLINK_REG_ITM_TER, STLINK_REG_ITM_TER_PORTS_ALL); - stlink_write_debug32(stlink, STLINK_REG_ITM_TPR, STLINK_REG_ITM_TPR_PORTS_ALL); - stlink_write_debug32(stlink, STLINK_REG_DWT_CTRL, 4 * STLINK_REG_DWT_CTRL_NUM_COMP | - STLINK_REG_DWT_CTRL_CYC_TAP | - 0xF * STLINK_REG_DWT_CTRL_POST_INIT | - 0xF * STLINK_REG_DWT_CTRL_POST_PRESET | - STLINK_REG_DWT_CTRL_CYCCNT_ENA); - stlink_write_debug32(stlink, STLINK_REG_DEMCR, STLINK_REG_DEMCR_TRCENA); - - uint32_t prescaler; - stlink_read_debug32(stlink, STLINK_REG_TPI_ACPR_MAX, &prescaler); - if (prescaler) { - uint32_t system_clock_speed = (prescaler + 1) * trace_frequency; - uint32_t system_clock_speed_mhz = (system_clock_speed + 500000) / 1000000; - ILOG("Trace Port Interface configured to expect a %d MHz system clock.\n", system_clock_speed_mhz); - } else { - WLOG("Trace Port Interface not configured. Specify the system clock with a --clock=XX command\n"); - WLOG("line option or set it in your device's clock initialization routine, such as with:\n"); - WLOG(" TPI->ACPR = HAL_RCC_GetHCLKFreq() / %d - 1;\n", trace_frequency); +static bool enable_trace(stlink_t *stlink, const st_settings_t *settings, + uint32_t trace_frequency) { + + if (stlink_force_debug(stlink)) { + ELOG("Unable to debug device\n"); + if (!settings->force) + return false; + } + + if (settings->reset_board && stlink_reset(stlink, RESET_AUTO)) { + ELOG("Unable to reset device\n"); + if (!settings->force) + return false; + } + + stlink_write_debug32(stlink, STLINK_REG_DHCSR, + STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN | + STLINK_REG_DHCSR_C_HALT); + stlink_write_debug32(stlink, STLINK_REG_DEMCR, STLINK_REG_DEMCR_TRCENA); + stlink_write_debug32(stlink, STLINK_REG_CM3_FP_CTRL, + STLINK_REG_CM3_FP_CTRL_KEY); + stlink_write_debug32(stlink, STLINK_REG_DWT_FUNCTION0, 0); + stlink_write_debug32(stlink, STLINK_REG_DWT_FUNCTION1, 0); + stlink_write_debug32(stlink, STLINK_REG_DWT_FUNCTION2, 0); + stlink_write_debug32(stlink, STLINK_REG_DWT_FUNCTION3, 0); + stlink_write_debug32(stlink, STLINK_REG_DWT_CTRL, 0); + stlink_write_debug32( + stlink, STLINK_REG_DBGMCU_CR, + STLINK_REG_DBGMCU_CR_DBG_SLEEP | STLINK_REG_DBGMCU_CR_DBG_STOP | + STLINK_REG_DBGMCU_CR_DBG_STANDBY | STLINK_REG_DBGMCU_CR_TRACE_IOEN | + STLINK_REG_DBGMCU_CR_TRACE_MODE_ASYNC); + + if (stlink_trace_enable(stlink, trace_frequency)) { + ELOG("Unable to turn on tracing in stlink\n"); + if (!settings->force) + return false; + } + + stlink_write_debug32(stlink, STLINK_REG_TPI_CSPSR, + STLINK_REG_TPI_CSPSR_PORT_SIZE_1); + + if (settings->core_frequency) { + uint32_t prescaler = settings->core_frequency / trace_frequency - 1; + if (prescaler > STLINK_REG_TPI_ACPR_MAX) { + ELOG("Trace frequency prescaler %d out of range. Try setting a faster " + "trace frequency.\n", + prescaler); + if (!settings->force) + return false; } - ILOG("Trace frequency set to %d Hz.\n", trace_frequency); - - return true; + stlink_write_debug32(stlink, STLINK_REG_TPI_ACPR, + prescaler); // Set TPIU_ACPR clock divisor + } + stlink_write_debug32(stlink, STLINK_REG_TPI_FFCR, + STLINK_REG_TPI_FFCR_TRIG_IN); + stlink_write_debug32(stlink, STLINK_REG_TPI_SPPR, + STLINK_REG_TPI_SPPR_SWO_NRZ); + stlink_write_debug32(stlink, STLINK_REG_ITM_LAR, STLINK_REG_ITM_LAR_KEY); + stlink_write_debug32(stlink, STLINK_REG_ITM_TCC, + 0x00000400); // Set sync counter + stlink_write_debug32(stlink, STLINK_REG_ITM_TCR, + STLINK_REG_ITM_TCR_TRACE_BUS_ID_1 | + STLINK_REG_ITM_TCR_TS_ENA | + STLINK_REG_ITM_TCR_ITM_ENA); + stlink_write_debug32(stlink, STLINK_REG_ITM_TER, + STLINK_REG_ITM_TER_PORTS_ALL); + stlink_write_debug32(stlink, STLINK_REG_ITM_TPR, + STLINK_REG_ITM_TPR_PORTS_ALL); + stlink_write_debug32(stlink, STLINK_REG_DWT_CTRL, + 4 * STLINK_REG_DWT_CTRL_NUM_COMP | + STLINK_REG_DWT_CTRL_CYC_TAP | + 0xF * STLINK_REG_DWT_CTRL_POST_INIT | + 0xF * STLINK_REG_DWT_CTRL_POST_PRESET | + STLINK_REG_DWT_CTRL_CYCCNT_ENA); + stlink_write_debug32(stlink, STLINK_REG_DEMCR, STLINK_REG_DEMCR_TRCENA); + + uint32_t prescaler; + stlink_read_debug32(stlink, STLINK_REG_TPI_ACPR_MAX, &prescaler); + if (prescaler) { + uint32_t system_clock_speed = (prescaler + 1) * trace_frequency; + uint32_t system_clock_speed_mhz = (system_clock_speed + 500000) / 1000000; + ILOG("Trace Port Interface configured to expect a %d MHz system clock.\n", + system_clock_speed_mhz); + } else { + WLOG("Trace Port Interface not configured. Specify the system clock with " + "a --clock=XX command\n"); + WLOG("line option or set it in your device's clock initialization routine, " + "such as with:\n"); + WLOG(" TPI->ACPR = HAL_RCC_GetHCLKFreq() / %d - 1;\n", trace_frequency); + } + ILOG("Trace frequency set to %d Hz.\n", trace_frequency); + + return true; } -static trace_state update_trace_idle(st_trace_t* trace, uint8_t c) { - // Handle a trace byte when we are in the idle state. - - if (TRACE_OP_IS_TARGET_SOURCE(c)) { - return TRACE_STATE_TARGET_SOURCE; - } - - if (TRACE_OP_IS_SOURCE(c)) { - uint8_t size = TRACE_OP_GET_SOURCE_SIZE(c); - if (TRACE_OP_IS_SW_SOURCE(c)) { - uint8_t addr = TRACE_OP_GET_SW_SOURCE_ADDR(c); - if (!(trace->unknown_sources & (1 << addr))) - WLOG("Unsupported source 0x%x size %d\n", addr, size); - trace->unknown_sources |= (1 << addr); - } - if (size == 1) return TRACE_STATE_SKIP_1; - if (size == 2) return TRACE_STATE_SKIP_2; - if (size == 3) return TRACE_STATE_SKIP_4; - } - - if (TRACE_OP_IS_LOCAL_TIME(c) || TRACE_OP_IS_GLOBAL_TIME(c)) { - trace->count_time_packets++; - return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME : TRACE_STATE_IDLE; - } - - if (TRACE_OP_IS_EXTENSION(c)) { - return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME : TRACE_STATE_IDLE; - } - - if (TRACE_OP_IS_OVERFLOW(c)) { - trace->count_hw_overflow++; - } - - if (!(trace->unknown_opcodes[c / 8] & (1 << c % 8))) - WLOG("Unknown opcode 0x%02x\n", c); - trace->unknown_opcodes[c / 8] |= (1 << c % 8); - - trace->count_error++; - return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME : TRACE_STATE_IDLE; +static trace_state update_trace_idle(st_trace_t *trace, uint8_t c) { + // Handle a trace byte when we are in the idle state. + + if (TRACE_OP_IS_TARGET_SOURCE(c)) { + return TRACE_STATE_TARGET_SOURCE; + } + + if (TRACE_OP_IS_SOURCE(c)) { + uint8_t size = TRACE_OP_GET_SOURCE_SIZE(c); + if (TRACE_OP_IS_SW_SOURCE(c)) { + uint8_t addr = TRACE_OP_GET_SW_SOURCE_ADDR(c); + if (!(trace->unknown_sources & (1 << addr))) + WLOG("Unsupported source 0x%x size %d\n", addr, size); + trace->unknown_sources |= (1 << addr); + } + if (size == 1) + return TRACE_STATE_SKIP_1; + if (size == 2) + return TRACE_STATE_SKIP_2; + if (size == 3) + return TRACE_STATE_SKIP_4; + } + + if (TRACE_OP_IS_LOCAL_TIME(c) || TRACE_OP_IS_GLOBAL_TIME(c)) { + trace->count_time_packets++; + return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME + : TRACE_STATE_IDLE; + } + + if (TRACE_OP_IS_EXTENSION(c)) { + return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME + : TRACE_STATE_IDLE; + } + + if (TRACE_OP_IS_OVERFLOW(c)) { + trace->count_hw_overflow++; + } + + if (!(trace->unknown_opcodes[c / 8] & (1 << c % 8))) + WLOG("Unknown opcode 0x%02x\n", c); + trace->unknown_opcodes[c / 8] |= (1 << c % 8); + + trace->count_error++; + return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME + : TRACE_STATE_IDLE; } -static trace_state update_trace(st_trace_t* trace, uint8_t c) { - trace->count_raw_bytes++; +static trace_state update_trace(st_trace_t *trace, uint8_t c) { + trace->count_raw_bytes++; - // Parse the input using a state machine. + // Parse the input using a state machine. - if (trace->state == TRACE_STATE_UNKNOWN) { - if (TRACE_OP_IS_TARGET_SOURCE(c) || TRACE_OP_IS_LOCAL_TIME(c) || TRACE_OP_IS_GLOBAL_TIME(c)) - trace->state = TRACE_STATE_IDLE; - } + if (trace->state == TRACE_STATE_UNKNOWN) { + if (TRACE_OP_IS_TARGET_SOURCE(c) || TRACE_OP_IS_LOCAL_TIME(c) || + TRACE_OP_IS_GLOBAL_TIME(c)) + trace->state = TRACE_STATE_IDLE; + } - switch (trace->state) - { - case TRACE_STATE_IDLE: - return update_trace_idle(trace, c); + switch (trace->state) { + case TRACE_STATE_IDLE: + return update_trace_idle(trace, c); - case TRACE_STATE_TARGET_SOURCE: - putchar(c); - if (c == '\n') - fflush(stdout); - trace->count_target_data++; - return TRACE_STATE_IDLE; + case TRACE_STATE_TARGET_SOURCE: + putchar(c); + if (c == '\n') + fflush(stdout); + trace->count_target_data++; + return TRACE_STATE_IDLE; - case TRACE_STATE_SKIP_FRAME: - return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME : TRACE_STATE_IDLE; + case TRACE_STATE_SKIP_FRAME: + return TRACE_OP_GET_CONTINUATION(c) ? TRACE_STATE_SKIP_FRAME + : TRACE_STATE_IDLE; - case TRACE_STATE_SKIP_4: - return TRACE_STATE_SKIP_3; + case TRACE_STATE_SKIP_4: + return TRACE_STATE_SKIP_3; - case TRACE_STATE_SKIP_3: - return TRACE_STATE_SKIP_2; + case TRACE_STATE_SKIP_3: + return TRACE_STATE_SKIP_2; - case TRACE_STATE_SKIP_2: - return TRACE_STATE_SKIP_1; + case TRACE_STATE_SKIP_2: + return TRACE_STATE_SKIP_1; - case TRACE_STATE_SKIP_1: - return TRACE_STATE_IDLE; + case TRACE_STATE_SKIP_1: + return TRACE_STATE_IDLE; - case TRACE_STATE_UNKNOWN: - return TRACE_STATE_UNKNOWN; + case TRACE_STATE_UNKNOWN: + return TRACE_STATE_UNKNOWN; - default: - ELOG("Invalid state %d. This should never happen\n", trace->state); - return TRACE_STATE_IDLE; - } + default: + ELOG("Invalid state %d. This should never happen\n", trace->state); + return TRACE_STATE_IDLE; + } } -static bool read_trace(stlink_t* stlink, st_trace_t* trace) { - uint8_t buffer[STLINK_TRACE_BUF_LEN]; - int length = stlink_trace_read(stlink, buffer, sizeof(buffer)); - - if (length < 0) { - ELOG("Error reading trace (%d)\n", length); - return false; - } - - if (length == 0) { - usleep(100); - return true; - } - - if (length == sizeof(buffer)) { - if (trace->count_sw_overflow++) - DLOG("Buffer overflow.\n"); - else - WLOG("Buffer overflow. Try using a slower trace frequency.\n"); - trace->state = TRACE_STATE_UNKNOWN; - } +static bool read_trace(stlink_t *stlink, st_trace_t *trace) { + uint8_t buffer[STLINK_TRACE_BUF_LEN]; + int length = stlink_trace_read(stlink, buffer, sizeof(buffer)); - for (int i = 0; i < length; i++) { - trace->state = update_trace(trace, buffer[i]); - } + if (length < 0) { + ELOG("Error reading trace (%d)\n", length); + return false; + } + if (length == 0) { + usleep(100); return true; -} - -static void check_for_configuration_error(stlink_t* stlink, st_trace_t* trace, uint32_t trace_frequency) { - // Only check configuration one time after the first 10 seconds of running. - time_t elapsed_time_s = time(NULL) - trace->start_time; - if (trace->configuration_checked || elapsed_time_s < 10) { - return; - } - trace->configuration_checked = true; + } - // Simple huristic to determine if we are configured poorly. - bool error_no_data = (trace->count_raw_bytes < 100); - bool error_low_data = (trace->count_time_packets < 10 && trace->count_target_data < 1000); - bool error_bad_data = (trace->count_error > 1 || trace->unknown_sources > 0); - bool error_dropped_data = (trace->count_sw_overflow > 0); + if (length == sizeof(buffer)) { + if (trace->count_sw_overflow++) + DLOG("Buffer overflow.\n"); + else + WLOG("Buffer overflow. Try using a slower trace frequency.\n"); + trace->state = TRACE_STATE_UNKNOWN; + } - if (!error_no_data && !error_low_data && !error_bad_data && !error_dropped_data) - return; - - WLOG("****\n"); - WLOG("We do not appear to be retrieving data from the stlink correctly.\n"); - - if (error_dropped_data) { - WLOG("Try setting a slower trace frequency with the --trace=%d command line option.\n", trace_frequency / 2); - } + for (int i = 0; i < length; i++) { + trace->state = update_trace(trace, buffer[i]); + } - if (error_no_data || error_low_data || error_bad_data) { - uint32_t prescaler; - stlink_read_debug32(stlink, STLINK_REG_TPI_ACPR, &prescaler); - if (prescaler) { - uint32_t system_clock_speed = (prescaler + 1) * trace_frequency; - uint32_t system_clock_speed_mhz = (system_clock_speed + 500000) / 1000000; - WLOG("Verify the system clock is running at %d MHz.\n", system_clock_speed_mhz); - } - WLOG("Try specifying the system clock with the --clock=XX command line option.\n"); - WLOG("Try setting the trace speed in your device's clock initialization routine:\n"); - WLOG(" TPI->ACPR = HAL_RCC_GetHCLKFreq() / %d - 1;\n", trace_frequency); - } + return true; +} - WLOG("Diagnostic Information:\n"); - WLOG("Raw Bytes: %d\n", trace->count_raw_bytes); - WLOG("Target Data: %d\n", trace->count_target_data); - WLOG("Time Packets: %d\n", trace->count_time_packets); - WLOG("Hardware Overflow Count: %d\n", trace->count_hw_overflow); - WLOG("Software Overflow Count: %d\n", trace->count_sw_overflow); - WLOG("Errors: %d\n", trace->count_error); - - char buffer[1024]; - memset(buffer, 0, sizeof(buffer)); - uint32_t offset = 0; - for (uint32_t i = 0; i <= 0xFF; i++) - if (trace->unknown_opcodes[i / 8] & (1 << i % 8)) - offset += snprintf(buffer + offset, sizeof(buffer) - offset, "%02x, ", i); - WLOG("Unknown Opcodes: %s\n", buffer); - - memset(buffer, 0, sizeof(buffer)); - offset = 0; - for (uint32_t i = 0; i < 32; i++) - if (trace->unknown_sources & (1 << i)) - offset += snprintf(buffer + offset, sizeof(buffer) - offset, "%d, ", i); - WLOG("Unknown Sources: %s\n", buffer); - - WLOG("Chip ID: 0x%04x\n", stlink->chip_id); - WLOG("****\n"); +static void check_for_configuration_error(stlink_t *stlink, st_trace_t *trace, + uint32_t trace_frequency) { + // Only check configuration one time after the first 10 seconds of running. + time_t elapsed_time_s = time(NULL) - trace->start_time; + if (trace->configuration_checked || elapsed_time_s < 10) { + return; + } + trace->configuration_checked = true; + + // Simple huristic to determine if we are configured poorly. + bool error_no_data = (trace->count_raw_bytes < 100); + bool error_low_data = + (trace->count_time_packets < 10 && trace->count_target_data < 1000); + bool error_bad_data = (trace->count_error > 1 || trace->unknown_sources > 0); + bool error_dropped_data = (trace->count_sw_overflow > 0); + + if (!error_no_data && !error_low_data && !error_bad_data && + !error_dropped_data) + return; + + WLOG("****\n"); + WLOG("We do not appear to be retrieving data from the stlink correctly.\n"); + + if (error_dropped_data) { + WLOG("Try setting a slower trace frequency with the --trace=%d command " + "line option.\n", + trace_frequency / 2); + } + + if (error_no_data || error_low_data || error_bad_data) { + uint32_t prescaler; + stlink_read_debug32(stlink, STLINK_REG_TPI_ACPR, &prescaler); + if (prescaler) { + uint32_t system_clock_speed = (prescaler + 1) * trace_frequency; + uint32_t system_clock_speed_mhz = (system_clock_speed + 500000) / 1000000; + WLOG("Verify the system clock is running at %d MHz.\n", + system_clock_speed_mhz); + } + WLOG("Try specifying the system clock with the --clock=XX command line " + "option.\n"); + WLOG("Try setting the trace speed in your device's clock initialization " + "routine:\n"); + WLOG(" TPI->ACPR = HAL_RCC_GetHCLKFreq() / %d - 1;\n", trace_frequency); + } + + WLOG("Diagnostic Information:\n"); + WLOG("Raw Bytes: %d\n", trace->count_raw_bytes); + WLOG("Target Data: %d\n", trace->count_target_data); + WLOG("Time Packets: %d\n", trace->count_time_packets); + WLOG("Hardware Overflow Count: %d\n", trace->count_hw_overflow); + WLOG("Software Overflow Count: %d\n", trace->count_sw_overflow); + WLOG("Errors: %d\n", trace->count_error); + + char buffer[1024]; + memset(buffer, 0, sizeof(buffer)); + uint32_t offset = 0; + for (uint32_t i = 0; i <= 0xFF; i++) + if (trace->unknown_opcodes[i / 8] & (1 << i % 8)) { + uint32_t n = + snprintf(buffer + offset, sizeof(buffer) - offset, "%02x, ", i); + if (n >= sizeof(buffer) - offset) { + break; + } + offset += n; + } + WLOG("Unknown Opcodes: %s\n", buffer); + + memset(buffer, 0, sizeof(buffer)); + offset = 0; + for (uint32_t i = 0; i < 32; i++) + if (trace->unknown_sources & (1 << i)) { + uint32_t n = + snprintf(buffer + offset, sizeof(buffer) - offset, "%d, ", i); + if (n >= sizeof(buffer) - offset) { + break; + } + offset += n; + } + WLOG("Unknown Sources: %s\n", buffer); + + WLOG("Chip ID: 0x%04x\n", stlink->chip_id); + WLOG("****\n"); } -int main(int argc, char** argv) -{ +int main(int argc, char **argv) { #if defined(_WIN32) - SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE); + SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE); #else - signal(SIGINT, &abort_trace); - signal(SIGTERM, &abort_trace); - signal(SIGSEGV, &abort_trace); - signal(SIGPIPE, &abort_trace); + signal(SIGINT, &abort_trace); + signal(SIGTERM, &abort_trace); + signal(SIGSEGV, &abort_trace); + signal(SIGPIPE, &abort_trace); #endif + st_settings_t settings; + if (!parse_options(argc, argv, &settings)) { + usage(); + return APP_RESULT_INVALID_PARAMS; + } + + DLOG("show_help = %s\n", settings.show_help ? "true" : "false"); + DLOG("show_version = %s\n", settings.show_version ? "true" : "false"); + DLOG("logging_level = %d\n", settings.logging_level); + DLOG("core_frequency = %d Hz\n", settings.core_frequency); + DLOG("trace_frequency = %d Hz\n", settings.trace_frequency); + DLOG("reset_board = %s\n", settings.reset_board ? "true" : "false"); + DLOG("force = %s\n", settings.force ? "true" : "false"); + DLOG("serial_number = %s\n", + settings.serial_number ? settings.serial_number : "any"); + + if (settings.show_help) { + usage(); + return APP_RESULT_SUCCESS; + } - st_settings_t settings; - if (!parse_options(argc, argv, &settings)) { - usage(); - return APP_RESULT_INVALID_PARAMS; - } - - DLOG("show_help = %s\n", settings.show_help ? "true" : "false"); - DLOG("show_version = %s\n", settings.show_version ? "true" : "false"); - DLOG("logging_level = %d\n", settings.logging_level); - DLOG("core_frequency = %d Hz\n", settings.core_frequency); - DLOG("trace_frequency = %d Hz\n", settings.trace_frequency); - DLOG("reset_board = %s\n", settings.reset_board ? "true" : "false"); - DLOG("force = %s\n", settings.force ? "true" : "false"); - DLOG("serial_number = %s\n", settings.serial_number ? settings.serial_number : "any"); - - if (settings.show_help) { - usage(); - return APP_RESULT_SUCCESS; - } - - if (settings.show_version) { - printf("v%s\n", STLINK_VERSION); - return APP_RESULT_SUCCESS; - } - - stlink_t* stlink = stlink_connect(&settings); - if (!stlink) { - ELOG("Unable to locate an stlink\n"); - return APP_RESULT_STLINK_NOT_FOUND; - } - - stlink->verbose = settings.logging_level; - - if (stlink->chip_id == STLINK_CHIPID_UNKNOWN) { - ELOG("Your stlink is not connected to a device\n"); - if (!settings.force) - return APP_RESULT_STLINK_MISSING_DEVICE; - } - - if (!(stlink->version.flags & STLINK_F_HAS_TRACE)) { - ELOG("Your stlink does not support tracing\n"); - if (!settings.force) - return APP_RESULT_STLINK_UNSUPPORTED_LINK; - } - - if (!(stlink->chip_flags & CHIP_F_HAS_SWO_TRACING)) { - const struct stlink_chipid_params *params = stlink_chipid_get_params(stlink->chip_id); - ELOG("We do not support SWO output for device '%s'\n", params->description); - if (!settings.force) - return APP_RESULT_STLINK_UNSUPPORTED_DEVICE; - } - - uint32_t trace_frequency = settings.trace_frequency; - if (!trace_frequency) - trace_frequency = STLINK_DEFAULT_TRACE_FREQUENCY; - if (trace_frequency > stlink->max_trace_freq) { - ELOG("Invalid trace frequency %d (max %d)\n", trace_frequency, stlink->max_trace_freq); - if (!settings.force) - return APP_RESULT_UNSUPPORTED_TRACE_FREQUENCY; - } - - if (!enable_trace(stlink, &settings, trace_frequency)) { - ELOG("Unable to enable trace mode\n"); - if (!settings.force) - return APP_RESULT_STLINK_STATE_ERROR; - } - - ILOG("Reading Trace\n"); - st_trace_t trace; - memset(&trace, 0, sizeof(trace)); - trace.start_time = time(NULL); - - if (stlink_run(stlink, RUN_NORMAL)) { - ELOG("Unable to run device\n"); - if (!settings.force) - return APP_RESULT_STLINK_STATE_ERROR; - } - - while (!g_abort_trace && read_trace(stlink, &trace)) { - check_for_configuration_error(stlink, &trace, trace_frequency); - } - - stlink_trace_disable(stlink); - stlink_close(stlink); - + if (settings.show_version) { + printf("v%s\n", STLINK_VERSION); return APP_RESULT_SUCCESS; + } + + stlink_t *stlink = stlink_connect(&settings); + if (!stlink) { + ELOG("Unable to locate an stlink\n"); + return APP_RESULT_STLINK_NOT_FOUND; + } + + stlink->verbose = settings.logging_level; + + if (stlink->chip_id == STLINK_CHIPID_UNKNOWN) { + ELOG("Your stlink is not connected to a device\n"); + if (!settings.force) + return APP_RESULT_STLINK_MISSING_DEVICE; + } + + if (!(stlink->version.flags & STLINK_F_HAS_TRACE)) { + ELOG("Your stlink does not support tracing\n"); + if (!settings.force) + return APP_RESULT_STLINK_UNSUPPORTED_LINK; + } + + if (!(stlink->chip_flags & CHIP_F_HAS_SWO_TRACING)) { + const struct stlink_chipid_params *params = + stlink_chipid_get_params(stlink->chip_id); + ELOG("We do not support SWO output for device '%s'\n", params->description); + if (!settings.force) + return APP_RESULT_STLINK_UNSUPPORTED_DEVICE; + } + + uint32_t trace_frequency = settings.trace_frequency; + if (!trace_frequency) + trace_frequency = STLINK_DEFAULT_TRACE_FREQUENCY; + if (trace_frequency > stlink->max_trace_freq) { + ELOG("Invalid trace frequency %d (max %d)\n", trace_frequency, + stlink->max_trace_freq); + if (!settings.force) + return APP_RESULT_UNSUPPORTED_TRACE_FREQUENCY; + } + + if (!enable_trace(stlink, &settings, trace_frequency)) { + ELOG("Unable to enable trace mode\n"); + if (!settings.force) + return APP_RESULT_STLINK_STATE_ERROR; + } + + ILOG("Reading Trace\n"); + st_trace_t trace; + memset(&trace, 0, sizeof(trace)); + trace.start_time = time(NULL); + + if (stlink_run(stlink, RUN_NORMAL)) { + ELOG("Unable to run device\n"); + if (!settings.force) + return APP_RESULT_STLINK_STATE_ERROR; + } + + while (!g_abort_trace && read_trace(stlink, &trace)) { + check_for_configuration_error(stlink, &trace, trace_frequency); + } + + stlink_trace_disable(stlink); + stlink_close(stlink); + + return APP_RESULT_SUCCESS; } diff --git a/src/stlink-lib/logging.c b/src/stlink-lib/logging.c index ce0a2baab..87978230d 100644 --- a/src/stlink-lib/logging.c +++ b/src/stlink-lib/logging.c @@ -1,12 +1,13 @@ /* * UglyLogging * - * Slow, yet another wheel reinvented, but enough to make the rest of our code pretty enough. + * Slow, yet another wheel reinvented, but enough to make the rest of our code + * pretty enough. */ +#include #include #include #include -#include #include #include "logging.h" @@ -14,77 +15,89 @@ static int max_level = UDEBUG; int ugly_init(int maximum_threshold) { - max_level = maximum_threshold; - return(0); + max_level = maximum_threshold; + return (0); } int ugly_log(int level, const char *tag, const char *format, ...) { - if (level > max_level) { - return(0); - } + if (level > max_level) { + return (0); + } - fflush(stdout); // flush to maintain order of streams + fflush(stdout); // flush to maintain order of streams - va_list args; - va_start(args, format); - time_t mytt = time(NULL); - struct tm *tt; - tt = localtime(&mytt); - fprintf(stderr, "%d-%02d-%02dT%02d:%02d:%02d ", tt->tm_year + 1900, tt->tm_mon + 1, - tt->tm_mday, tt->tm_hour, tt->tm_min, tt->tm_sec); + va_list args; + va_start(args, format); + time_t mytt = time(NULL); + struct tm *tt; + tt = localtime(&mytt); + fprintf(stderr, "%d-%02d-%02dT%02d:%02d:%02d ", tt->tm_year + 1900, + tt->tm_mon + 1, tt->tm_mday, tt->tm_hour, tt->tm_min, tt->tm_sec); - switch (level) { - case UDEBUG: - fprintf(stderr, "DEBUG %s: ", tag); - break; - case UINFO: - fprintf(stderr, "INFO %s: ", tag); - break; - case UWARN: - fprintf(stderr, "WARN %s: ", tag); - break; - case UERROR: - fprintf(stderr, "ERROR %s: ", tag); - break; - default: - fprintf(stderr, "%d %s: ", level, tag); - break; - } + switch (level) { + case UDEBUG: + fprintf(stderr, "DEBUG %s: ", tag); + break; + case UINFO: + fprintf(stderr, "INFO %s: ", tag); + break; + case UWARN: + fprintf(stderr, "WARN %s: ", tag); + break; + case UERROR: + fprintf(stderr, "ERROR %s: ", tag); + break; + default: + fprintf(stderr, "%d %s: ", level, tag); + break; + } - vfprintf(stderr, format, args); - fflush(stderr); - va_end(args); - return(1); + vfprintf(stderr, format, args); + fflush(stderr); + va_end(args); + return (1); } /* * Log message levels. - * - LIBUSB_LOG_LEVEL_NONE (0) : no messages ever printed by the library (default) + * - LIBUSB_LOG_LEVEL_NONE (0) : no messages ever printed by the library + * (default) * - LIBUSB_LOG_LEVEL_ERROR (1) : error messages are printed to stderr - * - LIBUSB_LOG_LEVEL_WARNING (2) : warning and error messages are printed to stderr - * - LIBUSB_LOG_LEVEL_INFO (3) : informational messages are printed to stderr - * - LIBUSB_LOG_LEVEL_DEBUG (4) : debug and informational messages are printed to stderr + * - LIBUSB_LOG_LEVEL_WARNING (2) : warning and error messages are printed to + * stderr + * - LIBUSB_LOG_LEVEL_INFO (3) : informational messages are printed to + * stderr + * - LIBUSB_LOG_LEVEL_DEBUG (4) : debug and informational messages are + * printed to stderr */ int ugly_libusb_log_level(enum ugly_loglevel v) { #ifdef __FreeBSD__ - // FreeBSD includes its own reimplementation of libusb. - // Its libusb_set_debug() function expects a lib_debug_level - // instead of a lib_log_level and is verbose enough to drown out - // all other output. - switch (v) { - case UDEBUG: return (3); // LIBUSB_DEBUG_FUNCTION + LIBUSB_DEBUG_TRANSFER - case UINFO: return (1); // LIBUSB_DEBUG_FUNCTION only - case UWARN: return (0); // LIBUSB_DEBUG_NO - case UERROR: return (0); // LIBUSB_DEBUG_NO - } - return (0); + // FreeBSD includes its own reimplementation of libusb. + // Its libusb_set_debug() function expects a lib_debug_level + // instead of a lib_log_level and is verbose enough to drown out + // all other output. + switch (v) { + case UDEBUG: + return (3); // LIBUSB_DEBUG_FUNCTION + LIBUSB_DEBUG_TRANSFER + case UINFO: + return (1); // LIBUSB_DEBUG_FUNCTION only + case UWARN: + return (0); // LIBUSB_DEBUG_NO + case UERROR: + return (0); // LIBUSB_DEBUG_NO + } + return (0); #else - switch (v) { - case UDEBUG: return (4); - case UINFO: return (3); - case UWARN: return (2); - case UERROR: return (1); - } + switch (v) { + case UDEBUG: + return (4); + case UINFO: + return (3); + case UWARN: return (2); + case UERROR: + return (1); + } + return (2); #endif } From 6993491f90b15581668088a6e522b8fb9a3bb84e Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Wed, 21 Apr 2021 00:00:33 +0200 Subject: [PATCH 63/65] Revert "Updated libusb to v1.0.24" This reverts commit 89a495d169a15f42d8cfd1a68c6738c984d052f8. --- .gitignore | 1 - .travis.sh | 18 +++++++-------- .travis.yml | 24 ++++++++++---------- cmake/modules/Findlibusb.cmake | 6 ++--- cmake/packaging/windows/generate_binaries.sh | 24 ++++++++++---------- 5 files changed, 36 insertions(+), 37 deletions(-) diff --git a/.gitignore b/.gitignore index 82c1195e4..a07eed9ca 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ build build-mingw -build-mingw-* .project .cmake/ diff --git a/.travis.sh b/.travis.sh index 58cea5746..e45cd3609 100755 --- a/.travis.sh +++ b/.travis.sh @@ -8,20 +8,20 @@ echo "----" echo "WORK DIR:$DIR" DIR=$PWD -if [ "$TRAVIS_JOB_NAME" == "linux-mingw-32" ]; then +if [ "$TRAVIS_JOB_NAME" == "linux-mingw-64" ]; then + echo "--> Building for Windows (x86-64) ..." + mkdir -p build-mingw && cd build-mingw-64 + cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ + -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR + make && rm -rf build-mingw-64 && cd - + +elif [ "$TRAVIS_JOB_NAME" == "linux-mingw-32" ]; then echo "--> Building for Windows (i686) ..." - mkdir -p build-mingw-32 && cd build-mingw-32 + mkdir -p build-mingw && cd build-mingw-32 cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR make && rm -rf build-mingw-32 && cd - -# elif [ "$TRAVIS_JOB_NAME" == "linux-mingw-64" ]; then -# echo "--> Building for Windows (x86-64) ..." -# mkdir -p build-mingw-64 && cd build-mingw-64 -# cmake -DCMAKE_SYSTEM_NAME=Windows -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ -# -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake -DCMAKE_INSTALL_PREFIX=$PWD/install $DIR -# make && rm -rf build-mingw-64 && cd - - elif [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq || true diff --git a/.travis.yml b/.travis.yml index 307c0bfa0..a733019a1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,8 +6,8 @@ jobs: - os: linux dist: focal - env: BADGE=linux-mingw-32 - name: linux-mingw-32 + env: BADGE=linux-mingw-64 + name: linux-mingw compiler: gcc-10 addons: apt: @@ -15,16 +15,16 @@ jobs: packages: ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] - # - os: linux - # dist: focal - # env: BADGE=linux-mingw-64 - # name: linux-mingw-64 - # compiler: gcc-10 - # addons: - # apt: - # sources: ["ubuntu-toolchain-r-test"] - # packages: - # ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] + - os: linux + dist: focal + env: BADGE=linux-mingw-32 + name: linux-mingw + compiler: gcc-10 + addons: + apt: + sources: ["ubuntu-toolchain-r-test"] + packages: + ["gcc-10", "libusb-1.0.0-dev", "libgtk-3-dev", "rpm", "mingw-w64"] script: - git fetch --tags diff --git a/cmake/modules/Findlibusb.cmake b/cmake/modules/Findlibusb.cmake index 99f4d56ec..257c682ce 100644 --- a/cmake/modules/Findlibusb.cmake +++ b/cmake/modules/Findlibusb.cmake @@ -77,7 +77,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to if (NOT LIBUSB_FOUND) # Preparations for installing libusb library - set(LIBUSB_WIN_VERSION 1.0.24) # set libusb version + set(LIBUSB_WIN_VERSION 1.0.23) # set libusb version set(LIBUSB_WIN_ARCHIVE libusb-${LIBUSB_WIN_VERSION}.7z) if (WIN32 AND NOT EXISTS "/etc/debian_version") # ... on native Windows systems set(LIBUSB_WIN_ARCHIVE_PATH ${CMAKE_BINARY_DIR}/${LIBUSB_WIN_ARCHIVE}) @@ -94,7 +94,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to message(STATUS "downloading libusb ${LIBUSB_WIN_VERSION}") file(DOWNLOAD https://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-${LIBUSB_WIN_VERSION}/libusb-${LIBUSB_WIN_VERSION}.7z/download - ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 5c944b1c8aa9d43e026a94302d0f8ac4 + ${LIBUSB_WIN_ARCHIVE_PATH} EXPECTED_MD5 cf3d38d2ff053ef343d10c0b8b0950c2 ) endif () @@ -128,7 +128,7 @@ elseif (WIN32 OR (EXISTS "/etc/debian_version" AND MINGW)) # Windows or MinGW-to set(LIBUSB_NAME libusb-1.0.lib) find_library( LIBUSB_LIBRARY NAMES ${LIBUSB_NAME} - HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/**/MS${ARCH}/dll + HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS${ARCH}/dll NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH ) diff --git a/cmake/packaging/windows/generate_binaries.sh b/cmake/packaging/windows/generate_binaries.sh index 5616ecb38..bf2453d10 100644 --- a/cmake/packaging/windows/generate_binaries.sh +++ b/cmake/packaging/windows/generate_binaries.sh @@ -5,6 +5,18 @@ # Install this cross-compiler toolchain: #sudo apt-get install mingw-w64 +# x86_64 +mkdir build-mingw-64 +cd build-mingw-64 +cmake -DCMAKE_SYSTEM_NAME=Windows \ + -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ + -DCMAKE_TOOLCHAIN_FILE=./../cmake/modules/set_toolchain.cmake .. +make package +cp dist/*.zip ../build/Release/dist +make clean +cd .. +rm -rf build-mingw-64 + # i686 mkdir build-mingw-32 cd build-mingw-32 @@ -16,15 +28,3 @@ cp dist/*.zip ../build/Release/dist make clean cd .. rm -rf build-mingw-32 - -# x86_64 -# mkdir build-mingw-64 -# cd build-mingw-64 -# cmake -DCMAKE_SYSTEM_NAME=Windows \ -# -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ -# -DCMAKE_TOOLCHAIN_FILE=./../cmake/modules/set_toolchain.cmake .. -# make package -# cp dist/*.zip ../build/Release/dist -# make clean -# cd .. -# rm -rf build-mingw-64 From c115ab2e0fcc3103e2ceb848c18b12641cfe7d0e Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 24 Apr 2021 14:16:29 +0200 Subject: [PATCH 64/65] General Project Update - Formatting fixes - Commented CI build setting for Ubuntu 16.04 - Updated CHANGELOG.md --- .github/workflows/c-cpp.yml | 210 +++++++++++---------- CHANGELOG.md | 4 +- inc/stm32.h | 31 ++-- src/stlink-lib/chipid.c | 353 ++++++++++++++++++++---------------- 4 files changed, 323 insertions(+), 275 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 97f48d88d..ef9e5f172 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -7,98 +7,97 @@ on: branches: [master, develop, testing] jobs: + # Linux -# Linux - - job_linux_16_04_64_gcc: - name: ubuntu-16.04 gcc - runs-on: ubuntu-16.04 - steps: - - uses: actions/checkout@v2 - - name: Install dependencies - run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm - - name: make debug - run: sudo make clean && make debug - - name: make test - run: sudo make clean && make test - - name: make release - run: sudo make clean && make release - - name: sudo make install - run: sudo make clean && sudo make install - - name: sudo make package - run: sudo make package - - name: sudo make uninstall - run: sudo make uninstall && sudo make clean + # job_linux_16_04_64_gcc: + # name: ubuntu-16.04 gcc + # runs-on: ubuntu-16.04 + # steps: + # - uses: actions/checkout@v2 + # - name: Install dependencies + # run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm + # - name: make debug + # run: sudo make clean && make debug + # - name: make test + # run: sudo make clean && make test + # - name: make release + # run: sudo make clean && make release + # - name: sudo make install + # run: sudo make clean && sudo make install + # - name: sudo make package + # run: sudo make package + # - name: sudo make uninstall + # run: sudo make uninstall && sudo make clean - job_linux_16_04_32_gcc: - name: ubuntu-16.04 gcc 32-bit - runs-on: ubuntu-16.04 - steps: - - uses: actions/checkout@v2 - - name: Install dependencies - run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm - - name: Set compiler flags - run: | - CFLAGS="$CFLAGS -m32" - CXXFLAGS="$CXXFLAGS -m32" - LDFLAGS="$LDFLAGS -m32" - - name: make debug - run: sudo make clean && make debug - - name: make test - run: sudo make clean && make test - - name: make release - run: sudo make clean && make release - - name: sudo make install - run: sudo make clean && sudo make install - - name: sudo make package - run: sudo make package - - name: sudo make uninstall - run: sudo make uninstall && sudo make clean + # job_linux_16_04_32_gcc: + # name: ubuntu-16.04 gcc 32-bit + # runs-on: ubuntu-16.04 + # steps: + # - uses: actions/checkout@v2 + # - name: Install dependencies + # run: sudo apt-get install gcc-5 libusb-1.0.0-dev libgtk-3-dev rpm + # - name: Set compiler flags + # run: | + # CFLAGS="$CFLAGS -m32" + # CXXFLAGS="$CXXFLAGS -m32" + # LDFLAGS="$LDFLAGS -m32" + # - name: make debug + # run: sudo make clean && make debug + # - name: make test + # run: sudo make clean && make test + # - name: make release + # run: sudo make clean && make release + # - name: sudo make install + # run: sudo make clean && sudo make install + # - name: sudo make package + # run: sudo make package + # - name: sudo make uninstall + # run: sudo make uninstall && sudo make clean - job_linux_16_04_64_clang: - name: ubuntu-16.04 clang - runs-on: ubuntu-16.04 - steps: - - uses: actions/checkout@v2 - - name: Install dependencies - run: sudo apt-get install clang-3.5 libusb-1.0.0-dev libgtk-3-dev rpm - - name: make debug - run: sudo make clean && make debug - - name: make test - run: sudo make clean && make test - - name: make release - run: sudo make clean && make release - - name: sudo make install - run: sudo make clean && sudo make install - - name: sudo make package - run: sudo make package - - name: sudo make uninstall - run: sudo make uninstall && sudo make clean + # job_linux_16_04_64_clang: + # name: ubuntu-16.04 clang + # runs-on: ubuntu-16.04 + # steps: + # - uses: actions/checkout@v2 + # - name: Install dependencies + # run: sudo apt-get install clang-3.5 libusb-1.0.0-dev libgtk-3-dev rpm + # - name: make debug + # run: sudo make clean && make debug + # - name: make test + # run: sudo make clean && make test + # - name: make release + # run: sudo make clean && make release + # - name: sudo make install + # run: sudo make clean && sudo make install + # - name: sudo make package + # run: sudo make package + # - name: sudo make uninstall + # run: sudo make uninstall && sudo make clean - job_linux_16_04_32_clang: - name: ubuntu-16.04 clang 32-bit - runs-on: ubuntu-16.04 - steps: - - uses: actions/checkout@v2 - - name: Install dependencies - run: sudo apt-get install clang-3.5 libusb-1.0.0-dev libgtk-3-dev rpm - - name: Set compiler flags - run: | - CFLAGS="$CFLAGS -m32" - CXXFLAGS="$CXXFLAGS -m32" - LDFLAGS="$LDFLAGS -m32" - - name: make debug - run: sudo make clean && make debug - - name: make test - run: sudo make clean && make test - - name: make release - run: sudo make clean && make release - - name: sudo make install - run: sudo make clean && sudo make install - - name: sudo make package - run: sudo make package - - name: sudo make uninstall - run: sudo make uninstall && sudo make clean + # job_linux_16_04_32_clang: + # name: ubuntu-16.04 clang 32-bit + # runs-on: ubuntu-16.04 + # steps: + # - uses: actions/checkout@v2 + # - name: Install dependencies + # run: sudo apt-get install clang-3.5 libusb-1.0.0-dev libgtk-3-dev rpm + # - name: Set compiler flags + # run: | + # CFLAGS="$CFLAGS -m32" + # CXXFLAGS="$CXXFLAGS -m32" + # LDFLAGS="$LDFLAGS -m32" + # - name: make debug + # run: sudo make clean && make debug + # - name: make test + # run: sudo make clean && make test + # - name: make release + # run: sudo make clean && make release + # - name: sudo make install + # run: sudo make clean && sudo make install + # - name: sudo make package + # run: sudo make package + # - name: sudo make uninstall + # run: sudo make uninstall && sudo make clean job_linux_18_04_64_gcc: name: ubuntu-18.04 gcc @@ -144,7 +143,7 @@ jobs: run: sudo make package - name: sudo make uninstall run: sudo make uninstall && sudo make clean - + job_linux_18_04_64_clang: name: ubuntu-18.04 clang runs-on: ubuntu-18.04 @@ -280,7 +279,7 @@ jobs: - name: sudo make uninstall run: sudo make uninstall && sudo make clean -# macOS + # macOS # job_macos_10_14_64_gcc: # name: macos-10.14 gcc @@ -411,7 +410,6 @@ jobs: run: sudo make package - name: sudo make uninstall run: sudo make uninstall && sudo make clean - # job_macos_11_gcc: # name: macos-11.0 gcc # runs-on: macos-11.0 @@ -431,7 +429,6 @@ jobs: # run: sudo make package # - name: sudo make uninstall # run: sudo make uninstall && sudo make clean - # job_macos_11_clang: # name: macos-11.0 clang # runs-on: macos-11.0 @@ -451,20 +448,19 @@ jobs: # run: sudo make package # - name: sudo make uninstall # run: sudo make uninstall && sudo make clean - # Linux MinGW cross compliation - # job_linux_20_04_cross: - # name: ubuntu-20.04 mingw64 - # runs-on: ubuntu-20.04 - # steps: - # - uses: actions/checkout@v2 - # - name: Install dependencies - # run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm mingw-w64 - # - name: Building Release for Windows (x86-64) ... - # run: sudo mkdir -p build-mingw && cd build-mingw && sudo cmake \ - # -DCMAKE_SYSTEM_NAME=Windows \ - # -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ - # -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake \ - # -DCMAKE_INSTALL_PREFIX=$PWD/install $PWD && \ - # sudo make && sudo rm -rf build-mingw && cd - +# job_linux_20_04_cross: +# name: ubuntu-20.04 mingw64 +# runs-on: ubuntu-20.04 +# steps: +# - uses: actions/checkout@v2 +# - name: Install dependencies +# run: sudo apt-get install gcc-10 libusb-1.0.0-dev libgtk-3-dev rpm mingw-w64 +# - name: Building Release for Windows (x86-64) ... +# run: sudo mkdir -p build-mingw && cd build-mingw && sudo cmake \ +# -DCMAKE_SYSTEM_NAME=Windows \ +# -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ +# -DCMAKE_TOOLCHAIN_FILE=$PWD/../cmake/modules/set_toolchain.cmake \ +# -DCMAKE_INSTALL_PREFIX=$PWD/install $PWD && \ +# sudo make && sudo rm -rf build-mingw && cd - diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ac52da73..a3e7dbafc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,7 +41,7 @@ Updates & changes: Fixes: - Flash loader rework ([#356](https://github.com/stlink-org/stlink/pull/356), [#556](https://github.com/stlink-org/stlink/pull/556), [#593](https://github.com/stlink-org/stlink/pull/593), [#597](https://github.com/stlink-org/stlink/pull/597), [#607](https://github.com/stlink-org/stlink/pull/607), [#612](https://github.com/stlink-org/stlink/pull/612), [#638](https://github.com/stlink-org/stlink/pull/638), [#661](https://github.com/stlink-org/stlink/pull/661), [#690](https://github.com/stlink-org/stlink/pull/690), [#807](https://github.com/stlink-org/stlink/pull/807), [#817](https://github.com/stlink-org/stlink/pull/817), [#818](https://github.com/stlink-org/stlink/pull/818), [#854](https://github.com/stlink-org/stlink/pull/854), [#868](https://github.com/stlink-org/stlink/pull/868), [#967](https://github.com/stlink-org/stlink/pull/967), [#979](https://github.com/stlink-org/stlink/pull/979), [#1043](https://github.com/stlink-org/stlink/pull/1043), [#1054](https://github.com/stlink-org/stlink/pull/1054), [#1092](https://github.com/stlink-org/stlink/pull/1092), [#1105](https://github.com/stlink-org/stlink/pull/1105), [#1113](https://github.com/stlink-org/stlink/pull/1113)) -- Fixed old DFU serial number for STLINK programmers ([#417](https://github.com/stlink-org/stlink/pull/417), [#494](https://github.com/stlink-org/stlink/pull/494), [#1106](https://github.com/stlink-org/stlink/pull/1106)) +- Fixed old DFU serial number for STLINK programmers ([#417](https://github.com/stlink-org/stlink/pull/417), [#494](https://github.com/stlink-org/stlink/pull/494), [#1106](https://github.com/stlink-org/stlink/pull/1106), [#1121](https://github.com/stlink-org/stlink/pull/1121)) - Use vl flashloader for all STM32F1 series ([#769](https://github.com/stlink-org/stlink/pull/769), [#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) - [regression] Changed timeout on flash write ([#787](https://github.com/stlink-org/stlink/pull/787), [#981](https://github.com/stlink-org/stlink/pull/981), [#987](https://github.com/stlink-org/stlink/pull/987)) - cmake compile failure with external `CMAKE_MODULE_PATH` set ([#962](https://github.com/stlink-org/stlink/pull/962)) @@ -165,7 +165,7 @@ Fixes: - Set static link for `libssp` (stack-smashing protection) ([#960](https://github.com/stlink-org/stlink/pull/960), [#961](https://github.com/stlink-org/stlink/pull/961)) - Fixed udev rules installing to wrong directory ([#966](https://github.com/stlink-org/stlink/pull/966)) - Fixed formatting for options display in `st-flash` & `st-info` (commits [#c783d0e](https://github.com/stlink-org/stlink/commit/c783d0e777ccc83a7a8be26a4f4d3414e0478560) and [#562cd24](https://github.com/stlink-org/stlink/commit/562cd2496e696dbd22950925866aac662d81ee5f)) -- Fixed reading of chip ID on Cortex-M0+ core ([#1125](https://github.com/stlink-org/stlink/pull/1125), [#1126](https://github.com/stlink-org/stlink/pull/1126)) +- Fixed reading of chip ID on Cortex-M0+ core ([#1125](https://github.com/stlink-org/stlink/pull/1125), [#1126](https://github.com/stlink-org/stlink/pull/1126), [#1133](https://github.com/stlink-org/stlink/pull/1133)) # v1.6.0 diff --git a/inc/stm32.h b/inc/stm32.h index 7d60ab5de..21da2f563 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -8,24 +8,31 @@ #define STM32_H /* Cortex core ids */ -#define STM32VL_CORE_ID 0x1ba01477 -#define STM32F7_CORE_ID 0x5ba02477 -#define STM32H7_CORE_ID 0x6ba02477 // STM32H7 SWD ID Code +#define STM32VL_CORE_ID 0x1ba01477 +#define STM32F7_CORE_ID 0x5ba02477 +#define STM32H7_CORE_ID 0x6ba02477 // STM32H7 SWD ID Code #define STM32H7_CORE_ID_JTAG 0x6ba00477 // STM32H7 JTAG ID Code (RM0433 pg3065) /* Constant STM32 memory map figures */ -#define STM32_FLASH_BASE ((uint32_t)0x08000000) -#define STM32_F1_FLASH_BANK2_BASE ((uint32_t)0x08080000) -#define STM32_H7_FLASH_BANK2_BASE ((uint32_t)0x08100000) -#define STM32_SRAM_BASE ((uint32_t)0x20000000) -#define STM32_G0_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) -#define STM32_G4_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800) -#define STM32_L0_CATx_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) +#define STM32_SRAM_BASE ((uint32_t)0x20000000) +#define STM32_FLASH_BASE ((uint32_t)0x08000000) +#define STM32_F1_FLASH_BANK2_BASE ((uint32_t)0x08080000) +#define STM32_H7_FLASH_BANK2_BASE ((uint32_t)0x08100000) + #define STM32_F2_OPTION_BYTES_BASE ((uint32_t)0x1FFFC000) -#define STM32_L4_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) -#define STM32_L1_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) #define STM32_F4_OPTION_BYTES_BASE ((uint32_t)0x40023C14) #define STM32_F7_OPTION_BYTES_BASE ((uint32_t)0x1FFF0000) #define STM32_H7_OPTION_BYTES_BASE ((uint32_t)0x5200201C) +#define STM32_G0_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) +#define STM32_L4_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) + +#define STM32_L0_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) +#define STM32_L1_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) + +#define STM32_F0_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800) +#define STM32_F1_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800) +#define STM32_F3_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800) +#define STM32_G4_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800) + #endif // STM32_H diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 221234bbb..187a6d957 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -7,12 +7,15 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F7XXXX, .description = "F76xxx", .flash_type = STLINK_FLASH_TYPE_F7, - .flash_size_reg = 0x1ff0f442, // section 45.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x80000, // "SRAM" byte size in hex from - .bootrom_base = 0x00200000, // ! "System memory" starting address from - .bootrom_size = 0xEDC0, // ! @todo "System memory" byte size in hex from - .option_base = STM32_F7_OPTION_BYTES_BASE, // Used for reading back the option bytes, writing uses FLASH_F7_OPTCR and FLASH_F7_OPTCR1 + .flash_size_reg = 0x1ff0f442, // section 45.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x80000, // "SRAM" byte size in hex from + .bootrom_base = 0x00200000, // ! "System memory" starting address from + .bootrom_size = 0xEDC0, // ! @todo "System memory" byte size in hex from + .option_base = + STM32_F7_OPTION_BYTES_BASE, // Used for reading back the option + // bytes, writing uses FLASH_F7_OPTCR + // and FLASH_F7_OPTCR1 .option_size = 0x20, .flags = CHIP_F_HAS_SWO_TRACING, }, @@ -21,11 +24,13 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F7, .description = "F7xx", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1ff0f442, // section 41.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x50000, // "SRAM" byte size in hex from DS Fig 18 - .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 18 - .bootrom_size = 0xEDC0, // "System memory" byte size in hex from DS Fig 18 + .flash_size_reg = 0x1ff0f442, // section 41.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x50000, // "SRAM" byte size in hex from DS Fig 18 + .bootrom_base = + 0x00100000, // "System memory" starting address from DS Fig 18 + .bootrom_size = + 0xEDC0, // "System memory" byte size in hex from DS Fig 18 .flags = CHIP_F_HAS_SWO_TRACING, }, { @@ -33,14 +38,17 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F72XXX, .description = "F72x/F73x", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1ff07a22, // section 35.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x40000, // "SRAM" byte size in hex from DS Fig 24 - .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 24 - .bootrom_size = 0xEDC0, // "System memory" byte size in hex from DS Fig 24 + .flash_size_reg = 0x1ff07a22, // section 35.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x40000, // "SRAM" byte size in hex from DS Fig 24 + .bootrom_base = + 0x00100000, // "System memory" starting address from DS Fig 24 + .bootrom_size = + 0xEDC0, // "System memory" byte size in hex from DS Fig 24 .flags = CHIP_F_HAS_SWO_TRACING, }, - { // table 2, PM0063 + { + // table 2, PM0063 .chip_id = STLINK_CHIPID_STM32_F1_MEDIUM, .description = "F1xx Medium-density", .flash_type = STLINK_FLASH_TYPE_F0, @@ -51,11 +59,12 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x800, .flags = CHIP_F_HAS_SWO_TRACING, }, - { // table 1, PM0059 + { + // table 1, PM0059 .chip_id = STLINK_CHIPID_STM32_F2, .description = "F2xx", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1fff7a22, // as in RM0033 Rev 5 + .flash_size_reg = 0x1fff7a22, // as in RM0033 Rev 5 .flash_pagesize = 0x20000, .sram_size = 0x20000, .bootrom_base = 0x1fff0000, @@ -64,7 +73,8 @@ static const struct stlink_chipid_params devices[] = { .option_size = 4, .flags = CHIP_F_HAS_SWO_TRACING, }, - { // PM0063 + { + // PM0063 .chip_id = STLINK_CHIPID_STM32_F1_LOW, .description = "F1 Low-density device", .flash_type = STLINK_FLASH_TYPE_F0, @@ -79,7 +89,7 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F4, .description = "F4xx", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // As in rm0090 since Rev 2 + .flash_size_reg = 0x1FFF7A22, // As in rm0090 since Rev 2 .flash_pagesize = 0x4000, .sram_size = 0x30000, .bootrom_base = 0x1fff0000, @@ -92,7 +102,7 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F4_DSI, .description = "F46x/F47x", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // As in rm0090 since Rev 2 + .flash_size_reg = 0x1FFF7A22, // As in rm0090 since Rev 2 .flash_pagesize = 0x4000, .sram_size = 0x40000, .bootrom_base = 0x1fff0000, @@ -103,7 +113,7 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F4_HD, .description = "F42x/F43x", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // As in rm0090 since Rev 2 + .flash_size_reg = 0x1FFF7A22, // As in rm0090 since Rev 2 .flash_pagesize = 0x4000, .sram_size = 0x40000, .bootrom_base = 0x1fff0000, @@ -224,7 +234,8 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x4800, .flags = CHIP_F_HAS_SWO_TRACING, }, - { // Low and Medium density VL have same chipid. RM0041 25.6.1 + { + // Low and Medium density VL have same chipid. RM0041 25.6.1 .chip_id = STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW, .description = "F1xx Value Line", .flash_type = STLINK_FLASH_TYPE_F0, @@ -315,11 +326,12 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F0_CAN, .description = "F07x", .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x800, // Page sizes listed in Table 4 - .sram_size = 0x4000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffC800, // "System memory" starting address from Table 2 - .bootrom_size = 0x3000, // "System memory" byte size in hex from Table 2 + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x800, // Page sizes listed in Table 4 + .sram_size = 0x4000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = + 0x1fffC800, // "System memory" starting address from Table 2 + .bootrom_size = 0x3000, // "System memory" byte size in hex from Table 2 }, { // Use this as an example for mapping future chips: @@ -327,11 +339,12 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F0, .description = "F0xx", .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = + 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 }, { // RM0402 document was used to find these parameters @@ -339,11 +352,12 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F412, .description = "F412", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // "Flash size data register" (pg1135) - .flash_pagesize = 0x4000, // Table 5. Flash module organization ? - .sram_size = 0x40000, // "SRAM" byte size in hex from Table 4 - .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 - .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 + .flash_size_reg = 0x1FFF7A22, // "Flash size data register" (pg1135) + .flash_pagesize = 0x4000, // Table 5. Flash module organization ? + .sram_size = 0x40000, // "SRAM" byte size in hex from Table 4 + .bootrom_base = + 0x1FFF0000, // "System memory" starting address from Table 4 + .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 .flags = CHIP_F_HAS_SWO_TRACING, }, { @@ -352,22 +366,27 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F413, .description = "F413", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // "Flash size data register" Section 35.2 - .flash_pagesize = 0x4000, // Table 5. Flash module organization (variable sector sizes, but 0x4000 is smallest) - .sram_size = 0x50000, // "SRAM" byte size in hex from Figure 2 (Table 4 only says 0x40000) - .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 - .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 + .flash_size_reg = 0x1FFF7A22, // "Flash size data register" Section 35.2 + .flash_pagesize = + 0x4000, // Table 5. Flash module organization (variable sector + // sizes, but 0x4000 is smallest) + .sram_size = 0x50000, // "SRAM" byte size in hex from Figure 2 (Table 4 + // only says 0x40000) + .bootrom_base = + 0x1FFF0000, // "System memory" starting address from Table 4 + .bootrom_size = 0x7800, // "System memory" byte size in hex from Table 4 .flags = CHIP_F_HAS_SWO_TRACING, }, { .chip_id = STLINK_CHIPID_STM32_F09X, .description = "F09X", .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x800, // Page sizes listed in Table 4 (pg 56) - .sram_size = 0x8000, // "SRAM" byte size in hex from Table 2 (pg 50) - .bootrom_base = 0x1fffd800, // "System memory" starting address from Table 2 - .bootrom_size = 0x2000, // "System memory" byte size in hex from Table 2 + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x800, // Page sizes listed in Table 4 (pg 56) + .sram_size = 0x8000, // "SRAM" byte size in hex from Table 2 (pg 50) + .bootrom_base = + 0x1fffd800, // "System memory" starting address from Table 2 + .bootrom_size = 0x2000, // "System memory" byte size in hex from Table 2 }, { // Use this as an example for mapping future chips: @@ -375,11 +394,12 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F04, .description = "F04x", .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x1800, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x1800, // "SRAM" byte size in hex from Table 2 + .bootrom_base = + 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 }, { // Use this as an example for mapping future chips: @@ -387,11 +407,12 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F0_SMALL, .description = "F0xx small", .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = + 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00, // "System memory" byte size in hex from Table 2 }, { // STM32F30x @@ -416,7 +437,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x2000, .bootrom_base = 0x1ff0000, .bootrom_size = 0x1000, - .option_base = STM32_L0_CATx_OPTION_BYTES_BASE, + .option_base = STM32_L0_OPTION_BYTES_BASE, .option_size = 20, }, { @@ -430,7 +451,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x5000, .bootrom_base = 0x1ff0000, .bootrom_size = 0x2000, - .option_base = STM32_L0_CATx_OPTION_BYTES_BASE, + .option_base = STM32_L0_OPTION_BYTES_BASE, .option_size = 20, }, { @@ -444,7 +465,7 @@ static const struct stlink_chipid_params devices[] = { .sram_size = 0x2000, .bootrom_base = 0x1ff0000, .bootrom_size = 0x1000, - .option_base = STM32_L0_CATx_OPTION_BYTES_BASE, + .option_base = STM32_L0_OPTION_BYTES_BASE, .option_size = 20, }, { @@ -466,10 +487,10 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_F303_HIGH, .description = "F303 high density", .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // 34.2.1 Flash size data register - .flash_pagesize = 0x800, // 4.2.1 Flash memory organization - .sram_size = 0x10000, // 3.3 Embedded SRAM - .bootrom_base = 0x1fffd800, // 3.3.2 / Table 4 System Memory + .flash_size_reg = 0x1ffff7cc, // 34.2.1 Flash size data register + .flash_pagesize = 0x800, // 4.2.1 Flash memory organization + .sram_size = 0x10000, // 3.3 Embedded SRAM + .bootrom_base = 0x1fffd800, // 3.3.2 / Table 4 System Memory .bootrom_size = 0x2000, .flags = CHIP_F_HAS_SWO_TRACING, }, @@ -479,15 +500,18 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_L4, .description = "L4xx", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1FFF75e0, // "Flash size data register" (sec 45.2, page 1671) - .flash_pagesize = 0x800, // 2k (sec 3.2, page 78; also appears in sec 3.3.1 - // and tables 4-6 on pages 79-81) - // SRAM1 is "up to" 96k in the standard Cortex-M memory map; - // SRAM2 is 32k mapped at at 0x10000000 (sec 2.3, page 73 for - // sizes; table 2, page 74 for SRAM2 location) + .flash_size_reg = + 0x1FFF75e0, // "Flash size data register" (sec 45.2, page 1671) + .flash_pagesize = + 0x800, // 2k (sec 3.2, page 78; also appears in sec 3.3.1 + // and tables 4-6 on pages 79-81) + // SRAM1 is "up to" 96k in the standard Cortex-M memory map; + // SRAM2 is 32k mapped at at 0x10000000 (sec 2.3, page 73 for + // sizes; table 2, page 74 for SRAM2 location) .sram_size = 0x18000, - .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) - .bootrom_size = 0x7000, // 28k (per bank), same source as base + .bootrom_base = + 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) + .bootrom_size = 0x7000, // 28k (per bank), same source as base .option_base = STM32_L4_OPTION_BYTES_BASE, .option_size = 4, .flags = CHIP_F_HAS_SWO_TRACING, @@ -498,11 +522,13 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_L4RX, .description = "L4Rx", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 52.2, page 2049) - .flash_pagesize = 0x1000, // 4k, section 3.3, pg 97 - .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 - .bootrom_base = 0x1fff0000, // 3.3.1, pg 99 - .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 99) + .flash_size_reg = + 0x1fff75e0, // "Flash size data register" (sec 52.2, page 2049) + .flash_pagesize = 0x1000, // 4k, section 3.3, pg 97 + .sram_size = + 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 + .bootrom_base = 0x1fff0000, // 3.3.1, pg 99 + .bootrom_size = 0x7000, // 28k (per bank), same source as base (pg 99) .flags = CHIP_F_HAS_SWO_TRACING, }, { @@ -511,13 +537,16 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_L41X, .description = "L41x", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (RM0394, sec 47.2, page 1586) - .flash_pagesize = 0x800, // 2k (DS12469, sec 3.4, page 17) - // SRAM1 is 32k at 0x20000000 - // SRAM2 is 8k at 0x10000000 and 0x20008000 (DS12469, sec 3.5, page 18) - .sram_size = 0xa000, // 40k (DS12469, sec 3.5, page 18) - .bootrom_base = 0x1fff0000, // System Memory (RM0394, sec 3.3.1, table 8) - .bootrom_size = 0x7000, // 28k, same source as base + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (RM0394, + // sec 47.2, page 1586) + .flash_pagesize = 0x800, // 2k (DS12469, sec 3.4, page 17) + // SRAM1 is 32k at 0x20000000 + // SRAM2 is 8k at 0x10000000 and 0x20008000 + // (DS12469, sec 3.5, page 18) + .sram_size = 0xa000, // 40k (DS12469, sec 3.5, page 18) + .bootrom_base = + 0x1fff0000, // System Memory (RM0394, sec 3.3.1, table 8) + .bootrom_size = 0x7000, // 28k, same source as base .flags = CHIP_F_HAS_SWO_TRACING, }, { @@ -526,15 +555,18 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_L43X, .description = "L43x/L44x", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 43.2, page 1410) - .flash_pagesize = 0x800, // 2k (sec 3.2, page 74; also appears in sec 3.3.1 - // and tables 7-8 on pages 75-76) - // SRAM1 is "up to" 64k in the standard Cortex-M memory map; - // SRAM2 is 16k mapped at 0x10000000 (sec 2.3, page 73 for - // sizes; table 2, page 74 for SRAM2 location) + .flash_size_reg = + 0x1fff75e0, // "Flash size data register" (sec 43.2, page 1410) + .flash_pagesize = + 0x800, // 2k (sec 3.2, page 74; also appears in sec 3.3.1 + // and tables 7-8 on pages 75-76) + // SRAM1 is "up to" 64k in the standard Cortex-M memory map; + // SRAM2 is 16k mapped at 0x10000000 (sec 2.3, page 73 for + // sizes; table 2, page 74 for SRAM2 location) .sram_size = 0xc000, - .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) - .bootrom_size = 0x7000, // 28k (per bank), same source as base + .bootrom_base = + 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) + .bootrom_size = 0x7000, // 28k (per bank), same source as base .option_base = STM32_L4_OPTION_BYTES_BASE, .option_size = 4, .flags = CHIP_F_HAS_SWO_TRACING, @@ -545,13 +577,15 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_L496X, .description = "L496x/L4A6x", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 49.2, page 1809) - .flash_pagesize = 0x800, // Page erase (2 Kbyte) (sec 3.2, page 93) - // SRAM1 is 256k at 0x20000000 - // SRAM2 is 64k at 0x20040000 (sec 2.2.1, fig 2, page 74) - .sram_size = 0x40000, // Embedded SRAM (sec 2.4, page 84) - .bootrom_base = 0x1fff0000, // System Memory (Bank 1) (sec 3.3.1) - .bootrom_size = 0x7000, // 28k (per bank), same source as base + .flash_size_reg = + 0x1fff75e0, // "Flash size data register" (sec 49.2, page 1809) + .flash_pagesize = + 0x800, // Page erase (2 Kbyte) (sec 3.2, page 93) + // SRAM1 is 256k at 0x20000000 + // SRAM2 is 64k at 0x20040000 (sec 2.2.1, fig 2, page 74) + .sram_size = 0x40000, // Embedded SRAM (sec 2.4, page 84) + .bootrom_base = 0x1fff0000, // System Memory (Bank 1) (sec 3.3.1) + .bootrom_size = 0x7000, // 28k (per bank), same source as base .option_base = STM32_L4_OPTION_BYTES_BASE, .option_size = 4, .flags = CHIP_F_HAS_SWO_TRACING, @@ -562,14 +596,18 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_L46X, .description = "L45x/46x", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1463) - .flash_pagesize = 0x800, // 2k (sec 3.2, page 73; also appears in sec 3.3.1 - // and tables 7 on pages 73-74) - // SRAM1 is 128k at 0x20000000; - // SRAM2 is 32k mapped at 0x10000000 (sec 2.4.2, table 3-4, page 68, also fig 2 on page 63) + .flash_size_reg = + 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1463) + .flash_pagesize = + 0x800, // 2k (sec 3.2, page 73; also appears in sec 3.3.1 + // and tables 7 on pages 73-74) + // SRAM1 is 128k at 0x20000000; + // SRAM2 is 32k mapped at 0x10000000 (sec 2.4.2, table 3-4, + // page 68, also fig 2 on page 63) .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, // Tables 6, pages 71-72 (Bank 1 system memory, also fig 2 on page 63) - .bootrom_size = 0x7000, // 28k (per bank), same source as base + .bootrom_base = 0x1fff0000, // Tables 6, pages 71-72 (Bank 1 system + // memory, also fig 2 on page 63) + .bootrom_size = 0x7000, // 28k (per bank), same source as base .flags = CHIP_F_HAS_SWO_TRACING, }, { @@ -588,11 +626,11 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_G0_CAT1, .description = "G030/G031/G041", .flash_type = STLINK_FLASH_TYPE_G0, - .flash_size_reg = 0x1FFF75E0, // Section 38.2 - .flash_pagesize = 0x800, // 2k (sec 3.2) - .sram_size = 0x2000, // 8k (sec 2.3) + .flash_size_reg = 0x1FFF75E0, // Section 38.2 + .flash_pagesize = 0x800, // 2k (sec 3.2) + .sram_size = 0x2000, // 8k (sec 2.3) .bootrom_base = 0x1fff0000, - .bootrom_size = 0x2000, // 8k (sec 2.2.2 table 3) + .bootrom_size = 0x2000, // 8k (sec 2.2.2 table 3) .option_base = STM32_G0_OPTION_BYTES_BASE, .option_size = 4, }, @@ -601,11 +639,11 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_G0_CAT2, .description = "G070/G071/G081", .flash_type = STLINK_FLASH_TYPE_G0, - .flash_size_reg = 0x1FFF75E0, // Section 38.2 - .flash_pagesize = 0x800, // 2k (sec 3.2) - .sram_size = 0x9000, // 36k (sec 2.3) + .flash_size_reg = 0x1FFF75E0, // Section 38.2 + .flash_pagesize = 0x800, // 2k (sec 3.2) + .sram_size = 0x9000, // 36k (sec 2.3) .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 2) + .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 2) .option_base = STM32_G0_OPTION_BYTES_BASE, .option_size = 4, }, @@ -614,14 +652,15 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_G4_CAT2, .description = "G4 Category-2", .flash_type = STLINK_FLASH_TYPE_G4, - .flash_size_reg = 0x1FFF75E0, // Section 47.2 - .flash_pagesize = 0x800, // 2k (sec 3.3.1) - // SRAM1 is 16k at 0x20000000 - // SRAM2 is 6k at 0x20014000 - // SRAM3/CCM is 10k at 0x10000000, aliased at 0x20018000 - .sram_size = 0x8000, // 32k (sec 2.4) + .flash_size_reg = 0x1FFF75E0, // Section 47.2 + .flash_pagesize = + 0x800, // 2k (sec 3.3.1) + // SRAM1 is 16k at 0x20000000 + // SRAM2 is 6k at 0x20014000 + // SRAM3/CCM is 10k at 0x10000000, aliased at 0x20018000 + .sram_size = 0x8000, // 32k (sec 2.4) .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (table 2) + .bootrom_size = 0x7000, // 28k (table 2) .option_base = STM32_G4_OPTION_BYTES_BASE, .option_size = 4, .flags = CHIP_F_HAS_SWO_TRACING, @@ -631,14 +670,15 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_G4_CAT3, .description = "G4 Category-3", .flash_type = STLINK_FLASH_TYPE_G4, - .flash_size_reg = 0x1FFF75E0, // Section 47.2 - .flash_pagesize = 0x800, // 2k (sec 3.3.1) - // SRAM1 is 80k at 0x20000000 - // SRAM2 is 16k at 0x20014000 - // SRAM3/CCM is 32k at 0x10000000, aliased at 0x20018000 - .sram_size = 0x18000, // 128k (sec 2.4) + .flash_size_reg = 0x1FFF75E0, // Section 47.2 + .flash_pagesize = + 0x800, // 2k (sec 3.3.1) + // SRAM1 is 80k at 0x20000000 + // SRAM2 is 16k at 0x20014000 + // SRAM3/CCM is 32k at 0x10000000, aliased at 0x20018000 + .sram_size = 0x18000, // 128k (sec 2.4) .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (table 2) + .bootrom_size = 0x7000, // 28k (table 2) .option_base = STM32_G4_OPTION_BYTES_BASE, .option_size = 4, .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, @@ -649,7 +689,7 @@ static const struct stlink_chipid_params devices[] = { .description = "WB55", .flash_type = STLINK_FLASH_TYPE_WB, .flash_size_reg = 0x1FFF75E0, - .flash_pagesize = 0x1000, // 4k + .flash_pagesize = 0x1000, // 4k .sram_size = 0x40000, .bootrom_base = 0x1fff0000, // see the memory map .bootrom_size = 0x7000, @@ -660,13 +700,15 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_H74XXX, .description = "H74x/H75x", .flash_type = STLINK_FLASH_TYPE_H7, - .flash_size_reg = 0x1ff1e880, // "Flash size register" (pg3272) - .flash_pagesize = 0x20000, // 128k sector (pg147) - .sram_size = 0x20000, // 128k "DTCM" from Table 7 - .bootrom_base = 0x1ff00000, // "System memory" starting address from Table 7 - .bootrom_size = 0x20000, // "System memory" byte size in hex from Table 7 + .flash_size_reg = 0x1ff1e880, // "Flash size register" (pg3272) + .flash_pagesize = 0x20000, // 128k sector (pg147) + .sram_size = 0x20000, // 128k "DTCM" from Table 7 + .bootrom_base = + 0x1ff00000, // "System memory" starting address from Table 7 + .bootrom_size = + 0x20000, // "System memory" byte size in hex from Table 7 .option_base = STM32_H7_OPTION_BYTES_BASE, - .option_size = 44, // FLASH_OPTSR_CUR to FLASH_BOOT_PRGR from Table 28 + .option_size = 44, // FLASH_OPTSR_CUR to FLASH_BOOT_PRGR from Table 28 .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, }, { @@ -674,11 +716,13 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_H7AX, .description = "H7Ax/H7Bx", .flash_type = STLINK_FLASH_TYPE_H7, - .flash_size_reg = 0x08FFF80C, // "Flash size register" (p.2949) - .flash_pagesize = 0x2000, // 8k sector (p.146) - .sram_size = 0x20000, // 128k "DTCM" (Figure 1) - .bootrom_base = 0x1FF00000, // "System memory" starting address (Table 12-14) - .bootrom_size = 0x20000, // "System memory" byte size in hex splitted to two banks (Table 12-14) + .flash_size_reg = 0x08FFF80C, // "Flash size register" (p.2949) + .flash_pagesize = 0x2000, // 8k sector (p.146) + .sram_size = 0x20000, // 128k "DTCM" (Figure 1) + .bootrom_base = + 0x1FF00000, // "System memory" starting address (Table 12-14) + .bootrom_size = 0x20000, // "System memory" byte size in hex splitted to + // two banks (Table 12-14) .option_base = STM32_H7_OPTION_BYTES_BASE, .option_size = 44, .flags = CHIP_F_HAS_DUAL_BANK | CHIP_F_HAS_SWO_TRACING, @@ -688,11 +732,12 @@ static const struct stlink_chipid_params devices[] = { .chip_id = STLINK_CHIPID_STM32_H72X, .description = "H72x/H73x", .flash_type = STLINK_FLASH_TYPE_H7, - .flash_size_reg = 0x1FF1E880, // "Flash size register" (p.3286) - .flash_pagesize = 0x20000, // 128k sector (p.152) - .sram_size = 0x20000, // 128k "DTCM" (Figure 1) - .bootrom_base = 0x1FF00000, // "System memory" starting address (Table 6) - .bootrom_size = 0x20000, // "System memory" byte size in hex (Table 6) + .flash_size_reg = 0x1FF1E880, // "Flash size register" (p.3286) + .flash_pagesize = 0x20000, // 128k sector (p.152) + .sram_size = 0x20000, // 128k "DTCM" (Figure 1) + .bootrom_base = + 0x1FF00000, // "System memory" starting address (Table 6) + .bootrom_size = 0x20000, // "System memory" byte size in hex (Table 6) .option_base = STM32_H7_OPTION_BYTES_BASE, .option_size = 44, .flags = CHIP_F_HAS_SWO_TRACING, @@ -712,13 +757,13 @@ static const struct stlink_chipid_params devices[] = { }; const struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) { - const struct stlink_chipid_params *params = NULL; + const struct stlink_chipid_params *params = NULL; - for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) - if (devices[n].chip_id == chipid) { - params = &devices[n]; - break; - } + for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) + if (devices[n].chip_id == chipid) { + params = &devices[n]; + break; + } - return(params); + return (params); } From b97296be8f22421b5beb21a4462bf8e515f74ab8 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sat, 24 Apr 2021 22:47:02 +0200 Subject: [PATCH 65/65] Release v1.7.0 --- .gitignore | 3 ++- .version | 2 +- CHANGELOG.md | 12 ++++++------ README.md | 4 ++-- cmake/packaging/windows/generate_binaries.sh | 4 ++-- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index a07eed9ca..1a5fd5ab1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ build -build-mingw +build-mingw-32 +build-mingw-64 .project .cmake/ diff --git a/.version b/.version index 9c6d6293b..bd8bf882d 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -1.6.1 +1.7.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index a3e7dbafc..9f63eca81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,14 +2,14 @@ # v1.7.0 -Release date: 2020-04-xx +Release date: 2021-04-25 This release drops support for the STLINK/V1 programmer on macOS 10.13. Features: - Extended set of cmd line arguments for st-info and st-util ([#332](https://github.com/stlink-org/stlink/pull/332), [#990](https://github.com/stlink-org/stlink/pull/990), [#1091](https://github.com/stlink-org/stlink/pull/1091), [#1114](https://github.com/stlink-org/stlink/pull/1114)) -- Extended support for STM32H7 & rework of software reset ([#532](https://github.com/stlink-org/stlink/pull/532), [#801](https://github.com/stlink-org/stlink/pull/801), [#868](https://github.com/stlink-org/stlink/pull/868), [#1059](https://github.com/stlink-org/stlink/pull/1059), [#1063](https://github.com/stlink-org/stlink/pull/1063), [#1071](https://github.com/stlink-org/stlink/pull/1071)) +- Extended support for STM32H7 & rework of software reset ([#532](https://github.com/stlink-org/stlink/pull/532), [#801](https://github.com/stlink-org/stlink/pull/801), [#868](https://github.com/stlink-org/stlink/pull/868), [#1008](https://github.com/stlink-org/stlink/pull/1008), [#1059](https://github.com/stlink-org/stlink/pull/1059), [#1063](https://github.com/stlink-org/stlink/pull/1063), [#1071](https://github.com/stlink-org/stlink/pull/1071)) - Added support for STM32H742/743/753 ([#671](https://github.com/stlink-org/stlink/pull/671), [#793](https://github.com/stlink-org/stlink/pull/793), [#823](https://github.com/stlink-org/stlink/pull/823), [#998](https://github.com/stlink-org/stlink/pull/998), [#1052](https://github.com/stlink-org/stlink/pull/1052)) - Official support for STLINK-V3 programmers (commit [#5e0a502](https://github.com/stlink-org/stlink/commit/5e0a502df812495bfa96fa9116a19f1306152b17), [#820](https://github.com/stlink-org/stlink/pull/820), [#1022](https://github.com/stlink-org/stlink/pull/1022), [#1025](https://github.com/stlink-org/stlink/pull/1025)) - Added preliminary support for STM32L5x2 ([#904](https://github.com/stlink-org/stlink/pull/904), [#999](https://github.com/stlink-org/stlink/pull/999)) @@ -40,7 +40,8 @@ Updates & changes: Fixes: -- Flash loader rework ([#356](https://github.com/stlink-org/stlink/pull/356), [#556](https://github.com/stlink-org/stlink/pull/556), [#593](https://github.com/stlink-org/stlink/pull/593), [#597](https://github.com/stlink-org/stlink/pull/597), [#607](https://github.com/stlink-org/stlink/pull/607), [#612](https://github.com/stlink-org/stlink/pull/612), [#638](https://github.com/stlink-org/stlink/pull/638), [#661](https://github.com/stlink-org/stlink/pull/661), [#690](https://github.com/stlink-org/stlink/pull/690), [#807](https://github.com/stlink-org/stlink/pull/807), [#817](https://github.com/stlink-org/stlink/pull/817), [#818](https://github.com/stlink-org/stlink/pull/818), [#854](https://github.com/stlink-org/stlink/pull/854), [#868](https://github.com/stlink-org/stlink/pull/868), [#967](https://github.com/stlink-org/stlink/pull/967), [#979](https://github.com/stlink-org/stlink/pull/979), [#1043](https://github.com/stlink-org/stlink/pull/1043), [#1054](https://github.com/stlink-org/stlink/pull/1054), [#1092](https://github.com/stlink-org/stlink/pull/1092), [#1105](https://github.com/stlink-org/stlink/pull/1105), [#1113](https://github.com/stlink-org/stlink/pull/1113)) +- Improvements and fixes of the flash loaders, unification of the reset function ([#244](https://github.com/stlink-org/stlink/pull/244), [#382](https://github.com/stlink-org/stlink/pull/382), [#705](https://github.com/stlink-org/stlink/pull/705), [#980](https://github.com/stlink-org/stlink/pull/980), [#995](https://github.com/stlink-org/stlink/pull/995), [#1008](https://github.com/stlink-org/stlink/pull/1008), [#1115](https://github.com/stlink-org/stlink/pull/1115), [#1117](https://github.com/stlink-org/stlink/pull/1117), [#1122](https://github.com/stlink-org/stlink/pull/1122), [#1124](https://github.com/stlink-org/stlink/pull/1124)) +- Flash loader rework ([#356](https://github.com/stlink-org/stlink/pull/356), [#556](https://github.com/stlink-org/stlink/pull/556), [#593](https://github.com/stlink-org/stlink/pull/593), [#597](https://github.com/stlink-org/stlink/pull/597), [#607](https://github.com/stlink-org/stlink/pull/607), [#612](https://github.com/stlink-org/stlink/pull/612), [#638](https://github.com/stlink-org/stlink/pull/638), [#661](https://github.com/stlink-org/stlink/pull/661), [#690](https://github.com/stlink-org/stlink/pull/690), [#807](https://github.com/stlink-org/stlink/pull/807), [#817](https://github.com/stlink-org/stlink/pull/817), [#818](https://github.com/stlink-org/stlink/pull/818), [#854](https://github.com/stlink-org/stlink/pull/854), [#868](https://github.com/stlink-org/stlink/pull/868), [#967](https://github.com/stlink-org/stlink/pull/967), [#979](https://github.com/stlink-org/stlink/pull/979), [#1008](https://github.com/stlink-org/stlink/pull/1008), [#1043](https://github.com/stlink-org/stlink/pull/1043), [#1054](https://github.com/stlink-org/stlink/pull/1054), [#1092](https://github.com/stlink-org/stlink/pull/1092), [#1105](https://github.com/stlink-org/stlink/pull/1105), [#1113](https://github.com/stlink-org/stlink/pull/1113)) - Fixed old DFU serial number for STLINK programmers ([#417](https://github.com/stlink-org/stlink/pull/417), [#494](https://github.com/stlink-org/stlink/pull/494), [#1106](https://github.com/stlink-org/stlink/pull/1106), [#1121](https://github.com/stlink-org/stlink/pull/1121)) - Use vl flashloader for all STM32F1 series ([#769](https://github.com/stlink-org/stlink/pull/769), [#1041](https://github.com/stlink-org/stlink/pull/1041), [#1044](https://github.com/stlink-org/stlink/pull/1044)) - [regression] Changed timeout on flash write ([#787](https://github.com/stlink-org/stlink/pull/787), [#981](https://github.com/stlink-org/stlink/pull/981), [#987](https://github.com/stlink-org/stlink/pull/987)) @@ -53,7 +54,7 @@ Fixes: - Fixed `connect under reset` for `st-flash` and `st-util` ([#983](https://github.com/stlink-org/stlink/pull/983)) - Fix for `mmap() size_t overflow` in `st-flash` ([#988](https://github.com/stlink-org/stlink/pull/988), [#989](https://github.com/stlink-org/stlink/pull/989)) - [regression] `stlink-gui` installation issue on Ubuntu-18.04 ([#1001](https://github.com/stlink-org/stlink/pull/1001), [#1004](https://github.com/stlink-org/stlink/pull/1004), [#1006](https://github.com/stlink-org/stlink/pull/1006)) -- `st-util`: wrong register values passed to `gdb` (STLink/V2) ([#1002](https://github.com/stlink-org/stlink/pull/1002), [#1011](https://github.com/stlink-org/stlink/pull/1011), [#1026](https://github.com/stlink-org/stlink/pull/1026), [#1027](https://github.com/stlink-org/stlink/pull/1027), [#1038](https://github.com/stlink-org/stlink/pull/1038),[#1064](https://github.com/stlink-org/stlink/pull/1064), [#1065](https://github.com/stlink-org/stlink/pull/1065)) +- `st-util`: wrong register values passed to `gdb` (STLink/V2) ([#1002](https://github.com/stlink-org/stlink/pull/1002), [#1011](https://github.com/stlink-org/stlink/pull/1011), [#1026](https://github.com/stlink-org/stlink/pull/1026), [#1027](https://github.com/stlink-org/stlink/pull/1027), [#1038](https://github.com/stlink-org/stlink/pull/1038), [#1064](https://github.com/stlink-org/stlink/pull/1064), [#1065](https://github.com/stlink-org/stlink/pull/1065)) - GDB: Fixed problems with target description ([#1013](https://github.com/stlink-org/stlink/pull/1013), [#1088](https://github.com/stlink-org/stlink/pull/1088), [#1109](https://github.com/stlink-org/stlink/pull/1109)) - [doc] Fixed wrong path for `rules.d` folder ([#1020](https://github.com/stlink-org/stlink/pull/1020)) - Fixed support for STLINK/V1 programmer ([#1045](https://github.com/stlink-org/stlink/pull/1045), [#1105](https://github.com/stlink-org/stlink/pull/1105)) @@ -66,7 +67,7 @@ Fixes: - [doc] Corrected spelling mistake in bug report template ([#1103](https://github.com/stlink-org/stlink/pull/1103)) - Fixed STM32WB55 reading DEBUG IDCODE from the wrong address ([#1100](https://github.com/stlink-org/stlink/pull/1100), [#1101](https://github.com/stlink-org/stlink/pull/1101)) - Applied missing changes to tests ([#1119](https://github.com/stlink-org/stlink/pull/1119)) -- Improvements for Chip_ID read ([#1120](https://github.com/stlink-org/stlink/pull/1120)) +- Improvements for Chip_ID read ([#1008](https://github.com/stlink-org/stlink/pull/1008), [#1120](https://github.com/stlink-org/stlink/pull/1120)) # v1.6.1 @@ -143,7 +144,6 @@ Updates & changes: Fixes: -- Improvements and fixes of the flash loaders, unification of the reset function ([#244](https://github.com/stlink-org/stlink/pull/244), [#382](https://github.com/stlink-org/stlink/pull/382), [#705](https://github.com/stlink-org/stlink/pull/705), [#980](https://github.com/stlink-org/stlink/pull/980), [#995](https://github.com/stlink-org/stlink/pull/995), [#1115](https://github.com/stlink-org/stlink/pull/1115), [#1117](https://github.com/stlink-org/stlink/pull/1117), [#1122](https://github.com/stlink-org/stlink/pull/1122), [#1124](https://github.com/stlink-org/stlink/pull/1124)) - Fixed wait-loop for `flash_loader_run()` ([#290](https://github.com/stlink-org/stlink/pull/290)) - Better argument parsing for CLI tools: `stlink_open_usb` can address v1, v2, v3 ([#378](https://github.com/stlink-org/stlink/pull/378), [#922](https://github.com/stlink-org/stlink/pull/922)) - Clear the PG bit before setting the `PER` bit ([#579](https://github.com/stlink-org/stlink/pull/579), [#876](https://github.com/stlink-org/stlink/pull/876)) diff --git a/README.md b/README.md index 93994db49..600879580 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![BSD licensed](https://img.shields.io/badge/license-BSD-blue.svg)](https://raw.githubusercontent.com/hyperium/hyper/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/stlink-org/stlink.svg)](https://github.com/stlink-org/stlink/releases/latest) [![Downloads](https://img.shields.io/github/downloads/stlink-org/stlink/total)](https://github.com/stlink-org/stlink/releases/latest) -![GitHub commits](https://img.shields.io/github/commits-since/stlink-org/stlink/v1.6.1/develop) +![GitHub commits](https://img.shields.io/github/commits-since/stlink-org/stlink/v1.7.0/develop) ![GitHub activity](https://img.shields.io/github/commit-activity/m/stlink-org/stlink) ![GitHub contributors](https://img.shields.io/github/contributors/stlink-org/stlink) [![CodeQL](https://github.com/stlink-org/stlink/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/stlink-org/stlink/actions/workflows/codeql-analysis.yml) @@ -66,7 +66,7 @@ Our [tutorial](doc/tutorial.md) may help you along with some advanced tasks and **Windows**: As of Release v1.6.1 stand-alone Windows binaries are made available (again) on the release page of the project. -Please ensure to select the correct version for your system (i686 or x86_64). The archive file can be unzipped to any desired location as it does not contain any hardcoded paths. However we suggest to move the unzipped application folder to `C:\Program Files\` on 32-bit systems and to `C:\Program Files (x86)\` on 64-bit systems (the toolset is a 32-bit). +Please ensure to select the correct version for your system (i686 or x86_64). The archive file can be unzipped to any desired location as it does not contain any hardcoded paths. However we suggest to move the unzipped application folder to `C:\Program Files\` on 32-bit systems and to `C:\Program Files (x86)\` on 64-bit systems (the toolset is 32-bit). Alternatively one may compile and install from source as described in our [compiling manual](doc/compiling.md#Windows). diff --git a/cmake/packaging/windows/generate_binaries.sh b/cmake/packaging/windows/generate_binaries.sh index bf2453d10..f3642c316 100644 --- a/cmake/packaging/windows/generate_binaries.sh +++ b/cmake/packaging/windows/generate_binaries.sh @@ -12,7 +12,7 @@ cmake -DCMAKE_SYSTEM_NAME=Windows \ -DTOOLCHAIN_PREFIX=x86_64-w64-mingw32 \ -DCMAKE_TOOLCHAIN_FILE=./../cmake/modules/set_toolchain.cmake .. make package -cp dist/*.zip ../build/Release/dist +sudo cp dist/*.zip ../build/Release/dist make clean cd .. rm -rf build-mingw-64 @@ -24,7 +24,7 @@ cmake -DCMAKE_SYSTEM_NAME=Windows \ -DTOOLCHAIN_PREFIX=i686-w64-mingw32 \ -DCMAKE_TOOLCHAIN_FILE=./../cmake/modules/set_toolchain.cmake .. make package -cp dist/*.zip ../build/Release/dist +sudo cp dist/*.zip ../build/Release/dist make clean cd .. rm -rf build-mingw-32