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

📄 ata.c

📁 samsung最近推出的s3c2443 soc芯片的完整测试代码(官方),外围设备包括ADC,Audio,Timer,RTC,WDT,Video,cs8900,IIC,SPI,CF,SD/MMC,以及
💻 C
📖 第 1 页 / 共 3 页
字号:
void GetMaxMultiple(unsigned int* maxMulti)
{
	*maxMulti = uMaxMultiple;
}

/**********************************
 * PIO mode maximum transfer rate
 * PIO0 : 3.3MB/s
 * PIO1 : 5.2MB/s
 * PIO2 : 8.3MB/s
 * PIO3 : 11.1MB/s
 * PIO4 : 16.7MB/s
 *
***********************************/
 
void SetPioMode(PIOMODE  pmode) 
{
	unsigned char nMode = (pmode == PIO0) ? 0 :
				(pmode == PIO1) ? 1 :
				(pmode == PIO2) ? 2 :
				(pmode == PIO3) ? 3 :
				(pmode == PIO4) ? 4 : 0;
	
	unsigned int uT1;
	unsigned int uT2;
	unsigned int uTeoc;
	unsigned int i;
	
	unsigned int uPioTime[5];
	unsigned int m_uPioT1[5] = {70,50,30,30,30};    // min = {70,50,30,30,25};  edited by junon 060827
	unsigned int m_uPioT2[5] = {290,290,290,80,70}; // min = {290,290,290,80,70};
	unsigned int m_uPioTeoc[5] = {20,20,10,10,10};  // min = {20,15,10,10,10};

	unsigned int uCycleTime = (unsigned int)(1000000000/HCLK);


	for (i=0; i<5; i++)
	{
		uT1   = (m_uPioT1[i]  /uCycleTime)&0xff;  // edited by junon 060827
		uT2   = (m_uPioT2[i]  /uCycleTime)&0xff;
		uTeoc = (m_uPioTeoc[i]/uCycleTime)&0x0f;
		uPioTime[i] = (uTeoc<<12)|(uT2<<4)|uT1;
		DbgAta(("PIO%dTIME = %x\n", i, uPioTime[i]));
	}
	
	Outp32(ATA_IRQ, 0xff);
	Outp32(ATA_IRQ_MASK, ATAPI_MASK);


    WriteOnTaskFileReg(DEV_CONTROL,0);
	WriteOnTaskFileReg(DEV_FEATURE,0x03); //set transfer mode based on value in Sector Count register
	WriteOnTaskFileReg(DEV_SECTOR,0x08|(nMode&0x7)); // PIO flow control transfer mode
	WriteOnTaskFileReg(DEV_LOWLBA,0x00);
	WriteOnTaskFileReg(DEV_MIDLBA,0x00);
	WriteOnTaskFileReg(DEV_HIGHLBA,0x00);
	WriteOnTaskFileReg(DEV_DEVICE,0x40);
	
	WriteOnTaskFileReg(DEV_COMMAND,SETFEATURES); //set feature command

	WaitForDeviceReady();

	switch(pmode) { // modified by Bryan W. Lee (Oct. 19th, 2005)
		case PIO1:
			uCfgReg &= (~0x2); //IORDY disable
			Outp32(ATA_PIO_TIME, uPioTime[1]);
			break;
		case PIO2:
			uCfgReg &= (~0x2); //IORDY disable
			Outp32(ATA_PIO_TIME, uPioTime[2]);
			break;
		case PIO3:
			uCfgReg |= 0x2; //IORDY enable
			Outp32(ATA_PIO_TIME, uPioTime[3]);
			break;
		case PIO4:
			uCfgReg |= 0x2; //IORDY enable
			Outp32(ATA_PIO_TIME, uPioTime[4]);
			break;
		default:
			uCfgReg &= (~0x2); //IORDY disable
			Outp32(ATA_PIO_TIME, uPioTime[0]);
			break;
		}
	Outp32(ATA_CFG, uCfgReg);
	eCurrentPioMode = pmode;

}

//uSector: the number of sectors per block
// if the block count is not supported, an Abort Command error is posted,
// and the Read Multiple and Write Multiple commands are disabled.
void SetMultiple(unsigned int uSector) 
{
	uCurrentMultiple = uSector;

    WriteOnTaskFileReg(DEV_CONTROL,0);
	WriteOnTaskFileReg(DEV_SECTOR,uSector&0xff);
	WriteOnTaskFileReg(DEV_LOWLBA,0x00);
	WriteOnTaskFileReg(DEV_MIDLBA,0x00);
	WriteOnTaskFileReg(DEV_HIGHLBA,0x00);
	WriteOnTaskFileReg(DEV_DEVICE,0x40);
	WriteOnTaskFileReg(DEV_COMMAND,0xC6); //Set Multiple mode (implemented in ATA IP ??)

	WaitForDeviceReady();
}

/**********************************
 * UDMA mode maximum transfer rate
 * UDMA0 : 16.7MB/s
 * UDMA1 : 25.0MB/s
 * UDMA2 : 33.3MB/s
 * UDMA3 : 44.4MB/s
 * UDMA4 : 66.7MB/s
 * UDMA5 : 100 MB/s 
 *
***********************************/
void SetUdmaMode(UDMAMODE umode) 
{
	unsigned char nMode = 0;
	unsigned int uTdvh1;
	unsigned int uTdvs;
	unsigned int uTrp;
	unsigned int uTss;
	unsigned int uTackenv;
	unsigned int i;

	unsigned int uUdmaTime[5];					// Tdvh+Tdvs min = {120,80,60,45,30}
	unsigned int uUdmaTdvh[5] = {10,10,10,10,10}; 	// min = {6.2,6.2,6.2,6.2,6.2}; edited by junon 060827
	unsigned int uUdmaTdvs[5] = {100,60,50,35,20}; 	// min = {70,48,31,20,6.7};
	unsigned int uUdmaTrp[5] = {160,125,100,100,100}; // min = {160,125,100,100,100};
	unsigned int uUdmaTss[5] = {50,50,50,50,50};		 // min = {50,50,50,50,50};
	unsigned int uUdmaTackenvMin[5] = {20,20,20,20,20};
	

	unsigned int uCycleTime = (unsigned int)(1000000000/HCLK);

	for (i=0; i<5; i++)
	{
		uTdvh1	= (uUdmaTdvh[i] / uCycleTime)&0x0f;		// edited by junon 060827
		uTdvs	= (uUdmaTdvs[i] / uCycleTime)&0xff;
		uTrp	= (uUdmaTrp[i]  / uCycleTime)&0xff;
		uTss	= (uUdmaTss[i]  / uCycleTime)&0x0f;
		uTackenv= (uUdmaTackenvMin[i]/uCycleTime)&0x0f;
		uUdmaTime[i] = (uTdvh1<<24)|(uTdvs<<16)|(uTrp<<8)|(uTss<<4)|uTackenv;
		DbgAta(("UDMA%dTIME = %x\n", i, uUdmaTime[i]));
	}	

	Outp32(ATA_IRQ, 0xff);
	Outp32(ATA_IRQ_MASK, ATAPI_MASK);

    WriteOnTaskFileReg(DEV_CONTROL,0);
	WriteOnTaskFileReg(DEV_FEATURE,0x03);
	WriteOnTaskFileReg(DEV_SECTOR,0x40|(nMode&0x7));
	WriteOnTaskFileReg(DEV_LOWLBA,0x00);
	WriteOnTaskFileReg(DEV_MIDLBA,0x00);
	WriteOnTaskFileReg(DEV_HIGHLBA,0x00);
	WriteOnTaskFileReg(DEV_DEVICE,0x40);
	WriteOnTaskFileReg(DEV_COMMAND,SETFEATURES);

	WaitForDeviceReady();

	
	switch(umode) {
		case UDMA0:
			nMode = 0;
			Outp32(ATA_UDMA_TIME, uUdmaTime[0]);
			break;		
		case UDMA1:
			nMode = 1;
			Outp32(ATA_UDMA_TIME, uUdmaTime[1]);
			break;
		case UDMA2:
			nMode = 2;
			Outp32(ATA_UDMA_TIME, uUdmaTime[2]);
			break;
		case UDMA3:
			nMode = 3;
			Outp32(ATA_UDMA_TIME, uUdmaTime[3]);
			break;
		case UDMA4:
			nMode = 4;
			Outp32(ATA_UDMA_TIME, uUdmaTime[4]);
			break;
		default:
			DbgAta(("Wrong UDMA mode in SetUdmaMode()\n"));
			break;
		}
	uCurrentUdmaMode = nMode;
	

}

bool OpenATAMedia(void)
{
	ATA_MODE mode;
	
	Init();

	IdentifyDevice();

	// Decide what mode is best choice in this media.
	if (uMaxUdmaMode == 0)
	{
		mode = PIO_DMA;
	}
	else
	{
		mode = UDMA;
	}

	SetAtaMode(mode);
	if (mode == PIO_CPU || mode == PIO_DMA)
	{
		SetPioMode(eMaxPioMode);				
	}
	else 
	{
		UDMAMODE udmaMode = 
			(uMaxUdmaMode == 0) ? UDMA0 :
			(uMaxUdmaMode == 1) ? UDMA1 :
			(uMaxUdmaMode == 2) ? UDMA2 :
			(uMaxUdmaMode == 3) ? UDMA3 : UDMA4;
		SetPioMode(PIO0);
		SetUdmaMode(udmaMode);		
	}

	return TRUE;
}

bool OpenATAMediaWithMode(ATA_MODE mode)
{	
	Init();

	IdentifyDevice();

	SetAtaMode(mode);
	if (mode == PIO_CPU || mode == PIO_DMA)
	{
		SetPioMode(eMaxPioMode);				
		DbgAta(("Now PIO mode%d is set!!\n",eMaxPioMode));
	}
	else 
	{
		UDMAMODE udmaMode = 
			(uMaxUdmaMode == 0) ? UDMA0 :
			(uMaxUdmaMode == 1) ? UDMA1 :
			(uMaxUdmaMode == 2) ? UDMA2 :
			(uMaxUdmaMode == 3) ? UDMA3 : UDMA4;
		SetPioMode(PIO0);
		SetUdmaMode(udmaMode);		
		DbgAta(("Now PIO mode0, UDMA mode%d is set!!\n",udmaMode));
	}
	

	return TRUE;
}

bool CloseATAMedia(void)
{
	SetAtaOnOff(0);

	// Output pad disable, Card power off, PC card mode
	Outp32(ATA_MUX, 0x06);

	return TRUE;
}

bool ReadATABlocks(unsigned int uStBlock, unsigned int uBlocks, unsigned int uBufAddr)
{
	unsigned int k;
	ATA_MODE mode = eMode;
	bool status = FALSE;
	
#if PERF_TEST_ATA	
	unsigned int op_time=0;
	SetResStopwatch(10000); // us order, 10000us = 10ms
	StartStopwatch(); // Start timer
#endif
	switch(mode) 
	{
		case PIO_CPU:
			status = ReadSectors_Pio( uStBlock, uBlocks, uBufAddr);
			break;
			
		case PIO_DMA:
			for(k=0; k<uBlocks; k++) 
			{
				ReadSector_PioDma(uStBlock+k, uBufAddr+ATA_SECTORSIZE*k);
				WaitForTransferDone();
			}
			status = TRUE; // need to move..
			break;
			
		case UDMA:
			status = ReadSectors_Udma( uStBlock, uBlocks, uBufAddr);
			break;
			
		default:
			DbgAta(("Not supported mode in ReadBlocks()\n"));
			break;
	}
#if PERF_TEST_ATA	
	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 status;
}

