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

SD卡驱动分析


SDIO 总线
SDIO 总线和 USB 总线类似, SDIO 总线也有两端, 其中一端是主机 (HOST) 端,另一端是设备端(DEVICE),采用 HOST- DEVICE 这样的设计是为了简化 DEVICE 的设计,所有的通信都是由 HOST 端发出命令开始的。在 DEVICE 端 只要能解溪 HOST 的命令,就可以同 HOST 进行通信了。 SDIO 的 HOST 可以连接多个 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卡驱动分析
SD 卡 SDIO 模式的驱动分析 4.1 SD 卡的初始化 步骤是:1)配置时钟,慢速一般为 400K,设置工作模式 2)发送 CMD0,进入空闲态,该指令没有反馈 3)发送 CMD55+...
Linux SD卡驱动分析
Linux SD卡驱动分析_计算机软件及应用_IT/计算机_专业资料。Linux SD 卡驱动分析 摘要:随着计算机硬件的发展及数据量的增加,对存储设备的要求 也越来越高。 因此 ...
SD卡驱动分析
SD卡驱动分析 隐藏>> Linux 课程设计 项目名称: 院系: 专学姓业: 号: 名: 单片机 SD 卡 信息工程学院 10 电子信息工程 指导教师: : 1 SDIO 总线 SDIO ...
sd卡(驱动)工作原理分析完整版
SD卡工作原理介绍和工作原... 35页 2财富值如要投诉违规内容,请到百度文库投诉...sd卡(驱动)工作原理分析完整版sd卡(驱动)工作原理分析完整版隐藏>> sd 卡工作...
基于ARM含SD控制器的SD卡的SDIO模式驱动解析
SD 卡 SDIO 模式的驱动分析 4.1 SD 卡的初始化 步骤是:1)配置时钟,慢速一般为 400K,设置工作模式 2)发送 CMD0,进入空闲态,该指令没有反馈 3)发送 CMD55+...
linux sd卡驱动分析
linux sd卡驱动分析_IT/计算机_专业资料。linux sd卡驱动分析,基于mini2440,sdio mmc sd卡驱动编写的完整版,这个太贵了,下不起,就自己找了一个,比这个更全哈...
Linux内核MTD驱动程序与SD卡驱动程序
Linux内核MTD驱动程序与SD卡驱动程序_IT/计算机_专业资料。linux MTD 内核驱动程序解析,SD卡驱动程序分析 Linux 内核 MTD 驱动程序与 SD 卡驱动程序 flash 闪存...
SD卡详解
包括协议、安全算法、 数据存取、ECC 算法、缺陷处理和分析、电源管理、时钟管理...关于djyos下sd卡驱动开发... 9页 免费 sd 卡spi模式的控制方法... 13页 ...
SD卡驱动中各层中主要的类,结构体和接口函数
SD 卡驱动中各层中主要的类、 卡驱动中各层中主要的类、 结构体、 结构体、函数接口分析 1.1 Host Control Driver 主要功能: 主要功能: HCD 通知总线驱动卡...
单片机驱动SD卡
单片机驱动SD卡_电子/电路_工程科技_专业资料。大连科技学院 2013 届本科毕业生...实际应用中要求数据 采集器工作可靠,成本低廉,操作简单便于数据收集和分析;既要...
更多相关标签: