📄 sd.c
字号:
{
ST_MCARD_MAIL *sMcardRMail;
register ST_MCARD_DEV *pDev = ((ST_MCARD_DEV *) pMcardDev);
sMcardRMail = pDev->sMcardRMail;
McardSetClock(sInfo.dwClock);
Select();
switch (sMcardRMail->wCmd)
{
case INIT_CARD_CMD:
pDev->Flag.Detected = Ui_CheckSdPlugIn();
if (pDev->Flag.Detected)
{
MP_DEBUG("-I- SD Cardin & Detected");
//card in
sInfo.bInitFlag = FALSE;
sInfo.dwCardTag = MCARD_DMA_SD;
sInfo.dwBusWidth = DBUS_1BIT;
sInfo.dwClock = dwINITIAL_CLOCK;
McardSetClock(sInfo.dwClock);
pDev->Flag.Detected = 1;
MP_DEBUG("-I- SD GoTransferMode");
if ((pDev->swStatus = GoTransferMode()))
{
//pDev->Flag.Detected = 0;
pDev->Flag.Present = 0;
pDev->dwCapacity = 0;
pDev->wSectorSize = 0;
McardSetCurLun(pDev->dwLunNum, NULL_DEVICE);
}
else
{
MP_DEBUG("-I- SD GoTransferMode out");
pDev->wRenewCounter++;
pDev->Flag.ReadOnly = GetWPFlag();
pDev->Flag.Present = 1;
pDev->dwCapacity = sInfo.dwCapacity;
pDev->wSectorSize = MCARD_SECTOR_SIZE;
McardSetCurLun(pDev->dwLunNum, pDev->wMcardType);
//EventSet(UI_EVENT, EVENT_CARD_INIT);
}
MP_DEBUG("-I- SD init cmd pass");
}
else if (!(pDev->Flag.Detected))
{
//card out
pDev->Flag.Detected = 0;
pDev->Flag.Present = 0;
pDev->Flag.ReadOnly = 0;
pDev->Flag.PipeEnable = 0;
pDev->swStatus = 0;
pDev->dwCapacity = 0;
pDev->wSectorSize = 0;
McardSetCurLun(pDev->dwLunNum, NULL_DEVICE);
//EventSet(UI_EVENT, EVENT_CARD_INIT);
}
break;
case REMOVE_CARD_CMD: //Athena 03.11.2006 seperate card in & out
MP_DEBUG("sd remove");
//card out
pDev->Flag.Detected = 0;
pDev->Flag.Present = 0;
pDev->Flag.ReadOnly = 0;
pDev->Flag.PipeEnable = 0;
pDev->swStatus = 0;
pDev->dwCapacity = 0;
pDev->wSectorSize = 0;
McardSetCurLun(pDev->dwLunNum, NULL_DEVICE);
McardIODelay(2000); // solve cf command fail when mmc plug out
//EventSet(UI_EVENT, EVENT_CARD_INIT);
break;
case READ_PAGE_CMD:
pDev->swStatus =
FlatRead(sMcardRMail->dwBuffer, sMcardRMail->dwBlockCount, sMcardRMail->dwBlockAddr);
break;
case WRITE_PAGE_CMD:
pDev->swStatus =
FlatWrite(sMcardRMail->dwBuffer, sMcardRMail->dwBlockCount, sMcardRMail->dwBlockAddr);
break;
case FORMAT_CMD:
pDev->swStatus = Format();
break;
default:
MP_DEBUG("-E- INVALID CMD");
break;
}
DeSelect();
}
static void DeSelect(void)
{
register MCARD *sMcard;
sMcard = (MCARD *) (MCARD_BASE);
// sMcard->McardC = 0;
register GPIO *sGpio;
sGpio = (GPIO *) (GPIO_BASE);
#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600 )
#if((CHIP_VER & 0x0000ffff) == CHIP_VER_A)
sGpio->Fgpcfg[0] &= ~0x02000200;
sGpio->Fgpdat[0] |= 0x00200020;// gpio 9 clk
#elif(((CHIP_VER & 0x0000ffff) == CHIP_VER_B)||((CHIP_VER & 0x0000ffff) == CHIP_VER_C))
#if((STD_BOARD_VER == MP600PQFP_8M_SDRAM)||(STD_BOARD_VER == MP600_128PQFP_CPU_8M_SDRAM))
sGpio->Fgpcfg[0] &= ~0x02000200;
sGpio->Fgpdat[0] |= 0x00200020;// gpio 9 clk
#else
sGpio->Fgpcfg[1] &= ~0x00200020;
sGpio->Fgpdat[1] |= 0x00200020;// gpio 21 clk
#endif
#endif
#else
sGpio->Fgpcfg[2] &= ~0x40004000;
sGpio->Fgpdat[2] |= 0x40004000; // gpio 46 clk
#endif
}
static void DeSelectData(void)//
{
register GPIO *sGpio;
sGpio = (GPIO *) (GPIO_BASE);
sGpio->Fgpcfg[0] &= ~0x00ff00ff;
sGpio->Fgpdat[0] &= ~0x00ff00ff;
}
static void Select(void)
{
register MCARD *sMcard;
register GPIO *sGpio;
sGpio = (GPIO *) (GPIO_BASE);
sMcard = (MCARD *) (MCARD_BASE);
#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600 )
#if((CHIP_VER & 0x0000ffff) == CHIP_VER_A)
sGpio->Fgpcfg[0] |= 0x0000830f; // FGPIO[0] ~[3] : D0 ~D3, FGPIO[8],[9],[15] : CMD ,CLK,WP
sGpio->Fgpcfg[1] |= 0x00000004; //FGPIO[18] : CD
#elif(((CHIP_VER & 0x0000ffff) == CHIP_VER_B)||((CHIP_VER & 0x0000ffff) == CHIP_VER_C))
#if((STD_BOARD_VER == MP600PQFP_8M_SDRAM)||(STD_BOARD_VER == MP600_128PQFP_CPU_8M_SDRAM))
sGpio->Fgpcfg[0] |= 0x0000830f; // FGPIO[0] ~[3] : D0 ~D3, FGPIO[8],[9],[15] : CMD ,CLK,WP
sGpio->Fgpcfg[1] |= 0x00000004; //FGPIO[18] : CD
#else
sGpio->Fgpcfg[0] |= 0x0000010f; // FGPIO[0] ~[7] : D0 ~D7, FGPIO[8]: CMD
sGpio->Fgpcfg[1] |= 0x00000024; //FGPIO[18] : CD , FGPIO[21] : CLK
sGpio->Agpcfg &= ~ 0x00000010; // set Agpcfg 4 fun2 as sd wp
sGpio->Agpcfg |= 0x00100000; // set Agpcfg 4 fun2 as sd wp
#endif
#endif
#else
sGpio->Fgpcfg[0] |= GPIO_DEFINE_0; // FD8 ~ FD15 : D0 ~ D7
sGpio->Fgpcfg[1] |= GPIO_DEFINE_1; // FD18 : CMD
sGpio->Fgpcfg[2] |= GPIO_DEFINE_2; // FGPIO[46] : CLK
sGpio->Fgpcfg[3] |= GPIO_DEFILE_3; // FGPIO[55],[56] : CD, WP
#endif
sMcard->McWdt = WATCHDOG_TIMER;
sMcard->McWdt &=~ BIT21 ;
#if((STD_BOARD_VER == MP600PQFP_8M_SDRAM)||(STD_BOARD_VER == MP600_128PQFP_CPU_8M_SDRAM))
sMcard->McardC = MCARD_ENABLE + sInfo.dwCardTag + BIT11;
#else
sMcard->McardC = MCARD_ENABLE + sInfo.dwCardTag;
#endif
}
static BYTE GetWPFlag(void)
{
register GPIO *sGpio;
sGpio = (GPIO *) (GPIO_BASE);
#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600)
#if((CHIP_VER & 0x0000ffff) == CHIP_VER_A)
return ((sGpio->Fgpdat[0] & 0x00008000) ? 1 : 0); // M600 Fgpio15 as Sd WP#
#elif (((CHIP_VER & 0x0000ffff) == CHIP_VER_B)||((CHIP_VER & 0x0000ffff) == CHIP_VER_C))
return ((sGpio->Agpdat & 0x00000010) ? 1 : 0);
#endif
#else
return ((sGpio->Fgpdat[3] & 0x100) ? 1 : 0);
#endif
}
static void SetClockSpeed(DWORD dwSpeed)
{
DWORD dwIndex;
for (dwIndex = dwSD_MMC_MAX_CLOCK; dwIndex >= dwSD_MMC_MIN_CLOCK; dwIndex--)
{
if (sClockSpeedTable[dwIndex].dwClockValue <= dwSpeed)
{
break;
}
}
MP_DEBUG2("setting clock: %d Hz, Value =%d", sClockSpeedTable[dwIndex].dwClockValue,sClockSpeedTable[dwIndex].bSettingValue);
sInfo.dwClock = sClockSpeedTable[dwIndex].bSettingValue;
McardSetClock(sInfo.dwClock);
}
static SWORD GoTransferMode(void)
{
#define MAX_RETRY_TIMES 1
register MCARD *sMcard;
DWORD dwResp, dwParam, dwReadBlLen, dwCSizeMult, dwCSize, dwTryCount, dwSpeed;
SWORD swRetValue;
BYTE bVersion, bRetryTimes,bCCS=0,bHCS=0;
BYTE *pbBuffer1;
BYTE bTempMemID0;
sMcard = (MCARD *) (MCARD_BASE);
#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600 )
DeSelectData();
#endif
if (sInfo.bInitFlag == FALSE)
{
sMcard->McSdC = 0;
#if((STD_BOARD_VER == MP600PQFP_8M_SDRAM)||(STD_BOARD_VER == MP600_128PQFP_CPU_8M_SDRAM))
sMcard->McardC = MCARD_ENABLE + sInfo.dwCardTag + BIT11;
#else
sMcard->McardC = MCARD_ENABLE + sInfo.dwCardTag;
#endif
}
bRetryTimes = MAX_RETRY_TIMES;
swRetValue = SD_PASS;
do
{
if (swRetValue != SD_PASS)
{
bRetryTimes--;
swRetValue = SD_PASS;
MP_DEBUG2("-E- MMC/SD Init Failed: Trial %d out of %d", bRetryTimes, MAX_RETRY_TIMES);
}
// at the IDLE state, issus the APP command, if MMC inserted, it will not response
SetCommand(CMD_GO_IDLE_STATE, 0);
OpenDrainDelay();
WaitHostReady();
// if (sInfo.bInitFlag == TRUE)
// {
SetCommand(CMD_GO_IDLE_STATE, 0);
OpenDrainDelay();
WaitHostReady();
sInfo.dwClock = dwINITIAL_CLOCK;
McardSetClock(sInfo.dwClock);
OpenDrainDelay();
sInfo.dwCardTag = MCARD_DMA_SD;
#if((STD_BOARD_VER == MP600PQFP_8M_SDRAM)||(STD_BOARD_VER == MP600_128PQFP_CPU_8M_SDRAM))
sMcard->McardC = MCARD_ENABLE + sInfo.dwCardTag + BIT11;
#else
sMcard->McardC = MCARD_ENABLE + sInfo.dwCardTag;
#endif
sInfo.dwBusWidth = DBUS_1BIT;
sInfo.bInitFlag = FALSE;
SetCommand(CMD_GO_IDLE_STATE, 0);
OpenDrainDelay();
WaitHostReady();
// }
dwTryCount = 1;
while (dwTryCount)
{
WaitHostReady();
MP_DEBUG("Send OP Cmd for MMC");
SetCommand(CMD_SEND_OP_COND, HOST_OCR_VALUE);
OpenDrainDelay();
if(WaitResponse() == PASS)
MP_DEBUG1("SD op condition = ",sMcard->McSdRspA);
swRetValue = WaitResponse();
dwTryCount--;
}
if (swRetValue)
{
MP_DEBUG("sd card");
sInfo.bType = SD_TYPE;
// send OP_COND command for getting into READY state
dwTryCount = 1000;
#ifdef SDHC_FLAG // SDHC
MP_DEBUG("Send command 8 for SDHC");
SetCommand(CMD_SEND_IF_COND,0x000001aa);
OpenDrainDelay();
OpenDrainDelay();
WaitHostReady();
if ((swRetValue = WaitResponse()))
{
dwResp = sMcard->McSdRspA;
}
dwResp = sMcard->McSdRspA;
if((sMcard->McSdRspA & 0xff) == SDHC_CHECK_PATTERN)
{
bHCS = 1;
}
#endif
do
{
dwResp = 0;
dwTryCount--;
SetCommand(CMD_APP_COM, 0);
OpenDrainDelay();
OpenDrainDelay();
WaitHostReady();
if ((swRetValue = WaitResponse()))
{
continue;
}
#ifdef SDHC_FLAG // SDHC
if (bHCS == 1)
SetCommand(ACMD_SD_APP_OP_COND, HOST_OCR_VALUE|HCS);
else
#endif
SetCommand(ACMD_SD_APP_OP_COND,HOST_OCR_VALUE);
OpenDrainDelay();
OpenDrainDelay();
WaitHostReady();
if ((swRetValue = WaitResponse()))
{
continue;
}
dwResp = sMcard->McSdRspA;
}
while (!(dwResp >> 31) && (dwTryCount > 0));
#ifdef SDHC_FLAG
if(dwResp & HCS)
bCCS =1;
#endif
MP_DEBUG1("SD dwResp = %x", dwResp);
// while card is still busy, keep sending OP_COND command
if (swRetValue != SD_PASS)
{
MP_DEBUG("-E- ACMD_SD_APP_OP_COND FAIL");
continue;
}
SetCommand(CMD_ALL_SEND_CID, 0);
OpenDrainDelay();
WaitHostReady();
if ((swRetValue = WaitResponse()))
{
MP_DEBUG1("-E- CMD_ALL_SEND_CID FAIL (swRetValue: %d)", swRetValue);
continue;
}
// send the host designating RCA to card and change to STANDBY state
SetCommand(CMD_SEND_RELATIVE_ADDR, 0);
OpenDrainDelay();
if ((swRetValue = WaitHostReady()))
{
MP_DEBUG1("-E- CMD_SEND_RELATIVE_ADDR FAIL (swRetValue: %d)", swRetValue);
continue;
}
sInfo.dwRelativeCardAddr = sMcard->McSdRspA;
sInfo.dwRelativeCardAddr &= 0xffff0000;
MP_DEBUG1("dwRelativeCardAddr = %x", sInfo.dwRelativeCardAddr);
}
else
{
sInfo.bType = MMC_TYPE;
MP_DEBUG("mmc card");
IODelay(1000); // rick add for mmc detect fail issue
sInfo.dwCardTag = MCARD_DMA_MMC;
#if((STD_BOARD_VER == MP600PQFP_8M_SDRAM)||(STD_BOARD_VER == MP600_128PQFP_CPU_8M_SDRAM))
sMcard->McardC = MCARD_ENABLE + sInfo.dwCardTag + BIT11;
#else
sMcard->McardC = MCARD_ENABLE + sInfo.dwCardTag;
#endif
dwTryCount = 100;
do
{
dwTryCount--;
dwResp = 0;
SetCommand(CMD_SEND_OP_COND, HOST_OCR_VALUE);
OpenDrainDelay();
OpenDrainDelay();
WaitHostReady();
if ((swRetValue = WaitResponse()))
{
continue;
}
dwResp = sMcard->McSdRspA;
}
while (!(dwResp >> 31) && (dwTryCount > 0));
MP_DEBUG1("mmc op condition = %x", dwResp);
if (swRetValue != SD_PASS)
{
MP_DEBUG("-E- CMD_SEND_OP_COND FAIL");
continue;
}
SetCommand(CMD_ALL_SEND_CID, 0);
OpenDrainDelay();
WaitHostReady();
if ((swRetValue = WaitResponse()))
{
MP_DEBUG1("-E- CMD_ALL_SEND_CID FAIL (swRetValue: %d)", swRetValue);
continue;
}
// send the host designating RCA to card and change to STANDBY state
sInfo.dwRelativeCardAddr = MMC_DEFAULT_ADDR;
SetCommand(CMD_SEND_RELATIVE_ADDR, sInfo.dwRelativeCardAddr);
OpenDrainDelay();
WaitHostReady();
if ((swRetValue = WaitResponse()))
{
MP_DEBUG1("-E- CMD_SEND_RELATIVE_ADDR FAIL (swRetValue: %d)", swRetValue);
continue;
}
MP_DEBUG1("dwRelativeCardAddr = %x", sInfo.dwRelativeCardAddr);
}
#if ((CHIP_VER & 0xffff0000) == CHIP_VER_600 )
Select();
#endif
// get the Card Specific Register
SetCommand(CMD_SEND_CSD, sInfo.dwRelativeCardAddr);
OpenDrainDelay();
WaitHostReady();
if ((swRetValue = WaitResponse()))
{
MP_DEBUG1("-E- CMD_SEND_CSD FAIL (swRetValue: %d)", swRetValue);
continue;
}
if(bCCS == 0)
{
// calculate the card capacity
dwResp = sMcard->McSdRspB;
dwReadBlLen = (dwResp & 0x000f0000) >> 16;
dwCSize = (dwResp & 0x000003ff) << 2;
dwResp = sMcard->McSdRspC;
dwCSize += ((dwResp >> 30) + 1);
dwCSizeMult = ((dwResp & 0x00038000) >> 15) + 2;
sInfo.dwCapacity =
((1 << dwReadBlLen) * ((1 << dwCSizeMult) * dwCSize)) / MCARD_SECTOR_SIZE;
}
else
{
sInfo.bType = SDHC_TYPE;
bVersion = (sMcard->McSdRspA &0xc0000000)>>30;
dwReadBlLen = (sMcard->McSdRspB & 0x000f0000)>>16;
dwCSize = (sMcard->McSdRspC & 0xffff0000)>>16;
dwCSize +=1;
sInfo.dwCapacity = (dwCSize / MCARD_SECTOR_SIZE)*(1<<(dwReadBlLen+10));
MP_DEBUG1(" SDHC Capacity = %d",sInfo.dwCapacity);
}
dwResp = sMcard->McSdRspA;
#ifdef ENABLE_CHACK_TACC_MECHANISM
// if TAAC less than 1ms, not ues multiblock read
if (((dwResp & 0x00060000) >> 17) == 3)
{
sInfo.bMultiReadFlag = 1;
}
else
{
sInfo.bMultiReadFlag = 0;
}
#endif
// if mmc card get spec version.
if (sInfo.dwCardTag == MCARD_DMA_MMC)
{
bVersion = (dwResp & 0x3c000000) >> 26;
MP_DEBUG1("MMC Version = %x", bVersion);
}
else
{
bVersion = 0;
}
//change frequency
dwResp = (sMcard->McSdRspA & 0xff);
sInfo.dwSpeed = (dwSpeedUnit[(dwResp & 0x7)] * bSpeedFactor[((dwResp & 0xf8) >> 3)]) / 10;
MP_DEBUG1("card max speed = %d kHz", sInfo.dwSpeed);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -