大家好,我是痞子衡,是正經(jīng)搞技術的痞子。今天痞子衡給大家介紹的是在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的雙邊沿均觸發(fā)數(shù)據(jù)傳輸。DTR有時候跟另一個名詞DDR會混用,DDR是Double Data Rate的縮寫,反正這兩個名詞均表示雙邊沿觸發(fā)的意思,跟SDR單邊沿觸發(fā)相比快了一倍(同等SCK頻率下而言)。下面痞子衡結合i.MXRT的FlexSPI外設來對比介紹SDR模塊與DDR模式的區(qū)別:
1.1 FlexSPI的DTR輸入輸出
下圖是FlexSPI的輸入時序圖(FlexSPI從Flash讀取存儲數(shù)據(jù))。左邊是SDR模式,可以看到FlexSPI是在DQS的下沿才會去鎖存一次SIO上的數(shù)據(jù)。右邊是DDR模式,F(xiàn)lexSPI外設在DQS的上沿和下沿都會去鎖存一次SIO上的數(shù)據(jù)。注意不管是SDR模塊還是DDR模式,DQS信號都是與SCK同頻的。
Note: 關于DQS信號的意義,可以去看痞子衡的舊文 《串行NOR Flash的DQS信號功能簡介》,F(xiàn)lexSPI外設的DQS信號既可以來自真實的Flash器件輸出,也可以從i.MXRT的DQS引腳loopback(回環(huán))。
再來看FlexSPI的輸出時序圖(FlexSPI給Flash發(fā)送地址,模式等)。左邊是SDR模式,F(xiàn)lash器件應在SCK的上沿去鎖存DATA (SIO)上的數(shù)據(jù)。右邊是DDR模式,F(xiàn)lash器件需要在SCK的上沿和下沿都去鎖存DATA (SIO)上的數(shù)據(jù)。
1.2 Fast Read Quad I/O DTR時序
了解了SDR與DDR模式區(qū)別,我們再來看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傳輸下發(fā)送命令規(guī)定使用CMD_SDR子序列。
從引腳信號上來看,完整Quad I/O Read DDR傳輸時序如下圖所示。下圖是以兩片四線S25FS512S組parallel mode(八線)來示例的。如果是常見的individual mode,我們僅關注PCSA1相關的信號時序即可。
1.3 DTR下實際Dummy Cycle輸出與LUT中設定值關系
從Flash器件端來看,實際Dummy Cycle輸出數(shù)是跟SCK信號周期數(shù)一一對應的。在SDR模式下,在Dummy Cycle序列時間內,有多少個SCK周期,即是有多少個Dummy Cycle數(shù),填進LUT的Dummy Cycle也是這個值,這個沒有疑義。那么在DDR模式,填入LUT的Dummy Cycle值與SCK周期數(shù)是什么關系呢?翻看FlexSPI章節(jié),在LUT指令集表格里有答案,此時Dummy Cycle值應該是實際SCK周期數(shù)的2倍(可能有+/-1,需要看Flash手冊),這是因為LUT中Dummy Cycle值是與FlexSPI外設端的Serial Root Clk數(shù)一一對應的:在SDR模式下,Serial Root Clk周期等于SCK周期;而在DDR模式下,Serial Root Clk周期只有SCK周期的一半。
1.4 DTR下支持的最高SCK頻率
上面在講Dummy Cycle值的時候提到了Serial Root Clk概念,這個其實就是FlexSPI模塊本身的工作時鐘,目前已量產(chǎn)的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就是這么設計的)。
具體SCK能配到多高的頻率跟FlexSPI模塊一個寄存器的配置值有關,即FlexSPI->MCR0[RXCLKSRC],RXCLKSRC配置的是DQS信號的來源,DQS信號一共有三種來源:無DQS自回環(huán)(支持的SCK頻率最低),有DQS自回環(huán)(支持的SCK頻率升高),來自外部Flash器件的DQS引腳(支持的SCK頻率最高)。
那么RXCLKSRC三種配置下,SCK分別能達到多高頻率呢?這需要查看i.MXRT芯片的datasheet,在 FlexSPI input/read timing 小節(jié)里有詳細介紹,痞子衡整理如下:
Flash工作模式 | RXCLKSRC = 0 | RXCLKSRC = 1 | RXCLKSRC = 3 |
---|---|---|---|
SDR | SCK最高60MHz | SCK最高133MHz | SCK最高166MHz |
DDR | SCK最高30MHz | SCK最高66MHz | SCK最高166MHz |
二、在客戶問題中實戰(zhàn)
了解了上面DTR模式基礎知識后,我們去恩智浦官方論壇找兩個相關問題實踐一下。
2.1 Flash型號IS25LP064A
先來看第一個問題 《i.MX RT1021 + IS25LP064A XIP flash in DDR mode settings》,這個客戶使用的Flash型號是IS25LP064A,客戶已經(jīng)修改了FDCB頭,但是他犯了一個比較嚴重的錯誤,他使用了CMD_DDR來發(fā)送命令而不是CMD_SDR,這顯然不符合Flash時序規(guī)范。
此外,該款Flash在DTR模式下最高能支持到66MHz,客戶在FDCB里配置SCK頻率為 kFlexSpiSerialClk_60MHz 是沒問題的,這個速度下DTR模式需要4個SCK周期做Dummy Cycle,F(xiàn)lash器件里的默認值3按說不符合要求,但實測啟動也沒問題。
下面痞子衡給一個適用的FDCB頭(50MHz SCK,DTR模式,LUT里等效Dummy Cycle值是0x2 + 0x4,即6個Dummy Cycle)。想同步修改Flash器件里的Dummy Cycle值去規(guī)范地調高SCK頻率到60MHz,請參考 《IS25LP系列Dummy Cycle設置》。
const?flexspi_nor_config_t?qspiflash_config?=?{
????.memConfig?=
????????{
????????????.tag??????????????=?FLEXSPI_CFG_BLK_TAG,
????????????.version??????????=?FLEXSPI_CFG_BLK_VERSION,
????????????//?設置?FlexSPI->MCR0[RXCLKSRC]?為?1
????????????.readSampleClkSrc?=?kFlexSPIReadSampleClk_LoopbackFromDqsPad,
????????????.csHoldTime???????=?3u,
????????????.csSetupTime??????=?3u,
????????????//?使能?DDR?模式
????????????.controllerMiscOption?=?kFlexSpiMiscOffset_DdrModeEnable?|?kFlexSpiMiscOffset_SafeConfigFreqEnable,
????????????.sflashPadType????=?kSerialFlash_4Pads,
????????????//?設置?DDR?模式下工作頻率
????????????.serialClkFreq????=?kFlexSpiSerialClk_50MHz,
????????????.sflashA1Size?????=?8u?*?1024u?*?1024u,
????????????.lookupTable?=
????????????????{
????????????????????//?Read?LUTs
????????????????????[4*CMD_LUT_SEQ_IDX_READ]?????=?FLEXSPI_LUT_SEQ(CMD_SDR,???FLEXSPI_1PAD,?0xED,?RADDR_DDR,?FLEXSPI_4PAD,?0x18),
????????????????????//?MODE8_DDR子序列等效2個cycle,DUMMY_DDR子序列里還需設置4個cycle,總計3個SCK周期
????????????????????[4*CMD_LUT_SEQ_IDX_READ?+?1]?=?FLEXSPI_LUT_SEQ(MODE8_DDR,?FLEXSPI_4PAD,?0x00,?DUMMY_DDR,?FLEXSPI_4PAD,?0x04),
????????????????????[4*CMD_LUT_SEQ_IDX_READ?+?2]?=?FLEXSPI_LUT_SEQ(READ_DDR,??FLEXSPI_4PAD,?0x04,?STOP,??????FLEXSPI_1PAD,?0x00),
????????????????},
????????},
????.pageSize???????????=?256u,
????.sectorSize?????????=?4u?*?1024u,
????.blockSize??????????=?64u?*?1024u,
????.isUniformBlockSize?=?false,
};
2.2 Flash型號IS25WP064D
再來看第二個問題 《i.MX RT106x + IS25WP064D QSPI DDR mode》,這個客戶使用的Flash型號是IS25WP064D,客戶也修改好了FDCB頭,由于Flash器件本身最高能支持80MHz DTR模式,于是這個客戶就想在FDCB里將SCK頻率設為 kFlexSpiSerialClk_80MHz,但是Flash本身沒有DQS信號,F(xiàn)lexSPI端僅能從DQS引腳loopback,這種情況下FlexSPI最高僅能支持66MHz DTR,這顯然不符合FlexSPI規(guī)范。
痞子衡特別注意到,這款IS25WP064D與上一個客戶用的IS25LP064A在時序上尤其是Dummy Cycle上有明顯的區(qū)別。同樣SCK頻率下,IS25LP064A下SDR與DDR模式的Dummy Cycle是兩倍關系,但是IS25WP064D下SDR與DDR模式的Dummy Cycle數(shù)是一樣的。
IS25WP064D默認6個Dummy Cycle下對應最高DTR工作頻率是69MHz,這已經(jīng)達FlexSPI外設最高支持的DTR頻率上限了,因此不需更改Flash里的Dummy Cycle設置了。
下面痞子衡給一個適用的FDCB頭(60MHz SCK,DTR模式,LUT里等效Dummy Cycle值是0x2 + 0xa,即12個Dummy Cycle)。
const?flexspi_nor_config_t?qspiflash_config?=?{
????.memConfig?=
????????{
????????????.tag??????????????=?FLEXSPI_CFG_BLK_TAG,
????????????.version??????????=?FLEXSPI_CFG_BLK_VERSION,
????????????//?設置?FlexSPI->MCR0[RXCLKSRC]?為?1
????????????.readSampleClkSrc?=?kFlexSPIReadSampleClk_LoopbackFromDqsPad,
????????????.csHoldTime???????=?3u,
????????????.csSetupTime??????=?3u,
????????????//?使能?DDR?模式
????????????.controllerMiscOption?=?kFlexSpiMiscOffset_DdrModeEnable?|?kFlexSpiMiscOffset_SafeConfigFreqEnable,
????????????.sflashPadType????=?kSerialFlash_4Pads,
????????????//?設置?DDR?模式下工作頻率
????????????.serialClkFreq????=?kFlexSpiSerialClk_60MHz,
????????????.sflashA1Size?????=?8u?*?1024u?*?1024u,
????????????.lookupTable?=
????????????????{
????????????????????//?Read?LUTs
????????????????????[4*CMD_LUT_SEQ_IDX_READ]?????=?FLEXSPI_LUT_SEQ(CMD_SDR,???FLEXSPI_1PAD,?0xED,?RADDR_DDR,?FLEXSPI_4PAD,?0x18),
????????????????????//?MODE8_DDR子序列等效2個cycle,DUMMY_DDR子序列里還需設置10個cycle,總計6個SCK周期
????????????????????[4*CMD_LUT_SEQ_IDX_READ?+?1]?=?FLEXSPI_LUT_SEQ(MODE8_DDR,?FLEXSPI_4PAD,?0x00,?DUMMY_DDR,?FLEXSPI_4PAD,?0x0a),
????????????????????[4*CMD_LUT_SEQ_IDX_READ?+?2]?=?FLEXSPI_LUT_SEQ(READ_DDR,??FLEXSPI_4PAD,?0x04,?STOP,??????FLEXSPI_1PAD,?0x00),
????????????????},
????????},
????.pageSize???????????=?256u,
????.sectorSize?????????=?4u?*?1024u,
????.blockSize??????????=?64u?*?1024u,
????.isUniformBlockSize?=?false,
};
至此,在FDCB里使能串行NOR Flash的DTR模式痞子衡便介紹完畢了,掌聲在哪里~~~