500 lines
22 KiB
C
500 lines
22 KiB
C
/*
|
|
* Copyright 2020, 2023 NXP
|
|
* All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include "fsl_romapi.h"
|
|
#include "fsl_debug_console.h"
|
|
#include "fsl_cache.h"
|
|
|
|
#include "pin_mux.h"
|
|
#include "clock_config.h"
|
|
#include "board.h"
|
|
#include "fsl_common.h"
|
|
/*${header:start}*/
|
|
/*******************************************************************************
|
|
* Definitions
|
|
******************************************************************************/
|
|
/*${macro:start}*/
|
|
#define FlexSpiInstance 0U
|
|
#define EXAMPLE_FLEXSPI_AMBA_BASE FlexSPI_AMBA_BASE
|
|
#define FLASH_SIZE 0x4000000UL /* 64MBytes */
|
|
#define FLASH_PAGE_SIZE 512UL /* 512Bytes */
|
|
#define FLASH_SECTOR_SIZE 0x40000UL /* 256KBytes */
|
|
#define FLASH_BLOCK_SIZE 0x40000UL /* 256KBytes */
|
|
/*******************************************************************************
|
|
* Definitions
|
|
******************************************************************************/
|
|
#define BUFFER_LEN FLASH_PAGE_SIZE
|
|
|
|
/*******************************************************************************
|
|
* Prototypes
|
|
******************************************************************************/
|
|
#if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1))
|
|
void BOARD_SetupFlexSpiClock(void);
|
|
#endif
|
|
/* Get FlexSPI NOR Configuration Block */
|
|
void FLEXSPI_NorFlash_GetConfig(flexspi_nor_config_t *config);
|
|
void error_trap(void);
|
|
void app_finalize(void);
|
|
|
|
#if !defined(XIP_EXTERNAL_FLASH) || (XIP_EXTERNAL_FLASH != 1)
|
|
extern status_t FLEXSPI_NorFlash_VerifyID(uint32_t instance);
|
|
#endif
|
|
|
|
/*******************************************************************************
|
|
* Variables
|
|
******************************************************************************/
|
|
|
|
/*! @brief FLEXSPI NOR flash driver Structure */
|
|
static flexspi_nor_config_t norConfig;
|
|
/*! @brief Buffer for program */
|
|
static uint8_t s_buffer[BUFFER_LEN];
|
|
/*! @brief Buffer for readback */
|
|
static uint8_t s_buffer_rbc[BUFFER_LEN];
|
|
|
|
typedef struct _flexspi_cache_status
|
|
{
|
|
volatile bool DCacheEnableFlag;
|
|
volatile bool ICacheEnableFlag;
|
|
} flexspi_cache_status_t;
|
|
|
|
/*******************************************************************************
|
|
* Code
|
|
******************************************************************************/
|
|
/* Get FLEXSPI NOR Configuration Block */
|
|
void FLEXSPI_NorFlash_GetConfig(flexspi_nor_config_t *config)
|
|
{
|
|
config->memConfig.tag = FLEXSPI_CFG_BLK_TAG;
|
|
config->memConfig.version = FLEXSPI_CFG_BLK_VERSION;
|
|
config->memConfig.readSampleClkSrc = kFLEXSPIReadSampleClk_ExternalInputFromDqsPad;
|
|
config->memConfig.serialClkFreq =
|
|
kFLEXSPISerialClk_30MHz; /* Serial Flash Frequencey.See System Boot Chapter for more details */
|
|
config->memConfig.lutCustomSeqEnable = true;
|
|
config->memConfig.sflashA1Size = FLASH_SIZE;
|
|
config->memConfig.csHoldTime = 3U; /* Data hold time, default value: 3 */
|
|
config->memConfig.csSetupTime = 3U; /* Date setup time, default value: 3 */
|
|
config->memConfig.deviceType = kFLEXSPIDeviceType_SerialNOR; /* Flash device type default type: Serial NOR */
|
|
config->memConfig.deviceModeType = kDeviceConfigCmdType_Generic;
|
|
config->memConfig.columnAddressWidth = 3U;
|
|
config->memConfig.deviceModeCfgEnable = 0U;
|
|
config->memConfig.waitTimeCfgCommands = 0U;
|
|
config->memConfig.configCmdEnable = 0U;
|
|
config->memConfig.busyOffset = 15U;
|
|
config->memConfig.busyBitPolarity = 1U;
|
|
/* Always enable Safe configuration Frequency */
|
|
config->memConfig.controllerMiscOption = FSL_ROM_FLEXSPI_BITMASK(kFLEXSPIMiscOffset_DiffClkEnable) |
|
|
FSL_ROM_FLEXSPI_BITMASK(kFLEXSPIMiscOffset_WordAddressableEnable) |
|
|
FSL_ROM_FLEXSPI_BITMASK(kFLEXSPIMiscOffset_SafeConfigFreqEnable) |
|
|
FSL_ROM_FLEXSPI_BITMASK(kFLEXSPIMiscOffset_DdrModeEnable);
|
|
config->memConfig.sflashPadType = kSerialFlash_8Pads; /* Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal */
|
|
config->pageSize = FLASH_PAGE_SIZE;
|
|
config->sectorSize = FLASH_SECTOR_SIZE;
|
|
config->blockSize = FLASH_BLOCK_SIZE;
|
|
config->isUniformBlockSize = true;
|
|
config->ipcmdSerialClkFreq = kFLEXSPISerialClk_30MHz; /* Clock frequency for IP command */
|
|
config->serialNorType = kSerialNorType_HyperBus;
|
|
|
|
// Read
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_READ + 0U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0xA0U, RADDR_DDR, FLEXSPI_8PAD, 0x18U);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_READ + 1U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CADDR_DDR, FLEXSPI_8PAD, 0x10U, DUMMY_DDR, FLEXSPI_8PAD, 0x06U);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_READ + 2U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(READ_DDR, FLEXSPI_8PAD, 0x04U, STOP, FLEXSPI_1PAD, 0x0U);
|
|
|
|
// Read Status
|
|
// 0
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_READSTATUS] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0x00U);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_READSTATUS + 1U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0xAAU);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_READSTATUS + 2U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0x05U);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_READSTATUS + 3U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0x70U);
|
|
// 1
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_READSTATUS + 4U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0xA0U, RADDR_DDR, FLEXSPI_8PAD, 0x18U);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_READSTATUS + 5U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CADDR_DDR, FLEXSPI_8PAD, 0x10U, DUMMY_RWDS_DDR, FLEXSPI_8PAD, 0x0BU);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_READSTATUS + 6U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(READ_DDR, FLEXSPI_8PAD, 0x04U, STOP, FLEXSPI_1PAD, 0x00U);
|
|
|
|
// Write Enable
|
|
// 0
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_WRITEENABLE] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0x00U);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_WRITEENABLE + 1U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0xAAU);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_WRITEENABLE + 2U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0x05U);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_WRITEENABLE + 3U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0xAAU);
|
|
// 1
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_WRITEENABLE + 4U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0x00U);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_WRITEENABLE + 5U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0x55U);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_WRITEENABLE + 6U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0x02U);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_WRITEENABLE + 7U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0x55U);
|
|
|
|
// Page Program
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0x00U);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 1U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0xAAU);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 2U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0x05U);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 3U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0xA0U);
|
|
// 1
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 4U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, RADDR_DDR, FLEXSPI_8PAD, 0x18U);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 5U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CADDR_DDR, FLEXSPI_8PAD, 0x10U, WRITE_DDR, FLEXSPI_8PAD, 0x80U);
|
|
|
|
// Erase Sector
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0x00U);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR + 1U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0xAAU);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR + 2U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0x05U);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR + 3U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0x80U);
|
|
// 1
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR + 4U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0x00U);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR + 5U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0xAAU);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR + 6U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0x05U);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR + 7U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0xAAU);
|
|
// 2
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR + 8U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0x00U);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR + 9U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0x55U);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR + 10U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0x02U);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR + 11U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, CMD_DDR, FLEXSPI_8PAD, 0x55U);
|
|
// 3
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR + 12U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00U, RADDR_DDR, FLEXSPI_8PAD, 0x18U);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR + 13U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CADDR_DDR, FLEXSPI_8PAD, 0x10U, CMD_DDR, FLEXSPI_8PAD, 0x00U);
|
|
config->memConfig.lookupTable[4U * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR + 14U] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x30U, STOP, FLEXSPI_1PAD, 0x0U);
|
|
|
|
// Erase Chip
|
|
config->memConfig.lookupTable[4 * NOR_CMD_LUT_SEQ_IDX_CHIPERASE] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00, CMD_DDR, FLEXSPI_8PAD, 0x00);
|
|
config->memConfig.lookupTable[4 * NOR_CMD_LUT_SEQ_IDX_CHIPERASE + 1] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00, CMD_DDR, FLEXSPI_8PAD, 0xAA);
|
|
config->memConfig.lookupTable[4 * NOR_CMD_LUT_SEQ_IDX_CHIPERASE + 2] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00, CMD_DDR, FLEXSPI_8PAD, 0x05);
|
|
config->memConfig.lookupTable[4 * NOR_CMD_LUT_SEQ_IDX_CHIPERASE + 3] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00, CMD_DDR, FLEXSPI_8PAD, 0x80);
|
|
// 1
|
|
config->memConfig.lookupTable[4 * NOR_CMD_LUT_SEQ_IDX_CHIPERASE + 4] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00, CMD_DDR, FLEXSPI_8PAD, 0x00);
|
|
config->memConfig.lookupTable[4 * NOR_CMD_LUT_SEQ_IDX_CHIPERASE + 5] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00, CMD_DDR, FLEXSPI_8PAD, 0xAA);
|
|
config->memConfig.lookupTable[4 * NOR_CMD_LUT_SEQ_IDX_CHIPERASE + 6] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00, CMD_DDR, FLEXSPI_8PAD, 0x05);
|
|
config->memConfig.lookupTable[4 * NOR_CMD_LUT_SEQ_IDX_CHIPERASE + 7] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00, CMD_DDR, FLEXSPI_8PAD, 0xAA);
|
|
// 2
|
|
config->memConfig.lookupTable[4 * NOR_CMD_LUT_SEQ_IDX_CHIPERASE + 8] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00, CMD_DDR, FLEXSPI_8PAD, 0x00);
|
|
config->memConfig.lookupTable[4 * NOR_CMD_LUT_SEQ_IDX_CHIPERASE + 9] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00, CMD_DDR, FLEXSPI_8PAD, 0x55);
|
|
config->memConfig.lookupTable[4 * NOR_CMD_LUT_SEQ_IDX_CHIPERASE + 10] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00, CMD_DDR, FLEXSPI_8PAD, 0x02);
|
|
config->memConfig.lookupTable[4 * NOR_CMD_LUT_SEQ_IDX_CHIPERASE + 11] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00, CMD_DDR, FLEXSPI_8PAD, 0x55);
|
|
// 3
|
|
config->memConfig.lookupTable[4 * NOR_CMD_LUT_SEQ_IDX_CHIPERASE + 12] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00, CMD_DDR, FLEXSPI_8PAD, 0x00);
|
|
config->memConfig.lookupTable[4 * NOR_CMD_LUT_SEQ_IDX_CHIPERASE + 13] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00, CMD_DDR, FLEXSPI_8PAD, 0xAA);
|
|
config->memConfig.lookupTable[4 * NOR_CMD_LUT_SEQ_IDX_CHIPERASE + 14] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00, CMD_DDR, FLEXSPI_8PAD, 0x05);
|
|
config->memConfig.lookupTable[4 * NOR_CMD_LUT_SEQ_IDX_CHIPERASE + 15] =
|
|
FSL_ROM_FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x00, CMD_DDR, FLEXSPI_8PAD, 0x10);
|
|
|
|
// LUT customized sequence
|
|
config->memConfig.lutCustomSeq[NOR_CMD_INDEX_WRITEENABLE].seqNum = 2U;
|
|
config->memConfig.lutCustomSeq[NOR_CMD_INDEX_WRITEENABLE].seqId = NOR_CMD_LUT_SEQ_IDX_WRITEENABLE;
|
|
config->memConfig.lutCustomSeq[NOR_CMD_INDEX_READSTATUS].seqNum = 2U;
|
|
config->memConfig.lutCustomSeq[NOR_CMD_INDEX_READSTATUS].seqId = NOR_CMD_LUT_SEQ_IDX_READSTATUS;
|
|
config->memConfig.lutCustomSeq[NOR_CMD_INDEX_PAGEPROGRAM].seqNum = 2U;
|
|
config->memConfig.lutCustomSeq[NOR_CMD_INDEX_PAGEPROGRAM].seqId = NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM;
|
|
config->memConfig.lutCustomSeq[NOR_CMD_INDEX_ERASESECTOR].seqNum = 4U;
|
|
config->memConfig.lutCustomSeq[NOR_CMD_INDEX_ERASESECTOR].seqId = NOR_CMD_LUT_SEQ_IDX_ERASESECTOR;
|
|
config->memConfig.lutCustomSeq[NOR_CMD_INDEX_CHIPERASE].seqNum = 4U;
|
|
config->memConfig.lutCustomSeq[NOR_CMD_INDEX_CHIPERASE].seqId = NOR_CMD_LUT_SEQ_IDX_CHIPERASE;
|
|
}
|
|
#if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1))
|
|
/* Configure clock for FlexSPI peripheral */
|
|
void BOARD_SetupFlexSpiClock(void)
|
|
{
|
|
/* Disable FlexSPI peripheral */
|
|
FLEXSPI->MCR0 |= FLEXSPI_MCR0_MDIS_MASK;
|
|
CLOCK_DisableClock(kCLOCK_FlexSpi);
|
|
|
|
/* Init Usb1 PLL3 to 480MHZ. */
|
|
CLOCK_InitUsb1Pll(&usb1PllConfig_BOARD_BootClockRUN);
|
|
/* Init Usb1 PLL3->pfd0 360MHZ. */
|
|
CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 24);
|
|
/* Enable Usb1 PLL output for USBPHY1. */
|
|
CCM_ANALOG->PLL_USB1 |= CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK;
|
|
|
|
/* Set FLEXSPI_PODF, FlexSPI out clock is 60MHZ. */
|
|
CLOCK_SetDiv(kCLOCK_FlexspiDiv, 5);
|
|
/* Set flexspi clock source to PLL3->pfd0 */
|
|
CLOCK_SetMux(kCLOCK_FlexspiMux, 3);
|
|
|
|
CLOCK_EnableClock(kCLOCK_FlexSpi);
|
|
/* Enable FlexSPI peripheral */
|
|
FLEXSPI->MCR0 &= ~FLEXSPI_MCR0_MDIS_MASK;
|
|
}
|
|
#endif
|
|
|
|
|
|
/*
|
|
* @brief Gets called when an error occurs.
|
|
*
|
|
* @details Print error message and trap forever.
|
|
*/
|
|
void error_trap(void)
|
|
{
|
|
PRINTF("\r\n\r\n\r\n\t---- HALTED DUE TO FLEXSPI NOR ERROR! ----");
|
|
while (1)
|
|
{
|
|
}
|
|
}
|
|
|
|
/*
|
|
* @brief Gets called when the app is complete.
|
|
*
|
|
* @details Print finshed message and trap forever.
|
|
*/
|
|
void app_finalize(void)
|
|
{
|
|
/* Print finished message. */
|
|
PRINTF("\r\n End of FLEXSPI NOR Example! \r\n");
|
|
while (1)
|
|
{
|
|
}
|
|
}
|
|
|
|
void get_cache_status(flexspi_cache_status_t *cacheStatus)
|
|
{
|
|
if (SCB_CCR_DC_Msk == (SCB_CCR_DC_Msk & SCB->CCR))
|
|
{
|
|
cacheStatus->DCacheEnableFlag = true;
|
|
}
|
|
else
|
|
{
|
|
cacheStatus->DCacheEnableFlag = false;
|
|
}
|
|
|
|
if (SCB_CCR_IC_Msk == (SCB_CCR_IC_Msk & SCB->CCR))
|
|
{
|
|
cacheStatus->ICacheEnableFlag = true;
|
|
}
|
|
else
|
|
{
|
|
cacheStatus->ICacheEnableFlag = false;
|
|
}
|
|
}
|
|
|
|
void flexspi_nor_handle_cache(bool isPre, flexspi_cache_status_t cacheStatus)
|
|
{
|
|
if (isPre)
|
|
{
|
|
if (cacheStatus.DCacheEnableFlag == true)
|
|
{
|
|
SCB_DisableDCache();
|
|
}
|
|
else
|
|
{
|
|
; /* Do nothing */
|
|
}
|
|
|
|
if (cacheStatus.ICacheEnableFlag == true)
|
|
{
|
|
SCB_DisableICache();
|
|
}
|
|
else
|
|
{
|
|
; /* Do nothing */
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (cacheStatus.DCacheEnableFlag == true)
|
|
{
|
|
SCB_EnableDCache();
|
|
}
|
|
else
|
|
{
|
|
; /* Do nothing */
|
|
}
|
|
|
|
if (cacheStatus.ICacheEnableFlag == true)
|
|
{
|
|
SCB_EnableICache();
|
|
}
|
|
else
|
|
{
|
|
; /* Do nothing */
|
|
}
|
|
}
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
status_t status;
|
|
uint32_t i = 0U;
|
|
uint32_t serialNorAddress; /* Address of the serial nor device location */
|
|
uint32_t FlexSPISerialNorAddress; /* Address of the serial nor device in FLEXSPI memory */
|
|
uint32_t serialNorTotalSize;
|
|
uint32_t serialNorSectorSize;
|
|
uint32_t serialNorPageSize;
|
|
|
|
BOARD_ConfigMPU();
|
|
BOARD_InitBootPins();
|
|
BOARD_InitBootClocks();
|
|
#if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1))
|
|
BOARD_SetupFlexSpiClock();
|
|
#endif
|
|
BOARD_InitDebugConsole();
|
|
|
|
PRINTF("\r\n FLEXSPI NOR example started!\r\n");
|
|
|
|
flexspi_cache_status_t cacheStatus;
|
|
get_cache_status(&cacheStatus);
|
|
|
|
/* Clean up FLEXSPI NOR flash driver Structure */
|
|
memset(&norConfig, 0, sizeof(flexspi_nor_config_t));
|
|
|
|
/* Setup FLEXSPI NOR Configuration Block */
|
|
FLEXSPI_NorFlash_GetConfig(&norConfig);
|
|
|
|
/* Disable I cache and D cache before invoking ROM APIs. */
|
|
flexspi_nor_handle_cache(true, cacheStatus);
|
|
/* Initializes the FLEXSPI module for the other FLEXSPI APIs */
|
|
status = ROM_FLEXSPI_NorFlash_Init(FlexSpiInstance, &norConfig);
|
|
flexspi_nor_handle_cache(false, cacheStatus);
|
|
if (status == kStatus_Success)
|
|
{
|
|
PRINTF("\r\n Successfully init FLEXSPI serial NOR flash\r\n ");
|
|
}
|
|
else
|
|
{
|
|
PRINTF("\r\n Erase sector failure !\r\n");
|
|
error_trap();
|
|
}
|
|
|
|
/* Perform software reset after initializing flexspi module */
|
|
ROM_FLEXSPI_NorFlash_ClearCache(FlexSpiInstance);
|
|
|
|
#if !defined(XIP_EXTERNAL_FLASH) || (XIP_EXTERNAL_FLASH != 1)
|
|
/* Read ID-CFI Parameters */
|
|
status = FLEXSPI_NorFlash_VerifyID(FlexSpiInstance);
|
|
if (status == kStatus_Success)
|
|
{
|
|
PRINTF("\r\n HyperFlash has been found successfully\r\n ");
|
|
}
|
|
else
|
|
{
|
|
PRINTF("\r\n HyperFlash can not be found!\r\n");
|
|
error_trap();
|
|
}
|
|
#endif // XIP_EXTERNAL_FLASH
|
|
|
|
serialNorTotalSize = norConfig.memConfig.sflashA1Size;
|
|
serialNorSectorSize = norConfig.sectorSize;
|
|
serialNorPageSize = norConfig.pageSize;
|
|
|
|
/* Print HyperFlash information */
|
|
PRINTF("\r\n HyperFlash Information: ");
|
|
PRINTF("\r\n Total program flash size:\t%d KB, Hex: (0x%x)", (serialNorTotalSize / 1024U), serialNorTotalSize);
|
|
PRINTF("\r\n Program flash sector size:\t%d KB, Hex: (0x%x) ", (serialNorSectorSize / 1024U), serialNorSectorSize);
|
|
PRINTF("\r\n Program flash page size:\t%d B, Hex: (0x%x)\r\n", serialNorPageSize, serialNorPageSize);
|
|
|
|
/*
|
|
* SECTOR_INDEX_FROM_END = 1 means the last sector,
|
|
* SECTOR_INDEX_FROM_END = 2 means (the last sector - 1) ...
|
|
*/
|
|
#ifndef SECTOR_INDEX_FROM_END
|
|
#define SECTOR_INDEX_FROM_END 1U
|
|
#endif
|
|
/* Erase a sector from target device dest address */
|
|
serialNorAddress = serialNorTotalSize - (SECTOR_INDEX_FROM_END * serialNorSectorSize);
|
|
FlexSPISerialNorAddress = EXAMPLE_FLEXSPI_AMBA_BASE + serialNorAddress;
|
|
|
|
/* Erase one sector. */
|
|
PRINTF("\r\n Erasing serial NOR flash over FLEXSPI");
|
|
flexspi_nor_handle_cache(true, cacheStatus);
|
|
status = ROM_FLEXSPI_NorFlash_Erase(FlexSpiInstance, &norConfig, serialNorAddress, serialNorSectorSize);
|
|
flexspi_nor_handle_cache(false, cacheStatus);
|
|
if (status == kStatus_Success)
|
|
{
|
|
/* Print message for user. */
|
|
PRINTF("\r\n Successfully erased one sector of NOR flash device 0x%x -> 0x%x\r\n", serialNorAddress,
|
|
(serialNorAddress + serialNorSectorSize));
|
|
}
|
|
else
|
|
{
|
|
PRINTF("\r\n Erase sector failure!\r\n");
|
|
error_trap();
|
|
}
|
|
|
|
PRINTF("\r\n Program a buffer to a page of NOR flash");
|
|
/* Prepare user buffer. */
|
|
for (i = 0; i < BUFFER_LEN; i++)
|
|
{
|
|
s_buffer[i] = i;
|
|
}
|
|
|
|
/* Program user buffer into FLEXSPI NOR flash */
|
|
status =
|
|
ROM_FLEXSPI_NorFlash_ProgramPage(FlexSpiInstance, &norConfig, serialNorAddress, (const uint32_t *)s_buffer);
|
|
if (status != kStatus_Success)
|
|
{
|
|
PRINTF("\r\n Page program failure!\r\n");
|
|
error_trap();
|
|
}
|
|
|
|
DCACHE_InvalidateByRange(FlexSPISerialNorAddress, sizeof(s_buffer_rbc));
|
|
/* Verify programming by reading back from FLEXSPI memory directly */
|
|
memcpy(s_buffer_rbc, (void *)(FlexSPISerialNorAddress), sizeof(s_buffer_rbc));
|
|
if (memcmp(s_buffer_rbc, s_buffer, sizeof(s_buffer)) == 0)
|
|
{
|
|
PRINTF("\r\n Successfully programmed and verified location FLEXSPI memory 0x%x -> 0x%x \r\n",
|
|
(FlexSPISerialNorAddress), (FlexSPISerialNorAddress + sizeof(s_buffer)));
|
|
}
|
|
else
|
|
{
|
|
PRINTF("\r\n Program data - read out data value incorrect!\r\n ");
|
|
error_trap();
|
|
}
|
|
|
|
/* Erase the context we have progeammed before*/
|
|
status = ROM_FLEXSPI_NorFlash_Erase(FlexSpiInstance, &norConfig, serialNorAddress, serialNorSectorSize);
|
|
|
|
app_finalize();
|
|
|
|
return 0;
|
|
}
|