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

📄 ata_driver.c

📁 文件包含了开发motorola mc9s12uf32单片机一些源码。  1、USB device 实现  2、CF卡读取  3、SD卡读取  4、ATA硬盘读取
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************
*                                                  
*  (c) copyright Freescale Semiconductor Hong Kong Ltd 2004
*  ALL RIGHTS RESERVED
*                                                                       
*******************************************************************************  
** THIS  CODE IS ONLY INTENDED AS AN EXAMPLE FOR DEMONSTRATING THE FREESCALE **
** MICROCONTROLLERS.  IT  HAS ONLY BEEN GIVEN A MIMIMUM LEVEL OF TEST. IT IS **
** PROVIDED  'AS  SEEN'  WITH  NO  GUARANTEES  AND  NO  PROMISE  OF SUPPORT. **
*******************************************************************************  
*                                                                           
* FILE:        ata_driver.c	 REVISION 0.1
*  
* DESCRIPTION:  Major part of ATA Driver module. (APIs & Functions)
*
* NOTES:       All modules remain at their reset addresses
*                                                  
* UPDATED HISTORY:
*
* REV   YYYY.MM.DD  AUTHOR        DESCRIPTION OF CHANGE
* ---   ----------  ------        --------------------- 
* 0.0   2002.06.27  Derek Lau     Initial version
* 0.1   2004.04.08  Derek Lau			Demo version
*
******************************************************************************/                                                                        
/* Freescale  is  not  obligated  to  provide  any  support, upgrades or new */
/* releases  of  the Software. Freescale may make changes to the Software at */
/* any time, without any obligation to notify or provide updated versions of */
/* the  Software  to you. Freescale expressly disclaims any warranty for the */
/* Software.  The  Software is provided as is, without warranty of any kind, */
/* either  express  or  implied,  including, without limitation, the implied */
/* warranties  of  merchantability,  fitness  for  a  particular purpose, or */
/* non-infringement.  You  assume  the entire risk arising out of the use or */
/* performance of the Software, or any systems you design using the software */
/* (if  any).  Nothing  may  be construed as a warranty or representation by */
/* Freescale  that  the  Software  or  any derivative work developed with or */
/* incorporating  the  Software  will  be  free  from  infringement  of  the */
/* intellectual property rights of third parties. In no event will Freescale */
/* be  liable,  whether in contract, tort, or otherwise, for any incidental, */
/* special,  indirect, consequential or punitive damages, including, but not */
/* limited  to,  damages  for  any loss of use, loss of time, inconvenience, */
/* commercial loss, or lost profits, savings, or revenues to the full extent */
/* such  may be disclaimed by law. The Software is not fault tolerant and is */
/* not  designed,  manufactured  or  intended by Freescale for incorporation */
/* into  products intended for use or resale in on-line control equipment in */
/* hazardous, dangerous to life or potentially life-threatening environments */
/* requiring  fail-safe  performance,  such  as  in the operation of nuclear */
/* facilities,  aircraft  navigation  or  communication systems, air traffic */
/* control,  direct  life  support machines or weapons systems, in which the */
/* failure  of  products  could  lead  directly to death, personal injury or */
/* severe  physical  or  environmental  damage  (High  Risk Activities). You */
/* specifically  represent and warrant that you will not use the Software or */
/* any  derivative  work of the Software for High Risk Activities.           */
/* Freescale  and the Freescale logos are registered trademarks of Freescale */
/* Semiconductor Inc.                                                        */ 
/*****************************************************************************/

#include	"FreescaleDef.h"			// Get my definitions (Constants & Macros)
#include	"uf32reg.h"			// Get the DP256 registers.
#include	"mk_extern.h"		// Get Mini-Kernel global prototypes
#include	"ata_includes.h"	// Get ATA Driver Configuration
#include	"usbms_extern.h"	// Get USB Mass Storage Drvier global
#include	"usbms_includes.h"
#include	"ata_extern.h"		// Get ATA exported global prototypes
#include	"utl_includes.h"

// code is placed in the main code area.
#pragma CODE_SEG	DEFAULT

// PIO0 - PIO4 timing
const muint16 kATARPIOReg1[] = 
	{kATARPIO0Reg1,kATARPIO1Reg1,kATARPIO2Reg1,kATARPIO3Reg1,kATARPIO4Reg1};
const muint16 kATAPIOReg1[] = 
	{kATAPIO0Reg1,kATAPIO1Reg1,kATAPIO2Reg1,kATAPIO3Reg1,kATAPIO4Reg1};
const muint16 kATAPIOReg2[] = 
	{kATAPIO0Reg2,kATAPIO1Reg2,kATAPIO2Reg2,kATAPIO3Reg2,kATAPIO4Reg2};
const muint16 kATAPIOReg3[] = 
	{kATAPIO0Reg3,kATAPIO1Reg3,kATAPIO2Reg3,kATAPIO3Reg3,kATAPIO4Reg3};
const muint16 kATAPIOReg4[] = 
	{kATAPIO0Reg4,kATAPIO1Reg4,kATAPIO2Reg4,kATAPIO3Reg4,kATAPIO4Reg4};

// UDMA0 - UDMA4 timing
const muint16 kATAUDMAReg1[] = 
	{kATAUDMA0Reg1,kATAUDMA1Reg1,kATAUDMA2Reg1, 
	kATAUDMA3Reg1,kATAUDMA4Reg1,kATAUDMA5Reg1};
const muint16 kATAUDMAReg2[] = 
	{kATAUDMA0Reg2,kATAUDMA1Reg2,kATAUDMA2Reg2,	
	kATAUDMA3Reg2,kATAUDMA4Reg2,kATAUDMA5Reg2};
const muint16 kATAUDMAReg3[] = 
	{kATAUDMA0Reg3,kATAUDMA1Reg3,kATAUDMA2Reg3,	
	kATAUDMA3Reg3,kATAUDMA4Reg3,kATAUDMA5Reg3};
const muint16 kATAUDMAReg4[] = 
	{kATAUDMA0Reg4,kATAUDMA1Reg4,kATAUDMA2Reg4,	
	kATAUDMA3Reg4,kATAUDMA4Reg4,kATAUDMA5Reg4};
const muint16 kATAUDMAReg5[] = 
	{kATAUDMA0Reg5,kATAUDMA1Reg5,kATAUDMA2Reg5,	
	kATAUDMA3Reg5,kATAUDMA4Reg5,kATAUDMA5Reg5};
const muint16 kATAUDMAReg6[] = 
	{kATAUDMA0Reg6,kATAUDMA1Reg6,kATAUDMA2Reg6,	
	kATAUDMA3Reg6,kATAUDMA4Reg6,kATAUDMA5Reg6};
const muint16 kATAUDMAReg7[] = 
	{kATAUDMA0Reg7,kATAUDMA1Reg7,kATAUDMA2Reg7,	
	kATAUDMA3Reg7,kATAUDMA4Reg7,kATAUDMA5Reg7};
const muint16 kATAUDMAReg8[] = 
	{kATAUDMA0Reg8,kATAUDMA1Reg8,kATAUDMA2Reg8,	
	kATAUDMA3Reg8,kATAUDMA4Reg8,kATAUDMA5Reg8};
const muint16 kATAUDMAReg9[] = 
	{kATAUDMA0Reg9,kATAUDMA1Reg9,kATAUDMA2Reg9,	
	kATAUDMA3Reg9,kATAUDMA4Reg9,kATAUDMA5Reg9};

// Multi-word DMA0 - MDMA2 timing
const muint16 kATAMDMAReg1[] =
	{kATAMDMA0Reg1,kATAMDMA1Reg1,kATAMDMA2Reg1};
const muint16 kATAMDMAReg2[] =
	{kATAMDMA0Reg2,kATAMDMA1Reg2,kATAMDMA2Reg2};
const muint16 kATAMDMAReg3[] =
	{kATAMDMA0Reg3,kATAMDMA1Reg3,kATAMDMA2Reg3};
const muint16 kATAMDMAReg4[] =
	{kATAMDMA0Reg4,kATAMDMA1Reg4,kATAMDMA2Reg4};

// PIO, UMDA, MDMA mode setting in ATA Set Feature
const muint8 kATAPIO2Mode[] = 
	{kATAFCmdXfPIO0,kATAFCmdXfPIO1,kATAFCmdXfPIO2,
	kATAFCmdXfPIO3,kATAFCmdXfPIO4};
const muint8 kATAUDMA2Mode[] = 
	{kATAFCmdXfUDMA0,kATAFCmdXfUDMA1,kATAFCmdXfUDMA2,
	kATAFCmdXfUDMA3,kATAFCmdXfUDMA4};
const muint8 kATAMDMA2Mode[] = 
	{kATAFCmdXfMDMA0,kATAFCmdXfMDMA1,kATAFCmdXfMDMA2};



void ATA_Delay(muint16 delay)
{
	muint16 BegTime,CurTime;
	
	BegTime = MK_GetCurrentTime();

	do
	{
		CurTime = MK_GetCurrentTime();
	} 
	while ( ((CurTime-BegTime) < delay) || ((BegTime - CurTime) < delay));

}

volatile ATAErrorCode ATA_WaitRegBusy(void)
{

	muint16 j;

		for (j=0; j<0x100; j++)
		{
			if (!(ATA_HSR_H & ((1<<ATATIP) | (1<<ATADRAB))))
			{
				return(kCSWPass);
			}
		}
	mSetBit(DBRST,QC12DCR);
	ATA_DCR_L = 0;
	return (kCSWFailed);
}


void ATA_PreInit(void)
{
	gATAPIOMode = 0xff;
	gATASenseKey = kSCSISKNotReady;

}	

ATAErrorCode ATA_Init(muint8 resetpin, volatile muint8 *resetport)
{
	#ifdef CUSTOMER_BOARD3
		MODRR |= 0x03;
	#endif	

	mClearBit(resetpin,*resetport);	// set resetpin to zero
	mSetBit(resetpin,*(resetport+2));	// set resetpin to output

	ATA_SetRPIOTiming(1);
	ATA_HCFG_H	= (1<<ATASMR)+(1<<ATAFR)+(1<<ATACLKEN)+(1<<ATAXNW)+(1<<ATAIORDY);
	ATA_HCFG_H	= (1<<ATACLKEN)+(1<<ATAXNW)+(1<<ATAIORDY);


	ATA_Delay(20);						// delay 20ms

	mClearBit(resetpin,*(resetport+2));	// set resetpin to input
	ATA_Delay(100);						// delay 100ms

	return ATA_GetSetDeviceInfo();
}


// ==================================================================
//   ATA_SoftwareReset() -
//
//     To issues reset command to the ATA device.
//
//	Input -		=	nil
//				
//	Output - 	=	nil
//
//	Function 
//
// ==================================================================

ATAErrorCode ATA_SoftwareReset(void)
{
	ATAErrorCode error;

	ATA_DCTR_B = (1<<ATASRST);	// reset device 
	error = ATA_WaitRegBusy();
	if (error)
		return(error);

	ATA_Delay(2);				// delay 2ms
	ATA_DCTR_B = 0;
	error = ATA_WaitRegBusy();
	if (error)
		return(error);

	ATA_Delay(3);				// delay 3ms

	return (ATA_WaitATABusy());
}


// ==================================================================
//   ATA_PacketCommand() -
//
//     To set command to ATAPI device
//
//	Input -		=	ATAPI command pointer
//				
//	Output - 	=	ATAErrorCode
//
//	Function returns error code
//
// ==================================================================
ATAErrorCode ATA_PacketCommand(muint16 *pCommand)
{
	muint8	i;
	ATAErrorCode	error;
	muint8	atadcrl;

	if (mCheckBit(bitATAUDMAMode,gATAStatus))				// if udma mode supported
	{
		if ( (*pCommand == (kSCSIRead10<<kOneByte)) || (*pCommand == (kSCSIRead12<<kOneByte)))
		{													// if udma read
			ATA_DFR_B = 0x01;								// inform device udma mode
			atadcrl = (1<<ATAUDMA) | (1<<ATAUDMARD);		// prepare udma read for host
		}
		else												// if udma write
		{
			if ((*pCommand == (kSCSIWrite10<<kOneByte)) || 	\
				(*pCommand == (kSCSIWrite12<<kOneByte)) ||	\
				(*pCommand == (kSCSIVerify10<<kOneByte)))
			{
				ATA_DFR_B = 0x01;							// inform device udma mode
				atadcrl = (1<<ATAUDMA) | (1<<ATAUDMAWR);	// prepare udma write for host
			}
			else
			{
				ATA_DFR_B = 0;
				atadcrl = 0;
			}
		}
	}
	else													// udma not support
	{
		ATA_DFR_B = 0x00;
		atadcrl = 0;
	}
	
	error = ATA_WaitRegBusy();
	if (error)
		return(error);		
	
	ATA_DSCR_B = 0x00;
	error = ATA_WaitRegBusy();
	if (error)
		return(error);		

	ATA_LBAM_B = 0xFE;										// Maximum byte of transfer
	error = ATA_WaitRegBusy();
	if (error)
		return(error);			
    
    ATA_LBAH_B = 0xFF;
	error = ATA_WaitRegBusy();
	if (error)
		return(error);		

	ATA_DDHR_B = 0x00;
	error = ATA_WaitRegBusy();
	if (error)
		return(error);			
    
	ATA_DCR = (kATACmdPacket << 8);							// issue command
	error = ATA_WaitRegBusy();
	if (error)
		return(error);

	error = ATA_WaitATABusy();								// wait for ATA not busy
	if (error)
		return(error);

	for (i=0; i<gATAPacketLen; i++)		// write 6 or 8 words of command
	{
		ATA_DDR = *pCommand++;
		
		error = ATA_WaitRegBusy();
		if (error)
			return(error);			// PIO
	}
	
	if (atadcrl)
	{
		ATA_DCR_L = atadcrl;
		return(kATAPass);
	}

	return(ATA_WaitATABusy());
}


// ==================================================================
//   ATA_Command() -
//
//     To set command to ATA device
//
//	Input -		=	7 command parameters
//				
//	Output - 	=	
//
//	Function returns error code
//
// ==================================================================
muint8 ATA_Command(sATACommand *psATACommand)
{
	muint8 error;
	
	error = ATA_WaitATABusy();
		
	if (error)
		return(error);

	ATA_DFR_B	= psATACommand->features;
	error = ATA_WaitRegBusy();
	if (error)
		return(error);	
    	
    ATA_DSCR_B = psATACommand->count;
	error = ATA_WaitRegBusy();
	if (error)
		return(error);			
    
    ATA_LBAL_B = psATACommand->lba_low;
	error = ATA_WaitRegBusy();
	if (error)
		return(error);		
    
    ATA_LBAM_B = psATACommand->lba_mid;
	error = ATA_WaitRegBusy();
	if (error)
		return(error);		

    ATA_LBAH_B = psATACommand->lba_high;
	error = ATA_WaitRegBusy();
	if (error)
		return(error);		
    
    ATA_DDHR_B = psATACommand->device;
	error = ATA_WaitRegBusy();
	if (error)
		return(error);		
    
	ATA_DCR = ( (muint16) psATACommand->command << 8);
	
	error = ATA_WaitRegBusy();
	if (error)
		return(error);

	ATA_DCR_L = psATACommand->dmamode;

	return (ATA_WaitATABusy());

}

// ==================================================================
//   ATA_LBAATACommand() -
//
//     To set command to ATA device
//
//	Input -		=	7 command parameters
//				
//	Output - 	=	
//
//	Function returns error code
//
// ==================================================================
ATAErrorCode ATA_LBAATACommand(muint8 Block, muint8 ATACmd)
{
	volatile ATAErrorCode error;
	muint8	*pLBA;

	pLBA = (muint8*) &gATALBA;

	error = ATA_WaitRegBusy();
	if (error)
		return(error);
	
	(void) ATA_WaitATABusy();

	if (*pLBA & 0xf0)				// if memory > 128G
  {
   	ATA_DSCR_B = 0;					// high byte of sector count
		error = ATA_WaitRegBusy();
		if (error)
			return(error);			

    ATA_LBAL_B = *pLBA;		// LBA 31:24
		error = ATA_WaitRegBusy();
		if (error)
			return(error);			

   	ATA_LBAM_B = 0;					// LBA 39:32
		error = ATA_WaitRegBusy();
		if (error)
			return(error);			

   	ATA_LBAH_B = 0;
		error = ATA_WaitRegBusy();		// LBA 47:40
		if (error)
			return(error);
	}	

  ATA_DSCR_B = Block;

⌨️ 快捷键说明

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