?? hal_atapi.c
字號:
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 + -