Subdirectory provided by Embedded Artists

Dependencies:   DM_FATFileSystem DM_HttpServer DM_USBHost EthernetInterface USBDevice mbed-rpc mbed-rtos mbed-src

Dependents:   lpc4088_displaymodule_hello_world_Sept_2018

Fork of DMSupport by Embedded Artists

Revision:
22:1a58a518435c
Parent:
19:2efb6f5f69a4
Child:
29:b1ec19000e15
--- a/FileSystems/QSPIFileSystem.cpp	Mon Jan 12 10:37:57 2015 +0100
+++ b/FileSystems/QSPIFileSystem.cpp	Fri Jan 16 11:13:39 2015 +0100
@@ -190,71 +190,30 @@
     /* Make sure it is a tested flash module */
     switch (SPIFI::instance().device()) {
       case SPIFI::Spansion_S25FL032:
-        /* For the Spansion memory the TOC occupies 256bytes and the TOC block will
-           hold 256 TOCs. */
         strcpy(memInfo.memName, "Spansion S25FL032");
-        memInfo.memSize        = obj->memSize;
-        memInfo.eraseBlockSize = 64*1024;
-        memInfo.numEraseBlocks = memInfo.memSize / memInfo.eraseBlockSize;
-        memInfo.tocSizeInBytes = sizeof(toc_entry_t) * memInfo.numEraseBlocks;
-        memInfo.numTocs        = memInfo.eraseBlockSize / memInfo.tocSizeInBytes;
-        memInfo.tocBlockAddr   = SPIFI_MEM_BASE + (NUM_BLOCKS * ERASE_SIZE) - (memInfo.numTocs * memInfo.tocSizeInBytes);
         break;
       
       case SPIFI::Winbond_W25Q64FV:
-        /* For the Winbond memory the TOC occupies 8192 bytes and that is bigger than 
-           one erase block (which is 4096 bytes). It is possible to either keep only
-           one TOC or to create a couple to reduce wear on the memory. In this case 
-           the multiple TOCs option is used. */
         strcpy(memInfo.memName, "Winbond W25Q64FV");
-        memInfo.memSize        = obj->memSize;
-        memInfo.eraseBlockSize = 4*1024;
-        memInfo.numEraseBlocks = memInfo.memSize / memInfo.eraseBlockSize;
-        memInfo.tocSizeInBytes = sizeof(toc_entry_t) * memInfo.numEraseBlocks;
-        memInfo.numTocs        = 8;
-        memInfo.tocBlockAddr   = SPIFI_MEM_BASE + (NUM_BLOCKS * ERASE_SIZE) - (memInfo.numTocs * memInfo.tocSizeInBytes);      
         break;
       
       case SPIFI::Macronix_MX25L6435E:
-        /* For the Macronix memory the TOC occupies 8192 bytes and that is bigger than 
-           one erase block (which is 4096 bytes). It is possible to either keep only
-           one TOC or to create a couple to reduce wear on the memory. In this case 
-           the multiple TOCs option is used. */
         strcpy(memInfo.memName, "Macronix_MX25L6435E");
-        memInfo.memSize        = obj->memSize;
-        memInfo.eraseBlockSize = 4*1024;
-        memInfo.numEraseBlocks = memInfo.memSize / memInfo.eraseBlockSize;
-        memInfo.tocSizeInBytes = sizeof(toc_entry_t) * memInfo.numEraseBlocks;
-        memInfo.numTocs        = 8;
-        memInfo.tocBlockAddr   = SPIFI_MEM_BASE + (NUM_BLOCKS * ERASE_SIZE) - (memInfo.numTocs * memInfo.tocSizeInBytes);      
         break;
       
       case SPIFI::Macronix_MX25L12835F:
-        /* For the Macronix memory the TOC occupies 16384 bytes and that is bigger than 
-           one erase block (which is 4096 bytes). It is possible to either keep only
-           one TOC or to create a couple to reduce wear on the memory. In this case 
-           the multiple TOCs option is used. */
         strcpy(memInfo.memName, "Macronix_MX25L12835F");
-        memInfo.memSize        = obj->memSize;
-        memInfo.eraseBlockSize = 4*1024;
-        memInfo.numEraseBlocks = memInfo.memSize / memInfo.eraseBlockSize;
-        memInfo.tocSizeInBytes = sizeof(toc_entry_t) * memInfo.numEraseBlocks;
-        memInfo.numTocs        = 4;
-        memInfo.tocBlockAddr   = SPIFI_MEM_BASE + (NUM_BLOCKS * ERASE_SIZE) - (memInfo.numTocs * memInfo.tocSizeInBytes);      
+        break;
+      
+      case SPIFI::SpecifiedInBios:
+        strcpy(memInfo.memName, "Specified in BIOS");
         break;
       
       case SPIFI::UnknownDevice:
       default:
         debug("INIT: Memory is unknown and may not work as expected\n");
         
-        // Asuming it has 64Kb erase blocks (i.e. same setup as the Spansion S25FL032
         strcpy(memInfo.memName, "Unknown - check ID");
-        memInfo.memSize        = obj->memSize;
-        memInfo.eraseBlockSize = 64*1024;
-        memInfo.numEraseBlocks = memInfo.memSize / memInfo.eraseBlockSize;      
-        memInfo.tocSizeInBytes = sizeof(toc_entry_t) * memInfo.numEraseBlocks;
-        memInfo.numTocs        = memInfo.eraseBlockSize / memInfo.tocSizeInBytes;
-        memInfo.tocBlockAddr   = SPIFI_MEM_BASE + (NUM_BLOCKS * ERASE_SIZE) - (memInfo.numTocs * memInfo.tocSizeInBytes);      
 
         /*
          * If this happens, check the manufacturer and device information
@@ -264,6 +223,35 @@
          */
         break;
     }
+    
+    /*
+     * The size of the erase blocks gives the number of erase blocks on the
+     * flash which in turn dictates the size of each TOC. For a flash with
+     * a large erase block size (Spansion_S25FL032 has 64Kb blocks) the
+     * the number of blocks is low, resulting in a small TOC with many fitting
+     * inside a single erase block.
+     * For a large flash with small erase block size (Macronix_MX25L12835F is
+     * 16Mb with 4Kb erase blocks) the number of blocks is high, resulting in
+     * a large TOC which doesn't even fit in one erase block.
+     *
+     *  4Mb, 64Kb erase block => TOC size   256b => 256 TOC/erase block
+     *  8Mb,  4Kb erase block => TOC size  8192b => 0.5 TOC/erase block
+     * 16Mb,  4Kb erase block => TOC size 16384b => 0.25 TOC/erase block
+     *
+     * In all cases we select a number of TOCs so that we use 64Kb of the
+     * memory for them. This will reduce wear on the flash as the TOC can
+     * be moved around.
+     */
+    memInfo.memSize        = obj->memSize;
+    memInfo.eraseBlockSize = SPIFI::instance().eraseBlockSize();
+    memInfo.numEraseBlocks = memInfo.memSize / memInfo.eraseBlockSize;      
+    memInfo.tocSizeInBytes = sizeof(toc_entry_t) * memInfo.numEraseBlocks;
+    memInfo.numTocs        = (64*1024) / memInfo.tocSizeInBytes;
+    if (memInfo.numTocs < 2) {
+      // just in case a unknown size combination appears
+      memInfo.numTocs = 2;
+    }
+    memInfo.tocBlockAddr   = SPIFI_MEM_BASE + (NUM_BLOCKS * ERASE_SIZE) - (memInfo.numTocs * memInfo.tocSizeInBytes);      
       
     debug_if(QSPI_DBG, "INIT: Found %dMB %s\n", memInfo.memSize/0x100000, memInfo.memName);