From f5d6cec4c72989fe2bb8ec4f4d03cce6f4505d23 Mon Sep 17 00:00:00 2001 From: Tom de Boer Date: Fri, 6 May 2016 13:47:00 +0200 Subject: [PATCH] Fix for broken STML0 and STML1 Commits 907383da8ef95fedc630cdf7cf102d44ae229200 and e43a737c3c9ffe56045181b306509c942fd9998a were causing issues for people with STML0's and STML1's. This commit reverses the changes in these two commits. --- flashloaders/stm32l0x.s | 20 +++++---- flashloaders/stm32lx.s | 20 +++++---- src/common.c | 91 ++++++++++++++++++++++++----------------- 3 files changed, 76 insertions(+), 55 deletions(-) diff --git a/flashloaders/stm32l0x.s b/flashloaders/stm32l0x.s index fcbd06e..9fc4446 100644 --- a/flashloaders/stm32l0x.s +++ b/flashloaders/stm32l0x.s @@ -34,29 +34,31 @@ .global write /* - r0 - source address - r1 - destination address + r0 - destination address + r1 - source address r2 - count */ + // Set 0 to r3 + movs r3, #0 // Go to compare - b test_done + b.n test_done write_word: // Load one word from address in r0, increment by 4 - ldr r4, [r0] + ldr r4, [r1] // Store the word to address in r1, increment by 4 - str r4, [r1] - // Decrement r2 - subs r2, #1 + str r4, [r0] + // Increment r3 + adds r3, #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: - // Test r2 - cmp r2, #0 + // Compare r3 and r2 + cmp r3, r2 // Loop if not zero bcc.n write_word diff --git a/flashloaders/stm32lx.s b/flashloaders/stm32lx.s index bb8f7c9..799d134 100644 --- a/flashloaders/stm32lx.s +++ b/flashloaders/stm32lx.s @@ -34,25 +34,27 @@ .global write /* - r0 - source address - r1 - destination address + r0 - destination address + r1 - source address r2 - count */ + // Set 0 to r3 + movs r3, #0 // Go to compare - b test_done + b.n test_done write_word: // Load one word from address in r0, increment by 4 - ldr.w ip, [r0], #4 + ldr.w ip, [r1], #4 // Store the word to address in r1, increment by 4 - str.w ip, [r1], #4 - // Decrement r2 - subs r2, #1 + str.w ip, [r0], #4 + // Increment r3 + adds r3, #1 test_done: - // Test r2 - cmp r2, #0 + // Compare r3 and r2 + cmp r3, r2 // Loop if not zero bcc.n write_word diff --git a/src/common.c b/src/common.c index a167bb6..7504c27 100644 --- a/src/common.c +++ b/src/common.c @@ -593,12 +593,6 @@ 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; @@ -1511,19 +1505,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, source addr - r1, input, dest addr + r0, input, dest addr + r1, input, source addr r2, input, word count - r2, output, remaining word count + r3, output, word count */ + 0x00, 0x23, 0x04, 0xe0, - 0x50, 0xf8, 0x04, 0xcb, - 0x41, 0xf8, 0x04, 0xcb, - 0x01, 0x3a, + 0x51, 0xf8, 0x04, 0xcb, + 0x40, 0xf8, 0x04, 0xcb, + 0x01, 0x33, - 0x00, 0x2a, + 0x93, 0x42, 0xf8, 0xd3, 0x00, 0xbe }; @@ -1531,21 +1526,22 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { static const uint8_t loader_code_stm32l0[] = { /* - r0, input, source addr - r1, input, dest addr + r0, input, dest addr + r1, input, source addr r2, input, word count - r2, output, remaining word count + r3, output, word count */ + 0x00, 0x23, 0x04, 0xe0, - 0x04, 0x68, - 0x0c, 0x60, - 0x01, 0x3a, + 0x0c, 0x68, + 0x04, 0x60, + 0x01, 0x33, 0x04, 0x31, 0x04, 0x30, - 0x00, 0x2a, + 0x93, 0x42, 0xf8, 0xd3, 0x00, 0xbe }; @@ -1608,7 +1604,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { 0xfb, 0xd1, // bne.n 0x00, 0xf1, 0x08, 0x00, // add.w r0, r0, #8 0x01, 0xf1, 0x08, 0x01, // add.w r1, r1, #8 - 0xa2, 0xf1, 0x01, 0x02, // sub.w r2, r2, #1 + 0xa2, 0xf1, 0x02, 0x02, // add.w r2, r2, #2 0xef, 0xe7, // b.n 0x00, 0xbe, // done: bkpt 0x0000 0x00, 0x20, 0x02, 0x40 // flash_base: .word 0x40022000 @@ -2072,8 +2068,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 i = 0; - size_t count = 0; + int target_reg, source_reg, i = 0; + size_t count; DLOG("Running flash loader, write address:%#x, size: %zd\n", target, size); // FIXME This can never return -1 @@ -2083,23 +2079,36 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } - if (sl->flash_type == FLASH_TYPE_F0) { - count = size / sizeof(uint16_t); - if (size % sizeof(uint16_t)) - ++count; - } else if (sl->flash_type == FLASH_TYPE_F4 || sl->flash_type == FLASH_TYPE_L0) { + if (sl->flash_type == FLASH_TYPE_L0) { count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; - } else if (sl->flash_type == FLASH_TYPE_L4) { - count = size / sizeof(uint64_t); - if (size % sizeof(uint64_t)) + target_reg = 0; + source_reg = 1; + } else 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) { + 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; } /* setup core */ - stlink_write_reg(sl, fl->buf_addr, 0); /* source */ - stlink_write_reg(sl, target, 1); /* target */ + stlink_write_reg(sl, fl->buf_addr, source_reg); /* source */ + stlink_write_reg(sl, target, target_reg); /* 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 */ @@ -2120,11 +2129,19 @@ 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 */ - stlink_read_reg(sl, 2, &rr); - if (rr.r[2] != 0) { - fprintf(stderr, "write error, count == %u\n", rr.r[2]); - return -1; + 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; + } } return 0;