The wait in mci_WaitForEvent will delay all card transactions.

Dependencies:   FATFileSystem

Fork of EALib by EmbeddedArtists AB

Revision:
8:fe3cb3fbb64e
Parent:
0:0fdadbc3d852
--- a/QSPIFileSystem.cpp	Mon Nov 11 09:39:58 2013 +0000
+++ b/QSPIFileSystem.cpp	Wed Dec 11 12:16:40 2013 +0000
@@ -1,7 +1,7 @@
 #include "QSPIFileSystem.h"
 #include "mbed_debug.h"
 
-#include "spifi_rom_api.h"
+#include "SPIFI.h"
 
 /******************************************************************************
  * Defines and typedefs
@@ -9,27 +9,11 @@
 
 #define QSPI_DBG             0
 
-/* 
- * The SPIFI_ROM_PTR (0x1FFF1FF8) points to an area where the pointers to
- * different drivers in ROM are stored.
- */
-typedef struct {
-   /*const*/ unsigned p_usbd;     // USBROMD 
-   /*const*/ unsigned p_clib;
-   /*const*/ unsigned p_cand;
-   /*const*/ unsigned p_pwrd;     // PWRROMD
-   /*const*/ unsigned p_promd;    // DIVROMD
-   /*const*/ SPIFI_RTNS *pSPIFID; // SPIFIROMD
-   /*const*/ unsigned p_dev3;
-   /*const*/ unsigned p_dev4; 
-} ROM;
-
-#define ROM_DRIVERS_PTR ((ROM *)(*((unsigned int *)SPIFI_ROM_PTR)))
 #define IS_ADDR_IN_SPIFI(__addr)  ( (((uint32_t)(__addr)) & 0xff000000) == SPIFI_MEM_BASE )
 
-#define MEM_SIZE    (memInfo.memSize)          //(8*1024*1024)
-#define ERASE_SIZE  (memInfo.eraseBlockSize)   //(64*1024)
-#define NUM_BLOCKS  (memInfo.numEraseBlocks)   //(MEM_SIZE/ERASE_SIZE)
+#define MEM_SIZE    (memInfo.memSize)
+#define ERASE_SIZE  (memInfo.eraseBlockSize)
+#define NUM_BLOCKS  (memInfo.numEraseBlocks)
 
 typedef uint32_t toc_entry_t;
 
@@ -130,11 +114,11 @@
  * Local variables
  *****************************************************************************/
 
-static toc_entry_t* TOC = NULL;//[NUM_BLOCKS];
+static toc_entry_t* TOC = NULL;
 static int activeTOC = -1;
 
 static const SPIFI_RTNS *spifi = NULL;
-static SPIFIobj obj;
+static SPIFIobj* obj;
 static SPIFIopers opers;
 
 static char addr_conflict_buff[PROG_SIZE];
@@ -178,77 +162,65 @@
 static fresult qspifs_init()
 {
   if (spifi == NULL) {
-    
-    // Turn on SPIFI block as it is disabled on reset
-    LPC_SC->PCONP |= 0x00010000;
-
-    // pinsel for SPIFI
-    LPC_IOCON->P2_7 = 5; /* SPIFI_CSN @ P2.7 */
-    LPC_IOCON->P0_22 = 5; /* SPIFI_CLK @ P0.22 */
-    LPC_IOCON->P0_15 = 5; /* SPIFI_IO2 @ P0.15 */
-    LPC_IOCON->P0_16 = 5; /* SPIFI_IO3 @ P0.16 */
-    LPC_IOCON->P0_17 = 5; /* SPIFI_IO1 @ P0.17 */
-    LPC_IOCON->P0_18 = 5; /* SPIFI_IO0 @ P0.18 */
+    SPIFI::SpifiError err;
+    err = SPIFI::instance().init();
+    if (err != SPIFI::Ok) {
+      spifi = NULL;
+      return FS_ERR_SPIFI;
+    }
     
-    uint32_t spifi_clk_div = (*((volatile uint32_t*)0x400FC1B4)) & 0x1f;
-    uint32_t spifi_clk_mhz = (SystemCoreClock / spifi_clk_div) / 1000000;
-
-    spifi = ROM_DRIVERS_PTR->pSPIFID;
-    
-    /* Typical time tCS is 20 ns min, we give 200 ns to be on safer side */
-    int rc = spifi->spifi_init (&obj, spifi_clk_mhz/5, S_FULLCLK+S_RCVCLK, spifi_clk_mhz);
-    if (rc) {
-      spifi = NULL;
-      return qspifs_translateSpifiError(rc);
-    }
+    SPIFI::instance().internalData(&obj, &spifi);
 
     /* Make sure it is a tested flash module */
-    if ((obj.mfger == 1) && (obj.devType == 0x2) && (obj.devID == 0x15) && (obj.memSize > 0x100000)) 
-    {
-      /* 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);      
-    } 
-    else if ((obj.mfger == 0xef) && (obj.devType == 0x40) && (obj.devID == 0x17) && (obj.memSize > 0x100000))
-    {
-      /* 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);      
-    } 
-    else 
-    {
-      debug("INIT: Memory is unknown and may not work as expected\n");
+    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;
       
-      // 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);      
+      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::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
-       * and compare with the data sheet for your chip. Also make sure
-       * that the sector sizes are the same (i.e. 64KB) for your chip.
-       * If everything is the same then add an exception for your chip.
-       */
+        /*
+         * If this happens, check the manufacturer and device information
+         * and compare with the data sheet for your chip. Also make sure
+         * that the sector sizes are the same (i.e. 64KB) for your chip.
+         * If everything is the same then add an exception for your chip.
+         */
+        break;
     }
+      
     debug_if(QSPI_DBG, "INIT: Found %dMB %s\n", memInfo.memSize/0x100000, memInfo.memName);
     
     if (TOC != NULL) {
@@ -434,7 +406,7 @@
           opers.scratch = NULL;
           opers.protect = 0;
           opers.options = S_NO_VERIFY;
-          rc = spifi->spifi_erase(&obj, &opers);
+          rc = spifi->spifi_erase(obj, &opers);
           if (rc) {
             return qspifs_translateSpifiError(rc);
           }
@@ -456,7 +428,7 @@
     for (int i = 0; i < (TOC_SIZE / PROG_SIZE); i++) 
     {
       opers.dest = (char *)(TOC_BLOCK_ADDR + activeTOC*TOC_SIZE + i*PROG_SIZE);
-      rc = spifi->spifi_program(&obj, ((char*)TOC)+i*PROG_SIZE, &opers);
+      rc = spifi->spifi_program(obj, ((char*)TOC)+i*PROG_SIZE, &opers);
       if (rc) 
       {
         break;
@@ -579,7 +551,7 @@
   opers.scratch = NULL;
   opers.protect = 0;
   opers.options = S_NO_VERIFY;
-  return qspifs_translateSpifiError(spifi->spifi_erase (&obj, &opers));
+  return qspifs_translateSpifiError(spifi->spifi_erase (obj, &opers));
 }
 
 /******************************************************************************
@@ -651,7 +623,7 @@
         opers.protect = 0;
         opers.options = S_VERIFY_PROG | S_FORCE_ERASE;// S_CALLER_ERASE;
         opers.dest = (char *)(i*ERASE_SIZE);
-        rc = spifi->spifi_program(&obj, (char*)pSrc, &opers);
+        rc = spifi->spifi_program(obj, (char*)pSrc, &opers);
         if (rc) {
           return qspifs_translateSpifiError(rc);
         }
@@ -827,7 +799,7 @@
   opers.scratch = NULL;
   opers.protect = 0;
   opers.options = S_NO_VERIFY;
-  rc = spifi->spifi_erase(&obj, &opers);
+  rc = spifi->spifi_erase(obj, &opers);
   if (rc) {
     return qspifs_translateSpifiError(rc);
   }
@@ -937,9 +909,9 @@
             }
             if (IS_ADDR_IN_SPIFI(pData)) {
                 memcpy(addr_conflict_buff, pSrc, opers.length);
-                rc = spifi->spifi_program(&obj, addr_conflict_buff, &opers);
+                rc = spifi->spifi_program(obj, addr_conflict_buff, &opers);
             } else {
-                rc = spifi->spifi_program(&obj, (char*) pSrc, &opers);
+                rc = spifi->spifi_program(obj, (char*) pSrc, &opers);
             }
             res = qspifs_translateSpifiError(rc);
             if ((res == FS_ERR_SPIFI_VERIFICATION)
@@ -1278,23 +1250,6 @@
 QSPIFileSystem::QSPIFileSystem(const char* name) :
     FileSystemLike(name) {
 
-    // Turn on SPIFI block as it is disabled on reset
-    LPC_SC->PCONP |= 0x00010000;
-
-    // pinsel for SPIFI
-    LPC_IOCON->P2_7 &= ~0x07;
-    LPC_IOCON->P2_7 |= 0x05; /* SPIFI_CSN @ P2.7 */
-    LPC_IOCON->P0_22 &= ~0x07;
-    LPC_IOCON->P0_22 |= 0x05; /* SPIFI_CLK @ P0.22 */
-    LPC_IOCON->P0_15 &= ~0x07;
-    LPC_IOCON->P0_15 |= 0x5; /* SPIFI_IO2 @ P0.15 */
-    LPC_IOCON->P0_16 &= ~0x07;
-    LPC_IOCON->P0_16 |= 0x5; /* SPIFI_IO3 @ P0.16 */
-    LPC_IOCON->P0_17 &= ~0x07;
-    LPC_IOCON->P0_17 |= 0x5; /* SPIFI_IO1 @ P0.17 */
-    LPC_IOCON->P0_18 &= ~0x07;
-    LPC_IOCON->P0_18 |= 0x5; /* SPIFI_IO0 @ P0.18 */
-
     activeTOC = -1;
     spifi = NULL;
 }
@@ -1493,7 +1448,3 @@
   }
   return false;
 }
-
-
-
-