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

📄 atapi.c

📁 2443 wince5.0 bsp, source code
💻 C
📖 第 1 页 / 共 3 页
字号:
	g_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 SetUdmaMode(UDMAMODE umode) 
{
	UINT8 nMode;
	UINT32 uTdvh1;
	UINT32 uTdvs;
	UINT32 uTrp;
	UINT32 uTss;
	UINT32 uTackenv;
	UINT32 i;

	UINT32 uUdmaTime[5];
	UINT32 uUdmaTdvh[5] = {20,20,10,10,10}; //{7,7,7,7,7};
	UINT32 uUdmaTdvs[5] = {100,60,50,35,20}; //{70,48,31,20,7};
	UINT32 uUdmaTrp[5] = {160,125,100,100,100};
	UINT32 uUdmaTss[5] = {50,50,50,50,50};
	UINT32 uUdmaTackenvMin[5] = {20,20,20,20,20};
	UINT32 uUdmaTackenvMax[5] = {70,70,70,55,55};	
	UINT32 uCycleTime = (UINT32)(1000000000/S3C2443_HCLK);

#ifdef __EVT1
	g_vIOPORTRegs->GPADAT &= ~(1<<5); // GPA10 RDATA_fOEN setting
//	rGPACDH = 0xaa8a; // GPA10 RDATA_OEN setting
//	rGPBCON = rGPBCON & ~(3<<12) | (1<<12); // GPB6 output setting (nXBREQ)
//	rGPBDAT &= ~(1<<6); // GPB6 -> L, buffer Output enable 
#else
	g_vIOPORTRegs->GPBCON = (g_vIOPORTRegs->GPBCON & ~(0xf<<10)) | (5<<10); // GPB5,6 output mode
	g_vIOPORTRegs->GPBCON = (g_vIOPORTRegs->GPBCON &  ~(0x3<<8)) |( 1<<8); // GPB4 output mode		
	g_vIOPORTRegs->GPBCON = (g_vIOPORTRegs->GPBCON &  ~(0x3<<0)) |( 1<<0); // GPB4 output mode			
	g_vIOPORTRegs->GPBDAT |= (3<<5); // GPB5,6 -> H	
#endif	
	
//	ChangeBufferControl(PIO_CPU);    
	
	for (i=0; i<5; i++)
	{
		uTdvh1	= (uUdmaTdvh[i] / uCycleTime + 1)&0x0f;
		uTdvs	= (uUdmaTdvs[i] / uCycleTime + 1)&0xff;
		uTrp	= (uUdmaTrp[i]  / uCycleTime + 1)&0xff;
		uTss	= (uUdmaTss[i]  / uCycleTime + 1)&0x0f;
		uTackenv= (uUdmaTackenvMin[i]/uCycleTime + 1)&0x0f;
		uUdmaTime[i] = (uTdvh1<<24)|(uTdvs<<16)|(uTrp<<8)|(uTss<<4)|uTackenv;
//		DbgAta(("UDMA%dTIME = %x\n", i, uUdmaTime[i]));
	}	

       g_vATAPIRegs->ATA_IRQ_MASK=0xfffffffe;
        g_vATAPIRegs->ATA_IRQ =0xff;

        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();

	
	switch(umode) {
		case UDMA0:
			nMode = 0;
                    g_vATAPIRegs->ATA_UDMA_TIME = uUdmaTime[0];
			break;		
		case UDMA1:
			nMode = 1;
                    g_vATAPIRegs->ATA_UDMA_TIME = uUdmaTime[1];
			break;
		case UDMA2:
			nMode = 2;
                    g_vATAPIRegs->ATA_UDMA_TIME = uUdmaTime[2];
			break;
		case UDMA3:
			nMode = 3;
                    g_vATAPIRegs->ATA_UDMA_TIME = uUdmaTime[3];
			break;
		case UDMA4:
			nMode = 4;
                    g_vATAPIRegs->ATA_UDMA_TIME = uUdmaTime[4];
			break;
		default:
                    RETAILMSG(1,(TEXT("UDMA mode is supported between 0 to 4 !!!! . %d\r\n"),umode));
			break;
		}
	g_oDevice[0].CurrentUdmaMode = nMode;
	

}



int CheckDevice(void) 
{
	UINT8 rRead;

	if (!(ReadDeviceReg(DEV_SECTOR, &rRead)))
		return FALSE;
	if (rRead != 0x10) 
		g_oDevice[0].DeviceType = ATA_ABSENT;
	
	if (!(ReadDeviceReg(DEV_LOWLBA, &rRead)))
		return FALSE;
	if (rRead != 0x10) 
		g_oDevice[0].DeviceType = ATA_ABSENT;

	if (!(ReadDeviceReg(DEV_MIDLBA, &rRead)))
		return FALSE;
	if (rRead == 0x00) {
		g_oDevice[0].DeviceType = ATA_ATA;
		//DbgAta(("ATA_ATA\n"));
	}
	else if(rRead == 0x14) 
		g_oDevice[0].DeviceType = ATA_ATAPI;

	return TRUE;
}


int ReadSector_PioDma(UINT32 uLBA, UINT32 uDesAddress) 
{

	if (!(StartReadingBlocks(uLBA,  0x1, uDesAddress)))
		return FALSE;	
	return IsReadingBlocksDone();
}

int StartReadingBlocks(UINT32 uStBlock, UINT32 uBlocks, UINT32 uBufAddr)
{

	UINT32 deviceCmd = (g_eMode == UDMA) ? READDMA : READSECTOR;
	RETAILMSG(RTL_MSG,(TEXT("### Current MOde is %d %d\r\n"),g_eMode,PIO_DMA));
	
	/*Track Buffer 1 Setting*/
	g_vATAPIRegs->ATA_TBUF_START = (UINT32)PIODMA_BUFFER_PA;
	g_vATAPIRegs->ATA_TBUF_SIZE = uBlocks*ATA_SECTORSIZE;
	g_vATAPIRegs->ATA_XFR_NUM = (uBlocks*ATA_SECTORSIZE);

	if (!(SetAtaDevice(uStBlock, uBlocks)))
		return FALSE;
	if (!(WriteOnTaskFileReg(DEV_COMMAND, deviceCmd)))
		return FALSE;
	if (!(WaitForNoBusyStatus()))
		return FALSE;
	
	SetConfigMode(g_eMode,FALSE);

//	ChangeBufferControl(UDMA);
#if 0
 	if (g_eMode == UDMA) // apply at specific set using buffer control
	{
		SetBufferDirection(READDMA);
	}   
#endif	
	if (!(SetTransferCommand(ATA_CMD_START)))
		return FALSE;
	return TRUE;
}

#if 0
void ChangeBufferControl(ATA_MODE mode) // added by junon for second UDMA test b'd 060902
{
	if (mode == UDMA)
	{
            g_vIOPORTRegs->GPBDAT = g_vIOPORTRegs->GPBDAT & ~((1<<4)|(1)); // GPB0->low,GPB1->low => UDMA mode 	
	}
	else // PIO
       {
            g_vIOPORTRegs->GPBDAT = g_vIOPORTRegs->GPBDAT & ~((1<<4) |(1))|(1<<4); // GPB0->low,GPB1->high => ATA mode	  	
	}
}
#endif


#if 0
void SetBufferDirection(UINT32 uDirection) // only for SMDK b'd 060812
{
	switch(uDirection)
	{
		case READDMA :
			g_vIOPORTRegs->GPBDAT &= ~(3<<5); // GPB5 -> L, buffer direction - read setting 
								// GPB6 -> L, buffer Output enable 
			break;
		case WRITEDMA :
			g_vIOPORTRegs->GPBDAT |= (1<<5); 	// GPB5 -> H, buffer direction - write setting 
			g_vIOPORTRegs->GPBDAT &= ~(1<<6); // GPB6 -> L, buffer Output enable 060812
			break;
		default : // clear
			g_vIOPORTRegs->GPBDAT |= (3<<5); 	// GPB5 -> H, buffer direction - write setting 
								// GPB6 -> H, buffer Output disable 
			break;
	}		
}
#endif

int ReadSectors_Udma(DWORD dStartSec, BYTE *pTargetBuf, UINT16 usNumSec)
{
	UINT32 uCurrentCount;
	UINT32 uRemainderCount;
	UINT32 uCurrentLba;
	UINT32 uCurrentDstAddr;
	UINT32 uRound,uLoop;
    UINT32 start_time;
    UINT32 end_time;
       int dwRet;

        RETAILMSG(RTL_MSG,(TEXT("ReadSectors_Udma::: 0x%x 0x%x 0x%x \r\n"),dStartSec,pTargetBuf,usNumSec));

	uRemainderCount = usNumSec;
	uRound = 0;	

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

#ifdef USE_MUTEX
            GetMutex(g_hMutex);
#endif //USE_MUTEX
            StartReadingBlocks(uCurrentLba, uCurrentCount, uCurrentDstAddr);
 //           IsReadingBlocksDone();

#if 1            
    dwRet = WaitForSingleObject(g_hATAEvent, 1000);  // time out 1sec

    if ( dwRet != WAIT_OBJECT_0 )
    {
        RETAILMSG(1,(TEXT("### ATA_INTERRUPT IS NOT OCCURED.\nATA_IRQ 0x%x ATA_IRQMASK 0x%x ATA_XFR_CNT 0x%x\r\n"),g_vATAPIRegs->ATA_IRQ,g_vATAPIRegs->ATA_IRQ_MASK,g_vATAPIRegs->ATA_XFR_CNT));        
        return FALSE;
    }

    if (!(IsDmaDone()))
        return FALSE;
    InterruptDone(g_dwATASysIrq);
//    RETAILMSG(1,(TEXT("ATA_IRQ 0x%x ATA_IRQMASK 0x%x ATA_XFR_CNT 0x%x\r\n"),g_vATAPIRegs->ATA_IRQ,g_vATAPIRegs->ATA_IRQ_MASK,g_vATAPIRegs->ATA_XFR_CNT));
    
#endif            

#ifdef USE_MUTEX
            ReleaseMutex(g_hMutex);
#endif //USE_MUTEX

                memcpy((PBYTE)uCurrentDstAddr,g_vDmaBuffer,uCurrentCount*ATA_SECTORSIZE);
            uRound++;
	}

	return TRUE;
}


int WriteSectors_Udma(DWORD dStartSec, BYTE *pTargetBuf, UINT16 usNumSec)
{
	UINT32 uCurrentCount;
	UINT32 uRemainderCount;
	UINT32 uCurrentLba;
	UINT32 uCurrentSrcAddr;
	UINT32 uRound;
    DWORD dwRet;
	
	uRemainderCount = usNumSec;
	uRound = 0;	

	
	while(uRemainderCount != 0) {
		if(uRemainderCount>256) {
			uCurrentCount = 256; //0 means 256
			uRemainderCount -= 256;
		} else {
			uCurrentCount = uRemainderCount;
			uRemainderCount = 0;
		}
		uCurrentLba = dStartSec + uRound*256;
		uCurrentSrcAddr = pTargetBuf + uRound*256*ATA_SECTORSIZE;
                memcpy(g_vDmaBuffer,(PBYTE)uCurrentSrcAddr,uCurrentCount*ATA_SECTORSIZE);

#ifdef USE_MUTEX
            GetMutex(g_hMutex);
#endif //USE_MUTEX

//        RETAILMSG(1,(TEXT("INTPEND = %x
		StartWritingBlocks(uCurrentLba, uCurrentCount, uCurrentSrcAddr);
//		IsWritingBlocksDone();
#if 1
        dwRet = WaitForSingleObject(g_hATAEvent, 1000);  // time out 1sec

        if ( dwRet != WAIT_OBJECT_0 )
        {
            RETAILMSG(1,(TEXT("### ATA_INTERRUPT IS NOT OCCURED.\nATA_IRQ 0x%x ATA_IRQMASK 0x%x ATA_XFR_CNT 0x%x\r\n"),g_vATAPIRegs->ATA_IRQ,g_vATAPIRegs->ATA_IRQ_MASK,g_vATAPIRegs->ATA_XFR_CNT));        
            return FALSE;
        }

        if (!(IsDmaDone()))
            return FALSE;
        InterruptDone(g_dwATASysIrq);
#endif

#ifdef USE_MUTEX
            ReleaseMutex(g_hMutex);
#endif //USE_MUTEX

               uRound++;

	}

	return TRUE;
}

void SetConfigMode(ATA_MODE mode, int isWriteMode)
{
	switch(mode)
	{
		case PIO_CPU:
			g_uCfgReg = ((g_uCfgReg&0x1F3) | (0<<2)); // set PIO_CPU class
			break;
		case PIO_DMA:
			g_uCfgReg = ((g_uCfgReg&0x1F3) | (1<<2)); // set PDMA class
			if (isWriteMode == TRUE)
				g_uCfgReg |= 0x10; // DMA write mode
			else
				g_uCfgReg &= (~0x10); // DMA read mode
			break;
		case UDMA:
			g_uCfgReg = ((g_uCfgReg&0x1F3) | (2<<2)); // set UDMA class
			g_uCfgReg |= 0x200; // set ATA DMA auto mode (enable multi block transfer)
			if (isWriteMode == TRUE)
				g_uCfgReg |= 0x10; // DMA write mode
			else
				g_uCfgReg &= (~0x10); // DMA read mode
			break;
		default:
			break;
	}
	g_vATAPIRegs->ATA_CFG = g_uCfgReg;
}

int SetTransferCommand(ATA_TRANSFER_CMD command)
{
	UINT8 cmd = (command == ATA_CMD_STOP) ? 0 :
			(command == ATA_CMD_START) ? 1 :
			(command == ATA_CMD_ABORT) ? 2 : 3;
	if (!(WaitForDeviceAccessReady()))
		return FALSE;
	g_vATAPIRegs->ATA_COMMAND = cmd;
	return TRUE;
}


int IsReadingBlocksDone(void)
{
	RETAILMSG(RTL_MSG,(TEXT("### PIO_DMA Check Point 3.\r\n")));
	return IsWritingBlocksDone();
}

int IsWritingBlocksDone(void)
{
	RETAILMSG(RTL_MSG,(TEXT("### PIO_DMA Check Point 4.\r\n")));
	if (!(WaitForTransferDone()))
		return FALSE;	
	RETAILMSG(RTL_MSG,(TEXT("### PIO_DMA Check Point 6.\r\n")));
	return IsDmaDone();
}

int WaitForTransferDone(void)
{
	UINT32 x;
	UINT32 count=1;
	UINT16 retVal=TRUE;

	do {
		count++;

		if(!(WaitForDeviceAccessReady()))	// timeout
			return FALSE; 
		if(count == 10000000 )					// timeout
		{
			retVal = FALSE;
			break;
		}

		x = g_vATAPIRegs->ATA_STATUS;
	} while((x & 3)!=0);

	return retVal;
}

int IsDmaDone(void)
{
	if (!(SetTransferCommand(ATA_CMD_ABORT)))
		return FALSE;
	RETAILMSG(RTL_MSG,(TEXT("### PIO_DMA Check Point 7.\r\n")));
//       SetBufferDirection(0); // clear to H
//       ChangeBufferControl(PIO_CPU);
    
	SetConfigMode(PIO_CPU, TRUE);
	RETAILMSG(RTL_MSG,(TEXT("### PIO_DMA Check Point 8.\r\n")));
	if (!(WaitForNoBusyStatus()))
		return FALSE;
	RETAILMSG(RTL_MSG,(TEXT("### PIO_DMA Check Point 9.\r\n")));

	if (g_eMode == UDMA)
	{
		g_uCfgReg &= (~0x200); // disable ATA DMA auto mode
		g_vATAPIRegs->ATA_CFG = g_uCfgReg;
	}
	return TRUE;
}


int WriteSector_PioDma(UINT32 uLBA, UINT32 uSrcAddress) 
{

	if (!(StartWritingBlocks(uLBA, 1, uSrcAddress)))
		return FALSE;
	return IsWritingBlocksDone();
}

int StartWritingBlocks(UINT32 uStBlock, UINT32 uBlocks, UINT32 uBufAddr)
{

	UINT32 deviceCmd = (g_eMode == UDMA) ? WRITEDMA : WRITESECTOR;

	g_vATAPIRegs->ATA_SBUF_START = (UINT32)PIODMA_BUFFER_PA;
	g_vATAPIRegs->ATA_SBUF_SIZE = uBlocks*ATA_SECTORSIZE;
	g_vATAPIRegs->ATA_XFR_NUM = uBlocks*ATA_SECTORSIZE;

	if (!(SetAtaDevice(uStBlock, uBlocks)))
		return FALSE;
	if (!(WriteOnTaskFileReg(DEV_COMMAND, deviceCmd)))
		return FALSE;

	if (!(WaitForNoBusyStatus()))
		return FALSE;
	
	SetConfigMode(g_eMode,TRUE);
//	ChangeBufferControl(UDMA);
#if 0    
	if (g_eMode == UDMA) // apply at specific set using buffer control
	{
		SetBufferDirection(WRITEDMA); // for SMDK buffer direction only
	}
#endif

	if (!(SetTransferCommand(ATA_CMD_START)))
		return FALSE;
	
	return TRUE;

}

⌨️ 快捷键说明

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