AnsweredAssumed Answered

LPC4357 SPIFI peripheral hardfault

Question asked by Dolphin Apadana on Sep 25, 2017
Latest reply on Oct 2, 2017 by Carlos_Mendoza

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:

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;
}

Outcomes