/*================================================================================================== * Project : RTD AUTOSAR 4.4 * Platform : CORTEXM * Peripheral : ADC * 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 * * @addtogroup adc_ip Adc IPL * @{ */ #include "Adc_Ip.h" #include "Adc_Ip_HwAccess.h" #include "SchM_Adc.h" #include "OsIf.h" #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) #include "Devassert.h" #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ #if (STD_ON == ADC_IP_ENABLE_USER_MODE_SUPPORT) /* USER_MODE_REG_PROT_ENABLED is defined for Base sanity check in RegLockMacros.h */ #define USER_MODE_REG_PROT_ENABLED (ADC_IP_ENABLE_USER_MODE_SUPPORT) #include "RegLockMacros.h" #endif /* (STD_ON == ADC_IP_ENABLE_USER_MODE_SUPPORT) */ /******************************************************************************* * Source file version information ******************************************************************************/ #define ADC_IP_VENDOR_ID_C 43 #define ADC_IP_AR_RELEASE_MAJOR_VERSION_C 4 #define ADC_IP_AR_RELEASE_MINOR_VERSION_C 4 #define ADC_IP_AR_RELEASE_REVISION_VERSION_C 0 #define ADC_IP_SW_MAJOR_VERSION_C 1 #define ADC_IP_SW_MINOR_VERSION_C 0 #define ADC_IP_SW_PATCH_VERSION_C 0 /******************************************************************************* * File version checks ******************************************************************************/ /* Check if Adc_Ip.c file and Adc_Ip.h file are of the same vendor */ #if (ADC_IP_VENDOR_ID_C != ADC_IP_VENDOR_ID_H) #error "Adc_Ip.c and Adc_Ip.h have different vendor ids" #endif /* Check if Adc_Ip.c file and Adc_Ip.h file are of the same Autosar version */ #if ((ADC_IP_AR_RELEASE_MAJOR_VERSION_C != ADC_IP_AR_RELEASE_MAJOR_VERSION_H) || \ (ADC_IP_AR_RELEASE_MINOR_VERSION_C != ADC_IP_AR_RELEASE_MINOR_VERSION_H) || \ (ADC_IP_AR_RELEASE_REVISION_VERSION_C != ADC_IP_AR_RELEASE_REVISION_VERSION_H) \ ) #error "AutoSar Version Numbers of Adc_Ip.c and Adc_Ip.h are different" #endif /* Check if Adc_Ip.c file and Adc_Ip.h file are of the same Software version */ #if ((ADC_IP_SW_MAJOR_VERSION_C != ADC_IP_SW_MAJOR_VERSION_H) || \ (ADC_IP_SW_MINOR_VERSION_C != ADC_IP_SW_MINOR_VERSION_H) || \ (ADC_IP_SW_PATCH_VERSION_C != ADC_IP_SW_PATCH_VERSION_H) \ ) #error "Software Version Numbers of Adc_Ip.c and Adc_Ip.h are different" #endif /* Check if Adc_Ip.c file and Adc_Ip_HwAccess.h file are of the same vendor */ #if (ADC_IP_VENDOR_ID_C != ADC_IP_VENDOR_ID_HWACCESS_H) #error "Adc_Ip.c and Adc_Ip_HwAccess.h have different vendor ids" #endif /* Check if Adc_Ip.c file and Adc_Ip_HwAccess.h file are of the same Autosar version */ #if ((ADC_IP_AR_RELEASE_MAJOR_VERSION_C != ADC_IP_AR_RELEASE_MAJOR_VERSION_HWACCESS_H) || \ (ADC_IP_AR_RELEASE_MINOR_VERSION_C != ADC_IP_AR_RELEASE_MINOR_VERSION_HWACCESS_H) || \ (ADC_IP_AR_RELEASE_REVISION_VERSION_C != ADC_IP_AR_RELEASE_REVISION_VERSION_HWACCESS_H) \ ) #error "AutoSar Version Numbers of Adc_Ip.c and Adc_Ip_HwAccess.h are different" #endif /* Check if Adc_Ip.c file and Adc_Ip_HwAccess.h file are of the same Software version */ #if ((ADC_IP_SW_MAJOR_VERSION_C != ADC_IP_SW_MAJOR_VERSION_HWACCESS_H) || \ (ADC_IP_SW_MINOR_VERSION_C != ADC_IP_SW_MINOR_VERSION_HWACCESS_H) || \ (ADC_IP_SW_PATCH_VERSION_C != ADC_IP_SW_PATCH_VERSION_HWACCESS_H) \ ) #error "Software Version Numbers of Adc_Ip.c and Adc_Ip_HwAccess.h are different" #endif #ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK /* Check if Adc_Ip.c file and OsIf.h file are of the same Autosar version */ #if ((ADC_IP_AR_RELEASE_MAJOR_VERSION_C != OSIF_AR_RELEASE_MAJOR_VERSION) || \ (ADC_IP_AR_RELEASE_MINOR_VERSION_C != OSIF_AR_RELEASE_MINOR_VERSION) \ ) #error "AutoSar Version Numbers of Adc_Ip.c and OsIf.h are different" #endif #if (STD_ON == ADC_IP_ENABLE_USER_MODE_SUPPORT) /* Checks against RegLockMacros.h */ #if ((ADC_IP_AR_RELEASE_MAJOR_VERSION_C != REGLOCKMACROS_AR_RELEASE_MAJOR_VERSION) || \ (ADC_IP_AR_RELEASE_MINOR_VERSION_C != REGLOCKMACROS_AR_RELEASE_MINOR_VERSION)) #error "AutoSar Version Numbers of Adc_Ip.c and RegLockMacros.h are different" #endif #endif /* (STD_ON == ADC_IP_ENABLE_USER_MODE_SUPPORT) */ /* Check if Adc_Ip.c and SchM_Adc.h are of the same Autosar version */ #if ((ADC_IP_AR_RELEASE_MAJOR_VERSION_C != SCHM_ADC_AR_RELEASE_MAJOR_VERSION) || \ (ADC_IP_AR_RELEASE_MINOR_VERSION_C != SCHM_ADC_AR_RELEASE_MINOR_VERSION) \ ) #error "AutoSar Version Numbers of Adc_Ip.c and SchM_Adc.h are different" #endif #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) /* Check if Adc_Ip.c and Devassert.h are of the same Autosar version */ #if ((ADC_IP_AR_RELEASE_MAJOR_VERSION_C != DEVASSERT_AR_RELEASE_MAJOR_VERSION) || \ (ADC_IP_AR_RELEASE_MINOR_VERSION_C != DEVASSERT_AR_RELEASE_MINOR_VERSION) \ ) #error "AutoSar Version Numbers of Adc_Ip.c and Devassert.h are different" #endif #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ #endif /* DISABLE_MCAL_INTERMODULE_ASR_CHECK */ /******************************************************************************* * Pre-check ******************************************************************************/ #ifndef MCAL_ENABLE_USER_MODE_SUPPORT #if (STD_ON == ADC_IP_ENABLE_USER_MODE_SUPPORT) #error MCAL_ENABLE_USER_MODE_SUPPORT is not enabled. For running ADC in user mode the MCAL_ENABLE_USER_MODE_SUPPORT needs to be defined #endif /* (STD_ON == ADC_IP_ENABLE_USER_MODE_SUPPORT) */ #endif /* ifndef MCAL_ENABLE_USER_MODE_SUPPORT */ /******************************************************************************* * Local function prototypes ******************************************************************************/ #define ADC_START_SEC_CODE #include "Adc_MemMap.h" #if (ADC_IP_SUPPLY_MONITORING_ENABLED == STD_ON) static void ADC_SetSupplyMonitoringEnable_TrustedCall(const boolean SupplyEnable); static void ADC_SetSupplyMonitoringEnable(const boolean SupplyEnable); static void ADC_ConfigSupplyMonitoringChannel_TrustedCall(const uint32 SupplyChannel); static void ADC_ConfigSupplyMonitoringChannel(const uint32 SupplyChannel); static void ADC_ResetSupplyMonitoringChannel_TrustedCall(void); static void ADC_ResetSupplyMonitoringChannel(void); #endif /* (ADC_IP_SUPPLY_MONITORING_ENABLED == STD_ON) */ #if (ADC_IP_ENABLE_SIM_SOURCE_SELECTION == STD_ON) static void ADC_SetTriggerSourceSelect_TrustedCall(const uint32 Instance, const uint8 TriggerSource); static void ADC_SetTriggerSourceSelect(const uint32 Instance, const uint8 TriggerSource); static void ADC_SetPretriggerSourceSelect_TrustedCall(const uint32 Instance, const uint8 PretriggerSource); static void ADC_SetPretriggerSourceSelect(const uint32 Instance, const uint8 PretriggerSource); static void ADC_SetSoftwarePretrigger_TrustedCall(const uint32 Instance, const uint8 SoftwarePretrigger); #endif /* (ADC_IP_ENABLE_SIM_SOURCE_SELECTION == STD_ON) */ #define ADC_STOP_SEC_CODE #include "Adc_MemMap.h" /******************************************************************************* * Variables ******************************************************************************/ #define ADC_START_SEC_CONST_UNSPECIFIED #include "Adc_MemMap.h" /* Table of Base addresses for ADC instances. */ static ADC_Type * const AdcBase[ADC_INSTANCE_COUNT] = IP_ADC_BASE_PTRS; #define ADC_STOP_SEC_CONST_UNSPECIFIED #include "Adc_MemMap.h" #define ADC_START_SEC_VAR_CLEARED_UNSPECIFIED #include "Adc_MemMap.h" /* Global state structure */ static Adc_Ip_StateStructType AdcIpState[ADC_INSTANCE_COUNT]; #define ADC_STOP_SEC_VAR_CLEARED_UNSPECIFIED #include "Adc_MemMap.h" #define ADC_START_SEC_CODE #include "Adc_MemMap.h" /*FUNCTION********************************************************************** * * Function Name : Adc_DoCalibration_SetParams * Description : This function configures averaging, sample time, input clock and trigger * mode for Adc_Ip_DoCalibration service. * * END**************************************************************************/ static inline void Adc_DoCalibration_SetParams(ADC_Type * const Base, const Adc_Ip_ClockConfigType * const Config, const Adc_Ip_TrigType TriggerMode); static inline void Adc_DoCalibration_SetParams(ADC_Type * const Base, const Adc_Ip_ClockConfigType * const Config, const Adc_Ip_TrigType TriggerMode) { /* Configure averaging */ SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_29(); Adc_HwAcc_SetAveraging(Base, Config->AvgEn, Config->AvgSel); SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_29(); /* Configure trigger mode */ SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_24(); Adc_HwAcc_SetTriggerMode(Base, TriggerMode); SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_24(); /* Configure sample time */ SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_15(); Adc_HwAcc_SetSampleTime(Base, Config->SampleTime); SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_15(); /* Configure input clock */ SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_13(); Adc_HwAcc_SetClock(Base, Config->ClockDivide, Config->InputClock); SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_13(); } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_Init * Description : This function initializes the ADC module by configuring all * available features. * * @implements Adc_Ip_Init_Activity * END**************************************************************************/ void Adc_Ip_Init(const uint32 Instance, const Adc_Ip_ConfigType * const Config) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); DevAssert(Config != NULL_PTR); DevAssert(Config->NumChannels <= ADC_MAX_CHAN_COUNT); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ ADC_Type * const Base = AdcBase[Instance]; uint32 SC2Reg = 0u; uint32 SC2ClearMask = 0u; uint8 Index; Adc_HwAcc_SetClock(Base, Config->ClockDivide, Config->InputClock); Adc_HwAcc_SetSampleTime(Base, Config->SampleTime); Adc_HwAcc_SetAveraging(Base, Config->AvgEn, Config->AvgSel); Adc_Ip_SetResolution(Instance, Config->Resolution); #if (ADC_IP_ENABLE_SIM_SOURCE_SELECTION == STD_ON) ADC_SetTriggerSourceSelect(Instance, Config->TriggerSel); ADC_SetPretriggerSourceSelect(Instance, Config->PretriggerSel); #endif /* (ADC_IP_ENABLE_SIM_SOURCE_SELECTION == STD_ON) */ #if (ADC_IP_SUPPLY_MONITORING_ENABLED == STD_ON) if (Instance == 0U) { ADC_SetSupplyMonitoringEnable(Config->SupplyMonitoringEnable); } #endif /* (ADC_IP_SUPPLY_MONITORING_ENABLED == STD_ON) */ /* Configure trigger mode */ SC2ClearMask |= ADC_SC2_ADTRG_MASK; SC2Reg |= ADC_SC2_ADTRG(Config->TriggerMode); /* Configure DMA enable */ if (Config->DmaEnable) { SC2Reg |= ADC_SC2_DMAEN_MASK; } else { SC2ClearMask |= ADC_SC2_DMAEN_MASK; } /* Configure voltage reference selector */ SC2ClearMask |= ADC_SC2_REFSEL_MASK; SC2Reg |= ADC_SC2_REFSEL(Config->VoltageRef); /* Configure compare enables and values */ SC2ClearMask |= ADC_SC2_ACFE_MASK | ADC_SC2_ACFGT_MASK | ADC_SC2_ACREN_MASK; SC2Reg |= ADC_SC2_ACFE(Config->CompareEnable ? 1u : 0u); SC2Reg |= ADC_SC2_ACFGT(Config->CompareGreaterThanEnable ? 1u : 0u); SC2Reg |= ADC_SC2_ACREN(Config->CompareRangeFuncEnable ? 1u : 0u); Base->CV[0u] = ADC_CV_CV(Config->CompVal1); Base->CV[1u] = ADC_CV_CV(Config->CompVal2); Adc_HwAcc_SetSC2Reg(Base, SC2ClearMask, SC2Reg); Adc_HwAcc_SetUserGainAndOffset(Base, Config->UsrGain, Config->UsrOffset); Adc_Ip_SetContinuousMode(Instance, Config->ContinuousConvEnable); if (Config->ChannelConfigs != NULL_PTR) { for (Index = 0u; Index < Config->NumChannels; Index++) { Adc_Ip_ConfigChannel(Instance, &(Config->ChannelConfigs[Index])); } } AdcIpState[Instance].ConversionCompleteNotification = Config->ConversionCompleteNotification; AdcIpState[Instance].CalibrationClockDivide = Config->CalibrationClockDivide; AdcIpState[Instance].Init = TRUE; #if (ADC_IP_ENABLE_SIM_SOURCE_SELECTION == STD_ON) AdcIpState[Instance].PretriggerSel = Config->PretriggerSel; #endif /* (ADC_IP_ENABLE_SIM_SOURCE_SELECTION == STD_ON) */ } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_DeInit * Description : This function resets the ADC internal registers to default values. * * @implements Adc_Ip_Deinit_Activity * END**************************************************************************/ void Adc_Ip_DeInit(const uint32 Instance) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ Adc_Ip_ConfigType DefaultConfig; Adc_Ip_ChanConfigType ChannelConfigs[ADC_MAX_CHAN_COUNT]; uint8 Index; DefaultConfig.ClockDivide = ADC_IP_CLK_FULL_BUS; DefaultConfig.CalibrationClockDivide = ADC_IP_CLK_EIGHTH_BUS; DefaultConfig.InputClock = ADC_IP_CLK_ALT_1; DefaultConfig.SampleTime = ADC_IP_DEFAULT_SAMPLE_TIME; DefaultConfig.AvgEn = FALSE; DefaultConfig.AvgSel = ADC_IP_AVG_4_CONV; DefaultConfig.Resolution = ADC_IP_RESOLUTION_8BIT; DefaultConfig.TriggerMode = ADC_IP_TRIGGER_SOFTWARE; #if (ADC_IP_ENABLE_SIM_SOURCE_SELECTION == STD_ON) DefaultConfig.PretriggerSel = ADC_IP_PRETRIGGER_SEL_PDB; DefaultConfig.TriggerSel = ADC_IP_TRIGGER_SEL_PDB; #endif /* (ADC_IP_ENABLE_SIM_SOURCE_SELECTION == STD_ON) */ DefaultConfig.DmaEnable = FALSE; DefaultConfig.VoltageRef = ADC_IP_VOLTAGEREF_VREF; DefaultConfig.ContinuousConvEnable = FALSE; #if (ADC_IP_SUPPLY_MONITORING_ENABLED == STD_ON) DefaultConfig.SupplyMonitoringEnable = FALSE; #endif /* (ADC_IP_SUPPLY_MONITORING_ENABLED == STD_ON) */ DefaultConfig.CompareEnable = FALSE; DefaultConfig.CompareGreaterThanEnable = FALSE; DefaultConfig.CompareRangeFuncEnable = FALSE; DefaultConfig.CompVal1 = 0u; DefaultConfig.CompVal2 = 0u; DefaultConfig.UsrGain = ADC_IP_DEFAULT_USER_GAIN; DefaultConfig.UsrOffset = 0u; DefaultConfig.NumChannels = ADC_MAX_CHAN_COUNT; for (Index = 0u; Index < ADC_MAX_CHAN_COUNT; Index++) { ChannelConfigs[Index].ChnIdx = Index; ChannelConfigs[Index].Channel = ADC_IP_INPUTCHAN_DISABLED; ChannelConfigs[Index].InterruptEnable = FALSE; } DefaultConfig.ChannelConfigs = ChannelConfigs; DefaultConfig.ConversionCompleteNotification = NULL_PTR; Adc_Ip_Init(Instance, &DefaultConfig); #if (ADC_IP_SUPPLY_MONITORING_ENABLED == STD_ON) if (Instance == 0U) { ADC_ResetSupplyMonitoringChannel(); } #endif /* (ADC_IP_SUPPLY_MONITORING_ENABLED == STD_ON) */ AdcIpState[Instance].Init = FALSE; } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_SetAveraging * Description : This function enables averaging and selects the number of * conversions to average. * The mask parameter should be set using the Adc_Ip_AvgSelectType enum elements * that have the pattern ADC_IP_AVG_... e.g. ADC_IP_AVG_4_CONV. * * @implements Adc_Ip_SetAveraging_Activity * END**************************************************************************/ void Adc_Ip_SetAveraging(const uint32 Instance, const boolean AvgEn, const Adc_Ip_AvgSelectType AvgSel) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ ADC_Type * const Base = AdcBase[Instance]; SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_27(); Adc_HwAcc_SetAveraging(Base, AvgEn, AvgSel); SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_27(); } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_SetSampleTime * Description : This function sets the sample time for selected ADC instance. * * @implements Adc_Ip_SetSampleTime_Activity * END**************************************************************************/ void Adc_Ip_SetSampleTime(const uint32 Instance, const uint8 SampleTime) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ ADC_Type * const Base = AdcBase[Instance]; SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_16(); Adc_HwAcc_SetSampleTime(Base, SampleTime); SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_16(); } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_EnableDma * Description : This function enables DMA. * * @implements Adc_Ip_EnableDma_Activity * END**************************************************************************/ void Adc_Ip_EnableDma(const uint32 Instance) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ ADC_Type * const Base = AdcBase[Instance]; SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_26(); Base->SC2 |= ADC_SC2_DMAEN_MASK; SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_26(); } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_DisableDma * Description : This function disables DMA. * * @implements Adc_Ip_DisableDma_Activity * END**************************************************************************/ void Adc_Ip_DisableDma(const uint32 Instance) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ ADC_Type * const Base = AdcBase[Instance]; SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_22(); Base->SC2 &= ~(ADC_SC2_DMAEN_MASK); SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_22(); } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_SetTriggerMode * Description : This function enables either hardware or software trigger. * * @implements Adc_Ip_SetTriggerMode_Activity * END**************************************************************************/ void Adc_Ip_SetTriggerMode(const uint32 Instance, const Adc_Ip_TrigType TriggerMode) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ ADC_Type * const Base = AdcBase[Instance]; SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_23(); Adc_HwAcc_SetTriggerMode(Base, TriggerMode); SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_23(); } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_SetContinuousMode * Description : This function switches between ADC continuous conversion mode * and one shot mode. * * @implements Adc_Ip_SetContinuousMode_Activity * END**************************************************************************/ void Adc_Ip_SetContinuousMode(const uint32 Instance, const boolean ContinuousModeEnable) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ ADC_Type * const Base = AdcBase[Instance]; SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_30(); uint32 Sc3Reg = Base->SC3; Sc3Reg &= ~(ADC_SC3_ADCO_MASK); Sc3Reg |= ADC_SC3_ADCO(ContinuousModeEnable ? 1u : 0u); Base->SC3 = Sc3Reg; SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_30(); } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_SetResolution * Description : This function sets ADC module resolution. * * @implements Adc_Ip_SetResolution_Activity * END**************************************************************************/ void Adc_Ip_SetResolution(const uint32 Instance, const Adc_Ip_ResolutionType Resolution) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ ADC_Type * const Base = AdcBase[Instance]; SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_10(); uint32 Cfg1Reg = Base->CFG1; Cfg1Reg &= ~(ADC_CFG1_MODE_MASK); Cfg1Reg |= ADC_CFG1_MODE(Resolution); Base->CFG1 = Cfg1Reg; SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_10(); } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_SetClockMode * Description : This function initializes the ADC clock configuration. * * @implements Adc_Ip_SetClockMode_Activity * END**************************************************************************/ void Adc_Ip_SetClockMode(const uint32 Instance, const Adc_Ip_ClockConfigType * const Config) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); DevAssert(Config != NULL_PTR); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ ADC_Type * const Base = AdcBase[Instance]; SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_11(); Adc_HwAcc_SetClock(Base, Config->ClockDivide, Config->InputClock); SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_11(); SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_14(); Adc_HwAcc_SetSampleTime(Base, Config->SampleTime); SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_14(); SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_28(); Adc_HwAcc_SetAveraging(Base, Config->AvgEn, Config->AvgSel); SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_28(); } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_ConfigChannel * Description : Configures the selected control channel with the given * configuration structure. * * When Software Trigger mode is enabled, configuring control channel index 0, * implicitly triggers a new conversion on the selected ADC input channel. * Therefore, Adc_Ip_ConfigChannel can be used for sw-triggering conversions. * * Configuring any control channel while it is actively controlling a conversion * (sw or hw triggered) will implicitly abort the on-going conversion. * * @implements Adc_Ip_ConfigChannel_Activity * END**************************************************************************/ void Adc_Ip_ConfigChannel(const uint32 Instance, const Adc_Ip_ChanConfigType * const ChanConfig) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); DevAssert(ChanConfig != NULL_PTR); #if (ADC_IP_SUPPLY_MONITORING_ENABLED == STD_ON) DevAssert((Instance == 0u) || ((uint32)ChanConfig->Channel < (uint32)ADC_IP_INPUTCHAN_SUPPLY_VDD)); #endif /* (ADC_IP_SUPPLY_MONITORING_ENABLED == STD_ON) */ #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ ADC_Type * const Base = AdcBase[Instance]; Adc_Ip_InputChannelType InputChanDemapped; #if (ADC_IP_SUPPLY_MONITORING_ENABLED == STD_ON) /* Internal supply monitor channels need special configuration */ if (ChanConfig->Channel >= ADC_IP_INPUTCHAN_SUPPLY_VDD) { /* De-map ADC_IP_INPUTCHAN_SUPPLY_ into actual index. */ const uint32 SupplyChannel = (uint32)ChanConfig->Channel - (uint32)ADC_IP_INPUTCHAN_SUPPLY_VDD; ADC_ConfigSupplyMonitoringChannel(SupplyChannel); /* Supply monitor channels are measured on ADC internal input channel 0 */ InputChanDemapped = ADC_IP_INPUTCHAN_INT0; } else #endif /* (ADC_IP_SUPPLY_MONITORING_ENABLED == STD_ON) */ { InputChanDemapped = ChanConfig->Channel; } SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_21(); Adc_HwAcc_SetChannel(Base, ChanConfig->ChnIdx, InputChanDemapped, ChanConfig->InterruptEnable); SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_21(); /* Also update in state structure */ AdcIpState[Instance].ChannelConfig[ChanConfig->ChnIdx] = ChanConfig->Channel; } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_SetDisabledChannel * Description : This function sets the input channel of the selected control * channel to ADC_IP_INPUTCHAN_DISABLED. If WithTimeout is TRUE then the * function will also wait for the register to be updated. * Note: the control channel index is the numeric index of SC1x * (e.g. SC1A has index 0), not the input channel. * * @implements Adc_Ip_SetDisabledChannel_Activity * END**************************************************************************/ Adc_Ip_StatusType Adc_Ip_SetDisabledChannel(const uint32 Instance, const uint8 ControlChanIdx, const boolean WithTimeout) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); DevAssert(ControlChanIdx < ADC_MAX_CHAN_COUNT); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ ADC_Type * const Base = AdcBase[Instance]; Adc_Ip_StatusType Status = ADC_IP_STATUS_SUCCESS; uint32 TimeoutTicks = OsIf_MicrosToTicks(ADC_IP_TIMEOUT_VAL, ADC_IP_TIMEOUT_TYPE); uint32 CurrentTicks = OsIf_GetCounter(ADC_IP_TIMEOUT_TYPE); uint32 ElapsedTicks = 0u; SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_17(); /* Set input channel select to disabled */ SC1(Base, ControlChanIdx) |= ADC_SC1_ADCH_MASK; SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_17(); if (WithTimeout == TRUE) { while (((SC1(Base, ControlChanIdx) & ADC_SC1_ADCH_MASK) != ADC_SC1_ADCH_MASK) && (ElapsedTicks < TimeoutTicks)) { ElapsedTicks += OsIf_GetElapsed(&CurrentTicks, ADC_IP_TIMEOUT_TYPE); } if (ElapsedTicks >= TimeoutTicks) { Status = ADC_IP_STATUS_TIMEOUT; } } return Status; } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_StartConversion * Description : This function starts a software conversion on the selected * input channel by writing the given values to the SC1A register. * The result can be read with Adc_Ip_GetConvData with index 0. * Note: hardware configuration on the control channel with index 0 will be * overwritten. * Note: this will not work if hardware triggered mode is selected. * * @implements Adc_Ip_StartConversion_Activity * END**************************************************************************/ void Adc_Ip_StartConversion(const uint32 Instance, Adc_Ip_InputChannelType InputChannel, const boolean InterruptEnable) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ ADC_Type * const Base = AdcBase[Instance]; SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_18(); /* Configure SC1A register */ Adc_HwAcc_SetChannel(Base, 0u, InputChannel, InterruptEnable); SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_18(); } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_GetConvActiveFlag * Description : Reads and return conversion active flag status. * * @implements Adc_Ip_GetConvActiveFlag_Activity * END**************************************************************************/ boolean Adc_Ip_GetConvActiveFlag(const uint32 Instance) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ const ADC_Type * const Base = AdcBase[Instance]; uint32 Sc2Reg = Base->SC2; Sc2Reg = (Sc2Reg & ADC_SC2_ADACT_MASK) >> ADC_SC2_ADACT_SHIFT; return (Sc2Reg != 0u) ? TRUE : FALSE; } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_GetChanInterrupt * Description : This function checks and returns if the selected control * channel has the interrupt flag set. * * @implements Adc_Ip_GetChanInterrupt_Activity * END**************************************************************************/ boolean Adc_Ip_GetChanInterrupt(const uint32 Instance, const uint8 ControlChanIdx) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); DevAssert(ControlChanIdx < ADC_MAX_CHAN_COUNT); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ const ADC_Type * const Base = AdcBase[Instance]; const uint32 Sc1Reg = SC1(Base, ControlChanIdx); return Adc_HwAcc_GetAIEN(Sc1Reg); } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_GetConvCompleteFlag * Description : This function returns the value of the conversion * complete(COCO) flag of a given channel. * * @implements Adc_Ip_GetConvCompleteFlag_Activity * END**************************************************************************/ boolean Adc_Ip_GetConvCompleteFlag(const uint32 Instance, const uint8 ControlChanIdx) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); DevAssert(ControlChanIdx < ADC_MAX_CHAN_COUNT); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ const ADC_Type * const Base = AdcBase[Instance]; const uint32 Sc1Reg = SC1(Base, ControlChanIdx); return Adc_HwAcc_GetCOCO(Sc1Reg); } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_GetConvData * Description : This function retrieves the last conversion result for the * selected control channel. This function does no validity check on the result. * In order to check if the result is valid, the user must call * Adc_Ip_GetConvCompleteFlag function before this one. * * @implements Adc_Ip_GetConvData_Activity * END**************************************************************************/ uint16 Adc_Ip_GetConvData(const uint32 Instance, const uint8 ControlChanIdx) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); DevAssert(ControlChanIdx < ADC_MAX_CHAN_COUNT); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ const ADC_Type * const Base = AdcBase[Instance]; return Adc_HwAcc_GetData(Base, ControlChanIdx); } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_DoCalibration * Description : This function performs a calibration of the ADC. The input * clock frequency for calibration must be less than or equal to half of the maximum * specified frequency (50Mhz) and greater than minimum specified frequency (20Mhz). * * @implements Adc_Ip_DoCalibration_Activity * END**************************************************************************/ Adc_Ip_StatusType Adc_Ip_DoCalibration(const uint32 Instance) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ ADC_Type * const Base = AdcBase[Instance]; Adc_Ip_StatusType Status = ADC_IP_STATUS_SUCCESS; Adc_Ip_TrigType TriggerMode; uint32 TimeoutTicks = OsIf_MicrosToTicks(ADC_IP_TIMEOUT_VAL, ADC_IP_TIMEOUT_TYPE); uint32 CurrentTicks = OsIf_GetCounter(ADC_IP_TIMEOUT_TYPE); uint32 ElapsedTicks = 0u; uint32 Reg; Adc_Ip_ClockConfigType PreClockConfig; Adc_Ip_ClockConfigType CalClockConfig; /* Store settings before calibration */ Reg = Base->SC3; PreClockConfig.AvgEn = ((Reg & ADC_SC3_AVGE_MASK) != 0u) ? TRUE : FALSE; PreClockConfig.AvgSel = Adc_HwAcc_GetAverageSelect(Reg); Reg = Base->CFG2; PreClockConfig.SampleTime = (uint8) ((Reg & ADC_CFG2_SMPLTS_MASK) >> ADC_CFG2_SMPLTS_SHIFT); TriggerMode = Adc_HwAcc_GetTriggerMode(Base->SC2); Reg = Base->CFG1; PreClockConfig.ClockDivide = Adc_HwAcc_GetClockDivide(Reg); PreClockConfig.InputClock = Adc_HwAcc_GetInputClock(Reg); CalClockConfig.AvgEn = TRUE; CalClockConfig.AvgSel = ADC_IP_AVG_32_CONV; CalClockConfig.SampleTime = ADC_IP_DEFAULT_SAMPLE_TIME; CalClockConfig.ClockDivide = AdcIpState[Instance].CalibrationClockDivide; CalClockConfig.InputClock = PreClockConfig.InputClock; /* Prepare required settings for calibration. */ Adc_DoCalibration_SetParams(Base, &CalClockConfig, ADC_IP_TRIGGER_SOFTWARE); Base->CLPS = 0u; Base->CLP3 = 0u; Base->CLP2 = 0u; Base->CLP1 = 0u; Base->CLP0 = 0u; Base->CLPX = 0u; Base->CLP9 = 0u; /* Start calibration by writing to the calibration field */ SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_29(); Reg = Base->SC3; Reg &= ~(ADC_SC3_CAL_MASK); Reg |= ADC_SC3_CAL(1u); Base->SC3 = Reg; SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_29(); /* Wait for the calibration to finish */ while (((Base->SC3 & ADC_SC3_CAL_MASK) != 0u) && (ElapsedTicks < TimeoutTicks)) { ElapsedTicks += OsIf_GetElapsed(&CurrentTicks, ADC_IP_TIMEOUT_TYPE); } if (ElapsedTicks >= TimeoutTicks) { Status = ADC_IP_STATUS_TIMEOUT; } /* Revert settings as same as before calibration. */ Adc_DoCalibration_SetParams(Base, &PreClockConfig, TriggerMode); /* Clear COCO flag */ (void) R(Base, 0u); return Status; } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_ClearLatchedTriggers * Description : This function clears all trigger latched flags of the ADC instance. * This function must be called after the hardware trigger source for the ADC * has been deactivated. * * @implements Adc_Ip_ClearLatchedTriggers_Activity * END**************************************************************************/ Adc_Ip_StatusType Adc_Ip_ClearLatchedTriggers(const uint32 Instance) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); DevAssert(Instance != 0u); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ ADC_Type * const Base = AdcBase[Instance]; Adc_Ip_StatusType Status = ADC_IP_STATUS_SUCCESS; uint32 TimeoutTicks = OsIf_MicrosToTicks(ADC_IP_TIMEOUT_VAL, ADC_IP_TIMEOUT_TYPE); uint32 CurrentTicks = OsIf_GetCounter(ADC_IP_TIMEOUT_TYPE); uint32 ElapsedTicks = 0u; SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_12(); /* Write bit to clear latched triggers */ Base->CFG1 |= ADC_CFG1_CLRLTRG(0x01u); SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_12(); /* Wait for latched triggers to be cleared */ while (((Base->SC2 & ADC_SC2_TRGSTLAT_MASK) != 0u) && (ElapsedTicks < TimeoutTicks)) { ElapsedTicks += OsIf_GetElapsed(&CurrentTicks, ADC_IP_TIMEOUT_TYPE); } if (ElapsedTicks >= TimeoutTicks) { Status = ADC_IP_STATUS_TIMEOUT; } return Status; } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_EnableChannelNotification * Description : This function enables the notification for the selected channel. * Note : It's required to read result data in user notification in order to clear the COCO flags and avoid ISR getting invoked repeatedly * * @implements Adc_Ip_EnableChannelNotification_Activity * END**************************************************************************/ void Adc_Ip_EnableChannelNotification(const uint32 Instance, const uint8 ControlChanIdx) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); DevAssert(ControlChanIdx < ADC_MAX_CHAN_COUNT); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ ADC_Type * const Base = AdcBase[Instance]; SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_19(); SC1(Base, ControlChanIdx) |= ADC_SC1_AIEN_MASK; SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_19(); } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_DisableChannelNotification * Description : This function disables the notification for the selected channel. * * @implements Adc_Ip_DisableChannelNotification_Activity * END**************************************************************************/ void Adc_Ip_DisableChannelNotification(const uint32 Instance, const uint8 ControlChanIdx) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); DevAssert(ControlChanIdx < ADC_MAX_CHAN_COUNT); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ ADC_Type * const Base = AdcBase[Instance]; SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_20(); SC1(Base, ControlChanIdx) &= ~(ADC_SC1_AIEN_MASK); SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_20(); } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_ClearTrigErrReg * Description : This function clears all trigger error flags of the ADC instance. * * @implements Adc_Ip_ClearTrigErrReg_Activity * END**************************************************************************/ void Adc_Ip_ClearTrigErrReg(const uint32 Instance) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); DevAssert(Instance != 0u); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ ADC_Type * const Base = AdcBase[Instance]; SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_25(); Base->SC2 |= ADC_SC2_TRGSTERR_MASK; SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_25(); } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_GetTrigErrReg * Description : This function returns all trigger error flags of the ADC instance. * * @implements Adc_Ip_GetTrigErrReg_Activity * END**************************************************************************/ uint32 Adc_Ip_GetTrigErrReg(const uint32 Instance) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); DevAssert(Instance != 0u); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ const ADC_Type * const Base = AdcBase[Instance]; return (Base->SC2 & ADC_SC2_TRGSTERR_MASK) >> ADC_SC2_TRGSTERR_SHIFT; } /*FUNCTION********************************************************************* * * Function Name : Adc_Ip_GetDataAddress * Description : Returns the address of the specified Rn register. * * @implements Adc_Ip_GetDataAddress_Activity *END*************************************************************************/ uint32 Adc_Ip_GetDataAddress(const uint32 Instance, const uint8 Index) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ return (uint32)&(R(AdcBase[Instance], Index)); } /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_GetChanData * Description : This function retrieves the last conversion result for the * selected input channel, by looking which control channel was configured * with it. If multiple control channels are configured simultaneously with * the same requested input channel, the result of the first control channel * found will be returned. If no control channel is configured with the given * input channel then ADC_IP_STATUS_ERROR will be returned. * This function does no validity check on the result. * In order to check if the result is valid, the user must call * Adc_Ip_GetConvCompleteFlag function before this one. * * @implements Adc_Ip_GetChanData_Activity * END**************************************************************************/ Adc_Ip_StatusType Adc_Ip_GetChanData(const uint32 Instance, const Adc_Ip_InputChannelType Channel, uint16 * const Result) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); #if (ADC_IP_SUPPLY_MONITORING_ENABLED == STD_ON) DevAssert((Instance == 0u) || ((uint32)Channel < (uint32)ADC_IP_INPUTCHAN_SUPPLY_VDD)); #endif /* (ADC_IP_SUPPLY_MONITORING_ENABLED == STD_ON) */ #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ const ADC_Type * const Base = AdcBase[Instance]; Adc_Ip_StatusType Status = ADC_IP_STATUS_SUCCESS; uint16 Temp = 0u; uint8 ControlChanIdx; boolean Found = FALSE; for (ControlChanIdx = 0u; ControlChanIdx < ADC_MAX_CHAN_COUNT; ControlChanIdx++) { if (AdcIpState[Instance].ChannelConfig[ControlChanIdx] == Channel) { Found = TRUE; break; } } if (Found == TRUE) { Temp = (uint16) R(Base, ControlChanIdx); Temp = (uint16) ((Temp & ADC_R_D_MASK) >> ADC_R_D_SHIFT); } else { Status = ADC_IP_STATUS_ERROR; } *Result = Temp; return Status; } #if (ADC_IP_ENABLE_SIM_SOURCE_SELECTION == STD_ON) /*FUNCTION********************************************************************** * * Function Name : Adc_Ip_SetSoftwarePretrigger * Description : This function sets the software pretrigger source for * an ADC instance. * * @implements Adc_Ip_SetSoftwarePretrigger_Activity * END**************************************************************************/ void Adc_Ip_SetSoftwarePretrigger(const uint32 Instance, const Adc_Ip_SoftwarePretriggerType SoftwarePretrigger) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); /* If SW Pretrigger Select is not enabled, the SW pretriggers will be ignored by ADC. */ DevAssert(AdcIpState[Instance].PretriggerSel == ADC_IP_PRETRIGGER_SEL_SW); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ #if (STD_ON == ADC_IP_ENABLE_USER_MODE_SUPPORT) OsIf_Trusted_Call2params(ADC_SetSoftwarePretrigger_TrustedCall, Instance, (uint8)SoftwarePretrigger); #else ADC_SetSoftwarePretrigger_TrustedCall(Instance, (uint8)SoftwarePretrigger); #endif /* (STD_ON == ADC_IP_ENABLE_USER_MODE_SUPPORT) */ } #endif /* (ADC_IP_ENABLE_SIM_SOURCE_SELECTION == STD_ON) */ /*FUNCTION********************************************************************* * * Function Name : Adc_Ip_IRQHandler * Description : Handles Adc interrupts. * Note : It's required to read result data in user notification in order to clear the COCO flags and avoid ISR getting invoked repeatedly * * @implements Adc_Ip_IRQHandler_Activity *END*************************************************************************/ /* The IAR build wants to see function prototypes */ void Adc_Ip_IRQHandler(const uint32 Instance); void Adc_Ip_IRQHandler(const uint32 Instance) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert(Instance < ADC_INSTANCE_COUNT); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ const ADC_Type * const Base = AdcBase[Instance]; uint32 Sc1Reg; uint8 ControlChanIdx; boolean ChanIntFlag = FALSE; boolean ChanCocoFlag = FALSE; /* NOTE: CPR_RTD_00028 wasn't fulfilled in because ISR cannot distinguish if an interrupt is spurious or if conversion was initiated on purpose with AIEN = 0 * The reasons are: * - There is a single interrupt line for all COCO flags * - It is a valid usecase to have COCO flag set but AIEN=0 (e.g. in HLD only interrupt for last channel in group is enabled) * - Clearing of COCO flag is only done by reading the result register - COCO is not w1c */ /* Check if the Adc unit is initialized and if the interrupt is not NULL * first since all channels use the same callback */ if ((AdcIpState[Instance].Init == TRUE) && (AdcIpState[Instance].ConversionCompleteNotification != NULL_PTR)) { for (ControlChanIdx = 0u; ControlChanIdx < ADC_MAX_CHAN_COUNT; ControlChanIdx++) { Sc1Reg = SC1(Base, ControlChanIdx); ChanIntFlag = Adc_HwAcc_GetAIEN(Sc1Reg); ChanCocoFlag = Adc_HwAcc_GetCOCO(Sc1Reg); /* Check if the interrupt was spurrios by checking if the interrupt * is enabled and equivalent conversion has finished */ if ((TRUE == ChanIntFlag) && (TRUE == ChanCocoFlag)) { AdcIpState[Instance].ConversionCompleteNotification(ControlChanIdx); } else if ((ADC_IP_INPUTCHAN_DISABLED == AdcIpState[Instance].ChannelConfig[ControlChanIdx]) && (TRUE == ChanCocoFlag)) { /* This will only clear the obvious spurious COCO flags. If the flag will be spuriously set on active channels it will not be caught by this. */ (void)Adc_HwAcc_GetData(Base, ControlChanIdx); } else { ; /* Empty else branch to avoid MISRA */ } } } else { for (ControlChanIdx = 0u; ControlChanIdx < ADC_MAX_CHAN_COUNT; ControlChanIdx++) { /* Do a dummy read to clear the COCO flags */ (void)Adc_HwAcc_GetData(Base, ControlChanIdx); } } } #if (ADC_IP_SUPPLY_MONITORING_ENABLED == STD_ON) static void ADC_SetSupplyMonitoringEnable_TrustedCall(const boolean SupplyEnable) { /* Set or clear ADC_SUPPLY field of CHIPCTL register from SIM based on SupplyEnable */ if (SupplyEnable == TRUE) { IP_SIM->CHIPCTL |= SIM_CHIPCTL_ADC_SUPPLYEN_MASK; } else { IP_SIM->CHIPCTL &= ~SIM_CHIPCTL_ADC_SUPPLYEN_MASK; } } /*FUNCTION********************************************************************** * * Function Name : ADC_SetSupplyMonitoringEnable * Description : This function enable supply monitoring for the internal channels * on SIM registers * * END**************************************************************************/ static void ADC_SetSupplyMonitoringEnable(const boolean SupplyEnable) { #if (STD_ON == ADC_IP_ENABLE_USER_MODE_SUPPORT) OsIf_Trusted_Call1param(ADC_SetSupplyMonitoringEnable_TrustedCall, SupplyEnable); #else ADC_SetSupplyMonitoringEnable_TrustedCall(SupplyEnable); #endif /* (STD_ON == ADC_IP_ENABLE_USER_MODE_SUPPORT) */ } static void ADC_ConfigSupplyMonitoringChannel_TrustedCall(const uint32 SupplyChannel) { #if (ADC_IP_DEV_ERROR_DETECT == STD_ON) DevAssert((IP_SIM->CHIPCTL & SIM_CHIPCTL_ADC_SUPPLYEN_MASK) != 0UL); #endif /* (ADC_IP_DEV_ERROR_DETECT == STD_ON) */ SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_32(); uint32 Reg = IP_SIM->CHIPCTL; Reg &= ~SIM_CHIPCTL_ADC_SUPPLY_MASK; Reg |= SIM_CHIPCTL_ADC_SUPPLY(SupplyChannel); IP_SIM->CHIPCTL = Reg; SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_32(); } /*FUNCTION********************************************************************** * * Function Name : ADC_ConfigSupplyMonitoringChannel * Description : This function configures the internal channels on on SIM registers * * END**************************************************************************/ static void ADC_ConfigSupplyMonitoringChannel(const uint32 SupplyChannel) { #if (STD_ON == ADC_IP_ENABLE_USER_MODE_SUPPORT) OsIf_Trusted_Call1param(ADC_ConfigSupplyMonitoringChannel_TrustedCall, SupplyChannel); #else ADC_ConfigSupplyMonitoringChannel_TrustedCall(SupplyChannel); #endif /* (STD_ON == ADC_IP_ENABLE_USER_MODE_SUPPORT) */ } static void ADC_ResetSupplyMonitoringChannel_TrustedCall(void) { /* Clear ADC supply mask from CHIPCTL of SIM register */ IP_SIM->CHIPCTL &= ~SIM_CHIPCTL_ADC_SUPPLY_MASK; } /*FUNCTION********************************************************************** * * Function Name : ADC_ResetSupplyMonitoringChannel * Description : This function resets the muxing for ADC channel on SIM register to reset value * * END**************************************************************************/ static void ADC_ResetSupplyMonitoringChannel(void) { #if (STD_ON == ADC_IP_ENABLE_USER_MODE_SUPPORT) OsIf_Trusted_Call(ADC_ResetSupplyMonitoringChannel_TrustedCall); #else ADC_ResetSupplyMonitoringChannel_TrustedCall(); #endif /* (STD_ON == ADC_IP_ENABLE_USER_MODE_SUPPORT) */ } #endif /* (ADC_IP_SUPPLY_MONITORING_ENABLED == STD_ON) */ #if (ADC_IP_ENABLE_SIM_SOURCE_SELECTION == STD_ON) /*FUNCTION********************************************************************** * * Function Name : ADC_SetTriggerSourceSelect * Description : This function selects trigger source for an ADC instance * * END**************************************************************************/ static void ADC_SetTriggerSourceSelect(const uint32 Instance, const uint8 TriggerSource) { #if (STD_ON == ADC_IP_ENABLE_USER_MODE_SUPPORT) OsIf_Trusted_Call2params(ADC_SetTriggerSourceSelect_TrustedCall, Instance, TriggerSource); #else ADC_SetTriggerSourceSelect_TrustedCall(Instance, TriggerSource); #endif /* (STD_ON == ADC_IP_ENABLE_USER_MODE_SUPPORT) */ } static void ADC_SetTriggerSourceSelect_TrustedCall(const uint32 Instance, const uint8 TriggerSource) { uint32 Reg = (uint32)IP_SIM->ADCOPT; #if (ADC_INSTANCE_COUNT > 1u) switch (Instance) { case 0u: { #endif /* (ADC_INSTANCE_COUNT > 1u) */ Reg &= ~SIM_ADCOPT_ADC0TRGSEL_MASK; Reg |= SIM_ADCOPT_ADC0TRGSEL(TriggerSource); #if (ADC_INSTANCE_COUNT > 1u) break; } case 1u: { Reg &= ~SIM_ADCOPT_ADC1TRGSEL_MASK; Reg |= SIM_ADCOPT_ADC1TRGSEL(TriggerSource); break; } default: { ; /* no-op */ break; } } #else (void)Instance; #endif /* (ADC_INSTANCE_COUNT > 1u) */ IP_SIM->ADCOPT = Reg; } /*FUNCTION********************************************************************** * * Function Name : ADC_SetPretriggerSourceSelect * Description : This function selects pretrigger source for an ADC instance * * END**************************************************************************/ static void ADC_SetPretriggerSourceSelect(const uint32 Instance, const uint8 PretriggerSource) { #if (STD_ON == ADC_IP_ENABLE_USER_MODE_SUPPORT) OsIf_Trusted_Call2params(ADC_SetPretriggerSourceSelect_TrustedCall, Instance, PretriggerSource); #else ADC_SetPretriggerSourceSelect_TrustedCall(Instance, PretriggerSource); #endif /* (STD_ON == ADC_IP_ENABLE_USER_MODE_SUPPORT) */ } static void ADC_SetPretriggerSourceSelect_TrustedCall(const uint32 Instance, const uint8 PretriggerSource) { uint32 Reg = (uint32)IP_SIM->ADCOPT; #if (ADC_INSTANCE_COUNT > 1u) switch (Instance) { case 0u: { #endif /* (ADC_INSTANCE_COUNT > 1u) */ Reg &= ~SIM_ADCOPT_ADC0PRETRGSEL_MASK; Reg |= SIM_ADCOPT_ADC0PRETRGSEL(PretriggerSource); #if (ADC_INSTANCE_COUNT > 1u) break; } case 1u: { Reg &= ~SIM_ADCOPT_ADC1PRETRGSEL_MASK; Reg |= SIM_ADCOPT_ADC1PRETRGSEL(PretriggerSource); break; } default: { ; /* no-op */ break; } } #else (void)Instance; #endif /* (ADC_INSTANCE_COUNT > 1u) */ IP_SIM->ADCOPT = Reg; } /*FUNCTION********************************************************************** * * Function Name : ADC_SetSoftwarePretrigger_TrustedCall * Description : This function writes the software pretrigger source to be * configured for an ADC instance * * END**************************************************************************/ static void ADC_SetSoftwarePretrigger_TrustedCall(const uint32 Instance, const uint8 SoftwarePretrigger) { SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_31(); uint32 Reg = (uint32)IP_SIM->ADCOPT; #if (ADC_INSTANCE_COUNT > 1u) switch (Instance) { case 0u: { #endif /* (ADC_INSTANCE_COUNT > 1u) */ Reg &= ~SIM_ADCOPT_ADC0SWPRETRG_MASK; Reg |= SIM_ADCOPT_ADC0SWPRETRG(SoftwarePretrigger); #if (ADC_INSTANCE_COUNT > 1u) break; } case 1u: { Reg &= ~SIM_ADCOPT_ADC1SWPRETRG_MASK; Reg |= SIM_ADCOPT_ADC1SWPRETRG(SoftwarePretrigger); break; } default: { ; /* no-op */ break; } } #else (void)Instance; #endif /* (ADC_INSTANCE_COUNT > 1u) */ IP_SIM->ADCOPT = Reg; SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_31(); } #endif /* (ADC_IP_ENABLE_SIM_SOURCE_SELECTION == STD_ON) */ #define ADC_STOP_SEC_CODE #include "Adc_MemMap.h" /** @} */