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

📄 hal_atapi.c

📁 STi5518机顶盒ATAPI源代码!绝对超值!
💻 C
📖 第 1 页 / 共 3 页
字号:
    hal_RegOutByte (HalHndl_p,ATA_REG_CONTROL,nIEN_SET);}/************************************************************************Name:   hal_AwaitInt()Description:     This function waits for an interrupt generated any of the ata devicesParameters:    HalHndl     Handle of the HAL (for the base address)    Timeout     Timeout value for (internal) semaphore************************************************************************/BOOL hal_AwaitInt (hal_Handle_t *HalHndl_p, U32 Timeout){    clock_t     TO;    BOOL        Error = FALSE;        TO = time_plus (time_now(), Timeout);        if (semaphore_wait_timeout(&HalHndl_p->InterruptSemaphore, &TO))    {        STTBX_Print(("No interrupt received\n"));        Error = TRUE;    }        return (Error);}       /************************************************************************Name: ata_InterruptHandlerDescription:Parameters:    none************************************************************************/void ata_InterruptHandler (void){    volatile U32 Dummy;#if defined(ST_5514)    U32 intvalue = 0;#endif#if defined(ST_5514)    /* Back to PIO mode */    intvalue = ReadReg((U32)(The_HalHandle_p->BaseAddress) + HDDI_DMA_STA);    if (intcount < 15)        inttrace[intcount] = 0x100;    intcount++;    if (intcount < 15)        inttrace[intcount] = intvalue;    intcount++;    WriteReg((U32)(The_HalHandle_p->BaseAddress) + HDDI_MODE, HDDI_MODE_PIOREG);        /* Mask interrupts */    intvalue = ReadReg((U32)(The_HalHandle_p->BaseAddress) + HDDI_DMA_ITS);    if (intcount < 15)        inttrace[intcount] = intvalue;    intcount++;    WriteReg((U32)(The_HalHandle_p->BaseAddress) + HDDI_DMA_ITM,            HDDI_DMA_ITM_DEND | HDDI_DMA_ITM_IRQ | HDDI_DMA_ITM_DEVTERMOK);#endif        /* clear interrupt = read status register */    Dummy = hal_RegInByte (The_HalHandle_p,ATA_REG_ALTSTAT);    Dummy = hal_RegInByte (The_HalHandle_p,ATA_REG_STATUS);    Dummy = hal_RegInByte (The_HalHandle_p, ATA_REG_SECCOUNT); /* ?! */#if defined(ST_5514)    The_HalHandle_p->DmaAborted = FALSE;    if (intvalue & HDDI_DMA_ITS_DEND)     {        /* DMA ended */        if (intcount < 15)            inttrace[intcount++] = 0x20;    }    if ((intvalue & HDDI_DMA_ITS_DEVTERMOK) == 0)    {        /* Aborted? */        if (intcount < 15)            inttrace[intcount++] = 0x30;    }    if (intvalue & HDDI_DMA_ITS_IRQ)     {        if (intcount < 15)            inttrace[intcount++] = 0x10;        semaphore_signal(&The_HalHandle_p->InterruptSemaphore);    }    /* Unmask interrupts */    WriteReg((U32)(The_HalHandle_p->BaseAddress) + HDDI_DMA_ITM, 0);#else    semaphore_signal(&The_HalHandle_p->InterruptSemaphore);#endif}/****************************************************************************Name:        hal_ClearInterruptDescription:     Clears the pending Interrupts, and reset the semaphore counterParameters:    HalHndl     Handle of the HAL (for the base address)****************************************************************************/BOOL hal_ClearInterrupt (hal_Handle_t *HalHndl_p){    volatile U8  Dummy;        if (HalHndl_p != The_HalHandle_p)         return TRUE;        Dummy = hal_RegInByte (HalHndl_p, ATA_REG_ALTSTAT);    Dummy = hal_RegInByte (HalHndl_p, ATA_REG_STATUS);          return FALSE;}/************************************************************************Name: hal_RegOutBlockDescription:     This function works as interface to the  device's ATA  DATA register     allowing the user to  WRITE data in this register. No bus acquisition    procedure is done. User must manage this Parameters:     HalHndl     Handle of the HAL (for the base address)    data        data buffer to write    Size        Number of bytes to write    UseDMA      Whether a DMA engine should be used to transfer the                data to the data port (if available)*********************************************************************/ST_ErrorCode_t __inline hal_RegOutBlock (hal_Handle_t *HalHndl_p,                                          U16 *data,                                          U32 Size,                                         BOOL UseDMA){       DU16    *addr;    ST_ErrorCode_t error;#if defined(ATAPI_GPDMA)    STGPDMA_DmaTransfer_t       Dma;    STGPDMA_DmaTransferId_t     Tid;    STGPDMA_DmaTransferStatus_t Status;#endif#if defined(ST_5514)    U32 loop;#endif    /* Stops compiler complaining about 'error' for non-5514 platforms */    error = ST_NO_ERROR;        /* Work out where to send the data */    addr = (DU16 *)((U32)HalHndl_p->BaseAddress | RegsMasks[ATA_REG_DATA]);#if !defined(ST_5514)    memcpy((void *)addr, data, Size);#else    /* See if we have the option (and it's desired) to use GPDMA */#if defined(ATAPI_GPDMA)    if (UseDMA == TRUE)    {        Dma.TimingModel = STGPDMA_TIMING_FREE_RUNNING;        Dma.Source.TransferType = STGPDMA_TRANSFER_1D_INCREMENTING;        Dma.Source.Address = (U32)data;        Dma.Source.UnitSize = 32;        Dma.Destination.TransferType = STGPDMA_TRANSFER_0D;        Dma.Destination.Address = (U32)addr;        Dma.Destination.UnitSize = 2;        Dma.Count = Size;        Dma.Next = NULL;        /* Start DMA on channel */        do         {            error = STGPDMA_DmaStartChannel(HalHndl_p->GPDMAHandle,                                     STGPDMA_MODE_BLOCK, &Dma, 1,                                     0, /* Ignored for free running */                                    0, /* Timeout => forever */                                    &Tid,                                    &Status                                   );            if (error != ST_NO_ERROR)            {                Dma.Source.UnitSize >>= 1;                if (Dma.Source.UnitSize == 0)                {                    STTBX_Print(("hal_RegOutBlock: STGPDMA error: %u\n",                                 error));                }            }        } while ((error != ST_NO_ERROR) && (Dma.Source.UnitSize > 0));    }    else#endif    {        /* 16-bits at a time, size is in bytes, so halve */        loop = Size >> 1;        for (; loop > 0; loop--)        {            *addr = *data;                data++;        }    }#endif    return error;}/************************************************************************Name: hal_RegInBlockDescription:     This function works as interface to the device's ATA DATA register allowing    the user to  READ data in these registers. No bus acquisition procedure is    done. User must manage this Parameters:     HalHndl     Handle of the HAL (for the base address)    data        data buffer to fill    Size        Number of bytes to read    UseDMA      Whether a DMA engine should be used to transfer the data                from the data port, if available************************************************************************/ST_ErrorCode_t __inline hal_RegInBlock (hal_Handle_t *HalHndl_p,                                         U16 *data,                                         U32 Size,                                        BOOL UseDMA){       DU16    *addr;    ST_ErrorCode_t error;#if defined(ST_5514)    U32 loop;#endif        /* Stops compiler complaining about 'error' for non-5514 platforms */    error = ST_NO_ERROR;    addr = (DU16*)((U32)HalHndl_p->BaseAddress | (RegsMasks[ATA_REG_DATA]));#if !defined(ST_5514)    memcpy(data, (void *)addr, Size);#else    /* 16-bits read at a time, size is in bytes, so halve */    loop = Size >> 1;    for (; loop > 0; loop--)    {        *data = *addr;        data++;    }#endif    return error;}/****************************************************************************Name: ata_BlockMoveIntHandlerDescription:     routine that clears the pending Interrupts, and reset the semaphore     counter****************************************************************************/#ifdef BMDMA_ENABLEstatic void ata_BlockMoveIntHandler (void){    volatile U32 data;    U32         valid_bits = (1<<2)-1;    U32         expected_value = 0x3;#pragma ST_device (BMDMAReg)	volatile U8 *BMDMAReg;    BMDMAReg = (volatile U8*)BMDMA_Status;    data = *BMDMAReg;    if ((data & valid_bits) == expected_value)    {        BMDMAReg = (volatile U8*)BMDMA_IntAck;        *BMDMAReg = 1;		BMDMAReg = (volatile U8*)BMDMA_Status;		data = *BMDMAReg;        semaphore_signal(&The_HalHandle_p->BMDMA_IntSemaphore);    }    else    {             semaphore_signal(&The_HalHandle_p->BMDMA_IntSemaphore);    }}/***************************************************************Name: ATA_BMDMADescription:     Performs Block Move DMAParameters:     Source              Source address    Destination         Destination address    Size                Amount of data to be moved****************************************************************/void ATA_BMDMA (void *Source, void *Destination, U32 Size){#pragma ST_device (BMDMAReg)    volatile U8 *BMDMAReg;    BMDMAReg = (volatile U8*) BMDMA_DestAddress;  	*BMDMAReg = (U32) (Destination);  	BMDMAReg = (volatile U8*)BMDMA_SrcAddress;	*BMDMAReg = (U32) Source;	BMDMAReg = (volatile U8*)BMDMA_IntEn;	*BMDMAReg = 1;	BMDMAReg = (volatile U8*)BMDMA_Count;	*BMDMAReg = Size;        semaphore_wait(&The_HalHandle_p->BMDMA_IntSemaphore);}#endif  /* BMDMA_ENABLE *//************************************************************************Name:   hal_HardReset()Description:     Performs a hardware reset on all the devicesParameters:    HalHndl     Handle of the HAL (for the base address)************************************************************************/BOOL hal_HardReset (hal_Handle_t *HalHndl_p){    BOOL Error = FALSE;#if defined (ST_5512)    *(HalHndl_p->HWResetAddress) = ATA_HRD_RST_ASSERT;    task_delay (TWO_MS);    *(HalHndl_p->HWResetAddress) = ATA_HRD_RST_DEASSERT;    Error = FALSE;    #elif defined (ST_5508) | defined (ST_5518)    /* Instead a Hard Reset we perform another SW reset */    hal_RegOutByte(HalHndl_p,ATA_REG_CONTROL,0x0C);    task_delay(TWO_MS);    hal_RegOutByte(HalHndl_p,ATA_REG_CONTROL,0x08);    Error = TRUE;#elif defined(ST_5514)    WriteReg((U32)(HalHndl_p->BaseAddress) + HDDI_ATA_RESET, 1);    task_delay( TWO_MS / 4);       /* Wait 2*25us */        /* Clear the reset signal */    WriteReg((U32)(HalHndl_p->BaseAddress) + HDDI_ATA_RESET, 0);    /* Delay period? */    task_delay( TWO_MS * 2 );         /* Wait 2*2ms */        if (WaitForBit(HalHndl_p, ATA_REG_ALTSTAT, BSY_BIT_MASK,0))    {        STTBX_Print(("Timed out waiting for busy to be clear\n"));    }    Error = FALSE;#endif    return Error;}   /************************************************************************Name:       hal_SetDmaMode()Description:     Sets the HAL handle to use the passed modeParameters:    Mode        DMA mode to use for future transfers************************************************************************/BOOL hal_SetDmaMode (hal_Handle_t *HalHndl_p, STATAPI_DmaMode_t Mode){    CurrentDmaMode = Mode;#if defined(ST_5514)    if (Mode <= STATAPI_DMA_MWDMA_MODE_2)        DMAIsUDMA = FALSE;    else        DMAIsUDMA = TRUE;#endif    return FALSE;}/************************************************************************Name:       hal_SetPIOMode()Description:     Sets the HAL handle to use the passed modeParameters:    Mode        PIO mode to use for future transfers************************************************************************/BOOL hal_SetPioMode (hal_Handle_t *HalHndl_p, STATAPI_PioMode_t Mode){    CurrentPioMode = Mode;    return FALSE;}/************************************************************************Name:   hal_GetDmaTiming()Description:     retrieves the current Timing setings of the DMA ModeParameters:************************************************************************/BOOL hal_GetDmaTiming (hal_Handle_t *HalHndl_p, STATAPI_DmaTiming_t *Time){    /* Check parameters */    if ((Time == NULL) || (HalHndl_p != The_HalHandle_p))        return TRUE;    /* Copy data - won't actually be useful unless this is a 5514, but it is     * always present...      */

⌨️ 快捷键说明

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