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

Fixing and merging of STM32L0 and STM32L1 loaders #408

Merged
merged 6 commits into from
May 9, 2016
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
20 changes: 9 additions & 11 deletions flashloaders/stm32l0x.s
Original file line number Diff line number Diff line change
Expand Up @@ -34,31 +34,29 @@
.global write

/*
r0 - destination address
r1 - source address
r0 - source address
r1 - destination address
r2 - count
*/

// Set 0 to r3
movs r3, #0
// Go to compare
b.n test_done
b test_done

write_word:
// Load one word from address in r0, increment by 4
ldr r4, [r1]
ldr r4, [r0]
// Store the word to address in r1, increment by 4
str r4, [r0]
// Increment r3
adds r3, #1
str r4, [r1]
// Decrement r2
subs r2, #1
adds r1, #4
// does not matter, only first addr is important
// next 15 bytes are in sequnce RM0367 page 66
adds r0, #4

test_done:
// Compare r3 and r2
cmp r3, r2
// Test r2
cmp r2, #0
// Loop if not zero
bcc.n write_word

Expand Down
26 changes: 12 additions & 14 deletions flashloaders/stm32lx.s
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
***************************************************************************/


// Build : arm-eabi-gcc -c stm32lx.S
// Build : arm-eabi-gcc -c stm32lx.s
.text
.syntax unified
.cpu cortex-m3
Expand All @@ -34,29 +34,27 @@
.global write

/*
r0 - destination address
r1 - source address
r2 - count
r0 - source address
r1 - destination address
r2 - output, remaining word count
*/

// Set 0 to r3
movs r3, #0
// Go to compare
b.n test_done
b test_done

write_word:
// Load one word from address in r0, increment by 4
ldr.w ip, [r1], #4
ldr.w ip, [r0], #4
// Store the word to address in r1, increment by 4
str.w ip, [r0], #4
// Increment r3
adds r3, #1
str.w ip, [r1], #4
// Decrement r2
subs r2, #1

test_done:
// Compare r3 and r2
cmp r3, r2
// Test r2
cmp r2, #0
// Loop if not zero
bcc.n write_word
bhi write_word

// Set breakpoint to exit
bkpt #0x00
118 changes: 37 additions & 81 deletions src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,12 @@ int stlink_load_device_params(stlink_t *sl) {
return -1;
}

if (params->flash_type == FLASH_TYPE_UNKNOWN) {
WLOG("Invalid flash type, please check device declaration\n");
return -1;
}


// These are fixed...
sl->flash_base = STM32_FLASH_BASE;
sl->sram_base = STM32_SRAM_BASE;
Expand Down Expand Up @@ -1503,47 +1509,20 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) {
};

static const uint8_t loader_code_stm32l[] = {

/* openocd.git/contrib/loaders/flash/stm32lx.S
r0, input, dest addr
r1, input, source addr
r2, input, word count
r3, output, word count
*/

0x00, 0x23,
0x04, 0xe0,

0x51, 0xf8, 0x04, 0xcb,
0x40, 0xf8, 0x04, 0xcb,
0x01, 0x33,

0x93, 0x42,
0xf8, 0xd3,
0x00, 0xbe
};

static const uint8_t loader_code_stm32l0[] = {

/*
r0, input, dest addr
r1, input, source addr
r2, input, word count
r3, output, word count
*/

0x00, 0x23,
0x04, 0xe0,

0x0c, 0x68,
0x04, 0x60,
0x01, 0x33,
0x04, 0x31,
0x04, 0x30,

0x93, 0x42,
0xf8, 0xd3,
0x00, 0xbe
// flashloaders/stm32lx.s

0x04, 0xe0, // b test_done ; Go to compare
// write_word:
0x04, 0x68, // ldr r4, [r0] ; Load one word from address in r0
0x0c, 0x60, // str r4, [r1] ; Store the word to address in r1
0x04, 0x30, // adds r0, #4 ; Increment r0
0x04, 0x31, // adds r1, #4 ; Increment r1
0x01, 0x3a, // subs r2, #1 ; Decrement r2
// test_done:
0x00, 0x2a, // cmp r2, #0 ; Compare r2 to 0
0xf8, 0xd8, // bhi write_word ; Loop if above 0
0x00, 0xbe, // bkpt #0x00 ; Set breakpoint to exit
0x00, 0x00
};

static const uint8_t loader_code_stm32f4[] = {
Expand Down Expand Up @@ -1604,7 +1583,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) {
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
0xa2, 0xf1, 0x01, 0x02, // sub.w r2, r2, #1
0xef, 0xe7, // b.n <next>
0x00, 0xbe, // done: bkpt 0x0000
0x00, 0x20, 0x02, 0x40 // flash_base: .word 0x40022000
Expand Down Expand Up @@ -1632,7 +1611,8 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) {

if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_CAT2
|| sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS || sl->chip_id == STM32_CHIPID_L1_HIGH
|| sl->chip_id == STM32_CHIPID_L152_RE) { /* stm32l */
|| sl->chip_id == STM32_CHIPID_L152_RE
|| sl->chip_id == STM32_CHIPID_L0 || sl->chip_id == STM32_CHIPID_L0_CAT5) { /* stm32l */
loader_code = loader_code_stm32l;
loader_size = sizeof(loader_code_stm32l);
} else if (sl->core_id == STM32VL_CORE_ID
Expand Down Expand Up @@ -1663,9 +1643,6 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) {
} else if (sl->chip_id == STM32_CHIPID_F0 || sl->chip_id == STM32_CHIPID_F04 || sl->chip_id == STM32_CHIPID_F0_CAN || sl->chip_id == STM32_CHIPID_F0_SMALL || sl->chip_id == STM32_CHIPID_F09X) {
loader_code = loader_code_stm32f0;
loader_size = sizeof(loader_code_stm32f0);
} else if (sl->chip_id == STM32_CHIPID_L0 || sl->chip_id == STM32_CHIPID_L0_CAT5) {
loader_code = 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);
Expand Down Expand Up @@ -2068,8 +2045,8 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) {
int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, const uint8_t* buf, size_t size) {

reg rr;
int target_reg, source_reg, i = 0;
size_t count;
int i = 0;
size_t count = 0;

DLOG("Running flash loader, write address:%#x, size: %zd\n", target, size);
// FIXME This can never return -1
Expand All @@ -2079,36 +2056,23 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons
return -1;
}

if (sl->flash_type == FLASH_TYPE_L0) {
count = size / sizeof(uint32_t);
if (size % sizeof(uint32_t))
++count;
target_reg = 0;
source_reg = 1;
} else if (sl->flash_type == FLASH_TYPE_F0) {
if (sl->flash_type == FLASH_TYPE_F0) {
count = size / sizeof(uint16_t);
if (size % sizeof(uint16_t))
++count;
target_reg = 1;
source_reg = 0;
} else if (sl->flash_type == FLASH_TYPE_F4 || sl->flash_type == FLASH_TYPE_L4) {
} else if (sl->flash_type == FLASH_TYPE_F4 || sl->flash_type == FLASH_TYPE_L0) {
count = size / sizeof(uint32_t);
if (size % sizeof(uint32_t))
++count;
if (sl->chip_id == STM32_CHIPID_L4) {
if (count % 2)
++count;
}
target_reg = 1;
source_reg = 0;
} else {
fprintf(stderr, "unknown coreid 0x%x, don't know what flash loader to use\n", sl->core_id);
return -1;
} else if (sl->flash_type == FLASH_TYPE_L4) {
count = size / sizeof(uint64_t);
if (size % sizeof(uint64_t))
++count;
}

/* setup core */
stlink_write_reg(sl, fl->buf_addr, source_reg); /* source */
stlink_write_reg(sl, target, target_reg); /* target */
stlink_write_reg(sl, fl->buf_addr, 0); /* source */
stlink_write_reg(sl, target, 1); /* target */
stlink_write_reg(sl, 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, fl->loader_addr, 15); /* pc register */
Expand All @@ -2129,19 +2093,11 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons
return -1;
}

stlink_read_all_regs(sl, &rr);

/* check written byte count */
if (sl->flash_type == FLASH_TYPE_L0) {
if (rr.r[3] != count) {
fprintf(stderr, "write error, count == %u\n", rr.r[3]);
return -1;
}
} else {
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;
}

return 0;
Expand Down