Fork me on GitHub
0%

SDIO

本次文档基于 SDIO Simplified Specification Version 3.00 进行学习记录

SDIO卡描述

分类

  • SDIO卡。可插拔设备,SPI模式在SDIO卡中是强制的,但并非所有功能在SPI模式下可用
  • 嵌入式SDIO。不可插拔设备,焊接在电路板上。SPI模式在嵌入式SDIO设备中是可选的。并非所有的功能都可以在SPI模式下可用。

类型

  • 全速SDIO卡。支持SPI、1bitSD和4位bitSD传输模式,数据传输速率超过100Mb/秒(10MB/秒)
  • 低速SDIO卡。支持SPI和1bitSD传输模式,4bit的支持可选,支持0-400 KHz的全时钟范围

如果一个卡是一个“组合卡”(内存加上SDIO),那么对卡的内存和SDIO部分都是全速和4位操作是必须的。

模式

  • SPI

  • 1-bit。data[0]、CLK、CMD

  • 4-bit。data[3:0]、CLK、CMD

CIA

image

CIA(Common I/O Area)通用IO区域,是所有SDIO卡都要支持的一个固定的公共端口区域。它包含三部分:CCCR (Card Common Control Registers), FBR (Function Basic Registers) 和 CIS (Card Information Structure) ,这三部分的功能决定的CIA的功能,主机端通过读写Func0对CIA区域寄存器进行相关操作。

CCCR

CCCR (Card Common Control Registers)卡通用控制寄存器(Page-43)。主机端通过CMD52命令Func0对CCCR寄存器组进行读写,完成对SDIO卡的信息检查和状态操作,CCCR 地址为 0x000000-0x0000FF 。以下是相关寄存器列表,具体说明可参考手册

image

  • 00H。分别定义了CCCR/FBR格式版本 和 该卡所遵循的SDIO spec版本
  • 01H。定义了SD格式版本号(物理层规范)
  • 02H - 03H。定义了所要使能的Func号和是否使能成功的标志位
  • 06H。如果需要软件复位SDIO需要写RES比特
  • 08H。定义了一些SDIO卡的功能范围,是否支持中断, 是否支持热插拔等
    • SDC:是否支持CMD52
    • SMB:是否支持CMD53
    • LSC:定义卡的速率类型(低速卡 / 高速卡)
    • 4BLS:如果是低速卡(LSC=1前提),是否支持4Bit传输
  • 09H - 0BH。通用CIS的指针,可以通过这个指针找到公共CIS区域

FBR

FBR (Function Basic Registers) 功能基本寄存器(Page-53)。 每个支持的I/O功能都有一个256字节的区域,用于允许主机快速确定每个功能的能力和要求,为每个功能启用电源选择,并启用软件加载。该区域的地址为从0x00n00h到0x00nFFh(其中 n 为功能端口号 1-7)。

image

  • n00H - n01H。每个功能支持的接口类型
  • n09H - n0BH。各端口功能的 CIS 指针,指向各功能端口的 CIS
  • n10H - n11H。设置每个Func I/O操作块的大小

(其中 n是功能端口号1-7)

CIS

CIS (Card Information Structure) ,卡信息结构(Page-72)。CIS 存储关于SDIO卡的信息和配置,地址为 0x001000-0x017FFF。需要注意的是CIS分成公共CIS和各自Func的CIS,公共的CIS地址存储在CCCR的09H - 0BH地址区域,每个func的CIS地址存储在FBR的n09H - n11H地址区域

CIS 中的信息是以 TUPLE 为单位的, TUPLE 的格式如下:tuple code + next tuple address + context

image

  • 00H。指示这个Tuple的功能
  • 01H。下一个Tuple的地址
  • 02H - (2+n)。Tuple的实际内容,软件结合tuple code和这个内容解析配置

Tuple Code

image

  • CISTPL_MANFID:制造商标识字符串元组
  • CISTPL_FUNCE:函数扩展元组。这个为CIS提供了FUNC类型的扩展识别码,可以进一步通过新的协议内容判断是针对哪一个func的信息,其中下一个识别码如果是0x00代表通用func的信息,0x01代表特定的func的信息(具体参照Page-75)

需要注意的在驱动代码中,当解析特定Func的CIS区域时,主要是将每个func的max block size(0EH - 0FH)和enable func timeout(1EH - 1FH)取出来,具体参考Page-76

CSA

为了支持SDIO卡的“即插即用”的概念,卡中包含的每个功能可能需要包含一块内存,用于存储驱动程序和/或应用程序。此外,由于相同的SDIO卡可以在多个不同的主机平台上使用,因此每个功能可能需要几个不同版本的代码。一种选择是将这些程序存储在组合卡的标准SD内存部分。另外,在可选的代码存储区(CSA)中还包含了一种加载代码的标准访问手段。CSA是一个单独的16MB内存区域,可以使用CSA地址指针和包含在FBR寄存器中的CSA窗口寄存器进行访问。请注意,每个函数可能都有自己的CSA来支持它。CSA数据可以是只读的或R/W的。CSA的实际存储方法不是本规范的一部分,而留给实现者

为了让主机访问一个函数的CSA,它首先要确定该函数是否支持一个CSA。主机读取地址为00n00h的FBR寄存器,其中n是函数号(1到7)。如果位6=1,则该函数支持CSA,并且主机通过写入位7=1来启用访问。下一步是让主机加载24位地址以开始读取或写。这是通过将24位(A23-0)写入寄存器00n0Ch到00n0Eh来实现的,其中n是函数数(1到7)。一旦写入了起始地址,就可以通过访问CSA数据窗口寄存器00n0Fh来读取或写入数据。如果需要读取或写入多个字节,则可以使用OP代码0(固定地址)执行扩展I/O命令(字节或块)。地址指针应随着对窗口寄存器的每次访问而自动增加,因此访问将是对CSA内的顺序地址。操作完成后,NEXT操作的地址应保存在24位地址寄存器中,以便主机读取。

命令

对于这些所有CMD有些位是固定的,具体到每一个不再具体阐述

  • S(start bit):开始位。始终为0

  • D(direction):方向。1表示从主机转移到卡。0指示从卡到主机的传输。

  • Command Index:命令索引。是哪一个CMD正好对应6bit二进制数

  • CRC7:7位CRC校验数据

  • E(end bit):结束位。总是1

CMD5(IO_SEND_OP_COND)

CMD5对SDIO卡的功能类似于ACMD41对SD存储卡的操作。它用于查询I/O板卡所需的电压范围。对CMD5的正常反应是SD或SPI格式的R4。

image

  • Stuff Bits:内容位。未使用,应设置为0。
  • S18R:切换到1.8V请求(Switch 1v8 Request)
  • I/O OCR:操作条件寄存器。为VDD提供受支持的最小值和最大值。(参考Page-23 Table3-1)

R4(IO_SEND_OP_COND Response)

image

  • C:如果卡初始化后准备操作,则设置为1
  • I/O function个数:表示此卡支持的I/O功能总数。该范围为0-7。其中功能0处所有I/O卡上的公共区域不包括在此计数中。输入/输出功能应从功能1开始按顺序实现。
  • 内存是否存在:如果包含SD内存,则设置为1。如果仅为I/O,则设置为0。
  • S18A:切换到1.8V已接受(仅支持SD模式)
  • I/O OCR:操作条件寄存器。为VDD提供受支持的最小值和最大值。

CMD52(IO_RW_DIRECT)

IO_RW_DIRECT是访问任何I/O函数中总共128K的寄存器空间中的单个寄存器的最简单的方法,包括公共I/O区域(CIA)。此命令仅使用1个命令/响应对来读取或写出1个字节。常用的是初始化I/O功能的寄存器或监视状态值。此命令是读取或写入单个I/O寄存器的最快方法,因为它只需要单个命令/响应对(Page-35)

image

  • R/W标志:此位确定I/O操作的方向。如果该位为0,则该命令将从SDIO卡的函数号和寄存器地址指定的地址读取数据到主机,数据字节在响应R5中返回;如果此位设置为1,则该命令应将写入数据字段中的字节写入由函数编号和寄存器地址寻址的I/O位置。如果RAW标志为0,则应读取被写入的寄存器中的数据,并在响应中返回该值。
  • RAW标志:写后的标志。如果该位设置为1,而R/W标志设置为1,则该命令应在写入后读取寄存器的值。这对于允许写入控制寄存器并在同一地址读取状态非常有用。如果清除此位,则R5响应中返回的值应与命令中的写入数据相同。如果设置该位,R5响应的数据字段
  • 功能编号:您希望读取或写出的I/O卡内的功能编号。函数0会选择公共I/O区域(CIA)。
  • 寄存器地址:这是要读取或写的选定函数内的数据字节的地址。有17位可用的地址,因此寄存器位于该函数的前128K(131072)地址内。
  • 写入数据/内容位:对于直接写入命令(R/W=1),这是写入所选地址的字节。对于直接读取(R/W=0),不使用此字段,且应设置为0。

R5(IO_RW_DIRECT Response)

image

  • stuff bits:未使用,应设置为0
  • 响应标志:8位标志数据表示SDIO卡的状态
  • 读取或写入数据:对于具有RAW标志集(RAW=1)的I/O写入(R/W=1),该字段应包含在命令中包含的数据写入后从寻址寄存器读取的值。注意,在这种情况下,读取数据可能与写入寄存器的数据不相同,这取决于硬件的设计。对于使用RAW位=0的I/O写,SDIO函数不得进行逐读操作,该字段中的数据应与写命令中的数据字节相同。对于I/O读取(R/W=0),此处将返回从I/O位置读取的实际值。

CMD53(IO_RW_EXTENDED)

此命令允许使用一个命令读取或写入大量I/O寄存器。由于这是一个数据传输命令,因此它提供了最高可能的传输速率(Page-38)

image

  • 收发标志:此位确定I/O操作的方向。如果此位为0,则该命令将从SDIO卡的函数号和注册地址指定的地址读取数据到主机。读取的数据应在DAT行上返回。如果此位设置为1,则该命令应将DAT[x]行中的字节写入由函数号和寄存器地址寻址的I/O位置。

  • 功能编号:您希望读取或写出的I/O卡内的功能编号。注意,函数00h选择公共I/O区域(CIA)。

  • 块模式(可选):此位如果设置为1,则表示读取或写操作应按块执行,而不是按普通字节执行。如果设置了此位,则字节/块计数值应包含要读/写的块数。函数1-7的块大小是通过将块大小写入FBR中的I/O块大小寄存器来设置的(请参见表6-3和表6-4)。函数0的块大小是通过写入CCCR中的FN0块大小寄存器来设置的。

  • 操作码:定义读/写操作。0代表固定地址读写,1代表自增地址读写

  • 寄存器地址:要读取或写的I/O注册器的起始地址。范围为[1 FFFF h:0]

  • 字节/块计数:要读或写的字节/块数

SDIO卡初始化序列

通过非I/O感知主机进行的初始化

当SDIO卡插入的时候,不能使主机发生故障。CMD5(IO_SEND_OP_COND)代替ACMD41

复位或上电后,卡上的所有I/O功能都被禁用,卡上的I/O部分不得执行除CMD5或CMD0以外的任何操作。如果卡上有SD内存(也称为组合卡),则该内存应对所有强制内存命令进行正常响应。

通过I/O感知主机进行初始化

  1. 初始化IO。I/O部分保持不活动状态直至接收到CMD5。主机发送CMD5,卡以R4响应。通过R4主机知道可用的I/O函数的数量,以及是否有内存

  2. 读取CIA(公共信息区)。这是通过发出I/O函数0的地址00h的字节开始的读命令来实现的。CIA包含卡公共控制寄存器(CCCR)和功能基本寄存器(FBR)。还包括指向卡的公共卡信息结构(CIS)和每个单独函数的CIS的指针。CIS包括有关电源、功能、制造商和主机需要确定I/O功能是否适合通电的其他信息。如果主机确定应该激活卡,则CCCR区域的寄存器将启用卡和每个单独的功能。此时,I/O板卡的所有功能都已全部可用。此外,主机还可以逐个功能地控制功耗和启用/禁用中断。如果存在的I/O访问不会干扰对卡的内存访问。

API

  • int sdio_enable_func / sdio_disable_func (struct sdio_func *func)

    使能/失能特定的Func。通过CMD52操作CCCR-02H,等CCCR-03H ready返回,否则超时;失能不需要等完成

  • int sdio_set_block_size(struct sdio_func *func, unsigned blksz)

    设置特定Func的block size。通过CMD52操作CCCR - 10H~11H

  • sdio_readb / sdio_writeb
    读取/写入特定的Func中的register address的1个byte的内容。CMD52实现

  • sdio_memcpy_fromio / sdio_memcpy_toio
    采用增量的方式从特定的Func,register address读取/写入内容CMD53实现

其它还有一些读写IO的相关函数,其中如果是对Func0进行操作一般都是通过CMD52实现,通用函数的多字节读写都是通过CMD53实现,在此不进行描述

参考资料

Github - SDIO
SDIO Simplified Specification Version 3.00