SD卡的寄存器 SD总线协议 CRC算法

/*
SD卡的寄存器

RCA,16bits,相关卡地址,卡的本地地址,在主机初始化的时候被动态分配
CID,128bits,生产id,oem id,产品名,产品版本,序列号,生产时间
CSD,128bits,关于卡工作条件的专用信息,主要是数据操作方面的
OCR,32bits,工作条件寄存器,主要是电源电压情况寄存器
SCR,64bits,SD配置寄存器,关于卡的特殊性能的寄存器

SD总线协议

通信是通过一个 start位=0 开始,一个 stop位=1 结束

command,开始一个操作。主机发出一个或多个。
一个是address command,多个是broadcast command。
一个command是在cmd线上串行传输的。

response,来自一个卡或者多个卡,给host的,用来相应一个之前接收到的命令。
也是在cmd线上串行传输。

data,host去卡,或者卡去host都可以。读写嘛。通过data线。

command的格式, G(X)=X^7+X^3+1
对于CMD来说,MSB是先传的
S H [----content38------] CRC7 P

response的格式
S C [----content38------] CRC7 P
R1 : STA --- 48 bits = 6 bytes
R3 : OCR --- 48 bits = 6 bytes
R6 : RCA --- 48 bits = 6 bytes
R2 : CID --- 136 bits = 17 bytes
R2 : CSD --- 136 bits = 17 bytes

数据包的格式 : CRC算法。多项式产生是通过标准的CCITT格式:x16+x12+x5+1

1 bit : S MSB4095------------LSB0 CRC16 P

DATA3 : S MSB4095------------LSB0 CRC16 P
DATA2 : S MSB4095------------LSB0 CRC16 P
DATA1 : S MSB4095------------LSB0 CRC16 P
DATA0 : S MSB4095------------LSB0 CRC16 P

功能描述

host是个master的角色。它控制着和sd卡的通信。host会发出两种命令。

广播命令,给所有的sd卡。有些命令需要一个回复。
指定命令,也就是点对点命令。给一个指定的卡,并且需要回复。

sandisk的卡支持两种操作模式

card indentification模式,
reset之后,当host查找新插入的卡时,host会进入这个模式。
卡将会进入这个模式在重其后,直到SET_RCA被收到。
这个模式通常有idle,ready,identification这几种状态。

data transfer模式,
sd卡会进入这个模式,当RCA被先公布后。
host会进入这个模式当识别了总线上的卡后。
这个模式通常有standby,transfer,send data,receive data,
programming,disconnect等状态。

先看card identification模式 **************************************************

在这个模式里面啊,host会重置所有的卡,验证工作电压的范围,
验证并且请求卡去发布RCA。这件事是每个卡独立干的,通过CMD。
所有的数据通信在这个模式都只用CMD线。

1.先看reset : GO_IDLE_STATE(CMD0)

软件重启命令是GO_IDLE_STATE(CMD0),会把每个卡都弄到idle的状态,
不管卡当时是什么状态。这个处理方法很好,多样问题单一化,处理起来方便有效。
有一个特例,在inactive状态的卡不受影响。
在上电或CMD0后,所有的卡的CMD线都是输入模式了,都等待start bit。
此时的卡有一个默认的相关地址(RCA=0x0000)和
一个默认的驱动寄存器值的配置(低速,高驱动电流能力)

2.那么下面看看操作电压的验证 : SD_SEND_OP_COND(ACMD41)
(MMC卡对ACMD41不支持。mmc的初始化也有点不同。)

虽然sda规定了一个区间,这个区间内的电压都要被支持。但是有些卡就是不支持。
所以host需要去OCR寄存器中看看,能选就选,不能选就把卡吐出来。
SD_SEND_OP_COND(ACMD41)是用来给host来验证卡,或者发现电压不兼容来吐卡的机制。
host发个电源区间给卡,如果卡不能接受,那么就要进入非活跃状态。

通过用命令发出电压区间,host可以知道那些不兼容的卡,
并且是在把这些超出电压区间的卡踢入非活跃之前。
sandisk的卡在ACMD41的时候,会通过busy告诉host,卡是不是在上电或者重启的过程中,
还没能为通信准备好。这样的化,host就要不停的发ACMD41,知道busy没有。
在初始化过程那,host不能改变OCR,即使改了,卡也会忽略它。
如果真的想改,那么请用CMD0,把卡重置。
如果卡在非活跃状态,请先断电再上电

GO_INACTIVE_STATE(CMD15)能把卡打入非活跃状态。
主机当不想这个卡工作的时候会用CMD15,比如主机的电压改变成卡无法支持的了。

3.紧接着看看卡识别的过程 : ALL_SEND_CID(CMD2) SEND_RELATIVE_ADDR (CMD3)
host是通过识别时钟速率fod来开始的,在sd卡中,CMD线输出驱动是上拉下拉驱动。
当总线开始工作,主机会请求卡发出他们的有效操作条件。ACMD41的相应是卡的OCR。
同样的命令会发到所有的卡上。不兼容的卡就会进入非活跃状态。
host发出ALL_SEND_CID(CMD2)以得到各个卡的CID,没有被认出的卡就通过CMD线
发出CID以相应。当卡发出CID后,就会进入识别状态。其后那,
host会发出CMD3(SEND_RELATIVE_ADDR),请求卡发出一个相关地址RCA,这个比CID短,
这个地址以后就用作将来数据传输用的地址。
当RCA被收到后,卡的状态就进入stand-by了,
在这时候,如果host想让卡有另外的一个RCA数字,可以通过SEND_RELATIVE_ADDR来做。
最后得RCA就是实际的相关卡地址了。

当所有的SD卡都被初始化后,host会出世mmc,通过CMD2和CMD3,这些在MMC规格中有提到。

host发出SEND_CSD(CMD9)来得到一些卡的专用数据,比如block length等等。

现在看看卡的数据传输模式 *****************************************************

1.CMD7可以将卡置在传输模式。( 卡选择 )
只有一个卡可以在一个时间内在这个状态。
如果一个之前的卡在这个状态,那么与host的连接将会释放,并且回到stand-by模式,
当CMD7被发出保留相关卡地址0x0000,所有的卡传输都回到stand-by状态。
这个可以用来识别新插入卡,并且不会重置以及注册的卡。
以及有RCA的卡,不需要对识别命令相应。

取消选择发生在一个特定的卡在重试CMD7的时候,发现RCA不匹配。
在另外一个卡和CMD线通用的时候,会自动发生。
因此,在SD卡系统中,系统需要负责做二选其一的事情。
A. 初始化后,通过公用CMD线工作,在这个情况下,取消选择会自动发生
B. 有意识去取消选择,如果CMD线是分开的

所有的数据通信在数据传输模式都是点对点的。
所有的命令都会有个在CMD线上的相应。

2.停止命令CMD12
能够忽略所有的读命令在任何时候,数据传输会中止,并且卡会返回到传输状态,
读命令能够阻止块读CMD17,多块读CMD18,发送写保护CMD30,
发送SCR ACMD51,和general命令在读模式中CMD56。

能够中止所有的数据写命令在任何时候。写命令必须在取消选择CMD7之前停止。
写命令被块写CMD24、CMD25,写CSD(CMD27),锁和解锁(CMD42),
和在写模式的通用命令(CMD56)阻止。

当数据传输完成的时候,sd卡会在数据写状态。
之后如果写成功了,那么就去编程状态,
如果失败了,就去传输状态。

如果block写操作被停止,并且block长度的crc是有效的,数据会被写入。

卡可以提供块写入的缓冲,下一个块可以在之前的块被写入的时候往卡里发送,
如果所有的卡buffer都满了的话,sd卡就会在编程状态,DAT0线会被拉低

**没有buffer提供给写CSD,写保护,和擦除。

当卡在忙于一个命令或前面的命令的时候,DAT0会被保持为低并且在编程状态。
实际上,如果CMD和DAT0被分开,并且host保持DAT0为忙,
并且和其他卡的DAT0是分开的时候,host可能会读写其他卡如果这个卡是忙的时候。

如果卡在编程中,参数设置命令是不被允许的。
参数设置涉及块长度CMD16,擦除块开始CMD32,和擦除块结束CMD33。
如果卡在编程中,读命令是被不会允许的

把另外一张卡从stand-by转到传输状态的时候(CMD7),不会中止编程操作。
卡会切换到非连接状态,并且释放DAT线。

通过CMD7,一个卡可以在非连接状态被重新选择。
在这个情景下,卡会去编程状态,并且激活busy的鉴别状态。

重置卡通过CMD0,CMD15,会中止如何挂起或有效的操作,这个有可能破坏卡上的数据。
host有责任去阻止对数据的潜在伤害。

宽总线的选择和取消选择 *******************************************************

在上电或者GO_IDLE后的默认的宽度是1bit。
4bits当然就是宽的了,是通过ACMD6来选择的。
ACMD6只在传输状态有效。也就是说只有在CMD7,一个卡被选择了后,总线宽度才能改变。


下面看一下擦除 ***************************************************************

通过ERASE_WR_BLK_START(CMD32),ERASE_WR_BLK_END(CMD33),来伴随着块写入的完成。
host发命令的顺序必须是CMD32,CMD33,和ERASE(CMD38)。
如果这三个命令没有安装这个顺序,那么ERASE_SEQ_ERROR就会被置高,并且重置所有的顺序。
如果一个乱序的命令(除了SEND_STATUS)被接收了,
卡会把ERASE_RESET设置,重置擦除的顺序并且执行最后的命令。

在擦除中的块会把DAT0拉低。实际的擦除时间可能有点长,
host可能会用CMD7来释放卡的连接,来干别的事情。

卡被擦除了后,可以为0,可以为1,决定于制造商。
可以通过DATA_STAT_AFTER_ERASE(bit55)来定义0、1。

SD卡和MMC卡的异同 ************************************************************

两者在外型的规格上是几乎一致, 接口是兼容的. 两者可以用同一个卡座来进行读取.
而且, 两者在时序上也是一致的, 读写命令控制也完全一样.

在数据位宽方面, MMC卡最大支持8BIT, 而SD卡只能支持4BIT传输.
在卡的激活过程, MMC使用CMD1来进行激活, 而SD卡使用ACMD41来进行激活的.
在获取卡的RCA地址时, MMC卡是由主机分配RCA给设备, 而SD卡则是由设备返回RCA给主机.

MMC有EXT_CSD的概念, 主要用CMD8进行读取, CMD6进行设置.
SD卡则只用CMD6进行UserFunction的设置.
SD卡的CMD8主要用于区别SD1.0和SD2.0

MMC卡还支持CMD11, CMD20这类数据流操作.
MMC还支持CMD14和CMD19进行主线测试, 主要用于检查是否支持8bit, 4bit的数据位宽,
从而选择合适总线进行通信. CMD14发送一个数据包, 再用CMD19读回该数据包, 进行校验.
SD则不支持.

一般来说刚上电时,

SD卡不支持CMD1而支持CMD55,

MMC卡不支持CMD55而支持CMD1.

通过CMD8来区分SD1.1和SD2.0卡,

通过ACMD41来区分SD2.0 SDSC or SDHC.

 

*/

posted @ 2013-03-23 20:03  IAmAProgrammer  阅读(4003)  评论(0编辑  收藏  举报