From a7385dc70c13a15301511ecc8efb83dab4066ae3 Mon Sep 17 00:00:00 2001 From: Chen Guokai Date: Mon, 18 May 2020 00:36:25 +0800 Subject: [PATCH 1/5] Quick and dirty fix for flashloaders --- flashloaders/stm32f0.bin | Bin 0 -> 108 bytes src/flash_loader.c | 9 +++------ src/usb.c | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) create mode 100755 flashloaders/stm32f0.bin diff --git a/flashloaders/stm32f0.bin b/flashloaders/stm32f0.bin new file mode 100755 index 0000000000000000000000000000000000000000..f7da9a896a05493101000e5efb9cd46499f3989f GIT binary patch literal 108 zcmX@$cEC;8-zG!Y-!8*UQrO=%LswGB-#EkC**Jl@gS$b%|A6F4Nj`t=3~Q&~7x?_G zotQ6j`CpP|(0YB51E_8{P#wd*18xioOb!AJ3=BL#?7_gG-~+?~K+Fi_GXXIR5CZ^; Ct{D~p literal 0 HcmV?d00001 diff --git a/src/flash_loader.c b/src/flash_loader.c index 6862d493c..c544a874a 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -41,7 +41,6 @@ /* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ static const uint8_t loader_code_stm32f0[] = { -#if 1 /* * These two NOPs here are a safety precaution, added by Pekka Nikander * while debugging the STM32F05x support. They may not be needed, but @@ -54,9 +53,7 @@ * #if 0 them out, with a comment when these were taken out, and to remove * these only a few months later... But YMMV. */ - 0x00, 0x30, // nop /* add r0,#0 */ - 0x00, 0x30, // nop /* add r0,#0 */ -#endif + 0x13, 0x4f, 0x3c, 0x68, 0x13, 0x4f, 0x3e, 0x68, 0x36, 0x19, 0x13, 0x4f, @@ -82,7 +79,7 @@ 0x4c, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00 + 0x04, 0x00, 0x00, 0x00, }; static const uint8_t loader_code_stm32l[] = { @@ -191,7 +188,7 @@ int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { - size_t size; + size_t size = 0; /* allocate the loader in sram */ if (stlink_flash_loader_write_to_sram(sl, &fl->loader_addr, &size) == -1) { diff --git a/src/usb.c b/src/usb.c index 3445a7464..40464f144 100644 --- a/src/usb.c +++ b/src/usb.c @@ -365,7 +365,7 @@ int _stlink_usb_core_id(stlink_t * sl) { int _stlink_usb_status_v2(stlink_t *sl) { int result; - uint32_t status; + uint32_t status = 0; result = _stlink_usb_read_debug32(sl, DCB_DHCSR, &status); DLOG("core status: %08X\n", status); From 865ae3941494a59d163b70c9693de7452b3cfbc0 Mon Sep 17 00:00:00 2001 From: wliang Date: Fri, 19 Jun 2020 19:58:32 +0800 Subject: [PATCH 2/5] h743 --- include/stlink.h | 9 ++- include/stlink/chipid.h | 3 +- src/chipid.c | 12 ++++ src/common.c | 144 ++++++++++++++++++++++++++++++++++++---- src/flash_loader.c | 12 +++- src/usb.c | 77 +++++++++++++++++++-- tests/usb.c | 8 ++- 7 files changed, 244 insertions(+), 21 deletions(-) diff --git a/include/stlink.h b/include/stlink.h index c87c6b173..7f96f2308 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -60,6 +60,11 @@ enum target_state { #define STLINK_DEBUG_APIV2_SWD_SET_FREQ 0x43 +//add by wliang +#define STLINK_DEBUG_APIV2_READ_DAP_REG 0x45 +#define STLINK_DEBUG_APIV2_WRITE_DAP_REG 0x46 +//add by wliang + #define STLINK_APIV3_SET_COM_FREQ 0x61 #define STLINK_APIV3_GET_COM_FREQ 0x62 @@ -125,7 +130,9 @@ enum stlink_flash_type { STLINK_FLASH_TYPE_L4, // l4, l4+ */ STLINK_FLASH_TYPE_G0, STLINK_FLASH_TYPE_G4, - STLINK_FLASH_TYPE_WB + STLINK_FLASH_TYPE_WB, + //add by wliang + STLINK_FLASH_TYPE_H7 }; struct stlink_reg { diff --git a/include/stlink/chipid.h b/include/stlink/chipid.h index 98164a8fc..ddd123e9b 100644 --- a/include/stlink/chipid.h +++ b/include/stlink/chipid.h @@ -63,7 +63,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, /* taken from the STM32L4R9I-DISCO board */ - STLINK_CHIPID_STM32_WB55 = 0x495 + STLINK_CHIPID_STM32_WB55 = 0x495, + STLINK_CHIPID_STM32_H74XXX = 0x450 /* Found on page 3069 in the RM0433*/ }; /** diff --git a/src/chipid.c b/src/chipid.c index fcc1c55eb..67abd2bd6 100644 --- a/src/chipid.c +++ b/src/chipid.c @@ -2,6 +2,18 @@ #include static const struct stlink_chipid_params devices[] = { + { + //RM0433 document was used to find these paramaters + .chip_id = STLINK_CHIPID_STM32_H74XXX, + .description = "H743xx device", + .flash_type = STLINK_FLASH_TYPE_H7, + .flash_size_reg = 0x1FF1E880, // section 60.2 + .flash_pagesize = 0x20000, // No flash pages + .sram_size = 0x100000, // "SRAM" byte size in hex from + .bootrom_base = 0x1FFF0000, //! "System memory" starting address from + .bootrom_size = 0x1E800 //! @todo "System memory" byte size in hex from + }, + { //RM0410 document was used to find these paramaters .chip_id = STLINK_CHIPID_STM32_F7XXXX, diff --git a/src/common.c b/src/common.c index e8f7cebc6..8b74f75fb 100644 --- a/src/common.c +++ b/src/common.c @@ -252,6 +252,25 @@ #define FLASH_F4_CR_SNB_MASK 0xf8 #define FLASH_F4_SR_BSY 16 +//add by wliang +#define FLASH_H7_CR_LOCK 0 +#define FLASH_H7_CR_PG 1 +#define FLASH_H7_CR_BER 3 +#define FLASH_H7_CR_PSIZE 4 +#define FLASH_H7_CR_START 7 +#define FLASH_H7_CR_SNB 8 + +#define FLASH_H7_SR_BSY 0 +#define FLASH_H7_SR_QW 2 + +#define FLASH_H7_REGS_ADDR ((uint32_t)0x52002000) +#define FLASH_H7_KEYR1 (FLASH_H7_REGS_ADDR + 0x04) +#define FLASH_H7_CR1 (FLASH_H7_REGS_ADDR + 0x0C) +#define FLASH_H7_SR1 (FLASH_H7_REGS_ADDR + 0x10) +//add by wliang + + + //STM32F2 #define FLASH_F2_REGS_ADDR ((uint32_t)0x40023c00) #define FLASH_F2_KEYR (FLASH_F2_REGS_ADDR + 0x04) @@ -332,11 +351,14 @@ static uint32_t __attribute__((unused)) read_flash_rdp(stlink_t *sl) { return rdp & 0xff; } -static inline uint32_t read_flash_cr(stlink_t *sl) { +//inline +static uint32_t read_flash_cr(stlink_t *sl) { uint32_t reg, res; if (sl->flash_type == STLINK_FLASH_TYPE_F4) reg = FLASH_F4_CR; + else if (sl->flash_type == STLINK_FLASH_TYPE_H7) //add by wliang + reg = FLASH_H7_CR1; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) reg = STM32L4_FLASH_CR; else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || @@ -390,6 +412,10 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; cr_lock_shift = STM32WB_FLASH_CR_LOCK; + //add by wliang + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; + cr_lock_shift = FLASH_H7_CR_LOCK; } else { ELOG("unsupported flash method, abort\n"); return -1; @@ -425,6 +451,9 @@ static void unlock_flash(stlink_t *sl) { key_reg = STM32Gx_FLASH_KEYR; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { key_reg = STM32WB_FLASH_KEYR; + //add by wliang + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + key_reg = FLASH_H7_KEYR1; } else { ELOG("unsupported flash method, abort\n"); return; @@ -475,6 +504,10 @@ static void lock_flash(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; cr_lock_shift = STM32WB_FLASH_CR_LOCK; +//add by wliang + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; + cr_lock_shift = FLASH_H7_CR_LOCK; } else { ELOG("unsupported flash method, abort\n"); return; @@ -660,6 +693,10 @@ static void set_flash_cr_pg(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; x |= (1 << FLASH_CR_PG); + //add by wliang + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; + x |= (1 << FLASH_H7_CR_PG); } else { cr_reg = FLASH_CR; x = 1 << FLASH_CR_PG; @@ -815,6 +852,10 @@ static void set_flash_cr_strt(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; cr_strt = 1 << STM32WB_FLASH_CR_STRT; + //add by wliang + }else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; + cr_strt = 1 << FLASH_H7_CR_START; } else { cr_reg = FLASH_CR; cr_strt = 1 << FLASH_CR_STRT; @@ -849,6 +890,9 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { sr_reg = STM32Gx_FLASH_SR; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { sr_reg = STM32WB_FLASH_SR; +//add by wliang + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + sr_reg = FLASH_H7_SR1; } else { ELOG("unsupported flash method, abort"); return -1; @@ -880,6 +924,9 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { sr_busy_shift = STM32Gx_FLASH_SR_BSY; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { sr_busy_shift = STM32WB_FLASH_SR_BSY; + //add by wliang + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + sr_busy_shift = FLASH_SR_BSY; } else { ELOG("unsupported flash method, abort"); return -1; @@ -900,6 +947,24 @@ static void wait_flash_busy(stlink_t *sl) { ; } +// add by wliang + +static inline unsigned int is_queuewait_flag(stlink_t *sl) { + uint32_t sr_waitflag_shift; + unsigned int res; + + sr_waitflag_shift = FLASH_H7_SR_QW; + res = read_flash_sr(sl) & (1 << sr_waitflag_shift); + + return res; +} + +static void wait_QW_busy(stlink_t *sl) { + /* todo: add some delays here */ + while (is_queuewait_flag(sl)) + ; +} + static void wait_flash_busy_progress(stlink_t *sl) { int i = 0; fprintf(stdout, "Mass erasing"); @@ -965,8 +1030,13 @@ static inline void write_flash_ar2(stlink_t *sl, uint32_t n) { static inline void write_flash_cr_psiz(stlink_t *sl, uint32_t n) { uint32_t x = read_flash_cr(sl); - x &= ~(0x03 << 8); - x |= (n << 8); + if (sl->flash_type == STLINK_FLASH_TYPE_H7){ + x &= ~(0x03 << FLASH_H7_CR_PSIZE); + x |= (n << FLASH_H7_CR_PSIZE); + + stlink_write_debug32(sl, FLASH_H7_CR1, x); + return ; + } #if DEBUG_FLASH fprintf(stdout, "PSIZ:0x%x 0x%x\n", x, n); #endif @@ -985,6 +1055,17 @@ static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n) { stlink_write_debug32(sl, FLASH_F4_CR, x); } +//add by wliang +static inline void write_flash_cr_ber_snb(stlink_t *sl, uint32_t n) { + uint32_t x = read_flash_cr(sl); + x |= (n << FLASH_H7_CR_SNB); + x |= (1 << FLASH_H7_CR_BER); +#if DEBUG_FLASH + fprintf(stdout, "SNB:0x%x 0x%x\n", x, n); +#endif + stlink_write_debug32(sl, FLASH_H7_CR1, x); +} + static inline void write_flash_cr_bker_pnb(stlink_t *sl, uint32_t n) { stlink_write_debug32(sl, STM32L4_FLASH_SR, 0xFFFFFFFF & ~(1<chip_id = chip_id & 0xfff; /* Fix chip_id for F4 rev A errata , Read CPU ID, as CoreID is the same for F2/F4*/ @@ -1508,6 +1600,12 @@ void stlink_core_stat(stlink_t *sl) { } void stlink_print_data(stlink_t * sl) { + +//add by wliang + // printf("data_len = %d 0x%x\n", sl->q_len, sl->q_len); +//add by wliang + + if (sl->q_len <= 0 || sl->verbose < UDEBUG) return; if (sl->verbose > 2) @@ -1522,7 +1620,7 @@ void stlink_print_data(stlink_t * sl) { fprintf(stdout, "\n-> 0x%08x ", sl->q_addr + i); */ } - DLOG(" %02x", (unsigned int) sl->q_buf[i]); + DLOG(" %02x\n", (unsigned int) sl->q_buf[i]); } DLOG("\n\n"); } @@ -1981,6 +2079,11 @@ uint32_t calculate_F7_sectornum(uint32_t flashaddr){ else return(flashaddr/0x40000) +4; } +//add by wliang +uint32_t calculate_H7_sectornum(uint32_t flashaddr){ + flashaddr &= ~STM32_FLASH_BASE; //Page now holding the actual flash address + return(flashaddr/0x20000); +} // Returns BKER:PNB for the given page address uint32_t calculate_L4_page(stlink_t *sl, uint32_t flashaddr) { @@ -2044,7 +2147,8 @@ 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_L4) { + sl->flash_type == STLINK_FLASH_TYPE_L4 || + sl->flash_type == STLINK_FLASH_TYPE_H7) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -2071,15 +2175,21 @@ 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) { + + // add by wliang + 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_ber_snb(sl, sector); + } else { // calculate the actual page from the address uint32_t sector=calculate_F4_sectornum(flashaddr); fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x ", sector, stlink_calculate_pagesize(sl, flashaddr)); - //the SNB values for flash sectors in the second bank do not directly follow the values for the first bank on 2mb devices... - if (sector >= 12) sector += 4; - write_flash_cr_snb(sl, sector); } @@ -2487,7 +2597,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t if (eraseonly) return 0; - if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || (sl->flash_type == STLINK_FLASH_TYPE_L4)) { + if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || (sl->flash_type == STLINK_FLASH_TYPE_L4) + || (sl->flash_type == STLINK_FLASH_TYPE_H7)){ //add by wliang /* todo: check write operation */ ILOG("Starting Flash write for F2/F4/L4\n"); @@ -2546,9 +2657,18 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t printf("size: %u\n", (unsigned int)size); - 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; + //add by wliang + if (sl->flash_type == STLINK_FLASH_TYPE_H7){ + size = 32; + wait_QW_busy(sl); + memcpy(sl->q_buf, base + off, size); + stlink_write_mem32(sl, addr + (uint32_t) off, size); + wait_QW_busy(sl); + } else{ + 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; diff --git a/src/flash_loader.c b/src/flash_loader.c index a2c5879ce..a380725a8 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -270,7 +270,10 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* } else if (sl->core_id == STM32F7_CORE_ID || sl->chip_id == STLINK_CHIPID_STM32_F7 || sl->chip_id == STLINK_CHIPID_STM32_F7XXXX || - sl->chip_id == STLINK_CHIPID_STM32_F72XXX + sl->chip_id == STLINK_CHIPID_STM32_F72XXX || + // add by wliang + sl->chip_id == STLINK_CHIPID_STM32_H74XXX + // add by wliang ) { int retval; retval = loader_v_dependent_assignment(sl, @@ -342,6 +345,11 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe count = size / sizeof(uint64_t); if (size % sizeof(uint64_t)) ++count; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + //add by wliang + count = size / sizeof(uint32_t); + if (size % sizeof(uint32_t)) + ++count; } if ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (target >= FLASH_BANK2_START_ADDR)) { @@ -368,7 +376,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe // by increasing the sleep-per-round to the same order-of-magnitude as // the tick-rounding that the OS uses, the wait until the error message is // reduced to the same order of magnitude as what was intended. -- REW. -#define WAIT_ROUNDS 100 +#define WAIT_ROUNDS 1000 /* wait until done (reaches breakpoint) */ for (i = 0; i < WAIT_ROUNDS; i++) { usleep(1000); diff --git a/src/usb.c b/src/usb.c index a711749da..d44efcfb5 100644 --- a/src/usb.c +++ b/src/usb.c @@ -202,9 +202,13 @@ int _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { ssize_t size; const int rep_len = 8; + //add by wliang + memset(rdata, 0, rep_len); + //add by wliang + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_JTAG_READDEBUG_32BIT; + cmd[i++] = STLINK_JTAG_READDEBUG_32BIT; //0x36 write_uint32(&cmd[i], addr); size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); if (size == -1) { @@ -329,7 +333,7 @@ int _stlink_usb_core_id(stlink_t * sl) { if (sl->version.jtag_api == STLINK_JTAG_API_V1) { cmd[i++] = STLINK_DEBUG_READCOREID; } else { - cmd[i++] = STLINK_DEBUG_APIV2_READ_IDCODES; + cmd[i++] = STLINK_DEBUG_APIV2_READ_IDCODES; //0x31 } size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { @@ -734,7 +738,12 @@ int _stlink_usb_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { } else { cmd[i++] = STLINK_DEBUG_APIV2_READREG; } - + // cmd[i++] = STLINK_DEBUG_APIV2_READ_DAP_REG; + // } + // cmd[i++] = (uint8_t) 0xff; + // cmd[i++] = (uint8_t) 0xff; + // cmd[i++] = (uint8_t) 0x00; + // cmd[i++] = (uint8_t) 0xf8; cmd[i++] = (uint8_t) r_idx; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); @@ -771,6 +780,61 @@ int _stlink_usb_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { return 0; } +//add by wliang +int _stlink_usb_read_dap_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { + struct stlink_libusb * const slu = sl->backend_data; + unsigned char* const data = sl->q_buf; + unsigned char* const cmd = sl->c_buf; + ssize_t size; + uint32_t r; + uint32_t rep_len = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 4 : 8; + int reg_offset = sl->version.jtag_api == STLINK_JTAG_API_V1 ? 0 : 4; + 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_APIV1_READREG; + } else { + cmd[i++] = STLINK_DEBUG_APIV2_READ_DAP_REG; + } + cmd[i++] = (uint8_t) 0xff; + cmd[i++] = (uint8_t) 0xf8; + size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); + + if (size == -1) { + printf("[!] send_recv STLINK_DEBUG_READREG\n"); + return (int) size; + } + + sl->q_len = (int) size; + stlink_print_data(sl); + r = read_uint32(sl->q_buf, reg_offset); + DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); + + switch (r_idx) { + case 16: + regp->xpsr = r; + break; + case 17: + regp->main_sp = r; + break; + case 18: + regp->process_sp = r; + break; + case 19: + regp->rw = r; // XXX ?(primask, basemask etc.) + break; + case 20: + regp->rw2 = r; // XXX ?(primask, basemask etc.) + break; + default: + regp->r[r_idx] = r; + } + + return 0; +} + /* See section C1.6 of the ARMv7-M Architecture Reference Manual */ int _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { uint32_t r; @@ -892,7 +956,12 @@ int _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { } else { cmd[i++] = STLINK_DEBUG_APIV2_WRITEREG; } - + // cmd[i++] = STLINK_DEBUG_APIV2_WRITE_DAP_REG; + // } + // cmd[i++] = (uint8_t) 0xff; + // cmd[i++] = (uint8_t) 0xff; + // cmd[i++] = (uint8_t) 0x00; + // cmd[i++] = (uint8_t) 0xf8; cmd[i++] = idx; write_uint32(&cmd[i], reg); size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); diff --git a/tests/usb.c b/tests/usb.c index ce72e24a5..f9d5a98cb 100644 --- a/tests/usb.c +++ b/tests/usb.c @@ -26,7 +26,7 @@ int main(int ac, char** av) { return 0; } - sl = stlink_open_usb(10, reset, NULL, 0); + sl = stlink_open_usb(100, reset, NULL, 0); if (sl != NULL) { printf("-- version\n"); stlink_version(sl); @@ -93,9 +93,15 @@ int main(int ac, char** av) { stlink_reset(sl); stlink_force_debug(sl); /* Test reg write */ + stlink_read_reg(sl, 1, ®s); + stlink_write_reg(sl, 0xE00E0003, 3); + stlink_load_device_params(sl); + + stlink_write_reg(sl, 0x01234567, 3); stlink_write_reg(sl, 0x89abcdef, 4); stlink_write_reg(sl, 0x12345678, 15); + for (off = 0; off < 21; off += 1) stlink_read_reg(sl, off, ®s); From 9950f14d9793bfd2667c4a5ba434013df9101a19 Mon Sep 17 00:00:00 2001 From: wliang Date: Sat, 20 Jun 2020 09:24:31 +0800 Subject: [PATCH 3/5] stm32h7 flash upload support --- src/common.c | 35 +++++++++-------------------------- src/flash_loader.c | 5 +---- src/usb.c | 18 ++---------------- 3 files changed, 12 insertions(+), 46 deletions(-) diff --git a/src/common.c b/src/common.c index 8b74f75fb..da0e91c3f 100644 --- a/src/common.c +++ b/src/common.c @@ -252,7 +252,7 @@ #define FLASH_F4_CR_SNB_MASK 0xf8 #define FLASH_F4_SR_BSY 16 -//add by wliang +//STM32H7xx #define FLASH_H7_CR_LOCK 0 #define FLASH_H7_CR_PG 1 #define FLASH_H7_CR_BER 3 @@ -267,7 +267,7 @@ #define FLASH_H7_KEYR1 (FLASH_H7_REGS_ADDR + 0x04) #define FLASH_H7_CR1 (FLASH_H7_REGS_ADDR + 0x0C) #define FLASH_H7_SR1 (FLASH_H7_REGS_ADDR + 0x10) -//add by wliang + @@ -357,7 +357,7 @@ static uint32_t read_flash_cr(stlink_t *sl) { if (sl->flash_type == STLINK_FLASH_TYPE_F4) reg = FLASH_F4_CR; - else if (sl->flash_type == STLINK_FLASH_TYPE_H7) //add by wliang + else if (sl->flash_type == STLINK_FLASH_TYPE_H7) reg = FLASH_H7_CR1; else if (sl->flash_type == STLINK_FLASH_TYPE_L4) reg = STM32L4_FLASH_CR; @@ -412,7 +412,6 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; cr_lock_shift = STM32WB_FLASH_CR_LOCK; - //add by wliang } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { cr_reg = FLASH_H7_CR1; cr_lock_shift = FLASH_H7_CR_LOCK; @@ -451,7 +450,6 @@ static void unlock_flash(stlink_t *sl) { key_reg = STM32Gx_FLASH_KEYR; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { key_reg = STM32WB_FLASH_KEYR; - //add by wliang } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { key_reg = FLASH_H7_KEYR1; } else { @@ -504,7 +502,6 @@ static void lock_flash(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; cr_lock_shift = STM32WB_FLASH_CR_LOCK; -//add by wliang } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { cr_reg = FLASH_H7_CR1; cr_lock_shift = FLASH_H7_CR_LOCK; @@ -693,7 +690,6 @@ static void set_flash_cr_pg(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; x |= (1 << FLASH_CR_PG); - //add by wliang } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { cr_reg = FLASH_H7_CR1; x |= (1 << FLASH_H7_CR_PG); @@ -852,7 +848,6 @@ static void set_flash_cr_strt(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; cr_strt = 1 << STM32WB_FLASH_CR_STRT; - //add by wliang }else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { cr_reg = FLASH_H7_CR1; cr_strt = 1 << FLASH_H7_CR_START; @@ -890,7 +885,6 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { sr_reg = STM32Gx_FLASH_SR; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { sr_reg = STM32WB_FLASH_SR; -//add by wliang } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { sr_reg = FLASH_H7_SR1; } else { @@ -924,7 +918,6 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { sr_busy_shift = STM32Gx_FLASH_SR_BSY; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { sr_busy_shift = STM32WB_FLASH_SR_BSY; - //add by wliang } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { sr_busy_shift = FLASH_SR_BSY; } else { @@ -947,8 +940,7 @@ static void wait_flash_busy(stlink_t *sl) { ; } -// add by wliang - +// STM32H7 need check QW flag static inline unsigned int is_queuewait_flag(stlink_t *sl) { uint32_t sr_waitflag_shift; unsigned int res; @@ -1030,10 +1022,10 @@ static inline void write_flash_ar2(stlink_t *sl, uint32_t n) { static inline void write_flash_cr_psiz(stlink_t *sl, uint32_t n) { uint32_t x = read_flash_cr(sl); + //stm32h7 support if (sl->flash_type == STLINK_FLASH_TYPE_H7){ x &= ~(0x03 << FLASH_H7_CR_PSIZE); x |= (n << FLASH_H7_CR_PSIZE); - stlink_write_debug32(sl, FLASH_H7_CR1, x); return ; } @@ -1055,7 +1047,7 @@ static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n) { stlink_write_debug32(sl, FLASH_F4_CR, x); } -//add by wliang +//stm32h7 choose right bank number and sector number static inline void write_flash_cr_ber_snb(stlink_t *sl, uint32_t n) { uint32_t x = read_flash_cr(sl); x |= (n << FLASH_H7_CR_SNB); @@ -1142,7 +1134,7 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { ret = stlink_read_debug32(sl, 0xE0042000, chip_id); if (ret == -1) return ret; -//add by liang 0x5C001000 + //stm32h7 chipid in 0x5C001000 if (*chip_id == 0) { ret = stlink_read_debug32(sl, 0x5C001000, chip_id); @@ -1192,9 +1184,6 @@ int stlink_load_device_params(stlink_t *sl) { uint32_t chip_id; uint32_t flash_size; -// add by wliang -//_stlink_usb_read_all_regs -// add by wliang stlink_chip_id(sl, &chip_id); sl->chip_id = chip_id & 0xfff; /* Fix chip_id for F4 rev A errata , Read CPU ID, as CoreID is the same for F2/F4*/ @@ -1600,12 +1589,6 @@ void stlink_core_stat(stlink_t *sl) { } void stlink_print_data(stlink_t * sl) { - -//add by wliang - // printf("data_len = %d 0x%x\n", sl->q_len, sl->q_len); -//add by wliang - - if (sl->q_len <= 0 || sl->verbose < UDEBUG) return; if (sl->verbose > 2) @@ -2598,7 +2581,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t return 0; if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || (sl->flash_type == STLINK_FLASH_TYPE_L4) - || (sl->flash_type == STLINK_FLASH_TYPE_H7)){ //add by wliang + || (sl->flash_type == STLINK_FLASH_TYPE_H7)){ /* todo: check write operation */ ILOG("Starting Flash write for F2/F4/L4\n"); @@ -2657,7 +2640,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t printf("size: %u\n", (unsigned int)size); - //add by wliang + //stm32h7 program flash directly if (sl->flash_type == STLINK_FLASH_TYPE_H7){ size = 32; wait_QW_busy(sl); diff --git a/src/flash_loader.c b/src/flash_loader.c index a380725a8..f5f32db75 100644 --- a/src/flash_loader.c +++ b/src/flash_loader.c @@ -271,9 +271,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* sl->chip_id == STLINK_CHIPID_STM32_F7 || sl->chip_id == STLINK_CHIPID_STM32_F7XXXX || sl->chip_id == STLINK_CHIPID_STM32_F72XXX || - // add by wliang sl->chip_id == STLINK_CHIPID_STM32_H74XXX - // add by wliang ) { int retval; retval = loader_v_dependent_assignment(sl, @@ -346,7 +344,6 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe if (size % sizeof(uint64_t)) ++count; } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { - //add by wliang count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -376,7 +373,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe // by increasing the sleep-per-round to the same order-of-magnitude as // the tick-rounding that the OS uses, the wait until the error message is // reduced to the same order of magnitude as what was intended. -- REW. -#define WAIT_ROUNDS 1000 +#define WAIT_ROUNDS 100 /* wait until done (reaches breakpoint) */ for (i = 0; i < WAIT_ROUNDS; i++) { usleep(1000); diff --git a/src/usb.c b/src/usb.c index d44efcfb5..d78216e5e 100644 --- a/src/usb.c +++ b/src/usb.c @@ -202,13 +202,11 @@ int _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { ssize_t size; const int rep_len = 8; - //add by wliang memset(rdata, 0, rep_len); - //add by wliang int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; - cmd[i++] = STLINK_JTAG_READDEBUG_32BIT; //0x36 + cmd[i++] = STLINK_JTAG_READDEBUG_32BIT; write_uint32(&cmd[i], addr); size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); if (size == -1) { @@ -333,7 +331,7 @@ int _stlink_usb_core_id(stlink_t * sl) { if (sl->version.jtag_api == STLINK_JTAG_API_V1) { cmd[i++] = STLINK_DEBUG_READCOREID; } else { - cmd[i++] = STLINK_DEBUG_APIV2_READ_IDCODES; //0x31 + cmd[i++] = STLINK_DEBUG_APIV2_READ_IDCODES; } size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { @@ -738,12 +736,6 @@ int _stlink_usb_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { } else { cmd[i++] = STLINK_DEBUG_APIV2_READREG; } - // cmd[i++] = STLINK_DEBUG_APIV2_READ_DAP_REG; - // } - // cmd[i++] = (uint8_t) 0xff; - // cmd[i++] = (uint8_t) 0xff; - // cmd[i++] = (uint8_t) 0x00; - // cmd[i++] = (uint8_t) 0xf8; cmd[i++] = (uint8_t) r_idx; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); @@ -956,12 +948,6 @@ int _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { } else { cmd[i++] = STLINK_DEBUG_APIV2_WRITEREG; } - // cmd[i++] = STLINK_DEBUG_APIV2_WRITE_DAP_REG; - // } - // cmd[i++] = (uint8_t) 0xff; - // cmd[i++] = (uint8_t) 0xff; - // cmd[i++] = (uint8_t) 0x00; - // cmd[i++] = (uint8_t) 0xf8; cmd[i++] = idx; write_uint32(&cmd[i], reg); size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); From 9b4d45edb1f5631b30d3e305b7853063173eba04 Mon Sep 17 00:00:00 2001 From: Laurent GONZALEZ Date: Fri, 26 Jun 2020 16:40:00 +0200 Subject: [PATCH 4/5] Add L5 support --- inc/stlink.h | 1 + inc/stm32.h | 1 + src/common.c | 105 ++++++++++++++++++++++++++++++++++++++++ src/stlink-lib/chipid.c | 14 ++++++ src/stlink-lib/chipid.h | 1 + 5 files changed, 122 insertions(+) diff --git a/inc/stlink.h b/inc/stlink.h index 140d68866..5957995bd 100644 --- a/inc/stlink.h +++ b/inc/stlink.h @@ -123,6 +123,7 @@ enum stlink_flash_type { STLINK_FLASH_TYPE_F4, // used by f2, f4, f7 */ STLINK_FLASH_TYPE_L0, // l0, l1 */ STLINK_FLASH_TYPE_L4, // l4, l4+ */ + STLINK_FLASH_TYPE_L5, // l5x2 */ STLINK_FLASH_TYPE_G0, STLINK_FLASH_TYPE_G4, STLINK_FLASH_TYPE_WB diff --git a/inc/stm32.h b/inc/stm32.h index 36c14ee23..eab914a2c 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -20,5 +20,6 @@ #define STM32_F2_OPTION_BYTES_BASE ((uint32_t)0x1FFFC000) #define STM32_L4_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) #define STM32_L1_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) +#define STM32_L5_OPTION_BYTES_BASE ((uint32_t)0x40022040) #endif // STM32_H diff --git a/src/common.c b/src/common.c index 3459a53a0..4aaeaa83f 100644 --- a/src/common.c +++ b/src/common.c @@ -191,6 +191,47 @@ // WB Flash status register. #define STM32WB_FLASH_SR_BSY (16) /* FLASH_SR Busy */ +// L5 (RM0438) +#define STM32L5_FLASH_REGS_ADDR ((uint32_t)0x40022000) +#define STM32L5_FLASH_ACR (STM32L5_FLASH_REGS_ADDR + 0x00) +#define STM32L5_FLASH_PDKEYR (STM32L5_FLASH_REGS_ADDR + 0x04) +#define STM32L5_FLASH_NSKEYR (STM32L5_FLASH_REGS_ADDR + 0x08) +#define STM32L5_FLASH_SECKEYR (STM32L5_FLASH_REGS_ADDR + 0x0C) +#define STM32L5_FLASH_OPTKEYR (STM32L5_FLASH_REGS_ADDR + 0x10) +#define STM32L5_FLASH_LVEKEYR (STM32L5_FLASH_REGS_ADDR + 0x14) +#define STM32L5_FLASH_NSSR (STM32L5_FLASH_REGS_ADDR + 0x20) +#define STM32L5_FLASH_SECSR (STM32L5_FLASH_REGS_ADDR + 0x24) +#define STM32L5_FLASH_NSCR (STM32L5_FLASH_REGS_ADDR + 0x28) +#define STM32L5_FLASH_SECCR (STM32L5_FLASH_REGS_ADDR + 0x2C) +#define STM32L5_FLASH_ECCR (STM32L5_FLASH_REGS_ADDR + 0x30) +#define STM32L5_FLASH_OPTR (STM32L5_FLASH_REGS_ADDR + 0x40) +#define STM32L5_FLASH_NSBOOTADDR0R (STM32L5_FLASH_REGS_ADDR + 0x44) +#define STM32L5_FLASH_NSBOOTADDR1R (STM32L5_FLASH_REGS_ADDR + 0x48) +#define STM32L5_FLASH_SECBOOTADDR0R (STM32L5_FLASH_REGS_ADDR + 0x4C) +#define STM32L5_FLASH_SECWM1R1 (STM32L5_FLASH_REGS_ADDR + 0x50) +#define STM32L5_FLASH_SECWM1R2 (STM32L5_FLASH_REGS_ADDR + 0x54) +#define STM32L5_FLASH_WRP1AR (STM32L5_FLASH_REGS_ADDR + 0x58) +#define STM32L5_FLASH_WRP1BR (STM32L5_FLASH_REGS_ADDR + 0x5C) +#define STM32L5_FLASH_SECWM2R1 (STM32L5_FLASH_REGS_ADDR + 0x60) +#define STM32L5_FLASH_SECWM2R2 (STM32L5_FLASH_REGS_ADDR + 0x64) +#define STM32L5_FLASH_WRP2AR (STM32L5_FLASH_REGS_ADDR + 0x68) +#define STM32L5_FLASH_WRP2BR (STM32L5_FLASH_REGS_ADDR + 0x6C) +#define STM32L5_FLASH_SECBB1Rx (STM32L5_FLASH_REGS_ADDR + 0x80) +#define STM32L5_FLASH_SECBB2Rx (STM32L5_FLASH_REGS_ADDR + 0xA0) +#define STM32L5_FLASH_SECHDPCR (STM32L5_FLASH_REGS_ADDR + 0xC0) +#define STM32L5_FLASH_PRIVCFGR (STM32L5_FLASH_REGS_ADDR + 0xC4) + +// L5 Flash control register. +#define STM32L5_FLASH_CR_MER1 (2) /* Mass erase */ +#define STM32L5_FLASH_CR_MER2 (15) /* Mass erase (2nd bank)*/ +#define STM32L5_FLASH_CR_STRT (16) /* FLASH_CR Start */ +#define STM32L5_FLASH_CR_OPTLOCK (30) /* FLASH_CR Option Lock */ +#define STM32L5_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ +// L5 Flash status register. +#define STM32L5_FLASH_SR_BSY (16) /* FLASH_SR Busy */ +// L5 Flash option register +#define STM32L5_FLASH_OPTR_DBANK (22) /* FLASH_OPTR Dual Bank Mode */ + // 32L4 register base is at FLASH_REGS_ADDR (0x40022000) #define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) #define STM32L4_FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x0C) @@ -352,6 +393,8 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { reg = STM32Gx_FLASH_CR; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { reg = STM32WB_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L5) { + reg = STM32L5_FLASH_NSCR; } else { reg = FLASH_CR; } @@ -399,6 +442,9 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; cr_lock_shift = STM32WB_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L5) { + cr_reg = STM32L5_FLASH_NSCR; + cr_lock_shift = STM32L5_FLASH_CR_LOCK; } else { ELOG("unsupported flash method, abort\n"); return(-1); @@ -433,6 +479,8 @@ static void unlock_flash(stlink_t *sl) { key_reg = STM32Gx_FLASH_KEYR; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { key_reg = STM32WB_FLASH_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L5) { + key_reg = STM32L5_FLASH_NSKEYR; } else { ELOG("unsupported flash method, abort\n"); return; @@ -485,6 +533,9 @@ static void lock_flash(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; cr_lock_shift = STM32WB_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L5) { + cr_reg = STM32L5_FLASH_NSCR; + cr_lock_shift = STM32L5_FLASH_CR_LOCK; } else { ELOG("unsupported flash method, abort\n"); return; @@ -533,6 +584,10 @@ static bool is_flash_option_locked(stlink_t *sl) { optcr_reg = STM32WB_FLASH_CR; optlock_shift = STM32WB_FLASH_CR_OPTLOCK; break; + case STLINK_FLASH_TYPE_L5: + optcr_reg = STM32L5_FLASH_NSCR; + optlock_shift = STM32L5_FLASH_CR_OPTLOCK; + break; default: ELOG("unsupported flash method, abort\n"); return(-1); @@ -580,6 +635,10 @@ static int lock_flash_option(stlink_t *sl) { optcr_reg = STM32WB_FLASH_CR; optlock_shift = STM32WB_FLASH_CR_OPTLOCK; break; + case STLINK_FLASH_TYPE_L5: + optcr_reg = STM32L5_FLASH_NSCR; + optlock_shift = STM32L5_FLASH_CR_OPTLOCK; + break; default: ELOG("unsupported flash method, abort\n"); return(-1); @@ -627,6 +686,9 @@ static int unlock_flash_option(stlink_t *sl) { case STLINK_FLASH_TYPE_WB: optkey_reg = STM32WB_FLASH_OPT_KEYR; break; + case STLINK_FLASH_TYPE_L5: + optkey_reg = STM32L5_FLASH_OPTKEYR; + break; default: ELOG("unsupported flash method, abort\n"); @@ -674,6 +736,9 @@ static void set_flash_cr_pg(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; x |= (1 << FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_L5) { + cr_reg = STM32L5_FLASH_NSCR; + x |= (1 << FLASH_CR_PG); } else { cr_reg = FLASH_CR; x = (1 << FLASH_CR_PG); @@ -694,6 +759,8 @@ 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_L5) { + cr_reg = STM32L5_FLASH_NSCR; } else { cr_reg = FLASH_CR; } @@ -710,6 +777,8 @@ static void set_flash_cr_per(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_L5) { + cr_reg = STM32L5_FLASH_NSCR; } else { cr_reg = FLASH_CR; } @@ -732,6 +801,8 @@ static void clear_flash_cr_per(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_L5) { + cr_reg = STM32L5_FLASH_NSCR; } else { cr_reg = FLASH_CR; } @@ -765,6 +836,13 @@ 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_L5) { + cr_reg = STM32L5_FLASH_NSCR; + cr_mer = (1 << STM32L5_FLASH_CR_MER1); + if (sl->has_dual_bank) { + cr_mer |= (1 << STM32L5_FLASH_CR_MER2); + } + cr_pg = (1 << FLASH_CR_PG); } else { cr_reg = FLASH_CR; cr_mer = (1 << FLASH_CR_MER); @@ -840,6 +918,9 @@ static void set_flash_cr_strt(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; cr_strt = (1 << STM32WB_FLASH_CR_STRT); + } else if (sl->flash_type == STLINK_FLASH_TYPE_L5) { + cr_reg = STM32L5_FLASH_NSCR; + cr_strt = (1 << STM32L5_FLASH_CR_STRT); } else { cr_reg = FLASH_CR; cr_strt = (1 << FLASH_CR_STRT); @@ -875,6 +956,8 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { sr_reg = STM32Gx_FLASH_SR; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { sr_reg = STM32WB_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L5) { + sr_reg = STM32L5_FLASH_NSSR; } else { ELOG("unsupported flash method, abort"); return(-1); @@ -907,6 +990,8 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { sr_busy_shift = STM32Gx_FLASH_SR_BSY; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { sr_busy_shift = STM32WB_FLASH_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L5) { + sr_busy_shift = STM32L5_FLASH_SR_BSY; } else { ELOG("unsupported flash method, abort"); return(-1); @@ -1108,6 +1193,9 @@ int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { ret = stlink_read_debug32(sl, 0x40015800, chip_id); } + if (*chip_id == 0) + ret = stlink_read_debug32(sl, 0xE0044000, chip_id); //Try L5 DBGMCU_IDCODE + return(ret); } @@ -1224,6 +1312,14 @@ int stlink_load_device_params(stlink_t *sl) { if (!(flash_optr & (1 << STM32G4_FLASH_OPTR_DBANK))) { sl->flash_pgsz <<= 1; } } + if (sl->chip_id == STLINK_CHIPID_STM32_L5x2) { + uint32_t flash_optr; + stlink_read_debug32(sl, STM32L5_FLASH_OPTR, &flash_optr); + if (!(flash_optr & (1 << STM32L5_FLASH_OPTR_DBANK))) { + sl->flash_pgsz <<= 1; + } + } + #if 0 // Old code -- REW ILOG("Device connected is: %s, id %#x\n", params->description, chip_id); @@ -2259,6 +2355,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { val |= (1 << 0) | (1 << 1) | (1 << 2); stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val); } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || + sl->flash_type == STLINK_FLASH_TYPE_L5 || sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { uint32_t val; @@ -2276,6 +2373,13 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) { val |= ((flash_page & 0xFF) << 3); stlink_write_debug32(sl, STM32WB_FLASH_CR, val); + } else if (sl->flash_type == STLINK_FLASH_TYPE_L5) { + uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); + stlink_read_debug32(sl, STM32L5_FLASH_NSCR, &val); + // sec 6.9.9 - PNB[6:0] is offset by 3. PER is 0x2. + val &= ~(0x7F << 3); + val |= ((flash_page & 0x7F) << 3) | ( 1 << FLASH_CR_PER ); + stlink_write_debug32(sl, STM32L5_FLASH_NSCR, val); } else if (sl->flash_type == STLINK_FLASH_TYPE_G0) { uint32_t flash_page = ((flashaddr - STM32_FLASH_BASE) / (uint32_t)(sl->flash_pgsz)); stlink_read_debug32(sl, STM32Gx_FLASH_CR, &val); @@ -2615,6 +2719,7 @@ int stlink_write_flash( // STM32F4END } else if (sl->flash_type == STLINK_FLASH_TYPE_WB || + sl->flash_type == STLINK_FLASH_TYPE_L5 || sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { fprintf(stdout, "Writing\r\n"); diff --git a/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index bf0a56c96..fb9e5b70e 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -612,6 +612,20 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1fff0000, // see the memory map .bootrom_size = 0x7000 }, + { + // STM32L5x2 (from RM0438) + .chip_id = STLINK_CHIPID_STM32_L5x2, + .description = "L5x2", + .flash_type = STLINK_FLASH_TYPE_L5, + .has_dual_bank = true, + .flash_size_reg = 0x0BFA05E0, + .flash_pagesize = 0x800, // 2 banks of 128 x 2K pages + .sram_size = 0x40000, + .bootrom_base = 0x0BF90000, // See the memory map + .bootrom_size = 0x8000, + .option_base = STM32_L5_OPTION_BYTES_BASE, + .option_size = 4, + }, { // unknown .chip_id = STLINK_CHIPID_UNKNOWN, diff --git a/src/stlink-lib/chipid.h b/src/stlink-lib/chipid.h index b591f0012..71b7a2167 100644 --- a/src/stlink-lib/chipid.h +++ b/src/stlink-lib/chipid.h @@ -63,6 +63,7 @@ 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_L5x2 = 0x472, STLINK_CHIPID_STM32_WB55 = 0x495 }; From 7e37151959a350bd5069dda74d2423b7b22178a5 Mon Sep 17 00:00:00 2001 From: nightwalker-87 <15526941+Nightwalker-87@users.noreply.github.com> Date: Sun, 20 Sep 2020 18:35:46 +0200 Subject: [PATCH 5/5] Fix for serial numbers from libusb ASCII format used for stings. --- src/st-flash/flash_opts.c | 14 +----- src/st-info/info.c | 15 +++--- src/st-util/gdb-server.c | 96 ++++++++++++++++----------------------- tests/flash.c | 4 +- 4 files changed, 50 insertions(+), 79 deletions(-) diff --git a/src/st-flash/flash_opts.c b/src/st-flash/flash_opts.c index e74ecc1ce..c47b62b0e 100644 --- a/src/st-flash/flash_opts.c +++ b/src/st-flash/flash_opts.c @@ -106,18 +106,8 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) { serial = av[0] + strlen("--serial="); } - /** @todo This is not really portable, as strlen really returns size_t we need to obey - and not cast it to a signed type. */ - int j = (int)strlen(serial); - int length = j / 2; // the length of the destination-array - - if (j % 2 != 0) { return(-1); } - - for (size_t k = 0; j >= 0 && k < sizeof(o->serial); ++k, j -= 2) { - char buffer[3] = {0}; - memcpy(buffer, serial + j, 2); - o->serial[length - k] = (uint8_t)strtol(buffer, NULL, 16); - } + strncpy((char*)o->serial, serial, STLINK_SERIAL_MAX_SIZE - 1); + o->serial[STLINK_SERIAL_MAX_SIZE - 1] = '\0'; } else if (strcmp(av[0], "--area") == 0 || starts_with(av[0], "--area=")) { const char * area; diff --git a/src/st-info/info.c b/src/st-info/info.c index 2343140de..d2a96aeda 100644 --- a/src/st-info/info.c +++ b/src/st-info/info.c @@ -19,20 +19,17 @@ static void usage(void) { /* Print normal or OpenOCD hla_serial with newline */ static void stlink_print_serial(stlink_t *sl, bool openocd) { - const char *fmt; if (openocd) { printf("\""); - fmt = "\\x%02x"; + for (int n = 0; n < sl->serial_size; n+=2) { + printf("\\x%c%c", sl->serial[n], sl->serial[n+1]); + } + printf("\""); + printf("\n"); } else { - fmt = "%02x"; + printf("%s\n", sl->serial); } - - for (int n = 0; n < sl->serial_size; n++) { printf(fmt, sl->serial[n]); } - - if (openocd) { printf("\""); } - - printf("\n"); } static void stlink_print_info(stlink_t *sl) { diff --git a/src/st-util/gdb-server.c b/src/st-util/gdb-server.c index 60c9c16d3..2acef10d2 100644 --- a/src/st-util/gdb-server.c +++ b/src/st-util/gdb-server.c @@ -43,7 +43,7 @@ static stlink_t *connected_stlink = NULL; static bool semihosting = false; static bool serial_specified = false; -static char serialnumber[28] = {0}; +static char serialnumber[STLINK_SERIAL_MAX_SIZE] = {0}; #if defined(_WIN32) #define close_socket win32_close_socket @@ -153,61 +153,45 @@ int parse_options(int argc, char** argv, st_state_t *st) { while ((c = getopt_long(argc, argv, "hv::p:mn", long_options, &option_index)) != -1) switch (c) { - case 0: - break; - case 'h': - printf(help_str, argv[0]); - exit(EXIT_SUCCESS); - break; - case 'v': - - if (optarg) { - st->logging_level = atoi(optarg); - } else { - st->logging_level = DEBUG_LOGGING_LEVEL; - } - - break; - case 'p': - sscanf(optarg, "%i", &q); - - if (q < 0) { - fprintf(stderr, "Can't use a negative port to listen on: %d\n", q); - exit(EXIT_FAILURE); - } - - st->listen_port = q; - break; - case 'm': - st->persistent = 1; - break; - case 'n': - st->reset = 0; - break; - case 'V': - printf("v%s\n", STLINK_VERSION); - exit(EXIT_SUCCESS); - case SEMIHOSTING_OPTION: - semihosting = true; - break; - case SERIAL_OPTION: - printf("use serial %s\n", optarg); - /* TODO: This is not really portable, as strlen really returns size_t, - * we need to obey and not cast it to a signed type. - */ - int j = (int)strlen(optarg); - int length = j / 2; // the length of the destination-array - - if (j % 2 != 0) { return(-1); } - - for (size_t k = 0; j >= 0 && k < sizeof(serialnumber); ++k, j -= 2) { - char buffer[3] = {0}; - memcpy(buffer, optarg + j, 2); - serialnumber[length - k] = (uint8_t)strtol(buffer, NULL, 16); - } - - serial_specified = true; - break; + case 0: + break; + case 'h': + printf(help_str, argv[0]); + exit(EXIT_SUCCESS); + break; + case 'v': + if (optarg) { + st->logging_level = atoi(optarg); + } else { + st->logging_level = DEBUG_LOGGING_LEVEL; + } + break; + case 'p': + sscanf(optarg, "%i", &q); + if (q < 0) { + fprintf(stderr, "Can't use a negative port to listen on: %d\n", q); + exit(EXIT_FAILURE); + } + st->listen_port = q; + break; + case 'm': + st->persistent = 1; + break; + case 'n': + st->reset = 0; + break; + case 'V': + printf("v%s\n", STLINK_VERSION); + exit(EXIT_SUCCESS); + case SEMIHOSTING_OPTION: + semihosting = true; + break; + case SERIAL_OPTION: + printf("use serial %s\n",optarg); + strncpy((char*)serialnumber, optarg, STLINK_SERIAL_MAX_SIZE - 1); + serialnumber[STLINK_SERIAL_MAX_SIZE - 1] = '\0'; + serial_specified = true; + break; } diff --git a/tests/flash.c b/tests/flash.c index a8d479b2d..b3bd4d4e4 100644 --- a/tests/flash.c +++ b/tests/flash.c @@ -214,7 +214,7 @@ static struct Test tests[] = { { "--serial A1020304 erase sometext", -1, FLASH_OPTS_INITIALIZER }, { "--serial A1020304 erase", 0, { .cmd = FLASH_CMD_ERASE, - .serial = "\xA1\x02\x03\x04", + .serial = "A1020304", .filename = NULL, .addr = 0, .size = 0, @@ -225,7 +225,7 @@ static struct Test tests[] = { }, { "--serial=A1020304 erase", 0, { .cmd = FLASH_CMD_ERASE, - .serial = "\xA1\x02\x03\x04", + .serial = "A1020304", .filename = NULL, .addr = 0, .size = 0,