📄 ide.c
字号:
/****************************************Copyright (c)**************************************************
** 广州周立功单片机发展有限公司
** 研 究 所
** 产品一部
**
** http://www.zlgmcu.com
**
**--------------文件信息--------------------------------------------------------------------------------
**文 件 名: IDE.c
**创 建 人: 周立山
**最后修改日期:
**描 述: CF卡操作程序。使用到接口函数:
** void SYS_BusIni(void); //ATA总线初始化函数
** void SYS_IdeHardReset(void); //硬件复位
** uint8 SYS_HaveCard(void); //控测CF卡是否存在
**
** GetData() //读数据寄存器
** SetData(x) //写数据寄存器
** GetERR() //读错误寄存器
** SetFeature(x) //写特征寄存器
** GetSECCNT() //读扇区计数寄存器
** SetSECCNT(x) //写扇区计数寄存器
** GetSector() //读扇区寄存器
** SetSector(x) //写扇区寄存器
** GetCylinderLow() //读柱面低8位寄存器
** SetCylinderLow(x) //写柱面低8位寄存器
** GetCylinderHigh() //读柱面高8位寄存器
** SetCylinderHigh(x) //写柱面高8位寄存器
** GetDeviceHead() //读设备磁头寄存器
** SetDeviceHead(x) //写设备磁头寄存器
** GetStatus() //读状态寄存器
** SetCommand(x) //写命令寄存器
** GetAStatus() //读辅助状态寄存器
** SetControl(x) //写控制寄存器
**--------------历史版本信息----------------------------------------------------------------------------
** 创建人: 周立山
** 版 本: v1.0
** 日 期:
** 描 述:
**
**--------------当前版本修订------------------------------------------------------------------------------
** 修改人:
** 日 期:
** 描 述:
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#include "config.h"
#ifdef UCOSII
OS_EVENT *CFIDESem; /*定义一个信号事件*/
#endif
uint8 ATA_DevReg ; /*设备磁头寄存器值,通过该寄存器可以确定*/
ATADEVICE ATA[MAX_DEVICE]; /*设备识别信息识别结构,及设备的状态*/
/*********************************************************************************************************
** 函数名称: ATA_GetStatus 所在文件:IDE.C
** 功能描述: 读取ATA状态寄程器
** 输 入: Status,存放状态值的变量指针
** 输 出: 无
** 全局变量: THIS_DEVICE,当前选中的设备
** ATA,设备信息数据结构
** 调用模块: GetAStatus(),读辅助状态寄存器
** GetStatus(),读状态寄存器
** GetERR(),读错误寄存器
********************************************************************************************************/
void ATA_GetStatus(uint8 *Status)
{
if(SYS_HaveCard())
{
GetAStatus(); /*读助状态寄存器不作处理,以保证读状态寄存器返回有效的值*/
*Status = (uint8)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
= (uint8)GetERR(); /*读取出错代码,保存出错代码,以便查询*/
if(ATA[THIS_DEVICE].ERRCODE & ATA_EER_REG_IDNF) /*如果是寻址出错,即记录出错的扇区号*/
{
ATA[THIS_DEVICE].ERRSECTOR
= (uint8)GetSector(); /*读出首次错误的扇区号LBA7~0*/
ATA[THIS_DEVICE].ERRSECTOR
|= ((uint8)GetCylinderLow())*0x100; /*读出首次错误的扇区号LBA15~8*/
ATA[THIS_DEVICE].ERRSECTOR
|= ((uint8)GetCylinderHigh())*0x10000; /*读出首次错误的扇区号LBA23~16*/
ATA[THIS_DEVICE].ERRSECTOR
|= ((uint8)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(),读取状态函数
********************************************************************************************************/
uint8 ATA_WaitOnBusyNDrdy(void)
{
uint8 ATAStatus;
uint32 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(),读取状态函数
********************************************************************************************************/
uint8 ATA_WaitOnBusyNDrq(void)
{
uint8 ATAStatus;
uint32 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(),读取状态函数
********************************************************************************************************/
uint8 ATA_WaitOnBusy(void)
{
uint8 ATAStatus;
uint32 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(),等待设备不忙
********************************************************************************************************/
uint8 ATA_SelectDevice(uint8 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(uint8 Feature,
uint8 SecCnt,
uint8 SecNum,
uint8 CylLow,
uint8 CylHigh,
uint8 C_D_H,
uint8 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(),等设备请求数据传输
********************************************************************************************************/
uint8 ATA_DriveBasicInfo(uint8 Device)
{
uint8 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 =(uint32)GetData(); //*Word 57
ATA[Device].INFODATA.CurrentSectorCapacity|=(uint32)GetData()<<16; //*Word 58
for(c=59;c< 255;c++) GetData();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -