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

📄 atapi.c

📁 2443 wince5.0 bsp, source code
💻 C
📖 第 1 页 / 共 3 页
字号:
	
	RETAILMSG(INFO_MSG,(TEXT("Max PIO Mode : %d\n"),g_oDevice[0].MaxPioMode));

	g_oDevice[0].MaxUdmaMode =0;
	tempBuffer = readBuffer[88]>>8;
	for(i=4;i>=0;i--) {
		if(tempBuffer&(0x01<<i)) {
			g_oDevice[0].MaxUdmaMode = i;
			break; 
		}
	}

	RETAILMSG(RTL_MSG,(TEXT("+++ Last Check 1.%d\n"),g_oDevice[0].MaxPioMode));
	
	g_oDevice[0].CurrentUdmaMode =0;
	tempBuffer = readBuffer[88]&0x00ff;
	for(i=0;i<5;i++) {
		if(tempBuffer&(0x01<<i)) {
			g_oDevice[0].CurrentUdmaMode = i;
			break; ///
		}
	}
	RETAILMSG(RTL_MSG,(TEXT("+++ Last Check 2.%d\n"),g_oDevice[0].MaxPioMode));



	RETAILMSG(INFO_MSG,(TEXT("Max UDMA Mode : %d\n"),g_oDevice[0].MaxUdmaMode));
	RETAILMSG(INFO_MSG,(TEXT("Current UDMA Mode : %d\n"),g_oDevice[0].CurrentUdmaMode));
	//
	//verify identify data~~~~~~~~~~~~~~~~~~~~~~~END
	//

	g_uCfgReg &= (~0x40); // set Little endian
	g_vATAPIRegs->ATA_CFG = g_uCfgReg;
	//Outp32(ATA_CFG, g_uCfgReg);

	return TRUE;
}

void SetLittleEndian(void)
{
	// set Little endian		
	
	g_uCfgReg &= (~0x40); 
	g_vATAPIRegs->ATA_CFG = g_uCfgReg;
}


void SetAtaOnOff(UINT8 OnOff)
{
	UINT32 temp;
	//Inp32(ATA_CONTROL, temp);
	temp = g_vATAPIRegs->ATA_CONTROL;

	if(OnOff==1)
		//Outp32(ATA_CONTROL, temp | 0x1);
		g_vATAPIRegs->ATA_CONTROL = temp | 0x1;
	else if(OnOff == 0)
		//Outp32(ATA_CONTROL, temp &0xfffffffe);
		g_vATAPIRegs->ATA_CONTROL = temp & 0xfffffffe;
}

void Init(void)
{

	SetLittleEndian();
        
	SetAtaOnOff(1);

        Sleep(200);
        
	g_uCfgReg = 0;

	//CheckDevice(); 	
}

void Init12(PIOMODE pmode, UINT32 multisize, UDMAMODE umode)
{	
	SetAtaOnOff(1);
	
	
	g_uCfgReg = 0;
	g_uCfgReg &= (~0x40); // set Little endian
	//Outp32(ATA_CFG, m_uCfgReg);
	g_vATAPIRegs->ATA_CFG = g_uCfgReg;

	SetPioMode(pmode);
	SetMultiple(multisize);
	//SetUdmaMode(umode);
	
	CheckDevice(); 

}



int OpenMedia()
{

        ATA_MODE mode;
        UDMAMODE udmaMode;
        
	Init();
	
	if (!(IdentifyDevice()))
		return FALSE;

	if (g_oDevice[0].MaxUdmaMode == 0 )
	{
		mode = PIO_CPU;
	}
	else
	{
        #ifdef USE_MUTEX
    		RETAILMSG(1, (TEXT("### This CF Card is running by using UDMA %d\r\n")));	
           	mode = UDMA;  // to only use PIO mode 061024 hsjang        
        #else
    		RETAILMSG(1, (TEXT("### This CF Card is running by using PIO %d\r\n")));	        
        	mode = PIO_CPU;  // to only use PIO mode 061024 hsjang        
        #endif //USE_MUTEX
	}

	SetAtaMode(mode);

	if (mode == PIO_CPU || mode == PIO_DMA)
	{
		RETAILMSG(1, (TEXT("### ATAPI MAXPIOMODE %d\r\n"),g_oDevice[0].MaxPioMode));	
		if (!(SetPioMode(g_oDevice[0].MaxPioMode)))
			return FALSE;
	}
	else 
	{
		 udmaMode = 
			(g_oDevice[0].MaxPioMode == 0) ? UDMA0 :
			(g_oDevice[0].MaxPioMode == 1) ? UDMA1 :
			(g_oDevice[0].MaxPioMode == 2) ? UDMA2 :
			(g_oDevice[0].MaxPioMode == 3) ? UDMA3 : UDMA4;
		SetPioMode(PIO0);
		SetUdmaMode(udmaMode);		
	}

	return TRUE;

}

int SetAtaDevice(UINT32 uLBA, UINT32 uSectorCount)
{
	if (!(WriteOnTaskFileReg(DEV_SECTOR,uSectorCount&0xFF)))
		return FALSE;
	if (!(WriteOnTaskFileReg(DEV_LOWLBA,uLBA&0xFF)))
		return FALSE;
	if (!(WriteOnTaskFileReg(DEV_MIDLBA,(uLBA>>8)&0xFF)))
		return FALSE;
	if (!(WriteOnTaskFileReg(DEV_HIGHLBA,(uLBA>>16)&0xFF)))
		return FALSE;
	if (!(WriteOnTaskFileReg(DEV_DEVICE,((uLBA>>24)&0xF)|0x40)))
		return FALSE;

	return TRUE;
}


int AtaDiskRead(DWORD dStartSec, BYTE *pTargetBuf, UINT16 usNumSec)
{

//	Assert(uStBlock+uBlocks <= m_uMaxSectors);
	
	UINT32 k;
	ATA_MODE mode = g_eMode;
	int status;
        Lock();

    RETAILMSG(RTL_MSG,(TEXT("ATADISKREAD::: 0x%x 0x%x 0x%x \r\n"),dStartSec,pTargetBuf,usNumSec));
	switch(mode) 
	{
		case PIO_CPU:
			status = ReadSectors_Pio( dStartSec, pTargetBuf, usNumSec);
			break;
			
		case PIO_DMA:
			for(k=0; k<usNumSec; k++) 
			{
				ReadSector_PioDma(dStartSec+k, pTargetBuf+ATA_SECTORSIZE*k);
				WaitForTransferDone();
			}
			status = TRUE; // need to move..
			break;
			
		case UDMA:
                    status   = ReadSectors_Udma( dStartSec, pTargetBuf, usNumSec);
			//status = ReadSectors_Pio( dStartSec, pTargetBuf, usNumSec);
			break;
			
		default:
			RETAILMSG(1,(TEXT("Not supported mode in ReadBlocks()\n")));
			break;
	}
        UnLock();
	return status;
}

int  ReadSectors_Pio(DWORD dStartSec, BYTE *pTargetBuf, UINT16 usNumSec)
{

	UINT32 resCount;
	UINT32 remainCount;
	UINT32 goingLBA;
	UINT32 goingDstAddr;
	UINT32 wCount;
	UINT8* uAtaHostAddr;
	UINT32 i;
	
	remainCount = usNumSec;
	goingLBA = dStartSec;
	wCount = 0;	

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

		else 
		{
			resCount = remainCount;
			remainCount = 0;
		}

		goingLBA = dStartSec + wCount*256;

		uAtaHostAddr = pTargetBuf + wCount*256*ATA_SECTORSIZE;


		SetAtaDevice(goingLBA, resCount);
		WriteOnTaskFileReg(DEV_COMMAND, READSECTOR);
		
		while(resCount-- ) {
			if (!(WaitForNoBusyStatus()))
				return FALSE;
			for (i=0;i<ATA_SECTORSIZE/2;i++) {
				 GetByteDataFromDevice(uAtaHostAddr);
				 uAtaHostAddr+=2;
			}
		}
		if (!(WaitForNoBusyStatus()))
			return FALSE;
		wCount++;
	}
	return TRUE;
}


int PutDataToDevice(UINT16 *data) 
{
	if (!(WaitForDeviceAccessReady()))
		return FALSE;

	g_vATAPIRegs->ATA_PIO_DTR = *data;
	return TRUE;
}


int AtaDiskWrite(DWORD dStartSec, BYTE *pTargetBuf, UINT16 usNumSec)
{
//	Assert(uStBlock+uBlocks <= m_uMaxSectors);
	
	UINT32 k;
	ATA_MODE mode = g_eMode;
	int status;

    Lock();
    RETAILMSG(RTL_MSG,(TEXT("ATADISKWRITE::: 0x%x 0x%x 0x%x \r\n"),dStartSec,pTargetBuf,usNumSec));
	switch(mode) 
	{
		case PIO_CPU:
			status = WriteSector_Pio( dStartSec, pTargetBuf, usNumSec);
			break;
			
		case PIO_DMA:
			for(k=0; k<usNumSec; k++) 
			{
				ReadSector_PioDma(dStartSec+k, pTargetBuf+ATA_SECTORSIZE*k);
				WaitForTransferDone();
			}
			status = TRUE; // need to move..
			break;
			
		case UDMA:
			//status = WriteSector_Pio( dStartSec, pTargetBuf, usNumSec);
			status = WriteSectors_Udma( dStartSec, pTargetBuf, usNumSec);
			break;
			
		default:
			RETAILMSG(1,(TEXT("Not supported mode in ReadBlocks()\n")));
			break;
	}
    UnLock();
	return status;
}


int WriteSector_Pio(DWORD dStartSec, BYTE *pTargetBuf, UINT16 usNumSec)
{
	UINT32 resCount;
	UINT32 remainCount;
	UINT32 goingLBA;
	UINT32 goingSrcAddr;
	UINT32 wCount;
	UINT16* uAtaHostAddr;
	UINT32 i;
	
	remainCount = usNumSec;
	goingLBA = dStartSec;
	wCount = 0;	

	RETAILMSG(RTL_MSG,(TEXT("+++ ATADISK:::Write() Check Point 1.\r\n")));

	SetLittleEndian();
	
	while(remainCount != 0) 
	{
		if(remainCount>256) 
		{
			resCount = 256; //0 means 256
			remainCount -= 256;
		} 
		else 
		{
			resCount = remainCount;
			remainCount = 0;
		}
		goingLBA = dStartSec+ wCount*256;
		(UINT8 *)uAtaHostAddr =  pTargetBuf + wCount*256*ATA_SECTORSIZE;
		
		if (!(SetAtaDevice(goingLBA, resCount)))
		{
          	return FALSE;
		}
		
		if (!(WriteOnTaskFileReg(DEV_COMMAND, WRITESECTOR)))
		{
			return FALSE;
		}
		while(resCount-- ) 
		{	
			if (!(WaitForNoBusyStatus()))
			{
				return FALSE;
			}
        g_vIOPORTRegs->GPFDAT &= ~(3<<6);
        
			for (i=0;i<ATA_SECTORSIZE/2;i++) 
			{			
				if (!(PutDataToDevice(uAtaHostAddr)))
				{
					return FALSE;
				}
				uAtaHostAddr++;
			}
        g_vIOPORTRegs->GPFDAT |= (1<<6);            
		}		
		if (!(WaitForNoBusyStatus()))
        {
			return FALSE;
		}
		wCount++;
	}
	RETAILMSG(RTL_MSG,(TEXT("+++ ATADISK:::Write() Check Point 3.\r\n")));	
	return TRUE;
}

void SetAtaMode(ATA_MODE mode)
{
	g_eMode = mode;
}

int SetPioMode(PIOMODE  pmode) 
{
	UINT8 nMode = (pmode == PIO0) ? 0 :
				(pmode == PIO1) ? 1 :
				(pmode == PIO2) ? 2 :
				(pmode == PIO3) ? 3 :
				(pmode == PIO4) ? 4 : 0;
	
	UINT32 uT1;
	UINT32 uT2;
	UINT32 uTeoc;
	UINT32 i;
	
	UINT32 uPioTime[5];
	UINT32 m_uPioT1[5] = {200,50,30,50,30};    // min = {70,50,30,30,25};
	UINT32 m_uPioT2[5] = {300,300,290,100,70}; // min = {290,290,290,80,70};
	UINT32 m_uPioTeoc[5] = {100,40,20,30,20};  // min = {20,15,10,10,10};
	
	UINT32 uCycleTime = (UINT32)(1000000000/S3C2443_HCLK);


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


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

	switch(pmode) { // modified by Bryan W. Lee (Oct. 19th, 2005)
		case PIO1:
			g_uCfgReg &= (~0x2); //IORDY disable
			g_vATAPIRegs->ATA_PIO_TIME=uPioTime[1];
			break;
		case PIO2:
			g_uCfgReg &= (~0x2); //IORDY disable
			g_vATAPIRegs->ATA_PIO_TIME=uPioTime[2];

			break;
		case PIO3:
			g_uCfgReg |= 0x2; //IORDY enable
			g_vATAPIRegs->ATA_PIO_TIME=uPioTime[3];			
			break;
		case PIO4:
			g_uCfgReg |= 0x2; //IORDY enable
			g_vATAPIRegs->ATA_PIO_TIME=uPioTime[4];
			break;
		default:
			g_uCfgReg &= (~0x2); //IORDY disable
			g_vATAPIRegs->ATA_PIO_TIME=uPioTime[0];
			break;
		}
	g_vATAPIRegs->ATA_CFG = g_uCfgReg;
	//Outp32(ATA_CFG, m_uCfgReg);
	g_oDevice[0].CurrentPioMode = nMode;

	return TRUE;

}

//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(UINT32 nSector) 
{

⌨️ 快捷键说明

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