花了幾天寫了SD卡裸機驅(qū)動,現(xiàn)在還不完善,只支持4G以內(nèi)的卡,以后再加上;現(xiàn)在經(jīng)過修改可以寫入數(shù)據(jù)了,親測沒問題.
S3C6410_SDIO.C
#include?"s3c6410_system.h" #include?"s3c6410_sdio.h" /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //配置 //塊大小寄存器(0通道)BLKSIZE0 #define?BLKSIZE0_BLKSIZE 0x0200 //塊大小為512字節(jié) //傳輸模式寄存器(0通道)TRNMOD0 #define?TRNMOD0_CCSCON 0 //正常模式 #define?TRNMOD0_MUL1SIN0 (0?<<?5) //默認(rèn)為單區(qū)段操作模式 #define?TRNMOD0_RD1WT0 (1?<<?4) //默認(rèn)為讀操作模式 #define?TRNMOD0_ENACMD12 (0?<<?2) //自動CMD12禁止,多區(qū)段操作完成后主機自動發(fā)出停止命令 #define?TRNMOD0_ENBLKCNT (0?<<?1) //塊計數(shù)器無效 #define?TRNMOD0_ENDMA (0?<<?0) //DMA無效 //主機控制寄存器(0通道)HOSTCTL0 #define?HOSTCTL0_WIDE8 (0?<<?5) //這個為寬度被位1指定?(數(shù)據(jù)傳輸寬度) #define?HOSTCTL0_DMASEL (0?<<?3) //SDMA #define?HOSTCTL0_OUTEDGEINV (0?<<?2) //時鐘上升沿沿數(shù)據(jù)有效 //這個寄存器有歧義,不知道到底是干啥用的 #define?HOSTCTL0_WIDE4 (0?<<?4) //數(shù)據(jù)傳輸寬度。1BIT模式 //電源控制寄存器(0通道)PWRCON0 #define?PWRCON0_SELPWRLVL (7?<<?1) //3.3V電源模式 #define?PWRCON0_PWRON (1?<<?0) //電源打開 //容限寄存器(0?通道)CAPAREG0 #define?CAPAREG0_V18 (1?<<?26) //電壓支持1.8V #define?CAPAREG0_V30 (0?<<?25) //電壓不支持3v #define?CAPAREG0_V33 (1?<<?24) //電壓支持3.3V #define?CAPAREG0_SUSRES (1?<<?23) //支持暫停/恢復(fù)操作 #define?CAPAREG0_DMA (1?<<?22) //支持DMA #define?CAPAREG0_HSPD (1?<<?21) //支持高速模式 #define?CAPAREG0_ADMA2 (0?<<?19) //不支持DMA2 #define?CAPAREG0_MAXBLKLEN (0?<<?16) //最大塊大小為512B #define?CAPAREG0_BASECLK (25?<<?8) //SD基礎(chǔ)始終25MHz #define?CAPAREG0_TOUTUNIT (0?<<?7) //超時時鐘單位KHZ #define?CAPAREG0_TOUTCLK (10?<<?0) //超時時鐘頻率為10KHZ //最大電流容限寄存器(0?通道)MAXCURR0 #define?MAXCURR0_MAXCURR18 (10?<<?16) //對于1.8V,最大電流為40MA #define?MAXCURR0_MAXCURR30 (10?<<?8) //對于3.0V,最大電流為40MA #define?MAXCURR0_MAXCURR33 (10?<<?0) //對于3.3V,最大電流為40MA //控制寄存器2?CONTROL2_0 #define?CONTROL2_0_ENSTAASYNCCLR (0?<<?31) //該位可以使正常和錯誤中斷的異步明確啟用狀態(tài)位 #define?CONTROL2_0_ENCMDCNFMSK (0?<<?30) //不屏蔽指令沖突 #define?CONTROL2_0_CDINVRXD3 (0?<<?29) //卡檢測信號倒置對于RX_DAT[3]。禁止 #define?CONTROL2_0_SELCARDOUT (0?<<?28) //卡移除條件是“無卡插入”?狀態(tài)。 #define?CONTROL2_0_FLTCLKSEL (8?<<?24) //濾波器時鐘?(iFLTCLK)?選擇。 #define?CONTROL2_0_ENFBCLKTX (0?<<?15) //反饋時鐘禁止,對于發(fā)送數(shù)據(jù)時鐘 #define?CONTROL2_0_ENFBCLKRX (0?<<?14) //反饋時鐘禁止,對于接收數(shù)據(jù)時鐘 #define?CONTROL2_0_SDCDSEL (0?<<?13) //nSDCD?用于SD?卡檢測信號 #define?CONTROL2_0_SDSIGPC (0?<<?12) //同步控制輸出有效信號 #define?CONTROL2_0_ENBUSYCHKTXSTART?(0?<<?11) //發(fā)送數(shù)據(jù)啟動狀態(tài)前忙碌狀態(tài)檢測。 #define?CONTROL2_0_DFCNT (0?<<?9) //反跳濾波器計數(shù)16?iSDCLK #define?CONTROL2_0_ENCLKOUTHOLD (1?<<?8) //SDCLK?操作有效。 #define?CONTROL2_0_RWAITMODE (0?<<?7) //主機控制器釋放讀等待狀態(tài)(自動) #define?CONTROL2_0_DISBUFRD (0?<<?6) //正常模式,用0x20?寄存器使用者可以讀緩沖區(qū)(FIFO)數(shù)據(jù) //HCLK?=?128MHZ EPLL?=?24MHZ #define?CONTROL2_0_SELBASECLK (2?<<?4) //基礎(chǔ)時鐘源選擇。00?或01?=?HCLK,10?=?EPLL?輸出時鐘(來自系統(tǒng))11?=?外部時鐘源(XTI?或XEXTCLk) #define?CONTROL2_0_PWRSYNC (0?<<?3) //不同步,控制輸入有效信號(指令,數(shù)據(jù)) #define?CONTROL2_0_ENCLKOUTMSKCON (0?<<?1) //當(dāng)卡插入被清除時,SDCLK?輸出時鐘屏蔽。當(dāng)處于無卡狀態(tài)時,設(shè)置該區(qū)域為高位來停止SDCLK。 #define?CONTROL2_0_HWINITFIN (1?<<?0) //SD?主機控制器硬件初始化完成。 //時鐘控制寄存器(0?通道)CLKCON0 #define?CLKCON0_SELFREQ (0x80?<<?8) //SDCLK頻率最低 #define?CLKCON0_ENSDCLK (1?<<?2) //SD?時鐘啟動。 #define?CLKCON0_ENINTCLK (1?<<?0) //中斷時鐘啟動。 //超時控制寄存器(0?通道)TIMEOUTCON0 /******************************************************************************* *?Function?Name??:?SDIO_DeInit *?Description????:?Deinitializes?the?SDIO?peripheral?registers?to?their?default *??????????????????reset?values. *?Input??????????:?None *?Output?????????:?None *?Return?????????:?None *******************************************************************************/ void?SDIO_DeInit(void) { //初始化硬件IO rGPGCON?=?0x2222222; //初始化IO為SDIO模式 rGPGPUD?=?0; //禁止上下拉 //時鐘控制寄存器配置 SDIO0->CLKCON?=?CLKCON0_SELFREQ?+?CLKCON0_ENSDCLK?+?CLKCON0_ENINTCLK; //主機控制寄存器配置 SDIO0->HOSTCTL?=?HOSTCTL0_WIDE8?+?HOSTCTL0_DMASEL?+?HOSTCTL0_OUTEDGEINV?+?HOSTCTL0_WIDE4; //容限寄存器配置 SDIO0->CAPAREG?=?CAPAREG0_V18?+?CAPAREG0_V30?+?CAPAREG0_V33?+?CAPAREG0_SUSRES?+?CAPAREG0_DMA?+?CAPAREG0_HSPD?+?CAPAREG0_ADMA2?+ CAPAREG0_MAXBLKLEN?+?CAPAREG0_BASECLK?+?CAPAREG0_TOUTUNIT?+?CAPAREG0_TOUTCLK; //控制寄存器2配置 SDIO0->CONTROL2?=?CONTROL2_0_ENSTAASYNCCLR?+?CONTROL2_0_ENCMDCNFMSK?+?CONTROL2_0_CDINVRXD3?+?CONTROL2_0_SELCARDOUT?+?CONTROL2_0_FLTCLKSEL?+? CONTROL2_0_ENFBCLKTX?+?CONTROL2_0_ENFBCLKRX?+?CONTROL2_0_SDCDSEL?+?CONTROL2_0_SDSIGPC?+?CONTROL2_0_ENBUSYCHKTXSTART?+? ? CONTROL2_0_DFCNT?+?CONTROL2_0_ENCLKOUTHOLD?+?CONTROL2_0_RWAITMODE?+?CONTROL2_0_DISBUFRD?+?CONTROL2_0_SELBASECLK?+? CONTROL2_0_PWRSYNC?+?CONTROL2_0_ENCLKOUTMSKCON?+?CONTROL2_0_HWINITFIN; //傳輸模式寄存器配置 SDIO0->TRNMOD?=?TRNMOD0_CCSCON?+?TRNMOD0_MUL1SIN0?+?TRNMOD0_RD1WT0?+?TRNMOD0_ENACMD12?+?TRNMOD0_ENBLKCNT?+?TRNMOD0_ENDMA; //超時控制寄存器(0?通道) SDIO0->TIMEOUTCON =?0x0e; //超時設(shè)置最大 //電源控制寄存器配置 SDIO0->PWRCON?=?PWRCON0_SELPWRLVL?+?PWRCON0_PWRON; //塊間隔寄存器 SDIO0->BLKGAP?=?0; //開啟卡插入+卡移除+傳輸完成+指令完成中斷狀態(tài)+數(shù)據(jù)超時錯誤+命令索引錯誤+指令最后位錯誤+指令超時錯誤+指令CRC?+?緩沖區(qū)讀就緒?+?寫緩沖區(qū)就緒 SDIO_FlagConfig(SDIO_FLAG_CARDREMOVAL?|?SDIO_FLAG_CARDINSERTION?|?SDIO_FLAG_TRANSFER?|?SDIO_FLAG_COMMANDEND?|?SDIO_FLAG_DATACRC?| SDIO_FLAG_DATATIMEOUT?|?SDIO_FLAG_COMMANDINDEX?|?SDIO_FLAG_COMMANDCRC?|?SDIO_FLAG_COMMANDTIMEOUT?|?SDIO_FLAG_BUFFREAD?|?SDIO_FLAG_BUFFWRITE,Enable); //使能卡插入拔出中斷 SDIO_FlagITConfig(SDIO_FLAG_CARDREMOVAL?|?SDIO_FLAG_CARDINSERTION,Enable); SDIO_ClearFlag(SDIO_FLAG_ALL); //清除所有中斷標(biāo)志 } void?SDIO_FlagITConfig(u32?SDIO_FLAG,?u8?EN) { if(EN) //中斷使能 SDIO0->INTSEGEN?|=?SDIO_FLAG; else SDIO0->INTSEGEN?&=?~SDIO_FLAG; } void?SDIO_FlagConfig(u32?SDIO_FLAG,?u8?EN) { if(EN) //狀態(tài)使能 SDIO0->INTSTSEN?|=?SDIO_FLAG; else SDIO0->INTSTSEN?&=?~SDIO_FLAG; } /************************************************************************************************************************* *函數(shù)????????: void?SD_SendCommand(vu8?CmdIdx,vu32?CmdArg,vu8?CmdTyp,vu8?Misc) *功能????????: 向SD卡發(fā)送一個命令 *參數(shù)????????: CmdIdx:指令索引;CmdArg:命令參數(shù);CmdMisc:其它雜項設(shè)置,詳見說明 *返回????????: 無 *依賴????????:? 底層宏定義 *作者????????: 陳鵬 *時間????????: 20120507 *最后修改時間: 20120507 *說明????????: 寫SD命令寄存器; 指令索引:這些位設(shè)置為SD存儲卡物理層規(guī)范中指令格式的第40到45位和SDIO卡規(guī)范中指定的指令數(shù)(CMD0-63,?ACMD0-63)。 雜項: SDIO_Type_Default 一般為0 SDIO_Type_Pend??????寫總線暫停 SDIO_Type_FS 功能選擇 SDIO_Type_IT 中斷模式 SDIO_CMDIndexEn?????SDIO指令索引使能 SDIO_CMDCrcEn???????SDIO指令CRC校驗使能 SDIO_Response_No???????????無應(yīng)答 SDIO_Response_Short????????短應(yīng)答 48 SDIO_Response_Long????????長應(yīng)答 136 SDIO_Response_ShortBusy????短應(yīng)答+檢測繁忙情況 *************************************************************************************************************************/ void?SDIO_SendCommand(vu8?CmdIdx,vu32?CmdArg,vu8?CmdMisc) {u16?temreg?=?0;SDIO_ClearFlag(SDIO_FLAG_ALL);//清除所有狀態(tài)寄存temreg?=?CmdIdx;temreg?<<=?8;temreg?|=?CmdMisc;SDIO0->ARGUMENT?=?CmdArg;//先寫入命令參數(shù)SDIO0->CMDREG?=?temreg;//再寫入命令索引以及類型等參數(shù)while(!(SDIO0->PRNSTS?&?BIT0));//等待命令線空忙,也就是開始執(zhí)行命令while(SDIO0->PRNSTS?&?BIT0);//等待命令線空閑,也就是命令執(zhí)行完畢 } /************************************************************************************************************************* *函數(shù)????????: u32?SD_GetResponse(u8?SDIO_RESP) *功能????????: 獲取SD卡的應(yīng)答 *參數(shù)????????: Rep:應(yīng)答數(shù)據(jù)存放的位置 SDIO_RESP1:?Response?Register?1 *???????????????SDIO_RESP2:?Response?Register?2 *???????????????SDIO_RESP3:?Response?Register?3 *???????????????SDIO_RESP4:?Response?Register?4?? *返回????????: 返回應(yīng)答 *依賴????????:? 底層宏定義 *作者????????: 陳鵬 *時間????????: 20120507 *最后修改時間: 20120507 *說明????????: 存放應(yīng)答數(shù)據(jù)的緩沖區(qū)為128BIT;4個32bit; 指令應(yīng)答。下表27-4為每一個應(yīng)答描述了從SD總線到寄存器的指令映射。在這個表中,在表中?R[]指出在SD總線上傳輸?shù)膽?yīng)答數(shù)據(jù)的范圍, REP[]指出應(yīng)答寄存器中位的范圍。128位應(yīng)答位的順序:?{RSPREG3,?RSPREG2,?RSPREG1,?RSPREG0} *************************************************************************************************************************/ u32?SDIO_GetResponse(u8?SDIO_RESP) { return?(SDIO0->RSPREG[SDIO_RESP]); } u32?SDIO_ReadData(void) {? ?? return?SDIO0->BDATA; //從緩沖區(qū)讀數(shù)據(jù) } void?SDIO_WriteData(u32?Data) {? SDIO0->BDATA?=?Data; } u8?SDIO_GetFlagStatus(u32?SDIO_FLAG) {? return?((SDIO_STATUS?&?SDIO_FLAG)???1?:?0); } void?SDIO_ClearFlag(u32?SDIO_FLAG) {? SDIO_STATUS?|=?SDIO_FLAG; } /************************************************************************************************************************* *?函數(shù) : void?SDIO_SetFIFOInterruptAddress(u8?FIFOxAdd,u8?WordAdd) *?功能 : 設(shè)置FIFO中斷觸發(fā)位置 *?參數(shù) : FIFOxAdd:FIFO地址選擇 WordAdd:觸發(fā)位置選擇,單位為字,共512B,也就是1-128字 *?返回 : SD_OK:成功,其它見SD?Card?Error?code. *?依賴 : 底層寄存器操作函數(shù) *?作者 : 陳鵬 *?時間 : 20120516 *?最后修改時間?:?20120516 *?說明 :? 無 *************************************************************************************************************************/ void?SDIO_SetFIFOInterruptAddress(u8?FIFOxAdd,u8?WordAdd) { if(WordAdd?>?128) WordAdd?=?128; switch?(FIFOxAdd) { case?FIFO_A0: { SDIO0->CONTROL3?&=?~(0x1f); SDIO0->CONTROL3?|=?WordAdd; }break; case?FIFO_A1: { SDIO0->CONTROL3?&=?~(0x1f?<<?8); SDIO0->CONTROL3?|=?WordAdd?<<?8; }break; case?FIFO_A2: { SDIO0->CONTROL3?&=?~(0x1f?<<?16); SDIO0->CONTROL3?|=?WordAdd?<<?16; }break; case?FIFO_A3: { SDIO0->CONTROL3?&=?~(0x1f?<<?24); SDIO0->CONTROL3?|=?WordAdd?<<?24; }break; default?:?break; } } /************************************************************************************************************************* *?函數(shù) : void?SDIO_CLKFrequencySelect(u8?SDCLK) *?功能 : 設(shè)置SDIO時鐘分頻系數(shù) *?參數(shù) : SDCLK:設(shè)置SDIO時鐘分頻系數(shù) *?返回 : SD_OK:成功,其它見SD?Card?Error?code. *?依賴 : 底層寄存器操作函數(shù) *?作者 : 陳鵬 *?時間 : 20120516 *?最后修改時間?:?20120516 *?說明 :? 高速基礎(chǔ)時鐘為50MHz 低速基礎(chǔ)時鐘為25MHz *************************************************************************************************************************/ void?SDIO_CLKFrequencySelect(u8?SDCLK) { SDIO_SDClkDisable(); //時鐘停止 SDIO0->CAPAREG?&=?~(0x3f?<<?8); //清除設(shè)置 SDIO0->CAPAREG?|=?(50?<<?8); //這一位設(shè)置其實沒作用 SDIO0->CLKCON?&=?~(0xff?<<?8); //清除 SDIO0->CLKCON?|=?(SDCLK?<<?8); //設(shè)置基礎(chǔ)時鐘分頻系數(shù) SDIO_SDClkEnable(); //時鐘使能 while(!(SDIO0->CLKCON?&?BIT0)); //等待時鐘穩(wěn)定 } /************************************************************************************************************************* *?函數(shù) : void?SDIO_SoftwareReset(u32?SDIO_RST) *?功能 : 設(shè)置SDIO軟件復(fù)位 *?參數(shù) : SDIO_RST: SDIO_RSTDAT //復(fù)位DAT線 SDIO_RSTCMD //復(fù)位CMD線 SDIO_RSTALL //復(fù)位所有 *?返回 : SD_OK:成功,其它見SD?Card?Error?code. *?依賴 : 底層寄存器操作函數(shù) *?作者 : 陳鵬 *?時間 : 20120516 *?最后修改時間?:?20120516 *?說明 :? 無 *************************************************************************************************************************/ void?SDIO_SoftwareReset(u32?SDIO_RST) { SDIO0->SWRST?|=?SDIO_RST; //復(fù)位 while(SDIO0->SWRST?&?SDIO_RST); //等待復(fù)位完成 } /************************************************************************************************************************* *函數(shù)????????: void?SDIO_SetTimeOutClock(u8?Unit,u8?Frequency) *功能????????: 超時時鐘設(shè)置 *參數(shù)????????: Unit:超時時鐘單位選擇 TIME_OUT_UNIT_KHZ(0):超時時鐘單位為KHZ TIME_OUT_UNIT_MHZ(1):超時時鐘單位為MHZ Frequency:時鐘頻率:1~63 *返回????????: 返回應(yīng)答 *依賴????????:? 底層宏定義 *作者????????: 陳鵬 *時間????????: 20120521 *最后修改時間: 20120521 *說明????????: 配置指令超時時間 *************************************************************************************************************************/ void?SDIO_SetTimeOutClock(u8?Unit,u8?Frequency) { SDIO0->CAPAREG?&=?~(0xff); //清除原先設(shè)置 if(Unit) //配置超時時鐘單位:MHZ SDIO0->CAPAREG?|=?(1?<<?7); if(Frequency?>?63) //最大只能設(shè)置為63 Frequency?=?63; SDIO0->CAPAREG?|=?Frequency; }
s3c6410_sdio.h
#ifndef?_S3C6410_SDIO_H_ #define?_S3C6410_SDIO_H_ #include?"s3c6410_system.h" #define?FIFO_A0 0 //FIFO中斷地址0 #define?FIFO_A1 1 //FIFO中斷地址1 #define?FIFO_A2 2 //FIFO中斷地址2 #define?FIFO_A3 3 //FIFO中斷地址3 //SDIO總線寬度設(shè)置 #define?SDIO_BusWide_1b?????????????????????((u8)0) #define?SDIO_BusWide_4b?????????????????????((u8)1) #define?SDIO_BusWide_8b?????????????????????((u8)2) //SDIO?命令雜項設(shè)置 //SDIO響應(yīng)類型 #define?SDIO_Response_No????????????????????((u8)0) //無應(yīng)答 #define?SDIO_Response_Long??????????????????((u8)1) //長應(yīng)答 136 #define?SDIO_Response_Short?????????????????((u8)2) //短應(yīng)答 48 #define?SDIO_Response_ShortBusy?????????????((u8)3) //短應(yīng)答+檢測繁忙情況 //其它設(shè)置 #define?SDIO_CMDIndexEn?????????????????????((u8)1?<<?4)//SDIO指令索引使能 #define?SDIO_CMDCrcEn???????????????????????((u8)1?<<?3)//SDIO指令CRC校驗使能 #define?SDIO_DataSelect ((u8)1?<<?5)//SDIO當(dāng)前數(shù)據(jù)選擇 //SDIO指令類型CmdTyp #define?SDIO_Type_Default ((u8)0?<<?6)//一般為0 #define?SDIO_Type_Pend????????????????????? ((u8)1?<<?6)//寫總線暫停 #define?SDIO_Type_FS ((u8)2?<<?6)//功能選擇 #define?SDIO_Type_IT ?? ((u8)3?<<?6)//中斷模式 //SDIO響應(yīng)寄存器選擇 #define?SDIO_RESP1??????????????????????????((u8)0) #define?SDIO_RESP2??????????????????????????((u8)1) #define?SDIO_RESP3??????????????????????????((u8)2) #define?SDIO_RESP4??????????????????????????((u8)3) /*?SDIO?Data?Block?Size?------------------------------------------------------*/ #define?SDIO_DataBlockSize_1b???????????????((u16)1) #define?SDIO_DataBlockSize_2b???????????????((u16)2) #define?SDIO_DataBlockSize_4b???????????????((u16)3) #define?SDIO_DataBlockSize_8b???????????????((u16)4) #define?SDIO_DataBlockSize_16b??????????????((u16)16) #define?SDIO_DataBlockSize_32b??????????????((u16)32) #define?SDIO_DataBlockSize_64b??????????????((u16)64) #define?SDIO_DataBlockSize_128b?????????????((u16)128) #define?SDIO_DataBlockSize_256b?????????????((u16)256) #define?SDIO_DataBlockSize_512b?????????????((u16)512) #define?SDIO_DataBlockSize_1024b????????????((u16)1024) #define?SDIO_DataBlockSize_2048b????????????((u16)2048) #define?SDIO_DataBlockSize_4096b????????????((u16)4096) #define?SDIO_DataBlockSize_8192b????????????((u16)8192) #define?SDIO_DataBlockSize_16384b???????????((u16)16384) /*?SDIO?Flags?----------------------------------------------------------------*/ //SDIO中斷狀態(tài) #define?SDIO_STATUS (SDIO0->INTSTS) #define?SDIO_FLAG_FIFOADDERR3 ((u32)1?<<?14) //FIFO?SD?地址指示器中斷3?狀態(tài)?(RW1C) #define?SDIO_FLAG_FIFOADDERR2 ((u32)1?<<?13) //FIFO?SD?地址指示器中斷2?狀態(tài)?(RW1C) #define?SDIO_FLAG_FIFOADDERR1 ((u32)1?<<?12) //FIFO?SD?地址指示器中斷1?狀態(tài)?(RW1C) #define?SDIO_FLAG_FIFOADDERR0 ((u32)1?<<?11) //FIFO?SD?地址指示器中斷0?狀態(tài)?(RW1C) #define?SDIO_FLAG_READWAIT ((u32)1?<<?10) //讀等待中斷狀態(tài)?(RW1C)。 #define?SDIO_FLAG_CCS ((u32)1?<<?9) //CCS?中斷狀態(tài)?(RW1C)。 #define?SDIO_FLAG_CARD ((u32)1?<<?8) //卡?中斷。 #define?SDIO_FLAG_CARDREMOVAL ((u32)1?<<?7) //卡移除 #define?SDIO_FLAG_CARDINSERTION ((u32)1?<<?6) //卡插入 #define?SDIO_FLAG_BUFFREAD ((u32)1?<<?5) //讀緩沖區(qū)就緒 #define?SDIO_FLAG_BUFFWRITE ((u32)1?<<?4) //寫緩沖區(qū)就緒 #define?SDIO_FLAG_DMA ((u32)1?<<?3) //DMA #define?SDIO_FLAG_BLOCKGAP ((u32)1?<<?2) //塊間隔事件。 #define?SDIO_FLAG_TRANSFER ((u32)1?<<?1) //傳輸完成。超時錯誤優(yōu)先 #define?SDIO_FLAG_COMMANDEND ((u32)1?<<?0) //指令完成。超時錯誤優(yōu)先 #define?SDIO_FLAG_ADMA ((u32)1?<<?25) //DMA錯誤 #define?SDIO_FLAG_AUTOCMD12 ((u32)1?<<?24) //自動CMD12錯誤 #define?SDIO_FLAG_DATAENDBIT ((u32)1?<<?22) //數(shù)據(jù)最后位錯誤 #define?SDIO_FLAG_DATACRC ((u32)1?<<?21) //數(shù)據(jù)CRC錯誤 #define?SDIO_FLAG_DATATIMEOUT ((u32)1?<<?20) //數(shù)據(jù)超時錯誤 #define?SDIO_FLAG_COMMANDINDEX ((u32)1?<<?19) //命令索引錯誤 #define?SDIO_FLAG_COMMANDENDBIT ((u32)1?<<?18) //指令最后位錯誤 #define?SDIO_FLAG_COMMANDCRC ((u32)1?<<?17) //指令CRC錯誤 #define?SDIO_FLAG_COMMANDTIMEOUT ((u32)1?<<?16) //指令超時錯誤 #define?SDIO_FLAG_ALL ((u32)0xffffffff) //所有標(biāo)志 void?SDIO_DeInit(void); void?SDIO_ClockCmd(u8?EN); void?SDIO_SetPowerState(u32?SDIO_PowerState); void?SDIO_FlagITConfig(u32?SDIO_FLAG,?u8?EN); void?SDIO_FlagConfig(u32?SDIO_FLAG,?u8?EN); void?SDIO_SendCommand(vu8?CmdIdx,vu32?CmdArg,vu8?CmdMisc); u32?SDIO_GetResponse(u8?SDIO_RESP); u32?SDIO_ReadData(void); void?SDIO_WriteData(u32?Data); u8?SDIO_GetFlagStatus(u32?SDIO_FLAG); void?SDIO_ClearFlag(u32?SDIO_FLAG); void?SDIO_SetFIFOInterruptAddress(u8?FIFOxAdd,u8?WordAdd); void?SDIO_SetTimeOutClock(u8?Unit,u8?Frequency); void?SDIO_CLKFrequencySelect(u8?SDCLK); void?SDIO_SoftwareReset(u32?SDIO_RST);//軟件復(fù)位 //設(shè)置需要傳輸?shù)膲K數(shù)量 #define?SDIO_SetTransferBlockCnt(x) (SDIO0->BLKCNT?=?x) //獲取剩余傳輸?shù)膲K的數(shù)量 #define?SDIO_GetTransferBlockCnt() (SDIO0->BLKCNT) //設(shè)置單次傳輸?shù)膲K的大小 #define?SDIO_SetTransferBlockSize(x) (SDIO0->BLKSIZE?=?(x?&?0xfff)) //設(shè)置為單塊傳輸模式 #define?SDIO_SingleBlockMode() (SDIO0->TRNMOD?&=?~(BIT5)) //設(shè)置為多區(qū)段傳輸模式 #define?SDIO_MultipleBlockMode() (SDIO0->TRNMOD?|=?BIT5) //自動CMD12命令啟動 #define?SDIO_AutoCMD12Enable() (SDIO0->TRNMOD?|=?BIT2) //自動CMD12命令禁止 #define?SDIO_AuotCMD12Disable() (SDIO0->TRNMOD?&=?~(BIT2)) //設(shè)置SDIO為寫數(shù)據(jù)模式 #define?SDIO_WriteMode() (SDIO0->TRNMOD?&=?~(BIT4)) //設(shè)置SDIO為讀數(shù)據(jù)模式 #define?SDIO_ReadMode() (SDIO0->TRNMOD?|=?BIT4) //塊計數(shù)器啟動 #define?SDIO_BlockCountEnable() (SDIO0->TRNMOD?|=?BIT1) //禁止塊計數(shù)器啟動 #define?SDIO_BlockCountDisable() (SDIO0->TRNMOD?&=?~(BIT1)) //DMA啟動 #define?SDIO_DMAEnable() (SDIO0->TRNMOD?|=?BIT0) //DMA禁止 #define?SDIO_DMADisable() (SDIO0->TRNMOD?&=?~(BIT0)) //數(shù)據(jù)線忙 #define?SDIO_DATLineActive() (SDIO0->PRNSTS?&?BIT2) //指令禁止 #define?SDIO_CommandInhibit() (SDIO0->PRNSTS?&?BIT0) //高速時鐘模式使能 #define?SDIO_HighSpeedEnable() (SDIO0->CAPAREG?|=?BIT21) //取消高速時鐘模式 #define?SDIO_HighSpeedDisable() (SDIO0->CAPAREG?&=?~BIT21) //數(shù)據(jù)線寬度設(shè)置為4bit #define?SDIO_SetDataDataWidth_4b() (SDIO0->HOSTCTL?|=?BIT1) //數(shù)據(jù)線寬設(shè)置為1bit #define?SDIO_SetDataDataWidth_1b() (SDIO0->HOSTCTL?&=?~BIT1) //總線電壓選擇3.3V #define?SDIO_SetBusVoltage_3_3V() (SDIO0->PWRCON?&=?~(0x7?<<?1);?SDIO0->PWRCON?|=?(7?<<?1)) //總線電源開啟 #define?SDIO_BusPowerON() (SDIO0->PWRCON?|=?BIT0) //總線電壓關(guān)閉 #define?SDIO_BusPowerOFF() (SDIO0->PWRCON?&=?~BIT0) //喚醒發(fā)生在SD卡插入 #define?SDIO_WakeupOnSDInsertion() (SDIO0->WAKCON?|=?BIT1 //使能SD時鐘 #define?SDIO_SDClkEnable() (SDIO0->CLKCON?|=?BIT2) //SD時鐘停止 #define?SDIO_SDClkDisable() (SDIO0->CLKCON?&=?~BIT2) //超時時鐘單位設(shè)置 #define?TIME_OUT_UNIT_KHZ 0 //超時時鐘單位為KHZ #define?TIME_OUT_UNIT_MHZ 1 //超時時鐘單位為MHZ //時鐘分頻系數(shù) #define?SDCLK_1_256? ((u8)0x80) //基礎(chǔ)時鐘256分頻 #define?SDCLK_1_128? ((u8)0x40) //基礎(chǔ)時鐘128分頻 #define?SDCLK_1_64? ((u8)0x20) //基礎(chǔ)時鐘64分頻 #define?SDCLK_1_32 ((u8)0x10) //基礎(chǔ)時鐘32分頻 #define?SDCLK_1_16? ((u8)0x08) //基礎(chǔ)時鐘16分頻 #define?SDCLK_1_8? ((u8)0x04) //基礎(chǔ)時鐘8分頻 #define?SDCLK_1_4? ((u8)0x02) //基礎(chǔ)時鐘4分頻 #define?SDCLK_1_2? ((u8)0x01) //基礎(chǔ)時鐘2分頻 #define?SDCLK_1_1 ((u8)0x00) //基礎(chǔ)時鐘1分頻 //軟件復(fù)位選擇 #define?SDIO_RSTDAT BIT2 //復(fù)位DAT線 #define?SDIO_RSTCMD BIT1 //復(fù)位CMD線 #define?SDIO_RSTALL BIT0 //復(fù)位所有 #endif
sdcard_sdio.c,
/******************************************************************************* //功能:SDCARD?驅(qū)動,SDIO?模式 //作者:陳鵬 //創(chuàng)建時間:2012-05-16?10:32 //修改時間:2012-05-16?10:32 //修訂說明: //聲明:源程序借鑒了意法STM32F103X庫函數(shù) ********************************************************************************/ #include?"sdcard_sdio.h" #include?"s3c6410_sdio.h" #include?"s3c6410_system.h" u8?SDMMC0_MOV_Flag?=?0; //sdmmc0卡移除信號有 /* 1.3?寄存器 名稱?寬度?描述 CID?128?卡標(biāo)識號 RCA?16?相對卡地址(Relative?card?address):本地系統(tǒng)中卡的地 址,動態(tài)變化,在主機初始化的時候確定 *SPI?模式中沒有 CSD?128?卡描述數(shù)據(jù):卡操作條件相關(guān)的信息數(shù)據(jù) SCR?64?SD?配置寄存器:SD?卡特定信息數(shù)據(jù) OCR?32?操作條件寄存器*/ //容量?=?BLOCKNR?*?BLOCK_LEN?=?(C_SIZE+1)*2^(C_SIZE_MULT+2)*2^(READ_BL_LEN) #define?SD_BlockSize? 512 //SD卡塊大小 #define?SDIO_CMD0TIMEOUT 1000000 //超時計數(shù)器大小 #define?SDIO_READTIMEOUT 1000000 //讀等待超時 #define?SDIO_WRITETIMEOUT 2000000 //寫等待超時 //?SD卡指令表?? ??? #define?CMD0????0???????//卡復(fù)位 #define?CMD1????1 #define?CMD9????9???????//命令9?,讀CSD數(shù)據(jù) #define?CMD10???10??????//命令10,讀CID數(shù)據(jù) #define?CMD12???12??????//命令12,停止數(shù)據(jù)傳輸 #define?CMD16???16??????//命令16,設(shè)置SectorSize?應(yīng)返回0x00 #define?CMD17???17??????//命令17,讀sector #define?CMD18???18??????//命令18,讀Multi?sector #define?ACMD23??23??????//命令23,設(shè)置多sector寫入前預(yù)先擦除N個block #define?CMD24???24??????//命令24,寫sector #define?CMD25???25??????//命令25,寫Multi?sector #define?ACMD41??41??????//命令41,應(yīng)返回0x00 #define?CMD55???55??????//命令55,應(yīng)返回0x01 #define?CMD58???58??????//命令58,讀OCR信息 #define?CMD59???59??????//命令59,使能/禁止CRC,應(yīng)返回0x0 /*?Mask?for?errors?Card?Status?R1?(OCR?Register)?*/ #define?SD_OCR_ADDR_OUT_OF_RANGE????????((u32)0x80000000) #define?SD_OCR_ADDR_MISALIGNED??????????((u32)0x40000000) #define?SD_OCR_BLOCK_LEN_ERR????????????((u32)0x20000000) #define?SD_OCR_ERASE_SEQ_ERR????????????((u32)0x10000000) #define?SD_OCR_BAD_ERASE_PARAM??????????((u32)0x08000000) #define?SD_OCR_WRITE_PROT_VIOLATION?????((u32)0x04000000) #define?SD_OCR_LOCK_UNLOCK_FAILED???????((u32)0x01000000) #define?SD_OCR_COM_CRC_FAILED???????????((u32)0x00800000) #define?SD_OCR_ILLEGAL_CMD??????????????((u32)0x00400000) #define?SD_OCR_CARD_ECC_FAILED??????????((u32)0x00200000) #define?SD_OCR_CC_ERROR?????????????????((u32)0x00100000) #define?SD_OCR_GENERAL_UNKNOWN_ERROR????((u32)0x00080000) #define?SD_OCR_STREAM_READ_UNDERRUN?????((u32)0x00040000) #define?SD_OCR_STREAM_WRITE_OVERRUN?????((u32)0x00020000) #define?SD_OCR_CID_CSD_OVERWRIETE???????((u32)0x00010000) #define?SD_OCR_WP_ERASE_SKIP????????????((u32)0x00008000) #define?SD_OCR_CARD_ECC_DISABLED????????((u32)0x00004000) #define?SD_OCR_ERASE_RESET??????????????((u32)0x00002000) #define?SD_OCR_AKE_SEQ_ERROR????????????((u32)0x00000008) #define?SD_OCR_ERRORBITS????????????????((u32)0xFDFFE008) /*?Masks?for?R6?Response?*/ #define?SD_R6_GENERAL_UNKNOWN_ERROR?????((u32)0x00002000) #define?SD_R6_ILLEGAL_CMD???????????????((u32)0x00004000) #define?SD_R6_COM_CRC_FAILED????????????((u32)0x00008000) #define?SD_VOLTAGE_WINDOW_SD????????????((u32)0x80100000) #define?SD_HIGH_CAPACITY????????????????((u32)0x40000000) #define?SD_STD_CAPACITY?????????????????((u32)0x00000000) #define?SD_CHECK_PATTERN????????????????((u32)0x000001AA) #define?SD_MAX_VOLT_TRIAL???????????????((u32)0x0000FFFF) #define?SD_ALLZERO??????????????????????((u32)0x00000000) #define?SD_WIDE_BUS_SUPPORT?????????????((u32)0x00040000) #define?SD_SINGLE_BUS_SUPPORT???????????((u32)0x00010000) #define?SD_CARD_LOCKED??????????????????((u32)0x02000000) #define?SD_CARD_PROGRAMMING?????????????((u32)0x00000007) #define?SD_CARD_RECEIVING???????????????((u32)0x00000006) #define?SD_DATATIMEOUT??????????????????((u32)0x000FFFFF) #define?SD_0TO7BITS?????????????????????((u32)0x000000FF) #define?SD_8TO15BITS????????????????????((u32)0x0000FF00) #define?SD_16TO23BITS???????????????????((u32)0x00FF0000) #define?SD_24TO31BITS???????????????????((u32)0xFF000000) #define?SD_MAX_DATA_LENGTH??????????????((u32)0x01FFFFFF) #define?SD_HALFFIFO?????????????????????((u32)0x00000008) #define?SD_HALFFIFOBYTES????????????????((u32)0x00000020) /*?Command?Class?Supported?*/ #define?SD_CCCC_LOCK_UNLOCK?????????????((u32)0x00000080) #define?SD_CCCC_WRITE_PROT??????????????((u32)0x00000040) #define?SD_CCCC_ERASE???????????????????((u32)0x00000020) /*?Following?commands?are?SD?Card?Specific?commands. ???SDIO_APP_CMD?should?be?sent?before?sending?these?commands.?*/ #define?SDIO_SEND_IF_COND???????????????((u32)0x00000008) //#define?SDIO_MULTIMEDIA_CARD???????????????((u32)0x0) #define?SDIO_SECURE_DIGITAL_CARD???????????((u32)0x1) //#define?SDIO_SECURE_DIGITAL_IO_CARD????????((u32)0x2) //#define?SDIO_HIGH_SPEED_MULTIMEDIA_CARD????((u32)0x3) //#define?SDIO_SECURE_DIGITAL_IO_COMBO_CARD??((u32)0x4) //#define?SDIO_HIGH_CAPACITY_SD_CARD?????????((u32)0x5) //#define?SDIO_HIGH_CAPACITY_MMC_CARD????????((u32)0x6) #define?SDIO_INIT_CLK_DIV??????????????????((u8)0xB2) #define?SDIO_TRANSFER_CLK_DIV??????????????((u8)0x01)??//時鐘分頻 /*?Private?macro?-------------------------------------------------------------*/ /*?Private?variables?---------------------------------------------------------*/ static?u32?CardType?=??SDIO_SECURE_DIGITAL_CARD; static?u32?CSD_Tab[4],?CID_Tab[4],?RCA?=?0; //static?u32?DeviceMode?=?SD_POLLING_MODE; //static?u32?TotalNumberOfBytes?=?0,?StopCondition?=?0; u32?*SrcBuffer,?*DestBuffer; volatile?SD_Error?TransferError?=?SD_OK; vu32?TransferEnd?=?0; vu32?NumberOfBytes?=?0; //SD卡中斷服務(wù)程序,用來檢測卡的插入與移除的 static?void?__irq?Isr_SDMMC_Card(void); /*?Private?function?prototypes?-----------------------------------------------*/ static?SD_Error?CmdError(void); static?SD_Error?CmdResp1Error(void); static?SD_Error?CmdResp7Error(void); static?SD_Error?CmdResp3Error(void); static?SD_Error?CmdResp2Error(void); static?SD_Error?CmdResp6Error(u16?*prca); static?SD_Error?SDEnWideBus(u8?EN); static?SD_Error?IsCardProgramming(u8?*pstatus); static?SD_Error?FindSCR(u16?rca,?u32?*pscr); #define?DebugPrintf?printf /************************************************************************************************************************* *?函數(shù) : SD_Error?SD_Init(void) *?功能 : SD卡初始化 *?參數(shù) : 無 *?返回 : SD_OK:成功,其它見SD?Card?Error?code. *?依賴 : 底層寄存器操作函數(shù) *?作者 : 陳鵬 *?時間 : 20120516 *?最后修改時間?:?20120524 *?說明 :? 初始化SD卡 *************************************************************************************************************************/ SD_Error?SD_Init(void) { SD_Error?errorstatus?=?SD_OK; SDIO_SoftwareReset(SDIO_RSTALL); //軟件復(fù)位所有寄存器 SDIO_DeInit(); //初始化SDIO硬件 SDIO_FlagITConfig(SDIO_FLAG_CARDREMOVAL?|?SDIO_FLAG_CARDINSERTION,Enable);//使能卡插入拔出中斷 Set_IsrAddr(INT_HSMMC0,(vu32)Isr_SDMMC_Card); //設(shè)置中斷矢量入口 Set_IntEnable(INT_HSMMC0,Enable); //開啟SDMMC0中斷 errorstatus?=?SD_SetIdleSta(); //SD卡上電 if?(errorstatus?!=?SD_OK) //卡上電發(fā)送錯誤 { DebugPrintf("SD?power?up?error:(%d)!n",errorstatus); //調(diào)試,打印錯誤 return(errorstatus); //返回錯誤 } errorstatus?=?SD_InitializeCards(); if?(errorstatus?!=?SD_OK) { DebugPrintf("SD?initialize?error(%d)!n",errorstatus); //調(diào)試,打印錯誤 return(errorstatus); } return(errorstatus); } /************************************************************************************************************************* *?函數(shù) : SD_Error?SD_SetIdleSta(void) *?功能 : SD卡上電進(jìn)入空閑模式,并識別卡 *?參數(shù) : 無 *?返回 : SD_OK:成功,其它見SD?Card?Error?code. *?依賴 : 底層寄存器操作函數(shù) *?作者 : 陳鵬 *?時間 : 20120516 *?最后修改時間?:?20120516 *?說明 :???SD卡上電進(jìn)入空閑模式 *************************************************************************************************************************/ SD_Error?SD_SetIdleSta(void) { ??SD_Error?errorstatus?=?SD_OK; ??u32?response?=?0,?count?=?0; ??bool?validvoltage?=?FALSE; ??u32?SDType?=?SD_STD_CAPACITY; ??u16?i; SDIO_CLKFrequencySelect(SDCLK_1_64); //設(shè)置時鐘400KHZ SDIO_SetTimeOutClock(TIME_OUT_UNIT_KHZ,1); //設(shè)置超時時鐘頻率最低 //發(fā)送至少74個時鐘,等待SD卡上電成功并同步 for(response?=?0;response?<?1000;response?++); ?? ?? ?? //循環(huán)發(fā)生發(fā)送CMD0,無響應(yīng),無返回,讓SD卡進(jìn)入空閑模式 ?? for(i?=?0;i?<?50;i?++) ?? { ?? SDIO_SendCommand(CMD0,0,0); errorstatus?=?CmdError(); //判斷命令是否執(zhí)行成功,此命令只要初始化了SDIO就會執(zhí)行成功 if(errorstatus?==?SD_OK) break; ?? } ?? if(errorstatus?!=?SD_OK) ?? { ?? DEBUG("error!(%d)n",errorstatus); //調(diào)試,打印信息 ?? return(errorstatus); ?? } ?? //發(fā)送CMD8:SEND_IF_COND;短響應(yīng),命令參數(shù):SD_CHECK_PATTERN;返回響應(yīng)R7 ?? //識別卡版本 SDIO_SendCommand(SDIO_SEND_IF_COND,SD_CHECK_PATTERN,SDIO_CMDIndexEn?|?SDIO_CMDCrcEn?|?SDIO_Response_Short); errorstatus?=?CmdResp7Error(); if?(errorstatus?==?SD_OK) //返回成功;說明卡為SD?Card?2.0?V2.0 { CardType?=?SDIO_STD_CAPACITY_SD_CARD_V2_0;?/*?SD?Card?2.0?*/ SDType?=?SD_HIGH_CAPACITY; DEBUG("SDIO_STD_CAPACITY_SD_CARD_V2_0!n"); //調(diào)試,打印錯誤信息 } else //V1.0?V1.1 { DEBUG("SD?Card?V1.1!n"); //調(diào)試,打印信息 CardType?=?SDIO_STD_CAPACITY_SD_CARD_V1_1;? //V1.0?V1.1 SDIO_SendCommand(CMD55,0,SDIO_CMDIndexEn?|?SDIO_CMDCrcEn?|?SDIO_Response_Short); CmdResp1Error(); } do { //發(fā)送CMD55?SDIO_APP_CMD;命令參數(shù):0;返回響應(yīng)R1,設(shè)置RCA為0,短響應(yīng) ?????? SDIO_SendCommand(SDIO_APP_CMD,0,SDIO_CMDIndexEn?|?SDIO_CMDCrcEn?|?SDIO_Response_Short); errorstatus?=?CmdResp1Error(); if?(errorstatus?!=?SD_OK) { DEBUG("CMD55?error(%d)!n",errorstatus); //調(diào)試,打印錯誤信息 return(errorstatus); } //發(fā)送ACM41命令;命令參數(shù):SD_APP_OP_COND(0x80100000);短響應(yīng).響應(yīng)為R3,返回操作條件寄存器RCA SDIO_SendCommand(SDIO_SD_APP_OP_COND,SD_VOLTAGE_WINDOW_SD?|?SDType,SDIO_CMDIndexEn?|?SDIO_CMDCrcEn?|?SDIO_Response_Short); errorstatus?=?CmdResp3Error(); if?(errorstatus?!=?SD_OK) { DEBUG("ACM41?error(%d)!n",errorstatus); //調(diào)試,打印錯誤信息 return(errorstatus); } response?=?SDIO_GetResponse(SDIO_RESP1); //獲取響應(yīng),RESE1 validvoltage?=?(bool)?(((response?>>?31)?==?1)???1?:?0); count++; } while((!validvoltage)?&&?(count?<?SD_MAX_VOLT_TRIAL));//循環(huán)初始化,直到返回成功或者超時 ????if?(count?>=?SD_MAX_VOLT_TRIAL) //重試次數(shù)超出 ????{ errorstatus?=?SD_INVALID_VOLTRANGE; return(errorstatus); ????} ????if?(response?&=?SD_HIGH_CAPACITY) ????{ CardType?=?SDIO_HIGH_CAPACITY_SD_CARD; ????} return(errorstatus); } /************************************************************************************************************************* *?函數(shù) : SD_Error?SD_PowerOFF(void) *?功能 : SD卡掉電 *?參數(shù) : 無 *?返回 : SD_OK:成功,其它見SD?Card?Error?code. *?依賴 : 底層寄存器操作函數(shù) *?作者 : 陳鵬 *?時間 : 20120516 *?最后修改時間?:?20120516 *?說明 :? SD卡掉電 *************************************************************************************************************************/ SD_Error?SD_PowerOFF(void) { SD_Error?errorstatus?=?SD_OK; SDIO_BusPowerOFF(); //關(guān)閉總線電源 return(errorstatus); } /************************************************************************************************************************* *?函數(shù) : SD_Error?SD_PowerON(void) *?功能 : SD卡電源開啟 *?參數(shù) : 無 *?返回 : SD_OK:成功,其它見SD?Card?Error?code. *?依賴 : 底層寄存器操作函數(shù) *?作者 : 陳鵬 *?時間 : 20120516 *?最后修改時間?:?20120524 *?說明 :? SD卡電源開啟 *************************************************************************************************************************/ SD_Error?SD_PowerON(void) { SD_Error?errorstatus?=?SD_OK; SDIO_BusPowerON(); //打開總線電源 return(errorstatus); } /************************************************************************************************************************* *?函數(shù) : SD_Error?SD_InitializeCards(void) *?功能 : 將所有的卡進(jìn)行初始化配置 *?參數(shù) : 無 *?返回 : SD_OK:成功,其它見SD?Card?Error?code. *?依賴 : 底層寄存器操作函數(shù) *?作者 : 陳鵬 *?時間 : 20120516 *?最后修改時間?:?20120516 *?說明 :? 將所有的卡進(jìn)行初始化配置 *************************************************************************************************************************/ SD_Error?SD_InitializeCards(void) { SD_Error?errorstatus?=?SD_OK; u16?rca?=?0x01; //發(fā)送CMD2?SDIO_ALL_SEND_CID命令,命令參數(shù):0;長回復(fù),R2 //發(fā)送CMD用來獲取CID信息的 SDIO_SendCommand(SDIO_ALL_SEND_CID,0,SDIO_CMDIndexEn?|?SDIO_CMDCrcEn?|?SDIO_Response_Long); errorstatus?=?CmdResp2Error(); //獲取響應(yīng)R2 if?(errorstatus?!=?SD_OK) { DEBUG("error!(%d)n",errorstatus); //調(diào)試,打印錯誤信息 return(errorstatus); } //到每個卡以獲取每個卡的唯一標(biāo)識CID CID_Tab[0]?=?SDIO_GetResponse(SDIO_RESP1); CID_Tab[1]?=?SDIO_GetResponse(SDIO_RESP2); CID_Tab[2]?=?SDIO_GetResponse(SDIO_RESP3); CID_Tab[3]?=?SDIO_GetResponse(SDIO_RESP4); //發(fā)送CMD3,SET_REL_ADDR命令,參數(shù)0,響應(yīng),短響應(yīng),R6 //用來獲取卡地址 //主機發(fā)送CMD3(SEND_RELATIVE_ADDR)要求卡發(fā)布一個新的相對卡地址RCA,地址比CID短,在以后的數(shù)據(jù)傳輸模式中用來尋址卡。一旦獲得RCA后,卡狀態(tài)變成就緒狀態(tài)(Stand-by?state) SDIO_SendCommand(SDIO_SET_REL_ADDR,0,SDIO_CMDIndexEn?|?SDIO_CMDCrcEn?|?SDIO_Response_Short); ????errorstatus?=?CmdResp6Error(&rca); //獲取卡地址 ????if?(errorstatus?!=?SD_OK) ????{ DEBUG("error!(%d)!n",errorstatus); //調(diào)試,打印錯誤信息 return(errorstatus); ????} RCA?=?rca;//存儲卡地址 //發(fā)送CMD9?SDIO_SEND_CSD命令,參數(shù):rca地址;長響應(yīng),R2; //給卡發(fā)送一個新的RCA,主要是用來設(shè)置卡地址的 ????SDIO_SendCommand(SDIO_SEND_CSD,(u32)rca?<<?16,SDIO_CMDIndexEn?|?SDIO_CMDCrcEn?|?SDIO_Response_Long); ????errorstatus?=?CmdResp2Error(); ????if?(errorstatus?!=?SD_OK) ????{ DEBUG("error!(%d)!n",errorstatus);