+ }
+ /* 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;
+ }
+ if (len > L1_WRITE_BLOCK_SIZE) {
+ if (stm32l1_write_half_pages(sl, addr, base, len/L1_WRITE_BLOCK_SIZE) == -1){
+ WLOG("\nwrite_half_pages failed == -1\n");
+ return -1;
+ }
+ }
+
+ /* write remainingword in program memory */
+ for (off = (len /L1_WRITE_BLOCK_SIZE)*L1_WRITE_BLOCK_SIZE; off < len; off += sizeof(uint32_t)) {
+ uint32_t data;
+ 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;