I am trying to interface MIMXRT1166 with octal flash IS25WX256, and I'm not sure about the correct setting of dummy cycles for the 0xFD (4-BYTE DDR OCTAL I/O FAST READ with DDR ADDRESS and DATA) command.
The FCB generated by MCUXpresso Secure Provisioning Tool uses 6 dummy cycles, whereas the flash datasheet specifies 16 dummy cycles as default. Both of these settings result in the board crashing after some time. I've tried different clocks and combinations of dummy cycles, all of which end up in a crash after a few minutes or an hour.
The FCB code is below:
/* Default dummy cycles for 0xFD read command. Max freq. of 162 MHz in Octal DDR mode */
#define DUMMY_CYCLES 16
const flexspi_nor_config_t
issi_flash_config =
{
.memConfig =
{
.tag = (0x42464346UL),
.version = (0x56010400UL),
.reserved0 = 0,
.readSampleClksrc=kFlexSPIReadSampleClk_ExternalInputFromDqsPad,
.csHoldTime = 3,
.csSetupTime = 3,
.columnAddressWidth = 0,
.deviceModeCfgEnable = 1, /* Device mode command enabled */
.deviceModeType = kDeviceConfigCmdType_Spi2Xpi,
.waitTimeCfgCommands = 1, /* If not zero, flexspi will wait instead of read status */
.deviceModeSeq =
{
.seqNum = 1U,
.seqId = 6U,
.reserved = 0U,
},
/* Only effective when deviceModeCfgEnable = 1 */
.deviceModeArg = 0xE7,
/* Enable flash configuration feature */
.configCmdEnable = 0,
.configModeType[0] = kDeviceConfigCmdType_Generic,
.configModeType[1] = kDeviceConfigCmdType_Generic,
.configModeType[2] = kDeviceConfigCmdType_Generic,
.configCmdSeqs[0] = {.seqNum = 1U, .seqId = 13U, .reserved = 0U}, /* cmd seq 0 Set dummy cycles */
.configCmdSeqs[1] = {.seqNum = 1U, .seqId = 10U, .reserved = 0U}, /* cmd seq 1 Enable XIP */
.configCmdSeqs[2] = {.seqNum = 1U, .seqId = 7U, .reserved = 0U}, /* cmd seq 2 Enable 4-byte addressing */
.reserved1 = 0,
.configCmdArgs[0] = DUMMY_CYCLES, /* Argument for cmd seq 0 */
.configCmdArgs[1] = 0xFE, /* Argument for cmd seq 1 */
.configCmdArgs[2] = 0xFE, /* Argument for cmd seq 2 */
.reserved2 = 0,
/* Do not override pad settings with the Misc option */
.controllerMiscOption =
0x00 | (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DdrModeEnable),
.deviceType = kFlexSpiDeviceType_SerialNOR,
.sflashPadType = 8,
.serialClkFreq = kFlexSpiSerialClk_80MHz, /* Note DDR frequency is double that figure */
.lutCustomSeqEnable = 0,
.reserved3[0] = 0,
.reserved3[1] = 0,
.sflashA1Size = 32 * 1024 * 1024,
.sflashA2Size = 0,
.sflashB1Size = 0,
.sflashB2Size = 0,
.csPadSettingOverride = 0xA, /* Pulldown enabled, normal drive strength */
.sclkPadSettingOverride = 0xA,
.dataPadSettingOverride = 0xA,
.dqsPadSettingOverride = 0xA,
.timeoutInMs = 0,
.commandInterval = 10,
.dataValidTime[0] = 16,
.dataValidTime[1] = 16,
.busyOffset = 0,
.busyBitPolarity = 0,
.lookupTable =
{
/* LUT table discussed at p. 297 of the RM */
/* [0] DDR OCTAL I/O FAST READ FDh */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_8PAD, 0xFD, RADDR_DDR, FLEXSPI_8PAD, 32),
FLEXSPI_LUT_SEQ(DUMMY_DDR, FLEXSPI_8PAD, DUMMY_CYCLES, READ_DDR, FLEXSPI_8PAD, 4),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
/* [1] Read Status Register - SPI */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 4),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
/* [2] Read Status Register in octal mode*/
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_8PAD, 0x05, DUMMY_DDR, FLEXSPI_8PAD, DUMMY_CYCLES),
FLEXSPI_LUT_SEQ(READ_DDR, FLEXSPI_8PAD, 1, STOP, FLEXSPI_1PAD, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
/* [3] Write Enable */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, 0, 0, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
/* [4] Write Enable Octal */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_8PAD, 6, 0, 0, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
/* [5] Erase Sector */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_8PAD, 33, RADDR_DDR, FLEXSPI_8PAD, 32),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
/* [6] Write volatile configuration register for entering octal mode */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, CMD_SDR, FLEXSPI_1PAD, 0),
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0, CMD_SDR, FLEXSPI_1PAD, 0),
FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 1, 0, 0, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
/* [7] Write NVREG at address 6 to enable 4-byte addr
*/
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, CMD_SDR, FLEXSPI_1PAD, 0x00),
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x00, CMD_SDR, FLEXSPI_1PAD, 0x05),
FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x01, STOP, FLEXSPI_1PAD, 0x00),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
/* [8] 4-BYTE 128KB SECTOR ERASE */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_8PAD, 220, RADDR_DDR, FLEXSPI_8PAD, 32),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
/* [9] Page Program 4 byte */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_8PAD, 18, RADDR_DDR, FLEXSPI_8PAD, 32),
FLEXSPI_LUT_SEQ(WRITE_DDR, FLEXSPI_8PAD, 4, 0, 0, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
/* [10] Write NVREG at address 6 to enable XIP - SPI */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, CMD_SDR, FLEXSPI_1PAD, 0x00),
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x00, CMD_SDR, FLEXSPI_1PAD, 0x06),
FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x01, STOP, FLEXSPI_1PAD, 0x00),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
/* [11] Chip Erase */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_8PAD, 96, 0, 0, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
/* [12] Write NVREG at address 1 to set dummy cycles in octal mode */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_8PAD, 0x81, CMD_DDR, FLEXSPI_8PAD, 0x00),
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_8PAD, 0x00, CMD_DDR, FLEXSPI_8PAD, 0x01),
FLEXSPI_LUT_SEQ(WRITE_DDR, FLEXSPI_8PAD, 0x01, STOP, FLEXSPI_8PAD, 0x00),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
/* [13] Write NVREG at address 1 to set the dummy cycles - SPI */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, CMD_SDR, FLEXSPI_1PAD, 0x00),
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x00, CMD_SDR, FLEXSPI_1PAD, 0x01),
FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x01, STOP, FLEXSPI_1PAD, 0x00),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
/* (14) Write NVREG at address 0 to switch to chosen
interface-Type - SPI */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x81, CMD_SDR, FLEXSPI_1PAD, 0x00),
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x00, CMD_SDR, FLEXSPI_1PAD, 0x00),
FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x01, STOP, FLEXSPI_1PAD, 0x00),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
/* [15] Dummy command */
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
},
},
.pageSize = 256,
.sectorSize = 4096,
.ipcmdSerialClkFreq = 1, /* 30 MHz for IP commands */
.isUniformBlockSize = 0,
.reserved0 = 0,
.serialNorType = 2,
.needExitNoCmdMode = 0,
.halfClkForNonReadCmd = 0,
.needRestoreNoCmdMode = 0,
.blockSize = 128 * 1024,
};