/*================================================================================================== * Project : RTD AUTOSAR 4.4 * Platform : CORTEXM * Peripheral : * Dependencies : none * * Autosar Version : 4.4.0 * Autosar Revision : ASR_REL_4_4_REV_0000 * Autosar Conf.Variant : * SW Version : 1.0.0 * Build Version : S32K1_RTD_1_0_0_HF01_D2109_ASR_REL_4_4_REV_0000_20210907 * * (c) Copyright 2020-2021 NXP Semiconductors * All Rights Reserved. * * NXP Confidential. This software is owned or controlled by NXP and may only be * used strictly in accordance with the applicable license terms. By expressly * accepting such terms or by downloading, installing, activating and/or otherwise * using the software, you are agreeing that you have read, and that you agree to * comply with and are bound by, such license terms. If you do not agree to be * bound by the applicable license terms, then you may not retain, install, * activate or otherwise use the software. ==================================================================================================*/ /** * @file Clock_Ip_Specific.c * @version 1.0.0 * * @brief CLOCK driver implementations. * @details CLOCK driver implementations. * * @addtogroup CLOCK_DRIVER Clock Ip Driver * @{ */ #include "Clock_Ip_Private.h" #if (defined(CLOCK_IP_ENABLE_USER_MODE_SUPPORT)) #if (STD_ON == CLOCK_IP_ENABLE_USER_MODE_SUPPORT) #define USER_MODE_REG_PROT_ENABLED (STD_ON) #include "RegLockMacros.h" #endif #endif /* CLOCK_IP_ENABLE_USER_MODE_SUPPORT */ /*================================================================================================== SOURCE FILE VERSION INFORMATION ==================================================================================================*/ #define CLOCK_IP_SPECIFIC_VENDOR_ID_C 43 #define CLOCK_IP_SPECIFIC_AR_RELEASE_MAJOR_VERSION_C 4 #define CLOCK_IP_SPECIFIC_AR_RELEASE_MINOR_VERSION_C 4 #define CLOCK_IP_SPECIFIC_AR_RELEASE_REVISION_VERSION_C 0 #define CLOCK_IP_SPECIFIC_SW_MAJOR_VERSION_C 1 #define CLOCK_IP_SPECIFIC_SW_MINOR_VERSION_C 0 #define CLOCK_IP_SPECIFIC_SW_PATCH_VERSION_C 0 /*================================================================================================== * FILE VERSION CHECKS ==================================================================================================*/ /* Check if Clock_Ip_Specific.c file and Clock_Ip_Private.h file are of the same vendor */ #if (CLOCK_IP_SPECIFIC_VENDOR_ID_C != CLOCK_IP_PRIVATE_VENDOR_ID) #error "Clock_Ip_Specific.c and Clock_Ip_Private.h have different vendor ids" #endif /* Check if Clock_Ip_Specific.c file and Clock_Ip_Private.h file are of the same Autosar version */ #if ((CLOCK_IP_SPECIFIC_AR_RELEASE_MAJOR_VERSION_C != CLOCK_IP_PRIVATE_AR_RELEASE_MAJOR_VERSION) || \ (CLOCK_IP_SPECIFIC_AR_RELEASE_MINOR_VERSION_C != CLOCK_IP_PRIVATE_AR_RELEASE_MINOR_VERSION) || \ (CLOCK_IP_SPECIFIC_AR_RELEASE_REVISION_VERSION_C != CLOCK_IP_PRIVATE_AR_RELEASE_REVISION_VERSION) \ ) #error "AutoSar Version Numbers of Clock_Ip_Specific.c and Clock_Ip_Private.h are different" #endif /* Check if Clock_Ip_Specific.c file and Clock_Ip_Private.h file are of the same Software version */ #if ((CLOCK_IP_SPECIFIC_SW_MAJOR_VERSION_C != CLOCK_IP_PRIVATE_SW_MAJOR_VERSION) || \ (CLOCK_IP_SPECIFIC_SW_MINOR_VERSION_C != CLOCK_IP_PRIVATE_SW_MINOR_VERSION) || \ (CLOCK_IP_SPECIFIC_SW_PATCH_VERSION_C != CLOCK_IP_PRIVATE_SW_PATCH_VERSION) \ ) #error "Software Version Numbers of Clock_Ip_Specific.c and Clock_Ip_Private.h are different" #endif #if (defined(CLOCK_IP_ENABLE_USER_MODE_SUPPORT)) #if (STD_ON == CLOCK_IP_ENABLE_USER_MODE_SUPPORT) #ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK /* Check if Clock_Ip_Specific.c file and RegLockMacros.h file are of the same Autosar version */ #if ((CLOCK_IP_SPECIFIC_AR_RELEASE_MAJOR_VERSION_C != REGLOCKMACROS_AR_RELEASE_MAJOR_VERSION) || \ (CLOCK_IP_SPECIFIC_AR_RELEASE_MINOR_VERSION_C != REGLOCKMACROS_AR_RELEASE_MINOR_VERSION)) #error "AutoSar Version Numbers of Clock_Ip_Specific.c and RegLockMacros.h are different" #endif #endif #endif #endif /* CLOCK_IP_ENABLE_USER_MODE_SUPPORT */ /*================================================================================================== LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS) ==================================================================================================*/ /*================================================================================================== * LOCAL MACROS ==================================================================================================*/ #define SCS_SELECTOR_HARDWARE_VALUES_NO 7U #define RUN_POWER_MODE_STATUS 1U #if (defined (CLOCK_IP_S32K118) || defined(CLOCK_IP_S32K116)) #define SYS_OSC 1U #define CMU 1U #define SCS_RUN 4U #define FIRCOSC 4U #define DIVCORE_RUN 5U #define DIVBUS_RUN 7U #define DIVSLOW_RUN 9U #elif (defined (CLOCK_IP_S32K142W) || defined(CLOCK_IP_S32K144W)) #define SYS_OSC 1U #define SYS_PLL 1U #define FIRCOSC 4U #define SCS_RUN 5U #define DIVCORE_RUN 6U #define DIVBUS_RUN 8U #define DIVSLOW_RUN 10U #elif (defined (CLOCK_IP_S32K142) || defined(CLOCK_IP_S32K144) || defined(CLOCK_IP_S32K146) || defined(CLOCK_IP_S32K148)) #define SYS_OSC 1U #define SYS_PLL 1U #define FIRCOSC 4U #define SCS_RUN 5U #define DIVCORE_RUN 6U #define SCS_HSRUN 7U #define DIVCORE_HSRUN 8U #define DIVBUS_RUN 9U #define DIVBUS_HSRUN 11U #define DIVSLOW_RUN 12U #define DIVSLOW_HSRUN 14U #endif /*================================================================================================== LOCAL CONSTANTS ==================================================================================================*/ /*================================================================================================== LOCAL VARIABLES ==================================================================================================*/ /*================================================================================================== GLOBAL CONSTANTS ==================================================================================================*/ /*================================================================================================== GLOBAL VARIABLES ==================================================================================================*/ #ifdef FEATURE_CLOCK_IP_HAS_FLASH_WAIT_STATES /* Clock start ram section code */ #define MCU_START_SEC_RAMCODE #include "Mcu_MemMap.h" static void CodeInRam_SetFlashWaitStates(void); /* Clock start ram section code */ #define MCU_STOP_SEC_RAMCODE #include "Mcu_MemMap.h" #endif /* FEATURE_CLOCK_IP_HAS_FLASH_WAIT_STATES */ /* Clock start initialized section data */ #define MCU_START_SEC_VAR_CLEARED_BOOLEAN #include "Mcu_MemMap.h" static boolean fircWasEnabledBeforeMcuInit; /* Firc clock was enabled before MCU initialization */ /* Clock stop initialized section data */ #define MCU_STOP_SEC_VAR_CLEARED_BOOLEAN #include "Mcu_MemMap.h" /* Clock start initialized section data */ #define MCU_START_SEC_VAR_CLEARED_UNSPECIFIED #include "Mcu_MemMap.h" static const Clock_Ip_ClockConfigType *config_clock; #if defined(FEATURE_CLOCK_IP_HAS_SPLL_CLK) static const pllCallback * spllClock; #endif static const extOscCallback *soscClock; static const intOscCallback *fircClock; #if defined(FEATURE_CLOCK_IP_HAS_FIRC_MON1_CLK) || defined(FEATURE_CLOCK_IP_HAS_FIRC_MON2_CLK) static const clockMonitorCallback *cmuFircMonitor; #endif static const selectorCallback *scsRunClockSelector; static const dividerCallback *coreRunClockDivider; static const dividerCallback *busRunClockDivider; static const dividerCallback *slowRunClockDivider; static const Clock_Ip_IrcoscConfigType *fircConfig; static const Clock_Ip_XoscConfigType *soscConfig; #if defined(FEATURE_CLOCK_IP_HAS_SPLL_CLK) static const Clock_Ip_PllConfigType *spllConfig; #endif #if defined(FEATURE_CLOCK_IP_HAS_FIRC_MON1_CLK) || defined(FEATURE_CLOCK_IP_HAS_FIRC_MON2_CLK) const Clock_Ip_CmuConfigType *cmuFircMon1Config,*cmuFircMon2Config; #endif static const Clock_Ip_SelectorConfigType *scsConfig_Run_Mode, *scsConfig_Vlpr_Mode; static const Clock_Ip_DividerConfigType *coreConfig_Run_Mode, *coreConfig_Vlpr_Mode, *busConfig_Run_Mode, *busConfig_Vlpr_Mode, *slowConfig_Run_Mode, *slowConfig_Vlpr_Mode; #if defined(FEATURE_CLOCK_IP_HAS_SLOW_HSRUN_CLK) static const selectorCallback *scsHsrunClockSelector; static const dividerCallback *coreHsrunClockDivider; static const dividerCallback *busHsrunClockDivider; static const dividerCallback *slowHsrunClockDivider; static const Clock_Ip_SelectorConfigType *scsConfig_Hsrun_Mode; static const Clock_Ip_DividerConfigType *coreConfig_Hsrun_Mode, *busConfig_Hsrun_Mode, *slowConfig_Hsrun_Mode; #endif /* Clock stop initialized section data */ #define MCU_STOP_SEC_VAR_CLEARED_UNSPECIFIED #include "Mcu_MemMap.h" /*================================================================================================== * LOCAL FUNCTION PROTOTYPES ==================================================================================================*/ #define MCU_START_SEC_CODE #include "Mcu_MemMap.h" static const Clock_Ip_IrcoscConfigType *getFircConfig(void); static const Clock_Ip_XoscConfigType *getSoscConfig(void); static const Clock_Ip_XoscConfigType *getSoscConfig(void); #if defined(FEATURE_CLOCK_IP_HAS_SPLL_CLK) static const Clock_Ip_PllConfigType *getSpllConfig(void); #endif #if defined(FEATURE_CLOCK_IP_HAS_FIRC_MON1_CLK) || defined(FEATURE_CLOCK_IP_HAS_FIRC_MON2_CLK) static const Clock_Ip_CmuConfigType *getCmuFircConfig(Clock_Ip_NameType name); #endif static const Clock_Ip_SelectorConfigType *getSelectorConfig(Clock_Ip_NameType name); static const Clock_Ip_DividerConfigType *getCoreDividerConfig(Clock_Ip_NameType name); static const Clock_Ip_DividerConfigType *getBusDividerConfig(Clock_Ip_NameType name); static const Clock_Ip_DividerConfigType *getSlowDividerConfig(Clock_Ip_NameType name); static void SetSimLpoclksRegister_TrustedCall(Clock_Ip_ClockConfigType const *config); #if defined(FEATURE_CLOCK_IP_HAS_FIRC_MON1_CLK) || defined(FEATURE_CLOCK_IP_HAS_FIRC_MON2_CLK) static void EnableCmuGate_TrustedCall(void); #endif #define MCU_STOP_SEC_CODE #include "Mcu_MemMap.h" /*================================================================================================== * LOCAL FUNCTIONS ==================================================================================================*/ /*================================================================================================== * GLOBAL FUNCTIONS ==================================================================================================*/ #ifdef FEATURE_CLOCK_IP_HAS_RAM_WAIT_STATES #define MCU_START_SEC_CODE_AC #include "Mcu_MemMap.h" static void PRAMC_SetRamIWS(void); #define MCU_STOP_SEC_CODE_AC #include "Mcu_MemMap.h" #endif #define MCU_START_SEC_CODE #include "Mcu_MemMap.h" #ifdef FEATURE_CLOCK_IP_HAS_RAM_WAIT_STATES void SetRamWaitStates(void) { #ifdef CLOCK_IP_ENABLE_USER_MODE_SUPPORT #if (STD_ON == CLOCK_IP_ENABLE_USER_MODE_SUPPORT) OsIf_Trusted_Call(PRAMC_SetRamIWS); #else PRAMC_SetRamIWS(); #endif #else PRAMC_SetRamIWS(); #endif } #endif #ifdef FEATURE_CLOCK_IP_HAS_FLASH_WAIT_STATES void FLASH_SetFlashIWS(void); void SetFlashWaitStates(void) { FLASH_SetFlashIWS(); } #endif /* Configure the specific modules like eMios */ void SpecificPeripheralClockInitialization(Clock_IP_SpecificPeriphConfigType const * config) { (void)config; } void DisableSafeClock(Clock_Ip_ClockConfigType const * config) { uint32 i; boolean fircConfigFound = FALSE; if (config != NULL_PTR) { for (i = 0U; i < config_clock->ircoscsCount; i++) { if (config_clock->ircoscs[i].name == FIRC_CLK) { fircConfigFound = TRUE; if (config_clock->ircoscs[i].enable == FALSE) { /* Disable FIRC according to configuration */ intOscCallbacks[ircoscCallbackIndex[FIRCOSC]].Disable(FIRC_CLK); } break; } } } if ((fircConfigFound == FALSE) && (fircWasEnabledBeforeMcuInit == FALSE)) { /* Disable FIRC according to configuration */ intOscCallbacks[ircoscCallbackIndex[FIRCOSC]].Disable(FIRC_CLK); } } static void SetFircToResetValue_TrustedCall(void) { /* Range is 48Mhz. */ IP_SCG->FIRCCFG = SCG_FIRCCFG_RANGE(0U); /* Enable clock, regulator is enabled. */ IP_SCG->FIRCCSR |= (SCG_FIRCCSR_FIRCEN(1U) | SCG_FIRCCSR_FIRCREGOFF(0U)); } static void SetSimLpoclksRegister_TrustedCall(Clock_Ip_ClockConfigType const *config) { uint32 SimLpoValue = 3U; /* Reset value of SIM_LPOCLKS register */ uint32 i; /* The LPOCLKS register is a write-once register so configuration will be written here*/ for (i = 0U; i < config->selectorsCount; i++) { /* Selector for RTC_CLK */ if (RTC_CLK == config->selectors[i].name) { SimLpoValue |= ((uint32)(selectorEntry_hardwareValue[config->selectors[i].value]) << SIM_LPOCLKS_RTCCLKSEL_SHIFT); } /* Selector for LPO_CLK */ if (LPO_CLK == config->selectors[i].name) { SimLpoValue |= ((uint32)(selectorEntryPCS_hardwareValue[config->selectors[i].value]) << SIM_LPOCLKS_LPOCLKSEL_SHIFT); } } for (i = 0U; i < config->gatesCount; i++) /* Set clock gates that are under clock control. */ { /* Gate for LPO_32K_CLK */ if (LPO_32K_CLK == config->gates[i].name) { SimLpoValue |= ((uint32)(config->gates[i].enable) << SIM_LPOCLKS_LPO32KCLKEN_SHIFT); } /* Gate for LPO_1K_CLK */ if (LPO_1K_CLK == config->gates[i].name) { SimLpoValue |= ((uint32)(config->gates[i].enable) << SIM_LPOCLKS_LPO1KCLKEN_SHIFT); } } IP_SIM->LPOCLKS = SimLpoValue; } #if defined(FEATURE_CLOCK_IP_HAS_FIRC_MON1_CLK) || defined(FEATURE_CLOCK_IP_HAS_FIRC_MON2_CLK) static void EnableCmuGate_TrustedCall(void) { uint32 regValue; regValue = IP_PCC->PCCn[clockFeatures[CMU0_CLK][GATE_INDEX]]; regValue &= ~PCC_PCCn_CGC_MASK; regValue |= PCC_PCCn_CGC_MASK; IP_PCC->PCCn[clockFeatures[CMU0_CLK][GATE_INDEX]] = regValue; regValue = IP_PCC->PCCn[clockFeatures[CMU1_CLK][GATE_INDEX]]; regValue &= ~PCC_PCCn_CGC_MASK; regValue |= PCC_PCCn_CGC_MASK; IP_PCC->PCCn[clockFeatures[CMU1_CLK][GATE_INDEX]] = regValue; } #endif void SpecificPlatformInitClock(Clock_Ip_ClockConfigType const * config) { boolean TimeoutOccurred = FALSE; uint32 StartTime; uint32 ElapsedTime; uint32 TimeoutTicks; uint32 IrcoscStatus; config_clock = config; (void)RUN_POWER_MODE_STATUS; /* Clocks cannot be configured while the chip is in other mode than RUN_MODE */ CLOCK_DEV_ASSERT(RUN_POWER_MODE_STATUS == ((IP_SMC->PMSTAT & SMC_PMSTAT_PMSTAT_MASK) >> SMC_PMSTAT_PMSTAT_SHIFT)); /* Check whether FIRC is disabled, enable it in this case. */ if ((IP_SCG->FIRCCSR & SCG_FIRCCSR_FIRCEN_MASK) == 0U) { fircWasEnabledBeforeMcuInit = FALSE; #ifdef CLOCK_IP_ENABLE_USER_MODE_SUPPORT #if (STD_ON == CLOCK_IP_ENABLE_USER_MODE_SUPPORT) OsIf_Trusted_Call(SetFircToResetValue_TrustedCall); #else SetFircToResetValue_TrustedCall(); #endif #endif /* CLOCK_IP_ENABLE_USER_MODE_SUPPORT */ ClockStartTimeout(&StartTime, &ElapsedTime, &TimeoutTicks, CLOCK_TIMEOUT_VALUE_US); /* Wait until ircosc is locked */ do { IrcoscStatus = (((IP_SCG->FIRCCSR & SCG_FIRCCSR_FIRCVLD_MASK) >> SCG_FIRCCSR_FIRCVLD_SHIFT)); TimeoutOccurred = ClockTimeoutExpired(&StartTime, &ElapsedTime, TimeoutTicks); } while ((IrcoscStatus == 0U) && (FALSE == TimeoutOccurred)); if (FALSE != TimeoutOccurred) { /* Report timeout error */ ReportClockErrors(CLOCK_IP_REPORT_TIMEOUT_ERROR, FIRC_CLK); } } else { fircWasEnabledBeforeMcuInit = TRUE; } #ifdef CLOCK_IP_ENABLE_USER_MODE_SUPPORT #if (STD_ON == CLOCK_IP_ENABLE_USER_MODE_SUPPORT) OsIf_Trusted_Call1param(SetSimLpoclksRegister_TrustedCall,(config)); #else SetSimLpoclksRegister_TrustedCall(config); #endif #endif /* CLOCK_IP_ENABLE_USER_MODE_SUPPORT */ #if defined(FEATURE_CLOCK_IP_HAS_FIRC_MON1_CLK) || defined(FEATURE_CLOCK_IP_HAS_FIRC_MON2_CLK) #ifdef CLOCK_IP_ENABLE_USER_MODE_SUPPORT #if (STD_ON == CLOCK_IP_ENABLE_USER_MODE_SUPPORT) OsIf_Trusted_Call(EnableCmuGate_TrustedCall); #else EnableCmuGate_TrustedCall(); #endif #endif /* CLOCK_IP_ENABLE_USER_MODE_SUPPORT */ #endif } /** * @brief This function will get current configuration of FIRC. */ static const Clock_Ip_IrcoscConfigType *getFircConfig(void) { uint32 i; const Clock_Ip_IrcoscConfigType *returnValue = NULL_PTR; static Clock_Ip_IrcoscConfigType fircConfiguration; if (config_clock != NULL_PTR) { for (i = 0U; i < config_clock->ircoscsCount; i++) { if (config_clock->ircoscs[i].name == FIRC_CLK) { returnValue = &config_clock->ircoscs[i]; break; } } } /* Element is not under mcu control */ if (returnValue == NULL_PTR) { returnValue = &fircConfiguration; fircConfiguration.name = FIRC_CLK; fircConfiguration.enable = (uint16)(IP_SCG->FIRCCSR & SCG_FIRCCSR_FIRCEN_MASK) >> SCG_FIRCCSR_FIRCEN_SHIFT; fircConfiguration.range = (uint8)(IP_SCG->FIRCCFG & SCG_FIRCCFG_RANGE_MASK) >> SCG_FIRCCFG_RANGE_SHIFT; fircConfiguration.regulator = (uint8)(IP_SCG->FIRCCSR & SCG_FIRCCSR_FIRCREGOFF_MASK) >> SCG_FIRCCSR_FIRCREGOFF_SHIFT; } return returnValue; } /** * @brief This function will get current configuration of SOSC. */ static const Clock_Ip_XoscConfigType *getSoscConfig(void) { uint32 i; const Clock_Ip_XoscConfigType *returnValue = NULL_PTR; static Clock_Ip_XoscConfigType soscConfiguration; if (config_clock != NULL_PTR) { for (i = 0U; i < config_clock->xoscsCount; i++) { if (config_clock->xoscs[i].name == SOSC_CLK) { returnValue = &config_clock->xoscs[i]; break; } } } /* Element is not under mcu control */ if (returnValue == NULL_PTR) { returnValue = &soscConfiguration; soscConfiguration.name = SOSC_CLK; soscConfiguration.enable = (uint16)(IP_SCG->SOSCCSR & SCG_SOSCCSR_SOSCEN_MASK) >> SCG_SOSCCSR_SOSCEN_SHIFT; soscConfiguration.freq = FEATURE_CLOCK_IP_DEFAULT_SOSC_FREQUENCY; } return returnValue; } #if defined(FEATURE_CLOCK_IP_HAS_SPLL_CLK) /** * @brief This function will get current configuration of SPLL. */ static const Clock_Ip_PllConfigType *getSpllConfig(void) { uint32 i; const Clock_Ip_PllConfigType *returnValue = NULL_PTR; static Clock_Ip_PllConfigType spllConfiguration; if (config_clock != NULL_PTR) { for (i = 0U; i < config_clock->pllsCount; i++) { if (config_clock->plls[i].name == SPLL_CLK) { returnValue = &config_clock->plls[i]; break; } } } /* Element is not under mcu control */ if (returnValue == NULL_PTR) { returnValue = &spllConfiguration; spllConfiguration.name = SPLL_CLK; spllConfiguration.enable = (uint16)(IP_SCG->SPLLCSR & SCG_SPLLCSR_SPLLEN_MASK) >> SCG_SPLLCSR_SPLLEN_SHIFT; spllConfiguration.predivider = (uint8)((IP_SCG->SPLLCFG & SCG_SPLLCFG_PREDIV_MASK) >> SCG_SPLLCFG_PREDIV_SHIFT); spllConfiguration.mulFactorDiv = (uint8)((IP_SCG->SPLLCFG & SCG_SPLLCFG_MULT_MASK) >> SCG_SPLLCFG_MULT_SHIFT); } return returnValue; } #endif #if defined(FEATURE_CLOCK_IP_HAS_FIRC_MON1_CLK) || defined(FEATURE_CLOCK_IP_HAS_FIRC_MON2_CLK) static const Clock_Ip_CmuConfigType *getCmuFircConfig(Clock_Ip_NameType name) { uint32 i; const Clock_Ip_CmuConfigType *returnValue = NULL_PTR; static Clock_Ip_CmuConfigType cmuConfiguration; if (config_clock != NULL_PTR) { for (i = 0U; i < config_clock->cmusCount; i++) { if (config_clock->cmus[i].name == name) { returnValue = &config_clock->cmus[i]; break; } } } /* Element is not under mcu control */ if (returnValue == NULL_PTR) { returnValue = &cmuConfiguration; cmuConfiguration.name = FIRC_CLK; cmuConfiguration.enable = (cmu[0U]->GCR & CMU_FC_GCR_FCE_MASK) >> CMU_FC_GCR_FCE_SHIFT; } return returnValue; } #endif static const Clock_Ip_SelectorConfigType *getSelectorConfig(Clock_Ip_NameType name) { const Clock_Ip_SelectorConfigType *returnValue = NULL_PTR; static Clock_Ip_SelectorConfigType selectorConfigurations[3U]; uint32 selectorConfigIndex, i; static const Clock_Ip_NameType clockSource[SCS_SELECTOR_HARDWARE_VALUES_NO] = { CLOCK_IS_OFF, /* clock name for 0 hardware value */ SOSC_CLK, /* clock name for 1 hardware value */ SIRC_CLK, /* clock name for 2 hardware value */ FIRC_CLK, /* clock name for 3 hardware value */ CLOCK_IS_OFF, /* clock name for 4 hardware value */ CLOCK_IS_OFF, /* clock name for 5 hardware value */ #if defined(FEATURE_CLOCK_IP_HAS_SPLL_CLK) SPLL_CLK, /* clock name for 6 hardware value */ #else CLOCK_IS_OFF, /* clock name for 6 hardware value */ #endif }; switch(name) { case SCS_RUN_CLK: selectorConfigIndex = 0U; break; case SCS_VLPR_CLK: selectorConfigIndex = 1U; break; #if defined(FEATURE_CLOCK_IP_HAS_SCS_HSRUN_CLK) case SCS_HSRUN_CLK: selectorConfigIndex = 2U; break; #endif default: selectorConfigIndex = 0U; break; } if (config_clock != NULL_PTR) { for (i = 0U; i < config_clock->selectorsCount; i++) { if (config_clock->selectors[i].name == name) { returnValue = &config_clock->selectors[i]; break; } } } /* Element is not under mcu control */ if (returnValue == NULL_PTR) { returnValue = &selectorConfigurations[selectorConfigIndex]; selectorConfigurations[selectorConfigIndex].name = name; switch(name) { case SCS_RUN_CLK: selectorConfigurations[selectorConfigIndex].value = clockSource[(IP_SCG->RCCR & SCG_RCCR_SCS_MASK) >> SCG_RCCR_SCS_SHIFT]; break; case SCS_VLPR_CLK: selectorConfigurations[selectorConfigIndex].value = clockSource[(IP_SCG->VCCR & SCG_VCCR_SCS_MASK) >> SCG_VCCR_SCS_SHIFT]; break; #if defined(FEATURE_CLOCK_IP_HAS_SCS_HSRUN_CLK) case SCS_HSRUN_CLK: selectorConfigurations[selectorConfigIndex].value = clockSource[(IP_SCG->HCCR & SCG_HCCR_SCS_MASK) >> SCG_HCCR_SCS_SHIFT]; break; #endif default: /* Invalid clock name */ break; } } return returnValue; } static const Clock_Ip_DividerConfigType *getCoreDividerConfig(Clock_Ip_NameType name) { const Clock_Ip_DividerConfigType *returnValue = NULL_PTR; static Clock_Ip_DividerConfigType dividerConfigurations[3U]; uint32 dividerConfigIndex = 0U; uint32 i; switch(name) { case CORE_RUN_CLK: dividerConfigIndex = 0U; break; case CORE_VLPR_CLK: dividerConfigIndex = 1U; break; #if defined(FEATURE_CLOCK_IP_HAS_CORE_HSRUN_CLK) case CORE_HSRUN_CLK: dividerConfigIndex = 2U; break; #endif default: /* Invalid clock name */ break; } if (config_clock != NULL_PTR) { for (i = 0U; i < config_clock->dividersCount; i++) { if (config_clock->dividers[i].name == name) { returnValue = &config_clock->dividers[i]; break; } } } /* Element is not under mcu control */ if (returnValue == NULL_PTR) { returnValue = ÷rConfigurations[dividerConfigIndex]; dividerConfigurations[dividerConfigIndex].name = name; switch(name) { case CORE_RUN_CLK: dividerConfigurations[dividerConfigIndex].value = ((IP_SCG->RCCR & SCG_RCCR_DIVCORE_MASK) >> SCG_RCCR_DIVCORE_SHIFT) + 1U; break; case CORE_VLPR_CLK: dividerConfigurations[dividerConfigIndex].value = ((IP_SCG->VCCR & SCG_VCCR_DIVCORE_MASK) >> SCG_VCCR_DIVCORE_SHIFT) + 1U; break; #if defined(FEATURE_CLOCK_IP_HAS_CORE_HSRUN_CLK) case CORE_HSRUN_CLK: dividerConfigurations[dividerConfigIndex].value = ((IP_SCG->HCCR & SCG_HCCR_DIVCORE_MASK) >> SCG_HCCR_DIVCORE_SHIFT) + 1U; break; #endif default: /* Invalid clock name */ break; } } return returnValue; } static const Clock_Ip_DividerConfigType *getBusDividerConfig(Clock_Ip_NameType name) { const Clock_Ip_DividerConfigType *returnValue = NULL_PTR; static Clock_Ip_DividerConfigType dividerConfigurations[3U]; uint32 dividerConfigIndex = 0U; uint32 i; switch(name) { case BUS_RUN_CLK: dividerConfigIndex = 0U; break; case BUS_VLPR_CLK: dividerConfigIndex = 1U; break; #if defined(FEATURE_CLOCK_IP_HAS_BUS_HSRUN_CLK) case BUS_HSRUN_CLK: dividerConfigIndex = 2U; break; #endif default: /* Invalid clock name */ break; } if (config_clock != NULL_PTR) { for (i = 0U; i < config_clock->dividersCount; i++) { if (config_clock->dividers[i].name == name) { returnValue = &config_clock->dividers[i]; break; } } } /* Element is not under mcu control */ if (returnValue == NULL_PTR) { returnValue = ÷rConfigurations[dividerConfigIndex]; dividerConfigurations[dividerConfigIndex].name = name; switch(name) { case BUS_RUN_CLK: dividerConfigurations[dividerConfigIndex].value = ((IP_SCG->RCCR & SCG_RCCR_DIVBUS_MASK) >> SCG_RCCR_DIVBUS_SHIFT) + 1U; break; case BUS_VLPR_CLK: dividerConfigurations[dividerConfigIndex].value = ((IP_SCG->VCCR & SCG_VCCR_DIVBUS_MASK) >> SCG_VCCR_DIVBUS_SHIFT) + 1U; break; #if defined(FEATURE_CLOCK_IP_HAS_BUS_HSRUN_CLK) case BUS_HSRUN_CLK: dividerConfigurations[dividerConfigIndex].value = ((IP_SCG->HCCR & SCG_HCCR_DIVBUS_MASK) >> SCG_HCCR_DIVBUS_SHIFT) + 1U; break; #endif default: /* Invalid clock name */ break; } } return returnValue; } static const Clock_Ip_DividerConfigType *getSlowDividerConfig(Clock_Ip_NameType name) { const Clock_Ip_DividerConfigType *returnValue = NULL_PTR; static Clock_Ip_DividerConfigType dividerConfigurations[3U]; uint32 dividerConfigIndex = 0U; uint32 i; switch(name) { case SLOW_RUN_CLK: dividerConfigIndex = 0U; break; case SLOW_VLPR_CLK: dividerConfigIndex = 1U; break; #if defined(FEATURE_CLOCK_IP_HAS_SLOW_HSRUN_CLK) case SLOW_HSRUN_CLK: dividerConfigIndex = 2U; break; #endif default: /* Invalid clock name */ break; } if (config_clock != NULL_PTR) { for (i = 0U; i < config_clock->dividersCount; i++) { if (config_clock->dividers[i].name == name) { returnValue = &config_clock->dividers[i]; break; } } } /* Element is not under mcu control */ if (returnValue == NULL_PTR) { returnValue = ÷rConfigurations[dividerConfigIndex]; dividerConfigurations[dividerConfigIndex].name = name; switch(name) { case SLOW_RUN_CLK: dividerConfigurations[dividerConfigIndex].value = ((IP_SCG->RCCR & SCG_RCCR_DIVSLOW_MASK) >> SCG_RCCR_DIVSLOW_SHIFT) + 1U; break; case SLOW_VLPR_CLK: dividerConfigurations[dividerConfigIndex].value = ((IP_SCG->VCCR & SCG_VCCR_DIVSLOW_MASK) >> SCG_VCCR_DIVSLOW_SHIFT) + 1U; break; #if defined(FEATURE_CLOCK_IP_HAS_SLOW_HSRUN_CLK) case SLOW_HSRUN_CLK: dividerConfigurations[dividerConfigIndex].value = ((IP_SCG->HCCR & SCG_HCCR_DIVSLOW_MASK) >> SCG_HCCR_DIVSLOW_SHIFT) + 1U; break; #endif default: /* Invalid clock name */ break; } } return returnValue; } /* Initialize objects for clock */ void ClockInitializeObjects(void) { #if defined(FEATURE_CLOCK_IP_HAS_SPLL_CLK) spllClock = &pllCallbacks[pllCallbackIndex[SYS_PLL]]; #endif soscClock = &extOscCallbacks[xoscCallbackIndex[SYS_OSC]]; fircClock = &intOscCallbacks[ircoscCallbackIndex[FIRCOSC]]; #if defined(FEATURE_CLOCK_IP_HAS_FIRC_MON1_CLK) || defined(FEATURE_CLOCK_IP_HAS_FIRC_MON2_CLK) cmuFircMonitor = &cmuCallbacks[cmuCallbackIndex[CMU]]; #endif scsRunClockSelector = &selectorCallbacks[selectorCallbackIndex[SCS_RUN]]; #if defined(FEATURE_CLOCK_IP_HAS_SCS_HSRUN_CLK) scsHsrunClockSelector = &selectorCallbacks[selectorCallbackIndex[SCS_HSRUN]]; #endif coreRunClockDivider = ÷rCallbacks[dividerCallbackIndex[DIVCORE_RUN]]; #if defined(FEATURE_CLOCK_IP_HAS_CORE_HSRUN_CLK) coreHsrunClockDivider = ÷rCallbacks[dividerCallbackIndex[DIVCORE_HSRUN]]; #endif busRunClockDivider = ÷rCallbacks[dividerCallbackIndex[DIVBUS_RUN]]; #if defined(FEATURE_CLOCK_IP_HAS_BUS_HSRUN_CLK) busHsrunClockDivider = ÷rCallbacks[dividerCallbackIndex[DIVBUS_HSRUN]]; #endif slowRunClockDivider = ÷rCallbacks[dividerCallbackIndex[DIVSLOW_RUN]]; #if defined(FEATURE_CLOCK_IP_HAS_SLOW_HSRUN_CLK) slowHsrunClockDivider = ÷rCallbacks[dividerCallbackIndex[DIVSLOW_HSRUN]]; #endif fircConfig = getFircConfig(); soscConfig = getSoscConfig(); #if defined(FEATURE_CLOCK_IP_HAS_SPLL_CLK) spllConfig = getSpllConfig(); #endif #if defined(FEATURE_CLOCK_IP_HAS_FIRC_MON1_CLK) cmuFircMon1Config = getCmuFircConfig(FIRC_MON1_CLK); #endif #if defined(FEATURE_CLOCK_IP_HAS_FIRC_MON2_CLK) cmuFircMon2Config = getCmuFircConfig(FIRC_MON2_CLK); #endif scsConfig_Run_Mode = getSelectorConfig(SCS_RUN_CLK); scsConfig_Vlpr_Mode = getSelectorConfig(SCS_VLPR_CLK); #if defined(FEATURE_CLOCK_IP_HAS_SCS_HSRUN_CLK) scsConfig_Hsrun_Mode = getSelectorConfig(SCS_HSRUN_CLK); #endif coreConfig_Run_Mode = getCoreDividerConfig(CORE_RUN_CLK); coreConfig_Vlpr_Mode = getCoreDividerConfig(CORE_VLPR_CLK); #if defined(FEATURE_CLOCK_IP_HAS_CORE_HSRUN_CLK) coreConfig_Hsrun_Mode = getCoreDividerConfig(CORE_HSRUN_CLK); #endif busConfig_Run_Mode = getBusDividerConfig(BUS_RUN_CLK); busConfig_Vlpr_Mode = getBusDividerConfig(BUS_VLPR_CLK); #if defined(FEATURE_CLOCK_IP_HAS_BUS_HSRUN_CLK) busConfig_Hsrun_Mode = getBusDividerConfig(BUS_HSRUN_CLK); #endif slowConfig_Run_Mode = getSlowDividerConfig(SLOW_RUN_CLK); slowConfig_Vlpr_Mode = getSlowDividerConfig(SLOW_VLPR_CLK); #if defined(FEATURE_CLOCK_IP_HAS_SLOW_HSRUN_CLK) slowConfig_Hsrun_Mode = getSlowDividerConfig(SLOW_HSRUN_CLK); #endif } void ClockPowerModeChangeNotification(power_modes_t powerMode, power_notification_t notification) { switch(powerMode) { case VLPR_MODE: case VLPS_MODE: { if(BEFORE_POWER_MODE_CHANGE == notification) { /* Disable all cmus */ #if defined(FEATURE_CLOCK_IP_HAS_FIRC_MON1_CLK) /* Check enable clock gate for CMU0 */ if(((IP_PCC->PCCn[62] & PCC_PCCn_CGC_MASK) >> PCC_PCCn_CGC_SHIFT) == 1U) { cmuFircMonitor->Disable(FIRC_MON1_CLK); } #endif #if defined(FEATURE_CLOCK_IP_HAS_FIRC_MON2_CLK) /* Check enable clock gate for CMU1 */ if(((IP_PCC->PCCn[63] & PCC_PCCn_CGC_MASK) >> PCC_PCCn_CGC_SHIFT) == 1U) { cmuFircMonitor->Disable(FIRC_MON2_CLK); } #endif /* Load system clock settings for VLPR mode */ scsRunClockSelector->Set(scsConfig_Vlpr_Mode); coreRunClockDivider->Set(coreConfig_Vlpr_Mode); busRunClockDivider->Set(busConfig_Vlpr_Mode); slowRunClockDivider->Set(slowConfig_Vlpr_Mode); /* Disable all clock sources except SIRC */ #if defined(FEATURE_CLOCK_IP_HAS_SPLL_CLK) spllClock->Disable(spllConfig->name); #endif soscClock->Disable(soscConfig->name); fircClock->Disable(fircConfig->name); } } break; case RUN_MODE: { if(POWER_MODE_CHANGED == notification) { /* Restore clock source settings */ fircClock->Enable(fircConfig); soscClock->Enable(soscConfig); /* Enable */ soscClock->Complete(soscConfig); /* Wait to lock */ #if defined(FEATURE_CLOCK_IP_HAS_SPLL_CLK) spllClock->Enable(spllConfig); /* Enable */ (void)(spllClock->Complete(spllConfig->name)); /* Wait to lock */ #endif /* Restore system clock settings */ scsRunClockSelector->Set(scsConfig_Run_Mode); coreRunClockDivider->Set(coreConfig_Run_Mode); busRunClockDivider->Set(busConfig_Run_Mode); slowRunClockDivider->Set(slowConfig_Run_Mode); /* Restore all cmus */ #if defined(FEATURE_CLOCK_IP_HAS_FIRC_MON1_CLK) /* Check enable clock gate for CMU0 */ if(((IP_PCC->PCCn[62] & PCC_PCCn_CGC_MASK) >> PCC_PCCn_CGC_SHIFT) == 1U) { cmuFircMonitor->Enable(cmuFircMon1Config); } #endif #if defined(FEATURE_CLOCK_IP_HAS_FIRC_MON2_CLK) /* Check enable clock gate for CMU1 */ if(((IP_PCC->PCCn[63] & PCC_PCCn_CGC_MASK) >> PCC_PCCn_CGC_SHIFT) == 1U) { cmuFircMonitor->Enable(cmuFircMon2Config); } #endif } } break; case HSRUN_MODE: { if(POWER_MODE_CHANGED == notification) { /* Restore clock source settings */ fircClock->Enable(fircConfig); soscClock->Enable(soscConfig); /* Enable */ soscClock->Complete(soscConfig); /* Wait to lock */ #if defined(FEATURE_CLOCK_IP_HAS_SPLL_CLK) spllClock->Enable(spllConfig); /* Enable */ (void)(spllClock->Complete(spllConfig->name)); /* Wait to lock */ #endif /* Restore system clock settings */ #if defined(FEATURE_CLOCK_IP_HAS_SCS_HSRUN_CLK) scsHsrunClockSelector->Set(scsConfig_Hsrun_Mode); #endif #if defined(FEATURE_CLOCK_IP_HAS_CORE_HSRUN_CLK) coreHsrunClockDivider->Set(coreConfig_Hsrun_Mode); #endif #if defined(FEATURE_CLOCK_IP_HAS_BUS_HSRUN_CLK) busHsrunClockDivider->Set(busConfig_Hsrun_Mode); #endif #if defined(FEATURE_CLOCK_IP_HAS_SLOW_HSRUN_CLK) slowHsrunClockDivider->Set(slowConfig_Hsrun_Mode); #endif /* Restore all cmus */ #if defined(FEATURE_CLOCK_IP_HAS_FIRC_MON1_CLK) /* Check enable clock gate for CMU0 */ if(((IP_PCC->PCCn[62] & PCC_PCCn_CGC_MASK) >> PCC_PCCn_CGC_SHIFT) == 1U) { cmuFircMonitor->Enable(cmuFircMon1Config); } #endif #if defined(FEATURE_CLOCK_IP_HAS_FIRC_MON2_CLK) /* Check enable clock gate for CMU1 */ if(((IP_PCC->PCCn[63] & PCC_PCCn_CGC_MASK) >> PCC_PCCn_CGC_SHIFT) == 1U) { cmuFircMonitor->Enable(cmuFircMon2Config); } #endif } } break; default: { /* Invalid power mode */ } break; } } /* Clock stop section code */ #define MCU_STOP_SEC_CODE #include "Mcu_MemMap.h" #ifdef FEATURE_CLOCK_IP_HAS_RAM_WAIT_STATES /* Clock start rom section code */ #define MCU_START_SEC_CODE_AC #include "Mcu_MemMap.h" static void PRAMC_SetRamIWS(void) { /* CORE_CLK frequency is greater than 80MHz or CORE_CLK and AIPS_PLAT_CLK have the same frequency */ if ((configuredCoreClock > 80000000U) || (configuredCoreClock == configuredAipsPlatClock)) { /* Enable RAM WS */ PRAMC_0->PRCR1 |= PRAMC_PRCR1_FT_DIS_MASK; PRAMC_1->PRCR1 |= PRAMC_PRCR1_FT_DIS_MASK; } else { /* Disable RAM WS */ PRAMC_0->PRCR1 &= ~PRAMC_PRCR1_FT_DIS_MASK; PRAMC_1->PRCR1 &= ~PRAMC_PRCR1_FT_DIS_MASK; } } /* Clock stop rom section code */ #define MCU_STOP_SEC_CODE_AC #include "Mcu_MemMap.h" #endif #ifdef FEATURE_CLOCK_IP_HAS_FLASH_WAIT_STATES /* Clock start ram section code */ #define MCU_START_SEC_RAMCODE #include "Mcu_MemMap.h" static void CodeInRam_SetFlashWaitStates(void) { uint32 rwsc_setting = 0U; if (configuredCoreClock <= 167000000U) { if (configuredCoreClock <= 66000000U) { rwsc_setting = 1U; } else if (configuredCoreClock <= 100000000U) { rwsc_setting = 2U; } else if (configuredCoreClock <= 133000000U) { rwsc_setting = 3U; } else { rwsc_setting = 4U; } } else { if (configuredCoreClock <= 200000000U) { rwsc_setting = 5U; } else if (configuredCoreClock <= 233000000U) { rwsc_setting = 6U; } else if (configuredCoreClock <= 250000000U) { rwsc_setting = 7U; } else { rwsc_setting = 7U; } } FLASH->CTL &= ~FLASH_CTL_RWSL_MASK; FLASH->CTL &= ~FLASH_CTL_RWSC_MASK; FLASH->CTL |= FLASH_CTL_RWSC(rwsc_setting); } /* Clock stop ram section code */ #define MCU_STOP_SEC_RAMCODE #include "Mcu_MemMap.h" /* Clock start initialized section data */ #define MCU_START_SEC_VAR_INIT_UNSPECIFIED #include "Mcu_MemMap.h" typedef void (*SetFlashWaitStatesCallbackType)(void); SetFlashWaitStatesCallbackType SetFlashWaitStatesCallback = CodeInRam_SetFlashWaitStates; /* Set Flash Wait States callback */ /* Clock stop initialized section data */ #define MCU_STOP_SEC_VAR_INIT_UNSPECIFIED #include "Mcu_MemMap.h" /* Clock start section code */ #define MCU_START_SEC_CODE #include "Mcu_MemMap.h" void FLASH_SetFlashIWS(void) { SetFlashWaitStatesCallback(); } /* Clock stop section code */ #define MCU_STOP_SEC_CODE #include "Mcu_MemMap.h" #endif /*! @}*/ /******************************************************************************* * EOF ******************************************************************************/