/** * @file module_driver_cmu.c * @author Flagchip0100 * @brief CMU Module driver type definition and API * @version 2.0.0 * @date 2024-08-20 * * SDK Version: 2.6.0 * * @copyright Copyright 2020-2024 Flagchip Semiconductors Co., Ltd. */ /******************************************************************************** * Revision History: * * Version Date Initials CR# Descriptions * --------- ---------- ------------ ---------- --------------- * 0.1.0 2022-12-12 Flagchip084 N/A FC7xxx release version * 0.2.0 2023-02-13 Flagchip084 N/A FC7xxx release version * 2.0.0 2024-08-01 Flagchip0100 N/A SDK2.0 release version ********************************************************************************/ #include "module_driver_cmu.h" #include "module_driver_scg.h" #if (CMU_INSTANCE_COUNT > 0U) /******************************************************************************* * Definitions ******************************************************************************/ #ifndef CMU_DEV_ERROR_REPORT #define CMU_DEV_ERROR_REPORT STD_OFF #endif #if CMU_DEV_ERROR_REPORT == STD_ON #define CMU_ReportDevError(func, error) ReportDevError(CMU_MODULE_ID, func, error) #endif #define CMU_MULTIPLY_FACTOR 100U #define CMU_PERCENT_FACTOR 100U #define CMU_DIVID_FACTOR_1K 1000U /******************************************************************************* * Prototypes ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ static CMU_Type *const s_apCmuBase[CMU_INSTANCE_COUNT] = CMU_BASE_PTRS; /******************************************************************************* * Code ******************************************************************************/ /** * @brief Initializes a CMU configuration structure with default values * * This function configures the provided CMU configuration structure with a set of default settings, * including interrupt enable, low-power mode, clock divider, and more. If the passed configuration * structure pointer is NULL and error reporting is enabled, an error will be reported. * * @param pInitCfg Pointer to a CMU_CfgType structure that will be initialized with default configuration values * * @note The function checks for NULL pointer only if error reporting (`CMU_DEV_ERROR_REPORT`) is turned on. * By default, it sets the structure fields to: * - Interrupt Enable: true * - Low Power Enable: false * - Clock Monitor Enable: false * - Module Enable: true * - Peripheral Monitor Enable: false * - Clock Divider: CMU_REFCLK_NODIV * - Error Callback: NULL */ void CMU_GetDefaultConfig(CMU_CfgType *const pInitCfg) { #if CMU_DEV_ERROR_REPORT == STD_ON if (pInitCfg == NULL) { CMU_ReportDevError(CMU_GET_DEFAULT_CONFIG_ID, CMU_E_PARAM_NULLPTR); } else #endif { pInitCfg->bIntEnable = true; pInitCfg->bLpen = false; pInitCfg->bSten = false; pInitCfg->bEnable = true; pInitCfg->bPerMonitorEnable = false; pInitCfg->eDiv = CMU_REFCLK_NODIV; } } /** * @brief Calculates monitor window values for the CMU based on the given configuration * * This function calculates the reference and monitor clock window values for the specified CMU instance. * It verifies input parameters, checks the clock status, and performs necessary calculations. * If any input is invalid or an error occurs, appropriate error reporting may be triggered. * * @param pInitCfg Pointer to a CMU configuration structure with user-defined settings * * @preconditions * - A valid CMU handle and configuration structure must be provided * - The CMU instance number should be within the supported range * * @postconditions * - The `pInitCfg` structure will be updated with calculated window and counter values * - If the reference or monitor clock is zero, all configuration flags will be set to disabled * * @note Error reporting is enabled when `CMU_DEV_ERROR_REPORT` is set to `STD_ON`. */ void CMU_CaculateMonitorWindowsValue(CMU_CfgType *const pInitCfg) { #if CMU_DEV_ERROR_REPORT == STD_ON if (pInitCfg == NULL) { CMU_ReportDevError(CMU_CAL_MONITOR_WINDOW_ID, CMU_E_PARAM_NULLPTR); } else #endif { uint32_t u32RefWindow, u32MaxRefWindow, u32MinRefWindow; uint32_t u32MonitorCnts, u32MinMonitorCnts, u32MaxMonitorCnts; uint32_t u32RefClk, u32MonitorClk; uint32_t u32MaxPeriod; /* divide the clock value by 1K_factor */ u32RefClk = (pInitCfg->u32RefClk >> pInitCfg->eDiv) / CMU_DIVID_FACTOR_1K; u32MonitorClk = pInitCfg->u32MonitorClk / CMU_DIVID_FACTOR_1K; if ((u32RefClk != 0U) && (u32MonitorClk != 0U)) { if (u32RefClk / u32MonitorClk <= 0x100U) { u32MaxRefWindow = (0xFFFFFFU - 3U) / u32MonitorClk * u32RefClk / 105U * CMU_PERCENT_FACTOR - 2U; if (u32MaxRefWindow > 0xFFFFFFU) { u32MaxRefWindow = 0xFFFFFFU; } } else { u32MaxRefWindow = 0xFFFFFFU; } u32MinRefWindow = 6U + 5U * u32RefClk / u32MonitorClk; u32RefWindow = 100U * u32MinRefWindow; if (u32RefWindow > u32MaxRefWindow) { u32RefWindow = u32MaxRefWindow; } u32MonitorCnts = u32MonitorClk * (u32RefWindow + 2U) / u32RefClk; u32MinMonitorCnts = u32MonitorCnts * 95U / CMU_PERCENT_FACTOR - 3U; u32MaxMonitorCnts = u32MonitorCnts * 105U / CMU_PERCENT_FACTOR + 3U; /* Program program PERIOD[EN] and PERIOD[WINDOW]. */ u32MaxPeriod = u32RefClk / u32RefWindow; if (u32MaxPeriod >> CMU_PERIOD_WINDOW_WIDTH) { u32MaxPeriod = ((uint32_t)1U << CMU_PERIOD_WINDOW_WIDTH) - 1U; } pInitCfg->u32RefWindow = u32RefWindow; pInitCfg->u32PerMonitorWindow = u32MaxPeriod; pInitCfg->u32MinMonitorCnts = u32MinMonitorCnts; pInitCfg->u32MaxMonitorCnts = u32MaxMonitorCnts; } else { pInitCfg->bIntEnable = false; pInitCfg->bLpen = false; pInitCfg->bSten = false; pInitCfg->bEnable = false; pInitCfg->bPerMonitorEnable = false; pInitCfg->u32RefWindow = 0U; pInitCfg->u32PerMonitorWindow = 0U; pInitCfg->u32MinMonitorCnts = 0U; pInitCfg->u32MaxMonitorCnts = 0U; } } } /** * @brief Initializes the CMU module with the provided configuration * * This function initializes the Clock Monitor Unit (CMU) according to the specified configuration. * It performs parameter validation, initializes hardware registers, and sets up callback functions. * If any input is invalid, an error will be reported and the function will return `CMU_STATUS_FAIL`. * * @param pHandle Pointer to a CMU handle structure containing the instance information * @param pInitCfg Pointer to a constant CMU configuration structure with initialization settings * * @return Status of the initialization process * - CMU_STATUS_SUCCESS: Initialization successful * - CMU_STATUS_FAIL: Initialization failed due to an error or invalid parameter * * @preconditions * - A valid CMU handle and configuration structure must be provided * - The CMU instance number should be within the supported range * * @postconditions * - The CMU hardware registers will be configured according to the provided `pInitCfg` * - The handle's error callback will be set to the value from `pInitCfg->pErrorCallback` * * @note Error reporting is enabled when `CMU_DEV_ERROR_REPORT` is set to `STD_ON`. */ CMU_StatusType CMU_Init(CMU_HandleType *const pHandle, const CMU_CfgType *const pInitCfg) { CMU_StatusType eStatus = CMU_STATUS_SUCCESS; #if CMU_DEV_ERROR_REPORT == STD_ON if (pHandle == NULL) { CMU_ReportDevError(CMU_INIT_ID, CMU_E_PARAM_NULLPTR); eStatus = CMU_STATUS_FAIL; } else if (pInitCfg == NULL) { CMU_ReportDevError(CMU_INIT_ID, CMU_E_PARAM_NULLPTR); eStatus = CMU_STATUS_FAIL; } else if (pHandle->eInstance >= CMU_INSTANCE_COUNT) { CMU_ReportDevError(CMU_INIT_ID, CMU_E_PARAM_INSTANCE); eStatus = CMU_STATUS_FAIL; } else #endif { CMU_Type *const pCmu = s_apCmuBase[pHandle->eInstance]; uint32_t u32Temp = 0x1FFU;; CMU_HWA_SetCtrl(pCmu, 0U); CMU_HWA_SoftwareRST(pCmu); while (CMU_HWA_GetSoftwareRST(pCmu)) { u32Temp--; if (u32Temp == 0U) { eStatus = CMU_STATUS_FAIL; break; } } if (u32Temp != 0U) { CMU_HWA_SetRefWindow(pCmu, pInitCfg->u32RefWindow); CMU_HWA_SetMinCnts(pCmu, pInitCfg->u32MinMonitorCnts); CMU_HWA_SetMaxCnts(pCmu, pInitCfg->u32MaxMonitorCnts); CMU_HWA_SetPeriodWindow(pCmu, pInitCfg->u32PerMonitorWindow); CMU_HWA_SetPeriodEnable(pCmu, pInitCfg->bPerMonitorEnable); /* Program DIV,IRQ_EN,LP_EN,STOP_EN,ENABLE */ u32Temp = CMU_CTRL_REF_DIV(pInitCfg->eDiv) | CMU_CTRL_IRQ_EN(pInitCfg->bIntEnable) | #ifdef CMU_CTRL_LP_SUPPORT CMU_CTRL_LP_EN(pInitCfg->bLpen) | #endif CMU_CTRL_STOP_EN(pInitCfg->bSten) | CMU_CTRL_ENABLE(pInitCfg->bEnable); CMU_HWA_SetCtrl(pCmu, u32Temp); } } return eStatus; } /** * @brief Enables the Clock Monitor Unit (CMU) for the specified instance * * This function enables the CMU module for the given handle's instance. It performs parameter * validation and updates the control register to activate the CMU. If an error occurs or the * handle is invalid, an error report will be generated. * * @param pHandle Pointer to a CMU handle structure containing the instance information * * @preconditions * - A valid CMU handle must be provided * - The CMU instance number should be within the supported range * * @postconditions * - The CMU will be enabled if it was previously disabled * * @note Error reporting is enabled when `CMU_DEV_ERROR_REPORT` is set to `STD_ON`. */ void CMU_Enable(CMU_HandleType *const pHandle) { #if CMU_DEV_ERROR_REPORT == STD_ON if (pHandle == NULL) { CMU_ReportDevError(CMU_ENABLE_ID, CMU_E_PARAM_NULLPTR); } else if (pHandle->eInstance >= CMU_INSTANCE_COUNT) { CMU_ReportDevError(CMU_ENABLE_ID, CMU_E_PARAM_INSTANCE); } else #endif { uint32_t u32Temp; CMU_Type *const pCmu = s_apCmuBase[pHandle->eInstance]; u32Temp = CMU_HWA_GetCtrl(pCmu); u32Temp |= CMU_CTRL_ENABLE_MASK; CMU_HWA_SetCtrl(pCmu, u32Temp); } } /** * @brief Disables the Clock Monitor Unit (CMU) for the specified instance * * This function disables the CMU module for the given handle's instance. It performs parameter * validation, clears the control register flags for enabling and interrupts, and resets the * status. If an error occurs or the handle is invalid, an error report will be generated. * * @param pHandle Pointer to a CMU handle structure containing the instance information * * @preconditions * - A valid CMU handle must be provided * - The CMU instance number should be within the supported range * * @postconditions * - The CMU will be disabled if it was previously enabled * - Interrupts will be disabled and the status will be cleared * * @note Error reporting is enabled when `CMU_DEV_ERROR_REPORT` is set to `STD_ON`. */ void CMU_Disable(CMU_HandleType *const pHandle) { #if CMU_DEV_ERROR_REPORT == STD_ON if (pHandle == NULL) { CMU_ReportDevError(CMU_DISABLE_ID, CMU_E_PARAM_NULLPTR); } else if (pHandle->eInstance >= CMU_INSTANCE_COUNT) { CMU_ReportDevError(CMU_DISABLE_ID, CMU_E_PARAM_INSTANCE); } else #endif { uint32_t u32Temp; CMU_Type *const pCmu = s_apCmuBase[pHandle->eInstance]; u32Temp = CMU_HWA_GetCtrl(pCmu); u32Temp &= ~(CMU_CTRL_ENABLE_MASK | CMU_CTRL_IRQ_EN_MASK); CMU_HWA_SetCtrl(pCmu, u32Temp); CMU_HWA_ClsST(pCmu); } } /** * @brief Enables the Clock Monitor Unit (CMU) interrupt for the specified instance * * This function enables the interrupt for the CMU module associated with the given handle's instance. * It performs parameter validation and updates the control register to enable the interrupt. * If an error occurs or the handle is invalid, an error report will be generated. * * @param pHandle Pointer to a CMU handle structure containing the instance information * * @preconditions * - A valid CMU handle must be provided * - The CMU instance number should be within the supported range * * @postconditions * - The CMU interrupt will be enabled if it was previously disabled * * @note Error reporting is enabled when `CMU_DEV_ERROR_REPORT` is set to `STD_ON`. */ void CMU_EnableInterrupt(CMU_HandleType *const pHandle) { #if CMU_DEV_ERROR_REPORT == STD_ON if (pHandle == NULL) { CMU_ReportDevError(CMU_ENABLE_IRQ_ID, CMU_E_PARAM_NULLPTR); } else if (pHandle->eInstance >= CMU_INSTANCE_COUNT) { CMU_ReportDevError(CMU_ENABLE_IRQ_ID, CMU_E_PARAM_INSTANCE); } else #endif { uint32_t u32Temp; CMU_Type *const pCmu = s_apCmuBase[pHandle->eInstance]; u32Temp = CMU_HWA_GetCtrl(pCmu); u32Temp |= CMU_CTRL_IRQ_EN_MASK; CMU_HWA_SetCtrl(pCmu, u32Temp); } } /** * @brief Disables the Clock Monitor Unit (CMU) interrupt for the specified instance * * This function disables the interrupt for the CMU module associated with the given handle's instance. * It performs parameter validation and updates the control register to disable the interrupt. * If an error occurs or the handle is invalid, an error report will be generated. * * @param pHandle Pointer to a CMU handle structure containing the instance information * * @preconditions * - A valid CMU handle must be provided * - The CMU instance number should be within the supported range * * @postconditions * - The CMU interrupt will be disabled if it was previously enabled * * @note Error reporting is enabled when `CMU_DEV_ERROR_REPORT` is set to `STD_ON`. */ void CMU_DisableInterrupt(CMU_HandleType *const pHandle) { #if CMU_DEV_ERROR_REPORT == STD_ON if (pHandle == NULL) { CMU_ReportDevError(CMU_DISABLE_IRQ_ID, CMU_E_PARAM_NULLPTR); } else if (pHandle->eInstance >= CMU_INSTANCE_COUNT) { CMU_ReportDevError(CMU_DISABLE_IRQ_ID, CMU_E_PARAM_INSTANCE); } else #endif { uint32_t u32Temp; CMU_Type *const pCmu = s_apCmuBase[pHandle->eInstance]; u32Temp = CMU_HWA_GetCtrl(pCmu); u32Temp &= ~CMU_CTRL_IRQ_EN_MASK; CMU_HWA_SetCtrl(pCmu, u32Temp); } } /** * @brief Enables or disables low power mode on the CMU module. * * This function configures the CMU module to enter or exit low power mode based on the parameters provided. * It supports both standby and stop modes, and can optionally enable low power restart. * * @param pHandle Pointer to the CMU handle structure. * @param eMode The low power mode type to be set (CMU_STANDBY_MODE or CMU_STOP_MODE). * @param bModeEnable Boolean flag indicating whether to enable (true) or disable (false) the low power mode. * @param bRestartEnable Boolean flag indicating whether to enable (true) or disable (false) low power restart. * * @note If the handle pointer is NULL or the instance index is out of range, a device error will be reported. */ void CMU_LowPowerModeEnable(CMU_HandleType *const pHandle, CMU_LowpowerModeType eMode, bool bModeEnable, bool bRestartEnable) { #if CMU_DEV_ERROR_REPORT == STD_ON if (pHandle == NULL) { CMU_ReportDevError(CMU_ENABLE_LOWPOWER_MODE_ID, CMU_E_PARAM_NULLPTR); } else if (pHandle->eInstance >= CMU_INSTANCE_COUNT) { CMU_ReportDevError(CMU_ENABLE_LOWPOWER_MODE_ID, CMU_E_PARAM_INSTANCE); } else #endif { CMU_Type *const pCmu = s_apCmuBase[pHandle->eInstance]; if (eMode == CMU_STANDBY_MODE) { CMU_HWA_StopModeEnable(pCmu, bModeEnable); #ifdef CMU_CTRL_LP_SUPPORT CMU_HWA_StanbyModeEnable(pCmu, bModeEnable); #endif } else if (eMode == CMU_STOP_MODE) { CMU_HWA_StopModeEnable(pCmu, bModeEnable); } else { } CMU_HWA_LPRestartEnable(pCmu, bRestartEnable); } } /** * @brief Retrieves the current count from the CMU module. * * This function returns the current count value from the specified CMU module instance. * * @param pHandle Pointer to the CMU handle structure. * * @return uint32_t The current count value from the CMU module. * * @note If the handle pointer is NULL or the instance index is out of range, a device error will be reported. */ uint32_t CMU_GetCount(CMU_HandleType *const pHandle) { uint32_t u32Value = 0U; #if CMU_DEV_ERROR_REPORT == STD_ON if (pHandle == NULL) { CMU_ReportDevError(CMU_GET_CURRENTCOUNT_ID, CMU_E_PARAM_NULLPTR); } else if (pHandle->eInstance >= CMU_INSTANCE_COUNT) { CMU_ReportDevError(CMU_GET_CURRENTCOUNT_ID, CMU_E_PARAM_INSTANCE); } else #endif { CMU_Type *const pCmu = s_apCmuBase[pHandle->eInstance]; u32Value = CMU_HWA_GetCount(pCmu); } return u32Value; } /** * @brief Retrieves the minimum count value from the CMU module. * * This function returns the minimum count value that the specified CMU module instance can support. * * @param pHandle Pointer to the CMU handle structure. * * @return uint32_t The minimum count value supported by the CMU module. * * @note If the handle pointer is NULL or the instance index is out of range, a device error will be reported. */ uint32_t CMU_GetMinCount(CMU_HandleType *const pHandle) { uint32_t u32Value = 0U; #if CMU_DEV_ERROR_REPORT == STD_ON if (pHandle == NULL) { CMU_ReportDevError(CMU_GET_MINCOUNT_ID, CMU_E_PARAM_NULLPTR); } else if (pHandle->eInstance >= CMU_INSTANCE_COUNT) { CMU_ReportDevError(CMU_GET_MINCOUNT_ID, CMU_E_PARAM_INSTANCE); } else #endif { CMU_Type *const pCmu = s_apCmuBase[pHandle->eInstance]; u32Value = CMU_HWA_GetMinCnts(pCmu); } return u32Value; } /** * @brief Retrieves the maximum count value from the CMU module. * * This function returns the maximum count value that the specified CMU module instance can support. * * @param pHandle Pointer to the CMU handle structure. * * @return uint32_t The maximum count value supported by the CMU module. * * @note If the handle pointer is NULL or the instance index is out of range, a device error will be reported. */ uint32_t CMU_GetMaxCount(CMU_HandleType *const pHandle) { uint32_t u32Value = 0U; #if CMU_DEV_ERROR_REPORT == STD_ON if (pHandle == NULL) { CMU_ReportDevError(CMU_GET_MAXCOUNT_ID, CMU_E_PARAM_NULLPTR); } else if (pHandle->eInstance >= CMU_INSTANCE_COUNT) { CMU_ReportDevError(CMU_GET_MAXCOUNT_ID, CMU_E_PARAM_INSTANCE); } else #endif { CMU_Type *const pCmu = s_apCmuBase[pHandle->eInstance]; u32Value = CMU_HWA_GetMaxCnts(pCmu); } return u32Value; } /** * @brief Sets the reference clock source for CMU4. * * This function configures the CMU4 reference clock source to either the Fast Oscillator Clock (FOSC) or the Slow Internal RC Oscillator Clock (SIRC). * * @param eSrc The CMU4 clock source type (CMU_CMU4_REF_CLK_FOSC or CMU_CMU4_REF_CLK_SIRC). * * @note The function clears the current CMU4 clock setting before applying the new source. */ void CMU_SetCmu4RefSrc(CMU_Cmu4ClkSrcType eSrc) { uint32_t u32Cmu4ClkMask; SCG_HWA_SetCmu4Clk(0U); if (CMU_CMU4_REF_CLK_FOSC == eSrc) { u32Cmu4ClkMask = SCG_CLKOUTCFG_CMU4CLK_FOSC(1U); SCG_HWA_SetCmu4Clk(u32Cmu4ClkMask); } else if (CMU_CMU4_REF_CLK_SIRC == eSrc) { u32Cmu4ClkMask = SCG_CLKOUTCFG_CMU4CLK_SIRC(1U); SCG_HWA_SetCmu4Clk(u32Cmu4ClkMask); } else { } } /** * @brief Retrieves the interrupt type of the CMU (Clock Monitor Unit) module. * * This function reads the status register of the CMU module to determine if a LOC (Loss of Clock) * or MIS (Mismatch) interrupt has occurred. * * @param pHandle Pointer to the CMU module handle. The handle contains information about the CMU instance. * * @return CMU_InterruptType The current interrupt type, which can be one of the following: * - CMU_INTERRUPT_NONE: No interrupt has occurred. * - CMU_INTERRUPT_LOC: A LOC interrupt has occurred. * - CMU_INTERRUPT_MIS: A MIS interrupt has occurred. * * @note If device error reporting is enabled (CMU_DEV_ERROR_REPORT == STD_ON), * the function will report an error if the handle pointer is NULL or if the instance number is invalid. */ CMU_InterruptType CMU_GetInterruptType(CMU_HandleType *const pHandle) { CMU_InterruptType eStatus = CMU_INTERRUPT_NONE; #if CMU_DEV_ERROR_REPORT == STD_ON if (pHandle == NULL) { CMU_ReportDevError(CMU_GET_INQTYPE_ID, CMU_E_PARAM_NULLPTR); } else if (pHandle->eInstance >= CMU_INSTANCE_COUNT) { CMU_ReportDevError(CMU_GET_INQTYPE_ID, CMU_E_PARAM_INSTANCE); } else #endif { CMU_Type *const pCmu = s_apCmuBase[pHandle->eInstance]; uint32_t u32Temp; u32Temp = CMU_HWA_GetST(pCmu); if ((u32Temp & CMU_ST_LOC_MASK) != 0U) { eStatus = CMU_INTERRUPT_LOC; } else if ((u32Temp & CMU_ST_MIS_MASK) != 0U) { eStatus = CMU_INTERRUPT_MIS; } else { } } return eStatus; } /** * @brief Common Clock Monitor Unit (CMU) Interrupt Service Routine (ISR) * * This ISR handles common interrupt scenarios for the CMU module associated with the given handle. * It retrieves the current interrupt status, performs error handling as needed, and calls * the registered error callback function if present. Additionally, it addresses a specific * hardware erratum (ERR_CMU_001). After processing, the ISR clears the status flags. * * @param pHandle Pointer to a CMU handle structure containing the instance information * * @preconditions * - A valid CMU handle must be provided * - The CMU instance number should be within the supported range * - The error callback function pointer in the handle should be properly initialized * * @note This function assumes that the CMU interrupt has already occurred and is being serviced. * @note Error reporting and handling are performed based on the interrupt status. */ void CMU_CommonIRQHandler(CMU_HandleType *const pHandle) { #if CMU_DEV_ERROR_REPORT == STD_ON if (pHandle == NULL) { CMU_ReportDevError(CMU_COMMONIRQHANDLER_ID, CMU_E_PARAM_NULLPTR); } else if (pHandle->eInstance >= CMU_INSTANCE_COUNT) { CMU_ReportDevError(CMU_COMMONIRQHANDLER_ID, CMU_E_PARAM_INSTANCE); } else #endif { CMU_Type *const pCmu = s_apCmuBase[pHandle->eInstance]; CMU_InterruptType eStatus; eStatus = CMU_GetInterruptType(pHandle); #ifdef CMU_ERRATA_CMU_001_FIX uint32_t u32Count; /* Errata: ERR_CMU_001 */ /* After assert software reset, you need init cmu again */ if (eStatus == CMU_INTERRUPT_NONE && CMU_HWA_GetPeriodEnable(pCmu)) { if (CMU_INSTANCE_0 == pHandle->eInstance) { u32Count = 0x1FFU; } else { u32Count = 0x1FU; } CMU_HWA_SetCtrl(pCmu, 0U); CMU_HWA_SoftwareRST(pCmu); while (CMU_HWA_GetSoftwareRST(pCmu)) { u32Count--; if (u32Count == 0U) { break; } } if (u32Count == 0U) { eStatus = CMU_INTERRUPT_LOC; } else { eStatus = CMU_INTERRUPT_MIS; } } #endif CMU_HWA_ClsST(pCmu); if (pHandle->tSettings.pErrorCallback != NULL) { pHandle->tSettings.pErrorCallback(pHandle, eStatus); } } } #endif /* (CMU_INSTANCE_COUNT > 0U) */