?? 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 + -