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

📄 pccard.c

📁 samsung 最新芯片2450 的测试程序.
💻 C
字号:

#include "system.h"
#include "etc.h"
#include "pccard.h"

#define PERF_TEST_PCCARD 		0   // overall time
#define PERF_TEST_PCCARD_D 		0   // only data transfering time


#define DBG_PCCARD

#ifdef DBG_PCCARD
#define DbgPccard(x) printf x
#else
#define DbgPccard(x) 0;
#endif

#define CFMEM_BASE      0x4B800000

// ATA, Basic PC card select
#define ATA_MUX           CFMEM_BASE+0x1800

// PC card SFR base
#define PCCARD_SFR_BASE   CFMEM_BASE+0x1820

// PC Card Memory map
#define PCCARD_ATT_BASE   CFMEM_BASE		// refer to attribute memory region
#define PCCARD_IO_BASE    CFMEM_BASE+0x800  // refer to IO region
#define PCCARD_MEM_BASE   CFMEM_BASE+0x1000 // refer to common memory region

#define PCCARD_MEM_MODE		0
#define PCCARD_IO_MODE1		1
#define PCCARD_IO_MODE2		2
#define PCCARD_IO_MODE3		3


/*=========================================================================
 *        	             ATA Commands
 *=========================================================================
 */

#define IDENTIFYDEVICE				0xec
#define READSECTOR					0x20
#define READMULTIPLE				0xc4
#define READDMA						0xc8
#define WRITESECTOR					0x30
#define WRITEMULTIPLE				0xc5
#define WRITEDMA					0xca
#define SETFEATURES					0xef


/*=========================================================================
 *        	             I/O configuration address
 *=========================================================================
 */

#define PCCARD_CONFIG_OPTION	(PCCARD_ATT_BASE + 0x200)
#define PCCARD_CONFIG_STATUS	(PCCARD_ATT_BASE + 0x202)
#define PCCARD_CONFIG_REPLACE	(PCCARD_ATT_BASE + 0x200)
#define PCCARD_CONFIG_SOCKET	(PCCARD_ATT_BASE + 0x200)


/*=========================================================================
 *          	          PC card ATA Register Address
 *=========================================================================
 */

static unsigned int PCCARD_DATA =    	(PCCARD_MEM_BASE + 0x00);
//static unsigned int PCCARD_ERROR =       (PCCARD_MEM_BASE + 0x01);
static unsigned int PCCARD_FEATURE =     (PCCARD_MEM_BASE + 0x01);
static unsigned int PCCARD_SECTOR =      (PCCARD_MEM_BASE + 0x02);
static unsigned int PCCARD_LOWLBA =      (PCCARD_MEM_BASE + 0x03);
static unsigned int PCCARD_MIDLBA =      (PCCARD_MEM_BASE + 0x04);
static unsigned int PCCARD_HIGHLBA =     (PCCARD_MEM_BASE + 0x05);
static unsigned int PCCARD_DEVICE =      (PCCARD_MEM_BASE + 0x06);
static unsigned int PCCARD_STATUS =      (PCCARD_MEM_BASE + 0x07);
static unsigned int PCCARD_COMMAND =     (PCCARD_MEM_BASE + 0x07);
//static unsigned int PCCARD_DUP_EVEN =	(PCCARD_MEM_BASE + 0x08);
//static unsigned int PCCARD_DUP_ODD =		(PCCARD_MEM_BASE + 0x09);
//static unsigned int PCCARD_DUP_ERR =		(PCCARD_MEM_BASE + 0x0D);
//static unsigned int PCCARD_DUP_FEATURE =	(PCCARD_MEM_BASE + 0x0D);
//static unsigned int PCCARD_ALTANATE =    (PCCARD_MEM_BASE + 0x0E);
//static unsigned int PCCARD_CONTROL =     (PCCARD_MEM_BASE + 0x0E);
//static unsigned int PCCARD_DRV_ADDR =	(PCCARD_MEM_BASE + 0x0F);


//=========================================================================
//          	          PCCARD Functions
//=========================================================================

bool ChangePccardMode(unsigned int mode)
{
	if (mode == PCCARD_IO_MODE1) 
	{
		PCCARD_DATA =		(PCCARD_IO_BASE + 0x00);
//		PCCARD_ERROR =      (PCCARD_IO_BASE + 0x01);
		PCCARD_FEATURE =    (PCCARD_IO_BASE + 0x01);
		PCCARD_SECTOR =     (PCCARD_IO_BASE + 0x02);
		PCCARD_LOWLBA =     (PCCARD_IO_BASE + 0x03);
		PCCARD_MIDLBA =     (PCCARD_IO_BASE + 0x04);
		PCCARD_HIGHLBA =    (PCCARD_IO_BASE + 0x05);
		PCCARD_DEVICE =     (PCCARD_IO_BASE + 0x06);
		PCCARD_STATUS =     (PCCARD_IO_BASE + 0x07);
		PCCARD_COMMAND =    (PCCARD_IO_BASE + 0x07);
//		PCCARD_DUP_EVEN =	(PCCARD_IO_BASE + 0x08);
//		PCCARD_DUP_ODD =	(PCCARD_IO_BASE + 0x09);
//		PCCARD_DUP_ERR =	(PCCARD_IO_BASE + 0x0D);
//		PCCARD_DUP_FEATURE =(PCCARD_IO_BASE + 0x0D);
//		PCCARD_ALTANATE =   (PCCARD_IO_BASE + 0x0E);
//		PCCARD_CONTROL =    (PCCARD_IO_BASE + 0x0E);		
//		PCCARD_DRV_ADDR =	(PCCARD_IO_BASE + 0x0F);		

		Outp8(PCCARD_CONFIG_OPTION, PCCARD_IO_MODE1);
	}
	else if (mode == PCCARD_IO_MODE2) 
	{
		PCCARD_DATA =		(PCCARD_IO_BASE + 0x1F0);
		//PCCARD_ERROR =      (PCCARD_IO_BASE + 0x1F1);
		PCCARD_FEATURE =    (PCCARD_IO_BASE + 0x1F1);
		PCCARD_SECTOR =     (PCCARD_IO_BASE + 0x1F2);
		PCCARD_LOWLBA =     (PCCARD_IO_BASE + 0x1F3);
		PCCARD_MIDLBA =     (PCCARD_IO_BASE + 0x1F4);
		PCCARD_HIGHLBA =    (PCCARD_IO_BASE + 0x1F5);
		PCCARD_DEVICE =     (PCCARD_IO_BASE + 0x1F6);
		PCCARD_STATUS =     (PCCARD_IO_BASE + 0x1F7);
		PCCARD_COMMAND =    (PCCARD_IO_BASE + 0x1F7);
		//PCCARD_ALTANATE =   (PCCARD_IO_BASE + 0x3F6);
		//PCCARD_DRV_ADDR =	(PCCARD_IO_BASE + 0x3F7);		

		Outp8(PCCARD_CONFIG_OPTION, PCCARD_IO_MODE2);
	}
	else if (mode == PCCARD_IO_MODE3) 
	{
		PCCARD_DATA =		(PCCARD_IO_BASE + 0x170);
		//PCCARD_ERROR =      (PCCARD_IO_BASE + 0x171);
		PCCARD_FEATURE =    (PCCARD_IO_BASE + 0x171);
		PCCARD_SECTOR =     (PCCARD_IO_BASE + 0x172);
		PCCARD_LOWLBA =     (PCCARD_IO_BASE + 0x173);
		PCCARD_MIDLBA =     (PCCARD_IO_BASE + 0x174);
		PCCARD_HIGHLBA =    (PCCARD_IO_BASE + 0x175);
		PCCARD_DEVICE =     (PCCARD_IO_BASE + 0x176);
		PCCARD_STATUS =     (PCCARD_IO_BASE + 0x177);
		PCCARD_COMMAND =    (PCCARD_IO_BASE + 0x177);
		//PCCARD_ALTANATE =   (PCCARD_IO_BASE + 0x376);
		//PCCARD_DRV_ADDR =	(PCCARD_IO_BASE + 0x377);		
 		Outp8(PCCARD_CONFIG_OPTION, PCCARD_IO_MODE3);
	}
	else // defualt PCCARD_MEM_MODE
	{
		PCCARD_DATA =		(PCCARD_MEM_BASE + 0x00);
		//PCCARD_ERROR =      (PCCARD_MEM_BASE + 0x01);
		PCCARD_FEATURE =    (PCCARD_MEM_BASE + 0x01);
		PCCARD_SECTOR =     (PCCARD_MEM_BASE + 0x02);
		PCCARD_LOWLBA =     (PCCARD_MEM_BASE + 0x03);
		PCCARD_MIDLBA =     (PCCARD_MEM_BASE + 0x04);
		PCCARD_HIGHLBA =    (PCCARD_MEM_BASE + 0x05);
		PCCARD_DEVICE =     (PCCARD_MEM_BASE + 0x06);
		PCCARD_STATUS =     (PCCARD_MEM_BASE + 0x07);
		PCCARD_COMMAND =    (PCCARD_MEM_BASE + 0x07);
		//PCCARD_DUP_EVEN =	(PCCARD_MEM_BASE + 0x08);
		//PCCARD_DUP_ODD =	(PCCARD_MEM_BASE + 0x09);
		//PCCARD_DUP_ERR =	(PCCARD_MEM_BASE + 0x0D);
		//PCCARD_DUP_FEATURE =(PCCARD_MEM_BASE + 0x0D);
		//PCCARD_ALTANATE =   (PCCARD_MEM_BASE + 0x0E);
		//PCCARD_CONTROL =    (PCCARD_MEM_BASE + 0x0E);				
		//PCCARD_DRV_ADDR =	(PCCARD_MEM_BASE + 0x0F);				

		Outp8(PCCARD_CONFIG_OPTION, PCCARD_MEM_MODE);
	}
	return TRUE;	
}

bool OpenPccardMediaWithMode(unsigned int mode)
{	
	// TDelay timer setting
	SetResTDelay(10); // TDelay 1 unit = 10us
	InitTDelayFunc();

	// GPIO, EBI setting
	rEBICON |= (1<<10)|(1<<9); // bank3_cfg->CF,bank2_cfg->CF 
    rGPGCON |= (3<<30)|(3<<28)|(3<<26)|(3<<24)|(3<<22); //nCARD_PWREN, RESET_CF,nRE3G_CF,nINPACK,nIREQ_CF
#ifdef __EVT1
	//rGPACDH = 0x1aa8a; // GPA10 RDATA_OEN setting
#else
	rGPACON |= (1<<27)|(1<<11)|(1<<14)|(1<<13);// nWE_CF,nOE_CF,nRCS3,nRCS2 enable //S3C2443X01
#endif
	rMISCCR &=(~(1<<30)); // card detect when card is detected ,the bit should be '0'.
	
	// Buffer direction mode setting for SMDK2443 061027
	rGPBCON = rGPBCON & ~((3<<8)|(3)) | (1<<8)|(1); // GPB0,4 output setting (TOUT0, TCLK - TP21,20)
	rGPBDAT &= ~((1<<4)|(1)); // GPB0,4 -> low => pc card mode
	
	// CF controller - PC card mode setting
	Outp32(ATA_MUX, 0x06); 	// Output pad disable, Card power off, PC card mode
	TDelay(100);
	Outp32(ATA_MUX, 0x02); 	// Output pad enable, Card power off, PC card mode
	TDelay(100);
	Outp32(ATA_MUX, 0x00); 	// Card Power on (PC Card mode)
	// wait for at least 20ms (SanDisk: 25ms, MicroDrive: 125ms, Hagiwara: )
	// No other method available.
	TDelay(12500); // 125ms

	// Card configuration
	rPCCARD_CFG = (1<<11)|(1<<10)|(1<<9)|(1<<8); // wain en, attr mem 16bit, com mem 16bit, IO 16bit
    rPCCARD_INT = (1<<10)|(1<<9)|(1<<8); // mask ERR, IREQ, CD
    rPCCARD_ATTR = (3<<16)|(0x19<<8)|(9); // Timing Hold, Command, Setup in attr mem mode
    rPCCARD_IO = (3<<16)|(0x19<<8)|(9); // Timing Hold, Command, Setup in IO mode
    rPCCARD_COMM = (3<<16)|(0x19<<8)|(9); // Timing Hold, Command, Setup in comm mem mode
	
	// Card reset
	rPCCARD_CFG |= (1<<13);
	TDelay(100); // 1ms
	rPCCARD_CFG &= ~(1<<13);
	TDelay(10000); // 100ms

	// Change access mode
	ChangePccardMode(mode);
	
	return TRUE;
}

bool ClosePccardMedia(void)
{
	// Output pad disable, Card power off, PC card mode
	Outp32(ATA_MUX, 0x06);
	
	return TRUE;
}

void GetAttribData(unsigned int index, unsigned char *data)
{
	Inp8(PCCARD_ATT_BASE+index, *data);
}

void ReadPccardRegister(unsigned int nRegister, unsigned char *data)
{
	Inp8(nRegister, *data);
}

void WritePccardRegister(unsigned int nRegister, unsigned char nValue)
{
	unsigned char temp;
	do
	{
		ReadPccardRegister(PCCARD_STATUS, &temp);
	} while (temp == 0x80) ;
	Outp8(nRegister, nValue);
	DbgPccard(("reg addr : 0x%x\n", nRegister));
}

void PutDataToPccardDevice(unsigned short nData)
{
	Outp16(PCCARD_DATA, nData);
}

void GetDataFromPccardDevice(unsigned short *uData)
{
	Inp16(PCCARD_DATA, *uData);

}

bool ReadBlocks(unsigned int uStBlock, unsigned int uBlocks, unsigned int uBufAddr)
{
	// uBlocks: sector count
	// uLba:     (head&0x0f)<<24 | (LBA_high<<16) | (LBA_mid<<8) | LBA_low
	// uDstAddr:    host address
	
	unsigned char temp;
	unsigned short* uCurrentAddr = (unsigned short*) uBufAddr;
    unsigned int i,j;
    
	unsigned int op_time=0;
#if PERF_TEST_PCCARD	
	SetResStopwatch(10000); // us order, 10000us = 10ms
	StartStopwatch(); // Start timer
#endif

	WritePccardRegister(PCCARD_FEATURE,0);
	WritePccardRegister(PCCARD_SECTOR,uBlocks);
	WritePccardRegister(PCCARD_LOWLBA,(uStBlock&0x00ff));
	WritePccardRegister(PCCARD_MIDLBA,((uStBlock>>8)&0x00ff));
	WritePccardRegister(PCCARD_HIGHLBA,((uStBlock>>16)&0x00ff));
	WritePccardRegister(PCCARD_DEVICE,((uStBlock>>24)&0x000f) | 0xe0);  //LBA enabled, Drive 0

#ifdef DBG_PCCARD
	ReadPccardRegister(PCCARD_SECTOR,&temp);
	printf("Sector W:0x%x, R:0x%x\n",uBlocks,temp);
	ReadPccardRegister(PCCARD_LOWLBA,&temp);
	printf("lLBA W:0x%x, R:0x%x\n",(uStBlock&0x00ff),temp);
	ReadPccardRegister(PCCARD_MIDLBA,&temp);
	printf("mLBA W:0x%x, R:0x%x\n",((uStBlock>>8)&0x00ff),temp);
	ReadPccardRegister(PCCARD_HIGHLBA,&temp);
	printf("hLBA W:0x%x, R:0x%x\n",((uStBlock>>16)&0x00ff),temp);
	ReadPccardRegister(PCCARD_DEVICE,&temp);  //LBA enabled, Drive 0
	printf("device W:0x%x, R:0x%x\n",((uStBlock>>24)&0x000f) | 0xe0,temp);
#endif

	WritePccardRegister(PCCARD_COMMAND, READSECTOR);

	do
	{
		ReadPccardRegister(PCCARD_STATUS, &temp);
		TDelay(1);  // need over 25MHz
		DbgPccard(("(0x%x) ",temp));
	}
	while(temp != 0x58) ;


#if PERF_TEST_PCCARD_D
	SetResStopwatch(10000); // us order, 10000us = 10ms
	StartStopwatch(); // Start timer
#endif

	for (j=0; j<uBlocks; j++)
	{
		for (i=0; i<512/2; i++)
		{
#if 1	// both case are OK	
			GetDataFromPccardDevice(uCurrentAddr);
#else
			Inp16(PCCARD_BASE+0x400+i*2, *uCurrentAddr);
#endif
			uCurrentAddr++;
		}

		do
		{
			ReadPccardRegister(PCCARD_STATUS, &temp);
			TDelay(1); // need over 25MHz
			DbgPccard(("{0x%x} ",temp));
		}
		while(temp != 0x50 && temp != 0x58);

	}

#if PERF_TEST_PCCARD | PERF_TEST_PCCARD_D
	op_time = EndStopwatch(); 	   // end timer, us order
	printf (" Reading time : %d us, Performance : %lf MByte/sec\n"
			,op_time,(float)(uBlocks*512./op_time));	
#endif

	return TRUE;
}
   

bool WriteBlocks(unsigned int uStBlock, unsigned int uBlocks, unsigned int uBufAddr)
{
	unsigned char temp;
	unsigned short* uCurrentAddr = (unsigned short*) uBufAddr;
	unsigned int i,j;
	
	unsigned int op_time=0;
#if PERF_TEST_PCCARD	
	SetResStopwatch(10000); // us order, 10000us = 10ms
	StartStopwatch(); // Start timer
#endif

	// uBlocks: sector count
	// uLba:     (head&0x0f)<<24 | (LBA_high<<16) | (LBA_mid<<8) | LBA_low
	// uSrcAddr:    host address
	WritePccardRegister(PCCARD_FEATURE,0);
	WritePccardRegister(PCCARD_SECTOR,uBlocks);
	WritePccardRegister(PCCARD_LOWLBA,(uStBlock&0x00ff));
	WritePccardRegister(PCCARD_MIDLBA,((uStBlock>>8)&0x00ff));
	WritePccardRegister(PCCARD_HIGHLBA,((uStBlock>>16)&0x00ff));
	WritePccardRegister(PCCARD_DEVICE,((uStBlock>>24)&0x000f) | 0xe0);  //LBA enabled, Drive 0

#ifdef DBG_PCCARD
	ReadPccardRegister(PCCARD_SECTOR,&temp);
	printf("Sector W:0x%x, R:0x%x\n",uBlocks,temp);
	ReadPccardRegister(PCCARD_LOWLBA,&temp);
	printf("lLBA W:0x%x, R:0x%x\n",(uStBlock&0x00ff),temp);
	ReadPccardRegister(PCCARD_MIDLBA,&temp);
	printf("mLBA W:0x%x, R:0x%x\n",((uStBlock>>8)&0x00ff),temp);
	ReadPccardRegister(PCCARD_HIGHLBA,&temp);
	printf("hLBA W:0x%x, R:0x%x\n",((uStBlock>>16)&0x00ff),temp);
	ReadPccardRegister(PCCARD_DEVICE,&temp);  //LBA enabled, Drive 0
	printf("device W:0x%x, R:0x%x\n",((uStBlock>>24)&0x000f) | 0xe0,temp);
#endif

	WritePccardRegister(PCCARD_COMMAND, WRITESECTOR);

	do
	{
		ReadPccardRegister(PCCARD_STATUS, &temp);
		TDelay(1);  // need over 25MHz
		DbgPccard(("[0x%x] ",temp));
	}
	while(temp != 0x58) ;   	


#if PERF_TEST_PCCARD_D
	SetResStopwatch(10000); // us order, 10000us = 10ms
	StartStopwatch(); // Start timer
#endif

	for (j=0; j<uBlocks; j++)
	{
		for (i=0; i<512/2; i++)
		{
#if 1	// both case are OK	
			PutDataToPccardDevice(*uCurrentAddr);	
#else
			Outp16(PCCARD_BASE+0x400+i*2, *uCurrentAddr);
#endif
			uCurrentAddr++;
		}

		do
		{
			ReadPccardRegister(PCCARD_STATUS, &temp);
			TDelay(1); // need over 25MHz
			DbgPccard(("|0x%x| ",temp));
		}
		while(temp != 0x50 && temp != 0x58) ;

	}

#if PERF_TEST_PCCARD | PERF_TEST_PCCARD_D
	op_time = EndStopwatch(); 	   // end timer, us order
	printf (" Writing time : %d us, Performance : %lf MByte/sec\n"
			,op_time,(float)(uBlocks*512./op_time));	
#endif

	return TRUE;
}

⌨️ 快捷键说明

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