0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

缺失DQS信號的FlexSPI連接Flash有何不同?

冬至子 ? 來源:痞子衡嵌入式 ? 作者:痞子衡 ? 2023-06-02 17:53 ? 次閱讀

一、FlexSPI的DQS信號作用

文章中沒有提及四線 QSPI Flash,因為一般的四線 QSPI Flash 芯片并沒有 DQS 信號引腳。FlexSPI 模塊的 DQS 信號當然可以用來連接 Octal Flash、Hyper Flash 上的 DQS 引腳,那么對于四線 QSPI Flash,這個 DQS 信號就沒有作用了嗎?其實不是的。

我們翻開 i.MXRT1170 的數(shù)據(jù)手冊(Data Sheet)找到 FlexSPI parameters 小節(jié)里的如下內(nèi)容,就很清楚了。FlexSPIn_MCR0[RXCLKSRC] 位對應(yīng)了三種 DQS 信號源設(shè)置:0x0 - Dummy read strobe looped back internally 設(shè)置即完全不用 DQS 引腳(可作它用),對應(yīng)最高 60MHz SDR 訪問速度;0x1 - Dummy read strobe looped back through the DQS pad 設(shè)置即從 DQS 引腳上回環(huán),因此 DQS 引腳需要懸空,對應(yīng)最高 133MHz SDR 訪問速度;0x3 - Read strobe from memory device DQS pad 設(shè)置即接到存儲芯片 DQS 引腳上,對應(yīng)最高 166MHz SDR 訪問速度;

? Dummy read strobe generated by FlexSPI controller and looped back internally (FlexSPIn_MCR0[RXCLKSRC] = 0x0)
? Dummy read strobe generated by FlexSPI controller and looped back through the DQS pad (FlexSPIn_MCR0[RXCLKSRC] = 0x1)
? Read strobe provided by memory device and input from DQS pad (FlexSPIn_MCR0[RXCLKSRC] = 0x3)

圖片

圖片

二、哪些FlexSPI引腳組不支持DQS?

目前恩智浦已量產(chǎn)的所有 i.MXRT 型號里(RT500/600/1010/1015/1020/1050/1060/1160/1170),大部分的 FlexSPI 引腳組合都是包含 DQS 信號設(shè)計的,只有如下兩個例外。沒有 DQS 信號的引腳組合連 Flash 時,應(yīng)配置 FlexSPIn_MCR0[RXCLKSRC] 為 0x0 - looped back internally。

2.1 i.MXRT600 FlexSPI0 PortB

2.2 i.MXRT1160/1170 FlexSPI2 2nd PortA

三、使能沒有DQS的FlexSPI連接的Flash

對于不含 DQS 信號的 FlexSPI 引腳組合,使用恩智浦相關(guān)工具操作連接在其上的 NOR Flash 是需要做一些改動的,我們以 i.MXRT1170-Validation 板卡為例來介紹具體改動。

i.MXRT1170-Validation 板卡是專供恩智浦內(nèi)部使用的,分為 CPU1/2/3/4 四款,每款的硬件連接不同,其中 CPU2 板卡在 FlexSPI2 2nd PortA 上連接了一顆鎂光的 MT25QL128:

圖片

圖片

3.1 SDK中FlexSPI擦寫Flash例程改動

我們現(xiàn)在打開 SDK 里的 FlexSPI 例程,這個例程是針對 MIMXRT1170-EVK 板卡寫的,在 EVK 上 NOR Flash 默認是連在 FlexSPI1 1st PortA 上的,因此我們需要對例程做一些改動。

例程路徑:\\SDK_2.x.x_MIMXRT1170-EVK\\boards\\evkmimxrt1170\\driver_examples\\flexspi\\nor\\polling_transfer\\cm7

首當其沖的改動當然是 pin_mux.c 文件里的 BOARD_InitPins() 函數(shù),需要將 FlexSPI1 1st Pinmux 換成 FlexSPI2 2nd Pinmux:

void BOARD_InitPins(void) 
{
    CLOCK_EnableClock(kCLOCK_Iomuxc);

    //IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B2_05_FLEXSPI1_A_DQS, 1U);
    //IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B2_06_FLEXSPI1_A_SS0_B, 1U;
    //IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B2_07_FLEXSPI1_A_SCLK, 1U);
    //IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B2_08_FLEXSPI1_A_DATA00, 1U);
    //IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B2_09_FLEXSPI1_A_DATA01, 1U);
    //IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B2_10_FLEXSPI1_A_DATA02, 1U);
    //IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B2_11_FLEXSPI1_A_DATA03, 1U);
    //IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B2_05_FLEXSPI1_A_DQS, 0x0AU);
    //IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B2_06_FLEXSPI1_A_SS0_B, 0x0AU);
    //IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B2_07_FLEXSPI1_A_SCLK, 0x0AU);
    //IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B2_08_FLEXSPI1_A_DATA00, 0x0AU);
    //IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B2_09_FLEXSPI1_A_DATA01, 0x0AU);
    //IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B2_10_FLEXSPI1_A_DATA02, 0x0AU);
    //IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B2_11_FLEXSPI1_A_DATA03, 0x0AU);
    IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_00_FLEXSPI2_A_SS0_B, 1U;
    IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_01_FLEXSPI2_A_SCLK, 1U);
    IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_02_FLEXSPI2_A_DATA00, 1U);
    IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_03_FLEXSPI2_A_DATA01, 1U);
    IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_04_FLEXSPI2_A_DATA02, 1U);
    IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_05_FLEXSPI2_A_DATA03, 1U);
    IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_00_FLEXSPI2_A_SS0_B, 0x0AU);
    IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_01_FLEXSPI2_A_SCLK, 0x0AU);
    IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_02_FLEXSPI2_A_DATA00, 0x0AU);
    IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_03_FLEXSPI2_A_DATA01, 0x0AU);
    IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_04_FLEXSPI2_A_DATA02, 0x0AU);
    IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_05_FLEXSPI2_A_DATA03, 0x0AU);
}

然后再改一下 app.h 文件里的宏定義,從 FlexSPI1 換到 FlexSPI2,并相應(yīng)調(diào)整 Flash 屬性(EVK 上是 IS25WP128,Validation 板上是 MT25QL128),以及更新 flexspi_clock_init() 函數(shù):

//#define EXAMPLE_FLEXSPI FLEXSPI1
//#define EXAMPLE_FLEXSPI_AMBA_BASE FlexSPI1_AMBA_BASE
//#define EXAMPLE_FLEXSPI_CLOCK kCLOCK_Flexspi1
#define EXAMPLE_FLEXSPI FLEXSPI2
#define EXAMPLE_FLEXSPI_AMBA_BASE FlexSPI2_AMBA_BASE
#define EXAMPLE_FLEXSPI_CLOCK kCLOCK_Flexspi2

static inline void flexspi_clock_init(void)
{
    // 在 BOARD_BootClockRUN() 函數(shù)里給 FlexSPI 設(shè)置的時鐘源是 OSC_RC_48M_DIV2 / 2 即 12MHz
    // 這里沒有再次分頻,因此 FlexSPI root clock 就是 12MHz
    //CLOCK_SetRootClockDiv(kCLOCK_Root_Flexspi1, 2);
    //CLOCK_SetRootClockMux(kCLOCK_Root_Flexspi1, 0);
    CLOCK_SetRootClockDiv(kCLOCK_Root_Flexspi2, 2);
    CLOCK_SetRootClockMux(kCLOCK_Root_Flexspi2, 0);
}

上面都是大家能意識到的改動,但其實最容易被忽略的改動是 flexspi_nor_flash_ops.c 文件里的 flexspi_nor_flash_init() 函數(shù),config.rxSampleClock 設(shè)置必須要改成 kFLEXSPI_ReadSampleClkLoopbackInternally 才行。代碼全部改完之后下載運行就可以正常擦寫 Flash 了。

