📄 sdi.c
字号:
#ifndef SDI_C
#define SDI_C
#include "Def.h"
#include "option.h"
//#include ""
#include "2410addr.h"
int *wt_buffer;
int *rd_buffer;
int rca;
int status;
/*
static int delayLoopCount = 75000000/10000/10;
void Delay(int time)
{
// time=0: adjust the Delay function by WatchDog timer.
// time>0: the number of loop time
// resolution of time is 100us.
int i,adjust=0;
if(time==0)
{
time = 200;
adjust = 1;
delayLoopCount = 400;
//PCLK/1M,Watch-dog disable,1/64,interrupt disable,reset disable
rWTCON = ((PCLK/1000000-1)<<8)|(2<<3);
rWTDAT = 0xffff; //for first update
rWTCNT = 0xffff; //resolution=64us @any PCLK
rWTCON = ((PCLK/1000000-1)<<8)|(2<<3)|(1<<5); //Watch-dog timer start
}
for(;time>0;time--)
for(i=0;i<delayLoopCount;i++);
if(adjust==1)
{
rWTCON = ((PCLK/1000000-1)<<8)|(2<<3); //Watch-dog timer stop
i = 0xffff - rWTCNT; //1count->64us, 200*400 cycle runtime = 64*i us
delayLoopCount = 8000000/(i*64); //200*400:64*i=1*x:100 -> x=80000*100/(64*i)
}
}
*/
void Flush_Rx_buf(void)
{
//-- Flushing Rx buffer
int i;
rd_buffer=(int *)0x31800000;
for(i=0;i<2048;i++) //128[word]*16[blk]=8192[byte]
*(rd_buffer+i)=2;
// Uart_Printf("\n--End Rx buffer flush\n");
}
void TR_Buf_new(void)
{
//-- Tx & Rx Buffer initialize
int i, j;
int start = 0x03020100;
wt_buffer=(int *)0x31000000;
j=0;
for(i=0;i<2048;i++) //128[word]*16[blk]=8192[byte]
*(wt_buffer+i)=i+j; //i+j's value sent into the address
// *(Tx_buffer+i)=0x5555aaaa;
Flush_Rx_buf();
}
void CheckEnd(void)
{
int finish;
finish=rSDICSTA;
while((finish&0x800)!=0x800) // Check cmdend==1,
finish=rSDICSTA;
rSDICSTA=finish;// Clear cmd end state
}
int WatResCheckEnd(void) //0:timeout
{
int finish;
finish=rSDICSTA;
while( !( ((finish&0x200)==0x200) | ((finish&0x400)==0x400) )) // Check cmd/rsp end
finish=rSDICSTA;
if( (finish&0x1f00) != 0xa00 )
{
rSDICSTA=finish;
if(((finish&0x400)==0x400))
return 0;
}
rSDICSTA=finish;
return 1;
}
int WatResCheckEnd0(void) //0:timeout
{
int finish;
finish=rSDICSTA;
while( !( ((finish&0x200)==0x200) | ((finish&0x400)==0x400) )) // Check cmd/rsp end
finish=rSDICSTA;
if( (finish&0xf00) != 0xa00 )
{
rSDICSTA=finish;
if(((finish&0x400)==0x400))
return 0;
}
rSDICSTA=finish;
return 1;
}
void CMD0(void)
{
rSDICARG=0;
rSDICCON=1<<8|0x40;
CheckEnd();
}
int CMD55(void)
{
rSDICARG=0;
rSDICCON=1<<9|1<<8|0x77;
return WatResCheckEnd();
}
int ACMD41(void) //0 timeout
{
int i,j;
CMD55();
rSDICARG=0xff8000;//fc0000
rSDICCON=1<<9|1<<8|0x69;
i=WatResCheckEnd0();
j=(rSDIRSP0==0x80ff8000);
return (i&j);
}
int CMD2(void)
{
//rSDICARG=0xff8000;// no use
rSDICARG=0x0;
rSDICCON=(0x1<<10)|1<<9|1<<8|0x42;
return WatResCheckEnd();
}
int CMD3(void)
{
//rSDICARG=0xff8000;//no use
rSDICCON=1<<9|1<<8|0x43;
return WatResCheckEnd();
}
int ACMD6(void)
{
CMD55();
rSDICARG=0x0;
rSDICCON=1<<9|1<<8|0x46;
return WatResCheckEnd();
}
/*
int CMD7(void)
{
//rSDICARG=rSDIRSP0&0xffff0000;
int i,j;
rSDICARG=rca<<16;
rSDICCON=1<<9|1<<8|0x47;
i=WatResCheckEnd();
j=((rSDIRSP0&0x1e00)==0x800);
return (i&j);
}
*/
int CMD25(void)
{
rSDICARG=0;
rSDICCON=(1<<9)|(1<<8)|0x59;
return WatResCheckEnd();
}
int CMD12(void)
{
rSDICARG=0x0;
rSDICCON=(0x1<<9)|(0x1<<8)|0x4c;
return WatResCheckEnd();
}
int SdiInit(void)
{
int i;
//int rca;
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;
rSDICON=(1<<4)|1<<1|1;//FIFO RESET clock enable
rSDIPRE=PCLK/(2*400000)-1;
rSDIBSIZE=0x200;
rSDIDTIMER=0xffff;
for(i=0;i<0x1000;i++); // Wait 74SDCLK for MMC card
CMD0();
for(i=0;i<15;i++)
{
if(ACMD41()==1) break;
Delay(200);
}
if(i==15) return 0;
//Delay(200);
while(!(rSDIRSP0&0x80000000)) ;//wait for system ready
while(!CMD2()) ;
L: while(!CMD3()) ;
rca=( rSDIRSP0 & 0xffff0000 )>>16;
if( (rSDIRSP0 & 0x1e00)!=0x600 ) // CURRENT_STATE check
goto L;
rSDIPRE=PCLK/(2*5000000)-1;
//while(!CMD7()) ;
RECMDS7:
//SDICARG CmdArg [31:0] = RCA<<16 : CMD7(RCA,stuff bit)
rSDICARG=rca<<16;
//SDICCON CmdIndex [7:0] = 0X47 : 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)|0x47; // sht_resp, wait_resp, start, CMD7
//-- Check end of CMD7
if(!WatResCheckEnd())
goto RECMDS7;
//rSDICSTA=0xa00; // Clear cmd_end(with rsp)
//--State(transfer) check
//if( (rSDIRSP0 & 0x1e00)!=0x800 )
// goto RECMDS7;
while(!ACMD6()) ;
TR_Buf_new();
return 1;
}
int Chk_BUSYend(void)
{
int finish;
finish=rSDIDSTA;
while( !( ((finish&0x08)==0x08) | ((finish&0x20)==0x20) ))
finish=rSDIDSTA;
if( (finish&0xfc) != 0x08 )
{
//Uart_Printf("DATA:finish=0x%x\n", finish);
rSDIDSTA=0xf4; //clear error state
return 0;
}
return 1;
}
int Chk_DATend(void)
{
int finish;
finish=rSDIDSTA;
while( !( ((finish&0x10)==0x10) | ((finish&0x20)==0x20) ))
// Chek timeout or data end
finish=rSDIDSTA;
if( (finish&0xfc) != 0x10 )
{
//Uart_Printf("DATA:finish=0x%x\n", finish);
rSDIDSTA=0xec; // Clear error state
return 0;
}
return 1;
}
void Write(void)
{
int i;
int wt_cnt=0;
//rSDICON |= rSDICON|(1<<1);
rSDIDCON=1<<20|1<<17|0<<16|3<<12|16;
while(!CMD25()) ;
while(wt_cnt<128*16)
{
status=rSDIFSTA;
if((status&0x2000)==0x2000)
{
rSDIDAT=*(wt_buffer++);
wt_cnt++;
}
}
/*
while(!((rSDIDSTA&0x20)==0x20|(rSDIDSTA&0x10)==0x10))
// finish=rSDIDSTA;
if((rSDIDSTA&0x10)!=0x10) //timeout
{
rSDIDSTA=0xec;
//date error
}
else
rSDIDSTA=rSDIDSTA;*/
Chk_DATend();
rSDIDSTA=0x10;
rSDIDCON=(1<<18)|(1<<17)|(0<<16)|(1<<12)|(16);
i=CMD12();
while(!i) i=CMD12();
Chk_BUSYend();
rSDIDSTA=0x08;
}
int CMD18(void)
{
rSDICARG=0x0;
rSDICCON=(0x1<<9)|(0x1<<8)|0x52;
return WatResCheckEnd();
}
void Read(void)
{
int i;
int rd_cnt=0;
int x;
//rSDICON |= rSDICON|(1<<1);
rSDIDCON=(1<<19)|(1<<17)|(0<<16)|(2<<12)|(16);
while(!CMD18()) ;
while(rd_cnt<128*16)
{
status=rSDIDSTA;
if((status&0x20)==0x20) // Check timeout
{
rSDIDSTA=0x1<<0x5;
break;
}
//if((rSDIDSTA&0x40)==0x40)//error
// rSDIDSTA=1<<6;
x=rSDIFSTA;
if((x&0x1000)==0x1000)
{
*rd_buffer++=rSDIDAT;
rd_cnt++;
}
}
Chk_DATend(); //0:timeout
rSDIDSTA=0x10;
while(!CMD12()) ;
// rSDIDCON=(1<<18)|(1<<17)|(0<<16)|(1<<12)|(16);
// Chk_BUSYend();
// rSDIDSTA=0x08;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -