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