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

📄 atapi.c

📁 三星公司 2440 开发板 wince 5.0 BSP
💻 C
📖 第 1 页 / 共 2 页
字号:
		g_vATAPIRegs->ATA_CONTROL = temp | 0x1;
	else if(OnOff == 0)
		//Outp32(ATA_CONTROL, temp &0xfffffffe);
		g_vATAPIRegs->ATA_CONTROL = temp & 0xfffffffe;*/
}

void Init(void)
{

	SetAtaOnOff(1);
	g_uCfgReg = 0;
	//jungpil
	CheckDevice(); 	
}

int OpenMedia(ATA_MODE mode)
{

	Init();
	
	if (!(IdentifyDevice()))
	{
        RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : IdentifyDevice Error\r\n")));
        return FALSE;
	}
	

	SetAtaMode(mode);
	if (mode == PIO_CPU || mode == PIO_DMA)
	{
		//RETAILMSG(RTL_MSG, (TEXT("### ATAPI MAXPIOMODE %d\r\n"),g_oDevice[0].MaxPioMode));	
		if (!(SetPioMode(g_oDevice[0].MaxPioMode)))
			return FALSE;
	}
	else 
	{
		UDMAMODE 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 waitDRQ(void)
{    
    UINT8 bStatus;
    UINT32 timeoutCount=MAX_DELAY_BUSY_TO_DRQ;            
    do
    {
        bStatus = g_vATAPIRegs->ATA_PIO_DAD;
        if (bStatus & 0x80) 
        {
        }
        else if(bStatus & 0x01) 
        {
            RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : ERROR in waitDRQ %x\r\n"),bStatus));    
            return DRQ_ERROR;
        }
        else if(bStatus & 0x08)
        {
            return DRQ_OK;
        }
        else // some wrong state
        {
        }
    }while(--timeoutCount);
    return DRQ_TIMEOUT;
}


int AtaDiskRead(DWORD dStartSec, BYTE *pTargetBuf, UINT16 usNumSec)
{
	UINT32 resCount;
	UINT32 remainCount;
	UINT32 goingLBA;
	UINT32 wCount;
	UINT8* pTargetBuffer;
	UINT32 i;
    UINT16 tempRead;
    UINT8 bStatus;
    
L_READ_AGAIN:;

	remainCount = usNumSec;
	goingLBA = dStartSec;
	wCount = 0;	

//    RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : READ Sector from:%d num:%d\r\n"),dStartSec,usNumSec));    

	while(remainCount != 0) 
	{
		if(remainCount>256) 
		{
			resCount = 256; //0 means 256
			remainCount -= 256;
		} 
		else 
		{
			resCount = remainCount;
			remainCount = 0;
		}
		goingLBA = dStartSec + wCount*256;
		pTargetBuffer = pTargetBuf + wCount*256*ATA_SECTORSIZE;


		if (!(SetAtaDevice(goingLBA, resCount)))
			return FALSE;
		if (!(WriteOnTaskFileReg(DEV_COMMAND, READSECTOR)))
			return FALSE;

		while(resCount-- ) 
		{
            int retWait = waitDRQ();
            if(retWait == DRQ_TIMEOUT) goto L_READ_AGAIN;
            else if(retWait == DRQ_ERROR) return FALSE;
            
			for (i=0;i<ATA_SECTORSIZE/2;i++) 
			{
                tempRead = g_vATAPIRegs->ATA_PIO_DAT;
                *pTargetBuffer++ = (UINT8)(tempRead&0xFF);
                *pTargetBuffer++ =(UINT8)((tempRead>>8)&0xFF);
/*                if(i == 0) 
                    RETAILMSG(RTL_MSG, (TEXT("%02X %02X\n"),tempRead & 0xff, (tempRead>>8)&0xFF));  */
			}
            //            bStatus = g_vATAPIRegs->ATA_PIO_CSD; // clear pending interrupt
		}
		if (!(WaitForNoBusyStatus()))
			return FALSE;
		wCount++;
	}
    bStatus = g_vATAPIRegs->ATA_PIO_CSD; // clear pending interrupt

#define CHECK_READ_SECNUM
#ifdef CHECK_READ_SECNUM    
    {
        DWORD secNumRead;
        secNumRead = (g_vATAPIRegs->ATA_PIO_LLR)				& 0x000000ff | 
                     (g_vATAPIRegs->ATA_PIO_LMR << 8)			& 0x0000ff00 | 
                     (g_vATAPIRegs->ATA_PIO_LHR << 16)			& 0x00ff0000 | 
                     ((g_vATAPIRegs->ATA_PIO_DVR & 0x0f) <<24)	& 0xff000000;
        if((dStartSec + usNumSec - 1) != secNumRead)
        {
//            RETAILMSG(RTL_MSG, (TEXT("AGAIN!!! sec:%d num:%d last:%d\n"), dStartSec, usNumSec, secNumRead));
            goto L_READ_AGAIN;
        }

    }
#endif
	return TRUE;
}

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

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


int AtaDiskWrite(DWORD dStartSec, BYTE *pTargetBuf, UINT16 usNumSec)
{
	UINT32 resCount;
	UINT32 remainCount;
	UINT32 goingLBA;
	UINT32 wCount;
	UINT16* pTargetBuffer;
	UINT32 i;
    UINT32 numReCommand;
    UINT8 bStatus;

L_WRITE_AGAIN:;

    numReCommand = 0;
	remainCount = usNumSec;
	goingLBA = dStartSec;
	wCount = 0;	

	while(remainCount != 0) 
	{
		if(remainCount>256) 
		{
			resCount = 256; //0 means 256
			remainCount -= 256;
		} 
		else 
		{
			resCount = remainCount;
			remainCount = 0;
		}
		goingLBA = dStartSec+ wCount*256;
		(UINT8 *)pTargetBuffer =  pTargetBuf + wCount*256*ATA_SECTORSIZE;
		
		if (!(SetAtaDevice(goingLBA, resCount)))
			return FALSE;
		if (!(WriteOnTaskFileReg(DEV_COMMAND, WRITESECTOR)))
			return FALSE;

		while(resCount-- ) 
		{	
            int retWait = waitDRQ();
            if(retWait == DRQ_TIMEOUT) goto L_WRITE_AGAIN;
            else if(retWait == DRQ_ERROR) return FALSE;

			for (i=0;i<ATA_SECTORSIZE/2;i++) 
			{			
                g_vATAPIRegs->ATA_PIO_DAT= *pTargetBuffer;
                pTargetBuffer++;
			}
		}		
		if (!(WaitForNoBusyStatus()))
			return FALSE;

		wCount++;
	}
    bStatus = g_vATAPIRegs->ATA_PIO_CSD; // clear pending interrupt
	//RETAILMSG(RTL_MSG,(TEXT("+++ ATADISK:::Write() Check Point 3.\r\n")));	
	return TRUE;
//Need CHECK_READ_SECNUM ??? 

}

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

int SetPioMode(PIOMODE  pmode) 
{
    UINT8 bStatus;
	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/S3C2440A_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;
	}
	
//	g_vATAPIRegs->ATA_IRQ=0xff;
//	g_vATAPIRegs->ATA_IRQ_MASK = ATAPI_MASK;


	if (!(WriteOnTaskFileReg(DEV_CONTROL,0)))
		return FALSE;
	if (!(WriteOnTaskFileReg((UINT8 *)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
//    if (!(WriteOnTaskFileReg(DEV_SECTOR,1))) // 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;
    bStatus = g_vATAPIRegs->ATA_PIO_DAD;
    RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : Set PIO Mode %x\r\n"),bStatus));   

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

// jungpil can't understand. initial values are all zero
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;
}

void CFHDDTest()
{
    AtapiDeviceInit();

}

⌨️ 快捷键说明

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