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

📄 ata_driver.c

📁 微机+CF卡+SD卡+USB的开发示例希望大家能用
💻 C
📖 第 1 页 / 共 3 页
字号:
		return (kCSWPhaseError);
	}	

	if (mCheckBit(ATAERR,Status))		// ATA error found
	{
		Status = ATA_DER_B;
		error = ATA_WaitRegBusy();
		if (error)
			return(error);
		Status = ATA_DER_B;
			
		if (mCheckBit(ATAICRC,Status))	// CRC error
		{
			gATAError = kSCSISKRecoveredError;
		}	
		else 
		{
			if (mCheckBit(ATAUNC,Status))	// uncorrectable data
			{	
				gATAError = kSCSISKMediumError;
			}
			else
			{
				if ( (Status & (1<<ATAMC)) | (Status & (1<<ATAMCR)))	// media changed
				{
				gATAError = kSCSISKUnitAttention;
				}
				else
				{
					if (mCheckBit(ATAABRT,Status))
					{
						gATAError = kSCSISKAbortedCommand;
					}
					else
					{
						if (mCheckBit(ATANM,Status))
						{
							gATAError =	kSCSISKNotReady;
						}
						else
							return(kCSWPass);
					}		
				}		
			}	
		}	
		return(kCSWFailed);		
    }	
	return(kCSWPass);
}

// ==================================================================
//   ATA_WaitATABusyDRQ() -
//
//     To wait until device not busy
//
//	Input -		=	nil
//				
//	Output - 	=	nil
//
//	Function returns error code
//
// ==================================================================

ATAErrorCode ATA_WaitATABusyDRQ()
{
    muint16 BegTime, CurTime;
    muint8	Status;
    ATAErrorCode	error;
    
	BegTime = MK_GetCurrentTime();		// begin time
	do
	{
		error = ATA_WaitRegBusy();
		if (error)
			return(error);
		
		Status = ATA_DSR_B;				// get Status register
		error = ATA_WaitRegBusy();
		if (error)
			return(error);
		Status = ATA_DSR_B;
	    
	    if ( mCheckBit(ATABSY,Status) ^ mCheckBit(ATADRQ,Status))
			return(kATAPass);

//	    if (mCheckBit(ATADRQ,Status))
//	    	return(kATAPass);						// exit if not busy
	    	
		CurTime = MK_GetCurrentTime();	// current time
	}
	while ( ((CurTime-BegTime) < kATATimeout) || ((BegTime - CurTime) < kATATimeout));

	if (mCheckBit(ATABSY,Status))		// ATA still busy, timeout
	{
		#ifdef	__kEnableSciDebugger__
			(void)MK_Debug_StrPrint((muint8*)"ATA Device Timout!\r\n");
			ATA_Delay(100);
		#endif
		gATAError = kSCSISKHardwareError;	// timeout => hardware error
		return(kCSWPhaseError);
	}

	if (mCheckBit(ATADF,Status))		// ATA Device Fault
	{
		gATAError = kSCSISKHardwareError;	// device fault => hardware error
		return (kCSWPhaseError);
	}	

	if (mCheckBit(ATAERR,Status))		// ATA error found
	{
		#ifdef	__kEnableSciDebugger__
			(void)MK_Debug_StrPrint((muint8*)"ATA Device Error!\r\n");
			ATA_Delay(100);
		#endif	

		Status = ATA_DER_B;
		error = ATA_WaitRegBusy();
		if (error)
			return(error);
		Status = ATA_DER_B;
			
		if (mCheckBit(ATAICRC,Status))	// CRC error
		{
			gATAError = kSCSISKRecoveredError;
		}	
		else 
		{
			if (mCheckBit(ATAUNC,Status))	// uncorrectable data
			{	
				gATAError = kSCSISKMediumError;
			}
			else
			{
				if ( (Status & (1<<ATAMC)) | (Status & (1<<ATAMCR)))	// media changed
				{
				gATAError = kSCSISKUnitAttention;
				}
				else
				{
					if (mCheckBit(ATAABRT,Status))
					{
						gATAError = kSCSISKAbortedCommand;
					}
					else
					{
						if (mCheckBit(ATANM,Status))
						{
							gATAError =	kSCSISKNotReady;
						}
					}		
				}		
			}	
		}	
		return(kCSWFailed);		
    }	
	return(kCSWPass);
}


// ==================================================================
//   ATA_SetRPIOTiming() -
//
//     To set PIO timing read/write for register
//
//	Input -		=	pio mode (0 - 4)
//				
//	Output - 	=	nil
//
//	Function returns: nil
//
// ==================================================================
void ATA_SetRPIOTiming(muint8 pio)
{
	ATA_SetPIOTiming(pio);
	ATA_PIO1 = kATARPIOReg1[pio];
}


// ==================================================================
//   ATA_SetPIOTiming() -
//
//     To set PIO timing read/write for data 
//
//	Input -		=	pio mode (0 - 4)
//				
//	Output - 	=	nil
//
//	Function returns: nil
//
// ==================================================================
void ATA_SetPIOTiming(muint8 pio)
{
	ATA_PIO1 = kATAPIOReg1[pio];
	ATA_PIO2 = kATAPIOReg2[pio];
	ATA_PIO3 = kATAPIOReg3[pio];
	ATA_PIO4 = kATAPIOReg4[pio];
}


// ==================================================================
//   ATA_SetUDMATiming() -
//
//     To set UDMA timing read/write for dat
//
//	Input -		=	udma mode (0 - 4)
//				
//	Output - 	=	nil
//
//	Function returns: nil
//
// ==================================================================
void ATA_SetUDMATiming(muint8 udma)
{
	ATA_UDMA1 = kATAUDMAReg1[udma];
	ATA_UDMA2 = kATAUDMAReg2[udma];
	ATA_UDMA3 = kATAUDMAReg3[udma];
	ATA_UDMA4 = kATAUDMAReg4[udma];
	ATA_UDMA5 = kATAUDMAReg5[udma];
	ATA_UDMA6 = kATAUDMAReg6[udma];
	ATA_UDMA7 = kATAUDMAReg7[udma];
	ATA_UDMA8 = kATAUDMAReg8[udma];
	ATA_UDMA9 = kATAUDMAReg9[udma];
}


// ==================================================================
//   ATA_SetMDMATiming() -
//
//     To set Multi-Word DMA timing read/write for dat
//
//	Input -		=	MDMA mode (0 - 2)
//				
//	Output - 	=	nil
//
//	Function returns: nil
//
// ==================================================================

void ATA_SetMDMATiming(muint8 mdma)
{
	ATA_DMA1 = kATAUDMAReg1[mdma];
	ATA_DMA2 = kATAUDMAReg2[mdma];
	ATA_DMA3 = kATAUDMAReg3[mdma];
	ATA_DMA4 = kATAUDMAReg4[mdma];
}

// ==================================================================
//   ATA_GetDeviceInfo() -
//
//     Get device information and do the initization
//
//	Input -		= NIL
//				
//	Output - 	= Data wrote to ATA device	
//
//	Function returns ATA error code
//
// ==================================================================
ATAErrorCode ATA_GetSetDeviceInfo()
{
	muint16	*pBuffer;
	muint8	LBAHigh, LBAMid, UDMAMode;
	volatile ATAErrorCode  error;
	sATACommand	sATACmd;

	pBuffer = (muint16 *) (kIQUERAMBegin+0x400);

	ATA_DDHR = 0;
	error = ATA_WaitRegBusy();
	if (error)
		return(error);

	LBAMid = ATA_LBAM_B;
	error = ATA_WaitRegBusy();
	if (error)
		return(error);
	LBAMid	= ATA_LBAM_B;

	LBAHigh = ATA_LBAH_B;
	error = ATA_WaitRegBusy();
	if (error)
		return(error);
	LBAHigh	= ATA_LBAH_B;

	error = ATA_WaitATABusy();
	if (error)
		return(error);

//	INITEE = 0x21;

	if ((LBAHigh==0xeb) && (LBAMid==0x14))
		mSetBit(bitATAATAPI,gATADevInfo);	// ATAPI device

	else									// ATA device
		gATADevInfo = 0;					// ATA device

	UTL_LoopDelay(0x1000);

	error = ATA_IdentifyDevice(pBuffer, 0x100);
	if (error)
		return (error);
		
	if ( pBuffer[kATADevInfoGen] & kBit8)
		gATAPacketLen = 8;				// 8 word packet length
	else
		gATAPacketLen = 6;				// 6 word	
		
	gATAPIOMode = (muint8) (pBuffer[kATADevInfoPIO] >> kOneByte);

	if ((*pBuffer != 0x8a84) && (!gATAPIOMode || (gATAPIOMode>4)))
		return(kCSWFailed);

	gATAMaxCapacity = (muint32) (pBuffer[kATADevInfoMaxCap+1]) << kThreeByte \
					| (pBuffer[kATADevInfoMaxCap+1]) >>kOneByte ;
	gATAMaxCapacity = (gATAMaxCapacity << kTwoByte) \
					| (pBuffer[kATADevInfoMaxCap]) << kOneByte | (pBuffer[kATADevInfoMaxCap]) >> kOneByte;
	gATAMaxCapacity--;					

	sATACmd.features = kATAFCmdSetTransfer;
	sATACmd.lba_low = 0;
	sATACmd.lba_mid = 0;
	sATACmd.lba_high = 0;
	sATACmd.device = 0;
	sATACmd.command = kATACmdSetFeatures;
	sATACmd.dmamode = 0;

	if (gATAPIOMode)
	{
		do
		{
			sATACmd.count = kATAPIO2Mode[gATAPIOMode];
			error = ATA_Command(&sATACmd);

			if (!error)
			{
				ATA_SetPIOTiming(gATAPIOMode);
			}
			else	// error happen
			{
				if (!gATAPIOMode--)			// if error happens and ATAPIOMode = 0)
					return (kATASetPIOError);
			}
		}
		while (error);
	}
	
	UDMAMode = (muint8) (pBuffer[kATADevInfoUDMA] >> 8) & 0x1f;

	if (UDMAMode)
	{
//		UDMAMode=0x7;
		
		if (UDMAMode & kBit0)
			gATAUDMAMode = 0;
		if (UDMAMode & kBit1)
			gATAUDMAMode = 1;
		if (UDMAMode & kBit2)
			gATAUDMAMode = 2;
		if (UDMAMode & kBit3)
			gATAUDMAMode = 3;
		if (UDMAMode & kBit4)
			gATAUDMAMode = 4;
	
		do
		{
			sATACmd.count = kATAUDMA2Mode[gATAUDMAMode];
			error = ATA_Command(&sATACmd);

			if (!error)
			{
				ATA_SetUDMATiming(gATAUDMAMode);
				mSetBit(bitATAUDMAMode,gATAStatus);
			}
			else	// error happen
			{
				if (!gATAUDMAMode--)			// if error happens and ATAPIOMode = 0)
					return (kATASetPIOError);
			}
		}
		while (error);
	}

	return (ATA_WaitATABusy());

}

void ATA_FillNZero(muint16 XferWordLen)
{
	muint16 i;
	
	for (i=0; i<XferWordLen; i++)
	{
		ATA_DDR = 0x0000;
		(void) ATA_WaitRegBusy();
	}	
}

void ATA_UDMARead(muint8 pIQUEBuffer)
{
	mSetBit(DBRST,QC34DCR);						// reset QC34 double buffer
	QC3SZB = 0x10 | pIQUEBuffer;
	QC3REQ = kQCREQUSBTx;
	QC4REQ	= kQCREQATARx;						// QC3 = ATA Tx

	while (!mCheckBit(ATAINTRQ,PORTS));
	(void) ATA_WaitATABusy();


	QC3REQ	= kQCREQNone;						// QC1 = none
	QC4REQ	= kQCREQNone;						// QC2 = none
	(void) ATA_WaitATABusy();
}		



void ATA_UDMAWrite(muint8 pIQUEBuffer)
{
	mSetBit(DBRST,QC12DCR);						// reset QC12 double buffer
	QC1SZB = 0x10 | pIQUEBuffer;

	QC1REQ = kQCREQUSBRx;
	QC2REQ	= kQCREQATATx;						// QC2 = ATA Tx
	UTL_LoopDelay(0x100);

	mSetBit(RXDA,QC12DTR);
	
	//while ((QC12DSR & 0x03) != 0);
	while (!mCheckBit(ATAINTRQ,PORTS));
	(void) ATA_WaitATABusy();

	QC1REQ	= kQCREQNone;						// QC1 = USB Rx
	QC2REQ	= kQCREQNone;						// QC2 = ATA Tx
}		

//
// The end of file ATA_Driver.c 
// *********************************************************************************

⌨️ 快捷键说明

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