对于SD卡的代码初始化部分如下:
SDC_CMD_STATUS SD_Initialize(void)
{
kal_uint32 cid[4],csd[4],scr[4];
kal_uint16 rca;
SDC_CMD_STATUS status;
#ifdef __CARD_DOWNLOAD__
if (MSDC_QueryIsPowerControllable())
{
MSDC_SetPower(KAL_FALSE);
kal_sleep_task(2);
MSDC_SetPower(KAL_TRUE);
}
#else//__CARD_DOWNLOAD__
#ifdef __DRV_MSDC_VMC_FROM_PMIC__
//if we don't use DAT3 for carddetection and uses PMIC_VMC as power source, we can switch it off then on for HW reset
#if !defined(__MSDC_TFLASH_DAT3_1BIT_HOT_PLUG__)
#ifdef PMIC_6318_REG_API
pmic_vmc_enable(KAL_FALSE);
kal_sleep_task(2);
pmic_vmc_enable(KAL_TRUE);
#endif
#if defined(PMIC_6235_REG_API)||defined(PMIC_6238_REG_API)
// Add by GuoXin
pmu_set_vbt_en(KAL_FALSE);
kal_sleep_task(2);
pmu_set_vbt_en(KAL_TRUE);
// Add by GuoXin
#endif
#endif
#endif//__DRV_MSDC_VMC_FROM_PMIC__
#endif//__CARD_DOWNLOAD__
//add by songshan
#if (defined(AVANTECH6239_DEMO_BB)||defined(__LIPTON_REV_B__))
GPIO_WriteIO(0, GPIO_EXT_SD_LDO_SWITCH);
kal_sleep_task(2);
GPIO_WriteIO(1, GPIO_EXT_SD_LDO_SWITCH);
#endif
//add by songshan
if(msdc_custom_handle.PowerCtrl)
{
msdc_custom_handle.PowerCtrl(KAL_FALSE);
kal_sleep_task(2);
msdc_custom_handle.PowerCtrl(KAL_TRUE);
}
if(gMSDC_Handle->mIsInitialized == KAL_TRUE)
{
return NO_ERROR;
}
#ifndef __UBL__
#ifdef __TST_WRITE_TO_FILE__ /*error recording: considering error recording additionally*/
if(KAL_FALSE == INT_QueryExceptionStatus())
#endif
// reset the events
kal_set_eg_events(gMSDC_Handle->MSDC_Events, 0, KAL_AND);
#else//__UBL__
// TODO: [Samuel]
#endif//__UBL__
// reset msdc
#ifndef DRV_LSD
if(MSDC_Reg32(MSDC_CFG) & MSDC_CFG_RST)
#else
ASSERT(LSD_Support());
if(LSD_Reg32(MSDC_CFG) & MSDC_CFG_RST)
#endif
{
MSDC_LSD_ClearBits32(MSDC_CFG, MSDC_CFG_RST);
}
else
{
RESET_MSDC();
}
//#if defined(MT6225)
#if defined(DRV_MSDC_MT6225_SERIES)
MSDC_LSD_SetBits32(MSDC_CFG,MSDC_CFG_CRED);
#endif
// set the output driving capability from customization interface
#if defined(__SIM_PLUS__)
#if defined(DRV_MSDC_MT6225_SERIES)
MSDC_LSD_WriteReg32(MSDC_IOCON,0x2DB);
#else
MSDC_LSD_WriteReg(MSDC_IOCON,0x2DB);
#endif
#else
#if defined(DRV_MSDC_MT6225_SERIES)
MSDC_SetData32(MSDC_IOCON, 0xff, MSDC_GetIOCtrlParam());
#else
MSDC_SetData(MSDC_IOCON, 0xff, MSDC_GetIOCtrlParam());
#endif
#endif//__SIM_PLUS__
// set read timeout x5ms
/*in 50MHZ case, we should set 80 to have at least 100ms timeout*/
BitFieldWrite32((kal_uint32*)SDC_CFG,(kal_uint32)80,SDC_CFG_DTOC);
//set clock of serial clcok for initialization
#ifndef DRV_LSD
MSDC_LSD_ClearBits32(MSDC_CFG, MSDC_CFG_CLKSRC);
gMSDC_Handle->msdc_clock = MSDC_CLOCK;
MSDC_SetClock(MSDC_INI_CLOCK);
#else
LSD_HostSetClock(LSD_SPEED_INIT);
#endif
// disable 4-bit
MSDC_LSD_ClearBits32(SDC_CFG,SDC_CFG_MDLEN);
// initial global sturctures
SD_SetDefault();
MSDC_SetIOCONRegDLT();
#if defined(DRV_MSDC_IOCON_V2)
MSDC_WriteReg32(MSDC_IOCON1, 0x22222);
#endif//#if defined(DRV_MSDC_IOCON_V2)
#if defined(__SIM_PLUS__)
// turn on the power of the MMC of the SIM+
if(INT_USBBoot() == KAL_TRUE && current_card == SD_SIM)
{
static kal_bool is_first = KAL_TRUE;
if(is_first)
{
is_first = KAL_FALSE;
GPIO_WriteIO(1, GPIO_LDO_SWITCH);
GPTI_BusyWait(300);
}
}
#endif
#ifdef DRV_MSDC_ENHANCED_PULL_CTRL
MSDC_SetBits32(MSDC_CFG, 0x0c000000);
#endif
#ifdef DRV_LSD
LSD_Host74TCMDHigh();
#else
/* enable 74 SD clk by s/w */
MSDC_SetBits32(MSDC_CFG, 0x80);
{
kal_uint32 i;
for(i=0;i<100000;i++);
}
/* stop SD clk by s/w */
MSDC_ClearBits32(MSDC_CFG, 0x80);
#endif
// send the card to IDLE state
status = SD_Reset();
SD_INITIALIZE_STATUS_CHECK();
// and validate the OCR (CMD0,CMD1 or ADMD41)
if(SD_CheckSDorMMC() == UNKNOWN_CARD)
{
SD_TRACE2(TRACE_GROUP_5, MSDC_GENERAL_FAIL, MSDC_DRV_TRC_FILE_SD, __LINE__);
status = ERR_STATUS;
goto err;
}
// get CID(CMD2)
status = SD_GetCID(cid);
SD_INITIALIZE_STATUS_CHECK();
// get or set RCA(CMD3)
status = SD_ValidateRCA(&rca);
SD_INITIALIZE_STATUS_CHECK();
// get CSD and analysis the CSD(CMD9)
status = SD_GetCSD(gSD->mRCA,csd);
SD_INITIALIZE_STATUS_CHECK();
// Set driver stage register DSR to default value (0x0404)(CMD4)
if(gSD->mCSD.dsr_imp)
if((status = SD_SetDSR())!=NO_ERROR)
{
//dbg_print("6\r\n");
SD_TRACE2(TRACE_GROUP_5, MSDC_GENERAL_FAIL, MSDC_DRV_TRC_FILE_SD, __LINE__);
goto err;
}
#ifndef DRV_LSD
#if !defined(__MSDC_NO_WRITE_PROTECT__)
// check write proctect switch(WP at SDC_STA)
#if defined(__SIM_PLUS__)
if(current_card == SD_EXT)
#endif
{
if((MSDC_Reg(SDC_STA) & SDC_STA_WP))
gSD->mWPEnabled = KAL_TRUE;
}
#endif
#endif
// select the card (CMD7) ,maybe locked
status = SD_SelectCard(gSD->mRCA);
SD_INITIALIZE_STATUS_CHECK();
if(status == CARD_IS_LOCKED)
gSD->mIsLocked = KAL_TRUE;
#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
if(gSD->flags & SD_FLAG_SD_TYPE_CARD)
#else
if(gMSDC_Handle->mMSDC_type == SD_CARD)
#endif
{
#if defined(MSDC_USE_USB_CLK) && !defined(__SIM_PLUS__)
SD_Use24M_Clock();
MSDC_SetIOCONRegDLT();
#else
#ifndef DRV_MSDC_CLK_SEARCH
/*JRD SIM+ issue on 2007_03_08, JRD data line signal not stable, we can't use 24M even without SIM+ existence*/
if((!MSDC_Blk[SD_SIM].mIsInitialized) && (MSDC_24M == MSDC_GetClockWithoutSIMPlus()))
SD_Use24M_Clock();
else
SD_Use13M_Clock();
#endif
#endif
status = SD_ReadSCR(scr);
SD_INITIALIZE_STATUS_CHECK();
#if defined(MSDC_SD_BITS4_BUS)
if(KAL_FALSE == gMSDC_Handle->trySingleLine){
status = SD_SetBusWidth(BIT_4W);
SD_INITIALIZE_STATUS_CHECK();
}
#endif
#if !defined(__MSDC_TFLASH_DAT3_1BIT_HOT_PLUG__)
status = SD_Acmd42(KAL_FALSE);
SD_INITIALIZE_STATUS_CHECK();
#endif
if(gSD->flags & SD_FLAG_CMD6_SUPPORT)
{
status = SD_SelectHighSpeed_SD11();
if(status == NO_ERROR)
{
dbg_print("SD_SelectHighSpeed_SD11 fail\r\n");
gSD->flags |= SD_FLAG_HS_ENABLED;
//1 NEED to Modify such as using 48M clock
#ifndef DRV_MSDC_CLK_SEARCH
MSDC_LSD_ClearBits32(MSDC_CFG, MSDC_CFG_CLKSRC);
gMSDC_Handle->msdc_clock = MSDC_CLOCK;
MSDC_SetClock(26000);
MSDC_SetIOCONRegDLT();
#endif
}
}
}
else
{
#if defined(MSDC_MMC40_SUPPORT)
if((gMSDC_Handle->mMSDC_type == MMC_CARD || gMSDC_Handle->mMSDC_type == MMC42_CARD) && gSD->mCSD.spec_ver >= 4)
{
if(gMSDC_Handle->mMSDC_type == MMC_CARD)/*we don't need to change MMC42_CARD to MMC40_CARD*/
gMSDC_Handle->mMSDC_type = MMC40_CARD;
status = SD_SetMMC40_bus_high_speed();
SD_INITIALIZE_STATUS_CHECK();
}
else
#endif
{
SD_Use13M_Clock();
MSDC_SetIOCONRegDLT();
}
}
//! patch for MT6268/6253/6516 and later chips
#if defined(DRV_MSDC_IOCON_MT6268_SERIES)
BitFieldWrite32((kal_uint32*)MSDC_IOCON, 1, MSDC_IOCON_CMDSEL);
#endif
#ifdef DRV_MSDC_CLK_SEARCH
if(KAL_FALSE == SD_tuneCLK2())
SD_TRACE2(TRACE_GROUP_5, MSDC_ERROR_TUNECLKFAIL, MSDC_Reg32(MSDC_CFG), MSDC_Reg32(MSDC_IOCON));
#endif
#ifdef __MSDC_BASIC_LOAD__
if(0 == (gSD->flags & SD_FLAG_HCS_SUPPORT)){
/*here we test non 4N trasnfer in DVT basic load*/
/*read sector 0 to buffer*/
status = SD_SetBlength(512);
SD_ReadSingleBlock(0, MSDC_Sector);
if(msdcOddNumberSizeTestByDMA){
status = SD_SetBlength(11);
SD_ReadSingleBlock(0, msdc_testBuffer);
}
msdcTransferLengthTest(100, (kal_uint8 *)MSDC_Sector, 0);
msdcTransferLengthTest(11, (kal_uint8 *)MSDC_Sector, 0);
msdcTransferLengthTest(10, (kal_uint8 *)MSDC_Sector, 0);
msdcTransferLengthTest(9, (kal_uint8 *)MSDC_Sector, 0);
/*because some card can support partial block size read, but can't support partial size write*/
if(1 == gSD->mCSD.w_blk_part){
msdcWriteLengthTest(9, (kal_uint8 *)MSDC_Sector, 0, KAL_FALSE);
msdcWriteLengthTest(10, (kal_uint8 *)MSDC_Sector, 0, KAL_FALSE);
msdcWriteLengthTest(11, (kal_uint8 *)MSDC_Sector, 0, KAL_FALSE);
msdcWriteLengthTest(11, (kal_uint8 *)MSDC_Sector, 0, KAL_TRUE);
kal_print("non-4N transfer write verified okay");
}
kal_print("non-4N transfer verified okay");
}
#endif
// set block length (CMD16)
status = SD_SetBlength(512);
SD_INITIALIZE_STATUS_CHECK();
err:
if(status != NO_ERROR)
{
kal_print("SD mount fail!");
SD_SetDefault();
gMSDC_Handle->mIsInitialized = KAL_FALSE;
}
else
{
kal_print("SD mount ok!");
gMSDC_Handle->mIsInitialized = KAL_TRUE;
}
kal_set_eg_events(gMSDC_Handle->MSDC_Events, 0, KAL_AND);
return status ;
}
调CLK的代码如下:
kal_bool SD_tuneCLK2()
{
.........
for(cs.clksrc = 0; cs.clksrc<MSDC_CLKSRC_NUM; cs.clksrc ++)
{
}
.........
}
本文出自 “关于MTK平台知识” 博客,谢绝转载!