ADM/GW/RTD/src/Clock_Ip.c
2024-08-08 10:00:15 +09:00

817 lines
31 KiB
C

/*==================================================================================================
* 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.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_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_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
*
* @section Clock_Ip_c_REF_3
* Violates MISRA 2012 Advisory Directive 4.9, A function should be used in preference to a function-like macro where they are interchangeable.
* Function like macro are used to reduce code complexity
*
* @section Clock_Ip_c_REF_4
* Violates MISRA 2012 Advisory Rule 12.3, The comma operator should not be used.
* The comma is used to abstract the trusted call function and to determine when the return into user mode is needed.
*
* @section Clock_Ip_c_REF_5
* Violates MISRA 2012 Advisory Rule 8.7, Functions and objects should not be defined with external linkage if
* they are referenced in only one translation unit.
* These functions represent the API of the driver. External linkage is needed to "export" the API.
*/
#include "Clock_Ip_Private.h"
#include "OsIf.h"
/*==================================================================================================
SOURCE FILE VERSION INFORMATION
==================================================================================================*/
#define CLOCK_IP_VENDOR_ID_C 43
#define CLOCK_IP_AR_RELEASE_MAJOR_VERSION_C 4
#define CLOCK_IP_AR_RELEASE_MINOR_VERSION_C 4
#define CLOCK_IP_AR_RELEASE_REVISION_VERSION_C 0
#define CLOCK_IP_SW_MAJOR_VERSION_C 0
#define CLOCK_IP_SW_MINOR_VERSION_C 9
#define CLOCK_IP_SW_PATCH_VERSION_C 0
/*==================================================================================================
* FILE VERSION CHECKS
==================================================================================================*/
/* Check if Clock_Ip.c file and Clock_Ip_Private.h file are of the same vendor */
#if (CLOCK_IP_VENDOR_ID_C != CLOCK_IP_PRIVATE_VENDOR_ID)
#error "Clock_Ip.c and Clock_Ip_Private.h have different vendor ids"
#endif
/* Check if Clock_Ip.c file and Clock_Ip_Private.h file are of the same Autosar version */
#if ((CLOCK_IP_AR_RELEASE_MAJOR_VERSION_C != CLOCK_IP_PRIVATE_AR_RELEASE_MAJOR_VERSION) || \
(CLOCK_IP_AR_RELEASE_MINOR_VERSION_C != CLOCK_IP_PRIVATE_AR_RELEASE_MINOR_VERSION) || \
(CLOCK_IP_AR_RELEASE_REVISION_VERSION_C != CLOCK_IP_PRIVATE_AR_RELEASE_REVISION_VERSION) \
)
#error "AutoSar Version Numbers of Clock_Ip.c and Clock_Ip_Private.h are different"
#endif
/* Check if Clock_Ip.c file and Clock_Ip_Private.h file are of the same Software version */
#if ((CLOCK_IP_SW_MAJOR_VERSION_C != CLOCK_IP_PRIVATE_SW_MAJOR_VERSION) || \
(CLOCK_IP_SW_MINOR_VERSION_C != CLOCK_IP_PRIVATE_SW_MINOR_VERSION) || \
(CLOCK_IP_SW_PATCH_VERSION_C != CLOCK_IP_PRIVATE_SW_PATCH_VERSION) \
)
#error "Software Version Numbers of Clock_Ip.c and Clock_Ip_Private.h are different"
#endif
#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
/* Check if Clock_Ip.c file and OsIf.h file are of the same Autosar version */
#if ((CLOCK_IP_AR_RELEASE_MAJOR_VERSION_C != OSIF_AR_RELEASE_MAJOR_VERSION) || \
(CLOCK_IP_AR_RELEASE_MINOR_VERSION_C != OSIF_AR_RELEASE_MINOR_VERSION))
#error "AutoSar Version Numbers of Clock_Ip.c and OsIf.h are different"
#endif
#endif
/*******************************************************************************
* Definitions
******************************************************************************/
#define MCU_START_SEC_CODE
/**
* @violates @ref Clock_Ip_c_REF_1 #include directives should only be preceded by preprocessor
* directives or comments.
*/
#include "Mcu_MemMap.h"
static void ClockNotificatonsEmptyCallback(Clock_Ip_ClockNotificationType notification, Clock_Ip_NameType clockName);
static void Clock_Ip_Sleep(void);
#define MCU_STOP_SEC_CODE
/**
* @violates @ref Clock_Ip_c_REF_1 #include directives should only be preceded by preprocessor
* directives or comments.
*/
#include "Mcu_MemMap.h"
/* Clock start initialized section data */
#define MCU_START_SEC_VAR_INIT_BOOLEAN
/**
* @violates @ref Clock_Ip_c_REF_1 #include directives should only be preceded by preprocessor
* directives or comments.
*/
#include "Mcu_MemMap.h"
static boolean clockTreeIsConsumingPll = FALSE; /* Clock tree is using a PLL output */
/* Clock stop initialized section data */
#define MCU_STOP_SEC_VAR_INIT_BOOLEAN
/**
* @violates @ref Clock_Ip_c_REF_1 #include directives should only be preceded by preprocessor
* directives or comments.
*/
#include "Mcu_MemMap.h"
#define MCU_START_SEC_VAR_INIT_UNSPECIFIED
/**
* @violates @ref Clock_Ip_c_REF_1 #include directives should only be preceded by preprocessor
* directives or comments.
*/
#include "Mcu_MemMap.h"
static Clock_Ip_NotificationsCallbackType clockNotificationsCallback = ClockNotificatonsEmptyCallback; /* Clock Report Error Callback */
const Clock_Ip_ClockConfigType *clockConfig = NULL_PTR; /* Reference to the current clock configuration */
/* Clock stop initialized section data */
#define MCU_STOP_SEC_VAR_INIT_UNSPECIFIED
/**
* @violates @ref Clock_Ip_c_REF_1 #include directives should only be preceded by preprocessor
* directives or comments.
*/
#include "Mcu_MemMap.h"
/* Clock start uninitialized section data */
#define MCU_START_SEC_VAR_NO_INIT_8
/**
* @violates @ref Clock_Ip_c_REF_1 #include directives should only be preceded by preprocessor
* directives or comments.
*/
#include "Mcu_MemMap.h"
static uint8 ClockCalcFreqCallIdx;
/* Clock stop uninitialized section data */
#define MCU_STOP_SEC_VAR_NO_INIT_8
/**
* @violates @ref Clock_Ip_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_c_REF_1 #include directives should only be preceded by preprocessor
* directives or comments.
*/
#include "Mcu_MemMap.h"
/*FUNCTION******************************************************************************
*
* Function Name : Clock_Ip_Init
* Description : This function configures all clocks according to a clock configuration.
*
* @implements Clock_Ip_Init_Activity
* END**********************************************************************************/
Clock_Ip_StatusType Clock_Ip_Init(Clock_Ip_ClockConfigType const * config)
{
Clock_Ip_StatusType clockStatus = CLOCK_IP_ERROR;
Clock_Ip_PllStatusType pllStatus;
(void)consumerClockCallbacks;
(void)xoscCallbackIndex;
(void)extOscCallbacks;
(void)ircoscCallbackIndex;
(void)intOscCallbacks;
(void)pcfsCallbackIndex;
(void)pcfsCallbacks;
(void)dividerCallbackIndex;
(void)dividerCallbacks;
(void)calcFreqCallbacks;
(void)CLOCK_MODULE_INSTANCE;
(void)CLOCK_CALLBACK;
(void)INTERFACE_CLOCK;
(void)SELECTOR_INDEX;
(void)PCFS_INSTANCE;
(void)DIVIDER_INDEX;
(void)PCTL_INDEX;
(void)PCC_INDEX;
(void)PARTITION_INDEX;
(void)COLLECTION_INDEX;
(void)PCFS_HW_INDEX;
(void)ENABLE_REQUEST;
(void)PCFS_SW_INDEX;
(void)TRIGGER_FEATURE;
#if (defined(CLOCK_IP_ENABLE_USER_MODE_SUPPORT))
#if (STD_ON == CLOCK_IP_ENABLE_USER_MODE_SUPPORT)
/* Set user access allowed for Clock */
Clock_Ip_SetUserAccessAllowed();
#endif
#endif
CLOCK_DEV_ASSERT(NULL_PTR != config);
Clock_Ip_InitClock(config);
if (clockTreeIsConsumingPll)
{
pllStatus = Clock_Ip_GetPllStatus();
if (CLOCK_IP_PLL_LOCKED == pllStatus)
{
Clock_Ip_DistributePll();
clockStatus = CLOCK_IP_SUCCESS;
}
}
else
{
clockStatus = CLOCK_IP_SUCCESS;
}
return clockStatus;
}
/*FUNCTION******************************************************************************
*
* Function Name : Clock_Ip_InitClock
* Description : This function configures all clocks according to a clock configuration.
*
* @implements Clock_Ip_InitClock_Activity
* END**********************************************************************************/
void Clock_Ip_InitClock(Clock_Ip_ClockConfigType const * config)
{
uint32 callbackIndex;
uint32 i;
ClockCalcFreqCallIdx = 0U;
CLOCK_DEV_ASSERT(NULL_PTR != config);
/* Clear all the settings for CMU0/1/2... */
/* In case one clock configuration has the CMU disabled, then need to make the transition to
reset state of CMU modules. */
if (NULL_PTR != clockConfig)
{
for (i = 0U; i < config->cmusCount; i++) /* Reset all clock monitor units from previous configuration. */
{
callbackIndex = cmuCallbackIndex[clockFeatures[config->cmus[i].name][CLOCK_CALLBACK]];
cmuCallbacks[callbackIndex].Reset(&config->cmus[i]);
}
}
/* Save the current clock configuration to be used by "Clock_Ip_DistributePllClock". */
clockConfig = config;
/* Platform specific initialization:
* DFS reset, FIRC_CLK configuration etc. */
SpecificPlatformInitClock(config);
/*********************************************************************
*** Ramp down to safe configuration. Reset elements from clock tree:
*** selectors, fractional dividers, plls and xoscs
***********************************************************************/
for (i = 0U; i < config->selectorsCount; i++) /* Ramp down all selectors from configuration to SAFE_CLOCK */
{
callbackIndex = selectorCallbackIndex[clockFeatures[config->selectors[i].name][CLOCK_CALLBACK]];
selectorCallbacks[callbackIndex].Reset(&config->selectors[i]);
}
for (i = 0U; i < config->fracDivsCount; i++) /* Put in reset state all fractional dividers from configuration */
{
callbackIndex = fractional_dividerCallbackIndex[clockFeatures[config->fracDivs[i].name][CLOCK_CALLBACK]];
fracDivCallbacks[callbackIndex].Reset(&config->fracDivs[i]);
}
for (i = 0U; i < config->pllsCount; i++) /* Power down all plls from configuration */
{
callbackIndex = pllCallbackIndex[clockFeatures[config->plls[i].name][CLOCK_CALLBACK]];
pllCallbacks[callbackIndex].Reset(&config->plls[i]);
}
for (i = 0U; i < config->xoscsCount; i++) /* Power down all xoscs from configuration */
{
callbackIndex = xoscCallbackIndex[clockFeatures[config->xoscs[i].name][CLOCK_CALLBACK]];
extOscCallbacks[callbackIndex].Reset(&config->xoscs[i]);
}
/*******************************************************
*** Load the new configuration. Selectors that might
*** be clocked from PLLs/XOCs shouldn't be configured.
*******************************************************/
for (i = 0U; i < config->ircoscsCount; i++) /* Set internal oscillators from configuration */
{
callbackIndex = ircoscCallbackIndex[clockFeatures[config->ircoscs[i].name][CLOCK_CALLBACK]];
intOscCallbacks[callbackIndex].Set(&config->ircoscs[i]);
}
for (i = 0U; i < config->xoscsCount; i++) /* Configure all xoscs from configuration */
{
callbackIndex = xoscCallbackIndex[clockFeatures[config->xoscs[i].name][CLOCK_CALLBACK]];
extOscCallbacks[callbackIndex].Set(&config->xoscs[i]);
}
/* Complete the process frequency calculations */
Clock_Ip_Sleep();
/* Configure the PCFS */
for (i = 0U; i < config->pcfsCount; i++) /* Configure all progressive frequency switching clocks from configuration */
{
callbackIndex = pcfsCallbackIndex[clockFeatures[config->pcfs[i].name][CLOCK_CALLBACK]];
pcfsCallbacks[callbackIndex].Set(&config->pcfs[i]);
}
/* Configure the clock divider triggers that are under MCU control */
for (i = 0U; i < config->dividerTriggersCount; i++) /* Set divider triggers from configuration. */
{
callbackIndex = dividertriggerCallbackIndex[clockFeatures[config->dividerTriggers[i].name][CLOCK_CALLBACK]];
dividerTriggerCallbacks[callbackIndex].Configure(&config->dividerTriggers[i]);
}
/* Configure the clock dividers that are under MCU control */
for (i = 0U; i < config->dividersCount; i++) /* Set dividers from configuration. */
{
callbackIndex = dividerCallbackIndex[clockFeatures[config->dividers[i].name][CLOCK_CALLBACK]];
dividerCallbacks[callbackIndex].Set(&config->dividers[i]);
}
/* Trigger update for all divider trigger that are under MCU control */
for (i = 0U; i < config->dividerTriggersCount; i++) /* Set divider triggers from configuration. */
{
callbackIndex = dividertriggerCallbackIndex[clockFeatures[config->dividerTriggers[i].name][CLOCK_CALLBACK]];
dividerTriggerCallbacks[callbackIndex].TriggerUpdate(&config->dividerTriggers[i]);
}
/* Configure PLL clock generators */
for (i = 0U; i < config->pllsCount; i++) /* Configure all plls from configuration asynchronously. Do not wait. */
{
callbackIndex = pllCallbackIndex[clockFeatures[config->plls[i].name][CLOCK_CALLBACK]];
pllCallbacks[callbackIndex].Set(&config->plls[i]);
}
/* Configure fractional dividers */
/* Note: The DFS configuration might actually need to be done after we
* know that the PLLs are all locked in "Clock_Ip_GetPllStatus". */
for (i = 0U; i < config->fracDivsCount; i++) /* Configure all fractional dividers from configuration asynchronously. Do not wait. */
{
callbackIndex = fractional_dividerCallbackIndex[clockFeatures[config->fracDivs[i].name][CLOCK_CALLBACK]];
fracDivCallbacks[callbackIndex].Set(&config->fracDivs[i]);
}
#ifdef FEATURE_CLOCK_IP_HAS_RAM_WAIT_STATES
/* The entry point of the flash and RAM controllers configuration. */
clockNotificationsCallback(CLOCK_IP_RAM_MEMORY_CONFIG_ENTRY_POINT, RESERVED_CLK);
SetRamWaitStates();
/* The exit point of the flash and RAM controllers configuration. */
clockNotificationsCallback(CLOCK_IP_RAM_MEMORY_CONFIG_EXIT_POINT, RESERVED_CLK);
#endif
#ifdef FEATURE_CLOCK_IP_HAS_FLASH_WAIT_STATES
/* The entry point of the flash and RAM controllers configuration. */
clockNotificationsCallback(CLOCK_IP_FLASH_MEMORY_CONFIG_ENTRY_POINT, RESERVED_CLK);
SetFlashWaitStates();
/* The exit point of the flash and RAM controllers configuration. */
clockNotificationsCallback(CLOCK_IP_FLASH_MEMORY_CONFIG_EXIT_POINT, RESERVED_CLK);
#endif
clockTreeIsConsumingPll = FALSE; /* Check if the clock tree is using a PLL output */
/* Switch the clock multiplexers under MCU control to the configured source clocks */
/* Note: if the configured source clock of a ClockMux is the output clock of a PLL/DFS,
* the configuration will be skipped and the respective ClockMux will be switched in
* the "Clock_Ip_DistributePllClock" function instead, when the source clock will have
* stabilized already. */
for (i = 0U; i < config->selectorsCount; i++) /* Set only if selected inputs are not clocked from XOSCs or PLLs */
{
if ((IRCOSC_TYPE == clockName_sourceType[config->selectors[i].value])) {
callbackIndex = selectorCallbackIndex[clockFeatures[config->selectors[i].name][CLOCK_CALLBACK]];
selectorCallbacks[callbackIndex].Set(&config->selectors[i]);
}
else
{
/* At least one mux is consuming pll */
clockTreeIsConsumingPll = TRUE;
}
}
for (i = 0U; i < config->gatesCount; i++) /* Set clock gates that are under clock control. */
{
callbackIndex = gateCallbackIndex[clockFeatures[config->gates[i].name][CLOCK_CALLBACK]];
gateCallbacks[callbackIndex].Set(&config->gates[i]);
}
/* Check if the clock tree is using a PLL output */
if ( FALSE == clockTreeIsConsumingPll )
{
#if CLOCK_SPECIFIC_PERIPH_NO > 0U
/* Configure the specific modules like eMios */
SpecificPeripheralClockInitialization(&config->specificPeriphalConfiguration);
#endif
/* Set the Clock Monitoring Units ( CMU0 .. n ). */
for (i = 0U; i < config->cmusCount; i++)
{
callbackIndex = cmuCallbackIndex[clockFeatures[config->cmus[i].name][CLOCK_CALLBACK]];
cmuCallbacks[callbackIndex].Set(&config->cmus[i]);
}
}
else
{
/* The clock tree is using at least one PLL/DFS output clock as source. */
/* The user must wait until the PLLs and DFSs are locked by polling Clock_Ip_GetPllStatus */
/* and then call "Clock_Ip_DistributePllClock" */
}
/* When mcu clock distribution is updated or power mode is changed, frequencies must be updated. */
UpdateFrequencies(RUN_MODE);
}
/*FUNCTION******************************************************************************
*
* Function Name : Clock_Ip_GetPllStatus
* Description : This function configures all clocks according to a clock configuration.
* If no configuration is received, no change will be processed in HW and clock driver
* will calculate frequencies only.
*
* @implements Clock_Ip_GetPllStatus_Activity
* END**********************************************************************************/
Clock_Ip_PllStatusType Clock_Ip_GetPllStatus(void)
{
Clock_Ip_PllStatusType retValue = CLOCK_IP_PLL_STATUS_UNDEFINED;
clock_pll_status_t pllStatus;
#ifdef CLOCK_IP_DFS_SUPPORT
#if (STD_ON == CLOCK_IP_DFS_SUPPORT)
clock_dfs_status_t dfsStatus;
#endif
#endif
uint32 i, callbackIndex;
for (i = 0U; i < NUMBER_OF_HARDWARE_PLL; i++)
{
callbackIndex = pllCallbackIndex[clockFeatures[HwPllName[i]][CLOCK_CALLBACK]];
pllStatus = pllCallbacks[callbackIndex].Complete(HwPllName[i]);
if (STATUS_PLL_UNLOCKED == pllStatus)
{
retValue = CLOCK_IP_PLL_UNLOCKED;
break;
}
else
{
if (STATUS_PLL_LOCKED == pllStatus)
{
retValue = CLOCK_IP_PLL_LOCKED;
}
}
}
#ifdef CLOCK_IP_DFS_SUPPORT
#if (STD_ON == CLOCK_IP_DFS_SUPPORT)
if (CLOCK_IP_PLL_LOCKED == retValue)
{
for (i = 0U; i < NUMBER_OF_HARDWARE_DFS; i++)
{
callbackIndex = fractional_dividerCallbackIndex[clockFeatures[HwDfsName[i]][CLOCK_CALLBACK]];
dfsStatus = fracDivCallbacks[callbackIndex].Complete(HwDfsName[i]);
if (STATUS_DFS_UNLOCKED == dfsStatus)
{
retValue = CLOCK_IP_PLL_UNLOCKED;
break;
}
}
}
#endif
#endif
return retValue;
}
/*FUNCTION******************************************************************************
*
* Function Name : Clock_Ip_DistributePll
* Description : Function completes the PLL configuration and then activates the PLL clock to Mcu
* The function will not distribute the PLL clock if the driver state does not allow it, or the PLL is not stable.
*
* @implements Clock_Ip_DistributePll_Activity
* END**********************************************************************************/
void Clock_Ip_DistributePll(void)
{
uint32 i, callbackIndex;
CLOCK_DEV_ASSERT(NULL_PTR != clockConfig);
/* 'clockConfig' is set by Clock_Ip_InitClock().
* It doesn't make sense to call PLL distribution without clock initialization. */
if (NULL_PTR != clockConfig)
{
for (i = 0U; i < clockConfig->selectorsCount; i++) /* Set only if selected inputs are clocked from XOSCs or PLLs */
{
if (IRCOSC_TYPE != clockName_sourceType[clockConfig->selectors[i].value]) {
callbackIndex = selectorCallbackIndex[clockFeatures[clockConfig->selectors[i].name][CLOCK_CALLBACK]];
selectorCallbacks[callbackIndex].Set(&clockConfig->selectors[i]);
}
}
/* In the case of PLL is enabled but PLL clock source is not used by any clock Mux.
So, no need to re-configure for CMUs, because they are configured by Clock_Ip_InitClock */
/* Check if the clock tree is using a PLL output */
if ( clockTreeIsConsumingPll )
{
#if CLOCK_SPECIFIC_PERIPH_NO > 0U
SpecificPeripheralClockInitialization(&clockConfig->specificPeriphalConfiguration);
#endif
/* Enable CMU if used */
for (i = 0U; i < clockConfig->cmusCount; i++)
{
callbackIndex = cmuCallbackIndex[clockFeatures[clockConfig->cmus[i].name][CLOCK_CALLBACK]];
cmuCallbacks[callbackIndex].Set(&clockConfig->cmus[i]);
}
}
}
/* When mcu clock distribution is updated or
* power mode is changed, frequencies must be updated.
*/
UpdateFrequencies(RUN_MODE);
}
/*FUNCTION******************************************************************************
*
* Function Name : Clock_Ip_DisableClockMonitor
* Description : Disables a clock monitor.
*
* @implements Clock_Ip_DisableClockMonitor_Activity
* END**********************************************************************************/
void Clock_Ip_DisableClockMonitor(Clock_Ip_NameType clockName)
{
uint32 callbackIndex;
callbackIndex = cmuCallbackIndex[clockFeatures[clockName][CLOCK_CALLBACK]];
cmuCallbacks[callbackIndex].Disable(clockName);
}
/*FUNCTION******************************************************************************
*
* Function Name : Clock_Ip_GetClockMonitorStatus
* Description : Returns the clock monitor status.
*
* @implements Clock_Ip_GetClockMonitorStatus_Activity
* END**********************************************************************************/
Clock_Ip_CmuStatusType Clock_Ip_GetClockMonitorStatus(Clock_Ip_NameType clockName)
{
uint32 callbackIndex;
callbackIndex = cmuCallbackIndex[clockFeatures[clockName][CLOCK_CALLBACK]];
return cmuCallbacks[callbackIndex].GetStatus(clockName);
}
/*FUNCTION******************************************************************************
*
* Function Name : Clock_Ip_ClearClockMonitorStatus
* Description : Clears status flags for a monitor clock.
*
* @implements Clock_Ip_ClearClockMonitorStatus_Activity
* END**********************************************************************************/
void Clock_Ip_ClearClockMonitorStatus(Clock_Ip_NameType clockName)
{
uint32 callbackIndex;
callbackIndex = cmuCallbackIndex[clockFeatures[clockName][CLOCK_CALLBACK]];
cmuCallbacks[callbackIndex].Clear(clockName);
}
/*FUNCTION******************************************************************************
*
* Function Name : Clock_Ip_PowerModeChangeNotification
* Description : Notifies clock driver when a power mode is changed.
*
* @implements Clock_Ip_PowerModeChangeNotification_Activity
* END**********************************************************************************/
void Clock_Ip_PowerModeChangeNotification(power_modes_t powerMode,power_notification_t notification)
{
(void)notification;
UpdateFrequencies(powerMode);
}
/*FUNCTION******************************************************************************
*
* Function Name : Clock_Ip_InstallNotificationsCallback
* Description : This function installs a callback for clock notifications.
*
* @implements Clock_Ip_InstallNotificationsCallback_Activity
* END**********************************************************************************/
void Clock_Ip_InstallNotificationsCallback(Clock_Ip_NotificationsCallbackType callback)
{
CLOCK_DEV_ASSERT(NULL_PTR != callback);
clockNotificationsCallback = callback;
}
/*FUNCTION******************************************************************************
*
* Function Name : Clock_Ip_DisableModuleClock
* Description : Disables clock for a peripheral.
*
* @implements Clock_Ip_DisableModuleClock_Activity
* END**********************************************************************************/
void Clock_Ip_DisableModuleClock(Clock_Ip_NameType clockName)
{
uint32 callbackIndex;
callbackIndex = gateCallbackIndex[clockFeatures[clockName][CLOCK_CALLBACK]];
gateCallbacks[callbackIndex].Update(clockName,TRUE);
}
/*FUNCTION******************************************************************************
*
* Function Name : Clock_Ip_EnableModuleClock
* Description : Enable clock for a peripheral.
*
* @implements Clock_Ip_EnableModuleClock_Activity
* END**********************************************************************************/
void Clock_Ip_EnableModuleClock(Clock_Ip_NameType clockName)
{
uint32 callbackIndex;
callbackIndex = gateCallbackIndex[clockFeatures[clockName][CLOCK_CALLBACK]];
gateCallbacks[callbackIndex].Update(clockName,FALSE);
}
/*FUNCTION**********************************************************************
*
* Function Name : Clock_Ip_GetClockFrequency
* Description : This function returns the frequency of a given clock
*
* @implements Clock_Ip_GetClockFrequency_Activity
* END**************************************************************************/
uint32 Clock_Ip_GetClockFrequency(Clock_Ip_NameType clockName)
{
uint32 frequency;
#if (defined(CLOCK_IP_DEV_ERROR_DETECT))
#if (CLOCK_IP_DEV_ERROR_DETECT == STD_ON)
CLOCK_DEV_ASSERT((((uint32)clockName) < ((uint32)CLOCK_NAMES_NO)) && (THE_LAST_PRODUCER_CLK != clockName));
#endif
#endif
if(((uint32)clockName) > ((uint32)THE_LAST_PRODUCER_CLK))
{
frequency = consumerClockCallbacks[((uint32)clockName) - ((uint32)THE_LAST_PRODUCER_CLK) - (uint32)1U]();
}
else
{
frequency = GetProducerClockFreq(clockName);
}
return frequency;
}
/*FUNCTION**********************************************************************
*
* Function Name : Clock_Ip_Sleep.
* Description : Complete the process frequency calculations
*
*END**************************************************************************/
static void Clock_Ip_Sleep(void)
{
while(ClockCalcFreqCallIdx < (CALC_FREQ_CALLBACKS_NO-1U))
{
calcFreqCallbacks[ClockCalcFreqCallIdx]();
ClockCalcFreqCallIdx++;
}
}
/*FUNCTION**********************************************************************
*
* Function Name : Clock_Ip_TimeDelay.
* Description : TimeDelay. Process frequency calculations on behalf of TimeDelay function.
*
*END**************************************************************************/
void Clock_Ip_TimeDelay(void)
{
calcFreqCallbacks[ClockCalcFreqCallIdx]();
if (ClockCalcFreqCallIdx < (CALC_FREQ_CALLBACKS_NO-1U))
{
ClockCalcFreqCallIdx++;
}
}
#if (defined(CLOCK_IP_ENABLE_USER_MODE_SUPPORT))
#if (STD_ON == CLOCK_IP_ENABLE_USER_MODE_SUPPORT)
/*FUNCTION**********************************************************************
*
* Function Name : Clock_Ip_SetUserAccessAllowed.
* Description : Set user access allowed.
*
*END**************************************************************************/
void Clock_Ip_SetUserAccessAllowed(void)
{
/**
* @violates @ref Clock_Ip_c_REF_3 A function should be used in preference to a function-like macro where they are interchangeable.
*/
/**
* @violates @ref Clock_Ip_c_REF_4 The comma is used to abstract the trusted call function and to determine when the return into user mode is needed.
*/
OsIf_Trusted_Call(SpecificSetUserAccessAllowed);
}
#endif
#endif
/*FUNCTION**********************************************************************
*
* Function Name : ClockNotificatonsEmptyCallback.
* Description : Notification clock call back.
*
*END**************************************************************************/
static void ClockNotificatonsEmptyCallback(Clock_Ip_ClockNotificationType notification, Clock_Ip_NameType clockName)
{
/* No implementation */
(void)notification;
(void)clockName;
}
/*FUNCTION**********************************************************************
*
* Function Name : ReportClockErrors
* Description : Report clock error
*
*END**************************************************************************/
void ReportClockErrors(Clock_Ip_ClockNotificationType error, Clock_Ip_NameType clockName)
{
clockNotificationsCallback(error,clockName);
}
/*FUNCTION**********************************************************************
*
* Function Name : ClockStartTimeout
* Description : Checks for timeout condition
*
*END**************************************************************************/
void ClockStartTimeout(uint32 *startTimeOut,
uint32 *elapsedTimeOut,
uint32 *timeoutTicksOut,
uint32 timeoutUs)
{
*startTimeOut = OsIf_GetCounter(CLOCK_TIMEOUT_TYPE);
*elapsedTimeOut = 0U;
*timeoutTicksOut = OsIf_MicrosToTicks(timeoutUs, CLOCK_TIMEOUT_TYPE);
}
/*FUNCTION**********************************************************************
*
* Function Name : ClockTimeoutExpired
* Description : Checks for timeout expiration condition
*
*END**************************************************************************/
boolean ClockTimeoutExpired(uint32 *startTimeInOut,
uint32 *elapsedTimeInOut,
uint32 TimeoutTicks)
{
*elapsedTimeInOut += OsIf_GetElapsed(startTimeInOut, CLOCK_TIMEOUT_TYPE);
return ((*elapsedTimeInOut >= TimeoutTicks)? TRUE : FALSE);
}
/* Clock stop section code */
#define MCU_STOP_SEC_CODE
/**
* @violates @ref Clock_Ip_c_REF_1 #include directives should only be preceded by preprocessor
* directives or comments.
*/
#include "Mcu_MemMap.h"
/*! @}*/
/*******************************************************************************
* EOF
******************************************************************************/