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

📄 ata.c

📁 s3c6400 ADS下官方测试程序
💻 C
📖 第 1 页 / 共 5 页
字号:

		/*Source Buffer 1 Setting*/
		ATA_SetSBufStart( ucCon, uCurrentSrcAddr);
		ATA_SetSBufSize( ucCon, uCurrentCount*ATA_SECTORSIZE);
		ATA_SetXfrNum(ucCon, uCurrentCount*ATA_SECTORSIZE);
		
		ATA_SetDevicePosition(ucCon, uCurrentLba, uCurrentCount);
		ATA_SetTaskFileRegValue(ucCon, eCF_TASKFILE_COMMAND, ATA_CMD_WRITEDMA);

		ATA_WaitForDeviceReady(ucCon);
		ATA_SetConfig(ucCon, eATA_MODE_UDMA, eATA_DMA_WRITE_DATA);

#if PERF_TEST_UDMA	
	StartTimer(1);
#endif

		/*ATA Transfer Command */
		ATA_SetTransferCommand(ucCon, eATA_XFR_CMD_START);
		ATA_WaitForTransferDone(ucCon);

		ATA_SetTransferCommand(ucCon, eATA_XFR_CMD_ABORT);
#if PERF_TEST_UDMA
	uElapsedTime += StopTimer(1);
#endif

		ATA_SetConfig(ucCon, eATA_MODE_PIOCPU, eATA_DMA_WRITE_DATA);
		ATA_WaitForDeviceReady(ucCon);

		ATA_SetUdmaAutoMode(ucCon, DISABLE);

		uRound++;
	}

#if PERF_TEST_UDMA
	Disp(" UDMA Writing time : %d us, Performance : %lf MByte/sec\n"
			,uElapsedTime,(float)(uSectorCount*512./uElapsedTime));
#endif

	return TRUE;
}

//////////
// Function Name : ATA_ReadSectors_UDMA
// Function Description : This function writes sector data to device in UDMA mode.
// Input : 	ucCon - ATA Controller Number
//			uLBA 		- LBA Block
//			uSectorCount	- Sector Count
//			uSrcAddress	- Address of Buffer
// Output : 	true/false
// Version : v0.1
bool ATA_ReadSectors_UDMA(u8 ucCon, u32 uLBA, u32 uSectorCount, u32 uDstAddress)
{
	u32 uCurrentCount;
	u32 uRemainderCount;
	u32 uCurrentLba;
	u32 uCurrentDstAddr;
	u32 uRound;

#if PERF_TEST_UDMA	
	u32			uElapsedTime = 0;
#endif

	uRemainderCount = uSectorCount;
	uRound = 0;	
	
	while(uRemainderCount != 0) {
		if(uRemainderCount>256) {
			uCurrentCount = 256; //0 means 256
			uRemainderCount -= 256;
		} else {
			uCurrentCount = uRemainderCount;
			uRemainderCount = 0;
		}
		uCurrentLba = uLBA + uRound*256;
		uCurrentDstAddr = uDstAddress + uRound*256*ATA_SECTORSIZE;

		/*Source Buffer 1 Setting*/
		ATA_SetTBufStart( ucCon, uCurrentDstAddr);
		ATA_SetTBufSize( ucCon, uCurrentCount*ATA_SECTORSIZE);
		ATA_SetXfrNum(ucCon, uCurrentCount*ATA_SECTORSIZE);
		
		ATA_SetDevicePosition(ucCon, uCurrentLba, uCurrentCount);
		ATA_SetTaskFileRegValue(ucCon, eCF_TASKFILE_COMMAND, ATA_CMD_READDMA);

		ATA_WaitForDeviceReady(ucCon);
		ATA_SetConfig(ucCon, eATA_MODE_UDMA, eATA_DMA_READ_DATA);

#if PERF_TEST_UDMA	
	StartTimer(1);
#endif

		/*ATA Transfer Command */
		ATA_SetTransferCommand(ucCon, eATA_XFR_CMD_START);

		ATA_WaitForTransferDone(ucCon);	// Host

		ATA_SetTransferCommand(ucCon, eATA_XFR_CMD_ABORT);

#if PERF_TEST_UDMA
	uElapsedTime += StopTimer(1);
#endif

		ATA_SetConfig(ucCon, eATA_MODE_PIOCPU, eATA_DMA_READ_DATA);
		ATA_WaitForDeviceReady(ucCon);

		ATA_SetUdmaAutoMode(ucCon, DISABLE);

		uRound++;
	}

#if PERF_TEST_UDMA
	Disp(" UDMA Reading time : %d us, Performance : %lf MByte/sec\n"
			,uElapsedTime,(float)(uSectorCount*512./uElapsedTime));
#endif

	return TRUE;
}

void ATA_SetDevicePosition(u8 ucCon, u32 uLba, u32 uSectorCount)
{
	ATA_SetTaskFileRegValue(ucCon, eCF_TASKFILE_SECTOR,	uSectorCount&0xff);	
	ATA_SetTaskFileRegValue(ucCon, eCF_TASKFILE_LOWLBA,	uLba&0xff);
	ATA_SetTaskFileRegValue(ucCon, eCF_TASKFILE_MIDLBA,		(uLba>>8)&0xff);
	ATA_SetTaskFileRegValue(ucCon, eCF_TASKFILE_HIGHLBA,	(uLba>>16)&0xff);
	ATA_SetTaskFileRegValue(ucCon, eCF_TASKFILE_DEVICE,		(uLba>>24)&0xf|0x40);
}


//////////
// Function Name : ATA_StartWritingSectors
// Function Description : This function sets writing function which transfers block data to device.
// Input : 	ucCon - ATA Controller Number
//			uStBlock 		- LBA Block
//			uBlocks		- Block Count
//			uBufAddr		- Buffer Address
// Output : 	true/false
// Version : v0.1
bool ATA_StartWritingSectors(u8 ucCon, u32 uStBlock, u32 uBlocks, u32 uBufAddr)
{
	u32 uDeviceCmd = 0;

//	Disp("uStBlock:%d, uBlocks:%d, uBufAddr:0x%x\n", uStBlock, uBlocks, uBufAddr);
	uDeviceCmd = (g_oaATAInform[ucCon].eAtaMode == eATA_MODE_UDMA) ? ATA_CMD_WRITEDMA : ATA_CMD_WRITESECTOR;

	/*Source Buffer Setting*/
	ATA_SetSBufStart( ucCon, uBufAddr);
	ATA_SetSBufSize( ucCon, uBlocks*ATA_SECTORSIZE);
	ATA_SetXfrNum(ucCon, uBlocks*ATA_SECTORSIZE);

	ATA_SetDevicePosition(ucCon, uStBlock, uBlocks);
	ATA_SetTaskFileRegValue( ucCon, eCF_TASKFILE_COMMAND , uDeviceCmd);

	ATA_WaitForDeviceReady( ucCon);
//	Disp("(");
	ATA_SetConfig(ucCon, g_oaATAInform[ucCon].eAtaMode, eATA_DMA_WRITE_DATA);
//	Disp(")");
#if 1	
	ATA_SetTransferCommand(ucCon, eATA_XFR_CMD_START);

	#if 0	// These lines are only for ATA Bug Test
	for ( uLoopCnt = 0; uLoopCnt < 1000; uLoopCnt++)
	{
		ATA_SetTransferCommand(ucCon, eATA_XFR_CMD_STOP);
		ATA_SetTransferCommand(ucCon, eATA_XFR_CMD_CONTINUE);
	}
	Disp("$");
	#endif
#else
	Set_Ata_Cmd_START();
#endif
	return TRUE;
	
}

//////////
// Function Name : ATA_StartReadingSectors
// Function Description : This function sets reading function which transfers block data from device.
// Input : 	ucCon - ATA Controller Number
//			uStBlock 		- LBA Block
//			uBlocks		- Block Count
//			uBufAddr		- Buffer Address
// Output : 	true/false
// Version : v0.1
bool ATA_StartReadingSectors(u8 ucCon, u32 uStBlock, u32 uBlocks, u32 uBufAddr)
{
	u32 uDeviceCmd = 0;
	
//	Disp("uStBlock:%d, uBlocks:%d, uBufAddr:0x%x\n", uStBlock, uBlocks, uBufAddr);
	uDeviceCmd = (g_oaATAInform[ucCon].eAtaMode == eATA_MODE_UDMA) ? ATA_CMD_READDMA : ATA_CMD_READSECTOR;

	/*Target Buffer Setting*/
	ATA_SetTBufStart( ucCon, uBufAddr);
	ATA_SetTBufSize( ucCon, uBlocks*ATA_SECTORSIZE);
	ATA_SetXfrNum(ucCon, uBlocks*ATA_SECTORSIZE);

	ATA_SetDevicePosition(ucCon, uStBlock, uBlocks);
	ATA_SetTaskFileRegValue( ucCon, eCF_TASKFILE_COMMAND , uDeviceCmd);
	
	ATA_WaitForDeviceReady( ucCon);
//	Disp("(");
	ATA_SetConfig(ucCon, g_oaATAInform[ucCon].eAtaMode, eATA_DMA_READ_DATA);
//	Disp(")");
#if 1
	ATA_SetTransferCommand(ucCon, eATA_XFR_CMD_START);
#else
	Set_Ata_Cmd_START();
#endif
	return TRUE;
	
}

//////////
// Function Name : ATA_IsWritingBlocksDone
// Function Description : This function checks that data transfer to device has done.
// Input : 	ucCon - ATA Controller Number
// Output : 	true/false
// Version : v0.1
bool ATA_IsWritingSectorsDone(u8 ucCon)
{
	bool			bRetValue	= false;

	ATA_WaitForTransferDone(ucCon);
	bRetValue	= ATA_IsDmaDone(ucCon);
	return bRetValue;
}

//////////
// Function Name : ATA_IsReadingBlocksDone
// Function Description : This function checks that data transfer from device to host has done.
// Input : 	ucCon - ATA Controller Number
// Output : 	true/false
// Version : v0.1
bool ATA_IsReadingSectorsDone(u8 ucCon)
{
	return ATA_IsWritingSectorsDone(ucCon);
}


//////////
// Function Name : ATA_IsDmaDone
// Function Description : This function checks that data DMA transfer to device has done.
// Input : 	ucCon - ATA Controller Number
// Output : 	NONE
// Version : v0.1
bool ATA_IsDmaDone(u8 ucCon)
{
	ATA_WaitForHostReady( ucCon);
	ATA_SetTransferCommand(ucCon, eATA_XFR_CMD_ABORT);
	ATA_WaitForHostReady( ucCon);
	ATA_SetConfig( ucCon, eATA_MODE_PIOCPU, eATA_DMA_WRITE_DATA);
	ATA_WaitForDeviceReady(ucCon);
	
	if (g_oaATAInform[ucCon].eAtaMode == eATA_MODE_UDMA)
	{
		ATA_SetUdmaAutoMode(ucCon, DISABLE);
	}

	return TRUE;
}
/*---------------------------------- APIs of ATA_CONTROL Registers ---------------------------------*/
//////////
// Function Name : ATA_SetEnable
// Function Description : This function enables/disables ATA controller.
// Input : 	ucCon - ATA Controller Number
//			ucEnFlag - ATA Enable/Disable
// Output : 	NONE
// Version : v0.1
void ATA_SetEnable(u8 ucCon, u8 ucEnFlag)
{
	u32		uRegValue = 0;

	uRegValue = ATA_GetRegValue(ucCon, eATA_CONTROL);
	uRegValue = uRegValue & ~(0x1) | (ucEnFlag << 0);

	ATA_SetRegValue(ucCon, eATA_CONTROL, uRegValue);			
}
/*---------------------------------- APIs of ATA_STATUS Registers ---------------------------------*/
//////////
// Function Name : ATA_WaitForTransferDone
// Function Description : This function implements wait function by checking ATA STATUS Register.
// Input : 	ucCon - ATA Controller Number
// Output : 	NONE
// Version : v0.1
void ATA_WaitForTransferDone(u8 ucCon)
{
	u32	uRegValue = 0;
//	Disp("MODE3:%s\n", ATA_GetModeName(g_oaATAInform[ucCon].eAtaMode));
	do {
		ATA_WaitForHostReady(ucCon); /// needed
		uRegValue	= ATA_GetRegValue(ucCon, eATA_STATUS);
//		Disp("%s,%d:Value:0x%x\n", __FUNCTION__, __LINE__, uRegValue);
	} while((uRegValue & 3)!=0);
}

