Merge pull request #148 from AleCher/master
[fw/stlink] / src / stlink-common.c
index 2d7db142cfa6ee5a5ed6d6bc7966bc2052a7fdf0..05ee12cd3cdd44c77826f8f99ebda67ef065658e 100644 (file)
@@ -18,6 +18,7 @@
 #define O_BINARY 0
 #endif
 
+
 #define LOG_TAG __FILE__
 #define DLOG(format, args...)         ugly_log(UDEBUG, LOG_TAG, format, ## args)
 #define ILOG(format, args...)         ugly_log(UINFO, LOG_TAG, format, ## args)
@@ -451,6 +452,22 @@ int stlink_load_device_params(stlink_t *sl) {
         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 if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) {
+        // if the flash size is zero, we assume it is 128k, if not we calculate the real value
+        uint32_t flash_size = stlink_read_debug32(sl,params->flash_size_reg) & 0xffff;
+        if ( flash_size == 0 ) {
+            sl->flash_size = 128 * 1024;
+        } else {
+            sl->flash_size = flash_size * 1024;
+        }
+    } else if ((sl->chip_id & 0xFFF) == STM32_CHIPID_L1_MEDIUM_PLUS) {
+        uint32_t flash_size = stlink_read_debug32(sl, params->flash_size_reg) & 0x1;
+        // 0 is 384k and 1 is 256k
+        if ( flash_size == 0 ) {
+            sl->flash_size = 384 * 1024;
+        } else {
+            sl->flash_size = 256 * 1024;
+        }
     } else {
         uint32_t flash_size = stlink_read_debug32(sl, params->flash_size_reg) & 0xffff;
         sl->flash_size = flash_size * 1024;
@@ -833,6 +850,7 @@ int stlink_fwrite_sram
     size_t off;
     mapped_file_t mf = MAPPED_FILE_INITIALIZER;
 
+
     if (map_file(&mf, path) == -1) {
         fprintf(stderr, "map_file() == -1\n");
         return -1;
@@ -853,7 +871,6 @@ int stlink_fwrite_sram
         fprintf(stderr, "unaligned addr or size\n");
         goto on_error;
     }
-
     /* do the copy by 1k blocks */
     for (off = 0; off < mf.len; off += 1024) {
         size_t size = 1024;
@@ -894,7 +911,7 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size)
     int error = -1;
     size_t off;
     int num_empty = 0;
-    unsigned char erased_pattern = (sl->chip_id == STM32_CHIPID_L1_MEDIUM)?0:0xff;
+    unsigned char erased_pattern = (sl->chip_id == STM32_CHIPID_L1_MEDIUM  || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS)?0:0xff;
 
     const int fd = open(path, O_RDWR | O_TRUNC | O_CREAT, 00700);
     if (fd == -1) {
@@ -1019,30 +1036,34 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr)
 #if DEBUG_FLASH
        fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl));
 #endif
-  } else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) {
+  } else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS) {
 
     uint32_t val;
 
-    /* disable pecr protection */
-    stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x89abcdef);
-    stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x02030405);
-
-    /* check pecr.pelock is cleared */
+    /* check if the locks are set */
     val = stlink_read_debug32(sl, STM32L_FLASH_PECR);
-    if (val & (1 << 0)) {
-      WLOG("pecr.pelock not clear (%#x)\n", val);
-      return -1;
-    }
+    if((val & (1<<0))||(val & (1<<1))) {
+        /* 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)) {
+            WLOG("pecr.pelock not clear (%#x)\n", val);
+            return -1;
+        }
 
-    /* unlock program memory */
-    stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x8c9daebf);
-    stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x13141516);
+        /* 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)) {
-      WLOG("pecr.prglock not clear (%#x)\n", val);
-      return -1;
+        /* check pecr.prglock is cleared */
+        val = stlink_read_debug32(sl, STM32L_FLASH_PECR);
+        if (val & (1 << 1)) {
+            WLOG("pecr.prglock not clear (%#x)\n", val);
+            return -1;
+        }
     }
 
     /* unused: unlock the option byte block */
@@ -1121,7 +1142,7 @@ int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr)
 }
 
 int stlink_erase_flash_mass(stlink_t *sl) {
-    if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) {
+    if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS ) {
         /* erase each page */
         int i = 0, num_pages = sl->flash_size/sl->flash_pgsz;
         for (i = 0; i < num_pages; i++) {
@@ -1291,7 +1312,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) {
     const uint8_t* loader_code;
     size_t loader_size;
 
-    if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) { /* stm32l */
+    if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS ) { /* stm32l */
         loader_code = loader_code_stm32l;
         loader_size = sizeof(loader_code_stm32l);
     } else if (sl->core_id == STM32VL_CORE_ID || sl->chip_id == STM32_CHIPID_F3  || sl->chip_id == STM32_CHIPID_F37x) {
@@ -1531,7 +1552,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t
 
     }  //STM32F4END
 
-    else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM)    {
+    else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS)    {
        /* use fast word write. todo: half page. */
        uint32_t val;
 
@@ -1687,7 +1708,7 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) {
     /* write the file in flash at addr */
     int err;
     unsigned int num_empty = 0, index;
-    unsigned char erased_pattern =(sl->chip_id == STM32_CHIPID_L1_MEDIUM)?0:0xff;
+    unsigned char erased_pattern =(sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS)?0:0xff;
     mapped_file_t mf = MAPPED_FILE_INITIALIZER;
     if (map_file(&mf, path) == -1) {
         ELOG("map_file() == -1\n");
@@ -1725,7 +1746,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons
         return -1;
     }
 
-    if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) {
+    if (sl->chip_id == STM32_CHIPID_L1_MEDIUM  || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS) {
 
         size_t count = size / sizeof(uint32_t);
         if (size % sizeof(uint32_t)) ++count;
@@ -1770,17 +1791,18 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons
 #define WAIT_ROUNDS 1000
     /* wait until done (reaches breakpoint) */
     for (i = 0; i < WAIT_ROUNDS; i++) {
+        usleep(10);
         if (is_core_halted(sl))
             break;
     }
 
     if (i >= WAIT_ROUNDS) {
-        fatal("flash loader run error\n");
+        ELOG("flash loader run error\n");
         return -1;
     }
 
     /* check written byte count */
-    if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) {
+    if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS) {
 
       size_t count = size / sizeof(uint32_t);
       if (size % sizeof(uint32_t)) ++count;