📄 test.c
字号:
_NOP(); //<1uS指令周期
}
/*********************************************************************************************************
** 函数名称: ATA_HaveCard
** 功能描述: 判断CF卡是否连接到,CF卡的CD1、CD2引脚与GND直接相接,可以通过该引脚判断CF卡是否存在
** (对于IDE硬盘也有也多共地的引脚,也可以像CF卡那样检测但是这点ATA规范中并没有说明)。
** 如果硬件上没有相关的检测,则应一直返回TRUE。
** 输 入: 无
** 输 出: TRUE,如果有设备存在,不管设备是主或是从,或可以返回TRUE(1);
** FALSE,如果设备不存在,即返回FALSE(0)
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
uint8 SYS_HaveCard(void)
{
#define DEVICE_IS_ATTACHED 0 /*硬件设备没有检测CF CARD是否存在*/
if(DEVICE_IS_ATTACHED) /*如果DEVICE_IS_ATTACHED为0却有设备存在,为1即没有*/
return FALSE; /*DEVICE_IS_ATTACHED不为0,没有设备存在,返回FALSE*/
else
return TRUE; /*DEVICE_IS_ATTACHED为0,有设备存在,返回TRUE*/
}
/*********************************************************************************************************
** 函数名称: SYS_PortIn
** 功能描述: 从ATA设备指定的寄存器中读出一个字的数据,有些寄存器只有一个字节数有效。
** 输 入: reg 寄存器名称
** 输 出: 读出的数据
** 全局变量: 无
** 调用模块: OS_ENTER_CRITICAL(),关中断
** OS_EXIT_CRITICAL(),清中断
********************************************************************************************************/
uint16 SYS_PortIn(uint8 reg)
{
uint16 res ;
OS_ENTER_CRITICAL(); /*关中断*/
CF_ADDR_DIR = 0XFF;
CF_DATA_DIR = 0;
CF_ADDR_OUT &= ~(A2 + A1 + A0 + CS1 + CS0);
CF_ADDR_OUT |= reg;
/*读低字节*/
CF_ADDR_OUT &= ~RD;
res = (uint8)CF_DATA_IN;
CF_ADDR_OUT |= RD;
/*读高字节*/
if(reg==ATA_REG_DATA) /*如果读数据寄存器,读高字节*/
{
CF_ADDR_OUT &= ~RD;
res += ((uint16)CF_DATA_IN<<8);
CF_ADDR_OUT |= RD;
}
CF_ADDR_OUT |= A2 + A1 + A0 + CS1 + CS0; /*输出控制信号置高*/
OS_EXIT_CRITICAL(); /*开中断*/
return res; /*返回数值*/
}
/*********************************************************************************************************
** 函数名称: SYS_PortOut
** 功能描述: 向ATA设备指定的寄存器中写入一个字的数据,有些寄存器只有一个字节数有效。
** 输 入: reg 寄存器名称
** 输 出: 无
** 全局变量: 无
** 调用模块: OS_ENTER_CRITICAL(),关中断
** OS_EXIT_CRITICAL(),清中断
********************************************************************************************************/
void SYS_PortOut(uint8 reg, uint16 data)
{
OS_ENTER_CRITICAL(); /*关中断*/
CF_DATA_DIR = 0XFF;
CF_ADDR_OUT &= ~(A2+A1+A0+CS1+CS0);
CF_ADDR_OUT |= reg;
CF_DATA_OUT = 0;
CF_DATA_OUT = (uint8)data;
CF_ADDR_OUT &= ~WR;/*写信号为低电平,保持大于165nS*/
CF_ADDR_OUT |= WR;/*写信号脚置高[与低>162ns]*/
if(reg==ATA_REG_DATA) /*如果访问的寄存器为16位的数据寄存器*/
{ /*写高字节*/
CF_DATA_OUT = 0;
CF_DATA_OUT = (uint8)(data>>8);
CF_ADDR_OUT &= ~WR;
CF_ADDR_OUT |= WR;
}
CF_ADDR_OUT |= A2+A1+A0+CS1+CS0;
CF_DATA_DIR=0;
OS_EXIT_CRITICAL(); /*开中断*/
}
/*********************************************************************************************************
** 函数名称: SYS_IdeHardReset
** 功能描述: ATA设备硬件复位
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: SYS_WaitInUS(),等待微秒函数。
********************************************************************************************************/
void SYS_IdeHardReset(void)
{
CF_ADDR_DIR &= ~RST; /*复位引脚置低 */
SYS_WaitInUS(30); /*延时大于25微秒 */
CF_ADDR_DIR |= RST; /*复位引脚置高 */
SYS_WaitInUS(5000); /*延时大于2毫秒,设备通常在480ms内完成硬件初始化和自诊断*/
}
/*********************************************************************************************************
** 函数名称: 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,柱面低寄存器*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -