From e43b434c8ac59885710cb4b2b05fb49d7c023ad4 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Tue, 27 Oct 2020 11:41:39 +0500 Subject: [PATCH 01/19] Small rewrote setting breakpoints in gdb-server for Cortex-M7 --- inc/stm32.h | 1 + src/common.c | 8 +++- src/st-util/gdb-server.c | 92 +++++++++++++--------------------------- src/stlink-lib/reg.h | 10 ++++- 4 files changed, 47 insertions(+), 64 deletions(-) diff --git a/inc/stm32.h b/inc/stm32.h index 1773e703b..768fabb87 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -10,6 +10,7 @@ /* Cortex core ids */ #define STM32VL_CORE_ID 0x1ba01477 #define STM32F7_CORE_ID 0x5ba02477 +#define STM32H7_CORE_ID 0x6ba02477 // 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 a08db2733..c7f2883db 100644 --- a/src/common.c +++ b/src/common.c @@ -1252,7 +1252,13 @@ int stlink_core_id(stlink_t *sl) { int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { int ret; - ret = stlink_read_debug32(sl, 0xE0042000, chip_id); + if (sl->core_id == STM32H7_CORE_ID) { + // STM32H7 chipid in 0x5c001000 (RM0433 pg3189) + ret = stlink_read_debug32(sl, 0x5c001000, chip_id); + } else { + // default chipid address + ret = stlink_read_debug32(sl, 0xE0042000, chip_id); + } if (ret == -1) { return(ret); diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 60c9c16d3..d2685cef6 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -575,21 +575,6 @@ char* make_memory_map(stlink_t *sl) { return(map); } -/* - * DWT_COMP0 0xE0001020 - * DWT_MASK0 0xE0001024 - * DWT_FUNCTION0 0xE0001028 - * DWT_COMP1 0xE0001030 - * DWT_MASK1 0xE0001034 - * DWT_FUNCTION1 0xE0001038 - * DWT_COMP2 0xE0001040 - * DWT_MASK2 0xE0001044 - * DWT_FUNCTION2 0xE0001048 - * DWT_COMP3 0xE0001050 - * DWT_MASK3 0xE0001054 - * DWT_FUNCTION3 0xE0001058 - */ - #define DATA_WATCH_NUM 4 enum watchfun { WATCHDISABLED = 0, WATCHREAD = 5, WATCHWRITE = 6, WATCHACCESS = 7 }; @@ -606,15 +591,15 @@ static void init_data_watchpoints(stlink_t *sl) { uint32_t data; DLOG("init watchpoints\n"); - stlink_read_debug32(sl, 0xE000EDFC, &data); + stlink_read_debug32(sl, STLINK_REG_CM3_DEMCR, &data); data |= 1 << 24; - // set trcena in debug command to turn on dwt unit - stlink_write_debug32(sl, 0xE000EDFC, data); + // set TRCENA in debug command to turn on DWT unit + stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, data); // make sure all watchpoints are cleared for (int i = 0; i < DATA_WATCH_NUM; i++) { data_watches[i].fun = WATCHDISABLED; - stlink_write_debug32(sl, 0xe0001028 + i * 16, 0); + stlink_write_debug32(sl, STLINK_REG_CM3_DWT_FUNn(i), 0); } } @@ -645,16 +630,16 @@ static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr data_watches[i].mask = mask; // insert comparator address - stlink_write_debug32(sl, 0xE0001020 + i * 16, addr); + stlink_write_debug32(sl, STLINK_REG_CM3_DWT_COMPn(i), addr); // insert mask - stlink_write_debug32(sl, 0xE0001024 + i * 16, mask); + stlink_write_debug32(sl, STLINK_REG_CM3_DWT_MASKn(i), mask); // insert function - stlink_write_debug32(sl, 0xE0001028 + i * 16, wf); + stlink_write_debug32(sl, STLINK_REG_CM3_DWT_FUNn(i), wf); // just to make sure the matched bit is clear ! - stlink_read_debug32(sl, 0xE0001028 + i * 16, &dummy); + stlink_read_debug32(sl, STLINK_REG_CM3_DWT_FUNn(i), &dummy); return(0); } } @@ -671,7 +656,7 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) { DLOG("delete watchpoint %d addr %x\n", i, addr); data_watches[i].fun = WATCHDISABLED; - stlink_write_debug32(sl, 0xe0001028 + i * 16, 0); + stlink_write_debug32(sl, STLINK_REG_CM3_DWT_FUNn(i), 0); return(0); } @@ -705,9 +690,15 @@ static void init_code_breakpoints(stlink_t *sl) { ILOG("Found %i hw breakpoint registers\n", code_break_num); + if (sl->core_id == STM32F7_CORE_ID || sl->core_id == STM32H7_CORE_ID) { + // Cortex-M7 can have locked to write FP_* registers + // IHI0029D, p. 48, Lock Access Register + stlink_write_debug32(sl, STLINK_REG_CM7_FP_LAR, STLINK_REG_CM7_FP_LAR_KEY); + } + for (int i = 0; i < code_break_num; i++) { code_breaks[i].type = 0; - stlink_write_debug32(sl, STLINK_REG_CM3_FP_COMP0 + i * 4, 0); + stlink_write_debug32(sl, STLINK_REG_CM3_FP_COMPn(i), 0); } } @@ -719,69 +710,46 @@ static int has_breakpoint(stm32_addr_t addr) { } static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { - stm32_addr_t fpb_addr; uint32_t mask; int type = (addr & 0x2) ? CODE_BREAK_HIGH : CODE_BREAK_LOW; + stm32_addr_t fpb_addr = addr & 0x1FFFFFFC; if (addr & 1) { ELOG("update_code_breakpoint: unaligned address %08x\n", addr); return(-1); } - if (sl->core_id == STM32F7_CORE_ID) { - fpb_addr = addr; - } else { - fpb_addr = addr & ~0x3; - } - int id = -1; - for (int i = 0; i < code_break_num; i++) if (fpb_addr == code_breaks[i].addr || (set && code_breaks[i].type == 0)) { id = i; break; } - if (id == -1) { - if (set) { - return(-1); - } // free slot not found - else { - return(0); - } // breakpoint is already removed - + if (set) + return(-1); // free slot not found + else + return(0); // breakpoint is already removed } struct code_hw_breakpoint* bp = &code_breaks[id]; - bp->addr = fpb_addr; - - if (sl->core_id == STM32F7_CORE_ID) { - if (set) { - bp->type = type; - } else { - bp->type = 0; - } - - mask = (bp->addr) | 1; - } else { - if (set) { - bp->type |= type; - } else { - bp->type &= ~type; - } - - mask = (bp->addr) | 1 | (bp->type << 30); - } + if (set) + bp->type |= type; + else + bp->type &= ~type; + + // DDI0403E, p. 759, FP_COMPn register description + mask = (bp->type << 30) | (bp->addr) | 1; if (bp->type == 0) { DLOG("clearing hw break %d\n", id); - stlink_write_debug32(sl, 0xe0002008 + id * 4, 0); + stlink_write_debug32(sl, STLINK_REG_CM3_FP_COMPn(id), 0); } else { DLOG("setting hw break %d at %08x (%d)\n", id, bp->addr, bp->type); DLOG("reg %08x \n", mask); - stlink_write_debug32(sl, 0xe0002008 + id * 4, mask); + stlink_write_debug32(sl, STLINK_REG_CM3_FP_COMPn(id), mask); } return(0); diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index dde77ef50..3a3682140 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -2,8 +2,16 @@ #define STLINK_REG_H_ #define STLINK_REG_CM3_CPUID 0xE000ED00 + #define STLINK_REG_CM3_FP_CTRL 0xE0002000 -#define STLINK_REG_CM3_FP_COMP0 0xE0002008 +#define STLINK_REG_CM3_FP_COMPn(n) (0xE0002008 + n*4) +#define STLINK_REG_CM7_FP_LAR 0xE0000FB0 +#define STLINK_REG_CM7_FP_LAR_KEY 0xC5ACCE55 + +#define STLINK_REG_CM3_DEMCR 0xE000EDFC +#define STLINK_REG_CM3_DWT_COMPn(n) (0xE0001020 + n*16) +#define STLINK_REG_CM3_DWT_MASKn(n) (0xE0001024 + n*16) +#define STLINK_REG_CM3_DWT_FUNn(n) (0xE0001028 + n*16) /* Cortex™-M3 Technical Reference Manual */ /* Debug Halting Control and Status Register */ From 31bea45e32d843b5b2d5bb2ea3bba3dbec73ac1b Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Thu, 29 Oct 2020 13:30:16 +0500 Subject: [PATCH 02/19] Autodetect breakpoint style and cache support --- src/st-util/gdb-server.c | 75 ++++++++++++++++++++++------------------ src/stlink-lib/reg.h | 14 +++++++- 2 files changed, 55 insertions(+), 34 deletions(-) diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index d2685cef6..c832098f1 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -669,9 +669,13 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) { static int code_break_num; static int code_lit_num; +static int code_break_rev; #define CODE_BREAK_NUM_MAX 15 #define CODE_BREAK_LOW 0x01 #define CODE_BREAK_HIGH 0x02 +#define CODE_BREAK_REMAP 0x04 +#define CODE_BREAK_REV_V1 0x00 +#define CODE_BREAK_REV_V2 0x01 struct code_hw_breakpoint { stm32_addr_t addr; @@ -683,14 +687,16 @@ static struct code_hw_breakpoint code_breaks[CODE_BREAK_NUM_MAX]; static void init_code_breakpoints(stlink_t *sl) { unsigned int val; memset(sl->q_buf, 0, 4); - stlink_write_debug32(sl, STLINK_REG_CM3_FP_CTRL, 0x03 /* KEY | ENABLE4 */); + stlink_write_debug32(sl, STLINK_REG_CM3_FP_CTRL, 0x03 /* KEY | ENABLE */); stlink_read_debug32(sl, STLINK_REG_CM3_FP_CTRL, &val); code_break_num = ((val >> 4) & 0xf); code_lit_num = ((val >> 8) & 0xf); + code_break_rev = ((val >> 28) & 0xf); ILOG("Found %i hw breakpoint registers\n", code_break_num); - if (sl->core_id == STM32F7_CORE_ID || sl->core_id == STM32H7_CORE_ID) { + stlink_read_debug32(sl, STLINK_REG_CM3_CPUID, &val); + if (((val>>4) & 0xFFF) == 0xC27) { // Cortex-M7 can have locked to write FP_* registers // IHI0029D, p. 48, Lock Access Register stlink_write_debug32(sl, STLINK_REG_CM7_FP_LAR, STLINK_REG_CM7_FP_LAR_KEY); @@ -711,14 +717,22 @@ static int has_breakpoint(stm32_addr_t addr) { static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { uint32_t mask; - int type = (addr & 0x2) ? CODE_BREAK_HIGH : CODE_BREAK_LOW; - stm32_addr_t fpb_addr = addr & 0x1FFFFFFC; + int type; + stm32_addr_t fpb_addr; if (addr & 1) { ELOG("update_code_breakpoint: unaligned address %08x\n", addr); return(-1); } + if (code_break_rev == CODE_BREAK_REV_V1) { + type = (addr & 0x2) ? CODE_BREAK_HIGH : CODE_BREAK_LOW; + fpb_addr = addr & 0x1FFFFFFC; + } else { + type = CODE_BREAK_REMAP; + fpb_addr = addr; + } + int id = -1; for (int i = 0; i < code_break_num; i++) if (fpb_addr == code_breaks[i].addr || (set && code_breaks[i].type == 0)) { @@ -741,7 +755,7 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { bp->type &= ~type; // DDI0403E, p. 759, FP_COMPn register description - mask = (bp->type << 30) | (bp->addr) | 1; + mask = ((bp->type&0x03) << 30) | bp->addr | 1; if (bp->type == 0) { DLOG("clearing hw break %d\n", id); @@ -870,16 +884,6 @@ static int flash_go(stlink_t *sl) { return(error); } -#define CLIDR 0xE000ED78 -#define CTR 0xE000ED7C -#define CCSIDR 0xE000ED80 -#define CSSELR 0xE000ED84 -#define CCR 0xE000ED14 -#define CCR_DC (1 << 16) -#define CCR_IC (1 << 17) -#define DCCSW 0xE000EF6C -#define ICIALLU 0xE000EF50 - struct cache_level_desc { unsigned int nsets; unsigned int nways; @@ -888,6 +892,8 @@ struct cache_level_desc { }; struct cache_desc_t { + unsigned used; + // minimal line size in bytes unsigned int dminline; unsigned int iminline; @@ -914,7 +920,7 @@ static void read_cache_level_desc(stlink_t *sl, struct cache_level_desc *desc) { unsigned int ccsidr; unsigned int log2_nsets; - stlink_read_debug32(sl, CCSIDR, &ccsidr); + stlink_read_debug32(sl, STLINK_REG_CM7_CCSIDR, &ccsidr); desc->nsets = ((ccsidr >> 13) & 0x3fff) + 1; desc->nways = ((ccsidr >> 3) & 0x1ff) + 1; desc->log2_nways = ceil_log2 (desc->nways); @@ -930,18 +936,22 @@ static void init_cache (stlink_t *sl) { unsigned int ctr; int i; - // assume only F7 has a cache - if (sl->core_id != STM32F7_CORE_ID) { return; } - - stlink_read_debug32(sl, CLIDR, &clidr); - stlink_read_debug32(sl, CCR, &ccr); - stlink_read_debug32(sl, CTR, &ctr); + // Check have cache + stlink_read_debug32(sl, STLINK_REG_CM7_CTR, &ctr); + if ((ctr >> 29) != 0x04) { + cache_desc.used = 0; + return; + } else + cache_desc.used = 1; cache_desc.dminline = 4 << ((ctr >> 16) & 0x0f); cache_desc.iminline = 4 << (ctr & 0x0f); + + stlink_read_debug32(sl, STLINK_REG_CM7_CLIDR, &clidr); cache_desc.louu = (clidr >> 27) & 7; + stlink_read_debug32(sl, STLINK_REG_CM7_CCR, &ccr); ILOG("Chip clidr: %08x, I-Cache: %s, D-Cache: %s\n", - clidr, ccr & CCR_IC ? "on" : "off", ccr & CCR_DC ? "on" : "off"); + clidr, ccr & STLINK_REG_CM7_CCR_IC ? "on" : "off", ccr & STLINK_REG_CM7_CCR_DC ? "on" : "off"); ILOG(" cache: LoUU: %u, LoC: %u, LoUIS: %u\n", (clidr >> 27) & 7, (clidr >> 24) & 7, (clidr >> 21) & 7); ILOG(" cache: ctr: %08x, DminLine: %u bytes, IminLine: %u bytes\n", ctr, @@ -953,13 +963,13 @@ static void init_cache (stlink_t *sl) { cache_desc.icache[i].width = 0; if (ct == 2 || ct == 3 || ct == 4) { // data - stlink_write_debug32(sl, CSSELR, i << 1); + stlink_write_debug32(sl, STLINK_REG_CM7_CSSELR, i << 1); ILOG("D-Cache L%d: ", i); read_cache_level_desc(sl, &cache_desc.dcache[i]); } if (ct == 1 || ct == 3) { // instruction - stlink_write_debug32(sl, CSSELR, (i << 1) | 1); + stlink_write_debug32(sl, STLINK_REG_CM7_CSSELR, (i << 1) | 1); ILOG("I-Cache L%d: ", i); read_cache_level_desc(sl, &cache_desc.icache[i]); } @@ -969,7 +979,7 @@ static void init_cache (stlink_t *sl) { static void cache_flush(stlink_t *sl, unsigned ccr) { int level; - if (ccr & CCR_DC) { + if (ccr & STLINK_REG_CM7_CCR_DC) { for (level = cache_desc.louu - 1; level >= 0; level--) { struct cache_level_desc *desc = &cache_desc.dcache[level]; unsigned addr; @@ -981,15 +991,15 @@ static void cache_flush(stlink_t *sl, unsigned ccr) { unsigned int way; for (way = 0; way < desc->nways; way++) { - stlink_write_debug32(sl, DCCSW, addr | (way << way_sh)); + stlink_write_debug32(sl, STLINK_REG_CM7_DCCSW, addr | (way << way_sh)); } } } } // invalidate all I-cache to oPU - if (ccr & CCR_IC) { - stlink_write_debug32(sl, ICIALLU, 0); + if (ccr & STLINK_REG_CM7_CCR_IC) { + stlink_write_debug32(sl, STLINK_REG_CM7_ICIALLU, 0); } } @@ -1005,14 +1015,13 @@ static void cache_change(stm32_addr_t start, unsigned count) { static void cache_sync(stlink_t *sl) { unsigned ccr; - if (sl->core_id != STM32F7_CORE_ID) { return; } + if (!cache_desc.used) { return; } if (!cache_modified) { return; } cache_modified = 0; - stlink_read_debug32(sl, CCR, &ccr); - - if (ccr & (CCR_IC | CCR_DC)) { cache_flush(sl, ccr); } + stlink_read_debug32(sl, STLINK_REG_CM7_CCR, &ccr); + if (ccr & (STLINK_REG_CM7_CCR_IC | STLINK_REG_CM7_CCR_DC)) { cache_flush(sl, ccr); } } static size_t unhexify(const char *in, char *out, size_t out_count) { diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index 3a3682140..734107d6a 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -6,7 +6,7 @@ #define STLINK_REG_CM3_FP_CTRL 0xE0002000 #define STLINK_REG_CM3_FP_COMPn(n) (0xE0002008 + n*4) #define STLINK_REG_CM7_FP_LAR 0xE0000FB0 -#define STLINK_REG_CM7_FP_LAR_KEY 0xC5ACCE55 +#define STLINK_REG_CM7_FP_LAR_KEY 0xC5ACCE55 #define STLINK_REG_CM3_DEMCR 0xE000EDFC #define STLINK_REG_CM3_DWT_COMPn(n) (0xE0001020 + n*16) @@ -25,4 +25,16 @@ #define STLINK_REG_AIRCR_VECTKEY 0x05fa0000 #define STLINK_REG_AIRCR_SYSRESETREQ 0x00000004 +/* ARM Cortex-M7 Processor Technical Reference Manual */ +/* Cache Control and Status Register */ +#define STLINK_REG_CM7_CTR 0xE000ED7C +#define STLINK_REG_CM7_CLIDR 0xE000ED78 +#define STLINK_REG_CM7_CCR 0xE000ED14 +#define STLINK_REG_CM7_CCR_DC (1 << 16) +#define STLINK_REG_CM7_CCR_IC (1 << 17) +#define STLINK_REG_CM7_CSSELR 0xE000ED84 +#define STLINK_REG_CM7_DCCSW 0xE000EF6C +#define STLINK_REG_CM7_ICIALLU 0xE000EF50 +#define STLINK_REG_CM7_CCSIDR 0xE000ED80 + #endif // STLINK_REG_H_ From 504858566be82af996566795c41684b701b52ce1 Mon Sep 17 00:00:00 2001 From: anton Date: Sun, 1 Nov 2020 20:42:21 +0500 Subject: [PATCH 03/19] Improv MCU reseting --- src/stlink-lib/reg.h | 1 + src/stlink-lib/usb.c | 43 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index 734107d6a..653852440 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -17,6 +17,7 @@ /* Debug Halting Control and Status Register */ #define STLINK_REG_DHCSR 0xe000edf0 #define STLINK_REG_DHCSR_DBGKEY 0xa05f0000 +#define STLINK_REG_DHCSR_S_RESET_ST 0x02000000 #define STLINK_REG_DCRSR 0xe000edf4 #define STLINK_REG_DCRDR 0xe000edf8 diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 9726ddc4a..6b914d805 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -508,9 +508,14 @@ int _stlink_usb_reset(stlink_t * sl) { unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; ssize_t size; - int rep_len = 2; - int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); + uint32_t dhcsr; + int ret, i, rep_len = 2; + // clear S_RESET_ST in DHCSR registr + stlink_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; if (sl->version.jtag_api == STLINK_JTAG_API_V1) { @@ -526,9 +531,37 @@ int _stlink_usb_reset(stlink_t * sl) { return((int)size); } - // reset through AIRCR so that NRST does not need to be connected - return(stlink_write_debug32(sl, STLINK_REG_AIRCR, STLINK_REG_AIRCR_VECTKEY | - STLINK_REG_AIRCR_SYSRESETREQ)); + usleep(10000); + + dhcsr = 0; + ret = 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"); + ret = stlink_write_debug32(sl, STLINK_REG_AIRCR, STLINK_REG_AIRCR_VECTKEY | + STLINK_REG_AIRCR_SYSRESETREQ); + if (ret) + return(ret); + + usleep(10000); + } + + // waiting for a reset within 500ms + for (i=0; i<50; i++) { + // 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) + break; + usleep(10000); + } + + if (i >= 50) + return(-1); + return(0); } int _stlink_usb_jtag_reset(stlink_t * sl, int value) { From 4d07eb363dc9ca68936fd828d62340d8a9b558e3 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Mon, 2 Nov 2020 21:52:13 +0500 Subject: [PATCH 04/19] Split flash write function to optimize gdb flash loading --- inc/stlink.h | 4 + src/common.c | 382 +++++++++++++++++++++------------------ src/st-util/gdb-server.c | 28 ++- 3 files changed, 234 insertions(+), 180 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index 39f5f283c..e78b9569f 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -303,6 +303,10 @@ int stlink_write_option_control_register1_32(stlink_t *sl, uint32_t option_contr int stlink_write_option_bytes(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t len); int stlink_fwrite_option_bytes(stlink_t *sl, const char* path, stm32_addr_t addr); +int stlink_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); + #include #include #include diff --git a/src/common.c b/src/common.c index c7f2883db..71caeeaa8 100644 --- a/src/common.c +++ b/src/common.c @@ -2669,151 +2669,140 @@ int stm32l1_write_half_pages( 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; - 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 (%zd bytes), not supported, " - "check page start address and compare with flash module organisation " - "in related ST reference manual of your device.\n", 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(%#zx) == -1\n", 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 %d (%#x) bytes\n", - page_count, sl->flash_pgsz, sl->flash_pgsz); - - if (eraseonly) { return(0); } - +int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || (sl->flash_type == STLINK_FLASH_TYPE_F7) || (sl->flash_type == STLINK_FLASH_TYPE_L4)) { - // TODO: check write operation - ILOG("Starting Flash write for F2/F4/F7/L4\n"); + // Flash loader initialisation - if (stlink_flash_loader_init(sl, &fl) == -1) { + 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 - // TODO: Check that Voltage range is 2.7 - 3.6 V - 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)) { + 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(voltage); + } - if ( sl->version.stlink_v == 1) { - printf("STLINK V1 cannot read voltage, defaulting to 32-bit " - "writes on F4 devices\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); } else { - // set parallelism to 32 bit - int voltage = stlink_target_voltage(sl); - - if (voltage == -1) { - printf("Failed to read Target voltage\n"); - return(voltage); - } else if (voltage > 2700) { - printf("enabling 32-bit flash writes\n"); - write_flash_cr_psiz(sl, 2); - } else { - printf("Target voltage (%d mV) too low for 32-bit flash, " - "using 8-bit flash writes\n", voltage); - write_flash_cr_psiz(sl, 0); - } + ILOG("Target voltage (%d mV) too low for 32-bit flash, " + "using 8-bit flash writes\n", voltage); + write_flash_cr_psiz(sl, 0); } + } + + // set programming mode + set_flash_cr_pg(sl); + } 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"); + + wait_flash_busy(sl); + unlock_flash_if(sl); // unlock flash if necessary + set_flash_cr_pg(sl); // 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 { - // L4 does not have a byte-write mode - int voltage = stlink_target_voltage(sl); + flash_regs_base = STM32L_FLASH_REGS_ADDR; + } - if (voltage == -1) { - printf("Failed to read Target voltage\n"); - return(voltage); - } else if (voltage < 1710) { - printf("Target voltage (%d mV) too low for flash writes!\n", voltage); - return(-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); + if (val & (1 << 0)) { + ELOG("pecr.pelock not clear\n"); + return(-1); } - // set programming mode - set_flash_cr_pg(sl); + // 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); - size_t buf_size = (sl->sram_size > 0x8000) ? 0x8000 : 0x4000; + // 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); // set programming mode + } 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; - printf("size: %u\n", (unsigned int)size); - - if (stlink_flash_loader_run(sl, &fl, addr + (uint32_t)off, base + off, size) == -1) { + if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, size) == -1) { ELOG("stlink_flash_loader_run(%#zx) failed! == -1\n", addr + off); return(-1); } off += size; } - - clear_flash_cr_pg(sl); - lock_flash(sl); - - // STM32F4END } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { - fprintf(stdout, "Writing\r\n"); - fflush(stdout); - wait_flash_busy(sl); - unlock_flash_if(sl); // unlock flash if necessary - set_flash_cr_pg(sl); // set PG 'allow programming' bit - // write all words. - off = 0; - fprintf(stdout, "Starting %3u page write\r\n", (unsigned int)(len / sl->flash_pgsz)); - fflush(stdout); - - for ( ; off < len; off += sizeof(uint32_t)) { + 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 > 254) { fprintf(stdout, "\r"); } - if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { fprintf(stdout, "\r%3u/%3u pages written", (unsigned int)(off / sl->flash_pgsz), @@ -2825,18 +2814,14 @@ int stlink_write_flash( 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 } - - clear_flash_cr_pg(sl); // reset PG bit. - lock_flash(sl); } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - // use fast word write - // TODO: half page uint32_t val; uint32_t flash_regs_base; uint32_t pagesize; @@ -2852,32 +2837,6 @@ int stlink_write_flash( pagesize = L1_WRITE_BLOCK_SIZE; } - // TODO: check write operation - - // 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)) { - fprintf(stderr, "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)) { - fprintf(stderr, "pecr.prglock not clear\n"); - return(-1); - } - off = 0; if (len > pagesize) { @@ -2892,9 +2851,7 @@ int stlink_write_flash( // write remaining word in program memory for ( ; off < len; off += sizeof(uint32_t)) { uint32_t data; - - if (off > 254) { fprintf(stdout, "\r"); } - + if ((off % sl->flash_pgsz) > (sl->flash_pgsz - 5)) { fprintf(stdout, "\r%3u/%3u pages written", (unsigned int)(off / sl->flash_pgsz), @@ -2912,29 +2869,13 @@ int stlink_write_flash( // TODO: check redo write operation } - fprintf(stdout, "\n"); - // 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_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { - ILOG("Starting Flash write for VL/F0/F3/F1_XL core id\n"); - - // flash loader initialisation - if (stlink_flash_loader_init(sl, &fl) == -1) { - ELOG("stlink_flash_loader_init() == -1\n"); - return(-1); - } - int write_block_count = 0; - for (off = 0; off < len; off += sl->flash_pgsz) { // adjust last write size - size_t size = sl->flash_pgsz; - - if ((off + sl->flash_pgsz) > len) { size = len - off; } + size_t size = len - off > sl->flash_pgsz ? sl->flash_pgsz : len - off; // unlock and set programming mode unlock_flash_if(sl); @@ -2943,7 +2884,7 @@ int stlink_write_flash( DLOG("Finished unlocking flash, running loader!\n"); - if (stlink_flash_loader_run(sl, &fl, addr + (uint32_t)off, base + off, size) == -1) { + if (stlink_flash_loader_run(sl, fl, addr + (uint32_t)off, base + off, size) == -1) { ELOG("stlink_flash_loader_run(%#zx) failed! == -1\n", addr + off); return(-1); } @@ -2952,19 +2893,15 @@ int stlink_write_flash( if (sl->verbose >= 1) { // show progress; writing procedure is slow and previous errors are misleading - fprintf(stdout, "\r%3u/%lu pages written", ++write_block_count, - (unsigned long)((len + sl->flash_pgsz - 1) / sl->flash_pgsz)); + fprintf(stdout, "\r%3u/%3u pages written", ++write_block_count, + (unsigned int)((len + sl->flash_pgsz - 1) / sl->flash_pgsz)); fflush(stdout); } } - - fprintf(stdout, "\n"); + if (sl->verbose >= 1) { + fprintf(stdout, "\n"); + } } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - ILOG("Starting Flash write for H7 core id\n"); - - unlock_flash_if(sl); // unlock the cr - set_flash_cr_pg(sl); // set programming mode - for (off = 0; off < len;) { // Program STM32H7x with 32-byte Flash words size_t chunk = (len - off > 32) ? 32 : len - off; @@ -2980,15 +2917,110 @@ int stlink_write_flash( fflush(stdout); } } - fprintf(stdout, "\n"); + if (sl->verbose >= 1) { + fprintf(stdout, "\n"); + } + } else { + return(-1); + } + + return(0); +} + +int stlink_flashloader_stop(stlink_t *sl) { + 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); lock_flash(sl); - } else { - ELOG("unknown coreid, not sure how to write: %x\n", sl->core_id); + } 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); + } + + 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 (%zd bytes), not supported, " + "check page start address and compare with flash module organisation " + "in related ST reference manual of your device.\n", 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(%#zx) == -1\n", 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 %d (%#x) bytes\n", + page_count, sl->flash_pgsz, 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); + if (ret) + return ret; + return(stlink_verify_write_flash(sl, addr, base, len)); } diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index c832098f1..5e8a2549e 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -847,13 +847,31 @@ static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { static int flash_go(stlink_t *sl) { int error = -1; - + int ret; + flash_loader_t fl; + // some kinds of clock settings do not allow writing to flash. stlink_reset(sl); stlink_force_debug(sl); for (struct flash_block* fb = flash_root; fb; fb = fb->next) { - DLOG("flash_do: block %08x -> %04x\n", fb->addr, fb->length); + ILOG("flash_erase: block %08x -> %04x\n", fb->addr, fb->length); + + for (stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += (uint32_t)FLASH_PAGE) { + // update FLASH_PAGE + stlink_calculate_pagesize(sl, page); + + ILOG("flash_erase: page %08x\n", page); + ret = stlink_erase_flash_page(sl, page); + if (ret < 0) { goto error; } + } + } + + ret = stlink_flashloader_start(sl, &fl); + if (ret < 0) { goto error; } + + for (struct flash_block* fb = flash_root; fb; fb = fb->next) { + ILOG("flash_do: block %08x -> %04x\n", fb->addr, fb->length); for (stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += (uint32_t)FLASH_PAGE) { unsigned length = fb->length - (page - fb->addr); @@ -861,14 +879,14 @@ static int flash_go(stlink_t *sl) { // update FLASH_PAGE stlink_calculate_pagesize(sl, page); - DLOG("flash_do: page %08x\n", page); + ILOG("flash_do: page %08x\n", page); unsigned len = (length > FLASH_PAGE) ? (unsigned int)FLASH_PAGE : length; - int ret = stlink_write_flash(sl, page, fb->data + (page - fb->addr), len, 0); - + ret = stlink_flashloader_write(sl, &fl, page, fb->data + (page - fb->addr), len); if (ret < 0) { goto error; } } } + stlink_flashloader_stop(sl); stlink_reset(sl); error = 0; From a7ea06d7d9b44e9033de68980b4ae2816b13a435 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Tue, 3 Nov 2020 10:23:07 +0500 Subject: [PATCH 05/19] Remove duplicate register definitions --- inc/stlink.h | 19 ------------------- src/stlink-lib/reg.h | 13 +++++++++++-- src/stlink-lib/usb.c | 8 ++++---- 3 files changed, 15 insertions(+), 25 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index e78b9569f..c4466b10b 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -83,25 +83,6 @@ enum target_state { #define STLINK_V3_MAX_FREQ_NB 10 -/* Cortex Debug Control Block */ -#define DCB_DHCSR 0xE000EDF0 -#define DCB_DCRSR 0xE000EDF4 -#define DCB_DCRDR 0xE000EDF8 -#define DCB_DEMCR 0xE000EDFC - -/* DCB_DHCSR bit and field definitions */ -#define DBGKEY (0xA05F << 16) -#define C_DEBUGEN (1 << 0) -#define C_HALT (1 << 1) -#define C_STEP (1 << 2) -#define C_MASKINTS (1 << 3) -#define S_REGRDY (1 << 16) -#define S_HALT (1 << 17) -#define S_SLEEP (1 << 18) -#define S_LOCKUP (1 << 19) -#define S_RETIRE_ST (1 << 24) -#define S_RESET_ST (1 << 25) - /* Map the relevant features, quirks and workaround for specific firmware version of stlink */ #define STLINK_F_HAS_TRACE (1 << 0) #define STLINK_F_HAS_SWD_SET_FREQ (1 << 1) diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index 653852440..926480648 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -16,8 +16,17 @@ /* Cortex™-M3 Technical Reference Manual */ /* Debug Halting Control and Status Register */ #define STLINK_REG_DHCSR 0xe000edf0 -#define STLINK_REG_DHCSR_DBGKEY 0xa05f0000 -#define STLINK_REG_DHCSR_S_RESET_ST 0x02000000 +#define STLINK_REG_DHCSR_DBGKEY (0xA05F << 16) +#define STLINK_REG_DHCSR_C_DEBUGEN (1 << 0) +#define STLINK_REG_DHCSR_C_HALT (1 << 1) +#define STLINK_REG_DHCSR_C_STEP (1 << 2) +#define STLINK_REG_DHCSR_C_MASKINTS (1 << 3) +#define STLINK_REG_DHCSR_S_REGRDY (1 << 16) +#define STLINK_REG_DHCSR_S_HALT (1 << 17) +#define STLINK_REG_DHCSR_S_SLEEP (1 << 18) +#define STLINK_REG_DHCSR_S_LOCKUP (1 << 19) +#define STLINK_REG_DHCSR_S_RETIRE_ST (1 << 24) +#define STLINK_REG_DHCSR_S_RESET_ST (1 << 25) #define STLINK_REG_DCRSR 0xe000edf4 #define STLINK_REG_DCRDR 0xe000edf8 diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 6b914d805..4e805a709 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -385,15 +385,15 @@ int _stlink_usb_status_v2(stlink_t *sl) { int result; uint32_t status = 0; - result = _stlink_usb_read_debug32(sl, DCB_DHCSR, &status); + result = _stlink_usb_read_debug32(sl, STLINK_REG_DHCSR, &status); DLOG("core status: %08X\n", status); if (result != 0) { sl->core_stat = TARGET_UNKNOWN; } else { - if (status & S_HALT) { + if (status & STLINK_REG_DHCSR_C_HALT) { sl->core_stat = TARGET_HALTED; - } else if (status & S_RESET_ST) { + } else if (status & STLINK_REG_DHCSR_S_RESET_ST) { sl->core_stat = TARGET_RESET; } else { sl->core_stat = TARGET_RUNNING; @@ -616,7 +616,7 @@ int _stlink_usb_run(stlink_t* sl) { int res; if (sl->version.jtag_api != STLINK_JTAG_API_V1) { - res = _stlink_usb_write_debug32(sl, DCB_DHCSR, DBGKEY | C_DEBUGEN); + res = _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_DEBUGEN); return(res); } From 922eba585b47d7ce5814a83fd96409c98acd9e6b Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Tue, 3 Nov 2020 12:19:47 +0500 Subject: [PATCH 06/19] Optimized timeout of the chip reset function --- CMakeLists.txt | 12 ++++++++++++ src/stlink-lib/helper.c | 13 +++++++++++++ src/stlink-lib/helper.h | 6 ++++++ src/stlink-lib/usb.c | 21 ++++++++++----------- src/win32/sys_time.c | 20 ++++++++++++++++++++ src/win32/sys_time.h | 30 ++++++++++++++++++++++++++++++ 6 files changed, 91 insertions(+), 11 deletions(-) create mode 100644 src/stlink-lib/helper.c create mode 100644 src/stlink-lib/helper.h create mode 100644 src/win32/sys_time.c create mode 100644 src/win32/sys_time.h diff --git a/CMakeLists.txt b/CMakeLists.txt index fae458dd7..4ab43271e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,6 +60,11 @@ if (STLINK_HAVE_SYS_MMAN_H) add_definitions(-DSTLINK_HAVE_SYS_MMAN_H) endif() +CHECK_INCLUDE_FILE(sys/time.h STLINK_HAVE_SYS_TIME_H) +if (STLINK_HAVE_SYS_TIME_H) + add_definitions(-DSTLINK_HAVE_SYS_TIME_H) +endif() + CHECK_INCLUDE_FILE(unistd.h STLINK_HAVE_UNISTD_H) if (STLINK_HAVE_UNISTD_H) add_definitions(-DSTLINK_HAVE_UNISTD_H) @@ -104,6 +109,7 @@ set(STLINK_HEADERS src/stlink-lib/md5.h src/stlink-lib/sg.h src/stlink-lib/usb.h + src/stlink-lib/helper.h ) set(STLINK_SOURCE @@ -114,6 +120,7 @@ set(STLINK_SOURCE src/stlink-lib/md5.c src/stlink-lib/sg.c src/stlink-lib/usb.c + src/stlink-lib/helper.c ) if (WIN32) @@ -132,6 +139,11 @@ if (WIN32) set(STLINK_SOURCE "${STLINK_SOURCE};src/win32/mmap.c") set(STLINK_HEADERS "${STLINK_HEADERS};src/win32/mmap.h") endif() + + if (NOT STLINK_HAVE_SYS_TIME_H) + set(STLINK_SOURCE "${STLINK_SOURCE};src/win32/sys_time.c") + set(STLINK_HEADERS "${STLINK_HEADERS};src/win32/sys_time.h") + endif() endif () ## Include test execution for test-targets for target Debug diff --git a/src/stlink-lib/helper.c b/src/stlink-lib/helper.c new file mode 100644 index 000000000..50c55230b --- /dev/null +++ b/src/stlink-lib/helper.c @@ -0,0 +1,13 @@ +#include + +#ifdef STLINK_HAVE_SYS_TIME_H +#include +#else +#include +#endif + +unsigned time_ms() { + struct timeval tv; + gettimeofday(&tv, NULL); + return (unsigned)tv.tv_sec * 1000 + tv.tv_usec / 1000; +} diff --git a/src/stlink-lib/helper.h b/src/stlink-lib/helper.h new file mode 100644 index 000000000..defd0504b --- /dev/null +++ b/src/stlink-lib/helper.h @@ -0,0 +1,6 @@ +#ifndef SYS_HELPER_H +#define SYS_HELPER_H + +unsigned time_ms(); + +#endif SYS_HELPER_H diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 4e805a709..b502ca2a6 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -17,6 +17,7 @@ #endif #include +#include #include "usb.h" enum SCSI_Generic_Direction {SG_DXFER_TO_DEV = 0, SG_DXFER_FROM_DEV = 0x80}; @@ -509,10 +510,10 @@ int _stlink_usb_reset(stlink_t * sl) { unsigned char* const cmd = sl->c_buf; ssize_t size; uint32_t dhcsr; - int ret, i, rep_len = 2; + int ret, timeout, i, rep_len = 2; // clear S_RESET_ST in DHCSR registr - stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + _stlink_usb_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); // send reset command i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); @@ -534,14 +535,14 @@ int _stlink_usb_reset(stlink_t * sl) { usleep(10000); dhcsr = 0; - ret = stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + ret = _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"); - ret = stlink_write_debug32(sl, STLINK_REG_AIRCR, STLINK_REG_AIRCR_VECTKEY | + ret = _stlink_usb_write_debug32(sl, STLINK_REG_AIRCR, STLINK_REG_AIRCR_VECTKEY | STLINK_REG_AIRCR_SYSRESETREQ); if (ret) return(ret); @@ -550,18 +551,16 @@ int _stlink_usb_reset(stlink_t * sl) { } // waiting for a reset within 500ms - for (i=0; i<50; i++) { + 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); + _stlink_usb_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); if ((dhcsr&STLINK_REG_DHCSR_S_RESET_ST) == 0) - break; - usleep(10000); + return(0); } - if (i >= 50) - return(-1); - return(0); + return(-1); } int _stlink_usb_jtag_reset(stlink_t * sl, int value) { diff --git a/src/win32/sys_time.c b/src/win32/sys_time.c new file mode 100644 index 000000000..ea7c25dda --- /dev/null +++ b/src/win32/sys_time.c @@ -0,0 +1,20 @@ +#include +#include + +#include "sys_time.h" + +/* Simple gettimeofday implementation without converting Windows time to Linux time */ +int gettimeofday(struct timeval *tv, struct timezone *tz) { + FILETIME ftime; + ULARGE_INTEGER ulint; + + GetSystemTimeAsFileTime(&ftime); + ulint.LowPart = ftime.dwLowDateTime; + ulint.HighPart = ftime.dwHighDateTime; + + tv->tv_sec = (long)(ulint.QuadPart / 10000000L); + tv->tv_usec = (long)(ulint.QuadPart % 10000000L); + + return 0; + (void)tz; +} diff --git a/src/win32/sys_time.h b/src/win32/sys_time.h new file mode 100644 index 000000000..87c3a42fd --- /dev/null +++ b/src/win32/sys_time.h @@ -0,0 +1,30 @@ +#ifndef STLINK_TIME_H +#define STLINK_TIME_H + +#ifdef STLINK_HAVE_SYS_TIME_H +#include +#else + +struct timeval { + long tv_sec; + long tv_usec; +}; + +struct timezone { + int tz_minuteswest; + int tz_dsttime; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +int gettimeofday(struct timeval *tv, struct timezone *tz); + +#ifdef __cplusplus +} +#endif + +#endif /* STLINK_HAVE_SYS_TIME_H */ + +#endif /* STLINK_TIME_H */ From ddd39354b545f6176345cce8f2d520bd109dcbe7 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Tue, 3 Nov 2020 14:49:19 +0500 Subject: [PATCH 07/19] Trying to use a soft reset before starting debugging --- inc/stlink.h | 1 + src/common.c | 50 ++++++++++++++++++++++++++++++++++++---- src/st-util/gdb-server.c | 13 +++++++---- src/stlink-lib/reg.h | 2 ++ 4 files changed, 57 insertions(+), 9 deletions(-) diff --git a/inc/stlink.h b/inc/stlink.h index c4466b10b..2ec2db367 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -223,6 +223,7 @@ 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_run(stlink_t *sl); int stlink_status(stlink_t *sl); int stlink_version(stlink_t *sl); diff --git a/src/common.c b/src/common.c index 71caeeaa8..ed3f7b222 100644 --- a/src/common.c +++ b/src/common.c @@ -1416,6 +1416,48 @@ int stlink_jtag_reset(stlink_t *sl, int value) { return(sl->backend->jtag_reset(sl, value)); } +int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { + int ret; + uint32_t dhcsr, demcr; + + DLOG("*** stlink_soft_reset ***\n"); + + // halt core and enable debugging (if not already done) + // C_DEBUGEN is required to Halt on reset (DDI0337E, p. 10-6) + _stlink_usb_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) + stlink_read_debug32(sl, STLINK_REG_CM3_DEMCR, &demcr); + if (halt_on_reset) { + demcr |= STLINK_REG_CM3_DEMCR_TRCENA | STLINK_REG_CM3_DEMCR_VC_CORERESET; + } else { + demcr &= ~STLINK_REG_CM3_DEMCR_VC_CORERESET; + } + stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, demcr); + + // clear S_RESET_ST in 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) + return(ret); + + // 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_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + if ((dhcsr&STLINK_REG_DHCSR_S_RESET_ST) == 0) + return(0); + } + + return(-1); +} + int stlink_run(stlink_t *sl) { DLOG("*** stlink_run ***\n"); return(sl->backend->run(sl)); @@ -2899,8 +2941,8 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr } } if (sl->verbose >= 1) { - fprintf(stdout, "\n"); - } + fprintf(stdout, "\n"); + } } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { for (off = 0; off < len;) { // Program STM32H7x with 32-byte Flash words @@ -2918,8 +2960,8 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr } } if (sl->verbose >= 1) { - fprintf(stdout, "\n"); - } + fprintf(stdout, "\n"); + } } else { return(-1); } diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 5e8a2549e..4eca5819e 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -591,9 +591,9 @@ static void init_data_watchpoints(stlink_t *sl) { uint32_t data; DLOG("init watchpoints\n"); + // set TRCENA in debug command to turn on DWT unit stlink_read_debug32(sl, STLINK_REG_CM3_DEMCR, &data); - data |= 1 << 24; - // set TRCENA in debug command to turn on DWT unit + data |= STLINK_REG_CM3_DEMCR_TRCENA; stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, data); // make sure all watchpoints are cleared @@ -887,7 +887,7 @@ static int flash_go(stlink_t *sl) { } stlink_flashloader_stop(sl); - stlink_reset(sl); + //stlink_reset(sl); error = 0; error: @@ -1804,13 +1804,16 @@ int serve(stlink_t *sl, st_state_t *st) { case 'R': { // reset the core. - ret = stlink_reset(sl); - + ret = stlink_soft_reset(sl, 1 /* halt on reset */); if (ret) { DLOG("R packet : stlink_reset failed\n"); } init_code_breakpoints(sl); init_data_watchpoints(sl); + if (stlink_status(sl) == TARGET_HALTED) { + stlink_run(sl); + } + attached = 1; reply = strdup("OK"); diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index 926480648..d9323a042 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -9,6 +9,8 @@ #define STLINK_REG_CM7_FP_LAR_KEY 0xC5ACCE55 #define STLINK_REG_CM3_DEMCR 0xE000EDFC +#define STLINK_REG_CM3_DEMCR_TRCENA (1 << 24) +#define STLINK_REG_CM3_DEMCR_VC_CORERESET (1 << 0) #define STLINK_REG_CM3_DWT_COMPn(n) (0xE0001020 + n*16) #define STLINK_REG_CM3_DWT_MASKn(n) (0xE0001024 + n*16) #define STLINK_REG_CM3_DWT_FUNn(n) (0xE0001028 + n*16) From b401eaff9a144f973f44f5914a70fc82da36d39f Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Thu, 5 Nov 2020 16:57:30 +0500 Subject: [PATCH 08/19] Improve soft reset with core halt --- src/common.c | 58 +++++++++++++++++++++++++++++----------- src/st-util/gdb-server.c | 22 +++++++-------- src/stlink-lib/helper.c | 2 ++ src/stlink-lib/helper.h | 2 +- src/stlink-lib/reg.h | 13 +++++++-- src/stlink-lib/usb.c | 14 ++++------ 6 files changed, 71 insertions(+), 40 deletions(-) diff --git a/src/common.c b/src/common.c index ed3f7b222..cdf0fa497 100644 --- a/src/common.c +++ b/src/common.c @@ -14,6 +14,7 @@ #include #include #include +#include #ifdef STLINK_HAVE_SYS_MMAN_H #include @@ -1418,44 +1419,71 @@ int stlink_jtag_reset(stlink_t *sl, int value) { int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { int ret; - uint32_t dhcsr, demcr; + unsigned timeout; + uint32_t dhcsr, dfsr; - DLOG("*** stlink_soft_reset ***\n"); + ELOG("*** 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_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | + 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) - stlink_read_debug32(sl, STLINK_REG_CM3_DEMCR, &demcr); if (halt_on_reset) { - demcr |= STLINK_REG_CM3_DEMCR_TRCENA | STLINK_REG_CM3_DEMCR_VC_CORERESET; + 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 { - demcr &= ~STLINK_REG_CM3_DEMCR_VC_CORERESET; + 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_write_debug32(sl, STLINK_REG_CM3_DEMCR, demcr); - // clear S_RESET_ST in DHCSR register + // 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) + 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) - return(0); + 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; + } } - return(-1); + // 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_run(stlink_t *sl) { @@ -2735,7 +2763,7 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { if (voltage == -1) { ELOG("Failed to read Target voltage\n"); - return(voltage); + return(-1); } if (sl->flash_type == STLINK_FLASH_TYPE_L4) { diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 4eca5819e..d69ac0626 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -591,7 +591,7 @@ static void init_data_watchpoints(stlink_t *sl) { uint32_t data; DLOG("init watchpoints\n"); - // set TRCENA in debug command to turn on DWT unit + // set TRCENA in debug command to turn on DWT unit stlink_read_debug32(sl, STLINK_REG_CM3_DEMCR, &data); data |= STLINK_REG_CM3_DEMCR_TRCENA; stlink_write_debug32(sl, STLINK_REG_CM3_DEMCR, data); @@ -849,7 +849,7 @@ static int flash_go(stlink_t *sl) { int error = -1; int ret; flash_loader_t fl; - + // some kinds of clock settings do not allow writing to flash. stlink_reset(sl); stlink_force_debug(sl); @@ -863,12 +863,12 @@ static int flash_go(stlink_t *sl) { ILOG("flash_erase: page %08x\n", page); ret = stlink_erase_flash_page(sl, page); - if (ret < 0) { goto error; } + if (ret) { goto error; } } } ret = stlink_flashloader_start(sl, &fl); - if (ret < 0) { goto error; } + if (ret) { goto error; } for (struct flash_block* fb = flash_root; fb; fb = fb->next) { ILOG("flash_do: block %08x -> %04x\n", fb->addr, fb->length); @@ -882,12 +882,12 @@ static int flash_go(stlink_t *sl) { ILOG("flash_do: page %08x\n", page); unsigned len = (length > FLASH_PAGE) ? (unsigned int)FLASH_PAGE : length; ret = stlink_flashloader_write(sl, &fl, page, fb->data + (page - fb->addr), len); - if (ret < 0) { goto error; } + if (ret) { goto error; } } } stlink_flashloader_stop(sl); - //stlink_reset(sl); + stlink_soft_reset(sl, 1 /* halt on reset */); error = 0; error: @@ -1390,8 +1390,8 @@ int serve(stlink_t *sl, st_state_t *st) { free(decoded); } else if (!strcmp(cmdName, "FlashDone")) { - if (flash_go(sl) < 0) { - reply = strdup("E00"); + if (flash_go(sl)) { + reply = strdup("E08"); } else { reply = strdup("OK"); } @@ -1804,16 +1804,12 @@ int serve(stlink_t *sl, st_state_t *st) { case 'R': { // reset the core. - ret = stlink_soft_reset(sl, 1 /* halt on reset */); + ret = stlink_reset(sl); if (ret) { DLOG("R packet : stlink_reset failed\n"); } init_code_breakpoints(sl); init_data_watchpoints(sl); - if (stlink_status(sl) == TARGET_HALTED) { - stlink_run(sl); - } - attached = 1; reply = strdup("OK"); diff --git a/src/stlink-lib/helper.c b/src/stlink-lib/helper.c index 50c55230b..8b2c8e8f7 100644 --- a/src/stlink-lib/helper.c +++ b/src/stlink-lib/helper.c @@ -1,5 +1,7 @@ #include +#include + #ifdef STLINK_HAVE_SYS_TIME_H #include #else diff --git a/src/stlink-lib/helper.h b/src/stlink-lib/helper.h index defd0504b..12c2ea2a7 100644 --- a/src/stlink-lib/helper.h +++ b/src/stlink-lib/helper.h @@ -3,4 +3,4 @@ unsigned time_ms(); -#endif SYS_HELPER_H +#endif /* SYS_HELPER_H */ diff --git a/src/stlink-lib/reg.h b/src/stlink-lib/reg.h index d9323a042..2e93dc5b1 100644 --- a/src/stlink-lib/reg.h +++ b/src/stlink-lib/reg.h @@ -10,6 +10,8 @@ #define STLINK_REG_CM3_DEMCR 0xE000EDFC #define STLINK_REG_CM3_DEMCR_TRCENA (1 << 24) +#define STLINK_REG_CM3_DEMCR_VC_HARDERR (1 << 10) +#define STLINK_REG_CM3_DEMCR_VC_BUSERR (1 << 8) #define STLINK_REG_CM3_DEMCR_VC_CORERESET (1 << 0) #define STLINK_REG_CM3_DWT_COMPn(n) (0xE0001020 + n*16) #define STLINK_REG_CM3_DWT_MASKn(n) (0xE0001024 + n*16) @@ -17,6 +19,12 @@ /* Cortex™-M3 Technical Reference Manual */ /* Debug Halting Control and Status Register */ +#define STLINK_REG_DFSR 0xE000ED30 +#define STLINK_REG_DFSR_HALT (1 << 0) +#define STLINK_REG_DFSR_BKPT (1 << 1) +#define STLINK_REG_DFSR_VCATCH (1 << 3) +#define STLINK_REG_DFSR_EXTERNAL (1 << 4) +#define STLINK_REG_DFSR_CLEAR 0x0000001F #define STLINK_REG_DHCSR 0xe000edf0 #define STLINK_REG_DHCSR_DBGKEY (0xA05F << 16) #define STLINK_REG_DHCSR_C_DEBUGEN (1 << 0) @@ -34,8 +42,9 @@ /* Application Interrupt and Reset Control Register */ #define STLINK_REG_AIRCR 0xe000ed0c -#define STLINK_REG_AIRCR_VECTKEY 0x05fa0000 -#define STLINK_REG_AIRCR_SYSRESETREQ 0x00000004 +#define STLINK_REG_AIRCR_VECTKEY 0x05fa0000 +#define STLINK_REG_AIRCR_SYSRESETREQ 0x00000004 +#define STLINK_REG_AIRCR_VECTRESET 0x00000001 /* ARM Cortex-M7 Processor Technical Reference Manual */ /* Cache Control and Status Register */ diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index b502ca2a6..7909a4e69 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -510,7 +510,8 @@ int _stlink_usb_reset(stlink_t * sl) { unsigned char* const cmd = sl->c_buf; ssize_t size; uint32_t dhcsr; - int ret, timeout, i, rep_len = 2; + unsigned timeout; + int i, rep_len = 2; // clear S_RESET_ST in DHCSR registr _stlink_usb_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); @@ -535,19 +536,14 @@ int _stlink_usb_reset(stlink_t * sl) { usleep(10000); dhcsr = 0; - ret = _stlink_usb_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + _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"); - ret = _stlink_usb_write_debug32(sl, STLINK_REG_AIRCR, STLINK_REG_AIRCR_VECTKEY | - STLINK_REG_AIRCR_SYSRESETREQ); - if (ret) - return(ret); - - usleep(10000); + return stlink_soft_reset(sl, 0); } // waiting for a reset within 500ms From 85f0e939111d7350bdd40746161da7ef656d5151 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Thu, 5 Nov 2020 17:00:48 +0500 Subject: [PATCH 09/19] Add switch to Thumb mode before starting flash loader --- src/stlink-lib/flash_loader.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 7de485ca3..c86aefbf7 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -316,6 +316,8 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe int i = 0; size_t count = 0; uint32_t flash_base = 0; + const char *error = NULL; + uint32_t dhcsr, dfsr; DLOG("Running flash loader, write address:%#x, size: %u\n", target, (unsigned int)size); @@ -354,6 +356,13 @@ 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 + /* Make sure we are in Thumb mode */ + 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); + } + /* Run loader */ stlink_run(sl); @@ -376,17 +385,26 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe } if (i >= WAIT_ROUNDS) { - ELOG("flash loader run error\n"); - return(-1); + error = "Flash loader run error"; + goto error; } // check written byte count stlink_read_reg(sl, 2, &rr); if (rr.r[2] != 0) { - ELOG("write error, count == %u\n", rr.r[2]); - return(-1); + error = "Write error"; + goto error; } return(0); + +error: + dhcsr = dfsr = 0; + stlink_read_debug32(sl, STLINK_REG_DHCSR, &dhcsr); + stlink_read_debug32(sl, STLINK_REG_DFSR, &dfsr); + 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); + + return(-1); } From 0135a0ea162e72a6d15de768140522078bb6bf81 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Thu, 5 Nov 2020 18:50:10 +0500 Subject: [PATCH 10/19] Expand and simplify stlink V2 + support --- src/stlink-lib/usb.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 7909a4e69..92ad4cbc5 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -262,7 +262,7 @@ int _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { } int _stlink_usb_get_rw_status(stlink_t *sl) { - if (sl->version.jtag_api == STLINK_JTAG_API_V1) { return(-1); } + if (sl->version.jtag_api == STLINK_JTAG_API_V1) { return(0); } unsigned char* const rdata = sl->q_buf; struct stlink_libusb * const slu = sl->backend_data; @@ -355,15 +355,17 @@ int _stlink_usb_core_id(stlink_t * sl) { unsigned char* const cmd = sl->c_buf; unsigned char* const data = sl->q_buf; ssize_t size; - int rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 4 : 12; + int offset, rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 4 : 12; int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; if (sl->version.jtag_api == STLINK_JTAG_API_V1) { cmd[i++] = STLINK_DEBUG_READCOREID; + offset = 0; } else { cmd[i++] = STLINK_DEBUG_APIV2_READ_IDCODES; + offset = 4; } size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); @@ -373,11 +375,7 @@ int _stlink_usb_core_id(stlink_t * sl) { return(-1); } - if (sl->version.jtag_api == STLINK_JTAG_API_V1) { - sl->core_id = read_uint32(data, 0); - } else { - sl->core_id = read_uint32(data, 4); - } + sl->core_id = read_uint32(data, offset); return(0); } @@ -440,6 +438,14 @@ int _stlink_usb_status(stlink_t * sl) { int _stlink_usb_force_debug(stlink_t *sl) { struct stlink_libusb *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_HALT | STLINK_REG_DHCSR_C_DEBUGEN); + return(res); + } + unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; ssize_t size; @@ -583,6 +589,17 @@ int _stlink_usb_jtag_reset(stlink_t * sl, int value) { int _stlink_usb_step(stlink_t* sl) { struct stlink_libusb * const slu = sl->backend_data; + + if (sl->version.jtag_api != STLINK_JTAG_API_V1) { + // emulates the JTAG v1 API by using DHCSR + _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | + STLINK_REG_DHCSR_C_MASKINTS | STLINK_REG_DHCSR_C_DEBUGEN); + _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_STEP | + STLINK_REG_DHCSR_C_MASKINTS | STLINK_REG_DHCSR_C_DEBUGEN); + return _stlink_usb_write_debug32(sl, STLINK_REG_DHCSR, STLINK_REG_DHCSR_DBGKEY | STLINK_REG_DHCSR_C_HALT | + STLINK_REG_DHCSR_C_DEBUGEN); + } + unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; ssize_t size; @@ -792,11 +809,11 @@ int _stlink_usb_read_all_regs(stlink_t *sl, struct stlink_reg *regp) { if (sl->verbose < 2) { return(0); } - DLOG("xpsr = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 64)); - DLOG("main_sp = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 68)); - DLOG("process_sp = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 72)); - DLOG("rw = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 76)); - DLOG("rw2 = 0x%08x\n", read_uint32(sl->q_buf, reg_offset + 80)); + DLOG("xpsr = 0x%08x\n", regp->xpsr); + DLOG("main_sp = 0x%08x\n", regp->main_sp); + DLOG("process_sp = 0x%08x\n", regp->process_sp); + DLOG("rw = 0x%08x\n", regp->rw); + DLOG("rw2 = 0x%08x\n", regp->rw2); return(0); } From f3c824c83e10548b89513b12f55f113452259a97 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Thu, 5 Nov 2020 18:54:03 +0500 Subject: [PATCH 11/19] More robust fw flash by gdb --- src/common.c | 2 +- src/st-util/gdb-server.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/common.c b/src/common.c index cdf0fa497..89f27aa66 100644 --- a/src/common.c +++ b/src/common.c @@ -1422,7 +1422,7 @@ int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { unsigned timeout; uint32_t dhcsr, dfsr; - ELOG("*** stlink_soft_reset %s***\n", halt_on_reset?"(halt) ":""); + 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) diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index d69ac0626..63ba68fcf 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -853,6 +853,8 @@ static int flash_go(stlink_t *sl) { // some kinds of clock settings do not allow writing to flash. stlink_reset(sl); 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); From 43019fcde99b8e745a767b8e2c307d5868c09878 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Thu, 5 Nov 2020 19:34:22 +0500 Subject: [PATCH 12/19] Fix change SWD frequency of stlink v3 --- doc/dev/developer.txt | 2 +- inc/backend.h | 2 +- inc/stlink.h | 2 +- src/common.c | 4 +-- src/stlink-lib/usb.c | 68 +++++++++++++++++-------------------------- 5 files changed, 31 insertions(+), 47 deletions(-) diff --git a/doc/dev/developer.txt b/doc/dev/developer.txt index 32afd4352..9c4da22f7 100644 --- a/doc/dev/developer.txt +++ b/doc/dev/developer.txt @@ -300,7 +300,7 @@ Return: -1 for error. 0 for success. int stlink_current_mode(stlink_t *sl); int stlink_force_debug(stlink_t *sl); int stlink_target_voltage(stlink_t *sl); - int stlink_set_swdclk(stlink_t *sl, uint16_t divisor); + int stlink_set_swdclk(stlink_t *sl, int freq_khz); int stlink_erase_flash_mass(stlink_t* sl); int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); diff --git a/inc/backend.h b/inc/backend.h index f852da05d..d60708031 100644 --- a/inc/backend.h +++ b/inc/backend.h @@ -28,7 +28,7 @@ int (*current_mode) (stlink_t * stl); int (*force_debug) (stlink_t *sl); int32_t (*target_voltage) (stlink_t *sl); - int (*set_swdclk) (stlink_t * stl, uint16_t divisor); + int (*set_swdclk) (stlink_t * stl, int freq_khz); } stlink_backend_t; #endif // STLINK_BACKEND_H_ diff --git a/inc/stlink.h b/inc/stlink.h index 2ec2db367..7fce9d3dc 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -242,7 +242,7 @@ int stlink_step(stlink_t *sl); int stlink_current_mode(stlink_t *sl); int stlink_force_debug(stlink_t *sl); int stlink_target_voltage(stlink_t *sl); -int stlink_set_swdclk(stlink_t *sl, uint16_t divisor); +int stlink_set_swdclk(stlink_t *sl, int freq_khz); int stlink_erase_flash_mass(stlink_t* sl); int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly); diff --git a/src/common.c b/src/common.c index 89f27aa66..7321b39a4 100644 --- a/src/common.c +++ b/src/common.c @@ -1491,9 +1491,9 @@ int stlink_run(stlink_t *sl) { return(sl->backend->run(sl)); } -int stlink_set_swdclk(stlink_t *sl, uint16_t divisor) { +int stlink_set_swdclk(stlink_t *sl, int freq_khz) { DLOG("*** set_swdclk ***\n"); - return(sl->backend->set_swdclk(sl, divisor)); + return(sl->backend->set_swdclk(sl, freq_khz)); } int stlink_status(stlink_t *sl) { diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 92ad4cbc5..f5a91abf4 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -651,7 +651,7 @@ int _stlink_usb_run(stlink_t* sl) { return(0); } -int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { +int _stlink_usb_set_swdclk(stlink_t* sl, int clk_freq) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const data = sl->q_buf; unsigned char* const cmd = sl->c_buf; @@ -661,6 +661,28 @@ int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { // clock speed only supported by stlink/v2 and for firmware >= 22 if (sl->version.stlink_v == 2 && sl->version.jtag_v >= 22) { + uint16_t clk_divisor; + if (clk_freq) { + const uint32_t map[] = {5, 15, 25, 50, 100, 125, 240, 480, 950, 1200, 1800, 4000}; + int speed_index = _stlink_match_speed_map(map, STLINK_ARRAY_SIZE(map), clk_freq); + switch (map[speed_index]) { + case 5: clk_divisor = STLINK_SWDCLK_5KHZ_DIVISOR; break; + case 15: clk_divisor = STLINK_SWDCLK_15KHZ_DIVISOR; break; + case 25: clk_divisor = STLINK_SWDCLK_25KHZ_DIVISOR; break; + case 50: clk_divisor = STLINK_SWDCLK_50KHZ_DIVISOR; break; + case 100: clk_divisor = STLINK_SWDCLK_100KHZ_DIVISOR; break; + case 125: clk_divisor = STLINK_SWDCLK_125KHZ_DIVISOR; break; + case 240: clk_divisor = STLINK_SWDCLK_240KHZ_DIVISOR; break; + case 480: clk_divisor = STLINK_SWDCLK_480KHZ_DIVISOR; break; + case 950: clk_divisor = STLINK_SWDCLK_950KHZ_DIVISOR; break; + case 1200: clk_divisor = STLINK_SWDCLK_1P2MHZ_DIVISOR; break; + default: + case 1800: clk_divisor = STLINK_SWDCLK_1P8MHZ_DIVISOR; break; + case 4000: clk_divisor = STLINK_SWDCLK_4MHZ_DIVISOR; break; + } + } else + clk_divisor = STLINK_SWDCLK_1P8MHZ_DIVISOR; + i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; @@ -691,7 +713,6 @@ int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { } int speeds_size = data[8]; - if (speeds_size > STLINK_V3_MAX_FREQ_NB) { speeds_size = STLINK_V3_MAX_FREQ_NB; } @@ -701,7 +722,8 @@ int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) { // Set to zero all the next entries for (i = speeds_size; i < STLINK_V3_MAX_FREQ_NB; i++) map[i] = 0; - speed_index = _stlink_match_speed_map(map, STLINK_ARRAY_SIZE(map), 1800); + if (!clk_freq) clk_freq = 1800; // set default frequency + speed_index = _stlink_match_speed_map(map, STLINK_ARRAY_SIZE(map), clk_freq); i = fill_command(sl, SG_DXFER_FROM_DEV, 16); @@ -1228,45 +1250,7 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, int reset, char serial[STL // should be done at this speed too // set the stlink clock speed (default is 1800kHz) DLOG("JTAG/SWD freq set to %d\n", freq); - - switch (freq) { - case 5: - stlink_set_swdclk(sl, STLINK_SWDCLK_5KHZ_DIVISOR); - break; - case 15: - stlink_set_swdclk(sl, STLINK_SWDCLK_15KHZ_DIVISOR); - break; - case 25: - stlink_set_swdclk(sl, STLINK_SWDCLK_25KHZ_DIVISOR); - break; - case 50: - stlink_set_swdclk(sl, STLINK_SWDCLK_50KHZ_DIVISOR); - break; - case 100: - stlink_set_swdclk(sl, STLINK_SWDCLK_100KHZ_DIVISOR); - break; - case 125: - stlink_set_swdclk(sl, STLINK_SWDCLK_125KHZ_DIVISOR); - break; - case 240: - stlink_set_swdclk(sl, STLINK_SWDCLK_240KHZ_DIVISOR); - break; - case 480: - stlink_set_swdclk(sl, STLINK_SWDCLK_480KHZ_DIVISOR); - break; - case 950: - stlink_set_swdclk(sl, STLINK_SWDCLK_950KHZ_DIVISOR); - break; - case 1200: - stlink_set_swdclk(sl, STLINK_SWDCLK_1P2MHZ_DIVISOR); - break; - case 0: case 1800: - stlink_set_swdclk(sl, STLINK_SWDCLK_1P8MHZ_DIVISOR); - break; - case 4000: - stlink_set_swdclk(sl, STLINK_SWDCLK_4MHZ_DIVISOR); - break; - } + stlink_set_swdclk(sl, freq); if (reset == 2) { stlink_jtag_reset(sl, 0); From 2acfa8b8f2211d5d53e3e39fa79c90c56dd54409 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Thu, 5 Nov 2020 20:42:32 +0500 Subject: [PATCH 13/19] Add debug message of current CPU mode --- src/common.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/common.c b/src/common.c index 7321b39a4..8eb3370ef 100644 --- a/src/common.c +++ b/src/common.c @@ -1487,7 +1487,12 @@ int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { } int stlink_run(stlink_t *sl) { + struct stlink_reg rr; DLOG("*** stlink_run ***\n"); + + stlink_read_reg(sl, 16, &rr); + DLOG("Run in %s mode\n", (rr.xpsr & (1 << 24))?"ARM":"THUMB"); + return(sl->backend->run(sl)); } From 4e58872913acd4bcbef5ac9b63514cb04bba4727 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Fri, 6 Nov 2020 16:17:54 +0500 Subject: [PATCH 14/19] Add printing st-link version to st-info --- src/common.c | 2 +- src/st-info/info.c | 30 +++++++++++++++++++++++------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/common.c b/src/common.c index 8eb3370ef..d04d10049 100644 --- a/src/common.c +++ b/src/common.c @@ -1487,7 +1487,7 @@ int stlink_soft_reset(stlink_t *sl, int halt_on_reset) { } int stlink_run(stlink_t *sl) { - struct stlink_reg rr; + struct stlink_reg rr; DLOG("*** stlink_run ***\n"); stlink_read_reg(sl, 16, &rr); diff --git a/src/st-info/info.c b/src/st-info/info.c index 2343140de..4f2fae1eb 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -35,23 +35,36 @@ static void stlink_print_serial(stlink_t *sl, bool openocd) { printf("\n"); } +static void stlink_print_version(stlink_t *sl) { + // Implementation of version printing is minimalistic + // but contains all available information from sl->version + printf("V%d", sl->version.stlink_v); + if (sl->version.jtag_v > 0) + printf("J%d", sl->version.jtag_v); + if (sl->version.swim_v > 0) + printf("S%d", sl->version.swim_v); + printf("\n"); +} + static void stlink_print_info(stlink_t *sl) { const struct stlink_chipid_params *params = NULL; if (!sl) { return; } - printf(" serial: "); + printf(" version: "); + stlink_print_version(sl); + printf(" serial: "); stlink_print_serial(sl, false); - printf(" hla-serial: "); + printf(" hla-serial: "); stlink_print_serial(sl, true); - printf(" flash: %u (pagesize: %u)\n", + 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); - printf(" chipid: 0x%.4x\n", sl->chip_id); + printf(" sram: %u\n", (uint32_t)sl->sram_size); + printf(" chipid: 0x%.4x\n", sl->chip_id); params = stlink_chipid_get_params(sl->chip_id); - if (params) { printf(" descr: %s\n", params->description); } + if (params) { printf(" descr: %s\n", params->description); } } static void stlink_probe(void) { @@ -62,7 +75,10 @@ static void stlink_probe(void) { printf("Found %u stlink programmers\n", (unsigned int)size); - for (size_t n = 0; n < size; n++) { stlink_print_info(stdevs[n]); } + for (size_t n = 0; n < size; n++) { + if (size>1) printf("%lu.\n", n+1); + stlink_print_info(stdevs[n]); + } stlink_probe_usb_free(&stdevs, size); } From 277eee7aec00493151d940a12d697651e8977d66 Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Sat, 7 Nov 2020 13:50:14 +0500 Subject: [PATCH 15/19] Move check of current instruction mode to stlink_run --- src/common.c | 8 +++++++- src/stlink-lib/flash_loader.c | 7 ------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/common.c b/src/common.c index d04d10049..e3c4fdd2e 100644 --- a/src/common.c +++ b/src/common.c @@ -1490,8 +1490,14 @@ int stlink_run(stlink_t *sl) { 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); - DLOG("Run in %s mode\n", (rr.xpsr & (1 << 24))?"ARM":"THUMB"); + 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)); } diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index c86aefbf7..b7726e875 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -356,13 +356,6 @@ 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 - /* Make sure we are in Thumb mode */ - 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); - } - /* Run loader */ stlink_run(sl); From 54000d67acefd86df4bdb0594dee940dd04763fa Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Mon, 9 Nov 2020 13:41:51 +0500 Subject: [PATCH 16/19] H7 add support dual bank, mass erase and new chips --- inc/stm32.h | 2 + src/common.c | 400 ++++++++++++++++++++-------------------- src/stlink-lib/chipid.c | 31 +++- src/stlink-lib/chipid.h | 2 + 4 files changed, 239 insertions(+), 196 deletions(-) diff --git a/inc/stm32.h b/inc/stm32.h index 768fabb87..1ea0d1f04 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -14,6 +14,8 @@ /* 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) diff --git a/src/common.c b/src/common.c index e3c4fdd2e..0ac2d1153 100644 --- a/src/common.c +++ b/src/common.c @@ -30,6 +30,9 @@ #define __attribute__(x) #endif +#define BANK_1 0 +#define BANK_2 1 + /* 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) @@ -50,7 +53,6 @@ #define FLASH_SR2 (FLASH_REGS_ADDR + 0x4c) #define FLASH_CR2 (FLASH_REGS_ADDR + 0x50) #define FLASH_AR2 (FLASH_REGS_ADDR + 0x54) -#define FLASH_BANK2_START_ADDR 0x08080000 // For STM32F05x, the RDPTR_KEY may be wrong, but as it is not used anywhere... #define FLASH_RDPTR_KEY 0x00a5 @@ -307,12 +309,17 @@ #define FLASH_H7_CR_LOCK 0 #define FLASH_H7_CR_PG 1 #define FLASH_H7_CR_SER 2 +#define FLASH_H7_CR_BER 3 #define FLASH_H7_CR_PSIZE 4 -#define FLASH_H7_CR_START 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_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_OPTCR_OPTLOCK 0 #define FLASH_H7_OPTCR_OPTSTART 1 @@ -325,10 +332,17 @@ #define FLASH_H7_REGS_ADDR ((uint32_t)0x52002000) #define FLASH_H7_KEYR1 (FLASH_H7_REGS_ADDR + 0x04) +#define FLASH_H7_KEYR2 (FLASH_H7_REGS_ADDR + 0x104) #define FLASH_H7_OPT_KEYR (FLASH_H7_REGS_ADDR + 0x08) +#define FLASH_H7_OPT_KEYR2 (FLASH_H7_REGS_ADDR + 0x108) #define FLASH_H7_CR1 (FLASH_H7_REGS_ADDR + 0x0c) +#define FLASH_H7_CR2 (FLASH_H7_REGS_ADDR + 0x10c) #define FLASH_H7_SR1 (FLASH_H7_REGS_ADDR + 0x10) +#define FLASH_H7_SR2 (FLASH_H7_REGS_ADDR + 0x110) +#define FLASH_H7_CCR1 (FLASH_H7_REGS_ADDR + 0x14) +#define FLASH_H7_CCR2 (FLASH_H7_REGS_ADDR + 0x114) #define FLASH_H7_OPTCR (FLASH_H7_REGS_ADDR + 0x18) +#define FLASH_H7_OPTCR2 (FLASH_H7_REGS_ADDR + 0x118) #define FLASH_H7_OPTSR_CUR (FLASH_H7_REGS_ADDR + 0x1c) #define FLASH_H7_OPTCCR (FLASH_H7_REGS_ADDR + 0x24) @@ -397,7 +411,7 @@ static uint32_t __attribute__((unused)) read_flash_rdp(stlink_t *sl) { return(rdp & 0xff); } -static inline uint32_t read_flash_cr(stlink_t *sl) { +static inline uint32_t read_flash_cr(stlink_t *sl, unsigned bank) { uint32_t reg, res; if (sl->flash_type == STLINK_FLASH_TYPE_F4) { @@ -412,9 +426,9 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { reg = STM32WB_FLASH_CR; } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - reg = FLASH_H7_CR1; + reg = (bank == BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; } else { - reg = FLASH_CR; + reg = (bank == BANK_1)?FLASH_CR:FLASH_CR2; } stlink_read_debug32(sl, reg, &res); @@ -425,15 +439,6 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { return(res); } -static inline uint32_t read_flash_cr2(stlink_t *sl) { - uint32_t res; - stlink_read_debug32(sl, FLASH_CR2, &res); -#if DEBUG_FLASH - fprintf(stdout, "CR2:0x%x\n", res); -#endif - return(res); -} - static inline unsigned int is_flash_locked(stlink_t *sl) { /* return non zero for true */ uint32_t cr_lock_shift; @@ -476,7 +481,7 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { } static void unlock_flash(stlink_t *sl) { - uint32_t key_reg; + 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 @@ -484,9 +489,11 @@ static void unlock_flash(stlink_t *sl) { * An invalid sequence results in a definitive lock of the FPEC block until next reset. */ - if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || - (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { + 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) { @@ -504,6 +511,9 @@ static void unlock_flash(stlink_t *sl) { key_reg = STM32WB_FLASH_KEYR; } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { key_reg = FLASH_H7_KEYR1; + if (sl->has_dual_bank) { + key2_reg = FLASH_H7_KEYR2; + } } else { ELOG("unsupported flash method, abort\n"); return; @@ -512,9 +522,9 @@ static void unlock_flash(stlink_t *sl) { stlink_write_debug32(sl, key_reg, flash_key1); stlink_write_debug32(sl, key_reg, flash_key2); - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - stlink_write_debug32(sl, FLASH_KEYR2, flash_key1); - stlink_write_debug32(sl, FLASH_KEYR2, flash_key2); + if (key2_reg) { + stlink_write_debug32(sl, key2_reg, flash_key1); + stlink_write_debug32(sl, key2_reg, flash_key2); } } @@ -534,13 +544,16 @@ static int unlock_flash_if(stlink_t *sl) { } static void lock_flash(stlink_t *sl) { - uint32_t cr_lock_shift, cr_reg, n; + uint32_t cr_lock_shift, cr_reg, n, cr2_reg = 0; uint32_t cr_mask = 0xffffffffu; - if (sl->flash_type == STLINK_FLASH_TYPE_F0 || - sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { + 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; @@ -562,6 +575,9 @@ static void lock_flash(stlink_t *sl) { cr_lock_shift = STM32WB_FLASH_CR_LOCK; } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { cr_reg = FLASH_H7_CR1; + if (sl->has_dual_bank) { + cr2_reg = FLASH_H7_CR2; + } cr_lock_shift = FLASH_H7_CR_LOCK; cr_mask = ~(1u << FLASH_H7_CR_SER); } else { @@ -574,9 +590,9 @@ static void lock_flash(stlink_t *sl) { n |= (1u << cr_lock_shift); stlink_write_debug32(sl, cr_reg, n); - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - n = read_flash_cr2(sl) | (1u << cr_lock_shift); - stlink_write_debug32(sl, FLASH_CR2, n); + if (cr2_reg) { + n = read_flash_cr(sl, BANK_2) | (1u << cr_lock_shift); + stlink_write_debug32(sl, cr2_reg, n); } } @@ -637,7 +653,7 @@ static bool is_flash_option_locked(stlink_t *sl) { } static int lock_flash_option(stlink_t *sl) { - uint32_t optlock_shift, optcr_reg, n; + uint32_t optlock_shift, optcr_reg, n, optcr2_reg = 0; int active_bit_level = 1; switch (sl->flash_type) { @@ -675,6 +691,8 @@ static int lock_flash_option(stlink_t *sl) { case STLINK_FLASH_TYPE_H7: optcr_reg = FLASH_H7_OPTCR; optlock_shift = FLASH_H7_OPTCR_OPTLOCK; + if (sl->has_dual_bank) + optcr2_reg = FLASH_H7_OPTCR2; break; default: ELOG("unsupported flash method, abort\n"); @@ -690,11 +708,24 @@ static int lock_flash_option(stlink_t *sl) { } 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); + } else { + n |= (1u << optlock_shift); + } + + stlink_write_debug32(sl, optcr2_reg, n); + } + return(0); } static int unlock_flash_option(stlink_t *sl) { - uint32_t optkey_reg; + uint32_t optkey_reg, optkey2_reg = 0; uint32_t optkey1 = FLASH_OPTKEY1; uint32_t optkey2 = FLASH_OPTKEY2; @@ -728,6 +759,8 @@ static int unlock_flash_option(stlink_t *sl) { break; case STLINK_FLASH_TYPE_H7: optkey_reg = FLASH_H7_OPT_KEYR; + if (sl->has_dual_bank) + optkey2_reg = FLASH_H7_OPT_KEYR2; break; default: ELOG("unsupported flash method, abort\n"); @@ -736,6 +769,12 @@ static int unlock_flash_option(stlink_t *sl) { 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); } @@ -756,10 +795,10 @@ static int unlock_flash_option_if(stlink_t *sl) { return(0); } -static void set_flash_cr_pg(stlink_t *sl) { +static void set_flash_cr_pg(stlink_t *sl, unsigned bank) { uint32_t cr_reg, x; - x = read_flash_cr(sl); + x = read_flash_cr(sl, bank); if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; @@ -779,7 +818,7 @@ static void set_flash_cr_pg(stlink_t *sl) { cr_reg = STM32WB_FLASH_CR; x |= (1 << FLASH_CR_PG); } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = FLASH_H7_CR1; + cr_reg = (bank == BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; x |= (1 << FLASH_H7_CR_PG); } else { cr_reg = FLASH_CR; @@ -789,8 +828,9 @@ static void set_flash_cr_pg(stlink_t *sl) { stlink_write_debug32(sl, cr_reg, x); } -static void clear_flash_cr_pg(stlink_t *sl) { +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; @@ -803,15 +843,18 @@ static void clear_flash_cr_pg(stlink_t *sl) { 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) & ~(1 << FLASH_CR_PG); + n = read_flash_cr(sl, bank) & ~(1 << bit); stlink_write_debug32(sl, cr_reg, n); } -static void set_flash_cr_per(stlink_t *sl) { +static void set_flash_cr_per(stlink_t *sl, unsigned bank) { uint32_t cr_reg, val; if (sl->flash_type == STLINK_FLASH_TYPE_G0 || @@ -820,7 +863,7 @@ static void set_flash_cr_per(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; } else { - cr_reg = FLASH_CR; + cr_reg = (bank==BANK_1)?FLASH_CR:FLASH_CR2; } stlink_read_debug32(sl, cr_reg, &val); @@ -828,12 +871,7 @@ static void set_flash_cr_per(stlink_t *sl) { stlink_write_debug32(sl, cr_reg, val); } -static void set_flash_cr2_per(stlink_t *sl) { - const uint32_t n = (1 << FLASH_CR_PER); - stlink_write_debug32(sl, FLASH_CR2, n); -} - -static void clear_flash_cr_per(stlink_t *sl) { +static void clear_flash_cr_per(stlink_t *sl, unsigned bank) { uint32_t cr_reg; if (sl->flash_type == STLINK_FLASH_TYPE_G0 || @@ -842,14 +880,14 @@ static void clear_flash_cr_per(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; } else { - cr_reg = FLASH_CR; + cr_reg = (bank==BANK_1)?FLASH_CR:FLASH_CR2; } - const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_PER); + 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) { +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) { @@ -878,8 +916,12 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) { 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 = FLASH_CR; + cr_reg = (bank==BANK_1)?FLASH_CR:FLASH_CR2; cr_mer = (1 << FLASH_CR_MER); cr_pg = (1 << FLASH_CR_PG); } @@ -901,46 +943,7 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) { stlink_write_debug32(sl, cr_reg, val); } -static void set_flash_cr2_mer(stlink_t *sl, bool v) { - const uint32_t cr_pg = (1 << FLASH_CR_PER); - const uint32_t cr_mer = (1 << FLASH_CR_MER); - uint32_t val; - - stlink_read_debug32(sl, FLASH_CR2, &val); - val &= ~cr_pg; - - if (v) { - val |= cr_mer; - } else { - val &= ~cr_mer; - } - - stlink_write_debug32(sl, FLASH_CR2, val); -} - -static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { - uint32_t val, cr_reg, cr_mer; - - if (sl->flash_type == STLINK_FLASH_TYPE_F4) { - cr_reg = FLASH_F4_CR; - cr_mer = 1 << FLASH_CR_MER; - } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { - cr_reg = FLASH_F7_CR; - cr_mer = 1 << FLASH_CR_MER; - } 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); - } else { - cr_reg = FLASH_CR; - cr_mer = (1 << FLASH_CR_MER); - } - - stlink_read_debug32(sl, cr_reg, &val); - val &= ~cr_mer; - stlink_write_debug32(sl, cr_reg, val); -} - -static void set_flash_cr_strt(stlink_t *sl) { +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) { @@ -960,10 +963,10 @@ static void set_flash_cr_strt(stlink_t *sl) { cr_reg = STM32WB_FLASH_CR; cr_strt = (1 << STM32WB_FLASH_CR_STRT); } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = FLASH_H7_CR1; - cr_strt = 1 << FLASH_H7_CR_START; + cr_reg = (bank==BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; + cr_strt = 1 << FLASH_H7_CR_START(sl->chip_id); } else { - cr_reg = FLASH_CR; + cr_reg = (bank==BANK_1)?FLASH_CR:FLASH_CR2; cr_strt = (1 << FLASH_CR_STRT); } @@ -972,20 +975,12 @@ static void set_flash_cr_strt(stlink_t *sl) { stlink_write_debug32(sl, cr_reg, val); } -static void set_flash_cr2_strt(stlink_t *sl) { - uint32_t val; - - stlink_read_debug32(sl, FLASH_CR2, &val); - val |= 1 << FLASH_CR_STRT; - stlink_write_debug32(sl, FLASH_CR2, val); -} - -static inline uint32_t read_flash_sr(stlink_t *sl) { +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 = FLASH_SR; + 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) { @@ -1000,7 +995,7 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { } 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 = FLASH_H7_SR1; + sr_reg = (bank==BANK_1)?FLASH_H7_SR1:FLASH_H7_SR2; } else { ELOG("unsupported flash method, abort"); return(-1); @@ -1010,12 +1005,6 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { return(res); } -static inline uint32_t read_flash_sr2(stlink_t *sl) { - uint32_t res; - stlink_read_debug32(sl, FLASH_SR2, &res); - return(res); -} - static inline unsigned int is_flash_busy(stlink_t *sl) { uint32_t sr_busy_shift; unsigned int res; @@ -1042,10 +1031,11 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { return(-1); } - res = read_flash_sr(sl) & (1 << sr_busy_shift); + res = read_flash_sr(sl, BANK_1) & (1 << sr_busy_shift); - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - res |= read_flash_sr2(sl) & (1 << sr_busy_shift); + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || + (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->has_dual_bank)) { + res |= read_flash_sr(sl, BANK_2) & (1 << sr_busy_shift); } return(res); @@ -1081,17 +1071,31 @@ static int check_flash_error(stlink_t *sl) switch (sl->flash_type) { case STLINK_FLASH_TYPE_F0: - res = read_flash_sr(sl) & FLASH_SR_ERROR_MASK; + res = read_flash_sr(sl, BANK_1) & FLASH_SR_ERROR_MASK; break; case STLINK_FLASH_TYPE_F7: - res = read_flash_sr(sl) & FLASH_F7_SR_ERROR_MASK; + res = read_flash_sr(sl, BANK_1) & FLASH_F7_SR_ERROR_MASK; break; case STLINK_FLASH_TYPE_G0: case STLINK_FLASH_TYPE_G4: - res = read_flash_sr(sl) & STM32Gx_FLASH_SR_ERROR_MASK; + res = read_flash_sr(sl, BANK_1) & STM32Gx_FLASH_SR_ERROR_MASK; break; case STLINK_FLASH_TYPE_L0: - res = read_flash_sr(sl) & STM32L0_FLASH_SR_ERROR_MASK; + res = read_flash_sr(sl, BANK_1) & STM32L0_FLASH_SR_ERROR_MASK; + break; + case STLINK_FLASH_TYPE_H7: + res = read_flash_sr(sl, BANK_1) & FLASH_H7_SR_ERROR_MASK; + if (sl->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->has_dual_bank) { + stlink_write_debug32(sl, FLASH_H7_CCR2, res); + } + } + break; default: break; } @@ -1104,35 +1108,16 @@ static int check_flash_error(stlink_t *sl) return(0); } -static inline unsigned int is_flash_eop(stlink_t *sl) { - return(read_flash_sr(sl) & (1 << FLASH_SR_EOP)); -} - -static void __attribute__((unused)) clear_flash_sr_eop(stlink_t *sl) { - const uint32_t n = read_flash_sr(sl) & ~(1 << FLASH_SR_EOP); - stlink_write_debug32(sl, FLASH_SR, n); -} - -static void __attribute__((unused)) wait_flash_eop(stlink_t *sl) { - // TODO: add some delays here - while (is_flash_eop(sl) == 0) - ; -} - -static inline void write_flash_ar(stlink_t *sl, uint32_t n) { - stlink_write_debug32(sl, FLASH_AR, n); -} - -static inline void write_flash_ar2(stlink_t *sl, uint32_t n) { - stlink_write_debug32(sl, FLASH_AR2, n); +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); } -static inline void write_flash_cr_psiz(stlink_t *sl, uint32_t 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); + uint32_t x = read_flash_cr(sl, bank); if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = FLASH_H7_CR1; + cr_reg = (bank==BANK_1)?FLASH_H7_CR1:FLASH_H7_CR2; psize_shift = FLASH_H7_CR_PSIZE; } else { cr_reg = FLASH_F4_CR; @@ -1147,12 +1132,12 @@ static inline void write_flash_cr_psiz(stlink_t *sl, uint32_t n) { stlink_write_debug32(sl, cr_reg, x); } -static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n) { +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); + uint32_t x = read_flash_cr(sl, bank); if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - cr_reg = FLASH_H7_CR1; + 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; @@ -1174,7 +1159,7 @@ static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n) { 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); + 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); @@ -1391,6 +1376,11 @@ int stlink_load_device_params(stlink_t *sl) { if (!(flash_optr & (1 << STM32G4_FLASH_OPTR_DBANK))) { sl->flash_pgsz <<= 1; } } + // H7 devices with small flash has one bank + if (sl->has_dual_bank && sl->flash_type == STLINK_FLASH_TYPE_H7) { + sl->has_dual_bank = (flash_size/sl->flash_pgsz) > 1; + } + #if 0 // Old code -- REW ILOG("Device connected is: %s, id %#x\n", params->description, chip_id); @@ -2314,9 +2304,9 @@ uint32_t calculate_F7_sectornum(uint32_t flashaddr) { } -uint32_t calculate_H7_sectornum(uint32_t flashaddr) { - flashaddr &= ~STM32_FLASH_BASE; // sector holding the flash address - return(flashaddr / 0x20000); +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 @@ -2392,8 +2382,7 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr) { int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { 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_H7) { + sl->flash_type == STLINK_FLASH_TYPE_L4) { // wait for ongoing op to finish wait_flash_busy(sl); @@ -2420,14 +2409,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, stlink_calculate_pagesize(sl, flashaddr)); - write_flash_cr_snb(sl, sector); - } else if (sl->chip_id == STLINK_CHIPID_STM32_H74XXX) { - // calculate the actual page from the address - uint32_t sector = calculate_H7_sectornum(flashaddr); - - fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", - sector, stlink_calculate_pagesize(sl, flashaddr)); - write_flash_cr_snb(sl, sector); + write_flash_cr_snb(sl, sector, BANK_1); } else { // calculate the actual page from the address uint32_t sector = calculate_F4_sectornum(flashaddr); @@ -2439,14 +2421,14 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { // follow the values for the first bank on 2mb devices... if (sector >= 12) { sector += 4; } - write_flash_cr_snb(sl, sector); + write_flash_cr_snb(sl, sector, BANK_1); } - set_flash_cr_strt(sl); // start erase operation + 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)); + fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl, BANK_1)); #endif } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { @@ -2526,7 +2508,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { uint32_t val; wait_flash_busy(sl); // wait for any ongoing Flash operation to finish unlock_flash_if(sl); - set_flash_cr_per(sl); // set the 'enable Flash erase' bit + 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) { @@ -2554,27 +2536,29 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { stlink_write_debug32(sl, STM32Gx_FLASH_CR, val); } - set_flash_cr_strt(sl); // set the 'start operation' bit + 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); // clear the 'enable page erase' bit + 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) && (flashaddr < FLASH_BANK2_START_ADDR))) { + } 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); // clear the pg bit - set_flash_cr_per(sl); // set the page erase bit - write_flash_ar(sl, flashaddr); // select the page to erase - set_flash_cr_strt(sl); // start erase operation, reset by hw with busy bit + 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); lock_flash(sl); - } else if ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (flashaddr >= FLASH_BANK2_START_ADDR)) { - wait_flash_busy(sl); - unlock_flash_if(sl); - set_flash_cr2_per(sl); // set the page erase bit - write_flash_ar2(sl, flashaddr); // select the page to erase - set_flash_cr2_strt(sl); // start erase operation, reset by hw with busy bit - wait_flash_busy(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 + 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); @@ -2586,7 +2570,9 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { } int stlink_erase_flash_mass(stlink_t *sl) { - // TODO: User MER bit to mass-erase G0, G4, WB series. + 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 @@ -2609,28 +2595,39 @@ int stlink_erase_flash_mass(stlink_t *sl) { } else { wait_flash_busy(sl); unlock_flash_if(sl); - set_flash_cr_mer(sl, 1); // set the mass erase bit - set_flash_cr_strt(sl); // start erase operation, reset by hw with busy bit - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - set_flash_cr2_mer(sl, 1); // set the mass erase bit in bank 2 - set_flash_cr2_strt(sl); // start erase operation in bank 2 + 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->has_dual_bank) { + write_flash_cr_psiz(sl, 3 /*64bit*/, 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 + + if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL || + (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->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 } wait_flash_busy_progress(sl); - check_flash_error(sl); + err = check_flash_error(sl); lock_flash(sl); - set_flash_cr_mer(sl, 0); // reset the mass erase bit - - if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) { - set_flash_cr2_mer(sl, 0); // reset the mass erase bit 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->has_dual_bank)) { + set_flash_cr_mer(sl, 0, BANK_2); } // TODO: verify the erased memory } - return(0); + return(err); } int stlink_fcheck_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { @@ -2786,16 +2783,16 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { } else { if (voltage > 2700) { ILOG("enabling 32-bit flash writes\n"); - write_flash_cr_psiz(sl, 2); + 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); + write_flash_cr_psiz(sl, 0, BANK_1); } } // set programming mode - set_flash_cr_pg(sl); + 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) { @@ -2803,7 +2800,7 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { wait_flash_busy(sl); unlock_flash_if(sl); // unlock flash if necessary - set_flash_cr_pg(sl); // set PG 'allow programming' bit + 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"); @@ -2852,7 +2849,17 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { ILOG("Starting Flash write for H7\n"); unlock_flash_if(sl); // unlock the cr - set_flash_cr_pg(sl); // set programming mode + set_flash_cr_pg(sl, BANK_1); // set programming mode + if (sl->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->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); @@ -2961,7 +2968,7 @@ 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); } + if (sl->flash_type != STLINK_FLASH_TYPE_F1_XL) { set_flash_cr_pg(sl, BANK_1); } DLOG("Finished unlocking flash, running loader!\n"); @@ -2984,10 +2991,10 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr } } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { for (off = 0; off < len;) { - // Program STM32H7x with 32-byte Flash words - size_t chunk = (len - off > 32) ? 32 : len - off; + // 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, 32); + stlink_write_mem32(sl, addr + (uint32_t)off, 64); wait_flash_busy(sl); off += chunk; @@ -3009,7 +3016,7 @@ int stlink_flashloader_write(stlink_t *sl, flash_loader_t *fl, stm32_addr_t addr } int stlink_flashloader_stop(stlink_t *sl) { - if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || + 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) || @@ -3017,7 +3024,10 @@ int stlink_flashloader_stop(stlink_t *sl) { (sl->flash_type == STLINK_FLASH_TYPE_G4) || (sl->flash_type == STLINK_FLASH_TYPE_H7)) { - clear_flash_cr_pg(sl); + clear_flash_cr_pg(sl, BANK_1); + if (sl->flash_type == STLINK_FLASH_TYPE_H7 && sl->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; diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index c191fa919..5cf2ddd1c 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -617,8 +617,9 @@ static const struct stlink_chipid_params devices[] = { { // STM32H742/743/753 (from RM0433) .chip_id = STLINK_CHIPID_STM32_H74XXX, - .description = "H742/743/753", + .description = "H74x/H75x", .flash_type = STLINK_FLASH_TYPE_H7, + .has_dual_bank = true, .flash_size_reg = 0x1ff1e880, // "Flash size register" (pg3272) .flash_pagesize = 0x20000, // 128k sector (pg147) .sram_size = 0x20000, // 128k "DTCM" from Table 7 @@ -627,6 +628,34 @@ static const struct stlink_chipid_params devices[] = { .option_base = STM32_H7_OPTION_BYTES_BASE, .option_size = 44, // FLASH_OPTSR_CUR to FLASH_BOOT_PRGR from Table 28 }, + { + // STM32H7A3/7B3 (from RM0455) + .chip_id = STLINK_CHIPID_STM32_H7AX, + .description = "H7Ax/H7Bx", + .flash_type = STLINK_FLASH_TYPE_H7, + .has_dual_bank = true, + .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, + }, + { + // STM32H72x/H73x (from RM0468) + .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) + .option_base = STM32_H7_OPTION_BYTES_BASE, + .option_size = 44, + }, + { // unknown .chip_id = STLINK_CHIPID_UNKNOWN, diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index f717022ca..a342df2dc 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -64,6 +64,8 @@ enum stlink_stm32_chipids { STLINK_CHIPID_STM32_G4_CAT2 = 0x468, /* See: RM 0440 s46.6.1 "MCU device ID code" */ STLINK_CHIPID_STM32_G4_CAT3 = 0x469, STLINK_CHIPID_STM32_L4RX = 0x470, /* ID found on the STM32L4R9I-DISCO board */ + STLINK_CHIPID_STM32_H7AX = 0x480, /* RM0455, p. 2863 */ + STLINK_CHIPID_STM32_H72X = 0x483, /* RM0468, p. 3199 */ STLINK_CHIPID_STM32_WB55 = 0x495 }; From d902fba40aa3db82c4b144849a5ea427492cb06e Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Wed, 11 Nov 2020 19:57:57 +0500 Subject: [PATCH 17/19] Fix printf format --- src/st-info/info.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/st-info/info.c b/src/st-info/info.c index 4f2fae1eb..2e1ce0e96 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -38,11 +38,11 @@ static void stlink_print_serial(stlink_t *sl, bool openocd) { static void stlink_print_version(stlink_t *sl) { // Implementation of version printing is minimalistic // but contains all available information from sl->version - printf("V%d", sl->version.stlink_v); + printf("V%u", sl->version.stlink_v); if (sl->version.jtag_v > 0) - printf("J%d", sl->version.jtag_v); + printf("J%u", sl->version.jtag_v); if (sl->version.swim_v > 0) - printf("S%d", sl->version.swim_v); + printf("S%u", sl->version.swim_v); printf("\n"); } From 1bbdd74c4b1b5ca7fe0bbfe367677503e20dc82d Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Sat, 5 Dec 2020 11:16:39 +0500 Subject: [PATCH 18/19] Fix the indentation --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ab43271e..b125803b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,7 +109,7 @@ set(STLINK_HEADERS src/stlink-lib/md5.h src/stlink-lib/sg.h src/stlink-lib/usb.h - src/stlink-lib/helper.h + src/stlink-lib/helper.h ) set(STLINK_SOURCE From 20e1d531153093842c6c37fec5dd4564e92934cd Mon Sep 17 00:00:00 2001 From: Ant-ON Date: Sat, 5 Dec 2020 15:16:14 +0500 Subject: [PATCH 19/19] Fix the indentation --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b125803b8..c8ab40257 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -120,7 +120,7 @@ set(STLINK_SOURCE src/stlink-lib/md5.c src/stlink-lib/sg.c src/stlink-lib/usb.c - src/stlink-lib/helper.c + src/stlink-lib/helper.c ) if (WIN32)