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

📄 ata.c

📁 三星2413芯片的测试代码,对进行驱动开发很有帮助.
💻 C
📖 第 1 页 / 共 3 页
字号:
	WriteOnTaskFileReg(DEV_COMMAND,SETFEATURES); //set feature command

	WaitForNoBusyStatus();

//printf ("gh0522.cha's debugging ...%d\n",pmode);//gh0522.cha

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

}

//nSector: 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(U32 nSector) 
{
	m_oDevice[0].CurrentMultiple = nSector;

    WriteOnTaskFileReg(DEV_CONTROL,0);
	WriteOnTaskFileReg(DEV_SECTOR,nSector&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 ??)

	WaitForNoBusyStatus();
}

void SetAtaDevice(U32 uLBA, U32 uSectorCount)
{
	WriteOnTaskFileReg(DEV_SECTOR,uSectorCount&0xFF);
	WriteOnTaskFileReg(DEV_LOWLBA,uLBA&0xFF);
	WriteOnTaskFileReg(DEV_MIDLBA,(uLBA>>8)&0xFF);
	WriteOnTaskFileReg(DEV_HIGHLBA,(uLBA>>16)&0xFF);
	WriteOnTaskFileReg(DEV_DEVICE,((uLBA>>24)&0xF)|0x40);
}

void SetUdmaMode(int umode) 
{
	U8 nMode;
	U32 uTdvh1;
	U32 uTdvs;
	U32 uTrp;
	U32 uTss;
	U32 uTackenv;
	U32 i;

	U32 uUdmaTime[5];
	U32 m_uUdmaTdvh[5] = {7,7,7,7,7};
	U32 m_uUdmaTdvs[5] = {70,48,31,20,7};
	U32 m_uUdmaTrp[5] = {160,125,100,100,100};
	U32 m_uUdmaTss[5] = {50,50,50,50,50};
	U32 m_uUdmaTackenvMin[5] = {20,20,20,20,20};
	U32 m_uUdmaTackenvMax[5] = {70,70,70,55,55};	
	U32 uCycleTime = (U32)(1000000000/HCLK);
	
	for (i=0; i<5; i++)
	{
		uTdvh1	= (m_uUdmaTdvh[i] / uCycleTime + 1)&0x0f;
		uTdvs	= (m_uUdmaTdvs[i] / uCycleTime + 1)&0xff;
		uTrp	= (m_uUdmaTrp[i]  / uCycleTime + 1)&0xff;
		uTss	= (m_uUdmaTss[i]  / uCycleTime + 1)&0x0f;
		uTackenv= (m_uUdmaTackenvMin[i]/uCycleTime + 1)&0x0f;
		uUdmaTime[i] = (uTdvh1<<24)|(uTdvs<<16)|(uTrp<<8)|(uTss<<4)|uTackenv;
//		DbgAta(("UDMA%dTIME = %x\n", i, uUdmaTime[i]));
	}	

	
	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:
			Disp("Wrong UDMA mode in SetUdmaMode()\n");
			break;
		}
	m_oDevice[0].CurrentUdmaMode = nMode;
	
	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);

	WaitForNoBusyStatus();
}

U32 OpenMedia(int mode)
{

	U32 udmaMode;

	ATA_Init();
	IdentifyDevice();
	
	// Decide what mode is best choice in this media.
	SetAtaMode(mode);
	
	if (mode == PIO || mode == PIODMA)
	{
		SetPioMode(m_oDevice[0].MaxPioMode);				
	}
	
	else 
	{
		udmaMode = 
			(m_oDevice[0].MaxUdmaMode == 0) ? UDMA0 :
			(m_oDevice[0].MaxUdmaMode == 1) ? UDMA1 :
			(m_oDevice[0].MaxUdmaMode == 2) ? UDMA2 :
			(m_oDevice[0].MaxUdmaMode == 3) ? UDMA3 : UDMA4;
			
		SetPioMode(PIO0);
		SetUdmaMode(udmaMode);
	}

	return TRUE;
}

void SetConfigMode(int mode, U32 isWriteMode)
{
	switch(mode)
	{
		case PIO:
			m_uCfgReg = ((m_uCfgReg&0x1F3) | (0<<2)); // set PIO class
			break;
		case PIODMA:
			m_uCfgReg = ((m_uCfgReg&0x1F3) |(1<<2)); // set PDMA class
			if (isWriteMode == 1)
				m_uCfgReg |= 0x10; // DMA write mode
			else
				m_uCfgReg &= (~0x10); // DMA read mode
			break;
		case UDMA:
			m_uCfgReg = ((m_uCfgReg&0x1F3) | (2<<2)); // set UDMA class
			m_uCfgReg |= 0x200; // set ATA DMA auto mode
			if (isWriteMode == 1)
				m_uCfgReg |= 0x10; // DMA write mode
			else
				m_uCfgReg &= (~0x10); // DMA read mode
			break;
		default:
			break;
	}
	Outp32(ATA_CFG, m_uCfgReg);
}

void SetTransferCommand(U8 command)
{
	WaitForDeviceAccessReady(); /// needed
	Outp32(ATA_COMMAND, command);
}

void PutDataToDevice(U16 data) 
{

	WaitForDeviceAccessReady();
	Outp32(ATA_PIO_DTR, data);
}

void VerifyData(U32 writeBufferAddr, U32 readBufferAddr, U32 sectors)
{

if (Compare32(writeBufferAddr, readBufferAddr, sectors*128) == FALSE)
	{
		Disp("Error detected\n");
		Dump32(readBufferAddr, sectors*128);
	}
	else
	{
		Disp("Write/Read is OK\n");
	}
}

U32 Compare32(U32 a0, U32 a1, U32 words)
{
	U32 i;
	
	U32* pD0 = (U32 *)a0;
	U32* pD1 = (U32 *)a1;

	U32 ret = TRUE;
		
	for (i=0; i<words; i++)
	{
		if (*pD0 != *pD1) {
			ret = FALSE;
			//Disp(" %08x=%08x : %08x=%08x\n", pD0, *pD0, pD1, *pD1);	//gh0522.cha 
		}

			//Disp(" %08x=%08x : %08x=%08x\n", pD0, *pD0, pD1, *pD1);	//gh0522.cha 
		pD0++;
		pD1++;
	}
	return ret;
	
}


U32 ReadSectors_Pio(U32 uLBA, U32 uSectorCount, U32 uDesAddress) 
{
	U32 resCount;
	U32 remainCount;
	U32 goingLBA;
	U32 goingDstAddr;
	U32 wCount;
	U16* uAtaHostAddr;
	U32 i;
	
	remainCount = uSectorCount;
	goingLBA = uLBA;
	wCount = 0;	

	SetLittleEndian();
	Init_LED();
	
	while(remainCount != 0)
	{
		if(remainCount>256)
		{
			resCount = 256; //0 means 256
			remainCount -= 256;
		}

		else
		{
			resCount = remainCount;
			remainCount = 0;
		}
		
		goingLBA = uLBA + wCount*256;
		goingDstAddr = uDesAddress + wCount*256*ATA_SECTORSIZE;
		uAtaHostAddr = (U16*)goingDstAddr;

		SetAtaDevice(goingLBA, resCount);
		WriteOnTaskFileReg(DEV_COMMAND, READSECTOR);

		while(resCount-- ) 
		{
			WaitForNoBusyStatus();
			WaitForDeviceAccessReady();
			for (i=0;i<ATA_SECTORSIZE/2;i++)
			{
				 //GetDataFromDevice(*uAtaHostAddr);
				 *uAtaHostAddr=GetDataFromDevice();	
				 uAtaHostAddr++;
			}
		}
		WaitForNoBusyStatus();

		wCount++;
	}
	return 1;
}

U32 WriteSectors_Pio(U32 nLBA,U32 nSectorCount,U32 nSrcAddress) 
{
	U32 resCount;
	U32 remainCount;
	U32 goingLBA;
	U32 goingSrcAddr;
	U32 wCount;
	U16* uAtaHostAddr;
	U32 i;
	
	remainCount = nSectorCount;
	goingLBA = nLBA;
	wCount = 0;	

	SetLittleEndian();
	
	while(remainCount != 0)
	{
		if(remainCount>256)
		{
			resCount = 256; //0 means 256
			remainCount -= 256;
		}

		else
		{
			resCount = remainCount;
			remainCount = 0;
		}
		
		goingLBA = nLBA + wCount*256;
		goingSrcAddr = nSrcAddress + wCount*256*ATA_SECTORSIZE;
		uAtaHostAddr = (U16*)goingSrcAddr;
		
		SetAtaDevice(goingLBA, resCount);
		WriteOnTaskFileReg(DEV_COMMAND, WRITESECTOR);

		while(resCount-- )
		{	
			WaitForNoBusyStatus();
			
			for (i=0;i<ATA_SECTORSIZE/2;i++)
			{
				PutDataToDevice(*uAtaHostAddr);
				uAtaHostAddr++;
			}
		}		
		WaitForNoBusyStatus();

		wCount++;
	}

	return 1;
}

/*=========================================================================
 *          	       INT, PIODMA function
 *=========================================================================
 */
