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

📄 hs_mmc.c

📁 三星2443芯片
💻 C
📖 第 1 页 / 共 3 页
字号:
/*****************************************
  NAME: HS_MMC.c
  DESC: High Speed MMC test
  HISTORY:
  2006.12.18:GOM: draft ver 1.0
 *****************************************/

#include <stdio.h>
#include <string.h>
#include "def.h"
#include "option.h"
#include "2443addr.h"
#include "system.h"
#include "pll.h"
#include "console.h"
#include "hs_mmc.h"

#define POL_Ver1		0
#define INT_Ver1		1
#define DMA_Ver1	2

#define SDI_Tx_buffer_HSMMC (_NONCACHE_STARTADDRESS)
#define SDI_Rx_buffer_HSMMC (_NONCACHE_STARTADDRESS+(0x01000000))
#define SDI_Compare_buffer_HSMMC (_NONCACHE_STARTADDRESS+(0x02000000))


#define Card_OneBlockSize_ver1 512

// Global variables
unsigned int *Tx_buffer_HSMMC;	
unsigned int *Rx_buffer_HSMMC;
unsigned int *Compare_buffer_HSMMC;

volatile unsigned int rd_cnt_HSMMC;
volatile unsigned int wt_cnt_HSMMC;
volatile unsigned int BlockNum_HSMMC=0;

volatile unsigned int WriteBlockCnt_INT=0;
volatile unsigned int ReadBlockCnt_INT=0;
volatile unsigned int WRITEINT_DONE=0;
volatile unsigned int READINT_DONE=0;
volatile unsigned int COMPARE_INT_DONE=0;
volatile unsigned int CompareCnt_INT=0;
volatile unsigned int BufferBoundary_INT_Cnt=0;

volatile unsigned int HS_DMA_END = 0;
volatile unsigned int HS_CARD_DETECT = 0;

volatile int OCRcheck=0;
volatile int ThisIsMmc=0;
volatile int m_uRca=0;
volatile int m_ucMMCSpecVer = 0;
volatile int SDSpecVer=0;
volatile int CE_ATA=0;
volatile int SectorMode =0;

extern	unsigned int ARMCLK, HCLK, PCLK;

//////////////////////////////////////////////////////////////////////////

#define NEW_SD_CARD		1
#define BUFFER_BOUNDARY	0
#define HCLK_OPERATION		0

//////////////////////////////////////////////////////////////////////////

void * func_HSMMC_test[][2]=
{	
	(void *)HS_MMC_WriteTest,       	  "SDIO Write                    ",
	(void *)HS_MMC_Write_AgingTest,   "SD/MMC Write Aging      ",
	(void *)HS_MMC_ReadTest,           	  "SDIO Read                    ",
	(void *)HS_MMC_EraseBlock,            "SDIO Block Erase           ",
	0,0
};

void Test_HS_MMC(void)
{  
	int i;

	HS_MMC_SETGPIO();	

	HS_MMC_Reset();	
	
	if(!HS_MMC_init())
	{
		printf("\nCard initial fail\n");
	}

	while(1)
	{
		i=0;
		printf("\n\n");
		while(1)
		{   //display menu
	   		printf("%2d:%s",i,func_HSMMC_test[i][1]);
	    	i++;
	    	if((int)(func_HSMMC_test[i][0])==0)
	    	{
				printf("\n");
				break;
	    	}
	    	if((i%3)==0)
	    	printf("\n");
		}

		printf("\nSelect (\"-1\" to exit) : ");
		i = GetIntNum();
		if(i==-1) 
	   		break;		// return.
		if( (i<((sizeof(func_HSMMC_test)-1)/8)) )	// select and execute...
	    	( (void (*)(void)) (func_HSMMC_test[i][0]) )();
	}
	
}


int HS_MMC_init(void)
{
	int uArg;

	ClockOnOff(0);
	rSCLKCON |=(1<<13);

	SetClock(SD_EXTCLK, 0x20);
	
	rHM_TIMEOUTCON = 0xe;

	HostCtrlSpeedMode(NORMAL);

	InterruptEnable(0xff, 0xff);

	printf("rHM_NORINTSTS = %x\n",rHM_NORINTSTS);

	IssueCommand(0,0x00,0);//Idle State
	printf("\nEnter to the Idle State\n");

	uArg = (0x1<<8)|(0xaa<<0); //This Line for HC SD card.
	IssueCommand(8,uArg,0);

	OCRcheck =1;

	if(!(SDSpecVer == 2))
		{
			if(SetMMCOCR())
			{
				ThisIsMmc=1;
				printf("MMC card is detected\n");
			}
			else if(SetSDOCR())
			{
				ThisIsMmc=0;
				printf("SD card is detected\n");
			}
			else
				return 0;
		}
	else
		{
			if(SetSDOCR())
			{
				ThisIsMmc=0;
				printf("SD card is detected\n");
			}		
		}

	OCRcheck =0;
	
	// Check the attached card and place the card in the IDENT state rHM_RSPREG0
	IssueCommand(2,0,0);	
	printf("\n - Product Name : %c%c%c%c%c%c\n",((rHM_RSPREG2>>24)&0xFF),((rHM_RSPREG2>>16)&0xFF),((rHM_RSPREG2>>8)&0xFF),(rHM_RSPREG2&0xFF),((rHM_RSPREG1>>24)&0xFF),((rHM_RSPREG1>>16)&0xFF));		

	// Send RCA(Relative Card Address). It places the card in the STBY state
	m_uRca = (ThisIsMmc) ? 0x0001 : 0x0000;
 	IssueCommand(3,m_uRca,0);	
	
	if(!ThisIsMmc)
 		{
			m_uRca = (rHM_RSPREG0>>16)&0xFFFF;			
			printf("=>  RCA=0x%x\n", m_uRca);			
 		}	
	
	printf("\nEnter to the Stand-by State\n");
	
	IssueCommand(9, m_uRca, 0);//Send CSD
	
	DisplayCardInformation();

	IssueCommand(7, m_uRca, 0);	
	//printf("\nEnter to the Transfer State\n");		
		
//////////////////////// Operating Clock setting ////////////////////////////
#if HCLK_OPERATION
	ClockConfig(SD_HCLK, 1);// Divisor 1 = Base clk /2	,Divisor 2 = Base clk /4, Divisor 4 = Base clk /8 ...		
#else
	rLOCKCON1=0x800; 
	rCLKSRC|=(1<<6);  // EPLL Output
	SetEPLL(42, 1, 1);//100MHz
	rEPLLCON &= ~(1<<24);  // EPLL ON 
	rCLKDIV1 = (rCLKDIV1 & ~(0x3<<6)) | (0x0<<6);
	rMISCCR = rMISCCR & ~(0x7<<8) | (1<<8);
	rGPHCON = rGPHCON & ~(0x3<<28) | (1<<29);
	ClockConfig(SD_EPLL, 1);// Divisor 1 = Base clk /2 ,Divisor 2 = Base clk /4, Divisor 4 = Base clk /8 ...	

#endif
///////////////////////////////////////////////////////////////////////
	if(ThisIsMmc)
		{
			if(!ReadExtCSD())
			printf("\nFail to read Ext CSD");
		}
	
	while (!SetDataTransferWidth());	

	while (!IsCardInProgrammingState());

	printf("\nSet a One Block size\n");
	while(!IssueCommand(16, 512, 0));//Set the One Block size	

	rHM_NORINTSTS = 0xffff;

	return 1;
}

int ReadExtCSD(void)
{	
       U32   uSfr;	
	U32  S_CMD_SET=0;	
	int i;
	
	Rx_buffer_HSMMC = (U32 *)SDI_Rx_buffer_HSMMC;
    	for(i=0 ; i<512/4 ; i++)	
		*(Rx_buffer_HSMMC+i) = 0x0;  
	
	if (!IssueCommand(16, 512, 0))		
		return 0;	
	else	
	{		

		SetBlockSizeReg(7, 512);// Maximum DMA Buffer Size, Block Size		
		SetBlockCountReg(1);  // Block Numbers to Read		
		SetArgumentReg(0); // Card Address to Read	
		
		SetTransferModeReg(0, 1, 0, 0, 0);
		if(!IssueCommand(8, 0, 0))	// cmd8			
			return 0;		
		else		
		{			
		       WaitForBufferReadReady();	
			ClearBufferReadReadyStatus();	

			for(i=1; i<129; i++)			
			{				
			      uSfr = rHM_BDATA;

				if (i==127)				
				 	S_CMD_SET = (uSfr & 0xff);				
			}

			WaitForTransferComplete();	
			ClearTransferCompleteStatus();
			
			if(S_CMD_SET & (1<<3))
				printf("\n========Secure MMC 2.0========\n");
			else if(S_CMD_SET & (1<<2))
				printf("\n========Content Protection SecureMMC Card detect========\n");
			else if(S_CMD_SET & (1<<1))
				printf("\n========Secure MMC Card detect========\n");
			else if(S_CMD_SET & (1<<0))
				printf("\n========Standard MMC Card detect========\n");

			return 1;		
		}	
	}
}

void HS_MMC_WriteTest(void)
{
	U32 i, j, StartAddr,  OneBlockSize, Offset, Testmode;
	U32 TotalWriteByte, WriteBlockCnt =0;
	U32 transtime=0;

	U32 uTxBufAddr = SDI_Tx_buffer_HSMMC;
	U32 uCompareBufAddr = SDI_Compare_buffer_HSMMC;
	
	wt_cnt_HSMMC=0;
	BlockNum_HSMMC = 0;
	wt_cnt_HSMMC = 0;
	WriteBlockCnt_INT = 0;
	HS_DMA_END = 0;
	
	printf("\nSD/MMC block write test\n");

	printf("\n0:Polling write   1:Interrupt write   2:DMA write");
	printf("\nSelect the test mode : ");
    
       Testmode=GetIntNum();
    	
	printf("\nInput Write Start block number : ");
	StartAddr = GetIntNum();

	printf("Input Write Data Offset : ");
	Offset = GetIntNum();

	while((BlockNum_HSMMC == 0) || (BlockNum_HSMMC > 65535))
	{
		printf("Input number of Block [1~65535] : ");
		BlockNum_HSMMC = GetIntNum();
	}

	if(SectorMode == 1)
		{
		StartAddr = StartAddr;
		printf("\nSector Mode Addressing");
		}
	else
		{
		StartAddr = StartAddr * 512;
		printf("\nByte Mode Addressing");
		}
	
	OneBlockSize = Card_OneBlockSize_ver1;
	
	Tx_buffer_HSMMC = (U32 *)SDI_Tx_buffer_HSMMC;
    	for(i=0 ; i<(OneBlockSize*BlockNum_HSMMC)/4 ; i++)
    		{
    		*(Tx_buffer_HSMMC+i) = (i+Offset);   	
   		}				
	
	switch(Testmode)
		{
			case  POL_Ver1:
				printf("\nPolling mode data write\n");

				SetBlockSizeReg(7, 512); // Maximum DMA Buffer Size, Block Size
				SetBlockCountReg(BlockNum_HSMMC); // Block Numbers to Write
				SetArgumentReg(StartAddr); // Card Address to Write

				if(BlockNum_HSMMC == 1)//single block
					{
						SetTransferModeReg(0, 0, 1, 1, 0);
						SetCommandReg(24, 0); 	
					}
				else//multi block
					{
						SetTransferModeReg(1, 0, 1, 1, 0);
						SetCommandReg(25, 0); 
					}

				if (!WaitForCommandComplete())
					{
						printf("\nCommand is NOT completed\n");
					}
				ClearCommandCompleteStatus();

				for(j=0; j<BlockNum_HSMMC; j++)
					{
						if (!WaitForBufferWriteReady())
							printf("WriteBuffer NOT Ready\n");
						else
							ClearBufferWriteReadyStatus();

						for(i=0; i<512/4; i++)//512 byte should be writed.
							{
								rHM_BDATA = *Tx_buffer_HSMMC++;	
				  		 		wt_cnt_HSMMC++;						
							}
						WriteBlockCnt ++;						
					}

				TotalWriteByte = wt_cnt_HSMMC *4;
				printf("\nWrite count=%dByte\n",TotalWriteByte);
				if(!WaitForTransferComplete())
					{
					printf(("Transfer is NOT Complete\n"));
					}
				ClearTransferCompleteStatus();
				
				break;

			case INT_Ver1:

				printf("Interrupt mode data write\n");
				pISR_SDI_1=(unsigned)HS_WRITE_INT;
				
				SetBlockSizeReg(7, 512); // Maximum DMA Buffer Size, Block Size
				SetBlockCountReg(BlockNum_HSMMC); // Block Numbers to Write
				SetArgumentReg(StartAddr); // Card Address to Write

				StartStopwatch();
				
				if(BlockNum_HSMMC == 1)//single block
					{
						SetTransferModeReg(0, 0, 1, 1, 0);
						SetCommandReg(24, 0); 	
					}
				else//multi block
					{
						SetTransferModeReg(1, 0, 1, 1, 0);
						SetCommandReg(25, 0); 
					}

				if (!WaitForCommandComplete())
					{
						printf("\nCommand is NOT completed\n");
					}
				ClearCommandCompleteStatus();

				rINTMSK &= ~(BIT_SDI1);
				rHM_NORINTSIGEN = rHM_NORINTSIGEN & ~(0xffff) | BUFFER_WRITEREADY_SIG_INT_EN;	

				while(!WRITEINT_DONE);

				if(!WaitForTransferComplete())
					{
					printf(("Transfer is NOT Complete\n"));
					}
				ClearTransferCompleteStatus();

				rHM_NORINTSTS |= (1<<4);
				
				transtime = EndStopwatch();
				CalculationBPS_HSMMC(transtime);

				ClearPending(BIT_TIMER0);
				
	    			break;
					
			case DMA_Ver1:

				#if BUFFER_BOUNDARY
				
				pISR_SDI_1 = (unsigned)HS_DMA_INT;
				rINTMSK &= ~(BIT_SDI1);				
				rHM_NORINTSTSEN |= (DMA_STS_INT_EN |TRANSFERCOMPLETE_STS_INT_EN);
				rHM_NORINTSIGEN = rHM_NORINTSIGEN & ~(0xffff) | DMA_SIG_INT_EN |TRANSFERCOMPLETE_SIG_INT_EN;
				
				SetSystemAddressReg(SDI_Tx_buffer_HSMMC);// AHB System Address For Write
				SetBlockSizeReg(0, 512); // 4K Byte Buffer Boundary, Block Size				
				SetBlockCountReg(BlockNum_HSMMC); // Block Numbers to Write	
				SetArgumentReg(StartAddr);// Card Start Block Address to Write				

				#else		

				pISR_SDI_1 = (unsigned)HS_DMA_INT;
				
				rINTMSK &= ~(BIT_SDI1);				
				rHM_NORINTSTSEN = (rHM_NORINTSTSEN & ~(0xffff)) |
									BUFFER_READREADY_STS_INT_EN | 
									BUFFER_WRITEREADY_STS_INT_EN |
									TRANSFERCOMPLETE_STS_INT_EN |
									COMMANDCOMPLETE_STS_INT_EN;
				rHM_NORINTSIGEN = (rHM_NORINTSIGEN & ~(0xffff)) | TRANSFERCOMPLETE_SIG_INT_EN;				
			
				SetSystemAddressReg(SDI_Tx_buffer_HSMMC);// AHB System Address For Write
				SetBlockSizeReg(7, 512); // Maximum DMA Buffer Size, Block Size				
				SetBlockCountReg(BlockNum_HSMMC); // Block Numbers to Write	
				SetArgumentReg(StartAddr);// Card Start Block Address to Write				
				
				#endif			

				StartStopwatch();

				if (BlockNum_HSMMC == 1)
				{
					SetTransferModeReg(0, 0, 1, 1, 1);
					SetCommandReg(24, 0); // CMD24: Single-Write
				}
				else
				{
					SetTransferModeReg(1, 0, 1, 1, 1);
					SetCommandReg(25, 0); // CMD25: Multi-Write
				}
				
				if (!WaitForCommandComplete())
				{
					printf("\nCommand is NOT completed\n");
				}
				ClearCommandCompleteStatus();		
				
				while(!HS_DMA_END);

				if(!WaitForTransferComplete())
					{
					printf(("Transfer is NOT Complete\n"));
					}
				ClearTransferCompleteStatus();
				
				rHM_NORINTSTS |= (1<<3);
				
				transtime = EndStopwatch();
				CalculationBPS_HSMMC(transtime);
				
				printf(("\nDMA Write End\n"));
				
				break;	
				
			default :
				break;					
		}	

	printf("\nPress Any key for Data compare\n");
	Uart_getc();
	DataRead_ForCompare(StartAddr);
	DataCompare_HSMMC(uTxBufAddr, uCompareBufAddr, BlockNum_HSMMC * 128);
	
	BlockNum_HSMMC = 0;
	wt_cnt_HSMMC = 0;
	WriteBlockCnt_INT = 0;
	HS_DMA_END = 0;
	BufferBoundary_INT_Cnt = 0;

	CompareCnt_INT = 0;
	Compare_buffer_HSMMC = 0;
}

unsigned int testNumber = 0;
volatile U32 realStartAddr=0;

void HS_MMC_Write_AgingTest(void)
{
	U32 i, j, StartAddr;
	U32 TotalWriteByte=0, WriteBlockCnt =0;

	wt_cnt_HSMMC=0;
	BlockNum_HSMMC = 0;
	wt_cnt_HSMMC = 0;
	WriteBlockCnt_INT = 0;
	HS_DMA_END = 0;
	
	printf("\nSD/MMC block write test\n");

	BlockNum_HSMMC = 100;
	testNumber =0;
	
	printf("\nPolling mode data write\n");

	for(realStartAddr=0;realStartAddr<BlockNum_HSMMC*1000;realStartAddr=realStartAddr+BlockNum_HSMMC ) 
		{

		StartAddr = realStartAddr * 512;

		printf( "Count : %d/8100 ,,, %x\n", realStartAddr, testNumber );

		SetBlockSizeReg(7, 512); // Maximum DMA Buffer Size, Block Size
		SetBlockCountReg(BlockNum_HSMMC); // Block Numbers to Write
		SetArgumentReg(StartAddr); // Card Address to Write

		if(BlockNum_HSMMC == 1)//single block
			{
				SetTransferModeReg(0, 0, 1, 1, 0);
				SetCommandReg(24, 0); 	
			}
		else//multi block
			{
				SetTransferModeReg(1, 0, 1, 1, 0);
				SetCommandReg(25, 0); 

			}

		if (!WaitForCommandComplete())
			{
				printf("\nCommand is NOT completed\n");
			}
		ClearCommandCompleteStatus();

		if (rHM_NORINTSTS&0x8000)
			printf("Command = %d, Error Stat = %x\n",(rHM_CMDREG>>8),rHM_ERRINTSTS);	

		for(j=0; j<BlockNum_HSMMC; j++)
			{
				if (!WaitForBufferWriteReady())
					printf("WriteBuffer NOT Ready\n");
				else
					ClearBufferWriteReadyStatus();

				for(i=0; i<512/4; i++)//512 byte should be writed.
					{
						rHM_BDATA = testNumber++;	
		  		 		wt_cnt_HSMMC++;						
					}
				WriteBlockCnt ++;
			}

		TotalWriteByte = wt_cnt_HSMMC *4;
		printf("\nWrite count=%dByte\n",TotalWriteByte);
		if(!WaitForTransferComplete())
			{
			printf(("Transfer is NOT Complete\n"));
			}
		ClearTransferCompleteStatus();

		while (!IsCardInProgrammingState());

		}

}

void HS_MMC_ReadTest(void)
{
	U32 i, j, StartAddr,  OneBlockSize, Testmode, Addr_temp;
	U32 TotalReadByte, WriteBlockCnt=0;	
	U32 transtime;
	
	rd_cnt_HSMMC=0;	
	HS_DMA_END = 0;	
	BlockNum_HSMMC = 0;
	rd_cnt_HSMMC = 0;

⌨️ 快捷键说明

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