/*
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 Presponse的格式
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.0MMC卡还支持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.
*/