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

📄 sdi.c

📁 三星2413芯片的测试代码,对进行驱动开发很有帮助.
💻 C
📖 第 1 页 / 共 4 页
字号:
					SDIO_Command(StartAddr<<9, WRITE_MULTIPLE_BLOCK, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
				} while((Check_CMDend(WRITE_MULTIPLE_BLOCK, 1) !=1));
			}
			rSDICSTA = CMD_END|RESP_END;	// Clear cmd_end(with rsp)
//			printf("\nBlock zise=%x\n",Card_OneBlockSize/4*BlockNum);
//			timpcount = rSDIDCNT;
			while(wt_cnt < (Card_OneBlockSize/4*BlockNum))
			{
//				status = rSDIFSTA;
				if(rSDIFSTA & TX_FIFO_AVAILABLE_DETECT) 
				{
					if ( rSDIDSTA & (1<<5) );
					else {
						rSDIDAT = *Tx_buffer++;
						//timpcount = timpcount -4;
//						if ( timpcount == rSDIDCNT )
//						{
//							//printf ( "[%d]rSDIDCNT mismatch %x,%x\n", wt_cnt,  timpcount, rSDIDCNT );
//							printf ( "[%d]rSDIDCNT same %x,%x, state:%x,FIFO:%x\n", wt_cnt,  timpcount, rSDIDCNT, rSDIDSTA, rSDIFSTA );
//							//timpcount = rSDIDCNT;
//						}
//						timpcount = rSDIDCNT;
			 			wt_cnt++;
//			 			timeout_count=0;
					}
				}
//				else if(rSDIDSTA & (1<<5) ) {
//					if ( timeout_count++ > 100 ) {
//						rSDIFSTA |= (1<<16);
//						rSDIDSTA |= (1<<5);
//					}
//				}
			}

//			printf("\nWrite count=%x\n",wt_cnt);
			break;

		case INT:
//			printf("\nInterrupt mode data write\n");
			
			pISR_SDI_CF=(unsigned)Wt_Int;
			rSDIDCON=(2<<22)|(1<<20)|(1<<17)|(Wide<<16)|(1<<14)|(3<<12)|(BlockNum<<0);
			Timer_Start(3);
    			if(BlockNum<2)//single block
			{
				do {	// StartAddr * 512
					SDIO_Command(StartAddr<<9, WRITE_BLOCK_CMD, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
				} while((Check_CMDend(WRITE_BLOCK_CMD, 1) !=1));
			}
			else//multi block
			{
				do {
					SDIO_Command(StartAddr<<9, WRITE_MULTIPLE_BLOCK, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
				} while((Check_CMDend(WRITE_MULTIPLE_BLOCK, 1) !=1));
			}
			rSDICSTA |= DATA_TIMEOUT|CMD_END|RESP_END;	// Clear cmd_end(with rsp)

    			rINTMSK &= ~(BIT_SDI_CF);
    			rINTSUBMSK &=~(BIT_SUB_SDI);

    			rSDIIMSK=0x10;  // Tx FIFO half int.
    			
    			while(!TR_end);

			rINTSUBMSK |= (BIT_SUB_SDI);
    			rINTMSK |= (BIT_SDI_CF);
    			TR_end=0;
    			rSDIIMSK=0;	// All mask
    			break;
				
		case DMA:
//			printf("\nDMA mode data write\n");
			
			pISR_DMA0=(unsigned)DMA_end;
			rINTMSK&=~(BIT_DMA0);
			//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;

			if(Wide!=0)
				rSDIDCON |= WIDE_BUS_EN;
			else
				rSDIDCON &= ~WIDE_BUS_EN;

			rSDIDCON |=BURST4_EN|WORD_TRANSFER|TRANS_AFTER_RESP|BLOCK_TRANSFER|DMA_EN|BlockNum;
			rSDIDCON |= DATA_TRANSMIT_MODE|DATA_TRANSMIT_START;
			Timer_Start(3);
			if(BlockNum<2)//single block
			{
				do { 	// StartAddr * 512
					SDIO_Command(StartAddr<<9, WRITE_BLOCK_CMD, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
				} while((Check_CMDend(WRITE_BLOCK_CMD, 1) !=1));
			}
			else//multi block
			{
				do {
					SDIO_Command(StartAddr<<9, WRITE_MULTIPLE_BLOCK, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
				} while((Check_CMDend(WRITE_MULTIPLE_BLOCK, 1) !=1));
			}
			rSDICSTA |= CMD_END|RESP_END;	// Clear cmd_end(with rsp)

			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); 	
		do {
			SDIO_Command(0, STOP_TRANSMISSION_CMD, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
		} while(Check_CMDend(12, 1) != 1)	;

		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'.
	}
	time=Timer_Stop();
	printf ("TIME is : %d us\n", time<<7);		// time is 1/128 mux
	printf ( "Transfer Rate is : %f MB per sec \n", ((float)(BlockNum<<9)) / ((float)(time<<7)) );
	BlockNum =0;
}

void eraseBlock_beforewrite(unsigned int StartAddr, unsigned EndAddr) {

	// clean data space.
	if(card_type == SD_CARD)
	{
		do {
			SDIO_Command(StartAddr, 32, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
		} while(Check_CMDend(32, 1) != 1)	;
		rSDICSTA = CMD_END|RESP_END;	// Clear cmd_end(with rsp)

		do {
			SDIO_Command(EndAddr, 33, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
		} while(Check_CMDend(33, 1) != 1);
		rSDICSTA = CMD_END|RESP_END;	// Clear cmd_end(with rsp)
	}
	else if(card_type == MMC_CARD || card_type == MOVI_NAND_CARD )
	{
		do {
			SDIO_Command(StartAddr, ERASE_GROUP_START_CMD, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
		} while(Check_CMDend(ERASE_GROUP_START_CMD, 1) != 1);
		rSDICSTA = CMD_END|RESP_END;	// Clear cmd_end(with rsp)

		do {
			SDIO_Command(EndAddr, ERASE_GROUP_END_CMD, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
		} while(Check_CMDend(ERASE_GROUP_END_CMD, 1) != 1);
		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;


	do {
		SDIO_Command(0, ERASE_CMD, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
	} while(Check_CMDend(ERASE_CMD, 1) != 1);
	rSDICSTA = CMD_END|RESP_END;	// Clear cmd_end(with rsp)
	
	if(!Check_BUSYend()) 
	   	printf("\nBusy Check Error...\n");

	rSDIDSTA = (1<<3);
	// ereasing block done.
	Delay(1000);
}
	
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(card_type == SD_CARD)
	{
		do {
			SDIO_Command(StartAddr, 32, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
		} while(Check_CMDend(32, 1) != 1)	;
		rSDICSTA = CMD_END|RESP_END;	// Clear cmd_end(with rsp)

		do {
			SDIO_Command(EndAddr, 33, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
		} while(Check_CMDend(33, 1) != 1);
		rSDICSTA = CMD_END|RESP_END;	// Clear cmd_end(with rsp)
	}
	else if(card_type == MMC_CARD || card_type == MOVI_NAND_CARD )
	{
		do {
			SDIO_Command(StartAddr, ERASE_GROUP_START_CMD, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
		} while(Check_CMDend(ERASE_GROUP_START_CMD, 1) != 1);
		rSDICSTA = CMD_END|RESP_END;	// Clear cmd_end(with rsp)

		do {
			SDIO_Command(EndAddr, ERASE_GROUP_END_CMD, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
		} while(Check_CMDend(ERASE_GROUP_END_CMD, 1) != 1);
		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;


	do {
		SDIO_Command(0, ERASE_CMD, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
	} while(Check_CMDend(ERASE_CMD, 1) != 1);
	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 datasize;
	U32 C_SIZE, C_SIZE_MULT, READ_BL_LEN, CardSize, OneBlockSize;
	U32 WRITE_BL_LEN,TRANS_SPEED,TRANS_SPEED_MUL;

	rSDIPRE=PCLK/(INICLK)-1;	// Clock setting

	// youngbo.song SD客 MMC 埃俊 构啊 促甫瘤 积阿茄促. - 弊府绊 捞甫 老瘤皑摹 备盒且 规过篮 绝摆绰啊?
	SDIO_TypeSetting(SDIO_SD_TYPE, SDIO_TYPE_A);// clock type setting
//	SDIO_TypeSetting(SDIO_MMC_TYPE, SDIO_TYPE_A);// clock type setting
	Delay(1);	// Give some time for reset.
	rSDICON |= ENCLK;	//Clock enable
	rSDIFSTA |= (1<<16);//FIFO reset

	SDIO_BlockSizeSetting(Card_OneBlockSize);	//block size setting
	rSDIDTIMER = 0x7fffff;	//busy timer setting

	Delay(0x1000);		// Wait 74SDCLK for MMC card

	SDIO_Command(0x0, GO_TO_IDLE_CMD, SDIO_NO_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
	Check_CMDend(GO_TO_IDLE_CMD,0);
//-------------------------------------------------------------------------------------//
	printf("\nEnter to the Idle State\n");

	card_type = Check_OCR();
	if(card_type==ERROR_CARD) {
		printf("\n\nInitialize fail\nNo Card assertion\n");
		return 0;
	}
	// initially we setted sd type.
	if ( card_type != SD_CARD ) {
		SDIO_TypeSetting(SDIO_MMC_TYPE, SDIO_TYPE_A);
	}
//-------------------------------------------------------------------------------------//

 	printf("\nCMD2 : CID response\n");
	do {
		SDIO_Command(0x0, ALL_SEND_SID_CMD, SDIO_WAIT_RESP, SDIO_LONG_RESP, SDIO_WITHOUT_DATA);
	} while(Check_CMDend(ALL_SEND_SID_CMD, 1) != 1);
	printf("\n - Product Name : %c%c%c%c%c%c",(rSDIRSP0&0xFF),((rSDIRSP1>>24)&0xFF),((rSDIRSP1>>16)&0xFF),((rSDIRSP1>>8)&0xFF),(rSDIRSP1&0xFF),((rSDIRSP2>>24)&0xFF));		

//-------------------------------------------------------------------------------------//

	printf("\nCMD3 : assign relative address\n");
	
	do {
		if ( card_type == SD_CARD )
		   	SDIO_Command((0<<16), SET_RELATIVE_ADDR, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITHOUT_DATA);
		else if ( card_type == MMC_CARD )
			SDIO_Command((1<<16), SET_RELATIVE_ADDR, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
		else if ( card_type == MOVI_NAND_CARD )
			SDIO_Command((1<<16), SET_RELATIVE_ADDR, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
	} while( Check_CMDend(3, 1) !=1);

//-------------------------------------------------------------------------------------//
	if(card_type == SD_CARD ) {
		 RCA = ( rSDIRSP0 & 0xffff0000 )>>16;
	}
	else if(card_type == MMC_CARD ) {
		RCA = 1;
	}
	else if(card_type == MOVI_NAND_CARD ) {
		RCA = 1;
	}
//-------------------------------------------------------------------------------------//

	do {
		SDIO_Command(RCA<<16, SEND_CSD_CMD, SDIO_WAIT_RESP, SDIO_LONG_RESP, SDIO_WITH_DATA);
	} while(Check_CMDend(SEND_CSD_CMD, 1) != 1);

	READ_BL_LEN = (rSDIRSP1>>16&0xF);
	C_SIZE = ((rSDIRSP1&0x3ff)<<2) | (rSDIRSP2>>30&0x3);
	C_SIZE_MULT = (rSDIRSP2>>15&0x7);
	WRITE_BL_LEN=(rSDIRSP3>>22&0xf);
	TRANS_SPEED= rSDIRSP0 & 0xff;
	TRANS_SPEED_MUL = (TRANS_SPEED >> 3)&0xf;
	TRANS_SPEED= (TRANS_SPEED&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 TRANS_SPEED: %d, Mul : %d\n", TRANS_SPEED, TRANS_SPEED_MUL);

	printf("\n One Block Size: %dByte",OneBlockSize);
	printf("\n Total Card Size: %dMByte\n",CardSize+1);	

//-------------------------------------------------------------------------------------//
	// CMD7 - SELECT Command
	CARD_SEL_DESEL(1);//Enter Card state to the transfer mode

	if(card_type == MMC_CARD) {
		SDIO_PrescalerSetting(MMCCLK);
		while(PCLK/(rSDIPRE+1) > 20000000)
			rSDIPRE = rSDIPRE+1; 
		printf("\nMMC Frequency is %dHz\n",(PCLK/(rSDIPRE+1)));
	}
	else if ( card_type == MOVI_NAND_CARD ) {		
		SDIO_PrescalerSetting(MOVICLK);
		while(PCLK/(rSDIPRE+1) > MOVICLK)
			rSDIPRE = rSDIPRE+1;

		printf("\nMOVINAND Frequency is %dHz\n",(PCLK/(rSDIPRE+1)));
	}
    	else if ( card_type == SD_CARD ) {
		SDIO_PrescalerSetting(SDCLK);
		while(PCLK/(rSDIPRE+1) > 25000000)
			rSDIPRE = rSDIPRE+1;
		printf("\nSD Frequency is %dHz\n",(PCLK/(rSDIPRE+1)));
    	}

    	Set_Bus(card_type);

    	if ( card_type==MOVI_NAND_CARD ) {
    		if (PCLK/(rSDIPRE+1) > 20000000 )
		{
			do {
				SDIO_Command((3<<24)|(185<<16)|(1<<8), SWITCH_CMD, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);//ACMD6 select bus width
			} while((Check_CMDend(6, 1) !=1));
		    	rSDICON &= ~(1);
		    	Delay(1);
		    	rSDICON  |= 1;
		    	Delay(1);
		}
    	}

	do {
		SDIO_Command(Card_OneBlockSize, SET_BLOCKLEN_CMD, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
	} while(Check_CMDend(SET_BLOCKLEN_CMD, 1) != 1);
	printf("\nSet Block Length");

	return 1;
    }


void Set_Bus(CardType type)
{
	if( type == SD_CARD ) {
		Wide = 1;
	}
	else if(type == MMC_CARD ) {
		Wide = 0;
	}
	else if( type == MOVI_NAND_CARD ) {
		Wide = 1;
	}
	SET_BUSWIDTH( type );
	
	if ( Wide )
		printf("\n****4bit bus****\n");
	else
		printf("\n****1bit bus****\n");
}

void SET_BUSWIDTH(CardType type)
{
	int arg;
	
	if ( type==MOVI_NAND_CARD ) {
		arg = (3<<24)|(183<<16)|(1<<8);
		do {
			SDIO_Command(arg, SWITCH_CMD, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);//ACMD6 select bus width
		} while((Check_CMDend(6, 1) !=1));
	}
	else if ( type == SD_CARD ) {
		do {
			SDIO_Command((RCA<<16), APP_CMD, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);//befoe using ACMD
		} while((Check_CMDend(APP_CMD, 1) !=1));

		do {
			SDIO_Command((Wide<<1), SWITCH_CMD, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);//ACMD6 select bus width
		} while((Check_CMDend(SWITCH_CMD, 1) !=1));
	}
	else if ( type == MMC_CARD ) {
		// do not need anything.
	}
	
	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), SELECT_CMD, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);
		if((Check_CMDend(SELECT_CMD, 1) !=1)||(rSDIRSP0 != 0x800))//entering the standby mode
			SDIO_Command((RCA<<16), SELECT_CMD, SDIO_WAIT_RESP, SDIO_SHORT_RESP, SDIO_WITH_DATA);

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

⌨️ 快捷键说明

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