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

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

3天内不再提示

ZYNQ-QSPI Flash读写操作

冬至子 来源:Embeddeder 作者:Vuko 2023-06-02 17:40 次阅读

Flash简介

Flash存储器,又叫做闪存,是一种非易失性存储器。具有操作方便读写速度快等优点。一般用于存储操作系统程序代码,或者用于数据存储。Flash的存储单元组织为块阵列,块是擦除操作的最小单位,擦除操作将块内的所有为置位为1,页是读写操作的基本单位。在对页进行写操作前,要判断该页内所有位是否为1。如果全部为1可以写操作,否则要对整块进行擦除操作(Flash只能从1反转到0)。Flash在内部结构(接口)上主要分为Nor flash 和NAND flash。Nor Flash :写入和擦除的速度低;结构复杂,成本高;存储容量较小;一般用于存储Bootloader以及操作系统或者程序代码,可以在芯片内部直接运行代码。NAND Flash :写入和擦除的速度较快;结构简单,成本低;存储容量较大;一般用于存储材料和数据。

Flash在外部接口上主要分为CFI flash 和SPI(STD/Dual/Quad) flash。CFI flash 读写速度快,需要的硬件引脚多且不同容量的硬件不兼容;而SPI(STD/Dual/Quad) flash读写速度慢,需要的硬件引脚少且不同容量的硬件兼容。

QSPI Flash简介

介绍

Quad-SPI闪存控制器是位于PS内的输入/输出外设(IOP)的一部分。它用于访问多位串行闪存设备,以实现高吞吐量和低引脚数应用。

控制器可以以三种模式运行: I / O模式线性寻址模式传统SPI模式

在I / O模式下,软件与闪存设备协议紧密交互,所以在该模式下需要对协议进行详细了解。软件通过使用四个TXD寄存器将闪存命令和数据写入控制器。软件通过读取RXD寄存器。

线性寻址模式使用设备操作的子集来消除I / O模式读取闪存所需的软件开销。也就是说线性寻址模式比IO模式要快的多。线性模式采用硬件来向闪存发出命令,并控制从flash到AXI接口的数据。控制器响应AXI接口上的存储器请求,就好像闪存是ROM存储器。

在传统模式下,QSPI控制器充当普通的SPI控制器。

控制器可以与一或两个闪存设备接口。可以并行连接两个设备以实现8位性能,也可以以堆叠的4位布局连接以最大程度地减少引脚数。

系统框图

QSPI Flash 控制器的系统框图如下所示:

图片

从上图中可知, QSPI Flash 控制器通过 MIO 与外部 Flash 器件连接,支持三种模式:单个从器件模式、双从器件并行模式和双从器件堆叠模式。双从器件并行模式把每个flash的IO进行单独连接,扩展成8位用于控制对不同flash的访问。而双从器件堆叠模式,使用SS片选信号进行区分flash的使能,所以想扩展 QSPI Flash 的存储容量,可以使用双从器件并行模式。

当使用单个设备时,直接存储器读取的地址映射从FC00_0000开始,最大为FCFF_FFFF(16 MB)。两台设备系统的地址映射取决于存储设备和I / O配置。

QSPI Flash 控制器内部框图

图片

由上图可知,在线性地址模式下,使用的是AXI的接口进行数据交互的,首先由AXI总线读取到响应的指令,并存到Command FIFO,然后使用AXI to SPI的命令转化器传输到选择器。在IO模式下,使用的是APB接口直接把接收到的信号传输给选择器进行选择。然后选择器进行功能选择后传输到TxFIFO,接着把Tx FIFO的数据进行串行化,然后通过MIO引脚发送。接收部分原理相反,而且可以看出在线性地址模式下,接收信号的转换使用的是数据转换器。所以在线性地址模式下,只支持读取数据,不支持发送数据。

流程控制

在数据传输期间,I / O模式具有不同的流控制模式。用户可以在自动和手动模式之间进行选择,该模式由config_reg.MANSTARTEN(Man_start_com)控制。在自动模式下,包括芯片选择控制在内的整个传输过程都在硬件中完成。无需软件干预。在手动模式下,用户控制数据传输的开始。在这种情况下,软件要么将整个传输序列写入TxFIFO,要么直到TxFIFO已满。在手动模式下,用户除了控制传输开始之外,还可以选择控制芯片选择。从命令开始,软件再次将传输序列写入TxFIFO,直到TxFIFO已满。然后,软件拉高CS,然后手动启动进行硬件管理。

编程指南

在xilinx给出的UG585指导手册中,对QSPI Flash 控制器编程设计进行了指导开发,用户可以根据自己的设计需要参考指导手册中的编程顺序实现自己的应用功能。

