📄 edma3.c
字号:
}
}
}
}
}
}
#ifdef EDMA3_INSTRUMENTATION_ENABLED
EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
EDMA3_DVT_dCOUNTER,
EDMA3_DVT_dNONE,
EDMA3_DVT_dNONE));
#endif /* EDMA3_INSTRUMENTATION_ENABLED */
return result;
}
/**
* \brief Free the specified channel (DMA/QDMA/Link) and its associated
* resources (PaRAM Set, TCC etc) and removes various mappings.
*
* This API internally uses EDMA3_RM_freeResource () to free the desired
* resources.
*
* For Link channels, this API only frees the associated PaRAM Set.
*
* For DMA/QDMA channels, it does the following operations:
* a) Disable any ongoing transfer on the channel,
* b) Unregister the TCC Callback function and disable the interrupts,
* c) Remove the channel to Event Queue mapping,
* d) For DMA channels, clear the DCHMAP register, if available
* e) For QDMA channels, clear the QCHMAP register,
* f) Frees the DMA/QDMA channel in the end.
*
* \param hEdma [IN] Handle to the EDMA Driver Instance.
* \param channelId [IN] Logical Channel number to be freed.
*
* \return EDMA3_DRV_SOK or EDMA3_DRV Error code
*
* \note This function disables the global interrupts while modifying
* the global CC registers and while modifying global data structures,
* to prevent simultaneous access to the global pool of resources.
* It internally calls EDMA3_RM_freeResource () for resource
* de-allocation. It is re-entrant.
*/
EDMA3_DRV_Result EDMA3_DRV_freeChannel (EDMA3_DRV_Handle hEdma,
unsigned int channelId)
{
EDMA3_RM_ResDesc resObj;
EDMA3_DRV_Result result = EDMA3_DRV_SOK;
EDMA3_DRV_Instance *drvInst = NULL;
EDMA3_DRV_Object *drvObject = NULL;
int paRAMId;
unsigned int tcc;
EDMA3_DRV_ChannelType chType = EDMA3_DRV_CHANNEL_TYPE_NONE;
#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 ((channelId > EDMA3_DRV_LOG_CH_MAX_VAL) || (hEdma == NULL))
{
result = EDMA3_DRV_E_INVALID_PARAM;
}
if (result == EDMA3_DRV_SOK)
{
drvInst = (EDMA3_DRV_Instance *)hEdma;
drvObject = drvInst->pDrvObjectHandle;
if (drvObject == NULL)
{
result = EDMA3_DRV_E_INVALID_PARAM;
}
}
if (result == EDMA3_DRV_SOK)
{
/* Check the channel type */
if (channelId <= EDMA3_DRV_DMA_CH_MAX_VAL)
{
/* DMA Channel */
chType = EDMA3_DRV_CHANNEL_TYPE_DMA;
}
if ((channelId >= EDMA3_DRV_LINK_CH_MIN_VAL) && (channelId <= EDMA3_DRV_LINK_CH_MAX_VAL))
{
/* LINK Channel */
chType = EDMA3_DRV_CHANNEL_TYPE_LINK;
}
if ((channelId >= EDMA3_DRV_QDMA_CH_MIN_VAL) && (channelId <= EDMA3_DRV_QDMA_CH_MAX_VAL))
{
/* QDMA Channel */
chType = EDMA3_DRV_CHANNEL_TYPE_QDMA;
}
if (chType == 0)
{
result = EDMA3_DRV_E_INVALID_PARAM;
}
}
if (result == EDMA3_DRV_SOK)
{
if (chType == EDMA3_DRV_CHANNEL_TYPE_LINK)
{
/* LINK Channel */
resObj.type = EDMA3_RM_RES_PARAM_SET;
/* Get the PaRAM id from the book-keeping info. */
resObj.resId = (unsigned int)(edma3DrvChBoundRes[drvObject->phyCtrllerInstId][channelId].paRAMId);
result = EDMA3_RM_freeResource(drvInst->resMgrInstance,
(EDMA3_RM_ResDesc *)&resObj);
if (result == EDMA3_DRV_SOK)
{
edma3DrvChBoundRes[drvObject->phyCtrllerInstId][channelId].paRAMId = -1;
}
}
else
{
/* DMA/QDMA Channel */
paRAMId = edma3DrvChBoundRes[drvObject->phyCtrllerInstId][channelId].paRAMId;
tcc = edma3DrvChBoundRes[drvObject->phyCtrllerInstId][channelId].tcc;
/* Check the paRAMId and tcc values first */
if ((paRAMId < 0) || (paRAMId >= drvObject->gblCfgParams.numPaRAMSets))
{
result = EDMA3_DRV_E_INVALID_PARAM;
}
if (tcc >= drvObject->gblCfgParams.numTccs)
{
result = EDMA3_DRV_E_INVALID_PARAM;
}
if (result == EDMA3_DRV_SOK)
{
/* Disable the transfer and remove various mappings. */
result = edma3RemoveMapping(hEdma, channelId);
}
if (result == EDMA3_DRV_SOK)
{
/* Now Free the PARAM set and TCC */
resObj.type = EDMA3_RM_RES_PARAM_SET;
resObj.resId = (unsigned int)paRAMId;
result = EDMA3_RM_freeResource(drvInst->resMgrInstance, (EDMA3_RM_ResDesc *)&resObj);
if (result == EDMA3_DRV_SOK)
{
/* PaRAM Set Freed */
edma3DrvChBoundRes[drvObject->phyCtrllerInstId][channelId].paRAMId = -1;
/* Free the TCC */
resObj.type = EDMA3_RM_RES_TCC;
resObj.resId = tcc;
result = EDMA3_RM_freeResource(drvInst->resMgrInstance,
(EDMA3_RM_ResDesc *)&resObj);
}
if (result == EDMA3_DRV_SOK)
{
/* TCC Freed. */
edma3DrvChBoundRes[drvObject->phyCtrllerInstId][channelId].tcc = 0;
/* Now free the DMA/QDMA Channel in the end. */
if (chType == EDMA3_DRV_CHANNEL_TYPE_QDMA)
{
resObj.type = EDMA3_RM_RES_QDMA_CHANNEL;
resObj.resId = (channelId - EDMA3_DRV_QDMA_CH_MIN_VAL);
result = EDMA3_RM_freeResource(drvInst->resMgrInstance,
(EDMA3_RM_ResDesc *)&resObj);
}
else
{
resObj.type = EDMA3_RM_RES_DMA_CHANNEL;
resObj.resId = channelId;
result = EDMA3_RM_freeResource(drvInst->resMgrInstance,
(EDMA3_RM_ResDesc *)&resObj);
}
}
}
}
}
#ifdef EDMA3_INSTRUMENTATION_ENABLED
EDMA3_LOG_EVENT(&DVTEvent_Log,"EDMA3",
EDMA3_DVT_DESC(EDMA3_DVT_eFUNC_END,
EDMA3_DVT_dCOUNTER,
EDMA3_DVT_dNONE,
EDMA3_DVT_dNONE));
#endif /* EDMA3_INSTRUMENTATION_ENABLED */
return result;
}
/**
* \brief Clears Event Register and Error Register for a specific
* DMA channel and brings back EDMA3 to its initial state.
*
* This API clears the Event register, Event Miss register Event Enable
* register for a specific DMA channel. It also clears the CC Error register.
*
* \param hEdma [IN] Handle to the EDMA Driver Instance.
* \param channelId [IN] DMA Channel needs to be cleaned.
*
* \return EDMA3_DRV_SOK or EDMA3_DRV Error code
*
* \note This function is re-entrant for unique channelId values. It is non-
* re-entrant for same channelId value.
*/
EDMA3_DRV_Result EDMA3_DRV_clearErrorBits (EDMA3_DRV_Handle hEdma,
unsigned int channelId)
{
EDMA3_DRV_Result result = EDMA3_DRV_SOK;
EDMA3_DRV_Instance *drvInst = NULL;
EDMA3_DRV_Object *drvObject = NULL;
volatile EDMA3_CCRL_Regs *globalRegs = NULL;
unsigned int count;
unsigned int value = 0;
#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 (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
{
if (channelId > EDMA3_DRV_DMA_CH_MAX_VAL)
{
result = EDMA3_DRV_E_INVALID_PARAM;
}
else
{
globalRegs = (volatile EDMA3_CCRL_Regs *)(drvObject->gblCfgParams.globalRegs);
#ifdef EDMA3_DRV_DEBUG
EDMA3_DRV_PRINTF("EMR =%l\r\n", globalRegs->EMR);
#endif
if(channelId < 32u)
{
/* Clear the Event Register */
drvInst->shadowRegs->ECR = (1u << channelId);
/* Write to EMCR to clear the corresponding EMR bit*/
globalRegs->EMCR = (1u << channelId);
/* Clear any SER*/
drvInst->shadowRegs->SECR = (1u << channelId);
/* Clear any EER */
drvInst->shadowRegs->EECR = (1u << channelId);
}
else
{
#ifdef EDMA3_DRV_DEBUG
EDMA3_DRV_PRINTF("EMRH =%l\r\n", globalRegs->EMRH);
#endif
/* Clear the Event Register */
drvInst->shadowRegs->ECRH = (1u << (channelId - 32u));
/* Write to EMCR to clear the corresponding EMR bit*/
globalRegs->EMCRH = (1u << (channelId - 32u));
/* Clear any SER*/
drvInst->shadowRegs->SECRH = (1u << (channelId - 32u));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -