0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

缺失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 的数据手册(Data Sheet)找到 FlexSPI parameters 小节里的如下内容,就很清楚了。FlexSPIn_MCR0[RXCLKSRC] 位对应了三种 DQS 信号源设置:0x0 - Dummy read strobe looped back internally 设置即完全不用 DQS 引脚(可作它用),对应最高 60MHz SDR 访问速度;0x1 - Dummy read strobe looped back through the DQS pad 设置即从 DQS 引脚上回环,因此 DQS 引脚需要悬空,对应最高 133MHz SDR 访问速度;0x3 - Read strobe from memory device DQS pad 设置即接到存储芯片 DQS 引脚上,对应最高 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?

目前恩智浦已量产的所有 i.MXRT 型号里(RT500/600/1010/1015/1020/1050/1060/1160/1170),大部分的 FlexSPI 引脚组合都是包含 DQS 信号设计的,只有如下两个例外。没有 DQS 信号的引脚组合连 Flash 时,应配置 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 引脚组合,使用恩智浦相关工具操作连接在其上的 NOR Flash 是需要做一些改动的,我们以 i.MXRT1170-Validation 板卡为例来介绍具体改动。

i.MXRT1170-Validation 板卡是专供恩智浦内部使用的,分为 CPU1/2/3/4 四款,每款的硬件连接不同,其中 CPU2 板卡在 FlexSPI2 2nd PortA 上连接了一颗镁光的 MT25QL128:

图片

图片

3.1 SDK中FlexSPI擦写Flash例程改动

我们现在打开 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() 函数,需要将 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,并相应调整 Flash 属性(EVK 上是 IS25WP128,Validation 板上是 MT25QL128),以及更新 flexspi_clock_init() 函数:

//#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() 函数里给 FlexSPI 设置的时钟源是 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() 函数,config.rxSampleClock 设置必须要改成 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工程使用

现在我们再来用一下 SDK 里的 flashloader 工程,这个应用程序可以与恩智浦专用命令行上位机 blhost.exe 进行交互,工程需要用调试器下载进主芯片内部 RAM 运行

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

flashloader 运行起来之后,使用 blhost 工具按序执行下列命令,也一样能对 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]是关键设置!!!
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 命令的参数 0xc1000053 是关键,从 flashloader 源代码里看它其实是在设置 serial_nor_config_option_t.option0.B.misc_mode 为 kSerialNorEnhanceMode_InternalLoopback,这个设置对于四线 QSPI Flash 而言就是设 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 设置),也可以正常擦写 Flash。熟悉这个工具原理的朋友应该知道它底层依赖得就是 3.2 节里的 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,
};
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • RAM
    RAM
    +关注

    关注

    8

    文章

    1403

    浏览量

    121156
  • 调试器
    +关注

    关注

    1

    文章

    329

    浏览量

    25241
  • Flash存储
    +关注

    关注

    0

    文章

    40

    浏览量

    8630
  • QSPI接口
    +关注

    关注

    0

    文章

    14

    浏览量

    3670
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    i.MX RT系列中FlexSPI DQS信号引脚配置GPIO方法

    在i.MX RT060项目(采用QSPI Flash)的实际应用中,客户反馈,其在设计阶段并未预留DQS信号引脚,而是将该引脚作为GPIO用于控制关键外设的开关,这导致程序无法正常运
    的头像 发表于 06-16 11:30 1656次阅读
    i.MX RT系列中<b class='flag-5'>FlexSPI</b> <b class='flag-5'>DQS</b><b class='flag-5'>信号</b>引脚配置GPIO方法

    恩智浦i.MXRT1180的FlexSPI NOR启动连接方式

    最近属于i.MXRT11xx阵营的第二代旗舰i.MXRT1180正式发布了,今天咱们就来介绍它的FlexSPI NOR启动连接方式,在阅读本文前最好把FlexSPI NOR启动连接方式
    的头像 发表于 11-08 10:20 6610次阅读
    恩智浦i.MXRT1180的<b class='flag-5'>FlexSPI</b> NOR启动<b class='flag-5'>连接</b>方式

    Vitex-6如何延迟dqs 3 ns

    嗨, 我正在为我的设计添加一个NAND闪存。闪存芯片支持源同步接口,可提供高达166MB / s的带宽。但是当我从闪存中读取DDR数据时。 DQS信号从闪存芯片传输到我的FPGA器件,以及与DQS
    发表于 03-29 14:03

    NOR Flash与NAND Flash何不

    Flash的原理是什么?Flash主要有哪几种?NOR Flash与NAND Flash何不
    发表于 10-22 08:47

    FlexSPIDQS信号作用是什么?哪些FlexSPI引脚组不支持DQS

    FlexSPIDQS信号作用是什么?哪些FlexSPI引脚组不支持DQS
    发表于 01-19 07:06

    启用FLEXSPI NOR Flash调试的教程

    如何启用FLEXSPI NOR Flash的调试
    发表于 12-12 06:13

    imxrt1170中flexspi如何使用AHB操作?

    一个 imxrt1170 板,想使用 flexspi1(连接到 fpga)。我想在 flexspi1 上使用 AHB 总线操作,但是当我访问 BASE_ADDR(0x3000000
    发表于 03-27 08:16

    求助,可以忽略FlexSPI DQS吗?

    DQS 线用于读写数据选通。我一直在看一些 FlexSPI 示例:-sdk_flexspi_nor_polling_transferpolling_transfer_hyperRAM 在这
    发表于 03-29 07:34

    调试器因FlexSPI Nor Flash指令失败的原因?如何解决?

    尝试执行函数 flexspi_nor_flash_init(...) ,调试器就会断开连接并显示:我一种感觉,它与一些时钟配置有关,但不知道从这里去哪里出现问题的代码片段:int main(void
    发表于 03-29 08:05

    启动后需要使用RT1052中的DQS引脚进行I2C,要怎么操作?

    FlexSPIDQS (数据选通),即使我不需要或不想使用引脚。硬件场景如下:单个 IS25WP064A-JBLE 连接,没有 DQS(数据选通),只有内部 RAM(没有外部
    发表于 04-10 08:41

    如何设法将固件直接下载到连接flexspi PORT B的闪存?

    大家好, 我们一块定制板,W25Q128JV 连接FLEXSPI 端口 B,我无法让 MCUXpresso/Keil 直接将固件下载到闪存,我可以确认下载算法是正确的,因为相同的算法适用于
    发表于 05-04 08:44

    i.MXRT117x - FlexSPI1和FlexSPI2能否以133MHz的全时钟速度运行?

    ,我们无法让 FlexSPI2 以 133MHz 的全时钟速度运行。如果这是可能的,我们还没有想出如何去做。我们只能以半时钟频率运行 FlexSPI2。GPIO_EMC_B2_12 上的 DQS 引脚是否配置为
    发表于 05-23 06:31

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

    由于i.MXRT内部没有非易失性存储器,因此在系统设计时为i.MXRT搭配一块存放应用程序代码的存储器是头等大事。i.MXRT支持启动的外部存储器类型众多,其中通过FlexSPI接口连接串行NOR Flash是首选。
    发表于 02-09 11:26 1次下载
    <b class='flag-5'>FlexSPI</b> NOR<b class='flag-5'>连接</b>方式大全(RT1015/1020/1050)

    I.MXRT1170从FLEXSPI2启动

    设计将使用FlexSPI1 接外部的 HyperRAM,FlexSPI2 接QSPI Flash存储器芯片作为RT1176 引导设备。当代码在内部RAM里面执行的时候是正常的,遇到了从外部Fl
    的头像 发表于 12-01 15:06 2307次阅读

    探讨i.MX RT下FlexSPI driver实现Flash编程时对于中断支持问题

    前段时间客户在官方社区反映i.MX RT1170下,使用官方SDK里FlexSPI驱动去擦写Flash时不能很好地支持全局中断。 客户项目里用了两块NOR Flash,分别挂在
    的头像 发表于 02-06 15:09 2164次阅读