Hello,
I'm using MIMXRT1176 where M7 is in XIP mode (on FLEXSPI1 port A) and M4 is running in SDRAM. I'm trying to access FlexSPI1 port B but without any luck. I've already followed some documentation, for example:
In my setup we have flash memory for MCU program on FlexSPI1 port A and then another flash memory for data on FlexSPI1 port B.
In my actual state I initialize M7 core and jumps into a function that runs in RAM memory until M4 initialization isn't done. That works fine.
On M4 I'm trying to access FLEXSPI1 port B and read vendors ID from flash memory. However, no matter what I try I always read vendors ID from the MCU flash memory. This is quite an unexpected behaviour because the MCU flash memory is on port A1 and I'm using FLEXSPI_TransferBlocking() for port B1.
When it comes to initialization, my XIP configuration on M7 side looks like this:
const flexspi_nor_config_t qspiflash_config = {
.memConfig =
{
.tag = FLEXSPI_CFG_BLK_TAG,
.version = FLEXSPI_CFG_BLK_VERSION,
.readSampleClksrc=kFlexSPIReadSampleClk_LoopbackInternally,
.csHoldTime = 3u,
.csSetupTime = 3u,
// Enable DDR mode, Wordaddassable, Safe configuration, Differential clock
.controllerMiscOption = 0x10,
.deviceType = kFlexSpiDeviceType_SerialNOR,
.sflashPadType = kSerialFlash_4Pads,
.serialClkFreq = kFlexSpiSerialClk_60MHz,
.sflashA1Size = 16u * 1024u * 1024u,
.sflashB1Size = 16u * 1024u * 1024u,
/* Enable flash configuration feature */
.configCmdEnable = 1u,
.configModeType[0] = kDeviceConfigCmdType_Generic,
/* Set configuration command sequences */
.configCmdSeqs[0] =
{
.seqNum = 1,
.seqId = 12,
.reserved = 0,
},
/* Prepare setting value for Read Register in flash */
.configCmdArgs[0] = (FLASH_DUMMY_VALUE << 3),
.lookupTable =
{
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD + 0] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xEB, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_4PAD, 0x18),
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD + 1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_4PAD, FLASH_DUMMY_CYCLES, kFLEXSPI_Command_READ_SDR, kFLEXSPI_4PAD, 0x04),
[4 * NOR_CMD_LUT_SEQ_IDX_READSTATUSREG] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x05, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_4BYTE + 0] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x12, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x20),
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_4BYTE + 1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0),
[4 * NOR_CMD_LUT_SEQ_IDX_WRITEENABLE] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x06, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
[4 * NOR_CMD_LUT_SEQ_IDX_READID] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x9F, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
[4 * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR_4kB] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x20, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
[4 * NOR_CMD_LUT_SEQ_IDX_READ_NORMAL + 0] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x13, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x20),
[4 * NOR_CMD_LUT_SEQ_IDX_READ_NORMAL + 1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
[4 * NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK_64kB] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xD8, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_3BYTE + 0] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x02, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_3BYTE + 1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0),
[4 * NOR_CMD_LUT_SEQ_IDX_CHIPERASE] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x60, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0),
[4 * NOR_CMD_LUT_SEQ_IDX_SETREADPARAMS + 0] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xC0, kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x01),
[4 * NOR_CMD_LUT_SEQ_IDX_SETREADPARAMS + 1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00, 0, 0, 0),
},
},
.pageSize = 256u,
.sectorSize = 4u * 1024u,
.ipcmdSerialClkFreq = 0x1,
.blockSize = 64u * 1024u,
.isUniformBlockSize = false,
};
I've made sure that I tell the XIP that there's another flash on FlexSPI1 (through the sflashB1Size). The internal loopback is there for a reason.
When it comes to the M4 side, I'm trying to initialize the port B as follows:
status_t flexspi1b_Init(FLEXSPI_Type *base) {
if(!base) {
return kStatus_Fail;
}
flexspi_cache_status_t cacheStatus = {0};
_flexspi1b_CacheEnable(&cacheStatus, false);
FLEXSPI_SetFlashConfig(base, &flexspi1bDeviceCfg, FLEXSPI1B_FLASH_PORT);
uint32_t tmpLUT[FLEXSPI1B_LUT_LENGTH] = {0};
memcpy(tmpLUT, flexspi1bLUT, sizeof(tmpLUT));
FLEXSPI_UpdateLUT(base, 1, &tmpLUT[1], FLEXSPI1B_LUT_LENGTH - 1);
FLEXSPI_SoftwareReset(base);
_flexspi1b_CacheEnable(&cacheStatus, true);
return kStatus_Success;
}
But this doesn't look to have any effect on the behaviour of FlexSPI1 port B. I've tried using FLEXSPI_Init() function, however when I use it, it crashes the whole MCU. I thought it might be because of the native initialization of clock but even after commenting that section, it still crashes the whole MCU. I thought maybe the init function isn't needed since the initialization of FlexSPI1 block is through the XIP but it doesn't seem like it.
My function for reading vendors ID looks like this:
status_t flexspi1b_GetVendorId(FLEXSPI_Type *base, uint32_t *vendorId) {
if(!base || !vendorId) {
return kStatus_Fail;
}
flexspi_transfer_t flashXfer = {
.deviceAddress = 0,
.port = kFLEXSPI_PortB1,
.cmdType = kFLEXSPI_Read,
.SeqNumber = 1,
.seqIndex = NOR_CMD_LUT_SEQ_IDX_READID,
.data = vendorId,
.dataSize = 3,
};
status_t sts = FLEXSPI_TransferBlocking(base, &flashXfer);
return sts;
}
What is quite mindblowing to me is the fact that when I use FLEXSPI_Init() function and debug only the M4 core alone, everything works pefectly, I'm even able to write data etc. to the flash memory that is located at FlexSPI1 port B1.
I'm sure M7 core is not doing anything with FlexSPI1 because I have oscilloscope connected to it the whole time and there's nothing happening there after I enter the RAM function so that shouldn't make any problem.
Does anyone have any idea what am I doing wrong or what information am I completely missing?
Thank you in advance for any tip or documentation that describes such issue.