Assume maximum FLASH size for F2 as for F4 (broken Flash size register)
[fw/stlink] / src / stlink-common.c
index 39a714b179ee7df00c10541107cda2cd516bd299..294f932b2bd7c4ad5d37e29e79db05e05bd6237e 100644 (file)
@@ -136,7 +136,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==STM32F4_CHIP_ID)
+       if((sl->chip_id==STM32_CHIPID_F2) ||(sl->chip_id==STM32F4_CHIP_ID))
                res = stlink_read_debug32(sl, FLASH_F4_CR);
        else
                res = stlink_read_debug32(sl, FLASH_CR);
@@ -148,7 +148,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==STM32F4_CHIP_ID)
+       if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID))
                return read_flash_cr(sl) & (1 << FLASH_F4_CR_LOCK);
        else
                return read_flash_cr(sl) & (1 << FLASH_CR_LOCK);
@@ -160,7 +160,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==STM32F4_CHIP_ID) {
+    if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID)) {
        stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY1);
                stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY2);
     }
@@ -186,7 +186,7 @@ static int unlock_flash_if(stlink_t *sl) {
 }
 
 static void lock_flash(stlink_t *sl) {
-    if(sl->chip_id==STM32F4_CHIP_ID) {
+    if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID)) {
        const uint32_t n = read_flash_cr(sl) | (1 << FLASH_F4_CR_LOCK);
        stlink_write_debug32(sl, FLASH_F4_CR, n);
     }
@@ -199,7 +199,7 @@ static void lock_flash(stlink_t *sl) {
 
 
 static void set_flash_cr_pg(stlink_t *sl) {
-    if(sl->chip_id==STM32F4_CHIP_ID) {
+    if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID)) {
                uint32_t x = read_flash_cr(sl);
                x |= (1 << FLASH_CR_PG);
        stlink_write_debug32(sl, FLASH_F4_CR, x);
@@ -212,7 +212,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==STM32F4_CHIP_ID)
+    if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID))
        stlink_write_debug32(sl, FLASH_F4_CR, n);
     else
         stlink_write_debug32(sl, FLASH_CR, n);
@@ -229,26 +229,34 @@ static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) {
 }
 
 static void set_flash_cr_mer(stlink_t *sl) {
-    const uint32_t n = 1 << FLASH_CR_MER;
-    stlink_write_debug32(sl, FLASH_CR, n);
+    if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID))
+        stlink_write_debug32(sl, FLASH_F4_CR,
+                             stlink_read_debug32(sl, FLASH_F4_CR) | (1 << FLASH_CR_MER));
+    else 
+        stlink_write_debug32(sl, FLASH_CR,
+                             stlink_read_debug32(sl, FLASH_CR) | (1 << FLASH_CR_MER));
 }
 
 static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) {
-    const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_MER);
-    stlink_write_debug32(sl, FLASH_CR, n);
+    if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID))
+        stlink_write_debug32(sl, FLASH_F4_CR,
+                             stlink_read_debug32(sl, FLASH_F4_CR) & ~(1 << FLASH_CR_MER));
+    else 
+        stlink_write_debug32(sl, FLASH_CR,
+                             stlink_read_debug32(sl, FLASH_CR) & ~(1 << FLASH_CR_MER));
 }
 
 static void set_flash_cr_strt(stlink_t *sl) {
-       if(sl->chip_id == STM32F4_CHIP_ID)
+       if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID))
        {
                uint32_t x = read_flash_cr(sl);
                x |= (1 << FLASH_F4_CR_STRT);
                stlink_write_debug32(sl, FLASH_F4_CR, x);
        }
        else {
-               /* assume come on the flash_cr_per path */
-           const uint32_t n = (1 << FLASH_CR_PER) | (1 << FLASH_CR_STRT);
-           stlink_write_debug32(sl, FLASH_CR, n);
+           stlink_write_debug32(
+                sl, FLASH_CR, 
+                stlink_read_debug32(sl,FLASH_CR) |(1 << FLASH_CR_STRT) );
        }
 }
 
@@ -258,7 +266,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==STM32F4_CHIP_ID)
+       if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID))
                res = stlink_read_debug32(sl, FLASH_F4_SR);
        else
                res = stlink_read_debug32(sl, FLASH_SR);
@@ -267,7 +275,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==STM32F4_CHIP_ID)
+       if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID))
                return read_flash_sr(sl) & (1 << FLASH_F4_SR_BSY);
        else
                return read_flash_sr(sl) & (1 << FLASH_SR_BSY);
@@ -279,6 +287,22 @@ static void wait_flash_busy(stlink_t *sl) {
         ;
 }
 
