查看: 1692|回复: 0

[分享] [痞子衡]Flash的DTR模式藏着什么玄机?

[复制链接]
  • TA的每日心情
    开心
    2024-3-26 15:16
  • 签到天数: 266 天

    [LV.8]以坛为家I

    3299

    主题

    6546

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32024
    最后登录
    2024-4-25
    发表于 2021-12-13 15:04:41 | 显示全部楼层 |阅读模式
    Flash的DTR模式藏着什么玄机?


    大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是在FDCB里使能串行NOR Flash的DTR模式。


    前两篇文章 《IS25WP系列Dummy Cycle设置》 与 《IS25LP系列Dummy Cycle设置》, 痞子衡均是设置Flash的Fast Read Quad I/O SDR模式去启动的,但最近在恩智浦官方论坛上,有不止一个客户需要使能Flash的DTR模式去启动,他们似乎都遇到了小问题,难道DTR模式藏着什么玄机?走,跟痞子衡去瞧瞧:


    一、什么是DTR模式?
    DTR是Dual Transfer Rate的缩写,即在时钟信号SCK的双边沿均触发数据传输。DTR有时候跟另一个名词DDR会混用,DDR是Double Data Rate的缩写,反正这两个名词均表示双边沿触发的意思,跟SDR单边沿触发相比快了一倍(同等SCK频率下而言)。下面痞子衡结合i.MXRT的FlexSPI外设来对比介绍SDR模块与DDR模式的区别:


    1.1 FlexSPI的DTR输入输出
    下图是FlexSPI的输入时序图(FlexSPI从Flash读取存储数据)。左边是SDR模式,可以看到FlexSPI是在DQS的下沿才会去锁存一次SIO上的数据。右边是DDR模式,FlexSPI外设在DQS的上沿和下沿都会去锁存一次SIO上的数据。注意不管是SDR模块还是DDR模式,DQS信号都是与SCK同频的。


    Note: 关于DQS信号的意义,可以去看痞子衡的旧文 《串行NOR Flash的DQS信号功能简介》,FlexSPI外设的DQS信号既可以来自真实的Flash器件输出,也可以从i.MXRT的DQS引脚loopback(回环)。
    13.png
    再来看FlexSPI的输出时序图(FlexSPI给Flash发送地址,模式等)。左边是SDR模式,Flash器件应在SCK的上沿去锁存DATA (SIO)上的数据。右边是DDR模式,Flash器件需要在SCK的上沿和下沿都去锁存DATA (SIO)上的数据。
    14.png
    1.2 Fast Read Quad I/O DTR时序
    了解了SDR与DDR模式区别,我们再来看LUT里Quad I/O Read DDR传输序列,它由CMD_SDR + RADDR_DDR + MODE8_DDR + DUMMY_DDR + LEARN_DDR(可选) + READ_DDR + STOP七个子序列组成,如下表所示。


    Note: 特别注意,虽然存在CMD_DDR子序列,但Quad I/O Read DDR传输下发送命令规定使用CMD_SDR子序列。
    15.png
    从引脚信号上来看,完整Quad I/O Read DDR传输时序如下图所示。下图是以两片四线S25FS512S组parallel mode(八线)来示例的。如果是常见的individual mode,我们仅关注PCSA1相关的信号时序即可。
    16.png
    1.3 DTR下实际Dummy Cycle输出与LUT中设定值关系
    从Flash器件端来看,实际Dummy Cycle输出数是跟SCK信号周期数一一对应的。在SDR模式下,在Dummy Cycle序列时间内,有多少个SCK周期,即是有多少个Dummy Cycle数,填进LUT的Dummy Cycle也是这个值,这个没有疑义。那么在DDR模式,填入LUT的Dummy Cycle值与SCK周期数是什么关系呢?翻看FlexSPI章节,在LUT指令集表格里有答案,此时Dummy Cycle值应该是实际SCK周期数的2倍(可能有+/-1,需要看Flash手册),这是因为LUT中Dummy Cycle值是与FlexSPI外设端的Serial Root Clk数一一对应的:在SDR模式下,Serial Root Clk周期等于SCK周期;而在DDR模式下,Serial Root Clk周期只有SCK周期的一半。
    17.png
    1.4 DTR下支持的最高SCK频率
    上面在讲Dummy Cycle值的时候提到了Serial Root Clk概念,这个其实就是FlexSPI模块本身的工作时钟,目前已量产的i.MXRT型号(包括i.MXRT1010/1020/1050/1060/1170),其FLEXSPI_CLK_ROOT最高频率均是332MHz(下表来自i.MXRT1050系列手册)。


    在332MHz FLEXSPI_CLK_ROOT频率下,DTR模式SCK频率理论上最高可以到166MHz,这个没有疑义。但是SDR模式SCK频率理论上最高也是166MHz,因为SDR模式下,只保证了在166MHz FLEXSPI_CLK_ROOT频率下时序可靠(别问,问就是FlexSPI就是这么设计的)。
    18.png
    具体SCK能配到多高的频率跟FlexSPI模块一个寄存器的配置值有关,即FlexSPI->MCR0[RXCLKSRC],RXCLKSRC配置的是DQS信号的来源,DQS信号一共有三种来源:无DQS自回环(支持的SCK频率最低),有DQS自回环(支持的SCK频率升高),来自外部Flash器件的DQS引脚(支持的SCK频率最高)。
    19.png
    那么RXCLKSRC三种配置下,SCK分别能达到多高频率呢?这需要查看i.MXRT芯片的datasheet,在 FlexSPI input/read timing 小节里有详细介绍,痞子衡整理如下:
    20.png
    二、在客户问题中实战
    了解了上面DTR模式基础知识后,我们去恩智浦官方论坛找两个相关问题实践一下。


    2.1 Flash型号IS25LP064A
    先来看第一个问题 《i.MX RT1021 + IS25LP064A XIP flash in DDR mode settings》,这个客户使用的Flash型号是IS25LP064A,客户已经修改了FDCB头,但是他犯了一个比较严重的错误,他使用了CMD_DDR来发送命令而不是CMD_SDR,这显然不符合Flash时序规范。
    21.png
    此外,该款Flash在DTR模式下最高能支持到66MHz,客户在FDCB里配置SCK频率为 kFlexSpiSerialClk_60MHz 是没问题的,这个速度下DTR模式需要4个SCK周期做Dummy Cycle,Flash器件里的默认值3按说不符合要求,但实测启动也没问题。
    22.png

    下面痞子衡给一个适用的FDCB头(50MHz SCK,DTR模式,LUT里等效Dummy Cycle值是0x2 + 0x4,即6个Dummy Cycle)。想同步修改Flash器件里的Dummy Cycle值去规范地调高SCK频率到60MHz,请参考 《IS25LP系列Dummy Cycle设置》。
    1. const flexspi_nor_config_t qspiflash_config = {
    2.     .memConfig =
    3.         {
    4.             .tag              = FLEXSPI_CFG_BLK_TAG,
    5.             .version          = FLEXSPI_CFG_BLK_VERSION,
    6.             // 设置 FlexSPI->MCR0[RXCLKSRC] 为 1
    7.             .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad,
    8.             .csHoldTime       = 3u,
    9.             .csSetupTime      = 3u,
    10.             // 使能 DDR 模式
    11.             .controllerMiscOption = kFlexSpiMiscOffset_DdrModeEnable | kFlexSpiMiscOffset_SafeConfigFreqEnable,
    12.             .sflashPadType    = kSerialFlash_4Pads,
    13.             // 设置 DDR 模式下工作频率
    14.             .serialClkFreq    = kFlexSpiSerialClk_50MHz,
    15.             .sflashA1Size     = 8u * 1024u * 1024u,
    16.             .lookupTable =
    17.                 {
    18.                     // Read LUTs
    19.                     [4*CMD_LUT_SEQ_IDX_READ]     = FLEXSPI_LUT_SEQ(CMD_SDR,   FLEXSPI_1PAD, 0xED, RADDR_DDR, FLEXSPI_4PAD, 0x18),
    20.                     // MODE8_DDR子序列等效2个cycle,DUMMY_DDR子序列里还需设置4个cycle,总计3个SCK周期
    21.                     [4*CMD_LUT_SEQ_IDX_READ + 1] = FLEXSPI_LUT_SEQ(MODE8_DDR, FLEXSPI_4PAD, 0x00, DUMMY_DDR, FLEXSPI_4PAD, 0x04),
    22.                     [4*CMD_LUT_SEQ_IDX_READ + 2] = FLEXSPI_LUT_SEQ(READ_DDR,  FLEXSPI_4PAD, 0x04, STOP,      FLEXSPI_1PAD, 0x00),
    23.                 },
    24.         },
    25.     .pageSize           = 256u,
    26.     .sectorSize         = 4u * 1024u,
    27.     .blockSize          = 64u * 1024u,
    28.     .isUniformBlockSize = false,
    29. };
    复制代码
    2.2 Flash型号IS25WP064D
    再来看第二个问题 《i.MX RT106x + IS25WP064D QSPI DDR mode》,这个客户使用的Flash型号是IS25WP064D,客户也修改好了FDCB头,由于Flash器件本身最高能支持80MHz DTR模式,于是这个客户就想在FDCB里将SCK频率设为 kFlexSpiSerialClk_80MHz,但是Flash本身没有DQS信号,FlexSPI端仅能从DQS引脚loopback,这种情况下FlexSPI最高仅能支持66MHz DTR,这显然不符合FlexSPI规范。


    痞子衡特别注意到,这款IS25WP064D与上一个客户用的IS25LP064A在时序上尤其是Dummy Cycle上有明显的区别。同样SCK频率下,IS25LP064A下SDR与DDR模式的Dummy Cycle是两倍关系,但是IS25WP064D下SDR与DDR模式的Dummy Cycle数是一样的。
    23.png
    IS25WP064D默认6个Dummy Cycle下对应最高DTR工作频率是69MHz,这已经达FlexSPI外设最高支持的DTR频率上限了,因此不需更改Flash里的Dummy Cycle设置了。
    24.png
    下面痞子衡给一个适用的FDCB头(60MHz SCK,DTR模式,LUT里等效Dummy Cycle值是0x2 + 0xa,即12个Dummy Cycle)。
    1. const flexspi_nor_config_t qspiflash_config = {
    2.     .memConfig =
    3.         {
    4.             .tag              = FLEXSPI_CFG_BLK_TAG,
    5.             .version          = FLEXSPI_CFG_BLK_VERSION,
    6.             // 设置 FlexSPI->MCR0[RXCLKSRC] 为 1
    7.             .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad,
    8.             .csHoldTime       = 3u,
    9.             .csSetupTime      = 3u,
    10.             // 使能 DDR 模式
    11.             .controllerMiscOption = kFlexSpiMiscOffset_DdrModeEnable | kFlexSpiMiscOffset_SafeConfigFreqEnable,
    12.             .sflashPadType    = kSerialFlash_4Pads,
    13.             // 设置 DDR 模式下工作频率
    14.             .serialClkFreq    = kFlexSpiSerialClk_60MHz,
    15.             .sflashA1Size     = 8u * 1024u * 1024u,
    16.             .lookupTable =
    17.                 {
    18.                     // Read LUTs
    19.                     [4*CMD_LUT_SEQ_IDX_READ]     = FLEXSPI_LUT_SEQ(CMD_SDR,   FLEXSPI_1PAD, 0xED, RADDR_DDR, FLEXSPI_4PAD, 0x18),
    20.                     // MODE8_DDR子序列等效2个cycle,DUMMY_DDR子序列里还需设置10个cycle,总计6个SCK周期
    21.                     [4*CMD_LUT_SEQ_IDX_READ + 1] = FLEXSPI_LUT_SEQ(MODE8_DDR, FLEXSPI_4PAD, 0x00, DUMMY_DDR, FLEXSPI_4PAD, 0x0a),
    22.                     [4*CMD_LUT_SEQ_IDX_READ + 2] = FLEXSPI_LUT_SEQ(READ_DDR,  FLEXSPI_4PAD, 0x04, STOP,      FLEXSPI_1PAD, 0x00),
    23.                 },
    24.         },
    25.     .pageSize           = 256u,
    26.     .sectorSize         = 4u * 1024u,
    27.     .blockSize          = 64u * 1024u,
    28.     .isUniformBlockSize = false,
    29. };
    复制代码
    至此,在FDCB里使能串行NOR Flash的DTR模式痞子衡便介绍完毕了,掌声在哪里~~~

    签到签到
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-26 05:45 , Processed in 0.120350 second(s), 22 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表