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.在这种情况下会产生数据超时的错误状态。按如下图所示以解决此问题:
(见原图)