Sd_card ======== 概述 -------- SD 卡 (Secure Digital Memory Card) , 控制器对SD卡进行读写通信操作一般有两种通信接口可选, 一种是 SPI 接口,另外一种是 SDIO 接口. (现目前只支持 spi 接口) 按物理规格分类,常见的 SD 卡有三种: - **标准的 SD 卡**,这种卡比较大,比如在相机或者电脑等上会使用; - **mini SD**,这种卡应用场景少,不作详述; - **TF 卡**,也称 mirco SD ,这种卡比较小,比如在手机等上会使用. 按容量分类,可以分为标准容量卡、高容量卡,扩展容量卡: - **Standard Capacity SD Memory Card (SDSC):** 容量小于等于 2GB - **High Capacity SD Memory Card (SDHC):** 容量大于 2GB, 小于等于 32GB - **Extended Capacity SD Memory Card (SDXC):** 容量大于 32GB, 小于等于 2TB .. admonition:: 说明 SD 卡上面印有 "HC" 字样,代表该卡是 SDHC 卡,同理, 印着 "XC" ,表示 SDXC 卡. 按照读写性能划分,SD 卡有 5 种规格,每种规格后面的数字象征最小的读写速度: - **Class 0** - 这种卡没有性能要求 - **Class 2** - 要求在 Default Speed mode 下,性能至少要达到(大于等于) 2MB/sec - **Class 4** - 要求在 Default Speed mode 下,性能至少要达到 4MB/sec - **Class 6** - 要求在 Default Speed mode 下,性能至少要达到 6MB/sec - **Class 10** - 要求在 High Speed mode 下,性能至少要达到 10MB/sec .. admonition:: 说明 SD 卡上面印着一个用圆圈包围起来的数字, 比如10 表示该卡是 Class 10 类型的卡. 物理结构 -------- .. image:: ../../../_static/sd_card_Physical_structure.png :align: center .. centered:: SD 卡物理结构 SD 卡的引脚及连接 ------------------ SD 卡使用 9-pin 的接口,其中 1 根时钟线、1 根命令线和 4 根数据线、3 根电源线,具体说明如下: (其中 Micro SD 卡不包含 VSS2 信号,即 Micro SD 卡仅有 8 根线) +--------+--------+-----------------------------+--------------------------------------+ | 名字 | 描述 | SD 模式 | SPI 模式 | +========+========+=============================+======================================+ | CLK | 时钟线 | 机到卡时钟信号 | 该引脚与 SPI 总线的 SCK 时钟信号相连 | +--------+--------+-----------------------------+--------------------------------------+ | CMD | 命令线 | 此线双向传递命令/响应信号 | 该引脚与 SPI 总线的 MOSI 信号 | | | | | | | | | | 相连, SPI 主机通过它向 SD 卡发送 | | | | | | | | | | 命令及数据,但因为 SPI 总线的 MOSI | | | | | | | | | | 仅用于主机向从机输出信号,所以 SD | | | | | | | | | | 卡返回应答信息时不使用该信号线 | +--------+--------+-----------------------------+--------------------------------------+ | D0-3 | 数据线 | 均为数据线,传输读写数据, | D0 与 SPI 总线的 MISO 信号相连, | | | | | | | | | SD 卡可将 D0 拉低表示忙状态 | SD 卡通过该信号线向主机发送数据 | | | | | | | | | | 或响应,D3 与总线的 CS 信号相连 | | | | | | | | | | , SPI 主机通过该信号线选择要通 | | | | | | | | | | 讯的 SD 卡 | +--------+--------+-----------------------------+--------------------------------------+ | VSS1 | 电源线 | 电源线 | 电源线 | | | | | | | 、VSS2 | | | | +--------+--------+-----------------------------+--------------------------------------+ | VDD | 地线 | 地线 | 地线 | +--------+--------+-----------------------------+--------------------------------------+ SD 卡与主机的信号连接见下图, SDIO 总线与多张 SD 卡连接时,可以共用 CLK 信号线,其它的如 CMD、D0~D3 信号线是每张 SD 卡独立的. .. image:: ../../../_static/Connection_between_SD_card_and_SDIO_bus.png :align: center .. centered:: SD 卡与 SDIO 总线的连接 .. image:: ../../../_static/Connection_between_SD_card_and_SPI_bus.png :align: center .. centered:: SD 卡与 SPI 总线的连接 SD 卡的寄存器 -------------- 每个寄存器位的含义可以和默认值等参考 :: sd_card_regs.h SD 卡命令控制说明 ------------------ 控制时序 ^^^^^^^^^^^ 与 SD 卡的通信是基于命令和数据传输的.通讯由一个起始位("0"),由一个停止位("1")终止. SD 通信一般是主机发送一个命令 (Command), 从设备在接收到命令后作出响应(Response),如有需要会有数据(Data)传输参与. SD 数据是以块(Block)形式传输的, 高容量卡数据块长度一般为 512 字节,数据可以从主机到卡, 也可以是从卡到主机. 数据块需要 CRC 位来保证数据传输成功, CRC 位由 SD 卡系统硬件生成. 单个数据块的读写时序见下图. (图中的 DataIn 和 DataOut 线分别是 SPI 的 MISO 及 MOSI 信号.) .. image:: ../../../_static/SD_Single_block_read_operation.png :align: center .. centered:: SD 单块读操作 .. image:: ../../../_static/SD_Single_block_wrtie_operation.png :align: center .. centered:: SD 单块写操作 读写操作都是由主机发起的,主机发送不同的命令表示读或写, SD 卡接收到命令后先针对命令返回响应. 在读操作中, SD 卡返回一个数据块,数据块中包含CRC校验码; 在写操作中,主机接收到命令响应后需要先发送一个标志 (TOKEN) 然后紧跟一个要写入的数据块, 卡接收完数据块后回反回一 个数据响应及忙碌标志,当 SD 卡把接收到的数据写入到内部存储单元完成后,会停止发送忙碌标志,主机确认 SD 卡空闲后,可以 发送下一个命令. SD 数据传输支持单块和多块读写,它们分别对应不同的操作命令,结束多块读写时需要使用命令来停止操作. 命令格式 ^^^^^^^^^^^ SD 命令由主机发出,命令格式固定为 48bit,都是通过 CMD 线连续传输的(数据线不参与),见下图. +-----------+---------+----------------+-------------+--------+-----+-------+ | position | 47 | 46 | [45:40] | [38:8] |[7:1]| 0 | +===========+=========+================+=============+========+=====+=======+ | width | 1 | 1 | 6 | 32 | 7 | 1 | +-----------+---------+----------------+-------------+--------+-----+-------+ | value | '0' | '1' | X | X | X | '1' | +-----------+---------+----------------+-------------+--------+-----+-------+ |Description|start bit|transmission bit|command index|argument|CRC7 |end bit| +-----------+---------+----------------+-------------+--------+-----+-------+ .. centered:: SD 命令格式 SD 命令的组成如下: - 起始位和终止位:命令的主体包含在起始位与终止位之间,它们都只包含一个数据位,起始位为 0, 终止位为 1. - 传输标志:用于区分传输方向,该位为1时表示命令,方向为主机传输到 SD 卡,该位为 0 时表示响应,方向为 SD 卡传输到主机. - 命令主体内容包括命令、地址信息/参数和 CRC 校验三个部分. - 命令号:它固定占用 6bit, 所以总共有 64 个命令(代号:CMD0~CMD63),每个命令都有特定的用途, 部分命令不适用于 SPI 总线,或不适用于 SD 卡操作,只是专门用于 MMC 卡或者 SD I/O 卡. - 地址/参数:每个命令有 32bit 地址信息/参数用于命令附加内容,例如,广播命令没有地址信息,这 32bit 用于指定参数, 而寻址命令这 32bit 用于指定目标SD卡的地址,当使用 SDIO 驱动多张 SD 卡时,通过地址信息区分控制不同的卡,使用 SPI 总线驱动时, 通过片选引脚来选择不同的卡,所以使用这些命令时地址可填充任意值. - CRC7 校验:长度为 7bit 的校验位用于验证命令传输内容正确性,如果发生外部干扰导致传输数据个别位状态改变将导致校准失败, 也意味着命令传输失败, SD 卡不执行命令.使用 SDIO 驱动时,命令中必须包含正确的 CRC7 校验值;而使用 SPI 驱动时, 命令中的 CRC7 校验默认是关闭的,即这 CRC7 校验位中可以写入任意值而不影响通讯,仅在发送 CMD0 命令时需要强制带标准的 CRC7 校验. 响应 ^^^^^^^^^^^ 当 SD 卡接收到命令时,它会向主机发出相应的命令,不同的命令有不同的响应类型. SDIO 协议一共有7个响应类型(代号: R1~R7 ),其中 SD 卡没有 R4、R5 类型响应. 特定的命令对应有特定的响应类型,比如当主机发送 CMD9 命令时,可以得到响应 R2, 使用 SPI 驱动时,响应通过 MOSI 信号线传输 给主机. 以下图中表示的 R1 响应为例, SD 卡接收到大部分命令后它都是返回这个类型的响应,用于指示工作状态,它是一个长度为 1 字节 的响应, 最高位固定为 0, 当其余位为 1 时,说明处于该位表示的状态中,主机根据该响应获得 SD 卡的反馈,然后处理. R1 响应类型说明: ===== ==================== ============================================ bit 名称 说明 ===== ==================== ============================================ 0 in idle state 当该位为 1 时,表示 SD 卡处于空闲状态 1 erase reset 因为接收到无需擦除操作的命令,擦除操作被复位 2 illegal command 接收到一个无效的命令代码 3 com crc error 接收到的上一个命令的 CRC 校验错误 4 erase sequence error 擦除命令的控制顺序错误 5 address error 读写的数据地址不对齐(数据地址需要按块大小对齐) 6 parameter error 命令的参数错误 ===== ==================== ============================================ 关于其它的响应类型可以查看 SD 相关协议文档 Token ^^^^^^^^^^^ 使用 SPI 驱动 SD 卡时,需要使用一种名为 Token 的单字节标志对数据传输流程进行控制. 数据响应 Token '''''''''''''''' 主机向 SD 卡写入数据时,每发送完一个数据块后,SD 卡会返回一个数据响应 Token, 见前面的单块写操作, 它的格式如下图, 主机可以通过数据响应 Token 确认是否写入正常. .. wavedrom:: { reg:[ {bits: 1, name: "1", type:2}, {bits: 3, name: "status", type: 4}, {bits: 1, name: "0", type:3}, {bits: 1, name: "X"}, {bits: 1, name: "X"}, {bits: 1, name: "X"} ], config: { hspace: 280 }, foot: { text:'数据响应 Token 的格式' }, } 该 Token 格式中的 Status 长度为 3 个数据位: - 010: 数据被接受; - 101: 因为 CRC 校验失败,数据被拒绝; - 110: 因为写入错误,数据被拒绝. 数据块开始和停止的 Token ''''''''''''''''''''''''''' 以上是 SD 卡接收到数据时要作出的数据响应 Token, 实际上在数据块之前还带有 Token 标志,在前面的单块写操作也有体现, 在单块读写以及多块读取的命令中,数据块前面的 Token 标志均使用一个字节的 "0xFE" 表示数据块的开始, 而在多块数据写入命令中, Token 标志使用 "0xFC" 表示数据块的开始,并且以 "0xFD" 表示数据块的结束. SD 卡的初始化流程 ------------------- SPI 模式 ^^^^^^^^^^ .. image:: ../../../_static/sd_initialization_process_spi_mode.png :align: center .. centered:: sd 初始化流程 (spi 模式) 资源依赖 --------- - SPI - DMA - GPIO - IRQ 用法流程 --------- - 初始化 :cpp:func:`sd_card_init` - 读数据 :cpp:func:`sd_card_read_data` - 写数据 :cpp:func:`sd_card_write_data` - 注销 :cpp:func:`sd_card_deinit` 参考示例 --------- :: examples/sd_spi_demo 示例说明 ^^^^^^^^^^^ - 本示例使用 WQ 开发板和 SD card通过 spi 建立通信连接。 .. image:: ../../../_static/sd_spi_demo.png :align: center .. centered:: SD card spi Demo 流程图 API 介绍 ----------- .. doxygenfile:: sd_card.h