花了幾天寫了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) //默認為單區(qū)段操作模式
#define?TRNMOD0_RD1WT0 (1?<<?4) //默認為讀操作模式
#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) //支持暫停/恢復操作
#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基礎始終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) //基礎時鐘源選擇。00?或01?=?HCLK,10?=?EPLL?輸出時鐘(來自系統(tǒng))11?=?外部時鐘源(XTI?或XEXTCLk)
#define?CONTROL2_0_PWRSYNC (0?<<?3) //不同步,控制輸入有效信號(指令,數(shù)據(jù))
#define?CONTROL2_0_ENCLKOUTMSKCON (0?<<?1) //當卡插入被清除時,SDCLK?輸出時鐘屏蔽。當處于無卡狀態(tài)時,設置該區(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; //超時設置最大
//電源控制寄存器配置
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); //清除所有中斷標志
}
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:其它雜項設置,詳見說明
*返回????????: 無
*依賴????????:? 底層宏定義
*作者????????: 陳鵬
*時間????????: 20120507
*最后修改時間: 20120507
*說明????????: 寫SD命令寄存器;
指令索引:這些位設置為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???????????無應答
SDIO_Response_Short????????短應答 48
SDIO_Response_Long????????長應答 136
SDIO_Response_ShortBusy????短應答+檢測繁忙情況
*************************************************************************************************************************/
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卡的應答
*參數(shù)????????: Rep:應答數(shù)據(jù)存放的位置
SDIO_RESP1:?Response?Register?1
*???????????????SDIO_RESP2:?Response?Register?2
*???????????????SDIO_RESP3:?Response?Register?3
*???????????????SDIO_RESP4:?Response?Register?4??
*返回????????: 返回應答
*依賴????????:? 底層宏定義
*作者????????: 陳鵬
*時間????????: 20120507
*最后修改時間: 20120507
*說明????????: 存放應答數(shù)據(jù)的緩沖區(qū)為128BIT;4個32bit;
指令應答。下表27-4為每一個應答描述了從SD總線到寄存器的指令映射。在這個表中,在表中?R[]指出在SD總線上傳輸?shù)膽饠?shù)據(jù)的范圍,
REP[]指出應答寄存器中位的范圍。128位應答位的順序:?{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)
*?功能 : 設置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)
*?功能 : 設置SDIO時鐘分頻系數(shù)
*?參數(shù) : SDCLK:設置SDIO時鐘分頻系數(shù)
*?返回 : SD_OK:成功,其它見SD?Card?Error?code.
*?依賴 : 底層寄存器操作函數(shù)
*?作者 : 陳鵬
*?時間 : 20120516
*?最后修改時間?:?20120516
*?說明 :? 高速基礎時鐘為50MHz
低速基礎時鐘為25MHz
*************************************************************************************************************************/
void?SDIO_CLKFrequencySelect(u8?SDCLK)
{
SDIO_SDClkDisable(); //時鐘停止
SDIO0->CAPAREG?&=?~(0x3f?<<?8); //清除設置
SDIO0->CAPAREG?|=?(50?<<?8); //這一位設置其實沒作用
SDIO0->CLKCON?&=?~(0xff?<<?8); //清除
SDIO0->CLKCON?|=?(SDCLK?<<?8); //設置基礎時鐘分頻系數(shù)
SDIO_SDClkEnable(); //時鐘使能
while(!(SDIO0->CLKCON?&?BIT0)); //等待時鐘穩(wěn)定
}
/*************************************************************************************************************************
*?函數(shù) : void?SDIO_SoftwareReset(u32?SDIO_RST)
*?功能 : 設置SDIO軟件復位
*?參數(shù) : SDIO_RST:
SDIO_RSTDAT //復位DAT線
SDIO_RSTCMD //復位CMD線
SDIO_RSTALL //復位所有
*?返回 : SD_OK:成功,其它見SD?Card?Error?code.
*?依賴 : 底層寄存器操作函數(shù)
*?作者 : 陳鵬
*?時間 : 20120516
*?最后修改時間?:?20120516
*?說明 :? 無
*************************************************************************************************************************/
void?SDIO_SoftwareReset(u32?SDIO_RST)
{
SDIO0->SWRST?|=?SDIO_RST; //復位
while(SDIO0->SWRST?&?SDIO_RST); //等待復位完成
}
/*************************************************************************************************************************
*函數(shù)????????: void?SDIO_SetTimeOutClock(u8?Unit,u8?Frequency)
*功能????????: 超時時鐘設置
*參數(shù)????????: Unit:超時時鐘單位選擇
TIME_OUT_UNIT_KHZ(0):超時時鐘單位為KHZ
TIME_OUT_UNIT_MHZ(1):超時時鐘單位為MHZ
Frequency:時鐘頻率:1~63
*返回????????: 返回應答
*依賴????????:? 底層宏定義
*作者????????: 陳鵬
*時間????????: 20120521
*最后修改時間: 20120521
*說明????????: 配置指令超時時間
*************************************************************************************************************************/
void?SDIO_SetTimeOutClock(u8?Unit,u8?Frequency)
{
SDIO0->CAPAREG?&=?~(0xff); //清除原先設置
if(Unit) //配置超時時鐘單位:MHZ
SDIO0->CAPAREG?|=?(1?<<?7);
if(Frequency?>?63) //最大只能設置為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總線寬度設置 #define?SDIO_BusWide_1b?????????????????????((u8)0) #define?SDIO_BusWide_4b?????????????????????((u8)1) #define?SDIO_BusWide_8b?????????????????????((u8)2) //SDIO?命令雜項設置 //SDIO響應類型 #define?SDIO_Response_No????????????????????((u8)0) //無應答 #define?SDIO_Response_Long??????????????????((u8)1) //長應答 136 #define?SDIO_Response_Short?????????????????((u8)2) //短應答 48 #define?SDIO_Response_ShortBusy?????????????((u8)3) //短應答+檢測繁忙情況 //其它設置 #define?SDIO_CMDIndexEn?????????????????????((u8)1?<<?4)//SDIO指令索引使能 #define?SDIO_CMDCrcEn???????????????????????((u8)1?<<?3)//SDIO指令CRC校驗使能 #define?SDIO_DataSelect ((u8)1?<<?5)//SDIO當前數(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響應寄存器選擇 #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) //所有標志 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);//軟件復位 //設置需要傳輸?shù)膲K數(shù)量 #define?SDIO_SetTransferBlockCnt(x) (SDIO0->BLKCNT?=?x) //獲取剩余傳輸?shù)膲K的數(shù)量 #define?SDIO_GetTransferBlockCnt() (SDIO0->BLKCNT) //設置單次傳輸?shù)膲K的大小 #define?SDIO_SetTransferBlockSize(x) (SDIO0->BLKSIZE?=?(x?&?0xfff)) //設置為單塊傳輸模式 #define?SDIO_SingleBlockMode() (SDIO0->TRNMOD?&=?~(BIT5)) //設置為多區(qū)段傳輸模式 #define?SDIO_MultipleBlockMode() (SDIO0->TRNMOD?|=?BIT5) //自動CMD12命令啟動 #define?SDIO_AutoCMD12Enable() (SDIO0->TRNMOD?|=?BIT2) //自動CMD12命令禁止 #define?SDIO_AuotCMD12Disable() (SDIO0->TRNMOD?&=?~(BIT2)) //設置SDIO為寫數(shù)據(jù)模式 #define?SDIO_WriteMode() (SDIO0->TRNMOD?&=?~(BIT4)) //設置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ù)線寬度設置為4bit #define?SDIO_SetDataDataWidth_4b() (SDIO0->HOSTCTL?|=?BIT1) //數(shù)據(jù)線寬設置為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) //總線電壓關閉 #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) //超時時鐘單位設置 #define?TIME_OUT_UNIT_KHZ 0 //超時時鐘單位為KHZ #define?TIME_OUT_UNIT_MHZ 1 //超時時鐘單位為MHZ //時鐘分頻系數(shù) #define?SDCLK_1_256? ((u8)0x80) //基礎時鐘256分頻 #define?SDCLK_1_128? ((u8)0x40) //基礎時鐘128分頻 #define?SDCLK_1_64? ((u8)0x20) //基礎時鐘64分頻 #define?SDCLK_1_32 ((u8)0x10) //基礎時鐘32分頻 #define?SDCLK_1_16? ((u8)0x08) //基礎時鐘16分頻 #define?SDCLK_1_8? ((u8)0x04) //基礎時鐘8分頻 #define?SDCLK_1_4? ((u8)0x02) //基礎時鐘4分頻 #define?SDCLK_1_2? ((u8)0x01) //基礎時鐘2分頻 #define?SDCLK_1_1 ((u8)0x00) //基礎時鐘1分頻 //軟件復位選擇 #define?SDIO_RSTDAT BIT2 //復位DAT線 #define?SDIO_RSTCMD BIT1 //復位CMD線 #define?SDIO_RSTALL BIT0 //復位所有 #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?卡標識號
RCA?16?相對卡地址(Relative?card?address):本地系統(tǒng)中卡的地
址,動態(tài)變化,在主機初始化的時候確定
*SPI?模式中沒有
CSD?128?卡描述數(shù)據(jù):卡操作條件相關的信息數(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???????//卡復位
#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,設置SectorSize?應返回0x00
#define?CMD17???17??????//命令17,讀sector
#define?CMD18???18??????//命令18,讀Multi?sector
#define?ACMD23??23??????//命令23,設置多sector寫入前預先擦除N個block
#define?CMD24???24??????//命令24,寫sector
#define?CMD25???25??????//命令25,寫Multi?sector
#define?ACMD41??41??????//命令41,應返回0x00
#define?CMD55???55??????//命令55,應返回0x01
#define?CMD58???58??????//命令58,讀OCR信息
#define?CMD59???59??????//命令59,使能/禁止CRC,應返回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卡中斷服務程序,用來檢測卡的插入與移除的
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); //軟件復位所有寄存器
SDIO_DeInit(); //初始化SDIO硬件
SDIO_FlagITConfig(SDIO_FLAG_CARDREMOVAL?|?SDIO_FLAG_CARDINSERTION,Enable);//使能卡插入拔出中斷
Set_IsrAddr(INT_HSMMC0,(vu32)Isr_SDMMC_Card); //設置中斷矢量入口
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卡上電進入空閑模式,并識別卡
*?參數(shù) : 無
*?返回 : SD_OK:成功,其它見SD?Card?Error?code.
*?依賴 : 底層寄存器操作函數(shù)
*?作者 : 陳鵬
*?時間 : 20120516
*?最后修改時間?:?20120516
*?說明 :???SD卡上電進入空閑模式
*************************************************************************************************************************/
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); //設置時鐘400KHZ
SDIO_SetTimeOutClock(TIME_OUT_UNIT_KHZ,1); //設置超時時鐘頻率最低
//發(fā)送至少74個時鐘,等待SD卡上電成功并同步
for(response?=?0;response?<?1000;response?++);
??
??
?? //循環(huán)發(fā)生發(fā)送CMD0,無響應,無返回,讓SD卡進入空閑模式
?? 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;短響應,命令參數(shù):SD_CHECK_PATTERN;返回響應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;返回響應R1,設置RCA為0,短響應
?????? 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);短響應.響應為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); //獲取響應,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(); //關閉總線電源
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)
*?功能 : 將所有的卡進行初始化配置
*?參數(shù) : 無
*?返回 : SD_OK:成功,其它見SD?Card?Error?code.
*?依賴 : 底層寄存器操作函數(shù)
*?作者 : 陳鵬
*?時間 : 20120516
*?最后修改時間?:?20120516
*?說明 :? 將所有的卡進行初始化配置
*************************************************************************************************************************/
SD_Error?SD_InitializeCards(void)
{
SD_Error?errorstatus?=?SD_OK;
u16?rca?=?0x01;
//發(fā)送CMD2?SDIO_ALL_SEND_CID命令,命令參數(shù):0;長回復,R2
//發(fā)送CMD用來獲取CID信息的
SDIO_SendCommand(SDIO_ALL_SEND_CID,0,SDIO_CMDIndexEn?|?SDIO_CMDCrcEn?|?SDIO_Response_Long);
errorstatus?=?CmdResp2Error(); //獲取響應R2
if?(errorstatus?!=?SD_OK)
{
DEBUG("error!(%d)n",errorstatus); //調(diào)試,打印錯誤信息
return(errorstatus);
}
//到每個卡以獲取每個卡的唯一標識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,響應,短響應,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地址;長響應,R2;
//給卡發(fā)送一個新的RCA,主要是用來設置卡地址的
????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); 




