imx rt: FlexSPI lookup tables

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

imx rt: FlexSPI lookup tables

ソリューションへジャンプ
401件の閲覧回数
bp1979
Senior Contributor I

I am having a hard time understanding how the nor polling SDK example deals with lookup tables.

From the reference manual, I understand that the LUT makes room for N sequences. Each sequence consists of 8 * 16bit instructions.

The SDK example defines a LUT sequence as an array of 4 32bit words (a bit weird, but sure, same length).

Then the SDK example defines the entire LUT for the internal flash memory device that comes with the 1024 CPU.

const uint32_t customLUT[CUSTOM_LUT_LENGTH] = {
    /* Normal read mode -SDR */
    /* 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),

    /* 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),

    /* Enable Quad mode */
    [4 * NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x31, 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),
};

 The macro FLEXSPI_LUT_SEQ creates the "LUT sequence" which is the array of 4 * 32bit words, equal to 8 * 16bit instructions.

Then, every time an IP command is send to FlexSPI, it refers to a SeqNumber and a SeqIndex. The SeqNumber is practically always 1. Why? Shouldn't this index match the index in the array?

 

0 件の賞賛
1 解決策
382件の閲覧回数
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @bp1979 ,

    I think you mentioned the code like the following IP method:

status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address)

{

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 */

flashXfer.deviceAddress = address;

flashXfer.port = FLASH_PORT;

flashXfer.cmdType = kFLEXSPI_Command;

flashXfer.SeqNumber = 1;

flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITEENABLE;

 

status = FLEXSPI_TransferBlocking(base, &flashXfer);

 

if (status != kStatus_Success)

{

return status;

}

 

flashXfer.deviceAddress = address;

flashXfer.port = FLASH_PORT;

flashXfer.cmdType = kFLEXSPI_Command;

flashXfer.SeqNumber = 1;

flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_ERASESECTOR;

status = FLEXSPI_TransferBlocking(base, &flashXfer);

 

if (status != kStatus_Success)

{

return status;

}

 

status = flexspi_nor_wait_bus_busy(base);

 

/* Do software reset. */

FLEXSPI_SoftwareReset(base);

 

#if defined(CACHE_MAINTAIN) && CACHE_MAINTAIN

flexspi_nor_enable_cache(cacheStatus);

#endif

 

return status;

}

To this situation, normally, the seqNumber is set to 1, as it just call 1 number.

Then, it use the SeqIndex to the related LUT commander to find the detail operation.

So, it's correct.

 

Wish it helps you!

Best Regards,

Kerry

元の投稿で解決策を見る

2 返答(返信)
383件の閲覧回数
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @bp1979 ,

    I think you mentioned the code like the following IP method:

status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address)

{

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 */

flashXfer.deviceAddress = address;

flashXfer.port = FLASH_PORT;

flashXfer.cmdType = kFLEXSPI_Command;

flashXfer.SeqNumber = 1;

flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITEENABLE;

 

status = FLEXSPI_TransferBlocking(base, &flashXfer);

 

if (status != kStatus_Success)

{

return status;

}

 

flashXfer.deviceAddress = address;

flashXfer.port = FLASH_PORT;

flashXfer.cmdType = kFLEXSPI_Command;

flashXfer.SeqNumber = 1;

flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_ERASESECTOR;

status = FLEXSPI_TransferBlocking(base, &flashXfer);

 

if (status != kStatus_Success)

{

return status;

}

 

status = flexspi_nor_wait_bus_busy(base);

 

/* Do software reset. */

FLEXSPI_SoftwareReset(base);

 

#if defined(CACHE_MAINTAIN) && CACHE_MAINTAIN

flexspi_nor_enable_cache(cacheStatus);

#endif

 

return status;

}

To this situation, normally, the seqNumber is set to 1, as it just call 1 number.

Then, it use the SeqIndex to the related LUT commander to find the detail operation.

So, it's correct.

 

Wish it helps you!

Best Regards,

Kerry

374件の閲覧回数
bp1979
Senior Contributor I

I think I am confusing the index with the number. My bad. Thx

0 件の賞賛