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