前言
SPI NAND支持QSPI接口,具备高速,高可靠,低功耗的特点,相较于传统并行接口,具有封装体积小,引脚少,易于使用的优势,并且可以与SPI NOR Flash共用Layout设计,易于切换,使得其越来越广泛使用。
本文以具体型号为GD5F1GM7xExxG的GD的NAND为例,对SPI NAND Flash进行介绍。不同厂家的不同型号都大同小异了解一款其他的也就都了解了。
GD的SPI NAND Flash介绍
参考官网:
https://www.gigadevice.com.cn/product/flash/product-series/spi-nand-flash/
主要有1.8V和3.3V两个电压等级,1Gb,2Gb,4Gb这几个容量可选。
频率133(x1,x2,x4),104(x1,x2,x4),80(x1,x2,x4)
都是2K页 2048+64B用户spare+64B硬件ECC
都带硬件ECC
支持DTR
温度:
-40℃~85℃,
-40℃~105℃
封装:
WSON8 8x6mm,
WSON8 6x5mm,
TFBGA24 8x6mm (5x5 ball array)
下面以GD5F1GM7xExxG详细介绍。
基本特征
l1Gb大小,块擦除,块含64个 PAGE,PAGE编程(2KB+128B)。
l支持Standard, Dual, Quad SPI,DTR(只针对读)
DTR即在Quad基础上下边沿都可以传输数据,带宽加倍,这个是一个高级功能。
l频率
最大
Standard/Dual/Quad SPI 时133MHz
DTR Quad SPI 时104MHz 即104Mx4x2b/S, 最快104MB/S。
l软硬件写保护,低电压LOCK保护。
l20KB OTP区域
lPAGE编程时间320uS,块擦除3mS,PAGE读120uS。
lBLOCK0保证OK。
l带ECC的P/E次数80K,符合SLC的一般水平。数据可保持10年以上。
l支持硬件ECC,默认使能。
8位ECC编码528B数据。
从FLASH中读PAGE数据到CACHE中时可以自动检测和校正错误,能够校正的直接校正返回给用户的就是正确的数据,有状态表示校正错误状态。额外空间有128字节,64字节给用户使用,64字节给ECC使用。
l内部数据移动和复制功能
这也是一个高级功能,针对FTL管理设计。
这在FTL中垃圾回收管理时非常有用,不需要再到用户的memory里读写倒腾一次,就可以直接移动和复制,并且是带ECC操作的。
l上电自动加载第一个块的第一个PAGE到CACHE,并且是带ECC校正和检测的。
用户可以直接读CACHE,可以加快启动时间。
有两个缓存data register 和 cache register,前者更接近于memory阵列,所以作为NAND Flash存储阵列操作的缓存,后者更接近IO,所以作为IO操作的数据缓存。
cache register使得可以进行页内的随机读写,和copy back操作。
引脚
CS默认必须拉高,DQS不使用必须浮空
WP和HOLD不用必须拉高。
框图
其中cache memory包括data register 和 cache register两个PAGE大小的缓存。
地址
CA:即列地址,页内地址, 虽然12位可以表示0~4095,但是实际范围是0~2175. 即2K+128字节的页空间。
列地址可以理解为矩阵几行几列的列。列地址即一行数据(页)里面的偏移。
RA:行地址, RA<5:0>表示页地址,RA<15:6>表示块地址。
存储组织
页大小是2K+128,一个块有64个页,以巩固1024个块。
一个PAGE有128字节的额外存储空间,其中前面的64字节是给用户用的,FTL的管理使用。后面64字节是硬件ECC使用。
使能CECC时后面的64字节用户不能写但是可以读。
硬件ECC不使能时,整个128字节用户都可以读写。
设备操作
SPI接口
支持两种模式
模式0 CPOL = 0, CPHA = 0 CLK默认低,第一个边沿锁存数据(第一个上升沿)
模式3 CPOL = 1, CPHA = 1 CLK默认高,第二个边沿多存数据(第一个上升沿)
两种方式都是上升沿设备输入数据锁存SI,然后下降沿主机输入数据锁存SO。
如下图所示
CS拉低是一次通讯的开始,
在SCLK的上升沿SI锁存数据(设备锁存数据):注意发送端实际在前一个下降沿就已经开始输出数据,因为数据需要有建立时间,然后上升沿设备对SI数据锁存,在下一个下降沿主机结束数据输出。
也就是SCLK为低时是SI的数据建立时间,SCLK为高时时SI的数据保持时间。
主机是在下降沿修改SI的数据的。
在SCLK的下降沿SO锁存数据(主机锁存数据):注意发送端实际在前一个上升降沿就已经开始输出数据,因为数据需要有建立时间,然后下降沿主机对SO数据锁存,在下一个上升沿沿设备结束数据输出。
也就是SCLK为高时是SO的数据建立时间,SCLK为低时是SO的数据保持时间。
设备是在上升沿修改SO的数据的。
所以理想状态是SCLK的上升沿在SI数据的中间。
在SCLK的下降沿在SO数据的中间。
还有就是需要注意下是高位在前的发送顺序。
还有就需要注意,CS是高时如果是模式0则SCLK要保持低,如果是模式3则需要保持高,不能翻转。只有CS拉低之后SCLK才能产生时钟。
默认最好硬件上拉CS,即不使用SPI FLASH时,设备处于idle状态。
标准SPI
发送命令时,和普通IO命令,都是用该模式
SCLK,CS,SI只做输入,SO只做输出
DualSPI
在使用x2 和 dual IO命令时的后面数据阶段:
SI变为SIO0 双向
SO变为SIO1 双向
Quad SPI
在使用x4 和 Quad IO命令时:的后面数据阶段
SI变为SIO0 双向
SO变为SIO1 双向
WP变为SIO2 双向
HOLD变为SIO3 双向
DTR Quad SPI
在状态寄存器的QE位置位,且使用DTR Quad I/O Fast Read命令时的数据阶段
在Quad SPI基础上,SCLK的上升沿和下降沿都锁存数据
HOLD模式
只有在QE=0时才支持该功能,如果QE=1则是使用DTR Quad SPI,HOLD引脚变为了SIO3.
在CS保持低时,HOLD拉低可以只暂停但是不停止正在进行的读,写,擦除操作。
HOLD的下降沿之后到SCLK变为空闲电平开始HOLD开始,
HOLD的上升沿之后SCLK变为空闲电平开始HOLD结束。
在HOLD阶段SO高阻态,SI和SCLK被忽略掉。
如果HOLD时CS拉高,则会复位内部状态机逻辑结束操作,重新开始操作需要HOLD拉高CS拉低。
写保护
WP用于硬件写保护, QE=0时才支持该模式.
WP为低时(BP0, BP1, BP2 和INV, CMP)不可写。
BRWD= 1,WP=0时 上述块保护位不能修改。
掉电时序
避免在写和擦除时掉电,或者在电压低时操作。写操作或者擦除进行中掉电会导致数据丢失或者损坏。问题:这里的丢失和损坏的影响域是什么,写PAGE则指挥这一个PAGE损坏,擦除BLOCK只有这个BLOCK损坏吗? 损坏只是数据不对,后面擦除就可以重新使用还是变为坏块?
DQS信号
DQS信号用于表示READ时输出数据是否有效。DQS只在BGA24封装有,用于高速传输时,相当于流控。只在 EEh命令用到。
设备接收到EEH命令时拉低QDS,表示忙,此时输出数据无效,因为设备还在进行内部处理,当DTR模式输出数据到IO引脚上时拉高DQS,表示数据就绪,主机就可以读数据了,相当于流控。
DQS的翻转速度和CLK频率是一样的,DTR读时数据必须在DQS的上升沿和下降沿锁存数据。这个引脚不使用时必须浮空。
命令表
注意读cache都需要有dummy,即需要等待一段时间让设备准备就绪。
FFH Reset命令会复位PAGE READ/PROGRAM/ERASE操作
复位状态寄存器P_FAIL/E_FAIL/WEL/OIP/ECCS/ECCSE
上电时序
需要注意的就是Vcc(min)之后至少需要tVSL时间之后才能拉低CS,之前必须一致保持高。
还有就是要注意Vwi,低于该电压不允许写,所以在设计电压看门狗,和掉电保护电路时需要考虑该值,留有一定裕度。
性能参数和时序
注意软复位0xFF之后需要延迟500uS以上才能发送下一个命令。
注意两个参数
输入信号的高低电平门限
低电平需要低于0.2VCC,高电平需要高于0.8VCC,这个需要测试下,保证IO能拉低到足够低,拉高到足够高。很多硬件设计有保护电路,上下拉电阻,串电阻导致分压,三极管二极管压降等导致电压不够足够低或者足够高,就不是很保险。
这里还有个参数需要注意下
正负过充不能超过2V,20nS,这个需要实际测试,理论上就不应该有过充,有些环境或者设计可能无法消除,也要保证不超过该值,越小越好。
坏块
保证寿命时间内,最多有20个坏块,坏块标记是块的spare区域的第一个字节0x800处为0x00,检测的话非0xFF即认为坏块。
操作
读比编程的指令更多,读可以使用x1,x2,x4,x4 DTR,且命令之后的Dummy和地址页也可以x2,x4,x4 DTR。
而编程只有x1,x4,没有DTR,命令之后的Dummy和地址也只能x1。
写禁止/使能(0x06/0x04)
写使能 直接发送0x06命令即可
页编程,OTP保护和OTP编程,块擦除前都需要写使能。
写使能生效后0xC0的寄存器WEL位置位
所以一般发送写使能命名后要查询该位确认是否使能。
注意以上编程操作之后WEL自动清0进入写禁止状态,这样做是为了安全避免误触发写。
写禁止 直接发送0x04命令即可
该命令几乎用不到,因为默认上电WEL就是0写禁止的,每次编程操作之后硬件也会自动清零WEL进入写禁止状态。
读
读需要先通过0x13从FLASH中读出数据到缓存中,然后通过0x03/0x0B,0x3B,0x6B等指令从缓冲区中随机地址开始读出数据。
0x03/0x0B,0x3B,0x6B除了数据阶段前面的时序都是一样的,数据阶段分别使用x1,x2,
X4位。
读到2048+128后绕回从0开始继续。
使用4个引脚的指令需要先使能0xB0寄存器的QE 位。
读ID(0x9F)
先发命令再9=8个Dummy Cycles,然后连续读2个字节的数据。
返回MID和DID可以用于区分具体的型号,具体值可以参考手册。
以下是一个实测波形
读PAGE(0x13)
0x13命令将FLASH中的页读到缓存中,需要提供24位的PAGE地址。设备收到地址后tRD时间内将FLASH读到缓冲中, 主机需要读寄存器0xC0的OIP位,等待OIP为0表示完成。
整个流程如下
拉低CS,发0x13H的命令,然后发24位地址,再释放CS,命令发送阶段完成。
然后是状态查询阶段,即读0xC0寄存器的OIP位,详见读寄存器章节的说明。
从缓冲区读数据(0x03/0x0B)
上述的PAGE读到缓冲区后,主机就可以从缓冲区随机读数据了。
需要注意的是发送完命令后需要等4个Dummy cycles。然后发送12位的PAGE内开始地址,然后再等待8个Dummy Cycles,然后就连续读数据。
注意如果时钟不停,CS不拉高则设备会一直吐数据,地址绕到2048+128的页边界后又从0开始绕回继续。注意这里的边界是2048+128而不是2048+64.
X2模式从缓冲区读数据(0x3B)
前面和0x03/0xB都是一样的,先发8位命令,接下来4位Dummy cycles,然后12位页内偏移地址,然后8个dummy cycles。
后面数据阶段则不一样,使用了IO0和IO1,IO0和IO1表示两位IO1表示高位,然后从高位开始输出,即4个Cycles吐出一个字节的数据。
X4模式从缓冲区读数据(0x6B)
该模式前面和0x03/0xB的时序都是一样的,从数据阶段开始不一样
使用了IO0和IO1,IO2,IO3,表示4位IO3表示高位,然后从高位开始输出,即2个Cycles吐出一个字节的数据。
Dual IO模式从缓冲区读数据(0xBB)
与0x3B的区别是,0xBB只有命令字使用单IO,其他所有数据都是使用双IO。
Quad IO模式从缓冲区读数据(0xEB)
与0x6B的区别是,0xEB只有命令字使用单IO,其他所有数据都是使用4IO。
Quad I/O DTR模式从缓冲区读数据(0xEE)
除了命令字节,其他的上升沿和下降沿都可以传输数据,使用4个IO。
不使用DQS
使用DQS
在Dummy和地址阶段DQS为低,在数据阶段DQS的双边沿锁存数据。其他时候高阻态。
读UID
UID是设备独特码,可以用于认证,设备编码等场景。
共32字节,前面16字节和后面16字节是取反的关系,所以异或前后16字节应该全部是0xFF。
为了可靠,避免bit错误导致读出错误,UID总共存了16份,如果前面的校验错误(前后16字节异或不为0xFF),则可以继续偏移32字节用后面的。
读之前需要设置B0寄存器的OTP_EN为1.
然后回读确认OTP_EN为1
然后用0x13指令读FLASH到缓冲区,24位地址写0.
确认OIP读完
然后用0x03/0x0B读UID数据,可以一次读32x16字节,也可以一次读32字节检查不对再读后面的。
读参数页
参数页是一些描述芯片的组织,特征,时序和行为的参数。为了可靠数据至少存了3份,即至少有3个页。
执行过程和读UID一样,只是24位地址变为了1.
读之前需要设置B0寄存器的OTP_EN为1.
然后回读确认OTP_EN为1
然后用0x13指令读FLASH到缓冲区,24位地址写1.
确认OIP读完
然后用0x03/0x0B读缓存区中的数据。
参数页符合ONFI标准(https://www.onfi.org/),比如uC-FS的NAND的FTL层就支持使用ONFI模式自动配置NAND参数。
编程
先用0x02或者0x32指令将数据写入缓冲区
然后0x06写使能,确认写使能成功
然后0x10执行缓冲区到FLASH的写
最后0x0F读寄存器0xC0确认P_FAIL是否有错,OIP是否完成
注意(84h/C4h/34h) 和(FFh) 指令是不会清除缓存中的内容的,所以下次编程时要注意是否缓存区都是需要更新的数据,所以必须是一次更新整个缓冲区,不要部分更新。
0x02和0x32指令之后紧接着0x10则未被0x02和0x32指令更新的缓冲区区域的值变为0xFF。
(84h/C4h/34h) 指令之后紧接着0x10指令,缓冲区的内容写入NAND FLASH中。
编程地址按照块的顺序
QE=1时才能使用0x32指令
如果写缓冲区,绕到了缓冲区边界2176,后面的数据忽略而不是绕回,这个和读是不一样的。如果使能ECC写最后面的64字节是忽略的。
编程加载PL(0x02)
8位命令0x02后是4个Dummy Cycles,然后是12位页内偏移地址,然后是数据。
使能ECC时只能写2112个字节,否则可写2176个字节。
编程加载PLx4(0x32)
必须QE=1
使能ECC时只能写2112个字节,否则可写2176个字节。
前面时序一样,从数据阶段开始使用4xIO
编程执行PE(0x10)
需要指定24位的PAGE地址, 执行后需要等待tPROG时间等待编程完,
可以查询0xC0寄存器的P_FAIL和OIP
注意编程完成后会自动写禁止,且缓冲区中的数据变得无效。
编程加载随机数据(0x84)
该指令和0x02的区别是,0x02一次更新整个缓冲区的数据,而本指令可以更新一部分缓冲区的数据,多次执行可以更新不连续的区域。
编程加载随机数据x4(0xC4/0x34)
和0x84一样,只是数据阶段使用4个IO
必须QE=1
内部数据移动
0x13读PAGE数据到缓冲区
84H/C4H/34H 编程加载随机数据到缓冲区(可选更新部分数据),如果有多个零散的区域更新则需要执行多次。
0x06写使能
0x10执行缓冲到NAND的写
0x0F查询状态
块擦除操作(0xD8)
先0x06写使能
0xD8擦除,指定24位页地址
等待tBERS 时间
0x0F读0xC0的E_FAIL和OIP查询状态
复位
软复位(0xFF)
停止操作进入idle状态
软复位后的寄存器值参考手册
使能上电复位和上电复位(0x66,0x99)
比软件复位更彻底,即和上电复位一样的效果,寄存器值也和上电复位一样。
复位完需要等待tVSL 时间,然后读OIP确认空闲再进行其他操作。
正在编程的存储器位置或正在擦除的块的内容不再有效。
先发0x66使能再发0x99执行操作
特征操作与读写寄存器
寄存器用于控制行为,表示状态
其中状态寄存器0xC0 0xF0是只读的,除了WEL可以通过0x06指令修改。
特征和保护寄存器0xA0 0xB0 0xD0可以读写进行配置。
注意OTP_PRT是非易失的即掉电保存的,其他的是掉电不保存。
特征寄存器一直保持直到上电复位或者重新修改。0xFF软复位不会清除。
保留值只能写0
QE=1才能使用4xIO
BRWD=1且WP为低时则不能修改块保护配置
寄存器如下
默认值分别是
0xA0 0x38
0xB0 0x10
0xC0 0x00
0xD0 0x00
0xF0 0x08
寄存器的一些状态位信息
ECC信息
驱动能力
OTP
提供一个受保护的10个PAGE大小的一次可编程区域。访问OTP的10个页需要按如下修改对应寄存器位。
PAGE0存UID
PAGE1存参数页
PAGE2-PAGE11 用户使用(只能通过0x02+0x10进行编程),0x13+03H/0BH/3BH/6BH/BBH/EBH 读出。需要按照如下设置OTP_PRT OTP_EN设置访问属性。写的话先使能OTP的写然后0x06写使能,再编程。
块保护
电源锁定保护
BPL=1时 块保护BP[0,2] , INV , CMP 和BRWD 将无法再修改除非掉电重启。
可以用于QE模式没有WP硬件保护时,软件进行保护,保护kuai块保护状态不被修改。
ECC
ECC_EN默认为1,软件可以修改使能或者禁用硬件ECC,
写数据硬件自动计算ECC,此时最后64字节用户不能写,读时自动进行数据校正,状态信息更新到ECCS0/1 ECCSE0/1
布局如下,使能ECC时最后64字节可读不可写
读寄存器(0x0F)
先发0x0F再发地址,无需dummy,然后读字节
只有普通SPI模式
以下是实测不同寄存器的波形
写寄存器(0x1F)
先发0x1F再发地址,无需dummy,然后写字节
只有普通SPI模式
休眠操作
只针对1.8V的设备
进入休眠(0xB9)
此模式忽略所有的编程操作,收到指令tDP 时间后进行真正的休眠
只接受0xAB 0xFF 0x66 0x99指令
退出休眠(0xAB)
上电复位 或者0xAB指令
收到指令后tRES1 时间才可查询状态,进行后续操作
总结
以上基于GD5F1GM7xExxG的GD的NAND为例,对SPI NAND Flash进行了详细的介绍,对于驱动编写来说重点关注其波形,所以逻辑分析仪不可少,然后是关注写保护相关的操作量产时合适的保护可以避免异常的改写数据。