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

📄 ctrl_atapi.c

📁 STi5518机顶盒ATAPI源代码!绝对超值!
💻 C
字号:
/************************************************************************Source file name : ctrl_atapi.cDescription: Implementation of the ATA Control Interface and Device/Protocol            setup  intermediate modules following the API Design Document             v0.9.0 of the ATAPI driver.             COPYRIGHT (C) STMicroelectronics  2000************************************************************************//*Includes-------------------------------------------------------------*/#include <string.h>#include "stlite.h"#include "stcommon.h"#include "statapi.h"#include "hal_atapi.h"#include "ata.h"/*Private Types--------------------------------------------------------*//*Private Constants----------------------------------------------------*/#define HARD_RESET_TIMEOUT_SECONDS  10/*Private Variables----------------------------------------------------*//*Private Macros-------------------------------------------------------*//*Private functions prototypes-----------------------------------------*//*Functions------------------------------------------------------------*/ /************************************************************************Name: ata_ctrl_SelectDeviceDescription: Attempts to select the device by writing to the Device/Header reg.             Also delays the mandatory 400 ns to ensure subsequent device access is             safeParameters: Two params:            Ata_p : Pointer to the ATA control block            Device: number identifying the device (0,1)            ************************************************************************/BOOL ata_ctrl_SelectDevice(ata_ControlBlock_t *Ata_p, U8 Device){    U8 data;                  /* First wait for not busy (BSY=0)... */    if(WaitForBit(Ata_p->HalHndl,ATA_REG_STATUS,BSY_BIT_MASK,0))    {         Ata_p->LastExtendedErrorCode=0x11;         return TRUE;    }            /* ..then wait for DRQ=0 */    if(WaitForBit(Ata_p->HalHndl,ATA_REG_STATUS,DRQ_BIT_MASK,0))    {         Ata_p->LastExtendedErrorCode=0x12;         return TRUE;    }                 data= hal_RegInByte(Ata_p->HalHndl,ATA_REG_DEVHEAD);    if(Device==DEVICE_0) data= data & ~BIT_4;    else          data= data | BIT_4;        hal_RegOutByte(Ata_p->HalHndl,ATA_REG_DEVHEAD,data);    WAIT400NS;                /* First wait for not busy (BSY=0)... */   if(WaitForBit(Ata_p->HalHndl,ATA_REG_STATUS,BSY_BIT_MASK,0))    {         Ata_p->LastExtendedErrorCode=0x11;         return TRUE;    }        /* ...then wait for DRQ=0 */    if(WaitForBit(Ata_p->HalHndl,ATA_REG_STATUS,DRQ_BIT_MASK,0))    {         Ata_p->LastExtendedErrorCode=0x12;         return TRUE;    }         return FALSE;}/************************************************************************Name: ata_ctrl_SoftResetDescription: Pulses the SRST bit in the DeviceCtrl register high for 400 ns and             then low. Delays for mandatory 400ns afterwardsParameters: Two params:            Ata_p : Pointer to the ATA control block            Device: number identifying the device (0,1)            ************************************************************************/BOOL ata_ctrl_SoftReset(ata_ControlBlock_t *Ata_p){    S32 TimeOut=ATA_TIMEOUT;    U8  sc,sn;        /* Assert SRST and disable interrupts */    hal_RegOutByte(Ata_p->HalHndl,ATA_REG_CONTROL,SRST_SET|nIEN_SET);        /* Wait t > 2ms */    task_delay(TWO_MS);        /*Deassert SRTS and enable interrupts if necessary*/#if ATAPI_USING_INTERRUPTS    hal_RegOutByte(Ata_p->HalHndl, ATA_REG_CONTROL, 0x00);#else        hal_RegOutByte(Ata_p->HalHndl, ATA_REG_CONTROL, 0x02);#endif        WAIT400NS;    /*RESET DONE. This causes device 0 be selected.*/    /* If there is a device 0, wait for device 0 to set BSY=0.*/    if(Ata_p->DevInBus[0] != NONE_DEVICE)    {        if(WaitForBit(Ata_p->HalHndl, ATA_REG_STATUS, BSY_BIT_MASK, 0))        {            Ata_p->LastExtendedErrorCode = 0x01;            return TRUE;        }    }        /* If there is a device 1, wait until device 1 allows       register access.*/           if(Ata_p->DevInBus[1] != NONE_DEVICE)    {          /* Select the device */        hal_RegOutByte(Ata_p->HalHndl, ATA_REG_DEVHEAD, DEVHEAD_DEV1);        WAIT400NS;                while(TimeOut >= 0)        {            sn = hal_RegInByte(Ata_p->HalHndl, ATA_REG_SECNUM);            sc = hal_RegInByte(Ata_p->HalHndl, ATA_REG_SECCOUNT);            if ((sn == 0x01) && (sc == 0x01))                break;            TimeOut--;        }                   if(TimeOut<0)         {            Ata_p->LastExtendedErrorCode = 0x02;            return TRUE;        }                /* Now wait for device 1 to set BSY=0 */        if(WaitForBit(Ata_p->HalHndl, ATA_REG_STATUS, BSY_BIT_MASK, 0))        {            Ata_p->LastExtendedErrorCode = 0x03;            return TRUE;        }    }       return FALSE;}/************************************************************************Name: ata_ctrl_ProbeDescription: Probes the ATA bus to determine the number of devices attached and             their type (ATA or ATAPI)Parameter:  Ata_p : Pointer to the ATA control block            ************************************************************************/BOOL ata_ctrl_Probe(ata_ControlBlock_t *Ata_p){    U8 error=0;    volatile U8 sc,sn,cl,ch,st;           Ata_p->DevInBus[0]=NONE_DEVICE;    Ata_p->DevInBus[1]=NONE_DEVICE;        /* lets see if there is a device 0*/        hal_RegOutByte(Ata_p->HalHndl,ATA_REG_DEVHEAD,DEVHEAD_DEV0);    WAIT400NS;    hal_RegOutByte(Ata_p->HalHndl,ATA_REG_SECCOUNT ,0x55);    hal_RegOutByte(Ata_p->HalHndl,ATA_REG_SECNUM ,0xaa);    hal_RegOutByte(Ata_p->HalHndl,ATA_REG_SECCOUNT ,0xaa);    hal_RegOutByte(Ata_p->HalHndl,ATA_REG_SECNUM ,0x55);    hal_RegOutByte(Ata_p->HalHndl,ATA_REG_SECCOUNT ,0x55);    hal_RegOutByte(Ata_p->HalHndl,ATA_REG_SECNUM ,0xaa);         sc = hal_RegInByte(Ata_p->HalHndl,ATA_REG_SECCOUNT);   sn = hal_RegInByte(Ata_p->HalHndl,ATA_REG_SECNUM);    if ( ( sc == 0x55 ) && ( sn == 0xaa ) )      Ata_p->DevInBus[0]= UNKNOWN_DEVICE;    /* lets see if there is a device 1*/        hal_RegOutByte(Ata_p->HalHndl,ATA_REG_DEVHEAD,DEVHEAD_DEV1);    WAIT400NS;    hal_RegOutByte(Ata_p->HalHndl,ATA_REG_SECCOUNT ,0x55);    hal_RegOutByte(Ata_p->HalHndl,ATA_REG_SECNUM ,0xaa);    hal_RegOutByte(Ata_p->HalHndl,ATA_REG_SECCOUNT ,0xaa);    hal_RegOutByte(Ata_p->HalHndl,ATA_REG_SECNUM ,0x55);    hal_RegOutByte(Ata_p->HalHndl,ATA_REG_SECCOUNT ,0x55);    hal_RegOutByte(Ata_p->HalHndl,ATA_REG_SECNUM ,0xaa);          sc = hal_RegInByte(Ata_p->HalHndl,ATA_REG_SECCOUNT);   sn = hal_RegInByte(Ata_p->HalHndl,ATA_REG_SECNUM);   if ( ( sc == 0x55 ) && ( sn == 0xaa ) )      Ata_p->DevInBus[1]= UNKNOWN_DEVICE;    /*   now we think we know which devices, if any are there,        so lets try a soft reset (ignoring any errors).*/        /*Assert SRST and disable interrupts */    hal_RegOutByte(Ata_p->HalHndl,ATA_REG_CONTROL,SRST_SET|nIEN_SET);    /* Wait t > 2ms */    task_delay(TWO_MS);    /*Deassert SRTS and enable interrupts if necessary*/   #if ATAPI_USING_INTERRUPTS         hal_RegOutByte(Ata_p->HalHndl,ATA_REG_CONTROL,0x08);    #else             hal_RegOutByte(Ata_p->HalHndl,ATA_REG_CONTROL,0x00);    #endif             WaitForBit(Ata_p->HalHndl,ATA_REG_STATUS,BSY_BIT_MASK,0);       /*RESET DONE. This causes device 0 be selected.*/       sc = hal_RegInByte(Ata_p->HalHndl,ATA_REG_SECCOUNT);   sn = hal_RegInByte(Ata_p->HalHndl,ATA_REG_SECNUM);   if ( ( sc == 0x01 ) && ( sn == 0x01 ) )   {      Ata_p->DevInBus[0]= UNKNOWN_DEVICE;      ch = hal_RegInByte(Ata_p->HalHndl,ATA_REG_CYLHIGH);      cl = hal_RegInByte(Ata_p->HalHndl,ATA_REG_CYLLOW);      st = hal_RegInByte(Ata_p->HalHndl,ATA_REG_STATUS);            if ( ( cl == 0x14 ) && ( ch == 0xeb ) )         Ata_p->DevInBus[0] = ATAPI_DEVICE;      else         if ( ( cl == 0x00 ) && ( ch == 0x00 ) && ( st != 0x00 ) )            Ata_p->DevInBus[0] = ATA_DEVICE;   }    /*Now for the device 1*/    hal_RegOutByte(Ata_p->HalHndl,ATA_REG_DEVHEAD,DEVHEAD_DEV1);    WAIT400NS;       sc = hal_RegInByte(Ata_p->HalHndl,ATA_REG_SECCOUNT);   sn = hal_RegInByte(Ata_p->HalHndl,ATA_REG_SECNUM);   if ( ( sc == 0x01 ) && ( sn == 0x01 ) )   {      Ata_p->DevInBus[1]= UNKNOWN_DEVICE;      cl = hal_RegInByte(Ata_p->HalHndl,ATA_REG_CYLHIGH);      ch = hal_RegInByte(Ata_p->HalHndl,ATA_REG_CYLLOW);      st = hal_RegInByte(Ata_p->HalHndl,ATA_REG_STATUS);            if ( ( cl == 0x14 ) && ( ch == 0xeb ) )         Ata_p->DevInBus[1] = ATAPI_DEVICE;      else         if ( ( cl == 0x00 ) && ( ch == 0x00 ) && ( st != 0x00 ) )            Ata_p->DevInBus[1] = ATA_DEVICE;   }             return error;    }/************************************************************************Name: ata_ctrl_HardResetDescription: Probes the ATA bus to determine the number of devices attached and             their type (ATA or ATAPI)Parameter:  Ata_p : Pointer to the ATA control block            ************************************************************************/BOOL ata_ctrl_HardReset(ata_ControlBlock_t *Ata_p){    volatile U8 Dummy;    clock_t     timeout;    U32         TimeoutTicks;    TimeoutTicks = HARD_RESET_TIMEOUT_SECONDS * ST_GetClocksPerSecond();    hal_HardReset(Ata_p->HalHndl);        timeout = time_plus(time_now(), TimeoutTicks);         /* Wait for BSY=0 or timeout */    while(TRUE)    {        WAIT400NS;        Dummy=hal_RegInByte(Ata_p->HalHndl,ATA_REG_STATUS);        if ((Dummy & BSY_BIT_MASK) == 0)             break;        /* Returns 1 if first time is after the second */        if (time_after(time_now(), timeout) == 1)            break;    }        /* Check */    if ((Dummy & BSY_BIT_MASK) == 0)        return FALSE;    else        return TRUE;}/************************************************************************Name: ata_bus_AcquireDescription: Obtains the bus check semaphore and checks the bus busy flag (SW             flag). If not set the bus busy flag is set. Releases the bus check             semaphoreParameter:  Ata_p : Pointer to the ATA control block            ************************************************************************/BOOL ata_bus_Acquire(ata_ControlBlock_t *Ata_p){    /* Semaphore needs to protect check, as well as any set */    semaphore_wait ( &Ata_p->BusMutexSemaphore );    if(Ata_p->BusBusy==FALSE)    {        Ata_p->BusBusy=TRUE;        semaphore_signal ( &Ata_p->BusMutexSemaphore );         return FALSE;    }    semaphore_signal ( &Ata_p->BusMutexSemaphore );     return TRUE;}/************************************************************************Name: ata_bus_ReleaseDescription: Obtains the bus check semaphore and checks the bus busy flag (SW             flag). If set the bus busy flag is cleared. Releases the bus check             semaphoreParameter:  Ata_p : Pointer to the ATA control block            ************************************************************************/BOOL ata_bus_Release(ata_ControlBlock_t *Ata_p){    /* Semaphore needs to protect check, as well as any set */    semaphore_wait ( &Ata_p->BusMutexSemaphore );    if(Ata_p->BusBusy == TRUE)    {        Ata_p->BusBusy=FALSE;        semaphore_signal ( &Ata_p->BusMutexSemaphore );         return FALSE;    }    semaphore_signal ( &Ata_p->BusMutexSemaphore );     return TRUE;}/************************************************************************Name: WaitForBitDescription: Wait for a bit to be setParameters: Three params:            HalHndl : Pointer to the HAL control block            regNo: Register number            bitNo: mask with the bit to test            expected_val: expected value of the register after applying a mask to            use only the relevant bits            ************************************************************************/BOOL WaitForBit(hal_Handle_t *HalHndl,ATA_Register_t regNo,U8 bitNo,U8 expected_val){    U32 i;    volatile U8 dummy;        for (i=0;i<ATA_TIMEOUT;i++)    {        WAIT400NS;        dummy=hal_RegInByte(HalHndl,regNo);                        if( (dummy & bitNo)== expected_val)             return FALSE;    }     return TRUE;}/************************************************************************Name: WaitForBitPktDescription: Wait for a bit to be set.Version for the packet command interface.we need a different verion because of the longer delay of the ATAPI devicesParameters: Three params:            HalHndl : Pointer to the HAL control block            regNo: Register number            bitNo: mask with the bit to test            expected_val: expected value of the register after applying a mask to            use only the relevant bits            ************************************************************************/BOOL WaitForBitPkt(hal_Handle_t *HalHndl,ATA_Register_t regNo,U8 bitNo,U8 expected_val){    U32 i;    volatile U8 dummy;        for (i=0;i<ATAPI_TIMEOUT;i++)    {        WAIT400NS;        dummy=hal_RegInByte(HalHndl,regNo);                        if( (dummy & bitNo)== expected_val)             return FALSE;    }     return TRUE;}/*end of ctrl_atapi.c --------------------------------------------------*/

⌨️ 快捷键说明

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