📄 edma3.c
字号:
* This API is used to close a previously opened EDMA3 Driver Instance.
*
* \param hEdma [IN] Handle to the previously opened EDMA3
* Driver Instance.
* \param param [IN] For possible future use
*
* \return EDMA3_DRV_SOK or EDMA3_DRV Error code
*
* \note This function disables the global interrupts (by calling API
* edma3OsProtectEntry with protection level
* EDMA3_OS_PROTECT_INTERRUPT) while modifying the global data
* structures, to make it re-entrant.
*/
EDMA3_DRV_Result EDMA3_DRV_close(EDMA3_DRV_Handle hEdma,
const void *param)
{
unsigned int intState = 0;
EDMA3_DRV_Result result = EDMA3_DRV_SOK;
EDMA3_DRV_Instance *drvInst = NULL;
EDMA3_DRV_Object *drvObject = NULL;
/*to remove CCS remark: parameter "param" was never referenced */
(void)param;
if (hEdma == NULL)
{
result = EDMA3_DRV_E_INVALID_PARAM;
}
else
{
drvInst = (EDMA3_DRV_Instance *)hEdma;
drvObject = drvInst->pDrvObjectHandle;
if (drvObject == NULL)
{
result = EDMA3_DRV_E_INVALID_PARAM;
}
else
{
/* Check state of driver */
if (drvObject->state != EDMA3_DRV_OPENED)
{
result = EDMA3_DRV_E_OBJ_NOT_OPENED;
}
else
{
result = EDMA3_RM_close (drvInst->resMgrInstance, NULL);
if (result != EDMA3_RM_SOK)
{
result = EDMA3_DRV_E_RM_CLOSE_FAIL;
}
else
{
/* Set the driver instance specific info null */
drvInst->resMgrInstance = NULL;
drvInst->pDrvObjectHandle = NULL;
edma3MemSet((void *)&(drvInst->drvInstInitConfig), 0x00,
sizeof (EDMA3_DRV_InstanceInitConfig));
drvInst->shadowRegs = NULL;
edma3OsProtectEntry (EDMA3_OS_PROTECT_INTERRUPT, &intState);
/* Decrease the Number of Opens */
--drvObject->numOpens;
if (NULL == drvObject->numOpens)
{
drvObject->state = EDMA3_DRV_CLOSED;
}
edma3OsProtectExit (EDMA3_OS_PROTECT_INTERRUPT, intState);
}
}
}
}
return (result);
}
/**
* \brief Request a DMA/QDMA/Link channel.
*
* Each channel (DMA/QDMA/Link) must be requested before initiating a DMA
* transfer on that channel.
*
* This API is used to allocate a logical channel (DMA/QDMA/Link) along with
* the associated resources. For DMA and QDMA channels, TCC and PaRAM Set are
* also allocated along with the requested channel. For Link channel, ONLY a
* PaRAM Set is allocated.
*
* User can request a specific logical channel by passing the channel id in
* 'pLCh'. Note that the channel id is the same as the actual resource id in
* case of DMA channels. To allocate specific QDMA channels, user SHOULD use the
* defines EDMA3_DRV_QDMA_CHANNEL_X mentioned above.
*
* User can also request ANY available logical channel also by specifying the
* below mentioned values in '*pLCh':
* a) EDMA3_DRV_DMA_CHANNEL_ANY: For DMA channels
* b) EDMA3_DRV_QDMA_CHANNEL_ANY: For QDMA channels, and
* c) EDMA3_DRV_LINK_CHANNEL: For Link channels. Normally user should use this
* value to request link channels (PaRAM Sets used for linking purpose
* only), unless he wants to use some specific link channels (PaRAM Sets)
* which is also allowed.
*
* This API internally uses EDMA3_RM_allocResource () to allocate the desired
* resources (DMA/QDMA channel, PaRAM Set and TCC).
*
* This API also registers a specific callback function against the allocated
* TCC.
*
* For DMA/QDMA channels, after allocating all the EDMA3 resources, this API
* sets the TCC field of the OPT PaRAM Word with the allocated TCC. It also sets
* the event queue for the channel allocated. The event queue needs to be
* specified by the user.
*
* For DMA channel, it also sets the DCHMAP register, if required.
*
* For QDMA channel, it sets the QCHMAP register and CCNT as trigger word and
* enables the QDMA channel by writing to the QEESR register.
*
* \param hEdma [IN] Handle to the previously opened Driver
* Instance.
* \param pLCh [IN/OUT] Requested logical channel id.
* Examples:
* - EDMA3_DRV_HW_CHANNEL_EVENT_0
* - To request a DMA Master Channel
* mapped to EDMA Event 0.
*
* - EDMA3_DRV_DMA_CHANNEL_ANY
* - For requesting any DMA Master channel
* with no event mapping.
*
* - EDMA3_DRV_QDMA_CHANNEL_ANY
* - For requesting any QDMA Master channel
*
* - EDMA3_DRV_QDMA_CHANNEL_0
* - For requesting the QDMA Channel 0.
*
* - EDMA3_DRV_LINK_CHANNEL
* - For requesting a DMA Slave Channel,
* - to be linked to some other Master
* - channel.
*
* In case user passes a specific channel
* Id, pLCh value is left unchanged. In
* case user requests ANY available
* resource, the allocated channel id is
* returned in pLCh.
*
* \note To request a PaRAM Set for the purpose of
* linking to another channel, call the function with
*
* *pLCh = EDMA3_DRV_LINK_CHANNEL;
*
* This function will update *pLCh with the allocated Link channel
* handle. This handle could be DIFFERENT from the actual PaRAM Set
* allocated by the Resource Manager internally. So user SHOULD NOT
* assume the handle as the PaRAM Set Id.
*
* \param pTcc [IN/OUT] The channel number on which the
* completion/error interrupt is generated.
* Not used if user requested for a Link
* channel.
* Examples:
* - EDMA3_DRV_HW_CHANNEL_EVENT_0
* - To request TCC associated with
* - DMA Master Channel mapped to EDMA
* - event 0.
*
* - EDMA3_DRV_TCC_ANY
* - For requesting any TCC with no
* - channel mapping.
* In case user passes a specific TCC
* value, pTcc value is left unchanged.
* In case user requests ANY available TCC,
* the allocated one is returned in pTcc
*
* \param evtQueue [IN] Event Queue Number to which the channel
* will be mapped (valid only for the
* Master Channel (DMA/QDMA) request)
*
* \param tccCb [IN] TCC callback - caters to channel-
* specific events like "Event Miss Error"
* or "Transfer Complete"
*
* \param cbData [IN] Data which will be passed directly to
* the tccCb callback function
*
* \return EDMA3_DRV_SOK or EDMA3_DRV Error code
*
* \note This function internally uses EDMA3 Resource Manager, which
* acquires a RM Instance specific semaphore
* to prevent simultaneous access to the global pool of resources.
* It also disables the global interrupts while modifying
* the global CC registers.
* It is re-entrant, but SHOULD NOT be called from the user callback
* function (ISR context).
*/
EDMA3_DRV_Result EDMA3_DRV_requestChannel (EDMA3_DRV_Handle hEdma,
unsigned int *pLCh,
unsigned int *pTcc,
EDMA3_RM_EventQueue evtQueue,
EDMA3_RM_TccCallback tccCb,
void *cbData)
{
unsigned int intState=0;
EDMA3_RM_ResDesc resObj;
EDMA3_RM_ResDesc channelObj;
EDMA3_DRV_Result result = EDMA3_DRV_SOK;
unsigned int linkBcntReld = 0;
EDMA3_DRV_Instance *drvInst = NULL;
EDMA3_DRV_Object *drvObject = NULL;
EDMA3_RM_ResType savedResType;
unsigned int mappedTcc = EDMA3_DRV_CH_NO_TCC_MAP;
int paRAMId = (int)EDMA3_RM_RES_ANY;
EDMA3_DRV_ChannelType chType = EDMA3_DRV_CHANNEL_TYPE_QDMA;
volatile EDMA3_CCRL_Regs *globalRegs = NULL;
int mappedPaRAMId;
#ifdef EDMA3_INSTRUMENTATION_ENABLED
EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_START,
EDMA3_DVT_dCOUNTER,
EDMA3_DVT_dNONE,
EDMA3_DVT_dNONE));
#endif /* EDMA3_INSTRUMENTATION_ENABLED */
if ((pLCh == NULL) || (hEdma == NULL))
{
result = EDMA3_DRV_E_INVALID_PARAM;
}
else
{
drvInst = (EDMA3_DRV_Instance *)hEdma;
drvObject = drvInst->pDrvObjectHandle;
if ((drvObject == NULL) || (drvObject->gblCfgParams.globalRegs == NULL))
{
result = EDMA3_DRV_E_INVALID_PARAM;
}
else
{
globalRegs = (volatile EDMA3_CCRL_Regs *)(drvObject->gblCfgParams.globalRegs);
if (((*pLCh) != EDMA3_DRV_LINK_CHANNEL) &&
((evtQueue >= drvObject->gblCfgParams.numEvtQueue) || (pTcc == NULL)))
{
result = EDMA3_DRV_E_INVALID_PARAM;
}
else
{
if ((*pLCh) == EDMA3_DRV_LINK_CHANNEL)
{
/*
* Do nothing. Do not allocate channel.
* Typically this option is for request
* of a PaRAM Set for linking purpose.
*/
result = EDMA3_DRV_SOK;
}
else if ((*pLCh) == EDMA3_DRV_DMA_CHANNEL_ANY)
{
/* First request for any available DMA channel */
resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
resObj.resId = EDMA3_RM_RES_ANY;
result = EDMA3_RM_allocResource(drvInst->resMgrInstance, (EDMA3_RM_ResDesc *)&resObj);
if (result == EDMA3_RM_SOK)
{
*pLCh = resObj.resId;
mappedPaRAMId = drvObject->gblCfgParams.dmaChannelPaRAMMap[*pLCh];
mappedTcc = drvObject->gblCfgParams.dmaChannelTccMap[*pLCh];
if (mappedPaRAMId != EDMA3_DRV_CH_NO_PARAM_MAP)
{
/*
* There is a PaRAM Set statically mapped to the returned
* channel number.
* This imposes a constraint on the PaRAM Set which we
* next request for.
* We update the PaRAM Set number with the one statically
* reserved for the afore-returned channel number.
*/
paRAMId = mappedPaRAMId;
}
chType = EDMA3_DRV_CHANNEL_TYPE_DMA;
/* Save the Resource Type for TCC registeration */
channelObj.type = EDMA3_RM_RES_DMA_CHANNEL;
}
else
{
result = EDMA3_DRV_E_DMA_CHANNEL_UNAVAIL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -