RT1052学习笔记(1)- FlexSPI启动

这篇文章分析RT1052芯片从FlexSPI上电启动到执行第一条指令的全过程

  • 设置RT1052从FlexSPI启动
  • FlexSPI的初始化流程

boot ROM对FlexSPI的初始化

boot ROM是固化在芯片内部的一段启动代码,这个代码会在系统上电时被执行。boot ROM先对芯片进行必要的初始化后,会根据各个GPIO电平来选择一个启动方式,参考下面的列表选择一个boot device

  • fuse 没有被设置
  • BOOT_MODE[1:0] = 00b or 10b -> Internal Boot Mode
  • BOOT_CFG1[7:4] = 0000b -> Serial NOR boot via FlexSPI
  • BOOT_CFG1[1]=0 1->使能加密启动 0->不使能加密启动
  • BOOT_CFG1[3:2]->设置SPI的读前保持时间 (0–500us; 1–1ms; 2–3ms; 3–10ms)
  • BOOT_CFG2[2:0]->设置Flash 类型 (000b-Device supports 3B readby default,001bDevice supports 4B read by default)
  • BOOT_CFG2[3]->Infinite-Loop,不使能:0。(只有在调试的时候使用)

没有设置熔丝情况下,设置好这堆引脚电平为所需值,然后芯片就从SPI启动了

此时boot ROM会根据前面的BOOT_CFG1[3:2]和BOOT_CFG2[2:0]信息简单设置一下FlexSPI接口,此时默认SPI时钟为30MHz。然后读取Flash的前512字节信息。boot ROM会认为这是初始化Flash的信息,然后boot ROM根据这些预设的信息对FlexSPI接口进行初始化。初始化后就可以满速跑了。

具体流程参考下图:
RT1052学习笔记(1)- FlexSPI启动_第1张图片

这里就是前512字节数据,对FlexSPI接口的初始化。

const flexspi_nor_config_t spiflash_config = {
    .memConfig =
        {
            .tag = FLEXSPI_CFG_BLK_TAG,/*标志:FCFB*/
            .version = FLEXSPI_CFG_BLK_VERSION,/*版本:V1.4.0*/
            .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackInternally,/*内部环回*/
            .csHoldTime = 3u, /*保持时间*/
            .csSetupTime = 3u,/*建立时间*/
            .columnAddressWidth = 0u,/*列地址宽度*/
            .deviceModeCfgEnable = 1u,/*设备模式配置使能*/
            .deviceModeType = 1u,/*Quad 使能命令*/
            .deviceModeSeq.seqNum = 1u,/*LUT序列号*/
            .deviceModeSeq.seqId = 4u, /*LUT序列索引*/    
            .deviceModeArg = 0x000200,/*设置 QE=1(S9)*/
            .deviceType = kFlexSpiDeviceType_SerialNOR,/*设备类型为nor flash*/
            .sflashPadType = kSerialFlash_4Pads,/*设备数据总线为4*/
            .serialClkFreq = kFlexSpiSerialClk_133MHz,/*flash 时钟*/
            .sflashA1Size = 32u * 1024u * 1024u,      /*flash 大小32MBytes*/
            //.dataValidTime = {16u, 16u},
            .lookupTable =
                {
                    /*快速读命令(四线)*/
                    [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),
                    

                    /*读状态命令*/
                    [1*4]   = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x04),
                    /*写使能命令*/
                    [3*4]   = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0),      
                    /*擦除扇区命令*/
                    [5*4]   = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 0x04),
                    /*页编程命令(四线)*/
                    [9*4]   = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18),  
                    [9*4+1] = FLEXSPI_LUT_SEQ(WRITE_SDR,FLEXSPI_4PAD , 0x04, STOP, FLEXSPI_1PAD, 0),                  
                    /*整片擦除*/
                    [11*4]  = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xc7, STOP, FLEXSPI_1PAD, 0),                  
                },
        },
    .pageSize = 256u,/*页大小为256字节*/
    .sectorSize = 4u * 1024u,/*扇区大小为4k字节*/
};

然后就是加载image了

这里分成了四部分

  • Image vector table—a list of pointers located at a fixed address that the ROMexamines to determine where theother components of the program image arelocated.
  • Boot data—a table that indicates the program image location, program image size inbytes, and the plugin flag.
  • Device configuration data—IC configuration data.
  • User code and data.

1、IVT:这段数据在flash中的偏移地址为0x1000,大小为32字节,这个字段包含了各个域的入口
2、boot data:这段数据的入口包含在IVT中,所以位置不规定。内容主要为image的入口以及flash的大小
3、DCD:这段数据的入口也包含在IVT中,所以位置不规定。主要作用是通过一系列的命令对内部寄存器进行设置,已达到初始化外设flash以及SDRAM的目的。这段数据最大为1768字。
4、前3字段都是内置的boot ROM在初始化芯片时需要被读取的数据。初始化完成后会跳转到用户代码开始执行,也即Reset_handler

内置的boot ROM能够解析这些数据那必然就对这些数据的格式有着一定的要求,具体字段的设置标准参考数据手册的第8章。这里就不搬过来了。

下一篇文章学习RT1052的cache特性

你可能感兴趣的:(RT1052)