基于ARM含SD控制器的SD卡的SDIO模式驱动解析.docx
- 文档编号:5765484
- 上传时间:2023-01-01
- 格式:DOCX
- 页数:9
- 大小:28.05KB
基于ARM含SD控制器的SD卡的SDIO模式驱动解析.docx
《基于ARM含SD控制器的SD卡的SDIO模式驱动解析.docx》由会员分享,可在线阅读,更多相关《基于ARM含SD控制器的SD卡的SDIO模式驱动解析.docx(9页珍藏版)》请在冰豆网上搜索。
基于ARM含SD控制器的SD卡的SDIO模式驱动解析
SD卡由日本松下、东芝及美国SanDisk公司于1999年8月共同开发研制。
SD卡的结构能保证数字文件传送的安全性,也很容易重新格式化,因此越来越多的被应用的嵌入式系统中。
SD卡的使用非常方便,常见的有两种工作模式:
SPI和SDIO。
SPI是串行的工作模式,速度相对较低,但是使用方便,只要MCU含有SPI接口均可使用。
SDIO模式,可以最多4线传输,因此速度比较快,由于SD卡的普及,越来越多的MCU内部集成了SDIO控制器,简化了我们的工作。
本文以三星s3c2410为例介绍。
1.SD卡的接口电路
2.SD卡的协议
SD卡的控制指令非常强大,支持SPI,SDIO模式,兼容MMC等。
而且不同的
指令有不同的响应(3种),这在我们使用指令是要注意的。
我在附件里面放了一个SD卡的中文协议,包括数据包介绍,指令索引介绍,反馈介绍等。
3.S3C2410SD卡控制器的介绍
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.1SD卡的初始化
步骤是:
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数据传输模式
代码如下:
intSD_card_init(void)
{
inti;
charkey;
rSDIPRE=PCLK/(2*INICLK)-1;//时钟400KHz
rSDICON=(1《《4)|(1《《1)|1;//TypeB,FIFOreset,clkenable
rSDIBSIZE=0x200;//512byte(128word)
rSDIDTIMER=0xffff;//Settimeoutcount
for(i=0;i《0x1000;i++);//Wait74SDCLKforMMCcard
CMD0();//进入idle
//--CheckSDcardOCR
if(Chk_SD_OCR())//发送AM41,判断电压正确否
;
else
{
;
return0;
}
RECMD2:
rSDICARG=0x0;
//CMD2(stuffbit),判断连接
rSDICCON=(0x1《《10)|(0x1《《9)|(0x1《《8)|0x42;
//lng_resp,wait_resp,start,CMD2
//--CheckendofCMD2
if(!
Chk_CMDend(2,1))//查询反馈是否正确
gotoRECMD2;
RECMD3:
//--SendRCA,得到SD卡的地址
rSDICARG=MMC《《16;
//CMD3(MMC:
SetRCA,SD:
AskRCA--》SBZ)
rSDICCON=(0x1《《9)|(0x1《《8)|0x43;
//sht_resp,wait_resp,start,CMD3
//--CheckendofCMD3
if(!
Chk_CMDend(3,1))
gotoRECMD3;
//--PublishRCA
RCA=(rSDIRSP0&0xffff0000)》》16;
//--State(stand-by)check
if(rSDIRSP0&0x1e00!
=0x600)
//CURRENT_STATEcheck验证反馈
gotoRECMD3;
rSDIPRE=PCLK/(2*NORCLK)-1;
//设置高速时钟Normalclock=“25MHz”
Card_sel_desel
(1);//SelectSD
Set_4bit_bus();//设置为4bit模式
}
voidSet_4bit_bus(void)
{
Wide=1;
SetBus();
}
voidSetBus(void)
{
SET_BUS:
CMD55();
//MakeACMD
//--CMD6implement
rSDICARG=Wide《《1;
//Wide0:
1bit,1:
4bit
rSDICCON=(0x1《《9)|(0x1《《8)|0x46;
//sht_resp,wait_resp,start,CMD55
if(!
Chk_CMDend(6,1))//ACMD6
gotoSET_BUS;
}
4.2SD卡的读与写
读写就是正反向的问题,这里只分析读
步骤:
1)读单blockCMD17多blockCMD18
(写单blockCMD24多blockCMD25)
2)发送CMD12,终止数据传输
程序如下:
采用DMA模式
voidRd_Block(void)
{
intstatus;
rd_cnt=0;
rSDICON|=rSDICON|(1《《1);//FIFOreset
rSDICARG=0x0;//CMD17/18(addr参数)
RERDCMD:
pISR_DMA0=(unsigned)DMA_end;//DMA的相关配置
rINTMSK=~(BIT_DMA0);
rDISRC0=(int)(SDIDAT);//SDIDAT
rDISRCC0=(1《《1)+(1《《0);//APB,fix
rDIDST0=(U32)(Rx_buffer);//Rx_buffer
rDIDSTC0=(0《《1)+(0《《0);//AHB,inc
rDCON0=(1《《31)+(0《《30)+(1《《29)+(0《《28)+(0《《27)+(2《《24)+(1《《23)+(1《《22)+(2《《20)+128*block;
//handshake,syncPCLK,TCint,singletx,singleservice,SDI,H/Wrequest,
//auto-reloadoff,word,128blk*num
rDMASKTRIG0=(0《《2)+(1《《1)+0;
//no-stop,DMA2channelon,no-swtrigger
rSDIDCON=(1《《19)|(1《《17)|(Wide《《16)|(1《《15)|(2《《12)|(block《《0);
//Rxafterrsp,blk,4bitbus,dmaenable,Rxstart,blknum
if(block《2)//SINGLE_READ
{
rSDICCON=(0x1《《9)|(0x1《《8)|0x51;
//sht_resp,wait_resp,dat,start,CMD17
if(!
Chk_CMDend(17,1))
//--CheckendofCMD17
gotoRERDCMD;
}
else//MULTI_READ
{
rSDICCON=(0x1《《9)|(0x1《《8)|0x52;
//sht_resp,wait_resp,dat,start,CMD18
if(!
Chk_CMDend(18,1))
//--CheckendofCMD18
gotoRERDCMD;
}
while(!
TR_end);
rINTMSK|=(BIT_DMA0);
TR_end=0;
rDMASKTRIG0=(1《《2);//DMA0stop
break;
default:
break;
}
//--CheckendofDATA
if(!
Chk_DATend())
;
rSDIDSTA=0x10;//CleardataTx/Rxend
if(block》1)
{
RERCMD12:
//--Stopcmd(CMD12)
rSDICARG=0x0;//CMD12(stuffbit)
rSDICCON=(0x1《《9)|(0x1《《8)|0x4c;
//sht_resp,wait_resp,start,CMD12
//--CheckendofCMD12
if(!
Chk_CMDend(12,1))
gotoRERCMD12;
}
}
4.3上面用到的响应判断函数
主要完成对反馈状态的分析。
函数如下:
intChk_CMDend(intcmd,intbe_resp)//指令反馈判断函数
{
intfinish0;
if(!
be_resp)//Noresponse
{
finish0=rSDICSTA;
while((finish0&0x800)!
=0x800)//验证指令是不是发送
finish0=rSDICSTA;
rSDICSTA=finish0;//Clearcmdendstate
return1;
}
else//Withresponse
{
finish0=rSDICSTA;
while(!
(((finish0&0x200)==0x200)|((finish0&0x400)==0x400)))
//验证反馈响应完成
finish0=rSDICSTA;
if(cmd==1|cmd==9|cmd==41)//CRCnocheck
{
if((finish0&0xf00)!
=0xa00)//CRC是否错误
{
rSDICSTA=finish0;//Clearerrorstate
if(((finish0&0x400)==0x400))//验证超时
return0;}
rSDICSTA=finish0;
//Clearcmd&rspendstate
}
else//CRCcheck
{
if((finish0&0x1f00)!
=0xa00)//Checkerror
{
;
rSDICSTA=finish0;//Clearerrorstate
if(((finish0&0x400)==0x400))
return0;//Timeouterror
}
rSDICSTA=finish0;
}
return1;
}
}
intChk_DATend(void)
{
intfinish;
finish=rSDIDSTA;
while(!
(((finish&0x10)==0x10)|((finish&0x20)==0x20)))
//Chektimeoutordataend
finish=rSDIDSTA;
if((finish&0xfc)!
=0x10)
{
rSDIDSTA=0xec;//Clearerrorstate
return0;
}
return1;
}
intChk_BUSYend(void)//数据反馈判断函数
{
intfinish;
finish=rSDIDSTA;
while(!
(((finish&0x08)==0x08)|((finish&0x20)==0x20)))
finish=rSDIDSTA;//等待数据发送完成或超时
if((finish&0xfc)!
=0x08)
{
rSD
IDSTA=0xf4;//clearerrorstate
return0;
}
return1;
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 ARM SD 控制器 SDIO 模式 驱动 解析