Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for flashing second bank on STM32F10x_XL #592

Merged
merged 1 commit into from
May 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion include/stlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ extern "C" {
STLINK_FLASH_TYPE_F0,
STLINK_FLASH_TYPE_L0,
STLINK_FLASH_TYPE_F4,
STLINK_FLASH_TYPE_L4
STLINK_FLASH_TYPE_L4,
STLINK_FLASH_TYPE_F1_XL,
};

struct stlink_reg {
Expand Down
2 changes: 1 addition & 1 deletion src/chipid.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ static const struct stlink_chipid_params devices[] = {
{
.chip_id = STLINK_CHIPID_STM32_F1_XL,
.description = "F1 XL-density device",
.flash_type = STLINK_FLASH_TYPE_F0,
.flash_type = STLINK_FLASH_TYPE_F1_XL,
.flash_size_reg = 0x1ffff7e0,
.flash_pagesize = 0x800,
.sram_size = 0x18000,
Expand Down
88 changes: 82 additions & 6 deletions src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@
#define FLASH_OBR (FLASH_REGS_ADDR + 0x1c)
#define FLASH_WRPR (FLASH_REGS_ADDR + 0x20)

// STM32F10x_XL has two flash memory banks with separate registers to control the second bank.
#define FLASH_KEYR2 (FLASH_REGS_ADDR + 0x44)
#define FLASH_SR2 (FLASH_REGS_ADDR + 0x4c)
#define FLASH_CR2 (FLASH_REGS_ADDR + 0x50)
#define FLASH_AR2 (FLASH_REGS_ADDR + 0x54)
#define FLASH_BANK2_START_ADDR 0x08080000

// For STM32F05x, the RDPTR_KEY may be wrong, but as it is not used anywhere...
#define FLASH_RDPTR_KEY 0x00a5
#define FLASH_KEY1 0x45670123
Expand Down Expand Up @@ -189,6 +196,15 @@ static inline uint32_t read_flash_cr(stlink_t *sl) {
return res;
}

static inline uint32_t read_flash_cr2(stlink_t *sl) {
uint32_t res;
stlink_read_debug32(sl, FLASH_CR2, &res);
#if DEBUG_FLASH
fprintf(stdout, "CR2:0x%x\n", res);
#endif
return res;
}

static inline unsigned int is_flash_locked(stlink_t *sl) {
/* return non zero for true */
uint32_t cr_lock_shift, cr = read_flash_cr(sl);
Expand Down Expand Up @@ -219,6 +235,11 @@ static void unlock_flash(stlink_t *sl) {

stlink_write_debug32(sl, key_reg, FLASH_KEY1);
stlink_write_debug32(sl, key_reg, FLASH_KEY2);

if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) {
stlink_write_debug32(sl, FLASH_KEYR2, FLASH_KEY1);
stlink_write_debug32(sl, FLASH_KEYR2, FLASH_KEY2);
}
}

static int unlock_flash_if(stlink_t *sl) {
Expand Down Expand Up @@ -251,6 +272,11 @@ static void lock_flash(stlink_t *sl) {

n = read_flash_cr(sl) | (1 << cr_lock_shift);
stlink_write_debug32(sl, cr_reg, n);

if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) {
n = read_flash_cr2(sl) | (1 << cr_lock_shift);
stlink_write_debug32(sl, FLASH_CR2, n);
}
}


Expand Down Expand Up @@ -293,6 +319,11 @@ static void set_flash_cr_per(stlink_t *sl) {
stlink_write_debug32(sl, FLASH_CR, n);
}

static void set_flash_cr2_per(stlink_t *sl) {
const uint32_t n = 1 << FLASH_CR_PER;
stlink_write_debug32(sl, FLASH_CR2, n);
}

static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) {
const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_PER);
stlink_write_debug32(sl, FLASH_CR, n);
Expand Down Expand Up @@ -367,6 +398,14 @@ static void set_flash_cr_strt(stlink_t *sl) {
stlink_write_debug32(sl, cr_reg, val);
}

static void set_flash_cr2_strt(stlink_t *sl) {
uint32_t val;

stlink_read_debug32(sl, FLASH_CR2, &val);
val |= 1 << FLASH_CR_STRT;
stlink_write_debug32(sl, FLASH_CR2, val);
}

static inline uint32_t read_flash_sr(stlink_t *sl) {
uint32_t res, sr_reg;

Expand All @@ -382,8 +421,15 @@ static inline uint32_t read_flash_sr(stlink_t *sl) {
return res;
}

static inline uint32_t read_flash_sr2(stlink_t *sl) {
uint32_t res;
stlink_read_debug32(sl, FLASH_SR2, &res);
return res;
}

static inline unsigned int is_flash_busy(stlink_t *sl) {
uint32_t sr_busy_shift;
unsigned int res;

if (sl->flash_type == STLINK_FLASH_TYPE_F4)
sr_busy_shift = FLASH_F4_SR_BSY;
Expand All @@ -392,7 +438,13 @@ static inline unsigned int is_flash_busy(stlink_t *sl) {
else
sr_busy_shift = FLASH_SR_BSY;

return read_flash_sr(sl) & (1 << sr_busy_shift);
res = read_flash_sr(sl) & (1 << sr_busy_shift);

if (sl->flash_type == STLINK_FLASH_TYPE_F1_XL) {
res |= read_flash_sr2(sl) & (1 << sr_busy_shift);
}

return res;
}

static void wait_flash_busy(stlink_t *sl) {
Expand Down Expand Up @@ -435,6 +487,10 @@ static inline void write_flash_ar(stlink_t *sl, uint32_t n) {
stlink_write_debug32(sl, FLASH_AR, n);
}

static inline void write_flash_ar2(stlink_t *sl, uint32_t n) {
stlink_write_debug32(sl, FLASH_AR2, n);
}

static inline void write_flash_cr_psiz(stlink_t *sl, uint32_t n) {
uint32_t x = read_flash_cr(sl);
x &= ~(0x03 << 8);
Expand Down Expand Up @@ -1531,7 +1587,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr)
stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val);
val |= (1 << 0) | (1 << 1) | (1 << 2);
stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val);
} else if (sl->flash_type == STLINK_FLASH_TYPE_F0) {
} else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (flashaddr < FLASH_BANK2_START_ADDR))) {
/* wait for ongoing op to finish */
wait_flash_busy(sl);

Expand All @@ -1550,6 +1606,27 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr)
/* wait for completion */
wait_flash_busy(sl);

/* relock the flash */
lock_flash(sl);
} else if ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (flashaddr >= FLASH_BANK2_START_ADDR)) {
/* wait for ongoing op to finish */
wait_flash_busy(sl);

/* unlock if locked */
unlock_flash_if(sl);

/* set the page erase bit */
set_flash_cr2_per(sl);

/* select the page to erase */
write_flash_ar2(sl, flashaddr);

/* start erase operation, reset by hw with bsy bit */
set_flash_cr2_strt(sl);

/* wait for completion */
wait_flash_busy(sl);

/* relock the flash */
lock_flash(sl);
} else {
Expand Down Expand Up @@ -1908,8 +1985,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t
stlink_read_debug32(sl, flash_regs_base + FLASH_PECR_OFF, &val);
val |= (1 << 0) | (1 << 1) | (1 << 2);
stlink_write_debug32(sl, flash_regs_base + FLASH_PECR_OFF, val);
} else if (sl->flash_type == STLINK_FLASH_TYPE_F0) {
ILOG("Starting Flash write for VL/F0/F3 core id\n");
} else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) {
ILOG("Starting Flash write for VL/F0/F3/F1_XL core id\n");
/* flash loader initialization */
if (stlink_flash_loader_init(sl, &fl) == -1) {
ELOG("stlink_flash_loader_init() == -1\n");
Expand All @@ -1924,8 +2001,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t

/* unlock and set programming mode */
unlock_flash_if(sl);
set_flash_cr_pg(sl);
DLOG("Finished setting flash cr pg, running loader!\n");
DLOG("Finished unlocking flash, running loader!\n");
if (stlink_flash_loader_run(sl, &fl, addr + (uint32_t) off, base + off, size) == -1) {
ELOG("stlink_flash_loader_run(%#zx) failed! == -1\n", addr + off);
return -1;
Expand Down
12 changes: 10 additions & 2 deletions src/flash_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
#include <string.h>
#include <unistd.h>

#define FLASH_REGS_BANK2_OFS 0x40
#define FLASH_BANK2_START_ADDR 0x08080000

/* from openocd, contrib/loaders/flash/stm32.s */
static const uint8_t loader_code_stm32vl[] = {
0x08, 0x4c, /* ldr r4, STM32_FLASH_BASE */
Expand Down Expand Up @@ -325,6 +328,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe
struct stlink_reg rr;
int i = 0;
size_t count = 0;
uint32_t flash_base = 0;

DLOG("Running flash loader, write address:%#x, size: %u\n", target, (unsigned int)size);
// FIXME This can never return -1
Expand All @@ -334,7 +338,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe
return -1;
}

if (sl->flash_type == STLINK_FLASH_TYPE_F0) {
if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) {
count = size / sizeof(uint16_t);
if (size % sizeof(uint16_t))
++count;
Expand All @@ -348,11 +352,15 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe
++count;
}

if ((sl->flash_type == STLINK_FLASH_TYPE_F1_XL) && (target >= FLASH_BANK2_START_ADDR)) {
flash_base = FLASH_REGS_BANK2_OFS;
}

/* setup core */
stlink_write_reg(sl, fl->buf_addr, 0); /* source */
stlink_write_reg(sl, target, 1); /* target */
stlink_write_reg(sl, (uint32_t) count, 2); /* count */
stlink_write_reg(sl, 0, 3); /* flash bank 0 (input), only used on F0, but armless fopr others */
stlink_write_reg(sl, flash_base, 3); /* flash register base, only used on VL/F1_XL, but harmless for others */
stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */

/* run loader */
Expand Down