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

📄 hal4ata.c

📁 用D12实现U盘的单片机程序
💻 C
📖 第 1 页 / 共 2 页
字号:

} /* end IssueIdentify()*/

BOOLEAN
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);

}

BOOLEAN
Hal4ATA_IsLBAmode(void)
{
//	if( ATADevExt_IDData.CurrentSectorCapacity.u0 >= ((INT32) 63<<14) ) /*63* 1024 * 16*/
//	{
        Hal4ATA_DevReg_LBA = 1;
//	}
//    else
//    {
//        Hal4ATA_DevReg_LBA = 0;
//    }
    return(Hal4ATA_DevReg_LBA);
}

BOOLEAN
Hal4ATA_IsModeOK(void)
{
	/*
	// This hideous hack is to deal with ESDI devices that return
	// garbage geometry in the IDENTIFY data.
	// This is ONLY for the crashdump environment as
	// these are ESDI devices.
	*/
    ATABF_IsSkipSetParameters = FALSE;


	if (Hal4ATA_DevExt.IdentifyData.SectorsPerTrack == 0x35 &&
		ATADevExt_IDData.NumberOfHeads == 0x07)
	{
		/*
		// Change these values to something reasonable.
		*/
		ATADevExt_IDData.SectorsPerTrack = 0x34;
		ATADevExt_IDData.NumberOfHeads = 0x0E;
	}

	if (ATADevExt_IDData.SectorsPerTrack == 0x35 &&
		ATADevExt_IDData.NumberOfHeads == 0x0F)
	{

		/*
		// Change these values to something reasonable.
		*/

		ATADevExt_IDData.SectorsPerTrack = 0x34;
		ATADevExt_IDData.NumberOfHeads = 0x0F;
	}

	if (ATADevExt_IDData.SectorsPerTrack == 0x36 &&
		ATADevExt_IDData.NumberOfHeads == 0x07)
	{

		/*
		// Change these values to something reasonable.
		*/
		ATADevExt_IDData.SectorsPerTrack = 0x3F;
		ATADevExt_IDData.NumberOfHeads = 0x10;
		ATABF_IsSkipSetParameters = TRUE;
	}

    return ATABF_IsSkipSetParameters;
}

BOOLEAN
Hal4ATA_SetFeature(void)
{
   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);
}

BOOLEAN
Hal4ATA_SetDriveParameters(void)
{
    BOOLEAN retStatus = FALSE;

    if(Hal4ATA_WaitOnBusy())
    {
        /*
	    // Set up registers for SET PARAMETER command.
	    */
   	    //Hal4Sys_ATAPortOutB(ATAREG4OUT_DEVICE_HEAD,Hal4ATA_DevReg|(ATADevExt_IDData.NumberOfHeads-1) );
        Hal4Sys_ATAPortOutB(ATAREG4OUT_DEVICE_HEAD,0xef );
        //Hal4Sys_ATAPortOutB(ATAREG4OUT_SECTOR_COUNT,ATADevExt_IDData.SectorsPerTrack);
        Hal4Sys_ATAPortOutB(ATAREG4OUT_SECTOR_COUNT,0x20);

        if(Hal4ATA_WaitOnBusyNDrdy())
        {

	        /*
	        // Send SET PARAMETER command.
	        // IDE_COMMAND_SET_DRIVE_PARAMETERS 0x91 (Init Device Parameter)
	        */
	        Hal4Sys_ATAPortOutB(ATAREG4OUT_COMMAND,IDE_COMMAND_SET_DRIVE_PARAMETERS);

            retStatus = Hal4ATA_WaitOnBusy();
        }
    }
    return retStatus;
} /* end Hal4ATA_SetDriveParameters()*/


BOOLEAN
Hal4ATA_SetMultipleMode(void)  //IDE_COMMAND_SET_MULTIPLE=0xC6
{
    BOOLEAN retStatus = FALSE;
	if ( ATABF_IsAttached && Hal4ATA_SelDevice() )
	{
        if(ATADevExt_IDData.MaximumBlockTransfer > MULTI_BLOCK_1 )
        {
	//	    Hal4Sys_ATAPortOutB(ATAREG4OUT_SECTOR_COUNT, ATADevExt_IDData.MaximumBlockTransfer);
	//	    Hal4Sys_ATAPortOutB(ATAREG4OUT_COMMAND, IDE_COMMAND_SET_MULTIPLE);
            if( Hal4ATA_WaitOnBusy())
            {
                ATABF_IsSupportMultiSector = TRUE;
                retStatus = TRUE;
            }
            else
			{
                ATABF_IsSupportMultiSector = FALSE;
			}
		}
        else
        {
            ATABF_IsSupportMultiSector = FALSE;
        }

        if(ATABF_IsSupportMultiSector == FALSE)
        {
            retStatus = Hal4ATA_IdeSoftReset();
        }
	}

    return retStatus;
}

/*
//*************************************************************************
//  Subroutines -- level 5 ATA transaction
//*************************************************************************
*/
BOOLEAN
Hal4ATA_IdeHardReset(void)
{
    INT8 c,a,b,d,e;
    BOOLEAN retStatus = FALSE;


    ATA_RST_N = 0;
    Hal4Sys_WaitInUS(320); // >25 US
    ATA_RST_N = 1;
/*
	while (TRUE)
	{	a= Hal4Sys_ATAPortInB(ATAREG4IN_SECTOR_COUNT);
		b = Hal4Sys_ATAPortInB(ATAREG4IN_SECTOR_NUMBER);
		d = Hal4Sys_ATAPortInB(ATAREG4IN_CYLINDER_LOW);
		e = Hal4Sys_ATAPortInB(ATAREG4IN_CYLINDER_HIGH);

		if ( (d+e >0) && (a+b >2))
		{ATA_RST_N = 0;
	     Hal4Sys_WaitInUS(320); // >25 US
	     ATA_RST_N = 1;
	 	}
	 else
	 break;
	}
*/
    for(c = 20; c != 0; c--)
    	Hal4Sys_WaitInUS(50000); // 50MS

    if(Hal4ATA_SelDevice())
	{

    Hal4ATA_DevReg_DEV = FALSE;
    Hal4Sys_ATAPortOutB(ATAREG4OUT_DEVICE_HEAD,Hal4ATA_DevReg);
	}

#ifndef DEBUG
    for(c = 31; c!=0; c--)  // 31 Seconds time out
#else
    while(TRUE)
#endif
    {
        if(Hal4ATA_WaitOnBusyNDrdy())
        {
            retStatus = TRUE;
            break;
        }
    }

 //   MCU_P1 = D12REG_ONLY;
    return retStatus;
}

BOOLEAN
Hal4ATA_FindIDEDevice(void)
{

    INT8    c;

    ATABF_IsAttached = FALSE;
    Hal4ATA_DevReg_DEV = FALSE;

	if(Hal4ATA_IdeHardReset())
    {
	//	Hal4Sys_ATAPortOutB(ATAREG4OUT_CONTROL,0xFA);
		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();

            if(!Hal4ATA_DevReg_LBA)
            {
			    //  Being cautious,
                //  CHS Harddisk set block=1
    		    ATADevExt_IDData.MaximumBlockTransfer = 1;

            }


            if( Hal4ATA_IsModeOK() == FALSE)
            {
		        ATABF_IsAttached = Hal4ATA_SetDriveParameters();
            }

            if(ATABF_IsAttached)
            {
                ATABF_IsAttached = Hal4ATA_SetMultipleMode();
		    }

        } // IDE HD is found

//Hal4Sys_ATAPortOutB(ATAREG4OUT_CONTROL,0xFA);
    } // IDE Reset OK

//    MCU_P1 = D12REG_ONLY;   //D12REG_ONLY =0xB8

    return ATABF_IsAttached;


} /*end Hal4ATA_FindIDEDevice()*/


BOOLEAN
Hal4ATA_ReadWriteSetting(void)
{

    BOOLEAN retStatus = FALSE;
    /*
	// Select device  .
	*/
	if(Hal4ATA_SelDevice())
	//if(TRUE)
    {
        //Assume Sector Counter <256
        Hal4Sys_ATAPortOutB(ATAREG4OUT_SECTOR_COUNT, RBC_CDB.RbcCdb_Read.XferLength_0);


	    if(Hal4ATA_DevReg_LBA )
	    /* IN LBA mode */
	    {
		    /*
		    // Set up sector number register.
		    */
		    /* From Read Card Capacity()
cdbReadCap.tmpVar.CapData.LBA_3 =cdbReadCap.tmpVar.l0[1].chars0.c3;
cdbReadCap.tmpVar.CapData.LBA_2 =cdbReadCap.tmpVar.l0[1].chars0.c2;
cdbReadCap.tmpVar.CapData.LBA_1 =cdbReadCap.tmpVar.l0[1].chars0.c1;
cdbReadCap.tmpVar.CapData.LBA_0 =cdbReadCap.tmpVar.l0[1].chars0.c0;
			*/

//-----------------------------------------
		if( ATABF_IDEXfer_dir )    // ATABF_Xfer_dir==1 Read(from Dev to Host)
  		    {


		    Hal4Sys_ATAPortOutB(ATAREG4OUT_SECTOR_NUMBER,RBC_CDB.RbcCdb_Read.LBA.LBA_W8.LBA_0);
		    Hal4Sys_ATAPortOutB(ATAREG4OUT_CYLINDER_LOW,RBC_CDB.RbcCdb_Read.LBA.LBA_W8.LBA_1);
		    Hal4Sys_ATAPortOutB(ATAREG4OUT_CYLINDER_HIGH,RBC_CDB.RbcCdb_Read.LBA.LBA_W8.LBA_2);
            Hal4Sys_ATAPortOutB(ATAREG4OUT_DEVICE_HEAD, (RBC_CDB.RbcCdb_Read.LBA.LBA_W8.LBA_3&0x0f) | Hal4ATA_DevReg );


	    }
	    else
	    {
		    // write command.
		    Hal4Sys_ATAPortOutB(ATAREG4OUT_SECTOR_NUMBER,RBC_CDB.RbcCdb_Write.LBA.LBA_W8.LBA_0);
		    Hal4Sys_ATAPortOutB(ATAREG4OUT_CYLINDER_LOW,RBC_CDB.RbcCdb_Write.LBA.LBA_W8.LBA_1);
		    Hal4Sys_ATAPortOutB(ATAREG4OUT_CYLINDER_HIGH,RBC_CDB.RbcCdb_Write.LBA.LBA_W8.LBA_2);
            Hal4Sys_ATAPortOutB(ATAREG4OUT_DEVICE_HEAD, (RBC_CDB.RbcCdb_Write.LBA.LBA_W8.LBA_3&0x0f) | Hal4ATA_DevReg );
		    }

 //----------------------------------------
	    }
	    else
	    /* CHS mode */
	    {
		    /*
		    // Set up sector number register.
		    */
		    Hal4Sys_ATAPortOutB(ATAREG4OUT_SECTOR_NUMBER,(INT8) ((RBC_CDB.RbcCdb_Read.LBA.LBA_W32 % ATADevExt_IDData.SectorsPerTrack) + 1));

		    /*
		    // Caculate Hal4ATA_Track & Hal4ATA_drvSelect
		    */
		    Hal4ATA_Track.u0 = RBC_CDB.RbcCdb_Read.LBA.LBA_W32/((INT32)(ATADevExt_IDData.SectorsPerTrack));
		    Hal4ATA_drvSelect = (INT8)(Hal4ATA_Track.u0%ATADevExt_IDData.NumberOfHeads);
		    Hal4ATA_Track.u0 /= ((INT32)(ATADevExt_IDData.NumberOfHeads));

		    /*
		    // Set up cylinder low register.
		    */
		    Hal4Sys_ATAPortOutB(ATAREG4OUT_CYLINDER_LOW,Hal4ATA_Track.chars0.c0);
		    Hal4Sys_ATAPortOutB(ATAREG4OUT_CYLINDER_HIGH,Hal4ATA_Track.chars0.c1);

		    /*
		    // Set up head and drive select register.
		    */
            Hal4Sys_ATAPortOutB(ATAREG4OUT_DEVICE_HEAD, Hal4ATA_DevReg|Hal4ATA_drvSelect);
	    }

	    if( ATABF_IDEXfer_dir )    // ATABF_Xfer_dir==1 Read(from Dev to Host)
	    {
		    /*
		    // Send read command.
		    */
		 //   if (ATABF_IsSupportMultiSector)
		//	    Hal4Sys_ATAPortOutB(ATAREG4OUT_COMMAND, IDE_COMMAND_READ_MULTIPLE);
		//    else
			    Hal4Sys_ATAPortOutB(ATAREG4OUT_COMMAND, IDE_COMMAND_READ);
	    }
	    else
	    {
		    /*
		    // Send write command.
		    */
		  //  if (ATABF_IsSupportMultiSector)
		//	    Hal4Sys_ATAPortOutB(ATAREG4OUT_COMMAND,IDE_COMMAND_WRITE_MULTIPLE);
		//    else
			    Hal4Sys_ATAPortOutB(ATAREG4OUT_COMMAND,IDE_COMMAND_WRITE);
	    }

	    retStatus = Hal4ATA_WaitOnBusyNDrq();
    }

  //  MCU_P1 = D12REG_ONLY;
    return retStatus;

} /* end Hal4ATA_ReadWriteSetting()*/


⌨️ 快捷键说明

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