📄 sdi.c
字号:
//-- Check end of CMD28
if(!Chk_CMDend(28, 1))
goto RECMD28;
//rSDICSTA=0xa00; // Clear cmd_end(with rsp)
}
void Clr_Prt(void)
{
//-- Clear protection addr.0 ~ 262144(32*16*512)
Uart_Printf("[Clear protection(addr.0 ~ 262144) test]\n");
RECMD29:
//--Make ACMD
//SDICARG CmdArg [31:0] = 0 : Command Argument
rSDICARG=0; // CMD29(addr)
//SDICCON CmdIndex [7:0] = 0X5d : CMD29
//SDICCON Command Start(CMST) [8 ] = 1 : command start
//SDICCON WaitRsp [9 ] = 1 : wait_resp
//SDICCON LongRsp [10 ] = 0 : short response
rSDICCON=(0x1<<9)|(0x1<<8)|0x5d; //sht_resp, wait_resp, start, CMD29
//-- Check end of CMD29
if(!Chk_CMDend(29, 1))
goto RECMD29;
//rSDICSTA=0xa00; // Clear cmd_end(with rsp)
}
//the new_funtion test
void SD_Clk400k(void)
{
rSDIPRE=PCLK/(2*INICLK)-1;
Uart_Printf("400k\n");
}
void SD_ClkToMax(void)
{
rSDIPRE=PCLK/(2*NORCLK)-1;
}
void SD_Powerup(void)
{
int i;
rSDICON=(1<<4)|(1<<1)|1;
rSDIBSIZE=SD_BLOCKSIZE;
rSDIDTIMER=0xffff;
//rSDIIMSK =0x0;
//SDIBSIZE BlkSize [11:0] = 0x200 : 512byte(128word)
//SDIDTIMER DataTimer [15:0] = 0xffff : Data / busy timeout period (0~65535 cycle
// rSDIDSTA=rSDIDSTA;
for(i=0;i<0x1000;i++);
Uart_Printf("power up\n");
}
void SD_HardWareInit(void)
{
//GPEUP GPE[15:0] 1: The pull-up function is disabled.
rGPEUP = 0xf83f; // The pull up
//GPECON GPE5 [11:10] = 10 : SDCLK
//GPECON GPE6 [13:12] = 10 : SDCMD
//GPECON GPE7 [15:14] = 10 : SDDAT0
//GPECON GPE8 [17:16] = 10 : SDDAT1
//GPECON GPE9 [19:18] = 10 : SDDAT2
//GPECON GPE10 [21:20] = 10 : SDDAT3
rGPECON = 0xaaaaaaaa;
SD_Clk400k();
SD_Powerup();
}
U8 SD_ResetSD(void)
{
return(CMD0());
}
U8 Card_Indentify(U16 RCA)
{
int i;
U8 c;
//-- Negotiate operating condition for SD, it makes card ready state
for(i=0;i<15;i++)
{
CMD55(RCA); // Make ACMD
rSDICARG=0xff8000; //ACMD41(OCR:2.7V~3.6V)
rSDICCON=(0x1<<9)|(0x1<<8)|0x69;//sht_resp, wait_resp, start, ACMD41
c=Chk_CMDend(41, 1);
//-- Check end of ACMD41
if( c==SD_NO_ERR & rSDIRSP0==0x80ff8000 )
{
//rSDICSTA=0xa00; // Clear cmd_end(with rsp)
return (U8)SD_CARD; // Success
}
Delay(200); // Wait Card power up status
}
//Uart_Printf("SDIRSP0=0x%x\n",rSDIRSP0);
//rSDICSTA=0xa00;
// Clear cmd_end(with rsp)
if(c!=SD_NO_ERR)return (U8)CMD_ERR;
Uart_Printf("Card_Indentify\n");
return (U8)MMC_CARD;
}
U8 SD_ReadAllCID(void)
{
U32 n;
for(n=0;n<100;n++)
{
//-- Check attaced cards, it makes card identification state
//SDICARG CmdArg [31:0] = 0 : Command Argument
rSDICARG=0x0; // CMD2(stuff bit)
//SDICCON CmdIndex [7:0] = 0X42 : Command index with start 2bit (8bit)
//SDICCON Command Start(CMST) [8 ] = 1 : command start
//SDICCON WaitRsp [9 ] = 1 : wait response
//SDICCON LongRsp [10 ] = 1 : long response
rSDICCON=(0x1<<10)|(0x1<<9)|(0x1<<8)|0x42; //lng_resp, wait_resp, start, CMD2
//-- Check end of CMD2
if(SD_NO_ERR==Chk_CMDend(2, 1))
{
Uart_Printf("\nEnd id\n");
return SD_NO_ERR;
}
}
//rSDICSTA=0xa00; // Clear cmd_end(with rsp)
return SD_ERR;
}
U8 SD_GetRCA(U8 card_type,U16 *pRCA)
{
U32 n,m;
if(card_type==SD_CARD)
{
for(n=0;n<100;n++)
{
// RECMD3:
//--Send RCA
//SDICARG CMD3(MMC:Set RCA, SD:Ask RCA-->SBZ)
for(m=0;m<100;m++)
{
rSDICARG=0<<16;
//SDICCON CmdIndex [7:0] = 0X43 : Command index with start 2bit (8bit)
//SDICCON Command Start(CMST) [8 ] = 1 : command start
//SDICCON WaitRsp [9 ] = 1 : wait response
//SDICCON LongRsp [10 ] = 0 : short response
rSDICCON=(0x1<<9)|(0x1<<8)|0x43; // sht_resp, wait_resp, start, CMD3
//-- Check end of CMD3
if(SD_NO_ERR==Chk_CMDend(3, 1))break;
}
//rSDICSTA=0xa00; // Clear cmd_end(with rsp)
//--Publish RCA
if(m==100)continue;
*pRCA=(( rSDIRSP0 & 0xffff0000 )>>16);
Uart_Printf("RCA=0x%x\n",*pRCA);
//--State(stand-by) check
if((( rSDIRSP0 & 0x1e00)==0x600) )
{
return SD_NO_ERR; // CURRENT_STATE check
}
}
Uart_Printf("CARD_STATUS=0x%x\n",rSDIRSP0 & 0x1e00);
return SD_ERR;
}
return MMC_CARD;
//goto RECMD3;
}
U8 SD_GetCardInfo(SDFSDisk *sds)
{
U32 n,i,temp,sum,C_Size;
U16 cRCA;
cRCA=sds->RCA;
for(n=0;n<100;n++)
{
rSDICARG =cRCA<<16;
rSDICCON=(0x1<<10)|(0x1<<9)|(0x1<<8)|0x49;
if(SD_NO_ERR==Chk_CMDend(9,1))break;
}
if(n==100)return SD_ERR;
temp=(U32)((rSDIRSP1&0x000f0000)>>16);//To get blocklen
sum=1;
for(i=0;i<temp;i++)
{
sum*=2;
}
sds->block_len=sum;
temp=(U32)((rSDIRSP2&0xc0000000)>>30);
C_Size=(U32)((rSDIRSP1&0x000003ff)<<2);
C_Size+=temp;
temp=(U32)(((rSDIRSP2&0x00038000)>>15)+2);
sum=1;
for(i=0;i<temp;i++)
{
sum*=2;
}
sds->block_num=((C_Size+1)*sum);
temp=(U32)((rSDIRSP2&0x00003f80)>>7);
sds->sector_size=temp;
return SD_NO_ERR;
}
U8 SD_SelectCard(U16 RCA)
{
return(Card_sel_desel(RCA,1));
}
U8 SD_DeSelectCard(void)
{
return(Card_sel_desel(0,0));
}
U8 SD_Initialize(SDFSDisk *sds)
{
U8 response[16],ret;
sds->RCA=0;
SD_HardWareInit();
ret=SD_ResetSD();
if(ret!=SD_NO_ERR)
{
Uart_Printf("reset SD err\n");
return ret;
}
Uart_Printf("reset SD\n");
ret=Card_Indentify(sds->RCA);
if(ret==CMD_ERR)
{
Uart_Printf("Indentify ERR\n");
return ret;
}
Uart_Printf("card_type success\n");
sds->card_type=ret;
ret=SD_ReadAllCID();
if(ret!=SD_NO_ERR)
{
Uart_Printf("read CID err\n");
return ret;
}
if(sds->RCA==0)
{
card_id++;
sds->RCA=card_id;
}
ret=SD_GetRCA(sds->card_type,&sds->RCA);
if(ret!=SD_NO_ERR)
{
Uart_Printf("get RCA err\n");
return ret;
}
ret=SD_GetCardInfo(sds);
if(ret!=SD_NO_ERR)
{
Uart_Printf("Get Card_Info err\n");
return ret;
}
Uart_Printf("block_num=0x%x\n",FS__pDevInfo[0].harddisk_info->block_num);
Uart_Printf("block_len=0x%x\n",FS__pDevInfo[0].harddisk_info->block_len);
Uart_Printf("sector_size=0x%x\n",FS__pDevInfo[0].harddisk_info->sector_size);
Uart_Printf("card_type=0x%x\n",FS__pDevInfo[0].harddisk_info->card_type);
SD_ClkToMax();
Uart_Printf("CLK_MAX\n");
return SD_NO_ERR;
}
U8 SD_ReadCard_Status(U16 RCA,U8 len,U8 status[])
{
U32 n,i;
int response0;
for(n=0;n<100;n++)
{
rSDICARG=RCA<<16;
rSDICCON=(0x1<<9)|(0x1<<8)|0x4d;
if(SD_NO_ERR==Chk_CMDend(13,1))break;
}
if(n==100)return SD_ERR;
for(i=0;i<len;i++)
{
status[i]=((rSDIRSP0&(0xff<<(i*8)))>>(i*8));
}
if(rSDIRSP0&0x100)
Uart_Printf("Ready for Data\n");
else
Uart_Printf("Not Ready\n");
response0=rSDIRSP0;
response0 &= 0x1e00;
response0 = response0 >> 9;
Uart_Printf("Current Status=%d\n", response0);
return SD_NO_ERR;
}
U8 SD_ReadBlock(SDFSDisk *sds,U32 blocknum,U8 *recbuf)
{
U8 ret,status[4];
U32 i;
U32 *src,dst[128];
for(i=0;i<128;i++)
{
dst[i]=0x0;
}
src=(U32 *)(blocknum*SD_BLOCKSIZE);
ret=SD_ReadCard_Status(sds->RCA,4,status);
if(ret!=SD_NO_ERR)return ret;
ret=SD_SelectCard(sds->RCA);
if(ret!=SD_NO_ERR) return ret;
if(sds->card_type==SD_CARD)
{
ret=Set_4bit_bus(sds->RCA);
if(ret!=SD_NO_ERR)return ret;
}
Uart_Printf("block_LEN=0x%x\n",rSDIBSIZE);
ret=Rd_Block((U32)1,(U32 *)src,(U32 *)dst);
if(ret!=SD_NO_ERR)return ret;
for(i=0;i<128;i++)
{
recbuf[4*i+3]=(U8)(dst[i]&0xff);
recbuf[4*i+2]=(U8)((dst[i]&0xff00)>>8);
recbuf[4*i+1]=(U8)((dst[i]&0xff0000)>>16);
recbuf[4*i+0]=(U8)((dst[i]&0xff000000)>>24);
}
ret=SD_DeSelectCard();
return SD_NO_ERR;
}
U8 SD_WriteBlock(SDFSDisk *sds,U32 blocknum,U8 *recbuf)
{
U8 ret,status[4];
U32 i;
U32 src[128],*dst;
for(i=0;i<128;i++)
{
src[i]=(recbuf[4*i+0]<<24)+(recbuf[4*i+1]<<16)+(recbuf[4*i+2]<<8)+(recbuf[4*i+3]);
}
dst=(U32 *)(blocknum*SD_BLOCKSIZE);
ret=SD_ReadCard_Status(sds->RCA,4,status);
if(ret!=SD_NO_ERR) return ret;
ret=SD_SelectCard(sds->RCA);
if(ret!=SD_NO_ERR) return ret;
if(sds->card_type==SD_CARD)
{
ret=Set_4bit_bus(sds->RCA);
if(ret!=SD_NO_ERR)return ret;
}
Uart_Printf("block_LEN=0x%x\n",rSDIBSIZE);
ret=Wt_Block((U32)1,(U32 *)src,(U32 *)dst);
if(ret!=SD_NO_ERR)return ret;
ret=SD_DeSelectCard();
return SD_NO_ERR;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -