Ruffian Heng embedded: know the lookuptable in the fdcb of i.mxrt startup head from the beginning

Time:2021-8-13

Hello, I’m ruffian Heng, a serious technical ruffian. What ruffian Heng introduced to you today isi. Lookuptable in fdcb of mxrt startup head

There are usually many peripheral modules inside an MCU. These peripheral modules are the essence of differentiated products made by MCU manufacturers and the core competitiveness of manufacturers (especially those manufacturers producing arm Cortex-M core MCU). Sometimes it is not necessary to know all the peripherals when developing MCU, because some peripherals are not necessarily used in the project, but to play with NXP i.mxrt Series MCU, one peripheral must be understood, which is flexspi. This peripheral is responsible for connecting with external serial nor flash to read application instructions and data in external nor flash, Serial nor flash is the preferred startup device for i.mxrt.

So what mechanism in the flexspi peripheral module realizes the reading function of application instructions and data in flash? Ruffian Heng starts with the setting of lookuptable in fdcb of i.mxrt startup head:

1、 Why can i.mxrt be started from an external flash XIP?

About the implementation principle of serial nor flash XIP, ruffian Heng was actually in a previous articlePrinciple of debugging in serial nor flash XIPThe second subsection ofi. Mxrt flexspi peripheral featuresYes, flexspi, a peripheral, implements the function of fetching instructions from any address of serial flash, which is a prerequisite.

With the precondition of fetching from any flash address, after the i.mxrt chip is powered on, the bootrom only needs to configure the flexspi peripheral to the specified working state (see details here)Initialization process of serial nor flash startup in i.mxrt1050 series ROMIn this paper, especially the second flexspi initialization mentioned in the last section, the content discussed in this paper actually belongs to the state after the second initialization). The flexspi peripheral configuration information comes entirely from the startup header fdcb (512bytes in total). After the flexspi configuration is completed, the bootrom gives the CPU control to the application program, which completes the startup task.

Qspiflash below_ Config is a typical fdcb header used in the i.mxrt SDK package for QSPI nor flash that conforms to JEDEC SFDP standard and has a capacity of 8MB. This startup header configures flexspi into four wire mode, 100MHz clock frequency and Quad I / O fast read timing mode (note that the writing method of lookuptable setting in this header is not standard, and the mode sequence and stop sequence are not explicitly written, which will be described in detail later):

When the PC starts to point to the flexspi mapping space (0x60000000 – 0x607fffff) to execute the user program, flexspi silently sends the specified instruction data to the CPU behind it, as shown by the green arrow in the following figure. Instruction data from external flash through IO_ CTL and according to seq_ The timing specified by CTL is sent to Rx_ FIFO to AHB_ RX_ BUF, finally through AHB_ The CTL is sent to the AHB bus of the system to be accessible by the CPU. The most important automation link in the whole process is actually SEQ in the yellow box_ CTL, this is SEQ_ CTL drives flexspi to send read access timing meeting flash requirements at any time.

2、 Seq for flexspi peripherals_ How does CTL work?

Through the analysis in the previous section, we know that it is SEQ in flexspi_ CTL component realizes the core flash access timing control, then seq_ CTL, how do we control it? Don’t worry. At this time, the LUT comes on stage. LUT is the abbreviation of look up table. It is actually a storage area inside flexspi (i.e. flexspi – > lutx register). Its organizational structure is as follows. LUT is composed of multiple sequences (for example, 16 on i.mxrt1050). Each sequence is composed of up to 8 instructions. The size of each instruction is 16bits, which is divided into opcode (sequence number) + num_ Pads (pin mode) + operand (sequence parameter value).

Each instruction can be understood as a flash access transmission sub sequence (such as command sequence, address sequence, mode sequence, dummy sequence, read / write data sequence, stop sequence, etc.), many basic instructions are pre implemented in the flexspi peripheral module, and the opcode in the instruction is the pre implemented sequence number. Opcode is numbered as follows:

Command sequence:

With these basic instructions, we can freely combine them (up to 8) to get the complete transmission sequence we want. For example, the most common Quad I / O read SDR transmission timing is determined by CMD_ SDR + RADDR_ SDR + MODE8_ SDR + DUMMY_ SDR + READ_ SDR + stop consists of six subsequences, as shown in the following table:

  • Note: about read_ The parameter value setting (i.e. read data length) of SDR needs special explanation. This parameter is only valid for the access timing of IP CMD mode; For the access timing of AHB CMD mode, this parameter value setting is invalid, and the actual read data length is flexibly determined by AHB RX buffer strategy.

From the pin signal, the complete Quad I / O read SDR transmission timing is shown in the figure below.It should be noted that in terms of flexspi peripherals themselves, mode8_ SDR sequence and dummy_ SDR sequences are independent of each other, but on many flash chips, mode8_ The two clock cycles occupied by SDR are also included in the total dummy clock cycles

A maximum of 16 sequences can be stored in the LUT. For XIP execution, only one read access timing (such as the most commonly used Quad I / O read SDR transmission timing) is required. If it is IAP, you also need to add erase timing, write access timing, write enable timing, read status register timing, etc. These sequences stored in LUT in advance are triggered by the user on demand to realize various types of flash access, which is SEQ_ CTL working mechanism.

3、 How is the lookuptable in fdcb configured into flexspi – > LUT?

In terms of flexspi peripheral module design, the 16 sequences in the LUT have the same status. For XIP execution, the necessary read access timing can be placed at any sequence position in the LUT. Only the ardseqid bit in flexspi – > flshxcr2 register (x can take A1 / A2 / B1 / B2, which is determined according to the flash pin connection) can indicate the position (index) of the read access timing in the LUT.

ButAfter all, the application is booted by bootrom. Bootrom has its own set of configuration flexspi rules, which will kill CMD_ LUT_ SEQ_ IDX_ The read position, that is, the read access sequence must be the first sequence in flexspi – > LUT [], because flexspi – > flshxcr2 [ardseqid] is configured to 0 by bootrom. Therefore, when preparing the fdcb, the first sequence in the lookuptable must place the read access sequence

Let’s take another look at the flexspi initialization function in bootrom, which basically initializes flexspi in the peripheral module_ After init() completes, then flexspi_ update_ LUT () is called to update the LUT once and ends directly. In fact, this LUT update just fills the lookuptable [0] – lookuptable [3] (the first sequence) in the fdcb into flexspi – > LUT [0] – flexspi – > LUT [3]. As for why you sometimes see more than one sequence in the lookuptable in the fdcb, this ruffian Heng has another article to talk about later.

status_ t flexspi_ nor_ flash_ init(uint32_ t instance, flexspi_ nor_ config_ t *config)

4、 Set an instance of lookuptable in fdcb

We use the typical flash model is25wp064ajble matched on the official evk of i.mxrt for actual combat. The following figure shows the fast read Quad I / O sequence of the flash. In this sequence diagram, the parameter values of command sequence, address sequence and dummy sequence are clear, but the parameter values of mode sequence and read data sequence are not clear. Let’s make it clear, In the mode sequence, we set the mode bits to 0x00 (in fact, as long as it is not 0xax), that is, non continuous read mode; In fact, the data out byte in the read data sequence cannot be set (as mentioned above, it is automatically controlled by RX buffer policy under AHB access). Just write a non-zero value.

Based on the above real FLASH read data transmission sequence diagram, our corresponding settings in lookuptable in fdcb should be as follows:

#define CMD_ LUT_ SEQ_ IDX_ READ        0

5、 The AHB read access to the flexspi mapping area will certainly start SEQ_ Does CTL work?

When we put the correct fdcb in place, the bootrom configures the flexspi normally, and starts the application, the CPU starts to access the application instructions directly from the AHB of the flexspi mapping area step by step. Does each CPU access make seq_ Does the CTL component send a read access timing according to the settings in the LUT? Not really!

