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

📄 pccard.c

📁 s3c6400 ADS下官方测试程序
💻 C
📖 第 1 页 / 共 3 页
字号:
void PCCARD_ReadBlocks(u8 ucCon, u32 uDeviceLba, u32 uBlockCount, u32 uBufAddr)
{
	u8		ucTaskFileRegValue 	= 0;
	u32		uBlockLoopCount		= 0;
	u32		uByteLoopCount		= 0;
	u16*	usCurrBufAddr		= (u16*) g_oaPCCARDInform[ucCon].puPCCARDReadBuf;
	u16		usReadData			= 0;

//	Disp("uDeviceLab : 0x%x, uBlockCount : 0x%x\n", uDeviceLba, uBlockCount);
#if PERF_TEST_PCCARD	
	u32			uElapsedTime = 0;
#endif
	
	//-------- step 1. Set up task file registers ------------
	// uBlocks: sector count
	// uLba:     (head&0x0f)<<24 | (LBA_high<<16) | (LBA_mid<<8) | LBA_low
	// uSrcAddr:    host address
	PCCARD_SetTaskFileRegValue(ucCon, eCF_TASKFILE_FEATURE, 0);
	PCCARD_SetTaskFileRegValue(ucCon, eCF_TASKFILE_SECTOR,	uBlockCount);
	PCCARD_SetTaskFileRegValue(ucCon, eCF_TASKFILE_LOWLBA,	(uDeviceLba&0xff));
	PCCARD_SetTaskFileRegValue(ucCon, eCF_TASKFILE_MIDLBA,	((uDeviceLba>>  8)&0xff));
	PCCARD_SetTaskFileRegValue(ucCon, eCF_TASKFILE_HIGHLBA,	((uDeviceLba>>16)&0xff));
	PCCARD_SetTaskFileRegValue(ucCon, eCF_TASKFILE_DEVICE,	((uDeviceLba>>24)&0x0f) | 0xe0);	//LBA enabled, Drive 0
#ifdef DBG_PCCARD
	ucTaskFileRegValue = PCCARD_GetTaskFileRegValue(ucCon, eCF_TASKFILE_SECTOR);
	printf("Sector W:0x%x, R:0x%x\n",uBlockCount,ucTaskFileRegValue);
	ucTaskFileRegValue = PCCARD_GetTaskFileRegValue(ucCon, eCF_TASKFILE_LOWLBA);
	printf("lLBA W:0x%x, R:0x%x\n",(uDeviceLba&0x00ff),ucTaskFileRegValue);
	ucTaskFileRegValue = PCCARD_GetTaskFileRegValue(ucCon, eCF_TASKFILE_MIDLBA);
	printf("mLBA W:0x%x, R:0x%x\n",((uDeviceLba>>8)&0x00ff),ucTaskFileRegValue);
	ucTaskFileRegValue = PCCARD_GetTaskFileRegValue(ucCon, eCF_TASKFILE_HIGHLBA);
	printf("hLBA W:0x%x, R:0x%x\n",((uDeviceLba>>16)&0x00ff),ucTaskFileRegValue);
	ucTaskFileRegValue = PCCARD_GetTaskFileRegValue(ucCon, eCF_TASKFILE_DEVICE);
	printf("device W:0x%x, R:0x%x\n",((uDeviceLba>>24)&0x000f) | 0xe0,ucTaskFileRegValue);
#endif

	//-------- step 2. Set '0x30(eATA_CMD_WRITESECTOR)' in the command register of task file registers ------------
	PCCARD_SetTaskFileRegValue(ucCon, eCF_TASKFILE_COMMAND,	eATA_CMD_READSECTOR );

	//-------- step 3. Read status register & compare with '0x58'  ------------
	//  0x58 : Data of device side is ready. The host should not write the command register when 0x58. (DRQ = 1)
	do
	{
		ucTaskFileRegValue = PCCARD_GetTaskFileRegValue(ucCon, eCF_TASKFILE_STATUS);
		Delay(1); // need over 25MHz
//		Disp("[STATUS:0x%x]\n", ucTaskFileRegValue);
	}
	while( ucTaskFileRegValue != 0x58) ;
	
#if PERF_TEST_PCCARD	
	StartTimer(0);
#endif
	//-------- step 4. Writes the data register until 256 times(512bytes) ------------
	// Note. We can transfer data in 16bit mode because PCCARD_DATA register is overlapped to the PCCARD_ERROR register.
	for ( uBlockLoopCount = 0; uBlockLoopCount < uBlockCount; uBlockLoopCount++ )
	{
		for ( uByteLoopCount = 0; uByteLoopCount <  (512/2); uByteLoopCount++ )
		{
			usReadData = PCCARD_GetTaskFileRegValue16(ucCon, eCF_TASKFILE_DATA);
//			printf("BufADDR:0x%x, Data : 0x%x\n", usCurrBufAddr, usReadData);
			*usCurrBufAddr =  usReadData;
			usCurrBufAddr++;
		}
		
		//-------- step 3. Read status register & compare with '0x50'  ------------
		do
		{
			ucTaskFileRegValue = PCCARD_GetTaskFileRegValue(ucCon, eCF_TASKFILE_STATUS);
			Delay(1); // need over 25MHz
//			Disp("[STATUS:0x%x]\n", ucTaskFileRegValue);
		}
		while( ucTaskFileRegValue != 0x50 && ucTaskFileRegValue != 0x58 ) ;
	}
#if PERF_TEST_PCCARD
	uElapsedTime = StopTimer(0);
	Disp(" PCCard Mode Reading time : %d us, Performance : %lf MByte/sec\n"
			,uElapsedTime,(float)(uBlockCount*512./uElapsedTime));
#endif	
}

//////////
// Function Name : PCCARD_WriteBlocks
// Function Description : This function implements block write function to PCCARD TaskFile Registers.
// Input : 	ucCon		- PCCRAD controller number
//			uDeviceLba	- LBA number
//			uBlockCount	- Block number
//			uBufAddr		- Buffer Address
// Output : 	NONE
// Version : v0.1
void PCCARD_WriteBlocks(u8 ucCon, u32 uDeviceLba, u32 uBlockCount, u32 uBufAddr)
{
	u8		ucTaskFileRegValue 	= 0;
	u32		uBlockLoopCount		= 0;
	u32		uByteLoopCount		= 0;
	u16*	usCurrBufAddr		= (u16*) g_oaPCCARDInform[ucCon].puPCCARDWriteBuf;

//	Disp("uDeviceLab : 0x%x, uBlockCount : 0x%x\n", uDeviceLba, uBlockCount);
#if PERF_TEST_PCCARD	
	u32			uElapsedTime = 0;
#endif
	//-------- step 1. Set up task file registers ------------
	// uBlocks: sector count
	// uLba:     (head&0x0f)<<24 | (LBA_high<<16) | (LBA_mid<<8) | LBA_low
	// uSrcAddr:    host address
	PCCARD_SetTaskFileRegValue(ucCon, eCF_TASKFILE_FEATURE, 0);
	PCCARD_SetTaskFileRegValue(ucCon, eCF_TASKFILE_SECTOR,	uBlockCount);
	PCCARD_SetTaskFileRegValue(ucCon, eCF_TASKFILE_LOWLBA,	(uDeviceLba&0xff));
	PCCARD_SetTaskFileRegValue(ucCon, eCF_TASKFILE_MIDLBA,	((uDeviceLba>>  8)&0xff));
	PCCARD_SetTaskFileRegValue(ucCon, eCF_TASKFILE_HIGHLBA,	((uDeviceLba>>16)&0xff));
	PCCARD_SetTaskFileRegValue(ucCon, eCF_TASKFILE_DEVICE,	((uDeviceLba>>24)&0x0f) | 0xe0);	//LBA enabled, Drive 0

#ifdef DBG_PCCARD
	ucTaskFileRegValue = PCCARD_GetTaskFileRegValue(ucCon, eCF_TASKFILE_SECTOR);
	printf("Sector W:0x%x, R:0x%x\n",uBlockCount,ucTaskFileRegValue);
	ucTaskFileRegValue = PCCARD_GetTaskFileRegValue(ucCon, eCF_TASKFILE_LOWLBA);
	printf("lLBA W:0x%x, R:0x%x\n",(uDeviceLba&0x00ff),ucTaskFileRegValue);
	ucTaskFileRegValue = PCCARD_GetTaskFileRegValue(ucCon, eCF_TASKFILE_MIDLBA);
	printf("mLBA W:0x%x, R:0x%x\n",((uDeviceLba>>8)&0x00ff),ucTaskFileRegValue);
	ucTaskFileRegValue = PCCARD_GetTaskFileRegValue(ucCon, eCF_TASKFILE_HIGHLBA);
	printf("hLBA W:0x%x, R:0x%x\n",((uDeviceLba>>16)&0x00ff),ucTaskFileRegValue);
	ucTaskFileRegValue = PCCARD_GetTaskFileRegValue(ucCon, eCF_TASKFILE_DEVICE);
	printf("device W:0x%x, R:0x%x\n",((uDeviceLba>>24)&0x000f) | 0xe0,ucTaskFileRegValue);
#endif

	//-------- step 2. Set '0x30(eATA_CMD_WRITESECTOR)' in the command register of task file registers ------------
	PCCARD_SetTaskFileRegValue(ucCon, eCF_TASKFILE_COMMAND,	eATA_CMD_WRITESECTOR );

	//-------- step 3. Read status register & compare with '0x58'  ------------
	//  0x58 : Data of device side is ready. The host should not write the command register when 0x58. (DRQ = 1)
	do
	{
		ucTaskFileRegValue = PCCARD_GetTaskFileRegValue(ucCon, eCF_TASKFILE_STATUS);
		Delay(1); // need over 25MHz
		Disp("[STATUS:0x%x]\n", ucTaskFileRegValue);
	}
	while( ucTaskFileRegValue != 0x58) ;

#if PERF_TEST_PCCARD	
	StartTimer(0);
#endif

	//-------- step 4. Writes the data register until 256 times(512bytes) ------------
	// Note. We can transfer data in 16bit mode because PCCARD_DATA register is overlapped to the PCCARD_ERROR register.
	for ( uBlockLoopCount = 0; uBlockLoopCount < uBlockCount; uBlockLoopCount++ )
	{
		for ( uByteLoopCount = 0; uByteLoopCount <  (512/2); uByteLoopCount++ )
		{
			PCCARD_SetTaskFileRegValue16(ucCon, eCF_TASKFILE_DATA,	*usCurrBufAddr );
//			printf("BufADDR:0x%x\n", usCurrBufAddr);
			usCurrBufAddr++;
		}
		
		//-------- step 3. Read status register & compare with '0x50'  ------------
		do
		{
			ucTaskFileRegValue = PCCARD_GetTaskFileRegValue(ucCon, eCF_TASKFILE_STATUS);
			Delay(1); // need over 25MHz
//			Disp("[STATUS:0x%x]\n", ucTaskFileRegValue);
		}
		while( ucTaskFileRegValue != 0x50 && ucTaskFileRegValue != 0x58 ) ;
	}
#if PERF_TEST_PCCARD
	uElapsedTime = StopTimer(0);
	Disp(" PCCard Mode Writing time : %d us, Performance : %lf MByte/sec\n"
			,uElapsedTime,(float)(uBlockCount*512./uElapsedTime));
#endif
	
	
}
//=========================================================================
//					          	          ATTRIBUTE MEMORY AREA
//=========================================================================
/*---------------------------------- APIs of controling Attribute memory area in PCCARD mode  ---------------------------------*/
//////////
// Function Name : PCCARD_SetAttConfigBaseAddr
// Function Description : This function sets up the base address of PCCARD Attribute Configuration Registers.
// Input : 	ucCon		- PCCRAD controller number
// Output : 	uBaseAddress	- the baseaddress of PCCARD Task File registers
// Version : v0.1
void PCCARD_SetAttConfigBaseAddr(u8 ucCon, u32 uBaseAddress)
{
	g_paPCCARDATTBase[ucCon] = (void *)uBaseAddress;
}

//////////
// Function Name : PCCARD_SetCardMode
// Function Description : 
//   This function changes CF CARD mode.
// Input : 	ucCon 		- PCCARD Controller Number 
//			ePccardAttId	- Attribute configuration register select
//			ePccardMode	-MEM/IO1/IO2/IO3 mode select
// Output : NONE
// Version : v0.1 
void PCCARD_SetCardMode(u8 ucCon, u8 ucPccardAttIdOffset, ePCCARD_MODE ePccardMode)
{
	u8		uRegValue = 0;

	uRegValue = PCCARD_GetAttRegValue(ucCon, ucPccardAttIdOffset);
	uRegValue = uRegValue & ~(0x3f<< 0 ) | (ePccardMode<<0);		

	PCCARD_SetAttRegValue(ucCon, ucPccardAttIdOffset, uRegValue);	
}

//////////
// Function Name : PCCARD_GetAttRegValue
// Function Description : This function gets the value of PCCARD Registers.
// Input : 	ucCon					- PCCRAD controller number
//			uPCCARDAttRegId			- the Id of PCCARD Attribute Configuration Register
// Output : 	*puPCCARDReg			- the value of specified register
// Version : v0.1
u8 PCCARD_GetAttRegValue(u8 ucCon, u8 uPCCARDAttRegIdOffset)
{
	volatile u16 *	puPCCARDAttBaseAddr;
	volatile u16 *	puPCCARDReg;	

	puPCCARDAttBaseAddr			= &(PCCARD_ATTR(ucCon)->rPCCARD_CONFIG_OPTION);
	puPCCARDReg				= puPCCARDAttBaseAddr + uPCCARDAttRegIdOffset;

	return (u8)(*puPCCARDReg);	
}

//////////
// Function Name : PCCARD_SetAttRegValue
// Function Description : This function clears the value of PCCARD TaskFile Registers.
// Input : 	ucCon			- PCCRAD controller number
//			ucPCCARDRegId	- the Id of PCCARD Registers
//			uValue			- the value of register
// Output : 	NONE
// Version : v0.1
void PCCARD_SetAttRegValue(u8 ucCon, u8 uPCCARDAttRegIdOffset, u8 uValue)
{
	volatile u16 *	puPCCARDAttBaseAddr;
	volatile u16 *	puPCCARDReg;	

	puPCCARDAttBaseAddr		= &(PCCARD_ATTR(ucCon)->rPCCARD_CONFIG_OPTION);
	puPCCARDReg			= puPCCARDAttBaseAddr + uPCCARDAttRegIdOffset;

	*puPCCARDReg			= uValue;
}

//////////
// Function Name : PCCARD_GetAttribData
// Function Description : This function gets the value of PCCARD Registers.
// Input : 	ucCon		- PCCRAD controller number
//			uIndex		- the Index of PCCARD Attribute Memory
// Output : 	*puPCCARDReg			- the value of specified register
// Version : v0.1
u8 PCCARD_GetAttribData(u8 ucCon, u8 uIndex)
{
	volatile u16 *	puPCCARDAttBaseAddr;
	volatile u16 *	puPCCARDReg;	

	puPCCARDAttBaseAddr			= &(PCCARD_ATTR(ucCon)->rPCCARD_CONFIG_OPTION);
	puPCCARDAttBaseAddr			-= 0x100;
	puPCCARDReg				= puPCCARDAttBaseAddr + uIndex;
//	printf("uIndex:0x%x, BaseAddr:0x%x, DestAddr:0x%x\n", uIndex, puPCCARDAttBaseAddr, puPCCARDReg);
	return (u8)(*puPCCARDReg);
}

//////////
// Function Name : PCCARD_SetAttribData
// Function Description : This function clears the value of PCCARD TaskFile Registers.
// Input : 	ucCon		- PCCRAD controller number
//			uIndex		- the Index of PCCARD Attribute Memory
//			uValue		- the value of register
// Output : 	NONE
// Version : v0.1
void PCCARD_SetAttribData(u8 ucCon, u8 uIndex, u8 uValue)
{
	volatile u16 *	puPCCARDAttBaseAddr;
	volatile u8 *	puPCCARDReg;	

	puPCCARDAttBaseAddr		= &(PCCARD_ATTR(ucCon)->rPCCARD_CONFIG_OPTION);
	puPCCARDAttBaseAddr		-= 0x100;
	puPCCARDReg			= (u8 *)puPCCARDAttBaseAddr + uIndex;

	*puPCCARDReg			= uValue;
}



⌨️ 快捷键说明

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