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

📄 cf_tureide.c

📁 arm9 嵌入式系统开发与实践光盘
💻 C
📖 第 1 页 / 共 3 页
字号:
		(U8)Sectors, 								/*SecNum,扇区号寄存器*/
		(U8)(Sectors/0x100),							/*CylLow,柱面低寄存器*/
		(U8)(Sectors/0x10000),						/*CylHigh,柱面高寄存器*/
		(U8)(((Sectors/0x1000000)&0x0f)|ATA_DevReg),	/*C_D_H,设备磁头寄存器*/
		(U8)IDE_CMD_READ 							/*Command,指令寄存器*/ 
				  );
}

/*********************************************************************************************************
** 函数名称: ATA_ReadData512B
** 功能描述: 从硬盘读出一个512B,在指定的缓冲区里
** 输   入: Buffer,缓冲区地址
** 输   出: 无
** 全局变量: 无
** 调用模块: GetData(),从ATA数据寄存器读取一个字节
********************************************************************************************************/
void ATA_ReadData512B(U16 * Buffer)
{ 	U16 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(),发送信号量
********************************************************************************************************/
U8 ATA_ReadSector(U8 Device,U16 *Buffer,U32 Sector,U8 count)
{	
	U8	Status=FALSE;
	if(ATA[Device].ATAIsOK==FALSE) 				/*设备不可用,立即返回*/
		return	FALSE;							/*设备无效直接返回*/

	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;						/*操作正确*/
	}	

	return Status;								/*返回*/
}

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

/*********************************************************************************************************
** 函数名称: ATA_WriteData512B
** 功能描述: 写入ATA设备512字节数据
** 输   入: Buffer,缓冲区地址
** 输   出: 无
** 全局变量: 无
** 调用模块: SetData(),从ATA数据寄存器读取一个字节
********************************************************************************************************/
void ATA_WriteData512B(U16 * Buffer)
{   	
	U16 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(),发送信号量
********************************************************************************************************/
U8 ATA_WriteSector(U8 Device,U16 * Buffer, U32 Sector ,U8 count)
{	
	U8	Status=FALSE;
	if(ATA[Device].ATAIsOK==FALSE) 			/*CF卡不可用,立即返回*/
		return	FALSE;
	
	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;					/*操作正确*/
	}

	return Status;							/*返回*/
}


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

	if(ATA_SelectDevice(Device))			/*选择设备*/
	{	
   		ATA_CommandSet( 					/*ATA指令设置*/
 	   		CF_NULL,							/*Feature,特征寄存器*/
			CF_NULL, 							/*SecCnt,扇区计数寄存器*/
			CF_NULL, 							/*SecNum,扇区号寄存器*/
			CF_NULL,							/*CylLow,柱面低寄存器*/
			CF_NULL,							/*CylHigh,柱面高寄存器*/
			ATA_DevReg,						/*C_D_H,设备磁头寄存器*/
			IDE_CMD_IDLE_IMMEDIATE			/*Command,指令寄存器*/ 
					   );
    	
    	retStatus =ATA_WaitOnBusyNDrdy();	/*指令执行后状态*/
	}

	return retStatus;						/*返回*/
}

/*********************************************************************************************************
** 函数名称: ATA_StandbyImmediate	所在文件:IDE.C
** 功能描述: 立即进入空闲(硬盘停转)
** 输   入: Device,主设备或从设备
** 输   出: TRUE,正常返回
**			 FALSE,出错返回
** 全局变量: ATA,设备状态及信息结构体
**			 CFIDESem,信号量
**			 ATA_DevReg,确定选择的是主设备或是从设备和地址模式(本驱动使用LBA模式)
** 调用模块: OSSemPend(),等待信号量
**			 ATA_SelDevice(),选择设备
**			 ATA_CommandSet(),ATA指令设置
**			 ATA_WaitOnBusyNDrdy(),等待设备就绪
**			 OSSemPost(),发送信号量
********************************************************************************************************/
U8 ATA_StandbyImmediate(U8 Device)
{	
	U8 retStatus = FALSE;
	if(ATA[Device].ATAIsOK==FALSE) 			/*CF卡不可用,立即返回*/
		return	FALSE;
	
	if(ATA_SelectDevice(Device))			/*选择设备*/
	{	
   		ATA_CommandSet( 					/*ATA指令设置*/
 	   		CF_NULL,							/*Feature,特征寄存器*/
			CF_NULL, 							/*SecCnt,扇区计数寄存器*/
			CF_NULL, 							/*SecNum,扇区号寄存器*/
			CF_NULL,							/*CylLow,柱面低寄存器*/
			CF_NULL,							/*CylHigh,柱面高寄存器*/
			ATA_DevReg,						/*C_D_H,设备磁头寄存器*/
			IDE_CMD_STANDBY_IMMEDIATE		/*Command,指令寄存器*/ 
					   );
					   
    	retStatus =ATA_WaitOnBusyNDrdy();	/*等待设备不忙*/	
	}

	return retStatus;						/*返回*/
}


/*********************************************************************************************************
** 函数名称: CF_Card_Test
** 功能描述: CF_Card_Test
********************************************************************************************************/
#define	TEST_SECTOR_NUMBER	0x1000

void CF_Card_Test( void )
{	
	U32 m,n ;
	U16 data[512] ;
	
	SYS_BusIni();	  //ATA总线初始化
	
	ATA_INI();		  //CF驱动初始化	
	
	if( ATA[THIS_DEVICE].ATAIsOK == TRUE )
		printf( "CF卡检测成功!\n" );
	else
	{
		printf( "CF卡检测失败!\n" );
		printf( "设备出错代码 = 0x%x\n", ATA[THIS_DEVICE].ERRCODE ) ;		//
		printf( "读写出错的扇区号 = 0x%x\n", ATA[THIS_DEVICE].ERRSECTOR ) ;		//
		return ;
	}

	printf( "柱面数 = 0x%x\n", ATA[THIS_DEVICE].INFODATA.NumberOfCylinders ) ;		//
	printf( "磁头数 = 0x%x\n", ATA[THIS_DEVICE].INFODATA.NumberOfHeads ) ;		//
	printf( "每磁道扇区数 = 0x%x\n", ATA[THIS_DEVICE].INFODATA.SectorsPerTrack ) ;		//
	printf( "当前扇区容量 = 0x%x\n", ATA[THIS_DEVICE].INFODATA.CurrentSectorCapacity ) ;		//

	//给要写入CF卡的数组赋值
	for( m = 0 ; m < 512 ; m++ )	data[m] = m ;
	printf("write data : \n");
	for( m = 0; m < 8; m++ )
    {
		for( n = 0; n < 7; n++ )
		    printf( "%03x ", data[m*7+n] ) ;
		    
		printf("\n");
    }
    
	printf("\nCF Card Write Sector Test\n\n" );
	ATA_WriteSector( THIS_DEVICE, data, TEST_SECTOR_NUMBER, 2 ) ;


	//在读出CF卡之前,先将数组清零
	for( m = 0 ; m < 512 ; m++ )	data[m] = 0 ;

	printf("\nCF Card Read Sector Test\n\n" );
	ATA_ReadSector( THIS_DEVICE, data, TEST_SECTOR_NUMBER, 2 ) ;

	for( m = 0; m < 8; m++ )
    {
		for( n = 0; n < 7; n++ )
		    printf( "%03x ", data[m*7+n] ) ;
		    
		printf("\n");
    }
     
	for( m = 0 ; m < 512 ; m++ )
	{
		if( data[m] != m ) 
			break ;
	}
	
	if( m == 512 )	printf("\n读出的数据与写入的数据完全相符!\n");
	else		printf("\n读出的数据与写入的数据在地址0x%04处不符! \n", m );
     
    printf("\nPress ESC key to exit\n");
    while( getkey() != ESC_KEY ) ;
}

static char title[] = "CF卡实验";
static char tip[]   = "探测CF卡获取相关信息,并实验扇区读写,按ESC键退出";

//Test_StepMotorItem在prog_entry.c里被引用
TEST_PROGRAM_ITEM Test_CF_CardItem = {
				(TEST_PROGRAM)CF_Card_Test, 	//入口地址
				title, 					//显示名称
				tip, 					//帮助或提示信息,可为NULL
				1};						//使用printf,puts,putch等函数时在LCD上也显示输出字符(串)

⌨️ 快捷键说明

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