📄 ata_driver.c
字号:
/******************************************************************************
*
* (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 + -