/*==================================================================================================
*   Project              : RTD AUTOSAR 4.4
*   Platform             : CORTEXM
*   Peripheral           : ADC_SAR
*   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
*
*   @addtogroup adc_sar_ip Adc Sar IPL
*   @{
*/

/**
 * @page mu32Isra_violations MISRA-C:2012 violations
 *
 * @section [global]
 * Violates MISRA 2012 Advisory Rule 11.4, Conversion between a pointer and integer type.
 * The cast is required to initialize a pointer with an unsigned long define, representing an address.
 *
 * @section [global]
 * Violates MISRA 2012 Required Rule 11.6, Cast from unsigned int to pointer.
 * The cast is required to initialize a pointer with an unsigned long define, representing an address.
 *
 * @section [global]
 * Violates MISRA 2012 Advisory Rule 8.7, External could be made static.
 * Function is defined for usage by application code.
 *
 * @section [global]
 * Violates MISRA 2012 Advisory Rule 10.5, Impermissible cast; cannot cast from 'essentially Boolean'
 * to 'essentially unsigned'. This is required by the conversion of a bool into a bit.
 *
 * @section [global]
 * Violates MISRA 2012 Required Rule 1.3,  Taking address of near auto variable.
 * The code is not dynamically linked. An absolute stack address is obtained
 * when taking the address of the near auto variable.
 *
 * @section [global]
 * Violates MISRA 2012 Advisory Rule 2.5, Global macro not referenced.
 * The macro defines a bitmask used to access status flags.
 *
 * @section [global]
 * Violates MISRA 2012 Advisory Rule 4.9, Function-like macro defined.
 * Function-like macros are used instead of inline functions in order to ensure
 * that the performance will not be decreased if the functions will not be
 * inlined by the compiler.
 *
 * @section [global]
 * Violates MISRA 2012 Advisory Rule 15.4, more than one 'break' terminates loop.
 * 'break' is used to terminate the loops on different and unrelated conditions
 *
 */

#include "Adc_Sar_Ip.h"
#include "Adc_Sar_Ip_HwAccess.h"
#include "Reg_eSys.h"
#include "SchM_Adc.h"

#if defined(ADC_SAR_IP_DEV_ERROR_DETECT)
/* Clock Manager is a dependency only when ADC_SAR_DEV_ASSERT is enabled, used in:
  - Adc_Sar_Ip_DoCalibration
  - Adc_Sar_Ip_Init
*/

#include "OsIf.h"

/* local definitions on the limits of the clock frequency */
#define ADC_CLOCK_FREQ_MAX_RUNTIME     (80000000U)
#define ADC_CLOCK_FREQ_MAX_CALIBRATION (40000000U)

#endif /* defined(ADC_SAR_IP_DEV_ERROR_DETECT) */

#if (STD_ON == ADC_SAR_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_SAR_IP_ENABLE_USER_MODE_SUPPORT)
    #include "RegLockMacros.h"
#endif /* (STD_ON == ADC_SAR_IP_ENABLE_USER_MODE_SUPPORT) */

/*******************************************************************************
 *   Source file version information
 ******************************************************************************/
#define ADC_SAR_IP_VENDOR_ID_C                      43
#define ADC_SAR_IP_AR_RELEASE_MAJOR_VERSION_C       4
#define ADC_SAR_IP_AR_RELEASE_MINOR_VERSION_C       4
#define ADC_SAR_IP_AR_RELEASE_REVISION_VERSION_C    0
#define ADC_SAR_IP_SW_MAJOR_VERSION_C               0
#define ADC_SAR_IP_SW_MINOR_VERSION_C               9
#define ADC_SAR_IP_SW_PATCH_VERSION_C               0

/*******************************************************************************
 *   File version checks
 ******************************************************************************/
/* Check if Adc_Sar_Ip.c file and Adc_Sar_Ip.h file are of the same vendor */
#if (ADC_SAR_IP_VENDOR_ID_C != ADC_SAR_IP_VENDOR_ID_H)
    #error "Adc_Sar_Ip.c and Adc_Sar_Ip.h have different vendor ids"
#endif

/* Check if Adc_Sar_Ip.c file and Adc_Sar_Ip.h file are of the same Autosar version */
#if ((ADC_SAR_IP_AR_RELEASE_MAJOR_VERSION_C != ADC_SAR_IP_AR_RELEASE_MAJOR_VERSION_H) || \
     (ADC_SAR_IP_AR_RELEASE_MINOR_VERSION_C != ADC_SAR_IP_AR_RELEASE_MINOR_VERSION_H) || \
     (ADC_SAR_IP_AR_RELEASE_REVISION_VERSION_C != ADC_SAR_IP_AR_RELEASE_REVISION_VERSION_H) \
    )
    #error "AutoSar Version Numbers of Adc_Sar_Ip.c and Adc_Sar_Ip.h are different"
#endif

/* Check if Adc_Sar_Ip.c file and Adc_Sar_Ip.h file are of the same Software version */
#if ((ADC_SAR_IP_SW_MAJOR_VERSION_C != ADC_SAR_IP_SW_MAJOR_VERSION_H) || \
     (ADC_SAR_IP_SW_MINOR_VERSION_C != ADC_SAR_IP_SW_MINOR_VERSION_H) || \
     (ADC_SAR_IP_SW_PATCH_VERSION_C != ADC_SAR_IP_SW_PATCH_VERSION_H) \
    )
  #error "Software Version Numbers of Adc_Sar_Ip.c and Adc_Sar_Ip.h are different"
#endif

/* Check if Adc_Sar_Ip.c file and Adc_Sar_Ip_HwAccess.h file are of the same vendor */
#if (ADC_SAR_IP_VENDOR_ID_C != ADC_SAR_IP_VENDOR_ID_HWACCESS_H)
    #error "Adc_Sar_Ip.c and Adc_Sar_Ip_HwAccess.h have different vendor ids"
#endif

/* Check if Adc_Sar_Ip.c file and Adc_Sar_Ip_HwAccess.h file are of the same Autosar version */
#if ((ADC_SAR_IP_AR_RELEASE_MAJOR_VERSION_C != ADC_SAR_IP_AR_RELEASE_MAJOR_VERSION_HWACCESS_H) || \
     (ADC_SAR_IP_AR_RELEASE_MINOR_VERSION_C != ADC_SAR_IP_AR_RELEASE_MINOR_VERSION_HWACCESS_H) || \
     (ADC_SAR_IP_AR_RELEASE_REVISION_VERSION_C != ADC_SAR_IP_AR_RELEASE_REVISION_VERSION_HWACCESS_H) \
    )
    #error "AutoSar Version Numbers of Adc_Sar_Ip.c and Adc_Sar_Ip_HwAccess.h are different"
#endif

/* Check if Adc_Sar_Ip.c file and Adc_Sar_Ip_HwAccess.h file are of the same Software version */
#if ((ADC_SAR_IP_SW_MAJOR_VERSION_C != ADC_SAR_IP_SW_MAJOR_VERSION_HWACCESS_H) || \
     (ADC_SAR_IP_SW_MINOR_VERSION_C != ADC_SAR_IP_SW_MINOR_VERSION_HWACCESS_H) || \
     (ADC_SAR_IP_SW_PATCH_VERSION_C != ADC_SAR_IP_SW_PATCH_VERSION_HWACCESS_H) \
    )
  #error "Software Version Numbers of Adc_Sar_Ip.c and Adc_Sar_Ip_HwAccess.h are different"
#endif

#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
/* Check if Adc_Sar_Ip.c file and Reg_eSys.h file are of the same Autosar version */
#if ((ADC_SAR_IP_AR_RELEASE_MAJOR_VERSION_C != REG_ESYS_AR_RELEASE_MAJOR_VERSION) || \
     (ADC_SAR_IP_AR_RELEASE_MINOR_VERSION_C != REG_ESYS_AR_RELEASE_MINOR_VERSION)    \
    )
    #error "AutoSar Version Numbers of Adc_Sar_Ip.c and Reg_eSys.h are different"
#endif

#if defined(ADC_SAR_IP_DEV_ERROR_DETECT)
    /* Check if Adc_Sar_Ip.c file and OsIf.h file are of the same Autosar version */
    #if ((ADC_SAR_IP_AR_RELEASE_MAJOR_VERSION_C != OSIF_AR_RELEASE_MAJOR_VERSION) || \
         (ADC_SAR_IP_AR_RELEASE_MINOR_VERSION_C != OSIF_AR_RELEASE_MINOR_VERSION)    \
        )
        #error "AutoSar Version Numbers of Adc_Sar_Ip.c and OsIf.h are different"
    #endif
#endif /* defined(ADC_SAR_IP_DEV_ERROR_DETECT) */

#if (STD_ON == ADC_SAR_IP_ENABLE_USER_MODE_SUPPORT)
    /* Checks against RegLockMacros.h */
    #if ((ADC_SAR_IP_AR_RELEASE_MAJOR_VERSION_C != REGLOCKMACROS_AR_RELEASE_MAJOR_VERSION) || \
         (ADC_SAR_IP_AR_RELEASE_MINOR_VERSION_C != REGLOCKMACROS_AR_RELEASE_MINOR_VERSION))
        #error "AUTOSAR Version Numbers of Adc_Sar_Ip.c and RegLockMacros.h are different"
    #endif
#endif /* (STD_ON == ADC_SAR_IP_ENABLE_USER_MODE_SUPPORT) */
#endif

/*******************************************************************************
 * Pre-check
 ******************************************************************************/
 /* If the bad access protection is not explicitly enabled, it is disabled */
#ifndef FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    #define FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL (0)
#endif

#ifndef FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    #define FEATURE_ADC_BAD_ACCESS_PROT_FEATURE (0)
#endif

#ifndef MCAL_ENABLE_USER_MODE_SUPPORT
    #if (STD_ON == ADC_SAR_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_ENABLE_USER_MODE_SUPPORT) */
#endif /* ifndef MCAL_ENABLE_USER_MODE_SUPPORT*/

/*******************************************************************************
 * Variables
 ******************************************************************************/

#define ADC_START_SEC_CONST_UNSPECIFIED
#include "Adc_MemMap.h"

/* Table of pBase addresses for ADC instances. */
static ADC_Type * const pAdcBase[ADC_SAR_INSTANCE_COUNT] = ADC_BASE_PTRS;
#if FEATURE_ADC_HAS_TEMPSENSE_CHN
#if (ADC_SAR_IP_TEMPSENSE_ENABLED == STD_ON)
static TEMPSENSE_Type * const pTempsenseBase[TEMPSENSE_INSTANCE_COUNT] = TEMPSENSE_BASE_PTRS;
#endif /* (ADC_SAR_IP_TEMPSENSE_ENABLED == STD_ON) */
#endif

#define ADC_STOP_SEC_CONST_UNSPECIFIED
#include "Adc_MemMap.h"

#define ADC_START_SEC_VAR_NO_INIT_UNSPECIFIED
#include "Adc_MemMap.h"
/* Global state structure */
static Adc_Sar_Ip_StateStructType aAdcSarState[ADC_SAR_INSTANCE_COUNT];

#define ADC_STOP_SEC_VAR_NO_INIT_UNSPECIFIED
#include "Adc_MemMap.h"

#define ADC_START_SEC_CONST_32
#include "Adc_MemMap.h"

#ifdef ADC_THRHLR_PER_INSTANCE_COUNT
static uint32 const u32AdcThrhlrCount[ADC_SAR_INSTANCE_COUNT] = ADC_THRHLR_PER_INSTANCE_COUNT;
#endif /* ADC_THRHLR_PER_INSTANCE_COUNT */

#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
static const uint32 u32AdcChanBitmap[ADC_SAR_INSTANCE_COUNT][ADC_SAR_NUM_GROUP_CHAN] = FEATURE_ADC_CHN_AVAIL_BITMAP;
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */

#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
static const uint32 u32AdcFeatureBitmap[ADC_SAR_INSTANCE_COUNT] = FEATURE_ADC_FEAT_AVAIL_BITMAP;
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_FEATURE */

#define ADC_STOP_SEC_CONST_32
#include "Adc_MemMap.h"
/*******************************************************************************
 * Defines
 ******************************************************************************/
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
/* ADC_INST_HAS_REG_<bitwidth> macros. Checks the availability of a
    register index based on the availability of the ADC channels
    for the particular u32Instance on the platform.
    <bitwidth> represents the width of the bitfield associated with each
    ADC channel in the register series.
*/
#define ADC_INST_HAS_REG_1(inst,regIdx)   (u32AdcChanBitmap[inst][(regIdx)] != 0u)
#define ADC_INST_HAS_REG_4(inst,regIdx)  ((u32AdcChanBitmap[inst][(regIdx) / 4u] & (0xFFUL << (((regIdx) % 4u) * 8u))) != 0u)
#define ADC_INST_HAS_REG_32(inst,regIdx) ((u32AdcChanBitmap[inst][(regIdx) / 32u] & (0x01UL << ((regIdx) % 32u))) != 0u)

/* <bitwidth> = 1. Each bit in these registers correspons to one ADC channel */
#define ADC_INST_HAS_CEOCFRn(inst,n) (ADC_INST_HAS_REG_1(inst,n))
#define ADC_INST_HAS_CIMRn(inst,n)   (ADC_INST_HAS_REG_1(inst,n))
#define ADC_INST_HAS_PSRn(inst,n)    (ADC_INST_HAS_REG_1(inst,n))
#define ADC_INST_HAS_CTRn(inst,n)    (ADC_INST_HAS_REG_1(inst,n))
#define ADC_INST_HAS_NCMRn(inst,n)   (ADC_INST_HAS_REG_1(inst,n))
#define ADC_INST_HAS_JCMRn(inst,n)   (ADC_INST_HAS_REG_1(inst,n))
#define ADC_INST_HAS_DMARn(inst,n)   (ADC_INST_HAS_REG_1(inst,n))
#define ADC_INST_HAS_CWENRn(inst,n)  (ADC_INST_HAS_REG_1(inst,n))
#define ADC_INST_HAS_AWORRn(inst,n)  (ADC_INST_HAS_REG_1(inst,n))

/* <bitwidth> = 4. Four bits in the register correspond to one ADC channel */
#define ADC_INST_HAS_CWSELRn(inst,x) (ADC_INST_HAS_REG_4(inst,x))

/* <bitwidth> = 32. The entire 4 byte register is associated with one ADC channel */
#define ADC_INST_HAS_CDRn(inst,n) (ADC_INST_HAS_REG_32(inst,n))
#define ADC_INST_HAS_CHANn(inst,n) (ADC_INST_HAS_REG_32(inst,n))

#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */

#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE

#ifdef ADC_DSDR_DSD
#define ADC_INST_HAS_DSDR(inst) ((u32AdcFeatureBitmap[inst] & (1UL << 0u)) != 0u)
#endif /* ADC_DSDR_DSD */
#define ADC_INST_HAS_PSCR(inst) ((u32AdcFeatureBitmap[inst] & (1UL << 1u)) != 0u)
#define ADC_INST_HAS_CTU(inst) ((u32AdcFeatureBitmap[inst] & (1UL << 2u)) != 0u)
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_FEATURE */

#define ADC_TIMEOUT_COUNTER 0xFFFFUL

#define ADC_START_SEC_CODE
#include "Adc_MemMap.h"
/*******************************************************************************
 * Private Functions
 ******************************************************************************/

#if (ADC_SAR_IP_SET_RESOLUTION == STD_ON)
/*FUNCTION*********************************************************************
 *
 * Function Name : Adc_Sar_GetResolution
 * Description   : Returns Adc Sar resolution for conversion data
 *
 *END*************************************************************************/
static inline uint8 Adc_Sar_GetResolution(const uint32 u32Instance)
{
    uint8 u8Resolution;
    ADC_Type * const pBase = pAdcBase[u32Instance];
    uint32 u32Calbistreg = pBase->CALBISTREG;
    uint8 u8ResolutionBits = (uint8)((u32Calbistreg & ADC_CALBISTREG_RESN_MASK) >> ADC_CALBISTREG_RESN_SHIFT);
    switch (u8ResolutionBits)
    {
        case 0u:
        {
            u8Resolution = 14U; /* 14-bit resolution */
            break;
        }
        case 1u:
        {
            u8Resolution = 12U; /* 12-bit resolution */
            break;
        }
        case 2u:
        {
            u8Resolution = 10U; /* 10-bit resolution */
            break;
        }
        case 3u:
        {
            u8Resolution = 8U; /* 8-bit resolution */
            break;
        }
        default:
        {
            u8Resolution = 14U; /* 14-bit resolution */
            break;
        }
    }
    return u8Resolution;
}
#endif /* (ADC_SAR_IP_SET_RESOLUTION == STD_ON) */

/*FUNCTION*********************************************************************
 *
 * Function Name : Adc_Sar_GetMaskedResult
 * Description   : Returns result masked accordingly with alignment
 *
 *END*************************************************************************/
static inline uint16 Adc_Sar_GetMaskedResult(const uint32 u32Instance, const uint32 u32Cdr)
{
    uint32 u32CdrMask;
    uint16 u16Result;
    uint8 u8Resolution;
#if (ADC_SAR_IP_SET_RESOLUTION == STD_ON)
    u8Resolution = Adc_Sar_GetResolution(u32Instance);
#else
    u8Resolution = ADC_MAX_RESOLUTION;
#endif /* (ADC_SAR_IP_SET_RESOLUTION == STD_ON) */

    /* Assumption: the width of the register is less than 16 */
    u32CdrMask = ADC_CDR_CDATA_MASK << (16u - u8Resolution);

    /* If the result is left aligned, adjust register mask accordingly */
    if (aAdcSarState[u32Instance].eDataAlign == ADC_SAR_IP_DATA_ALIGNED_LEFT)
    {
        /* Assumption: the width of the register is less than 16 */
        u32CdrMask = ADC_CDR_CDATA_MASK << (16u - u8Resolution);
#if (ADC_SAR_IP_SET_RESOLUTION == STD_ON)
        u16Result = ((uint16)(u32Cdr & u32CdrMask)) >> ADC_CDR_CDATA_SHIFT;
#endif /* (ADC_SAR_IP_SET_RESOLUTION == STD_ON) */
    }
#if (ADC_SAR_IP_SET_RESOLUTION == STD_ON)
    else
    {
        u32CdrMask = (ADC_CDR_CDATA_MASK >> 1) & (ADC_CDR_CDATA_MASK << (ADC_RESULT_RESOLUTION - u8Resolution));
        u16Result = ((uint16)(u32Cdr & u32CdrMask)) >> (ADC_RESULT_RESOLUTION - u8Resolution + ADC_CDR_CDATA_SHIFT);
    }
#else
    u16Result = ((uint16)(u32Cdr & u32CdrMask)) >> ADC_CDR_CDATA_SHIFT;
#endif /* (ADC_SAR_IP_SET_RESOLUTION == STD_ON) */
    return u16Result;
}


/*FUNCTION*********************************************************************
 *
 * Function Name : Adc_Sar_GetMsrFlags
 * Description   : Returns the flag status from MSR register
 *
 *END*************************************************************************/
static inline uint32 Adc_Sar_GetMsrFlags(const uint32 u32Instance)
{
    const ADC_Type * const pBase = pAdcBase[u32Instance];
    uint32 u32Msr = pBase->MSR;
    uint32 u32Flags = 0U;

    u32Flags |= ((u32Msr & ADC_MSR_CALIBRTD_MASK) != 0U) ? ADC_SAR_IP_STATUS_FLAG_CALIBRATED : 0U;
    u32Flags |= ((u32Msr & ADC_MSR_NSTART_MASK) != 0U) ? ADC_SAR_IP_STATUS_FLAG_NORMAL_STARTED : 0U;
    u32Flags |= ((u32Msr & ADC_MSR_JABORT_MASK) != 0U) ? ADC_SAR_IP_STATUS_FLAG_INJECTED_ABORTED : 0U;
    u32Flags |= ((u32Msr & ADC_MSR_JSTART_MASK) != 0U) ? ADC_SAR_IP_STATUS_FLAG_INJECTED_STARTED : 0U;
#if FEATURE_ADC_HAS_CTU
#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    if (ADC_INST_HAS_CTU(u32Instance))
    {
#endif /*FEATURE_ADC_BAD_ACCESS_PROT_FEATURE*/
        u32Flags |= ((u32Msr & ADC_MSR_CTUSTART_MASK) != 0U) ? ADC_SAR_IP_STATUS_FLAG_CTU_STARTED : 0U;
#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    }
#endif /*FEATURE_ADC_BAD_ACCESS_PROT_FEATURE*/
#endif /* FEATURE_ADC_HAS_CTU */
    u32Flags |= ((u32Msr & ADC_MSR_ACKO_MASK) != 0U) ? ADC_SAR_IP_STATUS_FLAG_AUTOCLOCKOFF : 0U;

    return u32Flags;
}

/*FUNCTION*********************************************************************
 *
 * Function Name : Adc_Sar_GetIsrFlags
 * Description   : Returns the flag status from ISR register
 *
 *END*************************************************************************/
static inline uint32 Adc_Sar_GetIsrFlags(const uint32 u32Instance)
{
    const ADC_Type * const pBase = pAdcBase[u32Instance];
    uint32 u32Isr = pBase->ISR;
    uint32 u32Flags = 0U;

    u32Flags |= ((u32Isr & ADC_ISR_EOC_MASK) != 0U) ? ADC_SAR_IP_NOTIF_FLAG_NORMAL_EOC : 0U;
    u32Flags |= ((u32Isr & ADC_ISR_ECH_MASK) != 0U) ? ADC_SAR_IP_NOTIF_FLAG_NORMAL_ENDCHAIN : 0U;
    u32Flags |= ((u32Isr & ADC_ISR_JEOC_MASK) != 0U) ? ADC_SAR_IP_NOTIF_FLAG_INJECTED_EOC : 0U;
    u32Flags |= ((u32Isr & ADC_ISR_JECH_MASK) != 0U) ? ADC_SAR_IP_NOTIF_FLAG_INJECTED_ENDCHAIN : 0U;
#if FEATURE_ADC_HAS_CTU
#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    if (ADC_INST_HAS_CTU(u32Instance))
    {
#endif /*FEATURE_ADC_BAD_ACCESS_PROT_FEATURE*/
        u32Flags |= ((u32Isr & ADC_ISR_EOCTU_MASK) != 0U) ? ADC_SAR_IP_NOTIF_FLAG_CTU_EOC : 0U;
#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    }
#endif /*FEATURE_ADC_BAD_ACCESS_PROT_FEATURE*/
#endif /* FEATURE_ADC_HAS_CTU */

    return u32Flags;
}

/*FUNCTION*********************************************************************
 *
 * Function Name : Adc_Sar_CollectMcrMasks
 * Description   : The function collects the mask for MCR register from provided
 * structure. The funcion is used to reduce the complexity of Adc_Sar_Ip_Init()
 *
 *END*************************************************************************/
static inline uint32 Adc_Sar_CollectMcrMasks(const uint32 u32Instance, const Adc_Sar_Ip_ConfigType * const pConfig)
{
    uint32 u32Mcr = 0U;

    u32Mcr |= ADC_MCR_MODE(pConfig->eConvMode);
#if FEATURE_ADC_HAS_CLKSEL_EXTENDED
    u32Mcr |= ADC_MCR_ADCLKSEL(pConfig->eClkSelect);
#else
    switch (pConfig->eClkSelect)
    {
        case ADC_SAR_IP_CLK_FULL_BUS:
            /* Full bus clock when MCR[ADCLKSEL] = 1 */
            u32Mcr |= ADC_MCR_ADCLKSEL(1U);
            break;
        case ADC_SAR_IP_CLK_HALF_BUS:
            /* Half bus clock when MCR[ADCLKSEL] = 0 */
            break;
        default:
            /* no-op */
            break;
    }
#endif /* FEATURE_ADC_HAS_CLKSEL_EXTENDED */
    u32Mcr |= ADC_MCR_ACKO(pConfig->bAutoClockOff ? 1U : 0u);
    u32Mcr |= ADC_MCR_OWREN(pConfig->bOverwriteEnable ? 1U : 0u);
    u32Mcr |= ADC_MCR_WLSIDE(pConfig->eDataAlign);

/*TODO: Re-use Adc_Sar_Ip_SetCtuMode */
#if FEATURE_ADC_HAS_CTU
#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    if (ADC_INST_HAS_CTU(u32Instance))
    {
#endif /*FEATURE_ADC_BAD_ACCESS_PROT_FEATURE*/
        switch (pConfig->eCtuMode)
        {
            case ADC_SAR_IP_CTU_MODE_CONTROL:
                /* Already in CTU Control Mode CTU_MODE = 0 */
                u32Mcr |= ADC_MCR_CTUEN(1U); /* Enable CTU */
                break;
#if FEATURE_ADC_HAS_CTU_TRIGGER_MODE
            case ADC_SAR_IP_CTU_MODE_TRIGGER:
                u32Mcr |= ADC_MCR_CTU_MODE(1U); /* Set CTU to Trigger Mode CTU_MODE = 1 */
                u32Mcr |= ADC_MCR_CTUEN(1U); /* Enable CTU */
                break;
#endif /* FEATURE_ADC_HAS_CTU_TRIGGER_MODE */
            case ADC_SAR_IP_CTU_MODE_DISABLED:
                /* CTU is disabled (CTUEN = 0 and CTU_MODE = 0) */
                /* Pass through */
            default:
                ; /* no-op */
                break;
        }
#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    }
#endif /*FEATURE_ADC_BAD_ACCESS_PROT_FEATURE*/
#endif /* FEATURE_ADC_HAS_CTU */
#if FEATURE_ADC_HAS_INJ_EXT_TRIGGER
    switch (pConfig->eInjectedEdge)
    {
        case ADC_SAR_IP_EXT_TRIG_EDGE_FALLING:
            /* Already on falling edge JEDGE = 0 */
            u32Mcr |= ADC_MCR_JTRGEN_MASK; /* enable Injected trigger */
            break;
        case ADC_SAR_IP_EXT_TRIG_EDGE_RISING:
            /* Enable Injected trigger and set to rising edge JEDGE = 1 */
            u32Mcr |= (ADC_MCR_JEDGE_MASK | ADC_MCR_JTRGEN_MASK);
            break;
        case ADC_SAR_IP_EXT_TRIG_EDGE_DISABLED:
            /* Already set to injected trigger disabled (JTRGEN = 0 and JEDGE = 0) */
        default:
            ; /* no-op */
            break;
    }
#endif /* FEATURE_ADC_HAS_INJ_EXT_TRIGGER */

#if FEATURE_ADC_HAS_EXT_TRIGGER
    /* Get normal trigger masks */
    u32Mcr |= (pConfig->eExtTrigger == ADC_SAR_IP_EXT_TRIG_EDGE_RISING) ? (ADC_MCR_EDGE(1U)) : 0U;
    if (pConfig->eExtTrigger != ADC_SAR_IP_EXT_TRIG_EDGE_DISABLED)
    {
        u32Mcr |= (pConfig->bNormalExtTrgEn) ? (ADC_MCR_TRGEN(1U)) : 0U;
        u32Mcr |= (pConfig->bNormalAuxExtTrgEn) ? (ADC_MCR_XSTRTEN(1U)) : 0U;
    }
#endif /* FEATURE_ADC_HAS_EXT_TRIGGER */

#if FEATURE_ADC_HAS_AVERAGING
    u32Mcr |= ADC_MCR_AVGEN(pConfig->bAvgEn ? 1U : 0U);
    u32Mcr |= ADC_MCR_AVGS(pConfig->eAvgSel);
#else
    /* On platforms that use AVGEN only for calibration, reset to default value */
    u32Mcr |= ADC_MCR_AVGEN_MASK;
#endif /* FEATURE_ADC_HAS_AVERAGING */
#if ADC_CALIBRATION_USES_MCR
    /* Reset NRSMPL to default value */
    u32Mcr |= ADC_MCR_NRSMPL_MASK;
#endif /* ADC_CALIBRATION_USES_MCR */

    return u32Mcr;
}

/*FUNCTION*********************************************************************
 *
 * Function Name : Adc_Sar_EnableChannelWatchdog
 * Description   : Enable Watchdog feature for channel in provided array of configuration
 * Also enable notification for those channels.
 *END*************************************************************************/
static inline void Adc_Sar_EnableChannelWatchdog(const uint32 u32Instance,
                                                 const Adc_Sar_Ip_ChanConfigType * pChannelConfigs,
                                                 uint8 u8NumChannels)
{
    ADC_Type * const pBase = pAdcBase[u32Instance];
    uint32 u32Mask;
    uint8 u8Index;

    for (u8Index = 0U; u8Index < u8NumChannels; u8Index++)
    {
        const Adc_Sar_Ip_ChanConfigType * pChnConfig = &(pChannelConfigs[u8Index]);
        /* compute which of the 11 registers of 32 bit should be written for a specific channel*/
        uint32 u32RegNum = (uint32) pChnConfig->u8ChannelIndex / 8U;
        /* compute which of the 8 fields(4 bits each field) of the register have to be written for a specific channel*/
        uint32 u32Pos = (uint32) pChnConfig->u8ChannelIndex % 8U;

#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        if (ADC_INST_HAS_CWSELRn(u32Instance, u32RegNum))
        {
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
            Adc_Sar_WriteChannelMapping(pBase, u32RegNum, u32Pos, pChnConfig->u8WdgThreshRegIndex);
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */

        /* Enable WDG and/or EOC notifications */
        u32Mask = 0u;
        if (pChnConfig->bEndOfConvNotification)
        {
            u32Mask |= ADC_SAR_IP_CHAN_NOTIF_EOC;
        }
        if (pChnConfig->bWdgNotification)
        {
            u32Mask |= ADC_SAR_IP_CHAN_NOTIF_WDG;
        }
        Adc_Sar_Ip_EnableChannelNotifications(u32Instance, (uint32)pChnConfig->u8ChannelIndex, u32Mask);

        u32RegNum = CHAN_2_VECT((uint32)pChnConfig->u8ChannelIndex);
        u32Pos = CHAN_2_BIT((uint32)pChnConfig->u8ChannelIndex);

        /* Configure channel presampling */
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        if (ADC_INST_HAS_PSRn(u32Instance, u32RegNum))
        {
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
            PSR(pBase, u32RegNum) |= (pChnConfig->bPresamplingEnable) ? (1UL << (u32Pos * ADC_PSR_PRES1_SHIFT)) : 0U;
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
    }
}

/*FUNCTION*********************************************************************
 *
 * Function Name : Adc_Sar_CheckSelfTestProgress
 * Description   : Configures watchdog threshold with provided array of configuration
 *
 *END*************************************************************************/
static inline Adc_Sar_Ip_StatusType Adc_Sar_CheckSelfTestProgress(const uint32 u32Instance)
{
    const ADC_Type * const pBase = pAdcBase[u32Instance];
    Adc_Sar_Ip_StatusType eStatus = ADC_SAR_IP_STATUS_SUCCESS;
    uint32 u32Reg = 0U;
    uint32 u32TimeoutTicks = OsIf_MicrosToTicks(ADC_SAR_IP_TIMEOUT_VAL, ADC_SAR_IP_TIMEOUT_TYPE);
    uint32 u32CurrentTicks = OsIf_GetCounter(ADC_SAR_IP_TIMEOUT_TYPE);
    uint32 u32ElapsedTicks;
    uint8 u8Index;

    /*  Each for loop checks the conversion of all steps in self-test S algorithm
    *   ForLoop(0): while(AlgS-start-1) ->S0 -> S1 -> S2 -> while(Alg-end-1) -> C0 to C11 ->
    *   ForLoop(1): while(AlgS-start-2) ->S0 -> S1 -> S2 -> while(Alg-end-2)
    */
    for (u8Index = 0U; u8Index < 2U; u8Index++)
    {
        /* Wait until Alg S has started*/
        u32ElapsedTicks = 0U;
        while (((pBase->MSR & ADC_MSR_SELF_TEST_S_MASK) != ADC_MSR_SELF_TEST_S_MASK) && (u32ElapsedTicks < u32TimeoutTicks))
        {
            u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, ADC_SAR_IP_TIMEOUT_TYPE);
        }
        if (u32ElapsedTicks >= u32TimeoutTicks)
        {
            eStatus = ADC_SAR_IP_STATUS_TIMEOUT;
            break;
        }
        /* Wait until Alg S has finished*/
        u32ElapsedTicks = 0U;
        while (((pBase->MSR & ADC_MSR_SELF_TEST_S_MASK) == ADC_MSR_SELF_TEST_S_MASK) && (u32ElapsedTicks < u32TimeoutTicks))
        {
            u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, ADC_SAR_IP_TIMEOUT_TYPE);
        }
        if (u32ElapsedTicks >= u32TimeoutTicks)
        {
            eStatus = ADC_SAR_IP_STATUS_TIMEOUT;
            break;
        }
    }
    if (eStatus != ADC_SAR_IP_STATUS_TIMEOUT)
    {
        u32Reg |= ADC_STSR1_ERR_S0_MASK | ADC_STSR1_ERR_S1_MASK | ADC_STSR1_ERR_S2_MASK | ADC_STSR1_ERR_C_MASK;

        if ((pBase->STSR1 & u32Reg) != 0UL)
        {
            eStatus = ADC_SAR_IP_STATUS_ERROR;
        }
    }

    return eStatus;
}

/*FUNCTION*********************************************************************
 *
 * Function Name : Adc_Sar_GetConvResults
 * Description   : Reads the conversion results to output arrays
 * Params:
 *  - u32Instance : the ADC u32Instance to read
 *  - pChainType : the conversion chain (Normal, Injected or CTU)
 *  - pResultsRaw : an uint16 array to write only conversion data
 *  - pResultsStruct : an Adc_Sar_Ip_ChanResultType array to write detailed information
                      about each conversion result
 *  - length : the maximum size of pResultsRaw and pResultsStruct
 *
 * pResultsRaw or pResultsStruct can be NULL, but not both, as the function will
 * have nowhere to write the results.
 *
 *END*************************************************************************/
static uint32 Adc_Sar_GetConvResults(const uint32 u32Instance,
                                     const Adc_Sar_Ip_ConvChainType pChainType,
                                     uint16 * const pResultsRaw,
                                     Adc_Sar_Ip_ChanResultType * const pResultsStruct,
                                     const uint32 u32Length)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    /* pResultsRaw and pResultsStruct cannot be both NULL */
    ADC_SAR_DEV_ASSERT((pResultsRaw != NULL_PTR) || (pResultsStruct != NULL_PTR));
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    uint32 u32Index = 0u;
    boolean bLengthExceeded = FALSE;
    ADC_Type * const pBase = pAdcBase[u32Instance];
    uint32 u32VectAdr;
    /* Go through each channel group */
    for (u32VectAdr = 0u; u32VectAdr < ADC_SAR_CEOCFR_COUNT; u32VectAdr++)
    {
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        if (!ADC_INST_HAS_CEOCFRn(u32Instance, u32VectAdr))
        {
            continue; /* skip if the CEOCFR[u32VectAdr] is not available */
        }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
        uint32 u32VectBit;
        /* go through each bit in the group, check if there is a completed conversion */
        for (u32VectBit = 0u; u32VectBit < 32u; u32VectBit++)
        {
            uint8 u8ChnIdx = (uint8)((u32VectAdr * 32u) + u32VectBit);
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
            if (!(ADC_INST_HAS_CDRn(u32Instance, u8ChnIdx)))
            {
                continue; /* skip if the CDR register is not available */
            }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
#if ((ADC_SAR_CEOCFR_COUNT * 32U) > ADC_SAR_CDR_COUNT)
            if (u8ChnIdx >= ADC_SAR_CDR_COUNT)
            {
                /* terminate if we exceeded the maximum u32Index of the channels */
                bLengthExceeded = TRUE;
                break;
            }
#endif /* (ADC_SAR_CEOCFR_COUNT * 32U) > ADC_SAR_CDR_COUNT */
            uint32 u32Cdr = CDR(pBase, u8ChnIdx);
            if ((ADC_CDR_RESULT((uint32)pChainType) | ADC_CDR_VALID_MASK) == (u32Cdr & (ADC_CDR_RESULT_MASK | ADC_CDR_VALID_MASK)))
            {
                /* if the result type matches the one request by pChainType
                   and the data is valid, write to the output array(s)
                */
                if (pResultsRaw != NULL_PTR)
                {
                    pResultsRaw[u32Index] = Adc_Sar_GetMaskedResult(u32Instance, u32Cdr);
                }
                if (pResultsStruct != NULL_PTR)
                {
                    pResultsStruct[u32Index].u16ConvData = Adc_Sar_GetMaskedResult(u32Instance, u32Cdr);
                    pResultsStruct[u32Index].u8ChnIdx = u8ChnIdx;
                    pResultsStruct[u32Index].bValid = ((u32Cdr & ADC_CDR_VALID_MASK) != 0U) ? TRUE : FALSE;
                    pResultsStruct[u32Index].bOverWritten = ((u32Cdr & ADC_CDR_OVERW_MASK) != 0U) ? TRUE : FALSE;
                }
                /* increment the current u32Index and reset the CEOCFR flag */
                CEOCFR(pBase, u32VectAdr) = ((uint32)1UL << u32VectBit); /* w1c bit */
                u32Index++;
                if (u32Index >= u32Length)
                {
                    /* We have filled the output buffer, exit de loop.
                     * Data may still exist in the result registers, which won't be reached.
                     */
                    bLengthExceeded = TRUE;
                    break;
                }
            }
        }
        if (bLengthExceeded)
        {
            break;
        }
    }
    return u32Index;
}

/*FUNCTION*********************************************************************
 *
 * Function Name : Adc_Sar_ResetWdog
 * Description   : Reset and disable the Analog Watchdog feature
 *
 *END*************************************************************************/
static void Adc_Sar_ResetWdog(const uint32 u32Instance)
{
    ADC_Type * const pBase = pAdcBase[u32Instance];
    uint32 u32ThrhlrCount;
    uint8 u8Index;
#ifdef ADC_THRHLR_PER_INSTANCE_COUNT
    u32ThrhlrCount = u32AdcThrhlrCount[u32Instance];
#else
    u32ThrhlrCount = ADC_SAR_THRHLR_COUNT;
#endif /* ADC_THRHLR_PER_INSTANCE_COUNT */

    for (u8Index = 0u; u8Index < ADC_SAR_CWENR_COUNT; u8Index++)
    {
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        if (!ADC_INST_HAS_CWENRn(u32Instance, u8Index))
        {
            continue; /* skip register if it's not available */
        }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
        CWENR(pBase, u8Index) = 0u;
    }

    for (u8Index = 0u; u8Index < ADC_SAR_AWORR_COUNT; u8Index++)
    {
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        if (!ADC_INST_HAS_AWORRn(u32Instance, u8Index))
        {
            continue; /* skip register if it's not available */
        }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
        AWORR(pBase, u8Index) = 0xFFFFFFFFu; /* w1c bits */
    }

    for (u8Index = 0u; u8Index < u32ThrhlrCount; u8Index++)
    {
        Adc_Sar_WriteThresholds(pBase, u8Index, 0xFFFFu, 0u);
    }

    for (u8Index = 0u; u8Index < ADC_CWSELR_COUNT; u8Index++)
    {
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        if (!(ADC_INST_HAS_CWSELRn(u32Instance, u8Index)))
        {
            continue; /* skip register if it's not available */
        }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
        Adc_Sar_ResetWdogCWSELR(pBase, u8Index);
    }
}

/*FUNCTION*********************************************************************
 *
 * Function Name : Adc_Sar_CheckAndCallNotification
 * Description   : Checks if the given callback is not NULL then calls it
 *
 *END*************************************************************************/
static inline void Adc_Sar_CheckAndCallNotification(const uint32 u32Instance, void (*pfCallback)(void))
{
    if ((pfCallback != NULL_PTR) && (aAdcSarState[u32Instance].bInit))
    {
        pfCallback();
    }
}

#if (STD_ON == ADC_SAR_IP_EOC_ENABLED)
/*FUNCTION*********************************************************************
 *
 * Function Name : Adc_Sar_CheckAndCallEocNotification
 * Description   : Checks if the given channel interrupt was triggered, clears
 *                 the interrupt, check if it is not spurrious, checks that the
 *                 callback is not null and calls it if bExecCallback is set to true.
 *
 *END*************************************************************************/
static inline void Adc_Sar_CheckAndCallEocNotification(uint32 u32Instance,
                                                       uint16 u16ChanIdx,
                                                       uint16 u16VectAdr,
                                                       const boolean bExecCallback)
{
    ADC_Type * const pBase = pAdcBase[u32Instance];

    uint32 u32Mask = (uint32)1UL << CHAN_2_BIT(u16ChanIdx);

    if (((CEOCFR(pBase, u16VectAdr) & u32Mask) != 0U) && ((CIMR(pBase, u16VectAdr) & u32Mask) != 0U))
    {
        /* Clears flag by w1c */
        CEOCFR(pBase, u16VectAdr) = u32Mask;
        /*
         * Check if the callback is not null, if the interrupt was spurious
         * and if the driver was initialized.
         */
        if ((bExecCallback) && (aAdcSarState[u32Instance].bInit) &&
            (aAdcSarState[u32Instance].pfEndOfConvNotification != NULL_PTR))
        {
            aAdcSarState[u32Instance].pfEndOfConvNotification(u16ChanIdx);
        }
    }
}
#endif /* (STD_ON == ADC_SAR_IP_EOC_ENABLED) */

#if (STD_ON == ADC_SAR_IP_WDG_ENABLED)
/*FUNCTION*********************************************************************
 *
 * Function Name : Adc_Sar_CheckAndCallWorrNotification
 * Description   : Checks if the given channel interrupt was triggered, clears
 *                 the interrupt, check if it is not spurrious, checks that the
 *                 callback is not null and calls it if bExecCallback is set to true.
 *
 *END*************************************************************************/
static inline void Adc_Sar_CheckAndCallWorrNotification(uint32 u32Instance,
                                                        uint16 u16ChanIdx,
                                                        uint16 u16VectAdr)
{
    ADC_Type * const pBase = pAdcBase[u32Instance];

    uint32 u32Mask = (uint32)1UL << CHAN_2_BIT(u16ChanIdx);
    uint32 u32Aworr = (AWORR(pBase, u16VectAdr) & u32Mask);
    uint32 u32Cwenr = (CWENR(pBase, u16VectAdr) & u32Mask);

    if ((u32Aworr != 0U) && (u32Cwenr != 0U))
    {
        /* Clears flag by w1c */
        AWORR(pBase, u16VectAdr) = u32Mask;
        /*
         * Check if the callback is not null, if the interrupt was spurious
         * and if the driver was initialized.
         */
        if ((aAdcSarState[u32Instance].bInit) &&
            (aAdcSarState[u32Instance].pfWdgOutOfRangeNotification != NULL_PTR))
        {
            aAdcSarState[u32Instance].pfWdgOutOfRangeNotification(u16ChanIdx);
        }
    }
}
#endif /* (STD_ON == ADC_SAR_IP_WDG_ENABLED) */

/*FUNCTION*********************************************************************
 *
 * Function Name : Adc_Sar_Ip_GetDataAddress
 * Description   : Returns the address of the specified CDR register
 *
 *END*************************************************************************/
uint32 Adc_Sar_Ip_GetDataAddress(uint32 u32Instance, uint32 u32ChannelIndex)
{
    return (uint32)&(CDR(pAdcBase[u32Instance], u32ChannelIndex));
}

#if ((STD_ON == ADC_SAR_IP_WDG_ENABLED) || (STD_ON == ADC_SAR_IP_EOC_ENABLED))
/*LOCAL FUNCTION*********************************************************************
 *
 * Function Name : Adc_CheckAndCallAllChannelNotification
 * Description   : Check for all watchdog interrupts and for all individual channel interrupts
 * if it was detected. And then call the appropriate notification
 *
 *END*********************************************************************************/
static inline void Adc_CheckAndCallAllChannelNotification(const uint32 u32Instance)
{
    uint16 u16Index;
    uint16 u16PhyChan;
    uint16 u16ChanCnt;
    const uint32 u32AdcChanCount[ADC_SAR_INSTANCE_COUNT][ADC_SAR_NUM_GROUP_CHAN] = FEATURE_ADC_MAX_CHN_COUNT;
#if (STD_ON == ADC_SAR_IP_EOC_ENABLED)
    const ADC_Type * const pBase = pAdcBase[u32Instance];
    boolean bChannelTriggered = FALSE;

    /* Check if the interrupt was spurious */
    if ((pBase->IMR & (ADC_IMR_MSKEOC_MASK | ADC_IMR_MSKJEOC_MASK)) != 0U)
    {
        bChannelTriggered = TRUE;
    }
#endif /* (STD_ON == ADC_SAR_IP_EOC_ENABLED) */

    for (u16Index = 0U; u16Index < ADC_SAR_NUM_GROUP_CHAN; u16Index++)
    {
        for (u16ChanCnt = 0U; u16ChanCnt < u32AdcChanCount[u32Instance][u16Index]; u16ChanCnt++)
        {
            u16PhyChan = (u16ChanCnt + (uint16)(ADC_HW_REG_SIZE * u16Index));

#if (STD_ON == ADC_SAR_IP_EOC_ENABLED)
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
            if (ADC_INST_HAS_CEOCFRn(u32Instance, u16Index))
            {
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
                /* Check end of conversion interrupt */
                Adc_Sar_CheckAndCallEocNotification(u32Instance, u16PhyChan, u16Index, bChannelTriggered);
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
            }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
#endif /* (STD_ON == ADC_SAR_IP_EOC_ENABLED) */

#if (STD_ON == ADC_SAR_IP_WDG_ENABLED)
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
            if (ADC_INST_HAS_AWORRn(u32Instance, u16Index))
            {
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
                /* Check watchdog out of range interrupt */
                Adc_Sar_CheckAndCallWorrNotification(u32Instance, u16PhyChan, u16Index);
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
            }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
#endif /* (STD_ON == ADC_SAR_IP_WDG_ENABLED) */
        }
    }
}
#endif /* ((STD_ON == ADC_SAR_IP_WDG_ENABLED) || (STD_ON == ADC_SAR_IP_EOC_ENABLED)) */

#if (FEATURE_ADC_HAS_INJ_EXT_TRIGGER || FEATURE_ADC_HAS_EXT_TRIGGER)
/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_ConfigExternalTrigger
* Description   : This function configures the external trigger.
*
* END**************************************************************************/
static inline void Adc_Sar_ConfigExternalTrigger(const uint32 u32Instance,
                                                 const Adc_Sar_Ip_ExtTriggerEdgeType eTriggerEdge,
                                                 const uint32 u32TrgEdgeSetMask,
                                                 const uint32 u32TrgEdgeClrMask,
                                                 const uint32 u32TrigSrcMask)
{
    ADC_Type * const pBase = pAdcBase[u32Instance];

    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_21();

    switch (eTriggerEdge)
    {
        case ADC_SAR_IP_EXT_TRIG_EDGE_FALLING:
            pBase->MCR &= ~u32TrgEdgeSetMask;  /* set to falling edge 0 */
            pBase->MCR |= u32TrigSrcMask;    /* enable external trigger */
            break;
        case ADC_SAR_IP_EXT_TRIG_EDGE_RISING:
            /* enable external trigger and set to rising edge EDGE = 1 */
            pBase->MCR |= (u32TrgEdgeSetMask | u32TrigSrcMask);
            break;
        case ADC_SAR_IP_EXT_TRIG_EDGE_DISABLED:
            /* disable external trigger and reset edge field */
            pBase->MCR &= ~(u32TrgEdgeClrMask | u32TrigSrcMask);
            break;
        default:
            ; /* no-op */
            break;
    }

    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_21();
}
#endif /* (FEATURE_ADC_HAS_INJ_EXT_TRIGGER || FEATURE_ADC_HAS_EXT_TRIGGER) */

#if FEATURE_ADC_HAS_TEMPSENSE_CHN
#if (ADC_SAR_IP_TEMPSENSE_ENABLED == STD_ON)
/*FUNCTION**********************************************************************
 *
 * Function Name : Adc_Sar_TempsenseConvFp2Int
 * Description   : The function converts the number in signed fixed point format
 * (1,11,4) to the integer number multipled with TEMPSENSE_MULTIPLIER to avoid
 * rounding the decimal part.
 *
 *END**************************************************************************/
static inline uint32 Adc_Sar_TempsenseConvFp2Int(const uint32 u32Fp)
{
    uint32 u32RetVal;
    /* The integer and decimal part multiple with TEMPSENSE_MULTIPLIER to avoid rounding the decimal part */
    u32RetVal  = ((u32Fp & TEMPSENSE_INTEGER_MASK) >> TEMPSENSE_INTEGER_SHIFT) * TEMPSENSE_MULTIPLIER;
    u32RetVal += ((u32Fp & TEMPSENSE_DECIMAL_MASK) * TEMPSENSE_MULTIPLIER) / (TEMPSENSE_DECIMAL_MASK + 1U);

    return u32RetVal;
}

/*FUNCTION**********************************************************************
 *
 * Function Name : Adc_Sar_TempsenseConvInt2Fp
 * Description   : The function converts the number in integer number to signed fixed
 * point format (1,11,4). The integer number parameter is multipled with TEMPSENSE_MULTIPLIER
 *
 *END**************************************************************************/
static inline uint16 Adc_Sar_TempsenseConvInt2Fp(const sint32 s32Int)
{
    uint16 u16RetVal;
    uint32 u32Temp;
    if (s32Int < 0)
    {
        u16RetVal = TEMPSENSE_SIGN_MASK;
        u32Temp = (uint32)(- s32Int);
    }
    else
    {
        u16RetVal = 0U;
        u32Temp = (uint32)s32Int;
    }

    /* Calculates the integer part */
    u16RetVal |= (uint16)(((u32Temp / TEMPSENSE_MULTIPLIER) << TEMPSENSE_INTEGER_SHIFT) & TEMPSENSE_INTEGER_MASK);
    /* Calculates the decimal part */
    u16RetVal |= (uint16)(((u32Temp % TEMPSENSE_MULTIPLIER) * (TEMPSENSE_DECIMAL_MASK + 1U)) / TEMPSENSE_MULTIPLIER);

    return u16RetVal;
}
#endif /* (ADC_SAR_IP_TEMPSENSE_ENABLED == STD_ON) */
#endif /* FEATURE_ADC_HAS_TEMPSENSE_CHN */

/*FUNCTION*********************************************************************
 *
 * Function Name : Adc_Sar_Ip_IRQHandler
 * Description   : Handles Adc Sar interrupts
 *
 * @implements     Adc_Sar_Ip_IRQHandler_Activity
 *END*************************************************************************/
/* The IAR build wants to see function prototypes */
void Adc_Sar_Ip_IRQHandler(const uint32 u32Instance);

void Adc_Sar_Ip_IRQHandler(const uint32 u32Instance)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    ADC_Type * const pBase = pAdcBase[u32Instance];

/* Check which interrupt was triggered, clear it and call the associated callback */
#if FEATURE_ADC_HAS_CTU
    if ((pBase->ISR & ADC_ISR_EOCTU_MASK) != 0U)
    {
        pBase->ISR = ADC_ISR_EOCTU_MASK;
        /* Check if the interrupt was spurious */
        if ((pBase->IMR & ADC_IMR_MSKEOCTU_MASK) != 0U)
        {
            Adc_Sar_CheckAndCallNotification(u32Instance, aAdcSarState[u32Instance].pfEndOfCtuConversionNotification);
        }
    }
#endif /* FEATURE_ADC_HAS_CTU */
    if ((pBase->ISR & ADC_ISR_ECH_MASK) != 0U)
    {
        pBase->ISR = ADC_ISR_ECH_MASK;
        /* Check if the interrupt was spurious */
        if ((pBase->IMR & ADC_IMR_MSKECH_MASK) != 0U)
        {
            Adc_Sar_CheckAndCallNotification(u32Instance, aAdcSarState[u32Instance].pfEndOfNormalChainNotification);
        }
    }
    if ((pBase->ISR & ADC_ISR_JECH_MASK) != 0U)
    {
        pBase->ISR = ADC_ISR_JECH_MASK;
        /* Check if the interrupt was spurious */
        if ((pBase->IMR & ADC_IMR_MSKJECH_MASK)!= 0U)
        {
            Adc_Sar_CheckAndCallNotification(u32Instance, aAdcSarState[u32Instance].pfEndOfInjectedChainNotification);
        }
    }

    /* Clear EOC/JEOC interrupt */
    if ((pBase->ISR & ADC_ISR_EOC_MASK) != 0U)
    {
        pBase->ISR = ADC_ISR_EOC_MASK;
    }
    if ((pBase->ISR & ADC_ISR_JEOC_MASK) != 0U)
    {
        pBase->ISR = ADC_ISR_JEOC_MASK;
    }

#if ((STD_ON == ADC_SAR_IP_WDG_ENABLED) || (STD_ON == ADC_SAR_IP_EOC_ENABLED))
    Adc_CheckAndCallAllChannelNotification(u32Instance);
#endif /* ((STD_ON == ADC_SAR_IP_WDG_ENABLED) || (STD_ON == ADC_SAR_IP_EOC_ENABLED)) */

#if (STD_ON == ADC_SAR_IP_WDG_ENABLED)
    /* Clear all active watchdog interrupt flags */
    pBase->WTISR = ADC_SAR_WTISR_CLEAR_MASK;
#endif /* ADC_SAR_IP_WDG_ENABLED */

}

#if (STD_ON == ADC_SAR_IP_ENABLE_USER_MODE_SUPPORT)
/*FUNCTION**********************************************************************
 *
 * Function Name : Adc_Sar_SetUserAccessAllowed
 * Description   : Sets the UAA bit in REG_PROT to make the instance accessible in user mode.
 *
 *END**************************************************************************/
static void Adc_Sar_SetUserAccessAllowed(const ADC_Type * const pBase)
{
    SET_USER_ACCESS_ALLOWED((uint32)pBase, SAR_ADC_PROT_MEM_U32);
}

/*FUNCTION**********************************************************************
 *
 * Function Name : Adc_Sar_ClrUserAccessAllowed
 * Description   : Clears the UAA bit in REG_PROT to make the instance inaccessible in user mode.
 *
 *END**************************************************************************/
static void Adc_Sar_ClrUserAccessAllowed(const ADC_Type * const pBase)
{
    CLR_USER_ACCESS_ALLOWED((uint32)pBase, SAR_ADC_PROT_MEM_U32);
}
#endif /* (STD_ON == ADC_SAR_IP_ENABLE_USER_MODE_SUPPORT) */

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_Init
* Description   : This function initializes the ADC_SAR module by configuring all
* available features.
*
* @implements      Adc_Sar_Ip_Init_Activity
* END**************************************************************************/
Adc_Sar_Ip_StatusType Adc_Sar_Ip_Init(const uint32 u32Instance,
                                      const Adc_Sar_Ip_ConfigType * const pConfig)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
    ADC_SAR_DEV_ASSERT(pConfig != NULL_PTR);
#if FEATURE_ADC_HAS_CTU
#if (FEATURE_ADC_HAS_CTU_TRIGGER_MODE == 0u)
    /* test that the feature is enabled only on platforms that have it */
    ADC_SAR_DEV_ASSERT(pConfig->eCtuMode != ADC_SAR_IP_CTU_MODE_TRIGGER);
#endif /* FEATURE_ADC_HAS_CTU */
#endif /* (FEATURE_ADC_HAS_CTU_TRIGGER_MODE == 0u) */
    /* TODO
    static const clock_names_t pAdcClocks[ADC_SAR_INSTANCE_COUNT] = ADC_CLOCKS;
    uint32 u32AdcFreq = 0U;
    Adc_Sar_Ip_StatusType pClockStatus = CLOCK_DRV_GetFreq(pAdcClocks[u32Instance], &u32AdcFreq);
    ADC_SAR_DEV_ASSERT(pClockStatus == ADC_SAR_IP_STATUS_SUCCESS);
    if (pConfig->eClkSelect == ADC_SAR_IP_CLK_HALF_BUS) {
        u32AdcFreq /= 2U;
    }
    ADC_SAR_DEV_ASSERT(u32AdcFreq > 0U);
    ADC_SAR_DEV_ASSERT(u32AdcFreq <= ADC_CLOCK_FREQ_MAX_RUNTIME); */
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    Adc_Sar_Ip_StatusType eStatus = ADC_SAR_IP_STATUS_SUCCESS;
    ADC_Type * const pBase = pAdcBase[u32Instance];
    uint8 u8Index = 0u;

#if (STD_ON == ADC_SAR_IP_ENABLE_USER_MODE_SUPPORT)
    /* Set the UAA bit in REG_PROT to make the instance accessible in user mode */
    OsIf_Trusted_Call1param(Adc_Sar_SetUserAccessAllowed, pBase);
#endif

    /* Stop any conversions, if any */
    (void)Adc_Sar_Ip_AbortChain(u32Instance, TRUE, FALSE);

    /* Clear CTUEN to allow Powerdown operation to succeed. */
#if defined(ADC_MCR_CTUEN_MASK)
    pBase->MCR &= ~ADC_MCR_CTUEN_MASK;
#endif /* ADC_MCR_CTUEN_MASK */

    eStatus = Adc_Sar_Ip_Powerdown(u32Instance);
    if (eStatus != ADC_SAR_IP_STATUS_SUCCESS)
    {
        return eStatus;
    }

    /* Collects the mask and writes MCR mask */
    pBase->MCR = Adc_Sar_CollectMcrMasks(u32Instance, pConfig);

    aAdcSarState[u32Instance].eDataAlign = pConfig->eDataAlign;

    eStatus = Adc_Sar_Ip_Powerup(u32Instance);
    if (eStatus != ADC_SAR_IP_STATUS_SUCCESS)
    {
        return eStatus;
    }
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    if (ADC_INST_HAS_CTRn(u32Instance, ADC_GROUP_0))
    {
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
        CTR(pBase, ADC_GROUP_0) = ADC_CTR_INPSAMP(pConfig->aSampleTime[0u]);
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    if (ADC_INST_HAS_CTRn(u32Instance, ADC_GROUP_1))
    {
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
        CTR(pBase, ADC_GROUP_1) = ADC_CTR_INPSAMP(pConfig->aSampleTime[1u]);
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
#if ((ADC_SAR_CIMR_COUNT > 2U) || (ADC_SAR_CTR_COUNT > 2U))
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    if (ADC_INST_HAS_CTRn(u32Instance, ADC_GROUP_2))
    {
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
        CTR(pBase, ADC_GROUP_2) = ADC_CTR_INPSAMP(pConfig->aSampleTime[2]);
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
#endif /* ((ADC_SAR_CIMR_COUNT > 2U) || (ADC_SAR_CTR_COUNT > 2U)) */

    pBase->PDEDR = ADC_PDEDR_PDED(pConfig->u8PowerDownDelay);

#ifdef ADC_DSDR_DSD
#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    if (ADC_INST_HAS_DSDR(u32Instance))
    {
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_FEATURE */
#if FEATURE_ADC_SAR_DECODE_DELAY
        pBase->DSDR = ADC_DSDR_DSD(pConfig->u16DecodeDelay);
#endif /* FEATURE_ADC_SAR_DECODE_DELAY */
#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_FEATURE */
#endif /* ADC_DSDR_DSD */

    /* Configure chain conversions */
    for (u8Index = 0U; u8Index < ADC_SAR_NCMR_COUNT; u8Index++)
    {
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        if (!ADC_INST_HAS_NCMRn(u32Instance, u8Index))
        {
            continue; /* skip register if it's not available */
        }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
        NCMR(pBase, u8Index) = pConfig->pChanMaskNormal[u8Index];
    }
    for (u8Index = 0U; u8Index < ADC_SAR_JCMR_COUNT; u8Index++)
    {
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        if (!ADC_INST_HAS_JCMRn(u32Instance, u8Index))
        {
            continue; /* skip register if it's not available */
        }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
        JCMR(pBase, u8Index) = pConfig->pChanMaskInjected[u8Index];
    }

#if (ADC_SAR_IP_SET_RESOLUTION == STD_ON)
    /* Configure resolution */
    Adc_Sar_Ip_SetResolution(u32Instance, pConfig->eAdcResolution);
#endif /* (ADC_SAR_IP_SET_RESOLUTION == STD_ON) */

    /* Configure WDG */
    if ((pConfig->pWdgThresholds != NULL_PTR) && (pConfig->u8NumWdgThresholds > 0u))
    {
        for (u8Index = 0U; u8Index < pConfig->u8NumWdgThresholds; u8Index++)
        {
            Adc_Sar_Ip_SetWdgThreshold(u32Instance, pConfig->pWdgThresholds[u8Index].u8WdgIndex, &pConfig->pWdgThresholds[u8Index]);
        }
    }

    /* Configure per channel notifications and presampling */
    if ((pConfig->pChannelConfigs != NULL_PTR) && (pConfig->u8NumChannels > 0u))
    {
        Adc_Sar_EnableChannelWatchdog(u32Instance, pConfig->pChannelConfigs, pConfig->u8NumChannels);
    }

    /* Configure presampling sources */
    pBase->PSCR &= ~(ADC_PSCR_PRECONV_MASK);
    pBase->PSCR |= ADC_PSCR_PRECONV(pConfig->bBypassSampling ? 1u : 0u);

    Adc_Sar_Ip_SetPresamplingSource(u32Instance, ADC_SAR_IP_CHAN_GROUP_0, pConfig->aPresamplingSource[0u]);
    Adc_Sar_Ip_SetPresamplingSource(u32Instance, ADC_SAR_IP_CHAN_GROUP_1, pConfig->aPresamplingSource[1u]);
#if ADC_SAR_NUM_GROUP_CHAN > 2u
    Adc_Sar_Ip_SetPresamplingSource(u32Instance, ADC_SAR_IP_CHAN_GROUP_2, pConfig->aPresamplingSource[2u]);
#endif /* ADC_SAR_NUM_GROUP_CHAN > 2u */

    /* Add notification callbacks to the state structure */
    aAdcSarState[u32Instance].pfEndOfNormalChainNotification = pConfig->pfEndOfNormalChainNotification;
    aAdcSarState[u32Instance].pfEndOfInjectedChainNotification = pConfig->pfEndOfInjectedChainNotification;
#if FEATURE_ADC_HAS_CTU
    aAdcSarState[u32Instance].pfEndOfCtuConversionNotification = pConfig->pfEndOfCtuConversionNotification;
#endif /* FEATURE_ADC_HAS_CTU */
    aAdcSarState[u32Instance].pfEndOfConvNotification = pConfig->pfEndOfConvNotification;
    aAdcSarState[u32Instance].pfWdgOutOfRangeNotification = pConfig->pfWdgOutOfRangeNotification;

    aAdcSarState[u32Instance].eCalibrationClkSelect = pConfig->eCalibrationClkSelect;

    /* Set DMA clear source */
    Adc_Sar_Ip_SetDmaClearSource(u32Instance, pConfig->eDmaClearSource);

    /* Configure user gain and offset */
    pBase->ADC_USER_OFFSET_GAIN_REG = ADC_USER_OFFSET(pConfig->u8UsrOffset) | ADC_USER_GAIN(pConfig->u16UsrGain);

    /* Mark that the driver was initialized */
    aAdcSarState[u32Instance].bInit = TRUE;

    return eStatus;
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_Deinit
* Description   : This function writes all the internal ADC registers with
*  their Reference Manual reset values.
*
* @implements      Adc_Sar_Ip_DeInit_Activity
* END**************************************************************************/
Adc_Sar_Ip_StatusType Adc_Sar_Ip_Deinit(const uint32 u32Instance)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    uint8 u8Index;
    Adc_Sar_Ip_ConfigType pDefaultConfig;
    Adc_Sar_Ip_StatusType eStatus;
    ADC_Type * const pBase = pAdcBase[u32Instance];

    pDefaultConfig.eConvMode = ADC_SAR_IP_CONV_MODE_ONESHOT;
    pDefaultConfig.eClkSelect = ADC_SAR_IP_CLK_FULL_BUS;
    pDefaultConfig.eCalibrationClkSelect = ADC_SAR_IP_CLK_HALF_BUS;
#if FEATURE_ADC_HAS_CTU
    pDefaultConfig.eCtuMode = ADC_SAR_IP_CTU_MODE_DISABLED;
#endif /* FEATURE_ADC_HAS_CTU */
#if FEATURE_ADC_HAS_INJ_EXT_TRIGGER
    pDefaultConfig.eInjectedEdge = ADC_SAR_IP_EXT_TRIG_EDGE_DISABLED;
#endif /* FEATURE_ADC_HAS_INJ_EXT_TRIGGER */
#if FEATURE_ADC_HAS_EXT_TRIGGER
    pDefaultConfig.eExtTrigger = ADC_SAR_IP_EXT_TRIG_EDGE_DISABLED;
    pDefaultConfig.bNormalExtTrgEn = FALSE;
    pDefaultConfig.bNormalAuxExtTrgEn = FALSE;
#endif /* FEATURE_ADC_HAS_EXT_TRIGGER */
    for (u8Index = 0u; u8Index < ADC_SAR_NUM_GROUP_CHAN; u8Index++)
    {
        pDefaultConfig.aSampleTime[u8Index] = ADC_SAR_IP_DEF_SAMPLE_TIME;
#if (ADC_PSCR_PREVAL0_WIDTH > 1u)
        pDefaultConfig.aPresamplingSource[u8Index] = ADC_SAR_IP_PRESAMPLE_DVDD;
#else
        pDefaultConfig.aPresamplingSource[u8Index] = ADC_SAR_IP_PRESAMPLE_VREFL;
#endif /* (ADC_PSCR_PREVAL0_WIDTH > 1u) */
    }
    pDefaultConfig.bBypassSampling = FALSE;
    pDefaultConfig.bAutoClockOff = FALSE;
    pDefaultConfig.bOverwriteEnable = FALSE;
    pDefaultConfig.eDataAlign = ADC_SAR_IP_DATA_ALIGNED_RIGHT;
    #if FEATURE_ADC_SAR_DECODE_DELAY
    pDefaultConfig.u16DecodeDelay = 0u;
#endif /* FEATURE_ADC_SAR_DECODE_DELAY */
    pDefaultConfig.u8PowerDownDelay = 0u;
#if FEATURE_ADC_HAS_AVERAGING
    pDefaultConfig.bAvgEn = FALSE;
    pDefaultConfig.eAvgSel = ADC_SAR_IP_AVG_4_CONV;
#endif /* FEATURE_ADC_HAS_AVERAGING */
    pDefaultConfig.u8UsrOffset = 0u;
    pDefaultConfig.u16UsrGain = 0u;
    pDefaultConfig.eDmaClearSource = ADC_SAR_IP_DMA_REQ_CLEAR_ON_ACK;
    pDefaultConfig.u8NumChannels = 0u;
    pDefaultConfig.pChannelConfigs = NULL_PTR;
    pDefaultConfig.u8NumWdgThresholds = 0u;
    pDefaultConfig.pWdgThresholds = NULL_PTR;
    pDefaultConfig.pfEndOfNormalChainNotification = NULL_PTR;
    pDefaultConfig.pfEndOfInjectedChainNotification = NULL_PTR;
#if FEATURE_ADC_HAS_CTU
    pDefaultConfig.pfEndOfCtuConversionNotification = NULL_PTR;
#endif /* FEATURE_ADC_HAS_CTU */
    pDefaultConfig.pfEndOfConvNotification = NULL_PTR;
    pDefaultConfig.pfWdgOutOfRangeNotification = NULL_PTR;

    eStatus = Adc_Sar_Ip_Init(u32Instance, &pDefaultConfig);
    if (eStatus != ADC_SAR_IP_STATUS_SUCCESS)
    {
        return eStatus;
    }

    /* Deinit channel interrupts */
    for (u8Index = 0U; u8Index < ADC_SAR_NUM_GROUP_CHAN; u8Index++)
    {
        /* Disable all channel interrupts */
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        if (ADC_INST_HAS_CIMRn(u32Instance, u8Index))
        {
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
            CIMR(pBase, u8Index) = 0u;
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */

        /* Disable all channel interrupt flags */
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        if (ADC_INST_HAS_CEOCFRn(u32Instance, u8Index))
        {
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
            CEOCFR(pBase, u8Index) = 0xFFFFFFFFu; /* w1c bits */
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */

        /* Clear all channel presampling */
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        if (ADC_INST_HAS_PSRn(u32Instance, u8Index))
        {
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
            PSR(pBase, u8Index) = 0u;
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
    }

    /* Deinit watchdog interrupts */
    Adc_Sar_ResetWdog(u32Instance);
    pBase->WTIMR = 0u;

    Adc_Sar_Ip_ClearStatusFlags(u32Instance, ADC_SAR_IP_NOTIF_FLAG_ALL);
#if (ADC_SAR_IP_SET_RESOLUTION == STD_ON)
    /* Set default resolution */
    Adc_Sar_Ip_SetResolution(u32Instance, RESOLUTION_12);
#endif /* (ADC_SAR_IP_SET_RESOLUTION == STD_ON) */

    /* Mark that the driver was deinitialized */
    aAdcSarState[u32Instance].bInit = FALSE;

    eStatus = Adc_Sar_Ip_Powerdown(u32Instance);

#if (STD_ON == ADC_SAR_IP_ENABLE_USER_MODE_SUPPORT)
    /* Clear the UAA bit in REG_PROT to reset the elevation requirement */
    OsIf_Trusted_Call1param(Adc_Sar_ClrUserAccessAllowed, pBase);
#endif

    return eStatus;
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_ChainConfig
* Description   : This function configures the ADC Normal and Injected Chains
*  with the options provided in the structure.
*
* @implements      Adc_Sar_Ip_ChainConfig_Activity
* END**************************************************************************/
void Adc_Sar_Ip_ChainConfig(const uint32 u32Instance,
                                const Adc_Sar_Ip_ChansIdxMaskType * const pChansIdxMask,
                                const Adc_Sar_Ip_ConvChainType pChainType)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
    ADC_SAR_DEV_ASSERT(pChansIdxMask != NULL_PTR);
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    /* Enabling unavailable channels is forbidden */
    uint8 i;
    for (i = 0U; i < ADC_SAR_NUM_GROUP_CHAN; i++)
    {
        ADC_SAR_DEV_ASSERT((pChansIdxMask->aChanMask[i] & (~u32AdcChanBitmap[u32Instance][i])) == 0u);
    }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    ADC_Type * const pBase = pAdcBase[u32Instance];
    uint8 u8Index;

    switch (pChainType)
    {
        case ADC_SAR_IP_CONV_CHAIN_NORMAL:
            for (u8Index = 0U; u8Index < ADC_SAR_NCMR_COUNT; u8Index++)
            {
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
                if (!ADC_INST_HAS_NCMRn(u32Instance, u8Index))
                {
                    continue; /* skip register if it's not available */
                }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
                NCMR(pBase, u8Index) = pChansIdxMask->aChanMask[u8Index];
            }
            break;
        case ADC_SAR_IP_CONV_CHAIN_INJECTED:
            for (u8Index = 0U; u8Index < ADC_SAR_JCMR_COUNT; u8Index++)
            {
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
                if (!ADC_INST_HAS_JCMRn(u32Instance, u8Index))
                {
                    continue; /* skip register if it's not available */
                }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
                JCMR(pBase, u8Index) = pChansIdxMask->aChanMask[u8Index];
            }
            break;
        default:
            ; /* no-op */
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
            ADC_SAR_DEV_ASSERT(FALSE);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */
            break;
    }
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_EnableChannel
* Description   : This function enables a channel in a conversion chain (
*  ADC_SAR_IP_CONV_CHAIN_NORMAL or ADC_SAR_IP_CONV_CHAIN_INJECTED).
*
* @implements      Adc_Sar_Ip_EnableChannel_Activity
* END**************************************************************************/
void Adc_Sar_Ip_EnableChannel(const uint32 u32Instance,
                                const Adc_Sar_Ip_ConvChainType pChainType,
                                const uint32 u32ChnIdx)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
    ADC_SAR_DEV_ASSERT(u32ChnIdx < ADC_SAR_CDR_COUNT);
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    ADC_SAR_DEV_ASSERT(ADC_INST_HAS_CHANn(u32Instance, u32ChnIdx));
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    ADC_Type * const pBase = pAdcBase[u32Instance];

    uint32 u32VectAdr = CHAN_2_VECT(u32ChnIdx);
    uint32 u32VectBit = CHAN_2_BIT(u32ChnIdx);

    switch (pChainType)
    {
        case ADC_SAR_IP_CONV_CHAIN_NORMAL:
            SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_23();
            NCMR(pBase, u32VectAdr) |= (1UL << u32VectBit);
            SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_23();
            break;
        case ADC_SAR_IP_CONV_CHAIN_INJECTED:
            SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_26();
            JCMR(pBase, u32VectAdr) |= (1UL << u32VectBit);
            SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_26();
            break;
        default:
            ; /* no-op */
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
            ADC_SAR_DEV_ASSERT(FALSE);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */
            break;
    }
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_DisableChannel
* Description   : This function disables a channel from a conversion chain (ADC_SAR_IP_CONV_CHAIN_NORMAL
*  or ADC_SAR_IP_CONV_CHAIN_INJECTED).
*
* @implements      Adc_Sar_Ip_DisableChannel_Activity
* END**************************************************************************/
void Adc_Sar_Ip_DisableChannel(const uint32 u32Instance,
                                const Adc_Sar_Ip_ConvChainType pChainType,
                                const uint32 u32ChnIdx)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
    ADC_SAR_DEV_ASSERT(u32ChnIdx < ADC_SAR_CDR_COUNT);
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    ADC_SAR_DEV_ASSERT(ADC_INST_HAS_CHANn(u32Instance, u32ChnIdx));
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */
    ADC_Type * const pBase = pAdcBase[u32Instance];

    uint32 u32VectAdr = CHAN_2_VECT(u32ChnIdx);
    uint32 u32VectBit = CHAN_2_BIT(u32ChnIdx);

    switch (pChainType)
    {
        case ADC_SAR_IP_CONV_CHAIN_NORMAL:
            SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_24();
            NCMR(pBase, u32VectAdr) &= ~(1UL << u32VectBit);
            SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_24();
            break;
        case ADC_SAR_IP_CONV_CHAIN_INJECTED:
            SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_27();
            JCMR(pBase, u32VectAdr) &= ~(1UL << u32VectBit);
            SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_27();
            break;
        default:
            ; /* no-op */
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
            ADC_SAR_DEV_ASSERT(FALSE);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */
            break;
    }
}

#if (ADC_SAR_IP_SET_RESOLUTION == STD_ON)
/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_SetResolution
* Description   : This function sets the conversion resolution (number of bits per conversion data)
*
* @implements      Adc_Sar_Ip_SetResolution_Activity
* END**************************************************************************/
void Adc_Sar_Ip_SetResolution(const uint32 u32Instance,
                              const Adc_Sar_Ip_Resolution eResolution)
{

    ADC_Type * const pBase = pAdcBase[u32Instance];

#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
    /* The selected ADC should be in IDLE state */
    ADC_SAR_DEV_ASSERT((pBase->MSR & ADC_MSR_ADCSTATUS_MASK) == ADC_MSR_ADCSTATUS(0UL));
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_37();
    uint32 u32Calbistreg = pBase->CALBISTREG;
    /* Clear the bits and set resolution value */
    u32Calbistreg &= ~(ADC_CALBISTREG_RESN_MASK);
    u32Calbistreg |= ADC_CALBISTREG_RESN(eResolution);
    pBase->CALBISTREG = u32Calbistreg;
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_37();
}
#endif /* (ADC_SAR_IP_SET_RESOLUTION == STD_ON) */

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_StartConversion
* Description   : This function starts a conversion chain (ADC_SAR_IP_CONV_CHAIN_NORMAL
*  or ADC_SAR_IP_CONV_CHAIN_INJECTED).
*
* @implements      Adc_Sar_Ip_StartConversion_Activity
* END**************************************************************************/
void Adc_Sar_Ip_StartConversion(const uint32 u32Instance,
                                const Adc_Sar_Ip_ConvChainType pChainType)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    ADC_Type * const pBase = pAdcBase[u32Instance];
    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_10();
    switch (pChainType)
    {
        case ADC_SAR_IP_CONV_CHAIN_NORMAL:
            pBase->MCR |= ADC_MCR_NSTART(1U);
            break;
        case ADC_SAR_IP_CONV_CHAIN_INJECTED:
            pBase->MCR |= ADC_MCR_JSTART(1U);
            break;
        default:
            ; /* no-op */
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
            ADC_SAR_DEV_ASSERT(FALSE);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */
            break;
    }
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_10();
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_GetStatusFlags
* Description   : This function returns the status flags of the ADC.
*
* @implements      Adc_Sar_Ip_GetStatusFlags_Activity
* END**************************************************************************/
uint32 Adc_Sar_Ip_GetStatusFlags(const uint32 u32Instance)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    uint32 u32Flags = 0U;

    /* Returns the flag status from MSR register */
    u32Flags |= Adc_Sar_GetMsrFlags(u32Instance);
    /* Returns the flag status from ISR register */
    u32Flags |= Adc_Sar_GetIsrFlags(u32Instance);

    return u32Flags;
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_ClearStatusFlags
* Description   : This function clears the status flags that are set to '1' in
*  the mask.
*
* @implements      Adc_Sar_Ip_ClearStatusFlags_Activity
* END**************************************************************************/
void Adc_Sar_Ip_ClearStatusFlags(const uint32 u32Instance,
                                const uint32 u32Mask)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
    ADC_SAR_DEV_ASSERT((u32Mask & (~ADC_SAR_IP_NOTIF_FLAG_ALL)) == 0UL);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    ADC_Type * const pBase = pAdcBase[u32Instance];
    uint32 u32IsrFlags = 0U;
    u32IsrFlags |= ((u32Mask & ADC_SAR_IP_NOTIF_FLAG_NORMAL_EOC) != 0U) ? ADC_ISR_EOC(1U) : 0U;
    u32IsrFlags |= ((u32Mask & ADC_SAR_IP_NOTIF_FLAG_NORMAL_ENDCHAIN) != 0U) ? ADC_ISR_ECH(1U) : 0U;
    u32IsrFlags |= ((u32Mask & ADC_SAR_IP_NOTIF_FLAG_INJECTED_EOC) != 0U) ? ADC_ISR_JEOC(1U) : 0U;
    u32IsrFlags |= ((u32Mask & ADC_SAR_IP_NOTIF_FLAG_INJECTED_ENDCHAIN) != 0U) ? ADC_ISR_JECH(1U) : 0U;
#if FEATURE_ADC_HAS_CTU
#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    if (ADC_INST_HAS_CTU(u32Instance))
    {
#endif /*FEATURE_ADC_BAD_ACCESS_PROT_FEATURE*/
        u32IsrFlags |= ((u32Mask & ADC_SAR_IP_NOTIF_FLAG_CTU_EOC) != 0U) ? ADC_ISR_EOCTU(1U) : 0U;
#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    }
#endif /*FEATURE_ADC_BAD_ACCESS_PROT_FEATURE*/
#endif /* FEATURE_ADC_HAS_CTU */

    /* Write-1-to-clear bits in ISR register */
    pBase->ISR = u32IsrFlags;
#ifdef FEATURE_CPU_HAS_WRITE_BUFFER
    (void) pBase->ISR;
#endif /* FEATURE_CPU_HAS_WRITE_BUFFER */
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_SelfTest
* Description   : This function executes a self test on the ADC instance.
*
* @implements      Adc_Sar_Ip_SelfTest_Activity
* END**************************************************************************/
Adc_Sar_Ip_StatusType Adc_Sar_Ip_SelfTest(const uint32 u32Instance)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    ADC_Type * const pBase = pAdcBase[u32Instance];
    Adc_Sar_Ip_StatusType eStatus = ADC_SAR_IP_STATUS_SUCCESS;
    uint32 u32Reg, u32MsrStatus;
    uint32 u32TimeoutTicks = OsIf_MicrosToTicks(ADC_SAR_IP_TIMEOUT_VAL, ADC_SAR_IP_TIMEOUT_TYPE);
    uint32 u32CurrentTicks = OsIf_GetCounter(ADC_SAR_IP_TIMEOUT_TYPE);
    uint32 u32ElapsedTicks = 0U;
#if FEATURE_ADC_SELFTEST_FULL_CLK
    uint32 u32AdcClkSel = 0u;
#endif /* FEATURE_ADC_SELFTEST_FULL_CLK */

#if FEATURE_ADC_SELFTEST_FULL_CLK
    /* Enter into power-down Mode */
    eStatus = Adc_Sar_Ip_Powerdown(u32Instance);
    if (eStatus != ADC_SAR_IP_STATUS_SUCCESS)
    {
        return eStatus;
    }

    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_11();
    /* Save the current state of ADCLKSEL in order to restore it */
    u32AdcClkSel = (pBase->MCR & ADC_MCR_ADCLKSEL_MASK);
    /* ADC self-test should be run with MCR[ADCLKSE] bit set to 1 */
    pBase->MCR &= ~(ADC_MCR_ADCLKSEL_MASK);
    pBase->MCR |= ADC_MCR_ADCLKSEL(1U);
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_11();

    /* Exit into power-down Mode */
    eStatus = Adc_Sar_Ip_Powerup(u32Instance);
    if (eStatus != ADC_SAR_IP_STATUS_SUCCESS)
    {
        return eStatus;
    }
#endif /* FEATURE_ADC_SELFTEST_FULL_CLK */

    /* 1. Program NCMR0 to select channels to be converted for normal conversion.*/
    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_25();
    NCMR(pBase, 0u) |= ADC_NCMR_CH0(0x1UL);
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_25();

    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_11();
    /* Self-test will only run with CPU mode so clear CTU enable */
#if defined(ADC_MCR_CTUEN_MASK)
    pBase->MCR &= ~ADC_MCR_CTUEN_MASK;
#endif /* ADC_MCR_CTUEN_MASK */

    /* 2. Program MCR[MODE] = 1 to select Scan mode. ADC_ONE_SHOT_MODE_U32 ADCDIG_CONTINUOUS_MODE_U32*/
    pBase->MCR |= ADC_MCR_MODE(0x1UL);
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_11();

    /* 3. Program sampling duration values in STCR1[INPSAMPx].*/
    u32Reg = 0u;
    u32Reg |= ADC_STCR1_INPSAMP_S(0x10UL) | ADC_STCR1_INPSAMP_C(0x10UL);
    pBase->STCR1 = u32Reg;

    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_35();
    /* 4. Select the self-testing algorithm in STCR3[ALG]. */
    pBase->STCR3 |= ADC_STCR3_ALG(0x3UL);

    /* 5. Enable the self-testing channel by setting STCR2[EN]. */
    pBase->STCR2 |= ADC_STCR2_EN(0x1UL);
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_35();

    /* 6. Start the normal conversion by setting MCR[NSTART]. */
    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_11();
    pBase->MCR |= ADC_MCR_NSTART(0x1UL);
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_11();

    /*  Check that all algorithms have executed at least once. */
    eStatus = Adc_Sar_CheckSelfTestProgress(u32Instance);

    /* Stop the conversion */
    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_11();
    pBase->MCR &= ~(ADC_MCR_NSTART(0x1UL));
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_11();

    /* Read ADC status */
    u32MsrStatus = (pBase->MSR & ADC_MSR_ADCSTATUS_MASK) >> ADC_MSR_ADCSTATUS_SHIFT;
    /* Wait for ADC changes to the expected Idle mode, The bitfield MSR[ADCSTATUS] should be checked to Idle state when MCR[NSTART] is written to 0 */
    u32ElapsedTicks = 0U;
    while ((u32MsrStatus != ADC_MSR_ADCSTATUS(0UL)) && (u32ElapsedTicks < u32TimeoutTicks))
    {
        u32MsrStatus = (pBase->MSR & ADC_MSR_ADCSTATUS_MASK) >> ADC_MSR_ADCSTATUS_SHIFT;
        u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, ADC_SAR_IP_TIMEOUT_TYPE);
    }

    /* Disable Self-test */
    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_35();
    pBase->STCR2 &= ~(ADC_STCR2_EN(0x1UL));
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_35();

#if FEATURE_ADC_SELFTEST_FULL_CLK
    /* Enter into power-down Mode */
    eStatus = Adc_Sar_Ip_Powerdown(u32Instance);
    if (eStatus != ADC_SAR_IP_STATUS_SUCCESS)
    {
        return eStatus;
    }

    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_11();
    /* Restore the state of ADCLKSEL */
    pBase->MCR &= ~(ADC_MCR_ADCLKSEL_MASK);
    pBase->MCR |= u32AdcClkSel;
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_11();

    /* Exit into power-down Mode */
    eStatus = Adc_Sar_Ip_Powerup(u32Instance);
    if (eStatus != ADC_SAR_IP_STATUS_SUCCESS)
    {
        return eStatus;
    }
#endif /* FEATURE_ADC_SELFTEST_FULL_CLK */

    if (u32ElapsedTicks >= u32TimeoutTicks)
    {
        eStatus = ADC_SAR_IP_STATUS_TIMEOUT;
    }

    return eStatus;
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_GetConvDataToArray
* Description   : This function reads the conversion result values for a conversion chain
*  (ADC_SAR_IP_CONV_CHAIN_NORMAL, ADC_SAR_IP_CONV_CHAIN_INJECTED or ADC_SAR_IP_CONV_CHAIN_CTU).
*
* @implements      Adc_Sar_Ip_GetConvDataToArray_Activity
* END**************************************************************************/
uint32 Adc_Sar_Ip_GetConvDataToArray(const uint32 u32Instance,
                                const Adc_Sar_Ip_ConvChainType pChainType,
                                const uint32 u32Length,
                                uint16 * const pResults)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */
    return Adc_Sar_GetConvResults(u32Instance, pChainType, pResults, NULL_PTR, u32Length);
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_GetConvResultsToArray
* Description   : This function gets the conversion results for the selected
*  Conversion Chain. It follows the same algorithm as Adc_Sar_Ip_GetConvDataToArray,
*  but will copy some extra information to the output.
*
* @implements      Adc_Sar_Ip_GetConvResultsToArray_Activity
* END**************************************************************************/
uint32 Adc_Sar_Ip_GetConvResultsToArray(const uint32 u32Instance,
                                const Adc_Sar_Ip_ConvChainType pChainType,
                                const uint32 u32Length,
                                Adc_Sar_Ip_ChanResultType* const pResults)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */
    return Adc_Sar_GetConvResults(u32Instance, pChainType, NULL_PTR, pResults, u32Length);
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_GetConvData
* Description   : This function returns the result of the conversion for
* a single channel
*
* @implements      Adc_Sar_Ip_GetConvData_Activity
* END**************************************************************************/
uint16 Adc_Sar_Ip_GetConvData(const uint32 u32Instance,
                                const uint32 u32ChnIdx)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
    ADC_SAR_DEV_ASSERT(u32ChnIdx < ADC_SAR_CDR_COUNT);
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    ADC_SAR_DEV_ASSERT(ADC_INST_HAS_CHANn(u32Instance, u32ChnIdx));
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    uint16 u16Result = 0U;
    ADC_Type * const pBase = pAdcBase[u32Instance];

    uint32 u32VectAdr = CHAN_2_VECT(u32ChnIdx);
    uint32 u32VectBit = CHAN_2_BIT(u32ChnIdx);

    /* check if the conversion data is valid */
    uint32 u32Cdr = CDR(pBase, u32ChnIdx);
    if (((u32Cdr & ADC_CDR_VALID_MASK) != 0U))
    {
        /* the data is correct, store the result in and clear the flag */
        u16Result = Adc_Sar_GetMaskedResult(u32Instance, u32Cdr);
        CEOCFR(pBase, u32VectAdr) = ((uint32)1UL << u32VectBit); /* w1c bit */
    }

    return u16Result;
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_GetConvResult
* Description   : This function returns the result and the status of
* the conversion for a single channel
*
* @implements      Adc_Sar_Ip_GetConvResult_Activity
* END**************************************************************************/
void Adc_Sar_Ip_GetConvResult(const uint32 u32Instance,
                              const uint32 u32ChnIdx,
                              const Adc_Sar_Ip_ConvChainType pChainType,
                              Adc_Sar_Ip_ChanResultType * const pResult)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
    ADC_SAR_DEV_ASSERT(u32ChnIdx < ADC_SAR_CDR_COUNT);
    ADC_SAR_DEV_ASSERT(pResult != NULL_PTR);
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    ADC_SAR_DEV_ASSERT(ADC_INST_HAS_CHANn(u32Instance, u32ChnIdx));
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    ADC_Type * const pBase = pAdcBase[u32Instance];

    uint32 u32VectAdr = CHAN_2_VECT(u32ChnIdx);
    uint32 u32VectBit = CHAN_2_BIT(u32ChnIdx);

    pResult->u16ConvData = 0u;
    pResult->u8ChnIdx = (uint8)u32ChnIdx;
    pResult->bValid = FALSE;
    pResult->bOverWritten = FALSE;

    uint32 u32Cdr = CDR(pBase, u32ChnIdx);
    /* check if the result type matches the one request by pChainType */
    if ((ADC_CDR_RESULT((uint32)pChainType) == (u32Cdr & ADC_CDR_RESULT_MASK)))
    {
        /* check if the the conversion data is valid */
        if (((u32Cdr & ADC_CDR_VALID_MASK) != 0U))
        {
            /* the data is correct, store the result in and clear the flag */
            pResult->bValid = TRUE;
            pResult->bOverWritten = (((u32Cdr & ADC_CDR_OVERW_MASK) >> ADC_CDR_OVERW_SHIFT) == 1U);
            pResult->u16ConvData = Adc_Sar_GetMaskedResult(u32Instance, u32Cdr);
        }
    }
    CEOCFR(pBase, u32VectAdr) = ((uint32)1UL << u32VectBit); /* w1c bit */
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_DoCalibration
* Description   : This functions executes a calibration sequence. It is recommended
*  to run this sequence before using the ADC converter. The maximum clock frequency
*  for the calibration is 40 MHz, this function sets the ADCLKSEL bit resulting in
*  a maximum input clock frequency of 80 MHz.
*
* @implements      Adc_Sar_Ip_DoCalibration_Activity
* END**************************************************************************/
Adc_Sar_Ip_StatusType Adc_Sar_Ip_DoCalibration(const uint32 u32Instance)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
/*  TODO: remove or update these lines when clock is added */
    /* clock_names_t pAdcClocks[ADC_SAR_INSTANCE_COUNT] = ADC_CLOCKS
       uint32 u32AdcFreq = 0U
       Adc_Sar_Ip_StatusType pClockStatus = CLOCK_DRV_GetFreq
       ADC_SAR_DEV_ASSERT pClockStatus == ADC_SAR_IP_STATUS_SUCCESS */
    /* half bus speed will be used during calibration */
    /* u32AdcFreq = 2u
       ADC_SAR_DEV_ASSERT u32AdcFreq > 0U
       ADC_SAR_DEV_ASSERT u32AdcFreq <= ADC_CLOCK_FREQ_MAX_CALIBRATION */
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    Adc_Sar_Ip_StatusType eStatus = ADC_SAR_IP_STATUS_SUCCESS;
    Adc_Sar_Ip_StatusType eCalStatus = ADC_SAR_IP_STATUS_SUCCESS;
    ADC_Type * const pBase = pAdcBase[u32Instance];
    uint32 u32TimeoutTicks = OsIf_MicrosToTicks(ADC_SAR_IP_TIMEOUT_VAL, ADC_SAR_IP_TIMEOUT_TYPE);
    uint32 u32CurrentTicks = OsIf_GetCounter(ADC_SAR_IP_TIMEOUT_TYPE);
    uint32 u32ElapsedTicks = 0u;
    uint32 u32AdcClkSel = 0u;

    /* Set CLKSEL to eCalibrationClkSelect value */
    eStatus = Adc_Sar_Ip_Powerdown(u32Instance);
    if (eStatus != ADC_SAR_IP_STATUS_SUCCESS)
    {
        return eStatus;
    }
    /* Save the current state of ADCLKSEL in order to restore it */
    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_12();
    u32AdcClkSel = (pBase->MCR & ADC_MCR_ADCLKSEL_MASK);
    pBase->MCR &= ~(ADC_MCR_ADCLKSEL_MASK);
    pBase->MCR |= ADC_MCR_ADCLKSEL(aAdcSarState[u32Instance].eCalibrationClkSelect);
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_12();

    eStatus = Adc_Sar_Ip_Powerup(u32Instance);
    if (eStatus != ADC_SAR_IP_STATUS_SUCCESS)
    {
        return eStatus;
    }

#if ADC_CALIBRATION_USES_MCR

    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_12();
    /* Clear the bits and set to calibration values */
    pBase->MCR &= ~(ADC_MCR_TSAMP_MASK | ADC_MCR_NRSMPL_MASK | ADC_MCR_AVGEN_MASK);
    pBase->MCR |= ADC_MCR_NRSMPL(0x03u) | ADC_MCR_AVGEN(1U);

    /* Start calibration */
    pBase->MCR |= ADC_MCR_CALSTART(1U);
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_12();

    /* Wait for calibration to finish */
    while (((pBase->MSR & ADC_MSR_CALBUSY_MASK) != 0U) && (u32ElapsedTicks < u32TimeoutTicks))
    {
        u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, ADC_SAR_IP_TIMEOUT_TYPE);
    }

    if (u32ElapsedTicks >= u32TimeoutTicks)
    {
        eCalStatus = ADC_SAR_IP_STATUS_TIMEOUT;
    }
    else if ((pBase->MSR & ADC_MSR_CALFAIL_MASK) != 0U)
    {
        /* If the calibration failed, return error */
        eCalStatus = ADC_SAR_IP_STATUS_ERROR;
    }
    else
    {
        ; /* Empty else branch to avoid MISRA */
    }
#else
    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_36();
    uint32 u32Calbistreg = pBase->CALBISTREG;
    /* clear the bits and set to calibration values */
    u32Calbistreg &= ~(ADC_CALBISTREG_TSAMP_MASK | ADC_CALBISTREG_NR_SMPL_MASK | ADC_CALBISTREG_AVG_EN_MASK | ADC_CALBISTREG_TEST_EN_MASK);
    u32Calbistreg |= ADC_CALBISTREG_NR_SMPL(0x03u) | ADC_CALBISTREG_AVG_EN(1U);
    pBase->CALBISTREG = u32Calbistreg;
    /* clear the calibration failed before a new calibration */
    pBase->CALBISTREG |= ADC_CALBISTREG_TEST_FAIL_MASK;
    /* start calibration */
    pBase->CALBISTREG |= ADC_CALBISTREG_TEST_EN(1U);
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_36();

    /* Wait for calibration to finish */
    u32ElapsedTicks = 0U;
    while (((pBase->CALBISTREG & ADC_CALBISTREG_C_T_BUSY_MASK) != 0U) && (u32ElapsedTicks < u32TimeoutTicks))
    {
        u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, ADC_SAR_IP_TIMEOUT_TYPE);
    }
    if (u32ElapsedTicks >= u32TimeoutTicks)
    {
        eCalStatus = ADC_SAR_IP_STATUS_TIMEOUT;
    }
    else if ((pBase->CALBISTREG & ADC_CALBISTREG_TEST_FAIL_MASK) != 0U)
    {
        /* If the calibration failed, return error */
        eCalStatus = ADC_SAR_IP_STATUS_ERROR;
    }
    else
    {
        ; /* Empty else branch to avoid MISRA */
    }
#endif /* ADC_CALIBRATION_USES_MCR */

    /* Restore the state of ADCLKSEL */
    eStatus = Adc_Sar_Ip_Powerdown(u32Instance);
    if (eStatus != ADC_SAR_IP_STATUS_SUCCESS)
    {
        return eStatus;
    }
    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_12();
    pBase->MCR &= ~(ADC_MCR_ADCLKSEL_MASK);
    pBase->MCR |= u32AdcClkSel;
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_12();
    eStatus = Adc_Sar_Ip_Powerup(u32Instance);

    if (eCalStatus != ADC_SAR_IP_STATUS_SUCCESS)
    {
        eStatus = eCalStatus;
    }

    return eStatus;
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_Powerup
* Description   : This function enables the ADC module (by clearing the Powerdown
*  bit).
*
* @implements      Adc_Sar_Ip_Powerup_Activity
* END**************************************************************************/
Adc_Sar_Ip_StatusType Adc_Sar_Ip_Powerup(const uint32 u32Instance)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    ADC_Type * const pBase = pAdcBase[u32Instance];
    Adc_Sar_Ip_StatusType eStatus = ADC_SAR_IP_STATUS_SUCCESS;
    uint32 u32ExpectedStatus = ADC_MSR_ADCSTATUS(0UL);  /* expected status is IDLE (0) */
    uint32 u32Status = pBase->MSR & ADC_MSR_ADCSTATUS_MASK;
    uint32 u32TimeoutTicks = OsIf_MicrosToTicks(ADC_SAR_IP_TIMEOUT_VAL, ADC_SAR_IP_TIMEOUT_TYPE);
    uint32 u32CurrentTicks = OsIf_GetCounter(ADC_SAR_IP_TIMEOUT_TYPE);
    uint32 u32ElapsedTicks = 0u;

    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_13();
    Adc_Sar_Powerup(pBase);
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_13();

    /* Wait for the device to power up */
    while ((u32Status != u32ExpectedStatus) && (u32ElapsedTicks < u32TimeoutTicks))
    {
        u32Status = pBase->MSR & ADC_MSR_ADCSTATUS_MASK;
        u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, ADC_SAR_IP_TIMEOUT_TYPE);
    }
    if (u32ElapsedTicks >= u32TimeoutTicks)
    {
        eStatus = ADC_SAR_IP_STATUS_TIMEOUT;
    }

    return eStatus;
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_Powerdown
* Description   : This function disables the ADC module (by setting the Powerdown
*  bit).
*
* @implements      Adc_Sar_Ip_Powerdown_Activity
* END**************************************************************************/
Adc_Sar_Ip_StatusType Adc_Sar_Ip_Powerdown(const uint32 u32Instance)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    ADC_Type * const pBase = pAdcBase[u32Instance];
    Adc_Sar_Ip_StatusType eStatus = ADC_SAR_IP_STATUS_SUCCESS;
    uint32 u32ExpectedStatus = ADC_MSR_ADCSTATUS(1UL);  /* expected status is powered down (1) */
    uint32 u32Status = pBase->MSR & ADC_MSR_ADCSTATUS_MASK;
    uint32 u32TimeoutTicks = OsIf_MicrosToTicks(ADC_SAR_IP_TIMEOUT_VAL, ADC_SAR_IP_TIMEOUT_TYPE);
    uint32 u32CurrentTicks = OsIf_GetCounter(ADC_SAR_IP_TIMEOUT_TYPE);
    uint32 u32ElapsedTicks = 0u;

    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_14();
    Adc_Sar_Powerdown(pBase);
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_14();

    /* Wait for the device to power down */
    while ((u32Status != u32ExpectedStatus) && (u32ElapsedTicks < u32TimeoutTicks))
    {
        u32Status = pBase->MSR & ADC_MSR_ADCSTATUS_MASK;
        u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, ADC_SAR_IP_TIMEOUT_TYPE);
    }
    if (u32ElapsedTicks >= u32TimeoutTicks)
    {
        eStatus = ADC_SAR_IP_STATUS_TIMEOUT;
    }

    return eStatus;
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_EnableNotifications
* Description   : This function enables the ADC notifications set to '1' in the
*  mask parameter.
*
* @implements      Adc_Sar_Ip_EnableNotifications_Activity
* END**************************************************************************/
void Adc_Sar_Ip_EnableNotifications(const uint32 u32Instance,
                                const uint32 u32NotificationMask)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
    ADC_SAR_DEV_ASSERT((u32NotificationMask & (~ADC_SAR_IP_NOTIF_FLAG_ALL)) == 0UL);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    ADC_Type * const pBase = pAdcBase[u32Instance];

    uint32 u32ImrFlags = 0U;
    u32ImrFlags |= ((u32NotificationMask & ADC_SAR_IP_NOTIF_FLAG_NORMAL_EOC) != 0U) ? ADC_IMR_MSKEOC(1U) : 0U;
    u32ImrFlags |= ((u32NotificationMask & ADC_SAR_IP_NOTIF_FLAG_NORMAL_ENDCHAIN) != 0U) ? ADC_IMR_MSKECH(1U) : 0U;
    u32ImrFlags |= ((u32NotificationMask & ADC_SAR_IP_NOTIF_FLAG_INJECTED_EOC) != 0U) ? ADC_IMR_MSKJEOC(1U) : 0U;
    u32ImrFlags |= ((u32NotificationMask & ADC_SAR_IP_NOTIF_FLAG_INJECTED_ENDCHAIN) != 0U) ? ADC_IMR_MSKJECH(1U) : 0U;
#if FEATURE_ADC_HAS_CTU
#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    if (ADC_INST_HAS_CTU(u32Instance))
    {
#endif /*FEATURE_ADC_BAD_ACCESS_PROT_FEATURE*/
        u32ImrFlags |= ((u32NotificationMask & ADC_SAR_IP_NOTIF_FLAG_CTU_EOC) != 0U) ? ADC_IMR_MSKEOCTU(1U) : 0U;
#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    }
#endif /*FEATURE_ADC_BAD_ACCESS_PROT_FEATURE*/
#endif /* FEATURE_ADC_HAS_CTU */
    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_33();
    pBase->IMR |= u32ImrFlags;
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_33();
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_DisableNotifications
* Description   : This function disables the ADC notifications set to '1' in the
*  mask parameter.
*
* @implements      Adc_Sar_Ip_DisableNotifications_Activity
* END**************************************************************************/
void Adc_Sar_Ip_DisableNotifications(const uint32 u32Instance,
                                const uint32 u32NotificationMask)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
    ADC_SAR_DEV_ASSERT((u32NotificationMask & (~ADC_SAR_IP_NOTIF_FLAG_ALL)) == 0UL);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    ADC_Type * const pBase = pAdcBase[u32Instance];

    uint32 u32ImrFlags = 0U;
    u32ImrFlags |= ((u32NotificationMask & ADC_SAR_IP_NOTIF_FLAG_NORMAL_EOC) != 0U) ? ADC_IMR_MSKEOC(1U) : 0U;
    u32ImrFlags |= ((u32NotificationMask & ADC_SAR_IP_NOTIF_FLAG_NORMAL_ENDCHAIN) != 0U) ? ADC_IMR_MSKECH(1U) : 0U;
    u32ImrFlags |= ((u32NotificationMask & ADC_SAR_IP_NOTIF_FLAG_INJECTED_EOC) != 0U) ? ADC_IMR_MSKJEOC(1U) : 0U;
    u32ImrFlags |= ((u32NotificationMask & ADC_SAR_IP_NOTIF_FLAG_INJECTED_ENDCHAIN) != 0U) ? ADC_IMR_MSKJECH(1U) : 0U;
#if FEATURE_ADC_HAS_CTU
#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    if (ADC_INST_HAS_CTU(u32Instance))
    {
#endif /*FEATURE_ADC_BAD_ACCESS_PROT_FEATURE*/
        u32ImrFlags |= ((u32NotificationMask & ADC_SAR_IP_NOTIF_FLAG_CTU_EOC) != 0U) ? ADC_IMR_MSKEOCTU(1U) : 0U;
#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    }
#endif /*FEATURE_ADC_BAD_ACCESS_PROT_FEATURE*/
#endif /* FEATURE_ADC_HAS_CTU */
    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_34();
    pBase->IMR &= ~(u32ImrFlags);
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_34();
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_EnableChannelNotifications
* Description   : This function enables End-of-Conversion and watchdog
* interrupts generation for a single channel.
*
* @implements      Adc_Sar_Ip_EnableChannelNotifications_Activity
* END**************************************************************************/
void Adc_Sar_Ip_EnableChannelNotifications(const uint32 u32Instance,
                                const uint32 u32ChnIdx,
                                const uint32 u32Mask)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
    ADC_SAR_DEV_ASSERT(u32ChnIdx < ADC_SAR_CDR_COUNT);
    ADC_SAR_DEV_ASSERT((u32Mask & ~(ADC_SAR_IP_CHAN_NOTIF_FLAG_ALL)) == 0UL);
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    ADC_SAR_DEV_ASSERT(ADC_INST_HAS_CHANn(u32Instance, u32ChnIdx));
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    ADC_Type * const pBase = pAdcBase[u32Instance];

    uint32 u32VectAdr = CHAN_2_VECT(u32ChnIdx);
    uint32 u32VectBit = CHAN_2_BIT(u32ChnIdx);

    if ((u32Mask & ADC_SAR_IP_CHAN_NOTIF_EOC) != 0u)
    {
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        if (ADC_INST_HAS_CIMRn(u32Instance, u32VectAdr))
        {
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
            SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_30();
            CIMR(pBase, u32VectAdr) |= 1UL << u32VectBit;
            SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_30();
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
    }
    if ((u32Mask & ADC_SAR_IP_CHAN_NOTIF_WDG) != 0u)
    {
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        if (ADC_INST_HAS_CWENRn(u32Instance, u32VectAdr))
        {
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
            SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_28();
            CWENR(pBase, u32VectAdr) |= 1UL << u32VectBit;
            SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_28();
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
    }
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_DisableChannelNotifications
* Description   : This function disables End-of-Conversion and watchdog
* interrupts generation for a single channel.
*
* @implements      Adc_Sar_Ip_DisableChannelNotifications_Activity
* END**************************************************************************/
void Adc_Sar_Ip_DisableChannelNotifications(const uint32 u32Instance,
                                            const uint32 u32ChnIdx,
                                            const uint32 u32Mask)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
    ADC_SAR_DEV_ASSERT(u32ChnIdx < ADC_SAR_CDR_COUNT);
    ADC_SAR_DEV_ASSERT((u32Mask & ~(ADC_SAR_IP_CHAN_NOTIF_FLAG_ALL)) == 0UL);
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    ADC_SAR_DEV_ASSERT(ADC_INST_HAS_CHANn(u32Instance, u32ChnIdx));
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    ADC_Type * const pBase = pAdcBase[u32Instance];

    uint32 u32VectAdr = CHAN_2_VECT(u32ChnIdx);
    uint32 u32VectBit = CHAN_2_BIT(u32ChnIdx);

    if ((u32Mask & ADC_SAR_IP_CHAN_NOTIF_EOC) != 0u)
    {
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        if (ADC_INST_HAS_CIMRn(u32Instance, u32VectAdr))
        {
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
            SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_31();
            CIMR(pBase, u32VectAdr) &= ~(1UL << u32VectBit);
            SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_31();
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
    }
    if ((u32Mask & ADC_SAR_IP_CHAN_NOTIF_WDG) != 0u)
    {
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        if (ADC_INST_HAS_CWENRn(u32Instance, u32VectAdr))
        {
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
            SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_29();
            CWENR(pBase, u32VectAdr) &= ~(1UL << u32VectBit);
            SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_29();
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
    }
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_SetClockMode
* Description   : This function initializes the ADC clock configuration.
*
* @implements      Adc_Sar_Ip_SetClockMode_Activity
* END**************************************************************************/
Adc_Sar_Ip_StatusType Adc_Sar_Ip_SetClockMode(const uint32 u32Instance,
                                const Adc_Sar_Ip_ClockConfigType * const pConfig)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
    ADC_SAR_DEV_ASSERT(pConfig != NULL_PTR);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    Adc_Sar_Ip_StatusType eStatus = ADC_SAR_IP_STATUS_SUCCESS;
    ADC_Type * const pBase = pAdcBase[u32Instance];

    /* Read MCR value and clear values that will be replaced */
    uint32 u32Mcr = 0u;

#if FEATURE_ADC_HAS_CLKSEL_EXTENDED
    u32Mcr |= ADC_MCR_ADCLKSEL(pConfig->eClkSelect);
#else
    switch (pConfig->eClkSelect)
    {
        case ADC_SAR_IP_CLK_FULL_BUS:
            /* Full bus clock when MCR[ADCLKSEL] = 1 */
            u32Mcr |= ADC_MCR_ADCLKSEL(1u);
            break;
        case ADC_SAR_IP_CLK_HALF_BUS:
            /* Half bus clock when MCR[ADCLKSEL] = 0 */
            break;
        default:
            /* no-op */
            break;
    }
#endif /* FEATURE_ADC_HAS_CLKSEL_EXTENDED */

    eStatus = Adc_Sar_Ip_Powerdown(u32Instance);
    if (eStatus != ADC_SAR_IP_STATUS_SUCCESS)
    {
        return eStatus;
    }
    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_15();
    pBase->MCR = (pBase->MCR & ~(ADC_MCR_ADCLKSEL_MASK)) | u32Mcr;
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_15();

    eStatus = Adc_Sar_Ip_Powerup(u32Instance);
    if (eStatus != ADC_SAR_IP_STATUS_SUCCESS)
    {
        return eStatus;
    }

#if FEATURE_ADC_HAS_AVERAGING
    Adc_Sar_Ip_SetAveraging(u32Instance, pConfig->bAvgEn, pConfig->eAvgSel);
#endif /* FEATURE_ADC_HAS_AVERAGING */

    /* Set powerdown delay */
    pBase->PDEDR = ADC_PDEDR_PDED(pConfig->u8PowerDownDelay);

    /* Set sample times */
    Adc_Sar_Ip_SetSampleTimes(u32Instance, pConfig->aSampleTime);

    return eStatus;
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_SetSampleTimes
* Description   : This function sets the sample times for each channnel group.
*
* @implements      Adc_Sar_Ip_SetSampleTimes_Activity
* END**************************************************************************/
void Adc_Sar_Ip_SetSampleTimes(const uint32 u32Instance,
                                const uint8 * const aSampleTimes)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    ADC_Type * const pBase = pAdcBase[u32Instance];

    /* Set sample times */
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    if (ADC_INST_HAS_CTRn(u32Instance, ADC_GROUP_0))
    {
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
        CTR(pBase, ADC_GROUP_0) = ADC_CTR_INPSAMP(aSampleTimes[0u]);
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    if (ADC_INST_HAS_CTRn(u32Instance, ADC_GROUP_1))
    {
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
        CTR(pBase, ADC_GROUP_1) = ADC_CTR_INPSAMP(aSampleTimes[1u]);
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
#if ((ADC_SAR_CIMR_COUNT > 2U) || (ADC_SAR_CTR_COUNT > 2U))
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    if (ADC_INST_HAS_CTRn(u32Instance, ADC_GROUP_2))
    {
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
        CTR(pBase, ADC_GROUP_2) = ADC_CTR_INPSAMP(aSampleTimes[2u]);
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
#endif /* ((ADC_SAR_CIMR_COUNT > 2U) || (ADC_SAR_CTR_COUNT > 2U)) */
}

#if FEATURE_ADC_HAS_AVERAGING
/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_SetAveraging
* Description   : This function sets the sample times for each channnel group.
*
* @implements      Adc_Sar_Ip_SetAveraging_Activity
* END**************************************************************************/
void Adc_Sar_Ip_SetAveraging(const uint32 u32Instance,
                                const boolean bAvgEn,
                                const Adc_Sar_Ip_AvgSelectType eAvgSel)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    ADC_Type * const pBase = pAdcBase[u32Instance];

    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_16();
    /* Clear old values */
    pBase->MCR &= ~(ADC_MCR_AVGEN_MASK | ADC_MCR_AVGS_MASK);

    /* Write new values */
    pBase->MCR |= ADC_MCR_AVGEN(bAvgEn ? 1U : 0U) | ADC_MCR_AVGS(eAvgSel);
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_16();
}
#endif /* FEATURE_ADC_HAS_AVERAGING */

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_AbortConversion
* Description   : This function aborts an ongoing conversion.
*
* @implements      Adc_Sar_Ip_AbortConversion_Activity
* END**************************************************************************/
void Adc_Sar_Ip_AbortConversion(const uint32 u32Instance)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */
    ADC_Type * const pBase = pAdcBase[u32Instance];

    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_17();
    pBase->MCR |= ADC_MCR_ABORT(1U);
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_17();
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_AbortChain
* Description   : This function aborts an ongoing chain of conversions.
*
* @implements      Adc_Sar_Ip_AbortChain_Activity
* END**************************************************************************/
Adc_Sar_Ip_StatusType Adc_Sar_Ip_AbortChain(const uint32 u32Instance,
                                const boolean bBlocking,
                                const boolean bAllowRestart)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */
    ADC_Type * const pBase = pAdcBase[u32Instance];
    uint32 u32Status;
    uint32 u32TimeoutTicks = OsIf_MicrosToTicks(ADC_SAR_IP_TIMEOUT_VAL, ADC_SAR_IP_TIMEOUT_TYPE);
    uint32 u32CurrentTicks = OsIf_GetCounter(ADC_SAR_IP_TIMEOUT_TYPE);
    uint32 u32ElapsedTicks = 0u;

    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_18();
    /* The behavior of the ADC depends on MCR[MODE] (One-Shot/Scan Operation modes).
    If Scan Operation mode is disabled, MSR[NSTART] is automatically reset together with MCR[ABORTCHAIN].
    Otherwise, in Scan Operation mode, a new chain is started. Therefore MCR[NSTART] should be cleared
    before abort the current chain of conversions. */
    if (!bAllowRestart)
    {
        pBase->MCR &= ~(ADC_MCR_NSTART(1U));
    }
    pBase->MCR |= ADC_MCR_ABORTCHAIN(1U);
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_18();

    if (bBlocking)
    {
        /* Wait for the ongoing conversion to stop */
        u32Status = pBase->MSR & ADC_MSR_NSTART_MASK;
        while ((u32Status == ADC_MSR_NSTART_MASK) && (u32ElapsedTicks < u32TimeoutTicks))
        {
            u32Status = pBase->MSR & ADC_MSR_NSTART_MASK;
            u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, ADC_SAR_IP_TIMEOUT_TYPE);
        }
        if (u32ElapsedTicks >= u32TimeoutTicks)
        {
            return ADC_SAR_IP_STATUS_TIMEOUT;
        }

#if !FEATURE_ADC_SAR_W1C_ABORT
        SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_18();
        /* Clear the ABORT_CHAIN bit if set, otherwise the next chain will be ABORTED without any End of Chain Interrupt */
        if ((pBase->MCR & ADC_MCR_ABORTCHAIN_MASK) != 0u)
        {
            pBase->MCR &= ~(ADC_MCR_ABORTCHAIN(1U));
        }
        SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_18();
#endif /* FEATURE_ADC_SAR_W1C_ABORT */
    }

    return ADC_SAR_IP_STATUS_SUCCESS;
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_SetPresamplingSource
* Description   : This function configures the Presampling Source for a channel group (0-31, 32-63, 64 -95)
*
* @implements      Adc_Sar_Ip_SetPresamplingSource_Activity
* END**************************************************************************/
void Adc_Sar_Ip_SetPresamplingSource(const uint32 u32Instance,
                                const Adc_Sar_Ip_ChanGroupType pChanGroup,
                                const Adc_Sar_Ip_PresamplingSourceType pPresampleSource)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    if (ADC_INST_HAS_PSCR(u32Instance))
    {
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_FEATURE */
        ADC_Type * const pBase = pAdcBase[u32Instance];

        SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_38();
        uint32 u32Pscr = pBase->PSCR;
        switch (pChanGroup)
        {
#ifdef ADC_PSCR_PREVAL0
            case ADC_SAR_IP_CHAN_GROUP_0:
                u32Pscr &= ~(ADC_PSCR_PREVAL0_MASK);
                u32Pscr |= ADC_PSCR_PREVAL0((uint32)pPresampleSource);
                break;
#endif /* ADC_PSCR_PREVAL0 */
#ifdef ADC_PSCR_PREVAL1
            case ADC_SAR_IP_CHAN_GROUP_1:
                u32Pscr &= ~(ADC_PSCR_PREVAL1_MASK);
                u32Pscr |= ADC_PSCR_PREVAL1((uint32)pPresampleSource);
                break;
#endif /* ADC_PSCR_PREVAL1 */
#ifdef ADC_PSCR_PREVAL2
            case ADC_SAR_IP_CHAN_GROUP_2:
                u32Pscr &= ~(ADC_PSCR_PREVAL2_MASK);
                u32Pscr |= ADC_PSCR_PREVAL2((uint32)pPresampleSource);
                break;
#endif /* ADC_PSCR_PREVAL2 */
            default:
                ; /* no-op */
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
                /* Not supported */
                ADC_SAR_DEV_ASSERT(FALSE);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */
                break;
        }
        pBase->PSCR = u32Pscr;
        SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_38();
#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_FEATURE */
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_EnableChannelPresampling
* Description   : This function enables the Presampling on one channel of the ADC.
*
* @implements      Adc_Sar_Ip_EnableChannelPresampling_Activity
* END**************************************************************************/
void Adc_Sar_Ip_EnableChannelPresampling(const uint32 u32Instance,
                                const uint32 u32ChnIdx)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
    ADC_SAR_DEV_ASSERT(u32ChnIdx < ADC_SAR_CDR_COUNT);
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    ADC_SAR_DEV_ASSERT(ADC_INST_HAS_CHANn(u32Instance, u32ChnIdx));
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    if (ADC_INST_HAS_PSCR(u32Instance))
    {
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_FEATURE */
        ADC_Type * const pBase = pAdcBase[u32Instance];

        uint32 u32VectAdr = CHAN_2_VECT(u32ChnIdx);
        uint32 u32VectBit = CHAN_2_BIT(u32ChnIdx);

        SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_41();
        PSR(pBase, u32VectAdr) |= 1UL << u32VectBit;
        SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_41();

#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_FEATURE */
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_DisableChannelPresampling
* Description   : This function disables the Presampling on one channel of the ADC.
*
* @implements      Adc_Sar_Ip_DisableChannelPresampling_Activity
* END**************************************************************************/
void Adc_Sar_Ip_DisableChannelPresampling(const uint32 u32Instance,
                                const uint32 u32ChnIdx)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
    ADC_SAR_DEV_ASSERT(u32ChnIdx < ADC_SAR_CDR_COUNT);
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    ADC_SAR_DEV_ASSERT(ADC_INST_HAS_CHANn(u32Instance, u32ChnIdx));
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    if (ADC_INST_HAS_PSCR(u32Instance))
    {
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_FEATURE */
        ADC_Type * const pBase = pAdcBase[u32Instance];

        uint32 u32VectAdr = CHAN_2_VECT(u32ChnIdx);
        uint32 u32VectBit = CHAN_2_BIT(u32ChnIdx);

        SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_42();
        PSR(pBase, u32VectAdr) &= ~(1UL << u32VectBit);
        SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_42();
#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_FEATURE */
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_EnablePresampleConversion
* Description   : This function enables bypass of the Sampling Phase, resulting in a conversion
* of the presampled data. This is available only for channels that have presampling
* enabled.
*
* @implements      Adc_Sar_Ip_EnablePresampleConversion_Activity
* END**************************************************************************/
void Adc_Sar_Ip_EnablePresampleConversion(const uint32 u32Instance)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    if (ADC_INST_HAS_PSCR(u32Instance))
    {
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_FEATURE */
        ADC_Type * const pBase = pAdcBase[u32Instance];

        SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_39();
        pBase->PSCR |= ADC_PSCR_PRECONV(1U);
        SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_39();
#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_FEATURE */
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_DisablePresampleConversion
* Description   : This function disables Sampling Phase bypass.
*
* @implements      Adc_Sar_Ip_DisablePresampleConversion_Activity
* END**************************************************************************/
void Adc_Sar_Ip_DisablePresampleConversion(const uint32 u32Instance)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    if (ADC_INST_HAS_PSCR(u32Instance))
    {
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_FEATURE */
        ADC_Type * const pBase = pAdcBase[u32Instance];

        SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_40();
        pBase->PSCR &= ~(ADC_PSCR_PRECONV(1U));
        SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_40();
#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_FEATURE */
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_EnableDma
* Description   : This function enables requests to DMA from ADC
*
* @implements      Adc_Sar_Ip_EnableDma_Activity
* END**************************************************************************/
void Adc_Sar_Ip_EnableDma(const uint32 u32Instance)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    ADC_Type * const pBase = pAdcBase[u32Instance];

    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_43();
    pBase->DMAE |= ADC_DMAE_DMAEN(1U);
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_43();
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_DisableDma
* Description   : This function disables requests to DMA from ADC
*
* @implements      Adc_Sar_Ip_DisableDma_Activity
* END**************************************************************************/
void Adc_Sar_Ip_DisableDma(const uint32 u32Instance)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    ADC_Type * const pBase = pAdcBase[u32Instance];

    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_44();
    pBase->DMAE &= ~(ADC_DMAE_DMAEN(1U));
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_44();
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_EnableChannelDma
* Description   : This function enables DMA requests triggered by End of Conversion event from
*  a selected channel.
*
* @implements      Adc_Sar_Ip_EnableChannelDma_Activity
* END**************************************************************************/
void Adc_Sar_Ip_EnableChannelDma(const uint32 u32Instance,
                                const uint32 u32ChnIdx)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
    ADC_SAR_DEV_ASSERT(u32ChnIdx < ADC_SAR_CDR_COUNT);
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    ADC_SAR_DEV_ASSERT(ADC_INST_HAS_CHANn(u32Instance, u32ChnIdx));
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    ADC_Type * const pBase = pAdcBase[u32Instance];

    uint32 u32VectAdr = CHAN_2_VECT(u32ChnIdx);
    uint32 u32VectBit = CHAN_2_BIT(u32ChnIdx);

    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_46();
    DMAR(pBase, u32VectAdr) |= 1UL << u32VectBit;
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_46();
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_DisableChannelDma
* Description   : This function disables DMA requests triggered by End of Conversion event from
*  a selected channel.
*
* @implements      Adc_Sar_Ip_DisableChannelDma_Activity
* END**************************************************************************/
void Adc_Sar_Ip_DisableChannelDma(const uint32 u32Instance,
                                const uint32 u32ChnIdx)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
    ADC_SAR_DEV_ASSERT(u32ChnIdx < ADC_SAR_CDR_COUNT);
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
    ADC_SAR_DEV_ASSERT(ADC_INST_HAS_CHANn(u32Instance, u32ChnIdx));
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    ADC_Type * const pBase = pAdcBase[u32Instance];

    uint32 u32VectAdr = CHAN_2_VECT(u32ChnIdx);
    uint32 u32VectBit = CHAN_2_BIT(u32ChnIdx);

    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_47();
    DMAR(pBase, u32VectAdr) &= ~(1UL << u32VectBit);
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_47();
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_DisableChannelDmaAll
* Description   : This function disables DMA requests triggered by End of Conversion event from
*  all channels.
*
* @implements      Adc_Sar_Ip_DisableChannelDmaAll_Activity
* END**************************************************************************/
void Adc_Sar_Ip_DisableChannelDmaAll(const uint32 u32Instance)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    ADC_Type * const pBase = pAdcBase[u32Instance];
    uint8 u8Index = 0u;

    for (u8Index = 0U; u8Index < ADC_SAR_DMAR_COUNT; u8Index++)
    {
#if FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL
        if (!ADC_INST_HAS_DMARn(u32Instance, u8Index))
        {
            continue; /* skip register if it's not available */
        }
#endif /* FEATURE_ADC_BAD_ACCESS_PROT_CHANNEL */
        SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_48();
        DMAR(pBase, u8Index) &= ~(u32AdcChanBitmap[u32Instance][u8Index]);
        SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_48();
    }
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_SetDmaClearSource
* Description   : This function selects the DMA Request Flag Clear Source.
*
* @implements      Adc_Sar_Ip_SetDmaClearSource_Activity
* END**************************************************************************/
void Adc_Sar_Ip_SetDmaClearSource(const uint32 u32Instance,
                                const Adc_Sar_Ip_ClearSourceType pDmaClear)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    ADC_Type * const pBase = pAdcBase[u32Instance];

    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_45();
    pBase->DMAE &= ~(ADC_DMAE_DCLR_MASK);
    pBase->DMAE |= ADC_DMAE_DCLR((uint32)pDmaClear);
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_45();
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_SetWdgThreshold
* Description   : This function sets the watchdog thresholds for a certain register.
*
* @implements      Adc_Sar_Ip_SetWdgThreshold_Activity
* END**************************************************************************/
void Adc_Sar_Ip_SetWdgThreshold(const uint32 u32Instance,
                                const uint8 u8RegisterIdx,
                                const Adc_Sar_Ip_WdgThresholdType * const pThresholdValues)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
    ADC_SAR_DEV_ASSERT(pThresholdValues != NULL_PTR);
    ADC_SAR_DEV_ASSERT(u8RegisterIdx < ADC_SAR_THRHLR_COUNT);
#ifdef ADC_THRHLR_PER_INSTANCE_COUNT
    ADC_SAR_DEV_ASSERT(u8RegisterIdx < u32AdcThrhlrCount[u32Instance]);
#endif /* ADC_THRHLR_PER_INSTANCE_COUNT */
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    ADC_Type * const pBase = pAdcBase[u32Instance];

#if (ADC_SAR_IP_SET_RESOLUTION == STD_ON)
    /* Calculate the shift of the threshold value to get the number of bits 
     * needed by the hardware unit. */
    uint8 u8Shift = ADC_RESULT_RESOLUTION - Adc_Sar_GetResolution(u32Instance);
    /* Shift the threshold to obtain the value to be written in the threshold register. */
    uint16 u16HighThreshold = (pThresholdValues->u16HighThreshold) << u8Shift;
    uint16 u16LowThreshold = (pThresholdValues->u16LowThreshold) << u8Shift;
    
    Adc_Sar_WriteThresholds(pBase, u8RegisterIdx, u16HighThreshold, u16LowThreshold);
#else
    Adc_Sar_WriteThresholds(pBase, u8RegisterIdx,
                        pThresholdValues->u16HighThreshold,
                        pThresholdValues->u16LowThreshold);
#endif /* (ADC_SAR_IP_SET_RESOLUTION == STD_ON) */

    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_32();
    uint32 u32Wtimr = pBase->WTIMR;
    if (pThresholdValues->bLowThresholdIntEn)
    {
        u32Wtimr |= (ADC_WDOG_REG_MASK_HIGH(u8RegisterIdx));
    }
    else
    {
        u32Wtimr &= (~ADC_WDOG_REG_MASK_HIGH(u8RegisterIdx));
    }
    if (pThresholdValues->bHighThresholdIntEn)
    {
        u32Wtimr |= (ADC_WDOG_REG_MASK_LOW(u8RegisterIdx));
    }
    else
    {
        u32Wtimr &= (~ADC_WDOG_REG_MASK_LOW(u8RegisterIdx));
    }
    pBase->WTIMR = u32Wtimr;
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_32();
}

/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_SetConversionMode
* Description   : This function configures the used conversion mode.
* Note: The ADC instance must be in IDLE state in order to change this.
*
* @implements      Adc_Sar_Ip_SetConversionMode_Activity
* END**************************************************************************/
void Adc_Sar_Ip_SetConversionMode(const uint32 u32Instance,
                                const Adc_Sar_Ip_ConvModeType eConvMode)
{
    ADC_Type * const pBase = pAdcBase[u32Instance];

#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
    /* The selected ADC should be in IDLE state */
    ADC_SAR_DEV_ASSERT((pBase->MSR & ADC_MSR_ADCSTATUS_MASK) == ADC_MSR_ADCSTATUS(0UL));
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    /* Edit MODE */
    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_19();
    switch (eConvMode)
    {
    case ADC_SAR_IP_CONV_MODE_ONESHOT:
        pBase->MCR &= ~(ADC_MCR_MODE(1u)); /* MODE = 0 */
        break;
    case ADC_SAR_IP_CONV_MODE_SCAN:
        pBase->MCR |= ADC_MCR_MODE(1u); /* MODE = 1 */
        break;
    default:
        ; /* no-op */
        break;
    }
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_19();
}

#if FEATURE_ADC_HAS_CTU
/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_SetCtuMode
* Description   : This function configures the CTU mode and enable.
*
* @implements      Adc_Sar_Ip_SetCtuMode_Activity
* END**************************************************************************/
Adc_Sar_Ip_StatusType Adc_Sar_Ip_SetCtuMode(const uint32 u32Instance,
                                const Adc_Sar_Ip_CtuModeType eCtuMode)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    Adc_Sar_Ip_StatusType eStatus = ADC_SAR_IP_STATUS_SUCCESS;
    ADC_Type * const pBase = pAdcBase[u32Instance];

    /* Clear CTUEN to allow Powerdown operation to succeed. */
    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_20();
    pBase->MCR &= ~ADC_MCR_CTUEN_MASK;
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_20();

    /* Power down */
    eStatus = Adc_Sar_Ip_Powerdown(u32Instance);
    if (eStatus != ADC_SAR_IP_STATUS_SUCCESS)
    {
        return eStatus;
    }

    /* Configure CTU */
#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    if (ADC_INST_HAS_CTU(u32Instance))
    {
#endif /*FEATURE_ADC_BAD_ACCESS_PROT_FEATURE*/
        SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_20();
        switch (eCtuMode)
        {
            case ADC_SAR_IP_CTU_MODE_CONTROL:
                pBase->MCR &= ~(ADC_MCR_CTU_MODE(1U)); /* CTU_MODE = 0 */
                pBase->MCR |= ADC_MCR_CTUEN(1U); /* CTUEN = 1 */
                break;
#if FEATURE_ADC_HAS_CTU_TRIGGER_MODE
            case ADC_SAR_IP_CTU_MODE_TRIGGER:
                /* Set CTU_MODE = 1 and CTUEN = 1 */
                pBase->MCR |= (ADC_MCR_CTU_MODE(1U) | ADC_MCR_CTUEN(1U));
                break;
#endif /* FEATURE_ADC_HAS_CTU_TRIGGER_MODE */
                /* Set CTU_MODE = 0 and CTUEN = 0 */
            case ADC_SAR_IP_CTU_MODE_DISABLED:
                pBase->MCR &= ~(ADC_MCR_CTU_MODE(1U) | ADC_MCR_CTUEN(1U));
                break;
            default:
                ; /* no-op */
                break;
        }
        SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_20();
#if FEATURE_ADC_BAD_ACCESS_PROT_FEATURE
    }
#endif /*FEATURE_ADC_BAD_ACCESS_PROT_FEATURE*/

    /* Power up */
    eStatus = Adc_Sar_Ip_Powerup(u32Instance);

    return eStatus;
}
#endif /* FEATURE_ADC_HAS_CTU */

#if (FEATURE_ADC_HAS_INJ_EXT_TRIGGER || FEATURE_ADC_HAS_EXT_TRIGGER)
/*FUNCTION**********************************************************************
*
* Function Name : Adc_Sar_Ip_SetExternalTrigger
* Description   : This function configures the external trigger.
*
* @implements      Adc_Sar_Ip_SetExternalTrigger_Activity
* END**************************************************************************/
void Adc_Sar_Ip_SetExternalTrigger(const uint32 u32Instance,
                                   const Adc_Sar_Ip_ExtTriggerEdgeType eTriggerEdge,
                                   const Adc_Sar_Ip_ExtTriggerSourceType eTrggerSrc)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < ADC_SAR_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */

    /* Switch between injected and normal external trigger */
    switch (eTrggerSrc)
    {
#if FEATURE_ADC_HAS_EXT_TRIGGER
        case ADC_SAR_IP_NORMAL_EXT_TRIG:
            Adc_Sar_ConfigExternalTrigger(u32Instance, eTriggerEdge, ADC_MCR_EDGE_MASK, 0U, ADC_MCR_TRGEN_MASK);
            break;
        case ADC_SAR_IP_AUX_NORMAL_EXT_TRIG:
            Adc_Sar_ConfigExternalTrigger(u32Instance, eTriggerEdge, ADC_MCR_EDGE_MASK, 0U, ADC_MCR_XSTRTEN_MASK);
            break;
        case ADC_SAR_IP_ALL_NORMAL_EXT_TRIG:
            Adc_Sar_ConfigExternalTrigger(u32Instance, eTriggerEdge, ADC_MCR_EDGE_MASK, ADC_MCR_EDGE_MASK, (ADC_MCR_TRGEN_MASK | ADC_MCR_XSTRTEN_MASK));
            break;
#endif /* FEATURE_ADC_HAS_EXT_TRIGGER */
#if FEATURE_ADC_HAS_INJ_EXT_TRIGGER
        case ADC_SAR_IP_INJECTED_EXT_TRIG:
            Adc_Sar_ConfigExternalTrigger(u32Instance, eTriggerEdge, ADC_MCR_JEDGE_MASK, ADC_MCR_JEDGE_MASK, ADC_MCR_JTRGEN_MASK);
            break;
#endif /* FEATURE_ADC_HAS_INJ_EXT_TRIGGER */
        default:
            ; /* no-op */
            break;
    }
}
#endif /* (FEATURE_ADC_HAS_INJ_EXT_TRIGGER || FEATURE_ADC_HAS_EXT_TRIGGER) */

#if FEATURE_ADC_HAS_TEMPSENSE_CHN
#if (ADC_SAR_IP_TEMPSENSE_ENABLED == STD_ON)
/*FUNCTION**********************************************************************
 *
 * Function Name : Adc_Sar_Ip_TempSenseCalculateTemp
 * Description   : This function calculates the temperature on chip from the provided
 * parameter.
 *
 * @implements      Adc_Sar_Ip_TempSenseCalculateTemp_Activity
 * END**************************************************************************/
uint16 Adc_Sar_Ip_TempSenseCalculateTemp(const uint32 u32AdcInstance,
                                         const uint32 u32TempInstance,
                                         const uint16 u16TempSenseAdcConvData)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32TempInstance < TEMPSENSE_INSTANCE_COUNT);
    ADC_SAR_DEV_ASSERT(AdcVoltageRefs[u32AdcInstance] <= 0x58U); /* Vref should be less than 5.5V */
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */
    const TEMPSENSE_Type * const pBase = pTempsenseBase[u32TempInstance];
    uint32 u32Vets;
    uint32 u32Vref;
    uint32 u32Tca0 = pBase->TCA0;
    uint32 u32Tca1 = pBase->TCA1;
    uint32 u32Tca2 = pBase->TCA2;
    sint32 s32Tets;

    if (AdcVoltageRefs[u32AdcInstance] > ADC_SAR_IP_TEMPSENSE_VOLTAGE_SUPPLY)
    {
        u32Vref = Adc_Sar_TempsenseConvFp2Int(ADC_SAR_IP_TEMPSENSE_VOLTAGE_SUPPLY);
    }
    else
    {
        u32Vref = Adc_Sar_TempsenseConvFp2Int(AdcVoltageRefs[u32AdcInstance]);
    }

    if ((u32Tca0 & TEMPSENSE_SIGN_MASK) != 0U)
    {
        s32Tets = - (sint32)(Adc_Sar_TempsenseConvFp2Int(u32Tca0));
    }
    else
    {
        s32Tets = (sint32)(Adc_Sar_TempsenseConvFp2Int(u32Tca0));
    }

    u32Vets = (uint32)((u32Vref * u16TempSenseAdcConvData) / TEMPSENSE_RESOLUTION_12B);
    if ((u32Tca1 & TEMPSENSE_SIGN_MASK) != 0U)
    {
        s32Tets -= (sint32)((Adc_Sar_TempsenseConvFp2Int(u32Tca1) * u32Vets) / TEMPSENSE_MULTIPLIER);
    }
    else
    {
        s32Tets += (sint32)((Adc_Sar_TempsenseConvFp2Int(u32Tca1) * u32Vets) / TEMPSENSE_MULTIPLIER);
    }

    u32Vets = (u32Vets * u32Vets) / TEMPSENSE_MULTIPLIER;
    if ((u32Tca2 & TEMPSENSE_SIGN_MASK) != 0U)
    {
        s32Tets -= (sint32)((Adc_Sar_TempsenseConvFp2Int(u32Tca2) * u32Vets) / TEMPSENSE_MULTIPLIER);
    }
    else
    {
        s32Tets += (sint32)((Adc_Sar_TempsenseConvFp2Int(u32Tca2) * u32Vets) / TEMPSENSE_MULTIPLIER);
    }

    return Adc_Sar_TempsenseConvInt2Fp(s32Tets);
}


/*FUNCTION**********************************************************************
 *
 * Function Name : Adc_Sar_Ip_TempSenseGetTemp
 * Description   : This function starts a normal software conversion on tempsense
 * channel and calculates the temperature on chip from the data conversion
 * parameter. Tempsense calculations are done using 12bits operators, so it is
 * recommended for Adc to run on minimum resolution of 12-bit.
 *
 * @implements      Adc_Sar_Ip_TempSenseGetTemp_Activity
 * END**************************************************************************/
Adc_Sar_Ip_StatusType Adc_Sar_Ip_TempSenseGetTemp(const uint32 u32AdcInstance,
                                                  const uint32 u32TempInstance,
                                                  uint16 * const pTempSenseVal)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32AdcInstance < ADC_SAR_INSTANCE_COUNT);
    ADC_SAR_DEV_ASSERT(u32TempInstance < TEMPSENSE_INSTANCE_COUNT);
    ADC_SAR_DEV_ASSERT(AdcVoltageRefs[u32AdcInstance] <= 0x58U); /* Vref should be less than 5.5V */
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */
    ADC_Type * const pBase  = pAdcBase[u32AdcInstance];
    Adc_Sar_Ip_StatusType eStatus = ADC_SAR_IP_STATUS_SUCCESS;
    uint32 u32TimeoutTicks = OsIf_MicrosToTicks(ADC_SAR_IP_TIMEOUT_VAL, ADC_SAR_IP_TIMEOUT_TYPE);
    uint32 u32CurrentTicks = OsIf_GetCounter(ADC_SAR_IP_TIMEOUT_TYPE);
    uint32 u32ElapsedTicks = 0u;
    uint32 u32ExpectedStatus;
    uint32 u32Status;
    uint32 u32Cdr;
    uint16 u16Result;
    uint8 u8Resolution;

    uint32 u32VectAdr = CHAN_2_VECT(TEMPSENSE_ADC_CHANNEL);
    uint32 u32VectBit = CHAN_2_BIT(TEMPSENSE_ADC_CHANNEL);

    /* Enable tempsense channel */
    NCMR(pBase, u32VectAdr) |= (1UL << u32VectBit);
    /* One-shot mode */
    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_22();
    pBase->MCR &= ~(ADC_MCR_MODE(1U));
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_22();

    pBase->ISR = ADC_ISR_ECH(1U);

    /* Start normal software conversion */
    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_22();
    pBase->MCR |= ADC_MCR_NSTART(1U);
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_22();

    /* Wait for the conversion to be finished */
    u32ExpectedStatus = (1UL << u32VectBit);
    u32Status = CEOCFR(pBase, u32VectAdr) & (1UL << u32VectBit);
    while ((u32Status != u32ExpectedStatus) && (u32ElapsedTicks < u32TimeoutTicks))
    {
        u32Status = CEOCFR(pBase, u32VectAdr) & (1UL << u32VectBit);
        u32ElapsedTicks += OsIf_GetElapsed(&u32CurrentTicks, ADC_SAR_IP_TIMEOUT_TYPE);
    }
    if (u32ElapsedTicks >= u32TimeoutTicks)
    {
        eStatus = ADC_SAR_IP_STATUS_TIMEOUT;
    }

    if (eStatus == ADC_SAR_IP_STATUS_SUCCESS)
    {
        u32Cdr = CDR(pBase, (uint32)TEMPSENSE_ADC_CHANNEL);
        if (((u32Cdr & ADC_CDR_VALID_MASK) != 0U))
        {
            u8Resolution = Adc_Sar_GetResolution(u32AdcInstance);
            u16Result = Adc_Sar_GetMaskedResult(u32AdcInstance, u32Cdr);
            /* the data is correct, store the result in 12bit resolution and clear the flag */
            if (aAdcSarState[u32AdcInstance].eDataAlign == ADC_SAR_IP_DATA_ALIGNED_LEFT)
            {
                /* Assumption: the width of the register is less than 16 */
                u16Result = u16Result >> (16u - u8Resolution);
            }

            u16Result = (u8Resolution > TEMPSENSE_RESOLUTION) ? \
            (u16Result >> (u8Resolution - TEMPSENSE_RESOLUTION)) : \
            (u16Result << (TEMPSENSE_RESOLUTION - u8Resolution));
            
            CEOCFR(pBase, u32VectAdr) = ((uint32)1UL << u32VectBit); /* w1c bit */

            *pTempSenseVal = Adc_Sar_Ip_TempSenseCalculateTemp(u32AdcInstance, u32TempInstance, u16Result);
        }
    }

    /* Disable tempsense channel */
    NCMR(pBase, u32VectAdr) &= ~(1UL << u32VectBit);

    return eStatus;
}


/*FUNCTION**********************************************************************
 *
 * Function Name : Adc_Sar_Ip_TempSenseEnable
 * Description   : This function enables the temperature sensor.
 *
 * @implements      Adc_Sar_Ip_TempSenseEnable_Activity
 * END**************************************************************************/
void Adc_Sar_Ip_TempSenseEnable(const uint32 u32Instance)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < TEMPSENSE_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */
    TEMPSENSE_Type * const pBase = pTempsenseBase[u32Instance];

    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_49();
    pBase->ETSCTL |= TEMPSENSE_ETSCTL_ETS_EN_MASK;
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_49();
}

/*FUNCTION**********************************************************************
 *
 * Function Name : Adc_Sar_Ip_TempSenseDisable
 * Description   : This function disables the temperature sensor.
 *
 * @implements      Adc_Sar_Ip_TempSenseDisable_Activity
 * END**************************************************************************/
void Adc_Sar_Ip_TempSenseDisable(const uint32 u32Instance)
{
#if (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON)
    ADC_SAR_DEV_ASSERT(u32Instance < TEMPSENSE_INSTANCE_COUNT);
#endif /* (ADC_SAR_IP_DEV_ERROR_DETECT == STD_ON) */
    TEMPSENSE_Type * const pBase = pTempsenseBase[u32Instance];

    SchM_Enter_Adc_ADC_EXCLUSIVE_AREA_50();
    pBase->ETSCTL &= (~TEMPSENSE_ETSCTL_ETS_EN_MASK);
    SchM_Exit_Adc_ADC_EXCLUSIVE_AREA_50();
}
#endif /* (ADC_SAR_IP_TEMPSENSE_ENABLED == STD_ON) */
#endif /* FEATURE_ADC_HAS_TEMPSENSE_CHN */

#define ADC_STOP_SEC_CODE
#include "Adc_MemMap.h"

/** @} */
