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

📄 hs0_mmc.c

📁 samsung 最新芯片2450 的测试程序.
💻 C
📖 第 1 页 / 共 5 页
字号:
/*****************************************
  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 "2450addr.h"
#include "system.h"
#include "pll.h"
#include "console.h"
#include "hs0_mmc.h"

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

#define SDI_Tx_buffer_HSMMC_CH0 (_NONCACHE_STARTADDRESS)
#define SDI_Rx_buffer_HSMMC_CH0 (_NONCACHE_STARTADDRESS+(0x01000000))
#define SDI_Compare_buffer_HSMMC_CH0 (_NONCACHE_STARTADDRESS+(0x02000000))


#define Card_OneBlockSize_ver1 512

// Global variables
unsigned int *Tx_buffer_HSMMC_ch0;	
unsigned int *Rx_buffer_HSMMC_ch0;
unsigned int *Compare_buffer_HSMMC_ch0;

volatile unsigned int rd_cnt_HSMMC_ch0;
volatile unsigned int wt_cnt_HSMMC_ch0;
volatile unsigned int BlockNum_HSMMC_ch0=0;

volatile unsigned int WriteBlockCnt_INT_ch0=0;
volatile unsigned int ReadBlockCnt_INT_ch0=0;
volatile unsigned int WRITEINT_DONE_ch0=0;
volatile unsigned int READINT_DONE_ch0=0;
volatile unsigned int COMPARE_INT_DONE_ch0=0;
volatile unsigned int CompareCnt_INT_ch0=0;
volatile unsigned int BufferBoundary_INT_Cnt_ch0=0;

volatile unsigned int HS_DMA_END_ch0 = 0;
volatile unsigned int HS_ADMA_END_ch0 = 0;
volatile unsigned int HS_CARD_DETECT_ch0 = 0;
volatile unsigned int HS_DESCRIPTOR_INT_ch0 = 0;

volatile int OCRcheck_ch0=0;
volatile int ThisIsMmc_ch0=0;
volatile int m_uRca_ch0=0;
volatile int m_ucMMCSpecVer_ch0 = 0;
volatile int SDSpecVer_ch0=0;
volatile int CE_ATA_ch0=0;
volatile int SectorMode_ch0 =0;

volatile unsigned int CCS_END_ch0 = 0;
volatile unsigned int CEATA_ISR_ch0 = 0;

volatile unsigned int TotalCardBlock_number_ch0 =0;

extern	unsigned int ARMCLK, HCLK, PCLK;


#define		CEATA_DMA_ch0		0

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

#define NEW_SD_CARD_ch0				1
#define BUFFER_BOUNDARY_ch0		1
#define HCLK_OPERATION_ch0		1

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

void * func_HSMMC0_test[][2]=
{	
	(void *)HS_MMC_WriteTest_CH0,       	  "CH0 SD/MMC Write        ",
	(void *)HS_MMC_Write_AgingTest_CH0,   "CH0 SD/MMC Write Aging",
	(void *)HS_MMC_ReadTest_CH0,           	  "CH0 SD/MMC Read         ",
	(void *)HS_MMC_EraseBlock_CH0,            "CH0 SD/MMC Block Erase",
	(void *)HS_MMC_ADMATest_CH0,		  "CH0 SD/MMC ADMA Test           ",
	(void *)HS_MMC_ADMA_WriteTest_CH0,	  "CH0 SD/MMC ADMA Write Test   ",
	(void *)HS_MMC_ADMA_ReadTest_CH0,	  "CH0 SD/MMC ADMA Read Test   ",
	0,0
};

void * func_CEATA_test_ch0[][2]=
{	
    (void *)CE_ATA_WriteTest_CH0,       	    "CE ATA Write          ",
    (void *)CE_ATA_ReadTest_CH0,           	"CE ATA Read           ",
    0,0
};

void Test_HS_MMC_CH0(void)
{  
	int i;

	HS_MMC_SETGPIO_CH0();	

	//HS_MMC_CardDetect_CH0();

	HS_MMC_Reset_CH0();	
	
	if(!HS_MMC_init_CH0())
	{
		printf("\nCard initial fail\n");
	}

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

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

void Test_CE_ATA_CH0(void)
{  
	int i;

	CE_ATAInit_CH0();

	while(1)
	{
		i=0;
		printf("\n\n");
		while(1)
		{   //display menu
	   		printf("%2d:%s",i,func_CEATA_test_ch0[i][1]);
	    	i++;
	    	if((int)(func_CEATA_test_ch0[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_CEATA_test_ch0)-1)/8)) )	// select and execute...
	    	( (void (*)(void)) (func_CEATA_test_ch0[i][0]) )();
	}
	
}

int HS_MMC_init_CH0(void)
{
	int uArg;

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

	SetClock_CH0(SD_HCLK_CH0, 0x20);
	
	rHM0_TIMEOUTCON = 0xe;

	HostCtrlSpeedMode_CH0(NORMAL_CH0);

	InterruptEnable_CH0(0xff, 0xff);

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

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

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

	OCRcheck_ch0 =1;

	if(!(SDSpecVer_ch0 == 2))
		{
			if(SetMMCOCR_CH0())
			{
				ThisIsMmc_ch0=1;
				printf("MMC card is detected\n");
			}
			else if(SetSDOCR_CH0())
			{
				ThisIsMmc_ch0=0;
				printf("SD card is detected\n");
			}
			else
				return 0;
		}
	else
		{
			if(SetSDOCR_CH0())
			{
				ThisIsMmc_ch0=0;
				printf("SD card is detected\n");
			}		
		}

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

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

	IssueCommand_CH0(7, m_uRca_ch0, 0);	
	//printf("\nEnter to the Transfer State\n");		
		
//////////////////////// Operating Clock setting ////////////////////////////
#if 0
	ClockConfig_CH0(SD_HCLK_CH0, 2);// Divisor 1 = Base clk /2	,Divisor 2 = Base clk /4, Divisor 4 = Base clk /8 ...		
#else
	rLOCKCON1=0x800; 
	rCLKSRC|=(1<<6);  // EPLL Output
	//rCLKSRC &= ~(1<<6);  // EPLL Output disable
	SetEPLL(33, 1, 2);//100MHz
	rEPLLCON &= ~(1<<24);  // EPLL ON 
	//rEPLLCON |= (1<<24);  // EPLL OFF
	rCLKDIV1 = (rCLKDIV1 & ~(0x3<<6)) | (0x0<<6);
	rMISCCR = rMISCCR & ~(0x7<<8) | (1<<8);
	rGPHCON = rGPHCON & ~(0x3<<28) | (1<<29);
	ClockConfig_CH0(SD_EPLL_CH0, 8);// Divisor 1 = Base clk /2 ,Divisor 2 = Base clk /4, Divisor 4 = Base clk /8 ...
#endif
///////////////////////////////////////////////////////////////////////
	if(ThisIsMmc_ch0)
		{
			if(!ReadExtCSD_CH0())
			printf("\nFail to read Ext CSD");
		}
	
	while (!SetDataTransferWidth_CH0());	

	while (!IsCardInProgrammingState_CH0());

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

	rHM0_NORINTSTS = 0xffff;
	
	CE_ATA_ch0=0;
	if(CE_ATA_ch0 == 1)
	{
		printf("\n\n------------CE ATA Device detect------------");
		Test_CE_ATA_CH0();
	}
	return 1;
}

int ReadExtCSD_CH0(void)
{	
      U32   uSfr;	
	U32  S_CMD_SET, uHsTiming;	
	int i;
	
	Rx_buffer_HSMMC_ch0 = (U32 *)SDI_Rx_buffer_HSMMC_CH0;
    	for(i=0 ; i<512/4 ; i++)	
		*(Rx_buffer_HSMMC_ch0+i) = 0x0;  
	
	IssueCommand_CH0(16, 512, 0);	

	rHM0_BLKSIZE = (7<<12)|(512);	// Maximum DMA Buffer Size, Block Size	
	rHM0_BLKCNT = 1;	
	rHM0_TRNMOD = (0<<5)|(1<<4)|(0<<2)|(0<<1)|(0<<0);
	rHM0_CMDREG = (8<<8)|(1<<5)|(1<<4)|(1<<3)|(2<<0);
	
       WaitForBufferReadReady_CH0();	
	ClearBufferReadReadyStatus_CH0();	

	for(i=0; i<128; i++)			
	{		
	      uSfr = rHM0_BDATA;

		if (i==126)				
		 	S_CMD_SET = (uSfr & 0xff);
		if(i==53)
			{
			if(uSfr != 0)
				{
				TotalCardBlock_number_ch0 = uSfr;
				printf("TotalCardBlock_number_ch1 = %d",TotalCardBlock_number_ch0);
				}
			}				
		if (i==46)				
		 	uHsTiming = ((uSfr>>8) & 0xff);				
	}

	printf("\nS_CMD_SET=%x",S_CMD_SET);
	WaitForTransferComplete_CH0();	
	ClearTransferCompleteStatus_CH0();

	if(S_CMD_SET & (1<<4))
		CE_ATA_ch0 = 1;
	else 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_CH0(void)
{
	U32 i, j, StartAddr,  OneBlockSize, Offset, Testmode;
	U32 TotalWriteByte, WriteBlockCnt =0;
	U32 transtime=0;

	U32 uTxBufAddr = SDI_Tx_buffer_HSMMC_CH0;
	U32 uCompareBufAddr = SDI_Compare_buffer_HSMMC_CH0;
	
	wt_cnt_HSMMC_ch0=0;
	BlockNum_HSMMC_ch0 = 0;
	wt_cnt_HSMMC_ch0 = 0;
	WriteBlockCnt_INT_ch0 = 0;
	HS_DMA_END_ch0 = 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_ch0 == 0) || (BlockNum_HSMMC_ch0 > 65535))
	{
		printf("Input number of Block [1~65535] : ");
		BlockNum_HSMMC_ch0 = GetIntNum();
	}

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

				SetBlockSizeReg_CH0(7, 512); // Maximum DMA Buffer Size, Block Size
				SetBlockCountReg_CH0(BlockNum_HSMMC_ch0); // Block Numbers to Write
				SetArgumentReg_CH0(StartAddr); // Card Address to Write

				if(BlockNum_HSMMC_ch0 == 1)//single block
					{
						SetTransferModeReg_CH0(0, 0, 1, 1, 0);
						SetCommandReg_CH0(24, 0); 	
					}
				else//multi block
					{
						SetTransferModeReg_CH0(1, 0, 1, 1, 0);
						SetCommandReg_CH0(25, 0); 
					}

				if (!WaitForCommandComplete_CH0())
					{
						printf("\nCommand is NOT completed\n");
					}
				ClearCommandCompleteStatus_CH0();

				for(j=0; j<BlockNum_HSMMC_ch0; j++)
					{
						if (!WaitForBufferWriteReady_CH0())
							printf("WriteBuffer NOT Ready\n");
						else
							ClearBufferWriteReadyStatus_CH0();

						for(i=0; i<512/4; i++)//512 byte should be writed.
							{
								rHM0_BDATA = *Tx_buffer_HSMMC_ch0++;	
				  		 		wt_cnt_HSMMC_ch0++;						
							}
						WriteBlockCnt ++;						
					}

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

			case INT_Ver1:

				printf("Interrupt mode data write\n");
				pISR_SDI_0=(unsigned)HS_WRITE_INT_CH0;
				
				SetBlockSizeReg_CH0(7, 512); // Maximum DMA Buffer Size, Block Size
				SetBlockCountReg_CH0(BlockNum_HSMMC_ch0); // Block Numbers to Write
				SetArgumentReg_CH0(StartAddr); // Card Address to Write

				//StartStopwatch();
				
				if(BlockNum_HSMMC_ch0 == 1)//single block
					{
						SetTransferModeReg_CH0(0, 0, 1, 1, 0);
						SetCommandReg_CH0(24, 0); 	
					}
				else//multi block
					{
						SetTransferModeReg_CH0(1, 0, 1, 1, 0);
						SetCommandReg_CH0(25, 0); 
					}

				if (!WaitForCommandComplete_CH0())
					{
						printf("\nCommand is NOT completed\n");
					}
				ClearCommandCompleteStatus_CH0();

				rINTMSK &= ~(BIT_SDI0);
				rHM0_NORINTSIGEN = rHM0_NORINTSIGEN & ~(0xffff) | BUFFER_WRITEREADY_SIG_INT_EN_CH0;	

				while(!WRITEINT_DONE_ch0);

				if(!WaitForTransferComplete_CH0())
					{
					printf(("Transfer is NOT Complete\n"));
					}
				ClearTransferCompleteStatus_CH0();

				rHM0_NORINTSTS |= (1<<4);
				
				//transtime = EndStopwatch();
				//CalculationBPS_HSMMC_CH0(transtime);

				ClearPending(BIT_TIMER0);
				
	    			break;
					
			case DMA_Ver1:

				#if BUFFER_BOUNDARY_ch0
				
				pISR_SDI_0 = (unsigned)HS_DMA_INT_CH0;
				rINTMSK &= ~(BIT_SDI0);				
				rHM0_NORINTSTSEN |= (DMA_STS_INT_EN_CH0 |TRANSFERCOMPLETE_STS_INT_EN_CH0);
				rHM0_NORINTSIGEN = rHM0_NORINTSIGEN & ~(0xffff) | DMA_SIG_INT_EN_CH0 |TRANSFERCOMPLETE_SIG_INT_EN_CH0;
				
				SetSystemAddressReg_CH0(SDI_Tx_buffer_HSMMC_CH0);// AHB System Address For Write
				SetBlockSizeReg_CH0(0, 512); // 4K Byte Buffer Boundary, Block Size				
				SetBlockCountReg_CH0(BlockNum_HSMMC_ch0); // Block Numbers to Write	
				SetArgumentReg_CH0(StartAddr);// Card Start Block Address to Write				

				#else		

				pISR_SDI_0 = (unsigned)HS_DMA_INT_CH0;
				
				rINTMSK &= ~(BIT_SDI0);				
				rHM0_NORINTSTSEN = (rHM0_NORINTSTSEN & ~(0xffff)) |
									BUFFER_READREADY_STS_INT_EN_CH0 | 
									BUFFER_WRITEREADY_STS_INT_EN_CH0 |
									TRANSFERCOMPLETE_STS_INT_EN_CH0 |
									COMMANDCOMPLETE_STS_INT_EN_CH0;
				rHM0_NORINTSIGEN = (rHM0_NORINTSIGEN & ~(0xffff)) | TRANSFERCOMPLETE_SIG_INT_EN_CH0;				
			
				SetSystemAddressReg_CH0(SDI_Tx_buffer_HSMMC_CH0);// AHB System Address For Write
				SetBlockSizeReg_CH0(7, 512); // Maximum DMA Buffer Size, Block Size				
				SetBlockCountReg_CH0(BlockNum_HSMMC_ch0); // Block Numbers to Write	
				SetArgumentReg_CH0(StartAddr);// Card Start Block Address to Write				
				
				#endif			

				StartStopwatch();

				if (BlockNum_HSMMC_ch0 == 1)
				{
					SetTransferModeReg_CH0(0, 0, 1, 1, 1);
					SetCommandReg_CH0(24, 0); // CMD24: Single-Write
				}

⌨️ 快捷键说明

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