Xilinx ZYNQ 7000学习笔记三(qspi flash读写操作)

参考文献:Zynq-7000 SoC Technical Reference Manual (UG585)-ch12 Quad-SPI Flash Controller

一、nor Flash介绍

zynq 7000系列QSPI Flash控制器实现的是对nor flash的操作,至于nor flash的特点,这里在重复说明下:
1)erase的最小单位是扇区,擦除后的flash所有位会被置成1。
2)Program的基本单位是页。在对页进行写操作前,需要判断页内所有数据是否是全1,如果是全1则可以直接进行写操作;否则需要对整个扇区进行erase操作。
3)不同厂家的nor flash芯片的读写擦指令差异不大,一般flash启动都是上来通过读取flash ID的方式确定nor flash的型号进而实现该型号下的flash具体指令操作。(一般设备上电软件通过单spi 方式 read ID)。

二、QSPI Flash控制器介绍

Quad-SPI flash controller是位于PS内的输入/输出外设(IOP)的一部分,用来访问多位串行flash设备。

1.控制器运行模式:

flash控制器与内核之间通过AXI或APB总线进行通信。
控制器可配置为三种运行模式,I/O mode, linear addressing mode(线性寻址模式), egacy SPI mode(传统SPI模式)。
1)I/O模式:(线程寻址模式内核与控制器之间通过32bit APB总线进行通信),在这种模式下,软件需要详细了解flash的协议。软件通过使用4个TXD寄存器写flash命令和数据写入控制器;通过读RXD寄存器实现读flash接收到的数据。
2)线性寻址模式:(线程寻址模式内核与控制器之间通过32bit AXI总线进行通信),线性寻址模式使用了flash设备协议的部分子集指令,比IO模式要快的多。线性模式采用硬件来向闪存发出命令,并控制从flash到AXI接口的数据。控制器响应AXI接口上的存储器请求,就好像闪存是ROM存储器(即读操作可以直接读地址),本文内容主要针对线性寻址模式。
注意:这里说的线性寻址模式是针对读操作而言的,写操作并不支持线性寻址
3)传统模式下,QSPI控制器充当普通的SPI控制器(即传统SPI单线SI、SO、CLK、CS模式,可参XQSPIPS_CR_OFFSET寄存器 bit31)。

2.flash与控制器间通过MIO的连接方式:

控制器通过MIO与flash进行通信,控制器通过MIO支持与一个或者两个flash进行通信。共有三种,单个从器件模式(Single SS 4-bit I/O flash interface mode)、双从器件并行模式(Dual SS 8-bit parallel I/O flash interface mode)和双从器件堆叠模式(Dual SS 4-bit stacked I/O flash interface mode)。见下图系统框图。
系统框图:Xilinx ZYNQ 7000学习笔记三(qspi flash读写操作)_第1张图片单个从器件模式即外接单个flash,通过4bit I/O(即quad 、dual或单线)与flash进行通信。
双从器件并行模式把每个flash的IO进行了单独的连接,扩展成8bit用于控制同时访问两块flash,实现扩展 QSPI Flash 容量。
双从器件堆叠模式,使用片选SS信号进行区分flash的使能。对flash仍然是4bit,即同一时间只能操作一块flash。

控制器内部框图:
Xilinx ZYNQ 7000学习笔记三(qspi flash读写操作)_第2张图片通过控制器内部框图我们也可以看到线性寻址模式内部控制器走的是AXI总线,而I/O模式内部走的是APB总线(注意:读支持线性寻址模式,而写只有I/O模式)。

三、线性寻址模式

线性寻址支持的最大地址空间为32M,
单个从器件模式:在线性寻址模式且连接为单个flash,要求flash必须接在 QSPI 0,在这种条件下,flash地址映射空间是FC00_0000到最大FCFF_FFFF (16 MB)。
当连接的是两片flash时,要求两个flash必须是相同的制造商以保证他们相同的协议,地址映射依赖具体设备的大小和flash连接关系,具体而言:
双从器件并行模式:在这种模式下还要求flash要相同的容量,flash地址映射空间是FC00_0000 到最大FDFF_FFFF(32M)。(双从器件并行模式下,因为同一时刻操作两片flash,实际上地址是针对两个flash同时进行的,单片flash并没有明确地址空间)。
双从器件堆叠模式:QSPI 0连接的flash地址是FC00_0000到最大FCFF_FFFF (16 MB),QSPI 1连接的flash地址是FD00_0000到最大FDFF_FFFF(另外16M),如果第一个flash的容量小于16M,那么意味着在实际两个flash之间地址不连续。

四、功能描述

控制器支持I/O模式和线性地址模式。针对读操作,控制器在I/O模式和线性地址模式均支持单线(single spi)、双线(dual spi)和四线(quad spi)读操作;针对写操作,只在I/O模式下支持单线(single spi)、双线(dual spi)和四线(quad spi),线性地址模式不支持写操作。

1.I/O模式使用:

I/O模式:软件依据Quad-SPI协议发送格式化命令和数据写入一个TXD寄存器,Mux选择器将序列内容放入Tx FIFO并依据SPI接口序列将数据发送至flash,当发送逻辑发送Tx FIFO内容的同时,它同时采样原始串行数据,并通过串行数据反转换,将数据存入到RX FIFO中。(注意:四线SPI和双线SPI输入和输出是公用的,不像单线SPI区分输入输出在发送命令时输入是高阻态)
读指令:当读指令和地址发送完毕后,MIO在适当的时间从输出切换到输入传输逻辑的。转换到RxFIFO的数据反映了有效输入的数据。
软件需要对RxFIFO中的原始数据进行过滤,以获得相关的数据内容。控制器既不修改软件写入的指令,也不修改放入RxFIFO的捕获数据。(见1.3 FIFO 读和写)

1.1 控制流程

I/O模式有自动和手动模式控制数据传输,用户可以通过配置config_reg.MANSTARTEN (Man_start_com)在手动模式。
在手动模式下,用户可以通过配置Config_reg.SSFORCE(Manaual_CS)或手动(即软件MIO配置输出)进行片选,一旦片选使能,串口数据立即被认为是指令输出。
在自动模式下,整个的传输序列,包括控制片选在内都是由硬件完成,不需要软件干预。一旦数据通过写TXD寄存器将数据放入TxFIFO传输就立刻开始,片选自动激活,数据传输结束当TxFIFO空片选自动失效。在这种模式下要实现持续的数据传输,为了进行连续的数据传输,软件必须能够以等于或高于MIO上的数据移动速率向TxFIFO提供数据,这是比较困难的因为读RXD和写TXD是工作在APB时钟。
手动模式下:数据传输的开始由用户控制。在这种情况下,软件要么将整个传输序列写入TxFIFO,要么直到TxFIFO已满。在写Man_start_en(手动模式使能),控制器断言片选,开始传输数据TxFIFO输出和数据输入RxFIFO,适当地控制MIO的输入/输出状态,并在TxFIFO为空时通过取消断言片选终止序列,在这种模式下,每个命令序列的最大字节数受TxFIFO的252字节深度(63个字的存储空间)的限制。
在手动模式下,用户可以进一步通过控制片选信号来控制传输的开始。软件再次写入传输序列TxFIFO开始命令直到TxFIFO被填满。然后软件进行片选,手动传输开始。并由硬件接管。然而,当TxFIFO变为空时,片选不会被去断言。软件可以再次用适当的数据填充TxFIFO以继续前面的命令。这个方法删除对每个命令序列的字节数的限制,可以有效地用于大数据传输。在完成命令序列后,软件通过写入解除对CS的断言到Manual_CS位(也就是说可以通过不关闭片选判断TxFiFO是否为空,空则将命令序列在此写入TxFiFO的方法实现大数据的删除

1.2 I/O模式传输寄存器(TXD)

软件参考flash供应商quad-spi的协议写入特定闪存设备所需的字节序列,该控制器有4个只写的32位TXD寄存器,用于软件发出一系列命令,从而从闪存中获取状态和读/写数据。分别写入TXD0、TXD1、TXD2或TXD3
将寄存器相应的内容写到TxFIFO。
在连续访问下列寄存器见,用户必须清空TxFIFO:
• TXD0 to TXD1/TXD2/TXD3
• TXD1 to TXD0/TXD1/TXD2/TXD3
• TXD2 to TXD0/TXD1/TXD2/TXD3
• TXD3 to TXD0/TXD1/TXD2/TXD3
但是TxD0到TxD0的访问,不需要清空TxFIFO。
TXD寄存器写格式:
Xilinx ZYNQ 7000学习笔记三(qspi flash读写操作)_第3张图片

1.3 FIFO 读和写

TxFIFO和RxFIFO共享相同的门控时钟。因此,对于每个字节,包括从TxFIFO移出的命令和地址字节,一个相应的字节被移到RxFIFO中。

2.线性寻址模式使用:

该控制器有一个32位的axii接口,支持线性地址映射的读操作。当主机通过发出AXI读命令时,会生成quadi - spi控制器QSPI命令加载相应的内存数据,并通过AXI接口将其发送回去。在线性模式下,闪存子系统的行为就像一个典型的只读内存。与I/O模式相比,线性模式通过减少软件开销,提高了用户友好度和整体读内存吞吐量。从软件的角度来看,访问线性quadi - spi内存子系统与访问其他rom之间没有明显的区别,除了可能有较长的延迟。
qspi.LQSPI_CFG.[LQ_MODE] bit置1是传输进入线性寻址模式(LQSPI mode),在进入线性寻址模式之前,用户必须确保TXFIFO和RXFIFO都为空。一旦qspi.LQSPI_CFG[LQ_MODE]置位,则FIFOs由LQSPI模块自动控制,对TXD和RXD的IO模式访问是未定义的状态。
(注意:也就是说当读操作的时候可以配置为线性模式读,当需要写操作的的时候需要退出线性模式转为I/O模式进行写操作)。
在线性寻址模式下,片选引脚由控制器自动控制,在进入线性寻址模式之前,用户需要确保 qspi.Config_reg[Man_start_en] 和qspi.Config_reg[PCS]
均为0。

2.1 AXI接口操作:

线性寻址模式只支持AXI读命令。所有有效的写地址和写数据将立即被确认,但将被忽略,即不进行相应的编程对闪存进行(写)操作,所有的AXI写都在写相应通道上生成SLVERR错误。所有的读地址必须要求是字对齐的并且要求数据宽度必须是32-bits

2.1.1 AXI读命令过程

AXI读命令被转换成SPI flash读指令,发送到quadi -SPI控制器TxFIFO。控制器传输逻辑负责从FIFO检索读取的指令,并根据SPI协议将它们传递到SPI闪存。Rx FIFO一旦芯片选择信号激活,就开始接收数据,线性地址模块删除与指令代码相对应的传入数据。(也就是一般情况下线性寻址收到的数据是"干净"的数据,没有指令部分)。
如果发送读取的地址不是进行4字节对齐的那么控制器会按照下图所示原则进行地址读取来保证自动对齐.
Xilinx ZYNQ 7000学习笔记三(qspi flash读写操作)_第4张图片
在线性模式下,默认的读模式为Quad I/O 快速读。

五、软件编程

1.启动顺序:

1.配置时钟
2.配置接收/发送信号
3.重启控制器
4.配置控制器
其中,1和2都是在vivado底层搭建中已经完成设计,可不考虑。

1.1 配置控制器

该步骤适用于线性寻址和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。

2.操作:

2.1 线性寻址模式(读)

线性寻址模式下数据读取(存储器读取)的操作顺序如下:
1.将手动启动启用设置为自动模式。 设置qspi.Config_reg [Man_start_en] = 0。
2.使能片选信号。 设置qspi.Config_reg [PCS] = 0。
3.将配置寄存器编程为线性寻址模式。值配置情况见下图。(这样线性寻址就可以实现自动指令匹配)
Xilinx ZYNQ 7000学习笔记三(qspi flash读写操作)_第5张图片
4.启用控制器。 设置qspi.En_REG [SPI_EN] = 1。
5,从线性地址存储区读取数据,内存范围取决于大小和设备数量。 范围是从0xFC00_0000到0xFDFF_FFFF(最大32M空间)。
禁用控制器。 设置qspi.En_REG [SPI_EN] = 0。
取消使能片选信号。 设置qspi.Config_reg [PCS] = 1

注意:1和2是线性寻址模式必须要求的,不能改为其他配置;

2.2 示例:I/O模式(读和写)

1.启用手动模式。qspi.Config_reg [Man_start_en,Manual_CS] = 1。(示例为手动模式)
2.对单个闪存设备使用qspi.LQSPI_CFG寄存器的重置值。 如果是并行双闪存设备,则将1写入TWO_MEM,SEP_BUS位字段
3.使能片选。 设置qspi.Config_reg [PCS] = 0。
4.启用控制器。 设置qspi.En_REG [SPI_EN] = 1。
5.将字节序列写入闪存。 使用从1到4字节写入TXD寄存器(硬件实际写入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。
10.如果执行了读取操作:重新排列READ数据以消除由于空循环而读取的数据
11.取消使能片选信号。设置QSPI.Config_reg [PCS] = 1。
12.禁用控制器。设置qspi.En_REG [SPI_EN] = 0
注意:TxFIFO宽度必须被编程为32位:qspi.Config_reg FIFO_WIDTH = 0b11。
软件需要处理“连续的非字对齐”传输

2.3 复位

控制器有两个复位区域,APB接口和控制器自身,这两个区域必须同时使用,
Xilinx ZYNQ 7000学习笔记三(qspi flash读写操作)_第6张图片
复位操作示例:
1.设置复位,LQSPI_RST_CTRL寄存器的 [QSPI__REF_RST和slcr.LQSPI_CPU1X_RST]置位1.
2.清除复位,LQSPI_RST_CTRL寄存器的 [QSPI__REF_RST和slcr.LQSPI_CPU1X_RST]写0。

你可能感兴趣的:(ZYNQ7000系列学习笔记,学习,java,开发语言)