前言
Only整理我关心的内容,相当于笔记、便于后期回顾温习,部分图文转载自 “SD2.0协议详解:命令格式、初始化/读取/写入 ”。更多资料请阅读文后链接。
总结:
- SD协议与EMMC协议,其基本指令功能是一样的;特殊指令ACMD是SD专用。
- SD Card的初始化与EMMC Card初始化存在区别
- SD Card读写访问流程与EMMC Card基本一样
速率与电压:
UHS SDR12 SDR25 SDR50 SDR104 DDR50
- 12/25是SD 2.0的速率模式
- 50/104是SD 3.0的速率模式
Default Speed mode: 3.3V供电模式,频率上限25MHz,速度上限 12.5MB/sec
High Speed mode: 3.3V供电模式,频率上限50MHz,速度上限 25MB/sec
SDR12: UHS-I卡, 1.8V供电模式,频率上限25MHz,速度上限 12.5MB/sec
SDR25: UHS-I卡, 1.8V供电模式,频率上限50MHz,速度上限 25MB/sec
SDR50: UHS-I卡, 1.8V供电模式,频率上限100MHz,速度上限 50MB/sec
SDR104: UHS-I卡, 1.8V供电模式,频率上限208MHz,速度上限 104MB/sec
DDR50: UHS-I卡, 1.8V供电模式,频率上限50MHz,性能上限 50MB/sec
UHS156: UHS-II RCLK Frequency Range 26MHz - 52MHz, up to 1.56Gbps per lane.
目录
概述
简要介绍 SD2.0 协议,包括如何初始化卡、读卡、写卡。
另外,本文也可以作为 SD2.0 Specification 的导读。
SD卡是一种用闪存 (flash) 实现的便携式存储卡。目前已经发展出了不同的代数和规格,按照不同的指标分类如图1。目前最常用的仍然是图1最左侧的 SD 和 SDHC,它们都遵循 SD 2.0 协议。
感兴趣的读者可以去了解:一个基于 FPGA 的纯 RTL 的 SD 卡读取器:
1. SDIO 总线引脚定义
1.1 时钟要求
2 协议
2.1 CMD与ACMD
命令有两种:
- CMD (普通CMD),比如CMD2, CMD8等。
- ACMD (Application-Specific Command) 。
而 ACMD 则由 sdcmd 信号线上的两次命令-响应构成,如图7(b),第一次是 CMD55,第二次的命令就会被解读为 ACMD ,例如这里的 CMD41 就被解读为 ACMD41 。
2.2 寄存器一览
card 内部会维护如图8所示的各种寄存器。如果我们只想简单地进行初始化和读写,只需要关注 CSR, OCR, RCA 这三个寄存器。
2.3 响应格式
- R1响应: 常规响应,48bit,与命令格式相似。其中
[45:40]
应该填充与命令相同的命令号 (命令的命令号是什么,响应里就填充什么) 。[39:8]
位应该填充卡状态 (CSR) 寄存器,实时显示卡的状态。CRC7是校验码的计算类似命令格式,与命令格式类似,需要根据响应的[47:8]
位来计算。 - R6响应: 仅针对 CMD3 的响应,48bit。与 R1 响应格式相似,唯一的不同在于
[39:8]
位的不同。[39:24]
位是卡建议的 RCA 。[23:8]
位填充的是较短形式的 CSR 寄存器,只包括了{CSR[23:22], CSR[19], CSR[12:0]}
。 - R7响应: 仅针对 CMD8 的响应,48bit。与 R1 响应格式相似,唯一的不同在于
[39:8]
位的不同。 - R3响应: 仅针对 ACMD41 的响应,48bit。与 R1 响应格式相似,不同之处在于
[45:40]
不填充命令号,而是填充111111
。[7:1]
不填充 CRC7 ,而是填充1111111
。[39:8]
填充 OCR 寄存器。 - R2响应: 仅针对 CMD2, CMD9 的响应,总长度136bit,用来向主机返回 CID 和 CSD 寄存器。其中 CID 和 CSD 寄存器长度为 120bit (不算所谓的内部CRC),被填充在R2的
[127:8]
位。而[7:1]
填充 CRC7,需要根据 R2 响应的[135:8]
位来计算。
SD2.0 Specification 中还提到一种响应叫 R1b 响应,R1b是一种特殊的R1,除了同样在 sdcmd 上响应以外,card 还会在 sddat0 上发送一个可选的 busy 信号。根据卡在接收命令之前的状态,卡在接收到这些命令后可能会变得繁忙,并发送 busy 信号,主机应检查是否忙。
2.4 数据格式
2.4.1 数据块
块 (block) 就是硬盘中的扇区 (sector) 的概念。习惯上把任何硬盘 (机械硬盘、固态硬盘、SD卡等) 都分为多个 512B 的扇区,第0个扇区的地址为 0x0000, 第1个扇区的起始地址为 0x0200, ……
2.4.2 读写模式
SD 卡的读写数据 分为 Standard Bus (窄总线模式) 和 Wide Bus (宽总线模式) 两种模式:
- 窄总线模式:只使用 sddat0 线传输数据,传输的比特速率=时钟频率。SD卡上电时默认是窄总线模式。
- 宽总线模式:使用 sddat0~3 四根线传输数据,传输的比特速率=4×时钟频率。需要使用 ACMD6 命令 (SET_BUS_WIDTH) 开启或关闭。
SD 卡的读写都以 512B 的块 (block) 为单位。如图14分别是窄总线模式和宽总线模式下传输一块的位格式,对于两个方向 (读或写) 都适用。
2.5 CRC
2.5.1 CRC Token
host 发送完数据块 2 周期后,card 在 sddat0 上会反馈一个 CRC status 包,而 sddat1~3 这段时间内应该闲置)。
CRC status 包中包括 3-bit 的 CRC status,
- 若为
010
说明 card 检测到之前 sddat 上传输的 CRC 校验成功; - 若为
101
说明 card 检测到 CRC 校验失败。 - 若host非法操作(例如没有发送CMD24命令就直接在sdcmd上发送数据块),则card不会返回 CRC status 包,host 会读到
111
。
CRC status 发送完后,card 可能会立即发送一个 busy 包,busy 包持续把 sddat0 拉低,说明 card 正在把该块写入 (program) 到 flash 。当写入完成时,card 释放 sddat0 ,sddat0 恢复高电平(弱上拉) ,此时host 才能开始发送下一个命令。
5.1.2 CRC7 和 CRC16 的计算
2.6 命令
- "bc" : 广播命令,无需响应。广播是指如果SD总线上挂了多张 SD 卡,该命令会在所有卡上生效。本文只考虑 host 连接一张卡的情况。
- "bcr" : 广播命令,需要响应。
- "ac" : 非广播 (点对点) 命令,需要响应。只对选中的卡生效 (注: CMD7负责选中/解除选中一张卡) 。
- "adtc" : 非广播 (点对点) 命令,需要响应。另外还导致 sddat 上的数据传输。例如读命令 (CMD17) 。
3 Program Flow
3.1 卡初始化流程
(1)时钟
上电后,主机需要持续在 sdclk 上发送时钟,频率在范围 100kHz~400kHz 内 (卡初始化阶段要求的时钟频率) 。在图20的流程走完之前都不能提高到 25MHz
(2)发送CMD0复位
时钟稳定持续一段时间 (比如几毫秒) 后,host 发送 CMD0 命令,命令的 argument 字段取 0x00000000
(填充位) 。在这个过程中还需要保持 sddat3 信号为高电平,保证 SD 卡进入 SDIO 总线模式而不是 SPI 模式 (如果 sddat3 上有上拉电阻,则不需要特殊处理,否则需要 host 把 sddat3 强驱动到高电平) 。
(3)发送CMD8鉴别 SD1.X 和 SD2.0
host 发送 CMD8 命令并等待响应,命令的 argument 字段一般取 0x000001AA
,代表 VHS 字段=0x1 (2.7~3.6V) ,check pattern=0xAA 。如果 CMD8 超时没有响应 (超时的判断方法会在第9节讲) ,则要么提供的电压和 SD 卡要求的电压不匹配,要么是 SD 1.X 卡。如果有响应 (R7响应) ,则认为是 SD 2.0 卡。
(4) 发送ACMD41
发送 ACMD41 命令,命令的 argument 字段要取 0x40100000
,根据图15,其含义是 HCS=1 (代表主机支持大容量卡 SDHC) ,VDD Voltage Window (OCR[23:0]) = 0x100000
ACMD41 会返回 R3 类型的响应 (如图13) ,其中包含了 OCR 寄存器。对 OCR 寄存器的说明见第 4.3 节。host 需要检查 OCR[31] 是否位 1
。如果不为 1
,说明卡尚未上电,需要不断轮循发送 ACMD41 直到 OCR[31]=1
为止。当 OCR[31]=1
时,OCR[30] (CCS) 指示了卡是否为大容量卡。
结合之前 CMD8 的结果,可以区分出卡的三种类型:
- CMD8 无响应,ACMD41 响应的 OCR[30]=0 :SD 1.X 卡。
- CMD8 有响应,ACMD41 响应的 OCR[30]=0 :SD 2.0 非大容量卡。
- CMD8 有响应,ACMD41 响应的 OCR[30]=1 :SDHC 2.0 非大容量卡。
(5)发送 CMD2 : 获取CID寄存器
host 发送 CMD2 命令并等待响应,命令的 argument 字段取 0x00000000
(填充位) 。card 会返回 R2 类响应,其中包含了 CID 寄存器 (如图13) ,是该卡的识别号,host 可以忽略 CID 的内容。
(6)发送 CMD3 : 要求card指定一个RCA
host 发送 CMD3 命令并等待响应,命令的 argument 字段取 0x00000000
(填充位) 。card 会返回 R6 类响应,其中包含了卡指定的 RCA (16bit) ,这是卡自荐的地址,host 需要保存下来以便后续使用 CMD7 来选中此卡。
至此,SD卡初始化完成。进入 data transfer mode ,此时可以把时钟频率提高到最高 25MHz
3.2 数据传输流程
(1) 选中卡 (CMD7)
进入 data transfer mode 后的第一步一般是使用 card 指定的 RCA 来选中它。host 发送 CMD7 命令并等待响应,其中命令的 argument 字段的高 16bit 应该取 RCA ,而低 16bit 取 0x0000
(填充位) 。card 会响应 R1 。如图21,CMD7会让卡从 Standby State (未选中) 跳转到 Transfer State (选中) 。
(2) 设置 block length (CMD16)
选中卡后,host 发送 CMD16 命令并等待响应,其中命令的 argument 字段应该取 0x00000200
,代表 host 指定 block length=512B (0x200) ,也即一个硬盘扇区的大小。一般来说不能设定为其它值。
至此,SD卡读写前的所有准备工作完成。
(3)SD卡读写 (CMD17, CMD18, CMD24, CMD25)
SD卡的读写命令包括单块读 (CMD17), 多块读 (CMD18), 单块写 (CMD24), 多块写 (CMD25) 。它们的 argument 都是 32 位的要读/写的地址,分两种情况处理:
- 对于 SD 1.X 和 SD2.0 非大容量卡,argument 要填字节地址。例如,要读/写第0个扇区,argument 应该填充
0x00000000
;要读/写第1个扇区,argument 应该填充0x00000200
;要读/写第2个扇区,argument 应该填充0x00000400
…… - 对于 SDHC 2.0 大容量卡,argument 要填扇区地址。例如,要读/写第0个扇区,argument 应该填充
0x00000000
;要读/写第1个扇区,argument 应该填充0x00000001
;要读/写第2个扇区,argument 应该填充0x00000002
……
CMD17, CMD18, CMD24, CMD25 的响应都是 R1 ,其中会携带 CSR 寄存器。
CMD17, CMD18, CMD24, CMD25 还会导致 sddat 上的动作,其大致的时序见之前的图6(c)(d)(e)(f),而 sddat 上的位格式在之前 5.3 节讲过。下文第9节会细化其具体时序要求。
4 UHS
UHS(Ultra High Speed)是与SDXC同时推出的SD卡总线标准。此标准适用于SDHC和SDXC。
UHS-I最高传输速度(理论值)为104MB/s。英文字母I代表该设备(SD卡或读卡器)支持UHS-I接口。英文字母U,包含数目字1,代表该设备读写速度达U1。
UHS-II最高传输速度达312MB/s,是UHS-I的三倍。
设备(如智能手机)必须支持UHS,才能保证达到U1或U3最低写入速度。
下面介绍UHS-I初始化的命令序列流程。
参考
1、作者 | 博文 |
SD2.0协议详解:命令格式、初始化/读取/写入 | |
深入理解SD卡:协议 | |
SD卡通识篇 - 知乎 (zhihu.com) | |
09-sd卡的电压切换_sd卡cmd11 | |
嵌入式中SD卡接口电路设计_sd卡输出电流 | |
SD卡命令详解 |