⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hal4ata.c

📁 次文件包括uCOS-II中使用,ZLG_FS在CF卡上的例子,ARM采用的是LPC2210.
💻 C
字号:
/*
//////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1999 - 2003 PHILIPS Semiconductors - APIC
//
// Module Name:
//
//     HAL4ATA.c
//
// Abstract:
//
//     This is HAL for IDE controllers.
//
// Author:
//
//     Hilbert Zhang ZhenYu
//
// Environment:
//
//     kernel mode only
//
// Notes:
//
// Revision History:
//     Create Date: Nov. 19 1999
//
//////////////////////////////////////////////////////////////////////////////
// Implementation Notes:
*/

#include  "config.h"                /* special function register declarations   */

#undef   GLOBAL_EXT

#include "SysCnfg.h"

#include "BasicTyp.h"
#include "common.h"

#include "Hal4Sys.h"

#include "ATA.h"
#include "RBC.h"
#include "RBCCmd.h"
#include "Hal4ATA.h"

#include "TPBulk.h"


//*************************************************************************
//  Public Data
//*************************************************************************

STRUC_EXT TPBLK_STRUC		TPBulk_Block;
#define     TPBulk_CBW				TPBulk_Block.TPBulk_CommandBlock
#define	    RBC_CDB					TPBulk_CBW.cdbRBC
#define     RBC_LUN					TPBulk_CBW.bCBW_LUN
#define     TPBulk_CSW				TPBulk_Block.TPBulk_CommandStatus
#define     Hal4ATA_Atapi			RBC_CDB

STRUC_EXT   HW_ATA_DEVICES_EXTENSION	Hal4ATA_DevExt;
#define     ATADevExt_IDData            Hal4ATA_DevExt.IdentifyData

STRUC_EXT BITFLAGS     bFlags;

#define             MCUBF_Timer  					bFlags.bits.timer
#define             D12BF_SetupOverwritten  		bFlags.bits.setup_overwritten
#define             D12BF_Configuration	  			bFlags.bits.;configuration
#define             REQBF_DCPRequest_dir  			bFlags.bits.DCPRequst_Dir
#define             REQBF_DCPRequest_EPdir  		bFlags.bits.DCPRequst_EPDir
#define             REQBF_StallDCPRequest   		bFlags.bits.Stall_DCPRequest
#define             BOTBF_StallAtBulkOut  			bFlags.bits.BO_Stalled
#define             BOTBF_StallAtBulkIn  			bFlags.bits.BI_Stalled
#define             BOTXfer_Abort  					bFlags.bits.Abort_BOT
#define             ATABF_IsAttached  				bFlags.bits.ATABF_IsAttached
#define             ATABF_IsSupportMultiSector  	bFlags.bits.ATABF_IsSupportMultiSector
#define             ATABF_IDEXfer_dir	 			bFlags.bits.ATABF_IDEXfer_dir
#define             ATABF_IsSkipSetParameters 	 	bFlags.bits.ATABF_IsSkipSetParameters


INT8_EXT    Hal4ATA_SectCntInBlk;

//*************************************************************************
//  Private Data
//*************************************************************************

// Static
char_bit	_Hal4ATA_StatusByte;
#define		Hal4ATA_StatusByte  _Hal4ATA_StatusByte.char_
#define		Hal4ATA_StatusByte_ERR  _Hal4ATA_StatusByte.bit_.b0
#define		Hal4ATA_StatusByte_IDX  _Hal4ATA_StatusByte.bit_.b1
#define		Hal4ATA_StatusByte_CORR _Hal4ATA_StatusByte.bit_.b2
#define		Hal4ATA_StatusByte_DRQ  _Hal4ATA_StatusByte.bit_.b3
#define		Hal4ATA_StatusByte_DSC  _Hal4ATA_StatusByte.bit_.b4
#define		Hal4ATA_StatusByte_DF   _Hal4ATA_StatusByte.bit_.b5
#define		Hal4ATA_StatusByte_DRDY _Hal4ATA_StatusByte.bit_.b6
#define		Hal4ATA_StatusByte_BSY  _Hal4ATA_StatusByte.bit_.b7

char_bit	_Hal4ATA_DevReg;
#define    	Hal4ATA_DevReg _Hal4ATA_DevReg.char_	//= 0xA0;
#define		Hal4ATA_DevReg_DEV  _Hal4ATA_DevReg.bit_.b4
#define		Hal4ATA_DevReg_b5   _Hal4ATA_DevReg.bit_.b5
#define		Hal4ATA_DevReg_LBA  _Hal4ATA_DevReg.bit_.b6
#define		Hal4ATA_DevReg_b7   _Hal4ATA_DevReg.bit_.b7

// Temp
FLEXI_INT32		Hal4ATA_Track;
INT8			Hal4ATA_drvSelect;





//*************************************************************************
//  Subroutines -- Level 1
//*************************************************************************

void
Hal4ATA_GetStatus(void)
{
	Hal4ATA_StatusByte = (uint8)Hal4Sys_ATAPortInB(IDE_ASTATUS);
}

uint8
Hal4ATA_WaitOnBusyNDrdy(void)
{
    uint8 retStatus = FALSE;
    while(TRUE)
	{
		Hal4ATA_GetStatus();
        // if IDE_STATUS_BUSY && !IDE_STATUS_DRDY
        //Hal4ATA_StatusByte_ERR  = Hal4ATA_StatusByte^0
		if (Hal4ATA_StatusByte_ERR != 0 || Hal4ATA_StatusByte_DF != 0)
        {
            break;
        }
        else 
			if(Hal4ATA_StatusByte_BSY !=0 || Hal4ATA_StatusByte_DRDY !=1)
			//if(Hal4ATA_StatusByte_BSY !=0 )
				Hal4Sys_Wait4US();
        	else
        	{
            	retStatus = TRUE;
           		break;
        	}
	}
	return retStatus;
}


uint8
Hal4ATA_WaitOnBusyNDrq(void)
{
    uint8 retStatus = FALSE;
    while(TRUE)
	{	Hal4ATA_GetStatus();
		if (Hal4ATA_StatusByte_ERR != 0 || Hal4ATA_StatusByte_DF != 0)
        {
            break;
        }
        else 
			if(Hal4ATA_StatusByte_BSY !=0 || Hal4ATA_StatusByte_DRQ !=1)
				Hal4Sys_Wait4US();
        	else
        	{
		   		retStatus = TRUE;
            	break;
        	}
	}
    return TRUE;
}



uint8
Hal4ATA_WaitOnBusy(void)
{
    uint8 retStatus = FALSE;
    while(TRUE)
	{
		Hal4ATA_GetStatus();
		if (Hal4ATA_StatusByte_ERR != 0 || Hal4ATA_StatusByte_DF != 0)
        {
            break;
        }
        else 
			if(Hal4ATA_StatusByte_BSY)
        	{
				Hal4Sys_Wait4US();
        	}
			else
        	{
            	retStatus = TRUE;
				break;
        	}
	}
   return retStatus;
}



//*************************************************************************
//  Subroutines -- Level 2
//*************************************************************************

uint8
Hal4ATA_SelDevice(void)
{
    uint8 retStatus = FALSE;
    if(Hal4ATA_WaitOnBusy())
    {
	// ATAREG4OUT_DEVICE_HEAD =  ATAREG_GRP0+6 = 0x56
	// ATAREG_GRP0 =0x50
	// BUFF_DIR_RD, !D12CS, !BUFF_EN, !IDE_CS1, !IDE_CS0,  A2, 	A1, A0
	//0x56		0		1		0			1		0		1	1	0
      	Hal4Sys_ATAPortOutB(IDE_DEVICE_HEAD,Hal4ATA_DevReg);
       	retStatus = Hal4ATA_WaitOnBusyNDrdy();
    }
    return retStatus;
}



//*************************************************************************
//  Subroutines -- level 4
//*************************************************************************


uint8
Hal4ATA_IssueIDEIdentify(void)
{
    INT16 i;
    uint8 retStatus = FALSE;
    // Select device.
	if(Hal4ATA_SelDevice())
    {
	    // Send IDE IDENTIFY command.
		// IDE_COMMAND_IDENTIFY=0xEC ;
	    Hal4Sys_ATAPortOutB(IDE_COMMAND, IDE_COMMAND_IDENTIFY);

	    if(Hal4ATA_WaitOnBusyNDrq())
        {
            
	        // Suck out 256 words. After waiting for one model that asserts busy
	        // after receiving the Packet Identify command.
	       
	        if(Hal4ATA_InitDevExt())
                retStatus = TRUE;
        }

	  
	    // Work around for some IDE and one model Atapi that will present more than
	    // 256 words for the Identify data.
	   
	    for (i=10000; i != 0; i--)
        {
		    Hal4ATA_GetStatus();
		    if (Hal4ATA_StatusByte_DRQ)
            {
			    
			    // Suck out any remaining bytes and throw away.
			   
			    Hal4Sys_ATADataPortInW();
		    }
		    else
			    break;
	    }
    }
	return retStatus;
} /* end IssueIdentify()*/


uint8
Hal4ATA_InitDevExt(void)
{
    INT8 c;
    if(Hal4ATA_WaitOnBusyNDrq())
    {
        ATADevExt_IDData.GeneralConfiguration = Hal4Sys_ATADataPortInW();//INT16  00
        ATADevExt_IDData.NumberOfCylinders = Hal4Sys_ATADataPortInW();//INT16  01
        Hal4Sys_ATADataPortInW();
        ATADevExt_IDData.NumberOfHeads = Hal4Sys_ATADataPortInW();//INT16  03

        for(c = 2 ; c != 0; c--)
            Hal4Sys_ATADataPortInW();
        ATADevExt_IDData.SectorsPerTrack = Hal4Sys_ATADataPortInW();//INT16  06

        for(c = 40 ; c != 0; c--) // 7 -47
            Hal4Sys_ATADataPortInW();
        ATADevExt_IDData.MaximumBlockTransfer = Hal4Sys_ATADataPortInW();//INT8 47

        Hal4Sys_ATADataPortInW(); // 48
        ATADevExt_IDData.Capabilities = Hal4Sys_ATADataPortInW();//INT16  49

        for(c = 4; c != 0; c--)
            Hal4Sys_ATADataPortInW();
        ATADevExt_IDData.NumberOfCurrentCylinders = Hal4Sys_ATADataPortInW();//INT16  54
        ATADevExt_IDData.NumberOfCurrentHeads = Hal4Sys_ATADataPortInW();//INT16  55
        ATADevExt_IDData.CurrentSectorsPerTrack = Hal4Sys_ATADataPortInW();//INT16  56
        ATADevExt_IDData.CurrentSectorCapacity.ints.i0 = Hal4Sys_ATADataPortInW();//INT32  57
        ATADevExt_IDData.CurrentSectorCapacity.ints.i1 = Hal4Sys_ATADataPortInW();//

        if(ATADevExt_IDData.CurrentSectorCapacity.u0 == 0)
        {
            ATADevExt_IDData.NumberOfCurrentCylinders = ATADevExt_IDData.NumberOfCylinders;
            ATADevExt_IDData.NumberOfCurrentHeads = ATADevExt_IDData.NumberOfHeads ;//INT16  55
            ATADevExt_IDData.CurrentSectorsPerTrack = ATADevExt_IDData.SectorsPerTrack;//INT16  56
            ATADevExt_IDData.CurrentSectorCapacity.u0 = (INT32)ATADevExt_IDData.NumberOfCurrentCylinders * ATADevExt_IDData.NumberOfCurrentHeads * ATADevExt_IDData.CurrentSectorsPerTrack;
        }
        return(TRUE);
    }
    else
        return(FALSE);
}


uint8
Hal4ATA_IsLBAmode(void)
{  	Hal4ATA_DevReg_LBA = 1;
	return(Hal4ATA_DevReg_LBA);
}


uint8
Hal4ATA_SetFeature(void)
{ /*  uint8 retStatus = FALSE;
   Hal4Sys_ATAPortOutB(ATAREG4OUT_FEATURE,0x03);
   Hal4Sys_ATAPortOutB(ATAREG4OUT_SECTOR_COUNT, 0x08);

   Hal4Sys_ATAPortOutB(ATAREG4OUT_SECTOR_NUMBER,0);
   Hal4Sys_ATAPortOutB(ATAREG4OUT_CYLINDER_LOW,0);
   Hal4Sys_ATAPortOutB(ATAREG4OUT_CYLINDER_HIGH,0);

   Hal4Sys_ATAPortOutB(ATAREG4OUT_COMMAND, 0xEF);
    while(TRUE)
    {
        if(Hal4ATA_WaitOnBusyNDrdy())
        {
            retStatus = TRUE;
            break;
        }
    }
   return retStatus;*/
   return TRUE;
}



//*************************************************************************
//  Subroutines -- level 5 ATA transaction
//*************************************************************************
uint8
Hal4ATA_IdeHardReset(void)
{
	//INT8 c;
    uint8 retStatus = FALSE;

     IOCLR = IDE_RST; 						// 复位引脚置低
     Hal4Sys_WaitInUS(320); // >25 US
  	 IOSET = IDE_RST; 						// 复位引脚置高
 //   for(c = 10; c != 0; c--)
    	Hal4Sys_WaitInUS(500000); // 50MS

    if(Hal4ATA_SelDevice())
	{
//	    Hal4ATA_DevReg_DEV = FALSE;
 //	   Hal4Sys_ATAPortOutB(ATAREG4OUT_DEVICE_HEAD,Hal4ATA_DevReg);
//	}

    while(TRUE)
    {
        if(Hal4ATA_WaitOnBusyNDrdy())
        {
            retStatus = TRUE;
            break;
        }
    }
 	}
    return retStatus;
}


uint8
Hal4ATA_FindIDEDevice(void)
{
    INT8    c;
    ATABF_IsAttached = FALSE;
	Hal4ATA_DevReg = 0xA0;
    Hal4ATA_DevReg_DEV = FALSE;
	if(Hal4ATA_IdeHardReset())
    {	Hal4ATA_SetFeature();
	    for ( c = 2; c != 0; c--, Hal4ATA_DevReg_DEV^=1 )
	    {   if(Hal4ATA_SelDevice())
            {
		        if ( Hal4ATA_IssueIDEIdentify() )
		        {   ATABF_IsAttached = TRUE;
                    break;
		        }
            }
	    }

        if(ATABF_IsAttached)
        {  	Hal4ATA_IsLBAmode();// 设为LAB模式
        } // IDE HD is found
    } // IDE Reset OK
    return ATABF_IsAttached;
} /*end Hal4ATA_FindIDEDevice()*/


uint8
Hal4ATA_ReadWriteSetting(void)
{
    uint8 retStatus = FALSE;
    
	// Select device  .
	
	if(Hal4ATA_SelDevice())
    {   //Assume Sector Counter <256
        Hal4Sys_ATAPortOutB(IDE_SECCNT, RBC_CDB.RbcCdb_Read.XferLength_0);
	    /* IN LBA mode */
		if( ATABF_IDEXfer_dir )    // ATABF_Xfer_dir==1 Read(from Dev to Host)
  	    {
			Hal4Sys_ATAPortOutB(IDE_SECTOR,RBC_CDB.RbcCdb_Read.LBA_0);
			Hal4Sys_ATAPortOutB(IDE_CYLINDER_LOW,RBC_CDB.RbcCdb_Read.LBA_1);
			Hal4Sys_ATAPortOutB(IDE_CYLINDER_HIGH,RBC_CDB.RbcCdb_Read.LBA_2);
 	        Hal4Sys_ATAPortOutB(IDE_DEVICE_HEAD, (RBC_CDB.RbcCdb_Read.LBA_3&0x0f) | Hal4ATA_DevReg );
	    	Hal4Sys_ATAPortOutB(IDE_COMMAND, IDE_COMMAND_READ);
		}
	   	else
	   	{    	// write command.
		    Hal4Sys_ATAPortOutB(IDE_SECTOR,RBC_CDB.RbcCdb_Write.LBA_0);
		    Hal4Sys_ATAPortOutB(IDE_CYLINDER_LOW,RBC_CDB.RbcCdb_Write.LBA_1);
		    Hal4Sys_ATAPortOutB(IDE_CYLINDER_HIGH,RBC_CDB.RbcCdb_Write.LBA_2);
            Hal4Sys_ATAPortOutB(IDE_DEVICE_HEAD, (RBC_CDB.RbcCdb_Write.LBA_3&0x0f) | Hal4ATA_DevReg );
	    	Hal4Sys_ATAPortOutB(IDE_COMMAND,IDE_COMMAND_WRITE);
		}
	}
   	retStatus = Hal4ATA_WaitOnBusyNDrq();
    return retStatus;
} /* end Hal4ATA_ReadWriteSetting()*/


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -