SD card高速读写记录
苯人原创,排版很差,爱看不看。
SD卡有好几种总线协议,包括SD总线协议,SPI协议,UHS-II协议和PCIe协议。
还有两种接口,一种是八个触点的,这种卡包括低速卡和高速UHS-I卡。另一种是多了几个触点的UHS-II接口,这种是支持更高速的UHS-II协议的高速卡。
注意区分协议和接口以及传输模式。本文主要说一说UHS-I卡。
UHS-I使用开头所述的SD总线协议,此总线有4 bit模式or1 bit模式,接口和老旧的低速卡接口一致。
UHS-I支持两种卡类型:UHS50和UHS104.也就是你所买的UHS-I SD卡会是这两种中的一种。这两种卡的速度不同,具体的我就直接贴图了。
上图是时钟频率,如果是SDR(单边沿传输)则传输速率为频率/2(4bit传输,两个时钟传输一个字节),DDR(双边沿)时钟频率就是速率。注意上图电压是信号线的电压,供电电压大部分是3.3v。具体说明如下:
首先说一下卡的线:
VSS和VDD是电源线,CLK时钟,还有四条data线和一条cmd线,分别用来传输数据和命令。在加电前,dat3还用来选择sd模式或者spi模式。如果dat为低,是spi模式,否则sd模式。
命令组成:
所有的命令都通过命令线传输,一共48位。先传输第47位,再传输第0位。最高位为起始位,始终为0.次高位为传输方向,1代表从主机发送给sd卡。45到40位为命令编号,比如CMD11的这几位就是001011.接下来是参数位,共32位,然后是CRC7校验,最后一位停止位,始终为1.
传输时序:
两幅图结合着看。上图是UHS-1初始化流程。
加电后处于等待CMD0(rst)状态。然后发送CMD8命令,查询卡供电电压是否合适。如果合适,则卡会给出一个响应。
接下来发送ACMD41命令。ACMD41命令如下图所示。注意ACMD41命令由CMD55和CMD41拼凑,R1和R3代表响应。下边会详细介绍这个命令。
如果上边CMD8查询没反应(电压不匹配),接下来,第一次发送ACMD41时,通过把ACMD41命令参数中的OCR(电压窗口字段)设置为0,主机可以查询卡支持的供电范围,然后把主机修改自己的供电电压后,可以再次发送同样的ACMD41命令,此时卡会进入未激活状态。
如果上边CMD8查询有反应,在供电正常后的初始化过程中,不能修改电压。
第一次发送ACMD41的OCR参数不为0,进入初始化阶段,并且ACMD41的其余参数也都有效。接下来重复发送ACMD41命令,参数保持一致。下图是CMD41命令。
这里的参数设置了支持的卡类型,支持的功率,还有要不要切换到1.8v。我们为了高速,需要切换,因此把这几个bit都置为1.
第36位标识的卡的类型包含如下图:
我们一般买的都是SDHC或者SDXC
CMD41的响应如下图:
主要有最高位的初始化是否完成,卡的容量状态,以及是否准备好切换信号电压。
一直重复发送ACMD41,直到响应的busy变成1(代表初始化完成),然后检查CCS,UHS-II,S18A。如果S18A变成1了,可以发送电压切换命令CMD11。这里可以参考图X。
CMD11命令
CMD11会在命令线返回一个R1响应,表示开始切换电压。切换完成的标志是数据线全部被拉高。如果SD卡电压切换完成,卡会进入SDR12模式。
然后按部就班发送CMD2,CMD3,CMD7,CMD42命令。
发送完毕后,然后发送ACMD6命令,用来选择4bit总线宽度。在加电后,默认是1bit。对于UHS-I卡来说,这一步是必须的。UHS-I只支持4位模式。
ACMD6命令参数如下图。
其中,[31:2]为填充位,填0就行,[1:0]位为总线宽度设置,'00'代表1bit,'10'代表4bit,UHS-I卡必须设置为4bit的。
然后通过CMD6命令(注意不是ACMD6),可以选择传输速度模式,驱动强度。具体的可以看下图。
简单来说,每一次发送命令,可以选择一个方框。比如我想设置传输模式为SDR104,那么我应该把命令参数的[3:0]位设置为0x3,其余位设置位0xF(No infulence)。还有需要把mode位设置1,表示是set命令,如果mode=0,表示是get命令。
CMD6命令参数说明见下图。
在修改完传输速率后,需要等待CMD6的响应结束后再等8个时钟周期,然后才能修改主机的时钟频率。或者说大部分命令的执行周期都是8个时钟周期,对于需要切换状态(比如电压,时钟)的命令,都等ok标志8个周期后再操作主机。
一切设置完毕,然后需要进行采样点调优。这一步对于SDR104必须。
其主要原理就是主机发送一个CMD19命令后,SD卡会在数据线上发送一长串固定的数据,你用不同相位的时钟采样一下,然后找到最佳采样点。Data Block如下图所示。
这里Data Block总共16*32=512bit,每条数据线传输128bit,校验位16位,一位开始位,一位停止位共146位。
初始化先写到这儿。