電子產(chǎn)業(yè)一站式賦能平臺(tái)

PCB聯(lián)盟網(wǎng)

搜索
查看: 41|回復(fù): 0
收起左側(cè)

配置NOR Flash多個(gè)寄存器沒那么容易!

[復(fù)制鏈接]

168

主題

168

帖子

1509

積分

三級(jí)會(huì)員

Rank: 3Rank: 3

積分
1509
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 前天 22:32 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
大家好,我是痞子衡,是正經(jīng)搞技術(shù)的痞子。今天痞子衡給大家介紹的是在FDCB里配置串行NOR Flash多個(gè)寄存器的注意事項(xiàng)。
關(guān)于使用 i.MXRT 啟動(dòng)頭 FDCB 來設(shè)置 Flash 內(nèi)部寄存器,痞子衡寫過如下兩篇文章,在進(jìn)入本文之前,建議大家先閱讀下這兩篇文章,有個(gè)初步了解。
  • 《在FDCB里設(shè)置Flash的Dummy Cycle》
  • 《在FDCB里切換Flash模式至QPI/OPI》我們知道 Flash 內(nèi)部常常有多個(gè)狀態(tài)/配置寄存器,這些寄存器有些是易失性的,有些是非易失性的。當(dāng)芯片被指定從 Flash 啟動(dòng)的時(shí)候,我們?nèi)绻M?BootROM 能夠根據(jù)不同應(yīng)用需求來提前設(shè)置好這些 Flash 寄存器,那么在應(yīng)用程序里就不用再額外配置了(涉及 Flash 工作狀態(tài)變化的配置,如果是 XIP 程序去操作,需要考慮代碼重定向問題)。
    對于使用 FDCB 來配置 Flash 一個(gè)寄存器的操作,相信大家都很了解,在恩智浦 SDK 包里默認(rèn) FDCB 啟動(dòng)頭里都有成功示例。最近痞子衡同事嘗試使用 FDCB 去配置鎂光 MT35X 的兩個(gè)寄存器(地址為 0x000000 的寄存器切至 OPI DDR、地址為 0x000003 的寄存器設(shè) Drive Strength)發(fā)現(xiàn)有一個(gè)寄存器設(shè)置沒生效,這是怎么回事?今天我們來聊一聊:
  • Note: 本文適用于 i.MXRT500/600/1010/1020/1040/1050/1060/1160/1170一、FDCB提供的Flash寄存器配置能力我們先來看一下 FDCB 結(jié)構(gòu)里跟 Flash 配置相關(guān)的成員,痞子衡整理如下,簡單來說,就是有一條 deviceModeSeq 和三條 configCmdSeqs,所以最多能配置 Flash 里 4 個(gè)不同命令下對應(yīng)的寄存器(有些 Flash 里一條配置命令能連續(xù)寫入多個(gè)寄存器,這種情況下就能配置不止 4 個(gè)寄存器),這對于大部分應(yīng)用場景都完全夠用了。
  • Note 1: BootROM 執(zhí)行這四個(gè)配置的順序分別是 deviceModeSeq、configCmdSeqs[0]、configCmdSeqs[1]、configCmdSeqs[2],記住這個(gè)順序。
  • Note 2: deviceModeSeq 與 configCmdSeq 實(shí)現(xiàn)的配置功能幾乎沒有區(qū)別,兩者能做的事情是一樣的,可以互換。//!@brief FlexSPI Memory Configuration Block
    typedef struct _FlexSPIConfig
    {
        // ...
        //!
        uint8_t deviceModeCfgEnable;
        //!
        uint8_t deviceModeType;
        //!
        uint16_t waitTimeCfgCommands;
        //!
        flexspi_lut_seq_t deviceModeSeq;
        //!
        uint32_t deviceModeArg;
        //!
        uint8_t configCmdEnable;
        //!
        uint8_t configModeType[3];
        //!
        flexspi_lut_seq_t configCmdSeqs[3];
        //!
        uint32_t configCmdArgs[3];
        // ...
        //!
        uint16_t busyOffset;
        //!
        uint16_t busyBitPolarity;
        //!
        uint32_t lookupTable[64];
        // ...
    } flexspi_mem_config_t;
    在 《在FDCB里設(shè)置Flash的Dummy Cycle》 一文最后,痞子衡已經(jīng)分享了 BootROM 解析執(zhí)行 configCmdSeq 的代碼流程,在這個(gè)流程里我們能看到和 deviceModeType/configModeType[]、waitTimeCfgCommands 成員相關(guān)的邏輯代碼,這里有必要進(jìn)一步解釋一下。
    //!@brief Flash Configuration Command Type
    enum
    {
        kDeviceConfigCmdType_Generic,    //!
        kDeviceConfigCmdType_QuadEnable, //!
        kDeviceConfigCmdType_Spi2Xpi,    //!
        kDeviceConfigCmdType_Xpi2Spi,    //!
        kDeviceConfigCmdType_Spi2NoCmd,  //!
        kDeviceConfigCmdType_Reset,      //!
    };
    當(dāng) deviceModeType/configModeType 成員被設(shè)置為 kDeviceConfigCmdType_Spi2Xpi 時(shí);如果 FDCB 本身被獲取時(shí) BootROM 用得是 DPI/QPI/OPI 命令(根據(jù) efuse 配置決定),那么此條 Flash 寄存器配置會(huì)被直接忽略;如果 BootROM 用得是普通一線 SPI 模式讀取的 FDCB,那么這個(gè) Flash 寄存器配置仍然生效。
    kDeviceConfigCmdType_Spi2Xpi 等三個(gè)跟 Flash 命令模式切換相關(guān)的配置類型,顧名思義就是告訴 BootROM 這三種配置會(huì)導(dǎo)致 Flash 工作模式變化,而一旦 Flash 工作模式發(fā)生變化,用于判斷配置是否完成的 READ_STATUS 命令也隨之變得不可用(因?yàn)?SPI 模式下與 DPI/QPI/OPI 模式下的命令序列不同),這種情況下就需要借助 waitTimeCfgCommands 成員來實(shí)現(xiàn)軟件延時(shí)以等待對 Flash 的配置真正生效(如果不等生效就直接進(jìn)入后續(xù)流程,可能會(huì)導(dǎo)致啟動(dòng)問題)。
    kDeviceConfigCmdType_Generic 配置類型,則是用于跟工作模式切換無關(guān)的 Flash 寄存器配置,這種情況下 BootROM 可以使用 READ_STATUS 命令來判斷對 Flash 寄存器配置是否已經(jīng)生效,那么就不需要 waitTimeCfgCommands 實(shí)現(xiàn)的延時(shí)等待(需要查 Flash 數(shù)據(jù)手冊作相應(yīng)設(shè)置,比較麻煩,而且手冊里是給了典型值和最大值,取最大值會(huì)導(dǎo)致啟動(dòng)時(shí)間變長,典型值不能保證適用所有情況)。
    二、配置Flash多個(gè)寄存器注意點(diǎn)Flash 配置寄存器的寫入流程通常分三步:一、WRITE_ENABLE 使能寫操作;二、具體的 CONFIG_REG 操作;三、READ_STATUS 或者軟件延時(shí)確保配置已完成。這些命令序列全部存儲(chǔ)在 FDCB 里的 lookupTable[64] 成員里。
    關(guān)于 Flash 寄存器的配置操作,從寄存器屬性上來看,分為易失性和非易失性兩種,前者的操作一般是立即生效的,后者的操作不是立即生效(Flash 狀態(tài)寄存器 WIP 位會(huì)反映進(jìn)度)。從命令模式角度來看,分為非模式切換操作(比如設(shè)置 Dummy Cycle、Drive Strength)以及切換 SPI 與 DPI/QPI/OPI 模式操作兩種,同樣前者操作是立即生效,后者操作不是立即生效。
    現(xiàn)在回到文章開頭痞子衡同事遇到的問題,如果 deviceModeSeq 用于切換至 OPI DDR 模式,configCmdSeqs[0] 用于設(shè) Drive Strength,請問哪一個(gè)操作沒有生效?這里就不賣關(guān)子了,設(shè) Drive Strength 沒有生效,因?yàn)榈谝粋(gè)配置是切換至 OPI DDR 模式,當(dāng) Flash 切換到該模式時(shí),用于第二/三/四個(gè)配置的 WRITE_ENABLE 命令變得不可用了(還是因?yàn)?SPI 模式下與 DPI/QPI/OPI 模式下的命令序列不同),當(dāng)然對應(yīng) Flash 寄存器設(shè)置就無效了。
    那么如何避免這個(gè)問題?有一個(gè)一勞永逸的方法,那就是永遠(yuǎn)用 configCmdSeqs[2] 去做 SPI 與 DPI/QPI/OPI 模式切換操作,這樣就不會(huì)影響前面三個(gè)配置。前面講了,此時(shí)判斷命令模式是否切換完成不能用 READ_STATUS 命令,那么就一定需要 waitTimeCfgCommands 來做軟延時(shí),如果延時(shí)時(shí)間不夠,并且后續(xù) BootROM 執(zhí)行到驗(yàn)證 IVT 頭時(shí)模式切換仍未完成,這會(huì)導(dǎo)致 IVT 啟動(dòng)頭無法正確獲取從而導(dǎo)致啟動(dòng)失敗。
    假設(shè) waitTimeCfgCommands 延時(shí)設(shè)置對于命令模式切換已足夠,這樣問題就一定解決了嗎?其實(shí)還不一定,如果此時(shí)已將 deviceModeSeq 用于設(shè) Drive Strength,但是選擇得是寫入 Flash 非易失性存儲(chǔ)器,這需要確保 waitTimeCfgCommands 延時(shí)對于寫入非易失性寄存器也足夠。翻看 MT35X 的數(shù)據(jù)手冊可以發(fā)現(xiàn),寫入非易失性寄存器 cycle time 典型值是 0.2s,最大值是 1s。
  • 發(fā)表回復(fù)

    您需要登錄后才可以回帖 登錄 | 立即注冊

    本版積分規(guī)則


    聯(lián)系客服 關(guān)注微信 下載APP 返回頂部 返回列表