Pekka Nikander 2012-10-18 04:14:03 -07:00
commit 01a83d85e8
3 zmienionych plików z 184 dodań i 98 usunięć

Wyświetl plik

@ -0,0 +1,32 @@
/* Adopted from STM AN4065 stm32f0xx_flash.c:FLASH_ProgramWord */
write:
ldr r4, STM32_FLASH_BASE
mov r5, #1 /* FLASH_CR_PG, FLASH_SR_BUSY */
mov r6, #4 /* PGERR */
write_half_word:
ldr r3, [r4, #16] /* FLASH->CR */
orr r3, r5
str r3, [r4, #16] /* FLASH->CR |= FLASH_CR_PG */
ldrh r3, [r0] /* r3 = *sram */
strh r3, [r1] /* *flash = r3 */
busy:
ldr r3, [r4, #12] /* FLASH->SR */
tst r3, r5 /* FLASH_SR_BUSY */
beq busy
tst r3, r6 /* PGERR */
bne exit
add r0, r0, #2 /* sram += 2 */
add r1, r1, #2 /* flash += 2 */
sub r2, r2, #0x01 /* count-- */
cmp r2, #0
bne write_half_word
exit:
ldr r3, [r4, #16] /* FLASH->CR */
bic r3, r5
str r3, [r4, #16] /* FLASH->CR &= ~FLASH_CR_PG */
bkpt #0x00
STM32_FLASH_BASE: .word 0x40022000

Wyświetl plik

@ -18,12 +18,14 @@
#define DLOG(format, args...) ugly_log(UDEBUG, LOG_TAG, format, ## args)
#define ILOG(format, args...) ugly_log(UINFO, LOG_TAG, format, ## args)
#define WLOG(format, args...) ugly_log(UWARN, LOG_TAG, format, ## args)
#define ELOG(format, args...) ugly_log(UERROR, LOG_TAG, format, ## args)
#define fatal(format, args...) ugly_log(UFATAL, LOG_TAG, format, ## args)
/* todo: stm32l15xxx flash memory, pm0062 manual */
/* stm32f FPEC flash controller interface, pm0063 manual */
// TODO - all of this needs to be abstracted out....
// STM32F05x is identical, based on RM0091 (DM00031936, Doc ID 018940 Rev 2, August 2012)
#define FLASH_REGS_ADDR 0x40022000
#define FLASH_REGS_SIZE 0x28
@ -35,6 +37,7 @@
#define FLASH_OBR (FLASH_REGS_ADDR + 0x1c)
#define FLASH_WRPR (FLASH_REGS_ADDR + 0x20)
// For STM32F05x, the RDPTR_KEY may be wrong, but as it is not used anywhere...
#define FLASH_RDPTR_KEY 0x00a5
#define FLASH_KEY1 0x45670123
#define FLASH_KEY2 0xcdef89ab
@ -134,23 +137,23 @@ static inline uint32_t read_flash_obr(stlink_t *sl) {
}
static inline uint32_t read_flash_cr(stlink_t *sl) {
uint32_t res;
if((sl->chip_id==STM32_CHIPID_F2) ||(sl->chip_id==STM32_CHIPID_F4))
res = stlink_read_debug32(sl, FLASH_F4_CR);
else
res = stlink_read_debug32(sl, FLASH_CR);
uint32_t res;
if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4))
res = stlink_read_debug32(sl, FLASH_F4_CR);
else
res = stlink_read_debug32(sl, FLASH_CR);
#if DEBUG_FLASH
fprintf(stdout, "CR:0x%x\n", res);
fprintf(stdout, "CR:0x%x\n", res);
#endif
return res;
return res;
}
static inline unsigned int is_flash_locked(stlink_t *sl) {
/* return non zero for true */
if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4))
return read_flash_cr(sl) & (1 << FLASH_F4_CR_LOCK);
else
return read_flash_cr(sl) & (1 << FLASH_CR_LOCK);
if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4))
return read_flash_cr(sl) & (1 << FLASH_F4_CR_LOCK);
else
return read_flash_cr(sl) & (1 << FLASH_CR_LOCK);
}
static void unlock_flash(stlink_t *sl) {
@ -159,14 +162,13 @@ static void unlock_flash(stlink_t *sl) {
an invalid sequence results in a definitive lock of
the FPEC block until next reset.
*/
if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) {
if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) {
stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY1);
stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY2);
}
else {
stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY2);
} else {
stlink_write_debug32(sl, FLASH_KEYR, FLASH_KEY1);
stlink_write_debug32(sl, FLASH_KEYR, FLASH_KEY2);
}
stlink_write_debug32(sl, FLASH_KEYR, FLASH_KEY2);
}
}
@ -185,11 +187,10 @@ static int unlock_flash_if(stlink_t *sl) {
}
static void lock_flash(stlink_t *sl) {
if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) {
if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) {
const uint32_t n = read_flash_cr(sl) | (1 << FLASH_F4_CR_LOCK);
stlink_write_debug32(sl, FLASH_F4_CR, n);
}
else {
} else {
/* write to 1 only. reset by hw at unlock sequence */
const uint32_t n = read_flash_cr(sl) | (1 << FLASH_CR_LOCK);
stlink_write_debug32(sl, FLASH_CR, n);
@ -198,12 +199,11 @@ static void lock_flash(stlink_t *sl) {
static void set_flash_cr_pg(stlink_t *sl) {
if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) {
if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) {
uint32_t x = read_flash_cr(sl);
x |= (1 << FLASH_CR_PG);
stlink_write_debug32(sl, FLASH_F4_CR, x);
}
else {
} else {
const uint32_t n = 1 << FLASH_CR_PG;
stlink_write_debug32(sl, FLASH_CR, n);
}
@ -211,7 +211,7 @@ static void set_flash_cr_pg(stlink_t *sl) {
static void __attribute__((unused)) clear_flash_cr_pg(stlink_t *sl) {
const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_PG);
if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4))
if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4))
stlink_write_debug32(sl, FLASH_F4_CR, n);
else
stlink_write_debug32(sl, FLASH_CR, n);
@ -228,7 +228,7 @@ static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) {
}
static void set_flash_cr_mer(stlink_t *sl) {
if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4))
if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4))
stlink_write_debug32(sl, FLASH_F4_CR,
stlink_read_debug32(sl, FLASH_F4_CR) | (1 << FLASH_CR_MER));
else
@ -237,7 +237,7 @@ static void set_flash_cr_mer(stlink_t *sl) {
}
static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) {
if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4))
if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4))
stlink_write_debug32(sl, FLASH_F4_CR,
stlink_read_debug32(sl, FLASH_F4_CR) & ~(1 << FLASH_CR_MER));
else
@ -246,17 +246,14 @@ static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) {
}
static void set_flash_cr_strt(stlink_t *sl) {
if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4))
{
uint32_t x = read_flash_cr(sl);
x |= (1 << FLASH_F4_CR_STRT);
stlink_write_debug32(sl, FLASH_F4_CR, x);
}
else {
stlink_write_debug32(
sl, FLASH_CR,
stlink_read_debug32(sl,FLASH_CR) |(1 << FLASH_CR_STRT) );
}
if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) {
uint32_t x = read_flash_cr(sl);
x |= (1 << FLASH_F4_CR_STRT);
stlink_write_debug32(sl, FLASH_F4_CR, x);
} else {
stlink_write_debug32(sl, FLASH_CR,
stlink_read_debug32(sl, FLASH_CR) | (1 << FLASH_CR_STRT) );
}
}
static inline uint32_t read_flash_acr(stlink_t *sl) {
@ -264,20 +261,20 @@ static inline uint32_t read_flash_acr(stlink_t *sl) {
}
static inline uint32_t read_flash_sr(stlink_t *sl) {
uint32_t res;
if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4))
res = stlink_read_debug32(sl, FLASH_F4_SR);
else
res = stlink_read_debug32(sl, FLASH_SR);
uint32_t res;
if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4))
res = stlink_read_debug32(sl, FLASH_F4_SR);
else
res = stlink_read_debug32(sl, FLASH_SR);
//fprintf(stdout, "SR:0x%x\n", *(uint32_t*) sl->q_buf);
return res;
}
static inline unsigned int is_flash_busy(stlink_t *sl) {
if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4))
return read_flash_sr(sl) & (1 << FLASH_F4_SR_BSY);
else
return read_flash_sr(sl) & (1 << FLASH_SR_BSY);
if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4))
return read_flash_sr(sl) & (1 << FLASH_F4_SR_BSY);
else
return read_flash_sr(sl) & (1 << FLASH_SR_BSY);
}
static void wait_flash_busy(stlink_t *sl) {
@ -290,8 +287,7 @@ static void wait_flash_busy_progress(stlink_t *sl) {
int i = 0;
fprintf(stdout, "Mass erasing");
fflush(stdout);
while (is_flash_busy(sl))
{
while (is_flash_busy(sl)) {
usleep(10000);
i++;
if (i % 100 == 0) {
@ -427,11 +423,11 @@ int stlink_load_device_params(stlink_t *sl) {
/* Fix chip_id for F4 rev A errata , Read CPU ID, as CoreID is the same for F2/F4*/
if (sl->chip_id == 0x411) {
uint32_t cpuid = stlink_read_debug32(sl, 0xE000ED00);
if((cpuid & 0xfff0) == 0xc240)
if ((cpuid & 0xfff0) == 0xc240)
sl->chip_id = 0x413;
}
for(size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) {
for (size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) {
if(devices[i].chip_id == sl->chip_id) {
params = &devices[i];
break;
@ -894,7 +890,7 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size)
int error = -1;
size_t off;
int num_empty = 0;
unsigned char erased_pattern =(sl->chip_id == STM32_CHIPID_L1_MEDIUM)?0:0xff;
unsigned char erased_pattern = (sl->chip_id == STM32_CHIPID_L1_MEDIUM)?0:0xff;
const int fd = open(path, O_RDWR | O_TRUNC | O_CREAT, 00700);
if (fd == -1) {
@ -976,7 +972,7 @@ uint32_t calculate_F4_sectornum(uint32_t flashaddr){
}
uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){
if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) {
if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) {
uint32_t sector=calculate_F4_sectornum(flashaddr);
if (sector<4) sl->flash_pgsz=0x4000;
else if(sector<5) sl->flash_pgsz=0x10000;
@ -993,7 +989,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->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) {
if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) {
/* wait for ongoing op to finish */
wait_flash_busy(sl);
@ -1089,7 +1085,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr)
val = stlink_read_debug32(sl, STM32L_FLASH_PECR)
| (1 << 0) | (1 << 1) | (1 << 2);
stlink_write_debug32(sl, STM32L_FLASH_PECR, val);
} else if (sl->core_id == STM32VL_CORE_ID) {
} else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID) {
/* wait for ongoing op to finish */
wait_flash_busy(sl);
@ -1111,7 +1107,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr)
/* relock the flash */
lock_flash(sl);
} else {
WLOG("unknown coreid: %x\n", sl->core_id);
WLOG("unknown coreid %x, page erase failed\n", sl->core_id);
return -1;
}
@ -1197,6 +1193,54 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) {
0x00, 0x20, 0x02, 0x40, /* STM32_FLASH_BASE: .word 0x40022000 */
};
/* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */
static const uint8_t loader_code_stm32f0[] = {
#if 1
/*
* These two NOPs here are a safety precaution, added by Pekka Nikander
* while debugging the STM32F05x support. They may not be needed, but
* 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.
*/
0x00, 0x30, // nop /* add r0,#0 */
0x00, 0x30, // nop /* add r0,#0 */
#endif
0x0A, 0x4C, // ldr r4, STM32_FLASH_BASE
0x01, 0x25, // mov r5, #1 /* FLASH_CR_PG, FLASH_SR_BUSY */
0x04, 0x26, // mov r6, #4 /* PGERR */
// write_half_word:
0x23, 0x69, // ldr r3, [r4, #16] /* FLASH->CR */
0x2B, 0x43, // orr r3, r5
0x23, 0x61, // str r3, [r4, #16] /* FLASH->CR |= FLASH_CR_PG */
0x03, 0x88, // ldrh r3, [r0] /* r3 = *sram */
0x0B, 0x80, // strh r3, [r1] /* *flash = r3 */
// busy:
0xE3, 0x68, // ldr r3, [r4, #12] /* FLASH->SR */
0x2B, 0x42, // tst r3, r5 /* FLASH_SR_BUSY */
0xFC, 0xD0, // beq busy
0x33, 0x42, // tst r3, r6 /* PGERR */
0x04, 0xD1, // bne exit
0x02, 0x30, // add r0, r0, #2 /* sram += 2 */
0x02, 0x31, // add r1, r1, #2 /* flash += 2 */
0x01, 0x3A, // sub r2, r2, #0x01 /* count-- */
0x00, 0x2A, // cmp r2, #0
0xF0, 0xD1, // bne write_half_word
// exit:
0x23, 0x69, // ldr r3, [r4, #16] /* FLASH->CR */
0xAB, 0x43, // bic r3, r5
0x23, 0x61, // str r3, [r4, #16] /* FLASH->CR &= ~FLASH_CR_PG */
0x00, 0xBE, // bkpt #0x00
0x00, 0x20, 0x02, 0x40, /* STM32_FLASH_BASE: .word 0x40022000 */
};
static const uint8_t loader_code_stm32l[] = {
/* openocd.git/contrib/loaders/flash/stm32lx.S
@ -1244,17 +1288,20 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) {
size_t loader_size;
if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { /* stm32l */
loader_code = loader_code_stm32l;
loader_size = sizeof(loader_code_stm32l);
loader_code = loader_code_stm32l;
loader_size = sizeof(loader_code_stm32l);
} else if (sl->core_id == STM32VL_CORE_ID) {
loader_code = loader_code_stm32vl;
loader_size = sizeof(loader_code_stm32vl);
loader_code = loader_code_stm32vl;
loader_size = sizeof(loader_code_stm32vl);
} else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4) {
loader_code = loader_code_stm32f4;
loader_size = sizeof(loader_code_stm32f4);
loader_code = loader_code_stm32f4;
loader_size = sizeof(loader_code_stm32f4);
} else if (sl->chip_id == STM32_CHIPID_F0) {
loader_code = loader_code_stm32f0;
loader_size = sizeof(loader_code_stm32f0);
} else {
WLOG("unknown coreid, not sure what flash loader to use, aborting!: %x\n", sl->core_id);
return -1;
ELOG("unknown coreid, not sure what flash loader to use, aborting!: %x\n", sl->core_id);
return -1;
}
memcpy(sl->q_buf, loader_code, loader_size);
@ -1309,7 +1356,7 @@ int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data,
stlink_read_mem32(sl, address + off, aligned_size);
if (memcmp(sl->q_buf, data + off, cmp_size)) {
WLOG("Verification of flash failed at offset: %zd\n", off);
ELOG("Verification of flash failed at offset: %zd\n", off);
return -1;
}
}
@ -1376,19 +1423,22 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned
/* check addr range is inside the flash */
stlink_calculate_pagesize(sl, addr);
if (addr < sl->flash_base) {
WLOG("addr too low %#x < %#x\n", addr, sl->flash_base);
ELOG("addr too low %#x < %#x\n", addr, sl->flash_base);
return -1;
} else if ((addr + len) < addr) {
WLOG("addr overruns\n");
ELOG("addr overruns\n");
return -1;
} else if ((addr + len) > (sl->flash_base + sl->flash_size)) {
WLOG("addr too high\n");
ELOG("addr too high\n");
return -1;
} else if ((addr & 1) || (len & 1)) {
WLOG("unaligned addr or size\n");
} else if (addr & 1) {
ELOG("unaligned addr 0x%x\n", addr);
return -1;
} else if (len & 1) {
WLOG("unaligned len 0x%x -- padding with zero\n", len);
len += 1;
} else if (addr & (sl->flash_pgsz - 1)) {
WLOG("addr not a multiple of pagesize, not supported\n");
ELOG("addr not a multiple of pagesize, not supported\n");
return -1;
}
@ -1399,7 +1449,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned
for (off = 0; off < len; off += stlink_calculate_pagesize(sl, addr + off)) {
/* addr must be an addr inside the page */
if (stlink_erase_flash_page(sl, addr + off) == -1) {
WLOG("Failed to erase_flash_page(%#zx) == -1\n", addr + off);
ELOG("Failed to erase_flash_page(%#zx) == -1\n", addr + off);
return -1;
}
fprintf(stdout,"\rFlash page at addr: 0x%08lx erased",
@ -1411,13 +1461,13 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned
ILOG("Finished erasing %d pages of %d (%#x) bytes\n",
page_count, sl->flash_pgsz, sl->flash_pgsz);
if ((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) {
if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4)) {
/* todo: check write operation */
ILOG("Starting Flash write for F2/F4\n");
/* flash loader initialization */
if (init_flash_loader(sl, &fl) == -1) {
WLOG("init_flash_loader() == -1\n");
ELOG("init_flash_loader() == -1\n");
return -1;
}
@ -1437,7 +1487,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned
printf("size: %zu\n", size);
if (run_flash_loader(sl, &fl, addr + off, base + off, size) == -1) {
WLOG("run_flash_loader(%#zx) failed! == -1\n", addr + off);
ELOG("run_flash_loader(%#zx) failed! == -1\n", addr + off);
return -1;
}
@ -1583,11 +1633,11 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned
val = stlink_read_debug32(sl, STM32L_FLASH_PECR)
| (1 << 0) | (1 << 1) | (1 << 2);
stlink_write_debug32(sl, STM32L_FLASH_PECR, val);
} else if (sl->core_id == STM32VL_CORE_ID) {
ILOG("Starting Flash write for VL core id\n");
} else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID) {
ILOG("Starting Flash write for VL/F0 core id\n");
/* flash loader initialization */
if (init_flash_loader(sl, &fl) == -1) {
WLOG("init_flash_loader() == -1\n");
ELOG("init_flash_loader() == -1\n");
return -1;
}
@ -1602,7 +1652,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned
set_flash_cr_pg(sl);
//DLOG("Finished setting flash cr pg, running loader!\n");
if (run_flash_loader(sl, &fl, addr + off, base + off, size) == -1) {
WLOG("run_flash_loader(%#zx) failed! == -1\n", addr + off);
ELOG("run_flash_loader(%#zx) failed! == -1\n", addr + off);
return -1;
}
lock_flash(sl);
@ -1615,7 +1665,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned
}
fprintf(stdout, "\n");
} else {
WLOG("unknown coreid, not sure how to write: %x\n", sl->core_id);
ELOG("unknown coreid, not sure how to write: %x\n", sl->core_id);
return -1;
}
@ -1636,7 +1686,7 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) {
unsigned char erased_pattern =(sl->chip_id == STM32_CHIPID_L1_MEDIUM)?0:0xff;
mapped_file_t mf = MAPPED_FILE_INITIALIZER;
if (map_file(&mf, path) == -1) {
WLOG("map_file() == -1\n");
ELOG("map_file() == -1\n");
return -1;
}
for(index = 0; index < mf.len; index ++) {
@ -1667,7 +1717,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons
// FIXME This can never return -1
if (write_buffer_to_sram(sl, fl, buf, size) == -1) {
// IMPOSSIBLE!
WLOG("write_buffer_to_sram() == -1\n");
ELOG("write_buffer_to_sram() == -1\n");
return -1;
}
@ -1682,7 +1732,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons
stlink_write_reg(sl, count, 2); /* count (32 bits words) */
stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */
} else if (sl->core_id == STM32VL_CORE_ID) {
} else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID) {
size_t count = size / sizeof(uint16_t);
if (size % sizeof(uint16_t)) ++count;
@ -1706,20 +1756,22 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons
stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */
} else {
fprintf(stderr, "unknown coreid: 0x%x\n", sl->core_id);
fprintf(stderr, "unknown coreid 0x%x, don't know what flash loader to use\n", sl->core_id);
return -1;
}
/* run loader */
stlink_run(sl);
#define WAIT_ROUNDS 1000
/* wait until done (reaches breakpoint) */
while ((is_core_halted(sl) == 0) && (i <1000)) {
i++;
for (i = 0; i < WAIT_ROUNDS; i++) {
if (is_core_halted(sl))
break;
}
if ( i > 999) {
fprintf(stderr, "run error\n");
if (i >= WAIT_ROUNDS) {
fatal("flash loader run error\n");
return -1;
}
@ -1735,7 +1787,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons
return -1;
}
} else if (sl->core_id == STM32VL_CORE_ID) {
} else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID) {
stlink_read_reg(sl, 2, &rr);
if (rr.r[2] != 0) {
@ -1743,17 +1795,17 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons
return -1;
}
} else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4) {
} else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4) {
stlink_read_reg(sl, 2, &rr);
if (rr.r[2] != 0) {
fprintf(stderr, "write error, count == %u\n", rr.r[2]);
return -1;
}
stlink_read_reg(sl, 2, &rr);
if (rr.r[2] != 0) {
fprintf(stderr, "write error, count == %u\n", rr.r[2]);
return -1;
}
} else {
fprintf(stderr, "unknown coreid: 0x%x\n", sl->core_id);
fprintf(stderr, "unknown coreid 0x%x, can't check written byte count\n", sl->core_id);
return -1;
}

