FlexSPI FCB configuration commands The FlexSPI configuration block has two distinct members, which are used for specifying commands which the peripheral executes: deviceModeCfgEnable is used to enable deviceModeSeq, which receives an argument from deviceModeArg, and is of type deviceModeType configCmdEnable is used to enable up to three command sequences, defined in configCmdSeqs, which get their arguments from cfgCmdArgs, and are of type configModeType My questions are: Is there an order in which the two apparently different sets of commands are executed? Is there a difference between the two options above in addition to the number of commands that can be executed? When using the built-in bootloader, does it check the status register after each of the command sequences? If it does, how will it check the status register if a command sequence changes the device mode from xSPI to octal? The reason for these questions is that I have a FCB which changes the mode of an IS25WXxxx flash from xSPI to octal, and it works fine when I flash it via JTAG. I have also tested the FlexSPI command sequences and they all work. However, when I try to use it with MCUXpresso Secure Provisioning Tool and the USB bootloader, it fails unless the flash has been previously erased. Below is my flexspi_nor_config_t: const flexspi_nor_config_t issi_flash_config =
{
.memConfig =
{
.tag = (0x42464346UL),
.version = (0x56010400UL),
.reserved0 = 0,
.readSampleClksrc=kFlexSPIReadSampleClk_ExternalInputFromDqsPad,
.csHoldTime = 3,
.csSetupTime = 3,
.columnAddressWidth = 0,
/* Do not execute config enable - DDR mode setting handled
by configCmdSeqs */
.deviceModeCfgEnable = 0,
.deviceModeType = kDeviceConfigCmdType_Spi2Xpi,
.waitTimeCfgCommands = 0,
.deviceModeSeq =
{
.seqNum = 1U,
.seqId = 6U,
.reserved = 0U,
},
.deviceModeArg = 0xE7,
/* Config commands to set dummy cycles and octal mode. All
commands are sent in xSPI mode with 3-byte addresses */
.configCmdEnable = 1,
.configModeType[0] = kDeviceConfigCmdType_Generic,
.configModeType[1] = kDeviceConfigCmdType_Generic,
.configModeType[2] = kDeviceConfigCmdType_Spi2Xpi,
/* Set dummy cycles */
.configCmdSeqs[0] = {.seqNum = 1U, .seqId = 13U, .reserved = 0U},
/* Set drive strength */
.configCmdSeqs[1] = {.seqNum = 1U, .seqId = 14U, .reserved = 0U},
/* Set octal DDR */
.configCmdSeqs[2] = {.seqNum = 1U, .seqId = 6U, .reserved = 0U},
.reserved1 = 0,
.configCmdArgs[0] = DUMMY_CYCLES,
.configCmdArgs[1] = 0xFF,
.configCmdArgs[2] = 0xE7,
.reserved2 = 0,
.controllerMiscOption =
0x00 |
(1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) |
(1u << kFlexSpiMiscOffset_DdrModeEnable) |
(1 << 5) |
(1 << 7),
.deviceType = kFlexSpiDeviceType_SerialNOR,
.sflashPadType = 8,
.serialClkFreq = kFlexSpiSerialClk_166MHz,
.lutCustomSeqEnable = 0,
.reserved3[0] = 0,
.reserved3[1] = 0,
.sflashA1Size = 32 * 1024 * 1024,
.sflashA2Size = 0,
.sflashB1Size = 0,
.sflashB2Size = 0,
.csPadSettingOverride = 0xA,
.sclkPadSettingOverride = 0xA,
.dataPadSettingOverride = 0xA,
.dqsPadSettingOverride = 0xA,
.timeoutInMs = 0,
.commandInterval = 10,
.dataValidTime[0] = 0,
.dataValidTime[1] = 0,
.busyOffset = 0,
.busyBitPolarity = 0,
.lookupTable =
{
/* [0] Fast Read 8S-8D-8D */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_8PAD, 0x0C,
RADDR_DDR, FLEXSPI_8PAD, 32),
FLEXSPI_LUT_SEQ(DUMMY_DDR, FLEXSPI_8PAD,
(DUMMY_CYCLES * 2), READ_DDR,
FLEXSPI_8PAD, 128),
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,
READ_DDR, FLEXSPI_8PAD, 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),
/* [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, 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),
/* [5] Erase 4KB Sector DDR */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_8PAD, 0x21,
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, 0x0),
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x0, CMD_SDR,
FLEXSPI_1PAD, 0x0),
FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x01, STOP,
FLEXSPI_1PAD, 0x00),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
/* [7] Write NVREG at address 5 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 DDR */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_8PAD, 0xDC,
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 DDR */
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 3 - 4 byte
address */
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(CMD_SDR, FLEXSPI_1PAD, 0x03,
WRITE_SDR, FLEXSPI_1PAD, 0x01),
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0),
/* [11] Chip Erase DDR */
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_8PAD, 0x60, 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 3 to change
impedance - 3 byte address */
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, 0x03),
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,
.isUniformBlockSize = 0,
.reserved0 = 0,
.serialNorType = 2, /* Appears to indicate Octal DDR */
.needExitNoCmdMode = 0,
.halfClkForNonReadCmd = 0,
.needRestoreNoCmdMode = 0,
.blockSize = 131072, /* 0x20000 */
}; Re: FlexSPI FCB configuration commands Hi,
Would you plese give some backgroud about this question to us? such as which SDK, example and which EVK board/chips. Re: FlexSPI FCB configuration commands Fuses configuration: BT_FUSE_SEL = 1 BOOT_CFG[7:0] = 0x08 Re: FlexSPI FCB configuration commands I'm using Zephyr v3.7.1 and custom board with MIMXRT1166. Re: FlexSPI FCB configuration commands Sorry, I can't point out what the root cause is base on current information.
In detail, 'However, when I try to use it with MCUXpresso Secure Provisioning Tool and the USB bootloader, it fails unless the flash has been previously erased.' It is better to check in details with trace log.
查看全文