启动顺序

  1. 配置时钟
  2. 配置发送/接收信号。(以上两步在vivado底层搭建中已经完成设计)
  3. 重置控制器。
  4. 配置控制器。

配置控制器

该步骤适用于线性寻址和I / O模式。它配置了控制器的波特率,FIFO,flash模式,时钟相位/极性和对环回延迟进行编程。

  1. 配置控制器。写入qspi.Config_reg寄存器。a. 设置波特率[BAUD_RATE_DIV]。b. 选择主模式,[MODE_SEL] = 1。C. 选择flash模式(不是传统SPI),[LEG_FLSH] = 1。d. 选择Little Endian,[endian] = 0。e. 将FIFO宽度设置为32位[FIFO_WIDTH]。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. 将时钟延迟设置为0。qspi.LPBK_DLY_ADJ [DLY0] = 0b00。c. 设置时钟延迟1. qspi.LPBK_DLY_ADJ [DLY1] = 0b00。

线性寻址模式

线性寻址模式下数据读取(存储器读取)的操作顺序如下:

  1. 将手动启动启用设置为自动模式。设置qspi.Config_reg [Man_start_en] = 0。
  2. 使能片选信号。设置qspi.Config_reg [PCS] = 0。
  3. 将配置寄存器编程为线性寻址模式。
  4. 启用控制器。设置qspi.En_REG [SPI_EN] = 1。
  5. 从线性地址存储区读取数据。内存范围取决于大小和设备数量。范围是从0xFC00_0000到0xFDFF_FFFF。
  6. 禁用控制器。设置qspi.En_REG [SPI_EN] = 0。
  7. 取消使能片选信号。设置qspi.Config_reg [PCS] = 1。

配置I / O模式

使用I / O模式进行读取和写入编程步骤如下:

  1. 启用手动模式。qspi.Config_reg [Man_start_en,Manual_CS] = 1。
  2. 配置flash设备。对单个闪存设备使用qspi.LQSPI_CFG寄存器的重置值。如果是并行双闪存设备,则将1写入TWO_MEM,SEP_BUS位字段。
  3. 使能片选。设置qspi.Config_reg [PCS] = 0。
  4. 启用控制器。设置qspi.En_REG [SPI_EN] = 1。
  5. 将字节序列写入闪存。使用TXD从1到4字节写入TxFIFO寄存器。
  6. 避免TxFIFO溢出。当TxFIFO为空时,可以写入252个字节。此后,软件可以通过读取qspi.Intr_status_REG [TX_FIFO_full]并等待直到它等于0之后再写入TXD寄存器,来避免TxFIFO溢出。
  7. 启用中断。写入qspi.Intrpt_en_REG。
  8. 开始数据传输。设置qspi.Config_reg [Man_start_com] = 1。
  9. 中断处理程序:在编程/读取操作期间,将所有需要的数据传输到QSPI flash,并传输到Quad-SPI flash。
  10. 如果执行了读取操作:重新排列READ数据以消除由于空循环而读取的数据。
  11. 取消使能片选信号。设置QSPI.Config_reg [PCS] = 1。
  12. 禁用控制器。设置qspi.En_REG [SPI_EN] = 0。

I/O模式中断服务程序

配置ISR以根据Quad-SPI器件类型处理中断条件。要从Quad-SPI器件读取数据,最简单的ISR从RxFIFO读取数据并将内容写入TxFIFO。控制器生成系统外设中断(SPI),IRQ ID#51。对以下两种情况进行触发中断。a. 读取传输中断。RxFIFO不为空中断 b. 写传输中断。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. 清除中断。将1s写入中断状态寄存器qspi.Intr_status_REG。
  3. 清空RxFIFO。检查是否声明了RxFIFO非空中断。如果qspi.Intr_status_REG [RX_FIFO_not_empty] = 1,则RxFIFO中有数据。a. 如果状态为有效,则从RxFIFO读取数据。使用qspi.RX_data_REG寄存器读取数据。b. 从RxFIFO读取数据并轮询中断状态,直到RxFIFO为空。当qspi.Intr_status_REG [RX_FIFO_not_empty] = 0时,RxFIFO为空。
  4. 填充TxFIFO。检查TxFIFO未满状态是否有效。如果 qspi.Intr_status_REG [TX_FIFO_not_Full] = 1,则存在要发送到闪存设备的数据(编程和/或读取操作):a. 将数据写入qspi.TXD0寄存器。b. 轮询qspi.Intr_status_REG [TX_FIFO_full] = 1,这表明TX FIFO已满。c. 遵循步骤a和b,直到将所有数据写入TxFIFO或直到qspi.Intr_status_REG[TX_FIFO_full] = 1。
  5. 启用中断。将qspi.Intrpt_en_REG [TX_FIFO_not_full,RX_FIFO_full]都设置为1。
  6. 开始数据传输。设置qspi.Config_reg [MANSTRTEN] = 1。

工程系统框图

本次工程的系统框图如下:

图片

在本次工程设计中,使用QSPI Flash控制器对ZYNQ的QSPI Flash进行读写操作。通过对比读取数据和写入数据是否相等验证读写功能是否正常。

硬件平台搭建

新建工程,创建 Block Design。添加ZYNQ7 ip,根据本次工程需要对IP进行配置。勾选本次工程使用的资源。

图片

完成对所用资源的勾选,

图片

在clock configuration这里可以查看对QSPI的时钟配置。

图片

这里不需要对其他资源进行配置,所以可以使用默认配置。整体硬件系统构建完成如下:

图片

然后我们进行generate output product 然后生成HDL封装。这里用到了仅仅用到了PS部分的资源,所以不需要进行管脚分配。点击导出硬件资源(不用包含bit流文件),接着launch SDK,进入软件部分编写。

SDK软件部分

打开SDK后,新建application project。在system.mss中可以打开相关参考文档辅助设计。

图片

可以选择qspi的例程进行参考设计,导入例程模板,

图片

根据提供的模板,主要使用的函数如下,这里对他的读写测试进行了简化,

int QspiFlashPolledExample(XQspiPs *QspiInstancePtr, u16 QspiDeviceId)
{
	int Status;
	u8 *BufferPtr;
	u8 UniqueValue;
	int Count;
	int Page;
	XQspiPs_Config *QspiConfig;
	//初始化QSPI
	QspiConfig = XQspiPs_LookupConfig(QspiDeviceId);
	XQspiPs_CfgInitialize(QspiInstancePtr, QspiConfig,QspiConfig- >BaseAddress);
	//自测
	Status = XQspiPs_SelfTest(QspiInstancePtr);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	//初始化读写BUFFER
	for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < PAGE_SIZE;
	     Count++, UniqueValue++) {
		WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue + Test);
	}
	memset(ReadBuffer, 0x00, sizeof(ReadBuffer));
	//设置手动启动和手动片选模式
	XQspiPs_SetOptions(QspiInstancePtr, XQSPIPS_MANUAL_START_OPTION |
			XQSPIPS_FORCE_SSELECT_OPTION |
			XQSPIPS_HOLD_B_DRIVE_OPTION);
	//设置QSPI时钟的分频系数
	XQspiPs_SetClkPrescaler(QspiInstancePtr, XQSPIPS_CLK_PRESCALE_8);
	//片选信号置为有效
	XQspiPs_SetSlaveSelect(QspiInstancePtr);
	//读FLASH ID
	FlashReadID();
	//使能FLASH Quad模式
	FlashQuadEnable(QspiInstancePtr);
	//擦除FLASH
	FlashErase(QspiInstancePtr, TEST_ADDRESS, MAX_DATA);
	//向FLASH中写入数据
	for (Page = 0; Page < PAGE_COUNT; Page++) {
		FlashWrite(QspiInstancePtr, (Page * PAGE_SIZE) + TEST_ADDRESS,
			   PAGE_SIZE, WRITE_CMD);
	}
	//使用QUAD模式从FLASH中读出数据
	FlashRead(QspiInstancePtr, TEST_ADDRESS, MAX_DATA, READ_CMD);
	//对比写入FLASH与从FLASH中读出的数据
	BufferPtr = &ReadBuffer[DATA_OFFSET];
	for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
	     Count++, UniqueValue++) {
		if (BufferPtr[Count] != (u8)(UniqueValue + Test)) {
			return XST_FAILURE;
		}
	}
	return XST_SUCCESS;
}

运行效果

读写测试正常,运行效果如下:

图片

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 控制器
    +关注

    关注

    112

    文章

    15223

    浏览量

    171156
  • STD
    STD
    +关注

    关注

    0

    文章

    35

    浏览量

    14231
  • Flash存储器
    +关注

    关注

    3

    文章

    104

    浏览量

    25513
  • QSPI
    +关注

    关注

    0

    文章

    38

    浏览量

    11960
  • 选择器
    +关注

    关注

    0

    文章

    103

    浏览量

    14322
收藏 人收藏

    评论

    相关推荐

    编译可在QSPI Flash上运行的程序

    在前文中已经实现了一个能够在 MDK 平台进行下载代码到 QSPI Flash 中的下载算法,以及一个能跳转执行应用程序的 2nd Bootloader,但若想将代码下载到 QSPI Flas
    的头像 发表于 03-31 09:50 2375次阅读
    编译可在<b class='flag-5'>QSPI</b> <b class='flag-5'>Flash</b>上运行的程序

    使用PCIE更新AMD ZYNQQSPI Flash参考设计

    AMD ZYNQ 7000 的 S_AXI 端口提供了外设访问 PS 内部外设控制器的接口,这其中包括 4 个 S_AXI_HP 端口以及两个 S_AXI_GP 端口。一般来说,可以访问的内部资源包括 DDR 控制器,QSPI 控制器,OCM,IIC,SPI 等。
    的头像 发表于 11-17 10:02 489次阅读
    使用PCIE更新AMD <b class='flag-5'>ZYNQ</b>的<b class='flag-5'>QSPI</b> <b class='flag-5'>Flash</b>参考设计

    STM32H750 QSPI flash重映射模式下有方法能实现读写操作吗?

    STM32H750 QSPI flash重映射模式下有方法能实现读写操作
    发表于 03-25 08:06

    QSPI PK SPI读写速度?

    各位大神们,最近在捣鼓 QSPI读写发现 QSPI读写速度 比 SPI 的读写速度 貌似差不多,同样都是
    发表于 01-08 09:27

    Zynq无法设置为从QSPI闪存启动怎么解决?

    为了确保正确回退到金启动,AR#67221规定QSPI闪存的D2和D3数据条应连接到4K7上拉。但是看看Zynq xc7z030fbg676,这些引脚也可用作配置模式引脚。QSPI D2 =模式引脚
    发表于 06-09 17:24

    STM32CUBEMX_H750_QSPI单片flash间接读写模式

    STM32CUBEMX_H750_QSPI单片flash间接读写模式使用STM32cubemx配置串口,QSPI等(QSPI 配置初始化是g
    发表于 12-09 06:39

    使用硬件QSPI读写SPI Flash的方法

    本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件QSPI外设与 SPI Flash 通信(W25Q64)。
    发表于 01-26 07:29

    什么是QSPI?如何使用QSPIQSPI Flash进行通信呢?

    ,然后是交替字节,空指令周期,最后是数据,任意两个阶段之间都是紧挨着的。  一般来说,每次与 QSPI Flash 通信都至少包含指令阶段,其余的阶段都是可选的,例如读写 QSPI
    发表于 03-17 15:17

    使用 PCIE 更新 AMD ZYNQ™ 的 QSPI Flash 参考设计

    的内部资源包括 DDR 控制器,QSPI 控制器,OCM,IIC,SPI 等。 本教程提供一个最小的参考设计,使上位机可以通过 PCIE 端口,通过 S_AXI_GP0 端口访问 ZYNQ 内部
    发表于 11-30 18:49

    MSP430F169中对Flash的信息段A整段进行读写操作

    MSP430F169中对Flash的信息段A整段进行读写操作
    发表于 05-03 10:34 19次下载
    MSP430F169中对<b class='flag-5'>Flash</b>的信息段A整段进行<b class='flag-5'>读写</b><b class='flag-5'>操作</b>

    如何使用QSPI Flash控制器开发板上的 QSPI Flash进行写读操作

    学习内容 本文首先介绍FlashQSPI Flash控制器的相关内容,然后使用 QSPI Flash 控制器,开发板上的
    的头像 发表于 06-10 17:08 1.2w次阅读
    如何使用<b class='flag-5'>QSPI</b> <b class='flag-5'>Flash</b>控制器开发板上的 <b class='flag-5'>QSPI</b> <b class='flag-5'>Flash</b>进行写读<b class='flag-5'>操作</b>

    STM32内部Flash读写问题

    读写要注意几点keil的.map文件中包含了什么操作不当导致Flash损坏会怎样Flash上锁与解锁Keil编译器如何查看MCU寄存器的值Flash
    发表于 12-01 20:21 20次下载
    STM32内部<b class='flag-5'>Flash</b><b class='flag-5'>读写</b>问题

    nrf5340 LCD和flash 共用Qspi 息屏导致flash读写问题

    操作flash,影响qspr的时序,导致flash读写错误。现象表现:CPU工作频率低于qspr频率时,影响flash
    发表于 12-07 20:36 10次下载
    nrf5340 LCD和<b class='flag-5'>flash</b> 共用<b class='flag-5'>Qspi</b> 息屏导致<b class='flag-5'>flash</b><b class='flag-5'>读写</b>问题

    微控制器外置QSPI Flash选型的注意事项

    为了扩展微控制器可用的 Flash 空间,用户可以使用 QSPI 接口连接 QSPI Flash;为了让用户能尽量像使用片内 Flash
    的头像 发表于 04-07 09:23 1383次阅读

    Zynq中程序存储位置和设置方法

    Zynq中存储程序的地方有QSPI Flash,SD卡,EMMC。
    的头像 发表于 10-17 17:00 767次阅读