bool WriteATABlocks(unsigned int uStBlock, unsigned int uBlocks, unsigned int uBufAddr)
{
	unsigned int k;
	ATA_MODE mode = eMode;
	bool status = FALSE;

#if PERF_TEST_ATA
	unsigned int op_time=0;
	SetResStopwatch(10000); // us order, 10000us = 10ms
	StartStopwatch(); // Start timer
#endif
	switch(mode) 
	{
		case PIO_CPU:
			status = WriteSectors_Pio( uStBlock, uBlocks, uBufAddr);
			break;
			
		case PIO_DMA:
			for(k=0; k<uBlocks; k++)
			{
				WriteSector_PioDma(uStBlock+k, uBufAddr+ATA_SECTORSIZE*k);
				WaitForTransferDone();
			}
			status = TRUE;
			break;
		case UDMA:			
			status = WriteSectors_Udma( uStBlock, uBlocks, uBufAddr);
			break;
		default:
			DbgAta(("Not supported mode in WriteBlocks()\n"));
			break;
	}
#if PERF_TEST_ATA	
	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 status;
}


bool StartReadingBlocks(unsigned int uStBlock, unsigned int uBlocks, unsigned int uBufAddr)
{
	unsigned int deviceCmd = (eMode == UDMA) ? READDMA : READSECTOR;
	
	/*Track Buffer 1 Setting*/
	Outp32(ATA_TBUF_START, uBufAddr);
	Outp32(ATA_TBUF_SIZE, uBlocks*ATA_SECTORSIZE);
	Outp32(ATA_XFR_NUM, uBlocks*ATA_SECTORSIZE);

	SetAtaDevice(uStBlock, uBlocks);
	WriteOnTaskFileReg(DEV_COMMAND, deviceCmd);

	WaitForDeviceReady();
	
	SetConfigMode(eMode, FALSE);
#ifndef __EVT1
	if (eMode == UDMA) // apply at specific set using buffer control
	{
		DbgAta(("Ready for reading data in UDMA..\n"));
		SetBufferDirection(READDMA);
	}
#endif	
	SetTransferCommand(ATA_CMD_START);
	
	return TRUE;
}

bool IsReadingBlocksDone(void)
{
	return IsWritingBlocksDone();
}

void ContinueReadingBlocks(void)
{

}


bool StartWritingBlocks(unsigned int uStBlock, unsigned int uBlocks, unsigned int uBufAddr)
{
	unsigned int deviceCmd = (eMode == UDMA) ? WRITEDMA : WRITESECTOR;

	
	/*Source Buffer Setting*/
	Outp32(ATA_SBUF_START, uBufAddr);
	Outp32(ATA_SBUF_SIZE, uBlocks*ATA_SECTORSIZE);
	Outp32(ATA_XFR_NUM,   uBlocks*ATA_SECTORSIZE);
	
	SetAtaDevice(uStBlock, uBlocks);
	WriteOnTaskFileReg(DEV_COMMAND, deviceCmd);

	WaitForDeviceReady();

	SetConfigMode(eMode, TRUE);	
#ifndef __EVT1
	if (eMode == UDMA) // apply at specific set using buffer control
	{
		printf("Ready for writing data in UDMA. \n");
		SetBufferDirection(WRITEDMA); // for SMDK buffer direction only
	}
#endif
	SetTransferCommand(ATA_CMD_START);

	return TRUE;
}

bool IsWritingBlocksDone(void)
{
	WaitForTransferDone();
	
	return IsDmaDone();
}

void ContinueWritingBlocks(void)
{

}

bool IsDmaDone(void)
{
	SetTransferCommand(ATA_CMD_ABORT);
#ifndef __EVT1
	if (eMode == UDMA) // apply at specific set using buffer control
	{
		SetBufferDirection(0); // clear
		ChangeBufferControl(PIO_CPU);
		DbgAta(("Return to PIO mode. \n"));
	}
#endif
	SetConfigMode(PIO_CPU, TRUE);
	WaitForDeviceReady();

	if (eMode == UDMA)
	{
		uCfgReg &= (~0x200); // disable ATA DMA auto mode
		Outp32(ATA_CFG, uCfgReg);	
	}
	return TRUE;
}

⌨️ 快捷键说明

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