+static void wait_flash_busy_progress(stlink_t *sl) {
+    int i = 0;
+    fprintf(stdout, "Mass erasing");
+    fflush(stdout);
+    while (is_flash_busy(sl))
+    {
+        usleep(10000);
+        i++;
+        if (i % 100 == 0) {
+            fprintf(stdout, ".");
+            fflush(stdout);
+        }
+    }
+    fprintf(stdout, "\n");
+}
+
 static inline unsigned int is_flash_eop(stlink_t *sl) {
     return read_flash_sr(sl) & (1 << FLASH_SR_EOP);
 }
@@ -396,22 +420,23 @@ void stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) {
 int stlink_load_device_params(stlink_t *sl) {
     ILOG("Loading device parameters....\n");
     const chip_params_t *params = NULL;
-    
     sl->core_id = stlink_core_id(sl);
     uint32_t chip_id = stlink_chip_id(sl);
     
-    /* Fix chip_id for F4 rev A errata */
-    if (((chip_id & 0xFFF) == 0x411) && (sl->core_id == CORE_M4_R0)) {
-      chip_id = 0x413;
+    sl->chip_id = chip_id & 0xfff;
+    /* Fix chip_id for F4 rev A errata , Read CPU ID, as CoreID is the same for F2/F4*/
+    if (sl->chip_id == 0x411) {
+        uint32_t cpuid = stlink_read_debug32(sl, 0xE000ED00);
+        if((cpuid  & 0xfff0) == 0xc240)
+            sl->chip_id = 0x413;
     }
 
-    sl->chip_id = chip_id & 0xfff;
-       for(size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) {
-               if(devices[i].chip_id == sl->chip_id) {
-                       params = &devices[i];
-                       break;
-               }
-       }
+    for(size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) {
+        if(devices[i].chip_id == sl->chip_id) {
+            params = &devices[i];
+            break;
+        }
+    }
     if (params == NULL) {
         WLOG("unknown chip id! %#x\n", chip_id);
         return -1;
@@ -423,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 {
@@ -723,15 +748,21 @@ static void unmap_file(mapped_file_t * mf) {
     mf->len = 0;
 }
 
+/* Limit the block size to compare to 0x1800
+   Anything larger will stall the STLINK2
+   Maybe STLINK V1 needs smaller value!*/
 static int check_file(stlink_t* sl, mapped_file_t* mf, stm32_addr_t addr) {
     size_t off;
+    size_t n_cmp = sl->flash_pgsz;
+    if ( n_cmp > 0x1800)
+        n_cmp = 0x1800;
 
-    for (off = 0; off < mf->len; off += sl->flash_pgsz) {
+    for (off = 0; off < mf->len; off += n_cmp) {
         size_t aligned_size;
 
         /* adjust last page size */
-        size_t cmp_size = sl->flash_pgsz;
-        if ((off + sl->flash_pgsz) > mf->len)
+        size_t cmp_size = n_cmp;
+        if ((off + n_cmp) > mf->len)
             cmp_size = mf->len - off;
 
         aligned_size = cmp_size;
@@ -896,7 +927,7 @@ uint32_t calculate_F4_sectornum(uint32_t flashaddr){
 }
 
 uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){
-       if(sl->chip_id == STM32F4_CHIP_ID) {
+       if((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID)) {
                uint32_t sector=calculate_F4_sectornum(flashaddr);
                if (sector<4) sl->flash_pgsz=0x4000;
                else if(sector<5) sl->flash_pgsz=0x10000;
@@ -913,7 +944,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 == STM32F4_CHIP_ID)
+  if ((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID))
   {
     /* wait for ongoing op to finish */
     wait_flash_busy(sl);
@@ -941,7 +972,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;
@@ -1053,10 +1084,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_F4) {
-        DLOG("(FIXME) Mass erase of STM32F4\n");
-      }
-     else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) {
+     if (sl->chip_id == STM32_CHIPID_L1_MEDIUM) {
         /* erase each page */
         int i = 0, num_pages = sl->flash_size/sl->flash_pgsz;
         for (i = 0; i < num_pages; i++) {
@@ -1085,7 +1113,7 @@ int stlink_erase_flash_mass(stlink_t *sl) {
         set_flash_cr_strt(sl);
         
         /* wait for completion */
-        wait_flash_busy(sl);
+        wait_flash_busy_progress(sl);
         
         /* relock the flash */
         lock_flash(sl);
@@ -1157,7 +1185,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->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);
@@ -1209,17 +1237,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;
@@ -1331,7 +1355,7 @@ 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 == STM32F4_CHIP_ID) {
+    if ((sl->chip_id == STM32_CHIPID_F2) ||(sl->chip_id == STM32F4_CHIP_ID)) {
        /* todo: check write operation */
 
        /* First unlock the cr */
@@ -1376,7 +1400,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;
 
@@ -1571,7 +1595,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;
@@ -1614,7 +1638,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;