📄 sd.c
字号:
{
*((INT32U *)(&SdCmdBuf[1])) = RCA;
Status = SdSendCmd(SEND_STATUS, SdCmdBuf);
if(Status == STATUS_SUCCESS)
{
if(busWidth==8)
{
SDMI_CTL|=bmSD_BUS_8BIT_EN;
SDMI_CTL&=~bmSD_BUS_4BIT_EN;
}
else if((busWidth==4))
{
SDMI_CTL&=~bmSD_BUS_8BIT_EN;
SDMI_CTL|=bmSD_BUS_4BIT_EN;
}
else
{
SDMI_CTL&=~bmSD_BUS_4BIT_EN;
SDMI_CTL&=~bmSD_BUS_8BIT_EN;
}
}
//Status = SdReadExtCSD();
}
}
else // MMC 3.1 只支持1bit模式
{
SDMI_CTL&=~bmSD_BUS_4BIT_EN;
SDMI_CTL&=~bmSD_BUS_8BIT_EN;
}
}
return Status;
}
#ifdef DEBUG_FLASH_ERASE
STATUS SdReadExtCSD(void)
{
STATUS Status;
int RetryCount1 , RetryCount2;
BOOL ReadyForData;
// if (!SdCardExist())
// return STATUS_FLASH_ERROR;
SdWaitCard();
for(RetryCount1 = 0; RetryCount1 < 5; RetryCount1++)
{
ReadyForData = FALSE;
for(RetryCount2 = 0; RetryCount2 < 20; RetryCount2++)
{
*((INT32U *)(&SdCmdBuf[1])) = RCA;
Status = SdSendCmd(SEND_STATUS, SdCmdBuf);
if(Status != STATUS_SUCCESS)
continue;
if(SdRespBuf[3] & 0x01) // READY_FOR_DATA in Card Status
{
ReadyForData = TRUE;
break;
}
}
if(!ReadyForData){
CmdTimer=3;
while(CmdTimer);
continue;
}
SDMI_BUFBASE=0xEC; //FIFOB0--11.30 DEREK
//注意:EXT CSD的512字节数据在FIFO中从低到高排列~!
*((INT32U *)(&SdCmdBuf[1])) = 0;
Status = SdSendCmd(SEND_EXT_CSD, SdCmdBuf);
if(Status != STATUS_SUCCESS)
continue;
//*******************************
if(SDMI_ST&bmSD_CRC16_ERR)
{
SDMI_ST &=~bmSD_CRC16_ERR;
continue;
}
else
{
*((INT32U *)(&SdCmdBuf[1])) = RCA;
Status = SdSendCmd(SEND_STATUS, SdCmdBuf);
return STATUS_SUCCESS;
}
}
return STATUS_FLASH_ERROR;
}
#endif
//----------------------------------------------------------------------------
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(void)
{
STATUS Status;
UINT16 RetryCount;
*((UINT32 *)(&SdCmdBuf[1])) = OPERATION_VOL_RANGE;
if(SdVer2Flag)SdCmdBuf[1] = 0x40; //sd2.0卡支持high capacity support功能。Derek 2007.06.29
Status = SdSendAppCmd(SD_SEND_OP_COND, SdCmdBuf);
if(Status == STATUS_SUCCESS) //如果返回成功标志,说明是SD卡
{
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; //2007.06.29
if(SdVer2Flag)SdCmdBuf[1] = 0x40; //Derek 2007.06.29
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 //否则,是MMC卡
{
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;
}
}
//-----用来检测是否Sd 2.0卡-----------------------------------------------------
STATUS SdSendIFCon(void)
{
STATUS Status;
SdCmdBuf[3] = 0X01;
SdCmdBuf[4] = 0XAA;
Status = SdSendCmd(SEND_IF_COND, SdCmdBuf);
return Status;
}
//----------------------------------------------------------------------------
STATUS SdGoIdentifyState(void)
{
STATUS Status;
int i;
for(i = 1; i <= 4; i++)
SdCmdBuf[i] = 0;
Status = SdSendCmd(ALL_SEND_CID, SdCmdBuf);
return Status;
}
//--------------------------------------------------------------------
STATUS SdGoStandbyState(void)
{
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(void)
{
STATUS Status;
BYTE READ_BL_LEN;
BYTE C_SIZE_MUTI;
UINT32 C_SIZE;
//SD 2.0和SD1.01格式不一样。C_SIZE【69:48】
*((UINT32 *)(&SdCmdBuf[1])) = RCA;
Status = SdSendCmd(SEND_CSD, SdCmdBuf); //读取SD卡的CSD信息
if(Status != STATUS_SUCCESS)
return Status;
if(CardType == CARD_MMC) {
if(((SdRespBuf[1]&0x3f)>>2)==4) MmcProtol = 1; //判断是何种卡4.0 ?3.1?
else MmcProtol = 0; //MMC 3.1
} else {
if(SdRespBuf[1]&0xC0) //2007.08.16-从SD CSD中判断是否HC SD。
SdHcFlag = 1;
else
SdHcFlag = 0;
}
if(SdHcFlag == 0) { //Derek 2007.07.02 V1.0,1.01的SD卡CSD
//Derek 06.09.20
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)));
} else { //V1.1,2.0的SD卡CSD CSIZE---CSD[69:48]
C_SIZE = SdRespBuf[8] & 0x3F;
C_SIZE <<= 8;
C_SIZE |= SdRespBuf[9];
C_SIZE <<= 8;
C_SIZE |= SdRespBuf[10];
SdAvailableBlocks = (UINT32)((C_SIZE+1) << 10);//memory capacity blocks = (C_SIZE+1)*512KB/512B
}
SdAvailableBlocks -= 1; //计算得到可用block数。默认block大小为512字节
return STATUS_SUCCESS;
}
#if 0
//--------------------------------------------------------------------
//读取SCR寄存器的值,判断SD卡确切的版本~
STATUS SdReadSCR(void) //----
{
STATUS Status;
BYTE i;
for(i = 0;i < 10;i++){
*((UINT32 *)(&SdCmdBuf[1])) = 0;
SDMI_BUFBASE=0xF2; //FIFOB1
SDMI_LENH = 0;
SDMI_LENL = 8;
Status = SdSendAppCmd(SEND_SCR, SdCmdBuf); //读取SD卡的SCR信息
SDMI_LENH = 0X02;
SDMI_LENL = 0;
if(Status == STATUS_SUCCESS) {//
if((*(BYTE xdata*)(0xf200)&0x0F)>= 1) //SD 1.10,2.00卡
SdVer2Flag = 1;
else
SdVer2Flag = 0;
return Status;
}
}
SdVer2Flag = 0;
}
#endif
#if 0
STATUS SdProgCsd(void) //改写CSD
{
STATUS Status;
//BYTE CrcSts;
int RetryCount1 , RetryCount2,i;
BOOL ReadyForData;
if(SDMI_ST & bmSD_WR_PROTECT)
return STATUS_WRITE_PROTECT;
SdWaitCard();
for(RetryCount1 = 0; RetryCount1 < 5; RetryCount1++)
{
ReadyForData = FALSE;
for(RetryCount2 = 0; RetryCount2 < 20; RetryCount2++)
{
*((INT32U *)(&SdCmdBuf[1])) = RCA;
Status = SdSendCmd(SEND_STATUS, SdCmdBuf);
if(Status != STATUS_SUCCESS) //MMCerror1++;
continue;
if(SdRespBuf[3] & 0x01) // READY_FOR_DATA in Card Status
{
ReadyForData = TRUE;
break;
}
}
if(!ReadyForData) //MMCerror2++;
continue;
//SdReadCSD();
SDMI_BUFBASE=0xF2; //FIFOB0
for(i=0;i<17;i++)
((BYTE xdata *)DMA_FIFOB0)[i]=SdRespBufForProgCsd[i]; //.
((BYTE xdata *)DMA_FIFOB0)[6] |= 0x0A;//
Status = SdSendCmd(PROGRAM_CSD, SdCmdBuf);
if(Status != STATUS_SUCCESS)
continue;
//*******************************
///*CrcSts = (SDMI_ST&0x38) >> 3;
//if(CrcSts != GOOD_CRC16_STS) //MMCerror3++;
// continue;
//else //
return STATUS_SUCCESS;
}
return STATUS_FLASH_ERROR;
}
#endif
//----------------------------------------------------------------------------
STATUS SdGoTransferState(void)
{
STATUS Status;
BYTE CurrentState;
*((INT32U *)(&SdCmdBuf[1])) = RCA;
Status = SdSendCmd(SELECT_CARD, SdCmdBuf);
if(Status != STATUS_SUCCESS)
return Status;
*((INT32U *)(&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(4);
if(Status != STATUS_SUCCESS)
return Status;
}
else
{
Status = SdChangeBusWidth(8); //derek.
if(Status != STATUS_SUCCESS)
return Status;
}
}
else
return STATUS_FLASH_ERROR;
return STATUS_SUCCESS;
}
#if 0
//----------------------------------------------------------------------------
// Description:
// Stop the read or write command.
// Used for read or write multi blocks.
//----------------------------------------------------------------------------
STATUS SdStopCmd()
{
STATUS Status;
int i;
SDMI_CTL&=~bmSD_AUTO_CLK_EN;
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((!(SDMI_INT&bmSD_COMPLETE_INT))&&CmdTimer); //等待命令执行完毕
SDMI_INT&=~bmSD_COMPLETE_INT; //清除中断标志
if (CmdTimer) //没有超时,返回成功标志
return STATUS_SUCCESS;
else
{
SdCtrlReset();
return STATUS_FLASH_ERROR;
}
}
#endif
/*
//----------------------------------------------------------------------------
STATUS SdSetBlockLen(INT16U len)
{
STATUS Status;
SdWaitCard();
*((INT32U *)(&SdCmdBuf[1]))=len;
Status = SdSendCmd(SET_BLOCKLEN,SdCmdBuf);
if(Status == STATUS_SUCCESS)
{
SDMI_LENH=len>>8;
SDMI_LENL=len;
}
return Status;
}
*/
//--------------------------------------------------------------------
// Read single sector of data from SD/MMC,
// Read the first sector when execute multi-read command.
//--------------------------------------------------------------------
#pragma OPTIMIZE(4)
STATUS SdReadOneSector(BYTE*buff, DWORD sector)
{
STATUS Status;
int RetryCount1 , RetryCount2;
bool ReadyForData;
DWORD SectorStart,SectorCount;
SectorStart= sector;
SectorCount =1;
//buff =DMA_FIFOB0;
// (BYTE xdata *)DMA_FIFOB0
if (!SdCardExist())
return STATUS_FLASH_ERROR;
if(SectorStart > SdAvailableBlocks)
return STATUS_PARAM_ERROR;
SdWaitCard(); //等待上次操作执行完毕
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -