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

news/2024/11/13 22:25:07/文章来源:https://www.cnblogs.com/henjay724/p/18544956

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

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

  • 《在FDCB里设置Flash的Dummy Cycle》
  • 《在FDCB里切换Flash模式至QPI/OPI》

  我们知道 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 - Disableuint8_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: 100usuint16_t waitTimeCfgCommands;//!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt sequence number, [31:16] Reservedflexspi_lut_seq_t deviceModeSeq;//!< [0x018-0x01b] Argument/Parameter for device configurationuint32_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 deviceModeSeqflexspi_lut_seq_t configCmdSeqs[3];//!< [0x030-0x03b] Arguments/Parameters for device Configuration commandsuint32_t configCmdArgs[3];// ...//!< [0x07c-0x07d] Busy offset, valid value: 0-31uint16_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 busyuint16_t busyBitPolarity;//!< [0x080-0x17f] Lookup table holds Flash command sequencesuint32_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, etckDeviceConfigCmdType_QuadEnable, //!< Quad Enable commandkDeviceConfigCmdType_Spi2Xpi,    //!< Switch from SPI to DPI/QPI/OPI modekDeviceConfigCmdType_Xpi2Spi,    //!< Switch from DPI/QPI/OPI to SPI modekDeviceConfigCmdType_Spi2NoCmd,  //!< Switch to 0-4-4/0-8-8 modekDeviceConfigCmdType_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主页、知乎主页、微信公众号 平台上。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/833180.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nginx_基础

Nginx_基础 Nginx 基础一、Nginx 简介1.1 简介1.2 正向代理和反向代理 二、基本命令 三、配置格式3.1 基本配置格式3.2 时间和空间单位3.3 官方配置模板 四、部署静态网站4.1 增加配置4.2 检查配置4.3 重载配置 五、实现负载均衡5.1 部署后台服务5.2 负载均衡配置5.3 负载均衡策…

【Unity】对TMPAsset打包记录

TMPAsset中对于SourceFontFile引用,不会打包到AssetBundle中

4G核心网学习之4G EPS 中的 PDN Connection

PDN PDN(Packet Data Network分组数据网络),严格意义上讲可以分为内部 PDN 和外部 PDN:内部 PDN 即 EPS 系统中的分组数据网络,是 EPS 系统实体(e.g. MME、HSS、SGW、PGW、PCRF)之间的网络通信;而外部 PDN 即 EPS 系统之外的分组数据网络,例如:3GPP 网络 CDMA1X、Int…

spring初始学习

开始学习了容器 bean 依赖注入 Spring框架是一个开源的Java平台,它提供了全面的基础设施支持,以便你可以更容易地开发Java应用程序。以下是Spring框架中关于容器、Bean和依赖注入的一些基础知识点:Spring容器(Spring Container) Spring容器是Spring框架的核心,负责实例化…

sherpa-onnx:跨平台、多语言的语音处理工具包

Sherpa-onnx 是一个基于 ONNX 运行时的开源语音处理库,支持多种语音相关任务,包括语音识别、语音合成、说话人识别、语言识别等。它不仅支持多种编程语言(如 C++、C、Python、JavaScript、Java、C# 等),还支持多种操作系统和硬件平台(如 Windows、macOS、Linux、Android、…

基于FPGA的1024QAM基带通信系统,包含testbench,高斯信道模块,误码率统计模块,可以设置不同SNR

1.算法仿真效果 vivado2019.2仿真结果如下(完整代码运行后无水印):设置SNR=40db将数据导入matlab显示星座图:设置SNR=35db将数据导入matlab显示星座图:仿真操作步骤可参考程序配套的操作视频。2.算法涉及理论知识概要1024QAM是一种高级调制方式,可以携带更多的信息位(10…

Hive的分区和排序

一、Hive的分区(十分重要) 1、分区是什么 答:我们可以把一个大的文件分隔成一个个小的文件,这样每次操作一个小文件就很方便了 2、为什么要进行分区 答:通过分区,当我们查询的时候,可以只扫描与条件相关的分区,这样做,避免了全局扫描,加快查询速度 1、静态分区(SP) 静…

项目冲刺4-3

仓库地址:https://github.com/bitpurleclude/GDUT-Goofish.git这个作业属于哪个课程 (https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/join?id=CfDJ8AOXHS93SCdEnLt5HW8VuxT_rAhbZKO3TfjMmbv1B0Re5Fp2d0_QACha2ZoYZ4fxF-ZKCCAhfJl7B8mvCfesLYE02X8T6kx_2R8w0SR-ykrgDVRKW…

【Linux】git note -v command not found

安装note.js Node.Js中文网 『Win+E』『此电脑』右键点击『属性』『高级系统设置』-『环境变量』『系统变量』-『NOTE_PATH』“C:\Program Files\nodejs”『用户变量』-『Path』“C:\Program Files\nodejs”『Win+R』重新启动控制台『cmd』-“$NOTE -v” 双击重新启动『Git Ba…

2024.11.13 DP题单

录制唱片 你刚刚继承了流行的 “破锣摇滚” 乐队录制的尚未发表的 \(N\)(\(1\leq N\leq 20\))首歌的版权。你打算从中精选一些歌曲,发行 \(M\)(\(1\leq M\leq 20\))张 CD。每一张 CD 最多可以容纳 \(T\)(\(1\leq T\leq 20\))分钟的音乐,一首歌不能分装在两张 CD 中。CD…

基于HASM模型的高精度建模matlab仿真

1.程序功能描述 本课题主要使用HASM进行高精度建模,主要对HASM模型进行介绍以及在实际中如何进行简化实现的。HASM原始的模型如下所示: 2.测试软件版本以及运行结果展示MATLAB2022A版本运行 3.核心程序%第一类基本变量E(i,j) = 1 + (( f(i,j+1,n) - f(i,j-1,n) )/( …

CICD04 Jenkins容器化CICD实现及分布式构建, 流水线Pipeline ubuntu使用

2.14.3 案例: 基于 Docker 插件实现自由风格任务实现 Docker 镜像 制作 不如前面的直接脚本编写灵活 2.14.3.2 安装插件 docker-build-step jenkins上安装 docker-build-step 插件#选择jenkins使用的docker服务 #左侧系统管理,右侧系统配置,Docker Builder下Docker URL输入 u…