文章目录
- flash读写数据的特点
- 1. 扇擦除SE(Sector Erase)
- 1.1 flash_se 模块设计
- 1.1.1 信号连接示意图:
- 1.1.2 SE状态机
- 1.1.3 波形图设计:
- 1.1.4 代码
- 2. 页写PP(Page Program)
- 2.1 flash_pp模块设计
- 2.1.1 信号连接示意图:
- 2.1.2 PP状态机
- 2.1.3 波形图设计(WE部分和DELAY部分和上述一致)
- 2.1.4 代码
- 3.读flash操作
- 3.1 flash_rd模块设计
- 3.1.1 信号连接示意图
- 3.1.2 波形图设计
- 3.1.3 代码
- 4.控制器设计
开始之前需要先了解一下SPI通信协议的特点:
本篇内容要实现FPGA芯片通过SPI总线与flash芯片进行通信,连接如下图所示:
信号线解释:
- Cs_n:片选线,为 FPGA 的输出信号,Flash 的输入信号,低电平有效;
- Sck:时钟线,为 FPGA 的输出信号,Flash 的输入信号,Flash 根据该信 号的上升沿锁存 sdi 发来的数据,根据该信号的下降沿通过 sdo 输出数据;
- sdi:mosi,数据线,为 FPGA 的输出信号,Flash 的输入信号,FPGA 可通过 sdi总线串行的传输数据到 Flash;
- sdo:miso,数据线,为 FPGA 的输入信号,Flash 的输出信号,Flash 可通过 sdo总线串行的传输数据到 FPGA。
flash读写数据的特点
这里以 M25p16 型号的 flash 为例进行介绍。
M25p16 最大的时钟频率为 50Mhz,在此我们进行擦除时采用 12.5Mhz 的时钟,即 sck 的时钟频率为 12.5Mhz。该款 Flash 芯片的存储空间16Mbit,每个地址内存储 1byte(8bit)的数据,共 2M 的存储深度,其地址分为 32 扇区(sector)、每个扇区包含 256 页(page)、每一页包含 256字节(byte),因此该 Flash 芯片需要用到 21 位地址线,加上扩展的 3bit 地址线,
一共用到== 24bit 地址线==,具体如下图 3所示。
1. 扇擦除SE(Sector Erase)
通过前面的项目我们知道,ram存储器的特点是:,在同一个地址写入新的数据时,旧数据会被覆盖。而flash则不同,在对 Flash 进行写入数据时,首先需要将 Flash内部现有的数据进行擦除,Flash 的擦除分为扇区擦除(sector erase)和全擦除(bulk erase)。下面将以扇区擦除为例进行讲解.
在进行 SE 之前需要给出一个写使能指令
(WREN),然后进行扇区擦除,WREN的指令为8’h06。SE时序图如下:
注意:
- 在 WREN 结束后,cs_n 需要被拉高,为了确保 WREN 被 Flash 存储,因此 cs_n 拉高的时间至少需要 100ns(官方文档虽然没写拉高 100ns 但是为了稳定一定要 拉高 cs_n),之后再次拉低 cs_n 为发送 SE 指令做准备。
- 由于是扇区擦除,因此给出的地址位只有高 8bit有效,低 16bit 无论是何值都对该扇区的擦除没有影响。
1.1 flash_se 模块设计
1.1.1 信号连接示意图:
1.1.2 SE状态机
1.1.3 波形图设计:
1.1.4 代码
2. 页写PP(Page Program)
Flash 页写功能,简称 PP,Page Program 命令 8’h02。同样与擦除指令一样,需要再发送 PP 指令之前,执行 Write EN 操作,当执行完 PP 后 Write EN 会自动复位,所以每次 PP 之前必须发送 Write EN 操作。PP时序图如下:
2.1 flash_pp模块设计
说明:这里:这里pp进去的256byte数据是提前存在fifo的,因此开始向flash里pp数据的时候需要产生读fifo使能(rd_en)。
Fifo的位宽设置为8,fifo一次读出8bit数据,而sdi传输1bit数据,所以需要考虑fifo读使能拉高的时机以及读出的数据移位的时机
2.1.1 信号连接示意图:
2.1.2 PP状态机
2.1.3 波形图设计(WE部分和DELAY部分和上述一致)
rd_en和rd_data数据移位实现并转串细节:
2.1.4 代码
3.读flash操作
Read data byte 读数据字节指令,简称 RDB 指令,指令码为 8’h03,读指令可以读取 Flash 地址空间的任何一个byte 数据,不受扇区,页的限制,而且可以连续读取出所有数据。
读数据的必要条件:给出读命令码,然后紧跟 24bit 的起始地址,之后会在 SDO 总线串行输出读出数据,直到 Cs_n 信号拉高中断读出数据操作,否则地址在 flash 内部递增读出数据。
flash_rd操作时序图:
3.1 flash_rd模块设计
读控制器要能满足以下功能:
给定读起始地址和需要读取的数据长度,控制器自动启动读 flash, 并把读出数据缓存到 fifo 中,以供其他模块读取调用。
3.1.1 信号连接示意图
3.1.2 波形图设计
sdo是1bit ,而fifo的wr_data为8bit,因此要合理设计sdo的移位标志,与wr_en的标志,实现串转并写入fifo中。
3.1.3 代码
4.控制器设计
到目前为止,我们分别完成了flash_se、flash_pp、flash_rd三个对flash进行操作的模块,如何将他们整合在一起,实现:
上位机串口读写 flash 协议定义,我们通过串口给 fpga 发送指令,fpga 解析指令之后,转化为对 flash_se、flash_pp、flash_rd 的控制时序(即fpga能根据接收到的指令产生控制对应模块需要的输入信号),实现对 flash 的读or写or擦除操作。
既然要与上位机串口交互,我们必须制定一个协议,我们制定三种数据包类型,擦除命令包、写命令包、读命令包