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

📄 hs1_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 "hs1_mmc.h"

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

#define SDI_Tx_buffer_HSMMC_CH1 (_NONCACHE_STARTADDRESS)
#define SDI_Rx_buffer_HSMMC_CH1 (_NONCACHE_STARTADDRESS+(0x01000000))
#define SDI_Compare_buffer_HSMMC_CH1 (_NONCACHE_STARTADDRESS+(0x02000000))


#define Card_OneBlockSize_ver1 512

// Global variables
unsigned int *Tx_buffer_HSMMC_ch1;	
unsigned int *Rx_buffer_HSMMC_ch1;
unsigned int *Compare_buffer_HSMMC_ch1;

volatile unsigned int rd_cnt_HSMMC_ch1;
volatile unsigned int wt_cnt_HSMMC_ch1;
volatile unsigned int BlockNum_HSMMC_ch1=0;

volatile unsigned int WriteBlockCnt_INT_ch1=0;
volatile unsigned int ReadBlockCnt_INT_ch1=0;
volatile unsigned int WRITEINT_DONE_ch1=0;
volatile unsigned int READINT_DONE_ch1=0;
volatile unsigned int COMPARE_INT_DONE_ch1=0;
volatile unsigned int CompareCnt_INT_ch1=0;
volatile unsigned int BufferBoundary_INT_Cnt_ch1=0;

volatile unsigned int HS_DMA_END_ch1 = 0;
volatile unsigned int HS_ADMA_END_ch1 = 0;
volatile unsigned int HS_CARD_DETECT_ch1 = 0;
volatile unsigned int HS_DESCRIPTOR_INT_ch1 = 0;

volatile int OCRcheck_ch1=0;
volatile int ThisIsMmc_ch1=0;
volatile int m_uRca_ch1=0;
volatile int m_ucMMCSpecVer_ch1 = 0;
volatile int SDSpecVer_ch1=0;
volatile int CE_ATA_ch1=0;
volatile int SectorMode_ch1 =0;


volatile unsigned int CCS_END_ch1 = 0;
volatile unsigned int CEATA_ISR_ch1 = 0;
volatile unsigned int ISR_CCS_INT=0;

volatile unsigned int TotalCardBlock_number_ch1 =0;

extern	unsigned int ARMCLK, HCLK, PCLK;


#define		CEATA_DMA_ch1		0

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

#define NEW_SD_CARD_ch1		1
#define BUFFER_BOUNDARY_ch1	0
#define HCLK_OPERATION_ch1		1

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

void * func_HSMMC1_test[][2]=
{
	(void *)MoviNand_BootWrite_CH1_Auto,	"MoviNand Boot Write program Auto  ",
	(void *)MoviNand_BootWrite_CH1_Manual,	"MoviNand Boot Write program Manual  ",
	(void *)HS_MMC_WriteTest_CH1,       	  	"CH1 SD/MMC Write                    ",
	(void *)HS_MMC_Write_AgingTest_CH1,   	"CH1 SD/MMC Write Aging      ",
	(void *)HS_MMC_ReadTest_CH1,           	  	"CH1 SD/MMC Read                    ",
	(void *)HS_MMC_EraseBlock_CH1,           	"CH1 SD/MMC Block Erase           ",
	(void *)HS_MMC_ADMATest_CH1,		  	"CH1 SD/MMC ADMA Test           ",
	(void *)HS_MMC_ADMA_WriteTest_CH1,		"CH1 SD/MMC ADMA Write Test   ",
	(void *)HS_MMC_ADMA_ReadTest_CH1,		"CH1 SD/MMC ADMA Read Test   ",
	0,0
};

void * func_CEATA_test_ch1[][2]=
{	
    (void *)CE_ATA_WriteTest_CH1,       	    "CE ATA Write          ",
    (void *)CE_ATA_ReadTest_CH1,           	"CE ATA Read           ",
    0,0
};

void Test_HS_MMC_CH1(void)
{  
	int i;

	HS_MMC_SETGPIO_CH1();	

	//HS_MMC_CardDetect_CH1();

	HS_MMC_Reset_CH1();		
	
	if(!HS_MMC_init_CH1())
	{
		printf("\nCard initial fail\n");
	}

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

void Test_CE_ATA_CH1(void)
{  
	int i;

	CE_ATAInit_CH1();

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


int HS_MMC_init_CH1(void)
{
	int uArg;

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

	SetClock_CH1(SD_HCLK_CH1, 0x40);
	
	rHM1_TIMEOUTCON = 0xe;

	HostCtrlSpeedMode_CH1(NORMAL_CH1);

	InterruptEnable_CH1(0xff, 0xff);

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

	IssueCommand_CH1(0,0x00,0);//Idle State
	IssueCommand_CH1(0,0x00,0);//Idle State
	IssueCommand_CH1(0,0x00,0);//Idle State
	printf("\nEnter to the Idle State\n");
/*
	uArg = (0x1<<8)|(0xaa<<0); //This Line for HC SD card.
	IssueCommand_CH1(8,uArg,0);
*/
	OCRcheck_ch1 =1;

	if(!(SDSpecVer_ch1 == 2))
		{
			if(SetMMCOCR_CH1())
			{
				ThisIsMmc_ch1=1;
				printf("MMC card is detected\n");
			}
			else if(SetSDOCR_CH1())
			{
				ThisIsMmc_ch1=0;
				printf("SD card is detected\n");
			}
			else
				return 0;
		}
	else
		{
			if(SetSDOCR_CH1())
			{
				ThisIsMmc_ch1=0;
				printf("SD card is detected\n");
			}		
		}

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

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

	IssueCommand_CH1(7, m_uRca_ch1, 0);	
	//printf("\nEnter to the Transfer State\n");		
		
//////////////////////// Operating Clock setting ////////////////////////////
#if 0
	ClockConfig_CH1(SD_HCLK_CH1, 8);// Divisor 1 = Base clk /2	,Divisor 2 = Base clk /4, Divisor 4 = Base clk /8 ...		
#else
	rLOCKCON1=0x800; 
	rCLKSRC|=(1<<6);  // EPLL Output
	SetEPLL(33, 1, 2);//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_CH1(SD_EPLL_CH1, 8);// Divisor 1 = Base clk /2 ,Divisor 2 = Base clk /4, Divisor 4 = Base clk /8 ...	
#endif
///////////////////////////////////////////////////////////////////////
	while (!IsCardInProgrammingState_CH1());

	if(ThisIsMmc_ch1)
		{
			if(!ReadExtCSD_CH1())
			printf("\nFail to read Ext CSD");
		}

	while (!SetDataTransferWidth_CH1());	


	while (!IsCardInProgrammingState_CH1());

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

	rHM1_NORINTSTS = 0xffff;

	CE_ATA_ch1=0;
	if(CE_ATA_ch1 == 1)
	{
		printf("\n\n------------CE ATA Device detect------------");
		Test_CE_ATA_CH1();
	}

	return 1;
}

int ReadExtCSD_CH1(void)
{	
      U32   uSfr;	
	U32  S_CMD_SET, uHsTiming;	
	int i;
	
	Rx_buffer_HSMMC_ch1 = (U32 *)SDI_Rx_buffer_HSMMC_CH1;
    	for(i=0 ; i<512/4 ; i++)	
		*(Rx_buffer_HSMMC_ch1+i) = 0x0;  
	
	IssueCommand_CH1(16, 512, 0);	

	rHM1_BLKSIZE = (7<<12)|(512);	// Maximum DMA Buffer Size, Block Size	
	rHM1_BLKCNT = 1;	
	rHM1_TRNMOD = (0<<5)|(1<<4)|(0<<2)|(0<<1)|(0<<0);
	rHM1_CMDREG = (8<<8)|(1<<5)|(1<<4)|(1<<3)|(2<<0);
	
       WaitForBufferReadReady_CH1();	
	ClearBufferReadReadyStatus_CH1();	

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

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

	printf("\nS_CMD_SET=%x",S_CMD_SET);
	WaitForTransferComplete_CH1();	
	ClearTransferCompleteStatus_CH1();

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

	U32 uTxBufAddr = SDI_Tx_buffer_HSMMC_CH1;
	U32 uCompareBufAddr = SDI_Compare_buffer_HSMMC_CH1;
	
	wt_cnt_HSMMC_ch1=0;
	BlockNum_HSMMC_ch1 = 0;
	wt_cnt_HSMMC_ch1 = 0;
	WriteBlockCnt_INT_ch1 = 0;
	HS_DMA_END_ch1 = 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_ch1 == 0) || (BlockNum_HSMMC_ch1 > 65535))
	{
		printf("Input number of Block [1~65535] : ");
		BlockNum_HSMMC_ch1 = GetIntNum();
	}

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

				SetBlockSizeReg_CH1(7, 512); // Maximum DMA Buffer Size, Block Size
				SetBlockCountReg_CH1(BlockNum_HSMMC_ch1); // Block Numbers to Write
				SetArgumentReg_CH1(StartAddr); // Card Address to Write

				if(BlockNum_HSMMC_ch1 == 1)//single block
					{
						SetTransferModeReg_CH1(0, 0, 1, 1, 0);
						SetCommandReg_CH1(24, 0); 	
					}
				else//multi block
					{
						SetTransferModeReg_CH1(1, 0, 1, 1, 0);
						SetCommandReg_CH1(25, 0); 
					}

				if (!WaitForCommandComplete_CH1())
					{
						printf("\nCommand is NOT completed\n");
					}
				ClearCommandCompleteStatus_CH1();

				for(j=0; j<BlockNum_HSMMC_ch1; j++)
					{
						if (!WaitForBufferWriteReady_CH1())
							printf("WriteBuffer NOT Ready\n");
						else
							ClearBufferWriteReadyStatus_CH1();

						for(i=0; i<512/4; i++)//512 byte should be writed.
							{
								rHM1_BDATA = *Tx_buffer_HSMMC_ch1++;	
				  		 		wt_cnt_HSMMC_ch1++;						
							}
						WriteBlockCnt ++;						
					}

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

			case INT_Ver1:

				printf("Interrupt mode data write\n");
				pISR_SDI_1=(unsigned)HS_WRITE_INT_CH1;
				
				SetBlockSizeReg_CH1(7, 512); // Maximum DMA Buffer Size, Block Size
				SetBlockCountReg_CH1(BlockNum_HSMMC_ch1); // Block Numbers to Write
				SetArgumentReg_CH1(StartAddr); // Card Address to Write

				StartStopwatch();
				
				if(BlockNum_HSMMC_ch1 == 1)//single block
					{
						SetTransferModeReg_CH1(0, 0, 1, 1, 0);
						SetCommandReg_CH1(24, 0); 	
					}
				else//multi block
					{
						SetTransferModeReg_CH1(1, 0, 1, 1, 0);
						SetCommandReg_CH1(25, 0); 
					}

				if (!WaitForCommandComplete_CH1())
					{
						printf("\nCommand is NOT completed\n");
					}
				ClearCommandCompleteStatus_CH1();

				rINTMSK &= ~(BIT_SDI1);
				rHM1_NORINTSIGEN = rHM1_NORINTSIGEN & ~(0xffff) | BUFFER_WRITEREADY_SIG_INT_EN_CH1;	

				while(!WRITEINT_DONE_ch1);

				if(!WaitForTransferComplete_CH1())
					{
					printf(("Transfer is NOT Complete\n"));
					}
				ClearTransferCompleteStatus_CH1();

				rHM1_NORINTSTS |= (1<<4);
				
				transtime = EndStopwatch();
				CalculationBPS_HSMMC_CH1(transtime);

				ClearPending(BIT_TIMER0);
				
	    			break;
					
			case DMA_Ver1:

				#if BUFFER_BOUNDARY_ch1
				
				pISR_SDI_1 = (unsigned)HS_DMA_INT_CH1;
				rINTMSK &= ~(BIT_SDI1);				
				rHM1_NORINTSTSEN |= (DMA_STS_INT_EN_CH1 |TRANSFERCOMPLETE_STS_INT_EN_CH1);
				rHM1_NORINTSIGEN = rHM1_NORINTSIGEN & ~(0xffff) | DMA_SIG_INT_EN_CH1 |TRANSFERCOMPLETE_SIG_INT_EN_CH1;
				
				SetSystemAddressReg_CH1(SDI_Tx_buffer_HSMMC_CH1);// AHB System Address For Write
				SetBlockSizeReg_CH1(0, 512); // 4K Byte Buffer Boundary, Block Size				
				SetBlockCountReg_CH1(BlockNum_HSMMC_ch1); // Block Numbers to Write	
				SetArgumentReg_CH1(StartAddr);// Card Start Block Address to Write				

				#else		

				pISR_SDI_1 = (unsigned)HS_DMA_INT_CH1;
				
				rINTMSK &= ~(BIT_SDI1);				
				rHM1_NORINTSTSEN = (rHM1_NORINTSTSEN & ~(0xffff)) |
									BUFFER_READREADY_STS_INT_EN_CH1 | 
									BUFFER_WRITEREADY_STS_INT_EN_CH1 |
									TRANSFERCOMPLETE_STS_INT_EN_CH1 |
									COMMANDCOMPLETE_STS_INT_EN_CH1;
				rHM1_NORINTSIGEN = (rHM1_NORINTSIGEN & ~(0xffff)) | TRANSFERCOMPLETE_SIG_INT_EN_CH1;				
			
				SetSystemAddressReg_CH1(SDI_Tx_buffer_HSMMC_CH1);// AHB System Address For Write
				SetBlockSizeReg_CH1(7, 512); // Maximum DMA Buffer Size, Block Size				
				SetBlockCountReg_CH1(BlockNum_HSMMC_ch1); // Block Numbers to Write	
				SetArgumentReg_CH1(StartAddr);// Card Start Block Address to Write				

⌨️ 快捷键说明

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