Problems with FlexSPI2 on i.MX RT1172 and QSPI flash

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Problems with FlexSPI2 on i.MX RT1172 and QSPI flash

3,171 Views
a_sanchez
Contributor II

Hello, we have a custom board using an iMXRT1170 (model i.MX RT1172) with an external QSPI flash memory. We want to run our program from it, using XIP and boot mode "10" (external boot). The QSPI connection is made using the pins GPIO_SD_B1_[00:05]. These pins belong to the FlexSPI2, secondary pin group, port A, as shown in the next image:

FlexSPI2pinout.png

 
We are having problems to program this memory. We have been able to erase it, but we cannot write nor read any data from it. We are using both MCU-Link and PEMicro Multilink programmers with the same results.
 
These are the steps we have followed up to this point:
 
1. Burn the three eFuses said in the table, and also set "BT_FUSE_SEL=1" to avoid usage of GPIO pins for eFuses during boot process. We burn them using a PEMicro Cyclone programmer.
 
2. Create a custom SFDP QSPI flash driver, by making these changes to the original one:
 
  • Set FLASH_BASE_ADDR to 0x60000000
  • Set CONFIG_OPTION0  to 0xC1002007
    • device_type = 0 (read SFDP for SDR)
    • option_size = 1 (to activate the use of OPTION1)
    • query_pad = 0 (to use 1 pad during query command)
    • cmd_pad = 2 (to use 4 pads during flash access)
    • quad_mode_setting = 0 (not configured. Our memory boots in QSPI mode. We also tried to activate it, but it didn't change anything)
    • max_freq = 7 (we have tried different values here. We always see the same freq on the clock pin)
  • Set CONFIG_OPTION1 to 0x00010000
    • flash_connection= 0 (single flash on port A)
    • pin_group = 1 (secondary pin group)
    • dummy_cycles = 0 (Autodetect. We also tried to write the number of cycles said in the memory's datasheet)
 
3. We have also added some delay time before accesing the flash memory, according to the errata ERR011377 (link to the erratasheet). This did not fix the problem.
 
 
At this point we are stuck and don't know what else to do. The programmer is able to get the flash information and erase it, but it fails when trying to perform any write or read operations. We are also able to download and run code from the internal RAM memory.
 
It seems that the QSPI commands are not working and only single-SPI commands work. Maybe the QSPI mode is not being configured correctly on the FlexSPI2 peripheral? Do we need to add anything else to the driver or configure any other eFuse? Any idea?
 
Thanks in advance for your help.
 
 
Best regards,
Antonio
 

 

 

 

 

0 Kudos
Reply
13 Replies

3,058 Views
jagarcia
Contributor II

Hello @jingpan, I am Antonio's coworker.

We now are able to write and read from the flash. We had to change the readSampleClkSrc option in the flash driver's memory configuration to the internal loopback:

flashConfig.memConfig.readSampleClksrc=kFlexSPIReadSampleClk_LoopbackInternally;

By default this option is set to kFlexSPIReadSampleClk_LoopbackFromDqsPad, but with our pin configuration (FlexSPI2, secondary pin group) there is no DQS pin available.

Now we are trying to boot from the flash.

We see that the Boot ROM tries to access the memory at boot time, but we don't know if it can read the 512-byte FlexSPI NOR configuration parameters. ¿Do you know if there is a similar configuration that needs to be done to the fuses regarding the FlexSPI read clock so the Boot ROM can read the configuration block, or is it this not necessary?

 

Thank you. Regards,

José Andrés

0 Kudos
Reply

3,021 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi @jagarcia,

Yes, it can. When boot up, RT1172 will use 30Mhz clock and single wire mode to read flash. So, if your BOOT_CFG pin set correct, it can read out configuration from any flash.

You also can use eFuse to set boot config. Please refer to table 10-10 in RM.

 

Regards,

Jing

2,968 Views
jagarcia
Contributor II

Hello @jingpan, we still are not able to boot from the flash memory.


The memory we are using is the W25Q32JV (QSPI), connected to FlexSPI2, secondary pin group.

What we have done untill now is:

 

- Burn this eFuse configuration in the device:

    BT_FUSE_SEL=1

    FLEXSPI_INSTANCE=1

    FLEXSPI_PIN_GROUP_SEL=1

    FLASH_CONNECTION_SEL=0

 

- Build a flash driver with the next configuration:

CONFIG_OPTION0 0xC1000003

CONFIG_OPTION1 0x00010000

Added the next line before flexspi_nor_flash_init in the driver:

flashConfig.memConfig.readSampleClksrc=kFlexSPIReadSampleClk_LoopbackInternally

With this we can program the memory, but cannot start a debug session.


- Added the FlexSPI configuration parameters to our project:

We have the next XIP options in our preprocessor settings:

XIP_EXTERNAL_FLASH=1

XIP_BOOT_HEADER_ENABLE=1

XIP_BOOT_HEADER_DCD_ENABLE=0

Also, we have added the next files to the project:

evkmimxrt1170_flexspi_nor_config.c

evkmimxrt1170_flexspi_nor_config.h

fsl_flexspi_nor_boot.c

fsl_flexspi_nor_boot.h

In the first file we have modified the qspiflash_config structure to fit our memory:


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,

.columnAddressWidth = 0,

.deviceModeCfgEnable = 0, // Para HyprRAM

.deviceModeType = 1, //Quad enable

.waitTimeCfgCommands = 0,


.controllerMiscOption = 0x100,

.deviceType = kFlexSpiDeviceType_SerialNOR,

.sflashPadType = kSerialFlash_4Pads,

.serialClkFreq = kFlexSpiSerialClk_60MHz,

.lutCustomSeqEnable = 0u,

.sflashA1Size = 4u * 1024u * 1024u,

.lookupTable =

{

// Read LUTs

[0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),

[1] = FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04),


// Read Status LUTs

[4 * 1 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x04),


// Write Enable LUTs

[4 * 3 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0x0),


// Erase Sector LUTs

[4 * 5 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 0x18),


// Erase Block LUTs

[4 * 8 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8, RADDR_SDR, FLEXSPI_1PAD, 0x18),


// Pape Program LUTs

[4 * 9 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18),

[4 * 9 + 1] = FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0x0),


// Erase Chip LUTs

[4 * 11 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xC7, STOP, FLEXSPI_1PAD, 0x0),

},

},

.pageSize = 256u,

.sectorSize = 4u * 1024u,

.ipcmdSerialClkFreq = 0x3, //60 MHz

.blockSize = 64u * 1024u,

.isUniformBlockSize = false,

};

We can see that this structure is present in the compiled file, in the correct location (offset 0x400):

Captura.JPG

 But we still are not able to make the microcontroller start our program, or to start a debug session.

 

Do you know what we could be missing? Could you give us any pointers to the right direction?

Thank you very much.

Cheers,

José Andrés

0 Kudos
Reply

2,929 Views
jingpan
NXP TechSupport
NXP TechSupport
0 Kudos
Reply

2,794 Views
jagarcia
Contributor II

Hello @jingpan, we still cannot boot from the flash or start a debug session. I see that the FlexSPI communication starts at 30MHz, but then changes to ~100MHz. I'm trying to burn the xSPI_FLASH_FREQ efuse (table 26-2 of the RM) to limit the frequency to 60MHz. I'm using the OCOTP peripheral, but I don't see this efuse location in the OTP Memory Footprint (Figure 27-2 of the RM).

Is there a way to burn this efuse without changing the boot mode signals in our PCB? We have them set to internal boot mode, so we can't use the MCUBootUtility.

Thank you very much.

Regards,

José Andrés

0 Kudos
Reply

2,781 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi @jagarcia ,

It's not a good idea to fix the chip to internal boot mode by hardware in project development stage. Let it boot up flexible could avoid many inconvenient problem.

Since you have burned BOOT_CFG fuse by a multilink, burn 0xc80 is same. Figure 27-2 is shadow register, not efuse. It's value is get from efuse when boot up. For example, 0x14 BOOT_CFG1 is read from efuse 0x940, 0x48 BOOT_CFG_MISC1 is read from 0xc80.

But I think you needn't burn this fuse currently. If it work correctly, boot ROM will read frequency data from FCB and set to flexspi. So, flexspi will not run at 100M.

I'm not clear about your situation. It seems you still can't use multilink to download code to flash, isn't it?

 

Regards,

Jing

0 Kudos
Reply

2,773 Views
jagarcia
Contributor II

Hi @jingpan, we burned the other efuses with PEMicro´s Cyclone, but the efuse xSPI_FLASH_FREQ does not appear and can't be burned with their utility. I have opened also a ticket with them in this regard.

 

I have the frequency defined in the FCB as 60MHz, but the SPI clock signal runs first at 30MHz and then at 100MHz, as we observe in the oscilloscope. You can see the FCB in hexadecimal in the image upper in this thread. The byte for the serialClkFreq option is set to 0x03, which is the value corresponding to kFlexSpiSerialClk_60MHz. It appears then that the FCB is not being read correctly during the startup.

We can program the flash with the flash driver, but the MCU won't boot. In order to make the flash driver work we had to add this option, as with our pin configuration we don't have a DQS pad:

readSampleClksrc=kFlexSPIReadSampleClk_LoopbackInternally.

Do you know if there is a similar configuration that can be done to the ROM API, and we may be missing it?

 

Thank you. Regards,

José Andrés

0 Kudos
Reply

2,547 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi @jagarcia ,

Did you always use multilink to download? Have you tried MCUBootutility or SPT to download application? The difference is MCUBootutility or SPT will program the QE bit in W25Q32. So, please use SPT to download an application, like led_blinky for example. Note that fexspi2 start address is 0x60000000. You must modify the project settings.

readSampleClksrc=kFlexSPIReadSampleClk_LoopbackInternally is correct.

jingpan_0-1696835428624.png

 

Regards,

Jing

 

0 Kudos
Reply

2,541 Views
jagarcia
Contributor II

Hello @jingpan ,

Yes we have tried MCUBootUtility. Also, we tried building our flash driver with the option to set the QE bit of the second status register of the memory. Anyway, this is not needed, as per our memory datasheet this bit is already enabled from factory with our part number. We also confirmed the memory operation by modifying one of our prototype boards to connect the memory to FlexSPI1, port A, primary pin group. In this case the board performs correctly, but we still are not able to make it work when the memory is connected to our chosen pinout: FlexSPI2, secondary pin group.

We also update the Flash location in the project configuration accordingly: 0x60000000 for the FlexSPI2 and 0x30000000 for the board we are using to test the memory connected to FlexSPI1

This is our project status at this time:

1. The USB1 PHY is powered correctly, in case this matters.

2. We can program the flash memory, but the debugger is not able to start the debug session and neither the ROM bootloader is able to boot from there.

3. Our application is just a simple LED blink, with no other peripherals usage than GPIO and typical boot routines. When we run this application from RAM it works fine. It also works when we run it from the same flash chip connected to the FlexSPI1-primary-A (more info about this test given below).

4. We can see the QSPI lines, but we do not have the necessary equipment to make a full capture of the boot process. We can see that the clock starts at 30MHz and then goes to 100MHz, when it should be limited to 60MHz according to the FCB configuration.

 

Important fact: we have modified one board by removing some components and soldering the flash memory to the FlexSPI1-primary-A pins. On this board the same application runs from flash, we can program and debug it correctly. Be aware that this configuration uses the same hardware, the same power signals and the same FCB configuration, it just changes the FlexSPI pins. This is the reason why we think that the problem is not related to points 1, 2 or 3. It seems that the ROM bootloader is not capable of reading the FCB over the FlexSPI2.

More info: on the oscilloscope we see that the FlexSPI2 clock boots at 30MHz for a while and then goes to 100MHz. In one of the boards we have burned the xSPI_FLASH_FREQ eFuse to value 0x6 (thinking that there was a problem with the 100 MHz clock). With this change the FlexSPI2 now goes from 30 MHz to 60 MHz (so the limit of the eFuse is working), but the application still does not work.

 

Regards,

José Andrés.

0 Kudos
Reply

2,520 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi @jagarcia ,

You told me the QSPI flash part number is w25q32jv, it seems not a QE=1 part.

jingpan_0-1697006193545.png

You can use MCUBootUtility to download code to flexspi2 flash and read back data is correct, isn't it? Can you share your binary image? 

What's the status of GPIO_DISP_B1_06 when boot up and BOOT_CFG1[0] efuse?

 

Regards,

Jing

0 Kudos
Reply

2,511 Views
jagarcia
Contributor II

Hello @jingpan.

Sorry, the complete part name for the memory is 25Q32QJVIQ.

 

We cannot use the MCUBootUtility to write/read from the flash. The utility connects succesfully via the UART but we get an error when trying to write/read from the flash. The only way that we have been able to program the flash is with the customized driver in the MCUXpresso IDE.

 

The GPIO_DISP_B1_06 is free floating when booting up. We burnt the BT_FUSE_SEL efuse, so the BOOT_CFG1[0] value is read from the efuses. We burnt this efuse to see if it helped, so we have the FLASH_AUTO_PROBE_EN to 1. We did not observe any diference after setting this.

 

Regards,

José Andrés

0 Kudos
Reply

2,440 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi @jagarcia ,

You have the FLASH_AUTO_PROBE_EN to 1, this is why the system always set clock to 100M unless xSPI_FLASH_Frequency is burned to 60M. This bit has priority over FCB configuration.

But MCUBootUtility/SPT is very very important. It needn't eFuse help. If MCUBootUtility fail, we even not sure if the borad is fine. SPT/MCUBootUtility is the best starting point for flash configuration. Does your board has USB? It is more stable than UART.

If you have other efuse bit burned, please tell me.

 

Regards,

Jing

0 Kudos
Reply

3,122 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi @a_sanchez ,

Please try the option0/option1 by using Security Provisioning Tool.

jingpan_0-1693983828316.png

 

Regards,

Jing

 

0 Kudos
Reply