📄 harrierdma.c
字号:
LOCAL void harrierDmaIntr ( UINT32 devInstance /* Instance of Harrier */ ) { HARRIER_DMA_DRV_CTRL * pHarrierDmaCtrl; /* Setup pointer to DMA Driver control structure */ pHarrierDmaCtrl = &harrierDmaCtrl[devInstance]; /* Verify that the interrupt has occurred by reading FEST. */ if (!(*(UINT16 *)HARRIER_EXCEPTION_STATUS_REG & HARRIER_FEST_DMA)) return; /* * If the device instance wait is set to WAIT_FOREVER, * then give semaphore to waiting DMA start. * Else if the device instance wait is non-0, * then it contains a user interrupt routine, * so call it and pass the device instance. * Else the handler is done. */ if ((int)(pHarrierDmaCtrl->userHandler) == WAIT_FOREVER) semGive (pHarrierDmaCtrl->semIntId); else if ((int)(pHarrierDmaCtrl->userHandler) != 0) (pHarrierDmaCtrl->userHandler) (devInstance); /* Clear the interrupt by writing to FECL. */ *(UINT16 *)HARRIER_EXCEPTION_CLEAR_REG = HARRIER_FECL_DMA; return; }/******************************************************************************** harrierDmaStart - Configure and start the DMA controller.** This routine sets up the DMA controller for a specific DMA activity.* It expects the user to configure the DMA Descriptor List according to the* specifications and does not do any validation of the list. It uses the* link field of the list to identify if the transaction will be done in* Direct or Linked-List mode.** The user has three options for being notified of the completion of a DMA* transaction depending on the contents of the userHandler parameter.* The first is to have the DMA start routine wait for the done interrupt* which will return the contents of the DMA status register* (userHandler == WAIT_FOREVER). The second is to provide a routine for the* DMA interrupt handler to call upon completion which must follow the rules* for executing inside an ISR by not calling waits, prints, etc* (userHander == user routine). The third is to have DMA start return* immediately so the user task can proceed with its execution and then call* harrierDmaStatus later to get the results (userHandler == 0).** RETURNS: 0: if succeeded without wait;* DMA Status: if succeeded with wait;* -1: if error.*/int harrierDmaStart ( UINT32 devInstance, /* Instance of Harrier */ UINT32 (*userHandler)(), /* Address of user Interrupt Handler */ HARRIER_DMA_DESCRIPTOR * pDescList /* Address of DMA Descriptor List */ ) { HARRIER_DMA_DRV_CTRL * pHarrierDmaCtrl; int status = 0; /* Validate Device index */ if (devInstance >= HARRIER_MAX_DEV) return(-1); /* Setup pointer to DMA Driver control structure */ pHarrierDmaCtrl = &harrierDmaCtrl[devInstance]; /* Verify the driver has been initialized. */ if (pHarrierDmaCtrl->pHarrierBaseAdrs == 0) return(-1); /* Obtain semaphore for access to the device instance. */ semTake (pHarrierDmaCtrl->semDrvId, WAIT_FOREVER); /* Verify the DMA controller is not busy or paused. */ if (*(UINT16 *)HARRIER_DMA_STATUS_REG & (HARRIER_DSTA_BSY | HARRIER_DSTA_PAU)) { semGive (pHarrierDmaCtrl->semDrvId); return(-1); } /* Store wait information in control structure for interrupt handler. */ pHarrierDmaCtrl->userHandler = userHandler; /* * Initialize the DMA controller with the input descriptor. * If the Descriptor List Next Link Address (pDnla) entry is 0, * then the transfer will be in Direct Mode and the * descriptor list is copied into the controller registers. * Else the transfer will be in Linked-List Mode and only the * DMA Control and Link Address Registers will be loaded. */ if (pDescList->pDnla == 0) { *(UINT32 *)HARRIER_DMA_CONTROL_REG |= HARRIER_DCTL_MOD; *(UINT32 *)HARRIER_DMA_SOURCEADDR_REG = pDescList->dsad; *(UINT32 *)HARRIER_DMA_SOURCEATTR_REG = pDescList->dsat; *(UINT32 *)HARRIER_DMA_DESTINATIONADDR_REG = pDescList->ddad; *(UINT32 *)HARRIER_DMA_DESTINATIONATTR_REG = pDescList->ddat; *(UINT32 *)HARRIER_DMA_NEXTLINKADDR_REG = (UINT32) pDescList->pDnla; *(UINT32 *)HARRIER_DMA_COUNT_REG = pDescList->dcnt; } else { *(UINT32 *)HARRIER_DMA_CONTROL_REG &= ~HARRIER_DCTL_MOD; *(HARRIER_DMA_DESCRIPTOR **)HARRIER_DMA_NEXTLINKADDR_REG = pDescList; } /* Start the DMA operation by setting DMA Go. */ *(UINT32 *)HARRIER_DMA_CONTROL_REG |= HARRIER_DCTL_DGO; /* * If the device instance wait is set to -1, * then wait on semaphore from harrierDMAIntr * and return results from the DMA Status Register. */ if ((int)userHandler == WAIT_FOREVER) { semTake (pHarrierDmaCtrl->semIntId, WAIT_FOREVER); status = *(UINT32 *)HARRIER_DMA_STATUS_REG; } /* Release the device instance semaphore. */ semGive (pHarrierDmaCtrl->semDrvId); return (status); } /******************************************************************************** harrierDmaStatus - Read and return the DMA status registers.** Read the contents of the:* DMA Status Register;* DMA Current Source Address Register;* DMA Current Destination Address Register;* DMA Current Link Address Register.** The contents of these registers will be placed, in order, at where the* status parameter points to.** RETURNS: OK or ERROR if the device instance is invalid.*/STATUS harrierDmaStatus ( UINT32 devInstance, /* Instance of Harrier */ UINT32 * pStatus /* Address status block */ ) { /* Validate Device index */ if (devInstance >= HARRIER_MAX_DEV) return(ERROR); /* Read DMA Status Register and store. */ *pStatus++ = *(UINT32 *)HARRIER_DMA_STATUS_REG; /* Read DMA Current Source Address Register and store. */ *pStatus++ = *(UINT32 *)HARRIER_DMA_CURRENTSOURCEADDRREG; /* Read DMA Current Destination Address Register and store. */ *pStatus++ = *(UINT32 *)HARRIER_DMA_CURRENTDESTINATIONADDR_REG; /* Read DMA Current Link Address Register and store. */ *pStatus = *(UINT32 *)HARRIER_DMA_CURRENTLINKADDR_REG; return (OK); }/******************************************************************************** harrierDmaAbort - Initiate an abort of the current DMA operation.** If the DMA Controller is not busy, then ERROR is returned.* Otherwise, an abort command is issued and OK is returned.** The user will need to check the DMA Status Register to verify* the DMA Controller is aborted.** RETURNS: OK if abort succeeded or ERROR if an error occured.*/STATUS harrierDmaAbort ( UINT32 devInstance /* Instance of Harrier */ ) { HARRIER_DMA_DRV_CTRL * pHarrierDmaCtrl; /* Validate Device index */ if (devInstance >= HARRIER_MAX_DEV) return(ERROR); /* Setup pointer to DMA Driver control structure */ pHarrierDmaCtrl = &harrierDmaCtrl[devInstance]; /* Obtain semaphore for access to the device instance. */ semTake (pHarrierDmaCtrl->semDrvId, WAIT_FOREVER); /* Verify the DMA controller is busy, else return ERROR. */ if (!(*(UINT16 *)HARRIER_DMA_STATUS_REG & HARRIER_DSTA_BSY)) { return(ERROR); } /* Set the Abort bit in the DMA control register. */ *(UINT32 *)HARRIER_DMA_CONTROL_REG |= HARRIER_DCTL_ABT; /* Release the device instance semaphore. */ semGive (pHarrierDmaCtrl->semDrvId); return(OK); }/******************************************************************************** harrierDmaPause - Initiate a pause of the current DMA operation.** If the DMA Controller is not busy, then ERROR is returned.* Otherwise, a pause command is issued and OK is returned.** The user will need to check the DMA Status Register to verify* the DMA Controller is paused.** RETURNS: OK if pause succeeded or ERROR if an error occured.*/STATUS harrierDmaPause ( UINT32 devInstance /* Instance of Harrier */ ) { HARRIER_DMA_DRV_CTRL * pHarrierDmaCtrl; /* Validate Device index */ if (devInstance >= HARRIER_MAX_DEV) return(ERROR); /* Setup pointer to DMA Driver control structure */ pHarrierDmaCtrl = &harrierDmaCtrl[devInstance]; /* Obtain semaphore for access to the device instance. */ semTake (pHarrierDmaCtrl->semDrvId, WAIT_FOREVER); /* Verify the DMA controller is busy, else return ERROR. */ if (!(*(UINT16 *)HARRIER_DMA_STATUS_REG & HARRIER_DSTA_BSY)) { return(ERROR); } /* Set the Pause bit in the DMA control register. */ *(UINT32 *)HARRIER_DMA_CONTROL_REG |= HARRIER_DCTL_PAU; /* Release the device instance semaphore. */ semGive (pHarrierDmaCtrl->semDrvId); return(OK); }/******************************************************************************** harrierDmaResume - Resume a previously paused DMA operation.** If the DMA Controller is not paused, then ERROR is returned.* Otherwise, a Go command is issued and OK is returned.** The user will need to check the DMA Status Register to verify* the DMA Controller is no longer paused.** RETURNS: OK if resume succeeded or ERROR if an error occured.*/STATUS harrierDmaResume ( UINT32 devInstance /* Instance of Harrier */ ) { /* Validate Device index */ if (devInstance >= HARRIER_MAX_DEV) return(ERROR); /* Verify the DMA controller is paused, else return ERROR. */ if (!(*(UINT16 *)HARRIER_DMA_STATUS_REG & HARRIER_DSTA_PAU)) { return(ERROR); } /* Set the DMA Go bit in the DMA control register. */ *(UINT32 *)HARRIER_DMA_CONTROL_REG |= HARRIER_DCTL_DGO; return(OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -