📄 edma3resmgr.c
字号:
*
* This API is used to delete the EDMA3 RM Object. It should be called
* once for each EDMA3 hardware instance, ONLY after closing all the
* previously opened EDMA3 RM Instances.
*
* After successful completion of this API, Resource Manager Object's state
* changes to EDMA3_RM_DELETED.
*
* \param phyCtrllerInstId [IN] EDMA3 Phy Controller Instance Id (Hardware
* instance id, starting from 0).
* \param param [IN] For possible future use.
*
* \return EDMA3_RM_SOK or EDMA3_RM Error Code
*/
EDMA3_RM_Result EDMA3_RM_delete (unsigned int phyCtrllerInstId,
const void *param)
{
EDMA3_RM_Result result = EDMA3_RM_SOK;
if (phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES)
{
result = EDMA3_RM_E_INVALID_PARAM;
}
else
{
/*to remove CCS remark: parameter "param" was never referenced */
(void)param;
/**
* If number of RM Instances is 0, then state should be
* EDMA3_RM_CLOSED OR EDMA3_RM_CREATED.
*/
if ((NULL == resMgrObj[phyCtrllerInstId].numOpens)
&& ((resMgrObj[phyCtrllerInstId].state != EDMA3_RM_CLOSED)
&& (resMgrObj[phyCtrllerInstId].state != EDMA3_RM_CREATED)))
{
result = EDMA3_RM_E_OBJ_NOT_CLOSED;
}
else
{
/**
* If number of RM Instances is NOT 0, then this function
* SHOULD NOT be called by anybody.
*/
if (NULL != resMgrObj[phyCtrllerInstId].numOpens)
{
result = EDMA3_RM_E_INVALID_STATE;
}
else
{
/** Change state to EDMA3_RM_DELETED */
resMgrObj[phyCtrllerInstId].state = EDMA3_RM_DELETED;
/* Reset the Allocated TCCs Array also. */
allocatedTCCs[0u] = 0x0u;
allocatedTCCs[1u] = 0x0u;
/* Also, reset the RM Object Global Config Info */
edma3MemSet((void *)&(resMgrObj[phyCtrllerInstId].gblCfgParams),
0x00u,
sizeof(EDMA3_RM_GblConfigParams));
}
}
}
return result;
}
/**\fn EDMA3_RM_Handle EDMA3_RM_open (unsigned int phyCtrllerInstId,
* const EDMA3_RM_Param *initParam,
* EDMA3_RM_Result *errorCode)
* \brief Open EDMA3 Resource Manager Instance
*
* This API is used to open an EDMA3 Resource Manager Instance. It could be
* called multiple times, for each possible EDMA3 shadow region. Maximum
* EDMA3_MAX_RM_INSTANCES instances are allowed for each EDMA3 hardware
* instance.
*
* Also, only ONE Master Resource Manager Instance is permitted. This master
* instance (and hence the region to which it belongs) will only receive the
* EDMA3 interrupts, if enabled.
*
* User could pass the instance specific configuration structure
* (initParam->rmInstInitConfig) as a part of the 'initParam' structure,
* during init-time. In case user doesn't provide it, this information could
* be taken from the SoC specific configuration file edma3_<SOC_NAME>_cfg.c,
* in case it is available.
*
* \param phyCtrllerInstId [IN] EDMA3 Controller Instance Id (Hardware
* instance id, starting from 0).
* \param initParam [IN] Used to Initialize the Resource Manager
* Instance (Master or Slave).
* \param errorCode [OUT] Error code while opening RM instance.
*
* \return Handle to the opened Resource Manager instance Or NULL in case of
* error.
*
* \note This function disables the global interrupts (by calling API
* edma3OsProtectEntry with protection level
* EDMA3_OS_PROTECT_INTERRUPT) while modifying the global RM data
* structures, to make it re-entrant.
*/
EDMA3_RM_Handle EDMA3_RM_open (unsigned int phyCtrllerInstId,
const EDMA3_RM_Param *initParam,
EDMA3_RM_Result *errorCode)
{
unsigned int intState = 0u;
unsigned int resMgrIdx = 0u;
EDMA3_RM_Result result = EDMA3_RM_SOK;
EDMA3_RM_Obj *rmObj = NULL;
EDMA3_RM_Instance *rmInstance = NULL;
EDMA3_RM_Instance *temp_ptr_rm_inst = NULL;
EDMA3_RM_Handle retVal = NULL;
unsigned int dmaChDwrds = 0u;
unsigned int paramSetDwrds = 0u;
unsigned int tccDwrds = 0u;
volatile EDMA3_CCRL_Regs *globalRegs = NULL;
unsigned int mappedPaRAMId;
if (((initParam == NULL) || (phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES))
|| (errorCode == NULL))
{
result = EDMA3_RM_E_INVALID_PARAM;
}
else
{
/* Check whether the semaphore handle is null or not */
if (NULL == initParam->rmSemHandle)
{
result = EDMA3_RM_E_INVALID_PARAM;
}
else
{
rmObj = &resMgrObj[phyCtrllerInstId];
if (
(NULL == rmObj)
|| (initParam->regionId >=
resMgrObj[phyCtrllerInstId].gblCfgParams.numRegions)
)
{
result = EDMA3_RM_E_INVALID_PARAM;
}
else
{
edma3OsProtectEntry (EDMA3_OS_PROTECT_INTERRUPT, &intState);
/** Check state of RM Object.
* If no RM instance is opened and this is the first one,
* then state should be created/closed.
*/
if ((rmObj->numOpens == NULL) &&
((rmObj->state != EDMA3_RM_CREATED) &&
(rmObj->state != EDMA3_RM_CLOSED)))
{
result = EDMA3_RM_E_INVALID_STATE;
edma3OsProtectExit (EDMA3_OS_PROTECT_INTERRUPT, intState);
}
else
{
/**
* If num of instances opened is more than 0 and less than
* max allowed, then state should be opened.
*/
if (((rmObj->numOpens > 0) &&
(rmObj->numOpens < EDMA3_MAX_RM_INSTANCES))
&& (rmObj->state != EDMA3_RM_OPENED))
{
result = EDMA3_RM_E_INVALID_STATE;
edma3OsProtectExit(EDMA3_OS_PROTECT_INTERRUPT,intState);
}
else
{
/* Check if max opens have passed */
if (rmObj->numOpens >= EDMA3_MAX_RM_INSTANCES)
{
result = EDMA3_RM_E_MAX_RM_INST_OPENED;
edma3OsProtectExit (EDMA3_OS_PROTECT_INTERRUPT,
intState);
}
}
}
}
}
}
if (EDMA3_RM_SOK == result)
{
/*
* Check whether the RM instance is Master or not.
* If it is master, check whether a master already exists
* or not. There should NOT be more than 1 master.
* Return error code if master already exists
*/
if ((TRUE == masterExists) && (TRUE == initParam->isMaster))
{
/* No two masters should exist, return error */
result = EDMA3_RM_E_RM_MASTER_ALREADY_EXISTS;
edma3OsProtectExit (EDMA3_OS_PROTECT_INTERRUPT, intState);
}
else
{
/* Create Res Mgr Instance */
for (resMgrIdx = 0u; resMgrIdx < EDMA3_MAX_RM_INSTANCES; resMgrIdx++)
{
temp_ptr_rm_inst = ((EDMA3_RM_Instance *)(ptrRMIArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx);
if (NULL != temp_ptr_rm_inst)
{
if (NULL == temp_ptr_rm_inst->pResMgrObjHandle)
{
/* Handle to the EDMA3 HW Object */
temp_ptr_rm_inst->pResMgrObjHandle = rmObj;
/* Handle of the Res Mgr Instance */
rmInstance = temp_ptr_rm_inst;
/* Also make this data structure NULL, just for safety. */
edma3MemSet((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx),
0x00u,
sizeof(EDMA3_RM_InstanceInitConfig));
break;
}
}
}
/* Check whether a RM instance has been created or not */
if (NULL == rmInstance)
{
result = EDMA3_RM_E_MAX_RM_INST_OPENED;
edma3OsProtectExit (EDMA3_OS_PROTECT_INTERRUPT, intState);
}
else
{
/* Copy the InitPaRAM first */
edma3MemCpy((void *)(&rmInstance->initParam),
(const void *)(initParam),
sizeof (EDMA3_RM_Param));
if (rmObj->gblCfgParams.globalRegs != NULL)
{
globalRegs = (volatile EDMA3_CCRL_Regs *)
(rmObj->gblCfgParams.globalRegs);
rmInstance->shadowRegs = (EDMA3_CCRL_ShadowRegs *)
&(globalRegs->SHADOW[rmInstance->initParam.regionId]);
/* copy the instance specific semaphore handle */
rmInstance->initParam.rmSemHandle = initParam->rmSemHandle;
/**
* Check whether user has passed information about resources
* owned and reserved by this instance. This is region specific
* information. If he has not passed, dafault static config info will be taken
* from the config file edma3Cfg.c, according to the regionId specified.
*
* resMgrIdx specifies the RM instance number created just now.
* Use it to populate the userInitConfig [].
*/
if (NULL == initParam->rmInstInitConfig)
{
/* Take the info from the specific config file */
edma3MemCpy((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx),
(const void *)(&defInstInitConfig[phyCtrllerInstId][initParam->regionId]),
sizeof (EDMA3_RM_InstanceInitConfig));
}
else
{
/* User has passed the region specific info. */
edma3MemCpy((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx),
(const void *)(initParam->rmInstInitConfig),
sizeof (EDMA3_RM_InstanceInitConfig));
}
rmInstance->initParam.rmInstInitConfig =
((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + resMgrIdx);
dmaChDwrds = rmObj->gblCfgParams.numDmaChannels / 32u;
paramSetDwrds = rmObj->gblCfgParams.numPaRAMSets / 32u;
tccDwrds = rmObj->gblCfgParams.numTccs / 32u;
for (resMgrIdx = 0u; resMgrIdx < dmaChDwrds; ++resMgrIdx)
{
rmInstance->avlblDmaChannels[resMgrIdx]
= rmInstance->initParam.rmInstInitConfig->ownDmaChannels[resMgrIdx];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -