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

📄 ide.c

📁 ARM嵌入式系统软件开发实例(一) 里面含有很多UCOS教程和源码
💻 C
📖 第 1 页 / 共 3 页
字号:

	  	for(temp32=0;temp32<TIMEOUTSET;temp32++)		/*等待设备准备好*/
  		{
  			SetDeviceHead(0xfa);						/*写设备磁头寄存器*/
	  		if( 0xfa == (uint8)GetDeviceHead())			/*读出刚才写进设备磁头寄存器值*/
	  			break;									/*设备OK,完成复位*/
	   	}

		if(temp32<TIMEOUTSET)							/*如果设备不超时,则ATA接口上有设备*/
		{
			for(Device=0;MAX_DEVICE>Device;Device++)	/*初始化各设备,MAX_DEVICE最大值为1,即只能有主和从两个设备*/
			{
				ATA_SetFeature(Device);					/*特性设备,(总线设置)*/
				if(ATA_IssueIDEIdentify(Device))		/*ATA设备识别,获取CF卡内部信息*/
					ATA[Device].ATAIsOK = TRUE;			/*ATA设备可用,置位其标志位*/
				else
					ATA[Device].ATAIsOK = FALSE;		/**ATA设备不可用,清ATA设备准备好标志*/
			}
		}
	}
} 


/*********************************************************************************************************
** 函数名称: ATA_ReadSetting					所在文件:IDE.C
** 功能描述: 读扇区指令设置相关的寄存器。
** 输   入: Sectors ,读设备的起始扇区号
**			 Count ,扇区数
** 输   出: 无
** 全局变量: ATA_DevReg,确定选择的是主设备或是从设备和地址模式(本驱动使用LBA模式)
** 调用模块: ATA_CommandSet(),写命令设置
********************************************************************************************************/
void ATA_ReadSetting(uint32 Sectors , uint8 Count)
{
   	ATA_CommandSet( 									/*ATA指令设置*/
 		NULL,											/*Feature,特征寄存器*/
		(uint8)Count, 									/*SecCnt,扇区计数寄存器*/
		(uint8)Sectors, 								/*SecNum,扇区号寄存器*/
		(uint8)(Sectors/0x100),							/*CylLow,柱面低寄存器*/
		(uint8)(Sectors/0x10000),						/*CylHigh,柱面高寄存器*/
		(uint8)(((Sectors/0x1000000)&0x0f)|ATA_DevReg),	/*C_D_H,设备磁头寄存器*/
		(uint8)IDE_CMD_READ 							/*Command,指令寄存器*/ 
				  );
}

/*********************************************************************************************************
** 函数名称: ATA_ReadData512B
** 功能描述: 从硬盘读出一个512B,在指定的缓冲区里
** 输   入: Buffer,缓冲区地址
** 输   出: 无
** 全局变量: 无
** 调用模块: GetData(),从ATA数据寄存器读取一个字节
********************************************************************************************************/
void ATA_ReadData512B(uint16 * Buffer)
{ 	uint16 i;
	for(i = 0; i < 256; i ++)					/*连续读256个字(512字节)数据*/
    {
    	*(Buffer ++) = GetData();				/*读数据寄存器一个字数据*/
    }
}

/*********************************************************************************************************
** 函数名称: ATA_ReadSector					所在文件:IDE.C
** 功能描述: 从硬盘读取一或多个扇区,放入到形参指定的内存中
** 输   入: Device,设备号
**			 Buffer,读出数据存放的缓冲区地址
**			 Sector,读扇区号
**			 count, 读扇区数
** 输   出: TRUE,正常返回
**			 FALSE,出错返回
** 全局变量: ATA,设备状态及信息结构体
** 调用模块: OSSemPend(),等待信号量
**			 ATA_SelDevice(),选择设备
**			 ATA_ReadSetting(),读扇区设置
**			 ATA_WaitOnBusyNDrq(),等待数据请求
**			 ATA_ReadData512B(),读512字节数据
**			 ATA_WaitOnBusyNDrdy(),等待设备准备好
**			 OSSemPost(),发送信号量
********************************************************************************************************/
uint8 ATA_ReadSector(uint8 Device,uint16 *Buffer,uint32 Sector,uint8 count)
{	
#ifdef UCOSII
	uint8	err;
#endif

	uint8	Status=FALSE;
	if(ATA[Device].ATAIsOK==FALSE) 				/*设备不可用,立即返回*/
		return	FALSE;							/*设备无效直接返回*/

#ifdef UCOSII
	OSSemPend(CFIDESem, 0, &err);				/*等待信号量*/
#endif

	if(ATA_SelectDevice(Device))				/*选择主从设备*/
	{
		ATA_ReadSetting( Sector, count);		/*读扇区设置*/
		do
		{	
			count--;							/*扇区数减1*/
			if(ATA_WaitOnBusyNDrq())			/* 等待设备请求数据传输*/
		    {	
			   	ATA_ReadData512B( Buffer );		/*连续读取一扇区的数据*/
			   	Buffer +=256;					/*调整数据格式*/
			}
			else
			   	break;							/*出错,退出d0...while*/
		}while(count>0);						/*所有扇区数据传输完成*/
			
		if(ATA_WaitOnBusyNDrdy())				/*等待设备就绪,读取状态寄存器同时检测设备是否出错*/
			Status = TRUE;						/*操作正确*/
	}	
	
	
#ifdef UCOSII
	OSSemPost(CFIDESem);						/*发送信号量*/
#endif

	return Status;								/*返回*/
}

/*********************************************************************************************************
** 函数名称: ATA_WriteSetting					所在文件:IDE.C
** 功能描述: 写扇区指令设置相关的寄存器。
** 输   入: Sectors,写入的起始扇区号
**           Count,扇区数
** 输   出: 无
** 全局变量: ATA_DevReg,确定选择的是主设备或是从设备和地址模式(本驱动使用LBA模式)
** 调用模块: ATA_CommandSet(),写命令设置
********************************************************************************************************/
void ATA_WriteSetting(uint32 Sectors , uint8 Count)
{
	ATA_CommandSet( 									/*ATA指令设置*/
 		NULL,											/*Feature,特征寄存器*/
		(uint8)Count, 									/*SecCnt,扇区计数寄存器*/
		(uint8)Sectors, 								/*SecNum,扇区号寄存器*/
		(uint8)(Sectors/0x100),							/*CylLow,柱面低寄存器*/
		(uint8)(Sectors/0x10000),						/*CylHigh,柱面高寄存器*/
		(uint8)(((Sectors/0x1000000)&0x0f)|ATA_DevReg),	/*C_D_H,设备磁头寄存器*/
		(uint8)IDE_CMD_WRITE 							/*Command,指令寄存器*/ 
				  );	
} 

/*********************************************************************************************************
** 函数名称: ATA_WriteData512B
** 功能描述: 写入ATA设备512字节数据
** 输   入: Buffer,缓冲区地址
** 输   出: 无
** 全局变量: 无
** 调用模块: SetData(),从ATA数据寄存器读取一个字节
********************************************************************************************************/
void ATA_WriteData512B(uint16 * Buffer)
{   	
	uint16 i;
   	for(i = 0; i < 256; i ++)			/*连续写256个字(512字节)数据*/
   	{
     	SetData(*(Buffer++)); 			/*写数据寄存器一个字数据*/    	
   	}
}

/*********************************************************************************************************
** 函数名称: WriteSector					所在文件:IDE.C
** 功能描述: 向硬盘写入一或多个扇区
** 输   入: Device,选择主设备或从设备
**			 Buffer,缓冲区地址
**			 Sector,写入扇区号
**			 count, 写入扇区数
** 输   出: TRUE,正常返回
**			 FALSE,出错返回
** 全局变量: ATA,设备状态及信息结构体
** 调用模块: OSSemPend(),等待信号量
**			 ATA_SelDevice(),选择设备
**			 ATA_ReadSetting(),读扇区设置
**			 ATA_WaitOnBusyNDrq(),等待数据请求
**			 ATA_WriteData512B(),写512字节数据
**			 ATA_WaitOnBusyNDrdy(),等待设备准备好
**			 OSSemPost(),发送信号量
********************************************************************************************************/
uint8 ATA_WriteSector(uint8 Device,uint16 * Buffer, uint32 Sector ,uint8 count)
{	
#ifdef UCOSII
	uint8	err;
#endif
	uint8	Status=FALSE;
	if(ATA[Device].ATAIsOK==FALSE) 			/*CF卡不可用,立即返回*/
		return	FALSE;

#ifdef UCOSII
	OSSemPend(CFIDESem, 0, &err);			/*等待信号量*/
#endif
	
	if(ATA_SelectDevice(Device))			/*选择需要操作的设备*/
	{
		ATA_WriteSetting( Sector, count);	/*写扇区设置*/
	    do
	    {	count--;
	    	if(ATA_WaitOnBusyNDrq())		/*等待设备请求数据传输*/
			{
	    		ATA_WriteData512B(Buffer);	/*写入一个扇区数据*/
	    		Buffer +=256;				/*调要写入数据缓冲区的指针*/
			}
			else
				break;						/*出错退出*/
		}while(count>0);

		if(ATA_WaitOnBusyNDrdy())			/*等待设备就绪,读取状态寄存器同时检测设备是否出错*/
			Status = TRUE;					/*操作正确*/
	}
	
#ifdef UCOSII
	OSSemPost(CFIDESem);					/*发信号量*/
#endif

	return Status;							/*返回*/
}


/*********************************************************************************************************
** 函数名称: ATA_IdleImmediate					所在文件:IDE.C
** 功能描述: 直接进入空闲状态(硬件转动)
** 输   入: Device,选择主设备或从设备
** 输   出: TRUE,正常返回
**			 FALSE,出错返回
** 全局变量: ATA,设备状态及信息结构体
**			 CFIDESem,信号量
**			 ATA_DevReg,确定选择的是主设备或是从设备和地址模式(本驱动使用LBA模式)
** 调用模块: OSSemPend(),等待信号量
**			 ATA_SelDevice(),选择设备
**			 ATA_CommandSet(),ATA指令设置
**			 ATA_WaitOnBusyNDrdy(),等待设备就绪
**			 OSSemPost(),发送信号量
********************************************************************************************************/
uint8 ATA_IdleImmediate(uint8 Device)
{
#ifdef UCOSII
	uint8	err;
#endif
	uint8 	retStatus = FALSE;
	if(ATA[Device].ATAIsOK==FALSE) 			/*CF卡不可用,立即返回*/
		return	FALSE;

#ifdef UCOSII
	OSSemPend(CFIDESem, 0, &err);			/*等待信号量*/
#endif
	if(ATA_SelectDevice(Device))			/*选择设备*/
	{	
   		ATA_CommandSet( 					/*ATA指令设置*/
 	   		NULL,							/*Feature,特征寄存器*/
			NULL, 							/*SecCnt,扇区计数寄存器*/
			NULL, 							/*SecNum,扇区号寄存器*/
			NULL,							/*CylLow,柱面低寄存器*/
			NULL,							/*CylHigh,柱面高寄存器*/
			ATA_DevReg,						/*C_D_H,设备磁头寄存器*/
			IDE_CMD_IDLE_IMMEDIATE			/*Command,指令寄存器*/ 
					   );
    	
    	retStatus =ATA_WaitOnBusyNDrdy();	/*指令执行后状态*/
	}

#ifdef UCOSII
	OSSemPost(CFIDESem);					/*发信号量*/
#endif

	return retStatus;						/*返回*/
}

/*********************************************************************************************************
** 函数名称: ATA_StandbyImmediate	所在文件:IDE.C
** 功能描述: 立即进入空闲(硬盘停转)
** 输   入: Device,主设备或从设备
** 输   出: TRUE,正常返回
**			 FALSE,出错返回
** 全局变量: ATA,设备状态及信息结构体
**			 CFIDESem,信号量
**			 ATA_DevReg,确定选择的是主设备或是从设备和地址模式(本驱动使用LBA模式)
** 调用模块: OSSemPend(),等待信号量
**			 ATA_SelDevice(),选择设备
**			 ATA_CommandSet(),ATA指令设置
**			 ATA_WaitOnBusyNDrdy(),等待设备就绪
**			 OSSemPost(),发送信号量
********************************************************************************************************/
uint8 ATA_StandbyImmediate(uint8 Device)
{	
#ifdef UCOSII
	uint8	err;
#endif
	uint8 retStatus = FALSE;
	if(ATA[Device].ATAIsOK==FALSE) 			/*CF卡不可用,立即返回*/
		return	FALSE;

#ifdef UCOSII
	OSSemPend(CFIDESem, 0, &err);			/*等待信号量*/
#endif
	
	if(ATA_SelectDevice(Device))			/*选择设备*/
	{	
   		ATA_CommandSet( 					/*ATA指令设置*/
 	   		NULL,							/*Feature,特征寄存器*/
			NULL, 							/*SecCnt,扇区计数寄存器*/
			NULL, 							/*SecNum,扇区号寄存器*/
			NULL,							/*CylLow,柱面低寄存器*/
			NULL,							/*CylHigh,柱面高寄存器*/
			ATA_DevReg,						/*C_D_H,设备磁头寄存器*/
			IDE_CMD_STANDBY_IMMEDIATE		/*Command,指令寄存器*/ 
					   );
					   
    	retStatus =ATA_WaitOnBusyNDrdy();	/*等待设备不忙*/	
	}

#ifdef UCOSII
	OSSemPost(CFIDESem);					/*发信号量*/
#endif

	return retStatus;						/*返回*/
}






⌨️ 快捷键说明

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