X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fstlink-common.c;h=1e9c01114ffdbdaafdc90229e08fbb8ed22cf6f2;hb=b1e65ea367a450e8a37584cdee334562149b2a7c;hp=65d45904965b07ac8e929573b6594f65603eb9c4;hpb=f38ff8f91282113b42ded9b108c05e5e329b6ffc;p=fw%2Fstlink diff --git a/src/stlink-common.c b/src/stlink-common.c index 65d4590..1e9c011 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -9,8 +9,7 @@ #include #include #include -#include - +#include "mmap.h" #include "stlink-common.h" #include "uglylogging.h" @@ -136,7 +135,7 @@ 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_F4) + 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); @@ -148,7 +147,7 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { static inline unsigned int is_flash_locked(stlink_t *sl) { /* return non zero for true */ - if(sl->chip_id==STM32_CHIPID_F4) + 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); @@ -160,7 +159,7 @@ 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_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); } @@ -186,7 +185,7 @@ static int unlock_flash_if(stlink_t *sl) { } static void lock_flash(stlink_t *sl) { - if(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); } @@ -199,7 +198,7 @@ static void lock_flash(stlink_t *sl) { static void set_flash_cr_pg(stlink_t *sl) { - if(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); @@ -212,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_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); @@ -229,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_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 @@ -238,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_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 @@ -247,7 +246,7 @@ 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_F4) + 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); @@ -266,7 +265,7 @@ 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_F4) + 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); @@ -275,7 +274,7 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { } static inline unsigned int is_flash_busy(stlink_t *sl) { - if(sl->chip_id==STM32_CHIPID_F4) + 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); @@ -395,6 +394,7 @@ uint32_t stlink_core_id(stlink_t *sl) { uint32_t stlink_chip_id(stlink_t *sl) { uint32_t chip_id = stlink_read_debug32(sl, 0xE0042000); + if (chip_id == 0) chip_id = stlink_read_debug32(sl, 0x40015800); //Try Corex M0 DBGMCU_IDCODE register address return chip_id; } @@ -448,7 +448,7 @@ int stlink_load_device_params(stlink_t *sl) { // read flash size from hardware, if possible... if (sl->chip_id == STM32_CHIPID_F2) { - sl->flash_size = 0; // FIXME - need to work this out some other way, just set to max possible? + sl->flash_size = 0x100000; /* Use maximum, User must care!*/ } else if (sl->chip_id == STM32_CHIPID_F4) { sl->flash_size = 0x100000; //todo: RM0090 error; size register same address as unique ID } else { @@ -577,6 +577,11 @@ void stlink_read_all_regs(stlink_t *sl, reg *regp) { sl->backend->read_all_regs(sl, regp); } +void stlink_read_all_unsupported_regs(stlink_t *sl, reg *regp) { + DLOG("*** stlink_read_all_unsupported_regs ***\n"); + sl->backend->read_all_unsupported_regs(sl, regp); +} + void stlink_write_reg(stlink_t *sl, uint32_t reg, int idx) { DLOG("*** stlink_write_reg\n"); sl->backend->write_reg(sl, reg, idx); @@ -594,6 +599,27 @@ void stlink_read_reg(stlink_t *sl, int r_idx, reg *regp) { sl->backend->read_reg(sl, r_idx, regp); } +void stlink_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { + int r_convert; + + DLOG("*** stlink_read_unsupported_reg\n"); + DLOG(" (%d) ***\n", r_idx); + + /* Convert to values used by DCRSR */ + if (r_idx >= 0x1C && r_idx <= 0x1F) { /* primask, basepri, faultmask, or control */ + r_convert = 0x14; + } else if (r_idx == 0x40) { /* FPSCR */ + r_convert = 0x21; + } else if (r_idx >= 0x20 && r_idx < 0x40) { + r_convert = 0x40 + (r_idx - 0x20); + } else { + fprintf(stderr, "Error: register address must be in [0x1C..0x40]\n"); + return; + } + + sl->backend->read_unsupported_reg(sl, r_convert, regp); +} + unsigned int is_core_halted(stlink_t *sl) { /* return non zero if core is halted */ stlink_status(sl); @@ -927,7 +953,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_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; @@ -944,7 +970,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_F4) + if ((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32_CHIPID_F4)) { /* wait for ongoing op to finish */ wait_flash_busy(sl); @@ -972,7 +998,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr) fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl)); #endif } - else if (sl->core_id == STM32L_CORE_ID) + else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { uint32_t val; @@ -1182,10 +1208,32 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { 0x00, 0xbe }; + static const uint8_t loader_code_stm32f4[] = { + // flashloaders/stm32f4.s + + 0x07, 0x4b, + + 0x62, 0xb1, + 0x04, 0x68, + 0x0c, 0x60, + + 0xdc, 0x89, + 0x14, 0xf0, 0x01, 0x0f, + 0xfb, 0xd1, + 0x00, 0xf1, 0x04, 0x00, + 0x01, 0xf1, 0x04, 0x01, + 0xa2, 0xf1, 0x01, 0x02, + 0xf1, 0xe7, + + 0x00, 0xbe, + + 0x00, 0x3c, 0x02, 0x40, + }; + const uint8_t* loader_code; size_t loader_size; - if (sl->core_id == STM32L_CORE_ID) /* stm32l */ + if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) /* stm32l */ { loader_code = loader_code_stm32l; loader_size = sizeof(loader_code_stm32l); @@ -1195,6 +1243,11 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { 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); + } else { WLOG("unknown coreid, not sure what flash loader to use, aborting!: %x\n", sl->core_id); @@ -1237,17 +1290,13 @@ int stlink_fcheck_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { */ int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, unsigned length) { size_t off; - if (sl->chip_id == STM32_CHIPID_F4) { - DLOG("(FIXME)Skipping verification for F4, not enough ram (yet)\n"); - return 0; - } + size_t cmp_size = (sl->flash_pgsz > 0x1800)? 0x1800:sl->flash_pgsz; ILOG("Starting verification of write complete\n"); - for (off = 0; off < length; off += sl->flash_pgsz) { + for (off = 0; off < length; off += cmp_size) { size_t aligned_size; /* adjust last page size */ - size_t cmp_size = sl->flash_pgsz; - if ((off + sl->flash_pgsz) > length) + if ((off + cmp_size) > length) cmp_size = length - off; aligned_size = cmp_size; @@ -1300,7 +1349,7 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uns if (sl->verbose >= 1) { /* show progress. writing procedure is slow and previous errors are misleading */ - fprintf(stdout, "\r%3u/%u halfpages written", count, num_half_pages); + fprintf(stdout, "\r%3u/%u halfpages written", count + 1, num_half_pages); fflush(stdout); } while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) { @@ -1359,9 +1408,16 @@ 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_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"); + return -1; + } + /* First unlock the cr */ unlock_flash_if(sl); @@ -1372,6 +1428,20 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned /* set programming mode */ set_flash_cr_pg(sl); + for(off = 0; off < len;) { + size_t size = len - off > 0x8000 ? 0x8000 : len - off; + + printf("size: %u\n", size); + + if (run_flash_loader(sl, &fl, addr + off, base + off, size) == -1) { + WLOG("run_flash_loader(%#zx) failed! == -1\n", addr + off); + return -1; + } + + off += size; + } + +#if 0 #define PROGRESS_CHUNK_SIZE 0x1000 /* write a word in program memory */ for (off = 0; off < len; off += sizeof(uint32_t)) { @@ -1381,7 +1451,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned /* show progress. writing procedure is slow and previous errors are misleading */ const uint32_t pgnum = (off / PROGRESS_CHUNK_SIZE)+1; - const uint32_t pgcount = len / PROGRESS_CHUNK_SIZE; + const uint32_t pgcount = len / PROGRESS_CHUNK_SIZE +1; fprintf(stdout, "Writing %ukB chunk %u out of %u\n", PROGRESS_CHUNK_SIZE/1024, pgnum, pgcount); } } @@ -1393,6 +1463,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned wait_flash_busy(sl); } +#endif /* Relock flash */ lock_flash(sl); @@ -1404,7 +1475,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned } //STM32F4END - else if (sl->core_id == STM32L_CORE_ID) { + else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { /* use fast word write. todo: half page. */ uint32_t val; @@ -1455,7 +1526,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, unsigned fprintf(stdout, "\r"); if ((off % sl->flash_pgsz) > (sl->flash_pgsz -5)) { - fprintf(stdout, "\r%3u/%u pages written", + fprintf(stdout, "\r%3zd/%3zd pages written", off/sl->flash_pgsz, len/sl->flash_pgsz); fflush(stdout); } @@ -1599,7 +1670,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons return -1; } - if (sl->core_id == STM32L_CORE_ID) { + if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -1622,6 +1693,17 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons stlink_write_reg(sl, 0, 3); /* flash bank 0 (input) */ stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ + } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4) { + + size_t count = size / sizeof(uint32_t); + if (size % sizeof(uint32_t)) ++count; + + /* setup core */ + stlink_write_reg(sl, fl->buf_addr, 0); /* source */ + stlink_write_reg(sl, target, 1); /* target */ + stlink_write_reg(sl, count, 2); /* count (32 bits words) */ + stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ + } else { fprintf(stderr, "unknown coreid: 0x%x\n", sl->core_id); return -1; @@ -1642,7 +1724,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } /* check written byte count */ - if (sl->core_id == STM32L_CORE_ID) { + if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -1661,6 +1743,14 @@ 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) { + + 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);