i.MX RT1050 QSPI NOR boot initially fails

cancel
Showing results for 
Search instead for 
Did you mean: 

i.MX RT1050 QSPI NOR boot initially fails

Jump to solution
300 Views
Contributor II

Hi,

for a couple of months now we are developing with i.MX RT1050 on own HW equipped with a QSPI NOR flash (Macronix MX25L6433FM2I). During this time we learned how to configure the Flash Control Block in the first NOR sector to make the i.MX correctly boot the flashed images without requiring an boot image manipulation e.g. with elftosb utility. Until we implemented our own update procedure for programming the flash via USB, we used the Flashloader utilities (sdphost and blhost) for accessing the Flash memory. Up to now the boot configuration BOOT_CFG1 and BOOT_CFG2 is applied via strap pins - hence no eFUSE. This also applies to BOOT_MODE configuration that is set to "Internal Boot" via GPIOs.

Now where we are confident that the application works correctly we had a small pilot series for the final device where the NOR flash is pre-programmed prior to PCB mounting. Unfortunately these "vanilla" devices do not boot on its own when powered. Instead they boot into Serial Download mode. We've found out that they correctly start without HW or SW modification by only connecting to the ROM loader, loading and starting the Flashloader application (both via sdphost tool) and configuring boot device afterwards (via blhost tool). Below is an example with reduced command line parameters for better readability:

./sdphost -- write-file 0x20000000 ivt_flashloader.bin

./sdphost  -- jump-address 0x20000400

./blhost -- fill-memory 0x2000 4 0xC0000107 word    // QSPI NOR has Quad Mode Setting on StatusRegister1 Bit6
./blhost -- fill-memory 0x2004 4 0 word
./blhost -- configure-memory 9 0x2000
./blhost -- reset

These steps above where sufficient to make the device correctly boot into our application. By now we where not able to find out what is actually modified within the device (either i.MX or flash). We could only ensure that the application binary within the flash stays untouched (by reading it out again via Flashloader and comparing it against the original binary)

So does anyone have an idea what could prevent the i.MX from correctly booting without the "Floashloader" workaround? It seems that it isn't even able to read out the initial NOR flash sector for processing the FCB.

Cheers

André

P.S.: I attached the FlexSPI Configuration Block as C implementation that is linked at the beginning of the application binary (and yes, XIP_BOOT_HEADER_ENABLE is set to 1 during compilation)

Labels (1)
Tags (1)
0 Kudos
1 Solution
145 Views
Contributor II

Hi @kerryzhou,

many thanks for your code example. Unfortunately an application is not an option as it requires itself being executed - which was not the case as the device didn't boot at all.

But after quite some investigation the root cause more and more points to the programmer device/software not correctly configuring the QE bit within initial NOR flash programming task (although suggesting to do so). Hence in parallel we opened a request with the programmer's manufacturer.

For i.MX I was finally able to configure FCB accordingly to make the ROM loader enabling QE bit implicitly (writing 0x40 to StatusRegister1 with 'Write Status Register' (WRSR, 0x01) command):

const flexspi_nor_config_t nor_spi_config = {
  .memConfig = {
    // ...
    .deviceModeCfgEnable = 1u,
    .deviceModeType = kDeviceConfigCmdType_QuadEnable,
    .deviceModeSeq = {
      .seqId = NOR_CMD_LUT_SEQ_IDX_WRITE_STATUS,
      .seqNum = 1u,
    },
    .deviceModeArg = 0x40, // set Bit6 (=QE, quad enable)
    // ...
    .lookupTable = {
      // ...
      /* 4 - WriteStatus */
      [NOR_CMD_LUT_SEQ_IDX_WRITE_STATUS*4+0] =
                      FLEXSPI_LUT_SEQ(CMD_SDR       , FLEXSPI_1PAD, 0x01, // WRSR
                                      WRITE_SDR     , FLEXSPI_1PAD, 0x01),
      // ...
    },
  },
};

We could use this as workaround as long as the programmer issue isn't fixed - although I'm not happy with it as it writes the status register on each device start.

Nevertheless I've learned a lot about the whole i.MX ROM loader mechanism and would like to thank you for your patience.


Kind regards

André

View solution in original post

8 Replies
196 Views
NXP TechSupport
NXP TechSupport

Hi André Rex ,

  Do you try to test the external flash program , erase and readout? All the function works Ok now?

  If the flash operation works OK, then your external flash hardware have no issues.

  Then, could you please enter the serial download mode, and use the MCUbootUtility tool to download the code your external flash?

  You can download this tool from this link:

https://github.com/JayHeng/NXP-MCUBootUtility/archive/v2.3.0.zip
the related user manual is:
https://github.com/JayHeng/NXP-MCUBootUtility

You can use the tool's firmware:

NXP-MCUBootUtility-2.3.0\apps\NXP_X-IMXRT1050-VAL_Rev.A1\led_blinky_0x60002000.srec

Can you download it to your flash? This code will toggle GPIO1_IO09.

 About the Nor flash configuration, you can refer to ISSI QSPI flash:

pastedImage_2.png

But you need to check your chip QE bit, it is reg1[6]

pastedImage_3.png

pastedImage_4.png

Please try it on your side.

If you still have questions about it, please kindly let me know.

Wish it helps you!

Kerry

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
196 Views
Contributor II

Hi kerryzhou‌,

many thanks for your reply.

  Do you try to test the external flash program , erase and readout? All the function works Ok now?

  If the flash operation works OK, then your external flash hardware have no issues.

  Then, could you please enter the serial download mode, and use the MCUbootUtility tool to download the code your external flash?

Yes this is all working. Uploading the image into the external flash works and it boots afterwards.

You're referring the the NXP-MCUBootUtility. To be honest it was our first choice as long as our own USB update mechanism wasn't implemented. With this tool we actually found out that the "vanilla" device now could be made booting just by connecting to Flashloader and configuring Boot device. This is the working boot device config I took:

pastedImage_4.png

As told before it is already enough to connect to Flashloader and to apply the above boot device configuration. So I just stripped it down to the plain sdhost/blhost calls where I saw that they have the same effect.

From Macronix' datasheet the QE bit is marked "non-volatile". I'm not sure whether this is to be interpreted as "it is enough to write the bit once; it will survive further power cycles". This would explain why once connected to Flashloader (and configured boot device) the device afterwards boots correctly. That raises the question how to instruct the i.MX ROM loader to set the QE bit prior to read out the flash (via FCB).

Regards

André

0 Kudos
196 Views
Contributor II

Hi kerryzhou‌,

your highly extensive response is very appreciated! Unfortunately we cannot use an approach that is either based on Flashloader tools or an additional application to be run. What I am interested in is an approach of how the i.MX ROM loader could perform the steps you described with the "flexspi_nor_polling_transfer" example. Is there any way?

Regards

André

0 Kudos
196 Views
NXP TechSupport
NXP TechSupport

Hi André Rex,

   If you want to use the ROM flashloader, right? Use the elftosb, blhost, or the MFGTool to download it?

   If yes, you can use my last reply:

program_flexspinor_image_qspinor_status_reg1_bit6.bd, which can be found in the SDK:

SDK_2.8.0_EVKB-IMXRT1050\middleware\mcu-boot\bin\Tools\bd_file\imxrt105x

  To generate the related sb file, and use the MFGtool to download the data to the flash, then it can modify the related QE bit.

   You also can check the flashloader, which also use the WriteQEReg to write te QE bit.

static uint32_t WriteQEReg(uint32_t addr, uint8_t data)
{
uint32_t result = RESULT_OK;
    /*Clear interrupts*/
    FLEXSPI_INTR = 0x00000F3F;
    
    /*Set Transfer address*/
    FLEXSPI_IPCR0 = addr;
    /**/
    FLEXSPI_IPCR1 = (0<<20) | (WR_QE_REG_SEQUENCE<<16);
    /*Clear fifo. Watermark is 8 bytes*/
    FLEXSPI_IPTXFCR = 1;
    /*Start trensfer*/
    FLEXSPI_IPCMD = 1;
  
    FLEXSPI_TFDR0 = data;
  
    /*write data to fifo*/
    FLEXSPI_INTR |= (1<<6);
 
    /*wait transfer end*/
    while(!(FLEXSPI_INTR & (1<<0)));

    if(FLEXSPI_INTR & ((1<<1) | (1<<3)))
    {
      result = RESULT_ERROR;
    }
  
  return result;
}

   But from RT1060, the ROM add the option0 and option 1, which can use the ROM code operate it directly.

You can check the RTOM1060RM chapter 9.13 ROM APIs, Table 9-51. serial_nor_config_option_t
definition

pastedImage_1.png

Wish it helps you!

If you still have questions about it, please kindly let me know.

Best Regards,

Kerry

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
196 Views
Contributor II

Hi kerryzhou‌,

   If you want to use the ROM flashloader, right? Use the elftosb, blhost, or the MFGTool to download it?

No, we don't want to use Flashloader for production as this would increase line time. It is not part of RT1050 ROM and would require prior binary uploading via sdphost tool!

I'm looking for a way to make the ROM performing these steps at initial boot sequence, hence some way to include it in FCB located at flash's first 512 Bytes. So its also no option to implement some user code performing this operation (like above "WriteQEReg()" example).

It's also still not sure that the QE bit is the root cause. As asked in my initial post I'm actually interested in the things the Flashloader tool performs when receiving the command "configure-memory". Does it "only" configure QE bit?

Regards

André

0 Kudos
194 Views
NXP TechSupport
NXP TechSupport

Hi andre_rex,

   About the configure-memory, you need to refer to the blhost user manual, you can find it from the flashloader document:

 https://www.nxp.com/webapp/Download?colCode=IMX-RT1050-FLASHLOADER&appType=license

Flashloader_i.MXRT1050_GA\Flashloader_i.MXRT1050_GA\Flashloader_RT1050_1.1\doc

Kinetis blhost User's Guide.pdf

4.2.19 configure memory <memoryID> <addr>
Example: -- configure memory 1 0x20001000
Apply the configuration block at <addr> to external memory with ID <memoryID>. The specified configuration block must
have been previously written to memory using the write-memory command. The format of the configuration block is described
in the Kinetis Bootloader v2.0.0 Reference Manual (document KBTLDR200RM).

 

and MCUX Flashloader Reference Manual.pdf

Table 8-2. Memory ID for external memory devices

 

So,  the configure memory can used to configure the external memory devices, please check the related IDs.

 

Best Regards,

Kerry

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

 

 

0 Kudos
196 Views
NXP TechSupport
NXP TechSupport

Hi André Rex,

  QE bit in the QSPI new flash, just need to write once, after it is wrote, you don't need to write it any more.

  About the related instruction to set the QE with ROM, you can refer to program_flexspinor_image_qspinor_status_reg1_bit6.bd, which can be found in the SDK:

SDK_2.8.0_EVKB-IMXRT1050\middleware\mcu-boot\bin\Tools\bd_file\imxrt105x

# The source block assign file name to identifiers
sources {
 myBinFile = extern (0);
}

constants {
    kAbsAddr_Start= 0x60000000;
    kAbsAddr_Ivt = 0x60001000;
    kAbsAddr_App = 0x60002000;
}

# The section block specifies the sequence of boot commands to be written to the SB file
section (0) {

    #1. Prepare Flash option
    # 0xc0000105 is the tag for Serial NOR parameter selection
    # bit [31:28] Tag fixed to 0x0C
    # bit [27:24] Option size fixed to 0
    # bit [23:20] Flash type option
    #             0 - QuadSPI SDR NOR 
    #             1 - QUadSPI DDR NOR
    #             2 - HyperFLASH 1V8 
    #             3 - HyperFLASH 3V
    #             4 - Macronix Octal DDR 
    #             6 - Micron Octal DDR 
    #             8 - Adesto EcoXIP DDR
    # bit [19:16] Query pads (Pads used for query Flash Parameters)
    #             0 - 1
    #             2 - 4
    #             3 - 8
    # bit [15:12] CMD pads (Pads used for query Flash Parameters)
    #             0 - 1
    #             2 - 4
    #             3 - 8
    # bit [11: 08] Quad Mode Entry Setting
    #             0 - Not Configured, apply to devices: 
    #                 - With Quad Mode enabled by default or
    #                 - Compliant with JESD216A/B or later revision
    #             1 - Set bit 6 in Status Register 1
    #             2 - Set bit 1 in Status Register 2
    #             3 - Set bit 7 in Status Register 2
    #             4 - Set bit 1 in Status Register 2 by 0x31 command 
    # bit [07: 04]  Misc. control field
    #             3 - Data Order swapped, used for Macronix OctaFLASH devcies only (except MX25UM51345G)
    #             4 - Second QSPI NOR Pinmux
    # bit [03: 00] Flash Frequency, device specific
    load 0xc0000105 > 0x2000;
    # Configure QSPI NOR FLASH using option a address 0x2000
    enable flexspinor 0x2000;
    
    #2 Erase flash as needed.(Here only 256KBytes are erased)
    erase 0x60000000..0x60010000;

    #3. Program config block
    # 0xf000000f is the tag to notify Flashloader to program FlexSPI NOR config block to the start of device
    load 0xf000000f > 0x3000;
    # Notify Flashloader to response the option at address 0x3000
    enable flexspinor 0x3000;
    
    #5. Program image
    load myBinFile > kAbsAddr_Ivt;
}

 load 0xc0000105 > 0x2000;

# bit [11: 08] Quad Mode Entry Setting
# 0 - Not Configured, apply to devices:
# - With Quad Mode enabled by default or
# - Compliant with JESD216A/B or later revision
# 1 - Set bit 6 in Status Register 1
# 2 - Set bit 1 in Status Register 2
# 3 - Set bit 7 in Status Register 2
# 4 - Set bit 1 in Status Register 2 by 0x31 command

You select the adesto item is the same with my ISSI, in factor, normally the QSPI flash is nearly the same, just need to care about the QE bit position.

 So, if you are in the serial download mode, you still can use your previous command:

./blhost -- fill-memory 0x2000 4 0xc0000105 word

If you want to use the RAM code, you also can refer to the sdk flexspi_nor_polling_transfer.c, 

    /* Enter quad mode. */
    status = flexspi_nor_enable_quad_mode(EXAMPLE_FLEXSPI);
    if (status != kStatus_Success)
    {
        return status;
    }


status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base)
{
    flexspi_transfer_t flashXfer;
    status_t status;
    uint32_t writeValue = FLASH_QUAD_ENABLE;

    /* Write enable */
    status = flexspi_nor_write_enable(base, 0);

    if (status != kStatus_Success)
    {
        return status;
    }

    /* Enable quad mode. */
    flashXfer.deviceAddress = 0;
    flashXfer.port          = kFLEXSPI_PortA1;
    flashXfer.cmdType       = kFLEXSPI_Write;
    flashXfer.SeqNumber     = 1;
    flashXfer.seqIndex      = NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG;
    flashXfer.data          = &writeValue;
    flashXfer.dataSize      = 1;

    status = FLEXSPI_TransferBlocking(base, &flashXfer);
    if (status != kStatus_Success)
    {
        return status;
    }

    status = flexspi_nor_wait_bus_busy(base);

    /* Do software reset. */
    FLEXSPI_SoftwareReset(base);

    return status;
}

#define FLASH_QUAD_ENABLE        0x40

Wish it helps you!

If you still have questions about it, please kindly let me know.

Best Regards,

Kerry

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
146 Views
Contributor II

Hi @kerryzhou,

many thanks for your code example. Unfortunately an application is not an option as it requires itself being executed - which was not the case as the device didn't boot at all.

But after quite some investigation the root cause more and more points to the programmer device/software not correctly configuring the QE bit within initial NOR flash programming task (although suggesting to do so). Hence in parallel we opened a request with the programmer's manufacturer.

For i.MX I was finally able to configure FCB accordingly to make the ROM loader enabling QE bit implicitly (writing 0x40 to StatusRegister1 with 'Write Status Register' (WRSR, 0x01) command):

const flexspi_nor_config_t nor_spi_config = {
  .memConfig = {
    // ...
    .deviceModeCfgEnable = 1u,
    .deviceModeType = kDeviceConfigCmdType_QuadEnable,
    .deviceModeSeq = {
      .seqId = NOR_CMD_LUT_SEQ_IDX_WRITE_STATUS,
      .seqNum = 1u,
    },
    .deviceModeArg = 0x40, // set Bit6 (=QE, quad enable)
    // ...
    .lookupTable = {
      // ...
      /* 4 - WriteStatus */
      [NOR_CMD_LUT_SEQ_IDX_WRITE_STATUS*4+0] =
                      FLEXSPI_LUT_SEQ(CMD_SDR       , FLEXSPI_1PAD, 0x01, // WRSR
                                      WRITE_SDR     , FLEXSPI_1PAD, 0x01),
      // ...
    },
  },
};

We could use this as workaround as long as the programmer issue isn't fixed - although I'm not happy with it as it writes the status register on each device start.

Nevertheless I've learned a lot about the whole i.MX ROM loader mechanism and would like to thank you for your patience.


Kind regards

André

View solution in original post