加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

串行Flash Continuous read使能后軟復(fù)位啟動(dòng)問題解決方案之SW Reset

2021/05/27
345
閱讀需 14 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

大家好,我是痞子衡,是正經(jīng)搞技術(shù)的痞子。今天痞子衡給大家介紹的是i.MXRT上使能NOR Flash的Continuous read模式在軟復(fù)位后無法正常啟動(dòng)問題的解決經(jīng)驗(yàn)。

先回顧上篇 《串行NOR Flash的Continuous read模式下軟復(fù)位后i.MXRT無法啟動(dòng)問題解決方案之RESET#》,利用RESET#引腳復(fù)位功能是痞子衡找到的第一種解決方案,今天痞子衡繼續(xù)給大家介紹第二種解決方案。

  • 本系列會(huì)有多篇文章,每篇文章均從一個(gè)核心切入點(diǎn)出發(fā),給出一系列具體實(shí)現(xiàn)方案。本系列均以MIMXRT1170-EVK板為示例目標(biāo)對象,板載Flash型號為芯成IS25WP128(其他i.MXRT芯片和Flash型號下實(shí)現(xiàn)流程也差不多,需查看對應(yīng)數(shù)據(jù)手冊)。

 

一、解決思路

我們知道無法啟動(dòng)問題是由于主芯片發(fā)生軟復(fù)位但Flash仍處于Continuous read模式造成的,要解決這個(gè)問題無非如下三個(gè)角度,痞子衡會(huì)在后面具體實(shí)現(xiàn)方案里按這些角度全部搞一次(如果適用的話)。

  • 一、ROM方面不做任何相關(guān)處理,但App在調(diào)用NVIC_SystemReset()做復(fù)位前將Flash先切回到Normal模式;二、App方面不做任何相關(guān)處理,對BootROM相關(guān)配置做一些調(diào)整,讓BootROM也能正常處理處于Continuous read模式的Flash;三、ROM和App聯(lián)合對Flash模式切換做一些特殊處理。

 

二、核心切入點(diǎn)(借助Flash的軟復(fù)位命令功能)

本文找的核心切入點(diǎn)是利用Flash的軟件復(fù)位命令。Flash的軟件復(fù)位時(shí)序有兩種:一種是JEDEC標(biāo)準(zhǔn)規(guī)定的(嚴(yán)格來說其實(shí)算硬件復(fù)位,但因?yàn)槠湫鐲S#,SCK,IO0三根信號線配合完成,因此痞子衡將其歸為軟件復(fù)位時(shí)序類);另一種是廠商定義的軟件復(fù)位命令(因?yàn)镾OIC-8封裝的Flash沒有獨(dú)立RESET#引腳,因此廠商增加這個(gè)軟復(fù)位命令來代替缺失的獨(dú)立RESET#引腳功能)。

2.1 JEDEC標(biāo)準(zhǔn)復(fù)位時(shí)序

JEDEC協(xié)會(huì)規(guī)定了一種Flash復(fù)位時(shí)序,需要CS#,SCK,IO0三根信號線配合完成,時(shí)序如下,保持SCK電平不變(高/低均可),拉四次CS#信號,通過SI信號線輸出4'b0101(在CS#上升沿采樣),則Flash會(huì)進(jìn)入復(fù)位狀態(tài)。

JEDEC標(biāo)準(zhǔn)復(fù)位功能并不是所有Flash都集成的,華邦、芯成主流Flash型號均不支持JEDEC標(biāo)準(zhǔn)復(fù)位,痞子衡知道的Adesto ATXP032系列Flash里有JEDEC標(biāo)準(zhǔn)復(fù)位。

ATXP032數(shù)據(jù)手冊里關(guān)于JEDEC標(biāo)準(zhǔn)復(fù)位相關(guān)時(shí)序要求如下,進(jìn)入JEDEC復(fù)位后需要 tXUDPD 時(shí)間來恢復(fù)。

 

2.2 軟件復(fù)位命令時(shí)序

Flash數(shù)據(jù)手冊命令集里通常都可以找到reset相關(guān)命令。在IS25WP128數(shù)據(jù)手冊里我們可以找到如下軟復(fù)位時(shí)序,它由0x66(RSTEN)和0x99(RST)命令組合完成,主芯片發(fā)完該命令組合后,F(xiàn)lash即進(jìn)入復(fù)位狀態(tài)。

IS25WP128軟件復(fù)位最大需要100us的恢復(fù)時(shí)間,在恢復(fù)期間內(nèi)對Flash進(jìn)行讀寫擦操作并不會(huì)生效。

 

三、具體實(shí)現(xiàn)

本章節(jié)描述的方法,如果是在App里(這里均指XIP App)完成,那么App里增加的相關(guān)處理代碼(注意是執(zhí)行到的全部代碼)需要是 ramfunc 屬性(即運(yùn)行在內(nèi)部RAM里),這樣操作Flash時(shí)可以不受限制。此外代碼運(yùn)行前需要把全局中斷關(guān)掉,防止執(zhí)行過程中有中斷觸發(fā),導(dǎo)致Flash里的相關(guān)IRQHandler函數(shù)被執(zhí)行。

#if (defined(__ICCARM__))
__ramfunc 
#endif
void reset_flash_to_normal(void)
{
    __disable_irq();

    // 處理代碼,使Flash返回到Normal模式

    NVIC_SystemReset();
}

 

3.1 僅ROM方面做相關(guān)處理

我們先僅從ROM單方面角度來解決問題,可以先看下痞子衡之前的舊文 《了解i.MXRT1060系列ROM中串行NOR Flash啟動(dòng)初始化流程優(yōu)化點(diǎn)》 里的2.3節(jié)。部分i.MXRT型號ROM里在串行NOR Flash啟動(dòng)流程里集成了JEDEC標(biāo)準(zhǔn)復(fù)位。

如果要利用ROM里集成的JEDEC標(biāo)準(zhǔn)復(fù)位功能,則Flash本身必須支持JEDEC標(biāo)準(zhǔn)復(fù)位。本系列示例主芯片i.MXRT1170的fusemap表里關(guān)于JEDEC_RESET的相關(guān)定義如下,所以我們需要將fuse 0xC80[6]位燒寫為1。

 

 

3.2 僅App方面做相關(guān)處理

上一小節(jié)里的方法先決條件是Flash要支持JEDEC標(biāo)準(zhǔn)復(fù)位,但實(shí)際客戶項(xiàng)目中選型的Flash往往沒有集成JEDEC標(biāo)準(zhǔn)復(fù)位。所以我們更多應(yīng)該在廠商定義的軟復(fù)位命令上做文章,這就要從App方面的角度來解決問題了。

IS25WP128數(shù)據(jù)手冊里找到如下兩個(gè)關(guān)于reset的命令,reset_flash_to_normal() 函數(shù)里只需要按序發(fā)送這兩個(gè)命令,并且延時(shí)等夠軟復(fù)位恢復(fù)時(shí)間即可。

代碼可以基于 SDK_2.9.1_MIMXRT1170-EVKboardsevkmimxrt1170driver_examplesflexspinorpolling_transfercm7下面的 flexspi_nor_polling_transfer.c 和 flexspi_nor_flash_ops.c,并新增如下代碼:

#define NOR_CMD_LUT_SEQ_IDX_RESETENABLE 14
#define NOR_CMD_LUT_SEQ_IDX_RESET       15

#define CUSTOM_LUT_LENGTH 64
const uint32_t customLUT[CUSTOM_LUT_LENGTH] = {
    // ...

    /* 新增 Reset Enable */
    [4 * NOR_CMD_LUT_SEQ_IDX_RESETENABLE] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x66, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),

    /* 新增 Reset */
    [4 * NOR_CMD_LUT_SEQ_IDX_RESET] =
        FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x99, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
};

status_t flexspi_nor_software_reset(FLEXSPI_Type *base)
{
    flexspi_transfer_t flashXfer;
    status_t status;

    /* Write enable */
    flashXfer.deviceAddress = 0;
    flashXfer.port          = kFLEXSPI_PortA1;
    flashXfer.cmdType       = kFLEXSPI_Command;
    flashXfer.SeqNumber     = 1;
    flashXfer.seqIndex      = NOR_CMD_LUT_SEQ_IDX_RESETENABLE;

    status = FLEXSPI_TransferBlocking(base, &flashXfer);
    if (status != kStatus_Success)
    {
        return status;
    }

    flashXfer.seqIndex      = NOR_CMD_LUT_SEQ_IDX_RESET;

    status = FLEXSPI_TransferBlocking(base, &flashXfer);

    return status;
}

void reset_flash_to_normal(void)
{
    __disable_irq();

    flexspi_nor_flash_init(EXAMPLE_FLEXSPI);
    
    flexspi_nor_software_reset(EXAMPLE_FLEXSPI);

    // 這里需要插入足夠的延時(shí)
    SDK_DelayAtLeastUs(100, SystemCoreClock);
    
    NVIC_SystemReset();
}

為了保證上述代碼均執(zhí)行在RAM里,工程鏈接文件里(以IAR示例)需做如下改動(dòng):

initialize by copy { readwrite, 
                     section .textrw, 
                     object fsl_common.o,
                     object I64DivZer.o,
                     object I64DivMod.o,
                     object fsl_flexspi.o,
                     object flexspi_nor_flash_ops.o,
                     object flexspi_nor_polling_transfer.o,
                     section CodeQuickAccess };

 

3.3 ROM和App聯(lián)合處理

關(guān)于ROM和App聯(lián)合處理角度,在復(fù)位命令這個(gè)切入點(diǎn)上并沒有什么優(yōu)勢,此處略去。

至此,i.MXRT上使能NOR Flash的Continuous read模式在軟復(fù)位后無法正常啟動(dòng)問題的解決經(jīng)驗(yàn)痞子衡便介紹完畢了,掌聲在哪里~~~

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

碩士畢業(yè)于蘇州大學(xué)電子信息學(xué)院,目前就職于恩智浦(NXP)半導(dǎo)體MCU系統(tǒng)部門,擔(dān)任嵌入式系統(tǒng)應(yīng)用工程師。痞子衡會(huì)定期分享嵌入式相關(guān)文章