当前位置:首页 >> 信息与通信 >>

SD卡驱动分析


SDIO 总线
SDIO 总线和 USB 总线类似, SDIO 总线也有两端, 其中一端是主机 (HOST) 端,另一端是设备端(DEVICE),采用 HOST- DEVICE 这样的设计是为了简化 DEVICE 的设计,所有的通信都是由 HOST 端发出命令开始的。在 DEVICE 端 只要能解溪 HOST 的命令,就可以同 HOST 进行通信了。 SDIO 的 HO

ST 可以连接多个 DEVICE,如下图所示:

这个是同 SD 的总线一样的,其中有如下的几种信号 1. 2. 3. 4. 5. CLK 信号:HOST 给 DEVICE 的时钟信号. CMD 信号:双向的信号,用于传送命令和反应。 DAT0-DAT3 信号:四条用于传送的数据线。 VDD 信号:电源信号。 VSS1,VSS2:电源地信号。

在 SDIO 总线定义中,DAT1 信号线复用为中断线。 SDIO 的 1BIT 模式下 DAT0 在 用来传输数据,DAT1 用作中断线。在 SDIO 的 4BIT 模式下 DAT0-DAT3 用来 传输数据,其中 DAT1 复用作中断线。

SDIO 命令: 命令:
SDIO 总线上都是 HOST 端发起请求,然后 DEVICE 端回应请求。其中请求 和回应中会数据信息。 1. Command:用于开始传输的命令,是由 HOST 端发往 DEVICE 端的。其中命

令是通过 CMD 信号线传送的。 2. Response:回应是 DEVICE 返回的 HOST 的命令,作为 Command 的回应。也

是通过 CMD 线传送的。 3. Data:数据是双向的传送的。可以设置为 1 线模式,也可以设置为 4 线模式。

数据是通过 DAT0-DAT3 信号线传输的。

SDIO 的每次操作都是由 HOST 在 CMD 线上发起一个 CMD,对于有的 CMD,DEVICE 需要返回 Response,有的则不需要。 对于读命令,首先 HOST 会向 DEVICE 发送命令,紧接着 DEVICE 会返回 一个握手信号,此时,当 HOST 收到回应的握手信号后,会将数据放在 4 位的 当整个读传送完毕后, HOST 数据线上, 在传送数据的同时会跟随着 CRC 校验码。 会再次发送一个命令,通知 DEVICE 操作完毕,DEVICE 同时会返回一个响应。 对于写命令,首先 HOST 会向 DEVICE 发送命令,紧接着 DEVICE 会返回 一个握手信号,此时,当 HOST 收到回应的握手信号后,会将数据放在 4 位的 数据线上, 在传送数据的同时会跟随着 CRC 校验码。 当整个写传送完毕后, HOST 会再次发送一个命令,通知 DEVICE 操作完毕,DEVICE 同时会返回一个响应。

1.

SD 卡的接口电路

2.

SD 卡的协议

SD 卡的控制指令非常强大,支持 SPI,SDIO 模式,兼容 MMC 等。而且不同的 指令有不同的响应(3 种),这在我们使用指令是要注意的。我在附件里面放了一个 SD 卡 我在附件里面放了一个 的中文协议,包括数据包介绍,指令索引介绍,反馈介绍等。 的中文协议,包括数据包介绍,指令索引介绍,反馈介绍等。

3.

S3C2410 SD 卡控制器的介绍

SD 卡控制器帮我们完成了协议上的很多工作,我们只需要按照协议配置寄存器 以及按照协议流程对 SD 卡操作就可以完成 SD 卡的功能了。 SDICON:完成 SD 卡基础配置,包括大小端,中断允许,模式选择,时钟使能等。 SDIPRE:对 SDCLK 的配置。 SDICARG:指令的参数存放在这里 SDICCON:控制指令形式的寄存器,配置 SPI 还是 SDI 指令,指令的反馈长度,是否等 待反馈,是否运行指令,指令的索引等 SDICSTA:指令状态寄存器,指令是否超时,传送,结束,CRC 是否正确等

SDIRSPO:反映 SD 的状态 SDITIMER:设置超时时间 SDIBSIZE:block 的大小 SDIDCON:数据控制寄存器,配置是几线传输,数据发送方向,数据传送方式等。 SDIDSTA: 数据状态寄存器,数据是否发送完,CRC 效验,超时等 SDIFSTA: FIFO 状态积存器,DMA 传输时否判断 FIFO SDIMSK:中断屏蔽

4.

SD 卡 SDIO 模式的驱动分析

4.1 SD 卡的初始化 步骤是:1)配置时钟,慢速一般为 400K,设置工作模式 2)发送 CMD0,进入空闲态,该指令没有反馈 3)发送 CMD55+ACMD41,判断 SD 卡的上电是否正确,短反馈 4)发送 CMD2,验证 SD 卡是否接入,长反馈 5)发送 CMD3,读取 SD 卡的 RCA(地址),短反馈 6)发送 CMD7,使能 SD 卡 7)配置高速时钟,准备数据传输,一般 20M~25M 8)发送 CMD55+ACMD6 配置为 4bit 数据传输模式

代码如下: int SD_card_init(void) { int i; char key; rSDIPRE=PCLK/(2*INICLK)-1; rSDICON=(1<<4)|(1<<1)|1; //时钟 400KHz // Type B, FIFO reset, clk enable

rSDIBSIZE=0x200; rSDIDTIMER=0xffff;

// 512byte(128word) // Set timeout count

for(i=0;i<0x1000;i++);

// Wait 74SDCLK for MMC card

CMD0();

//进入 idle //-- Check SD card OCR

if(Chk_SD_OCR()) ; else { ; return 0; }

//发送 AM41,判断电压正确否

RECMD2: rSDICARG=0x0; // CMD2(stuff bit),判断连接 rSDICCON=(0x1<<10)|(0x1<<9)|(0x1<<8)|0x42; //lng_resp, wait_resp, start, CMD2 //-- Check end of CMD2 if(!Chk_CMDend(2, 1)) //查询反馈是否正确

goto RECMD2;

RECMD3:

//--Send RCA,得到 SD 卡的地址 rSDICARG=MMC<<16; // CMD3(MMC:Set RCA, SD:Ask RCA-->SBZ) rSDICCON=(0x1<<9)|(0x1<<8)|0x43; // sht_resp, wait_resp, start, CMD3

//-- Check end of CMD3 if(!Chk_CMDend(3, 1)) goto RECMD3; //--Publish RCA

RCA=( rSDIRSP0 & 0xffff0000 )>>16;

//--State(stand-by) check if( rSDIRSP0 & 0x1e00!=0x600 ) // CURRENT_STATE check 验证反馈 goto RECMD3;

rSDIPRE=PCLK/(2*NORCLK)-1; // 设置高速时钟 Normal clock="25MHz" Card_sel_desel(1); Set_4bit_bus(); } // Select SD //设置为 4bit 模式

void Set_4bit_bus(void)

{ Wide=1; SetBus(); } void SetBus(void) { SET_BUS: CMD55(); // Make ACMD //-- CMD6 implement rSDICARG=Wide<<1; //Wide 0: 1bit, 1: 4bit rSDICCON=(0x1<<9)|(0x1<<8)|0x46; //sht_resp, wait_resp, start, CMD55 if(!Chk_CMDend(6, 1)) goto SET_BUS; // ACMD6

}

4.2SD 卡的读与写 读写就是正反向的问题,这里只分析读 步骤:1)读单 block CMD17 多 block CMD18 (写单 block CMD24 多 block CMD25) 2)发送 CMD12,终止数据传输

程序如下:采用 DMA 模式

void Rd_Block(void) { int status; rd_cnt=0; rSDICON |= rSDICON|(1<<1); rSDICARG=0x0; RERDCMD: pISR_DMA0=(unsigned)DMA_end; rINTMSK = ~(BIT_DMA0); rDISRC0=(int)(SDIDAT); rDISRCC0=(1<<1)+(1<<0); rDIDST0=(U32)(Rx_buffer); rDIDSTC0=(0<<1)+(0<<0); // SDIDAT // APB, fix // Rx_buffer // AHB, inc //DMA 的相关配置 // FIFO reset // CMD17/18(addr 参数)

rDCON0=(1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(2<<24) +(1<<23)+(1<<22)+(2<<20)+128*block; //handshake, sync PCLK, TC int, single tx, single service, SDI, H/W request, //auto-reload off, word, 128blk*num rDMASKTRIG0=(0<<2)+(1<<1)+0; //no-stop, DMA2 channel on, no-sw trigger

rSDIDCON=(1<<19)|(1<<17)|(Wide<<16)|(1<<15)|(2<<12)|(block <<0); // Rx after rsp, blk, 4bit bus, dma enable, Rx start, blk num if(block<2) { rSDICCON=(0x1<<9)|(0x1<<8)|0x51; // sht_resp, wait_resp, dat, start, CMD17 // SINGLE_READ

if(!Chk_CMDend(17, 1)) //-- Check end of CMD17 goto RERDCMD; } else { rSDICCON=(0x1<<9)|(0x1<<8)|0x52; // sht_resp, wait_resp, dat, start, CMD18 if(!Chk_CMDend(18, 1)) //-- Check end of CMD18 goto RERDCMD; } while(!TR_end); rINTMSK |= (BIT_DMA0); TR_end=0; rDMASKTRIG0=(1<<2); break; default: break; } //-- Check end of DATA if(!Chk_DATend()) ; rSDIDSTA=0x10; // Clear data Tx/Rx end //DMA0 stop // MULTI_READ

if(block>1)

{ RERCMD12: //--Stop cmd(CMD12) rSDICARG=0x0; //CMD12(stuff bit)

rSDICCON=(0x1<<9)|(0x1<<8)|0x4c; //sht_resp, wait_resp, start, CMD12 //-- Check end of CMD12 if(!Chk_CMDend(12, 1)) goto RERCMD12; } }

主要完成对反馈状态的分析。 函数如下:

int Chk_CMDend(int cmd, int be_resp) { int finish0; if(!be_resp) { finish0=rSDICSTA; while((finish0&0x800)!=0x800) finish0=rSDICSTA; rSDICSTA=finish0; return 1;

//指令反馈判断函数

// No response

// 验证指令是不是发送

// Clear cmd end state

} else { finish0=rSDICSTA; while( !( ((finish0&0x200)==0x200) | ((finish0&0x400)==0x400) )) // 验证反馈响应完成 finish0=rSDICSTA; // With response

if(cmd==1 | cmd==9 | cmd==41) { if( (finish0&0xf00) != 0xa00 ) { rSDICSTA=finish0;

// CRC no check

// CRC 是否错误

// Clear error state

if(((finish0&0x400)==0x400))

// 验证超时

return 0; rSDICSTA=finish0; // Clear cmd & rsp end state } else { if( (finish0&0x1f00) != 0xa00 ) { ; rSDICSTA=finish0;

}

// CRC check

// Check error

// Clear error state

if(((finish0&0x400)==0x400)) return 0; } rSDICSTA=finish0; } return 1; } } // Timeout error

int Chk_DATend(void) { int finish;

finish=rSDIDSTA; while( !( ((finish&0x10)==0x10) | ((finish&0x20)==0x20) )) // Chek timeout or data end finish=rSDIDSTA;

if( (finish&0xfc) != 0x10 ) {

rSDIDSTA=0xec; return 0; } return 1;

// Clear error state

}

int Chk_BUSYend(void) { int finish; finish=rSDIDSTA;

//数据反馈判断函数

while( !( ((finish&0x08)==0x08) | ((finish&0x20)==0x20) )) finish=rSDIDSTA; //等待数据发送完成或超时

if( (finish&0xfc) != 0x08 ) { rSD IDSTA=0xf4; return 0; } return 1; } //clear error state


相关文章:
SD卡驱动分析
113 SD 卡驱动分析 SD 卡驱动分三层结构分别对应 driver/mmc 目录下的 card、host、core 三个文件夹。其 层次关系如下所示: 内核空间 file_operations 调用 块...
SD卡驱动分析
SD 卡 SDIO 模式的驱动分析 4.1 SD 卡的初始化 步骤是:1)配置时钟,慢速一般为 400K,设置工作模式 2)发送 CMD0,进入空闲态,该指令没有反馈 3)发送 CMD55+...
linux sd卡驱动分析
linux sd 卡驱动分析 1. 硬件基础: SD/MMC/SDIO 概念区分概要 SD (Secure Digital )与 MMC (Multimedia Card ) SD 是一种 flash memory card 的标准,也就...
sd卡(驱动)工作原理分析完整版
其他函数通过调用这个函数完成对 sd 卡的操作,这里主要有 3 个函 数:sd 卡驱动程序初始化、读 sd 卡操作和写 sd 卡操作函数,下面分别对这些 函数具体分析: ...
linux sd卡驱动分析,基于mini2440,sdio mmc sd卡驱动编写
linux sd卡驱动分析,基于mini2440,sdio mmc sd卡驱动编写_信息与通信_工程科技_专业资料。linux sd卡驱动分析,基于mini2440,sdio mmc sd卡驱动编写1...
SD卡驱动一些知识点
struct mmc_host 用来描述卡控制器位 kernel/include/linux/mmc/host.h 下面。...SD密码卡驱动程序设计 19页 3下载券 linux sd卡驱动分析 34页 免费 ©...
linux sd卡驱动分析
linux sd卡驱动分析_IT/计算机_专业资料。linux sd卡驱动分析,基于mini2440,sdio mmc sd卡驱动编写的完整版,这个太贵了,下不起,就自己找了一个,比这个更全哈...
SD卡驱动
本来打算把 SD 卡驱动移植到俺的 4.2BSP 下的,但是发现太难了,还不如直接把...linux sd卡驱动分析 20页 1下载券 Micro_SD_卡与SD卡编程 22页 免费©...
驱动开发详解手札
关于djyos下sd卡驱动开发... 9页 免费 windows驱动开发详解的p... 36页 2下载...●Device drivers(设备驱动) 按照 char、 MTD、 ATA、 SCSI、 IIC、 SPI、 ...
更多相关标签:
linux sd卡驱动分析 | sd卡驱动 | win10 sd卡驱动 | sd卡驱动下载 | linux sd卡驱动 | sd卡驱动win7 | 联想笔记本sd卡槽驱动 | dell sd卡驱动 |