/**
 * @file xmc_vadc.c
 * @date 2019-12-16
 *
 * @cond
 *****************************************************************************
 * XMClib v2.2.0 - XMC Peripheral Driver Library
 *
 * Copyright (c) 2015-2020, Infineon Technologies AG
 * All rights reserved.
 *
 * Boost Software License - Version 1.0 - August 17th, 2003
 *
 * Permission is hereby granted, free of charge, to any person or organization
 * obtaining a copy of the software and accompanying documentation covered by
 * this license (the "Software") to use, reproduce, display, distribute,
 * execute, and transmit the Software, and to prepare derivative works of the
 * Software, and to permit third-parties to whom the Software is furnished to
 * do so, all subject to the following:
 *
 * The copyright notices in the Software and this entire statement, including
 * the above license grant, this restriction and the following disclaimer,
 * must be included in all copies of the Software, in whole or in part, and
 * all derivative works of the Software, unless such copies or derivative
 * works are solely in the form of machine-executable object code generated by
 * a source language processor.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * To improve the quality of the software, users are encouraged to share
 * modifications, enhancements or bug fixes with Infineon Technologies AG
 * at XMCSupport@infineon.com.
 *****************************************************************************
 *
 * Change History
 * --------------
 *
 * 2015-02-15:
 *     - Initial <br>
 *
 * 2015-02-20:
 *     - Revised for XMC1201 device.<br>
 *
 * 2015-04-27:
 *     - Added new APIs for SHS.<br>
 *     - Added New APIs for trigger edge selection.<BR>
 *     - Added new APIs for Queue flush entries, boundary selection, Boundary node pointer.<BR>
 *     - Revised GatingMode APIs and EMUX Control Init API.<BR>
 *
 * 2015-06-20:
 *     - Removed version macros and declaration of GetDriverVersion API
 *
 * 2015-06-25:
 *     - BFL configuration in channel initialization fixed.
 *
 * 2015-07-28:
 *     - CLOCK_GATING_SUPPORTED and PERIPHERAL_RESET_SUPPORTED macros used
 *     - Clubbed the macro definitions for XMC13 XMC12 and XMC14
 *     - Clubbed the macro definitions for XMC44 XMC47 and XMC48
 *     - New APIs Created.
 *           - XMC_VADC_GLOBAL_SetIndividualBoundary
 *           - XMC_VADC_GROUP_SetIndividualBoundary
 *           - XMC_VADC_GROUP_GetAlias
 *           - XMC_VADC_GROUP_GetInputClass
 *           - XMC_VADC_GROUP_ChannelSetIclass
 *           - XMC_VADC_GROUP_ChannelGetResultAlignment
 *           - XMC_VADC_GROUP_ChannelGetInputClass
 *           - XMC_VADC_GROUP_SetResultSubtractionValue
 *
 * 2015-12-01:
 *     - Fixed the analog calibration voltage for XMC1100 to external reference upper supply range.
 *     - Fixed the XMC_VADC_GLOBAL_StartupCalibration() for XMC1100.
 *
 * 2016-06-17:
 *     - New macros added XMC_VADC_SHS_FULL_SET_REG, XMC_VADC_RESULT_PRIORITY_AVAILABLE
 *       and XMC_VADC_SYNCTR_START_LOCATION
 *     - New Enum added XMC_VADC_SHS_GAIN_LEVEL_t and XMC_VADC_SYNCTR_EVAL_t
 *     - Fixed the EVAL configuration in API XMC_VADC_GROUP_CheckSlaveReadiness and XMC_VADC_GROUP_IgnoreSlaveReadiness
 *     - New APIs added are:
 *           - XMC_VADC_GROUP_SetSyncSlaveReadySignal
 *           - XMC_VADC_GROUP_ChannelGetAssertedEvents
 *           - XMC_VADC_GROUP_GetAssertedResultEvents
 *           - XMC_VADC_GROUP_SetResultRegPriority
 *           - XMC_VADC_GROUP_SetSyncReadySignal
 *           - XMC_VADC_GROUP_GetSyncReadySignal
 *           - XMC_VADC_GROUP_GetResultRegPriority
 *
 * 2017-01-11:
 *     - Fix assertion in XMC_VADC_GROUP_CheckSlaveReadiness() and XMC_VADC_GROUP_IgnoreSlaveReadiness() checking the slave_group parameter
 *
 * 2018-06-26:
 *     - Fixed XMC_VADC_GLOBAL_StartupCalibration(), added wait until calibration is started
 *
 * 2019-03-30:
 *     - Changed XMC_VADC_GROUP_SetChannelAlias() to inline function
 *
 * 2019-05-07:
 *     - Fix compilation warnings
 *
 * 2019-10-18:
 *     - Changed XMC_VADC_GLOBAL_StartupCalibration() to ensure calibration has started
 *
 * 2019-12-16:
 *     - Fix including files following the convention: angle brackets are used for standard includes and double quotes for everything else.
 *
 * 2020-03-18:
 *     - Changed XMC_VADC_GLOBAL_Init() setting ADC clock to 48MHz for XMC1400 series
 *
 * @endcond
 *
 */

/*********************************************************************************************************************
 * HEADER FILES
 ********************************************************************************************************************/
#include "xmc_vadc.h"

/*********************************************************************************************************************
 * MACROS
 ********************************************************************************************************************/
#define XMC_VADC_MAX_ICLASS_SET          (2U)  /**< Defines the maximum number of conversion parameter sets */
#define XMC_VADC_NUM_EMUX_INTERFACES     (2U)  /**< Defines the maximum number of external multiplexer  interfaces */

#define XMC_VADC_RESULT_LEFT_ALIGN_10BIT (2U)  /**< Defines the 10 bit converted result register left align mask. It \
                                                    is used in the XMC_VADC_GLOBAL_SetCompareValue() API */

#define XMC_VADC_SYNCTR_START_LOCATION (3U)  /**< Defines the location in SYNCTR needed for calculations*/
/*********************************************************************************************************************
 * ENUMS
 ********************************************************************************************************************/

/*********************************************************************************************************************
 * DATA STRUCTURES
 ********************************************************************************************************************/

/*********************************************************************************************************************
 * GLOBAL DATA
 ********************************************************************************************************************/

#if (XMC_VADC_GROUP_AVAILABLE == 1U)

#if (XMC_VADC_MAXIMUM_NUM_GROUPS == 4U)
static VADC_G_TypeDef *const g_xmc_vadc_group_array[XMC_VADC_MAXIMUM_NUM_GROUPS] = {(VADC_G_TypeDef *)(void *)VADC_G0,
                                                                                    (VADC_G_TypeDef *)(void *)VADC_G1,
                                                                                    (VADC_G_TypeDef *)(void *)VADC_G2,
                                                                                    (VADC_G_TypeDef *)(void *)VADC_G3
                                                                                   };
#else
static VADC_G_TypeDef *const g_xmc_vadc_group_array[XMC_VADC_MAXIMUM_NUM_GROUPS] = {(VADC_G_TypeDef * )(void *) VADC_G0,
                                                                                    (VADC_G_TypeDef * )(void *)VADC_G1
                                                                                   };
#endif

#endif

/*********************************************************************************************************************
 * LOCAL ROUTINES
 ********************************************************************************************************************/

/*********************************************************************************************************************
 * API IMPLEMENTATION
 ********************************************************************************************************************/

/*API to enable the VADC Module*/
void XMC_VADC_GLOBAL_EnableModule(void)
{
  /*
   * Enable Out of Range Comparator for ADC channels pins P2.2to P2.9. This hack is applicable only for XMC1xxx devices
   * and in particular the G11 step.
   *
   * Please refer to the XMC1000 Errata sheet V1.4 released 2014-06 Errata ID : ADC_AI.003 Additonal bit to enable ADC
   * function
   */

#if defined (COMPARATOR)
  COMPARATOR->ORCCTRL = (uint32_t)0xFF;
#endif

#if defined(CLOCK_GATING_SUPPORTED)
  XMC_SCU_CLOCK_UngatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_VADC);
#endif

#if defined(PERIPHERAL_RESET_SUPPORTED)
  /* Reset the Hardware */
  XMC_SCU_RESET_DeassertPeripheralReset((XMC_SCU_PERIPHERAL_RESET_t)XMC_SCU_PERIPHERAL_RESET_VADC );
#endif
}

/*API to Disable the VADC Module*/
void XMC_VADC_GLOBAL_DisableModule(void)
{
#if defined(PERIPHERAL_RESET_SUPPORTED)
  /* Reset the Hardware */
  XMC_SCU_RESET_AssertPeripheralReset((XMC_SCU_PERIPHERAL_RESET_t)XMC_SCU_PERIPHERAL_RESET_VADC );
#endif

#if defined(CLOCK_GATING_SUPPORTED)
  XMC_SCU_CLOCK_GatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_VADC);
#endif

}


/* API to initialize global resources */
void XMC_VADC_GLOBAL_Init(XMC_VADC_GLOBAL_t *const global_ptr, const XMC_VADC_GLOBAL_CONFIG_t *config)
{
#if (XMC_VADC_GROUP_AVAILABLE == 0U)
  uint32_t reg;
#endif
  XMC_ASSERT("XMC_VADC_GLOBAL_Init:Wrong Module Pointer", (global_ptr == VADC))

#if (UC_SERIES == XMC14)
  XMC_SCU_CLOCK_SetAdcClockSrc(XMC_SCU_CLOCK_ADCCLKSRC_48MHZ);
#endif

  /* Enable the VADC module*/
  XMC_VADC_GLOBAL_EnableModule();

  global_ptr->CLC = (uint32_t)(config->clc);

  /* Clock configuration */

#if (XMC_VADC_GROUP_AVAILABLE == 1U)
  global_ptr->GLOBCFG  = (uint32_t)(config->clock_config.globcfg | (uint32_t)(VADC_GLOBCFG_DIVWC_Msk));
#endif

  /* ICLASS-0 configuration */
  global_ptr->GLOBICLASS[0] = (uint32_t)(config->class0.globiclass);

  /* ICLASS-1 configuration */
  global_ptr->GLOBICLASS[1] = (uint32_t)(config->class1.globiclass);


  /*Result generation related configuration */
  global_ptr->GLOBRCR = (uint32_t)(config->globrcr);

#if (XMC_VADC_BOUNDARY_AVAILABLE == 1U)

  /* Boundaries */
  global_ptr->GLOBBOUND = (uint32_t)(config->globbound);

#endif

  /* Configure the SHS register that are needed for XMC11xx devices*/
#if (XMC_VADC_GROUP_AVAILABLE == 0U)

  /* Enabling the Analog part of the converter*/
  reg = SHS0->SHSCFG  | SHS_SHSCFG_SCWC_Msk;
  reg &= ~(SHS_SHSCFG_ANOFF_Msk);
  SHS0->SHSCFG = reg;

  /* From the Errata sheet of XMC1100 V1.7*/
  XMC_VADC_CONV_ENABLE_FOR_XMC11 = 1U;
#endif

}

/* API to Set the Global IClass registers*/
void XMC_VADC_GLOBAL_InputClassInit(XMC_VADC_GLOBAL_t *const global_ptr, const XMC_VADC_GLOBAL_CLASS_t config,
                                    const XMC_VADC_GROUP_CONV_t conv_type, const uint32_t set_num)
{

  XMC_ASSERT("XMC_VADC_GLOBAL_InputClassInit:Wrong Module Pointer", (global_ptr == VADC))
  XMC_ASSERT("XMC_VADC_GLOBAL_InputClassInit:Wrong Conversion Type", ((conv_type) <= XMC_VADC_GROUP_CONV_EMUX))
  XMC_ASSERT("XMC_VADC_GLOBAL_InputClassInit:Wrong ICLASS set number", (set_num < XMC_VADC_MAX_ICLASS_SET))

#if(XMC_VADC_EMUX_AVAILABLE == 1U)
  if (conv_type == XMC_VADC_GROUP_CONV_STD )
  {
#endif
    XMC_UNUSED_ARG(conv_type);
    global_ptr->GLOBICLASS[set_num] = config.globiclass &
                                      (uint32_t)(VADC_GLOBICLASS_CMS_Msk | VADC_GLOBICLASS_STCS_Msk);
#if(XMC_VADC_EMUX_AVAILABLE == 1U)
  }
  else
  {
    global_ptr->GLOBICLASS[set_num] = config.globiclass & (uint32_t)(VADC_GLOBICLASS_CME_Msk | VADC_GLOBICLASS_STCE_Msk);
  }
#endif
}

/* API to enable startup calibration feature */
void XMC_VADC_GLOBAL_StartupCalibration(XMC_VADC_GLOBAL_t *const global_ptr)
{
#if (XMC_VADC_GROUP_AVAILABLE == 1U)
  uint8_t i;
  VADC_G_TypeDef *group_ptr;
#endif

  XMC_ASSERT("XMC_VADC_GLOBAL_StartupCalibration:Wrong Module Pointer", (global_ptr == VADC))

  global_ptr->GLOBCFG |= (uint32_t)VADC_GLOBCFG_SUCAL_Msk;

#if (XMC_VADC_GROUP_AVAILABLE == 1U)
  /* Loop until all active groups finish calibration */
  for (i = 0U; i < XMC_VADC_MAXIMUM_NUM_GROUPS; i++)
  {
    group_ptr = g_xmc_vadc_group_array[i];
    if ( (group_ptr->ARBCFG) & (uint32_t)VADC_G_ARBCFG_ANONS_Msk)
    {
      /* This group is active. Loop until it finishes calibration */
#if UC_FAMILY == XMC1
      // wait until calibration is started
      while ((group_ptr->ARBCFG & (uint32_t)VADC_G_ARBCFG_CALS_Msk) == 0)
      {
        __NOP();
      }
#endif
      while ((group_ptr->ARBCFG) & (uint32_t)VADC_G_ARBCFG_CAL_Msk)
      {
        __NOP();
      }
    }
  }
#else

  /* Loop until calibration is started */
  while ((((SHS0->SHSCFG) & (uint32_t)SHS_SHSCFG_STATE_Msk) >> (uint32_t)SHS_SHSCFG_STATE_Pos) !=
         XMC_VADC_SHS_START_UP_CAL_ACTIVE  )
  {
    __NOP();
  }
  /* Loop until it finishes calibration */
  while ((((SHS0->SHSCFG) & (uint32_t)SHS_SHSCFG_STATE_Msk) >> (uint32_t)SHS_SHSCFG_STATE_Pos) ==
         XMC_VADC_SHS_START_UP_CAL_ACTIVE )
  {
    __NOP();
  }
#endif
}

/* API to set boudaries for result of conversion. Should the boundaries be violated, interrupts are generated */
#if (XMC_VADC_BOUNDARY_AVAILABLE == 1U)
void XMC_VADC_GLOBAL_SetBoundaries(XMC_VADC_GLOBAL_t *const global_ptr,
                                   const uint32_t boundary0,
                                   const uint32_t boundary1)
{
  uint32_t globbound;

  XMC_ASSERT("XMC_VADC_GLOBAL_SetBoundaries:Wrong Module Pointer", (global_ptr == VADC))

  globbound = 0U;
  globbound |= (uint32_t) (boundary0 << VADC_GLOBBOUND_BOUNDARY0_Pos);
  globbound |= (uint32_t) (boundary1 << VADC_GLOBBOUND_BOUNDARY1_Pos);

  global_ptr->GLOBBOUND = globbound;
}

/* API to set an individual boundary for conversion results */
void XMC_VADC_GLOBAL_SetIndividualBoundary(XMC_VADC_GLOBAL_t *const global_ptr,
    const XMC_VADC_CHANNEL_BOUNDARY_t selection,
    const uint16_t boundary_value)
{

  uint32_t globbound;

  XMC_ASSERT("XMC_VADC_GLOBAL_SetBoundaries:Wrong Module Pointer", (global_ptr == VADC))
  XMC_ASSERT("XMC_VADC_GLOBAL_SetBoundaries:Wrong Boundary Selection",
             ((XMC_VADC_CHANNEL_BOUNDARY_GLOBAL_BOUND0 == selection) ||
              (XMC_VADC_CHANNEL_BOUNDARY_GLOBAL_BOUND1 == selection)))

  /* Program the Boundary registers */
  globbound = global_ptr->GLOBBOUND;

  if (XMC_VADC_CHANNEL_BOUNDARY_GLOBAL_BOUND0 == selection)
  {
    globbound &= ~((uint32_t) VADC_GLOBBOUND_BOUNDARY0_Msk);
    globbound |= (uint32_t) ((uint32_t) boundary_value << VADC_GLOBBOUND_BOUNDARY0_Pos);
  }
  else if (XMC_VADC_CHANNEL_BOUNDARY_GLOBAL_BOUND1 == selection)
  {
    globbound &= ~((uint32_t) VADC_GLOBBOUND_BOUNDARY1_Msk);
    globbound |= (uint32_t) ((uint32_t) boundary_value << VADC_GLOBBOUND_BOUNDARY1_Pos);
  }
  else
  {
    /* For MISRA*/
  }
  global_ptr->GLOBBOUND = globbound;

}

#endif

/* API to set compare value for the result register. Result of conversion is compared against this compare value */
void XMC_VADC_GLOBAL_SetCompareValue(XMC_VADC_GLOBAL_t *const global_ptr, const XMC_VADC_RESULT_SIZE_t compare_val)
{
  XMC_ASSERT("XMC_VADC_GLOBAL_SetCompareValue:Wrong Module Pointer", (global_ptr == VADC))

  global_ptr->GLOBRES &= ~((uint32_t)VADC_GLOBRES_RESULT_Msk);
  global_ptr->GLOBRES |= (uint32_t)((uint32_t)compare_val << XMC_VADC_RESULT_LEFT_ALIGN_10BIT);
}

/* API to retrieve the result of comparison */
XMC_VADC_FAST_COMPARE_t XMC_VADC_GLOBAL_GetCompareResult(XMC_VADC_GLOBAL_t *const global_ptr)
{
  XMC_VADC_FAST_COMPARE_t result;
  uint32_t res;

  XMC_ASSERT("XMC_VADC_GLOBAL_GetCompareResult:Wrong Module Pointer", (global_ptr == VADC))

  res = global_ptr->GLOBRES;

  if (res & (uint32_t)VADC_GLOBRES_VF_Msk)
  {
    result = (XMC_VADC_FAST_COMPARE_t)((uint32_t)(res >> (uint32_t)VADC_GLOBRES_FCR_Pos) & (uint32_t)1);
  }
  else
  {
    result = XMC_VADC_FAST_COMPARE_UNKNOWN;
  }

  return result;
}

/* Bind one of the four groups to one of the two EMUX interfaces */
#if (XMC_VADC_EMUX_AVAILABLE == 1U)
void XMC_VADC_GLOBAL_BindGroupToEMux(XMC_VADC_GLOBAL_t *const global_ptr, const uint32_t emuxif, const uint32_t group)
{
  uint32_t mask;
  uint32_t pos;

  XMC_ASSERT("XMC_VADC_GLOBAL_BindGroupToEMux:Wrong Module Pointer", (global_ptr == VADC))
  XMC_ASSERT("XMC_VADC_GLOBAL_BindGroupToEMux:Wrong EMUX Group", (emuxif < XMC_VADC_NUM_EMUX_INTERFACES))
  XMC_ASSERT("XMC_VADC_GLOBAL_BindGroupToEMux:Wrong VADC Group", (group < XMC_VADC_MAXIMUM_NUM_GROUPS))

  if (0U == emuxif)
  {
    pos  = (uint32_t)VADC_EMUXSEL_EMUXGRP0_Pos;
    mask = (uint32_t)VADC_EMUXSEL_EMUXGRP0_Msk;
  }
  else
  {
    pos  = (uint32_t)VADC_EMUXSEL_EMUXGRP1_Pos;
    mask = (uint32_t)VADC_EMUXSEL_EMUXGRP1_Msk;
  }

  global_ptr->EMUXSEL &= ~(mask);
  global_ptr->EMUXSEL |= (uint32_t) (group << pos);

}
#endif

/* API to bind result event with a service request line */
void XMC_VADC_GLOBAL_SetResultEventInterruptNode(XMC_VADC_GLOBAL_t *const global_ptr, XMC_VADC_SR_t sr)
{
  uint32_t node;

  XMC_ASSERT("XMC_VADC_GLOBAL_SetResultEventInterruptNode:Wrong Module Pointer", (global_ptr == VADC))
  XMC_ASSERT("XMC_VADC_GLOBAL_SetResultEventInterruptNode:Wrong SR Number", (sr <= XMC_VADC_SR_SHARED_SR3))

  if (sr >= XMC_VADC_SR_SHARED_SR0)
  {
    node = (uint32_t)sr - (uint32_t)XMC_VADC_SR_SHARED_SR0;
  }
  else
  {
    node = (uint32_t)sr;
  }

  global_ptr->GLOBEVNP &= ~((uint32_t)VADC_GLOBEVNP_REV0NP_Msk);
  global_ptr->GLOBEVNP |= (uint32_t)(node << VADC_GLOBEVNP_REV0NP_Pos);
}

/* API to bind request source event with a service request line */
void XMC_VADC_GLOBAL_BackgroundSetReqSrcEventInterruptNode(XMC_VADC_GLOBAL_t *const global_ptr, XMC_VADC_SR_t sr)
{
  uint32_t node;

  XMC_ASSERT("XMC_VADC_GLOBAL_BackgroundSetReqSrcEventInterruptNode:Wrong Module Pointer", (global_ptr == VADC))

  if (sr >= XMC_VADC_SR_SHARED_SR0)
  {
    node = (uint32_t)sr - (uint32_t)XMC_VADC_SR_SHARED_SR0;
  }
  else
  {
    node = (uint32_t)sr;
  }

  global_ptr->GLOBEVNP &= ~((uint32_t)VADC_GLOBEVNP_SEV0NP_Msk);
  global_ptr->GLOBEVNP |= (uint32_t) (node << VADC_GLOBEVNP_SEV0NP_Pos);
}

/* API to initialize an instance of group of VADC hardware */
#if (XMC_VADC_GROUP_AVAILABLE == 1U)
void XMC_VADC_GROUP_Init( XMC_VADC_GROUP_t *const group_ptr, const XMC_VADC_GROUP_CONFIG_t *config)
{
  XMC_ASSERT("XMC_VADC_GROUP_Init:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))

  /* Program the input classes */
  XMC_VADC_GROUP_InputClassInit(group_ptr, config->class0, XMC_VADC_GROUP_CONV_STD, 0U);
  XMC_VADC_GROUP_InputClassInit(group_ptr, config->class0, XMC_VADC_GROUP_CONV_EMUX, 0U);
  XMC_VADC_GROUP_InputClassInit(group_ptr, config->class1, XMC_VADC_GROUP_CONV_STD, 1U);
  XMC_VADC_GROUP_InputClassInit(group_ptr, config->class1, XMC_VADC_GROUP_CONV_EMUX, 1U);

  group_ptr->ARBCFG = config->g_arbcfg;

  group_ptr->BOUND = config->g_bound;

  /* External mux configuration */
  XMC_VADC_GROUP_ExternalMuxControlInit(group_ptr, config->emux_config);

}

/* API to program conversion characteristics */
void XMC_VADC_GROUP_InputClassInit(XMC_VADC_GROUP_t *const group_ptr, const XMC_VADC_GROUP_CLASS_t config,
                                   const XMC_VADC_GROUP_CONV_t conv_type, const uint32_t set_num)
{
  uint32_t        conv_class;
  uint32_t        conv_mode_pos;
  uint32_t        sample_time_pos;
  uint32_t        conv_mode_mask;
  uint32_t        sample_time_mask;
  uint32_t        sample_time;
  XMC_VADC_CONVMODE_t conv_mode;

  XMC_ASSERT("XMC_VADC_GROUP_InputClassInit:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_InputClassInit:Wrong Conversion Type", ((conv_type) <= XMC_VADC_GROUP_CONV_EMUX))
  XMC_ASSERT("XMC_VADC_GROUP_InputClassInit:Wrong ICLASS set number", (set_num < XMC_VADC_MAX_ICLASS_SET))

  /*
   * Obtain the mask and position macros of the parameters based on what is being requested - Standard channels vs
   * external mux channels.
   */
  if (XMC_VADC_GROUP_CONV_STD == conv_type)
  {
    conv_mode_pos    = (uint32_t) VADC_G_ICLASS_CMS_Pos;
    conv_mode_mask   = (uint32_t) VADC_G_ICLASS_CMS_Msk;
    sample_time_pos  = (uint32_t) VADC_G_ICLASS_STCS_Pos;
    sample_time_mask = (uint32_t) VADC_G_ICLASS_STCS_Msk;
    sample_time      = (uint32_t) config.sample_time_std_conv;
    conv_mode        = (XMC_VADC_CONVMODE_t)config.conversion_mode_standard;
  }
  else
  {
    conv_mode_pos    = (uint32_t) VADC_G_ICLASS_CME_Pos;
    conv_mode_mask   = (uint32_t) VADC_G_ICLASS_CME_Msk;
    sample_time_pos  = (uint32_t) VADC_G_ICLASS_STCE_Pos;
    sample_time_mask = (uint32_t) VADC_G_ICLASS_STCE_Msk;
    sample_time      = (uint32_t) config.sampling_phase_emux_channel;
    conv_mode        = (XMC_VADC_CONVMODE_t)config.conversion_mode_emux;
  }

  /* Determine the class */
  conv_class  = group_ptr->ICLASS[set_num];

  /* Program the class register */
  conv_class &= ~(conv_mode_mask);
  conv_class |= (uint32_t)((uint32_t) conv_mode << conv_mode_pos);
  conv_class &= ~(sample_time_mask);
  conv_class |= (uint32_t)(sample_time <<  sample_time_pos);
  group_ptr->ICLASS[set_num] = conv_class;
}

/* API which sets the power mode of analog converter of a VADC group */
void XMC_VADC_GROUP_SetPowerMode(XMC_VADC_GROUP_t *const group_ptr, const XMC_VADC_GROUP_POWERMODE_t power_mode)
{
  uint32_t arbcfg;

  XMC_ASSERT("XMC_VADC_GROUP_SetPowerMode:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_SetPowerMode:Wrong Power Mode", (power_mode <= XMC_VADC_GROUP_POWERMODE_NORMAL))

  arbcfg = group_ptr->ARBCFG;

  arbcfg &= ~((uint32_t)VADC_G_ARBCFG_ANONC_Msk);
  arbcfg |= (uint32_t)power_mode;

  group_ptr->ARBCFG = arbcfg;
}

/* API which programs a group as a slave group during sync conversions */
void XMC_VADC_GROUP_SetSyncSlave(XMC_VADC_GROUP_t *const group_ptr, uint32_t master_grp, uint32_t slave_grp)
{
  uint32_t synctr;
#if (XMC_VADC_MULTIPLE_SLAVEGROUPS == 1U )
#endif
  XMC_ASSERT("XMC_VADC_GROUP_SetSyncSlave:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))

#if (XMC_VADC_MULTIPLE_SLAVEGROUPS == 1U )

  /* Determine the coding of SYNCTR */
  if (slave_grp > master_grp)
  {
    master_grp = master_grp + 1U;
  }
#endif

  /* Program SYNCTR */
  synctr = group_ptr->SYNCTR;
  synctr   &= ~((uint32_t)VADC_G_SYNCTR_STSEL_Msk);
  synctr   |= master_grp;
  group_ptr->SYNCTR = synctr;
}

/* API which programs a group as a master group during sync conversions */
void XMC_VADC_GROUP_SetSyncMaster(XMC_VADC_GROUP_t *const group_ptr)
{
  uint32_t synctr;

  XMC_ASSERT("XMC_VADC_GROUP_SetSyncMaster:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))

  synctr = group_ptr->SYNCTR;
  synctr   &= ~((uint32_t)VADC_G_SYNCTR_STSEL_Msk);
  group_ptr->SYNCTR = synctr;
}

/* API to enable checking of readiness of slaves before a synchronous conversion request is issued */
void XMC_VADC_GROUP_CheckSlaveReadiness(XMC_VADC_GROUP_t *const group_ptr, uint32_t slave_group)
{
  uint32_t i, master_grp_num;
  XMC_ASSERT("XMC_VADC_GROUP_CheckSlaveReadiness:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_CheckSlaveReadiness:Wrong Slave group", (slave_group <= (XMC_VADC_MAXIMUM_NUM_GROUPS - 1)))

  master_grp_num = 0;
  for (i = 0; i < XMC_VADC_MAXIMUM_NUM_GROUPS; i++)
  {
    if (g_xmc_vadc_group_array[i] == group_ptr)
    {
      master_grp_num = i;
    }
  }


  if (slave_group < master_grp_num)
  {
    slave_group++;
  }
  group_ptr->SYNCTR |= (1U << (slave_group + XMC_VADC_SYNCTR_START_LOCATION));
}

/* API to disable checking of readiness of slaves during synchronous conversions */
void XMC_VADC_GROUP_IgnoreSlaveReadiness(XMC_VADC_GROUP_t *const group_ptr, uint32_t slave_group)
{
  uint32_t i, master_grp_num;
  XMC_ASSERT("XMC_VADC_GROUP_IgnoreSlaveReadiness:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_IgnoreSlaveReadiness:Wrong Slave group", (slave_group <= (XMC_VADC_MAXIMUM_NUM_GROUPS - 1)))

  master_grp_num = 0;
  for (i = 0; i < XMC_VADC_MAXIMUM_NUM_GROUPS; i++)
  {
    if (g_xmc_vadc_group_array[i] == group_ptr)
    {
      master_grp_num = i;
    }
  }

  if (slave_group < master_grp_num)
  {
    slave_group++;
  }
  group_ptr->SYNCTR &= ~(1U << (slave_group + XMC_VADC_SYNCTR_START_LOCATION));
}

/* API to configure EVAL bit in the slave groups*/
void XMC_VADC_GROUP_SetSyncSlaveReadySignal(XMC_VADC_GROUP_t *const group_ptr,
    uint32_t eval_waiting_group,
    uint32_t eval_origin_group)
{
  XMC_ASSERT("XMC_VADC_GROUP_SetSyncSlaveReadySignal:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_SetSyncSlaveReadySignal:Wrong Group numbers", (eval_waiting_group != eval_origin_group ))

  if (eval_origin_group < eval_waiting_group)
  {
    eval_origin_group++;
  }
  group_ptr->SYNCTR |= (1U << (eval_origin_group + XMC_VADC_SYNCTR_START_LOCATION));
}


/* API to enable the synchronous conversion feature - Applicable only to kernel configured as master */
void XMC_VADC_GROUP_EnableChannelSyncRequest(XMC_VADC_GROUP_t *const group_ptr, const uint32_t ch_num)
{
  uint32_t synctr;

  XMC_ASSERT("XMC_VADC_GROUP_EnableChannelSyncRequest:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_EnableChannelSyncRequest:Wrong Channel Number",
             ((ch_num) < XMC_VADC_NUM_CHANNELS_PER_GROUP))

  synctr  = group_ptr->SYNCTR;

  if (!(synctr &  (uint32_t)VADC_G_SYNCTR_STSEL_Msk))
  {
    group_ptr->CHCTR[ch_num] |= (uint32_t)((uint32_t)1 << VADC_G_CHCTR_SYNC_Pos);
  }
}

/* API to disable synchronous conversion feature */
void XMC_VADC_GROUP_DisableChannelSyncRequest(XMC_VADC_GROUP_t *const group_ptr, const uint32_t ch_num)
{
  uint32_t    synctr;

  XMC_ASSERT("XMC_VADC_GROUP_DisableChannelSyncRequest:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_DisableChannelSyncRequest:Wrong Channel Number",
             ((ch_num) < XMC_VADC_NUM_CHANNELS_PER_GROUP))

  synctr  = group_ptr->SYNCTR;

  if (synctr &  (uint32_t)VADC_G_SYNCTR_STSEL_Msk)
  {
    group_ptr->CHCTR[ch_num] &= ~((uint32_t)VADC_G_CHCTR_SYNC_Msk);
  }
}

/* API to retrieve the converter state - Idle vs Busy */
XMC_VADC_GROUP_STATE_t XMC_VADC_GROUP_IsConverterBusy(XMC_VADC_GROUP_t *const group_ptr)
{
  uint32_t      arbcfg;

  XMC_ASSERT("XMC_VADC_GROUP_IsConverterBusy:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))

  arbcfg  = group_ptr->ARBCFG;
  arbcfg &= (uint32_t)VADC_G_ARBCFG_BUSY_Msk;
  arbcfg = arbcfg >> VADC_G_ARBCFG_BUSY_Pos;

  return ( (XMC_VADC_GROUP_STATE_t)arbcfg);
}

/* API to set boundaries for conversion results */
void XMC_VADC_GROUP_SetBoundaries(XMC_VADC_GROUP_t *const group_ptr, const uint32_t boundary0, const uint32_t boundary1)
{
  uint32_t bound;

  XMC_ASSERT("XMC_VADC_GROUP_SetBoundaries:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))

  /* Program the Boundary registers */
  bound  = group_ptr->BOUND;
  bound &= ~((uint32_t) VADC_G_BOUND_BOUNDARY0_Msk);
  bound &= ~((uint32_t) VADC_G_BOUND_BOUNDARY1_Msk);
  bound |= (uint32_t) ((uint32_t) boundary0 << VADC_G_BOUND_BOUNDARY0_Pos);
  bound |= (uint32_t) ((uint32_t) boundary1 << VADC_G_BOUND_BOUNDARY1_Pos);
  group_ptr->BOUND = bound;
}

/* API to set an individual boundary for conversion results */
void XMC_VADC_GROUP_SetIndividualBoundary(XMC_VADC_GROUP_t *const group_ptr,
    const XMC_VADC_CHANNEL_BOUNDARY_t selection,
    const uint16_t boundary_value)
{

  uint32_t bound;

  XMC_ASSERT("XMC_VADC_GROUP_SetIndividualBoundary:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_SetIndividualBoundary:Wrong Boundary Selection",
             ((XMC_VADC_CHANNEL_BOUNDARY_GROUP_BOUND0 == selection) ||
              (XMC_VADC_CHANNEL_BOUNDARY_GROUP_BOUND1 == selection)))

  /* Program the Boundary registers */
  bound  = group_ptr->BOUND;
  if (XMC_VADC_CHANNEL_BOUNDARY_GROUP_BOUND0 == selection)
  {
    bound &= ~((uint32_t) VADC_G_BOUND_BOUNDARY0_Msk);
    bound |= (uint32_t) ((uint32_t) boundary_value << VADC_G_BOUND_BOUNDARY0_Pos);
  }
  else if (XMC_VADC_CHANNEL_BOUNDARY_GROUP_BOUND1 == selection)
  {
    bound &= ~((uint32_t) VADC_G_BOUND_BOUNDARY1_Msk);
    bound |= (uint32_t) ((uint32_t) boundary_value << VADC_G_BOUND_BOUNDARY1_Pos);
  }
  else
  {
    /* For MISRA*/
  }
  group_ptr->BOUND = bound;

}

/* Manually assert service request (Interrupt) to NVIC */
void XMC_VADC_GROUP_TriggerServiceRequest(XMC_VADC_GROUP_t *const group_ptr,
    const uint32_t sr_num,
    const XMC_VADC_GROUP_IRQ_t type)
{
  uint32_t sract;

  XMC_ASSERT("XMC_VADC_GROUP_TriggerServiceRequest:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_TriggerServiceRequest:Wrong SR number", (sr_num <= XMC_VADC_SR_SHARED_SR3))
  XMC_ASSERT("XMC_VADC_GROUP_TriggerServiceRequest:Wrong SR type", ((type) <= XMC_VADC_GROUP_IRQ_SHARED))

  sract = group_ptr->SRACT;

  if (XMC_VADC_GROUP_IRQ_KERNEL == type)
  {
    sract |= (uint32_t)((uint32_t)1 << sr_num);
  }
  else
  {
    sract |= (uint32_t)((uint32_t)1 << (sr_num + (uint32_t)8));
  }

  group_ptr->SRACT = sract;
}

#if XMC_VADC_BOUNDARY_FLAG_SELECT == 1U

/* API to set the SR line for the Boundary flag node pointer*/
void XMC_VADC_GROUP_SetBoundaryEventInterruptNode(XMC_VADC_GROUP_t *const group_ptr,
    const uint8_t boundary_flag_num,
    const XMC_VADC_BOUNDARY_NODE_t sr)
{
  uint32_t flag_pos;
  XMC_ASSERT("XMC_VADC_GROUP_SetBoundaryEventInterruptNode:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))

  /* Program the GxBFLNP */
  flag_pos = (uint32_t)boundary_flag_num << (uint32_t)2;
  group_ptr->BFLNP &= ~((uint32_t)VADC_G_BFLNP_BFL0NP_Msk << flag_pos);
  group_ptr->BFLNP |= (uint32_t)sr << flag_pos;
}

#endif

#endif

#if(XMC_VADC_SHS_AVAILABLE == 1U)

/* API to Initialize the Sample and hold features*/
void XMC_VADC_GLOBAL_SHS_Init(XMC_VADC_GLOBAL_SHS_t *const shs_ptr, const XMC_VADC_GLOBAL_SHS_CONFIG_t *config)
{
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_Init:Wrong SHS Pointer", (shs_ptr == (XMC_VADC_GLOBAL_SHS_t *)(void *)SHS0))
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_Init:Wrong Index number", (config == (XMC_VADC_GLOBAL_SHS_CONFIG_t *)NULL))

  /* Initialize the SHS Configuration register*/
  shs_ptr->SHSCFG = (uint32_t)((uint32_t)config->shscfg | (uint32_t)SHS_SHSCFG_SCWC_Msk);

#if(XMC_VADC_SHS_FULL_SET_REG == 1U)
  /* Select the Calibration order*/
  shs_ptr->CALCTR &= ~((uint32_t)SHS_CALCTR_CALORD_Msk);
  shs_ptr->CALCTR |=  (uint32_t) ((uint32_t)config->calibration_order << SHS_CALCTR_CALORD_Pos);
#endif
}

#if(XMC_VADC_SHS_FULL_SET_REG == 1U)
/* API to enable the accelerated mode of conversion */
void XMC_VADC_GLOBAL_SHS_EnableAcceleratedMode(XMC_VADC_GLOBAL_SHS_t *const shs_ptr, XMC_VADC_GROUP_INDEX_t group_num)
{
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_EnableAcceleratedMode:Wrong SHS Pointer",
             (shs_ptr == (XMC_VADC_GLOBAL_SHS_t *)(void *)SHS0))
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_EnableAcceleratedMode:Wrong Index number", (group_num <= XMC_VADC_GROUP_INDEX_1))

  /* Set the converted to Accelerated mode from compatible mode*/
  if (group_num == XMC_VADC_GROUP_INDEX_0 )
  {
    shs_ptr->TIMCFG0 |= (uint32_t)SHS_TIMCFG0_AT_Msk;
  }
  else if (group_num == XMC_VADC_GROUP_INDEX_1 )
  {
    shs_ptr->TIMCFG1 |= (uint32_t)SHS_TIMCFG1_AT_Msk;
  }
  else
  {
    /* for MISRA*/
  }
}

/* API to disable the accelerated mode of conversion */
void XMC_VADC_GLOBAL_SHS_DisableAcceleratedMode(XMC_VADC_GLOBAL_SHS_t *const shs_ptr, XMC_VADC_GROUP_INDEX_t group_num)
{
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_DisableAcceleratedMode:Wrong SHS Pointer",
             (shs_ptr == (XMC_VADC_GLOBAL_SHS_t *)(void *)SHS0))
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_DisableAcceleratedMode:Wrong Index number", (group_num <= XMC_VADC_GROUP_INDEX_1))

  /* Set the converted to Accelerated mode from compatible mode*/
  if (group_num == XMC_VADC_GROUP_INDEX_0 )
  {
    shs_ptr->TIMCFG0 &= ~(uint32_t)SHS_TIMCFG0_AT_Msk;
  }
  else if (group_num == XMC_VADC_GROUP_INDEX_1 )
  {
    shs_ptr->TIMCFG1 &= ~(uint32_t)SHS_TIMCFG1_AT_Msk;
  }
  else
  {
    /* for MISRA*/
  }
}

/* API to set the Short sample time of the Sample and hold module*/
void XMC_VADC_GLOBAL_SHS_SetShortSampleTime(XMC_VADC_GLOBAL_SHS_t *const shs_ptr,
    XMC_VADC_GROUP_INDEX_t group_num,
    uint8_t sst_value)
{
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_SetShortSampleTime:Wrong SHS Pointer",
             (shs_ptr == (XMC_VADC_GLOBAL_SHS_t *)(void *)SHS0))
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_SetShortSampleTime:Wrong Index number", (group_num <= XMC_VADC_GROUP_INDEX_1))
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_SetShortSampleTime:Wrong SST value", (sst_value < 64U))

  /* Set the short sample time for the Accelerated mode of operation*/
  if (group_num == XMC_VADC_GROUP_INDEX_0 )
  {
    shs_ptr->TIMCFG0 &= ~((uint32_t)SHS_TIMCFG0_SST_Msk);
    shs_ptr->TIMCFG0 |= (uint32_t)((uint32_t)sst_value << SHS_TIMCFG0_SST_Pos );
  }
  else if (group_num == XMC_VADC_GROUP_INDEX_1 )
  {
    shs_ptr->TIMCFG1 &= ~((uint32_t)SHS_TIMCFG1_SST_Msk);
    shs_ptr->TIMCFG1 |= (uint32_t)((uint32_t)sst_value << SHS_TIMCFG1_SST_Pos );
  }
  else
  {
    /* for MISRA*/
  }
}
#endif

/* API to set the gain factor of the Sample and hold module*/
void XMC_VADC_GLOBAL_SHS_SetGainFactor(XMC_VADC_GLOBAL_SHS_t *const shs_ptr,
                                       uint8_t gain_value,
                                       XMC_VADC_GROUP_INDEX_t group_num,
                                       uint8_t ch_num)
{
  uint32_t ch_mask;

  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_SetGainFactor:Wrong SHS Pointer", (shs_ptr == (XMC_VADC_GLOBAL_SHS_t *)(void *)SHS0))
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_SetGainFactor:Wrong Index number", (group_num <= XMC_VADC_GROUP_INDEX_1))

  /*Calculate location of channel bit-field*/
  ch_mask = ((uint32_t)ch_num << (uint32_t)2);
  if (group_num == XMC_VADC_GROUP_INDEX_0 )
  {
    shs_ptr->GNCTR00 &= ~((uint32_t)SHS_GNCTR00_GAIN0_Msk << ch_mask) ;
    shs_ptr->GNCTR00 |=  ((uint32_t)gain_value << ch_mask);
  }
  else if (group_num == XMC_VADC_GROUP_INDEX_1 )
  {
    shs_ptr->GNCTR10 &= ~((uint32_t)SHS_GNCTR10_GAIN0_Msk << ch_mask);
    shs_ptr->GNCTR10 |=  ((uint32_t)gain_value << ch_mask);
  }
  else
  {
    /* for MISRA*/
  }
}

#if(XMC_VADC_SHS_FULL_SET_REG == 1U)
/* API to enable the gain and offset calibration of the Sample and hold module*/
void XMC_VADC_GLOBAL_SHS_EnableGainAndOffsetCalibrations(XMC_VADC_GLOBAL_SHS_t *const shs_ptr,
    XMC_VADC_GROUP_INDEX_t group_num)
{
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_EnableGainAndOffsetCalibrations:Wrong SHS Pointer",
             (shs_ptr == (XMC_VADC_GLOBAL_SHS_t *)(void *)SHS0))
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_EnableGainAndOffsetCalibrations:Wrong group selected",
             (group_num <= (uint32_t)XMC_VADC_GROUP_INDEX_1))

  /* Enable gain and offset calibration*/
  if ( XMC_VADC_GROUP_INDEX_0 == group_num)
  {
    shs_ptr->CALOC0 &= ~((uint32_t)SHS_CALOC0_DISCAL_Msk);
  }
  else if ( XMC_VADC_GROUP_INDEX_1 == group_num)
  {
    shs_ptr->CALOC1 &= ~((uint32_t)SHS_CALOC1_DISCAL_Msk);
  }
  else
  {
    /* for MISRA */
  }
}

/* API to enable the gain and offset calibration of the Sample and hold module*/
void XMC_VADC_GLOBAL_SHS_DisableGainAndOffsetCalibrations(XMC_VADC_GLOBAL_SHS_t *const shs_ptr,
    XMC_VADC_GROUP_INDEX_t group_num)
{
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_DisableGainAndOffsetCalibrations:Wrong SHS Pointer",
             (shs_ptr == (XMC_VADC_GLOBAL_SHS_t *)(void *)SHS0))
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_DisableGainAndOffsetCalibrations:Wrong group selected",
             (group_num <= (uint32_t)XMC_VADC_GROUP_INDEX_1))

  if ( XMC_VADC_GROUP_INDEX_0 == group_num)
  {
    shs_ptr->CALOC0 |= (uint32_t)SHS_CALOC0_DISCAL_Msk;
  }
  else if ( XMC_VADC_GROUP_INDEX_1 == group_num)
  {
    shs_ptr->CALOC1 |= (uint32_t)SHS_CALOC1_DISCAL_Msk;
  }
  else
  {
    /* for MISRA */
  }
}

