diff --git a/flashloaders/stm32f0.bin b/flashloaders/stm32f0.bin new file mode 100755 index 000000000..f7da9a896 Binary files /dev/null and b/flashloaders/stm32f0.bin differ diff --git a/inc/stlink.h b/inc/stlink.h index 1566a0bd6..ae6fe2154 100644 --- a/inc/stlink.h +++ b/inc/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 @@ -124,9 +129,12 @@ enum stlink_flash_type { STLINK_FLASH_TYPE_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 + STLINK_FLASH_TYPE_WB, + //add by wliang + STLINK_FLASH_TYPE_H7 }; struct stlink_reg { diff --git a/inc/stm32.h b/inc/stm32.h index 96836c9b7..1cd1f1a29 100644 --- a/inc/stm32.h +++ b/inc/stm32.h @@ -14,12 +14,13 @@ /* Constant STM32 memory map figures */ #define STM32_FLASH_BASE ((uint32_t)0x08000000) #define STM32_SRAM_BASE ((uint32_t)0x20000000) +#define STM32_F2_OPTION_BYTES_BASE ((uint32_t)0x1FFFC000) +#define STM32_F7_OPTION_BYTES_BASE ((uint32_t)0x1FFF0000) #define STM32_G0_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) #define STM32_G4_OPTION_BYTES_BASE ((uint32_t)0x1FFFF800) #define STM32_L0_CATx_OPTION_BYTES_BASE ((uint32_t)0x1FF80000) -#define STM32_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_F7_OPTION_BYTES_BASE ((uint32_t)0x1FFF0000) +#define STM32_L4_OPTION_BYTES_BASE ((uint32_t)0x1FFF7800) +#define STM32_L5_OPTION_BYTES_BASE ((uint32_t)0x40022040) #endif // STM32_H diff --git a/src/common.c b/src/common.c index 86d2ca8ea..376f40ec5 100644 --- a/src/common.c +++ b/src/common.c @@ -29,7 +29,7 @@ #define __attribute__(x) #endif -/* stm32f FPEC flash controller interface, pm0063 manual */ +/* STM32Fx 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) #define FLASH_REGS_ADDR 0x40022000 @@ -56,18 +56,18 @@ #define FLASH_KEY1 0x45670123 #define FLASH_KEY2 0xcdef89ab -#define FLASH_L0_PRGKEY1 0x8c9daebf -#define FLASH_L0_PRGKEY2 0x13141516 - -#define FLASH_L0_PEKEY1 0x89abcdef -#define FLASH_L0_PEKEY2 0x02030405 - #define FLASH_OPTKEY1 0x08192A3B #define FLASH_OPTKEY2 0x4C5D6E7F #define FLASH_F0_OPTKEY1 0x45670123 #define FLASH_F0_OPTKEY2 0xCDEF89AB +#define FLASH_L0_PRGKEY1 0x8c9daebf +#define FLASH_L0_PRGKEY2 0x13141516 + +#define FLASH_L0_PEKEY1 0x89abcdef +#define FLASH_L0_PEKEY2 0x02030405 + #define FLASH_L0_OPTKEY1 0xFBEAD9C8 #define FLASH_L0_OPTKEY2 0x24252627 @@ -109,7 +109,7 @@ #define STM32Gx_FLASH_ECCR (STM32Gx_FLASH_REGS_ADDR + 0x18) #define STM32Gx_FLASH_OPTR (STM32Gx_FLASH_REGS_ADDR + 0x20) -// G0 (RM0444 Table 1, sec 3.7) +// STM32G0 (RM0444 Table 1, sec 3.7) // Mostly the same as G4 chips, but the notation // varies a bit after the 'OPTR' register. #define STM32G0_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR) @@ -121,7 +121,7 @@ #define STM32G0_FLASH_PCROP1BER (STM32G0_FLASH_REGS_ADDR + 0x38) #define STM32G0_FLASH_SECR (STM32G0_FLASH_REGS_ADDR + 0x80) -// G4 (RM0440 Table 17, sec 3.7.19) +// STM32G4 (RM0440 Table 17, sec 3.7.19) // Mostly the same as STM32G0 chips, but there are a few extra // registers because 'cat 3' devices can have two Flash banks. #define STM32G4_FLASH_REGS_ADDR (STM32Gx_FLASH_REGS_ADDR) @@ -137,7 +137,7 @@ #define STM32G4_FLASH_SEC1R (STM32G4_FLASH_REGS_ADDR + 0x70) #define STM32G4_FLASH_SEC2R (STM32G4_FLASH_REGS_ADDR + 0x74) -// G0/G4 FLASH control register +// STM32G0/G4 FLASH control register #define STM32Gx_FLASH_CR_PG (0) /* Program */ #define STM32Gx_FLASH_CR_PER (1) /* Page erase */ #define STM32Gx_FLASH_CR_MER1 (2) /* Mass erase */ @@ -154,15 +154,15 @@ #define STM32Gx_FLASH_CR_OPTLOCK (30) /* Options Lock */ #define STM32Gx_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ -// G0/G4 FLASH status register +// STM32G0/G4 FLASH status register #define STM32Gx_FLASH_SR_ERROR_MASK (0x3fa) #define STM32Gx_FLASH_SR_BSY (16) /* FLASH_SR Busy */ #define STM32Gx_FLASH_SR_EOP (0) /* FLASH_EOP End of Operation */ -// G4 FLASH option register +// STM32G4 FLASH option register #define STM32G4_FLASH_OPTR_DBANK (22) /* FLASH_OPTR Dual Bank Mode */ -// WB (RM0434) +// STM32WB (RM0434) #define STM32WB_FLASH_REGS_ADDR ((uint32_t)0x58004000) #define STM32WB_FLASH_ACR (STM32WB_FLASH_REGS_ADDR + 0x00) #define STM32WB_FLASH_KEYR (STM32WB_FLASH_REGS_ADDR + 0x08) @@ -184,14 +184,55 @@ #define STM32WB_FLASH_SFR (STM32WB_FLASH_REGS_ADDR + 0x80) #define STM32WB_FLASH_SRRVR (STM32WB_FLASH_REGS_ADDR + 0x84) -// WB Flash control register. +// STM32WB Flash control register. #define STM32WB_FLASH_CR_STRT (16) /* FLASH_CR Start */ #define STM32WB_FLASH_CR_OPTLOCK (30) /* FLASH_CR Option Lock */ #define STM32WB_FLASH_CR_LOCK (31) /* FLASH_CR Lock */ -// WB Flash status register. +// STM32WB Flash status register. #define STM32WB_FLASH_SR_BSY (16) /* FLASH_SR Busy */ -// 32L4 register base is at FLASH_REGS_ADDR (0x40022000) +// STM32L5 (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) + +// STM32L5 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 */ +// STM32L5 Flash status register. +#define STM32L5_FLASH_SR_BSY (16) /* FLASH_SR Busy */ +// STM32L5 Flash option register +#define STM32L5_FLASH_OPTR_DBANK (22) /* FLASH_OPTR Dual Bank Mode */ + +// STM32L4 register base is at FLASH_REGS_ADDR (0x40022000) #define STM32L4_FLASH_KEYR (FLASH_REGS_ADDR + 0x08) #define STM32L4_FLASH_OPTKEYR (FLASH_REGS_ADDR + 0x0C) #define STM32L4_FLASH_SR (FLASH_REGS_ADDR + 0x10) @@ -243,7 +284,7 @@ #define FLASH_OBR_OFF ((uint32_t) 0x1c) #define FLASH_WRPR_OFF ((uint32_t) 0x20) -//STM32F7 +// STM32F7 #define FLASH_F7_REGS_ADDR ((uint32_t)0x40023c00) #define FLASH_F7_KEYR (FLASH_F7_REGS_ADDR + 0x04) #define FLASH_F7_OPT_KEYR (FLASH_F7_REGS_ADDR + 0x08) @@ -270,7 +311,7 @@ #define FLASH_F7_SR_ERROR_MASK ((1 << FLASH_F7_SR_ERS_ERR) | (1 << FLASH_F7_SR_PGP_ERR) | (1 << FLASH_F7_SR_PGA_ERR) | (1 << FLASH_F7_SR_WRP_ERR) | (1 << FLASH_F7_SR_OP_ERR)) -//STM32F4 +// STM32F4 #define FLASH_F4_REGS_ADDR ((uint32_t)0x40023c00) #define FLASH_F4_KEYR (FLASH_F4_REGS_ADDR + 0x04) #define FLASH_F4_OPT_KEYR (FLASH_F4_REGS_ADDR + 0x08) @@ -286,6 +327,22 @@ #define FLASH_F4_CR_SNB_MASK 0xf8 #define FLASH_F4_SR_BSY 16 +// STM32H7xx +#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) + // STM32F2 #define FLASH_F2_REGS_ADDR ((uint32_t)0x40023c00) #define FLASH_F2_KEYR (FLASH_F2_REGS_ADDR + 0x04) @@ -367,18 +424,23 @@ 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_F7) { reg = FLASH_F7_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - reg = STM32L4_FLASH_CR; } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { reg = STM32Gx_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + reg = STM32L4_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L5) { + reg = STM32L5_FLASH_NSCR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + reg = FLASH_H7_CR1; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { reg = STM32WB_FLASH_CR; } else { @@ -418,16 +480,22 @@ static inline unsigned int is_flash_locked(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; cr_lock_shift = FLASH_F7_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + cr_lock_shift = STM32Gx_FLASH_CR_LOCK; } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; cr_lock_shift = STM32L0_FLASH_PELOCK; } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_lock_shift = STM32L4_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_lock_shift = STM32Gx_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L5) { + cr_reg = STM32L5_FLASH_NSCR; + cr_lock_shift = STM32L5_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; + cr_lock_shift = FLASH_H7_CR_LOCK; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; cr_lock_shift = STM32WB_FLASH_CR_LOCK; @@ -456,15 +524,19 @@ static void unlock_flash(stlink_t *sl) { key_reg = FLASH_F4_KEYR; } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { key_reg = FLASH_F7_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + key_reg = STM32Gx_FLASH_KEYR; } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { key_reg = get_stm32l0_flash_base(sl) + FLASH_PEKEYR_OFF; flash_key1 = FLASH_L0_PEKEY1; flash_key2 = FLASH_L0_PEKEY2; } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { key_reg = STM32L4_FLASH_KEYR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - key_reg = STM32Gx_FLASH_KEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L5) { + key_reg = STM32L5_FLASH_NSKEYR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + key_reg = FLASH_H7_KEYR1; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { key_reg = STM32WB_FLASH_KEYR; } else { @@ -509,16 +581,22 @@ static void lock_flash(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; cr_lock_shift = FLASH_F7_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + cr_lock_shift = STM32Gx_FLASH_CR_LOCK; } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { cr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; cr_lock_shift = STM32L0_FLASH_PELOCK; } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; cr_lock_shift = STM32L4_FLASH_CR_LOCK; - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; - cr_lock_shift = STM32Gx_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L5) { + cr_reg = STM32L5_FLASH_NSCR; + cr_lock_shift = STM32L5_FLASH_CR_LOCK; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; + cr_lock_shift = FLASH_H7_CR_LOCK; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; cr_lock_shift = STM32WB_FLASH_CR_LOCK; @@ -557,6 +635,11 @@ static bool is_flash_option_locked(stlink_t *sl) { optcr_reg = FLASH_F7_OPTCR; optlock_shift = FLASH_F7_OPTCR_LOCK; break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + optcr_reg = STM32Gx_FLASH_CR; + optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + break; case STLINK_FLASH_TYPE_L0: optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; optlock_shift = STM32L0_FLASH_OPTLOCK; @@ -565,10 +648,9 @@ static bool is_flash_option_locked(stlink_t *sl) { optcr_reg = STM32L4_FLASH_CR; optlock_shift = STM32L4_FLASH_CR_OPTLOCK; break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - optcr_reg = STM32Gx_FLASH_CR; - optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + case STLINK_FLASH_TYPE_L5: + optcr_reg = STM32L5_FLASH_NSCR; + optlock_shift = STM32L5_FLASH_CR_OPTLOCK; break; case STLINK_FLASH_TYPE_WB: optcr_reg = STM32WB_FLASH_CR; @@ -608,6 +690,11 @@ static int lock_flash_option(stlink_t *sl) { optcr_reg = FLASH_F7_OPTCR; optlock_shift = FLASH_F7_OPTCR_LOCK; break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + optcr_reg = STM32Gx_FLASH_CR; + optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + break; case STLINK_FLASH_TYPE_L0: optcr_reg = get_stm32l0_flash_base(sl) + FLASH_PECR_OFF; optlock_shift = STM32L0_FLASH_OPTLOCK; @@ -616,10 +703,9 @@ static int lock_flash_option(stlink_t *sl) { optcr_reg = STM32L4_FLASH_CR; optlock_shift = STM32L4_FLASH_CR_OPTLOCK; break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - optcr_reg = STM32Gx_FLASH_CR; - optlock_shift = STM32Gx_FLASH_CR_OPTLOCK; + case STLINK_FLASH_TYPE_L5: + optcr_reg = STM32L5_FLASH_NSCR; + optlock_shift = STM32L5_FLASH_CR_OPTLOCK; break; case STLINK_FLASH_TYPE_WB: optcr_reg = STM32WB_FLASH_CR; @@ -660,6 +746,10 @@ static int unlock_flash_option(stlink_t *sl) { case STLINK_FLASH_TYPE_F7: optkey_reg = FLASH_F7_OPT_KEYR; break; + case STLINK_FLASH_TYPE_G0: + case STLINK_FLASH_TYPE_G4: + optkey_reg = STM32Gx_FLASH_OPTKEYR; + break; case STLINK_FLASH_TYPE_L0: optkey_reg = get_stm32l0_flash_base(sl) + FLASH_OPTKEYR_OFF; optkey1 = FLASH_L0_OPTKEY1; @@ -668,9 +758,8 @@ static int unlock_flash_option(stlink_t *sl) { case STLINK_FLASH_TYPE_L4: optkey_reg = STM32L4_FLASH_OPTKEYR; break; - case STLINK_FLASH_TYPE_G0: - case STLINK_FLASH_TYPE_G4: - optkey_reg = STM32Gx_FLASH_OPTKEYR; + case STLINK_FLASH_TYPE_L5: + optkey_reg = STM32L5_FLASH_OPTKEYR; break; case STLINK_FLASH_TYPE_WB: optkey_reg = STM32WB_FLASH_OPT_KEYR; @@ -713,14 +802,20 @@ static void set_flash_cr_pg(stlink_t *sl) { } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; x |= 1 << FLASH_CR_PG; + } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || + sl->flash_type == STLINK_FLASH_TYPE_G4) { + cr_reg = STM32Gx_FLASH_CR; + x |= (1 << FLASH_CR_PG); } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { cr_reg = STM32L4_FLASH_CR; x &= ~STM32L4_FLASH_CR_OPBITS; x |= (1 << STM32L4_FLASH_CR_PG); - } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || - sl->flash_type == STLINK_FLASH_TYPE_G4) { - cr_reg = STM32Gx_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L5) { + cr_reg = STM32L5_FLASH_NSCR; x |= (1 << FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; + x |= (1 << FLASH_H7_CR_PG); } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; x |= (1 << FLASH_CR_PG); @@ -739,11 +834,13 @@ static void clear_flash_cr_pg(stlink_t *sl) { cr_reg = FLASH_F4_CR; } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L5) { + cr_reg = STM32L5_FLASH_NSCR; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; } else { @@ -760,6 +857,8 @@ static void set_flash_cr_per(stlink_t *sl) { if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L5) { + cr_reg = STM32L5_FLASH_NSCR; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; } else { @@ -782,6 +881,8 @@ static void clear_flash_cr_per(stlink_t *sl) { if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L5) { + cr_reg = STM32L5_FLASH_NSCR; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; } else { @@ -797,25 +898,26 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) { if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; - cr_mer = 1 << FLASH_CR_MER; - cr_pg = 1 << FLASH_CR_PG; + cr_mer = (1 << FLASH_CR_MER); + cr_pg = (1 << FLASH_CR_PG); } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; - cr_mer = 1 << FLASH_CR_MER; - cr_pg = 1 << FLASH_CR_PG; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); - cr_pg = (1 << STM32L4_FLASH_CR_PG); + cr_mer = (1 << FLASH_CR_MER); + cr_pg = (1 << FLASH_CR_PG); } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; cr_mer = (1 << STM32Gx_FLASH_CR_MER1); - - if (sl->has_dual_bank) { - cr_mer |= (1 << STM32Gx_FLASH_CR_MER2); - } - + if (sl->has_dual_bank) { cr_mer |= (1 << STM32Gx_FLASH_CR_MER2); } + cr_pg = (1 << FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + cr_mer = (1 << STM32L4_FLASH_CR_MER1) | (1 << STM32L4_FLASH_CR_MER2); + cr_pg = (1 << STM32L4_FLASH_CR_PG); + } else if (sl->flash_type == STLINK_FLASH_TYPE_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 if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; @@ -866,10 +968,10 @@ static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) { if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; - cr_mer = 1 << FLASH_CR_MER; + 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; + 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); @@ -888,17 +990,23 @@ static void set_flash_cr_strt(stlink_t *sl) { if (sl->flash_type == STLINK_FLASH_TYPE_F4) { cr_reg = FLASH_F4_CR; - cr_strt = 1 << FLASH_F4_CR_STRT; + cr_strt = (1 << FLASH_F4_CR_STRT); } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { cr_reg = FLASH_F7_CR; - cr_strt = 1 << FLASH_F7_CR_STRT; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - cr_reg = STM32L4_FLASH_CR; - cr_strt = (1 << STM32L4_FLASH_CR_STRT); + cr_strt = (1 << FLASH_F7_CR_STRT); } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { cr_reg = STM32Gx_FLASH_CR; cr_strt = (1 << STM32Gx_FLASH_CR_STRT); + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + cr_reg = STM32L4_FLASH_CR; + cr_strt = (1 << STM32L4_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 if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + cr_reg = FLASH_H7_CR1; + cr_strt = (1 << FLASH_H7_CR_START); } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { cr_reg = STM32WB_FLASH_CR; cr_strt = (1 << STM32WB_FLASH_CR_STRT); @@ -926,17 +1034,21 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { sr_reg = FLASH_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { - sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; } else if (sl->flash_type == STLINK_FLASH_TYPE_F4) { sr_reg = FLASH_F4_SR; } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { sr_reg = FLASH_F7_SR; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - sr_reg = STM32L4_FLASH_SR; } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { sr_reg = STM32Gx_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L0) { + sr_reg = get_stm32l0_flash_base(sl) + FLASH_SR_OFF; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + sr_reg = STM32L4_FLASH_SR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L5) { + sr_reg = STM32L5_FLASH_NSSR; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + sr_reg = FLASH_H7_SR1; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { sr_reg = STM32WB_FLASH_SR; } else { @@ -966,11 +1078,15 @@ static inline unsigned int is_flash_busy(stlink_t *sl) { sr_busy_shift = FLASH_F4_SR_BSY; } else if (sl->flash_type == STLINK_FLASH_TYPE_F7) { sr_busy_shift = FLASH_F7_SR_BSY; - } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { - sr_busy_shift = STM32L4_FLASH_SR_BSY; } else if (sl->flash_type == STLINK_FLASH_TYPE_G0 || sl->flash_type == STLINK_FLASH_TYPE_G4) { sr_busy_shift = STM32Gx_FLASH_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L4) { + sr_busy_shift = STM32L4_FLASH_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_L5) { + sr_busy_shift = STM32L5_FLASH_SR_BSY; + } else if (sl->flash_type == STLINK_FLASH_TYPE_H7) { + sr_busy_shift = FLASH_SR_BSY; } else if (sl->flash_type == STLINK_FLASH_TYPE_WB) { sr_busy_shift = STM32WB_FLASH_SR_BSY; } else { @@ -993,6 +1109,23 @@ static void wait_flash_busy(stlink_t *sl) { ; } +// STM32H7 need check QW flag +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"); @@ -1065,8 +1198,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); + //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 ; + } #if DEBUG_FLASH fprintf(stdout, "PSIZ:0x%x 0x%x\n", x, n); #endif @@ -1085,6 +1223,17 @@ static inline void write_flash_cr_snb(stlink_t *sl, uint32_t n) { stlink_write_debug32(sl, FLASH_F4_CR, x); } +//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); + 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 << STM32L4_FLASH_SR_BSY)); uint32_t x = read_flash_cr(sl); @@ -1162,21 +1311,30 @@ int stlink_core_id(stlink_t *sl) { } // stlink_chip_id() is called by stlink_load_device_params() -// do not call this procedure directly. +// Do not call this procedure directly. int stlink_chip_id(stlink_t *sl, uint32_t *chip_id) { int ret; ret = stlink_read_debug32(sl, 0xE0042000, chip_id); - if (ret == -1) { - return(ret); + if (ret == -1) { return ret; } + + // STM32H7 chipid in 0x5C001000 + if (*chip_id == 0) { + ret = stlink_read_debug32(sl, 0x5C001000, chip_id); + if (ret == -1) { return ret; } } + if (ret == -1) { return(ret); } + if (*chip_id == 0) { // Try Corex M0 DBGMCU_IDCODE register address 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); } @@ -1293,6 +1451,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); @@ -1660,8 +1826,7 @@ void stlink_print_data(stlink_t * sl) { } */ } - //DLOG(" %02x", (unsigned int) sl->q_buf[i]); - fprintf(stderr, " %02x", (unsigned int) sl->q_buf[i]); + DLOG(" %02x\n", (unsigned int) sl->q_buf[i]); } //DLOG("\n\n"); fprintf(stderr, "\n"); @@ -2135,6 +2300,11 @@ uint32_t calculate_F7_sectornum(uint32_t flashaddr) { } } +//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) { @@ -2209,6 +2379,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_H7 || sl->flash_type == STLINK_FLASH_TYPE_L4) { // wait for ongoing op to finish wait_flash_busy(sl); @@ -2237,6 +2408,15 @@ 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); @@ -2330,6 +2510,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; @@ -2347,6 +2528,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); @@ -2613,6 +2801,7 @@ int stlink_write_flash( if ((sl->flash_type == STLINK_FLASH_TYPE_F4) || (sl->flash_type == STLINK_FLASH_TYPE_F7) || + (sl->flash_type == STLINK_FLASH_TYPE_H7) || (sl->flash_type == STLINK_FLASH_TYPE_L4)) { // TODO: check write operation @@ -2674,9 +2863,18 @@ int stlink_write_flash( 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) { - ELOG("stlink_flash_loader_run(%#zx) failed! == -1\n", addr + off); - return(-1); + // STM32H7 program flash directly + 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; @@ -2687,6 +2885,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/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/src/stlink-lib/chipid.c b/src/stlink-lib/chipid.c index 3763587e1..e179277fe 100644 --- a/src/stlink-lib/chipid.c +++ b/src/stlink-lib/chipid.c @@ -3,41 +3,89 @@ static const struct stlink_chipid_params devices[] = { { - // RM0410 document was used to find these paramaters - .chip_id = STLINK_CHIPID_STM32_F7XXXX, - .description = "F76xxx", - .flash_type = STLINK_FLASH_TYPE_F7, - .flash_size_reg = 0x1ff0f442, // section 45.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x80000, // "SRAM" byte size in hex from - .bootrom_base = 0x00200000, // ! "System memory" starting address from - .bootrom_size = 0xEDC0, // ! @todo "System memory" byte size in hex from - .option_base = STM32_F7_OPTION_BYTES_BASE, // Used for reading back the option bytes, writing uses FLASH_F7_OPTCR and FLASH_F7_OPTCR1 - .option_size = 0x20 + // unknown device + .chip_id = STLINK_CHIPID_UNKNOWN, + .description = "unknown device", + .flash_type = STLINK_FLASH_TYPE_UNKNOWN, + .flash_size_reg = 0x0, + .flash_pagesize = 0x0, + .sram_size = 0x0, + .bootrom_base = 0x0, + .bootrom_size = 0x0 }, + + /* == STM32F0 == */ + { - // RM0385 and DS10916 document was used to find these paramaters - .chip_id = STLINK_CHIPID_STM32_F7, - .description = "F7xx", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1ff0f442, // section 41.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x50000, // "SRAM" byte size in hex from DS Fig 18 - .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 18 - .bootrom_size = 0xEDC0 // "System memory" byte size in hex from DS Fig 18 + // RM0091 + .chip_id = STLINK_CHIPID_STM32_F0, + .description = "F0xx", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" + .flash_pagesize = 0x400, // Page sizes listed in table 4 + .sram_size = 0x2000, // "SRAM" byte size in hex from table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from table 2 + .bootrom_size = 0xC00 // "System memory" byte size in hex from table 2 }, { - // RM0431 and DS document was used to find these paramaters - .chip_id = STLINK_CHIPID_STM32_F72XXX, - .description = "F72x/F73x", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1ff07a22, // section 35.2 - .flash_pagesize = 0x800, // No flash pages - .sram_size = 0x40000, // "SRAM" byte size in hex from DS Fig 24 - .bootrom_base = 0x00100000, // "System memory" starting address from DS Fig 24 - .bootrom_size = 0xEDC0 // "System memory" byte size in hex from DS Fig 24 + // RM0091 + .chip_id = STLINK_CHIPID_STM32_F0_SMALL, + .description = "F0xx small", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" + .flash_pagesize = 0x400, // Page sizes listed in table 4 + .sram_size = 0x1000, // "SRAM" byte size in hex from table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from table 2 + .bootrom_size = 0xC00 // "System memory" byte size in hex from table 2 + }, + { + // RM0091 + .chip_id = STLINK_CHIPID_STM32_F04, + .description = "F04x", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" + .flash_pagesize = 0x400, // Page sizes listed in table 4 + .sram_size = 0x1800, // "SRAM" byte size in hex from table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from table 2 + .bootrom_size = 0xC00 // "System memory" byte size in hex from table 2 + }, + { + // RM0091 + .chip_id = STLINK_CHIPID_STM32_F0_CAN, + .description = "F07x", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" + .flash_pagesize = 0x800, // Page sizes listed in table 4 + .sram_size = 0x4000, // "SRAM" byte size in hex from table 2 + .bootrom_base = 0x1fffC800, // "System memory" starting address from table 2 + .bootrom_size = 0x3000 // "System memory" byte size in hex from table 2 + }, + { // RM0091 + .chip_id = STLINK_CHIPID_STM32_F09X, + .description = "F09X", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" + .flash_pagesize = 0x800, // Page sizes listed in table 4 + .sram_size = 0x8000, // "SRAM" byte size in hex from table 2 + .bootrom_base = 0x1fffd800, // "System memory" starting address from table 2 + .bootrom_size = 0x2000 // "System memory" byte size in hex from table 2 + }, + + /* == STM32F1 == */ + + { + // PM0063 + .chip_id = STLINK_CHIPID_STM32_F1_LOW, + .description = "F1 Low-density", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x400, + .sram_size = 0x2800, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 }, - { // table 2, PM0063 + { + // PM0063, Table 2 .chip_id = STLINK_CHIPID_STM32_F1_MEDIUM, .description = "F1xx Medium-density", .flash_type = STLINK_FLASH_TYPE_F0, @@ -47,11 +95,70 @@ static const struct stlink_chipid_params devices[] = { .bootrom_base = 0x1ffff000, .bootrom_size = 0x800 }, - { // table 1, PM0059 + { + // TODO: Add missing reference here! + .chip_id = STLINK_CHIPID_STM32_F1_HIGH, + .description = "F1xx High-density", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x10000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, + { + // RM0041 25.6.1 - Low and Medium density VL have same chipid. + .chip_id = STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW, + .description = "F1xx Value Line", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x400, + .sram_size = 0x2000, // 0x1000 for low density devices + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, + { + // TODO: Add missing reference here! + .chip_id = STLINK_CHIPID_STM32_F1_VL_HIGH, + .description = "F1xx High-density Value Line", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x8000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, + { + // TODO: Add missing reference here! + .chip_id = STLINK_CHIPID_STM32_F1_XL, + .description = "F1xx XL-density", + .flash_type = STLINK_FLASH_TYPE_F1_XL, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x18000, + .bootrom_base = 0x1fffe000, + .bootrom_size = 0x1800 + }, + { + // TODO: Add missing reference here! + .chip_id = STLINK_CHIPID_STM32_F1_CONN, + .description = "F1 Connectivity Line", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x10000, + .bootrom_base = 0x1fffb000, + .bootrom_size = 0x4800 + }, + + /* == STM32F2 == */ + + { + // PM0059, Table 1 .chip_id = STLINK_CHIPID_STM32_F2, .description = "F2xx", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1fff7a22, // as in RM0033 Rev 5 + .flash_size_reg = 0x1fff7a22, // as in RM0033 Rev. 5 .flash_pagesize = 0x20000, .sram_size = 0x20000, .bootrom_base = 0x1fff0000, @@ -59,59 +166,122 @@ static const struct stlink_chipid_params devices[] = { .option_base = 0x1FFFC000, .option_size = 4, }, - { // PM0063 - .chip_id = STLINK_CHIPID_STM32_F1_LOW, - .description = "F1 Low-density device", + + /* == STM32F3 == */ + + { + // STM32F30x + // TODO: Add missing reference here! + .chip_id = STLINK_CHIPID_STM32_F3_SMALL, + .description = "F3xx small", .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x400, - .sram_size = 0x2800, + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0xa000, + .bootrom_base = 0x1fffd800, + .bootrom_size = 0x2000 + }, + { + // STM32F303VCT6 device from the STM32F3 Discovery board + // RM0316 + .chip_id = STLINK_CHIPID_STM32_F3, + .description = "F3xx", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0xa000, .bootrom_base = 0x1ffff000, .bootrom_size = 0x800 }, { - .chip_id = STLINK_CHIPID_STM32_F4, - .description = "F4xx", + // STM32F373VCT6 device from the STM32F373 evaluation board + // Support based on F303 above (F30x and F37x have the same memory map). + .chip_id = STLINK_CHIPID_STM32_F37x, + .description = "F37x", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0xa000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 + }, + { + // STM32F303RET6 device from the STM32F3 Nucleo board + // RM0316 Rev. 5 + .chip_id = STLINK_CHIPID_STM32_F303_HIGH, + .description = "F303 high-density", + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, // Flash size data register (34.2.1) + .flash_pagesize = 0x800, // Flash memory organisation (4.2.1) + .sram_size = 0x10000, // Embedded SRAM (3.3) + .bootrom_base = 0x1fffd800, // System Memory (3.3.2 Table 4) + .bootrom_size = 0x2000 + }, + { + // STM32F334, STM32F303x6/8 and STM32F328 + // RM0316 & RM0364 + .chip_id = STLINK_CHIPID_STM32_F334, + .description = "F334 medium-density", // RM0316 (Section 33.6.1) + .flash_type = STLINK_FLASH_TYPE_F0, + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0x3000, + .bootrom_base = 0x1fffd800, + .bootrom_size = 0x2000 + }, + + /* == STM32F4 == */ + + { + // TODO: Add missing reference here! + .chip_id = STLINK_CHIPID_STM32_F4_LP, + .description = "F4xx (Low Power)", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // As in rm0090 since Rev 2 + .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, - .sram_size = 0x30000, + .sram_size = 0x10000, .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800 }, - { - .chip_id = STLINK_CHIPID_STM32_F4_DSI, - .description = "F46x/F47x", + { + // RM0090 Rev. 2 + .chip_id = STLINK_CHIPID_STM32_F4, + .description = "F4xx", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // As in rm0090 since Rev 2 + .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, - .sram_size = 0x40000, + .sram_size = 0x30000, .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800 }, - { - .chip_id = STLINK_CHIPID_STM32_F4_HD, - .description = "F42x/F43x", + { + // TODO: Add missing reference here! + .chip_id = STLINK_CHIPID_STM32_F4_DE, + .description = "F4xx (Dynamic Efficiency)", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // As in rm0090 since Rev 2 + .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, - .sram_size = 0x40000, + .sram_size = 0x18000, .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800 }, { - .chip_id = STLINK_CHIPID_STM32_F4_LP, - .description = "F4xx (low power)", + // STM32F410 + // RM0401 + .chip_id = STLINK_CHIPID_STM32_F410, + .description = "F410", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, + .flash_size_reg = 0x1fff7a22, .flash_pagesize = 0x4000, - .sram_size = 0x10000, + .sram_size = 0x8000, .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800 }, - { + { + // STM32F411RE + // TODO: Add missing reference here! .chip_id = STLINK_CHIPID_STM32_F411RE, - .description = "stm32f411re", + .description = "F411RE", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, @@ -120,103 +290,44 @@ static const struct stlink_chipid_params devices[] = { .bootrom_size = 0x7800 }, { - .chip_id = STLINK_CHIPID_STM32_F4_DE, - .description = "F4xx (Dynamic Efficency)", + // STM32F412 + // RM0402 + .chip_id = STLINK_CHIPID_STM32_F412, + .description = "F412", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, // "Flash size data register" + .flash_pagesize = 0x4000, // Flash module organisation from table 5 + .sram_size = 0x40000, // "SRAM" byte size in hex from table 4 + .bootrom_base = 0x1FFF0000, // "System memory" starting address from table 4 + .bootrom_size = 0x7800 // "System memory" byte size in hex from table 4 + }, + { + // RM0430 Rev. 2 + .chip_id = STLINK_CHIPID_STM32_F413, + .description = "F413", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, // "Flash size data register" (Section 35.2) + .flash_pagesize = 0x4000, // Flash module organisation from table 5 (variable sector sizes, but 0x4000 is smallest) + .sram_size = 0x50000, // "SRAM" byte size in hex from figure 2 (Table 4 only says 0x40000) + .bootrom_base = 0x1FFF0000, // "System memory" starting address from table 4 + .bootrom_size = 0x7800 // "System memory" byte size in hex from table 4 + }, + { + // RM0090 Rev. 2 + .chip_id = STLINK_CHIPID_STM32_F4_HD, + .description = "F42x/F43x", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1FFF7A22, .flash_pagesize = 0x4000, - .sram_size = 0x18000, + .sram_size = 0x40000, .bootrom_base = 0x1fff0000, .bootrom_size = 0x7800 }, { - .chip_id = STLINK_CHIPID_STM32_F1_HIGH, - .description = "F1xx High-density", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x10000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 - }, - { - // This ignores the EEPROM! (and uses the page erase size, - // not the sector write protection...) - .chip_id = STLINK_CHIPID_STM32_L1_MEDIUM, - .description = "L1xx Medium-density", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8004c, - .flash_pagesize = 0x100, - .sram_size = 0x4000, - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 - }, - { - .chip_id = STLINK_CHIPID_STM32_L1_CAT2, - .description = "L1xx Cat.2", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8004c, - .flash_pagesize = 0x100, - .sram_size = 0x8000, - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 - }, - { - .chip_id = STLINK_CHIPID_STM32_L1_MEDIUM_PLUS, - .description = "L1xx Medium-Plus-density", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff800cc, - .flash_pagesize = 0x100, - .sram_size = 0x8000, // not completely clear if there are some with 48k - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 - }, - { - .chip_id = STLINK_CHIPID_STM32_L1_HIGH, - .description = "L1xx High-density", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff800cc, - .flash_pagesize = 0x100, - .sram_size = 0xC000, // not completely clear if there are some with 32k - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000, - .option_base = STM32_L1_OPTION_BYTES_BASE, - .option_size = 8, - }, - { - .chip_id = STLINK_CHIPID_STM32_L152_RE, - .description = "L152RE", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff800cc, - .flash_pagesize = 0x100, - .sram_size = 0x14000, // not completely clear if there are some with 32k - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 - }, - { - .chip_id = STLINK_CHIPID_STM32_F1_CONN, - .description = "F1 Connectivity line", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x10000, - .bootrom_base = 0x1fffb000, - .bootrom_size = 0x4800 - }, - { // Low and Medium density VL have same chipid. RM0041 25.6.1 - .chip_id = STLINK_CHIPID_STM32_F1_VL_MEDIUM_LOW, - .description = "F1xx Value Line", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x400, - .sram_size = 0x2000, // 0x1000 for low density devices - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 - }, - { - // STM32F446x family. Support based on DM00135183.pdf (RM0390) document. + // STM32F446x + // RM0390 .chip_id = STLINK_CHIPID_STM32_F446, - .description = "F446", + .description = "F446x", .flash_type = STLINK_FLASH_TYPE_F4, .flash_size_reg = 0x1fff7a22, .flash_pagesize = 0x20000, @@ -226,159 +337,133 @@ static const struct stlink_chipid_params devices[] = { .option_base = 0x1FFFC000, .option_size = 4, }, - { - // STM32F410 MCUs. Support based on DM00180366.pdf (RM0401) document. - .chip_id = STLINK_CHIPID_STM32_F410, - .description = "F410", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1fff7a22, - .flash_pagesize = 0x4000, - .sram_size = 0x8000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 - }, - { - // This is STK32F303VCT6 device from STM32 F3 Discovery board. - // Support based on DM00043574.pdf (RM0316) document. - .chip_id = STLINK_CHIPID_STM32_F3, - .description = "F3xx", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0xa000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 - }, - { - // This is STK32F373VCT6 device from STM32 F373 eval board - // Support based on 303 above (37x and 30x have same memory map) - .chip_id = STLINK_CHIPID_STM32_F37x, - .description = "F3xx", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0xa000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 - }, - { - .chip_id = STLINK_CHIPID_STM32_F1_VL_HIGH, - .description = "F1xx High-density value line", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x8000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 - }, - { - .chip_id = STLINK_CHIPID_STM32_F1_XL, - .description = "F1xx XL-density", - .flash_type = STLINK_FLASH_TYPE_F1_XL, - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x18000, - .bootrom_base = 0x1fffe000, - .bootrom_size = 0x1800 - }, - { - // Use this as an example for mapping future chips: - // RM0091 document was used to find these paramaters - .chip_id = STLINK_CHIPID_STM32_F0_CAN, - .description = "F07x", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x800, // Page sizes listed in Table 4 - .sram_size = 0x4000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffC800, // "System memory" starting address from Table 2 - .bootrom_size = 0x3000 // "System memory" byte size in hex from Table 2 + { + // RM0090 Rev. 2 + .chip_id = STLINK_CHIPID_STM32_F4_DSI, + .description = "F46x/F47x", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, + .sram_size = 0x40000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 }, + + /* == STM32F7 == */ + { - // Use this as an example for mapping future chips: - // RM0091 document was used to find these paramaters - .chip_id = STLINK_CHIPID_STM32_F0, - .description = "F0xx", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 + // RM0385 & DS10916 + .chip_id = STLINK_CHIPID_STM32_F7, + .description = "F7xx", + .flash_type = STLINK_FLASH_TYPE_F4, + .flash_size_reg = 0x1ff0f442, // Section 41.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x50000, // "SRAM" byte size in hex from figure 18 + .bootrom_base = 0x00100000, // "System memory" starting address from figure 18 + .bootrom_size = 0xEDC0 // "System memory" byte size in hex from figure 18 }, { - // RM0402 document was used to find these parameters - // Table 4. - .chip_id = STLINK_CHIPID_STM32_F412, - .description = "F412", + // RM0431 + .chip_id = STLINK_CHIPID_STM32_F72XXX, + .description = "F72x/F73x", .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // "Flash size data register" (pg1135) - .flash_pagesize = 0x4000, // Table 5. Flash module organization ? - .sram_size = 0x40000, // "SRAM" byte size in hex from Table 4 - .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 - .bootrom_size = 0x7800 // "System memory" byte size in hex from Table 4 + .flash_size_reg = 0x1ff07a22, // Section 35.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x40000, // "SRAM" byte size in hex from figure 24 + .bootrom_base = 0x00100000, // "System memory" starting address from figure 24 + .bootrom_size = 0xEDC0 // "System memory" byte size in hex from figure 24 }, { - // RM0430 DocID029473 Rev 2 document was used to find these parameters - // Figure 2, Table 4, Table 5, Section 35.2 - .chip_id = STLINK_CHIPID_STM32_F413, - .description = "F413", - .flash_type = STLINK_FLASH_TYPE_F4, - .flash_size_reg = 0x1FFF7A22, // "Flash size data register" Section 35.2 - .flash_pagesize = 0x4000, // Table 5. Flash module organization (variable sector sizes, but 0x4000 is smallest) - .sram_size = 0x50000, // "SRAM" byte size in hex from Figure 2 (Table 4 only says 0x40000) - .bootrom_base = 0x1FFF0000, // "System memory" starting address from Table 4 - .bootrom_size = 0x7800 // "System memory" byte size in hex from Table 4 + // RM0410 + .chip_id = STLINK_CHIPID_STM32_F7XXXX, + .description = "F76xxx", + .flash_type = STLINK_FLASH_TYPE_F7, + .flash_size_reg = 0x1ff0f442, // Section 45.2 + .flash_pagesize = 0x800, // No flash pages + .sram_size = 0x80000, // "SRAM" byte size in hex + .bootrom_base = 0x00200000, // ! "System memory" starting address + .bootrom_size = 0xEDC0, // ! @todo "System memory" byte size in hex + .option_base = STM32_F7_OPTION_BYTES_BASE, // Used for reading back the option bytes, writing uses FLASH_F7_OPTCR and FLASH_F7_OPTCR1 + .option_size = 0x20 }, + + + /* == STM32G0 == */ + { - .chip_id = STLINK_CHIPID_STM32_F09X, - .description = "F09X", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x800, // Page sizes listed in Table 4 (pg 56) - .sram_size = 0x8000, // "SRAM" byte size in hex from Table 2 (pg 50) - .bootrom_base = 0x1fffd800, // "System memory" starting address from Table 2 - .bootrom_size = 0x2000 // "System memory" byte size in hex from Table 2 + // STM32G030/031/041 + // RM0454 & RM0444 + .chip_id = STLINK_CHIPID_STM32_G0_CAT1, + .description = "G030/G031/G041", + .flash_type = STLINK_FLASH_TYPE_G0, + .flash_size_reg = 0x1FFF75E0, // Section 38.2 + .flash_pagesize = 0x800, // 2k (Section 3.2) + .sram_size = 0x2000, // 8k (Section 2.3) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x2000, // 8k (Section 2.2.2 Table 3) + .option_base = STM32_G0_OPTION_BYTES_BASE, + .option_size = 4, }, { - // Use this as an example for mapping future chips: - // RM0091 document was used to find these paramaters - .chip_id = STLINK_CHIPID_STM32_F04, - .description = "F04x", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x1800, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 + // STM32G071/081 + // RM0444 + .chip_id = STLINK_CHIPID_STM32_G0_CAT2, + .description = "G070/G071/G081", + .flash_type = STLINK_FLASH_TYPE_G0, + .flash_size_reg = 0x1FFF75E0, // Section 38.2 + .flash_pagesize = 0x800, // 2k (Section 3.2) + .sram_size = 0x9000, // 36k (Section 2.3) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7000, // 28k (Section 2.2.2 Table 2) + .option_base = STM32_G0_OPTION_BYTES_BASE, + .option_size = 4, }, + + /* == STM32G4 == */ + { - // Use this as an example for mapping future chips: - // RM0091 document was used to find these paramaters - .chip_id = STLINK_CHIPID_STM32_F0_SMALL, - .description = "F0xx small", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 + // STM32G431/441 + // RM0440 + .chip_id = STLINK_CHIPID_STM32_G4_CAT2, + .description = "G4 Category-2", + .flash_type = STLINK_FLASH_TYPE_G4, + .flash_size_reg = 0x1FFF75E0, // Section 47.2 + .flash_pagesize = 0x800, // 2k (Section 3.3.1) + // SRAM1 is 16k at 0x20000000 + // SRAM2 is 6k at 0x20014000 + // SRAM3/CCM is 10k at 0x10000000, aliased at 0x20018000 + .sram_size = 0x8000, // 32k (Section 2.4) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7000, // 28k (Table 2) + .option_base = STM32_G4_OPTION_BYTES_BASE, + .option_size = 4, }, { - // STM32F30x - .chip_id = STLINK_CHIPID_STM32_F3_SMALL, - .description = "F3xx small", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0xa000, - .bootrom_base = 0x1fffd800, - .bootrom_size = 0x2000 + // STM32G471/473/474/483/484 + // RM0440 + .chip_id = STLINK_CHIPID_STM32_G4_CAT3, + .description = "G4 Category-3", + .flash_type = STLINK_FLASH_TYPE_G4, + .has_dual_bank = true, + .flash_size_reg = 0x1FFF75E0, // Section 47.2 + .flash_pagesize = 0x800, // 2k (Section 3.3.1) + // SRAM1 is 80k at 0x20000000 + // SRAM2 is 16k at 0x20014000 + // SRAM3/CCM is 32k at 0x10000000, aliased at 0x20018000 + .sram_size = 0x18000, // 128k (Section 2.4) + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7000, // 28k (Table 2) + .option_base = STM32_G4_OPTION_BYTES_BASE, + .option_size = 4, }, + + /* == STM32L0 == */ + { - // STM32L0x - // RM0367,RM0377 documents was used to find these parameters - .chip_id = STLINK_CHIPID_STM32_L0, - .description = "L0x3", + // STM32L0x Category 2 + // RM0367 & RM0377 + .chip_id = STLINK_CHIPID_STM32_L0_CAT2, + .description = "L0xx Category 2", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8007c, .flash_pagesize = 0x80, @@ -390,7 +475,7 @@ static const struct stlink_chipid_params devices[] = { }, { // STM32L0x Category 5 - // RM0367,RM0377 documents was used to find these parameters + // RM0367 & RM0377 .chip_id = STLINK_CHIPID_STM32_L0_CAT5, .description = "L0xx Category 5", .flash_type = STLINK_FLASH_TYPE_L0, @@ -403,10 +488,10 @@ static const struct stlink_chipid_params devices[] = { .option_size = 4, }, { - // STM32L0x Category 2 - // RM0367,RM0377 documents was used to find these parameters - .chip_id = STLINK_CHIPID_STM32_L0_CAT2, - .description = "L0xx Category 2", + // STM32L0x3 + // RM0367 & RM0377 + .chip_id = STLINK_CHIPID_STM32_L0, + .description = "L0x3", .flash_type = STLINK_FLASH_TYPE_L0, .flash_size_reg = 0x1ff8007c, .flash_pagesize = 0x80, @@ -417,224 +502,224 @@ static const struct stlink_chipid_params devices[] = { .option_size = 4, }, { - // STM32F334, STM32F303x6/8, and STM32F328 - // From RM0364 and RM0316 - .chip_id = STLINK_CHIPID_STM32_F334, - .description = "F334 medium density", // (RM0316 sec 33.6.1) - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0x3000, - .bootrom_base = 0x1fffd800, + // STM32L011 + // TODO: Add missing reference here! + .chip_id = STLINK_CHIPID_STM32_L011, + .description = "L011", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8007c, + .flash_pagesize = 0x80, + .sram_size = 0x2000, + .bootrom_base = 0x1ff00000, .bootrom_size = 0x2000 }, + + /* == STM32L1 == */ + { - // This is STK32F303RET6 device from STM32 F3 Nucelo board. - // Support based on DM00043574.pdf (RM0316) document rev 5. - .chip_id = STLINK_CHIPID_STM32_F303_HIGH, - .description = "F303 high density", - .flash_type = STLINK_FLASH_TYPE_F0, - .flash_size_reg = 0x1ffff7cc, // 34.2.1 Flash size data register - .flash_pagesize = 0x800, // 4.2.1 Flash memory organization - .sram_size = 0x10000, // 3.3 Embedded SRAM - .bootrom_base = 0x1fffd800, // 3.3.2 / Table 4 System Memory - .bootrom_size = 0x2000 + // TODO: Add missing reference here! + // This ignores the EEPROM! (and uses the page erase size, not the sector write protection...) + .chip_id = STLINK_CHIPID_STM32_L1_MEDIUM, + .description = "L1xx Medium-density", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8004c, + .flash_pagesize = 0x100, + .sram_size = 0x4000, + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 + }, + { + // TODO: Add missing reference here! + .chip_id = STLINK_CHIPID_STM32_L1_MEDIUM_PLUS, + .description = "L1xx Medium-Plus-density", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff800cc, + .flash_pagesize = 0x100, + .sram_size = 0x8000, // unclear if there are some device with 48k + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 + }, + { + // TODO: Add missing reference here! + .chip_id = STLINK_CHIPID_STM32_L1_HIGH, + .description = "L1xx High-density", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff800cc, + .flash_pagesize = 0x100, + .sram_size = 0xC000, // unclear if there are some devices with 32k + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000, + .option_base = STM32_L1_OPTION_BYTES_BASE, + .option_size = 8, + }, + { + // TODO: Add missing reference here! + .chip_id = STLINK_CHIPID_STM32_L1_CAT2, + .description = "L1xx Category 2", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff8004c, + .flash_pagesize = 0x100, + .sram_size = 0x8000, + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 + }, + { + // STM32L152RE + // TODO: Add missing reference here! + .chip_id = STLINK_CHIPID_STM32_L152_RE, + .description = "L152RE", + .flash_type = STLINK_FLASH_TYPE_L0, + .flash_size_reg = 0x1ff800cc, + .flash_pagesize = 0x100, + .sram_size = 0x14000, // unclear if there are some devices with 32k + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 }, + + /* == STM32L4 == */ + { - // STM32L4x6 - // From RM0351. + // STM32L4xx + // RM0351 .chip_id = STLINK_CHIPID_STM32_L4, .description = "L4xx", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1FFF75e0, // "Flash size data register" (sec 45.2, page 1671) - .flash_pagesize = 0x800, // 2k (sec 3.2, page 78; also appears in sec 3.3.1 - // and tables 4-6 on pages 79-81) + .flash_size_reg = 0x1FFF75e0, // "Flash size data register" (Section 45.2) + .flash_pagesize = 0x800, // 2k (Section 3.2, also appears in section 3.3.1 and tables 4-6) // SRAM1 is "up to" 96k in the standard Cortex-M memory map; - // SRAM2 is 32k mapped at at 0x10000000 (sec 2.3, page 73 for - // sizes; table 2, page 74 for SRAM2 location) + // SRAM2 is 32k mapped at at 0x10000000 (Section 2.3 for sizes; table 2 for SRAM2 location) .sram_size = 0x18000, - .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) - .bootrom_size = 0x7000, // 28k (per bank), same source as base + .bootrom_base = 0x1fff0000, // Tables 4-6 (Bank 1 system memory) + .bootrom_size = 0x7000, // 28k (per bank), same source as base .option_base = STM32_L4_OPTION_BYTES_BASE, .option_size = 4, }, { - // STM32L4RX - // From DM00310109.pdf - .chip_id = STLINK_CHIPID_STM32_L4RX, - .description = "L4Rx", - .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 52.2, page 2049) - .flash_pagesize = 0x1000, // 4k, section 3.3, pg 97 - .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 - .bootrom_base = 0x1fff0000, // 3.3.1, pg 99 - .bootrom_size = 0x7000 // 28k (per bank), same source as base (pg 99) - }, - { - // STLINK_CHIPID_STM32_L41X - // From RM0394 Rev 4 and DS12469 Rev 5 + // RM0394 Rev. 4 & DS12469 Rev. 5 .chip_id = STLINK_CHIPID_STM32_L41X, .description = "L41x", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (RM0394, sec 47.2, page 1586) - .flash_pagesize = 0x800, // 2k (DS12469, sec 3.4, page 17) + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (RM0394, Section 47.2) + .flash_pagesize = 0x800, // 2k (DS12469, Section 3.4) // SRAM1 is 32k at 0x20000000 - // SRAM2 is 8k at 0x10000000 and 0x20008000 (DS12469, sec 3.5, page 18) - .sram_size = 0xa000, // 40k (DS12469, sec 3.5, page 18) - .bootrom_base = 0x1fff0000, // System Memory (RM0394, sec 3.3.1, table 8) - .bootrom_size = 0x7000 // 28k, same source as base + // SRAM2 is 8k at 0x10000000 and 0x20008000 (DS12469, Section 3.5) + .sram_size = 0xa000, // 40k (DS12469, Section 3.5) + .bootrom_base = 0x1fff0000, // System Memory (RM0394, Section 3.3.1, table 8) + .bootrom_size = 0x7000 // 28k, same source as base }, { - // STLINK_CHIPID_STM32_L43X - // From RM0392. + // RM0392 .chip_id = STLINK_CHIPID_STM32_L43X, .description = "L43x/L44x", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 43.2, page 1410) - .flash_pagesize = 0x800, // 2k (sec 3.2, page 74; also appears in sec 3.3.1 - // and tables 7-8 on pages 75-76) + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (Section 43.2) + .flash_pagesize = 0x800, // 2k (Section 3.2, also appears in section 3.3.1 and tables 7-8) // SRAM1 is "up to" 64k in the standard Cortex-M memory map; - // SRAM2 is 16k mapped at 0x10000000 (sec 2.3, page 73 for - // sizes; table 2, page 74 for SRAM2 location) + // SRAM2 is 16k mapped at 0x10000000 (Section 2.3 for sizes; table 2 for SRAM2 location) .sram_size = 0xc000, - .bootrom_base = 0x1fff0000, // Tables 4-6, pages 80-81 (Bank 1 system memory) - .bootrom_size = 0x7000, // 28k (per bank), same source as base + .bootrom_base = 0x1fff0000, // Tables 4-6 (Bank 1 system memory) + .bootrom_size = 0x7000, // 28k (per bank), same source as base .option_base = STM32_L4_OPTION_BYTES_BASE, .option_size = 4, }, { - // STLINK_CHIPID_STM32_L496X - // Support based on en.DM00083560.pdf (RM0351) document rev 5. + // RM0394 + .chip_id = STLINK_CHIPID_STM32_L46X, + .description = "L45x/46x", + .flash_type = STLINK_FLASH_TYPE_L4, + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (Section 45.2) + .flash_pagesize = 0x800, // 2k (Section 3.2, also appears in section 3.3.1 and table 7) + // SRAM1 is 128k at 0x20000000; + // SRAM2 is 32k mapped at 0x10000000 (Section 2.4.2, table 3-4 and figure 2) + .sram_size = 0x20000, + .bootrom_base = 0x1fff0000, // Tables 6 and figure 2 (Bank 1 system memory) + .bootrom_size = 0x7000 // 28k (per bank), same source as base + }, + { + // RM0351 Rev. 5 .chip_id = STLINK_CHIPID_STM32_L496X, .description = "L496x/L4A6x", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 49.2, page 1809) - .flash_pagesize = 0x800, // Page erase (2 Kbyte) (sec 3.2, page 93) + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (Section 49.2) + .flash_pagesize = 0x800, // Page erase (2 Kbyte) (Section 3.2) // SRAM1 is 256k at 0x20000000 - // SRAM2 is 64k at 0x20040000 (sec 2.2.1, fig 2, page 74) - .sram_size = 0x40000, // Embedded SRAM (sec 2.4, page 84) - .bootrom_base = 0x1fff0000, // System Memory (Bank 1) (sec 3.3.1) + // SRAM2 is 64k at 0x20040000 (Section 2.2.1, Figure 2) + .sram_size = 0x40000, // Embedded SRAM (Section 2.4) + .bootrom_base = 0x1fff0000, // System Memory (Bank 1) (Section 3.3.1) .bootrom_size = 0x7000, // 28k (per bank), same source as base .option_base = STM32_L4_OPTION_BYTES_BASE, .option_size = 4, }, { - // STLINK_CHIPID_STM32_L46X - // From RM0394 (updated version of RM0392?). - .chip_id = STLINK_CHIPID_STM32_L46X, - .description = "L45x/46x", + // STM32L4Rx + // RM0432 + .chip_id = STLINK_CHIPID_STM32_L4RX, + .description = "L4Rx", .flash_type = STLINK_FLASH_TYPE_L4, - .flash_size_reg = 0x1fff75e0, // "Flash size data register" (sec 45.2, page 1463) - .flash_pagesize = 0x800, // 2k (sec 3.2, page 73; also appears in sec 3.3.1 - // and tables 7 on pages 73-74) - // SRAM1 is 128k at 0x20000000; - // SRAM2 is 32k mapped at 0x10000000 (sec 2.4.2, table 3-4, page 68, also fig 2 on page 63) - .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, // Tables 6, pages 71-72 (Bank 1 system memory, also fig 2 on page 63) + .flash_size_reg = 0x1fff75e0, // "Flash size data register" (Section 52.2) + .flash_pagesize = 0x1000, // 4k (Section 3.3) + .sram_size = 0xa0000, // 192k (SRAM1) + 64k SRAM2 + 384k SRAM3 = 640k, or 0xA0000 + .bootrom_base = 0x1fff0000, // Section 3.3.1 .bootrom_size = 0x7000 // 28k (per bank), same source as base }, - { - // STM32L011 - .chip_id = STLINK_CHIPID_STM32_L011, - .description = "L011", - .flash_type = STLINK_FLASH_TYPE_L0, - .flash_size_reg = 0x1ff8007c, - .flash_pagesize = 0x80, - .sram_size = 0x2000, - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x2000 - }, - { - // STM32G030/031/041 (from RM0454 & RM0444) - .chip_id = STLINK_CHIPID_STM32_G0_CAT1, - .description = "G030/G031/G041", - .flash_type = STLINK_FLASH_TYPE_G0, - .flash_size_reg = 0x1FFF75E0, // Section 38.2 - .flash_pagesize = 0x800, // 2k (sec 3.2) - .sram_size = 0x2000, // 8k (sec 2.3) - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x2000, // 8k (sec 2.2.2 table 3) - .option_base = STM32_G0_OPTION_BYTES_BASE, - .option_size = 4, - }, - { - // STM32G071/081 (from RM0444) - .chip_id = STLINK_CHIPID_STM32_G0_CAT2, - .description = "G070/G071/G081", - .flash_type = STLINK_FLASH_TYPE_G0, - .flash_size_reg = 0x1FFF75E0, // Section 38.2 - .flash_pagesize = 0x800, // 2k (sec 3.2) - .sram_size = 0x9000, // 36k (sec 2.3) - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (sec 2.2.2 table 2) - .option_base = STM32_G0_OPTION_BYTES_BASE, - .option_size = 4, - }, - { - // STM32G431/441 (from RM0440) - .chip_id = STLINK_CHIPID_STM32_G4_CAT2, - .description = "G4 Category-2", - .flash_type = STLINK_FLASH_TYPE_G4, - .flash_size_reg = 0x1FFF75E0, // Section 47.2 - .flash_pagesize = 0x800, // 2k (sec 3.3.1) - // SRAM1 is 16k at 0x20000000 - // SRAM2 is 6k at 0x20014000 - // SRAM3/CCM is 10k at 0x10000000, aliased at 0x20018000 - .sram_size = 0x8000, // 32k (sec 2.4) - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (table 2) - .option_base = STM32_G4_OPTION_BYTES_BASE, + + /* == STM32L5 == */ + + { + // STM32L5x2 + // 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 memory map + .bootrom_size = 0x8000, + .option_base = STM32_L5_OPTION_BYTES_BASE, .option_size = 4, }, + + /* == STM32H7 == */ + { - // STM32G471/473/474/483/484 (from RM0440) - .chip_id = STLINK_CHIPID_STM32_G4_CAT3, - .description = "G4 Category-3", - .flash_type = STLINK_FLASH_TYPE_G4, - .has_dual_bank = true, - .flash_size_reg = 0x1FFF75E0, // Section 47.2 - .flash_pagesize = 0x800, // 2k (sec 3.3.1) - // SRAM1 is 80k at 0x20000000 - // SRAM2 is 16k at 0x20014000 - // SRAM3/CCM is 32k at 0x10000000, aliased at 0x20018000 - .sram_size = 0x18000, // 128k (sec 2.4) - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7000, // 28k (table 2) - .option_base = STM32_G4_OPTION_BYTES_BASE, - .option_size = 4, + // RM0433 + .chip_id = STLINK_CHIPID_STM32_H74XXX, + .description = "H743xx", + .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 + .bootrom_base = 0x1FFF0000, //! "System memory" starting address + .bootrom_size = 0x1E800 //! @todo "System memory" byte size in hex }, + + /* == STM32WB == */ + { - // STM32WB55 (from RM0434) + // STM32WB55 + // RM0434 .chip_id = STLINK_CHIPID_STM32_WB55, .description = "WB55", .flash_type = STLINK_FLASH_TYPE_WB, .flash_size_reg = 0x1FFF75E0, .flash_pagesize = 0x1000, // 4k .sram_size = 0x40000, - .bootrom_base = 0x1fff0000, // see the memory map + .bootrom_base = 0x1fff0000, // see the memory map .bootrom_size = 0x7000 }, - { - // unknown - .chip_id = STLINK_CHIPID_UNKNOWN, - .description = "unknown device", - .flash_type = STLINK_FLASH_TYPE_UNKNOWN, - .flash_size_reg = 0x0, - .flash_pagesize = 0x0, - .sram_size = 0x0, - .bootrom_base = 0x0, - .bootrom_size = 0x0 - }, }; const struct stlink_chipid_params *stlink_chipid_get_params(uint32_t chipid) { const struct stlink_chipid_params *params = NULL; - for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) + for (size_t n = 0; n < STLINK_ARRAY_SIZE(devices); n++) { if (devices[n].chip_id == chipid) { params = &devices[n]; break; } + } return(params); } 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 }; diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index 0e79c3c0a..6f6afb288 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -42,7 +42,19 @@ static const uint8_t loader_code_stm32vl[] = { /* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */ static const uint8_t loader_code_stm32f0[] = { - 0xc0, 0x46, 0xc0, 0x46, + /* + * These two NOPs here are a safety precaution, added by Pekka Nikander + * while debugging the STM32F05x support. They may not be needed, but + * there were strange problems with simpler programs, like a program + * that had just a breakpoint or a program that first moved zero to register r2 + * and then had a breakpoint. So, it appears safest to have these two nops. + * + * Feel free to remove them, if you dare, but then please do test the result + * rigorously. Also, if you remove these, it may be a good idea first to + * #if 0 them out, with a comment when these were taken out, and to remove + * these only a few months later... But YMMV. + */ + 0x13, 0x4f, 0x3c, 0x68, 0x13, 0x4f, 0x3e, 0x68, 0x36, 0x19, 0x13, 0x4f, @@ -63,9 +75,9 @@ static const uint8_t loader_code_stm32f0[] = { 0x00, 0x20, 0x02, 0x40, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x20, 0x48, 0x00, 0x00, 0x20, 0x4c, 0x00, 0x00, 0x20, - 0x50, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 @@ -79,7 +91,7 @@ static const uint8_t loader_code_stm32l[] = { 0x38, 0x44, 0x39, 0x44, 0x4f, 0xf0, 0x01, 0x07, 0xd2, 0x1b, 0x00, 0x2a, - 0xf4, 0xd1, 0x00, 0xbe, + 0xf4, 0xd1, 0x00, 0xbe }; static const uint8_t loader_code_stm32f4[] = { @@ -173,7 +185,6 @@ static const uint8_t loader_code_stm32f7_lv[] = { 0x0e, 0x00, 0x00, 0x00 }; - int stlink_flash_loader_init(stlink_t *sl, flash_loader_t *fl) { size_t size = 0; @@ -206,7 +217,7 @@ static int loader_v_dependent_assignment(stlink_t *sl, if (voltage == -1) { retval = -1; printf("Failed to read Target voltage\n"); - } else { + } else { if (voltage > 2700) { *loader_code = high_v_loader; *loader_size = high_v_loader_size; @@ -232,7 +243,7 @@ int stlink_flash_loader_write_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* sl->chip_id == STLINK_CHIPID_STM32_L011 || sl->chip_id == STLINK_CHIPID_STM32_L0 || sl->chip_id == STLINK_CHIPID_STM32_L0_CAT5 || - sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { // STM32l + sl->chip_id == STLINK_CHIPID_STM32_L0_CAT2) { // STM32L loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); } else if (sl->core_id == STM32VL_CORE_ID || diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 9726ddc4a..3d5b13369 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -222,9 +222,11 @@ int _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr, uint32_t *data) { ssize_t size; const int rep_len = 8; + memset(rdata, 0, rep_len); + 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; write_uint32(&cmd[i], addr); size = send_recv(slu, 1, cmd, slu->cmd_len, rdata, rep_len); @@ -362,7 +364,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; } size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); @@ -790,8 +792,7 @@ int _stlink_usb_read_reg(stlink_t *sl, int r_idx, struct stlink_reg *regp) { } else { cmd[i++] = STLINK_DEBUG_APIV2_READREG; } - - cmd[i++] = (uint8_t)r_idx; + cmd[i++] = (uint8_t) r_idx; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { @@ -827,6 +828,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; @@ -956,7 +1012,6 @@ int _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { } else { cmd[i++] = STLINK_DEBUG_APIV2_WRITEREG; } - cmd[i++] = idx; write_uint32(&cmd[i], reg); size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); 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, diff --git a/tests/usb.c b/tests/usb.c index 03c135f00..429138041 100644 --- a/tests/usb.c +++ b/tests/usb.c @@ -26,8 +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); @@ -96,6 +95,11 @@ 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);