📄 sd.c
字号:
}
}
rSDICSTA = 0xa00; // Clear cmd_end(with rsp)
Delay(50);
rDMASKTRIG0 = (0<<2)+(1<<1)+0; //no-stop, DMA0 channel on, no-sw trigger
while(!TR_end);
Uart_Printf("rSDIFSTA=0x%x\n",rSDIFSTA);
rINTMSK |= (BIT_DMA0);
TR_end = 0;
rDMASKTRIG0 = (1<<2); //DMA0 stop
break;
default:
break;
}
//-- Check end of DATA
for (i = 0; i < 50; i++)
{
if(Chk_DATend())
{
break;
}
else
{
Uart_Printf("Read Dat Error!!\n");
return 0;
}
}
rSDIDCON = rSDIDCON&~(7<<12); //YH 040220, Clear Data Transfer mode => no operation, Cleata Data Transfer start
rSDIFSTA = rSDIFSTA&0x200; //Clear Rx FIFO Last data Ready, YH 040221
rSDIDSTA = 0x10; // Clear data Tx/Rx end detect
if(blocknum > 1)
{
i = 0;
do
{
//--Stop cmd(CMD12)
rSDICARG = 0x0; //CMD12(stuff bit)
rSDICCON = (0x1<<9)|(0x1<<8)|0x4c;//sht_resp, wait_resp, start, CMD12
i++;
}
//-- Check end of CMD12
while(!Chk_CMDend(12, 1) && (i < 100));
rSDICSTA = 0xa00; // Clear cmd_end(with rsp)
}
//CMD13();
return 1;
}
int SD_Wt_Block(card_desc *CardInfo, U32 mode, U32 addr, U32 blocknum)
{
int status;
int i = 0;
int wt_cnt = 0;
const U32 cc = 1;
rSDIFSTA = rSDIFSTA | (1<<16); //YH 040223 FIFO reset
if (mode != 2)
{
//rSDIDCON=(2<<22)|(1<<20)|(1<<17)|(Wide<<16)|(3<<12)|(block<<0);
rSDIDCON=(2<<22)|(1<<20)|(1<<17)|(Wide<<16)|(1<<14)|(3<<12)|(blocknum<<0); //YH 040220
//Word Tx, Tx after rsp, blk, 4bit bus, Tx start,Data transmit mode, blk num
}
rSDICARG = addr; // CMD24/25(addr)写入地址
switch(mode)
{
case POL:
if(blocknum < 2) // SINGLE_WRITE
{
do
{
rSDICCON = (0x1<<9)|(0x1<<8)|0x58; //sht_resp, wait_resp, dat, start, CMD24
i++;
}
while(!Chk_CMDend(24, 1) && (i < 50)); //-- Check end of CMD24
}
else // MULTI_WRITE
{
do
{
rSDICCON=(0x1<<9)|(0x1<<8)|0x59; //sht_resp, wait_resp, dat, start, CMD25
i++;
}
while(!Chk_CMDend(25, 1) && (i < 50)); //-- Check end of CMD25
}
rSDICSTA = 0xa00; // Clear cmd_end(with rsp)
i = 0;
while(wt_cnt < 128*blocknum)
{
status = rSDIFSTA;
if((status&0x2000) == 0x2000)
{
rSDIDAT = *(Tx_buffer + i);
i++;
wt_cnt++;
//Uart_Printf("Dat=%d, wt_cnt=%d\n",*(Tx_buffer+i),wt_cnt);
}
}
break;
case INT:
return 0;
/*
pISR_SDI = (unsigned)Wt_Int;
rSDIIMSK = 0x10; // Tx FIFO half int.
rINTMSK &= ~(BIT_SDI);
if(blocknum<2) // SINGLE_WRITE
{
rSDICCON=(0x1<<9)|(0x1<<8)|0x58; //sht_resp, wait_resp, dat, start, CMD24
if(!Chk_CMDend(24, 1)) //-- Check end of CMD24
goto REWTCMD;
}
else // MULTI_WRITE
{
rSDICCON=(0x1<<9)|(0x1<<8)|0x59; //sht_resp, wait_resp, dat, start, CMD25
if(!Chk_CMDend(25, 1)) //-- Check end of CMD25
goto REWTCMD;
}
rSDICSTA=0xa00; // Clear cmd_end(with rsp)
while(!TR_end);
//while(wt_cnt<128);
rINTMSK |= (BIT_SDI);
TR_end=0;
rSDIIMSK=0; // All mask
break;
*/
case DMA:
pISR_DMA0 = (unsigned)DMA_end;
rINTMSK = ~(BIT_DMA0);
rSDIDCON = rSDIDCON|(1<<24); //YH 040227, Burst4 Enable
rDISRC0 = (int)(Tx_buffer); // source=Tx_buffer
rDISRCC0 = (0<<1) + (0<<0); // AHB, inc
rDIDST0 = (U32)(SDIDAT); // Destination=SDIDAT
rDIDSTC0 = (1<<1) + (1<<0); // APB, fix
rDCON0 = (cc<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(2<<24)+(1<<23)+(1<<22)+(2<<20)+128*blocknum;
//handshake, sync PCLK, TC int, single tx, single service, SDI, H/W request,
//auto-reload off, word, 128blk*num
rSDIDCON = (2<<22)|(1<<20)|(1<<17)|(Wide<<16)|(1<<15)|(1<<14)|(3<<12)|(blocknum<<0); //YH 040220
// Word Tx, Tx after rsp, blk, 4bit bus, dma enable, Tx start, blk num
i = 0;
if(blocknum < 2) // SINGLE_WRITE
{
do
{
rSDICCON = (0x1<<9)|(0x1<<8)|0x58; //sht_resp, wait_resp, dat, start, CMD24
i++;
}
while(!Chk_CMDend(24, 1) && (i < 50)); //-- Check end of CMD24
}
else // MULTI_WRITE
{
do
{
rSDICCON=(0x1<<9)|(0x1<<8)|0x59; //sht_resp, wait_resp, dat, start, CMD25
i++;
}
while(!Chk_CMDend(25, 1) && (i < 50)); //-- Check end of CMD25
}
rSDICSTA = 0xa00; // Clear cmd_end(with rsp)
Delay(50);
rDMASKTRIG0 = (0<<2) + (1<<1)+0; //no-stop, DMA0 channel on, no-sw trigger
while(!TR_end);
rINTMSK |= (BIT_DMA0);
TR_end = 0;
rDMASKTRIG0 = (1<<2) + (0<<1); //DMA0 stop,DMA0 channel off
break;
default:
break;
}
//-- Check end of DATA
for (i = 0; i < 50; i++)
{
if(Chk_DATend())
{
break;
}
}
if (i == 50)
{
Uart_Printf("Write Dat Error!!\n");
return 0;
}
rSDIDCON = rSDIDCON & ~(7<<12); //YH 040220, Clear Data Transfer mode => no operation, Cleata Data Transfer start
rSDIDSTA = 0x10; // Clear data Tx/Rx end
if((blocknum > 1) )
{
//--Stop cmd(CMD12)
i = 0;
do
{
rSDIDCON=(1<<18)|(1<<17)|(Wide<<16)|(1<<14)|(1<<12)|(blocknum<<0); //YH 040220
rSDICARG = 0x0; //CMD12(stuff bit)
rSDICCON=(0x1<<9)|(0x1<<8)|0x4c; //sht_resp, wait_resp, start, CMD12
}
//-- Check end of CMD12
while(!Chk_CMDend(12, 1) && (i < 50));
rSDICSTA = 0xa00; // Clear cmd_end(with rsp)
//-- Check end of DATA(with busy state)
if(!Chk_BUSYend())
{
Uart_Printf("Chk_BUSYend Error!!\n");
return 0;
}
rSDIDSTA = 0x08; //! Should be cleared by writing '1'.
}
return 1;
//CMD13();
}
int SD_Get_CardStat(int iRCA)//CMD13
{
int response0;
unsigned int cc = 1;
rSDICARG = iRCA<<16; // CMD13(RCA,stuff bit)
rSDICCON = (0x1<<9) | (0x1<<8) | 0x4d; // sht_resp, wait_resp, start, CMD13
//-- Check end of CMD13
if(!Chk_CMDend(13, 1))
{
return -1;
}
//Uart_Printf("rSDIRSP0=0x%x\n", rSDIRSP0);
if (rSDIRSP0 & (cc << 31))
{
Uart_Printf("Error: OUT_OF_RANGE!\n");
}
else if (rSDIRSP0 & (cc << 30))
{
Uart_Printf("Error: ADDRESS_ERROR!\n");
}
else if (rSDIRSP0 & (cc << 29))
{
Uart_Printf("Error: BLOCK_LEN_ERROR!\n");
}
else if (rSDIRSP0 & (cc << 28))
{
Uart_Printf("Error: ERASE_SEQUENCE_ERROR!\n");
}
else if (rSDIRSP0 & (cc << 27))
{
Uart_Printf("Error: ERASE_INVALID_BLOCKS_ERROR!\n");
}
else if (rSDIRSP0 & (cc << 26))
{
Uart_Printf("Error: WP_VIOLATION_ERROR!\n");
}
else if (rSDIRSP0 & (cc << 25))
{
Uart_Printf("CARD_IS_LOCKED!\n");
}
else if (rSDIRSP0 & (cc << 24))
{
Uart_Printf("Error: LOCK_UNLOCK_FAILED!\n");
}
else if (rSDIRSP0 & (cc << 23))
{
Uart_Printf("Error: COM_CRC_ERROR!\n");
}
else if (rSDIRSP0 & (cc << 22))
{
Uart_Printf("Error: ILLEGAL_COMMAND!\n");
}
if(rSDIRSP0 & 0x100)
{
Uart_Printf("Ready for Data,");
}
response0 = rSDIRSP0;
response0 &= 0x1e00; //wangq
response0 = (response0 >> 9);
switch (response0)
{
case 0:
Uart_Printf("Current Status = 'Idle'\n");
break;
case 1:
Uart_Printf("Current Status = 'Ready'\n");
break;
case 2:
Uart_Printf("Current Status = 'Ident'\n");
break;
case 3:
Uart_Printf("Current Status = 'stby:Stand-by'\n");
break;
case 4:
Uart_Printf("Current Status = 'tran:Transfer'\n");
break;
case 5:
Uart_Printf("Current Status = 'data:Sending data'\n");
break;
case 6:
Uart_Printf("Current Status = 'rcv:Receive data'\n");
break;
case 7:
Uart_Printf("Current Status = 'prg:Programming'\n");
break;
case 8:
Uart_Printf("Current Status = 'dis:Disconnect'\n");
break;
default:
Uart_Printf("Current Status = 'Reserved'\n");
break;
}
rSDICSTA = 0xa00; // Clear cmd_end(with rsp)
return response0;
}
void SD_Test(void)
{
//U32 bnum;
U32 save_rGPEUP, save_rGPECON;
card_desc CardInf;
save_rGPEUP = rGPEUP;
save_rGPECON = rGPECON;
Uart_Printf("SDI Card Read and Write Test\n");
if( !SD_Card_Init(&CardInf) ) // 初始化
{
Uart_Printf("Initialize SD Card fail,No Card assertion!!\n");
return;
}
if(!CMD9(CardInf.RCA)) // Get CSD
{
Uart_Printf("Get CSD Failed!!!\n");
}
TR_Buf_new(); // 初始化缓冲区
/*
INOM:
Uart_Printf("How many blocks to test? (1~16): ");
bnum = (U32)Uart_GetIntNum();
if ((bnum == 0) | (bnum > 16))
{
goto INOM;
}
Uart_Printf("\n");
*/
//CMD13(); // Get card status
Uart_Printf("---- Block Write Test ----\n");
if( !SD_Wt_Block(&CardInf, DMA, 0, 20) )
{
Uart_Printf("Write Test Failed!\n");
}
Uart_Printf("---- Block Read Test ----\n");
if( !SD_Rd_Block(&CardInf, POL, 0, 20) )
{
Uart_Printf("Read Test Failed!\n");
}
Check_RxTx_buf(16);
if(CardInf.Card_Type == ENUM_CARD_TYPE_MMC)
{
rSDICON |= (1<<5); // YH 0519, MMC Type SDCLK
//Wt_Stream(0,1);
//Rd_Stream(0,1);
//Check_RxTx_buf(1);
}
Card_Deselect(); // Card deselect
rSDIDCON = 0; //tark???
rSDICSTA = 0xffff;
rGPEUP = save_rGPEUP;
rGPECON = save_rGPECON;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -