新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 基于ARM含SD控制器的SD卡的SDIO模式驅(qū)動(dòng)解析

基于ARM含SD控制器的SD卡的SDIO模式驅(qū)動(dòng)解析

作者: 時(shí)間:2016-11-11 來(lái)源:網(wǎng)絡(luò) 收藏
SD卡由日本松下、東芝及美國(guó)SanDisk公司于1999年8月共同開(kāi)發(fā)研制。

SD卡的結(jié)構(gòu)能保證數(shù)字文件傳送的安全性,也很容易重新格式化,因此越來(lái)越多的被應(yīng)用的嵌入式系統(tǒng)中。

本文引用地址:http://2s4d.com/article/201611/316808.htm

SD卡的使用非常方便,常見(jiàn)的有兩種工作模式:SPI和SDIO。SPI是串行的工作模式,速度相對(duì)較低,但是使用方便,只要MCU含有SPI接口均可使用。SDIO模式,可以最多4線傳輸,因此速度比較快,由于SD卡的普及,越來(lái)越多的MCU內(nèi)部集成了SDIO控制器,簡(jiǎn)化了我們的工作。本文以三星s3c2410為例介紹。

1.SD卡的接口電路

2.SD卡的協(xié)議

SD卡的控制指令非常強(qiáng)大,支持SPI,SDIO模式,兼容MMC等。而且不同的

指令有不同的響應(yīng)(3種),這在我們使用指令是要注意的。我在附件里面放了一個(gè)SD卡的中文協(xié)議,包括數(shù)據(jù)包介紹,指令索引介紹,反饋介紹等。

3.S3C2410 SD卡控制器的介紹

SD卡控制器幫我們完成了協(xié)議上的很多工作,我們只需要按照協(xié)議配置寄存器

以及按照協(xié)議流程對(duì)SD卡操作就可以完成SD卡的功能了。

SDICON:完成SD卡基礎(chǔ)配置,包括大小端,中斷允許,模式選擇,時(shí)鐘使能等。

SDIPRE:對(duì)SDCLK的配置。

SDICARG:指令的參數(shù)存放在這里

SDICCON:控制指令形式的寄存器,配置SPI還是SDI指令,指令的反饋長(zhǎng)度,是否等待反饋,是否運(yùn)行指令,指令的索引等

SDICSTA:指令狀態(tài)寄存器,指令是否超時(shí),傳送,結(jié)束,CRC是否正確等

SDIRSPO:反映SD的狀態(tài)

SDITIMER:設(shè)置超時(shí)時(shí)間

SDIBSIZE:block的大小

SDIDCON:數(shù)據(jù)控制寄存器,配置是幾線傳輸,數(shù)據(jù)發(fā)送方向,數(shù)據(jù)傳送方式等。

SDIDSTA:數(shù)據(jù)狀態(tài)寄存器,數(shù)據(jù)是否發(fā)送完,CRC效驗(yàn),超時(shí)等

SDIFSTA:FIFO狀態(tài)積存器,DMA傳輸時(shí)否判斷FIFO

SDIMSK:中斷屏蔽

4.SD卡SDIO模式的驅(qū)動(dòng)分析

4.1SD卡的初始化

步驟是:1)配置時(shí)鐘,慢速一般為400K,設(shè)置工作模式

2)發(fā)送CMD0,進(jìn)入空閑態(tài),該指令沒(méi)有反饋

3)發(fā)送CMD55+ACMD41,判斷SD卡的上電是否正確,短反饋

4)發(fā)送CMD2,驗(yàn)證SD卡是否接入,長(zhǎng)反饋

5)發(fā)送CMD3,讀取SD卡的RCA(地址),短反饋

6)發(fā)送CMD7,使能SD卡

7)配置高速時(shí)鐘,準(zhǔn)備數(shù)據(jù)傳輸,一般20M~25M

8)發(fā)送CMD55+ACMD6配置為4bit數(shù)據(jù)傳輸模式

代碼如下:

int SD_card_init(void)

{

int i;

char key;

rSDIPRE=PCLK/(2*INICLK)-1;//時(shí)鐘400KHz

rSDICON=(1<<4)|(1<<1)|1;// Type B, FIFO reset, clk enable

rSDIBSIZE=0x200;// 512byte(128word)

rSDIDTIMER=0xffff;// Set timeout count

for(i=0;i<0x1000;i++);// Wait 74SDCLK for MMC card

CMD0();//進(jìn)入idle

//--CheckSDcard OCR

if(Chk_SD_OCR())//發(fā)送AM41,判斷電壓正確否

;

else

{

;

return 0;

}

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:SetRCA,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驗(yàn)證反饋

goto RECMD3;

rSDIPRE=PCLK/(2*NORCLK)-1;

//設(shè)置高速時(shí)鐘Normal clock="25MHz"

Card_sel_desel(1);// Select SD

Set_4bit_bus();//設(shè)置為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))// ACMD6

goto SET_BUS;

}

4.2SD卡的讀與寫(xiě)

讀寫(xiě)就是正反向的問(wèn)題,這里只分析讀

步驟:1)讀單block CMD17多block CMD18

(寫(xiě)單block CMD24多block CMD25)

2)發(fā)送CMD12,終止數(shù)據(jù)傳輸

程序如下:采用DMA模式

void Rd_Block(void)

{

int status;

rd_cnt=0;

rSDICON |= rSDICON|(1<<1);// FIFO reset

rSDICARG=0x0;// CMD17/18(addr參數(shù))

RERDCMD:

pISR_DMA0=(unsigned)DMA_end;//DMA的相關(guān)配置

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, 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)// SINGLE_READ

{

rSDICCON=(0x1<<9)|(0x1<<8)|0x51;

// sht_resp, wait_resp, dat, start, CMD17

if(!Chk_CMDend(17, 1))

//-- Check end of CMD17

goto RERDCMD;

}

else// MULTI_READ

{

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);//DMA0 stop

break;

default:

break;

}

//-- Check end of DATA

if(!Chk_DATend())

;

rSDIDSTA=0x10;// Clear data Tx/Rx end

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;

}

}

4.3上面用到的響應(yīng)判斷函數(shù)

主要完成對(duì)反饋狀態(tài)的分析。

函數(shù)如下:

int Chk_CMDend(int cmd, int be_resp)//指令反饋判斷函數(shù)

{

int finish0;

if(!be_resp)// No response

{

finish0=rSDICSTA;

while((finish0&0x800)!=0x800)//驗(yàn)證指令是不是發(fā)送

finish0=rSDICSTA;

rSDICSTA=finish0;// Clear cmd end state

return 1;

}

else// With response

{

finish0=rSDICSTA;

while( !( ((finish0&0x200)==0x200) | ((finish0&0x400)==0x400) ))

//驗(yàn)證反饋?lái)憫?yīng)完成

finish0=rSDICSTA;

if(cmd==1 | cmd==9 | cmd==41)// CRC no check

{

if( (finish0&0xf00) != 0xa00 )// CRC是否錯(cuò)誤

{

rSDICSTA=finish0;// Clear error state

if(((finish0&0x400)==0x400))//驗(yàn)證超時(shí)

return 0;}

rSDICSTA=finish0;

// Clear cmd & rsp end state

}

else// CRC check

{

if( (finish0&0x1f00) != 0xa00 )// Check error

{

;

rSDICSTA=finish0;// Clear error state

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

return 0;// Timeout error

}

rSDICSTA=finish0;

}

return 1;

}

}

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;// Clear error state

return 0;

}

return 1;

}

int Chk_BUSYend(void)//數(shù)據(jù)反饋判斷函數(shù)

{

int finish;

finish=rSDIDSTA;

while( !( ((finish&0x08)==0x08) | ((finish&0x20)==0x20) ))

finish=rSDIDSTA;//等待數(shù)據(jù)發(fā)送完成或超時(shí)

if( (finish&0xfc) != 0x08 )

{

rSD

IDSTA=0xf4;//clear error state

return 0;

}

return 1;

}



關(guān)鍵詞: ARMSD控制器SDIO模

評(píng)論


技術(shù)專區(qū)

關(guān)閉