A library with drivers for different peripherals on the LPC4088 QuickStart Board or related add-on boards.
Dependencies: FATFileSystem
Fork of EALib by
Diff: QSPIFileSystem.cpp
- Revision:
- 8:fe3cb3fbb64e
- Parent:
- 0:0fdadbc3d852
- Child:
- 12:15597e45eea0
diff -r e431d9d47db6 -r fe3cb3fbb64e QSPIFileSystem.cpp --- 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; } - - - -