SD卡
SD卡分类
根据存储容量
- Standard Capacity SD Memory Card(SDSC):容量 <= 2GB (231 byte)
- High Capacity SD Memory Card(SDHC):2GB< 容量 <= 32GB (235 byte)
- Extended Capacity SD Memory Card(SDXC):32GB< 容量 <= 2TB (241 byte)
- Ultra Capacity SD Memory Card(SDUC):2TB< 容量 <= 128TB (247 byte)
注:容量的单位 1MB = 1024x1024 B
根据性能
- Class 0:未指定速率
- Class 2:速率 >= 2MB/sec(默认速率模式)
- Class 4:速率 >= 4MB/sec(默认速率模式)
- Class 6:速率 >= 6MB/sec(默认速率模式)
- Class 10:速率 >= 10MB/sec(高速模式)
注:性能的单位 1MB/sec = 1000x1000 B/sec
SD卡协议
简介
SD卡的协议是一种简单的命令/响应的协议。全部命令由主机发起,SD卡接收到命令后并返回响应数据。根据命令的不同,返回的数据内容和长度也不同。SD卡命令是一个 6 字节组成的命令包,其中第一个字节为命令号, 命令号高位 bit7-6 为固定的 “01“,其它 6bit 为具体的命令号。第 2-5 字节为命令参数。第 6 个字节为 7bit 的 CRC 校验加 1bit 的结束位。如果在 SPI 模式的时候,CRC 校验位为可选。如下图所示,Command 表示命令,通常使用十进制表示名称,例如 CMD17,这个时候Command就是十进制的17。
SD卡对每个命令会返回一个响应,每个命令有一定的响应格式。响应的格式跟给它的命令号有关。
SPI 模式
命令
命令格式
命令类别
- 不同类别所支持的命令不同
- 通过 CMD27 更改 CSD 寄存器中的 CCC 参数,但该寄存器只有部分参数可写,其余都是只读
CMD
ACMD
响应
在 SPI 模式中,有 5 种响应格式:R1, R1b, R2, R3, R7,不同命令对应的响应格式也不一样,详细见上一章节“命令”。
R1
- 除了 bit0(in idle state),其余状态都是读清
R2
- 除了 bit0(Card is locked),其余状态都是读清
R3
R7
寄存器
SPI 模式除了不支持 RCA 寄存器,其余同 SD 模式一样
CSD
有三种不同寄存器定义,分别对应三种 SD 卡
总线
读操作
- SPI 模式支持单块读(CMD17)和多块读操作(CMD18)
- 对于标准容量卡,数据块的大小由 SET_BLOCKLEN 参数决定(CMD16)
- 对于 SDHC 和 SDXC 卡,数据块大小固定为 512B,起始地址必须与块边界对齐
- 每个数据块后面填充 16bit CRC 校验,使用标准 CCITT 多项式 X16 + X12 + X5 +1
- 最大块长度固定为 512B,无论 READ_BL_LEN 参数值(CSD 寄存器),除非 READ_BL_PARTIAL 为 1,块长度才可以设置为 1-512B 任意大小
- 每个块不能跨物理扇区
- 多块读每一块都填充 16bit CRC 校验,通过 CMD12 停止多块读操作
写操作
-
SPI 模式支持单块读(CMD24)和多块读操作(CMD25)
-
单块写时,每个数据块前需添加 “Start Block“;多块写只有第一块需要添加 ”Start Block“,但是最后一块需要添加 ”Stop Tran“
-
可通过 CMD13 查看写结果;通过 ACMD22 查看多块写时正确写入的块个数
-
当卡处于 busy 状态,置位 CS 信号不会中断写入进程,而且 busy 状态会忽略所有命令,除了 CMD0 可以复位卡,但是同时会破坏卡内数据(避免这样操作)
-
Data Response
- 写每个数据块时,卡都会给 Data Response,格式如下:
-
多块写操作时遇到 CRC 或者 Write Error时,主机要发送 CMD12 停止数据传输
-
当遇到 Write Error 时,可通过 CMD13 查看写错误原因,并可通过 ACMD22 查看多块写时正确写入的块个数
-
Start Block、Stop tran
-
对于单块写、单/多块读
- 第 1 byte:Start Block(8‘hFE)
- byte 2-513(具体取决于块大小):User data
- 最后 2 byte:16bit CRC
-
对于多块写
- 每个需要写入的数据块前面发送 1 Byte 的 Start Block(8’hFC)
- 停止写操作发送 1 Byte 的 Stop Tran(8‘hFD)
注:多块读通过发送 CMD12 停止读操作
-
-
Data Error
- 当读操作失败时,卡会响应 Data Error,格式如下:
擦除&写保护
初始化流程
- 上电后延时至少 74 个 clock,等待 SSD 卡内部操作完成
- SD 卡上电默认是 SD 模式,通过拉低 CS 信号,然后发送 CMD0 命令,试图进入 SPI 模式。若响应 R1 值为 0x01 时,则进入 SPI 模式,否则还是 SD 模式;(进入 SPI 模式后只有重新上电才能进入 SD 模式)
SD 模式
-
使用 SDIO 接口- 实现
-
参考如下链接:[SD2.0协议详解:命令格式、初始化/读取/写入 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/610495260#:~:text=SD2.0 Spec)
IP 设计
IP 例化界面
IP 接口
信号 | 方向 | 说明 |
---|---|---|
ref_clk | input | 模块参考时钟,100MHz |
ref_rst | input | 模块复位信号 |
spi_clk_o | output | SD 卡 SPI 模式时钟 |
spi_cs_n_o | output | SD 卡 SPI 模式片选信号 |
spi_miso_i | input | SD 卡 SPI 模式主端数据输入 |
spi_mosi_o | output | SD 卡 SPI 模式主端数据输出 |
o_sd_init_done | output | SD 卡初始化完成指示,高有效 |
o_status_flag[31:0] | output | 状态机状态,定义见下图 |
o_card_type[3:0] | output | SD 卡类型,定义见下图 |
i_sd_wr_en | input | 写使能,在 o_sd_wr_end 置位后更新状态。若只写一个 block,则在 o_sd_wr_end 拉低 i_sd_wr_en 信号 |
i_sd_wr_addr[31:0] | input | 写地址,对于 SDHC 和 SDXC 卡,数据块大小固定为 512B,起始地址必须与块边界对齐 |
i_sd_wr_data[7:0] | input | 写数据 |
o_sd_wr_data_req | output | 写数据请求,置位时下个时钟周期更新写数据 i_sd_wr_data |
o_sd_wr_end | output | 写完成指示,高有效 |
i_sd_rd_en | input | 读使能,在 o_sd_rd_end 或 o_sd_rd_err 置位后更新状态。若只读一个 block,则在 o_sd_rd_end 拉低 i_sd_rd_en信号 |
i_sd_rd_addr[31:0] | input | 读地址,对于 SDHC 和 SDXC 卡,数据块大小固定为 512B,起始地址必须与块边界对齐 |
o_sd_rd_data[7:0] | output | 读数据 |
o_sd_rd_data_vld | output | 读数据有效指示 |
o_sd_rd_err | output | 读操作错误 |
o_sd_rd_end | output | 读完成指示,高有效 |
IP 状态机
IP 验证
这里使用 闪迪HC-16G 和 雷龙 SD NAND (型号:CSNP32GCR01-BOW ) 进行单 block 读写测试。
注:SDHC 卡固定 block 大小为 512 bytes。
- 首先读取第二个 block 的数据,一开始为全 0
- 然后往第二个 block 写顺序数
- 写完成后再次读取第二个 block 数据,发现与写入数据一致
- 测试完成
雷龙贴片式TF卡
雷龙 SD NAND (型号:CSNP32GCR01-BOW ) 贴片式TF卡,,LGA-8封装,标准SDIO接口,兼容SPI/SD接口,可替代普通TF卡/SD卡,尺寸6x8mm毫米,内置SLC晶圆擦写寿命10万次,耐高低温,速度级别Class10(读取速度23.5MB/S写入速度12.3MB/S)。