/*---------------------------------- APIs of ATA_COMMAND Registers ---------------------------------*/
//////////
// Function Name : ATA_SetTransferCommand
// Function Description : This function sets up ATA transfer command.
// Input : 	ucCon - ATA Controller Number
//			eXfrCmd - STOP/START/ABORT/CONTINUE
// Output : 	NONE
// Version : v0.1
void ATA_SetTransferCommand(u8 ucCon, eATA_XFR_CMD eXfrCmd)
{
	u32		uRegValue = 0;

	uRegValue = ATA_GetRegValue(ucCon, eATA_COMMAND);
	uRegValue = uRegValue & ~(0x3) | (eXfrCmd << 0);

	ATA_SetRegValue(ucCon, eATA_COMMAND, uRegValue);			
}
/*---------------------------------- APIs of ATA_SWRST Registers ---------------------------------*/
//////////
// Function Name : ATA_SetSwRst
// Function Description : This function implements s/w reset function of ATA controller.
// Input : 	ucCon - ATA Controller Number
//			eIrqSrc - Interrupt source to mask
// Output : 	NONE
// Version : v0.1
void ATA_SetSwRst(u8 ucCon, u8 ucEnFlag)
{
	u32		uRegValue = 0;

	uRegValue = ATA_GetRegValue(ucCon, eATA_SWRST);
	uRegValue = uRegValue & ~(0x1) | (ucEnFlag << 0);

	ATA_SetRegValue(ucCon, eATA_SWRST, uRegValue);			
}

/*---------------------------------- APIs of ATA_IRQ/ATA_IRQ_MASK Registers ---------------------------------*/
//////////
// Function Name : ATA_SetIRQMask
// Function Description : This function implements interrupt masking function of ATA controller.
// Input : 	ucCon - ATA Controller Number
//			eIrqSrc - Interrupt source to mask
// Output : 	NONE
// Version : v0.1
void ATA_SetIRQ(u8 ucCon, eATA_IRQ_SRC eIrqSrc)
{
	u32		uRegValue = 0;

	uRegValue = ATA_GetRegValue(ucCon, eATA_IRQ);
	uRegValue = uRegValue & ~(0x1f) | (eIrqSrc << 0);

	ATA_SetRegValue(ucCon, eATA_IRQ, uRegValue);			
}

//////////
// Function Name : ATA_SetIRQMask
// Function Description : This function implements interrupt masking function of ATA controller.
// Input : 	ucCon - ATA Controller Number
//			eIrqSrc - Interrupt source to mask
// Output : 	NONE
// Version : v0.1
void ATA_SetIRQMask(u8 ucCon, eATA_IRQ_SRC eIrqSrc)
{
	u32		uRegValue = 0;

	uRegValue = ATA_GetRegValue(ucCon, eATA_IRQ_MASK);
	uRegValue = uRegValue & ~(0x1f) | (eIrqSrc << 0);

	ATA_SetRegValue(ucCon, eATA_IRQ_MASK, uRegValue);			
}

bool ATA_FindInterruptRequest(u8 ucCon, u32* uNthBit)
{
	u32	uLoopCnt = 0;
	u32	uRegValue1 = 0;
	u32	uRegValue2 = 0;
	
	for(uLoopCnt=0;uLoopCnt< ATA_INT_NUM;uLoopCnt++) {
		uRegValue1 = ATA_GetRegValue(ucCon, eATA_IRQ);
		uRegValue2 = ATA_GetRegValue(ucCon, eATA_IRQ_MASK);
		if(((uRegValue1&(~uRegValue2))>>uLoopCnt)&0x01) 
			break;
	}

	*uNthBit = uLoopCnt;
	
	if (uLoopCnt == ATA_INT_NUM)
		return FALSE;
	else
		return TRUE;
	
}

void ATA_ClearPending(u8 ucCon, u32 uSrcInt)
{
	u32		uRegValue = 0;

	uRegValue = ATA_GetRegValue(ucCon, eATA_IRQ);
	uRegValue = uRegValue & ~(0x1 << uSrcInt) | (0x1 << uSrcInt);

⌨️ 快捷键说明

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