PeripheralDriver_Flagchip_F.../Src/fc7xxx_driver_pcc.c

422 lines
20 KiB
C

/**
* @file fc7xxx_driver_pcc.c
* @author Flagchip
* @brief FC7xxx PCC driver type definition and API
* @version 0.1.0
* @date 2024-01-12
*
* @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd.
*
*/
/********************************************************************************
* Revision History:
*
* Version Date Initials CR# Descriptions
* --------- ---------- ------------ ---------- ---------------
* 0.1.0 2024-01-12 Flagchip085 N/A First version for FC7240
********************************************************************************/
#include "fc7xxx_driver_pcc.h"
#include "fc7xxx_driver_scg.h"
#include "fc7xxx_board_conf.h"
/***************** mcaro *********************/
/* PCC property MACRO, defines every peripheral clock system architecture */
#define PCC_CLK_NOT_APPLY (0U)
#define PCC_CGC_AVAILABLE (1U << 0U)
#define PCC_FUNCCLK_MUXDIVH_USED (1U << 1U)
#define PCC_FUNCCLK_MUXDIVM_USED (1U << 2U)
#define PCC_FUNCCLK_MUXDIVL_USED (1U << 3U)
#define PCC_FUNCCLK_MUXDIVHPIN_USED (1U << 4U)
#define PCC_MOUDULE_DIV_USED (1U << 5U)
#define PCC_CLK_DOMAIN_CORE (1U << 6U)
#define PCC_CLK_DOMAIN_BUS (1U << 7U)
#define PCC_CLK_DOMAIN_SLOW (1U << 8U)
#define PCC_DWP_SWR_AVAILABLE (0U << 9U)
#define PCC_PROPERTY_MUXDIV_MASK (PCC_FUNCCLK_MUXDIVH_USED | PCC_FUNCCLK_MUXDIVM_USED | PCC_FUNCCLK_MUXDIVL_USED)
#define PCC_PROPERTY_MUXDIV_ALL_MASK (PCC_FUNCCLK_MUXDIVH_USED | PCC_FUNCCLK_MUXDIVM_USED | PCC_FUNCCLK_MUXDIVL_USED | PCC_FUNCCLK_MUXDIVHPIN_USED)
/***************** Type define *********************/
/**
* @brief PCC clock attribution.
* @param u32RegOffset: the register offset base on PCC module base address 0x4002_4000h
* @param u8ClockProperty include clock domain and clock MUX information by bit filed setting.
*/
typedef struct
{
uint32_t u32RegOffset;
uint32_t u32ClockProperty;
} PCC_ClockMapType;
/**
* @brief PCC peripheral clock index map to SCG clock source
* @param ePccClkIndex: PCC peripheral clock index
* @param eScgClkIndex SCG clock source
*/
typedef struct
{
PCC_ClkGateSrcType ePccClkIndex;
SCG_ClkSrcType eScgClkIndex;
} PCC_ClockIndexMap;
/***************** Local Variables *********************/
/**
* @brief PCC clock index to SCG clock source map.
*/
static const PCC_ClockIndexMap s_tPccClocIndexkMap[PCC_MUX_MAX_NUMBER] = {
{PCC_CLKGATE_SRC_OFF_OR_TCLK, SCG_END_OF_CLOCKS},
{PCC_CLKGATE_SRC_FOSCDIV, SCG_FOSCDIVH_CLK},
{PCC_CLKGATE_SRC_SIRCDIV, SCG_SIRCDIVH_CLK},
{PCC_CLKGATE_SRC_FIRCDIV, SCG_FIRCDIVH_CLK},
{PCC_CLKGATE_SRC_RESERVE0, SCG_END_OF_CLOCKS},
{PCC_CLKGATE_SRC_PLL1DIV, SCG_PLL1DIVH_CLK},
{PCC_CLKGATE_SRC_PLL0DIV, SCG_PLL0DIVH_CLK},
{PCC_CLKGATE_SRC_RESERVE1, SCG_END_OF_CLOCKS}
};
/**
* @brief clock attribution map.
*/
static const PCC_ClockMapType s_tPccClockMap[PCC_END_OF_CLOCKS] =
{
{0x20, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* DMA0 */
{0x28, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* DMAMUX0 */
{0x4C, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* ROMC */
{0x60, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* ERM0 */
{0x64, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* EIM0 */
{0x68, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* INTM0 */
{0x6C, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* ISM0 */
{0x88, PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* WDOG0 */
{0x98, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* TRGSEL0 */
{0x9C, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* TRGSEL1 */
{0xA0, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* TRGSEL2 */
{0xA4, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* TRGSEL3 */
{0xA8, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* CRC0 */
{0xAC, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* CORDIC */
{0xB0, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* TSTMP0 */
{0xB4, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* TSTMP1 */
{0xB8, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_DWP_SWR_AVAILABLE}, /* FCPIT0 */
{0xBC, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_FUNCCLK_MUXDIVL_USED | PCC_MOUDULE_DIV_USED | PCC_DWP_SWR_AVAILABLE}, /* AONTIMER0 */
{0xC0, PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* RTC */
{0xC4, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* CMU0 */
{0xC8, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* CMU1 */
{0xCC, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* CMU2 */
{0xD0, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* CMU3 */
{0xD4, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* CMU4 */
{0xDC, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* PTIMER0 */
{0xE0, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* PTIMER1 */
{0xEC, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_MOUDULE_DIV_USED | PCC_DWP_SWR_AVAILABLE}, /* ADC0 */
{0xF0, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_MOUDULE_DIV_USED | PCC_DWP_SWR_AVAILABLE}, /* ADC1 */
{0xFC, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* WKU0 */
{0x100, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* CMP0 */
{0x104, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* CMP1 */
{0x10C, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_FUNCCLK_MUXDIVL_USED | PCC_DWP_SWR_AVAILABLE}, /* TMU0 */
{0x150, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVL_USED | PCC_MOUDULE_DIV_USED | PCC_DWP_SWR_AVAILABLE}, /* SENT0 */
{0x160, PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* MB0 */
{0x170, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_FUNCCLK_MUXDIVHPIN_USED | PCC_DWP_SWR_AVAILABLE}, /* FTU0 */
{0x174, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_FUNCCLK_MUXDIVHPIN_USED | PCC_DWP_SWR_AVAILABLE}, /* FTU1 */
{0x178, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_FUNCCLK_MUXDIVHPIN_USED | PCC_DWP_SWR_AVAILABLE}, /* FTU2 */
{0x17C, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_FUNCCLK_MUXDIVHPIN_USED | PCC_DWP_SWR_AVAILABLE}, /* FTU3 */
{0x188, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCSPI0 */
{0x18C, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCSPI1 */
{0x190, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCSPI2 */
{0x198, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCIIC0 */
{0x1A0, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCUART0 */
{0x1A4, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCUART1 */
{0x1A8, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCUART2 */
{0x1AC, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCUART3 */
{0x1C0, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* LU0 */
{0x1E0, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_DWP_SWR_AVAILABLE}, /* FREQM */
{0x1FC, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* STCU */
{0x200, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_MOUDULE_DIV_USED | PCC_DWP_SWR_AVAILABLE}, /* FLEXCAN0 */
{0x210, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_MOUDULE_DIV_USED | PCC_DWP_SWR_AVAILABLE}, /* FLEXCAN1 */
{0x34C, PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* WDOG1 */
{0x36C, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* TRGSEL4 */
{0x370, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_SLOW | PCC_DWP_SWR_AVAILABLE}, /* TRGSEL5 */
{0x37C, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCSPI3 */
{0x380, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCSPI4 */
{0x384, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCSPI5 */
{0x3FC, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_FUNCCLK_MUXDIVHPIN_USED | PCC_DWP_SWR_AVAILABLE}, /* FTU4 */
{0x400, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_FUNCCLK_MUXDIVHPIN_USED | PCC_DWP_SWR_AVAILABLE}, /* FTU5 */
{0x404, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_FUNCCLK_MUXDIVHPIN_USED | PCC_DWP_SWR_AVAILABLE}, /* FTU6 */
{0x408, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_FUNCCLK_MUXDIVHPIN_USED | PCC_DWP_SWR_AVAILABLE}, /* FTU7 */
{0x41C, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCIIC1 */
{0x420, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCUART4 */
{0x424, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCUART5 */
{0x428, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCUART6 */
{0x42C, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_DWP_SWR_AVAILABLE}, /* FCUART7 */
{0x450, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVM_USED | PCC_MOUDULE_DIV_USED | PCC_DWP_SWR_AVAILABLE}, /* MSC0 */
{0x480, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_MOUDULE_DIV_USED | PCC_DWP_SWR_AVAILABLE}, /* FLEXCAN2 */
{0x490, PCC_CGC_AVAILABLE | PCC_CLK_DOMAIN_BUS | PCC_FUNCCLK_MUXDIVH_USED | PCC_MOUDULE_DIV_USED | PCC_DWP_SWR_AVAILABLE}, /* FLEXCAN3 */
};
/***************** Local Prototype Functions *********************/
/***************** Local Functions *********************/
/***************** Global Functions *********************/
/**
* @brief get PCC function clock status and value.
*
* @param pcc_ClkSrcType eClockName: used for choose PCC clock source to query.
*/
uint32_t PCC_GetPccFunctionClock(const PCC_ClkSrcType eClockName)
{
uint32_t u32DivVal;
PCC_ClkGateSrcType eSelVal;
uint32_t u32ScgClkIndex = 0U;
uint32_t u32FunctionFreqVal = 0U;
uint32_t u32RegVal, u32ScgClkDivIndex;
const PCC_ClockMapType *pAttributeVal;
DEV_ASSERT((uint32_t)eClockName < (uint32_t)PCC_END_OF_CLOCKS);
/* Get peripheral PCC register value */
u32RegVal = PCC_HWA_GetRegister(s_tPccClockMap[(uint32_t)eClockName].u32RegOffset);
pAttributeVal = &s_tPccClockMap[(uint32_t)eClockName];
/* Check peripheral PCC is valid or not and peripheral have function clock or not */
if ((PCC_CGC_MASK == (u32RegVal & PCC_CGC_MASK)) && (0U != (pAttributeVal->u32ClockProperty & PCC_PROPERTY_MUXDIV_ALL_MASK)))
{
eSelVal = (PCC_ClkGateSrcType)((uint8_t)PCC_GetSEL(u32RegVal));
/* Get PCC divide value */
if (PCC_MOUDULE_DIV_USED == (pAttributeVal->u32ClockProperty & PCC_MOUDULE_DIV_USED))
{
u32DivVal = PCC_GetDIV(u32RegVal) + (uint32_t)1U;
}
else
{
u32DivVal = 1U;
}
/* Get peripheral function clock source which is from SCG or TCLK */
if (PCC_CLKGATE_SRC_OFF_OR_TCLK == eSelVal)
{
if (PCC_FUNCCLK_MUXDIVHPIN_USED == (pAttributeVal->u32ClockProperty & PCC_FUNCCLK_MUXDIVHPIN_USED))
{
u32FunctionFreqVal = PCC_FTU_TCLK_FREQ;
}
else
{
u32FunctionFreqVal = 0U;
}
}
else
{
if (PCC_FUNCCLK_MUXDIVH_USED == (pAttributeVal->u32ClockProperty & PCC_FUNCCLK_MUXDIVH_USED))
{
u32ScgClkDivIndex = 0U;
}
else if (PCC_FUNCCLK_MUXDIVM_USED == (pAttributeVal->u32ClockProperty & PCC_FUNCCLK_MUXDIVM_USED))
{
u32ScgClkDivIndex = 1U;
}
else if (PCC_FUNCCLK_MUXDIVL_USED == (pAttributeVal->u32ClockProperty & PCC_FUNCCLK_MUXDIVL_USED))
{
u32ScgClkDivIndex = 2U;
}
else
{
u32ScgClkDivIndex = 0U;
}
u32ScgClkIndex = (uint32_t)s_tPccClocIndexkMap[eSelVal].eScgClkIndex + u32ScgClkDivIndex;
}
/* If clock source is valid, calculate peripheral function clock */
if (u32ScgClkIndex < (uint32_t)SCG_END_OF_CLOCKS)
{
u32FunctionFreqVal = SCG_GetScgClockFreq((SCG_ClkSrcType)u32ScgClkIndex) / u32DivVal;
}
}
return u32FunctionFreqVal;
}
/**
* @brief get PCC interface clock status and value.
*
* @param pcc_ClkSrcType eClockName: used for choose PCC clock source to query.
*/
uint32_t PCC_GetPccInterfaceClock(const PCC_ClkSrcType eClockName)
{
uint32_t u32InterfaceFreqVal, u32AttributeVal;
DEV_ASSERT((uint32_t)eClockName < (uint32_t)PCC_END_OF_CLOCKS);
u32AttributeVal = s_tPccClockMap[(uint32_t)eClockName].u32ClockProperty;
if (PCC_CLK_DOMAIN_BUS == (u32AttributeVal & PCC_CLK_DOMAIN_BUS))
{
u32InterfaceFreqVal = SCG_GetScgClockFreq(SCG_BUS_CLK);
}
else if (PCC_CLK_DOMAIN_SLOW == (u32AttributeVal & PCC_CLK_DOMAIN_SLOW))
{
u32InterfaceFreqVal = SCG_GetScgClockFreq(SCG_SLOW_CLK);
}
else
{
u32InterfaceFreqVal = 0U;
}
return u32InterfaceFreqVal;
}
/**
* @brief set PCC one peripheral clock configuration.
*
* @param PCC_CtrlType* pConfig: the PCC initialize value point set by user.
* @return PCC_StatusType pcc function status
*/
PCC_StatusType PCC_SetPcc(const PCC_CtrlType *const pConfig)
{
PCC_StatusType eStatus = PCC_STATUS_SUCCESS;
uint32_t u32DivVal;
uint32_t u32ScgClkIndex = 0U, u32ScgClkDivIndex;
uint32_t u32FreqVal = 0U;
uint32_t u32FunctionFreqVal = 0U;
uint32_t u32RegVal = 0U;
uint32_t u32ExpectedRegVal;
const PCC_ClockMapType *pAttributeVal;
DEV_ASSERT(NULL_PTR != pConfig);
DEV_ASSERT((uint32_t)pConfig->eClockName < (uint32_t)PCC_END_OF_CLOCKS);
pAttributeVal = &s_tPccClockMap[(uint32_t)pConfig->eClockName];
/* check peripheral clock domain to calculate module clock */
if (PCC_CLK_DOMAIN_BUS == (pAttributeVal->u32ClockProperty & PCC_CLK_DOMAIN_BUS))
{
u32FreqVal = SCG_GetScgClockFreq(SCG_BUS_CLK);
}
else if (PCC_CLK_DOMAIN_SLOW == (pAttributeVal->u32ClockProperty & PCC_CLK_DOMAIN_SLOW))
{
u32FreqVal = SCG_GetScgClockFreq(SCG_SLOW_CLK);
}
else
{
/* Do nothing */
}
if (0U == u32FreqVal)
{
/* Please call SCG function first */
eStatus = PCC_STATUS_CLOCK_INVALID;
}
if (PCC_STATUS_SUCCESS == eStatus)
{
/* Disable PCC gate */
PCC_HWA_SetClockGateControl(pAttributeVal->u32RegOffset,false);
if (pConfig->bEn)
{
if (PCC_MOUDULE_DIV_USED == (pAttributeVal->u32ClockProperty & PCC_MOUDULE_DIV_USED))
{
u32DivVal = (uint32_t)pConfig->eDivider + (uint32_t)1U;
u32RegVal |= PCC_DIV(pConfig->eDivider);
}
else
{
u32DivVal = 1U;
}
if (0U != (pAttributeVal->u32ClockProperty & PCC_PROPERTY_MUXDIV_ALL_MASK))
{
u32RegVal |= PCC_SEL(pConfig->eClkSrc);
}
if (PCC_CGC_AVAILABLE == (pAttributeVal->u32ClockProperty & PCC_CGC_AVAILABLE))
{
/* Enable peripheral clock */
u32RegVal |= PCC_CGC_MASK;
}
/* Configure PCC register */
PCC_HWA_SetRegister(pAttributeVal->u32RegOffset,u32RegVal);
/* Get peripheral function clock source which is from SCG or TCLK */
if (PCC_CLKGATE_SRC_OFF_OR_TCLK == pConfig->eClkSrc)
{
if (PCC_FUNCCLK_MUXDIVHPIN_USED == (pAttributeVal->u32ClockProperty & PCC_FUNCCLK_MUXDIVHPIN_USED))
{
u32FunctionFreqVal = PCC_FTU_TCLK_FREQ;
}
else
{
u32FunctionFreqVal = 0U;
}
}
else if (PCC_CLKGATE_UNINVOLVED == pConfig->eClkSrc)
{
/* do nothing */
}
else
{
if (PCC_FUNCCLK_MUXDIVH_USED == (pAttributeVal->u32ClockProperty & PCC_FUNCCLK_MUXDIVH_USED))
{
u32ScgClkDivIndex = 0U;
}
else if (PCC_FUNCCLK_MUXDIVM_USED == (pAttributeVal->u32ClockProperty & PCC_FUNCCLK_MUXDIVM_USED))
{
u32ScgClkDivIndex = 1U;
}
else if (PCC_FUNCCLK_MUXDIVL_USED == (pAttributeVal->u32ClockProperty & PCC_FUNCCLK_MUXDIVL_USED))
{
u32ScgClkDivIndex = 2U;
}
else
{
u32ScgClkDivIndex = 0U;
}
u32ScgClkIndex = (uint32_t)s_tPccClocIndexkMap[(uint32_t)pConfig->eClkSrc].eScgClkIndex + u32ScgClkDivIndex;
}
/* Calculate peripheral function clock */
if (u32ScgClkIndex < (uint32_t)SCG_END_OF_CLOCKS)
{
u32FunctionFreqVal = SCG_GetScgClockFreq((SCG_ClkSrcType)u32ScgClkIndex) / u32DivVal;
}
u32ExpectedRegVal = u32RegVal;
}
else
{
/* Clear PCC register */
PCC_HWA_SetRegister(pAttributeVal->u32RegOffset,0U);
u32ExpectedRegVal = 0U;
u32FunctionFreqVal = 0U;
}
/* Check PCC register has been configured, If current CPU do not have permission to configure the PCC register, the except value
* will not match the actual value */
if (u32ExpectedRegVal != PCC_HWA_GetRegister(pAttributeVal->u32RegOffset))
{
/* In this case, current core does not have permission to control the register */
eStatus = PCC_STATUS_CONFIGURED_NOT_SUPPORT;
}
else if (u32FunctionFreqVal > 160000000U)
{
/* In this case, current function clock too high, must configured below 150M */
eStatus = PCC_STATUS_CONFIGURED_NOT_SUPPORT;
}
else
{
/* do nothing */
}
}
return eStatus;
}
/**
* @brief Generate peripheral reset
*
*/
void PCC_GenPeripheralReset(const PCC_ClkSrcType eClockName)
{
DEV_ASSERT((uint32_t)eClockName < (uint32_t)PCC_END_OF_CLOCKS);
PCC_HWA_SoftwareReset(s_tPccClockMap[(uint32_t)eClockName].u32RegOffset);
}