void flexspi_nor_flash_init(FLEXSPI_Type *base)
{
    // 省略部分代碼 ...

    flexspi_clock_init();

    flexspi_config_t config;
    FLEXSPI_GetDefaultConfig(&config);

    config.ahbConfig.enableAHBPrefetch    = true;
    config.ahbConfig.enableAHBBufferable  = true;
    config.ahbConfig.enableReadAddressOpt = true;
    config.ahbConfig.enableAHBCachable    = true;
    //config.rxSampleClock                  = kFLEXSPI_ReadSampleClkLoopbackFromDqsPad;
    config.rxSampleClock                  = kFLEXSPI_ReadSampleClkLoopbackInternally;
    FLEXSPI_Init(base, &config);

    // 省略部分代碼 ...
}

3.2 SDK中Flashloader工程使用

現(xiàn)在我們再來用一下 SDK 里的 flashloader 工程,這個應(yīng)用程序可以與恩智浦專用命令行上位機 blhost.exe 進行交互,工程需要用調(diào)試器下載進主芯片內(nèi)部 RAM 運行

工程路徑:\\SDK_2.x.x_MIMXRT1170-EVK\\boards\\evkmimxrt1170\\bootloader_examples\\flashloader\\cm7

flashloader 運行起來之后,使用 blhost 工具按序執(zhí)行下列命令,也一樣能對 Flash 進行擦寫:

blhost -u -- get-property 1

# 選中 FlexSPI2
blhost -u -- fill-memory 0x20000000 4 0xcf900002
blhost -u -- configure-memory 9 0x20000000

# 配置 NOR Flash(forced internal DQS)
blhost -u -- fill-memory 0x20000000 4 0xc1000053  # 其中bit[7:4]是關(guān)鍵設(shè)置!!!
blhost -u -- fill-memory 0x20000004 4 0x00110000
blhost -u -- configure-memory 9 0x20000000
blhost -u -- get-property 25 9

# 下載包含 IVT 頭的 App
blhost -u -- flash-erase-region 0x60000000 0x8000
blhost -u -- fill-memory 0x20000000 4 0xf000000f
blhost -u -- configure-memory 9 0x20000000
blhost -u -- write-memory 0x60001000 ivt_app.bin

上面命令序列里第二條 fill-memory 命令的參數(shù) 0xc1000053 是關(guān)鍵,從 flashloader 源代碼里看它其實是在設(shè)置 serial_nor_config_option_t.option0.B.misc_mode 為 kSerialNorEnhanceMode_InternalLoopback,這個設(shè)置對于四線 QSPI Flash 而言就是設(shè) config->memConfig.readSampleClkSrc 為 kFlexSPIReadSampleClk_LoopbackInternally:

enum
{
    kSerialNorEnhanceMode_Disabled = 0,
    kSerialNorEnhanceMode_0_4_4_Mode = 1,
    kSerialNorEnhanceMode_0_8_8_Mode = 2,
    kSerialNorEnhanceMode_DataOrderSwapped = 3,
    kSerialNorEnhanceMode_2ndPinMux = 4,
    kSerialNorEnhanceMode_InternalLoopback = 5,
};

status_t parse_sfdp(uint32_t instance,
                    flexspi_nor_config_t *config,
                    jedec_info_table_t *tbl,
                    serial_nor_config_option_t *option)
{
    status_t status = kStatus_InvalidArgument;
    do
    {
        // 省略部分代碼...
        uint8_t misc_mode = option- >option0.B.misc_mode;
        if (misc_mode == kSerialNorEnhanceMode_Disabled)
        {
            // 省略部分代碼...
        }
#if FLEXSPI_ENABLE_NO_CMD_MODE_SUPPORT
        else if (misc_mode == kSerialNorEnhanceMode_0_4_4_Mode)
        {
            // 省略部分代碼...
        }
#endif // FLEXSPI_ENABLE_NO_CMD_MODE_SUPPORT
        else if (misc_mode == kSerialNorEnhanceMode_InternalLoopback)
        {
            config- >memConfig.readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackInternally;
        }
        else
        {
            // Do nothing
        }
        // 省略部分代碼...
    } while (0);
    return status;
}

3.3 下載工具MCUBootUtility配置

flashloader 的使用對一般客戶來說太復雜了,還是圖形化工具 MCUBootUtility 更方便,打開這個工具,按如下配置(主要就是圖中藍框圈起來的 Misc Mode 設(shè)置),也可以正常擦寫 Flash。熟悉這個工具原理的朋友應(yīng)該知道它底層依賴得就是 3.2 節(jié)里的 flashloader 與 blhost。

圖片

3.4 SDK例程里的FDCB啟動頭改動

最后就是 SDK 里全部例程的 XIP build 都需要一個 FDCB 頭,這個頭定義在 evkmimxrt1170_flexspi_nor_config.c 文件里,這里也要改一下 readSampleClkSrc 和 serialClkFreq 配置才行。

const flexspi_nor_config_t qspiflash_config = {
    .memConfig =
        {
            .tag              = FLEXSPI_CFG_BLK_TAG,
            .version          = FLEXSPI_CFG_BLK_VERSION,
            //.readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad,
            .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackInternally,
            .csHoldTime       = 3u,
            .csSetupTime      = 3u,
            .controllerMiscOption = 0x10,
            .deviceType           = kFlexSpiDeviceType_SerialNOR,
            .sflashPadType        = kSerialFlash_4Pads,
            //.serialClkFreq        = kFlexSpiSerialClk_133MHz,
            .serialClkFreq        = kFlexSpiSerialClk_60MHz,
            .sflashA1Size         = 16u * 1024u * 1024u,
            .lookupTable =
                {
                    // Read LUTs
                    FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
                    FLEXSPI_LUT_SEQ(MODE8_SDR, FLEXSPI_4PAD, 0x00, DUMMY_SDR, FLEXSPI_4PAD, 0x04),
                    FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_4PAD, 0x04, 0, 0, 0),
                },
        },
    .pageSize           = 256u,
    .sectorSize         = 4u * 1024u,
    .ipcmdSerialClkFreq = 0x1,
    .blockSize          = 256u * 1024u,
    .isUniformBlockSize = false,
};
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • RAM
    RAM
    +關(guān)注

    關(guān)注

    8

    文章

    1344

    瀏覽量

    114215
  • 調(diào)試器
    +關(guān)注

    關(guān)注

    1

    文章

    297

    瀏覽量

    23568
  • Flash存儲
    +關(guān)注

    關(guān)注

    0

    文章

    38

    瀏覽量

    8265
  • QSPI接口
    +關(guān)注

    關(guān)注

    0

    文章

    14

    瀏覽量

    3317
收藏 人收藏

    評論

    相關(guān)推薦

    Vitex-6如何延遲dqs 3 ns

    嗨, 我正在為我的設(shè)計添加一個NAND閃存。閃存芯片支持源同步接口,可提供高達166MB / s的帶寬。但是當我從閃存中讀取DDR數(shù)據(jù)時。 DQS信號從閃存芯片傳輸?shù)轿业腇PGA器件,以及與DQS
    發(fā)表于 03-29 14:03

    NOR Flash與NAND Flash何不

    Flash的原理是什么?Flash主要有哪幾種?NOR Flash與NAND Flash何不
    發(fā)表于 10-22 08:47

    FlexSPIDQS信號作用是什么?哪些FlexSPI引腳組不支持DQS?

    FlexSPIDQS信號作用是什么?哪些FlexSPI引腳組不支持DQS?
    發(fā)表于 01-19 07:06

    啟用FLEXSPI NOR Flash調(diào)試的教程

    如何啟用FLEXSPI NOR Flash的調(diào)試
    發(fā)表于 12-12 06:13

    Hyperflash設(shè)備的不同FlexSPI數(shù)據(jù)信號順序是怎樣的?

    和 Hyperflash 之間的連接中,A_DATAx跡線與B_DATAx跡線交換。換句話說,我們以下場景:A_DATA0 與 B_DATA0 交換A_DATA1 與 B_DATA1 交換A_DATA2
    發(fā)表于 03-20 06:42

    imxrt1170中flexspi如何使用AHB操作?

    一個 imxrt1170 板,想使用 flexspi1(連接到 fpga)。我想在 flexspi1 上使用 AHB 總線操作,但是當我訪問 BASE_ADDR(0x3000000
    發(fā)表于 03-27 08:16

    求助,可以忽略FlexSPI DQS嗎?

    DQS 線用于讀寫數(shù)據(jù)選通。我一直在看一些 FlexSPI 示例:-sdk_flexspi_nor_polling_transferpolling_transfer_hyperRAM 在這
    發(fā)表于 03-29 07:34

    調(diào)試器因FlexSPI Nor Flash指令失敗的原因?如何解決?

    嘗試執(zhí)行函數(shù) flexspi_nor_flash_init(...) ,調(diào)試器就會斷開連接并顯示:我一種感覺,它與一些時鐘配置有關(guān),但不知道從這里去哪里出現(xiàn)問題的代碼片段:int main(void
    發(fā)表于 03-29 08:05

    啟動后需要使用RT1052中的DQS引腳進行I2C,要怎么操作?

    FlexSPIDQS (數(shù)據(jù)選通),即使我不需要或不想使用引腳。硬件場景如下:單個 IS25WP064A-JBLE 連接,沒有 DQS(數(shù)據(jù)選通),只有內(nèi)部 RAM(沒有外部
    發(fā)表于 04-10 08:41

    如何設(shè)法將固件直接下載到連接flexspi PORT B的閃存?

    大家好, 我們一塊定制板,W25Q128JV 連接FLEXSPI 端口 B,我無法讓 MCUXpresso/Keil 直接將固件下載到閃存,我可以確認下載算法是正確的,因為相同的算法適用于
    發(fā)表于 05-04 08:44

    MXRT1050 FlexSPI有沒有辦法支持超過16個flash命令的NOR Flash設(shè)備?

    flash 命令的 NOR Flash 設(shè)備? 2. 有沒有辦法在沒有 LUT 的情況下使用 FlexSPI 模塊?-----
    發(fā)表于 05-08 06:52

    i.MXRT117x - FlexSPI1和FlexSPI2能否以133MHz的全時鐘速度運行?

    ,我們無法讓 FlexSPI2 以 133MHz 的全時鐘速度運行。如果這是可能的,我們還沒有想出如何去做。我們只能以半時鐘頻率運行 FlexSPI2。GPIO_EMC_B2_12 上的 DQS 引腳是否配置為
    發(fā)表于 05-23 06:31

    FlexSPI NOR連接方式大全(RT1015/1020/1050)

    由于i.MXRT內(nèi)部沒有非易失性存儲器,因此在系統(tǒng)設(shè)計時為i.MXRT搭配一塊存放應(yīng)用程序代碼的存儲器是頭等大事。i.MXRT支持啟動的外部存儲器類型眾多,其中通過FlexSPI接口連接串行NOR Flash是首選。
    發(fā)表于 02-09 11:26 ?1次下載
    <b class='flag-5'>FlexSPI</b> NOR<b class='flag-5'>連接</b>方式大全(RT1015/1020/1050)

    I.MXRT1170從FLEXSPI2啟動

    設(shè)計將使用FlexSPI1 接外部的 HyperRAM,FlexSPI2 接QSPI Flash存儲器芯片作為RT1176 引導設(shè)備。當代碼在內(nèi)部RAM里面執(zhí)行的時候是正常的,遇到了從外部Fl
    的頭像 發(fā)表于 12-01 15:06 ?1243次閱讀

    探討i.MX RT下FlexSPI driver實現(xiàn)Flash編程時對于中斷支持問題

    前段時間客戶在官方社區(qū)反映i.MX RT1170下,使用官方SDK里FlexSPI驅(qū)動去擦寫Flash時不能很好地支持全局中斷。 客戶項目里用了兩塊NOR Flash,分別掛在
    的頭像 發(fā)表于 02-06 15:09 ?1097次閱讀