关于FlexSPI外设的lookupTable,之前写过一篇非常详细的文章 《从头开始认识i.MX RT启动头FDCB里的lookupTable》,这篇文章几乎可以帮助解决所有串行QuadSPI NOR Flash(四线) 以及Octal Flash(八线)的读时序配置问题,因为这些Flash都只用单一行地址(Row Addr)来寻址。
但是市面上也有一些特殊的存储器(比如八线HyperBus Flash/RAM,OctalRAM等)采用了行列混合寻址方式,对于这类存储器,我们在FlexSPI里配置读时序,尤其是读时序里的地址序列参数值时需要稍微注意一下,今天就来聊聊这个话题:
一、FlexSPI外设关于行列地址
Memory支持
先来看FlexSPI外设是如何支持行列混合寻址存储器的。
在FLSHxxCR1寄存器里有CAS控制位,这里配置的即是存储器列地址(Column Addr)位宽。对于不支持列地址的存储器,CAS需要设置为0;如果存储器支持列地址,那么CAS需要根据存储器实际情况来设置。
如果FLSHxxCR1[CAS]位不为0,那么FlexSPI外设在传输时序里会拆分实际映射Flash Address(即存储器自身偏移地址)为行地址FA[31:CAS]和列地址[CAS-1:0]来分别传输。
在最终lookupTable里我们可以用这样的时序配置来实现存储器的读访问,这里RADDR_DDR子序列即传输行地址,CADDR_DDR子序列即传输列地址(注:如下示例是在FLSHxxCR1[CAS] = 3的设置下)。
看到这里,似乎已经把FlexSPI对于行列地址Memory的支持讲完了。
但是我相信你还是会有疑问,上面序列表里RADDR_DDR和CADDR_DDR具体参数值设置似乎没有讲清楚,为什么行列地址加起来位宽是0x18 + 0x10一共40bit(一般 Memory行列地址总位宽也就32 bit)?并且明明CAS值只是 3,为何CADDR_DDR 里设成0x10也行?
是的,这里需要再详细展开!
首先我们要明白一点,因为FlexSPI连接的是八线Memory,在实际总线上行、列地址传输位一定都是8bits的整数倍,如果RADDR/CADDR_DDR参数值设置得不是8bits的整数倍,不足8bits的部分,FlexSPI会自动在低位插入相应保留位(即下图低保留bits,这些保留位的值是什么不确定,对FlexSPI来说也不在乎),然后在 RADDR/CADDR_DDR设置的参数值范围内,如果对应Memory实际行、列地址位宽小于参数值,超出实际行、列地址的部分会被FlexSPI自动填入0值(即下图高亮填充bits)。
二、常见行列混合地址Memory
读配置实例
大部分 HyperBus Flash/RAM 在行、列地址设计上是一样的,这里罗列了市面上常见的型号如下,我们就以MIMXRT1050-EVKB板卡上那颗S26KS512为例来介绍。
ISSI的IS26KSxxx系列HyperFlash
ISSI的IS66/67WVH系列HyperRAM
Cypress/Infineon的S26KSxxx系列HyperFlash
Cypress/Infineon的S80KSxxx系列HyperRAM
Winbond的W957D8、W959D8系列HyperRAM
我们在S26KS512手册里可以找到如下读时序图,主要关注时序最前面48bits的Command-Address序列,在手册Command / Address Bit Assignments表里有这48bits的详细定义,其中CA[37:16] 是行地址与高位列地址,CA[2:0] 是低位列地址。
再来看 SDK_2_12_0_EVKB-IMXRT1050oardsevkbimxrt1050driver_examplesflexspihyper_flashpolling_transfer 例程里的如下lookupTable,RADDR_DDR参数值是0x18,CADDR_DDR参数值是0x10,根据上一节的分析,RADDR_DDR里的高2bits会被FlexSPI设为0(RADDR[21:0]用于传输CA[37:16])。
因为CAS = 3,所以CADDR_DDR里的高13bits也会被FlexSPI设为0(CADDR[2:0]用于传输CA[2:0]),这是符合S26KS512手册时序定义的。
flexspi_device_config_t deviceconfig = { .columnspace = 3, .enableWordAddress = true, }; const uint32_t customLUT[CUSTOM_LUT_LENGTH] = { /* Read Data */ [0] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18), [1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04), };
三、特殊行列混合地址Memory
读配置实例
最近我们在支持客户的过程中也发现了一些Memory有着不一样的行、列地址设计,比如如下这颗IS66WVO OctalRAM。从手册里找到其Command / Address bit assignment表里48bits的定义。与上一节HyperBus Flash/RAM不一样的是,其高位列地址并不是在8bits对齐处出现的。
1. ISSI出品的IS66/67WVO系列OctalRAM
对于IS66WVO这样的行、列地址设计,我们在lookupTable里该如何填入RADDR/CADDR_DDR参数值呢?首先CAS设为4,CADDR_DDR设为0x08可以解决CA[3:0]传输问题。
现在的重点是RADDR_DDR参数值,总共24bits传输位,低位还需要留2个保留位,所以RADDR_DDR仅能被设为0x16(RADDR[20:2]用于传输RA[12:0] + CA[9:4]),即如下面代码:
flexspi_device_config_t deviceconfig = { .columnspace = 4, .enableWordAddress = false, }; const uint32_t customLUT[CUSTOM_LUT_LENGTH] = { /* Read Data with continuous burst Sequence in DDR command mode */ [0] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x00), [1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x16, kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x08), [2] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DUMMY_DDR, kFLEXSPI_8PAD, 0x1E, kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04), };
全部0条评论
快来发表一下你的评论吧 !