⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdi.c

📁 三星2443芯片
💻 C
📖 第 1 页 / 共 2 页
字号:

		 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)		
		}
	
	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)
{
	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);

	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);
    	}	
//-------------------------------------------------------------------------------------//

	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();
		}
	
	return 1;
    }

void Set_1bit_bus(void)
{
	Wide=0;
	SET_BUSWIDTH();
	printf("\n****1bit bus****\n");
}

void Set_4bit_bus(void)
{
	Wide=1;
       SET_BUSWIDTH();
       printf("\n****4bit bus****\n");
}

void Set_4bit_bus_MoviNand(void)
{
	Wide=1;
       SET_BUSWIDTH_MoviNand();
       printf("\n****4bit bus****\n");
}

void SET_BUSWIDTH(void)
{

	SDIO_Command((RCA<<16), 55, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);//befoe using ACMD
	while((Check_CMDend(55, 1) !=1))
		{
			SDIO_Command((RCA<<16), 55, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);//befoe using ACMD
		}

	SDIO_Command((Wide<<1), 6, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);//ACMD6 select bus width
	while((Check_CMDend(6, 1) !=1))
		SDIO_Command((Wide<<1), 6, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);//ACMD6 select bus width

	rSDICSTA |= CMD_END|RESP_END;	
}

void SET_BUSWIDTH_MoviNand(void)
{
	int uArg;

	uArg=((3<<24)|(183<<16)|(1<<8));
	
	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;	
}

void CARD_SEL_DESEL(U8 sel_desel)
{
	printf("\nCMD7 : Command toggles a card between the stand-by and transfer state\n");
	if(sel_desel)
		{
			printf("\nCMD7 : Select\n");
			SDIO_Command((RCA<<16), 7, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
			if((Check_CMDend(7, 1) !=1)||(rSDIRSP0 != 0x800))//entering the standby mode
				SDIO_Command((RCA<<16), 7, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);

			rSDICSTA |=CMD_END|RESP_END;
			printf("\nEntered to the Transfer state\n");			
		}
	else
		{
			printf("\nCMD7 : Deselect\n");
			SDIO_Command((RCA<<16), 7, SDIO_NO_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
			if((Check_CMDend(7, 0) !=1))
				SDIO_Command((RCA<<16), 7, SDIO_NO_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);

			rSDICSTA |= CMD_END;
			printf("\nEntered to the Stand-by State\n");			
		}
	

}


void SDIO_PrescalerSetting(U32 BaudRate)
{
	rSDIPRE = (PCLK/BaudRate) - 1;
}

void SDIO_Command(U32 CmdArg, U32 Command, U32 WaitResp, U32 LongResp, U32 WithData)
{
	U32 CmdIndex;
	
	rSDICARG = rSDICARG & ~(0xffffffff) | CmdArg;
	
	CmdIndex = Command | 0x40;
	rSDICCON = (WithData<<11)|(LongResp<<10)|(WaitResp<<9)|(CmdIndex);
	
	//Command Start
	rSDICCON |= (1<<8);
}

void SDIO_BlockSizeSetting(U32 Size)
{
	rSDIBSIZE = (Size & 0xFFF);
}


void SDIO_TypeSetting(U32 ClkType, U32 ByteType)
{
	if(ClkType == SDIO_SD_TYPE)
		rSDICON &= ~CLOCK_TYPE;
	else if(ClkType == SDIO_MMC_TYPE)
		rSDICON |= CLOCK_TYPE;

	if(ByteType == SDIO_TYPE_A)
		rSDICON &= ~BYTE_ORDER;
	else if(ByteType == SDIO_TYPE_B)
		rSDICON |= BYTE_ORDER;		
}

int Check_CMDend(int cmd, int be_resp)
//0: Timeout
{
    int finish0;

    if(!be_resp)    // No response
    {
    	finish0=rSDICSTA;
		while((finish0&CMD_END)!=CMD_END)	// Check cmd end
	    finish0=rSDICSTA;

	rSDICSTA=finish0;// Clear cmd end state

	return 1;
    }
    else	// With response
    {
    	finish0=rSDICSTA;
	while( !( ((finish0&RESP_END)==RESP_END) | ((finish0&CMD_TOUT)==CMD_TOUT) ))    // Check cmd/rsp end
	finish0=rSDICSTA;
	if(cmd==1 | cmd==41)	// CRC no check, CMD9 is a long Resp. command.

	{
	    if( (finish0&0xf00) != CMD_END|RESP_END )  // Check error
	    {
		rSDICSTA=finish0;   // Clear error state
		if(((finish0&CMD_TOUT)==CMD_TOUT))
		    return 0;	// Timeout error
    	    }
	    rSDICSTA=finish0;	// Clear cmd & rsp end state
	}
	else	// CRC check
	{
	    if( (finish0&0x1f00) != CMD_END|RESP_END)	// Check error
	    {
		//printf("CMD%d:rSDICSTA=0x%x, rSDIRSP0=0x%x\n",cmd, rSDICSTA, rSDIRSP0);
		rSDICSTA=finish0;   // Clear error state

		if(((finish0&CMD_TOUT)==CMD_TOUT))
		    return 0;	// Timeout error
    	    }
	    rSDICSTA=finish0;
	}
	return 1;
    }
}

int Check_BUSYend(void)
{
    int finish;

    finish=rSDIDSTA;

    while( !( ((finish&0x08)==0x08) | ((finish&0x20)==0x20) ))
	finish=rSDIDSTA;

    while( (finish&(0x1<<3)) != 0x8 )
    {
        finish=rSDIDSTA;
    }
   rSDIDSTA=0xf4;  //clear error state	
    return 1;
}


int Check_MMC_OCR(void)
{
    int i;


    //-- Negotiate operating condition for MMC, it makes card ready state
    for(i=0;i<200;i++)	//Negotiation time is dependent on CARD Vendors.
    {
    	SDIO_Command(0xff8000, 1, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);

	if(Check_CMDend(1, 1) && (rSDIRSP0>>16)==0x80ff) //[31]:Card Power up status bit (busy)
	{
	    rSDICSTA |= CMD_END|RESP_END;
	    return 1;	// Success
	}
    }
    rSDICSTA |= CMD_END|RESP_END;
    return 0;		// Fail
}

int Check_DATend(void)
{
    int finish;

    finish=rSDIDSTA;

    while( !((finish&DATA_FINISH)==DATA_FINISH))// Chek timeout or data end
    	{
		finish=rSDIDSTA;
    	}

    if( (finish&0xfc) != DATA_FINISH )
    {
        rSDIDSTA=0xec;  // Clear error state
        return 0;
    }
    return 1;
}

int Check_SD_OCR(void)
{
    int i=0;

    //-- Negotiate operating condition for SD, it makes card ready state
    for(i=0;i<200;i++)	//If this time is short, init. can be fail.
    {
    	SDIO_Command((RCA<<16), 55, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
	while(Check_CMDend(55, 1) != 1)
		{
			printf("\nCommand55 Fail...");
			return 0;
		}	
	
	SDIO_Command(0xff8000, 41, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
    	if( Check_CMDend(41, 1) & rSDIRSP0==0x80ff8000 ) 
	{
	    rSDICSTA=0xa00;	// Clear cmd_end(with rsp)
	    return 1;	// Success	    
	}
	Delay(200); // Wait Card power up status
    }
    rSDICSTA=0xa00;	// Clear cmd_end(with rsp)
    return 0;		// Fail
}


void __irq DMA_end(void)
{
	rSUBSRCPND |= BIT_SUB_DMA0;
	ClearPending(BIT_DMA);    
    	TR_end=1;
}

void __irq Rd_Int(void)
{
    	U32 i,status;

	ClearPending(BIT_SDI0);
	rINTMSK |= (BIT_SDI0);
	
	status=rSDIFSTA;
	if( (status&0x200) == 0x200 )	// Check Last interrupt?
	{
	for(i=(status & 0x7f)/4;i>0;i--)
	{
	    *Rx_buffer++=rSDIDAT;
	    rd_cnt++;
	}
	rSDIFSTA=rSDIFSTA&0x200;	//Clear Rx FIFO Last data Ready, YH 040221
	}
	else if( (status&0x80) == 0x80 )	// Check Half interrupt?
	{
	    for(i=0;i<8;i++)
	    	{
			*Rx_buffer++=rSDIDAT;
			rd_cnt++;
		}
	}
		
	rINTMSK &= ~(BIT_SDI0);
}

void __irq Wt_Int(void)
{
    ClearPending(BIT_SDI0);
	rINTMSK |= (BIT_SDI0);

    rSDIDAT=*Tx_buffer++;
    wt_cnt++;

    if(wt_cnt==128*BlockNum)
    {
	rINTMSK |= BIT_SDI0;
	rSDIDAT=*Tx_buffer;
	TR_end=1;
    }
	
	rINTMSK &= ~(BIT_SDI0);
}

void CalculationBPS_NORMALSD_MMC(int Time)
{
	float x=0;
	int y=0;
	float bps=0;

	x = (float)((float)1000000/(float)Time); //Unit is usec

	y = (BlockNum+1) * 512 * 8;
	
	bps = x*(float)y;
	
	printf("\n\n\nTransfer Time = %dusec",Time);
	printf("\nTransferSize = %dKByte",y/(8*1024));
	printf("\nBPS = %fMByte/sec\n\n",bps/(1000000*8));
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -