📄 ide.c
字号:
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 + -