/* API to get the offset calibration value of the Sample and hold module*/
uint8_t XMC_VADC_GLOBAL_SHS_GetOffsetCalibrationValue(XMC_VADC_GLOBAL_SHS_t *const shs_ptr,
    XMC_VADC_GROUP_INDEX_t group_num,
    XMC_VADC_SHS_GAIN_LEVEL_t gain_level)
{
  uint32_t calibration_value;
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_GetOffsetCalibrationValue:Wrong SHS Pointer",
             (shs_ptr == (XMC_VADC_GLOBAL_SHS_t *)(void *)SHS0))
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_GetOffsetCalibrationValue:Wrong Group number selected",
             (group_num == XMC_VADC_GROUP_INDEX_0) || (group_num == XMC_VADC_GROUP_INDEX_1))
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_GetOffsetCalibrationValue:Wrong gain level selected",
             (gain_level == XMC_VADC_SHS_GAIN_LEVEL_0) || (gain_level == XMC_VADC_SHS_GAIN_LEVEL_1) ||
             (gain_level == XMC_VADC_SHS_GAIN_LEVEL_2) || (gain_level == XMC_VADC_SHS_GAIN_LEVEL_3))

  calibration_value = 0U;
  if ( XMC_VADC_GROUP_INDEX_0 == group_num)
  {
    calibration_value = (shs_ptr->CALOC0 >> (uint32_t)gain_level) & (uint32_t)SHS_CALOC0_CALOFFVAL0_Msk;
  }
  else if ( XMC_VADC_GROUP_INDEX_1 == group_num)
  {
    calibration_value = (shs_ptr->CALOC1 >> (uint32_t)gain_level) & (uint32_t)SHS_CALOC1_CALOFFVAL0_Msk;
  }
  else
  {
    /* for MISRA */
  }
  return ((uint8_t)calibration_value);
}

/* API to set the offset calibration value of the Sample and hold module*/
void XMC_VADC_GLOBAL_SHS_SetOffsetCalibrationValue(XMC_VADC_GLOBAL_SHS_t *const shs_ptr,
    XMC_VADC_GROUP_INDEX_t group_num,
    XMC_VADC_SHS_GAIN_LEVEL_t gain_level,
    uint8_t offset_calibration_value)
{
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_SetOffsetCalibrationValue:Wrong SHS Pointer",
             (shs_ptr == (XMC_VADC_GLOBAL_SHS_t *)(void *)SHS0))
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_SetOffsetCalibrationValue:Wrong Group number selected",
             (group_num == XMC_VADC_GROUP_INDEX_0) || (group_num == XMC_VADC_GROUP_INDEX_1))
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_SetOffsetCalibrationValue:Wrong gain level selected",
             (gain_level == XMC_VADC_SHS_GAIN_LEVEL_0) || (gain_level == XMC_VADC_SHS_GAIN_LEVEL_1) ||
             (gain_level == XMC_VADC_SHS_GAIN_LEVEL_2) || (gain_level == XMC_VADC_SHS_GAIN_LEVEL_3))

  if ( XMC_VADC_GROUP_INDEX_0 == group_num)
  {
    shs_ptr->CALOC0 = (shs_ptr->CALOC0  & ~((uint32_t)SHS_CALOC0_CALOFFVAL0_Msk << (uint32_t)gain_level)) |
                      (uint32_t)SHS_CALOC0_OFFWC_Msk;
    shs_ptr->CALOC0 |=  ((uint32_t)offset_calibration_value << (uint32_t)gain_level) | (uint32_t)SHS_CALOC0_OFFWC_Msk;
  }
  else if ( XMC_VADC_GROUP_INDEX_1 == group_num)
  {
    shs_ptr->CALOC1 = (shs_ptr->CALOC1 & ~((uint32_t)SHS_CALOC1_CALOFFVAL0_Msk << (uint32_t)gain_level)) |
                      (uint32_t)SHS_CALOC1_OFFWC_Msk;
    shs_ptr->CALOC1 |=  ((uint32_t)offset_calibration_value << (uint32_t)gain_level) | (uint32_t)SHS_CALOC1_OFFWC_Msk;
  }
  else
  {
    /* for MISRA */
  }
}
#endif

/* API to set the values of sigma delta loop of the Sample and hold module*/
void XMC_VADC_GLOBAL_SHS_SetSigmaDeltaLoop(XMC_VADC_GLOBAL_SHS_t *const shs_ptr,
    XMC_VADC_GROUP_INDEX_t group_num,
    XMC_VADC_SHS_LOOP_CH_t loop_select,
    uint8_t ch_num)
{
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_SetSigmaDeltaLoop:Wrong SHS Pointer",
             (shs_ptr == (XMC_VADC_GLOBAL_SHS_t *)(void *)SHS0))
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_SetSigmaDeltaLoop:Wrong Group number selected",
             (group_num == XMC_VADC_GROUP_INDEX_0) || (group_num == XMC_VADC_GROUP_INDEX_1))
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_SetSigmaDeltaLoop:Wrong Delta sigma loop selected",
             (loop_select == XMC_VADC_SHS_LOOP_CH_0) || (loop_select == XMC_VADC_SHS_LOOP_CH_1))
  XMC_ASSERT("XMC_VADC_GLOBAL_SHS_SetSigmaDeltaLoop:Wrong Channel Number",
             ((ch_num) < XMC_VADC_NUM_CHANNELS_PER_GROUP))

  shs_ptr->LOOP &= ~(((uint32_t)SHS_LOOP_LPCH0_Msk | (uint32_t)SHS_LOOP_LPSH0_Msk | (uint32_t)SHS_LOOP_LPEN0_Msk)
                     << (uint32_t)loop_select);
  shs_ptr->LOOP |= ((uint32_t)ch_num | ((uint32_t)group_num << (uint32_t)SHS_LOOP_LPSH0_Pos)) << (uint32_t)loop_select;

}

#endif

#if (XMC_VADC_GSCAN_AVAILABLE == 1U)
/* API to initialize the group scan hardware of a kernel */
void XMC_VADC_GROUP_ScanInit(XMC_VADC_GROUP_t *const group_ptr, const XMC_VADC_SCAN_CONFIG_t *config)
{
  uint32_t      reg;

  XMC_ASSERT("XMC_VADC_GROUP_ScanInit:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))

  /* All configurations have to be performed with the arbitration slot disabled */
  XMC_VADC_GROUP_ScanDisableArbitrationSlot(group_ptr);

  /* Read in the existing contents of arbitration priority register */
  reg = group_ptr->ARBPR;

  /* Program the priority of the request source */
  reg &= ~(uint32_t)VADC_G_ARBPR_PRIO1_Msk;
  reg |= (uint32_t)((uint32_t)config->req_src_priority << VADC_G_ARBPR_PRIO1_Pos);

  /* Program the start mode */
  if (XMC_VADC_STARTMODE_WFS != (XMC_VADC_STARTMODE_t)(config->conv_start_mode))
  {
    reg |= (uint32_t)(VADC_G_ARBPR_CSM1_Msk);
  }

  group_ptr->ARBPR = reg;

  group_ptr->ASCTRL = (uint32_t)(config->asctrl | (VADC_G_ASCTRL_XTWC_Msk) | (VADC_G_ASCTRL_GTWC_Msk) |
                                 (VADC_G_ASCTRL_TMWC_Msk));

  group_ptr->ASMR  = (uint32_t)((config->asmr) | (uint32_t)((uint32_t)XMC_VADC_GATEMODE_IGNORE << VADC_G_ASMR_ENGT_Pos));

  if (XMC_VADC_STARTMODE_CNR == (XMC_VADC_STARTMODE_t)(config->conv_start_mode))
  {
    group_ptr->ASMR |= (uint32_t)VADC_G_ASMR_RPTDIS_Msk;
  }

  /* Enable arbitration slot now */
  XMC_VADC_GROUP_ScanEnableArbitrationSlot(group_ptr);

}

/* API to select one of the 16 inputs as a trigger input for Group Scan request source */
void XMC_VADC_GROUP_ScanSelectTrigger(XMC_VADC_GROUP_t *const group_ptr, XMC_VADC_TRIGGER_INPUT_SELECT_t trigger_input)
{
  uint32_t scanctrl;

  XMC_ASSERT("XMC_VADC_GROUP_ScanSelectTrigger:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_ScanSelectTrigger:Wrong Trigger Port", ((trigger_input) < XMC_VADC_NUM_PORTS))

  scanctrl      = group_ptr->ASCTRL;
  scanctrl     |= (uint32_t) VADC_G_ASCTRL_XTWC_Msk;
  scanctrl     &= ~((uint32_t)VADC_G_ASCTRL_XTSEL_Msk);
  scanctrl     |= (uint32_t)((uint32_t)trigger_input << VADC_G_ASCTRL_XTSEL_Pos);
  group_ptr->ASCTRL  = scanctrl;
}

/* Select a trigger edge*/
void XMC_VADC_GROUP_ScanSelectTriggerEdge(XMC_VADC_GROUP_t *const group_ptr, const XMC_VADC_TRIGGER_EDGE_t trigger_edge)
{
  uint32_t scanctrl;

  XMC_ASSERT("XMC_VADC_GROUP_ScanSelectTriggerEdge:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_ScanSelectTriggerEdge:Wrong Trigger Port", ((trigger_edge) <= XMC_VADC_TRIGGER_EDGE_ANY))

  scanctrl      = group_ptr->ASCTRL;
  scanctrl     |= (uint32_t) VADC_G_ASCTRL_XTWC_Msk;
  scanctrl     &= ~((uint32_t)VADC_G_ASCTRL_XTMODE_Msk);
  scanctrl     |= (uint32_t)((uint32_t)trigger_edge << VADC_G_ASCTRL_XTMODE_Pos);
  group_ptr->ASCTRL  = scanctrl;
}

/* API to select one of the 16 inputs as a trigger gating input for Group Scan request source */
void XMC_VADC_GROUP_ScanSelectGating(XMC_VADC_GROUP_t *const group_ptr, XMC_VADC_GATE_INPUT_SELECT_t gating_input)
{
  uint32_t scanctrl;

  XMC_ASSERT("XMC_VADC_GROUP_ScanSelectGating:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_ScanSelectGating:Wrong Gating Port", ((gating_input) < XMC_VADC_NUM_PORTS))

  scanctrl      = group_ptr->ASCTRL;
  scanctrl     |= (uint32_t)VADC_G_ASCTRL_GTWC_Msk;
  scanctrl     &= ~((uint32_t)VADC_G_ASCTRL_GTSEL_Msk);
  scanctrl     |= (uint32_t)((uint32_t)gating_input << VADC_G_ASCTRL_GTSEL_Pos);
  group_ptr->ASCTRL  = scanctrl;
}

/* API to stop an ongoing conversion of a sequence */
void XMC_VADC_GROUP_ScanSequenceAbort(XMC_VADC_GROUP_t *const group_ptr)
{
  uint32_t asctrl;
  bool arbitration_status;

  XMC_ASSERT("XMC_VADC_GROUP_ScanSequenceAbort:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))

  /* To disable trigger and gating before abort*/
  asctrl = group_ptr->ASCTRL;

  group_ptr->ASCTRL = (0U | (uint32_t)VADC_G_ASCTRL_XTWC_Msk |
                       (uint32_t)VADC_G_ASCTRL_GTWC_Msk | (uint32_t)VADC_G_ASCTRL_TMWC_Msk );

  /* To disable Arbitration before abort*/
  arbitration_status = (bool)((uint32_t)(group_ptr->ARBPR >> VADC_G_ARBPR_ASEN1_Pos) & 1U);
  XMC_VADC_GROUP_ScanDisableArbitrationSlot(group_ptr);

  group_ptr->ASMR &= ~((uint32_t)VADC_G_ASMR_ENGT_Msk);
  group_ptr->ASMR |= (uint32_t)VADC_G_ASMR_CLRPND_Msk;

  /* Enable the arbitration slot 1*/
  group_ptr->ARBPR |= (uint32_t)((uint32_t)arbitration_status << VADC_G_ARBPR_ASEN1_Pos);

  /* Enable any disabled gating*/
  group_ptr->ASCTRL = (asctrl | (uint32_t)VADC_G_ASCTRL_XTWC_Msk |
                       (uint32_t)VADC_G_ASCTRL_GTWC_Msk | (uint32_t)VADC_G_ASCTRL_TMWC_Msk );
}

/* API to find out number of channels awaiting conversion */
uint32_t XMC_VADC_GROUP_ScanGetNumChannelsPending(XMC_VADC_GROUP_t *const group_ptr)
{
  uint32_t reg;
  uint32_t i;
  uint32_t count;

  XMC_ASSERT("XMC_VADC_GROUP_ScanGetNumChannelsPending:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))


  count = 0U;

  if (group_ptr->ASPND)
  {
    reg = group_ptr->ASPND;

    for (i = 0U; i < XMC_VADC_NUM_CHANNELS_PER_GROUP; i++)
    {
      if (reg & 1U)
      {
        count++;
      }
      reg = (uint32_t)(reg >> (uint32_t)1);
    }
  }

  return count;
}

/* API to select a service request line (NVIC Node) for request source event */
void XMC_VADC_GROUP_ScanSetReqSrcEventInterruptNode(XMC_VADC_GROUP_t *const group_ptr, const XMC_VADC_SR_t sr)
{
  uint32_t sevnp;
  sevnp = group_ptr->SEVNP;

  XMC_ASSERT("XMC_VADC_GROUP_ScanSetReqSrcEventInterruptNode:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_ScanSetReqSrcEventInterruptNode:Wrong Service Request", ((sr)  <= XMC_VADC_SR_SHARED_SR3))

  sevnp &= ~((uint32_t)VADC_G_SEVNP_SEV1NP_Msk);
  sevnp |= (uint32_t)((uint32_t)sr << VADC_G_SEVNP_SEV1NP_Pos);

  group_ptr->SEVNP = sevnp;
}

/* Removes the selected channel from conversion*/
void XMC_VADC_GROUP_ScanRemoveChannel(XMC_VADC_GROUP_t *const group_ptr, const uint32_t channel_num)
{
  uint32_t assel;

  XMC_ASSERT("XMC_VADC_GROUP_ScanRemoveChannel:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_ScanRemoveChannel:Wrong channel number", ((channel_num) < XMC_VADC_NUM_CHANNELS_PER_GROUP))

  assel = group_ptr->ASSEL;
  assel &= (~( 1 << channel_num));
  group_ptr->ASSEL  = assel;
}
#endif

/* API to initialize background scan request source hardware */
void XMC_VADC_GLOBAL_BackgroundInit(XMC_VADC_GLOBAL_t *const global_ptr, const XMC_VADC_BACKGROUND_CONFIG_t *config)
{
#if (XMC_VADC_GROUP_AVAILABLE ==1U)
  uint8_t i;
  uint32_t reg;
  uint32_t conv_start_mask;
#endif

  XMC_ASSERT("XMC_VADC_GLOBAL_BackgroundInit:Wrong Module Pointer", (global_ptr == VADC))

#if (XMC_VADC_GROUP_AVAILABLE ==1U)
  for (i = (uint8_t)0; i < XMC_VADC_MAXIMUM_NUM_GROUPS; i++)
  {
    XMC_VADC_GROUP_BackgroundDisableArbitrationSlot((XMC_VADC_GROUP_t *)g_xmc_vadc_group_array[i]);
  }

  conv_start_mask = (uint32_t) 0;
  if (XMC_VADC_STARTMODE_WFS != (XMC_VADC_STARTMODE_t)config->conv_start_mode)
  {
    conv_start_mask = (uint32_t)VADC_G_ARBPR_CSM2_Msk;
  }

  for (i = 0U; i < XMC_VADC_MAXIMUM_NUM_GROUPS; i++)
  {
    reg = g_xmc_vadc_group_array[i]->ARBPR;

    reg &= ~(uint32_t)(VADC_G_ARBPR_PRIO2_Msk);

    /* Program the priority of the request source */
    reg |= (uint32_t)((uint32_t)config->req_src_priority << VADC_G_ARBPR_PRIO2_Pos);

    /* Program the start mode */
    reg |= conv_start_mask;

    g_xmc_vadc_group_array[i]->ARBPR = reg;

  }
#endif

  /* program BRSCTRL register */
  global_ptr->BRSCTRL = (uint32_t)(config->asctrl | (uint32_t)VADC_BRSCTRL_XTWC_Msk | (uint32_t)VADC_BRSCTRL_GTWC_Msk);

  /* program BRSMR register */
  global_ptr->BRSMR = (uint32_t)((config->asmr) | (uint32_t)((uint32_t)XMC_VADC_GATEMODE_IGNORE << VADC_BRSMR_ENGT_Pos));

#if (XMC_VADC_GROUP_AVAILABLE ==1U)
  if (XMC_VADC_STARTMODE_CNR == (XMC_VADC_STARTMODE_t)(config->conv_start_mode))
  {
    global_ptr->BRSMR |= (uint32_t)VADC_BRSMR_RPTDIS_Msk;
  }
#endif

#if (XMC_VADC_GROUP_AVAILABLE ==1U)
  for (i = (uint8_t)0; i < XMC_VADC_MAXIMUM_NUM_GROUPS; i++)
  {
    XMC_VADC_GROUP_BackgroundEnableArbitrationSlot((XMC_VADC_GROUP_t *)g_xmc_vadc_group_array[i]);
  }
#endif

}

/* API to select one of the 16 inputs as a trigger for background scan request source */
void XMC_VADC_GLOBAL_BackgroundSelectTrigger(XMC_VADC_GLOBAL_t *const global_ptr, const uint32_t input_num)
{
  uint32_t scanctrl;

  XMC_ASSERT("VADC_BCKGND_SelectTriggerInput:Wrong Module Pointer", (global_ptr == VADC))
  XMC_ASSERT("XMC_VADC_GLOBAL_BackgroundSelectTrigger:Wrong Trigger Port", ((input_num) < XMC_VADC_NUM_PORTS))


  scanctrl       = global_ptr->BRSCTRL;
  scanctrl      |= (uint32_t)VADC_BRSCTRL_XTWC_Msk;
  scanctrl      &= ~((uint32_t)VADC_BRSCTRL_XTSEL_Msk);
  scanctrl      |= (uint32_t)(input_num << VADC_BRSCTRL_XTSEL_Pos);
  global_ptr->BRSCTRL  = scanctrl;
}

/* Select a trigger edge*/
void XMC_VADC_GLOBAL_BackgroundSelectTriggerEdge(XMC_VADC_GLOBAL_t *const global_ptr,
    const XMC_VADC_TRIGGER_EDGE_t trigger_edge)
{
  uint32_t scanctrl;

  XMC_ASSERT("XMC_VADC_GLOBAL_BackgroundSelectTriggerEdge:Wrong Global Pointer", (global_ptr == VADC))
  XMC_ASSERT("XMC_VADC_GLOBAL_BackgroundSelectTriggerEdge:Wrong Trigger Port",
             ((trigger_edge) <= XMC_VADC_TRIGGER_EDGE_ANY))

  scanctrl      = global_ptr->BRSCTRL;
  scanctrl     |= (uint32_t) VADC_BRSCTRL_XTWC_Msk;
  scanctrl     &= ~((uint32_t)VADC_BRSCTRL_XTMODE_Msk);
  scanctrl     |= (uint32_t)((uint32_t)trigger_edge << VADC_BRSCTRL_XTMODE_Pos);
  global_ptr->BRSCTRL  = scanctrl;
}


/* API to select one of the 16 inputs as a trigger gate for background scan request source */
void XMC_VADC_GLOBAL_BackgroundSelectGating(XMC_VADC_GLOBAL_t *const global_ptr, const uint32_t input_num)
{
  uint32_t scanctrl;

  XMC_ASSERT("XMC_VADC_GLOBAL_BackgroundSelectGating:Wrong Module Pointer", (global_ptr == VADC))
  XMC_ASSERT("XMC_VADC_GLOBAL_BackgroundSelectGating:Wrong Gating Port", ((input_num) < XMC_VADC_NUM_PORTS))

  scanctrl       = global_ptr->BRSCTRL;
  scanctrl      |= (uint32_t)VADC_BRSCTRL_GTWC_Msk;
  scanctrl      &= ~((uint32_t)VADC_BRSCTRL_GTSEL_Msk);
  scanctrl      |= (uint32_t)(input_num << VADC_BRSCTRL_GTSEL_Pos);
  global_ptr->BRSCTRL  = scanctrl;
}

/* API to abort ongoing conversion of a sequence */
void XMC_VADC_GLOBAL_BackgroundAbortSequence(XMC_VADC_GLOBAL_t *const global_ptr)
{
  uint32_t brsctrl;
#if (XMC_VADC_GROUP_AVAILABLE ==1U)
  uint32_t i;
  uint8_t grp_asen2_flag[XMC_VADC_MAXIMUM_NUM_GROUPS];
#endif
  XMC_ASSERT("XMC_VADC_GLOBAL_BackgroundAbortSequence:Wrong Module Pointer", (global_ptr == VADC))

  /* To disable trigger and gating before abort*/
  brsctrl = global_ptr->BRSCTRL;

  global_ptr->BRSCTRL = (0U | (uint32_t)VADC_BRSCTRL_XTWC_Msk | (uint32_t)VADC_BRSCTRL_GTWC_Msk);

  /* Disable Background Request source */

#if (XMC_VADC_GROUP_AVAILABLE ==1U)
  for (i = (uint8_t)0; i < XMC_VADC_MAXIMUM_NUM_GROUPS; i++)
  {
    grp_asen2_flag[i] = (uint8_t)(g_xmc_vadc_group_array[i]->ARBPR >> VADC_G_ARBPR_ASEN2_Pos);
    XMC_VADC_GROUP_BackgroundDisableArbitrationSlot((XMC_VADC_GROUP_t *)g_xmc_vadc_group_array[i]);
  }
#endif

  /* Abort the ongoing sequence */
  global_ptr->BRSMR |= (uint32_t)VADC_BRSMR_CLRPND_Msk;

#if (XMC_VADC_GROUP_AVAILABLE ==1U)
  /* Enable Background Request source */
  for (i = (uint8_t)0; i < XMC_VADC_MAXIMUM_NUM_GROUPS; i++)
  {
    if ((uint8_t)1 == grp_asen2_flag[i])
    {
      XMC_VADC_GROUP_BackgroundEnableArbitrationSlot((XMC_VADC_GROUP_t *)g_xmc_vadc_group_array[i]);
    }
  }
#endif

  /* Re-enable any disabled trigger and gating*/
  global_ptr->BRSCTRL = (brsctrl | (uint32_t)VADC_BRSCTRL_XTWC_Msk | (uint32_t)VADC_BRSCTRL_GTWC_Msk);
}

/* API to determine how many channels are awaiting conversion */
uint32_t XMC_VADC_GLOBAL_BackgroundGetNumChannelsPending(XMC_VADC_GLOBAL_t *const global_ptr)
{
  uint32_t reg;
  uint32_t i;
  uint32_t j;
  uint32_t count;

  XMC_ASSERT("XMC_VADC_GLOBAL_BackgroundGetNumChannelsPending:Wrong Module Pointer", (global_ptr == VADC))

  count = 0U;

  /* Loop through all groups and find out who is awaiting conversion */
  for (i = 0U; i < XMC_VADC_MAXIMUM_NUM_GROUPS; i++)
  {
    if (global_ptr->BRSSEL[i])
    {
      reg = global_ptr->BRSPND[i];

      for (j = 0U; j < XMC_VADC_NUM_CHANNELS_PER_GROUP; j++)
      {
        if (reg & 1U)
        {
          count++;
        }

        reg = reg >> 1U;
      }
    }
  }

  return count;
}

#if (XMC_VADC_QUEUE_AVAILABLE == 1U)
/* API to initialize queue request source */
void XMC_VADC_GROUP_QueueInit(XMC_VADC_GROUP_t *const group_ptr, const XMC_VADC_QUEUE_CONFIG_t *config)
{
  uint32_t          reg;

  XMC_ASSERT("XMC_VADC_GROUP_QueueInit:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))

  /* Disable arbitration slot of the queue request source */
  XMC_VADC_GROUP_QueueDisableArbitrationSlot(group_ptr);

  reg = group_ptr->ARBPR;

  /* Request Source priority */
  reg &= ~((uint32_t)VADC_G_ARBPR_PRIO0_Msk);
  reg |= (uint32_t) ((uint32_t)config->req_src_priority << VADC_G_ARBPR_PRIO0_Pos);

  /* Conversion Start mode */
  if (XMC_VADC_STARTMODE_WFS != (XMC_VADC_STARTMODE_t)config->conv_start_mode)
  {
    reg |= (uint32_t)(VADC_G_ARBPR_CSM0_Msk);
  }

  group_ptr->ARBPR = reg;


  group_ptr->QCTRL0 = (uint32_t)((config->qctrl0) | (uint32_t)(VADC_G_QCTRL0_XTWC_Msk) |
                                 (uint32_t)(VADC_G_QCTRL0_TMWC_Msk) |
                                 (uint32_t)(VADC_G_QCTRL0_GTWC_Msk));

  /* Gating mode */
  group_ptr->QMR0 = ((uint32_t)(config->qmr0) | (uint32_t)((uint32_t)XMC_VADC_GATEMODE_IGNORE << VADC_G_QMR0_ENGT_Pos));

  if (XMC_VADC_STARTMODE_CNR == (XMC_VADC_STARTMODE_t)(config->conv_start_mode) )
  {
    group_ptr->QMR0 |= (uint32_t)((uint32_t)1 << VADC_G_QMR0_RPTDIS_Pos);
  }
  /* Enable arbitration slot for the queue request source */
  XMC_VADC_GROUP_QueueEnableArbitrationSlot(group_ptr);

}

/* API to select one of the 16 possible triggers as a conversion trigger for queue request source */
void XMC_VADC_GROUP_QueueSelectTrigger(XMC_VADC_GROUP_t *const group_ptr,
                                       const XMC_VADC_TRIGGER_INPUT_SELECT_t input_num)
{
  uint32_t    qctrl;

  XMC_ASSERT("XMC_VADC_GROUP_QueueSelectTrigger:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_QueueSelectTrigger:Wrong Trigger Port", ((input_num) < XMC_VADC_NUM_PORTS))


  /* Now select the conversion trigger */
  qctrl  = group_ptr->QCTRL0;
  qctrl  |= (uint32_t)VADC_G_QCTRL0_XTWC_Msk;
  qctrl &= ~((uint32_t)VADC_G_QCTRL0_XTSEL_Msk);
  qctrl |= (uint32_t)((uint32_t)input_num << VADC_G_QCTRL0_XTSEL_Pos);
  group_ptr->QCTRL0 = qctrl;
}

/* Select a trigger edge*/
void XMC_VADC_GROUP_QueueSelectTriggerEdge(XMC_VADC_GROUP_t *const group_ptr, const XMC_VADC_TRIGGER_EDGE_t trigger_edge)
{
  uint32_t qctrl;

  XMC_ASSERT("XMC_VADC_GROUP_QueueSelectTriggerEdge:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_QueueSelectTriggerEdge:Wrong Gating Port", ((trigger_edge) <= XMC_VADC_TRIGGER_EDGE_ANY))

  /* Now select the gating input */
  qctrl  = group_ptr->QCTRL0;
  qctrl |= (uint32_t)VADC_G_QCTRL0_XTWC_Msk;
  qctrl &= ~((uint32_t)VADC_G_QCTRL0_XTMODE_Msk);
  qctrl |= (uint32_t)((uint32_t)trigger_edge << VADC_G_QCTRL0_XTMODE_Pos);
  group_ptr->QCTRL0 = qctrl;
}

/* API to select one of the 16 possible trigger gates as a trigger gating signal for queue request source */
void XMC_VADC_GROUP_QueueSelectGating(XMC_VADC_GROUP_t *const group_ptr, const XMC_VADC_GATE_INPUT_SELECT_t input_num)
{
  uint32_t qctrl;

  XMC_ASSERT("XMC_VADC_GROUP_QueueSelectGating:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_QueueSelectGating:Wrong Gating Port", ((input_num) < XMC_VADC_NUM_PORTS))

  /* Now select the gating input */
  qctrl  = group_ptr->QCTRL0;
  qctrl |= (uint32_t)VADC_G_QCTRL0_GTWC_Msk;
  qctrl &= ~((uint32_t)VADC_G_QCTRL0_GTSEL_Msk);
  qctrl |= (uint32_t)((uint32_t)input_num << VADC_G_QCTRL0_GTSEL_Pos);
  group_ptr->QCTRL0 = qctrl;
}

/* API to determine the number of channels in the queue (length includes the valid channel in the Backup register)*/
uint32_t XMC_VADC_GROUP_QueueGetLength(XMC_VADC_GROUP_t *const group_ptr)
{
  uint32_t        qsr;
  uint32_t        qbur0;
  uint32_t        length;

  XMC_ASSERT("XMC_VADC_GROUP_QueueGetLength:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))

  qsr = group_ptr->QSR0;
  qbur0 = group_ptr->QBUR0;

  if (qsr & (uint32_t)VADC_G_QSR0_EMPTY_Msk)
  {
    length = 0U;
  }
  else
  {
    length = (qsr & (uint32_t)VADC_G_QSR0_FILL_Msk) + 1U;
  }

  if (qbur0 & (uint32_t)VADC_G_QBUR0_V_Msk )
  {
    length++;
  }

  return length;
}

/* API to abort ongoing conversion of a channel sequence */
void XMC_VADC_GROUP_QueueAbortSequence(XMC_VADC_GROUP_t *const group_ptr)
{
  uint32_t qctrl0;
  bool arbitration_status;

  XMC_ASSERT("XMC_VADC_GROUP_QueueAbortSequence:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))

  /* Disable any gating if present*/
  qctrl0 = group_ptr->QCTRL0;

  group_ptr->QCTRL0 = (0U | (uint32_t)VADC_G_QCTRL0_XTWC_Msk |
                       (uint32_t)VADC_G_QCTRL0_GTWC_Msk | (uint32_t)VADC_G_QCTRL0_TMWC_Msk );

  /* Disable the Arbitration 0 in the group before abort*/
  arbitration_status = (bool)((uint32_t)(group_ptr->ARBPR >> VADC_G_ARBPR_ASEN0_Pos) & 1U);
  XMC_VADC_GROUP_QueueDisableArbitrationSlot(group_ptr);

  /* Flush the Entries from queue*/
  XMC_VADC_GROUP_QueueFlushEntries(group_ptr);

  /* Enable the arbitration slot 0*/
  group_ptr->ARBPR |= (uint32_t)((uint32_t)arbitration_status << VADC_G_ARBPR_ASEN0_Pos);

  /* Enable any disabled gating*/
  group_ptr->QCTRL0 = (qctrl0 | (uint32_t)VADC_G_QCTRL0_XTWC_Msk |
                       (uint32_t)VADC_G_QCTRL0_GTWC_Msk | (uint32_t)VADC_G_QCTRL0_TMWC_Msk );
}

/* API to abort conversion of the channel queued up next */
void XMC_VADC_GROUP_QueueRemoveChannel(XMC_VADC_GROUP_t *const group_ptr)
{
  uint32_t length_before_abort;
  uint32_t length_after_abort;
  uint32_t qctrl0;
  bool arbitration_status;

  XMC_ASSERT("XMC_VADC_GROUP_QueueRemoveChannel:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))

  /* Disable any gating if present*/
  qctrl0 = group_ptr->QCTRL0;

  group_ptr->QCTRL0 = (0U | (uint32_t)VADC_G_QCTRL0_XTWC_Msk |
                       (uint32_t)VADC_G_QCTRL0_GTWC_Msk | (uint32_t)VADC_G_QCTRL0_TMWC_Msk );

  /* Disable the Arbitration 0 in the group before abort*/
  arbitration_status = (bool)((uint32_t)(group_ptr->ARBPR >> VADC_G_ARBPR_ASEN0_Pos) & 1U);
  XMC_VADC_GROUP_QueueDisableArbitrationSlot(group_ptr);

  length_before_abort = XMC_VADC_GROUP_QueueGetLength(group_ptr);

  if (length_before_abort)
  {
    /* Remove the first entry of the queue */
    group_ptr->QMR0 |= (uint32_t)VADC_G_QMR0_CLRV_Msk;

    length_after_abort = XMC_VADC_GROUP_QueueGetLength(group_ptr);

    /* Loop until a reduction in queue length is assessed */
    while (length_after_abort == length_before_abort)
    {
      length_after_abort = XMC_VADC_GROUP_QueueGetLength(group_ptr);
    }
  }
  /* Enable the arbitration slot 0*/
  group_ptr->ARBPR |= (uint32_t)((uint32_t)arbitration_status << VADC_G_ARBPR_ASEN0_Pos);

  /* Enable any disabled gating*/
  group_ptr->QCTRL0 = (qctrl0 | (uint32_t)VADC_G_QCTRL0_XTWC_Msk |
                       (uint32_t)VADC_G_QCTRL0_GTWC_Msk | (uint32_t)VADC_G_QCTRL0_TMWC_Msk );
}

/* Get details of channel meant to be converted right after the ongoing conversion */
int32_t XMC_VADC_GROUP_QueueGetNextChannel(XMC_VADC_GROUP_t *const group_ptr)
{
  int32_t ch_num;

  XMC_ASSERT("XMC_VADC_GROUP_QueueGetNextChannel:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))

  /*
   * Check if there is something in the backup stage. If not, read queue-0
   * entry.
   */
  if ( (group_ptr->QBUR0) & (uint32_t)VADC_G_QBUR0_V_Msk)
  {
    ch_num = (int32_t)(group_ptr->QBUR0 & (uint32_t)VADC_G_QBUR0_REQCHNR_Msk);
  }
  else if ( (group_ptr->Q0R0) & (uint32_t)VADC_G_Q0R0_V_Msk)
  {
    ch_num = (int32_t)(group_ptr->Q0R0 & (uint32_t)VADC_G_Q0R0_REQCHNR_Msk);
  }
  else
  {
    /* Nothing is pending */
    ch_num = -1;
  }

  return ch_num;
}

/* Get the channel number of the channel whose conversion had been interrupted */
int32_t XMC_VADC_GROUP_QueueGetInterruptedChannel(XMC_VADC_GROUP_t *const group_ptr)
{
  int32_t ch_num;

  XMC_ASSERT("XMC_VADC_GROUP_QueueGetInterruptedChannel:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))

  if ((group_ptr->QBUR0) & (uint32_t)VADC_G_QBUR0_V_Msk)
  {
    ch_num = (int32_t)(group_ptr->QBUR0 & (uint32_t)VADC_G_QBUR0_REQCHNR_Msk);
  }
  else
  {
    /* No such channel */
    ch_num = -1;
  }

  return ch_num;
}

/* Select a Service Request line for the request source event */
void XMC_VADC_GROUP_QueueSetReqSrcEventInterruptNode(XMC_VADC_GROUP_t *const group_ptr, const XMC_VADC_SR_t sr)
{
  uint32_t sevnp;

  XMC_ASSERT("XMC_VADC_GROUP_QueueSetReqSrcEventInterruptNode:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_QueueSetReqSrcEventInterruptNode:Wrong Service Request", ((sr)  <= XMC_VADC_SR_SHARED_SR3))

  sevnp = group_ptr->SEVNP;

  sevnp &= ~((uint32_t)VADC_G_SEVNP_SEV0NP_Msk);
  sevnp |= (uint32_t)((uint32_t)sr << VADC_G_SEVNP_SEV0NP_Pos);

  group_ptr->SEVNP = sevnp;

}
#endif

#if (XMC_VADC_GROUP_AVAILABLE ==1U)
/* API to initialize a channel unit */
void XMC_VADC_GROUP_ChannelInit(XMC_VADC_GROUP_t *const group_ptr, const uint32_t ch_num,
                                const XMC_VADC_CHANNEL_CONFIG_t *config)
{
  uint32_t prio;
  uint32_t ch_assign;
  uint32_t mask;


  XMC_ASSERT("XMC_VADC_GROUP_ChannelInit:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_ChannelInit:Wrong Channel Number", ((ch_num) < XMC_VADC_NUM_CHANNELS_PER_GROUP))

  prio  = (uint32_t)config->channel_priority;

  /* Priority channel */
  ch_assign  = group_ptr->CHASS;
  ch_assign &= ~((uint32_t)((uint32_t)1 << ch_num));
  ch_assign |= (uint32_t)(prio << ch_num);
  group_ptr->CHASS = ch_assign;

  /* Alias channel */
  if (config->alias_channel >= (int32_t)0)
  {
    mask = (uint32_t)0;
    if ((uint32_t)1 == ch_num)
    {
      mask = VADC_G_ALIAS_ALIAS1_Pos;
      group_ptr->ALIAS &= ~(uint32_t)(VADC_G_ALIAS_ALIAS1_Msk);
    }
    else if ((uint32_t)0 == ch_num)
    {
      mask = VADC_G_ALIAS_ALIAS0_Pos;
      group_ptr->ALIAS &= ~(uint32_t)(VADC_G_ALIAS_ALIAS0_Msk);
    }

    group_ptr->ALIAS |= (uint32_t)(config->alias_channel << mask);
  }

  group_ptr->BFL |= config->bfl;

#if (XMC_VADC_BOUNDARY_FLAG_SELECT == 1U)
  group_ptr->BFLC |= config->bflc;
#endif
  /* Program the CHCTR register */
  group_ptr->CHCTR[ch_num] = config->chctr;

}

/* API to determine whether input to a channel has violated boundary conditions */
bool XMC_VADC_GROUP_ChannelIsResultOutOfBounds(XMC_VADC_GROUP_t *const group_ptr, const uint32_t ch_num)
{
  bool retval;
  uint32_t    chctr;
  uint32_t    ceflag;

  XMC_ASSERT("XMC_VADC_GROUP_ChannelIsResultOutOfBounds:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_ChannelIsResultOutOfBounds:Wrong Channel Number",
             ((ch_num) < XMC_VADC_NUM_CHANNELS_PER_GROUP))

  retval = (bool)false;
  /*
    Check if the Channel event is configured to be generated in the event of
    boundary violation and if affirmative, check if the channel event is set.
  */
  /* Extract CHEVMODE for requested channel */
  chctr  = group_ptr->CHCTR[ch_num];
  chctr  = (uint32_t)(chctr >> (uint32_t)VADC_G_CHCTR_CHEVMODE_Pos) & (uint32_t)0x3;

  /* Extract CEFLAG for the requested channel */
  ceflag = group_ptr->CEFLAG;
  ceflag = ceflag & ((uint32_t)((uint32_t)1 << ch_num) );

  /* Check what was the channel event generation criteria */
  if ( (( (uint32_t)XMC_VADC_CHANNEL_EVGEN_INBOUND == chctr) \
        || ((uint32_t) XMC_VADC_CHANNEL_EVGEN_OUTBOUND == chctr)) && (ceflag) )
  {
    retval = (bool)true;
  }

  return retval;
}

/* Set a reference voltage for conversion */
void XMC_VADC_GROUP_ChannelSetInputReference(XMC_VADC_GROUP_t *const group_ptr,
    const uint32_t ch_num,
    const XMC_VADC_CHANNEL_REF_t ref)
{
  uint32_t chctr;
  XMC_ASSERT("XMC_VADC_GROUP_ChannelSetInputReference:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_ChannelSetInputReference:Wrong Channel Number", ((ch_num) < XMC_VADC_NUM_CHANNELS_PER_GROUP))
  XMC_ASSERT("XMC_VADC_GROUP_ChannelSetInputReference:Wrong Voltage Reference", ((ref) <= XMC_VADC_CHANNEL_REF_ALT_CH0))

  chctr = group_ptr->CHCTR[ch_num];
  chctr &= ~((uint32_t)VADC_G_CHCTR_REFSEL_Msk);
  chctr |= (uint32_t)((uint32_t)ref <<  VADC_G_CHCTR_REFSEL_Pos);

  group_ptr->CHCTR[ch_num] = chctr;
}

/* API to select one of the available 16 registers for storing the channel result */
void XMC_VADC_GROUP_ChannelSetResultRegister(XMC_VADC_GROUP_t *const group_ptr,
    const uint32_t ch_num,
    const uint32_t result_reg_num)
{
  uint32_t chctr;

  XMC_ASSERT("XMC_VADC_GROUP_ChannelSetResultRegister:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_ChannelSetResultRegister:Wrong Channel Number",
             ((ch_num) < XMC_VADC_NUM_CHANNELS_PER_GROUP))
  XMC_ASSERT("XMC_VADC_GROUP_ChannelSetResultRegister:Wrong Result Register",
             ((result_reg_num) < XMC_VADC_NUM_RESULT_REGISTERS))

  chctr = group_ptr->CHCTR[ch_num];
  chctr &= ~((uint32_t)VADC_G_CHCTR_RESREG_Msk);
  chctr |= (uint32_t)(result_reg_num <<  VADC_G_CHCTR_RESREG_Pos);

  group_ptr->CHCTR[ch_num] = chctr;
}

/* API to select one of the available 4 class conversion */
void XMC_VADC_GROUP_ChannelSetIclass(XMC_VADC_GROUP_t *const group_ptr,
                                     const uint32_t ch_num,
                                     const XMC_VADC_CHANNEL_CONV_t conversion_class)
{

  uint32_t chctr;

  XMC_ASSERT("XMC_VADC_GROUP_ChannelSetIclass:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_ChannelSetIclass:Wrong Channel Number",
             ((ch_num) < XMC_VADC_NUM_CHANNELS_PER_GROUP))
  XMC_ASSERT("XMC_VADC_GROUP_ChannelSetIclass:Wrong input class ",
             (XMC_VADC_CHANNEL_CONV_GLOBAL_CLASS1 >= conversion_class))

  chctr = group_ptr->CHCTR[ch_num];
  chctr &= ~((uint32_t)VADC_G_CHCTR_ICLSEL_Msk);
  chctr |= (uint32_t)((uint32_t)conversion_class <<  (uint32_t)VADC_G_CHCTR_ICLSEL_Pos);

  group_ptr->CHCTR[ch_num] = chctr;

}

/* API to retrieve the result register bound with specified channel */
uint8_t XMC_VADC_GROUP_ChannelGetResultRegister(XMC_VADC_GROUP_t *const group_ptr, const uint32_t ch_num)
{
  uint8_t resreg;

  XMC_ASSERT("XMC_VADC_GROUP_ChannelGetResultRegister:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_ChannelGetResultRegister:Wrong Channel Number",
             ((ch_num) < XMC_VADC_NUM_CHANNELS_PER_GROUP))

  resreg = (uint8_t)((group_ptr->CHCTR[ch_num] & (uint32_t)VADC_G_CHCTR_RESREG_Msk) >> VADC_G_CHCTR_RESREG_Pos) ;

  return resreg;
}

/* API to manually assert channel event */
void XMC_VADC_GROUP_ChannelTriggerEvent(XMC_VADC_GROUP_t *const group_ptr, const uint32_t ch_num)
{
  uint32_t ceflag;

  XMC_ASSERT("XMC_VADC_GROUP_ChannelTriggerEvent:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_ChannelTriggerEvent:Wrong Channel Number", ((ch_num) < XMC_VADC_NUM_CHANNELS_PER_GROUP))

  ceflag  = group_ptr->CEFLAG;
  ceflag |= (uint32_t)((uint32_t)1 << ch_num);
  group_ptr->CEFLAG = ceflag;
}

/* API to bind channel event with a service request (NVIC Node) */
void XMC_VADC_GROUP_ChannelSetEventInterruptNode(XMC_VADC_GROUP_t *const group_ptr,
    const uint32_t ch_num,
    const XMC_VADC_SR_t sr)
{
  uint32_t route_mask;

  XMC_ASSERT("XMC_VADC_GROUP_ChannelSetEventInterruptNode:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_ChannelSetEventInterruptNode:Wrong Channel Number",
             ((ch_num) < XMC_VADC_NUM_CHANNELS_PER_GROUP))
  XMC_ASSERT("XMC_VADC_GROUP_ChannelSetEventInterruptNode:Wrong Service Request", ((sr)  <= XMC_VADC_SR_SHARED_SR3))

  route_mask  = group_ptr->CEVNP0;
  route_mask &= ~((uint32_t)15 << (ch_num * (uint32_t)4));
  route_mask |= (uint32_t)( (uint32_t)sr << (ch_num * (uint32_t)4));
  group_ptr->CEVNP0 = route_mask;
}

/* API to configure conditions for generation of channel event */
void XMC_VADC_GROUP_ChannelTriggerEventGenCriteria( XMC_VADC_GROUP_t *const group_ptr,
    const uint32_t ch_num,
    const XMC_VADC_CHANNEL_EVGEN_t criteria)
{
  uint32_t chctr;

  XMC_ASSERT("XMC_VADC_GROUP_ChannelTriggerEventGenCriteria:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_ChannelTriggerEventGenCriteria:Wrong Channel Number",
             ((ch_num) < XMC_VADC_NUM_CHANNELS_PER_GROUP))
  XMC_ASSERT("XMC_VADC_GROUP_ChannelTriggerEventGenCriteria:Wrong Event Generation Criteria",
             ((criteria) <= XMC_VADC_CHANNEL_EVGEN_ALWAYS))

  chctr  = group_ptr->CHCTR[ch_num];
  chctr &= ~((uint32_t)VADC_G_CHCTR_CHEVMODE_Msk);
  chctr |= (uint32_t)((uint32_t)criteria << VADC_G_CHCTR_CHEVMODE_Pos);
  group_ptr->CHCTR[ch_num] = chctr;
}

/* API to configure the boundary selection */
void  XMC_VADC_GROUP_ChannelSetBoundarySelection(XMC_VADC_GROUP_t *const group_ptr,
    const uint32_t ch_num,
    XMC_VADC_BOUNDARY_SELECT_t boundary_sel,
    XMC_VADC_CHANNEL_BOUNDARY_t selection)
{
  XMC_ASSERT("XMC_VADC_GROUP_ChannelSetBoundarySelection:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_ChannelSetBoundarySelection:Wrong Channel Number",
             ((ch_num) < XMC_VADC_NUM_CHANNELS_PER_GROUP))

  group_ptr->CHCTR[ch_num] &= ~((uint32_t)VADC_G_CHCTR_BNDSELL_Msk << boundary_sel);
  group_ptr->CHCTR[ch_num] |= (selection << ((uint32_t)VADC_G_CHCTR_BNDSELL_Pos + (uint32_t)boundary_sel));
}

/* Make the specified result register part of Result FIFO */
void XMC_VADC_GROUP_AddResultToFifo(XMC_VADC_GROUP_t *const group_ptr, const uint32_t res_reg)
{
  uint32_t fen;

  XMC_ASSERT("XMC_VADC_GROUP_AddResultToFifo:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_AddResultToFifo:Wrong Result Register", ((res_reg) < XMC_VADC_NUM_RESULT_REGISTERS))

  /* Extract and clear the FIFO enable field */
  fen = group_ptr->RCR[res_reg];
  fen &= ~((uint32_t)VADC_G_RCR_FEN_Msk);
  /* Set this register up as a FIFO member */
  fen |= (uint32_t)((uint32_t)1 << VADC_G_RCR_FEN_Pos);
  group_ptr->RCR[res_reg] = fen;
}


/* Applicable to fast compare mode, this API sets up the value which is to be compared against conversion result */
void XMC_VADC_GROUP_SetResultFastCompareValue(XMC_VADC_GROUP_t *const group_ptr,
    const uint32_t res_reg,
    const XMC_VADC_RESULT_SIZE_t compare_val)
{
  uint32_t res = group_ptr->RES[res_reg];

  XMC_ASSERT("XMC_VADC_GROUP_SetResultFastCompareValue:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_SetResultFastCompareValue:Wrong Result Register",
             ((res_reg) < XMC_VADC_NUM_RESULT_REGISTERS))

  res &= ~((uint32_t)VADC_G_RES_RESULT_Msk);
  res |= (uint32_t)((uint32_t)compare_val << XMC_VADC_RESULT_LEFT_ALIGN_10BIT);
  group_ptr->RES[res_reg] = res;
}

/* API to retrieve the result of fast mode comparison */
XMC_VADC_FAST_COMPARE_t XMC_VADC_GROUP_GetFastCompareResult(XMC_VADC_GROUP_t *const group_ptr, const uint32_t res_reg)
{
  XMC_VADC_FAST_COMPARE_t result;
  uint32_t res;

  XMC_ASSERT("XMC_VADC_GROUP_GetFastCompareResult:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_GetFastCompareResult:Wrong Result Register", ((res_reg) < XMC_VADC_NUM_RESULT_REGISTERS))

  res = group_ptr->RES[res_reg];

  if (res & (uint32_t)VADC_G_RES_VF_Msk)
  {
    result = (XMC_VADC_FAST_COMPARE_t)((uint32_t)(res >> (uint32_t)VADC_G_RES_FCR_Pos) & (uint32_t)1);
  }
  else
  {
    result = XMC_VADC_FAST_COMPARE_UNKNOWN;
  }

  return result;
}

/* Applicable to fast compare mode, this API sets up the value which is to be compared against conversion result */
void XMC_VADC_GROUP_SetResultSubtractionValue(XMC_VADC_GROUP_t *const group_ptr,
    const uint16_t subtraction_val)
{
  uint32_t res;

  XMC_ASSERT("XMC_VADC_GROUP_SetResultSubtractionValue:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))

  res = group_ptr->RES[0];
  res &= ~((uint32_t)VADC_G_RES_RESULT_Msk);
  res |= (uint32_t)subtraction_val;
  group_ptr->RES[0] = res;
}


/* API to select a service request line (NVIC Node) for result event of specified unit of result hardware */
void XMC_VADC_GROUP_SetResultInterruptNode(XMC_VADC_GROUP_t *const group_ptr,
    const uint32_t res_reg,
    const XMC_VADC_SR_t sr)
{
  uint32_t route_mask;

  XMC_ASSERT("XMC_VADC_GROUP_SetResultInterruptNode:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_SetResultInterruptNode:Wrong Result Register", ((res_reg) < XMC_VADC_NUM_RESULT_REGISTERS))
  XMC_ASSERT("XMC_VADC_GROUP_SetResultInterruptNode:Wrong Service Request", ((sr)  <= XMC_VADC_SR_SHARED_SR3))

  if (res_reg <= 7U)
  {
    route_mask  = group_ptr->REVNP0;
    route_mask &= ~((uint32_t)((uint32_t)15 << (res_reg * (uint32_t)4) ));
    route_mask |= (uint32_t)((uint32_t)sr << (res_reg * (uint32_t)4));
    group_ptr->REVNP0 = route_mask;
  }
  else
  {
    route_mask = group_ptr->REVNP1;
    route_mask &= ~((uint32_t)((uint32_t)15 << (( res_reg - (uint32_t)8) * (uint32_t)4) ));
    route_mask |= (uint32_t)((uint32_t)sr << ((res_reg - (uint32_t)8) * (uint32_t)4));
    group_ptr->REVNP1 = route_mask;
  }
}

/* API to retrieve the tail of the fifo which the specified result register is a part of */
uint32_t XMC_VADC_GROUP_GetResultFifoTail(XMC_VADC_GROUP_t *const group_ptr, uint32_t res_reg)
{
  uint32_t tail;
  uint32_t rcr;
  int32_t i;
  bool exit_flag;

  XMC_ASSERT("XMC_VADC_GROUP_GetResultFifoTail:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_GetResultFifoTail:Wrong Result Register", ((res_reg) < XMC_VADC_NUM_RESULT_REGISTERS))

  tail = 0U;
  exit_flag = (bool)false;

  if ((bool)true == XMC_VADC_GROUP_IsResultRegisterFifoHead(group_ptr, res_reg))
  {
    res_reg = res_reg - 1U;
  }

  /* Border condition */
  if (0U == res_reg)
  {
    tail = 0U;
  }
  else
  {
    /* Stop either at a node that does not have FEN set or at Node-0 */
    for (i = (int32_t)res_reg; i >= (int32_t)0; i--)
    {
      rcr = group_ptr->RCR[i];
      rcr &= (uint32_t)VADC_G_RCR_FEN_Msk;

      if (rcr)
      {
        if ((int32_t)0 == i)
        {
          /* No more nodes. Stop here */
          tail = (uint32_t)0;
          exit_flag = (bool)true;
        }
      }
      else
      {
        /* The preceding register forms the tail of the FIFO */
        tail = (uint32_t)i + (uint32_t)1;
        exit_flag = (bool)true;
      }
      if (exit_flag)
      {
        break;
      }
    }
  }
  return tail;
}

/* API to retrieve the head of the fifo which the specified result register is a part of */
uint32_t XMC_VADC_GROUP_GetResultFifoHead(XMC_VADC_GROUP_t *const group_ptr, const uint32_t res_reg)
{
  uint32_t head;
  uint32_t rcr;
  uint32_t i;

  XMC_ASSERT("XMC_VADC_GROUP_GetResultFifoHead:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_GetResultFifoHead:Wrong Result Register", ((res_reg) < XMC_VADC_NUM_RESULT_REGISTERS))

  if ((bool)true == XMC_VADC_GROUP_IsResultRegisterFifoHead(group_ptr, res_reg))
  {
    head = res_reg;
  }
  else
  {
    head = XMC_VADC_NUM_RESULT_REGISTERS - (uint32_t)1;

    for (i = res_reg; i < XMC_VADC_NUM_RESULT_REGISTERS ; i++)
    {
      rcr = group_ptr->RCR[i];
      rcr &= (uint32_t)VADC_G_RCR_FEN_Msk;

      if (!rcr)
      {
        /* This node forms the head of the FIFO */
        head = i ;
        break;
      }
    }
  }
  return head;
}

/* API to determine if the specified result register is the head of a result fifo */
bool XMC_VADC_GROUP_IsResultRegisterFifoHead(XMC_VADC_GROUP_t *const group_ptr, const uint32_t res_reg)
{
  bool ret_val;
  uint32_t rcr_head;
  uint32_t rcr_next;

  XMC_ASSERT("XMC_VADC_GROUP_IsResultRegisterFifoHead:Wrong Group Pointer", XMC_VADC_CHECK_GROUP_PTR(group_ptr))
  XMC_ASSERT("XMC_VADC_GROUP_IsResultRegisterFifoHead:Wrong Result Register",
             ((res_reg) < XMC_VADC_NUM_RESULT_REGISTERS))

  rcr_head = group_ptr->RCR[res_reg];
  rcr_head &= (uint32_t)VADC_G_RCR_FEN_Msk;
  rcr_next = group_ptr->RCR[res_reg - (uint32_t)1];
  rcr_next &= (uint32_t)VADC_G_RCR_FEN_Msk;

  if (rcr_head)
  {
    ret_val = (bool)false;
  }
  else if (rcr_next)
  {
    ret_val = (bool)true;
  }
  else
  {
    ret_val = (bool)false;
  }

  return ret_val;
}

#endif
