I'm using lpc open SPIFI library (Latest version 1.01) on LPC4357 and S25Fl164K external flash.
I'm using spi flash as an external flash with simple command (Not memory mapped or for running firmware from it)
my problem is that in some cases (specially when erasing a sector by spifiDevEraseSubBlock function) the system throw hard fault
the hard fault rise at the following function:
function "spifi_HW_GetData8" in this code
static uint32_t spifiDeviceDataGetStatusS25FL164K(const SPIFI_HANDLE_T *pHandle)
{
static const uint8_t spifiCmdOp[3] = {CMD_05_RDSR1, CMD_35_RDSR2, CMD_33_RDSR3};
uint32_t statusRegs = 0;
LPC_SPIFI_CHIPHW_T *pSpifiCtrlAddr = (LPC_SPIFI_CHIPHW_T *) pHandle->pInfoData->spifiCtrlAddr;
uint32_t idx;
for (idx = 0; idx < sizeof(spifiCmdOp) / sizeof(spifiCmdOp[0]); ++idx) {
spifi_HW_SetCmd(pSpifiCtrlAddr,
(SPIFI_CMD_OPCODE(spifiCmdOp[idx]) |
SPIFI_CMD_DATALEN(1) |
SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) |
SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP)));
statusRegs |= (spifi_HW_GetData8(pSpifiCtrlAddr) << (8 * idx));
/* Wait for command to complete */
spifi_HW_WaitCMD(pSpifiCtrlAddr);
}
return statusRegs;
}
Call stack:
what is wrong with my system or spifi configuration?
Configs:
void SPIFI_Init(void) {
uint32_t spifiBaseClockRate;
uint32_t maxSpifiClock;
/* Setup SPIFI FLASH pin muxing (QUAD) */
Chip_SCU_SetPinMuxing(spifipinmuxing, sizeof(spifipinmuxing) / sizeof(PINMUX_GRP_T));
/* SPIFI base clock will be based on the main PLL rate and a divider */
spifiBaseClockRate = 160000000;
/* Setup SPIFI clock to run around 16Mhz. Use divider C for this */
Chip_Clock_SetDivider(CLK_IDIV_C, CLKIN_IDIVA, CalculateDivider(spifiBaseClockRate, 40000000));
Chip_Clock_SetBaseClock(CLK_BASE_SPIFI, CLKIN_IDIVC, true, false);
/* initialize and get a handle to the library */
pSpifi = initializeSpifi();
/* Get some info needed for the application */
maxSpifiClock = spifiDevGetInfo(pSpifi, SPIFI_INFO_MAXCLOCK);
/* Lower the clock to the max rate the test environment can support */
if (maxSpifiClock > MAX_SPIFI_CLOCK) {
maxSpifiClock = MAX_SPIFI_CLOCK;
}
/* Setup SPIFI clock to at the maximum interface rate the detected device
can use. This should be done after device init. */
Chip_Clock_SetDivider(CLK_IDIV_C, CLKIN_MAINPLL, CalculateDivider(spifiBaseClockRate, maxSpifiClock));
}static SPIFI_HANDLE_T *initializeSpifi(void) {
uint32_t memSize;
SPIFI_HANDLE_T *pReturnVal;
/* Initialize LPCSPIFILIB library, reset the interface */
spifiInit(CHIP_LPC_SPIFI_BASE, true);
/* register support for the family(s) we may want to work with
(only 1 is required) */
spifiRegisterFamily(spifi_REG_FAMILY_CommonCommandSet);
/* Enumerate the list of supported devices */
{
SPIFI_DEV_ENUMERATOR_T ctx;
const char * devName = spifiDevEnumerateName(&ctx, 1);
while (devName) {
devName = spifiDevEnumerateName(&ctx, 0);
}
}
/* Get required memory for detected device, this may vary per device family */
memSize = spifiGetHandleMemSize(CHIP_LPC_SPIFI_BASE);
if (memSize == 0) {
while(1);
}
/* Initialize and detect a device and get device context */
pReturnVal = spifiInitDevice(&lmem, sizeof(lmem), CHIP_LPC_SPIFI_BASE, SPIFLASH_BASE_ADDRESS);
if (pReturnVal == NULL) {
// ("spifiInitDevice", SPIFI_ERR_GEN);
while(1);
}
return pReturnVal;
}
static uint32_t CalculateDivider(uint32_t baseClock, uint32_t target) {
uint32_t divider = (baseClock / target);
/* If there is a remainder then increment the divider so that the resultant
clock is not over the target */
if(baseClock % target) {
++divider;
}
return divider;
}
Hi Dolphin,
I would recommend you to test and compare the lpcspifilib example that comes with LPCOpen with your project:
LPCOpen Software for LPC43XX|NXP
Hope it helps!
Best Regards,
Carlos Mendoza
Technical Support Engineer