U32 ReadSector_PioDma(U32 uLBA, U32 uDesAddress) 
{
	//	SetLittleEndian();
	
	/*Track Buffer 1 Setting*/
	Outp32(ATA_TBUF_START, uDesAddress);
	Outp32(ATA_TBUF_SIZE, 1*ATA_SECTORSIZE);
	Outp32(ATA_XFR_NUM, 1*ATA_SECTORSIZE);

	SetAtaDevice(uLBA, 1);
	WriteOnTaskFileReg(DEV_COMMAND, READSECTOR);
	
	WaitForNoBusyStatus();
		
	//SetConfigMode(PIODMA, false);
	SetConfigMode(PIODMA, 0);
		
	/*ATA Transfer Command */
	SetTransferCommand(ATA_CMD_START);
	
	//Delay(2); /// 0.2ms (1 transfer==0.6us, 256 transfer == 153.6us)
	WaitForTransferDone();
	SetTransferCommand(ATA_CMD_ABORT);

	//SetConfigMode(PIO, false);
	SetConfigMode(PIO, 1);

	WaitForNoBusyStatus();
			
	return 1;	
}

U32 WriteSector_PioDma(U32 uLBA, U32 uSrcAddress) 
{
	
	//	SetLittleEndian();
	
	/*Source Buffer 1 Setting*/
	Outp32(ATA_SBUF_START, uSrcAddress);
	Outp32(ATA_SBUF_SIZE, 1*ATA_SECTORSIZE);
	Outp32(ATA_XFR_NUM,   1*ATA_SECTORSIZE);
	
	SetAtaDevice(uLBA, 1);
	WriteOnTaskFileReg(DEV_COMMAND, WRITESECTOR);

	WaitForNoBusyStatus();

	//SetConfigMode(PIODMA, true);
	SetConfigMode(PIODMA, 1);
	
	/*ATA Transfer Command */
	SetTransferCommand(ATA_CMD_START);
	//Delay(2); /// 0.2ms (1 transfer==0.6us, 256 transfer == 153.6us)
	WaitForTransferDone();
	SetTransferCommand(ATA_CMD_ABORT);

	//SetConfigMode(PIO, true);
	SetConfigMode(PIO, 1);

	WaitForNoBusyStatus();
	
	//return true;
	return 1;
}


U32 ReadSectors_Udma(U32 uLBA,U32 uSectorCount,U32 uDstAddress) 
{

	/*Track Buffer 1 Setting*/
	Outp32(ATA_TBUF_START, uDstAddress);
	Outp32(ATA_TBUF_SIZE, uSectorCount*ATA_SECTORSIZE);
	Outp32(ATA_XFR_NUM, uSectorCount*ATA_SECTORSIZE);

	SetAtaDevice(uLBA, uSectorCount);
	WriteOnTaskFileReg(DEV_COMMAND,READDMA);

	WaitForNoBusyStatus();
	
	//SetConfigMode(UDMA, false);
	SetConfigMode(UDMA, 0);

	/*ATA Transfer Command */
	SetTransferCommand(ATA_CMD_START);
	WaitForTransferDone();
	SetTransferCommand(ATA_CMD_ABORT);
	
//		WaitForNoBusyStatus();
	//SetConfigMode(PIO, false);
	SetConfigMode(PIO, 0);
	Dbg("*");

	//return true;
	return 1;
	
}

U32 WriteSectors_Udma(U32 uLBA,U32 uSectorCount,U32 uSrcAddress) 
{
	U32 resCount;
	U32 remainCount;
	U32 goingLBA;
	U32 goingSrcAddr;
	U32 wCount;
	
	remainCount = uSectorCount;
	goingLBA = uLBA;
	wCount = 0;	

	SetLittleEndian();	
	
	while(remainCount != 0)
	{
		if(remainCount>256)
		{
			resCount = 256; //0 means 256
			remainCount -= 256;
		} 

		else
		{
			resCount = remainCount;
			remainCount = 0;
		}
		goingLBA = uLBA + wCount*256;
		goingSrcAddr = uSrcAddress + wCount*256*ATA_SECTORSIZE;

		/*Source Buffer 1 Setting*/
		Outp32(ATA_SBUF_START, uSrcAddress);
		Outp32(ATA_SBUF_SIZE, uSectorCount*ATA_SECTORSIZE);
		Outp32(ATA_XFR_NUM,   uSectorCount*ATA_SECTORSIZE);				
	
		SetAtaDevice(uLBA, uSectorCount);
		WriteOnTaskFileReg(DEV_COMMAND,WRITEDMA);

		WaitForNoBusyStatus();
		//SetConfigMode(UDMA, true);
		SetConfigMode(UDMA, 1);
	
		/*ATA Transfer Command */
		SetTransferCommand(ATA_CMD_START);	
		WaitForTransferDone();
		SetTransferCommand(ATA_CMD_ABORT);

//		WaitForNoBusyStatus();
		//SetConfigMode(PIO, true);
		SetConfigMode(PIO, 1);

		wCount++;
	}
	//return true;
	return 1;
}



U32 ReadBlocks(U32 uStBlock, U32 uBlocks, U32 uBufAddr)
{
	U32 i;
	int mode = m_eMode;
	U32 status;


//	Assert(uStBlock+uBlocks <= m_oDevice[0].MaxSectors);

⌨️ 快捷键说明

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