Skip to content

Commit

Permalink
Merge pull request #910 from grevaillot/to_merge/stm32gx_work
Browse files Browse the repository at this point in the history
STM32G0/G4 improvements

- Enable mass erase with a flash programming check
- Handle G4 Cat3 devices with configurable dual bank flash by using a helper
  • Loading branch information
Nightwalker-87 committed Apr 6, 2020
2 parents 89fa734 + 4437314 commit 5e3abc3
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 3 deletions.
2 changes: 2 additions & 0 deletions include/stlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ typedef struct flash_loader {
int serial_size;

enum stlink_flash_type flash_type; // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STLINK_FLASH_TYPE_xxx
bool has_dual_bank;

stm32_addr_t flash_base; // STM32_FLASH_BASE, set by stlink_load_device_params()
size_t flash_size; // calculated by stlink_load_device_params()
size_t flash_pgsz; // stlink_chipid_params.flash_pagesize, set by stlink_load_device_params()
Expand Down
1 change: 1 addition & 0 deletions include/stlink/chipid.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ struct stlink_chipid_params {
uint32_t chip_id;
char *description;
enum stlink_flash_type flash_type;
bool has_dual_bank;
uint32_t flash_size_reg;
uint32_t flash_pagesize;
uint32_t sram_size;
Expand Down
1 change: 1 addition & 0 deletions src/chipid.c
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,7 @@ static const struct stlink_chipid_params devices[] = {
.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
Expand Down
42 changes: 39 additions & 3 deletions src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
#define STM32Gx_FLASH_CR_PNB (3) /* Page number */
#define STM32G0_FLASH_CR_PNG_LEN (5) /* STM32G0: 5 page number bits */
#define STM32G4_FLASH_CR_PNG_LEN (7) /* STM32G4: 7 page number bits */
#define STM32Gx_FLASH_CR_MER2 (15) /* Mass erase (2nd bank)*/
#define STM32Gx_FLASH_CR_STRT (16) /* Start */
#define STM32Gx_FLASH_CR_OPTSTRT (17) /* Start of modification of option bytes */
#define STM32Gx_FLASH_CR_FSTPG (18) /* Fast programming */
Expand All @@ -128,8 +129,14 @@
#define STM32Gx_FLASH_CR_OBL_LAUNCH (27) /* Forces the option byte loading */
#define STM32Gx_FLASH_CR_OPTLOCK (30) /* Options Lock */
#define STM32Gx_FLASH_CR_LOCK (31) /* FLASH_CR Lock */

// G0/G4 FLASH status register
#define STM32Gx_FLASH_SR_ERROR_MASK (0x3fa)
#define STM32Gx_FLASH_SR_BSY (16) /* FLASH_SR Busy */
#define STM32Gx_FLASH_SR_EOP (0) /* FLASH_EOP End of Operation */

// G4 FLASH option register
#define STM32G4_FLASH_OPTR_DBANK (22) /* FLASH_OPTR Dual Bank Mode */

// WB (RM0434)
#define STM32WB_FLASH_REGS_ADDR ((uint32_t)0x58004000)
Expand Down Expand Up @@ -515,7 +522,10 @@ static void set_flash_cr_mer(stlink_t *sl, bool v) {
} else if (sl->flash_type == STLINK_FLASH_TYPE_G0 ||
sl->flash_type == STLINK_FLASH_TYPE_G4) {
cr_reg = STM32Gx_FLASH_CR;
cr_mer = (1 << FLASH_CR_MER);
cr_mer = (1 << STM32Gx_FLASH_CR_MER1);
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_WB) {
cr_reg = STM32WB_FLASH_CR;
Expand Down Expand Up @@ -680,6 +690,22 @@ static void wait_flash_busy_progress(stlink_t *sl) {
fprintf(stdout, "\n");
}

static int check_flash_error(stlink_t *sl)
{
uint32_t res = 0;
if ((sl->flash_type == STLINK_FLASH_TYPE_G0) ||
(sl->flash_type == STLINK_FLASH_TYPE_G4)) {
res = read_flash_sr(sl) & STM32Gx_FLASH_SR_ERROR_MASK;
}

if (res) {
ELOG("Flash programming error : %#010x\n", res);
return -1;
}

return 0;
}

static inline unsigned int is_flash_eop(stlink_t *sl) {
return read_flash_sr(sl) & (1 << FLASH_SR_EOP);
}
Expand Down Expand Up @@ -885,7 +911,9 @@ int stlink_load_device_params(stlink_t *sl) {
} else {
sl->flash_size = flash_size * 1024;
}

sl->flash_type = params->flash_type;
sl->has_dual_bank = params->has_dual_bank;
sl->flash_pgsz = params->flash_pagesize;
sl->sram_size = params->sram_size;
sl->sys_base = params->bootrom_base;
Expand All @@ -897,6 +925,14 @@ int stlink_load_device_params(stlink_t *sl) {
sl->sram_size = 0x1000;
}

if (sl->chip_id == STLINK_CHIPID_STM32_G4_CAT3) {
uint32_t flash_optr;
stlink_read_debug32(sl, STM32Gx_FLASH_OPTR, &flash_optr);
if (!(flash_optr & (1 << STM32G4_FLASH_OPTR_DBANK))) {
sl->flash_pgsz <<= 1;
}
}

#if 0
// Old code -- REW
ILOG("Device connected is: %s, id %#x\n", params->description, chip_id);
Expand Down Expand Up @@ -1961,8 +1997,6 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr)
int stlink_erase_flash_mass(stlink_t *sl) {
/* TODO: User MER bit to mass-erase G0, G4, WB series. */
if (sl->flash_type == STLINK_FLASH_TYPE_L0 ||
sl->flash_type == STLINK_FLASH_TYPE_G0 ||
sl->flash_type == STLINK_FLASH_TYPE_G4 ||
sl->flash_type == STLINK_FLASH_TYPE_WB) {
/* erase each page */
int i = 0, num_pages = (int) sl->flash_size/sl->flash_pgsz;
Expand Down Expand Up @@ -2001,6 +2035,8 @@ int stlink_erase_flash_mass(stlink_t *sl) {
/* wait for completion */
wait_flash_busy_progress(sl);

check_flash_error(sl);

/* relock the flash */
lock_flash(sl);

Expand Down

0 comments on commit 5e3abc3

Please sign in to comment.