📄 sd.c
字号:
*************************************************************************/
SDC_CMD_STATUS SD_EraseCmdClass(kal_uint32 cmd ,kal_uint32 address)
{
SDC_CMD_STATUS status;
if(cmd != SDC_CMD_CMD38)
{
if((status = SD_Send_Cmd(cmd,address))!=NO_ERROR)
return status;
}
else if((status = SD_Send_Cmd(cmd,SDC_NO_ARG))!=NO_ERROR)
return status;
//read R1
if((status = SD_CheckStatus())!=NO_ERROR)
return status;
if(cmd == SDC_CMD_CMD38)
{
SD_WaitCardNotBusy();
do{
SD_GetStatus(gSD.mRCA,(kal_uint32*)&status);
if(gMSDC_Handle.mIsPresent == KAL_FALSE)
break;
}while(CurState(status)!= TRAN_STA);
}
return NO_ERROR;
}
/*************************************************************************
* FUNCTION
* SD_Switch_MMC40
*
* DESCRIPTION
* CMD6: set the command set or write to the EXT_CSD (for MMC4.0)
*
* PARAMETERS
* access: access mode
* index: index to EXT_CSD
* value: value to write to EXT_CSD
* set: selected command set
*
* RETURNS
* SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*
* NOTE
*
*************************************************************************/
SDC_CMD_STATUS SD_Switch_MMC40(kal_uint8 access, kal_uint8 index, kal_uint8 value, kal_uint8 set)
{
SDC_CMD_STATUS status;
kal_uint32 arg = 0;
arg = (access<<24)|(index<<16)|(value<<8)|set;
// send command
if((status = SD_Send_Cmd(SDC_CMD_CMD6_MMC40,arg))!=NO_ERROR)
return status;
//read R1
if((status = SD_CheckStatus())!=NO_ERROR)
return status;
return NO_ERROR;
}
/*************************************************************************
* FUNCTION
* SD_SendEXTCSD_MMC40
*
* DESCRIPTION
* CMD8: read the content of EXT_CSD register
*
* PARAMETERS
* kal: access mode
* index: index to EXT_CSD
* value: value to write to EXT_CSD
* set: selected command set
*
* RETURNS
* SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*
* NOTE
*
*************************************************************************/
SDC_CMD_STATUS SD_SendEXTCSD_MMC40(kal_uint32* rxbuffer)
{
SDC_CMD_STATUS status;
kal_bool retry_4bit = KAL_FALSE;
start:
// read the block of 512 bytes (make sure the rxbuffer is 4 byte aligned)
EnableMSDC_DMA();
MSDC_DMATransferFirst((kal_uint32)rxbuffer,128,KAL_FALSE);
if((status = SD_Send_Cmd(SDC_CMD_CMD8_MMC40,SDC_NO_ARG))!=NO_ERROR)
return status;
//read R1
if((status = SD_CheckStatus())!=NO_ERROR)
return status;
// read the block of 512 bytes (make sure the rxbuffer is 4 byte aligned)
EnableMSDC_DMA();
status = MSDC_DMATransferFinal();
if(status != NO_ERROR)
goto ERR_Exit;
if((status = SD_WaitDatRdyOrTo())!=NO_ERROR)
goto ERR_Exit;
DisableMSDC_DMA();
MSDC_CLR_FIFO();
gSD.mCSD.ext_csd = (T_EXT_CSD_MMC40 *)rxbuffer;
return NO_ERROR;
ERR_Exit:
if(retry_4bit == KAL_FALSE)
{
retry_4bit = KAL_TRUE;
MSDC_SET_BIT32(SDC_CFG,SDC_CFG_MDLEN);
gSD.bus_width = 4;
goto start;
}
gSD.bus_width = 1;
DisableMSDC_DMA();
MSDC_CLR_FIFO();
RESET_MSDC();
return status;
}
/*************************************************************************
* FUNCTION
* SD_Switch_SD11
*
* DESCRIPTION
* CMD6: switch command to query and select the specific functions. (SD1.1 or later)
* PARAMETERS
* arg: argument
* resp: buffer to contain the ther 64 bytes status information
*
* RETURNS
* SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*
* NOTE
*
*************************************************************************/
SDC_CMD_STATUS SD_Switch_SD11(kal_uint32 arg, T_SWITCH_STATUS* info)
{
SDC_CMD_STATUS status = NO_ERROR;
BitFieldWrite32((kal_uint32*)SDC_CFG,SD_CMD6_RESP_LEN,SDC_CFG_BLKLEN);
EnableMSDC_DMA();
MSDC_DMATransferFirst((kal_uint32)info,(SD_CMD6_RESP_LEN>>2),KAL_FALSE);
if((status = SD_Send_Cmd(SDC_CMD_CMD6_SD11,arg))!=NO_ERROR)
goto exit;
if((status = SD_CheckStatus())!=NO_ERROR)
goto exit;
status = MSDC_DMATransferFinal();
exit:
DisableMSDC_DMA();
return status;
}
/*************************************************************************
* FUNCTION
* SD_Switch_SD11
*
* DESCRIPTION
* Enable the high speed interface to support up to 50M Hz clock
*
* PARAMETERS
* arg: argument
* resp: buffer to contain the ther 64 bytes status information
*
* RETURNS
* SDC_CMD_STATUS
*
* GLOBALS AFFECTED
*
* NOTE
*
*************************************************************************/
SDC_CMD_STATUS SD_SelectHighSpeed_SD11(void)
{
SDC_CMD_STATUS status;
T_SWITCH_STATUS *p = (T_SWITCH_STATUS*)MSDC_Sector;
if((status = SD_Switch_SD11(SD_CMD6_QUERY_HIGH_SPEED, p))!=NO_ERROR)
return status;
if(p->max_current == 0)
return ERR_SD_HS_FAIL;
if((p->group1_info & (1 << SD_FUNC_HIGH_SPEED)) &&
(p->group1_result == SD_FUNC_HIGH_SPEED))
{
if((status = SD_Switch_SD11(SD_CMD6_SELECT_HIGH_SPEED, p))!=NO_ERROR)
return status;
if(p->max_current == 0)
return ERR_SD_HS_FAIL;
if(p->group1_result == SD_FUNC_HIGH_SPEED)
gSD.flags |= SD_FLAG_HS_SUPPORT;
}
else
return ERR_SD_HS_FAIL;
return NO_ERROR;
}
#endif // defined(__MSDC_SD_MMC__)
#ifdef MSDC_DEBUG
#define TST_ADRS 512*12
static kal_uint8 rxbuffer[512*32],txbuffer[512*32];
//static kal_uint8 rxbuffer[512],txbuffer[512];
kal_uint32 SD_MMC_Test(void)
{
kal_uint32 result,resp;
int i;
SDC_CMD_STATUS status;
// initialize MSDC
MSDC_Initialize();
// initialize SDC
SD_Initialize();
//////////////////////////
//Mass data Tansfer(8M)//
//////////////////////////
#ifdef MASS
{
int block_num,i,j,cmp,loop = 1;
kal_uint32 ticks;
#ifdef BITS4_BUS
if(gMSDC_Handle.mMSDC_type == SD_CARD){
if(status = SD_SetBusWidth(BIT_4W))
return status;
}
#endif
for(i=0;i<512*32;i++)
txbuffer[i] = i%256;
j=0;
ticks = NU_Retrieve_Clock();
while(loop){
status = SD_WriteMultiBlock(j*512*32,(uint32*)txbuffer,32);
if(status)
{
ticks = NU_Retrieve_Clock()- ticks ;
//dbg_print("SD_WriteMultiBlock failed! %d \n\r",ticks);
//while(1);
}
status = SD_ReadMultiBlock(j*512*32,(uint32*)rxbuffer,32);
if(status)
{
ticks = NU_Retrieve_Clock()- ticks ;
//dbg_print("SD_ReadMultiBlock failed! %d \n\r",ticks);
//while(1);
}
ticks = NU_Retrieve_Clock()- ticks ;
cmp = memcmp(txbuffer,rxbuffer,512*32);
if(cmp)
{
ticks = NU_Retrieve_Clock()- ticks ;
//dbg_print("compare failed! %d \n\r",ticks);
//while(1);
}
//dbg_print("Check %d OK!\t",j);
kal_mem_set(rxbuffer,0,512*32);
j++;
if(j*32 >= gSD.mBKNum-32)
{
static count = 0;
ticks = NU_Retrieve_Clock()- ticks ;
//dbg_print("\n\r###############################\n\r",ticks);
//dbg_print("end of card %d at count %d\n\r",ticks,count++);
//dbg_print("\n\r###############################\n\r",ticks);
j=0;
ticks = NU_Retrieve_Clock();
//while(1);
}
}
/*
// (1) using single block transfer
ticks = NU_Retrieve_Clock();
block_num = 32;
//block_num = 1024;
for(i=0;i<block_num;i++)
if(status = SD_WriteSingleBlock(i*512,(kal_uint32*)txbuffer))
break;
ticks = NU_Retrieve_Clock()- ticks ;
ticks = NU_Retrieve_Clock();
for(i=0;i<block_num;i++)
{
if(status = SD_ReadSingleBlock(i*512,(kal_uint32*)rxbuffer))
break;
}
ticks = NU_Retrieve_Clock()- ticks ;
// (2) using multiple block transfer(requied to rewind the buffer pointer)
ticks = NU_Retrieve_Clock();
status = SD_WriteMultiBlock(0,(kal_uint32*)txbuffer,block_num);
ticks = NU_Retrieve_Clock()- ticks ;
ticks = NU_Retrieve_Clock();
status = SD_ReadMultiBlock(0,(kal_uint32*)rxbuffer,block_num);
ticks = NU_Retrieve_Clock()- ticks ;
*/
}
#endif // end of MASS
#ifdef SD_ERASE
// there are differences between SD and MMC
// tag erase start(CMD32)
if(status = SD_EraseCmdClass(SDC_CMD_CMD32,0))
return status;
// tag erase end(CMD33)
if(status = SD_EraseCmdClass(SDC_CMD_CMD33,512*32))
return status;
// erase...(CMD38)
if(status = SD_EraseCmdClass(SDC_CMD_CMD38,0))
return status;
// check result of erase
// single block read (CMD17)
if(status = SD_ReadSingleBlock(0,(kal_uint32*)rxbuffer))
return status;
result = 0;
for(i=0;i<512;i++)
{
if(gSD.mSCR.dat_after_erase)
{
if(rxbuffer[i] != 0xff)
result++;
}
else
{
if(rxbuffer[i] != 0x00)
result++;
}
}
#endif
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#ifdef BITS4_BUS
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -