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

📄 hs_mmc.c

📁 Samsung S3C2443 Test program source code
💻 C
📖 第 1 页 / 共 3 页
字号:
				while(!HS_DMA_END);				
				printf(("\nDMA Read End\n"));
				
				break;	

			default : break;			
				
		}
	
	Rx_buffer_HSMMC = (U32 *)SDI_Rx_buffer_HSMMC;
	for(j=0 ; j<(OneBlockSize*BlockNum_HSMMC)/4 ; j++)
	   	{
		      	if(j%4 == 0)
		   		printf("\n0x%04xh : ",Addr_temp);
		       	printf("0x%08x ",*Rx_buffer_HSMMC++);
		       	Addr_temp += 4;
		}
	
	printf("\n");    

	HS_DMA_END = 0;	
	BlockNum_HSMMC = 0;
	rd_cnt_HSMMC = 0;
	ReadBlockCnt_INT = 0;
}

void HS_MMC_EraseBlock(void)
{
	U32 StartAddr, EndAddr;	
	U16 EraseBlockStartNum, EraseBlockEndNum;
	
	printf("\nHigh speed MMC block erase test\n");

	printf("\nInput Erase Start Block Number(ex 0, 1, 2 ...) : ");
	EraseBlockStartNum = GetIntNum();

	printf("Input Erase End Block Number(ex 0, 1, 2 ...) : ");
	EraseBlockEndNum = GetIntNum();
	
	if(ThisIsMmc == 0)
		{
		SetArgumentReg(EraseBlockStartNum*512); 
		SetCommandReg(32, 0); 	

		while (!WaitForCommandComplete());
		ClearCommandCompleteStatus();
		
		SetArgumentReg(EraseBlockEndNum*512); 
		SetCommandReg(33, 0); 	

		while (!WaitForCommandComplete());
		ClearCommandCompleteStatus();
		}
	else if(ThisIsMmc == 1)
		{
		SetArgumentReg(EraseBlockStartNum*512); 
		SetCommandReg(35, 0); 

		while (!WaitForCommandComplete());
		ClearCommandCompleteStatus();
		
		SetArgumentReg(EraseBlockEndNum*512);
		SetCommandReg(36, 0); 

		while (!WaitForCommandComplete());
		ClearCommandCompleteStatus();
		}

	SetArgumentReg(0); 
	SetCommandReg(38, 0);

	printf("\n[SD/TFlash card Erase Block Test...End]\n");
	

}

void HS_MMC_CardDetect(void)
{
	rGPJCON = (rGPJCON & ~(0x3<<28)) | (1<<29); 
	//rHM_CONTROL2 |= (1<<13)|(1<<12);//Card Detect using a DAT[3] signal

	rHM_NORINTSTSEN |= (1<<7)|(1<<6); 
	rHM_NORINTSIGEN |= (1<<7)|(1<<6) ;

	if(rHM_PRNSTS & (1<<16))
		{
		HS_CARD_DETECT = 1;
		printf("\nCard is Inserted\n");
		}

	while(!HS_CARD_DETECT)
		{
			printf("\nInsert a Card\n");
			HS_CARD_DETECT=0;			
			HS_MMC_Irq();
		    	do {			
			printf(".");
			Delay(5000);
			} while(HS_CARD_DETECT==0);
		}	
	
	HS_CARD_DETECT = 0;
	rHM_CONTROL2 &= ~(1<<13);
}


int SetDataTransferWidth(void)
{
	U8  ucSfr=0;
	U8 uBitMode=0;
	U32 uArg=0;
	U8 m_ucHostCtrlReg = 0;
	U32 BD_BUS_WIDTH, ucBusWidth;

	printf("\nSelect the bus width 8-bit, 4-bit, 1-bit\n");
	printf("\nType a bus width:  ");
	BD_BUS_WIDTH = GetIntNum();

	switch (BD_BUS_WIDTH)
	{
		case 8:
			ucBusWidth = ThisIsMmc ? 8 : 4;
			break;
		case 4:
			ucBusWidth = 4;
			break;
		case 1:
			ucBusWidth = 1;
			break;
		default :
			ucBusWidth = 4;
			break;
	}

	SetSdhcCardIntEnable(0); // Disable sd card interrupt

	if(!ThisIsMmc)// <------------------------- SD Card Case
	{
		if (!IssueCommand(55, m_uRca, 0))
			return 0;
		else
		{
			if (ucBusWidth==1)
			{
				uBitMode = 0;
				if (!IssueCommand(6, 0, 1)) // 1-bits
					return 0;
			}
			else
			{
				uBitMode = 1;
				if (!IssueCommand(6, 2, 1)) // 4-bits
					return 0;
			}
		}
	}
	else // <-------------------------------- MMC Card Case
	{
		if (m_ucMMCSpecVer==4) // It is for a newest MMC Card
		{
			if (ucBusWidth==1)
				uBitMode = 0;
			else if (ucBusWidth==4)
				uBitMode = 1;//4            		// 4-bit bus
			else
				uBitMode = 2;//8-bit bus
			
			uArg=((3<<24)|(183<<16)|(uBitMode<<8));
			while(!IssueCommand(6, uArg, 0));
		}
		else
			uBitMode = 0;
	}
	
	if (uBitMode==2)
	{
		m_ucHostCtrlReg &= 0xdf;
		m_ucHostCtrlReg |= 1<<5;
	}
	else
	{
		m_ucHostCtrlReg &= 0xfd;
		m_ucHostCtrlReg |= uBitMode<<1;
	}
	
	rHM_HOSTCTL = m_ucHostCtrlReg;
	SetSdhcCardIntEnable(1);
	//printf(" transfer rHM_HOSTCTL = %x\n",rHM_HOSTCTL);
	return 1;
}

void SetSdhcCardIntEnable(U8 ucTemp)
{
    	rHM_NORINTSTSEN &= 0xFEFF;
	rHM_NORINTSTSEN |= (ucTemp<<8);
}

int SetSDOCR(void)
{
	U32 i, OCR;
	
	for(i=0; i<250; i++)
	{
	#if 0
		IssueCommand(55, 0x0000, 0); // CMD55 (For ACMD)
		IssueCommand(41, 0x0ff8000, 1); // (Ocr:2.7V~3.6V)
	#else
		IssueCommand(55, 0x0, 0); // CMD55 (For ACMD)
		IssueCommand(41, 0x0, 1); // (Ocr:2.7V~3.6V)
		OCR = rHM_RSPREG0;

		//Delay(1000);

		IssueCommand(55, 0x0, 0); // CMD55 (For ACMD)
		IssueCommand(41, OCR, 1); // (Ocr:2.7V~3.6V)		
		
	#endif
		if (rHM_RSPREG0&(0x1<<31))
		{
			//printf("\nrHM_RSPREG0=%x",rHM_RSPREG0);
			if(OCR & (1<<7))
				printf("\nVoltage range : 1.65V ~ 1.95V\n\n");
			if(OCR & (1<<21))
				printf("\nVoltage range: 2.7V ~ 3.4V\n\n");	
			else if(OCR & (1<<20))
				printf("\nVoltage range: 2.7V ~ 3.3V\n\n");	
			else if(OCR & (1<<19))
				printf("\nVoltage range: 2.7V ~ 3.2V\n\n");	
			else if(OCR & (1<<18))
				printf("\nVoltage range: 2.7V ~ 3.1V\n\n");	
			ThisIsMmc = 0;
			return 1;
		}
		Delay(1);
	}
	// The current card is MMC card, then there's time out error, need to be cleared.
	ClearErrInterruptStatus();
	return 0;
}

int SetMMCOCR(void)
{
	U32 i, OCR;
	for (i=0; i<250; i++)
	{
		IssueCommand(1, 0x0, 0);
		//printf("\nCMD 1 RSP = %x\n",rHM_RSPREG0);
		OCR = rHM_RSPREG0;	
		
		IssueCommand(1, OCR, 0); // (Ocr:2.7V~3.6V)
		if (rHM_RSPREG0&(0x1<<31))
		{
			if(OCR & (1<<7))
				printf("\nVoltage range : 1.65V ~ 1.95V\n\n");
			if(OCR & (1<<21))
				printf("\nVoltage range: 2.7V ~ 3.4V\n\n");	
			else if(OCR & (1<<20))
				printf("\nVoltage range: 2.7V ~ 3.3V\n\n");	
			else if(OCR & (1<<19))
				printf("\nVoltage range: 2.7V ~ 3.2V\n\n");	
			else if(OCR & (1<<18))
				printf("\nVoltage range: 2.7V ~ 3.1V\n\n");	
			ThisIsMmc=1;
			return 1;
		}
	}
	// The current card is SD card, then there's time out error, need to be cleared.
	ClearErrInterruptStatus();
	return 0;
}

void SetCommandReg(U16 uCmd,U32 uIsAcmd)
{
	U16 usSfr = 0;
	
	//rHM_CMDREG &= ~(0xffff);
	
	if (!uIsAcmd)//No ACMD
	{
		/* R2: 136-bits Resp.*/
		if ((uCmd==2||uCmd==9||uCmd==10))
			usSfr=(uCmd<<8)|(0<<4)|(1<<3)|(1<<0);

		/* R1,R6,R5: 48-bits Resp. */
		else if (uCmd==3||uCmd==13||uCmd==16||uCmd==27||uCmd==30||uCmd==32||uCmd==33||uCmd==35||uCmd==36||uCmd==42||uCmd==55||uCmd==56)
			usSfr=(uCmd<<8)|(1<<4)|(1<<3)|(2<<0);

		else if (uCmd==11||uCmd==14||uCmd==17||uCmd==18||uCmd==19||uCmd==20||uCmd==24||uCmd==25)
			usSfr=(uCmd<<8)|(1<<5)|(1<<4)|(1<<3)|(2<<0);

		/* R1b,R5b: 48-bits Resp. */
		else if (uCmd==6||uCmd==7||uCmd==12||uCmd==28||uCmd==29||uCmd==38)
		{
			if (uCmd==12)
				usSfr=(uCmd<<8)|(3<<6)|(1<<4)|(1<<3)|(3<<0);
			else if (uCmd==6)
			{
				if(!ThisIsMmc)	// SD card
					usSfr=(uCmd<<8)|(1<<5)|(1<<4)|(1<<3)|(2<<0);
				else			// MMC card
					usSfr=(uCmd<<8)|(1<<4)|(1<<3)|(3<<0);
					//usSfr=(uCmd<<8)|(1<<5)|(1<<4)|(1<<3)|(3<<0);
			}
			else
				usSfr=(uCmd<<8)|(1<<4)|(1<<3)|(3<<0);
		}

		/* R3,R4: 48-bits Resp.  */
		else if (uCmd==1)
			usSfr=(uCmd<<8)|(0<<4)|(0<<3)|(2<<0);

		/* No-Resp. */
		else
			usSfr=(uCmd<<8)|(0<<4)|(0<<3)|(0<<0);
	}
	else//ACMD
	{
		if (uCmd==6||uCmd==22||uCmd==23)		// R1
			usSfr=(uCmd<<8)|(1<<4)|(1<<3)|(2<<0);
		else if (uCmd==13||uCmd==51)
			usSfr=(uCmd<<8)|(1<<5)|(1<<4)|(1<<3)|(2<<0);
		else
			usSfr=(uCmd<<8)|(0<<4)|(0<<3)|(2<<0);
	}
	rHM_CMDREG = usSfr;
}


void SetMMCSpeedMode(U32 eSDSpeedMode)
{
	U8  ucSpeedMode;
	U32 uArg=0;
	ucSpeedMode = (eSDSpeedMode == HIGH) ? 1 : 0;
	uArg=(3<<24)|(185<<16)|(ucSpeedMode<<8); // Change to the high-speed mode
	while(!IssueCommand(6, uArg, 0));	
}


void SetSDSpeedMode(U32 eSDSpeedMode)
{
	U32 uSfr;
	U32 uArg = 0;
	U8  ucSpeedMode;
	int i;
	
	ucSpeedMode = (eSDSpeedMode == HIGH) ? 1 : 0;

	if (!IssueCommand(16, 64, 0)) // CMD16
		printf("CMD16 fail\n");
	else
	{
		SetBlockSizeReg(7, 64);
		SetBlockCountReg(1);
		SetArgumentReg(0*64);

		SetTransferModeReg(0, 1, 0, 0, 0);

		uArg = (0x1<<31)|(0xffff<<8)|(ucSpeedMode<<0);

		if (!IssueCommand(6, uArg, 0))
			printf("CMD6 fail\n");
		else
		{
			WaitForBufferReadReady();
			ClearBufferReadReadyStatus();
			
			for(i=0; i<16; i++)
			{
				uSfr = rHM_BDATA	;			
			}			

			WaitForTransferComplete();
			ClearTransferCompleteStatus();
		}
	}	
}


void SetClock(U32 ClkSrc, U16 Divisor)
{

	rHM_CONTROL2 = (rHM_CONTROL2 & ~(0xffffffff)) | (0x1<<15)|(0x1<<14)|(0x1<<8)|(ClkSrc<<4);
	//rHM_CONTROL2 = (rHM_CONTROL2 & ~(0xffffffff)) |(0x1<<14)|(0x1<<8)|(ClkSrc<<4);
	rHM_CONTROL3 = (0<<31) | (1<<23) | (0<<15) | (1<<7);
	rHM_CLKCON &= ~(0xff<<8);

	// SDCLK Value Setting + Internal Clock Enable	
	rHM_CLKCON = (rHM_CLKCON & ~((0xff<<8)|(0x1))) | (Divisor<<8)|(1<<0);

	// CheckInternalClockStable
	while (!(rHM_CLKCON&0x2));
	ClockOnOff(1);
	printf("rHM_CONTROL2 = %x\n",rHM_CONTROL2);
	printf("rHM_CLKCON = %x\n",rHM_CLKCON);
}

int IssueCommand( U16 uCmd, U32 uArg, U32 uIsAcmd)
{
	U32 uSfr;

	while ((rHM_PRNSTS&0x1)); // Check CommandInhibit_CMD

	if (!uIsAcmd)//R1b type commands have to check CommandInhibit_DAT bit
	{
		if((uCmd==6&&ThisIsMmc)||uCmd==7||uCmd==12||uCmd==28||uCmd==29||uCmd==38||((uCmd==42||uCmd==56)&&(!ThisIsMmc)))
		{
			do	{
				uSfr = rHM_PRNSTS;
			} while((uSfr&0x2)); // Check CommandInhibit_DAT
		}
	}
	// Argument Setting
	if (!uIsAcmd)// <------------------- Normal Command (CMD)
	{
		if(uCmd==3||uCmd==4||uCmd==7||uCmd==9||uCmd==10||uCmd==13||uCmd==15||uCmd==55)
			rHM_ARGUMENT = uArg<<16;
		else
			rHM_ARGUMENT = uArg;
	}
	else// <--------------------------- APP.Commnad (ACMD)
		rHM_ARGUMENT = uArg;

	SetCommandReg(uCmd,uIsAcmd);

	if (!WaitForCommandComplete())
		{
			printf(("Command NOT Complete\n"));
		}
	else
		ClearCommandCompleteStatus();	

	if (!(rHM_NORINTSTS&0x8000))
	{
		return 1;
	}
	else
	{
		if(OCRcheck == 1)
			return 0;
		else
			{
			printf("Command = %d, Error Stat = %x\n",(rHM_CMDREG>>8),rHM_ERRINTSTS);		
			return 0;								
			}
	}

}

void GetResponseData(U32 uCmd)
{
	U32 uSfr0,uSfr1,uSfr2,uSfr3;

	uSfr0 = rHM_RSPREG0;
	uSfr1 = rHM_RSPREG1;
	uSfr2 = rHM_RSPREG2;
	uSfr3 = rHM_RSPREG3;

	if(uCmd==3)
	{
 		if(!ThisIsMmc)
 		{
			m_uRca = (uSfr0>>16)&0xFFFF;			
			printf("=>  RCA=%d\n", m_uRca);
 		}
	}
	else if (uCmd==9)
	{
		if(ThisIsMmc)
		{
			m_ucMMCSpecVer=(rHM_RSPREG3>>18)& 0xF;
			//m_ucMMCSpecVer=(uSfr3>>26)& 0xF;
			printf("=>  m_ucMMCSpecVer=%d\n", m_ucMMCSpecVer);
		}
	}
}

int GetSdSCR()
{
	U32  uSCR1, uSCR2;

	if (!IssueCommand(16, 8, 0))
		return 0;
	else
	{
		SetBlockSizeReg(7, 8);
		SetBlockCountReg(1);
		SetArgumentReg(0*8);

		SetTransferModeReg(0, 1, 0, 0, 0);
		if (!IssueCommand(55, m_uRca, 0))		// CMD55 (For ACMD)
			return 0;
		else
		{
			if (!IssueCommand(51, 0, 1))			// Acmd51
				return 0;
			else
			{
				WaitForBufferReadReady();
				ClearBufferReadReadyStatus();

				uSCR1 = rHM_BDATA;
				uSCR2 = rHM_BDATA;

				WaitForTransferComplete();
				ClearTransferCompleteStatus();
/*
				printf("\nSCR = %d\n",(uSCR1>>24)&0xf);
				printf("\nSCR = %d\n",(uSCR2>>24)&0xf);

				if ((uSCR2>>24)&0xf)
					SDSpecVer = 1; // Version 1.10, support cmd6
				else
					SDSpecVer = 0; // Version 1.0 ~ 1.01
*/

				if (uSCR1&0x1)
					SDSpecVer = 1; // Version 1.10, support cmd6
				else
					SDSpecVer = 0; // Version 1.0 ~ 1.01

				printf("              =>  m_ucSDSpecVer=%d\n", SDSpecVer);
				return 1;
			}
		}
	}
}

int IsCardInProgrammingState(void)
{
	// check the card status.
	U32  uSfr;

	if (!IssueCommand(13, m_uRca, 0))
		return 0;
	else
	{
		if(((rHM_RSPREG0>>9)&0xf) == 4)
			{
			printf("Card is transfer status\n");
			return 1;
			}
	}
}

void HostCtrlSpeedMode(U8 SpeedMode)
{
	U8  ucSpeedMode;
	ucSpeedMode = (SpeedMode == HIGH) ? 1 : 0;
	rHM_HOSTCTL &= ~(0x1<<2);
	rHM_HOSTCTL |= ucSpeedMode<<2;	
}

#if NEW_SD_CARD

void ClockConfig(U32 Clksrc, U32 Divisior)
{
	U32 SrcFreq, WorkingFreq;
	U32 RealDivisor;
	//printf("Clock Config\n");
	
	if (Clksrc == SD_HCLK)
		SrcFreq = HCLK;
	else if (Clksrc == SD_EPLL)//Epll Out 48MHz
		SrcFreq = 100000000;
	else
		Clksrc = HCLK;

	WorkingFreq = SrcFreq/(Divisior*2);
	printf("WorkingFreq = %dMHz\n",WorkingFreq/(1000000));

	if (ThisIsMmc)
	{
		if (m_ucMMCSpecVer==4)
		{
			if (WorkingFreq>20000000)// It is necessary to enable the high speed mode in the card before changing the clock freq to a freq higher than 20MHz.
			{
				SetMMCSpeedMode(HIGH);					
				printf("\nSet MMC High speed mode OK!!\n");
			}
			else
			{
				SetMMCSpeedMode(NORMAL);	
				printf("\nSet MMC Normal speed mode OK!!\n");
			}
		}
		else // old version
			printf("Old version MMC card can not support working frequency higher than 25MHz");
	}
	else
	{

⌨️ 快捷键说明

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