这篇文章分析RT1052芯片从FlexSPI上电启动到执行第一条指令的全过程
- 设置RT1052从FlexSPI启动
- FlexSPI的初始化流程
boot ROM是固化在芯片内部的一段启动代码,这个代码会在系统上电时被执行。boot ROM先对芯片进行必要的初始化后,会根据各个GPIO电平来选择一个启动方式,参考下面的列表选择一个boot device
没有设置熔丝情况下,设置好这堆引脚电平为所需值,然后芯片就从SPI启动了
此时boot ROM会根据前面的BOOT_CFG1[3:2]和BOOT_CFG2[2:0]信息简单设置一下FlexSPI接口,此时默认SPI时钟为30MHz。然后读取Flash的前512字节信息。boot ROM会认为这是初始化Flash的信息,然后boot ROM根据这些预设的信息对FlexSPI接口进行初始化。初始化后就可以满速跑了。
这里就是前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字节*/
};
这里分成了四部分
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章。这里就不搬过来了。