?? sd.c
字號:
continue;
}
else
return STATUS_SUCCESS;
}
return STATUS_FLASH_ERROR;
}
STATUS SdSendAppCmd(BYTE AppCmdIndex, PBYTE AppCmdBuf)
{
STATUS Status;
int RetryCount;
BYTE CmdBuf55[MAX_CMD_LEN]; // for APP_CMD (CMD55)
for(RetryCount = 0; RetryCount < 3; RetryCount++)
{
*((UINT32 *)(&CmdBuf55[1])) = RCA;
Status = SdSendCmd(APP_CMD, CmdBuf55);
if(Status != STATUS_SUCCESS)
continue;
Status = SdSendCmd(AppCmdIndex, AppCmdBuf);
if(Status != STATUS_SUCCESS)
continue;
else
return STATUS_SUCCESS;
}
return STATUS_FLASH_ERROR;
}
//----------------------------------------------------------------------------
STATUS SdChangeBusWidth()
{
STATUS Status;
BYTE RegValue;
*((UINT32 *)(&SdCmdBuf[1])) = RCA | BUS_WIDTH_4BIT;
Status = SdSendAppCmd(SET_BUS_WIDTH, SdCmdBuf);
if(Status == STATUS_SUCCESS)
{
RegValue = CSRRead(SD_BASE + SD_CLK_CTRL);
//RegValue |= SD_CLK_NIBBLE;
RegValue |= 0x10;
CSRWrite(SD_BASE + SD_CLK_CTRL, RegValue);
}
return Status;
}
//----------------------------------------------------------------------------
STATUS SdReset()
{
STATUS Status;
int i;
RCA = 0;
SdLoClk();
Delay(5); // Wait 5ms for stable clock
for(i = 1; i <= 4; i++)
SdCmdBuf[i] = 0;
Status = SdSendCmd(GO_IDLE_STATE, SdCmdBuf);
return Status;
}
//----------------------------------------------------------------------------
STATUS SdDetect()
{
STATUS Status;
UINT16 RetryCount;
*((UINT32 *)(&SdCmdBuf[1])) = OPERATION_VOL_RANGE;
Status = SdSendAppCmd(SD_SEND_OP_COND, SdCmdBuf);
if(Status == STATUS_SUCCESS)
{
CardType = CARD_SD;
// Check if card power-up operation finished
if(SdRespBuf[1] & CARD_PWRUP_FINISH)
return STATUS_SUCCESS;
// Wait until card power-up operation finished
for(RetryCount = 0; RetryCount < 500; RetryCount++)
{
*((UINT32 *)(&SdCmdBuf[1])) = OPERATION_VOL_RANGE;
Status = SdSendAppCmd(SD_SEND_OP_COND, SdCmdBuf);
if(Status != STATUS_SUCCESS)
continue;
if(SdRespBuf[1] & CARD_PWRUP_FINISH)
return STATUS_SUCCESS;
}
return STATUS_FLASH_ERROR;
}
else
{
CardType = CARD_MMC;
// Wait until card power-up operation finished
for(RetryCount = 0; RetryCount < 500; RetryCount++)
{
*((UINT32 *)(&SdCmdBuf[1])) = OPERATION_VOL_RANGE;
Status = SdSendCmd(SEND_OP_COND, SdCmdBuf);
if(Status != STATUS_SUCCESS)
continue;
if(SdRespBuf[1] & CARD_PWRUP_FINISH)
return STATUS_SUCCESS;
}
return STATUS_FLASH_ERROR;
}
}
//----------------------------------------------------------------------------
STATUS SdGoIdentifyState()
{
STATUS Status;
int i;
for(i = 1; i <= 4; i++)
SdCmdBuf[i] = 0;
Status = SdSendCmd(ALL_SEND_CID, SdCmdBuf);
return Status;
}
//--------------------------------------------------------------------
STATUS SdGoStandbyState()
{
STATUS Status;
int i;
if(CardType == CARD_SD)
{
for(i = 1; i <= 4; i++)
SdCmdBuf[i] = 0;
}
else
{
RCA = 0x00010000;
*((UINT32 *)(&SdCmdBuf[1])) = RCA;
}
Status = SdSendCmd(SEND_RELATIVE_ADDR, SdCmdBuf);
if(CardType == CARD_SD)
RCA = *((UINT32 *)(&SdRespBuf[1])) & 0xffff0000;
return STATUS_SUCCESS;
// SD and MMC adopt different ways to set their relative card
// address. That is, they have different response to CMD3
// (SEND_RELATIVE_ADDR).
//
// According to SD Standard Version 1.01 page 25:
// the host issues CMD3 (SEND_RELATIVE_ADDR) asks the
// card to publish a new relative card address (RCA).
//
// According to MMC Standard Version 3.1 page 24:
// the host issues CMD3 (SEND_RELATIVE_ADDR) to assign
// to this card a relative card address (RCA).
//
// This means : when host send CMD3 to SD, it is SD telling host
// its new address, that is, SD is the one giving the new address
// (and host decides whether to accept it). Meanwhile, when host
// sends CMD3 to MMC, it is host assigning the card a new address,
// that is, host is the one decides the address (and MMC must
// accept it).
//
// For SD, CMD3 has a response of type R6, which contains address
// value returns by SD. For MMC, CMD3 has a response of type R1,
// which tells host if MMC accepts the address or error happens.
}
//--------------------------------------------------------------------
STATUS SdReadCSD()
{
STATUS Status;
BYTE READ_BL_LEN;
BYTE C_SIZE_MUTI;
UINT32 C_SIZE;
*((UINT32 *)(&SdCmdBuf[1])) = RCA;
Status = SdSendCmd(SEND_CSD, SdCmdBuf);
if(Status != STATUS_SUCCESS)
return Status;
READ_BL_LEN = SdRespBuf[6] & 0xf;
C_SIZE = SdRespBuf[7] & 0x3;
C_SIZE <<= 8;
C_SIZE |= SdRespBuf[8];
C_SIZE <<= 2;
C_SIZE |= (SdRespBuf[9] >> 6);
C_SIZE_MUTI = SdRespBuf[10] & 0x3;
C_SIZE_MUTI <<= 1;
C_SIZE_MUTI |= (SdRespBuf[11] >> 7);
SdAvailableBlocks = (UINT32)((C_SIZE + 1) << (C_SIZE_MUTI + 2 +
(READ_BL_LEN - BYTES_PER_SECTOR_SHIFT)));
SdAvailableBlocks -= 1;
return STATUS_SUCCESS;
}
//----------------------------------------------------------------------------
STATUS SdGoTransferState()
{
STATUS Status;
BYTE CurrentState , RegValue;
*((UINT32 *)(&SdCmdBuf[1])) = RCA;
Status = SdSendCmd(SELECT_CARD, SdCmdBuf);
if(Status != STATUS_SUCCESS)
return Status;
*((UINT32 *)(&SdCmdBuf[1])) = RCA;
Status = SdSendCmd(SEND_STATUS, SdCmdBuf);
if(Status != STATUS_SUCCESS)
return Status;
CurrentState = (SdRespBuf[3] >> 1) & 0x0F;
if(CurrentState == TRANSFER_STATE)
{
SdHiClk();
if(CardType == CARD_SD)
{
Status = SdChangeBusWidth();
if(Status != STATUS_SUCCESS)
return Status;
}
else // MMC 3.1
{
RegValue = CSRRead(SD_BASE + SD_CLK_CTRL);
RegValue &= ~SD_CLK_NIBBLE;
CSRWrite(SD_BASE + SD_CLK_CTRL, RegValue);
}
}
else
return STATUS_FLASH_ERROR;
return STATUS_SUCCESS;
}
//----------------------------------------------------------------------------
// Description:
// Stop the read or write command
//----------------------------------------------------------------------------
STATUS SdStopCmd()
{
STATUS Status;
BYTE RegValue;
int i;
RegValue = CSRRead(SD_BASE + SD_CLK_CTRL);
RegValue &= ~SD_CLK_AUTO_DIS;
CSRWrite(SD_BASE + SD_CLK_CTRL, RegValue);
for(i = 1; i <= 4; i++)
SdCmdBuf[i] = 0;
Status = SdSendCmd(STOP_TRANS, SdCmdBuf);
if(Status != STATUS_SUCCESS)
return Status;
SdWaitCard();
return STATUS_SUCCESS;
}
//----------------------------------------------------------------------------
STATUS SdWaitCmd()
{
CmdTimer = SD_CMD_TIMEOUT;
while ((!(CSRRead(SD_BASE + SD_IE) & SD_COMPLETE)) && CmdTimer);
// Clear command complete INT.
CSRWrite(SD_BASE + SD_IE, ~SD_COMPLETE);
if (CmdTimer)
return STATUS_SUCCESS;
else
{
//DebugShow("<SD> Wait TimeOut! Cmd = %02bx\r\n", CmdBuf[0]);
SdCtrlReset();
return STATUS_FLASH_ERROR;
}
}
//--------------------------------------------------------------------
// Read first sector of data from SD/MMC
//--------------------------------------------------------------------
STATUS SdReadOneSector()
{
STATUS Status;
int RetryCount1 , RetryCount2;
bool ReadyForData;
if(SectorStart > SdAvailableBlocks)
return STATUS_PARAM_ERROR;
SdWaitCard();
for(RetryCount1 = 0; RetryCount1 < 5; RetryCount1++)
{
ReadyForData = false;
for(RetryCount2 = 0; RetryCount2 < 20; RetryCount2++) //讀取SD/MMC卡的狀態,SD/MMC卡沒準備好發送數據則循環重試20次
{
*((UINT32 *)(&SdCmdBuf[1])) = RCA;
Status = SdSendCmd(SEND_STATUS, SdCmdBuf); //發送帶一個response的命令,以得到當前SD/MMC卡的狀態
if(Status != STATUS_SUCCESS)
continue;
if(SdRespBuf[3] & 0x01) // READY_FOR_DATA in Card Status
{
ReadyForData = true;
break;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -