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

📄 cf_tureide.c

📁 arm9 嵌入式系统开发与实践光盘
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
【文  件  名  称】CF_TrueIDE.C
【功  能  描  述】三星S3C2410A板demo程序代码
【程  序  版  本】4.0
【创建人及创建日期】icesoar//2002年11月19日19:26
【修改人及修改日期】icesoar//2005-2-18 13:55
****************************************************************************/

//***************************************************************************
#include "def.h"
#include "2410addr.h"
#include "config.h"
#include "board.h"
#include "utils.h"

#include "SysATA.h"
#include "CF_TureIDE.h"

U8		ATA_DevReg ;		/*设备磁头寄存器值,通过该寄存器可以确定*/
ATADEVICE 	ATA[MAX_DEVICE];	/*设备识别信息识别结构,及设备的状态*/ 


/*********************************************************************************************************
** 函数名称: ATA_GetStatus					所在文件:IDE.C
** 功能描述: 读取ATA状态寄程器
** 输   入: Status,存放状态值的变量指针
** 输   出: 无
** 全局变量: THIS_DEVICE,当前选中的设备
**			 ATA,设备信息数据结构
** 调用模块: GetAStatus(),读辅助状态寄存器
**			 GetStatus(),读状态寄存器
**			 GetERR(),读错误寄存器
********************************************************************************************************/
void ATA_GetStatus(U8 *Status)
{	
	if(SYS_HaveCard())				 
	{	
		GetAStatus();							/*读助状态寄存器不作处理,以保证读状态寄存器返回有效的值*/
		*Status = (U8)GetStatus();			/*读取ATA设备状态*/

		if((*Status)&ATA_STAT_REG_BSY)							/*设备状态寄存器BSY位为1,其它位无效*/
		{
			*Status = ATA_STAT_REG_BSY;							/*BSY位为1其它位无效,屏蔽其它位*/
			ATA[THIS_DEVICE].ERRCODE = CARD_IS_TRUE;			/*清错误码率代码*/
		}
		else													/*设备不忙*/
		{
			if((*Status) & ATA_STAT_REG_ERR)					/*设备是否出错*/
			{  													/*设备出错*/
				ATA[THIS_DEVICE].ERRCODE 
					= (U8)GetERR();							/*读取出错代码,保存出错代码,以便查询*/
				if(ATA[THIS_DEVICE].ERRCODE & ATA_EER_REG_IDNF)		/*如果是寻址出错,即记录出错的扇区号*/
				{	
					ATA[THIS_DEVICE].ERRSECTOR  
						= (U8)GetSector();						/*读出首次错误的扇区号LBA7~0*/
					ATA[THIS_DEVICE].ERRSECTOR 
					   |= ((U8)GetCylinderLow())*0x100;			/*读出首次错误的扇区号LBA15~8*/
					ATA[THIS_DEVICE].ERRSECTOR 
					   |= ((U8)GetCylinderHigh())*0x10000;		/*读出首次错误的扇区号LBA23~16*/
					ATA[THIS_DEVICE].ERRSECTOR 
					   |= ((U8)GetDeviceHead()&0x0f)*0x1000000;	/*读出首次错误的扇区号LBA27~4*/
				}
					
			}
			else
				if(*Status==0)										/*如果状态全为0,该设备是无效的*/
				{
					ATA[THIS_DEVICE].ERRCODE = CARD_IS_FALSE;	/*设备无效*/
					*Status = CARD_IS_FALSE;					/*返回函数结果*/
				}
				else
				{					
					ATA[THIS_DEVICE].ERRCODE = CARD_IS_TRUE;	/*清错误码率代码*/	
				}
		}
		
	}
	else
	{	
		*Status = CARD_IS_FALSE;								/*设备不可用*/
		ATA[THIS_DEVICE].ERRCODE = CARD_IS_FALSE;				/*设备不可用*/
		ATA[THIS_DEVICE].ATAIsOK = FALSE;						/*设备不可用*/
	}
}


/*********************************************************************************************************
** 函数名称: ATA_WaitOnBusyNDrdy					所在文件:IDE.C
** 功能描述:  设备忙等待直到设备不忙并设备准备好.
** 输   入: 无
** 输   出: 设备出错返回0
** 全局变量: ATA,数据结构体
** 调用模块: ATA_GetStatus(),读取状态函数
********************************************************************************************************/
U8 ATA_WaitOnBusyNDrdy(void)
{	
   	U8	ATAStatus;
   	U32 	timeout;
		
	for(timeout=0;timeout<TIMEOUTSET;timeout++)					/*超时返回,即多次读取,在读取一定的次数还没得到需要的状态就认为超时*/
	{
		ATA_GetStatus(&ATAStatus);								/*获取设备状态*/
	
		if( ATAStatus==CARD_IS_FALSE)							/*该设备有错误或无效*/
			return FALSE;										/*返回失败*/
		
		if(ATAStatus&ATA_STAT_REG_ERR)							/*如果设备出错*/
			return FALSE;
		
		if(ATA_STAT_REG_DRDY==(ATAStatus&ATA_STAT_BSY_DRDY))	/*如果设备准备好返回*/
  			return TRUE;
    }
	
	ATA[THIS_DEVICE].ERRCODE = CARD_TIMEOUT;					/*标志超时出错*/ 
	ATA[THIS_DEVICE].ERRSECTOR = -1;							/*清错误扇区号*/ 
	return FALSE;
}


/*********************************************************************************************************
** 函数名称: ATA_WaitOnBusyNDrq					所在文件:IDE.C
** 功能描述: 设备忙等待直到设备不忙并有数据传输请求时.
** 输   入: 无
** 输   出: 设备出错返回0
** 全局变量: ATA[THIS_DEVICE].ERRCODE,出错代码
**		     ATA[THIS_DEVICE].ERRSECTOR,出错扇区号
** 调用模块: ATA_GetStatus(),读取状态函数
********************************************************************************************************/
U8 ATA_WaitOnBusyNDrq(void)
{
	U8	ATAStatus;
    U32 timeout;

	for(timeout=0;timeout<TIMEOUTSET;timeout++)					/*超时返回,即多次读取,在读取一定的次数还没得到需要的状态就认为超时*/
	{	
		ATA_GetStatus(&ATAStatus);								/*获取设备状态*/
		if(ATAStatus==CARD_IS_FALSE)							/*卡有错误*/
			return FALSE;
		
		if(ATAStatus&ATA_STAT_REG_ERR)							/*如果设备出错*/
			return FALSE;

		if(ATA_STAT_REG_DRQ==(ATAStatus&ATA_STAT_BSY_DRQ))		/*有数据传输请求*/
       		return TRUE;
 	}
	ATA[THIS_DEVICE].ERRCODE = CARD_TIMEOUT;					/*标志超时出错*/
	ATA[THIS_DEVICE].ERRSECTOR = -1;							/*清错误扇区号*/
	return FALSE;
}


/*********************************************************************************************************
** 函数名称: ATA_WaitOnBusy					所在文件:IDE.C
** 功能描述: 设备忙等待
** 输   入: 无
** 输   出: 出错返回0
** 全局变量: ATA[THIS_DEVICE].ERRCODE,出错代码
**		     ATA[THIS_DEVICE].ERRSECTOR,出错扇区号
** 调用模块: ATA_GetStatus(),读取状态函数
********************************************************************************************************/
U8 ATA_WaitOnBusy(void)
{
	U8	ATAStatus;
    	U32 	timeout;

	for(timeout=0;timeout<TIMEOUTSET;timeout++)				/*超时返回,即多次读取,在读取一定的次数还没得到需要的状态就认为超时*/
	{
		ATA_GetStatus(&ATAStatus);							/*读取状态寄存器*/
		if(ATAStatus==CARD_IS_FALSE)						/*卡有错误*/
			return FALSE;									/*返回设备发生了错误*/

		if((ATAStatus & ATA_STAT_BSY_DRQ)==0)					/*设备不忙,*/
  			return TRUE;									/*正常返回*/
	}
	
	ATA[THIS_DEVICE].ERRCODE = CARD_TIMEOUT;				/*标志超时出错*/
	ATA[THIS_DEVICE].ERRSECTOR = -1;						/*清错误扇区号*/
	return FALSE;
}



/*********************************************************************************************************
** 函数名称: ATA_SelectDevice					所在文件:IDE.C
** 功能描述: 选择主从设备
** 输   入: Device,0为主设备,1为从设备
** 输   出: TRUE,正常返回
**			 FALSE,出错返回
** 全局变量: ATA_DevReg
** 调用模块: SetDeviceHead(),写设备寄存器
**			 ATA_WaitOnBusy(),等待设备不忙
********************************************************************************************************/
U8 ATA_SelectDevice(U8 Device)
{
	ATA_WaitOnBusy();									/*等待设备不忙*/
	if(Device>0)										/*选择的为从设备*/
		ATA_DevReg = ATA_DevReg_DEV1 + 					/*选择设备0*/
    			 	 ATA_DevReg_b5 +
    			 	 ATA_DevReg_LBA+					/*工作在LAB模式*/
    			 	 ATA_DevReg_b7;	
	else												/*选择的为主设备*/
		ATA_DevReg = ATA_DevReg_DEV0 + 					/*选择设备0*/
    			 	 ATA_DevReg_b5 +
    			 	 ATA_DevReg_LBA +					/*工作在LAB模式*/
    			 	 ATA_DevReg_b7;			
    			 	 
    SetDeviceHead(ATA_DevReg);							/*写设备磁头寄存器*/
   
    return ATA_WaitOnBusy();							/*等待设备不忙,返回状态*/

}



