7

行列混合寻址Memory如何被i.MXRT支持?

 1 year ago
source link: https://www.eefocus.com/embedded/527438
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是i.MXRT中FlexSPI外设lookupTable里配置访问行列混合寻址Memory的参数值

关于 FlexSPI 外设的 lookupTable,痞子衡之前写过一篇非常详细的文章 《从头开始认识i.MXRT启动头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 需要根据存储器实际情况来设置。

forward?url=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FicSsJyL95utZaWFtAicseISUbBia9eN3dPj2xEdibQARTMZN5YtMfGVMCw6M4kfDCH2pZ9uia9BLkz6dOW4EhibNG9Vg%2F640%3Fwx_fmt%3Dpng&s=dd15a1

如果 FLSHxxCR1[CAS] 位不为 0 ,那么 FlexSPI 外设在传输时序里会拆分实际映射 Flash Address (即存储器自身偏移地址) 为行地址 FA[31:CAS] 和列地址 [CAS-1:0] 来分别传输。

forward?url=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FicSsJyL95utZaWFtAicseISUbBia9eN3dPjbDGniaHykWSWEpLdMezO6a9vbNaQSViaAjsibNY6SfNLXVzmvjPI1tjUQ%2F640%3Fwx_fmt%3Dpng&s=73e454

在最终 lookupTable 里我们可以用这样的时序配置来实现存储器的读访问,这里 RADDR_DDR 子序列即传输行地址,CADDR_DDR 子序列即传输列地址(注:如下示例是在 FLSHxxCR1[CAS] = 3 的设置下)。

forward?url=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FicSsJyL95utZaWFtAicseISUbBia9eN3dPjQDMdl8AAxXHGtzs4HYcrTec4icnLsTYzI6M60roOsKKVOsNic3S2SrMQ%2F640%3Fwx_fmt%3Dpng&s=e36359

看到这里,似乎已经把 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 值(即下图高0填充bits)。

forward?url=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FicSsJyL95utZaWFtAicseISUbBia9eN3dPjNxibWFaRTTPlBxw1ggMSxz79Zv3hXxYPwhCxsT1jmjfTBGzEGqzE28Q%2F640%3Fwx_fmt%3Dpng&s=8feb05

二、常见行列混合地址Memory读配置实例

大部分 HyperBus Flash/RAM 在行、列地址设计上是一样的,痞子衡罗列了市面上常见的型号如下,我们就以 MIMXRT1050-EVKB 板卡上那颗 S26KS512 为例来介绍。

1. ISSI 出品的 IS26KSxxx 系列 HyperFlash
2. ISSI 出品的 IS66/67WVH 系列 HyperRAM
3. Cypress/Infineon 出品的 S26KSxxx 系列 HyperFlash
4. Cypress/Infineon 出品的 S80KSxxx 系列 HyperRAM
5. Winbond 出品的 W957D8、W959D8 系列 HyperRAM

我们在 S26KS512 手册里可以找到如下读时序图,主要关注时序最前面 48bits 的 Command-Address 序列,在手册 Command / Address Bit Assignments 表里有这 48bits 的详细定义,其中 CA[37:16] 是行地址与高位列地址,CA[2:0] 是低位列地址。

forward?url=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FicSsJyL95utZaWFtAicseISUbBia9eN3dPj25lVJrkNdT2ic1iaUo058teZ2HAuCr5gvEy5J5HWT1oLddnZ87EgmhTg%2F640%3Fwx_fmt%3Dpng&s=e0adac
forward?url=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FicSsJyL95utZaWFtAicseISUbBia9eN3dPjz8rPZyBFc8YG3mh2ge6EsYfsW00SiaaibInhhHtj1cBSibqbflukNqfjQ%2F640%3Fwx_fmt%3Dpng&s=c706f8

再来看 \SDK_2_12_0_EVKB-IMXRT1050\boards\evkbimxrt1050\driver_examples\flexspi\hyper_flash\polling_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
forward?url=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FicSsJyL95utZaWFtAicseISUbBia9eN3dPjNquznjaibXeC1wLXykbkVJJmLg1ibHmhAzSGMNmEbuLEZAQJy21eFuYQ%2F640%3Fwx_fmt%3Dpng&s=f2a651
forward?url=https%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FicSsJyL95utZaWFtAicseISUbBia9eN3dPjGs6VQgNxGIo0IOmkpLzrQGyvTwJy5wgxYwfhQa2a46OG5v87uibeLHw%2F640%3Fwx_fmt%3Dpng&s=33fd6d

对于 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),
};

至此,i.MXRT中FlexSPI外设lookupTable里配置访问行列混合寻址Memory的参数值痞子衡便介绍完毕了,掌声在哪里~~~


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK