LPC4357 SPIFI peripheral hardfault

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC4357 SPIFI peripheral hardfault

944 Views
dolphinapadana
Contributor I

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:

Capture1.PNG

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

Labels (3)
0 Kudos
Reply
1 Reply

635 Views
Carlos_Mendoza
NXP Employee
NXP Employee

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

0 Kudos
Reply