Zynq7000系列中的Quad-SPI(四线制串行外设接口)Flash控制器编程指南

news2024/9/30 12:21:35

Zynq7000系列中的Quad-SPI(四线制串行外设接口)Flash控制器是一个功能强大的组件,它支持高速数据传输和多种配置模式。以下是基于Zynq7000系列的Quad-SPI Flash控制器编程指南,旨在帮助开发者了解如何配置和使用该控制器。

编程指南:启动序列示例

这个序列包括配置时钟、配置传输/接收信号、重置控制器、配置控制器以及选择线性寻址模式或I/O模式。

  1. 配置时钟:根据设备的规格和需求,配置适当的时钟源和时钟频率。
  2. 配置Tx/Rx信号:配置传输(Tx)和接收(Rx)信号。这通常涉及选择正确的物理引脚、设置信号的方向(输入/输出)以及可能的信号特性(如电平、速率等)。
  3. 重置控制器:对控制器进行硬件或软件重置。重置操作将控制器恢复到初始状态,确保后续的配置操作在一个干净的环境中进行。
  4. 配置控制器:这可能包括设置工作模式、数据格式、波特率、超时等参数。

接下来,根据应用需求,您可以选择配置控制器为线性寻址模式或I/O模式。

配置

示例:配置控制器

此配置示例适用于线性寻址模式和I/O模式。它准备了控制器的波特率、FIFO、闪存模式、时钟相位/极性,并设置了回环延迟。需要编程到qspi.Config_reg寄存器的值如表12-3所示。

  1. 配置控制器:qspi.Config_reg寄存器写入配置值。

        a. 通过[BAUD_RATE_DIV]字段来设置波特率。
        b. 将[MODE_SEL]设置为1来选择主模式。
        c. 将[LEG_FLSH]设置为1来选择闪存模式(非传统SPI)。
        d .将[endian]设置为0 来选择小端模式。
        e. 通过[FIFO_WIDTH]字段来设置FIFO宽度为32位。
        f.  通过[CLK_PH][CLK_POL]字段来设置时钟相位和极性。

     2. 启用回环时钟

      如果使用回环时钟,请确保qspi.Config_reg[BAUD_RATE_DIV]被设置为0b00,并配置qspi.LPBK_DLY_ADJ(回环延迟调整)寄存器,设置如下:
     a. 将qspi.LPBK_DLY_ADJ[USE_LPBK]设置为1来选择内部时钟。
     b. 将qspi.LPBK_DLY_ADJ[DLY0]设置为0b00来设置时钟延迟0。
     c. 将qspi.LPBK_DLY_ADJ[DLY1]设置为0b00来设置时钟延迟1。

线性寻址模式

示例:线性寻址模式(内存读取)

在线性寻址模式下进行数据读取的操作序列如下:

  1. 设置手动启动为自动模式:将qspi.Config_reg[Man_start_en]设置为0,以启用自动模式。这允许控制器在接收到指令后自动开始数据传输,而无需手动触发。
  2. 激活芯片选择:将qspi.Config_reg[PCS]设置为0,以选择目标SPI设备。
  3. 为线性寻址模式配置配置寄存器:根据表12-3中的示例值,对配置寄存器进行编程。
  4. 启用控制器:将qspi.En_REG[SPI_EN]设置为1,以启用QSPI控制器。这将使控制器开始工作,并准备接收和发送数据。
  5. 从线性地址内存区域读取数据:数据读取的范围取决于连接的设备的大小和数量。在线性寻址模式下,内存地址范围可能是从0xFC00_00000xFDFF_FFFF。您需要通过向控制器发送读取指令和指定地址来从该范围内读取数据。
  6. 禁用控制器:在完成数据读取后,将qspi.En_REG[SPI_EN]设置为0,以禁用QSPI控制器。
  7. 取消激活芯片选择:将qspi.Config_reg[PCS]设置为1,以取消选择SPI设备。

配置I/O模式

示例:I/O模式(内存读写)

以下操作序列使用I/O模式进行读写操作:

  1. 启用手动模式:将qspi.Config_reg[Man_start_en, Manual_CS]的相应位设置为1,以启用手动模式。
  2. 配置闪存设备:参考图12-6。对于单个闪存设备,请使用qspi.LQSPI_CFG寄存器的复位值。如果是并行双闪存设备,请将TWO_MEMSEP_BUS位字段设置为1。

     3. 激活芯片选择:将qspi.Config_reg[PCS]设置为0,以选择目标SPI闪存设备。

     4. 启用控制器:将qspi.En_REG[SPI_EN]设置为1。

     5. 向闪存写入字节序列:使用TXD寄存器向TxFIFO写入1到4个字节。

     6. 避免TxFIFO溢出:当TxFIFO为空时,可以写入252个字节。之后,软件可以通过读取qspi.Intr_status_REG[TX_FIFO_full]并等待其值变为0来避免TxFIFO溢出,然后再向TXD寄存器写入数据。

     7. 启用中断:向qspi.Intrpt_en_REG写入值。

     8. 启动数据传输:将qspi.Config_reg[Man_start_com]设置为1,以手动启动数据传输。

     9. 中断处理程序:在程序/读取操作期间,中断处理程序负责将所需的所有数据传输到Quad-SPI闪存。

     10. 当执行读取操作时:由于存在虚拟(dummy)周期,读取的数据中会包含一些不需要的部分。为了消除这些数据,需要对读取的数据进行重新排列。

     11. 取消激活芯片选择QSPI.Config_reg[PCS]设置为1。

     12. 禁用控制器:将qspi.En_REG[SPI_EN]设置为0。

请注意,TxFIFO的宽度必须被编程为32位,即将qspi.Config_reg[FIFO_WIDTH]设置为0b11。如果传输的数据不是字对齐的(即不是32位的倍数),软件需要处理这种“连续非字对齐”的传输。

I/O模式中断服务例程示例

以下是一个I/O模式中断服务例程(ISR)的示例,该例程基于Quad-SPI设备类型处理中断条件:

  1. 配置ISR:根据Quad-SPI设备类型配置ISR。对于从Quad-SPI设备读取数据,最简单的ISR会从RxFIFO读取数据并将其内容写入TxFIFO(尽管在读取操作中,这通常不是必需的,除非有特定的数据回环或测试需求)。控制器生成系统外设中断(SPI),IRQ ID为#51。
         a. 读取传输中断:RxFIFO非空中断
  • 当RxFIFO中有数据时,此中断会被触发。
  • ISR应该读取RxFIFO中的数据,并根据需要处理这些数据(例如,将其存储到内存中)。

        b. 写入传输中断:TxFIFO非满中断

  • 当TxFIFO中有空间可以写入更多数据时,此中断会被触发。
  • 在写入操作中,ISR可能会准备更多的数据并将其写入TxFIFO中。然而,在读取操作中,这个中断可能不是必需的,除非有特定的数据传输需求。

I/O模式中断

在I/O模式下,当中断条件满足时,会触发控制器中断。Quad-SPI中断处理程序会检查中断的原因,并且一个单独的中断服务例程可以管理所有的中断条件。

中断服务例程示例:Rx和Tx

此中断服务例程由IRQ ID #51触发。它会一直读取RxFIFO直到其为空,然后填充TxFIFO。使用RxFIFO非空中断状态来确定是否可以从RxFIFO中读取内容,而TxFIFO非满中断则指示TxFIFO中是否有空间容纳更多内容。

中断处理步骤
  1. 禁用控制器中的所有中断:将qspi.Intrpt_dis_REG[TX_FIFO_not_full, RX_FIFO_full]都设置为1。
  2. 清除中断:向中断状态寄存器qspi.Intr_status_REG写入1,以清除当前的中断状态。
  3. 清空RxFIFO:检查RxFIFO非空中断是否被触发。如果qspi.Intr_status_REG[RX_FIFO_not_empty] = 1,则表示RxFIFO中有数据。
    • 继续从RxFIFO中读取数据并轮询中断状态,直到RxFIFO为空(即qspi.Intr_status_REG[RX_FIFO_not_empty] = 0)。
    • 如果状态被触发,则从RxFIFO中读取数据,使用qspi.RX_data_REG寄存器。
  4. 填充TxFIFO:检查TxFIFO非满状态是否被触发。如果qspi.Intr_status_REG[TX_FIFO_not_Full] = 1,则表示有数据需要发送到闪存设备(进行编程和/或读取操作)。
    • 重复上述步骤,直到所有数据都写入TxFIFO或qspi.Intr_status_REG[TX_FIFO_full] = 1
    • 轮询qspi.Intr_status_REG[TX_FIFO_full],直到其变为1,表示TxFIFO已满。
    • qspi.TXD0寄存器写入数据。
  5. 启用中断:将qspi.Intrpt_en_REG[TX_FIFO_not_full, RX_FIFO_full]都设置为1。
  6. 启动数据传输:将qspi.Config_reg[MANSTRTEN]设置为1,以手动启动数据传输。

注意

  • QSPI的Intr_status_reg.RX_FIFO_not_empty位更新存在延迟。这可能导致轮询软件错误地认为RxFIFO中仍有数据,而实际上已经没有数据了,从而导致RxFIFO下溢并读取到无效数据。为了避免这种情况,软件可以两次读取Intr_status_reg.RX_FIFO_not_empty位,以确保控制器有足够的时间更新状态位。
  • 非空阈值事件是在FIFO水平跨越阈值时检测到的变化,但是将阈值寄存器更改为小于当前水平的值不会生成中断。

Rx/Tx FIFO 对 I/O 命令序列的响应

以下是一些示例命令和序列,包括写使能命令、读状态命令和读数据序列。在这些示例中,YY 可以是任意值,每对 YY 可能具有不同的值。

在串行传统模式下接收数据时,数据会从 MISO/DQ1 线同步于时钟采样到 RxFIFO 中,而命令和地址事务则在 MOSI/DQ0 上发生。

示例:写使能命令(代码 0x06)

  1. 发送写使能命令(WREN):将 0xYYYY_YY06 写入 qspi.TXD1 寄存器。
    • 控制器将 TxFIFO 中的一个字节移出到设备,并在 RxFIFO 中接收一个字节。
    • YY = 0(在这个例子中,我们假设 YY 为 0,但 YY 可以是任意值)。
    • WREN 命令 = 0x06。
  2. 读状态:读取 qspi.RXD 寄存器,并接收 0xYYPP_PPPP。
    • 软件记住写使能命令产生的一个字节,并将 0xYY 返回给调用函数。这里的 0xYY 实际上是命令执行后的状态字节的前缀,但由于 YY 在这个例子中为 0,且状态没有改变,所以返回的是 0x00。
    • 当 YY = 0x0 时(表示状态),值为 0x0000_0000,PP_PPPP = 0x0 表示位的前一个状态(即状态寄存器中的值没有改变)。

发送WREN命令后RxFIFO中的内容如下。(Previous表示该值与寄存器的先前值没有变化。)

示例:读状态命令(代码 0x05)

  1. 发送读状态命令(RDSR)
    • qspi.TXD2寄存器写入0xYYYY_DD05。这里,05是读状态命令的代码,DD是虚拟数据(dummy data,即在这个命令中不重要的数据,通常用于填充传输的空闲时间或满足特定的数据长度要求),而YY是任意值,但在这个例子中假设为0
    • 控制器从TxFIFO中移出两个字节到闪存设备(因为QSPI通常使用至少两个字节(16位)的传输单位,即使命令本身只有一个字节)。同时,控制器从闪存设备接收两个字节到RxFIFO中。
  2. 读取状态值
    • qspi.RXD寄存器读取0xZZYY_PPPP。这里,ZZYYPPPP是接收到的数据的各个部分。
    • ZZ = 0x03(这通常表示状态寄存器的地址或某种特定的响应格式,但具体含义取决于设备和其文档),YY = 0x0(在这个例子中,由于我们发送的是0x00作为YY,所以接收到的YY通常也会是0x00,除非设备修改了这部分),PPPP = 0x0时,整个接收到的值为0x0300_0000
    • 软件记住这两个字节是有效的,并将0x00, 0x03(注意字节顺序,通常低位字节先发送/接收)返回给调用函数。这表示状态寄存器的值(或设备返回的特定响应)已被成功读取。

发送RDSR命令后RxFIFO中的内容如表所示(previous 表示该值与寄存器的先前值没有变化):

示例:读数据序列

这个示例的目的是从地址0读取四个字节的数据,并将这些数据返回给调用函数。

  1. 发送数据读取指令:向qspi.TXD0寄存器写入0xA2A1_A003。这里,03是读取数据的命令代码(具体代码取决于设备和其文档),而A2A1A0是地址的高位、中位和低位字节。
  2. 发送虚拟数据:向qspi.TXD0寄存器(或可能是另一个用于后续传输的TxFIFO条目)写入0xD0D1_D2D3作为虚拟数据。虚拟数据通常用于填充传输的空闲时间,以满足设备对数据传输长度的要求。控制器从TxFIFO中移出8个字节(包括命令、地址和虚拟数据)到闪存设备,并接收8个字节到RxFIFO中。

本例中TxFIFO的内容如下。从控制器到设备的字节序列为:0x03、A0、A1、A2、D0、D1、D2和D3。

      3. 读取指令字后的数据:读取qspi.RXD寄存器。接收到的数据为0xYYYY_YYYY,其中YY = 0。这一步通常是为了确认指令已经被正确发送,并且设备已经准备好返回数据。

     4. 读取闪存内存数据:再次读取qspi.RXD寄存器。接收到的数据为0xD3D2_D1D0

  • a. 第二次读取时,软件记住四个字节是有效的:这意味着从这次读取中,软件期望并接收到了四个字节的数据。这些数据是闪存设备从指定地址返回的实际数据。
  • b. 示例数据:0x2468ACEF:这是一个假设的数据值,用于说明接收到的数据可能是什么样子的。在实际操作中,这个值将由闪存设备的内容决定。
  • c. 软件读取的字节总体:根据前面的步骤和这次读取,软件实际上读取了以下字节序列:0x00, 0x00, 0x00, 0x000x24, 0x68, 0xAC, 0xEF。然后,软件将这四个数据字节(0x24, 0x68, 0xAC, 0xEF)返回给调用函数。

本例中RxFIFO的内容如下。从设备到控制器的字节序列为:YY、YY、YY,YY、0xEF、0xAC、0x68和0x24。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

医院配电系统谐波的分析及治理

七次谐波,流入电网。 4.计算机及UPS 目前大部分医院都是通过计算机实现运营和管理工作,计算机数量众多,计算机服务器配有UPS等备用电源,加之个人电脑的开关电源,都是产生谐波的电源。 3医院配电系统谐波设备的治理方…

【Golang】Go语言中时间time相关处理方法

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…

微信广告任务平台 ajax_upload 任意文件上传漏洞

0x01 漏洞描述: 微信广告任务平台ajax_upload接口处存在任意文件上传漏洞,攻击者可利用该漏洞将恶意文件上传至服务器,进而可能实现远程代码执行、篡改网站内容或发动其他形式的攻击,严重危及系统与数据安全。 位于控制器中IndexC…

x-cmd pkg | tokei - 代码统计利器,助你快速了解项目进度

目录 简介首次用户技术特点竞品和相关项目进一步阅读 简介 tokei 是一个使用 Rust 编写的显示有关代码统计信息的命令行工具,可以分门别类的统计目录内的代码行数。 tokei 具有良好的跨平台性,可以在 Linux、macOS、Windows 等多种平台上安装运行。 首…

SU03T(语音识别播报模块)

SU03T(语音识别播报模块) 注意:学习模块的方法是最重要的 目录 SU03T(语音识别播报模块) 查找资料 - SU03T 配置固件 1、进入智能公元,并注册登入 2、点击对应的模块,创建产品 3、随便选…

软件测试|数据库常见面试题

在软件测试数据库的面试中,面试官通常会考察应聘者对数据库的理解、SQL语言的应用、数据库性能优化、以及数据库相关的技术栈和工具等方面的知识。以下是一些可能的面试问题及建议的回答思路: 1、什么是关系型数据库,主键,外键&am…

揭秘网络钓鱼:如何识破并防范这场数字时代的诈骗游戏

网络钓鱼是一种网络攻击,它利用伪装的电子邮件欺骗收件人提供信息、下载恶意软件或采取其他期望的行动。 网络钓鱼是网络害虫,自20世纪90年代初从暗网出现以来,至今仍危害全球。根据SlashNext的报告,2023年平均每天有31,000次网络…

SpringCloudAlibaba的nacos启动注册实现

首先安装nacos,注意看清楚版本号码,后面设置pom依赖的时候有用。 安装地址:Nacos 快速开始 | Nacos 官网 选择这里: 然后在这个跳转的页面中,找到你需要的版本,比如选择2.0.4 进入之后,选择你…

软考题-数据库2-数据模型/ER图/关系模式规范化

一、概念数据模型-ER图 1.概念数据模型-ER图的构件-属性的分类 属性分多值属性和单值属性,题目已经给出联系方式的值有手机电话和办公室电话,所以是多值属性 派生属性是由其他属性而来,年龄来自于出生年月 部门号是EMP表的外键二、关系模式 …

vue-element 表格组合查询 - fc-table-search 组件封装

开发目的 解决搜索form参数读取,配合异步请求,更新渲染数据;支持自适应高度,分页查询,搜索查询/重置。 额外提供formater类型:标签定义,金额,时间格式化,跨页勾选&#x…

Minstrel自动生成结构化提示,让AI为AI写提示词的多代理提示生成框架

在人工智能快速发展的今天,如何有效利用大型语言模型(LLMs)成为了一个普遍关注的话题。这是9月份的一篇论文,提出了LangGPT结构化提示框架和Minstrel多代理提示生成系统,为非AI专家使用LLMs提供了强大支持。 对于非人…

PHP人才机遇桥梁招聘求职全能系统小程序源码

人才机遇桥梁 —— 招聘求职全能系统全解析 💼🚀 🌉 搭建人才与机遇的桥梁 在这个竞争激烈的职场环境中,找到一份心仪的工作或招募到合适的人才,往往不是一件容易的事。但幸运的是,我们有了“人才机遇桥梁…

Hello-Java-Sec靶场搭建

安装环境:宝塔Linux面板 1.将靶场克隆到本地 git clone https://github.com/j3ers3/Hello-Java-Sec 2.安装maven yum install maven (kali:apt install maven) 3.安装成功后 mvn -v验证⼀下 4. 配置数据库连接,数据…

SysML图例-悬架作动器(Suspension Aactuator)

DDD领域驱动设计批评文集>> 《软件方法》强化自测题集>> 《软件方法》各章合集>>

【Android】获取备案所需的公钥以及签名MD5值

目录 重要前提 获取签名MD5值 获取公钥 重要前提 生成jks文件以及gradle配置应用该文件。具体步骤请参考我这篇文章:【Android】配置Gradle打包apk的环境_generate signed bundle or apk-CSDN博客 你只需要从头看到该文章的配置build.gradle(app&…

【议题征集 】上海站 nMeetup 将于十月份开启!

上海,作为我国的经济和金融中心,正迅速发展成为全球领先的科技创新城市。这座城市不仅拥有深厚的文化底蕴,还积极拥抱数字化转型,推动着数据库和人工智能基础设施的快速发展。第三站 nMeetup 我们将走进上海,本次活动由…

面向未来的设计:数字化转型时代的企业架构与建模革新

在数字化转型浪潮席卷全球的今天,企业架构(Enterprise Architecture, EA)与建模技术正成为引领未来业务发展的核心工具。企业如何设计面向未来的架构,不仅关乎技术的部署,更直接影响业务的战略定位和市场竞争力。《面向…

【PCL】Ubuntu22.04 安装 PCL 库

文章目录 前言一、更新系统软件包二、安装依赖项三、下载 PCL 源码四、编译和安装 PCL五、测试安装成功1、 pcd_write.cpp2、CMakeLists.txt3、build 前言 PCL(Point Cloud Library)是一个开源的大型项目,专注于2D/3D图像和点云处理。PCL为点…

创客匠人第二期“老蒋面对面”交流会圆满收官!

磅礴的大雨浇不灭奋斗的激情。9月24日,创客匠人第二期老蒋面对面—“创客匠人让知识变现不走弯路”内部大会在集美隆重举行。 本次内部大会旨在传递公司战略精神,深度探讨公司品牌传播的价值、方向和策略。这不仅是一次内部的交流与分享,更是…

详解 JDBC和连接池

目录 一.JDBC概述 1.介绍 2.好处 3.JDBC API 二.数据库连接 1.前置工作 2.方法一 3.方法二 4.方法三 5.方法四 6.方式五(配置文件) 三.ResultSet(结果集) 1.介绍 2.代码演示 3.底层原理 四.预处理 1.SQL注入 2.PreparedStatement 接口 …