/*********************************************************************************************************
** 函数名称: ATA_CommandSet
** 功能描述: 指令设置相关的寄存器。
** 输   入: Feature,特征寄存器
**			 SecCnt,扇区计数寄存器
**			 SecNum,扇区号寄存器
**			 CylLow,柱面低寄存器
**			 CylHigh,柱面高寄存器
**			 C_D_H,设备磁头寄存器
**			 Command,指令寄存器 
** 输   出: 无
** 全局变量: 无
** 调用模块: SetFeature(),写Feature,特征寄存器
**			 SetSECCNT(),写SecCnt,扇区计数寄存器
**			 SetSector(),写扇区号寄存器
**			 SetCylinderLow(),写柱面低寄存器
**			 SetCylinderHigh(),写柱面高寄存器
**    		 SetDeviceHead(),写设备磁头寄存器
**			 SetCommand(),写指令寄存器
********************************************************************************************************/
void ATA_CommandSet(U8 Feature,
					U8 SecCnt,
					U8 SecNum,
					U8 CylLow,
					U8 CylHigh,
					U8 C_D_H,
					U8 Command 
					)
{
	SetFeature(Feature);			/*Feature,特征寄存器*/
   	SetSECCNT(SecCnt);				/*SecCnt,扇区计数寄存器*/
	SetSector(SecNum);				/*SecNum,扇区号寄存器*/
	SetCylinderLow(CylLow);			/*CylLow,柱面低寄存器*/
	SetCylinderHigh(CylHigh);		/*CylHigh,柱面高寄存器*/
    SetDeviceHead(C_D_H );			/*C_D_H,设备磁头寄存器*/
	SetCommand(Command);			/*Command,指令寄存器 */
}



/*********************************************************************************************************
** 函数名称: ATA_DriveBasicInfo					所在文件:IDE.C
** 功能描述: 获取设备基本信息
** 输   入: 无
** 输   出: TRUE,正常返回
**			 FALSE,出错返回
** 全局变量: ATA[Device].INFODATA,设备信息结构体
** 调用模块: GetData(),读ATA一个字的数据
**			 ATA_GetStatus(),获取状态
**			 ATA_WaitOnBusyNDrq(),等设备请求数据传输
********************************************************************************************************/
U8 ATA_DriveBasicInfo(U8 Device)
{
    	U8 c,Status;

   	if(ATA_WaitOnBusyNDrq())
   	{
		GetData();											//*Word 00
		ATA[Device].INFODATA.NumberOfCylinders = GetData();	//*Word 01
		GetData();											// Word 02
		ATA[Device].INFODATA.NumberOfHeads = GetData();		//*Word 03
		GetData();											// Word 04
		GetData();											// Word 05
		ATA[Device].INFODATA.SectorsPerTrack = GetData();	//*Word 06

		for(c=7;c< 57;c++)	GetData();

		ATA[Device].INFODATA.CurrentSectorCapacity =(U32)GetData();	   	//*Word 57
        ATA[Device].INFODATA.CurrentSectorCapacity|=(U32)GetData()<<16; 	//*Word 58

		for(c=59;c< 255;c++)	GetData();

		ATA_GetStatus(&Status);						/*获取设备状态寄存器*/
		if(Status==CARD_IS_FALSE) 					/*如果设备失败返回*/
			return	(FALSE);						/*返回FALSE*/
		for(c = 0;Status&ATA_STAT_REG_DRQ;c++)		/*如果设备还有数据需要传输,有些设备需传输多于256字,那并不是协议所规范的*/
        {	        		
        	GetData();				/*读取一个字数据并丢弃*/
        	ATA_GetStatus(&Status);					/*获取设备状态寄存器*/
        	if(Status==CARD_IS_FALSE) 				/*如果设备失败返回*/
				return	(FALSE);					/*返回FALSE*/
        }
        		
        if( ATA[Device].INFODATA.CurrentSectorCapacity == 0)	/*如果CurrentSectorCapacity值为,即无效,可以通过以下值计算出*/
        {
         	ATA[Device].INFODATA.CurrentSectorCapacity =
         		(U32)ATA[Device].INFODATA.NumberOfCylinders *	/*柱面数*/
        		(U32)ATA[Device].INFODATA.NumberOfHeads  *		/*磁头数*/
            		    ATA[Device].INFODATA.SectorsPerTrack;		/*磁道数*/
        }
        return(TRUE);
    }
    else
        return(FALSE);
}

/*********************************************************************************************************
** 函数名称: ATA_DriveAllInfo					所在文件:IDE.C
** 功能描述: 该函数获取IDE设备的特征信息,

⌨️ 快捷键说明

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