大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是在FDCB里配置串行NOR Flash多个寄存器的注意事项

  关于使用 i.MXRT 启动头 FDCB 来设置 Flash 内部寄存器,痞子衡写过如下两篇文章,在进入本文之前,建议大家先阅读下这两篇文章,有个初步了解。

  我们知道 Flash 内部常常有多个状态/配置寄存器,这些寄存器有些是易失性的,有些是非易失性的。当芯片被指定从 Flash 启动的时候,我们如果希望 BootROM 能够根据不同应用需求来提前设置好这些 Flash 寄存器,那么在应用程序里就不用再额外配置了(涉及 Flash 工作状态变化的配置,如果是 XIP 程序去操作,需要考虑代码重定向问题)。

  对于使用 FDCB 来配置 Flash 一个寄存器的操作,相信大家都很了解,在恩智浦 SDK 包里默认 FDCB 启动头里都有成功示例。最近痞子衡同事尝试使用 FDCB 去配置镁光 MT35X 的两个寄存器(地址为 0x000000 的寄存器切至 OPI DDR、地址为 0x000003 的寄存器设 Drive Strength)发现有一个寄存器设置没生效,这是怎么回事?今天我们来聊一聊:

  • Note: 本文适用于 i.MXRT500/600/1010/1020/1040/1050/1060/1160/1170

一、FDCB提供的Flash寄存器配置能力

  我们先来看一下 FDCB 结构里跟 Flash 配置相关的成员,痞子衡整理如下,简单来说,就是有一条 deviceModeSeq 和三条 configCmdSeqs,所以最多能配置 Flash 里 4 个不同命令下对应的寄存器(有些 Flash 里一条配置命令能连续写入多个寄存器,这种情况下就能配置不止 4 个寄存器),这对于大部分应用场景都完全够用了。

  • Note 1: BootROM 执行这四个配置的顺序分别是 deviceModeSeq、configCmdSeqs[0]、configCmdSeqs[1]、configCmdSeqs[2],记住这个顺序。
  • Note 2: deviceModeSeq 与 configCmdSeq 实现的配置功能几乎没有区别,两者能做的事情是一样的,可以互换。
//!@brief FlexSPI Memory Configuration Block
typedef struct _FlexSPIConfig
{
// ... //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable
uint8_t deviceModeCfgEnable;
//!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, Generic configuration, etc.
uint8_t deviceModeType;
//!< [0x012-0x013] Wait time for all configuration commands, unit: 100us
uint16_t waitTimeCfgCommands;
//!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt sequence number, [31:16] Reserved
flexspi_lut_seq_t deviceModeSeq;
//!< [0x018-0x01b] Argument/Parameter for device configuration
uint32_t deviceModeArg; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable
uint8_t configCmdEnable;
//!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe
uint8_t configModeType[3];
//!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq
flexspi_lut_seq_t configCmdSeqs[3];
//!< [0x030-0x03b] Arguments/Parameters for device Configuration commands
uint32_t configCmdArgs[3]; // ... //!< [0x07c-0x07d] Busy offset, valid value: 0-31
uint16_t busyOffset;
//!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - busy flag is 0 when flash device is busy
uint16_t busyBitPolarity;
//!< [0x080-0x17f] Lookup table holds Flash command sequences
uint32_t lookupTable[64]; // ... } flexspi_mem_config_t;

  在 《在FDCB里设置Flash的Dummy Cycle》 一文最后,痞子衡已经分享了 BootROM 解析执行 configCmdSeq 的代码流程,在这个流程里我们能看到和 deviceModeType/configModeType[]、waitTimeCfgCommands 成员相关的逻辑代码,这里有必要进一步解释一下。

//!@brief Flash Configuration Command Type
enum
{
kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc
kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command
kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode
kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode
kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode
kDeviceConfigCmdType_Reset, //!< Reset device command
};

  当 deviceModeType/configModeType 成员被设置为 kDeviceConfigCmdType_Spi2Xpi 时;如果 FDCB 本身被获取时 BootROM 用得是 DPI/QPI/OPI 命令(根据 efuse 配置决定),那么此条 Flash 寄存器配置会被直接忽略;如果 BootROM 用得是普通一线 SPI 模式读取的 FDCB,那么这个 Flash 寄存器配置仍然生效。

  kDeviceConfigCmdType_Spi2Xpi 等三个跟 Flash 命令模式切换相关的配置类型,顾名思义就是告诉 BootROM 这三种配置会导致 Flash 工作模式变化,而一旦 Flash 工作模式发生变化,用于判断配置是否完成的 READ_STATUS 命令也随之变得不可用(因为 SPI 模式下与 DPI/QPI/OPI 模式下的命令序列不同),这种情况下就需要借助 waitTimeCfgCommands 成员来实现软件延时以等待对 Flash 的配置真正生效(如果不等生效就直接进入后续流程,可能会导致启动问题)。

  kDeviceConfigCmdType_Generic 配置类型,则是用于跟工作模式切换无关的 Flash 寄存器配置,这种情况下 BootROM 可以使用 READ_STATUS 命令来判断对 Flash 寄存器配置是否已经生效,那么就不需要 waitTimeCfgCommands 实现的延时等待(需要查 Flash 数据手册作相应设置,比较麻烦,而且手册里是给了典型值和最大值,取最大值会导致启动时间变长,典型值不能保证适用所有情况)。

二、配置Flash多个寄存器注意点

  Flash 配置寄存器的写入流程通常分三步:一、WRITE_ENABLE 使能写操作;二、具体的 CONFIG_REG 操作;三、READ_STATUS 或者软件延时确保配置已完成。这些命令序列全部存储在 FDCB 里的 lookupTable[64] 成员里。

  关于 Flash 寄存器的配置操作,从寄存器属性上来看,分为易失性和非易失性两种,前者的操作一般是立即生效的,后者的操作不是立即生效(Flash 状态寄存器 WIP 位会反映进度)。从命令模式角度来看,分为非模式切换操作(比如设置 Dummy Cycle、Drive Strength)以及切换 SPI 与 DPI/QPI/OPI 模式操作两种,同样前者操作是立即生效,后者操作不是立即生效。

  现在回到文章开头痞子衡同事遇到的问题,如果 deviceModeSeq 用于切换至 OPI DDR 模式,configCmdSeqs[0] 用于设 Drive Strength,请问哪一个操作没有生效?这里就不卖关子了,设 Drive Strength 没有生效,因为第一个配置是切换至 OPI DDR 模式,当 Flash 切换到该模式时,用于第二/三/四个配置的 WRITE_ENABLE 命令变得不可用了(还是因为 SPI 模式下与 DPI/QPI/OPI 模式下的命令序列不同),当然对应 Flash 寄存器设置就无效了。

  那么如何避免这个问题?有一个一劳永逸的方法,那就是永远用 configCmdSeqs[2] 去做 SPI 与 DPI/QPI/OPI 模式切换操作,这样就不会影响前面三个配置。前面讲了,此时判断命令模式是否切换完成不能用 READ_STATUS 命令,那么就一定需要 waitTimeCfgCommands 来做软延时,如果延时时间不够,并且后续 BootROM 执行到验证 IVT 头时模式切换仍未完成,这会导致 IVT 启动头无法正确获取从而导致启动失败。

  假设 waitTimeCfgCommands 延时设置对于命令模式切换已足够,这样问题就一定解决了吗?其实还不一定,如果此时已将 deviceModeSeq 用于设 Drive Strength,但是选择得是写入 Flash 非易失性存储器,这需要确保 waitTimeCfgCommands 延时对于写入非易失性寄存器也足够。翻看 MT35X 的数据手册可以发现,写入非易失性寄存器 cycle time 典型值是 0.2s,最大值是 1s。

  再对比看看旺宏以及华邦家的 OctalFlash 非易失性寄存器写入时间,发现旺宏最短(<=60us),华邦其次(<=15ms),镁光有点略长了(<=1s)。越短的写入时间,启动时间也越短。

  如果此时 waitTimeCfgCommands 设置对写入非易失性寄存器来说不够,即没等到 Drive Strength 配置完成就去做切换 OPI 模式操作,这会导致模式切换失败(Flash 在 Busy 期间不能接受任何写入命令),当然也就无法正常启动了。

  以上介绍得都是比较复杂的 Flash 寄存器配置场景,如果是单纯的易失性寄存器配置操作且不涉及模式切换,那么 FDCB 里这四个配置顺序也就不重要了,而且也不需要启用 waitTimeCfgCommands,这样也不需要过多考虑了。

  至此,在FDCB里配置串行NOR Flash多个寄存器的注意事项痞子衡便介绍完毕了,掌声在哪里~~~

欢迎订阅

文章会同时发布到我的 博客园主页CSDN主页知乎主页微信公众号 平台上。

微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。

痞子衡嵌入式:在i.MXRT启动头FDCB里配置串行NOR Flash多个寄存器的注意事项的更多相关文章

  1. 痞子衡嵌入式:在i.MXRT启动头FDCB里使能串行NOR Flash的DTR模式

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是在FDCB里使能串行NOR Flash的DTR模式. 前两篇文章 <IS25WP系列Dummy Cycle设置> 与 < ...

  2. 痞子衡嵌入式:在i.MXRT启动头FDCB里使能串行NOR Flash的Continuous read模式

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是在FDCB里使能串行NOR Flash的Continuous read模式. 前面关于串行Flash传输时序的文章 <Fast R ...

  3. 痞子衡嵌入式:在i.MXRT启动头FDCB里使能串行NOR Flash的QPI/OPI模式

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是在FDCB里使能串行NOR Flash的QPI/OPI模式. 我们知道 Flash 读时序里有五大子序列 CMD + ADDR + MO ...

  4. 痞子衡嵌入式:从头开始认识i.MXRT启动头FDCB里的lookupTable

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT启动头FDCB里的lookupTable. 一个MCU内部通常有很多外设模块,这些外设模块是各MCU厂商做差异化产品的本质, ...

  5. 痞子衡嵌入式:在i.MXRT启动头FDCB里调整Flash工作频率也需同步设Dummy Cycle

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是Flash工作频率与Dummy Cycle的联系. 上一篇文章 <从头开始认识i.MXRT启动头FDCB里的lookupTable ...

  6. 痞子衡嵌入式:在串口波特率识别实例里逐步展示i.MXRT上提升代码执行性能的十八般武艺

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是在串口波特率识别实例里逐步展示i.MXRT上提升代码执行性能的十八般武艺. 恩智浦 MCU SE 团队近期一直在加班加点赶 SBL 项目 ...

  7. 痞子衡嵌入式:i.MXRT连接特殊Octal Flash时(OPI DTR模式下反转字节序)下载与启动注意事项(以MX25UM51245为例)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是OPI DTR模式下反转字节序的Octal Flash在i.MXRT下载与启动注意事项. 在恩智浦官方参考设计板 MIMXRT595-E ...

  8. 痞子衡嵌入式:i.MXRT中FlexSPI外设对AHB Burst Read特性的支持

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是FlexSPI外设对AHB Burst Read特性的支持. 痞子衡之前写过一篇关于FlexSPI LUT的文章 <从头开始认识i ...

  9. 痞子衡嵌入式:i.MXRT中不支持DQS的FlexSPI引脚组连接Flash下载与启动注意事项

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT中不支持DQS的FlexSPI引脚组连接Flash下载与启动注意事项. 最近痞子衡在支持一个印度客户,这个客户项目主芯片选择 ...

  10. 痞子衡嵌入式:i.MXRT中FlexSPI外设不常用的读选通采样时钟源 - loopbackFromSckPad

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT中FlexSPI外设不常用的读选通采样时钟源 - loopbackFromSckPad. 最近碰到一个客户,他们在 i.MX ...

随机推荐

  1. Go 互斥锁 Mutex 源码分析(二)

    原创文章,欢迎转载,转载请注明出处,谢谢. 0. 前言 在 Go 互斥锁 Mutex 源码分析(一) 一文中分析了互斥锁的结构和基本的抢占互斥锁的场景.在学习锁的过程中,看的不少文章是基于锁的状态解释 ...

  2. java_可变参数&增强for循环

    代码比较无厘头,记录看懂的意思 在可变参数的构造方法中,需要使用增强for循环遍历 public class name { String sex; public static void main(St ...

  3. win11(含win10)自带的一键镜像备份与还原方法

    winxp和win7时代小伙伴们备份或恢复系统时大都采用类似一键ghost类的软件制作系统盘的映像,当遇到故障时再恢复,但win10和win11其实自带有这种映像制作和还原功能,我们就再也不需要额外安 ...

  4. DPABInet做 Network Contruction时一直报错“函数或变量 'nets_netmats' 无法识别”

    DPABInet模块做 Network Contruction时一直显示报错"函数或变量 'nets_netmats' 无法识别",是因为没有将FSLNets导入路径,所以找不到该 ...

  5. springCloud allibaba 微服务引言

    微服务篇: springcloud 常见组件有哪些 nacos 的服务注册表结构是怎样的 nacos 如何支撑阿里内部数十万服务注册压力 nacos 如何避免并发读写冲突问题 nacos 和eurek ...

  6. Argo CD初体验

    什么是 Argo CD? Argo CD 是一个声明式的 GitOps 持续交付工具,用于 Kubernetes 集群.它通过持续监控 Git 仓库中的 Kubernetes 资源配置文件,将这些配置 ...

  7. 游戏AI行为决策——MLP(多层感知机/人工神经网络)

    游戏AI行为决策(特别篇)--MLP(附代码与项目) 你一定听说过神经网络的大名,你有想过将它用于游戏AI的行为决策上吗?其实在(2010年发布的)<最高指挥官2>中就有应用了,今天请允许 ...

  8. 音视频基础知识|ANS 噪声抑制原理解析

    ​ 在上一期课程<音视频开发进阶课程|第二讲:回声消除>中,我们接触了音频前处理的概念,还认识了音频前处理的三剑客之一 AEC 回声消除.今天,我们继续来认识三剑客中的第二位:噪声抑制 A ...

  9. DatetimeFormatter字符串转日期

    在Java中,我们经常需要将字符串形式的日期时间转换为LocalDateTime.LocalDate.LocalTime等日期时间对象,或者将日期时间对象转换为字符串.为了完成这些操作,我们可以使用D ...

  10. 暑假集训SCP提高模拟10

    我(看着百度百科):我已经知道这场谁组的题了 CTH: 谁 我:你想想,能在模拟赛里塞四道数学题还玩邦的,还能有谁 CTH: 我不知道 我:我不知道 CTH: 我知道了 我:我知道了 我:我是 Bob ...