Flash configuration confusion RT1176 Octal DDR Hello NXP I got some issues configuring the flash memory for Macronix Octal DDR mode. I am using the PX4 code stack on a custom board based on the NXP FMU-6XRT reference design. I am using the MX25UM51245G instead of the MX25UM51345G, but the part differences are minimal. I am trying to run it in Macronix Octal DDR mode with DQS external sampling at atleast 100MHz. Reference design is running it at 200MHz. The Boot Memory Configuration succesfully tests the memory with the desired configuration even at 166MHz. The configuration I have tried is the following default config. The first one, "g_flash_config" succesfully boots, writes, read, etc, but is not ideal for the software. "g_flash_fast_config" fails. I have tried reducing the frequency to 166MHZ, 133MHz, 50 MHz, and 30MHz without results in the DTR mode in the "fast_config". I have tried using the FCB generated from the Boot Memory Configuration, but there is some struct layout differences which have made it hard to apply to the PX4 code. I am tried different combinations of csHoldTime, csSetupTime and dataValidTime without results aswell. I tried DQS interal in low freq DTR Octal, but it did not work either. What could I try next? #include
/****************************************************************************
* Public Data
****************************************************************************/
locate_data(".boot_hdr.conf")
const struct flexspi_nor_config_s g_flash_config = {
.memConfig =
{
#if !defined(CONFIG_BOARD_BOOTLOADER_INVALID_FCB)
.tag = FLEXSPI_CFG_BLK_TAG,
#else
.tag = 0xffffffffL,
#endif
.version = FLEXSPI_CFG_BLK_VERSION,
.readSampleClksrc=kFlexSPIReadSampleClk_LoopbackInternally,
.csHoldTime = 1,
.csSetupTime = 1,
.deviceModeCfgEnable = 1,
.deviceModeType = kDeviceConfigCmdType_Generic,
.waitTimeCfgCommands = 1,
.controllerMiscOption =
(1u << kFlexSpiMiscOffset_SafeConfigFreqEnable),
.deviceType = kFlexSpiDeviceType_SerialNOR,
.sflashPadType = kSerialFlash_1Pad,
.serialClkFreq = kFlexSpiSerialClk_100MHz,
.sflashA1Size = 64ul * 1024u * 1024u,
.dataValidTime =
{
[0] = {.time_100ps = 0},
},
.busyOffset = 0u,
.busyBitPolarity = 0u,
.lookupTable =
{
/* Read Dedicated 3Byte Address Read(0x03), 24bit address */
[0 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x03, RADDR_SDR, FLEXSPI_1PAD, 0x18), //0x871187ee,
[0 + 1] = FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x04, STOP_EXE, FLEXSPI_1PAD, 0),//0xb3048b20
},
},
.pageSize = 256u,
.sectorSize = 4u * 1024u,
.blockSize = 64u * 1024u,
.isUniformBlockSize = false,
.ipcmdSerialClkFreq = 1,
.serialNorType = 2,
.reserve2[0] = 0x7008200,
};
const struct flexspi_nor_config_s g_flash_fast_config = {
.memConfig =
{
.tag = FLEXSPI_CFG_BLK_TAG,
.version = FLEXSPI_CFG_BLK_VERSION,
.readSampleClksrc=kFlexSPIReadSampleClk_LoopbackInternally,
.csHoldTime = 3,
.csSetupTime = 3,
.deviceModeCfgEnable = 1,
.deviceModeType = kDeviceConfigCmdType_Spi2Xpi,
.waitTimeCfgCommands = 1,
.deviceModeSeq =
{
.seqNum = 1,
.seqId = 6, /* See Lookup table for more details */
.reserved = 0,
},
.deviceModeArg = 2, /* Enable OPI DDR mode */
.controllerMiscOption =
(1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DdrModeEnable),
.deviceType = kFlexSpiDeviceType_SerialNOR,
.sflashPadType = kSerialFlash_8Pads,
.serialClkFreq = kFlexSpiSerialClk_133MHz,
.sflashA1Size = 64ul * 1024u * 1024u,
.dataValidTime =
{
[0] = {.time_100ps = 10},
},
.busyOffset = 0u,
.busyBitPolarity = 0u,
.lookupTable =
{
/* Read */// EEH+11H+32bit addr+20dummy cycles+ 4Bytes read data
/* Macronix manual says 20 dummy cycles @ 200Mhz, FlexSPI peripheral Operand value needs to be 2N in DDR mode hence 0x28 */
[0 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0xEE, CMD_DDR, FLEXSPI_8PAD, 0x11), //0x871187ee,
[0 + 1] = FLEXSPI_LUT_SEQ(RADDR_DDR, FLEXSPI_8PAD, 0x20, DUMMY_DDR, FLEXSPI_8PAD, 0x28),//0xb3288b20,
[0 + 2] = FLEXSPI_LUT_SEQ(READ_DDR, FLEXSPI_8PAD, 0x04, STOP_EXE, FLEXSPI_1PAD, 0x00), //0xa704,
/* Read status */
[4 * 2 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x05, CMD_DDR, FLEXSPI_8PAD, 0xfa),
[4 * 2 + 1] = FLEXSPI_LUT_SEQ(RADDR_DDR, FLEXSPI_8PAD, 0x20, DUMMY_DDR, FLEXSPI_8PAD, 0x04),
[4 * 2 + 2] = FLEXSPI_LUT_SEQ(READ_DDR, FLEXSPI_8PAD, 0x04, STOP_EXE, FLEXSPI_1PAD, 0x00),
/* Write enable SPI *///06h
[4 * 3 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP_EXE, FLEXSPI_1PAD, 0x00),//0x00000406,
/* Write enable OPI SPI *///06h
[4 * 4 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x06, CMD_DDR, FLEXSPI_8PAD, 0xF9),
/* Erase sector */
[4 * 5 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x21, CMD_DDR, FLEXSPI_8PAD, 0xDE),
[4 * 5 + 1] = FLEXSPI_LUT_SEQ(RADDR_DDR, FLEXSPI_8PAD, 0x20, STOP_EXE, FLEXSPI_1PAD, 0x00),
/*Write Configuration Register 2 =01, Enable OPI DDR mode*/ //72H +32bit address + CR20x00000000 = 0x01
[4 * 6 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x72, CMD_SDR, FLEXSPI_1PAD, 0x00),//0x04000472,
[4 * 6 + 1] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x00, CMD_SDR, FLEXSPI_1PAD, 0x00),//0x04000400,
[4 * 6 + 2] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x00, WRITE_SDR, FLEXSPI_1PAD, 0x01),//0x20010400,
/*Page program*/
[4 * 9 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0x12, CMD_DDR, FLEXSPI_8PAD, 0xED),//0x87ed8712,
[4 * 9 + 1] = FLEXSPI_LUT_SEQ(RADDR_DDR, FLEXSPI_8PAD, 0x20, WRITE_DDR, FLEXSPI_8PAD, 0x04),//0xa3048b20,
},
},
.pageSize = 256u,
.sectorSize = 4u * 1024u,
.blockSize = 64u * 1024u,
.isUniformBlockSize = false,
.ipcmdSerialClkFreq = 1,
.serialNorType = 2,
.reserve2[0] = 0x7008200,
}; Re: Flash configuration confusion RT1176 Octal DDR Hello @SimonHugr, If you plan to use DDR mode, please keep in mind that the byte swapping configuration must also be considered. this post provides useful information about why important take in mind the byte swapping on the MX25UM51245GXDI00 when you are using DDR mode.
I highly recommend use the Boot Memory Configuration to generate the FCB, the Secure provisioning tool v26.6 offers a template of the MX25UM51245G, which can serve as a good starting point for your configuration. Also, as you may know, this tool allows you to test your configurations.
Additionally, I recommend see this community post, particularly the steps starting from point 15. That section provides a more detailed explanation of how the Secure Provisioning Tool generates the boot memory configuration and may help clarify the parameters and output produced by the tool.
Finally, you can use the flexspi_nor_polling_transfer_cm7 example to validate the generated FCB and verify that read and write operations are functioning correctly before proceeding with the boot configuration.
BR Habib Re: Flash configuration confusion RT1176 Octal DDR No results yet sadly, I still think it has something to do with some data order swap is done and I am missing some configuration byte somewhere... Re: Flash configuration confusion RT1176 Octal DDR Thank you Masmiseim Indeed, I noticed that the data should be swapped for example. I will go through my LUT once more. Re: Flash configuration confusion RT1176 Octal DDR Refering to this thread: https://community.nxp.com/t5/i-MX-RT-Crossover-MCUs/Internal-Boot-from-Flash-memory-not-starting-on-imxRT1176-custom/m-p/1830699 I should swap the data order by editing the misc option and according to zephyr RTOS https://github.com/zephyrproject-rtos/hal_nxp/blob/3a36ee1f8b9fc2168fc0bf80377ace8298292993/mcux/mcux-sdk-ng/devices/RT/RT1170/MIMXRT1176/drivers/romapi/fsl_romapi.h#L340-L355 the dataswap byte goes in, but I think I am missing something. .pageSize = 256u,
.sectorSize = 4u * 1024u,
.blockSize = 64u * 1024u,
.isUniformBlockSize = false,
.ipcmdSerialClkFreq = 1,
.isDataOrderSwapped = true
.serialNorType = 2,
.reserve2[0] = 0x7008200, Re: Flash configuration confusion RT1176 Octal DDR Hey @SimonHugr, One thing I would verify first is the actual difference between the MX25UM51245G and MX25UM51345G. Although the part numbers are very similar, they are not identical devices. According to the Macronix datasheets, the MX25UM51345G explicitly supports DOPI (Double Transfer Rate OPI) Byte Mode data sequence, while the MX25UM51245G belongs to a different product variant. This can affect the command format, byte ordering and LUT configuration used by the FlexSPI controller. You can also compare my configuration which works with MX25UM513 and MX25UW6345G: https://github.com/Masmiseim36/Coremark_iMXRT/blob/master/XiP/flexspi_flash_OSPI_Macronix.c Regars Re: Flash configuration confusion RT1176 Octal DDR Hello Habib For our firmware I am not able to use the secure provisioning tool to generate the FCB, and instead the FCB needs to be loaded on boot in firmware and therefor I need to create the mem_config and flash_config struct and configure it myself. I found the zephyr project referenced a isDataOrderSwapped byte in the flash_nor_config https://github.com/zephyrproject-rtos/hal_nxp/blob/3a36ee1f8b9fc2168fc0bf80377ace8298292993/mcux/mcux-sdk-ng/devices/RT/RT1170/MIMXRT1176/drivers/romapi/fsl_romapi.h#L347-L348 and Claude reference a padSettingOverride bit on bit 5 and a dataSwap bit on bit 7 in the controllerMiscOption, but I am not sure if the LLM is heavily hallucinating this information. When generating the FCB using the Secure Provisioning tool and converting it into a C-struct using this tool https://community.nxp.com/t5/i-MX-RT-Crossover-MCUs-Knowledge/i-MX-RT-FLEXSPI-booting-guide/ta-p/1669262 I do not get bit 5 or 7 set so I think the LLM is wrong, but the isDataSwapped is set and is referenced as reserved0[0] in the FCB normally. I can not find a template for the MX25UM51245G in the secure provisioning tool, only the MX25U51245G (which is a Quad flash), the MX25UM51345G and the MX25UMxxx45G. But any config Octal DDR config that I have tried have not worked to boot. Interestingly often the MCU goes automatically into ISP mode after certain configuration despite BT_FUSE_SEL = 1 and having pins BOOTMODE0/1 = 0. This has not been consistent and I am not sure what configuration causes this. Does the MCU go into ISP mode after failing to read the flash or something? Thank you BR Re: Flash configuration confusion RT1176 Octal DDR Hello @SimonHugr, I apologies there is not a template to MX25UM51245G, only are available the MX25U51245G and MX25UM51345G.
Based on your description, it seems that communication with the flash device is working correctly using your current Boot Memory Configuration settings. When you click "Convert to Complete FCB", the tool programs the configuration into the flash and then reads it back using the parameters you specified, as described below:
If any of the selected settings are not supported by the flash device, the tool should report an error similar to the following:
To further verify that the LUT generated using the FCB converter from the community post is functioning correctly, could you please test it with the flexspi_nor_polling_transfer_cm7 SDK example while running the application from internal RAM? Please let me know if you have questions about the example.
In addition, could you provide me a few more details about the application you are trying to boot? -Is an SDK example or if your own application? -Which IDE you are using? -Is your application performing XIP or NON-XIP? -Are you accessing the flash at any point other than during the boot process?
Regarding to entering in ISP mode, could you please make sure that the boot pins on your custom board followed the recommendations mentioned in the chapter 5 "Boot, reset, and miscellaneous" of the Hardware Development Guide for the MIMXRT1160/1170? This to avoid any hardware issue regarding the boot pins.
Answering your question, you can enter in ISP mode if is not available a valid image, as shown the figure 10-1 "boot flow" of the RM:
BR Habib
View full article