📄 edma3resmgr.c
字号:
/**
* \brief Resources bound to a Channel
*
* When a request for a channel is made, the resources PaRAM Set and TCC
* get bound to that channel. This information is needed internally by the
* resource manager, when a request is made to free the channel,
* to free up the channel-associated resources.
*/
static EDMA3_RM_ChBoundResources edma3RmChBoundRes [EDMA3_MAX_EDMA3_INSTANCES][EDMA3_MAX_LOGICAL_CH];
/*---------------------------------------------------------------------------*/
/* Local functions prototypes */
/*---------------------------------------------------------------------------*/
/** EDMA3 Instance 0 Completion Handler Interrupt Service Routine */
void lisrEdma3ComplHandler0(unsigned int arg);
/** EDMA3 Instance 0 CC Error Interrupt Service Routine */
void lisrEdma3CCErrHandler0(unsigned int arg);
/**
* EDMA3 Instance 0 TC[0-7] Error Interrupt Service Routines
* for a maximum of 8 TCs (Transfer Controllers).
*/
void lisrEdma3TC0ErrHandler0(unsigned int arg);
void lisrEdma3TC1ErrHandler0(unsigned int arg);
void lisrEdma3TC2ErrHandler0(unsigned int arg);
void lisrEdma3TC3ErrHandler0(unsigned int arg);
void lisrEdma3TC4ErrHandler0(unsigned int arg);
void lisrEdma3TC5ErrHandler0(unsigned int arg);
void lisrEdma3TC6ErrHandler0(unsigned int arg);
void lisrEdma3TC7ErrHandler0(unsigned int arg);
/** Interrupt Handler for the Transfer Completion interrupt */
static void edma3ComplHandler (const EDMA3_RM_Obj *rmObj);
/** Interrupt Handler for the Channel Controller Error interrupt */
static void edma3CCErrHandler (const EDMA3_RM_Obj *rmObj);
/** Interrupt Handler for the Transfer Controller Error interrupt */
static void edma3TCErrHandler (const EDMA3_RM_Obj *rmObj, unsigned int tcNum);
/** Local MemSet function */
void edma3MemSet(void *dst, unsigned char data, unsigned int len);
/** Local MemCpy function */
void edma3MemCpy(void *dst, const void *src, unsigned int len);
/** Initialization of the Global region registers of the EDMA3 Controller */
static void edma3GlobalRegionInit (unsigned int phyCtrllerInstId);
/** Initialization of the Shadow region registers of the EDMA3 Controller */
static void edma3ShadowRegionInit (const EDMA3_RM_Instance *pRMInstance);
/* Internal functions for contiguous resource allocation */
/**
* Finds a particular bit ('0' or '1') in the particular word from 'start'.
* If found, returns the position, else return -1.
*/
static int findBitInWord (int source, unsigned int start, unsigned short bit);
/**
* Finds a particular bit ('0' or '1') in the specified resources' array
* from 'start' to 'end'. If found, returns the position, else return -1.
*/
static int findBit (EDMA3_RM_ResType resType,
unsigned int start,
unsigned int end,
unsigned short bit);
/**
* If successful, this function returns EDMA3_RM_SOK and the position
* of first available resource in 'positionRes'. Else returns error.
*/
static EDMA3_RM_Result allocAnyContigRes(EDMA3_RM_ResType resType,
unsigned int numResources,
unsigned int *positionRes);
/**
* Starting from 'firstResIdObj', this function makes the next 'numResources'
* Resources non-available for future. Also, it does some global resisters'
* setting also.
*/
static EDMA3_RM_Result gblChngAllocContigRes(EDMA3_RM_Instance *rmInstance,
const EDMA3_RM_ResDesc *firstResIdObj,
unsigned int numResources);
/*---------------------------------------------------------------------------*/
/**\fn EDMA3_RM_Result EDMA3_RM_create (unsigned int phyCtrllerInstId,
* const EDMA3_RM_GblConfigParams *gblCfgParams,
* const void *miscParam)
* \brief Create EDMA3 Resource Manager Object
*
* This API is used to create the EDMA3 Resource Manager Object. It should be
* called only ONCE for each EDMA3 hardware instance.
*
* Init-time Configuration structure for EDMA3 hardware is provided to pass the
* SoC specific information. This configuration information could be provided
* by the user at 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.
*
* This API clears the error specific registers (EMCR/EMCRh, QEMCR, CCERRCLR)
* and sets the TCs priorities and Event Queues' watermark levels, if the 'miscParam'
* argument is NULL. User can avoid these registers' programming (in some specific
* use cases) by SETTING the 'isSlave' field of 'EDMA3_RM_MiscParam' configuration
* structure and passing this structure as the third argument (miscParam).
*
* After successful completion of this API, Resource Manager Object's state
* changes to EDMA3_RM_CREATED from EDMA3_RM_DELETED.
*
* \param phyCtrllerInstId [IN] EDMA3 Controller Instance Id
* (Hardware instance id, starting from 0).
* \param gblCfgParams [IN] SoC specific configuration structure for the
* EDMA3 Hardware.
* \param miscParam [IN] Misc configuration options provided in the
* structure 'EDMA3_RM_MiscParam'.
* For default options, user can pass NULL
* in this argument.
*
* \return EDMA3_RM_SOK or EDMA3_RM Error Code
*/
EDMA3_RM_Result EDMA3_RM_create (unsigned int phyCtrllerInstId,
const EDMA3_RM_GblConfigParams *gblCfgParams,
const void *miscParam)
{
unsigned int count = 0u;
EDMA3_RM_Result result = EDMA3_RM_SOK;
/**
* Used to reset the Internal EDMA3 Resource Manager Data Structures for the first time.
*/
static unsigned short rmInitDone = FALSE;
const EDMA3_RM_MiscParam *miscOpt = (const EDMA3_RM_MiscParam *)miscParam;
/**
* We are NOT checking 'gblCfgParams' for NULL.
* If user has passed NULL, default config info will be
* taken from config file.
* 'param' is also not being checked because it could be
* NULL also.
*/
if (phyCtrllerInstId >= EDMA3_MAX_EDMA3_INSTANCES)
{
result = EDMA3_RM_E_INVALID_PARAM;
}
else
{
/* Initialize the global variables for the first time */
if (FALSE == rmInitDone)
{
edma3MemSet((void *)&(resMgrObj[count]) , 0x00u,
sizeof(resMgrObj));
rmInitDone = TRUE;
}
/* Initialization has been done */
if (resMgrObj[phyCtrllerInstId].state != EDMA3_RM_DELETED)
{
result = EDMA3_RM_E_OBJ_NOT_DELETED;
}
else
{
/**
* Check whether user has passed the Global Config Info.
* If yes, copy it to the driver data structures. Else, use the
* info from the config file edma3Cfg.c
*/
if (NULL == gblCfgParams)
{
/* Take info from the specific config file */
edma3MemCpy((void *)(&resMgrObj[phyCtrllerInstId].gblCfgParams),
(const void *)(&edma3GblCfgParams[phyCtrllerInstId]),
sizeof (EDMA3_RM_GblConfigParams));
}
else
{
/* User passed the info, save it in the RM object first */
edma3MemCpy((void *)(&resMgrObj[phyCtrllerInstId].gblCfgParams),
(const void *)(gblCfgParams),
sizeof (EDMA3_RM_GblConfigParams));
}
/**
* Check whether DMA channel to PaRAM Set mapping exists or not.
* If it does not exist, set the mapping array as 1-to-1 mapped.
*/
if (FALSE == resMgrObj[phyCtrllerInstId].gblCfgParams.dmaChPaRAMMapExists)
{
for (count = 0u; count < resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels; count++)
{
resMgrObj[phyCtrllerInstId].gblCfgParams.dmaChannelPaRAMMap[count] = count;
}
}
/**
* Update the actual number of PaRAM sets.
*/
edma3NumPaRAMSets = resMgrObj[phyCtrllerInstId].gblCfgParams.numPaRAMSets;
resMgrObj[phyCtrllerInstId].phyCtrllerInstId = phyCtrllerInstId;
resMgrObj[phyCtrllerInstId].state = EDMA3_RM_CREATED;
resMgrObj[phyCtrllerInstId].numOpens = 0u;
/* Make all the RM instances for this EDMA3 HW NULL */
for (count = 0u; count < EDMA3_MAX_RM_INSTANCES; count++)
{
edma3MemSet((void *)((EDMA3_RM_Instance *)(ptrRMIArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + count),
0x00u,
sizeof(EDMA3_RM_Instance));
/* Also make this data structure NULL */
edma3MemSet((void *)((EDMA3_RM_InstanceInitConfig *)(ptrInitCfgArray) + (phyCtrllerInstId*EDMA3_MAX_RM_INSTANCES) + count),
0x00u,
sizeof(EDMA3_RM_InstanceInitConfig));
}
/* Initialize the global edma3DmaChTccMapping array with EDMA3_MAX_TCC */
for ( count = 0u;
count < resMgrObj[phyCtrllerInstId].gblCfgParams.numDmaChannels;
count++
)
{
edma3DmaChTccMapping[count] = EDMA3_MAX_TCC;
}
/* Initialize the global edma3QdmaChTccMapping array with EDMA3_MAX_TCC */
for ( count = 0u;
count < resMgrObj[phyCtrllerInstId].gblCfgParams.numQdmaChannels;
count++
)
{
edma3QdmaChTccMapping[count] = EDMA3_MAX_TCC;
}
/* Make the global edma3IntrParams array for interrupts NULL */
edma3MemSet((void *)(&(edma3IntrParams[0u])), 0x00u,
sizeof(edma3IntrParams));
/* Reset edma3RmChBoundRes Array*/
for (count = 0u; count < EDMA3_MAX_LOGICAL_CH; count++)
{
edma3RmChBoundRes[phyCtrllerInstId][count].paRAMId = -1;
edma3RmChBoundRes[phyCtrllerInstId][count].tcc = EDMA3_MAX_TCC;
}
/* Make the contiguousParamRes array NULL */
edma3MemSet((void *)(&(contiguousParamRes[0u])), 0x00u,
sizeof(contiguousParamRes));
/**
* Check the misc configuration options structure.
* Check whether the global registers' initialization
* is required or not.
* It is required ONLY if RM is running on the Master Processor.
*/
if (NULL != miscOpt)
{
if (miscOpt->isSlave == FALSE)
{
/* It is a master. */
edma3GlobalRegionInit(phyCtrllerInstId);
}
}
else
{
/* By default, global registers will be initialized. */
edma3GlobalRegionInit(phyCtrllerInstId);
}
}
}
return result;
}
/**\fn EDMA3_RM_Result EDMA3_RM_delete (unsigned int phyCtrllerInstId,
* const void *param)
* \brief Delete EDMA3 Resource Manager Object
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -