/*================================================================================================== * 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 : 0.9.0 * Build Version : S32K3_RTD_0_9_0__ASR_REL_4_4_REV_0000_20210326 * * (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_Gate.c * @version 0.9.0 * * @brief CLOCK driver implementations. * @details CLOCK driver implementations. * * @addtogroup CLOCK_DRIVER Clock Ip Driver * @{ */ /** * @page misra_violations MISRA-C:2012 violations * * @section Clock_Ip_Gate_c_REF_1 * Violates MISRA 2012 Advisory Rule 20.1, #include directives should only be preceded by preprocessor * directives or comments. AUTOSAR imposes the specification of the sections in which certain parts * of the driver must be placed. * * @section Clock_Ip_Gate_c_REF_2 * Violates MISRA 2012 Advisory Rule 4.8, This file includes the definition * of types but does not use it. Header is common for all files * */ #include "Clock_Ip_Private.h" /*================================================================================================== SOURCE FILE VERSION INFORMATION ==================================================================================================*/ #define CLOCK_IP_GATE_VENDOR_ID_C 43 #define CLOCK_IP_GATE_AR_RELEASE_MAJOR_VERSION_C 4 #define CLOCK_IP_GATE_AR_RELEASE_MINOR_VERSION_C 4 #define CLOCK_IP_GATE_AR_RELEASE_REVISION_VERSION_C 0 #define CLOCK_IP_GATE_SW_MAJOR_VERSION_C 0 #define CLOCK_IP_GATE_SW_MINOR_VERSION_C 9 #define CLOCK_IP_GATE_SW_PATCH_VERSION_C 0 /*================================================================================================== * FILE VERSION CHECKS ==================================================================================================*/ /* Check if Clock_Ip_Gate.c file and Clock_Ip_Private.h file are of the same vendor */ #if (CLOCK_IP_GATE_VENDOR_ID_C != CLOCK_IP_PRIVATE_VENDOR_ID) #error "Clock_Ip_Gate.c and Clock_Ip_Private.h have different vendor ids" #endif /* Check if Clock_Ip_Gate.c file and Clock_Ip_Private.h file are of the same Autosar version */ #if ((CLOCK_IP_GATE_AR_RELEASE_MAJOR_VERSION_C != CLOCK_IP_PRIVATE_AR_RELEASE_MAJOR_VERSION) || \ (CLOCK_IP_GATE_AR_RELEASE_MINOR_VERSION_C != CLOCK_IP_PRIVATE_AR_RELEASE_MINOR_VERSION) || \ (CLOCK_IP_GATE_AR_RELEASE_REVISION_VERSION_C != CLOCK_IP_PRIVATE_AR_RELEASE_REVISION_VERSION) \ ) #error "AutoSar Version Numbers of Clock_Ip_Gate.c and Clock_Ip_Private.h are different" #endif /* Check if Clock_Ip_Gate.c file and Clock_Ip_Private.h file are of the same Software version */ #if ((CLOCK_IP_GATE_SW_MAJOR_VERSION_C != CLOCK_IP_PRIVATE_SW_MAJOR_VERSION) || \ (CLOCK_IP_GATE_SW_MINOR_VERSION_C != CLOCK_IP_PRIVATE_SW_MINOR_VERSION) || \ (CLOCK_IP_GATE_SW_PATCH_VERSION_C != CLOCK_IP_PRIVATE_SW_PATCH_VERSION) \ ) #error "Software Version Numbers of Clock_Ip_Gate.c and Clock_Ip_Private.h are different" #endif /* Clock start section code */ #define MCU_START_SEC_CODE /** * @violates @ref Clock_Ip_Gate_c_REF_1 #include directives should only be preceded by preprocessor * directives or comments. */ #include "Mcu_MemMap.h" static void ClockSetGateEmpty(Clock_Ip_GateConfigType const* config); static void ClockUpdateGateEmpty(Clock_Ip_NameType clockName, boolean gate); #ifdef MC_ME_PARTITION_COFB_ENABLE_REQUEST static void ClockSetGateMcMePartitionCollectionClockRequest(Clock_Ip_GateConfigType const* config); static void ClockUpdateGateMcMePartitionCollectionClockRequest(Clock_Ip_NameType clockName, boolean gate); #endif #ifdef SIM_LPO1K_ENABLE static void ClockSetSimLPO1KEnable(Clock_Ip_GateConfigType const* config); static void ClockUpdateSimLPO1KEnable(Clock_Ip_NameType clockName, boolean gate); #endif #ifdef SIM_LPO32K_ENABLE static void ClockSetSimLPO32KEnable(Clock_Ip_GateConfigType const* config); static void ClockUpdateSimLPO32KEnable(Clock_Ip_NameType clockName, boolean gate); #endif #ifdef SIM_CLKOUT_ENABLE static void ClockSetSimClkoutEnable(Clock_Ip_GateConfigType const* config); static void ClockUpdateSimClkoutEnable(Clock_Ip_NameType clockName, boolean gate); #endif #ifdef PCC_CGC_ENABLE static void ClockSetPccCgcEnable(Clock_Ip_GateConfigType const* config); static void ClockUpdatePccCgcEnable(Clock_Ip_NameType clockName, boolean gate); #endif #ifdef SIM_GATE static void ClockSetSimGate(Clock_Ip_GateConfigType const* config); static void ClockUpdateSimGate(Clock_Ip_NameType clockName, boolean gate); #endif #ifdef SIM_TRACE_ENABLE static void ClockSetSimTraceEnable(Clock_Ip_GateConfigType const* config); static void ClockUpdateSimTraceEnable(Clock_Ip_NameType clockName, boolean gate); #endif /* Clock stop section code */ #define MCU_STOP_SEC_CODE /** * @violates @ref Clock_Ip_Gate_c_REF_1 #include directives should only be preceded by preprocessor * directives or comments. */ #include "Mcu_MemMap.h" /* Clock start constant section data */ #define MCU_START_SEC_CONST_UNSPECIFIED /** * @violates @ref Clock_Ip_Gate_c_REF_1 #include directives should only be preceded by preprocessor * directives or comments. */ #include "Mcu_MemMap.h" const gateCallback gateCallbacks[GATE_CALLBACKS_COUNT] = { { ClockSetGateEmpty, /* Set */ ClockUpdateGateEmpty, /* Update */ }, #ifdef MC_ME_PARTITION_COFB_ENABLE_REQUEST { ClockSetGateMcMePartitionCollectionClockRequest, /* Set */ ClockUpdateGateMcMePartitionCollectionClockRequest, /* Update */ }, #endif #ifdef SIM_LPO1K_ENABLE { ClockSetSimLPO1KEnable, /* Set */ ClockUpdateSimLPO1KEnable, /* Update */ }, #endif #ifdef SIM_LPO32K_ENABLE { ClockSetSimLPO32KEnable, /* Set */ ClockUpdateSimLPO32KEnable, /* Update */ }, #endif #ifdef SIM_CLKOUT_ENABLE { ClockSetSimClkoutEnable, /* Set */ ClockUpdateSimClkoutEnable, /* Update */ }, #endif #ifdef PCC_CGC_ENABLE { ClockSetPccCgcEnable, /* Set */ ClockUpdatePccCgcEnable, /* Update */ }, #endif #ifdef SIM_GATE { ClockSetSimGate, /* Set */ ClockUpdateSimGate, /* Update */ }, #endif #ifdef SIM_TRACE_ENABLE { ClockSetSimTraceEnable, /* Set */ ClockUpdateSimTraceEnable, /* Update */ }, #endif }; /* Clock stop constant section data */ #define MCU_STOP_SEC_CONST_UNSPECIFIED /** * @violates @ref Clock_Ip_Gate_c_REF_1 #include directives should only be preceded by preprocessor * directives or comments. */ #include "Mcu_MemMap.h" /* Clock start section code */ #define MCU_START_SEC_CODE /** * @violates @ref Clock_Ip_Gate_c_REF_1 #include directives should only be preceded by preprocessor * directives or comments. */ #include "Mcu_MemMap.h" static void ClockSetGateEmpty(Clock_Ip_GateConfigType const* config) { (void)config; /* No implementation */ } static void ClockUpdateGateEmpty(Clock_Ip_NameType clockName, boolean gate) { (void)clockName; (void)gate; /* No implementation */ } #ifdef MC_ME_PARTITION_COFB_ENABLE_REQUEST static void ClockSetGateMcMePartitionCollectionClockRequest(Clock_Ip_GateConfigType const* config) { boolean TimeoutOccurred = FALSE; uint32 StartTime; uint32 ElapsedTime; uint32 TimeoutTicks; uint32 partition = clockFeatures[config->name][PARTITION_INDEX]; uint32 collection = clockFeatures[config->name][COLLECTION_INDEX]; uint32 enableRequest = clockFeatures[config->name][ENABLE_REQUEST]; if (config->enable != 0U) { if ((mcmeGetPartitions[partition]->PRTN_COFB_STAT[collection] & (1UL << enableRequest)) == 0U) { mcmeSetPartitions[partition]->PRTN_COFB_CLKEN[collection] |= (1UL << enableRequest); mcmeTriggerPartitions[partition]->PRTN_PCONF |= MC_ME_PRTN1_PCONF_PCE_MASK; mcmeTriggerPartitions[partition]->PRTN_PUPD |= MC_ME_PRTN1_PUPD_PCUD_MASK; McMeEnterKey(); /* Wait until clock gate is updated */ ClockStartTimeout(&StartTime, &ElapsedTime, &TimeoutTicks, CLOCK_TIMEOUT_VALUE_US); do { TimeoutOccurred = ClockTimeoutExpired(&StartTime, &ElapsedTime, TimeoutTicks); } while (((mcmeGetPartitions[partition]->PRTN_COFB_STAT[collection] & (1UL << enableRequest)) == 0U) && (FALSE == TimeoutOccurred)); /* timeout notification */ if (TRUE == TimeoutOccurred) { /* Report timeout error */ ReportClockErrors(CLOCK_IP_REPORT_TIMEOUT_ERROR, config->name); } } } else { if ((mcmeGetPartitions[partition]->PRTN_COFB_STAT[collection] & (1UL << enableRequest)) != 0U) { mcmeSetPartitions[partition]->PRTN_COFB_CLKEN[collection] &= (~(1UL << enableRequest)); mcmeTriggerPartitions[partition]->PRTN_PCONF |= MC_ME_PRTN1_PCONF_PCE_MASK; mcmeTriggerPartitions[partition]->PRTN_PUPD |= MC_ME_PRTN1_PUPD_PCUD_MASK; McMeEnterKey(); /* Wait until clock gate is updated */ ClockStartTimeout(&StartTime, &ElapsedTime, &TimeoutTicks, CLOCK_TIMEOUT_VALUE_US); do { TimeoutOccurred = ClockTimeoutExpired(&StartTime, &ElapsedTime, TimeoutTicks); } while (((mcmeGetPartitions[partition]->PRTN_COFB_STAT[collection] & (1UL << enableRequest)) != 0U) && (FALSE == TimeoutOccurred)); /* timeout notification */ if (TRUE == TimeoutOccurred) { /* Report timeout error */ ReportClockErrors(CLOCK_IP_REPORT_TIMEOUT_ERROR, config->name); } } } } static void ClockUpdateGateMcMePartitionCollectionClockRequest(Clock_Ip_NameType clockName, boolean gate) { Clock_Ip_GateConfigType config; config.name = clockName; if (gate == TRUE) { config.enable = 0U; } else { config.enable = 1U; } ClockSetGateMcMePartitionCollectionClockRequest(&config); } #endif #ifdef SIM_LPO1K_ENABLE static void ClockSetSimLPO1KEnable(Clock_Ip_GateConfigType const* config) { status_t result = STATUS_SUCCESS; uint32_t regValue; regValue = SIM->LPOCLKS; regValue &= SIM_LPOCLKS_LPO1KCLKEN_MASK; regValue |= (((config->enable) ? 1UL : 0UL) << SIM_LPOCLKS_LPO1KCLKEN_SHIFT); SIM->LPOCLKS = regValue; } static void ClockUpdateSimLPO1KEnable(Clock_Ip_NameType clockName, boolean gate) { Clock_Ip_GateConfigType config; config.name = clockName; if (gate == TRUE) { config.enable = 0U; } else { config.enable = 1U; } ClockSetSimLPO1KEnable(&config); } #endif #ifdef SIM_LPO32K_ENABLE static void ClockSetSimLPO32KEnable(Clock_Ip_GateConfigType const* config) { status_t result = STATUS_SUCCESS; uint32_t regValue; regValue = SIM->LPOCLKS; regValue &= SIM_LPOCLKS_LPO32KCLKEN_MASK; regValue |= (((config->enable) ? 1UL : 0UL) << SIM_LPOCLKS_LPO32KCLKEN_SHIFT); SIM->LPOCLKS = regValue; return result; } static void ClockUpdateSimLPO32KEnable(Clock_Ip_NameType clockName, boolean gate) { Clock_Ip_GateConfigType config; config.name = clockName; if (gate == TRUE) { config.enable = 0U; } else { config.enable = 1U; } ClockSetSimLPO32KEnable(&config); } #endif #ifdef SIM_CLKOUT_ENABLE static void ClockSetSimClkoutEnable(Clock_Ip_GateConfigType const* config) { status_t result = STATUS_SUCCESS; uint32_t regValue; regValue = SIM->CHIPCTL; regValue &= SIM_CHIPCTL_CLKOUTEN_MASK; regValue |= (((config->enable) ? 1UL : 0UL) << SIM_CHIPCTL_CLKOUTEN_SHIFT); SIM->CHIPCTL = regValue; } static void ClockUpdateSimClkoutEnable(Clock_Ip_NameType clockName, boolean gate) { Clock_Ip_GateConfigType config; config.name = clockName; if (gate == TRUE) { config.enable = 0U; } else { config.enable = 1U; } ClockSetSimClkoutEnable(&config); } #endif #ifdef PCC_CGC_ENABLE static void ClockSetPccCgcEnable(Clock_Ip_GateConfigType const* config) { status_t result = STATUS_SUCCESS; uint32_t regValue; regValue = PCC->PCCn[clockFeatures[config->name][PCC_INDEX]]; regValue &= PCC_PCCn_PCS_MASK; regValue |= (((config->enable) ? 1UL : 0UL) << PCC_PCCn_PCS_SHIFT); PCC->PCCn[clockFeatures[config->name][PCC_INDEX]] = regValue; } static void ClockSetPccCgcEnable(Clock_Ip_NameType clockName, boolean gate) { Clock_Ip_GateConfigType config; config.name = clockName; if (gate == TRUE) { config.enable = 0U; } else { config.enable = 1U; } ClockUpdatePccCgcEnable(&config); } #endif #ifdef SIM_GATE #define SIM_PLATCGC_CGC_SHIFT(x) (x) #define SIM_PLATCGC_CGC_MASK(x) (1U << x) static void ClockSetSimGate(Clock_Ip_GateConfigType const* config) { uint32_t enable = config->enable ? 1UL : 0UL; uint32_t gateIndex = clockFeatures[config->name][GATE_INDEX]; uint32_t regValue = (uint32_t)SIM->PLATCGC; regValue &= (uint32_t)(~(SIM_PLATCGC_CGC_MASK(gateIndex))); regValue |= enable << SIM_PLATCGC_CGC_SHIFT(gateIndex); SIM->PLATCGC = (uint32_t)regValue; return STATUS_SUCCESS; } static void ClockUpdateSimGate(Clock_Ip_NameType clockName, boolean gate) { Clock_Ip_GateConfigType config; config.name = clockName; if (gate == TRUE) { config.enable = 0U; } else { config.enable = 1U; } ClockSetSimGate(&config); } #endif #ifdef SIM_TRACE_ENABLE static void ClockSetSimTraceEnable(Clock_Ip_GateConfigType const* config) { status_t result = STATUS_SUCCESS; uint32_t regValue; regValue = SIM->CLKDIV4; if (config->enable) { regValue |= (SIM_CLKDIV4_TRACEDIVEN_MASK); } else { regValue &= ~(SIM_CLKDIV4_TRACEDIVEN_MASK); } } static void ClockUpdateSimTraceEnable(Clock_Ip_NameType clockName, boolean gate) { Clock_Ip_GateConfigType config; config.name = clockName; if (gate == TRUE) { config.enable = 0U; } else { config.enable = 1U; } ClockSetSimTraceEnable(&config); } #endif /* Clock stop section code */ #define MCU_STOP_SEC_CODE /** * @violates @ref Clock_Ip_Gate_c_REF_1 #include directives should only be preceded by preprocessor * directives or comments. */ #include "Mcu_MemMap.h" /*! @}*/ /******************************************************************************* * EOF ******************************************************************************/