kopia lustrzana https://github.com/stlink-org/stlink
Flash loader for STM32L4
rodzic
ab464492f7
commit
0419b8bec6
|
@ -0,0 +1,39 @@
|
||||||
|
.global start
|
||||||
|
.syntax unified
|
||||||
|
|
||||||
|
@ Adapted from stm32f4.s
|
||||||
|
@ STM32L4's flash controller expects double-word writes, has the flash
|
||||||
|
@ controller mapped in a different location with the registers we care about
|
||||||
|
@ moved down from the base address, and has BSY moved to bit 16 of SR.
|
||||||
|
@ r0 = source
|
||||||
|
@ r1 = target
|
||||||
|
@ r2 = wordcount
|
||||||
|
@ r3 = flash_base
|
||||||
|
@ r4 = temp
|
||||||
|
@ r5 = temp
|
||||||
|
|
||||||
|
start:
|
||||||
|
ldr r3, flash_base
|
||||||
|
next:
|
||||||
|
cbz r2, done
|
||||||
|
ldr r4, [r0] /* copy doubleword from source to target */
|
||||||
|
ldr r5, [r0, #4]
|
||||||
|
str r4, [r1]
|
||||||
|
str r5, [r1, #4]
|
||||||
|
|
||||||
|
wait:
|
||||||
|
ldrh r4, [r3, #0x12] /* high half of status register */
|
||||||
|
tst r4, #1 /* BSY = bit 16 */
|
||||||
|
bne wait
|
||||||
|
|
||||||
|
add r0, #8
|
||||||
|
add r1, #8
|
||||||
|
sub r2, #2
|
||||||
|
b next
|
||||||
|
done:
|
||||||
|
bkpt
|
||||||
|
|
||||||
|
.align 2
|
||||||
|
|
||||||
|
flash_base:
|
||||||
|
.word 0x40022000
|
|
@ -1503,6 +1503,25 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) {
|
||||||
0x00, 0x3c, 0x02, 0x40,
|
0x00, 0x3c, 0x02, 0x40,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const uint8_t loader_code_stm32l4[] = {
|
||||||
|
// flashloaders/stm32l4.s
|
||||||
|
0x08, 0x4b, // start: ldr r3, [pc, #32] ; <flash_base>
|
||||||
|
0x72, 0xb1, // next: cbz r2, <done>
|
||||||
|
0x04, 0x68, // ldr r4, [r0, #0]
|
||||||
|
0x45, 0x68, // ldr r5, [r0, #4]
|
||||||
|
0x0c, 0x60, // str r4, [r1, #0]
|
||||||
|
0x4d, 0x60, // str r5, [r1, #4]
|
||||||
|
0x5c, 0x8a, // wait: ldrh r4, [r3, #18]
|
||||||
|
0x14, 0xf0, 0x01, 0x0f, // tst.w r4, #1
|
||||||
|
0xfb, 0xd1, // bne.n <wait>
|
||||||
|
0x00, 0xf1, 0x08, 0x00, // add.w r0, r0, #8
|
||||||
|
0x01, 0xf1, 0x08, 0x01, // add.w r1, r1, #8
|
||||||
|
0xa2, 0xf1, 0x02, 0x02, // add.w r2, r2, #2
|
||||||
|
0xef, 0xe7, // b.n <next>
|
||||||
|
0x00, 0xbe, // done: bkpt 0x0000
|
||||||
|
0x00, 0x20, 0x02, 0x40 // flash_base: .word 0x40022000
|
||||||
|
};
|
||||||
|
|
||||||
const uint8_t* loader_code;
|
const uint8_t* loader_code;
|
||||||
size_t loader_size;
|
size_t loader_size;
|
||||||
|
|
||||||
|
@ -1535,6 +1554,9 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) {
|
||||||
} else if (sl->chip_id == STM32_CHIPID_L0) {
|
} else if (sl->chip_id == STM32_CHIPID_L0) {
|
||||||
loader_code = loader_code_stm32l0;
|
loader_code = loader_code_stm32l0;
|
||||||
loader_size = sizeof(loader_code_stm32l0);
|
loader_size = sizeof(loader_code_stm32l0);
|
||||||
|
} else if (sl->chip_id == STM32_CHIPID_L4) {
|
||||||
|
loader_code = loader_code_stm32l4;
|
||||||
|
loader_size = sizeof(loader_code_stm32l4);
|
||||||
} else {
|
} else {
|
||||||
ELOG("unknown coreid, not sure what flash loader to use, aborting!: %x\n", sl->core_id);
|
ELOG("unknown coreid, not sure what flash loader to use, aborting!: %x\n", sl->core_id);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1710,10 +1732,11 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t
|
||||||
(sl->chip_id == STM32_CHIPID_F4_LP) ||
|
(sl->chip_id == STM32_CHIPID_F4_LP) ||
|
||||||
(sl->chip_id == STM32_CHIPID_F4_HD) ||
|
(sl->chip_id == STM32_CHIPID_F4_HD) ||
|
||||||
(sl->chip_id == STM32_CHIPID_F411RE) ||
|
(sl->chip_id == STM32_CHIPID_F411RE) ||
|
||||||
(sl->chip_id == STM32_CHIPID_F446)) {
|
(sl->chip_id == STM32_CHIPID_F446) ||
|
||||||
|
(sl->chip_id == STM32_CHIPID_L4)) {
|
||||||
/* todo: check write operation */
|
/* todo: check write operation */
|
||||||
|
|
||||||
ILOG("Starting Flash write for F2/F4\n");
|
ILOG("Starting Flash write for F2/F4/L4\n");
|
||||||
/* flash loader initialization */
|
/* flash loader initialization */
|
||||||
if (init_flash_loader(sl, &fl) == -1) {
|
if (init_flash_loader(sl, &fl) == -1) {
|
||||||
ELOG("init_flash_loader() == -1\n");
|
ELOG("init_flash_loader() == -1\n");
|
||||||
|
@ -1724,14 +1747,23 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t
|
||||||
unlock_flash_if(sl);
|
unlock_flash_if(sl);
|
||||||
|
|
||||||
/* TODO: Check that Voltage range is 2.7 - 3.6 V */
|
/* TODO: Check that Voltage range is 2.7 - 3.6 V */
|
||||||
/* set parallelisim to 32 bit*/
|
if (sl->chip_id != STM32_CHIPID_L4) {
|
||||||
int voltage = stlink_target_voltage(sl);
|
/* set parallelisim to 32 bit*/
|
||||||
if (voltage > 2700) {
|
int voltage = stlink_target_voltage(sl);
|
||||||
printf("enabling 32-bit flash writes\n");
|
if (voltage > 2700) {
|
||||||
write_flash_cr_psiz(sl, 2);
|
printf("enabling 32-bit flash writes\n");
|
||||||
|
write_flash_cr_psiz(sl, 2);
|
||||||
|
} else {
|
||||||
|
printf("Target voltage (%d mV) too low for 32-bit flash, using 8-bit flash writes\n", voltage);
|
||||||
|
write_flash_cr_psiz(sl, 0);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("Target voltage (%d mV) too low for 32-bit flash, using 8-bit flash writes\n", voltage);
|
/* L4 does not have a byte-write mode */
|
||||||
write_flash_cr_psiz(sl, 0);
|
int voltage = stlink_target_voltage(sl);
|
||||||
|
if (voltage <= 2700) {
|
||||||
|
printf("Target voltage (%d mV) too low for flash writes!\n", voltage);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set programming mode */
|
/* set programming mode */
|
||||||
|
@ -1960,10 +1992,13 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons
|
||||||
|
|
||||||
} else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) ||
|
} else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) ||
|
||||||
sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE) ||
|
sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE) ||
|
||||||
(sl->chip_id == STM32_CHIPID_F446)) {
|
(sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_L4)) {
|
||||||
|
|
||||||
size_t count = size / sizeof(uint32_t);
|
size_t count = size / sizeof(uint32_t);
|
||||||
if (size % sizeof(uint32_t)) ++count;
|
if (size % sizeof(uint32_t)) ++count;
|
||||||
|
if (sl->chip_id == STM32_CHIPID_L4) {
|
||||||
|
if (count % 2) ++count;
|
||||||
|
}
|
||||||
|
|
||||||
/* setup core */
|
/* setup core */
|
||||||
stlink_write_reg(sl, fl->buf_addr, 0); /* source */
|
stlink_write_reg(sl, fl->buf_addr, 0); /* source */
|
||||||
|
@ -2021,7 +2056,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons
|
||||||
|
|
||||||
} else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) ||
|
} else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) ||
|
||||||
sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE) ||
|
sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD || (sl->chip_id == STM32_CHIPID_F411RE) ||
|
||||||
(sl->chip_id == STM32_CHIPID_F446)) {
|
(sl->chip_id == STM32_CHIPID_F446) || (sl->chip_id == STM32_CHIPID_L4)) {
|
||||||
|
|
||||||
stlink_read_reg(sl, 2, &rr);
|
stlink_read_reg(sl, 2, &rr);
|
||||||
if (rr.r[2] != 0) {
|
if (rr.r[2] != 0) {
|
||||||
|
|
Ładowanie…
Reference in New Issue