We know that the i.mxrt series will have L1 cache. If the instruction content in an address of flash is cached in L1 cache, the current CPU does not need to retrieve the instruction at the flash address from flash again. The CPU can get the instruction directly from the cache. At this time, seq_ CTL will not work.

Even if the instructions required by the CPU are not cached in L1 cache, if the cacheable and prefetch functions of flexspi are turned on, the instructions required by the CPU may also be cached in AHB Rx / TX buffer. If the required instruction is indeed cached in the AHB buffer, seq_ CTL still won’t work.

Only if the instruction required by the CPU is brand new and there is no cache at all, seq_ CTL will really start working. Press LUT setting to send read data access timing to flash.

6、 AHB reads and accesses seq_ How long does CTL work once to obtain data?

As mentioned earlier, we cannot effectively set the data out byte in the read data sequence in the lookuptable, because the length of the next read under AHB access is controlled by the RX buffer policy. In i.mxrt1050, the total size of AHB RX buffer is 1KB, which is divided into four parts: AHB RX buffer 0 – AHB RX buffer 3. The size of each buffer is configurable. The specific configuration is in the following flexspi – > ahbrxbufxcr0 register:

Bootrom uses the following flexspi_ config_ ahb_ The buffers() function configures the AHB buffer, that is, it turns on the prefetch function of flexspi, and sets the first three flexspi – > ahbrxbufxcr0 [BUFSZ] to 0 (retains the default configuration of flexspi – > ahbrxbuf3cr0 [BUFSZ], which is actually equivalent to setting all four RX buffers to 0). According to the manual, This configuration means that only buffer3 is enabled as the only RX buffer (when buffer3 is the only buffer, its buffersz setting is invalid, and its real size is always equal to the total buffer size), and the size of buffer3 is 1KB. So now we know that when prefetch is on, seq_ CTL will read 1KB data at a time. Of course, the prefetch function can be turned off in the application. If the prefetch is not enabled, seq_ The data obtained by CTL work at one time is determined by AHB burst read strategy (a separate article will be written about this ruffian Heng).

status_t flexspi_config_ahb_buffers(FLEXSPI_Type *base, flexspi_mem_config_t *config)
{
    uint32_t temp;
    uint32_t index;
    status_t status = kStatus_InvalidArgument;

    do
    {
        if ((base == NULL) || (config == NULL))
        {
            break;
        }

        if (config->deviceType == kFlexSpiDeviceType_SerialNOR)
        {
            // Configure AHBCR
            temp = base->AHBCR & (~FLEXSPI_AHBCR_APAREN_MASK);
            // Remove alignment limitation when Flash device works under DDR mode.
            temp |= FLEXSPI_AHBCR_READADDROPT_MASK;
#if FLEXSPI_FEATURE_HAS_PARALLEL_MODE
            if (flexspi_is_parallel_mode(config))
            {
                temp |= FLEXSPI_AHBCR_APAREN_MASK;
            }
#endif // FLEXSPI_FEATURE_HAS_PARALLEL_MODE
            base->AHBCR = temp;
        }

        // Enable prefetch feature
        base->AHBCR |= FLEXSPI_AHBCR_PREFETCHEN_MASK;

        // Skip AHB buffer configuration if corresponding bit is set
        if ((config->controllerMiscOption & (1<AHBRXBUFCR0[index] &=
                ~(FLEXSPI_AHBRXBUFCR0_BUFSZ_MASK | FLEXSPI_AHBRXBUFCR0_MSTRID_MASK | FLEXSPI_AHBRXBUFCR0_PRIORITY_MASK);
        }
        status = kStatus_Success;

    } while (0);

    return status;
}

So far, the lookuptable ruffian Heng in the fdcb of i.mxrt startup head has been introduced. Where are the applause~~~

Welcome to subscribe

The article will be published to me at the same timeBlog Park home pageCSDN home pageZhihu home pageWeChat official accountOn the platform.

Wechat search“Ruffian scale“Or scan the QR code below to see it for the first time on the mobile phone.