📄 sdi.c
字号:
printf("Input Write Block Number[1~4095] : ");
BlockNum = GetIntNum();
}
printf("Input Write Data Offset : ");
Offset = GetIntNum();
OneBlockSize = Card_OneBlockSize;
Tx_buffer = (U32 *)SDI_Tx_buffer;
for(i=0 ; i<(OneBlockSize*BlockNum)/4 ; i++)
*(Tx_buffer+i) = (i+Offset);
rSDIFSTA |=(1<<16); //FIFO reset
rSDIDCON=(2<<22)|(1<<20)|(1<<17)|(Wide<<16)|(1<<14)|(3<<12)|(BlockNum<<0);
switch(Testmode)
{
case POL:
printf("\nPolling mode data write\n");
if(BlockNum<2)//single block
{
SDIO_Command((StartAddr*512), 24, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
while((Check_CMDend(24, 1) !=1))
SDIO_Command((StartAddr*512), 24, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
}
else//multi block
{
SDIO_Command((StartAddr*512), 25, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
while((Check_CMDend(25, 1) !=1))
SDIO_Command((StartAddr*512), 25, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
}
rSDICSTA = CMD_END|RESP_END; // Clear cmd_end(with rsp)
printf("\nBlock zise=%x\n",OneBlockSize*BlockNum/4);
while(wt_cnt < (OneBlockSize*BlockNum)/4)
{
status = rSDIFSTA;
if(status && TX_FIFO_AVAILABLE_DETECT)
{
rSDIDAT = *Tx_buffer++;
wt_cnt++;
}
}
printf("\nWrite count=%x\n",wt_cnt);
break;
case INT:
printf("\nInterrupt mode data write\n");
pISR_SDI_0=(unsigned)Wt_Int;
rINTMSK &= ~(BIT_SDI0);
rSDIIMSK=0x10; // Tx FIFO half int.
StartStopwatch();
if(BlockNum<2)//single block
{
SDIO_Command((StartAddr*512), 24, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
while((Check_CMDend(24, 1) !=1))
SDIO_Command((StartAddr*512), 24, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
}
else//multi block
{
SDIO_Command((StartAddr*512), 25, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
while((Check_CMDend(25, 1) !=1))
SDIO_Command((StartAddr*512), 25, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
}
rSDICSTA |= CMD_END|RESP_END; // Clear cmd_end(with rsp)
while(!TR_end);
rINTMSK |= (BIT_SDI0);
TR_end=0;
rSDIIMSK=0; // All mask
break;
case DMA:
printf("\nDMA mode data write\n");
pISR_DMA=(unsigned)DMA_end;
rINTMSK&=~(BIT_DMA);
rINTSUBMSK&=~(BIT_SUB_DMA0);
rDISRC0 = (int)(Tx_buffer);
rDISRCC0 = (0<<1) | (0<<0);
rDIDST0 = (U32)(SDIDAT);
rDIDSTC0 = (1<<1)|(1<<0);
rDCON0 = (1<<31)|(0<<30)|(1<<29)|(1<<28)|(0<<27)|(1<<24)|(1<<22)|(2<<20) |((128*BlockNum)/4);
rDMASKTRIG0 = (0<<2)|(1<<1)|0; //no-stop, DMA0 channel on, no-sw trigger
rDMAREQSEL0 = (10 <<1) | 1;
StartStopwatch();
if(BlockNum<2)//single block
{
SDIO_Command((StartAddr*512), 24, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
while((Check_CMDend(24, 1) !=1))
SDIO_Command((StartAddr*512), 24, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
}
else//multi block
{
SDIO_Command((StartAddr*512), 25, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
while((Check_CMDend(25, 1) !=1))
SDIO_Command((StartAddr*512), 25, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
}
rSDICSTA |= CMD_END|RESP_END; // Clear cmd_end(with rsp)
if(Wide!=0)
rSDIDCON |= WIDE_BUS_EN;
else
rSDIDCON &= ~WIDE_BUS_EN;
//printf("Origin TC=%x\n",(rDSTAT0&0xff));
rSDIDCON |=BURST4_EN|WORD_TRANSFER|TRANS_AFTER_RESP|BLOCK_TRANSFER|DMA_EN|BlockNum;
rSDIDCON |= DATA_TRANSMIT_MODE|DATA_TRANSMIT_START;
while(!TR_end);
rINTMSK |= (1<<20);
rINTSUBMSK |= (1<<27);
TR_end=0;
rDMASKTRIG0 |=(1<<2);//DMA Stop
default : break;
}
while(!Check_DATend()) ;
//printf("\nData End Error\n");
rSDIDCON=rSDIDCON&~(7<<12); //YH 040220, Clear Data Transfer mode => no operation, Cleata Data Transfer start
rSDIDSTA |= DATA_FINISH; // Clear data Tx/Rx end
if(BlockNum>1)
{
rSDIDCON=BUSY_AFTER_CMD|BLOCK_TRANSFER|WIDE_BUS_DIS|DATA_TRANSMIT_START|ONLYBUSY_CHECK|(BlockNum<<0);
SDIO_Command(0, 12, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
while(Check_CMDend(12, 1) != 1)
SDIO_Command(0, 12, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
rSDICSTA = CMD_END|RESP_END; // Clear cmd_end(with rsp)
if(!Check_BUSYend())
//printf("error\n");
rSDIDSTA|= DATA_FINISH; //! Should be cleared by writing '1'.
}
transtime = EndStopwatch();
CalculationBPS_NORMALSD_MMC(transtime);
BlockNum =0;
}
void SDIO_EraseBlock(void)
{
U32 StartAddr, EndAddr;
printf("\nSD/MMC block erase test\n");
printf("\nInput Write Start Block Address(0x200, 0x400...) : "); //ex) 0x200[512bytes], 0x400, 0x800.....
StartAddr = GetIntNum();
printf("Input Write End Block Address(0x200, 0x400...) : "); //ex) 0x200[512bytes], 0x400, 0x800.......
EndAddr = GetIntNum();
#if 0
SDIO_Command(StartAddr, 32, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
while((Check_CMDend(32, 1) !=1))
{
SDIO_Command(StartAddr, 32, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
printf("\nCMD32 fail\n");
}
printf("\nCMD32 OK\n");
#else
if(MMC == 0)
{
SDIO_Command(StartAddr, 32, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
while(Check_CMDend(32, 1) != 1)
SDIO_Command(StartAddr, 32, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
rSDICSTA = CMD_END|RESP_END; // Clear cmd_end(with rsp)
SDIO_Command(EndAddr, 33, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
while(Check_CMDend(33, 1) != 1)
SDIO_Command(EndAddr, 33, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
rSDICSTA = CMD_END|RESP_END; // Clear cmd_end(with rsp)
}
else if(MMC == 1)
{
SDIO_Command(StartAddr, 35, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
while(Check_CMDend(35, 1) != 1)
SDIO_Command(StartAddr, 35, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
rSDICSTA = CMD_END|RESP_END; // Clear cmd_end(with rsp)
SDIO_Command(EndAddr, 36, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
while(Check_CMDend(36, 1) != 1)
SDIO_Command(EndAddr, 36, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
rSDICSTA = CMD_END|RESP_END; // Clear cmd_end(with rsp)
}
#endif
rSDIDSTA |= (1<<7)|(1<<6)|(1<<5)|(1<<4)|(1<<3)|(1<<2);
rSDIDCON = 0;
if(Wide==0)
rSDIDCON &= ~WIDE_BUS_EN;
else
rSDIDCON |= WIDE_BUS_EN;
rSDIDCON |= BUSY_AFTER_CMD|BLOCK_TRANSFER|BlockNum;
rSDIDCON |= ONLYBUSY_CHECK|DATA_TRANSMIT_START;
SDIO_Command(0, 38, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
while(Check_CMDend(38, 1) != 1)
SDIO_Command(0, 38, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
rSDICSTA = CMD_END|RESP_END; // Clear cmd_end(with rsp)
if(!Check_BUSYend())
printf("\nBusy Check Error...\n");
rSDIDSTA = (1<<3);
printf("\n[SD/TFlash card Erase Block Test...End]\n");
}
int SD_card_init(void)
{
int i, Card_State, blocksize;
char key;
int uArg;
U32 C_SIZE, C_SIZE_MULT, READ_BL_LEN, CardSize, OneBlockSize;
rSDIPRE=PCLK/(INICLK)-1; // Clock setting
SDIO_TypeSetting(SDIO_SD_TYPE, SDIO_TYPE_A);// clock type setting
rSDICON |= ENCLK; //Clock enable
rSDIFSTA |= (1<<16);//FIFO reset
SDIO_BlockSizeSetting(512); //block size setting
rSDIDTIMER |=0x7fffff; //busy timer setting
Delay(0x1000); // Wait 74SDCLK for MMC card
SDIO_Command(0x0, 0x0, SDIO_NO_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
Check_CMDend(0,0);
//-------------------------------------------------------------------------------------//
#if 0
printf("\nCMD8\n");
SDIO_Command(0x1aa, 0x8, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);//SD Card version Check
while(Check_CMDend(8,1) != 1)
SDIO_Command(0x1aa, 0x8, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);//SD Card version Check
printf("rSDIRSP0 = %x\n",rSDIRSP0);
#endif
//-------------------------------------------------------------------------------------//
printf("\nEnter to the Idle State\n");
if(Check_MMC_OCR())
{
printf("\n\n[In MMC Memory ready....]\n");
MMC = 1;
}
if(MMC == 0)
{
printf("\nChecking the SD/TFlash Memory....");
if(Check_SD_OCR())
printf("\n\n[In SD/TFlash Memory Ready State....]\n");
else
{
printf("\n\nInitialize fail\nNo Card assertion\n");
return 0;
}
}
//-------------------------------------------------------------------------------------//
printf("\nCMD2 : CID response\n");
SDIO_Command(0x0, 2, SDIO_WAIT_RESP, SDIO_LONG_RESP, SDIO_WITHOUT_DATA);
while(Check_CMDend(2, 1) != 1)
SDIO_Command(0x0, 2, SDIO_WAIT_RESP, SDIO_LONG_RESP, SDIO_WITHOUT_DATA);
printf("\n - Product Name : %c%c%c%c%c",(rSDIRSP0&0xFF),((rSDIRSP1>>24)&0xFF),((rSDIRSP1>>16)&0xFF),((rSDIRSP1>>8)&0xFF),(rSDIRSP1&0xFF));
//-------------------------------------------------------------------------------------//
printf("\nCMD3 : assign relative address\n");
SDIO_Command((MMC<<16), 3, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
while( Check_CMDend(3, 1) !=1)
{
SDIO_Command((MMC<<16), 3, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
}
//-------------------------------------------------------------------------------------//
if(MMC)
{
RCA=1;
SDIO_PrescalerSetting(MMCCLK);
while(PCLK/(rSDIPRE+1) > 20000000)
rSDIPRE = rSDIPRE+1;
//rSDIPRE = 2;
printf("\nMMC Frequency is %dHz\n",(PCLK/(rSDIPRE+1)));
}
else
{
SDIO_PrescalerSetting(SDCLK);
while(PCLK/(rSDIPRE+1) > 25000000)
rSDIPRE = rSDIPRE+1;
printf("\nSD Frequency is %dHz\n",(PCLK/(rSDIPRE+1)));
RCA = ( rSDIRSP0 & 0xffff0000 )>>16;
printf("RCA=0x%x\n",RCA);
}
/*
uArg=(3<<24)|(185<<16)|(1<<8); // Change to the high-speed mode
SDIO_Command(uArg, 6, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);//ACMD6 select bus width
while((Check_CMDend(6, 1) !=1))
SDIO_Command(uArg, 6, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);//ACMD6 select bus width
rSDICSTA |= CMD_END|RESP_END;
printf("\nMoviNand high speed mode set\n");
*/
//-------------------------------------------------------------------------------------//
SDIO_Command(RCA<<16, 9, SDIO_WAIT_RESP, SDIO_LONG_RESP, SDIO_WITHOUT_DATA);
while(Check_CMDend(9, 1) != 1)
SDIO_Command(RCA<<16, 9, SDIO_WAIT_RESP, SDIO_LONG_RESP, SDIO_WITHOUT_DATA);
READ_BL_LEN = ((rSDIRSP1>>16)&0xF);
C_SIZE = ((rSDIRSP1&0x3ff)<<2) | ((rSDIRSP2>>30)&0x3);
C_SIZE_MULT = ((rSDIRSP2>>15)&0x7);
CardSize = (1<<READ_BL_LEN)*(C_SIZE+1)*(1<<(C_SIZE_MULT+2))/1048576;
OneBlockSize = (1<<READ_BL_LEN);
printf("\n READ_BL_LEN: %d",READ_BL_LEN);
printf("\n C_SIZE: %d",C_SIZE);
printf("\n C_SIZE_MULT: %d\n",C_SIZE_MULT);
printf("\n One Block Size: %dByte",OneBlockSize);
printf("\n Total Card Size: %dMByte\n",CardSize+1);
//-------------------------------------------------------------------------------------//
CARD_SEL_DESEL(1);//Enter Card state to the transfer mode
SDIO_Command(512, 16, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
while(Check_CMDend(16, 1) != 1)
SDIO_Command(512, 16, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
printf("\nSet Block Length");
if(!MMC)
{
Set_4bit_bus();
}
else
{
Set_1bit_bus();
//Set_4bit_bus_MoviNand();
}
return 1;
}
void Set_1bit_bus(void)
{
Wide=0;
SET_BUSWIDTH();
printf("\n****1bit bus****\n");
}
void Set_4bit_bus(void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -