MCUXpresso_MIMXRT1052xxxxB/components/internal_flash/hyper_flash/fsl_adapter_flexspi_hyper_n...

1008 lines
36 KiB
C

/*
* Copyright 2020 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*!*********************************************************************************
*************************************************************************************
* Include
*************************************************************************************
********************************************************************************** */
#include "fsl_common.h"
#include "fsl_flexspi.h"
#include "fsl_adapter_flexspi_hyper_flash_config.h"
#include "fsl_adapter_flash.h"
/*****************************************************************************
*****************************************************************************
* Private macros
*****************************************************************************
*****************************************************************************/
#define HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA 0
#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA 1
#define HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS 2
#define HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE 4
#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR 6
#define HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM 10
#define HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP 12
#define CUSTOM_LUT_LENGTH 64
#ifndef CACHE_MAINTAIN
#define CACHE_MAINTAIN 0x01U
#endif
#ifndef EXAMPLE_BOOT_FLEXSPI
#define EXAMPLE_BOOT_FLEXSPI FLEXSPI
#endif
#ifndef FLASH_ADAPTER_SIZE
#define FLASH_ADAPTER_SIZE 0x10000U /* 64*1024 Kbyte */
#endif
#define FLASH_PAGE_SIZE 512U
#define SECTOR_SIZE 0x40000U /* 4K */
#ifdef APP_FLEXSPI_AMBA_BASE
#define FLEXSPI_AMBA_BASE APP_FLEXSPI_AMBA_BASE
#elif defined(FlexSPI1_AMBA_BASE)
#define FLEXSPI_AMBA_BASE FlexSPI1_AMBA_BASE
#elif defined(FlexSPI_AMBA_BASE)
#define FLEXSPI_AMBA_BASE FlexSPI_AMBA_BASE
#else
#error Unsupported flash case
#endif
/* Weak function. */
#if defined(__GNUC__)
#define __WEAK_FUNC __attribute__((weak))
#elif defined(__ICCARM__)
#define __WEAK_FUNC __weak
#elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
#define __WEAK_FUNC __attribute__((weak))
#endif
/*!*********************************************************************************
*************************************************************************************
* Private type definitions
*************************************************************************************
********************************************************************************** */
/*!*********************************************************************************
*************************************************************************************
* Private prototypes
*************************************************************************************
********************************************************************************** */
/*!*********************************************************************************
*************************************************************************************
* Public memory declarations
*************************************************************************************
********************************************************************************** */
static FLEXSPI_Type *s_flexspiBase[] = FLEXSPI_BASE_PTRS;
flexspi_device_config_t s_deviceconfig = {
.flexspiRootClk = 42000000, /* 42MHZ SPI serial clock */
.isSck2Enabled = false,
.flashSize = FLASH_ADAPTER_SIZE,
.CSIntervalUnit = kFLEXSPI_CsIntervalUnit1SckCycle,
.CSInterval = 2,
.CSHoldTime = 0,
.CSSetupTime = 3,
.dataValidTime = 1,
.columnspace = 3,
.enableWordAddress = true,
.AWRSeqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA,
.AWRSeqNumber = 1,
.ARDSeqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA,
.ARDSeqNumber = 1,
.AHBWriteWaitUnit = kFLEXSPI_AhbWriteWaitUnit2AhbCycle,
.AHBWriteWaitInterval = 20,
};
const uint32_t customLUT[CUSTOM_LUT_LENGTH] = {
/* Read Data */
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA + 1] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04),
/* Write Data */
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA + 1] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x02),
/* Read Status */
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 1] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 2] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 3] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x70), // DATA 0x70
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 4] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 5] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DUMMY_RWDS_DDR, kFLEXSPI_8PAD, 0x0B),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS + 6] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0),
/* Write Enable */
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 1] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 2] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 3] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // DATA 0xAA
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 4] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 5] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 6] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE + 7] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55),
/* Erase Sector */
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 1] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 2] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 3] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80), // DATA 0x80
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 4] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 5] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 6] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 7] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 8] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 9] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 10] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 11] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 12] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 13] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR + 14] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x30, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00),
/* program page with word program command sequence */
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 1] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA), // ADDR 0x555
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 2] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 3] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0), // DATA 0xA0
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 4] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM + 5] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x80),
/* Erase chip */
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 1] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 2] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 3] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x80),
// 1
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 4] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 5] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 6] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 7] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA),
// 2
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 8] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 9] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 10] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x02),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 11] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x55),
// 3
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 12] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 13] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xAA),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 14] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x05),
[4 * HYPERFLASH_CMD_LUT_SEQ_IDX_ERASECHIP + 15] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x10),
};
/*****************************************************************************
*****************************************************************************
* Private functions
*****************************************************************************
*****************************************************************************/
__WEAK_FUNC void flexspi_clock_update(flexspi_clock_t clockSelect, FLEXSPI_Type *base);
__WEAK_FUNC uint32_t flexspi_get_frequency(void);
__WEAK_FUNC void flexspi_clock_init(void);
__WEAK_FUNC void flexspi_clock_update(flexspi_clock_t clockSelect, FLEXSPI_Type *base){};
__WEAK_FUNC uint32_t flexspi_get_frequency(void)
{
return 0;
}
__WEAK_FUNC void flexspi_clock_init(void)
{
}
void flexspi_delay(void)
{
for (uint32_t i = 0; i < SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY / 1000000; i++)
{
__asm("nop");
}
}
static status_t flexspi_nor_write_enable(FLEXSPI_Type *base, uint32_t baseAddr)
{
flexspi_transfer_t flashXfer;
status_t status;
/* Write enable */
/* Write neable */
flashXfer.deviceAddress = baseAddr;
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Command;
flashXfer.SeqNumber = 2;
flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE;
status = FLEXSPI_TransferBlocking(base, &flashXfer);
return status;
}
status_t flexspi_nor_hyperbus_read(FLEXSPI_Type *base, uint32_t addr, uint32_t *buffer, uint32_t bytes)
{
flexspi_transfer_t flashXfer;
status_t status;
#if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
bool ICacheEnableFlag = false;
/* Disable I cache. */
if (SCB_CCR_IC_Msk == (SCB_CCR_IC_Msk & SCB->CCR))
{
SCB_DisableICache();
ICacheEnableFlag = true;
}
#endif /* __ICACHE_PRESENT */
#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
bool DCacheEnableFlag = false;
/* Disable D cache. */
if (SCB_CCR_DC_Msk == (SCB_CCR_DC_Msk & SCB->CCR))
{
SCB_DisableDCache();
DCacheEnableFlag = true;
}
#endif /* __DCACHE_PRESENT */
flashXfer.deviceAddress = addr * 2;
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Read;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_READDATA;
flashXfer.data = buffer;
flashXfer.dataSize = bytes;
status = FLEXSPI_TransferBlocking(base, &flashXfer);
#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
if (DCacheEnableFlag)
{
/* Enable D cache. */
SCB_EnableDCache();
}
#endif /* __DCACHE_PRESENT */
#if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
if (ICacheEnableFlag)
{
/* Enable I cache. */
SCB_EnableICache();
}
#endif /* __ICACHE_PRESENT */
if (status != kStatus_Success)
{
return status;
}
return status;
}
status_t flexspi_nor_hyperbus_write(FLEXSPI_Type *base, uint32_t addr, uint32_t *buffer, uint32_t bytes)
{
flexspi_transfer_t flashXfer;
status_t status;
#if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
bool ICacheEnableFlag = false;
/* Disable I cache. */
if (SCB_CCR_IC_Msk == (SCB_CCR_IC_Msk & SCB->CCR))
{
SCB_DisableICache();
ICacheEnableFlag = true;
}
#endif /* __ICACHE_PRESENT */
#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
bool DCacheEnableFlag = false;
/* Disable D cache. */
if (SCB_CCR_DC_Msk == (SCB_CCR_DC_Msk & SCB->CCR))
{
SCB_DisableDCache();
DCacheEnableFlag = true;
}
#endif /* __DCACHE_PRESENT */
flashXfer.deviceAddress = addr * 2;
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Write;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA;
flashXfer.data = buffer;
flashXfer.dataSize = bytes;
status = FLEXSPI_TransferBlocking(base, &flashXfer);
#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
if (DCacheEnableFlag)
{
/* Enable D cache. */
SCB_EnableDCache();
}
#endif /* __DCACHE_PRESENT */
#if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
if (ICacheEnableFlag)
{
/* Enable I cache. */
SCB_EnableICache();
}
#endif /* __ICACHE_PRESENT */
if (status != kStatus_Success)
{
return status;
}
return status;
}
static status_t flexspi_nor_wait_bus_busy(FLEXSPI_Type *base)
{
/* Wait status ready. */
bool isBusy;
uint32_t readValue;
status_t status;
flexspi_transfer_t flashXfer;
flashXfer.deviceAddress = 0;
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Read;
flashXfer.SeqNumber = 2;
flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS;
flashXfer.data = &readValue;
flashXfer.dataSize = 2;
do
{
status = FLEXSPI_TransferBlocking(base, &flashXfer);
if (status != kStatus_Success)
{
return status;
}
if (readValue & 0x8000)
{
isBusy = false;
}
else
{
isBusy = true;
}
if (readValue & 0x3200)
{
status = kStatus_Fail;
break;
}
} while (isBusy);
return status;
}
status_t flexspi_nor_hyperflash_cfi(FLEXSPI_Type *base)
{
/*
* Read ID-CFI Parameters
*/
// CFI Entry
status_t status;
uint32_t buffer[2];
uint8_t data[4] = {0x00, 0x98};
status = flexspi_nor_hyperbus_write(base, 0x555, (uint32_t *)data, 2);
if (status != kStatus_Success)
{
return status;
}
// ID-CFI Read
// Read Query Unique ASCII String
status = flexspi_nor_hyperbus_read(base, 0x10, &buffer[0], sizeof(buffer));
if (status != kStatus_Success)
{
return status;
}
buffer[1] &= 0xFFFF;
// Check that the data read out is unicode "QRY" in big-endian order
if ((buffer[0] != 0x52005100) || (buffer[1] != 0x5900))
{
status = kStatus_Fail;
return status;
}
// ASO Exit 0xF000
data[1] = 0xF0;
status = flexspi_nor_hyperbus_write(base, 0x0, (uint32_t *)data, 2);
if (status != kStatus_Success)
{
return status;
}
/* Do software reset. */
FLEXSPI_SoftwareReset(base);
return status;
}
/*!*********************************************************************************
*************************************************************************************
* Public functions
*************************************************************************************
********************************************************************************** */
/*!
* @brief Initializes the global flash properties structure members.
*
* This function initializes the Flash module for the other Flash APIs.
*
*
* @retval #kStatus_HAL_Flash_Success API was executed successfully.
* @retval #kStatus_HAL_Flash_InvalidArgument An invalid argument is provided.
* @retval #kStatus_HAL_Flash_ExecuteInRamFunctionNotReady Execute-in-RAM function is not available.
* @retval #kStatus_HAL_Flash_PartitionStatusUpdateFailure Failed to update the partition status.
*/
hal_flash_status_t HAL_FlashInit(void)
{
FLEXSPI_Type *base;
flexspi_config_t config;
uint32_t key;
#if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
bool ICacheEnableFlag = false;
/* Disable I cache. */
if (SCB_CCR_IC_Msk == (SCB_CCR_IC_Msk & SCB->CCR))
{
SCB_DisableICache();
ICacheEnableFlag = true;
}
#endif /* __ICACHE_PRESENT */
#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
bool DCacheEnableFlag = false;
/* Disable D cache. */
if (SCB_CCR_DC_Msk == (SCB_CCR_DC_Msk & SCB->CCR))
{
SCB_DisableDCache();
DCacheEnableFlag = true;
}
#endif /* __DCACHE_PRESENT */
key = DisableGlobalIRQ();
base = NULL;
for (uint8_t i = 0; i < (sizeof(s_flexspiBase) / sizeof(FLEXSPI_Type *)); i++)
{
if (NULL != s_flexspiBase[i])
{
base = s_flexspiBase[i];
break;
}
}
if (NULL == base)
{
return kStatus_HAL_Flash_Fail;
}
#if defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)
if (EXAMPLE_BOOT_FLEXSPI == base)
{
/* Wait for bus to be idle before changing flash configuration. */
while (false == FLEXSPI_GetBusIdleStatus(base))
{
}
}
#endif
flexspi_clock_init();
/*Get FLEXSPI default settings and configure the flexspi. */
FLEXSPI_GetDefaultConfig(&config);
/*Set AHB buffer size for reading data through AHB bus. */
config.ahbConfig.enableAHBPrefetch = true;
/*Allow AHB read start address do not follow the alignment requirement. */
config.ahbConfig.enableReadAddressOpt = true;
config.ahbConfig.enableAHBBufferable = true;
config.ahbConfig.enableAHBCachable = true;
/* enable diff clock and DQS */
config.enableSckBDiffOpt = true;
config.rxSampleClock = kFLEXSPI_ReadSampleClkExternalInputFromDqsPad;
#if !(defined(FSL_FEATURE_FLEXSPI_HAS_NO_MCR0_COMBINATIONEN) && FSL_FEATURE_FLEXSPI_HAS_NO_MCR0_COMBINATIONEN)
config.enableCombination = true;
#endif
FLEXSPI_Init(base, &config);
/* Set flexspi root clock. */
s_deviceconfig.flexspiRootClk = flexspi_get_frequency();
/* Configure flash settings according to serial flash feature. */
FLEXSPI_SetFlashConfig(base, &s_deviceconfig, kFLEXSPI_PortA1);
/* Update LUT table. */
FLEXSPI_UpdateLUT(base, 0, customLUT, CUSTOM_LUT_LENGTH);
/* Do software reset. */
FLEXSPI_SoftwareReset(base);
EnableGlobalIRQ(key);
#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
if (DCacheEnableFlag)
{
/* Enable D cache. */
SCB_EnableDCache();
}
#endif /* __DCACHE_PRESENT */
#if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
if (ICacheEnableFlag)
{
/* Enable I cache. */
SCB_EnableICache();
}
#endif /* __ICACHE_PRESENT */
flexspi_nor_hyperflash_cfi(base);
return kStatus_HAL_Flash_Success;
}
/*!
* \brief Verify erase data in Flash
*
* @param start The address of the Flash location
* @param lengthInBytes The number of bytes to be checked
* @param margin Flash margin value
* @retval #kStatus_HAL_Flash_Success API was executed successfully.
*/
hal_flash_status_t HAL_FlashVerifyErase(uint32_t start, uint32_t lengthInBytes, hal_flash_margin_value_t margin)
{
hal_flash_status_t state;
uint32_t address;
uint32_t value;
(void)margin;
if (start < FLEXSPI_AMBA_BASE)
{
return kStatus_HAL_Flash_Fail;
}
address = start;
while (address < (start + lengthInBytes))
{
value = 0U;
if ((address + sizeof(uint32_t)) < (start + lengthInBytes))
{
state = HAL_FlashRead(address, sizeof(uint32_t), (uint8_t *)&value);
if (0xffffffffUL != value)
{
return kStatus_HAL_Flash_Fail;
}
address += sizeof(uint32_t);
}
else
{
state = HAL_FlashRead(address, 1, (uint8_t *)&value);
if (0xffU != value)
{
return kStatus_HAL_Flash_Fail;
}
address++;
}
if (kStatus_HAL_Flash_Success != state)
{
return kStatus_HAL_Flash_Fail;
}
}
return kStatus_HAL_Flash_Success;
}
/*!
* \brief Write alligned data to FLASH
*
* @param dest The address of the Flash location
* @param size The number of bytes to be programed
* @param pData Pointer to the data to be programmed to Flash
*
* @retval #kStatus_HAL_Flash_Success API was executed successfully.
*
*/
hal_flash_status_t HAL_FlashProgram(uint32_t dest, uint32_t size, uint8_t *pData)
{
FLEXSPI_Type *base;
uint32_t address;
uint32_t writeLength;
status_t status = (status_t)kStatus_HAL_Flash_Error;
flexspi_transfer_t flashXfer;
uint32_t key;
flexspi_clock_t frequency;
#if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
bool ICacheEnableFlag = false;
/* Disable I cache. */
if (SCB_CCR_IC_Msk == (SCB_CCR_IC_Msk & SCB->CCR))
{
SCB_DisableICache();
ICacheEnableFlag = true;
}
#endif /* __ICACHE_PRESENT */
#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
bool DCacheEnableFlag = false;
/* Disable D cache. */
if (SCB_CCR_DC_Msk == (SCB_CCR_DC_Msk & SCB->CCR))
{
SCB_DisableDCache();
DCacheEnableFlag = true;
}
#endif /* __DCACHE_PRESENT */
if (dest < FLEXSPI_AMBA_BASE)
{
return kStatus_HAL_Flash_Fail;
}
dest = dest - FLEXSPI_AMBA_BASE;
base = NULL;
for (uint8_t i = 0; i < (sizeof(s_flexspiBase) / sizeof(FLEXSPI_Type *)); i++)
{
if (NULL != s_flexspiBase[i])
{
base = s_flexspiBase[i];
break;
}
}
if (NULL == base)
{
return kStatus_HAL_Flash_Fail;
}
address = dest;
while (address < (dest + size))
{
if (0U != (address & ((FLASH_PAGE_SIZE - 1U))))
{
writeLength = address - (address & (~(FLASH_PAGE_SIZE - 1U)));
writeLength = FLASH_PAGE_SIZE - writeLength;
if ((dest + size - address) < writeLength)
{
writeLength = (dest + size - address);
}
}
else
{
writeLength = dest + size - address;
}
if (writeLength > FLASH_PAGE_SIZE)
{
writeLength = FLASH_PAGE_SIZE;
}
key = DisableGlobalIRQ();
/* Write enable */
if (address == 0x3dc0000)
{
// memcpy(&s_hyperflash_program_buffer[0], pData, size);
}
__DSB();
// DCACHE_CleanByRange(&s_hyperflash_program_buffer[0], size);
/* Speed down flexspi clock, beacuse 50 MHz timings are only relevant when a burst write is used to load data
* during a HyperFlash Word Program command. */
frequency = kHAL_Flash_Flexspi_Clock_Low42M;
flexspi_clock_update(frequency, base);
/* Get current flexspi root clock. */
s_deviceconfig.flexspiRootClk = flexspi_get_frequency();
/* Update DLL value depending on flexspi root clock. */
FLEXSPI_UpdateDllValue(base, &s_deviceconfig, kFLEXSPI_PortA1);
/* Do software reset. */
FLEXSPI_SoftwareReset(base);
status = flexspi_nor_write_enable(base, address);
if (status != kStatus_Success)
{
EnableGlobalIRQ(key);
break;
}
flashXfer.deviceAddress = address;
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Write;
flashXfer.SeqNumber = 2;
flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM;
flashXfer.data = (uint32_t *)((void *)(&pData[address - dest]));
flashXfer.dataSize = writeLength;
status = FLEXSPI_TransferBlocking(base, &flashXfer);
if (status != kStatus_Success)
{
EnableGlobalIRQ(key);
break;
}
status = flexspi_nor_wait_bus_busy(base);
if (status != kStatus_Success)
{
EnableGlobalIRQ(key);
break;
}
address += writeLength;
/* Speed up flexspi clock for a high read performance. */
frequency = kHAL_Flash_Flexspi_Clock_High166M;
flexspi_clock_update(frequency, base);
/* Get current flexspi root clock. */
s_deviceconfig.flexspiRootClk = flexspi_get_frequency();
/* Update DLL value depending on flexspi root clock. */
FLEXSPI_UpdateDllValue(base, &s_deviceconfig, kFLEXSPI_PortA1);
FLEXSPI_SoftwareReset(base);
/*SDK_DelayAtLeastUs(2U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);*/
flexspi_delay();
EnableGlobalIRQ(key);
}
__DSB();
#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
if (DCacheEnableFlag)
{
/* Enable D cache. */
SCB_EnableDCache();
}
#endif /* __DCACHE_PRESENT */
#if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
if (ICacheEnableFlag)
{
/* Enable I cache. */
SCB_EnableICache();
}
#endif /* __ICACHE_PRESENT */
return (hal_flash_status_t)status;
}
/*!
* \brief Write data to FLASH
*
* @param dest The address of the Flash location
* @param size The number of bytes to be programed
* @param pData Pointer to the data to be programmed to Flash
*
* @retval #kStatus_HAL_Flash_Success API was executed successfully.
*
*/
hal_flash_status_t HAL_FlashProgramUnaligned(uint32_t dest, uint32_t size, uint8_t *pData)
{
return HAL_FlashProgram(dest, size, pData);
}
/*!
* \brief Erase to 0xFF one or more FLASH sectors.
*
* @param dest The start address of the first sector to be erased
* @param size The amount of flash to be erased (multiple of sector size)
*
* @retval #kStatus_HAL_Flash_Success API was executed successfully.
*
*/
hal_flash_status_t HAL_FlashEraseSector(uint32_t dest, uint32_t size)
{
FLEXSPI_Type *base;
uint32_t address;
status_t status = (status_t)kStatus_HAL_Flash_Error;
flexspi_transfer_t flashXfer;
uint32_t key;
if (dest < FLEXSPI_AMBA_BASE)
{
return kStatus_HAL_Flash_Fail;
}
#if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
bool ICacheEnableFlag = false;
/* Disable I cache. */
if (SCB_CCR_IC_Msk == (SCB_CCR_IC_Msk & SCB->CCR))
{
SCB_DisableICache();
ICacheEnableFlag = true;
}
#endif /* __ICACHE_PRESENT */
dest = dest - FLEXSPI_AMBA_BASE;
base = NULL;
for (uint8_t i = 0; i < (sizeof(s_flexspiBase) / sizeof(FLEXSPI_Type *)); i++)
{
if (NULL != s_flexspiBase[i])
{
base = s_flexspiBase[i];
break;
}
}
if (NULL == base)
{
return kStatus_HAL_Flash_Fail;
}
address = dest;
while (address < (dest + size))
{
/* Write enable */
status = flexspi_nor_write_enable(base, address);
if (status != kStatus_Success)
{
break;
}
flashXfer.deviceAddress = address;
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Command;
flashXfer.SeqNumber = 4;
flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR;
key = DisableGlobalIRQ();
status = FLEXSPI_TransferBlocking(base, &flashXfer);
if (status != kStatus_Success)
{
EnableGlobalIRQ(key);
break;
}
status = flexspi_nor_wait_bus_busy(base);
address += SECTOR_SIZE;
/* Do software reset. */
FLEXSPI_SoftwareReset(base);
/*SDK_DelayAtLeastUs(2U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);*/
flexspi_delay();
EnableGlobalIRQ(key);
}
if (status != kStatus_Success)
{
key = DisableGlobalIRQ();
/* Do software reset. */
FLEXSPI_SoftwareReset(base);
/*SDK_DelayAtLeastUs(2U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);*/
flexspi_delay();
EnableGlobalIRQ(key);
}
#if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
if (ICacheEnableFlag)
{
/* Enable I cache. */
SCB_EnableICache();
}
#endif /* __ICACHE_PRESENT */
return (hal_flash_status_t)status;
}
/*!
* \brief Read data from FLASH
*
*
* @param scr The address of the Flash location to be read
* @param size The number of bytes to be read
* @param pData Pointer to the data to be read from Flash
*
* @retval #kStatus_HAL_Flash_Success API was executed successfully.
*
*/
hal_flash_status_t HAL_FlashRead(uint32_t src, uint32_t size, uint8_t *pData)
{
#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
bool DCacheEnableFlag = false;
/* Disable D cache. */
if (SCB_CCR_DC_Msk == (SCB_CCR_DC_Msk & SCB->CCR))
{
SCB_DisableDCache();
DCacheEnableFlag = true;
}
#endif /* __DCACHE_PRESENT */
#if defined(CACHE_MAINTAIN) && CACHE_MAINTAIN
#endif
(void)memcpy(pData, (uint8_t *)src, size);
#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
if (DCacheEnableFlag)
{
/* Enable D cache. */
SCB_EnableDCache();
}
#endif /* __DCACHE_PRESENT */
return kStatus_HAL_Flash_Success;
}
/*!
* @brief Returns the desired hal flash property.
*
* @param Property The desired property from the list of properties in
* enum hal_flash_property_tag_t
* @param value A pointer to the value returned for the desired flash property.
*
* @retval #kStatus_HAL_Flash_Success API was executed successfully.
* @retval #kStatus_HAL_Flash_InvalidArgument An invalid argument is provided.
* @retval #kStatus_HAL_Flash_Success Flash currently not support.
*/
hal_flash_status_t HAL_FlashGetProperty(hal_flash_property_tag_t property, uint32_t *value)
{
return kStatus_HAL_Flash_Success;
}
/*!
* @brief Set the desired hal flash property.
*
* @param Property The desired property from the list of properties in
* enum hal_flash_property_tag_t
* @param value The value would be set to the desired flash property.
*
* @retval #kStatus_HAL_Flash_Success API was executed successfully.
* @retval #kStatus_HAL_Flash_InvalidArgument An invalid argument is provided.
* @retval #kStatus_HAL_Flash_Success Flash currently not support.
*/
hal_flash_status_t HAL_FlashSetProperty(hal_flash_property_tag_t property, uint32_t value)
{
return kStatus_HAL_Flash_Success;
}
/*!
* @brief Returns the security state via the pointer passed into the function.
*
* This function retrieves the current flash security status, including the
* security enabling state and the backdoor key enabling state.
*
* @param state A pointer to the value returned for the current security status
*
* @retval #kStatus_HAL_Flash_Success API was executed successfully.
* @retval #kStatus_HAL_Flash_InvalidArgument An invalid argument is provided.
* @retval #kStatus_HAL_Flash_Success Flash currently not support.
*/
hal_flash_status_t HAL_FlashGetSecurityState(hal_flash_security_state_t *state)
{
return kStatus_HAL_Flash_Success;
}