+ fprintf(stdout,"\n");
+ ILOG("Finished erasing %d pages of %d (%#x) bytes\n",
+ page_count, sl->flash_pgsz, sl->flash_pgsz);
+
+ if (sl->chip_id == STM32F4_CHIP_ID) {
+ /* todo: check write operation */
+
+ /* First unlock the cr */
+ unlock_flash_if(sl);
+
+ /* TODO: Check that Voltage range is 2.7 - 3.6 V */
+ /* set parallelisim to 32 bit*/
+ write_flash_cr_psiz(sl, 2);
+
+ /* set programming mode */
+ set_flash_cr_pg(sl);
+
+#define PROGRESS_CHUNK_SIZE 0x1000
+ /* write a word in program memory */
+ for (off = 0; off < len; off += sizeof(uint32_t)) {
+ uint32_t data;
+ if (sl->verbose >= 1) {
+ if ((off & (PROGRESS_CHUNK_SIZE - 1)) == 0) {
+ /* 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;
+ fprintf(stdout, "Writing %ukB chunk %u out of %u\n", PROGRESS_CHUNK_SIZE/1024, pgnum, pgcount);
+ }
+ }
+
+ write_uint32((unsigned char*) &data, *(uint32_t*) (base + off));
+ stlink_write_debug32(sl, addr + off, data);
+
+ /* wait for sr.busy to be cleared */
+ wait_flash_busy(sl);
+
+ }
+ /* Relock flash */
+ lock_flash(sl);
+
+#if 0 /* todo: debug mode */
+ fprintf(stdout, "Final CR:0x%x\n", read_flash_cr(sl));
+#endif
+
+
+
+ } //STM32F4END
+
+ else if (sl->core_id == STM32L_CORE_ID) {
+ /* use fast word write. todo: half page. */
+ uint32_t val;
+
+#if 0 /* todo: check write operation */
+
+ uint32_t nwrites = sl->flash_pgsz;
+
+ redo_write:
+
+#endif /* todo: check write operation */
+
+ /* disable pecr protection */
+ stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x89abcdef);
+ stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x02030405);
+
+ /* check pecr.pelock is cleared */
+ val = stlink_read_debug32(sl, STM32L_FLASH_PECR);
+ if (val & (1 << 0)) {
+ fprintf(stderr, "pecr.pelock not clear\n");
+ return -1;
+ }
+
+ /* unlock program memory */
+ stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x8c9daebf);
+ stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x13141516);
+
+ /* check pecr.prglock is cleared */
+ val = stlink_read_debug32(sl, STM32L_FLASH_PECR);
+ if (val & (1 << 1)) {
+ fprintf(stderr, "pecr.prglock not clear\n");
+ return -1;
+ }
+ off = 0;
+ if (len > L1_WRITE_BLOCK_SIZE) {
+ if (stm32l1_write_half_pages(sl, addr, base, len/L1_WRITE_BLOCK_SIZE) == -1){
+ /* This may happen on a blank device! */
+ WLOG("\nwrite_half_pages failed == -1\n");
+ }
+ else{
+ off = (len /L1_WRITE_BLOCK_SIZE)*L1_WRITE_BLOCK_SIZE;
+ }
+ }
+
+ /* write remainingword in program memory */
+ for ( ; off < len; off += sizeof(uint32_t)) {
+ uint32_t data;
+ if (off > 254)
+ fprintf(stdout, "\r");
+
+ if ((off % sl->flash_pgsz) > (sl->flash_pgsz -5)) {
+ fprintf(stdout, "\r%3u/%u pages written",
+ off/sl->flash_pgsz, len/sl->flash_pgsz);
+ fflush(stdout);
+ }
+
+ write_uint32((unsigned char*) &data, *(uint32_t*) (base + off));
+ stlink_write_debug32(sl, addr + off, data);
+
+ /* wait for sr.busy to be cleared */
+ while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) {
+ }
+
+#if 0 /* todo: check redo write operation */
+
+ /* check written bytes. todo: should be on a per page basis. */
+ data = stlink_read_debug32(sl, addr + off);
+ if (data == *(uint32_t*)(base + off)) {
+ /* re erase the page and redo the write operation */
+ uint32_t page;
+ uint32_t val;
+
+ /* fail if successive write count too low */
+ if (nwrites < sl->flash_pgsz) {
+ fprintf(stderr, "writes operation failure count too high, aborting\n");
+ return -1;
+ }
+
+ nwrites = 0;
+
+ /* assume addr aligned */
+ if (off % sl->flash_pgsz) off &= ~(sl->flash_pgsz - 1);
+ page = addr + off;
+
+ fprintf(stderr, "invalid write @0x%x(0x%x): 0x%x != 0x%x. retrying.\n",
+ page, addr + off, read_uint32(base + off, 0), read_uint32(sl->q_buf, 0));
+
+ /* reset lock bits */
+ val = stlink_read_debug32(sl, STM32L_FLASH_PECR)
+ | (1 << 0) | (1 << 1) | (1 << 2);
+ stlink_write_debug32(sl, STM32L_FLASH_PECR, val);
+
+ stlink_erase_flash_page(sl, page);
+
+ goto redo_write;
+ }
+
+ /* increment successive writes counter */
+ ++nwrites;
+
+#endif /* todo: check redo write operation */
+ }
+ fprintf(stdout, "\n");
+ /* reset lock bits */
+ 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");
+ /* flash loader initialization */
+ if (init_flash_loader(sl, &fl) == -1) {
+ WLOG("init_flash_loader() == -1\n");
+ return -1;
+ }