📄 sd.c
字号:
SetClockSpeed(sInfo.dwSpeed);
// change to TRANSFER state
SetCommand(CMD_SELECT_CARD, sInfo.dwRelativeCardAddr);
OpenDrainDelay();
WaitHostReady();
if ((swRetValue = WaitResponse()))
{
MP_DEBUG1("-E- CMD_SELECT_CARD FAIL (swRetValue: %d)", swRetValue);
continue;
}
if (sInfo.dwCardTag == MCARD_DMA_SD)
{
SetCommand(CMD_APP_COM, sInfo.dwRelativeCardAddr);
OpenDrainDelay();
if ((swRetValue = WaitResponse()))
{
MP_DEBUG1("-E- CMD_APP_COM FAIL (swRetValue: %d)", swRetValue);
continue;
}
WaitHostReady();
SetCommand(ACMD_SET_BUS_WIDTH, 2);
OpenDrainDelay();
WaitHostReady();
if ((swRetValue = WaitResponse()))
{
MP_DEBUG1("-E- ACMD_SET_BUS_WIDTH FAIL (swRetValue: %d)", swRetValue);
continue;
}
sInfo.dwBusWidth = DBUS_4BIT;
}
else
{
#ifdef HW_SUPPORT_MMC_4_0
if (bVersion == MMC_VER_4_0)
{
MP_DEBUG1("MMC_BUS_WIDTH = %d", MMC_BUS_WIDTH);
//access | index | value | command set
dwParam = (0x03 << 24) | (0xB7 << 16) | (MMC_BUS_WIDTH << 8) | 0x00;
SetCommand(CMD_SWITCH, dwParam);
OpenDrainDelay();
if ((swRetValue = WaitResponse()))
{
MP_DEBUG1("-E- CMD_SWITCH FAIL (swRetValue: %d)", swRetValue);
continue;
}
WaitHostReady();
OpenDrainDelay();
OpenDrainDelay();
OpenDrainDelay();
OpenDrainDelay();
#if (MMC_BUS_WIDTH == 1)
sInfo.dwBusWidth = DBUS_4BIT;
MP_DEBUG("-I- MMC transfer bus width to 4 bit");
#elif (MMC_BUS_WIDTH == 2)
sInfo.dwBusWidth = DBUS_8BIT;
MP_DEBUG("-I- MMC transfer bus width to 8 bit");
#else
sInfo.dwBusWidth = DBUS_1BIT;
MP_DEBUG("-I- MMC transfer bus width to 1 bit");
#endif
/*
McardIODelay(500);
SetBlockLen(MCARD_SECTOR_SIZE);
bTempMemID0 = OsTempMemAllocateMCARD();
pbBuffer1 = GetOsTempMemoryMCARD(bTempMemID0);
SetDataDma(pbBuffer1, (1 << MCARD_SECTOR_BIT_OFFSET),MCARD_DMA_DIR_CM);
SetCommand(CMD_SEND_EXT_CSD, sInfo.dwRelativeCardAddr);
OpenDrainDelay();
WaitHostReady();
if ((swRetValue = WaitResponse()))
{
OsTempMemRelease(bTempMemID0);
MP_DEBUG1("-E- CMD_SEND_EXT_CSD FAIL (swRetValue: %d)", swRetValue);
continue;
}
if ((swRetValue = WaitDataRead()) != SD_PASS)
{
OsTempMemRelease(bTempMemID0);
MP_DEBUG1("-E-EXT_CSD Command Wait Data End FAIL (swRetValue: %d)", swRetValue);
continue;
}
if(pbBuffer1[183] != MMC_BUS_WIDTH)
{
MP_DEBUG1("-E-EXT_CSD Command check bus width FAIL (swRetValue: %d)", swRetValue);
OsTempMemRelease(bTempMemID0);
#if 1
dwParam = (0x03 << 24) | (0xB7 << 16) | (0 << 8) | 0x00;
SetCommand(CMD_SWITCH, dwParam);
OpenDrainDelay();
if ((swRetValue = WaitResponse()))
{
MP_DEBUG1("-E- CMD_SWITCH FAIL (swRetValue: %d)", swRetValue);
continue;
}
WaitHostReady();
sInfo.dwBusWidth = DBUS_1BIT;
#endif
}
OsTempMemRelease(bTempMemID0);
*/
}
else
{
MP_DEBUG("-I- Only Support MMC 1 bit");
}
#else
MP_DEBUG("-I- Only Support MMC 1 bit");
#endif
}
// set BLOCK length
SetBlockLen(MCARD_SECTOR_SIZE);
#if SD_RW_COMPARE
if(sInfo.bType == SD_TYPE)
SD_READ_WRITE_COMPARE();
#endif
if (swRetValue == SD_PASS)
{
sInfo.bInitFlag = TRUE;
return swRetValue;
}
}
while (bRetryTimes > 0);
return GENERAL_FAIL;
}
static void SetCommand(WORD wCommand, DWORD dwArgument)
{
register MCARD *sMcard;
sMcard = (MCARD *) (MCARD_BASE);
sMcard->McSdC = (wCommand & 0x3f) + sInfo.dwBusWidth+BIT8;
sMcard->McSdArg = dwArgument;
sMcard->McSdIc = IM_ALL;
sMcard->McSdOp = (wCommand >> 8);
}
static SWORD WaitHostReady(void)
{
register MCARD *sMcard;
DWORD dwTimeOut;
sMcard = (MCARD *) (MCARD_BASE);
dwTimeOut = 10000;
OpenDrainDelay();
while (dwTimeOut)
{
//if (Polling_SD_Status()) return GENERAL_FAIL;
if (!(sMcard->McSdC & FSMBUSY))
{
return SD_PASS;
}
TASK_YIELD();
dwTimeOut--;
}
return GENERAL_FAIL;
}
static void OpenDrainDelay(void)
{
DWORD dwCounter;
dwCounter = dwOPEN_DRAIN_DELAY_1;
while (dwCounter)
{
dwCounter--;
}
if (sInfo.dwClock != dwINITIAL_CLOCK)
{
return;
}
dwCounter = dwOPEN_DRAIN_DELAY_2;
while (dwCounter)
{
dwCounter--;
}
}
static SWORD WaitResponse(void)
{
register MCARD *sMcard;
DWORD dwTimeOut, dwCause;
sMcard = (MCARD *) MCARD_BASE;
dwTimeOut = 10000000;
// OpenDrainDelay();
while (!(sMcard->McSdIc & IC_RSPDONE))
{
//if (Polling_SD_Status()) return GENERAL_FAIL;
if (dwTimeOut == 0)
{
//MP_DEBUG("-E- IC_RSPDONE fail");
return RES_TIMEOUT;
}
dwTimeOut--;
}
dwCause = sMcard->McSdIc;
if (dwCause & IC_RSPF)
{
MP_DEBUG("-E- IC_RSPF fail");
if (dwCause & IC_CRC16F)
{
MP_DEBUG("-E- IC_CRC16F fail");
return BAD_CRC16;
}
else if (dwCause & IC_CRC7F)
{
MP_DEBUG("-E- IC_CRC7F fail");
return BAD_CRC7;
}
else if (dwCause & IC_SDTO)
{
MP_DEBUG("-E- IC_SDTO fail");
return RES_TIMEOUT;
}
else if ((dwCause & IC_PGMF) || (dwCause & IC_WXF))
{
MP_DEBUG("-E- IC_PGMF or IC_WXF fail");
return PROGRAM_FAIL;
}
else
{
return PROGRAM_FAIL;
}
}
return SD_PASS;
}
static SWORD SetBlockLen(DWORD dwBlockLen)
{
register MCARD *sMcard;
DWORD dwTimeOut, dwCause;
sMcard = (MCARD *) (MCARD_BASE);
sMcard->McSdC = (CMD_SET_BLOCKLEN & 0x3f) + sInfo.dwBusWidth+BIT8; // set command index with current bus width setting
sMcard->McSdArg = dwBlockLen; // set argument
sMcard->McSdOp = CMD_SET_BLOCKLEN >> 8; // enable operation
dwTimeOut = 0xf0000000;
OpenDrainDelay();
while (dwTimeOut)
{
//if (Polling_SD_Status()) return RES_TIMEOUT;
dwCause = sMcard->McSdIc;
if (dwCause & IC_RSPDONE)
{
return SD_PASS;
}
dwTimeOut--;
}
MP_DEBUG1("-E- SetBlockLen FAIL (status: %x)", dwCause);
return RES_TIMEOUT;
}
static SWORD SelCard(void)
{
register MCARD *sMcard;
DWORD dwTimeOut, dwCause;
sMcard = (MCARD *) (MCARD_BASE);
sMcard->McSdC = (CMD_SELECT_CARD & 0x3f) + sInfo.dwBusWidth+BIT8;
sMcard->McSdArg = sInfo.dwRelativeCardAddr; // set argument
sMcard->McSdOp = (CMD_SELECT_CARD >> 8); // enable operation
dwTimeOut = 1000;
OpenDrainDelay();
while (dwTimeOut)
{
dwCause = sMcard->McSdIc;
if (dwCause & IC_RSPDONE)
{
return SD_PASS;
}
dwTimeOut--;
}
MP_DEBUG1("-E- SelCard FAIL (status: %x)", dwCause);
return RES_TIMEOUT;
}
static void TimeoutHandle(void)
{
register CHANNEL *sChannel;
sChannel = (CHANNEL *) (DMA_MC_BASE);
sChannel->Control = 0;
DmaIntDis(IM_MCRDDM);
blTimeOutFlag = 1;
TaskWakeup(MCARD_TASK);
}
static void SetDataDma(DWORD dwBufferAddress, DWORD dwSize, DWORD dwDirection)
{
register MCARD *sMcard;
register CHANNEL *sChannel;
DWORD dwTimeOut;
sChannel = (CHANNEL *) (DMA_MC_BASE);
sMcard = (MCARD *) (MCARD_BASE);
sMcard->McardC &= ~MCARD_FIFO_ENABLE;
dwTimeOut = 5000000;
while (!(sMcard->McardC & 0x400))
{
if (dwTimeOut-- == 0)
break;
//if (Polling_SD_Status()) return;
}
sChannel->Control = 0;
#if((STD_BOARD_VER == MP600PQFP_8M_SDRAM)||(STD_BOARD_VER == MP600_128PQFP_CPU_8M_SDRAM))
sMcard->McardC = (MCARD_ENABLE + sInfo.dwCardTag + dwDirection+BIT11);
#else
sMcard->McardC = (MCARD_ENABLE + sInfo.dwCardTag + dwDirection);
#endif
sChannel->StartA = dwBufferAddress;
sChannel->EndA = dwBufferAddress + dwSize - 1;
sMcard->McDmarl = MCARD_DMA_LIMIT_ENABLE + (dwSize >> 2);
sChannel->Control = MCARD_DMA_ENABLE;
sMcard->McardC |= MCARD_FIFO_ENABLE;
}
static SWORD WaitChannelStop(void)
{
register CHANNEL *sChannel;
DWORD dwTimeOut;
sChannel = (CHANNEL *) (DMA_MC_BASE);
dwTimeOut = 500000;
while (dwTimeOut)
{
if (!(sChannel->Control & MCARD_DMA_ENABLE))
{
return SD_PASS;
}
dwTimeOut--;
}
MP_DEBUG1("-E- WaitChannelStop FAIL (status: %x)", sChannel->Control);
return RES_TIMEOUT;
}
static void DmaReset(void)
{
register CHANNEL *sChannel;
register MCARD *sMcard;
sMcard = (MCARD *) (MCARD_BASE);
sChannel = (CHANNEL *) (DMA_MC_BASE);
sChannel->Control = 0;
sMcard->McDmarl = 0;
sChannel->StartA = 0;
sChannel->EndA = 0;
sMcard->McSdIc = IM_ALL;
}
static SWORD WaitTranState(void)
{
register MCARD *sMcard;
DWORD dwCurState, dwRetryTime;
dwRetryTime = 50000;
sMcard = (MCARD *) (MCARD_BASE);
while ((dwRetryTime--) > 0)
{
SetCommand(CMD_SEND_STATUS, sInfo.dwRelativeCardAddr);
if (WaitResponse() != SD_PASS)
{
MP_DEBUG("WaitTranState Wait Response fail");
return RES_TIMEOUT;
}
dwCurState = (sMcard->McSdRspA & 0xe00) >> 9;
if (dwCurState == TRANSFER_STATE)
{
//MP_DEBUG("Transfer state");
return SD_PASS;
}
if (dwCurState == RECEIVE_STATE)
{
// MP_DEBUG("Receive state");
McardIODelay(50);
/*
SetCommand(CMD_STOP_TRANSMISSION, 0);
if (WaitResponse() != SD_PASS)
{
MP_DEBUG("Stop Transmission Wait Response fail");
return RES_TIMEOUT;
}
SetCommand(CMD_SELECT_CARD, 0);
if (WaitResponse() != SD_PASS)
{
MP_DEBUG("Select Card to Stand by Wait Response fail");
return RES_TIMEOUT;
}
SetCommand(CMD_SELECT_CARD, sInfo.dwRelativeCardAddr);
if (WaitResponse() != SD_PASS)
{
MP_DEBUG("Select Card to Transfer State Wait Response fail");
return RES_TIMEOUT;
}
*/
}
if (dwCurState == STANDBY_STATE)
{
//MP_DEBUG("Standby state");
SetCommand(CMD_SELECT_CARD, sInfo.dwRelativeCardAddr);
if (WaitResponse() != SD_PASS)
{
MP_DEBUG("Select Card to Transfer State Wait Response fail");
return RES_TIMEOUT;
}
}
if (dwCurState == PROGRAM_STATE)
{
//MP_DEBUG("Program state");
McardIODelay(50);
}
if (dwCurState == NULL_STATE)
{
// MP_DEBUG("Null state");
McardIODelay(50);
}
TASK_YIELD();
}
MP_DEBUG1("re init (dwCurState = %d)", dwCurState);
OpenDrainDelay();
OpenDrainDelay();
return GoTransferMode();
}
static SWORD WaitDataRead(void)
{
register MCARD *sMcard;
DWORD dwTimeOut, dwCause;
sMcard = (MCARD *) (MCARD_BASE);
dwTimeOut = 10000000;
while (dwTimeOut)
{
dwCause = sMcard->McSdIc;
if (dwCause & IC_SDTO)
{
MP_DEBUG1("-E- IC_SDTO FAIL (status: %x)", dwCause);
return READ_TIMEOUT;
}
if (dwCause & IC_CRC16F)
{
MP_DEBUG1("-E- IC_CRC16F FAIL (status: %x)", dwCause);
return BAD_CRC16;
}
if (dwCause & IC_TREND)
{
return SD_PASS;
}
TASK_YIELD();
dwTimeOut--;
}
MP_DEBUG1("-E- WaitDataRead FAIL (status: %x)", dwCause);
return GENERAL_FAIL;
}
static SWORD WaitDataWrite(void)
{
register MCARD *sMcard;
DWORD dwTimeOut, dwCause;
sMcard = (MCARD *) (MCARD_BASE);
dwTimeOut = 10000000;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -