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

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

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

配置NOR Flash多個寄存器沒那么容易!

[復(fù)制鏈接]

173

主題

173

帖子

1594

積分

三級會員

Rank: 3Rank: 3

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

    使用道具 舉報

    發(fā)表回復(fù)

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

    本版積分規(guī)則


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