Boot rom enable QE bit in the nor flash

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

Boot rom enable QE bit in the nor flash

Jump to solution
3,705 Views
MCW
Contributor III

Hi all, 

Accroding to https://community.nxp.com/t5/i-MX-RT/boot-header-for-qspi-flash/td-p/1642446 

I am able to set QE bit to 1 successfully by adding QE enable related code in evbmimxrt1060_flexspi_nor_cofig.c file.

And then I considered if I set the QE bit to 0 manually and reboot my board, the QE bit should be set to 1 again.

However, the QE bit was still 0 (not expected) from my experiment. 

Is there any problem in my experiement flow?

 

Best Regards,

Doris

0 Kudos
1 Solution
2,788 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @MCW ,

    Sorry for my later information.

    Today, our internal side already have the summarize, after a lot testing internally, even with the MXIC FAE debug together in NXP.

    The issue until now, just related to the MXIC QSPI flash with the FCB to enable the QE.

   Reason: MXIC QSPI IO2/IO3 have the reset function, if the QSPI flash is not enable the QE function, the IO2/IO3 also have the reset funtion, and after reset, it nees at least 30us recovery time. But if the QSPI enable the QE, then the IO2/IO3 reset function is disabled.

  The issues is caused by, the ROM will do a reset after boot, and also will pull low the IO2/IO3, it will cause the MXIC QSPI flash enter reset, then ROM even can't use the 1bit to readout the FCB, it cause the issues.

  So, until now, maybe a sad story to you, to the MXIC QSPI, this issue can't be resolved, as the ROM is fixed, but we also tested a lot of other flash no issues, ISSI WP, winbond etc.  We also report to the internal R&D team.

  So, to you, two way: MXIC chip, use auto probe, or use other flash if you must use the FCB QE enabe function.

Wish it helps you!

If you still have questions about it, please help to create the new case, thanks.

Best Regards,

Kerry

View solution in original post

28 Replies
1,830 Views
MCW
Contributor III

Hi @kerryzhou ,

 

I have changed the qspi flash with MX25L12833F on the MIMXRT1060-EVK, but I cannot to program the blink led code successfully. The figure shows the information that I got.

led_blink_fail.jpg

I also run the evkmimxrt1060_flexspi_nor_polling_transfer. Normally, the log should print out the information about qspi flash.  Nevertheless, accroding to below logs, I think MX25L12833F was not accessed correctlly.

qspi_flash_log.jpg

For more details, I didn't modify any code and only replaced the qspi flash by MX25L12833F.

HW.jpg

 

Best regards,

Doris

0 Kudos
1,750 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @MCW ,

   From your picture, you download the code to the flash, you need to download to the internal RAM, and debug it, check the external memory works or not at first.

   BTW, you need to check the flash voltage, in my memory, the EVK is default 1.8V, so, your flash is 1.8V or 3.3V? You need to use the correct flash VDD voltage.

Best Regards,

Kerry

0 Kudos
1,082 Views
MCW
Contributor III

Hi @kerryzhou ,

 

Appreciate your suggestion. It works when the MX25L12833F was supplied by 3.3V.

The testing result with the MIMXRT1060-EVK is the same as using my board, which means the blink led code in MX25L12833F doesn't run after I disable QE bit by evkmimxrt1060_flexspi_nor_polling_transfer.

Here is my steps:

1. Make sure I can access the MX25L12833F firstly, and then program blink led code to the MX25L12833F

SFDP.jpg

2. Disable QE bit by evkmimxrt1060_flexspi_nor_polling_transfer, next,  reboot the MIMXRT1060-EVK

 

Best regards,

Doris

0 Kudos
1,046 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @MCW ,

  Good!

   What about the disable and enable QE, whether that printf result is OK or not?

   Your issue is interesting, I will try to buy the MX25L12833F chip and test it on my side.

    Please also upload your code which readout the SFDP code, I will check my situation and compare it with you.

 

Best Regards,

Kerry

0 Kudos
974 Views
MCW
Contributor III

Hi @kerryzhou ,

 

Yes, the log of disable/enable QE is correct.

Below I have attached a part of my code about SFDP.

Today, I do more tests related to this issue with MX25L12833F and my customize board, but the MX25L12833F is completely new one.

Here is my steps:

1. Directly program the code which contains QE enable related code in evbmimxrt1060_flexspi_nor_cofig.c file to the qspi flash by flash programmer, instead of Mcuxpresso or SEGGER J-Flash

2. Reboot my board. In this step, the code in the nor flash doesn't run because I don't get any printf result on the putty.

3. I connect the target (IMXRT) by SEGGER J-Flash.

螢幕擷取畫面 2023-06-02 084705.jpg

4. Reboot my board again. The code does run correctly.

 According to the result,  I have two questions.

1. Why does the code not run in the step2?

2. Why does the code run after I connect the target?

 

Add this function in flexspi_nor_flash_ops.c:

 

status_t flexspi_nor_flash_read_sfdp(FLEXSPI_Type *base, uint32_t dstAddr, const uint32_t *src, uint32_t length)
{
    status_t status;
    flexspi_transfer_t flashXfer;

#if defined(CACHE_MAINTAIN) && CACHE_MAINTAIN
    flexspi_cache_status_t cacheStatus;
    flexspi_nor_disable_cache(&cacheStatus);
#endif

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

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

    flashXfer.deviceAddress = dstAddr;
    flashXfer.port          = FLASH_PORT;
    flashXfer.cmdType       = kFLEXSPI_Read;
    flashXfer.SeqNumber     = 1;
    flashXfer.seqIndex      = NOR_CMD_LUT_SEQ_IDX_READSFDP;
    flashXfer.data          = (uint32_t *)src;
    flashXfer.dataSize      = length;
    status                  = FLEXSPI_TransferBlocking(base, &flashXfer);

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

    status = flexspi_nor_wait_bus_busy(base);

    /* Do software reset or clear AHB buffer directly. */
#if defined(FSL_FEATURE_SOC_OTFAD_COUNT) && defined(FLEXSPI_AHBCR_CLRAHBRXBUF_MASK) && \
    defined(FLEXSPI_AHBCR_CLRAHBTXBUF_MASK)
    base->AHBCR |= FLEXSPI_AHBCR_CLRAHBRXBUF_MASK | FLEXSPI_AHBCR_CLRAHBTXBUF_MASK;
    base->AHBCR &= ~(FLEXSPI_AHBCR_CLRAHBRXBUF_MASK | FLEXSPI_AHBCR_CLRAHBTXBUF_MASK);
#else
    FLEXSPI_SoftwareReset(base);
#endif

#if defined(CACHE_MAINTAIN) && CACHE_MAINTAIN
    flexspi_nor_enable_cache(cacheStatus);
#endif

    return status;
}

 

 flexspi_nor_polling_transfer.c:

 

#include "fsl_flexspi.h"
#include "app.h"
#include "fsl_debug_console.h"
#include "fsl_cache.h"

#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "fsl_common.h"
/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define VENDOR 1
#define SFDP 0
#define ENABLEWEL 1
#define QE 1

/*******************************************************************************
 * Variables
 ******************************************************************************/
/* Program data buffer should be 4-bytes alignment, which can avoid busfault due to this memory region is configured as
   Device Memory by MPU. */
SDK_ALIGN(static uint8_t s_nor_program_buffer[256], 4);
static uint8_t s_nor_read_buffer[256];

extern status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address);
extern status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t dstAddr, const uint32_t *src);
extern status_t flexspi_nor_get_vendor_id(FLEXSPI_Type *base, uint8_t *vendorId);
extern status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base);
extern status_t flexspi_nor_erase_chip(FLEXSPI_Type *base);
extern status_t flexspi_nor_flash_read_sfdp(FLEXSPI_Type *base, uint32_t dstAddr, const uint32_t *src, uint32_t length);
extern void flexspi_nor_flash_init(FLEXSPI_Type *base);
extern status_t flexspi_nor_wel_enable(FLEXSPI_Type *base);
extern uint32_t flexspi_nor_get_status_reg(FLEXSPI_Type *base);
/*******************************************************************************
 * Code
 ******************************************************************************/
flexspi_device_config_t deviceconfig = {
    .flexspiRootClk       = 133000000,
    .flashSize            = FLASH_SIZE,
    .CSIntervalUnit       = kFLEXSPI_CsIntervalUnit1SckCycle,
    .CSInterval           = 2,
    .CSHoldTime           = 3,
    .CSSetupTime          = 3,
    .dataValidTime        = 0,
    .columnspace          = 0,
    .enableWordAddress    = 0,
    .AWRSeqIndex          = 0,
    .AWRSeqNumber         = 0,
    .ARDSeqIndex          = NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD,
    .ARDSeqNumber         = 1,
    .AHBWriteWaitUnit     = kFLEXSPI_AhbWriteWaitUnit2AhbCycle,
    .AHBWriteWaitInterval = 0,
};

const uint32_t customLUT[CUSTOM_LUT_LENGTH] = {
    /* Normal read mode -SDR */
    [4 * NOR_CMD_LUT_SEQ_IDX_READ_NORMAL] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x03, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
    [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),

    /* Fast read mode - SDR */
    [4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x0B, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
    [4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST + 1] = FLEXSPI_LUT_SEQ(
        kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_1PAD, 0x08, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),

    /* Fast read quad mode - SDR */
    [4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD] =
        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, 0x06, kFLEXSPI_Command_READ_SDR, kFLEXSPI_4PAD, 0x04),

    /* Read extend parameters */
    [4 * NOR_CMD_LUT_SEQ_IDX_READSTATUS] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x81, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),

    /* Write Enable */
    [4 * NOR_CMD_LUT_SEQ_IDX_WRITEENABLE] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x06, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),

    /* Erase Sector  */
    [4 * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x20, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18), //0xD7

    /* Page Program - single mode */
    [4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_SINGLE] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x02, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
    [4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_SINGLE + 1] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),

    /* Page Program - quad mode */
    [4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x32, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
    [4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD + 1] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_4PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),

    /* Read ID */
    [4 * NOR_CMD_LUT_SEQ_IDX_READID] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x9F, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),

    /* Set Quad mode */
    [4 * NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG] =
        //FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x01, kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04),
    	FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x01, kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04),

    /* Enter QPI mode */
    [4 * NOR_CMD_LUT_SEQ_IDX_ENTERQPI] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x35, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),

    /* Exit QPI mode */
    [4 * NOR_CMD_LUT_SEQ_IDX_EXITQPI] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_4PAD, 0xF5, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),

    /* Read status register */
    [4 * NOR_CMD_LUT_SEQ_IDX_READSTATUSREG] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x05, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),

    /* Erase whole chip */
    [4 * NOR_CMD_LUT_SEQ_IDX_ERASECHIP] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xC7, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
#if SFDP
	[4 * NOR_CMD_LUT_SEQ_IDX_READSFDP] =
		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x5A, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
	[4 * NOR_CMD_LUT_SEQ_IDX_READSFDP + 1] =
		FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_1PAD, 0x08, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
#endif
#if ENABLEWEL
	[4 * NOR_CMD_LUT_SEQ_ENABLEWEL] =
	    FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x06, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x0),
#endif

};


int main(void)
{
    uint32_t i = 0;
    status_t status;
    uint8_t vendorID = 0;

    BOARD_ConfigMPU();
    BOARD_InitBootPins();
    BOARD_InitBootClocks();
    BOARD_InitDebugConsole();

    flexspi_nor_flash_init(EXAMPLE_FLEXSPI);

    PRINTF("\r\nFLEXSPI example started!\r\n");

#if VENDOR
    /* Get vendor ID. */
    status = flexspi_nor_get_vendor_id(EXAMPLE_FLEXSPI, &vendorID);
    if (status != kStatus_Success)
    {
        return status;
    }
    PRINTF("Vendor ID: 0x%x\r\n", vendorID);
#endif
    uint32_t status_reg = 0;
    status_reg = flexspi_nor_get_status_reg(EXAMPLE_FLEXSPI);
    PRINTF("Status register: 0x%x\r\n", status_reg & 0xFF);
#if ENABLEWEL
    flexspi_nor_wel_enable(EXAMPLE_FLEXSPI);
    status_reg = flexspi_nor_get_status_reg(EXAMPLE_FLEXSPI);
    PRINTF("Status register after enable WEL: 0x%x\r\n", status_reg);
#endif

#if SFDP
    // read sfdp
    uint32_t str_addr = 0x0;
    uint32_t rev_buf[16];
    memset(&rev_buf[0], 0, sizeof(rev_buf));
    flexspi_nor_flash_read_sfdp(EXAMPLE_FLEXSPI, str_addr, &rev_buf[0], 20);
    PRINTF("\r\n****** SFDP header ******\r\n");
    PRINTF("SFDP signature:  0x%x\r\n", rev_buf[0]);
    PRINTF("SFDP header revision:  %x.%x\r\n", (rev_buf[1]&0xFF00)>>8, rev_buf[1]&0xFF);
    PRINTF("Parameter revision:  %x.%x\r\n", (rev_buf[2]&0xFF0000)>>16, (rev_buf[2]&0xFF00)>>8);
    PRINTF("Manufacture ID: 0x%x\r\n", rev_buf[4]&0xFF);
    str_addr = rev_buf[3] & 0xFFFFFF;
    memset(&rev_buf[0], 0, sizeof(rev_buf));
    flexspi_nor_flash_read_sfdp(EXAMPLE_FLEXSPI, str_addr, &rev_buf[0], 64);
    PRINTF("\r\n****** SFDP table ******\r\n");
    for (int i=0; i<16; i++){
    	PRINTF("SFDP[%d]: 0x%x\r\n", i, rev_buf[i]);
    }


#endif

#if !(defined(XIP_EXTERNAL_FLASH))
    /* Erase whole chip . */
    PRINTF("Erasing whole chip over FlexSPI...\r\n");

    status = flexspi_nor_erase_chip(EXAMPLE_FLEXSPI);
    if (status != kStatus_Success)
    {
        return status;
    }
    PRINTF("Erase finished !\r\n");

#endif
#if QE
    /* Enter quad mode. */
    status = flexspi_nor_enable_quad_mode(EXAMPLE_FLEXSPI);
    if (status != kStatus_Success)
    {
        return status;
    }
    else
    {
    	PRINTF("Set QSPI mode...\r\n");
    	SDK_DelayAtLeastUs(2000000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
    	status_reg = 0x0;
    	status_reg = flexspi_nor_get_status_reg(EXAMPLE_FLEXSPI);
    	PRINTF("Read back status register: 0x%x\r\n", status_reg & 0xFF);

    }
#endif
    while (1)
    {
    }
}

 

 

Best regards,

Doris

0 Kudos
887 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @MCW ,

  Thanks for your test result sharing.

   So, after you enable the QE bit manually, not the FCB, you can boot, right?

   Now, just the FCB enable the QE bit can't work?

   Please keep patient, I already buy your mentioned QSPI flash, it is on the way, when I get it, I will test it on my EVK, then we can discuss it later.

   Thanks a lot for your understanding.

Best Regards,

Kerry

0 Kudos
728 Views
MCW
Contributor III

Hi @kerryzhou ,

 

Yes, I can enable the QE bit, and then the code in the nor flash runs.

The summary you mentioned is right.

Thanks for your help.

 

Best regards,

Doris

0 Kudos
667 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @MCW ,

  OK, got it!

   My chip will be get on the next week, when I get it, I will help you test it.

   If I meet any issues, I will also check it internally, any updated information, will let you know.

   Also, thanks so much for your effort!

 

Best Regards,

Kerry