📄 sd.c
字号:
for(RetryCount1 = 0; RetryCount1 < 15; RetryCount1++)
{
ReadyForData = false;
for(RetryCount2 = 0; RetryCount2 < 20; RetryCount2++)
{
*((UINT32 *)(&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=(DMA_FIFOB0>>8);
if(SdHcFlag) { //Derek 2007.07.02
*((UINT32 *)(&SdCmdBuf[1])) = SectorStart;
} else
*((UINT32 *)(&SdCmdBuf[1])) =
SectorStart << BYTES_PER_SECTOR_SHIFT;
//***********************
if (SectorCount > 1) // Muti-Read.
{
SDMI_CTL|=bmSD_AUTO_CLK_EN;
Status = SdSendCmd(READ_MUL_BLOCK, SdCmdBuf);
if(Status != STATUS_SUCCESS)
continue;
}
else
{
SDMI_CTL &= ~bmSD_AUTO_CLK_EN; //2007.01.18
Status = SdSendCmd(READ_BLOCK, SdCmdBuf);
if(Status != STATUS_SUCCESS)
continue;
else
memcpy(buff, (BYTE xdata *)DMA_FIFOB0, 512);
}
//*******************************
if(SDMI_ST&bmSD_CRC16_ERR)
{
SDMI_ST &=~bmSD_CRC16_ERR;
continue;
}
else
return STATUS_SUCCESS;
}
return STATUS_FLASH_ERROR;
}
/*
//----------------------------------------------------------------------------
// Description:
// Read one of the other sectors,except the first sector,
// when execute multi-read command.
//----------------------------------------------------------------------------
#pragma OPTIMIZE(4)
STATUS SdReadNextSectorData(void)
{
STATUS Status;
bit Stop;
Stop = SectorCount == 1;//
if (!SdCardExist())
return STATUS_FLASH_ERROR;//如果卡拔出,直接返回!!
// SDMI_BUFBASE = (FIFO_ADDRESS_IN>>8);
SDMI_CMD=SD_CMD_RX_DATA_ONLY;
SDMI_CTL|=bmSD_AUTO_CLK_EN;
if ((Status = SdWaitCmd()) != STATUS_SUCCESS)
return Status;
if(SDMI_ST&bmSD_CRC16_ERR) // CRC7 Error
{
SDMI_ST&=~bmSD_CRC16_ERR; // Clear INT
return STATUS_DATA_ERROR;
}
if (Stop)
return SdStopCmd();//所有block的数据已传输完毕,停止命令
return STATUS_SUCCESS;
} */
/*
STATUS SdReadNextSector(void)
{
BYTE RetryCount;
STATUS Status;
Status = SdReadNextSectorData();
if(Status != STATUS_SUCCESS)
{
for(RetryCount = 0 ; RetryCount < 15; RetryCount ++)
{
Status = SdStopCmd();
if(Status != STATUS_SUCCESS)
continue;
Status = SdReadOneSector();
break;
}
}
SectorStart ++;
return Status;
} */
//--------------------------------------------------------------------
// Write single sector of data to SD/MMC,
// or write the first sector when execute multi-write command.
//--------------------------------------------------------------------
STATUS SdWriteOneSector(BYTE*buff, DWORD sector)
{
STATUS Status;
BYTE CrcSts;
int RetryCount1 , RetryCount2;
bool ReadyForData;
BYTE MMCerror1;//09.12
DWORD SectorStart,SectorCount;
SectorStart= sector;
SectorCount =1;
if(SdCardExist()==0)
return STATUS_NO_MEDIA; //Derek 2007.03.14
if(SDMI_ST & bmSD_WR_PROTECT)
return STATUS_WRITE_PROTECT;
SdWaitCard(); //保证上次操作完成!
for(RetryCount1 = 0; RetryCount1 < 10; RetryCount1++)
{
ReadyForData = false;
for(RetryCount2 = 0; RetryCount2 < 20; RetryCount2++)
{
*((UINT32 *)(&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)
{
CmdTimer=2;
while(CmdTimer);
continue;}
memcpy((BYTE xdata *)DMA_FIFOB0,buff, 512);
SDMI_BUFBASE=(DMA_FIFOB0>>8);
if(SdHcFlag) { //Derek 2007.07.02 对于HC SD,以sector为单位。
*((UINT32 *)(&SdCmdBuf[1])) = SectorStart;
} else //对于standard,以字节为单位。
*((UINT32 *)(&SdCmdBuf[1])) =
SectorStart << BYTES_PER_SECTOR_SHIFT; //
//***********************
if (SectorCount > 1) // Muti-Write.
{
Status = SdSendCmd(WRITE_MUL_BLOCK, SdCmdBuf);
if(Status != STATUS_SUCCESS)
continue;
}
else
{
Status = SdSendCmd(WRITE_BLOCK, SdCmdBuf);
if(Status != STATUS_SUCCESS)
continue;
}
//*******************************
CrcSts = (SDMI_ST&0x38) >> 3;
if(CrcSts != GOOD_CRC16_STS) {
MMCerror1 ++;
continue;
}
else
return STATUS_SUCCESS;
}
return STATUS_FLASH_ERROR;
}
/*
STATUS SdWriteSector()
{
STATUS Status = SdWriteOneSector();
SectorStart ++;
return Status;
}
//----------------------------------------------------------------------------
// Description:
// Write one sector of data from the SD device
//----------------------------------------------------------------------------
STATUS SdWriteNextSector()
{
STATUS Status;
BYTE CrcSts;
bit Stop;
Stop = SectorCount == 1;
if(SdCardExist()==0)
return STATUS_NO_MEDIA; //Derek 2007.03.14
SdWaitCard();
CmdTimer = SD_CMD_TIMEOUT;
if (CmdTimer == 0)
{
return STATUS_FLASH_ERROR;
}
// SDMI_BUFBASE=(FIFO_ADDRESS_OUT>>8);
SDMI_CMD=SD_CMD_TX_DATA_ONLY;
if ((Status = SdWaitCmd()) != STATUS_SUCCESS)
return Status;
CrcSts = (SDMI_ST&0x38) >> 3;
if (CrcSts != GOOD_CRC16_STS)
{
return STATUS_DATA_ERROR;
}
if (Stop)
return SdStopCmd();
return STATUS_SUCCESS;
} */
#if 0
//--------------用于SD1.10,2.0卡function 切换----------------------
//主要是为了切换到high speed mode。
STATUS SDCMD6Test()
{
STATUS Status;
int i=0;
SDMI_BUFBASE=0xF2; //FIFOB1
SDMI_LENH = 0;
SDMI_LENL = 64;
*((UINT32 *)(&SdCmdBuf[1])) = 0x00FFFFF1; //check switchable function(mode0)
Status = SdSendCmd(CMD6, SdCmdBuf); //CMD6-adtc command type
SDMI_LENH = 0X02;
SDMI_LENL = 0;
if(Status != STATUS_SUCCESS)
return Status;
SDMI_LENH = 0;
SDMI_LENL = 64;
*((UINT32 *)(&SdCmdBuf[1])) = 0x80FFFFF1; //switch card function(mode1)
Status = SdSendCmd(CMD6, SdCmdBuf);
SDMI_LENH = 0X02;
SDMI_LENL = 0;
if(Status != STATUS_SUCCESS)
return Status;
return Status;
}
#endif
//--------------------------------------------------------------------
// Initialization sequence of SD/MMC
//--------------------------------------------------------------------
STATUS SdReadFlashInfo(void)
{
STATUS Status;
int RetryCount;
for(RetryCount = 0; RetryCount < 5; RetryCount++)
{
Status = SdReset();
if(Status != STATUS_SUCCESS)
continue;
////////////////SD 2.00 card detect.
Status = SdSendIFCon(); //SD2.0 only,
if(Status == STATUS_SUCCESS)
SdVer2Flag = 2; //SD 2.00 card
else
SdVer2Flag = 0; //non-Ver2.00 card.
/////////////////////
Status = SdDetect();
if(Status != STATUS_SUCCESS)
continue;
Status = SdGoIdentifyState();
if(Status != STATUS_SUCCESS)
continue;
Status = SdGoStandbyState();
if(Status != STATUS_SUCCESS)
continue;
Status = SdReadCSD();
if(Status != STATUS_SUCCESS)
continue;
Status = SdGoTransferState();
if(Status != STATUS_SUCCESS)
continue;
// if(CardType == CARD_SD) { //对于SD卡,要读取SCR寄存器。
// SdReadSCR();
//
// if(SdHcFlag|SdVer2Flag) { //For SD 1.10,2.0(include high capacity).
// Status = SDCMD6Test(); //derek 2007.06.29
// if(Status != STATUS_SUCCESS)
// SDMI_CTL &= ~bmSD_CLK_40; //根据卡的最大传输速率设定接口频率。
// //特别是对1.0的卡,要降低频率
// } else
// SDMI_CTL &= ~bmSD_CLK_40;
// }
return STATUS_SUCCESS;
}
return STATUS_FLASH_ERROR;
}
#ifdef DEBUG_FLASH_ERASE
//----------------------------------------------------------------------------
STATUS SdEraseDevice(void)
{
STATUS Status;
// ERASE_WR__BLK_START.
*((UINT32 *)(&CmdBuf[1])) = 0;
SdIssueCmd(32, SD_CMD_SHORT_RSP);
if ((Status = SdReadRsp(SdRespBuf, RSP_LEN)) != STATUS_SUCCESS)
return Status;
// ERASE_WR__BLK_END.
*((UINT32 *)(&CmdBuf[1])) = SdAvailableBlocks << BYTES_PER_SECTOR_SHIFT;
SdIssueCmd(33, SD_CMD_SHORT_RSP);
if ((Status = SdReadRsp(SdRespBuf, RSP_LEN)) != STATUS_SUCCESS)
return Status;
// ERASE.
*((UINT32 *)(&CmdBuf[1])) = 0;
SdIssueCmd(38, SD_CMD_SHORT_RSP);
if ((Status = SdReadRsp(SdRespBuf, RSP_LEN)) != STATUS_SUCCESS)
return Status;
return STATUS_SUCCESS;
}
#endif
//----------------------------------------------------------------------------
// Description:
// Handle the media change event
//----------------------------------------------------------------------------
void SdMediaChange(void)
{
if (SdCardExist())
{
BYTE i = MAX_FLASH_RETRY_TIMES;
SdLoClk();
SdHcFlag = 0; //每次读取SD卡信息前,将标志清零。
SdVer2Flag = 0;
do
{
SdMediaStatus = SdReadFlashInfo();
i--;
}while (i && (SdMediaStatus != STATUS_SUCCESS));
if (SdMediaStatus == STATUS_SUCCESS)
SdMediaStatus = STATUS_MEDIA_CHANGE;
//////////////////////////////////////////////
//{
//
// SectorStart = 0; //检测T5C SDMI接口性能.
// SectorCount = 1;
// FIFO_ADDRESS_OUT = DMA_FIFOA0;
// memset((BYTE xdata*)FIFO_ADDRESS_OUT,0,512);
// SdMediaStatus = SdWriteSector();//
//
// SectorStart = 0;
// SelectInFifo();
// SdMediaStatus = SdReadSector();//
//}
////////////////////////////////////////////
}
else
{
SdStopClk();
SdPowerOff();
SdAvailableBlocks = 0;
SdMediaStatus = STATUS_NO_MEDIA;
}
}
#if 0
//----------------------------------------------------------------------------
// Description:
// use to change STATUS when device "Start"
//----------------------------------------------------------------------------
void SdStart()
{
if(SdCardExist())
SdMediaStatus = STATUS_SUCCESS;
}
//----------------------------------------------------------------------------
// Description:
// use to change STATUS when device "eject"
//----------------------------------------------------------------------------
void SdEject(void)
{
SdMediaStatus = STATUS_NO_MEDIA;
}
//----------------------------------------------------------------------------
// Description:
// Query the current device information
//----------------------------------------------------------------------------
STATUS SdQueryDevice(void)
{
STATUS OrgStatus = SdMediaStatus;
if (SdMediaStatus == STATUS_NO_MEDIA)
return SdMediaStatus;
if (SdMediaStatus == STATUS_MEDIA_CHANGE)
SdMediaStatus = STATUS_SUCCESS;
DeviceInfo.TotalBlocks = SdAvailableBlocks;
DeviceInfo.BlockSize = BYTES_PER_SECTOR;
if (CardType == CARD_SD)
DeviceInfo.WriteProtect = SdWriteProtect();
else
DeviceInfo.WriteProtect = false;
return OrgStatus;
}
//----------------------------------------------------------------------------
// Description:
// Make the SD device into suspend mode
//----------------------------------------------------------------------------
void SdSuspend()
{
SdStopClk();
SdPowerOff();
}
//----------------------------------------------------------------------------
// Description:
// Make the CF device resume
//----------------------------------------------------------------------------
void SdResume()
{
if (SdCardExist())
{
SdPowerOn();
SdLoClk(); //Derek 2006.09.14 时钟设为低速
SdReadFlashInfo(); //重新识别读取SD信息
}
}
#endif
//----------------------------------------------------------------------------
// Description:
// Initiate the SD device
//----------------------------------------------------------------------------
void SdInit(void)
{
if (SdCardExist())
{
SdMediaChange();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -