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

📄 ata.cpp

📁 Samsung S3C2443 Test program source code
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	
	return IsDmaDone();
}

void ATA::ContinueWritingBlocks(void)
{

}

bool ATA::IsDmaDone(void)
{
	SetTransferCommand(ATA_CMD_ABORT);
	if (m_eMode == UDMA) // apply at specific set using buffer control
	{
		SetBufferDirection(0); // clear
		printf("Return to PIO mode. Change dip SW & Press Enter..\n");
		getchar();
	}

	SetConfigMode(PIO_CPU, true);
	WaitForDeviceReady();

	if (m_eMode == UDMA)
	{
		m_uCfgReg &= (~0x200); // disable ATA DMA auto mode
		Outp32(ATA_CFG, m_uCfgReg);	
	}
	return true;
}

void ATA::ChangeMode(void)
{
#ifdef CFCON_MODE
	SetResTDelay(10); // TDelay 1 unit = 10us
	InitTDelayFunc();
	
	// CF controller - True IDE mode setting
	Outp32(ATA_MUX, 0x07); // Output pad disable, Card power off, ATA mode
	TDelay(100);
	Outp32(ATA_MUX, 0x03); // Output pad enable, Card power off, ATA mode
	TDelay(100);
	Outp32(ATA_MUX, 0x01); // Output pad enable, Card power on, ATA mode
	TDelay(50000); // wait for 500ms
#endif
}

void ATA::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 ATA::SetConfigMode(ATA_MODE mode, bool isWriteMode)
{
	switch(mode)
	{
		case PIO_CPU:
			m_uCfgReg = ((m_uCfgReg&0x1F3) | (0<<2)); // set PIO_CPU class
			break;
		case PIO_DMA:
			m_uCfgReg = ((m_uCfgReg&0x1F3) | (1<<2)); // set PDMA class
			if (isWriteMode == true)
				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 (enable multi block transfer)
			if (isWriteMode == true)
				m_uCfgReg |= 0x10; // DMA write mode
			else
				m_uCfgReg &= (~0x10); // DMA read mode
			break;
		default:
			break;
	}
	Outp32(ATA_CFG, m_uCfgReg);
}

bool ATA::WriteSectors_Pio(U32 nLBA,U32 nSectorCount,U32 nSrcAddress) 
{
	U32 uCurrentCount;
	U32 uRemainderCount;
	U32 uCurrentLba;
	U32 uCurrentSrcAddr;
	U32 uRound;
	U16* uAtaHostAddr;
	U32 i;
	
	uRemainderCount = nSectorCount;
	uCurrentLba = nLBA;
	uRound = 0;	

	
	while(uRemainderCount != 0) {
		if(uRemainderCount>256) {
			uCurrentCount = 256; //0 means 256
			uRemainderCount -= 256;
		} else {
			uCurrentCount = uRemainderCount;
			uRemainderCount = 0;
		}
		uCurrentLba = nLBA + uRound*256;
		uCurrentSrcAddr = nSrcAddress + uRound*256*ATA_SECTORSIZE;
		uAtaHostAddr = (U16*)uCurrentSrcAddr;
		
		SetAtaDevice(uCurrentLba, uCurrentCount);
		WriteOnTaskFileReg(DEV_COMMAND, WRITESECTOR);

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

		uRound++;
	}
	return true;
}


bool ATA::ReadSectors_Pio(U32 uLBA, U32 uSectorCount, U32 uDesAddress) 
{
	U32 uCurrentCount;
	U32 uRemainderCount;
	U32 uCurrentLba;
	U32 uCurrentDstAddr;
	U32 uRound;
	U16* uAtaHostAddr;
	U32 i;
	
	uRemainderCount = uSectorCount;
	uCurrentLba = uLBA;
	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 = uDesAddress + uRound*256*ATA_SECTORSIZE;
		uAtaHostAddr = (U16*)uCurrentDstAddr;

		SetAtaDevice(uCurrentLba, uCurrentCount);
		WriteOnTaskFileReg(DEV_COMMAND, READSECTOR);

		while(uCurrentCount-- ) {
			WaitForDeviceReady();
			for (i=0;i<ATA_SECTORSIZE/2;i++) {
				 GetDataFromDevice(*uAtaHostAddr);
				 uAtaHostAddr++;
			}
		}
		WaitForDeviceReady();

		uRound++;
	}
	return true;
}




bool ATA::WriteSector_PioDma(U32 uLBA, U32 uSrcAddress) 
{
#if 1
	StartWritingBlocks(uLBA, 1, uSrcAddress);
	return IsWritingBlocksDone();
#else	
	/*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);

	WaitForDeviceReady();

	SetConfigMode(PIO_DMA, true);
	
	SetTransferCommand(ATA_CMD_START);
	WaitForTransferDone();
	SetTransferCommand(ATA_CMD_ABORT);

	SetConfigMode(PIO_CPU, true);

	WaitForDeviceReady();
	
	return true;
#endif	
}

bool ATA::ReadSector_PioDma(U32 uLBA, U32 uDesAddress) 
{
#if 1
	StartReadingBlocks(uLBA, 1, uDesAddress);
	return IsReadingBlocksDone();
#else
	/*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);
	
	WaitForDeviceReady();
		
	SetConfigMode(PIO_DMA, false);
		
	SetTransferCommand(ATA_CMD_START);
	WaitForTransferDone();
	SetTransferCommand(ATA_CMD_ABORT);

	SetConfigMode(PIO_CPU, false);

	WaitForDeviceReady();
			
	return true;
#endif	
}



bool ATA::WriteSectors_MultiplePioDma(U32 uLBA, U32 uSrcAddress) 
{	
	
	/*Source Buffer 1 Setting*/
	Outp32(ATA_SBUF_START, uSrcAddress);
	Outp32(ATA_SBUF_SIZE, m_uCurrentMultiple*ATA_SECTORSIZE);
	Outp32(ATA_XFR_NUM,   m_uCurrentMultiple*ATA_SECTORSIZE);
	
	SetAtaDevice(uLBA, m_uCurrentMultiple);
	WriteOnTaskFileReg(DEV_COMMAND, WRITEMULTIPLE);

	WaitForDeviceReady();
	SetConfigMode(PIO_DMA, true);
		
	/*ATA Transfer Command */
	SetTransferCommand(ATA_CMD_START);
	WaitForTransferDone();
	SetTransferCommand(ATA_CMD_ABORT);

	SetConfigMode(PIO_CPU, true);
	WaitForDeviceReady();
	
	return true;
}

bool ATA::ReadSectors_MultiplePioDma(U32 uLBA, U32 uDesAddress) 
{
	/*Track Buffer 1 Setting*/
	Outp32(ATA_TBUF_START, uDesAddress);
	Outp32(ATA_TBUF_SIZE, (m_uCurrentMultiple*ATA_SECTORSIZE));
	Outp32(ATA_XFR_NUM,  (m_uCurrentMultiple*ATA_SECTORSIZE));

	SetAtaDevice(uLBA, m_uCurrentMultiple);
	WriteOnTaskFileReg(DEV_COMMAND, READMULTIPLE);
	
	WaitForDeviceReady();
	SetConfigMode(PIO_DMA, false);

	SetTransferCommand(ATA_CMD_START);
	WaitForTransferDone();
	SetTransferCommand(ATA_CMD_ABORT);

	SetConfigMode(PIO_CPU, false);
	WaitForDeviceReady();

	return true;
}

bool ATA::WriteSectors_Udma(U32 uLBA, U32 uSectorCount, U32 uSrcAddress) 
{
	U32 uCurrentCount;
	U32 uRemainderCount;
	U32 uCurrentLba;
	U32 uCurrentSrcAddr;
	U32 uRound;
	
	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;
		uCurrentSrcAddr = uSrcAddress + uRound*256*ATA_SECTORSIZE;
#if 1
		StartWritingBlocks(uCurrentLba, uCurrentCount, uCurrentSrcAddr);
		IsWritingBlocksDone();
#else
		/*Source Buffer 1 Setting*/
		Outp32(ATA_SBUF_START, uCurrentSrcAddr);
		Outp32(ATA_SBUF_SIZE, uCurrentCount*ATA_SECTORSIZE);
		Outp32(ATA_XFR_NUM,   uCurrentCount*ATA_SECTORSIZE);	

		SetAtaDevice(uCurrentLba, uCurrentCount);
		WriteOnTaskFileReg(DEV_COMMAND,WRITEDMA);

		WaitForDeviceReady();
		SetConfigMode(UDMA, true);
	
		printf("Ready for writing in UDMA. Change dip SW & Press Enter..\n");
		getchar();

		/*ATA Transfer Command */
		SetBufferDirection(WRITEDMA);
		SetTransferCommand(ATA_CMD_START);

#if 1
		WaitForTransferDone();
#else  // abort operation
		while(1){
			Inp32(ATA_XFR_CNT, temp);
			if(temp <= uCurrentCount*ATA_SECTORSIZE) break;
		}
#endif
		SetTransferCommand(ATA_CMD_ABORT);
		SetBufferDirection(0); // clear to H

		printf("Return to PIO mode. Change dip SW & Press Enter..\n");
		getchar();

		SetConfigMode(PIO_CPU, true);
		WaitForDeviceReady();
		
		m_uCfgReg &= (~0x200); // disable ATA DMA auto mode
		Outp32(ATA_CFG, m_uCfgReg);	
#endif
		uRound++;
	}

	return true;

}


bool ATA::ReadSectors_Udma(U32 uLBA, U32 uSectorCount, U32 uDstAddress) 
{
	U32 uCurrentCount;
	U32 uRemainderCount;
	U32 uCurrentLba;
	U32 uCurrentDstAddr;
	U32 uRound;
	
	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;
#if 1
		StartReadingBlocks(uCurrentLba, uCurrentCount, uCurrentDstAddr);
		IsReadingBlocksDone();
#else
		/*Track Buffer 1 Setting*/
		Outp32(ATA_TBUF_START, uCurrentDstAddr);
		Outp32(ATA_TBUF_SIZE, uCurrentCount*ATA_SECTORSIZE);
		Outp32(ATA_XFR_NUM, uCurrentCount*ATA_SECTORSIZE);

		SetAtaDevice(uCurrentLba, uCurrentCount);
		WriteOnTaskFileReg(DEV_COMMAND,READDMA);

		WaitForDeviceReady();
		SetConfigMode(UDMA, false);

		printf("Ready for reading in UDMA. Change dip SW & Press Enter..\n");
		getchar();

		/*ATA Transfer Command */		
		SetBufferDirection(READDMA);
		SetTransferCommand(ATA_CMD_START);

		WaitForTransferDone(); // Host

		SetTransferCommand(ATA_CMD_ABORT);	
		SetBufferDirection(0); // clear to H

		printf("Return to PIO mode. Change dip SW & Press Enter..\n");
		getchar();

		SetConfigMode(PIO_CPU, false);
		WaitForDeviceReady();

		m_uCfgReg &= (~0x200); // disable ATA DMA auto mode
		Outp32(ATA_CFG, m_uCfgReg);
#endif		
		uRound++;
	}

	return true;
}


⌨️ 快捷键说明

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