MMC/SD/SDIO/ 主控制器
概述
S3C2410A 的SD的主控制器能够支持MMC/SD卡和SDIO设备。
特性
——兼容SD Memory卡(1.0版)和MMC卡(2.11版)
——兼容SDIO卡(1.0版)
——16字数据传输接收FIFO(64 bytes)
——40bit 命令寄存器(SDICARG[31:0]+SDICCON[7:0])
——138bit 响应寄存器(SDIRSPn[127:0]+ SDICSTA[7:0]))
——8bit 预分频逻辑(Freq. = System Clock / (2(P + 1)))
——支持7位校验和16位校验发生器
——支持PIO、中断和DMA数据传输模式
——1bit/4bit模式及模块/流模式选择支持
——SD/SDIO支持25MHz数据传输
——MMC支持20MHz数据传输
模块图(见原图)
SD操作
一个串行时钟同步5根数据线(4根数据线,1根命令线)的信息传输和采样
一般操作步骤
通过下面的基本步骤,可以对SDI模块编程。
1. 对SDICON寄存器设置以配置时钟和中断。
2. 设置SDIPRE寄存器以配置适当的值。
3. 等待74个SDCLK 周期以使卡初始化。
发送命令操作的过程
1. 写命令参数到SDICARG寄存器。
2. 确定要传输的命令,通过置SDICCON[8]位开始命令传输。
3. 当SDICSTA的特殊标志位置位,确认SDI命令操作结束。
——如果是无返回类型的命令,那么SDICSTA[11]是结束标志。
——如果是有返回类型的命令,那么SDICSTA[9]是结束标志。
4.通过对相应位写1,可以清除SDICSTA寄存器的对应位。
传输数据操作的过程
1. 向SDIDTIMER寄存器中写入数据传输超时值。
2. 向SDIBSIZE寄存器中写入块大小值(一般为0x200 byte)。
3. 决定模块模式,宽总线,DMA等。对SDIDCON寄存器相应位进行设置开始数据传输。
4. 要发送数据,当Tx FIFO可用时将要发送的数据写到SDIDAT寄存器。检测SDIFSTA寄存器可得到当前状态(可用,一半,空)。
5. 要接收数据,当Rx FIFO可用时从SDIDAT寄存器读取数据。检测SDIFSTA寄存器可得到当前状态(可用,一半,最后数据)。
6. 数据传输完成标志位(SDIDSTA[4])置位确认数据传输结束。
7. 通过对相当位写1,清除SDIDatSta的标志位。
注意
在长响应命令时,如果由硬件处理CRC也许会错误,用户可以忽略。如果有需要可用软件进行检测。
SDIO操作
SDIO操作有两个功能:SDIO中断接收和产生读等待请求。当寄存器SDICON的RcvOInt位和RwaitEn位分别被激活,这两个功能可能操作。这两个功能的详细步骤和状态描述如下:
SDIO 中断
在SD 1位模式时,范围内所有的中断都通过SDDAT 1 引脚接收。
在SD4位模式时,SDDAT 1 引脚被接收数据和中断共用。中断侦测范围在:
1. 单块:A与B之间的时间
——A:一个数据包完成传输后2个时钟。
——B:下一条包含数据命令的最后比特发送结束。
2. 多模块,SDIDCON[21]=0:A与B之间,在C复位中断侦测范围。
——A:一个数据包完成传输后2个时钟。
——B:A后的2个时钟。
——C:中止命令的响应的最后位传输后2个时钟。
3. 多模块, SDIDCON[21]=1:A与B之间,在A处复位。
——A:一个数据包完成传输后2个时钟。
——B:A后的2个时钟。
在最后一个块的情况下,中断开始于A,但并不在B结束(CMD 53)。
读等待请求
无论是1-bit或4-bit模式,在下列情况下,读等待信号将会通过SDDAT2线传递。
——在多块读取时,上一数据块传输后的2个时钟内发出请求。
——当用户向SDIDSTA[10]位写1(清除该标志位)时,数据传输中止。
SDI 寄存器描述
SDI控制寄存器(SDICON)
寄存器名称 | 地址 | 读/写 | 描述 | 复位值 |
SDICON | 0x5A000000 | 读/写 | SDI控制寄存器 | 0x0 |
SDICON | Bit位 | 描述 | 初始值 |
字节顺序类型 (ByteOrder) | [4] | 决定在你从SD主控制器的FIFO中字边界读(写)数据时的字节顺序 0=A类,1=B类 | 0 |
是否接收SDIO中断(RcvlOInt) | [3] | 决定SD主 控制器是否接收从SDIO卡来的中断 0=忽略,1=接收 | 0 |
读等待使能 (RWaitEn) | [2] | 决定在多块读模式时,是否产生读等待信号。这个位的设置将延时下一个数据块的传输。(SDIO卡) 0=禁止,1=全能 | 0 |
FIFO复位 (FRST) | [1] | 复位FIFO值,该位自动清除 0=正常,1=FIFO复位 | 0 |
时钟类型 (CTYP) | [0] | 决定哪个时钟类型作为SDCLK 0=MMC类型,1=SD类型 | 0 |
注意:字节顺序类型
——类型A:D[7:0] ->D[15:8] ->D[23:16]-> D[31:24]
——类型B:D[31:24]-> D[23:16]-> D[15:8]-> D[7:0]
SDI波特率预分频寄存器(SDIPRE)
寄存器名称 | 地址 | 读/写 | 描述 | 复位值 |
SDIPRE | 0x5A000004 | 读/写 | SDI波特率寄存器 | 0x0 |
SDIPRE | Bit位 | 描述 | 初始值 |
预分频值 | [7:0] | 用以下的公式来决定SDI时钟频率 波特率=PCLK/2/(预分频值+1) | 0x00 |
SDI命令参数寄存器(SDICARG)
寄存器名称 | 地址 | 读/写 | 描述 | 复位值 |
SDICARG | 0x5A000008 | 读/写 | SDI命令参数寄存器 | 0x0 |
SDICARG | Bit位 | 描述 | 初始值 |
命令参数 | [31:0] | 命令参数 | 0x00000000 |
SDI命令控制寄存器(SDICCON)
寄存器名称 | 地址 | 读/写 | 描述 | 复位值 |
SDICCON | 0x5A00000C | 读/写 | SDI命令控制寄存器 | 0x0 |
SDICCON | Bit位 | 描述 | 初始值 |
中止命令 (AbortCmd) | [12] | 决定命令是否是中止命令(SDIO) 0=正常命令,1=中止命令(CMD12,CMD52) | 0 |
有数据命令 (WithData) | [11] | 决定是否是有数据的命令(SDIO) 0=没有数据,1=有数据 | 0 |
长响应 | [10] | 决定主设备是否接收一个136-bit的响应 0=没有响应,1=长响应 | 0 |
等待响应 | [9] | 决定主设备是否等待响应 0=不等待,1=等待响应 | 0 |
开始命令传输 (CMST) | [8] | 决定是否开始命令 0=命令准备,1=命令开始传输 | 0 |
命令索引 | [7:0] | 包含开始2开始位bit的命令索引 | 0x00 |
SDI命令状态寄存器(SDICSTA)
寄存器名称 | 地址 | 读/写 | 描述 | 复位值 |
SDICSTA | 0x5A000010 | 读/(写) | SDI命令状态寄存器 | 0x0 |
SDICSTA | Bit位 | 描述 | 初始值 |
响应CRC失败 (RspCrc) | [12]R/W | 当收到命令响应时,校验失败标志。对该位写1清除标志。 0=不检测,1=CRC失败 | 0 |
命令发送 (CmdSent) | [11]R/W | 命令已发送(不包括响应),对该位写1清除标志。 0=不检测,1=命令结束 | 0 |
命令超时 (CmdTout) | [10]R/W | 命令响应超时(64个clk),对该位写1清除标志。 0=不检测,1=超时 | 0 |
接收到响应 (RspFin) | [9]R/W | 接收到命令响应,对该位写1清除标志。 0=不检测,1=响应结束 | 0 |
CMD线正在传输 (CmdOn) | [8]R | 命令正在传输 0=不检测,1=正在传输 | 0 |
响应索引 | [7:0]R | 包含2开始位的响应索引 | 0x00 |
SDI响应寄存器0(SDIRSP0)
寄存器名称 | 地址 | 读/写 | 描述 | 复位值 |
SDIRSP0 | 0x5A000014 | 读 | SDI命令响应寄存器0 | 0x0 |
SDIRSP0 | Bit位 | 描述 | 初始值 |
响应0 | [31:0] | 短响应时是card status[31:0] 长响应时是card status[127:96] | 0x00000000 |
SDI响应寄存器1(SDIRSP1)
寄存器名称 | 地址 | 读/写 | 描述 | 复位值 |
SDIRSP1 | 0x5A000018 | 读 | SDI命令响应寄存器1 | 0x0 |
SDIRSP1 | Bit位 | 描述 | 初始值 |
响应校验 | [31:24] | 短响应时是响应的CRC7相应位(有结束位) 长响应时是card status[95:88] | 0x00 |
响应1 | [23:0] | 短响应是无用 长响应时是card status[87:64] | 0x000000 |
SDI响应寄存器2(SDIRSP2)
寄存器名称 | 地址 | 读/写 | 描述 | 复位值 |
SDIRSP2 | 0x5A00001C | 读 | SDI命令响应寄存器2 | 0xy0 |
SDIRSP2 | Bit位 | 描述 | 初始值 |
响应2 | [31:0] | 短响应时无用 长响应时是card status[63:32] | 0x00000000 |
SDI响应寄存器3(SDIRSP3)
寄存器名称 | 地址 | 读/写 | 描述 | 复位值 |
SDIRSP3 | 0x5A000020 | 读 | SDI命令响应寄存器3 | 0x0y |
SDIRSP3 | Bit位 | 描述 | 初始值 |
响应3 | [31:0] | 短响应时无用 长响应时是card status[31:0] | 0x00000000 |
SDI数据超时定时器寄存器(SDIDTIMER)
寄存器名称 | 地址 | 读/写 | 描述 | 复位值 |
SDITIMER | 0x5A000024 | 读/写 | SDI数据超时定时器寄存器 | 0x2000 |
SDITIMER | Bit位 | 描述 | 初始值 |
定时器值 | [15:0] | 数据超时时间(0~65535个周期) | 0x2000 |
SDI块大小寄存器(SDIBSIZE)
寄存器名称 | 地址 | 读/写 | 描述 | 复位值 |
SDIBSIZE | 0x5A000028 | 读/写 | SDI块大小寄存器 | 0x0 |
SDIBSIZE | Bit位 | 描述 | 初始值 |
块大小 | [11:0] | 块大小值(0~4095byte)。流模式时不考虑 | 0x000 |
注意:在多模块情况下,块大小必须以字为单位(4 byte)(块大小[1:0]=0)
SDI数据控制寄存器(SDIDCON)
寄存器名称 | 地址 | 读/写 | 描述 | 复位值 |
SDIDCON | 0x5A00002C | 读/写 | SDI数据控制寄存器 | 0x0 |
SDIDCON | Bit位 | 描述 | 初始值 |
SDIO中断时间类型 (PrdType) | [21] | 当最后一块数据传输时,决定SDIO中断是2个周期还是更多。 0=2个周期,1=更多周期 | 0 |
收到响应后传送 (TARSP) | [20] | 决定数据传送是否在接收到响应之后开始 0=数据模式设置后直接开始 1=接收到响应后(假设数据模式的两位设置为11) | 0 |
命令发出后接收 (RACMD) | [19] | 决定数据接收是否在命令发出后开始 0=数据模式设置后直接开始 1=命令发出后(假设数据模式的两位设置为10) | 0 |
命令发出后接收忙 (BACMD) | [18] | 决定命令发出后是否接收忙开始 0=数据模式设置后直接开始 1=命令发出后(假设数据模式的两位设置为01) | 0 |
块模式 (BlkMode) | [17] | 数据传输模式 0=流数据传输模式,1=块数据传输模式 | 0 |
宽总线使能 (WideBus) | [16] | 决定是否使能宽总线 0=标准总线(只有SDIDAT[0] 1根使用) 1=宽总线(SDIDAT[3:0] 4根使用) | 0 |
DMA使能 (EnDMA) | [15] | 使能DMA 0=禁用,1=使能DMA | 0 |
强制停止 (STOP) | [14] | 决定是否强制停止数据传输 0=正常,1=强制停止 | 0 |
数据传输模式 (DatMode) | [13:12] | 决定数据传输 00=准备好, 01=忙检测开始 10=数据接收开始,11=数据传输开始 | 00 |
块号 | [11:0] | 块号(0~4095),流模式时不考虑 | 0x000 |
注意:
1.如果你想要对SDIOCON[20:18]中的任一位置位,需要先写数据控制寄存器(SDIDCON)再写命令控制寄存器(SDICCON)。
2.当DMA操作完成后,DMA使能位[15]应该被禁用。
SDI数据保留寄存器(SDIDCON)
寄存器名称 | 地址 | 读/写 | 描述 | 复位值 |
SDIDCNT | 0x5A000030 | 读 | SDI数据保留寄存器 | 0x0 |
SDIDCNT | Bit位 | 描述 | 初始值 |
模块数 | [23:12] | 保留模块数 | 0x000 |
模块字节 | [11:0] | 1个模块的保留数据字节 | 0x000 |
SDI数据状态寄存器(SDIDSTA)
寄存器名称 | 地址 | 读/写 | 描述 | 复位值 |
SDIDSTA | 0x5A000034 | 读/写 | SDI数据状态寄存器 | 0x0 |
SDIDSTA | Bit位 | 描述 | 初始值 |
读等待请求产生 (RWaitReq) | [10] | 读等待请求信号传送到SD卡。对本位置1时请求信号被中止(同时数据传输中止)并会清除(清0)标志位。 (SDIO卡) 0=没有发生,1=读等待请求产生 | 0 |
SDIO 中断检测 (IOIntDet) | [9] | SDIO中断发生检测,对本位置1清除(清0)标志。 (SDIO卡) 0=没有发生,1=SDIO中断发生 | 0 |
FIFO错误 (FFfail) | [8] | 当FIFO溢出/不足/存储失调时此FIFO错误 发生,对本位置1清除(清0)标志。 0=没有发生,1=FIFO错误 | 0 |
CRC状态失败 (CrcSta) | [7] | 数据块发送后,当CRC校验错误时出现CRC 状态失败(由卡返回),对本位置1清除(清 0)标志。 0=没有发生,1=CRC状态失败 | 0 |
数据接收CRC失败 (DatCrc) | [6] | 数据接收后,当CRC校验错误时出现(由主机校验),对本位置1清除(清0)标志。 0=没有发生,1=数据接收CRC失败 | 0 |
数据超时 (DatTout) | [5] | 数据/忙接收超时,对本位置1清除(清0)标志。 0=没有发生,1=超时 | 0 |
数据传输完成 (DatFin) | [4] | 数据传输完成(数据计数器值为0)。对本位置1清除(清0)标志。 0=没有发生,1=数据传输完成 | 0 |
忙检测完成 (BusyFin) | [3] | 仅忙检测完成,对本位置1清除(清0)标志。 0=没有发生,1=检测完成 | 0 |
保留 | [2] |
| 0 |
数据正在发送 (TxDatOn) | [1] | 数据正在传送过程中 0=没有传送,1=正在发送数据 | 0 |
数据正在接收 (RxDatOn) | [0] | 数据正在接收过程中 0=没有传送,1=正在接收数据 | 0 |
SDI FIFO状态突破口(SDIFSTA)
寄存器名称 | 地址 | 读/写 | 描述 | 复位值 |
SDIFSTA | 0x5A000038 | 读 | SDI FIFO状态寄存器 | 0x0 |
SDIFSTA | Bit位 | 描述 | 初始值 |
FIFO发送可用检测 (TFDET) | [13] | 当数据模式是数据发送模式时,指明FIFO对发送数据是否可用。如果DMA模式已使能,SD主设备请求DMA操作。 0=不可用(FIFO full),1=可用(1 £ FIFO £ 64) | 0 |
FIFO接收可用检测 (RFDET) | [12] | 当数据模式是数据接收模式时,指明FIFO对接收数据是否可用。如果DMA模式已使能,SD主设备请求DMA操作。 0=不可用(FIFO empty), 1=可用(1 £ FIFO £ 64) | 0 |
发送FIFO半满 (TFHalf) | [11] | 只要发送FIFO少于33 字节则置位。 0 = 33 £ Tx(发送) FIFO £ 64, 1 = 0 £ Tx (发送) FIFO £ 32 | 0 |
发送FIFO空 (TFEmpty) | [10] | 只要发送FIFO空则置位 0 = 1 £ Tx(发送) FIFO £ 64, 1 = 空(0 字节) | 0 |
接收FIFO上最后数据好 (RFLast) | [9] | 当接收(Rx) FIFO中出现所有操作数据块的最后数据时该位置位。 0=没有收到,1=收到最后数据 | 0 |
接收FIFO满 (RFFull) | [8] | 当接收FIFO满时置位。 0 = 0 £ 接收(Rx) FIFO £ 63, 1 = 满 (64byte) | 0 |
接收FIFO半满 (RFHalf) | [7] | 当接收FIFO中有数据多余31字节时置位。 0 = 0 £ 接收(Rx) FIFO £ 31, 1 = 32£ 接收(Rx) FIFO £ 64 | 0 |
FIFO计算器 (FFCNT) | [6:0] | FIFO中的数据量(字节数) | 0000000 |
SDI数据寄存器(SDIDAT)
寄存器名称 | 地址 | 读/写 | 描述 | 复位值 |
SDIDAT | 0x5A00003C(Li/W, Li/B, Bi/W) 0x5A00003F(Bi/B) | 读/写 | SDI 数据寄存器 | 0x0 |
SDIDAT | Bit位 | 描述 | 初始值 |
数据寄存器 | [31:0] | 该区域包括通过SDI通道发送或接收的数据 | 0x00000000 |
注意:
1.(Li/W,Li/B):小端模式下通过字,字节访问。
2.(Bi/W):大端模式下通过字单元访问。
3.(Bi/B):大端模式下通过字节单元访问。
SDI中断屏蔽寄存器(SDIIMSK)
寄存器名称 | 地址 | 读/写 | 描述 | 复位值 |
SDIIMSK | 0x5A000040 | 读/写 | SDI 中断屏蔽寄存器 | 0x0 |
SDIIMSK | Bit位 | 描述 | 初始值 |
响应校验中断使能 | [17] | 响应校验错误中断 0=禁止,1=使能 | 0 |
命令发送中断使能 | [16] | 命令发送(无响应)中断 0=禁止,1=使能 | 0 |
命令超时中断使能 | [15] | 命令响应超时中断 0=禁止,1=使能 | 0 |
响应结束中断使能 | [14] | 命令响应接收到中断 0=禁止,1=使能 | 0 |
读等待请求中断使能 | [13] | 读等待请求中断 0=禁止,1=使能 | 0 |
SDIO中断中断使能 | [12] | SD主设备接收到SDIO中断,决定SDI产生中断(SDIO卡)。 0=禁止,1=使能 | 0 |
FIFO失败中断 | [11] | FIFO失败错误中断 0=禁止,1=使能 | 0 |
校验状态中断 | [10] | 校验状态错误中断 0=禁止,1=使能 | 0 |
数据校验中断 | [9] | 数据校验失败中断 0=禁止,1=使能 | 0 |
数据超时中断 | [8] | 数据超时中断 0=禁止,1=使能 | 0 |
数据完成中断 | [7] | 数据计数器值为0时产生中断 0=禁止,1=使能 | 0 |
忙完成中断 | [6] | 忙检测完成中断 0=禁止,1=使能 | 0 |
保留 | [5] |
| 0 |
发送FIFO半满中断 | [4] | 发送FIFO半满中断 0=禁止,1=使能 | 0 |
发送FIFO空中断 | [3] | 发送FIFO空中断 0=禁止,1=使能 | 0 |
接收最后数据中断 | [2] | 接收FIFO收到最后数据产生中断 0=禁止,1=使能 | 0 |
接收FIFO满中断 | [1] | 接收FIFO满中断 0=禁止,1=使能 | 0 |
接收FIFO半满中断 | [0] | 接收FIFO半满中断 0=禁止,1=使能 | 0 |
SDI数据/忙定时器寄存器
SDI数据/忙定时器寄存器有16bit的计数器。在25MHz的条件下,可计数的最大时间是2.6ms(40ns*0x10000)。但有些卡有需要很长的访问时间(TAAC),有时这个时间达到了100ms.在这种情况下会产生数据超时的错误状态。按如下图所示以解决此问题:
(见原图)