嵌入式Linux知识:S3C2440上 MMC/SD卡驱动实例开发讲解

疯仔嵌入式 2011-02-24

嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。一为总结经验,二希望能 给想入门嵌入式Linux的朋友提供方便。如有错误之处,谢请指正。

一、开发环境

  • 主  机:VMWare--Fedora 9
  • 开发板:Mini2440--64MB Nand, Kernel:2.6.30.4
  • 编译器:arm-linux-gcc-4.3.2

二、MMC/SD介绍及SDI主机控制器

  首先我们来理清几个概念:
  1. MMC:(Multi Media Card)由西门子公司和首推CF的SanDisk于1997年推出的多媒体记忆卡标准。
  2. SD:(Secure Digital Memory Card)由日本松下、东芝及美国SanDisk公司于1999年8月共同开发研制的新一代记忆卡标准,已完全兼容MMC标准。
  3. SDIO:(Secure Digital Input and Output Card)安全数字输入输出卡。SDIO是在SD标 准上定义了一种外设接口,通过SDI/O接脚来连接外围设备,并且通过SD上的 I/O数据接位与这些外围设备进行数据传输。是目前较热门的技术,如下图中的一些设备:GPS、相机、Wi-Fi、调频广播、条形码读卡器、蓝牙等。
    嵌入式Linux知识:S3C2440上 MMC/SD卡驱动实例开发讲解

  4. 工作模式:工作模式是针对主机控制器来说的。也就是说,S3C2440中的SDI 控制器可以在符合MMC的标准下工作,或者可以在符合SD的标准下工作,或者可以在符合SDIO的标准下工作。故就分别简称为:MMC模式、SD模式和 SDIO模式。
  5. 传输模式:传输模式也是针对主机控制器来说的,指控制器与卡之间数据的传输模式, 或者说是总线类型。S3C2440中的SDI控制器可支持SPI、1位和4位的三种传输模式(总线类型)。那么什么又是SPI呢?请参考这里:SPI协议简介;至于1位和4位又是什么意思呢?他们是指传输数据总线的线宽,具体参考数据手册。

  下面使用表格列出了MMC、SD、SDIO的电气特性及性能和不同工作模式下支持的传输模式情况:
嵌入式Linux知识:S3C2440上 MMC/SD卡驱动实例开发讲解

  那么,我们现在怎样让主机控制器在我们所要求的工作模式和传输模式上工作呢?很简单,就是对主机控制器的各个寄存器进行相应的配置 即可。下面来简单介绍一下SDI主机控制器的结构和各寄存器的用途。

S3C2440内的SDI主机控制器结构图如下:
嵌入式Linux知识:S3C2440上 MMC/SD卡驱动实例开发讲解

  如上图所示,SDI主机控制器是使用1个串行时钟线与5条数据线同步进行信息移位和采样。传输频率通过设定SDIPRE寄存器的相应位的设定来 控制,可以修改频率来调节波特率数据寄存器的值。

各主要寄存器介绍,对于具体的寄存器位的设置就参考数据手册:

  1. SDICON:控制寄存器,完成SD卡基础配置,包括大小端,中断允许,模式选择,时钟使能 等。
  2. SDIPRE:波特率预定标器寄存器,对SDCLK的配置。
  3. SDICmdArg:指令参数寄存器,指令的参数存放在这里。
  4. SDICCON:控制指令形式的寄存器,配置SPI还是SDI指令,指令的反馈长 度,是否等待反馈,是否运行指令,指令的索引等。
  5. SDICmdSta:指令状态寄存器,指令是否超时,传送,结束,CRC是否正确 等。
  6. SDIRSP0-3:反映SD的状态。
  7. SDIDTimer:设置超时时间。
  8. SDIBSize:模块大小寄存器。
  9. SDIDatCon:数据控制寄存器,配置是几线传输,数据发送方向,数据传送方 式等。
  10. SDIDatSta:数据状态寄存器,数据是否发送完,CRC效验,超时等。
  11. SDIFSTA:FIFO状态寄存器,DMA传输是否判断FIFO。
  12. SDIIntMsk:中断屏蔽寄存器。
  13. SDIDAT:SDI数据寄存器。

SDI主机控制器在SD/MMC工作模式下的设置步骤:(注意:因为SD模式兼容MMC模式,所以我们只需了解SD模式的即可,而SDIO的工作模 式则是针对SDIO设备的,所以这里就不讨论了)

  1. 设置SDICON寄存器来配置适当的时钟及中断使能;
  2. 设置SDIPRE寄存器适当的值;
  3. 等待74个SDCLK时钟以初始化卡;
  4. 命令操作步骤:
    a. 写命令参数32位到SDICmdArg寄存器;
    b. 设置命令类型并通过设置SDICCON寄存器开始命令传输;
    c. 当SDICSTA寄存器的特殊标志被置位,确认命令操作完成;
    d. 如果命令类型相应,标志是RspFin,否则标志是CmdSend;
    e. 通过对相应位写1,清除SDICmdSta的标志。
  5. 数据操作步骤:
    a. 写数据超时时间到SDIDTimer寄存器;
    b. 写模块大小到SDIBSize寄存器(通常是0x80字节);
    c. 确定模块模式、总线线宽、DMA等且通过设置SDIDatCon寄存器开始数据传输;
    d. 发送数据->写数据到SDIDAT寄存器,当发送FIFO有效(TFDET置位),或一半(TFHalf置位),或空(TFEmpty置位);
    e. 接收数据->从数据寄存器SDIDAT读数据,当接收FIFO有效(RFDET置位),或满(RFFull置位),或一半(RFHalf置位),或 准备最后数据(RFLast置位);
    f. 当SDIDatSta寄存器的DatFin标志置位,确认数据操作完成;
    g. 通过对相应位写1,清除SDIDatSta的标志。

相关推荐

ganyouxianjava / 0评论 2012-05-31