Wyświetl plik

@ -85,6 +85,7 @@ extern "C" {
#define STM32VL_CORE_ID 0x1ba01477
#define STM32L_CORE_ID 0x2ba01477
#define STM32F4_CORE_ID 0x2ba01477
#define STM32F0_CORE_ID 0xbb11477
#define CORE_M3_R1 0x1BA00477
#define CORE_M3_R2 0x4BA00477
#define CORE_M4_R0 0x2BA01477
@ -104,6 +105,7 @@ extern "C" {
#define STM32_CHIPID_F1_VL_MEDIUM 0x420
#define STM32_CHIPID_F1_VL_HIGH 0x428
#define STM32_CHIPID_F1_XL 0x430
#define STM32_CHIPID_F0 0x440
// Constant STM32 memory map figures
#define STM32_FLASH_BASE 0x08000000
@ -129,9 +131,9 @@ extern "C" {
} chip_params_t;
// These maps are from a combination of the Programming Manuals, and
// also the Reference manuals. (flash size reg is normally in ref man)
static const chip_params_t devices[] = {
// These maps are from a combination of the Programming Manuals, and
// also the Reference manuals. (flash size reg is normally in ref man)
static const chip_params_t devices[] = {
{ // table 2, PM0063
.chip_id = 0x410,
.description = "F1 Medium-density device",