S3C6410裸機(jī)SD卡驅(qū)動(dòng)(SDIO模式)
花了幾天寫了SD卡裸機(jī)驅(qū)動(dòng),現(xiàn)在還不完善,只支持4G以內(nèi)的卡,以后再加上;現(xiàn)在經(jīng)過修改可以寫入數(shù)據(jù)了,親測(cè)沒問題.
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) //自動(dòng)CMD12禁止,多區(qū)段操作完成后主機(jī)自動(dòng)發(fā)出停止命令
#define?TRNMOD0_ENBLKCNT (0?<<?1) //塊計(jì)數(shù)器無效
#define?TRNMOD0_ENDMA (0?<<?0) //DMA無效
//主機(jī)控制寄存器(0通道)HOSTCTL0
#define?HOSTCTL0_WIDE8 (0?<<?5) //這個(gè)為寬度被位1指定?(數(shù)據(jù)傳輸寬度)
#define?HOSTCTL0_DMASEL (0?<<?3) //SDMA
#define?HOSTCTL0_OUTEDGEINV (0?<<?2) //時(shí)鐘上升沿沿?cái)?shù)據(jù)有效 //這個(gè)寄存器有歧義,不知道到底是干啥用的
#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) //超時(shí)時(shí)鐘單位KHZ
#define?CAPAREG0_TOUTCLK (10?<<?0) //超時(shí)時(shí)鐘頻率為10KHZ
//最大電流容限寄存器(0?通道)MAXCURR0
#define?MAXCURR0_MAXCURR18 (10?<<?16) //對(duì)于1.8V,最大電流為40MA
#define?MAXCURR0_MAXCURR30 (10?<<?8) //對(duì)于3.0V,最大電流為40MA
#define?MAXCURR0_MAXCURR33 (10?<<?0) //對(duì)于3.3V,最大電流為40MA
//控制寄存器2?CONTROL2_0
#define?CONTROL2_0_ENSTAASYNCCLR (0?<<?31) //該位可以使正常和錯(cuò)誤中斷的異步明確啟用狀態(tài)位
#define?CONTROL2_0_ENCMDCNFMSK (0?<<?30) //不屏蔽指令沖突
#define?CONTROL2_0_CDINVRXD3 (0?<<?29) //卡檢測(cè)信號(hào)倒置對(duì)于RX_DAT[3]。禁止
#define?CONTROL2_0_SELCARDOUT (0?<<?28) //卡移除條件是“無卡插入”?狀態(tài)。
#define?CONTROL2_0_FLTCLKSEL (8?<<?24) //濾波器時(shí)鐘?(iFLTCLK)?選擇。
#define?CONTROL2_0_ENFBCLKTX (0?<<?15) //反饋時(shí)鐘禁止,對(duì)于發(fā)送數(shù)據(jù)時(shí)鐘
#define?CONTROL2_0_ENFBCLKRX (0?<<?14) //反饋時(shí)鐘禁止,對(duì)于接收數(shù)據(jù)時(shí)鐘
#define?CONTROL2_0_SDCDSEL (0?<<?13) //nSDCD?用于SD?卡檢測(cè)信號(hào)
#define?CONTROL2_0_SDSIGPC (0?<<?12) //同步控制輸出有效信號(hào)
#define?CONTROL2_0_ENBUSYCHKTXSTART?(0?<<?11) //發(fā)送數(shù)據(jù)啟動(dòng)狀態(tài)前忙碌狀態(tài)檢測(cè)。
#define?CONTROL2_0_DFCNT (0?<<?9) //反跳濾波器計(jì)數(shù)16?iSDCLK
#define?CONTROL2_0_ENCLKOUTHOLD (1?<<?8) //SDCLK?操作有效。
#define?CONTROL2_0_RWAITMODE (0?<<?7) //主機(jī)控制器釋放讀等待狀態(tài)(自動(dòng))
#define?CONTROL2_0_DISBUFRD (0?<<?6) //正常模式,用0x20?寄存器使用者可以讀緩沖區(qū)(FIFO)數(shù)據(jù)
//HCLK?=?128MHZ EPLL?=?24MHZ
#define?CONTROL2_0_SELBASECLK (2?<<?4) //基礎(chǔ)時(shí)鐘源選擇。00?或01?=?HCLK,10?=?EPLL?輸出時(shí)鐘(來自系統(tǒng))11?=?外部時(shí)鐘源(XTI?或XEXTCLk)
#define?CONTROL2_0_PWRSYNC (0?<<?3) //不同步,控制輸入有效信號(hào)(指令,數(shù)據(jù))
#define?CONTROL2_0_ENCLKOUTMSKCON (0?<<?1) //當(dāng)卡插入被清除時(shí),SDCLK?輸出時(shí)鐘屏蔽。當(dāng)處于無卡狀態(tài)時(shí),設(shè)置該區(qū)域?yàn)楦呶粊硗V筍DCLK。
#define?CONTROL2_0_HWINITFIN (1?<<?0) //SD?主機(jī)控制器硬件初始化完成。
//時(shí)鐘控制寄存器(0?通道)CLKCON0
#define?CLKCON0_SELFREQ (0x80?<<?8) //SDCLK頻率最低
#define?CLKCON0_ENSDCLK (1?<<?2) //SD?時(shí)鐘啟動(dòng)。
#define?CLKCON0_ENINTCLK (1?<<?0) //中斷時(shí)鐘啟動(dòng)。
//超時(shí)控制寄存器(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; //禁止上下拉
//時(shí)鐘控制寄存器配置
SDIO0->CLKCON?=?CLKCON0_SELFREQ?+?CLKCON0_ENSDCLK?+?CLKCON0_ENINTCLK;
//主機(jī)控制寄存器配置
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;
//超時(shí)控制寄存器(0?通道)
SDIO0->TIMEOUTCON =?0x0e; //超時(shí)設(shè)置最大
//電源控制寄存器配置
SDIO0->PWRCON?=?PWRCON0_SELPWRLVL?+?PWRCON0_PWRON;
//塊間隔寄存器
SDIO0->BLKGAP?=?0;
//開啟卡插入+卡移除+傳輸完成+指令完成中斷狀態(tài)+數(shù)據(jù)超時(shí)錯(cuò)誤+命令索引錯(cuò)誤+指令最后位錯(cuò)誤+指令超時(shí)錯(cuò)誤+指令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ā)送一個(gè)命令
*參數(shù)????????: CmdIdx:指令索引;CmdArg:命令參數(shù);CmdMisc:其它雜項(xiàng)設(shè)置,詳見說明
*返回????????: 無
*依賴????????:? 底層宏定義
*作者????????: 陳鵬
*時(shí)間????????: 20120507
*最后修改時(shí)間: 20120507
*說明????????: 寫SD命令寄存器;
指令索引:這些位設(shè)置為SD存儲(chǔ)卡物理層規(guī)范中指令格式的第40到45位和SDIO卡規(guī)范中指定的指令數(shù)(CMD0-63,?ACMD0-63)。
雜項(xiàng): SDIO_Type_Default 一般為0
SDIO_Type_Pend??????寫總線暫停
SDIO_Type_FS 功能選擇
SDIO_Type_IT 中斷模式
SDIO_CMDIndexEn?????SDIO指令索引使能
SDIO_CMDCrcEn???????SDIO指令CRC校驗(yàn)使能
SDIO_Response_No???????????無應(yīng)答
SDIO_Response_Short????????短應(yīng)答 48
SDIO_Response_Long????????長(zhǎng)應(yīng)答 136
SDIO_Response_ShortBusy????短應(yīng)答+檢測(cè)繁忙情況
*************************************************************************************************************************/
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)答
*依賴????????:? 底層宏定義
*作者????????: 陳鵬
*時(shí)間????????: 20120507
*最后修改時(shí)間: 20120507
*說明????????: 存放應(yīng)答數(shù)據(jù)的緩沖區(qū)為128BIT;4個(gè)32bit;
指令應(yīng)答。下表27-4為每一個(gè)應(yīng)答描述了從SD總線到寄存器的指令映射。在這個(gè)表中,在表中?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ù)
*?作者 : 陳鵬
*?時(shí)間 : 20120516
*?最后修改時(shí)間?:?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ù)
*?參數(shù) : SDCLK:設(shè)置SDIO時(shí)鐘分頻系數(shù)
*?返回 : SD_OK:成功,其它見SD?Card?Error?code.
*?依賴 : 底層寄存器操作函數(shù)
*?作者 : 陳鵬
*?時(shí)間 : 20120516
*?最后修改時(shí)間?:?20120516
*?說明 :? 高速基礎(chǔ)時(shí)鐘為50MHz
低速基礎(chǔ)時(shí)鐘為25MHz
*************************************************************************************************************************/
void?SDIO_CLKFrequencySelect(u8?SDCLK)
{
SDIO_SDClkDisable(); //時(shí)鐘停止
SDIO0->CAPAREG?&=?~(0x3f?<<?8); //清除設(shè)置
SDIO0->CAPAREG?|=?(50?<<?8); //這一位設(shè)置其實(shí)沒作用
SDIO0->CLKCON?&=?~(0xff?<<?8); //清除
SDIO0->CLKCON?|=?(SDCLK?<<?8); //設(shè)置基礎(chǔ)時(shí)鐘分頻系數(shù)
SDIO_SDClkEnable(); //時(shí)鐘使能
while(!(SDIO0->CLKCON?&?BIT0)); //等待時(shí)鐘穩(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ù)
*?作者 : 陳鵬
*?時(shí)間 : 20120516
*?最后修改時(shí)間?:?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í)鐘設(shè)置
*參數(shù)????????: Unit:超時(shí)時(shí)鐘單位選擇
TIME_OUT_UNIT_KHZ(0):超時(shí)時(shí)鐘單位為KHZ
TIME_OUT_UNIT_MHZ(1):超時(shí)時(shí)鐘單位為MHZ
Frequency:時(shí)鐘頻率:1~63
*返回????????: 返回應(yīng)答
*依賴????????:? 底層宏定義
*作者????????: 陳鵬
*時(shí)間????????: 20120521
*最后修改時(shí)間: 20120521
*說明????????: 配置指令超時(shí)時(shí)間
*************************************************************************************************************************/
void?SDIO_SetTimeOutClock(u8?Unit,u8?Frequency)
{
SDIO0->CAPAREG?&=?~(0xff); //清除原先設(shè)置
if(Unit) //配置超時(shí)時(shí)鐘單位: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?命令雜項(xiàng)設(shè)置 //SDIO響應(yīng)類型 #define?SDIO_Response_No????????????????????((u8)0) //無應(yīng)答 #define?SDIO_Response_Long??????????????????((u8)1) //長(zhǎng)應(yīng)答 136 #define?SDIO_Response_Short?????????????????((u8)2) //短應(yīng)答 48 #define?SDIO_Response_ShortBusy?????????????((u8)3) //短應(yīng)答+檢測(cè)繁忙情況 //其它設(shè)置 #define?SDIO_CMDIndexEn?????????????????????((u8)1?<<?4)//SDIO指令索引使能 #define?SDIO_CMDCrcEn???????????????????????((u8)1?<<?3)//SDIO指令CRC校驗(yàn)使能 #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) //傳輸完成。超時(shí)錯(cuò)誤優(yōu)先 #define?SDIO_FLAG_COMMANDEND ((u32)1?<<?0) //指令完成。超時(shí)錯(cuò)誤優(yōu)先 #define?SDIO_FLAG_ADMA ((u32)1?<<?25) //DMA錯(cuò)誤 #define?SDIO_FLAG_AUTOCMD12 ((u32)1?<<?24) //自動(dòng)CMD12錯(cuò)誤 #define?SDIO_FLAG_DATAENDBIT ((u32)1?<<?22) //數(shù)據(jù)最后位錯(cuò)誤 #define?SDIO_FLAG_DATACRC ((u32)1?<<?21) //數(shù)據(jù)CRC錯(cuò)誤 #define?SDIO_FLAG_DATATIMEOUT ((u32)1?<<?20) //數(shù)據(jù)超時(shí)錯(cuò)誤 #define?SDIO_FLAG_COMMANDINDEX ((u32)1?<<?19) //命令索引錯(cuò)誤 #define?SDIO_FLAG_COMMANDENDBIT ((u32)1?<<?18) //指令最后位錯(cuò)誤 #define?SDIO_FLAG_COMMANDCRC ((u32)1?<<?17) //指令CRC錯(cuò)誤 #define?SDIO_FLAG_COMMANDTIMEOUT ((u32)1?<<?16) //指令超時(shí)錯(cuò)誤 #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) //自動(dòng)CMD12命令啟動(dòng) #define?SDIO_AutoCMD12Enable() (SDIO0->TRNMOD?|=?BIT2) //自動(dòng)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) //塊計(jì)數(shù)器啟動(dòng) #define?SDIO_BlockCountEnable() (SDIO0->TRNMOD?|=?BIT1) //禁止塊計(jì)數(shù)器啟動(dòng) #define?SDIO_BlockCountDisable() (SDIO0->TRNMOD?&=?~(BIT1)) //DMA啟動(dòng) #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) //高速時(shí)鐘模式使能 #define?SDIO_HighSpeedEnable() (SDIO0->CAPAREG?|=?BIT21) //取消高速時(shí)鐘模式 #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時(shí)鐘 #define?SDIO_SDClkEnable() (SDIO0->CLKCON?|=?BIT2) //SD時(shí)鐘停止 #define?SDIO_SDClkDisable() (SDIO0->CLKCON?&=?~BIT2) //超時(shí)時(shí)鐘單位設(shè)置 #define?TIME_OUT_UNIT_KHZ 0 //超時(shí)時(shí)鐘單位為KHZ #define?TIME_OUT_UNIT_MHZ 1 //超時(shí)時(shí)鐘單位為MHZ //時(shí)鐘分頻系數(shù) #define?SDCLK_1_256? ((u8)0x80) //基礎(chǔ)時(shí)鐘256分頻 #define?SDCLK_1_128? ((u8)0x40) //基礎(chǔ)時(shí)鐘128分頻 #define?SDCLK_1_64? ((u8)0x20) //基礎(chǔ)時(shí)鐘64分頻 #define?SDCLK_1_32 ((u8)0x10) //基礎(chǔ)時(shí)鐘32分頻 #define?SDCLK_1_16? ((u8)0x08) //基礎(chǔ)時(shí)鐘16分頻 #define?SDCLK_1_8? ((u8)0x04) //基礎(chǔ)時(shí)鐘8分頻 #define?SDCLK_1_4? ((u8)0x02) //基礎(chǔ)時(shí)鐘4分頻 #define?SDCLK_1_2? ((u8)0x01) //基礎(chǔ)時(shí)鐘2分頻 #define?SDCLK_1_1 ((u8)0x00) //基礎(chǔ)時(shí)鐘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ū)動(dòng),SDIO?模式
//作者:陳鵬
//創(chuàng)建時(shí)間:2012-05-16?10:32
//修改時(shí)間:2012-05-16?10:32
//修訂說明:
//聲明:源程序借鑒了意法STM32F103X庫(kù)函數(shù)
********************************************************************************/
#include?"sdcard_sdio.h"
#include?"s3c6410_sdio.h"
#include?"s3c6410_system.h"
u8?SDMMC0_MOV_Flag?=?0; //sdmmc0卡移除信號(hào)有
/*
1.3?寄存器
名稱?寬度?描述
CID?128?卡標(biāo)識(shí)號(hào)
RCA?16?相對(duì)卡地址(Relative?card?address):本地系統(tǒng)中卡的地
址,動(dòng)態(tài)變化,在主機(jī)初始化的時(shí)候確定
*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í)計(jì)數(shù)器大小
#define?SDIO_READTIMEOUT 1000000 //讀等待超時(shí)
#define?SDIO_WRITETIMEOUT 2000000 //寫等待超時(shí)
//?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個(gè)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)??//時(shí)鐘分頻
/*?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ù)程序,用來檢測(cè)卡的插入與移除的
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ù)
*?作者 : 陳鵬
*?時(shí)間 : 20120516
*?最后修改時(shí)間?:?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ā)送錯(cuò)誤
{
DebugPrintf("SD?power?up?error:(%d)!n",errorstatus); //調(diào)試,打印錯(cuò)誤
return(errorstatus); //返回錯(cuò)誤
}
errorstatus?=?SD_InitializeCards();
if?(errorstatus?!=?SD_OK)
{
DebugPrintf("SD?initialize?error(%d)!n",errorstatus); //調(diào)試,打印錯(cuò)誤
return(errorstatus);
}
return(errorstatus);
}
/*************************************************************************************************************************
*?函數(shù) : SD_Error?SD_SetIdleSta(void)
*?功能 : SD卡上電進(jìn)入空閑模式,并識(shí)別卡
*?參數(shù) : 無
*?返回 : SD_OK:成功,其它見SD?Card?Error?code.
*?依賴 : 底層寄存器操作函數(shù)
*?作者 : 陳鵬
*?時(shí)間 : 20120516
*?最后修改時(shí)間?:?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è)置時(shí)鐘400KHZ
SDIO_SetTimeOutClock(TIME_OUT_UNIT_KHZ,1); //設(shè)置超時(shí)時(shí)鐘頻率最低
//發(fā)送至少74個(gè)時(shí)鐘,等待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就會(huì)執(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
?? //識(shí)別卡版本
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)試,打印錯(cuò)誤信息
}
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)試,打印錯(cuò)誤信息
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)試,打印錯(cuò)誤信息
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)初始化,直到返回成功或者超時(shí)
????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ù)
*?作者 : 陳鵬
*?時(shí)間 : 20120516
*?最后修改時(shí)間?:?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ù)
*?作者 : 陳鵬
*?時(shí)間 : 20120516
*?最后修改時(shí)間?:?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ù)
*?作者 : 陳鵬
*?時(shí)間 : 20120516
*?最后修改時(shí)間?:?20120516
*?說明 :? 將所有的卡進(jìn)行初始化配置
*************************************************************************************************************************/
SD_Error?SD_InitializeCards(void)
{
SD_Error?errorstatus?=?SD_OK;
u16?rca?=?0x01;
//發(fā)送CMD2?SDIO_ALL_SEND_CID命令,命令參數(shù):0;長(zhǎng)回復(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)試,打印錯(cuò)誤信息
return(errorstatus);
}
//到每個(gè)卡以獲取每個(gè)卡的唯一標(biāo)識(shí)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
//用來獲取卡地址
//主機(jī)發(fā)送CMD3(SEND_RELATIVE_ADDR)要求卡發(fā)布一個(gè)新的相對(duì)卡地址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)試,打印錯(cuò)誤信息
return(errorstatus);
????}
RCA?=?rca;//存儲(chǔ)卡地址
//發(fā)送CMD9?SDIO_SEND_CSD命令,參數(shù):rca地址;長(zhǎng)響應(yīng),R2;
//給卡發(fā)送一個(gè)新的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); 




