上周看了卡的识别模式后,现在看看卡的数据传输模式,这是最重要的模式,勿庸置疑。
因为一些卡可能有时钟限制,fpp必须保持在fod,直到CSD寄存器被host读取。host发出SEND_CSD(CMD9)来得到一些卡的专用数据,比如block length等等。
CMD7可以将卡置在传输模式。只有一个卡可以在一个时间内在这个状态。如果一个之前的卡在这个状态,那么与host的连接将会释放,并且回到stand-by 模式,当CMD7被发出保留相关卡地址0x0000,所有的卡传输都回到stand-by 状态。这个可以用来识别新插入卡,并且不会重置以及注册的卡。以及有RCA
的卡,不需要对识别命令相应。
*取消选择发生在一个特定的卡在重试CMD7的时候,发现RCA不匹配。在另外一个卡和CMD线通用的时候,会自动发生。因此,在SD卡系统中,系统需要负责做二选其一的事情。
-初始化后,通过公用CMD线工作,在这个情况下,取消选择会自动发生
-有意识去取消选择,如果CMD线是分开的
所有的数据通信在数据传输模式都是点对点的。所有的命令都会有个在CMD线上的相应。
下面我们看下卡里的命令。
1 停止命令CMD12,能够忽略所有的读命令在任何时候,数据传输会中止,并且卡会返回到传输状态,读命令能够阻止块读CMD17,多块读CMD18,发送写保护CMD30,发送SCR ACMD51,和general命令在读模式中CMD56。
2 停止命令CMD12,能够中止所有的数据写命令在任何时候。写命令必须在取消选择CMD7之前停止。写命令被块写CMD24、CMD25,写CSD(CMD27),锁和解锁(CMD42),和在写模式的通用命令(CMD56)阻止。
3 当数据传输完成的时候,sd卡会在数据写状态。之后如果写成功了,那么就去编程状态,如果失败了,就去传输状态。
4 如果block写操作被停止,并且block长度的crc是有效的,数据会被写入。
5 卡可以提供块写入的缓冲,下一个块可以在之前的块被写入的时候往卡里发送,如果所有的卡buffer都满了的话,sd卡就会在编程状态,DAT0线会被拉低
6 没有buffer提供给写CSD,写保护,和擦除。当卡在忙于一个命令或前面的命令的时候,DAT0会被保持为低并且在编程状态。实际上,如果CMD和DAT0被分开,并且host保持DAT0为忙,并且和其他卡的DAT0是分开的时候,host可能会读写其他卡如果这个卡是忙的时候。
7 参数设置命令是不被允许的,如果卡在编程中。参数设置涉及块长度CMD16,擦除块开始CMD32,和擦除块结束CMD33。
8 卡被编程的时候,读命令是被不会允许的
9 把另外一张卡从stand-by转到传输状态的时候(CMD7),不会中止编程操作。卡会切换到非连接状态,并且释放DAT线。
10 通过CMD7,一个卡可以在非连接状态被重新选择。在这个情景下,卡会去编程状态,并且激活busy的鉴别状态。
11 重置卡通过CMD0,CMD15,会中止如何挂起或有效的操作,这个有可能破坏卡上的数据。host有责任去阻止对数据的潜在伤害。
宽总线的选择和取消选择
4bits当然就是宽的了,是通过ACMD6来选择的。在上电或者GO_IDLE后的默认的宽度是1bit。ACMD6只在传输状态有效。也就是说只有在CMD7,一个卡被选择了后,总线宽度才能改变。
下面看看读数据的格式
当数据没有被发送的时候,数据线是高的。一个传输的数据块包括一个低的开始位,之后是连续的数据流。这个数据流包含了负载的数据,错误校验位如果卡外面的ECC被使用。数据流会以一个结束位结束。数据传输是同步的操作于时钟的。
基于块的数据传输是通过CRC算法。多项式产生是通过标准的CCITT格式:x16+x12+x5+1
对于块读操作,我们单独来说说
块传输的最大长度是通过READ_BL_LEN在CSD寄存器中定义的。一些起始地址在一个物理块之内的长度,被READ_BL_LEN来定义的,可能会被传输,只是可能。附着在每个块后面的CRC能够保证数据的完整性。CMD17或者READ_SINGLE_BLOCK 开始一个块读,完成后返回到传输状态。CMD18或者READ_MULTIPLE_BLOCK启动一个连续的多块操作。块会被连续的传输,直到一个stop命令。stop命令那,由于一系列的命令,有一个延迟,数据传输会在收到结束命令后结束。
如果主机用了多个块以及块的部分作为一个累加传输长度,而这个长度不是块对齐的。卡会在第一个没有对齐没有对齐的块上,检测到块非对齐错误,在状态寄存器中设置ADDRESS_ERROR位,中断传输,并且在数据状态等待停止命令。
下面看下写数据的格式
其实那,这个数据传送格式,跟读的类似。对于基于块的写数据传输,CRC被插入在每个数据块。在这个操作之前那,卡会对接受到的数据块执行一个CRC检查,算法跟读的一样。这个操作就阻止了写入数据的错误。
对于块写操作,我们单独来说说
块写入(CMD24-27,42,56),的意思是一个或多个块的数据从主机发送到卡,同时主机在每个块后面会挂1bit或4bits的CRC。老san的卡那支持的块写入被块长度规定了,这个长度被CMD16设置,不管WRITE_BL_LEN设置为1k还是
2k bytes,都是512bytes。
下面有个表来说明这个事情
CSD值 | 当前块长度 | 写命令的开始地址
--------------------------------
最大块长度 | 不对齐 | 部分的 |
WRITE_BL_LEN | | |
----------------------------------------------------------------
512bytes dis dis 512bytes n*512bytes
1-kbytes dis dis 512bytes n*512bytes
2-kbytes dis dis 512bytes n*512bytes