/*
 * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD
 * All rights reserved.
 *
 * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use
 * exclusively with CVA's microcontroller products. This file can be freely
 * distributed within development tools that are supporting such microcontroller
 * products.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
 * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
 * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
 * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 */

#ifndef _ADC_REG_H_
#define _ADC_REG_H_

/*! \brief Contains public interface to various functions related
 *         to the ADC Registers
 */

/*******************************************************************************
 * the includes
 ******************************************************************************/

#include <stdint.h>
#include "../CVM012x_features.h"

#ifdef __cplusplus
extern "C" {
#endif

/*******************************************************************************
 * the defines
 ******************************************************************************/

#define ADC_REG_LOCK_KEY            (0x0U)
#define ADC_REG_UNLOCK_KEY          (0xA5D2C3C3U)

/* Number of channels register for every ADC instance */
#define ADC_REG_CH_COUNT            (24u)

/* CFG1 Bit Fields */
#define ADC_CFG1_WITHOUT_W1C_MASK   (0xFFFFFEFFu)
#define ADC_CFG1_CLRLTRG_MASK       (0x100u)
#define ADC_CFG1_CLRLTRG_SHIFT      (8u)
#define ADC_CFG1_CLRLTRG_WIDTH      (1u)
#define ADC_CFG1_MODE_MASK          (0x03u)
#define ADC_CFG1_MODE_SHIFT         (0u)
#define ADC_CFG1_MODE_WIDTH         (2u)

/* CFG2 Bit Fields */
#define ADC_CFG2_LEN_SMPL_1ST_MASK  (0xF0u)
#define ADC_CFG2_LEN_SMPL_1ST_SHIFT (4u)
#define ADC_CFG2_LEN_SMPL_1ST_WIDTH (4u)
#define ADC_CFG2_LEN_SMPL_MASK      (0x0Fu)
#define ADC_CFG2_LEN_SMPL_SHIFT     (0u)
#define ADC_CFG2_LEN_SMPL_WIDTH     (4u)

/* CV1 Bit Fields */
#define ADC_CV1_CV_MASK             (0xFFFFu)
#define ADC_CV1_CV_SHIFT            (0u)
#define ADC_CV1_CV_WIDTH            (16u)

/* CV2 Bit Fields */
#define ADC_CV2_CV_MASK             (0xFFFFu)
#define ADC_CV2_CV_SHIFT            (0u)
#define ADC_CV2_CV_WIDTH            (16u)

/* SC2 Bit Fields */
#define ADC_SC2_WITHOUT_W1C_MASK    (0xF0FFFFFFu)
#define ADC_SC2_TRGSTERR_MASK       (0xF000000u)
#define ADC_SC2_TRGSTERR_SHIFT      (24u)
#define ADC_SC2_TRGSTERR_WIDTH      (4u)
#define ADC_SC2_TRGSTLAT_MASK       (0xF0000u)
#define ADC_SC2_TRGSTLAT_SHIFT      (16u)
#define ADC_SC2_TRGSTLAT_WIDTH      (4u)
#define ADC_SC2_TRGPRNUM_MASK       (0x6000u)
#define ADC_SC2_TRGPRNUM_SHIFT      (13u)
#define ADC_SC2_TRGPRNUM_WIDTH      (2u)
#define ADC_SC2_ADACT_MASK          (0x80u)
#define ADC_SC2_ADACT_SHIFT         (7u)
#define ADC_SC2_ADACT_WIDTH         (1u)
#define ADC_SC2_ADTRG_MASK          (0x40u)
#define ADC_SC2_ADTRG_SHIFT         (6u)
#define ADC_SC2_ADTRG_WIDTH         (1u)
#define ADC_SC2_ACFE_MASK           (0x20u)
#define ADC_SC2_ACFE_SHIFT          (5u)
#define ADC_SC2_ACFE_WIDTH          (1u)
#define ADC_SC2_ACFGT_MASK          (0x10u)
#define ADC_SC2_ACFGT_SHIFT         (4u)
#define ADC_SC2_ACFGT_WIDTH         (1u)
#define ADC_SC2_ACREN_MASK          (0x08u)
#define ADC_SC2_ACREN_SHIFT         (3u)
#define ADC_SC2_ACREN_WIDTH         (1u)
#define ADC_SC2_DMAEN_MASK          (0x04u)
#define ADC_SC2_DMAEN_SHIFT         (2u)
#define ADC_SC2_DMAEN_WIDTH         (1u)

/* SC3 Bit Fields */
#define ADC_SC3_ADC_PD_MASK         (0x10000u)
#define ADC_SC3_ADC_PD_SHIFT        (16u)
#define ADC_SC3_ADC_PD_WIDTH        (1u)
#define ADC_SC3_CAL_GE_MASK         (0x20u)
#define ADC_SC3_CAL_GE_SHIFT        (5u)
#define ADC_SC3_CAL_GE_WIDTH        (1u)
#define ADC_SC3_CAL_OFS_MASK        (0x10u)
#define ADC_SC3_CAL_OFS_SHIFT       (4u)
#define ADC_SC3_CAL_OFS_WIDTH       (1u)
#define ADC_SC3_ADCO_MASK           (0x08u)
#define ADC_SC3_ADCO_SHIFT          (3u)
#define ADC_SC3_ADCO_WIDTH          (1u)
#define ADC_SC3_AVGE_MASK           (0x04u)
#define ADC_SC3_AVGE_SHIFT          (2u)
#define ADC_SC3_AVGE_WIDTH          (1u)
#define ADC_SC3_AVGS_MASK           (0x03u)
#define ADC_SC3_AVGS_SHIFT          (0u)
#define ADC_SC3_AVGS_WIDTH          (2u)

/* SINGLEGO Bit Fields */
#define ADC_SINGLEGO_VAL_GE_MASK    (0xFFF0000u)
#define ADC_SINGLEGO_VAL_GE_SHIFT   (16u)
#define ADC_SINGLEGO_VAL_GE_WIDTH   (12u)
#define ADC_SINGLEGO_SUB_OFS_MASK   (0x800u)
#define ADC_SINGLEGO_SUB_OFS_SHIFT  (11u)
#define ADC_SINGLEGO_SUB_OFS_WIDTH  (1u)
#define ADC_SINGLEGO_VAL_OFS_MASK   (0x7FFu)
#define ADC_SINGLEGO_VAL_OFS_SHIFT  (0u)
#define ADC_SINGLEGO_VAL_OFS_WIDTH  (11u)

/* DIFFGO Bit Fields */
#define ADC_DIFFGO_VAL_GE_MASK      (0x1FFF0000u)
#define ADC_DIFFGO_VAL_GE_SHIFT     (16u)
#define ADC_DIFFGO_VAL_GE_WIDTH     (13u)
#define ADC_DIFFGO_SUB_OFS_MASK     (0x1000u)
#define ADC_DIFFGO_SUB_OFS_SHIFT    (12u)
#define ADC_DIFFGO_SUB_OFS_WIDTH    (1u)
#define ADC_DIFFGO_VAL_OFS_MASK     (0xFFFu)
#define ADC_DIFFGO_VAL_OFS_SHIFT    (0u)
#define ADC_DIFFGO_VAL_OFS_WIDTH    (12u)

/* TOU Bit Fields */
#define ADC_TOU_DATA_MASK           (0x3FFF0000u)
#define ADC_TOU_DATA_SHIFT          (16u)
#define ADC_TOU_DATA_WIDTH          (14u)
#define ADC_TOU_ADACT_MASK          (0x02u)
#define ADC_TOU_ADACT_SHIFT         (1u)
#define ADC_TOU_ADACT_WIDTH         (1u)
#define ADC_TOU_COCO_MASK           (0x01u)
#define ADC_TOU_COCO_SHIFT          (0u)
#define ADC_TOU_COCO_WIDTH          (1u)

/* GLO1 Bit Fields */
#define ADC_GLO1_STSEL_MASK         (0x0Cu)
#define ADC_GLO1_STSEL_SHIFT        (2u)
#define ADC_GLO1_STSEL_WIDTH        (2u)
#define ADC_GLO1_STVCM_EN_MASK      (0x02u)
#define ADC_GLO1_STVCM_EN_SHIFT     (1u)
#define ADC_GLO1_STVCM_EN_WIDTH     (1u)
#define ADC_GLO1_LOWNOISE_EN_MASK   (0x01u)
#define ADC_GLO1_LOWNOISE_EN_SHIFT  (0u)
#define ADC_GLO1_LOWNOISE_EN_WIDTH  (1u)

/* GLO2 Bit Fields */
#define ADC_GLO2_LEN_PWR_ON_MASK    (0xF00u)
#define ADC_GLO2_LEN_PWR_ON_SHIFT   (8u)
#define ADC_GLO2_LEN_PWR_ON_WIDTH   (4u)
#define ADC_GLO2_ARB_CHANGE_MASK    (0x02u)
#define ADC_GLO2_ARB_CHANGE_SHIFT   (1u)
#define ADC_GLO2_ARB_CHANGE_WIDTH   (1u)
#define ADC_GLO2_ARB_MASK           (0x01u)
#define ADC_GLO2_ARB_SHIFT          (0u)
#define ADC_GLO2_ARB_WIDTH          (1u)

/* USRK Bit Fields */
#define ADC_USRK_USER_KEY_MASK      (0xFFFFFFFFu)
#define ADC_USRK_USER_KEY_SHIFT     (0u)
#define ADC_USRK_USER_KEY_WIDTH     (32u)

/* SC Bit Fields */
#define ADC_SC_COCO_MASK            (0x80u)
#define ADC_SC_COCO_SHIFT           (7u)
#define ADC_SC_COCO_WIDTH           (1u)
#define ADC_SC_AIEN_MASK            (0x40u)
#define ADC_SC_AIEN_SHIFT           (6u)
#define ADC_SC_AIEN_WIDTH           (1u)
#define ADC_SC_PCH_MASK             (0x3Fu)
#define ADC_SC_PCH_SHIFT            (0u)
#define ADC_SC_PCH_WIDTH            (6u)

/* R Bit Fields */
#define ADC_R_DATA_MASK             (0x3FFFu)
#define ADC_R_DATA_SHIFT            (0u)
#define ADC_R_DATA_WIDTH            (14u)

/*******************************************************************************
 * the typedefs
 ******************************************************************************/

/*! \brief The definition of ADC registers
 */
typedef struct _AdcRegType_
{
    volatile uint32_t       CFG1;                 /*!< Configs Register 1, Offset: 0000H */
    volatile uint32_t       CFG2;                 /*!< Configs Register 2, Offset: 0004H */
    volatile uint32_t       CV1;                  /*!< Compare Value 1, Offset: 0008H */
    volatile uint32_t       CV2;                  /*!< Compare Value 2, Offset: 000CH */
    volatile uint32_t       SC2;                  /*!< Status and Control Register 2, Offset: 0010H */
    volatile uint32_t       SC3;                  /*!< Status and Control Register 3, Offset: 0014H */
    volatile uint32_t       SINGLEGO;             /*!< Single-ended Rectify Register, Offset: 0018H */
    volatile uint32_t       DIFFGO;               /*!< Differential Rectify Register, Offset: 001CH */
    volatile uint32_t       TOU;                  /*!< Touch configs Register, Offset: 0020H */
    volatile uint32_t       GLO1;                 /*!< Global Register 1, Offset: 0024H */
    volatile uint32_t       GLO2;                 /*!< Global Register 2, Offset: 0028H */
    uint32_t                RESERVED0[5];         /*!< reserverd block, Offset: 002CH */
    volatile uint32_t       USRK;                 /*!< User Key Register, Offset: 0040H */
    uint32_t                RESERVED1[3];         /*!< reserverd block, Offset: 0044H */
    volatile uint32_t       SC[ADC_REG_CH_COUNT]; /*!< Status and Control Register, Offset: 0050H */
    uint32_t                RESERVED2[20];        /*!< reserverd block, Offset: 00B0H */
    const volatile uint32_t R[ADC_REG_CH_COUNT];  /*!< Conversion Result Register, Offset: 0100H */
} AdcRegType;

/*******************************************************************************
 * the globals
 ******************************************************************************/

/*******************************************************************************
 * the function prototypes
 ******************************************************************************/

/*! \brief Clear Latch Trigger in Trigger Handler Block
 *
 * This function clear Latch Trigger in Trigger Handler Block.
 * Writing a 1 to this field clears all the latched triggers inside the trigger handler except
 * the one under processing. Writing 0 has no effect. This is a write-only-one bit that
 * self-clears immediatel
 *
 * \param[in] obj : pointer to ADC register instance
 */
__attribute__((always_inline)) static inline void AdcReg_ClrlTrg(AdcRegType *obj)
{
    uint32_t tmp = obj->CFG1;

    tmp &= ~ADC_CFG1_CLRLTRG_MASK;
    tmp |= (((uint32_t)(((uint32_t)(1u)) << ADC_CFG1_CLRLTRG_SHIFT)) & ADC_CFG1_CLRLTRG_MASK);
    obj->CFG1 = tmp;
}

/*! \brief Gets the Conversion Mode Selection in single-ended mode
 *
 * This function gets the current Conversion Mode Selection in single-ended mode.
 * Selects the ADC resolution.
 *
 * \param[in] obj : pointer to ADC register instance
 * \return Conversion Mode Selection in single-ended mode
 *         - 00b : 8-bit conversion.
 *         - 10b : 10-bit conversion.
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetCfg1Mode(const AdcRegType *obj)
{
    return ((obj->CFG1 & ADC_CFG1_MODE_MASK) >> ADC_CFG1_MODE_SHIFT);
}

/*! \brief Sets the Conversion Mode Selection in single-ended mode
 *
 * This function sets the Conversion Mode Selection in single-ended mode.
 * Selects the ADC resolution.
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of Conversion Mode Selection in single-ended mode
 *                    - 00b : 8-bit conversion.
 *                    - 10b : 10-bit conversion.
 */
__attribute__((always_inline)) static inline void AdcReg_SetCfg1Mode(AdcRegType *obj, uint8_t value)
{
    uint32_t tmp = obj->CFG1;

    tmp &= ADC_CFG1_WITHOUT_W1C_MASK;
    tmp &= ~ADC_CFG1_MODE_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_CFG1_MODE_SHIFT)) & ADC_CFG1_MODE_MASK);
    obj->CFG1 = tmp;
}

/*! \brief Gets the First Sample Delay Config
 *
 * This function gets the current First Sample Delay Config.
 * After ADC power on or channel changes, the first sampling time needs to be LEN_SMPL added by
 * LEN_SMPL_1ST, so the actual sample time is (LEN_SMPL_1ST+LEN_SMPL+1)*clk_ad
 *
 * \param[in] obj : pointer to ADC register instance
 * \return First Sample Delay Config
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetCfg2LenSmpl1st(const AdcRegType *obj)
{
    return ((obj->CFG2 & ADC_CFG2_LEN_SMPL_1ST_MASK) >> ADC_CFG2_LEN_SMPL_1ST_SHIFT);
}

/*! \brief Sets the First Sample Delay Config
 *
 * This function sets the First Sample Delay Config.
 * After ADC power on or channel changes, the first sampling time needs to be LEN_SMPL added by
 * LEN_SMPL_1ST, so the actual sample time is (LEN_SMPL_1ST+LEN_SMPL+1)*clk_ad
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of First Sample Delay Config
 */
__attribute__((always_inline)) static inline void AdcReg_SetCfg2LenSmpl1st(AdcRegType *obj,
                                                                        uint8_t value)
{
    uint32_t tmp = obj->CFG2;

    tmp &= ~ADC_CFG2_LEN_SMPL_1ST_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_CFG2_LEN_SMPL_1ST_SHIFT)) & ADC_CFG2_LEN_SMPL_1ST_MASK);
    obj->CFG2 = tmp;
}

/*! \brief Gets the ADC Sampling Time
 *
 * This function gets the current ADC Sampling Time.
 * Configs ADC Sampling time, the actual time is (LEN_SMPL+1)*clk_ad
 *
 * \param[in] obj : pointer to ADC register instance
 * \return ADC Sampling Time
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetCfg2LenSmpl(const AdcRegType *obj)
{
    return ((obj->CFG2 & ADC_CFG2_LEN_SMPL_MASK) >> ADC_CFG2_LEN_SMPL_SHIFT);
}

/*! \brief Sets the ADC Sampling Time
 *
 * This function sets the ADC Sampling Time.
 * Configs ADC Sampling time, the actual time is (LEN_SMPL+1)*clk_ad
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of ADC Sampling Time
 */
__attribute__((always_inline)) static inline void AdcReg_SetCfg2LenSmpl(AdcRegType *obj,
                                                                     uint8_t value)
{
    uint32_t tmp = obj->CFG2;

    tmp &= ~ADC_CFG2_LEN_SMPL_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_CFG2_LEN_SMPL_SHIFT)) & ADC_CFG2_LEN_SMPL_MASK);
    obj->CFG2 = tmp;
}

/*! \brief Gets the Compare Value1
 *
 * This function gets the current compare Value1.
 *
 * \param[in] obj : pointer to ADC register instance
 * \return ADC Compare Value1
 */
__attribute__((always_inline)) static inline uint16_t AdcReg_GetCv1Cv(const AdcRegType *obj)
{
    return ((obj->CV1 & ADC_CV1_CV_MASK) >> ADC_CV1_CV_SHIFT);
}

/*! \brief Sets the Compare Value1
 *
 * This function sets the Compare Value1.
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of Compare Value1
 */
__attribute__((always_inline)) static inline void AdcReg_SetCv1Cv(AdcRegType *obj, uint16_t value)
{
    uint32_t tmp = obj->CV1;

    tmp &= ~ADC_CV1_CV_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_CV1_CV_SHIFT)) & ADC_CV1_CV_MASK);
    obj->CV1 = tmp;
}

/*! \brief Gets the Compare Value2
 *
 * This function gets the current Compare Value2.
 *
 * \param[in] obj : pointer to ADC register instance
 * \return ADC Compare Value2
 */
__attribute__((always_inline)) static inline uint16_t AdcReg_GetCv2Cv(const AdcRegType *obj)
{
    return ((obj->CV2 & ADC_CV2_CV_MASK) >> ADC_CV2_CV_SHIFT);
}

/*! \brief Sets the Compare Value2
 *
 * This function sets the Compare Value2.
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of Compare Value2
 */
__attribute__((always_inline)) static inline void AdcReg_SetCv2Cv(AdcRegType *obj, uint16_t value)
{
    uint32_t tmp = obj->CV2;

    tmp &= ~ADC_CV2_CV_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_CV2_CV_SHIFT)) & ADC_CV2_CV_MASK);
    obj->CV2 = tmp;
}

/*! \brief Gets the Error in Multiplexed Trigger Request
 *
 * This function gets the current Error in Multiplexed Trigger Request.
 * Each of these error signals indicate that a multiplexed hardware trigger request from a
 * source has been missed, in which case the request has already been latched or is being serviced.
 * Each bit in this field can be cleared by writing a 1 to it, and each bit corresponds to an
 * individual trigger request:
 * - Bit 24 corresponds to trigger request 0
 * - Bit 25 corresponds to trigger request 1
 * - Bit 26 corresponds to trigger request 2
 * - Bit 27 corresponds to trigger request 3
 * The read value of each bit in this field is interpreted individually as follows:
 *
 * \param[in] obj : pointer to ADC register instance
 * \return Error in Multiplexed Trigger Request
 *         - 0b : No error has occurred
 *         - 1b : An error has occurred
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2TrgStErr(const AdcRegType *obj)
{
    return ((obj->SC2 & ADC_SC2_TRGSTERR_MASK) >> ADC_SC2_TRGSTERR_SHIFT);
}

/*! \brief clear all the Error in Multiplexed Trigger Request
 *
 * This function clear all the Error in Multiplexed Trigger Request.
 * Each of these error signals indicate that a multiplexed hardware trigger request from a
 * source has been missed, in which case the request has already been latched or is being serviced.
 * Each bit in this field can be cleared by writing a 1 to it, and each bit corresponds to an
 * individual trigger request:
 * - Bit 24 corresponds to trigger request 0
 * - Bit 25 corresponds to trigger request 1
 * - Bit 26 corresponds to trigger request 2
 * - Bit 27 corresponds to trigger request 3
 *
 * \param[in] obj : pointer to ADC register instance
 */
__attribute__((always_inline)) static inline void AdcReg_ClrSc2TrgStErr(AdcRegType *obj)
{
    uint32_t tmp = obj->SC2;

    tmp &= ~ADC_SC2_TRGSTERR_MASK;
    tmp |= (((uint32_t)(((uint32_t)(0xFu)) << ADC_SC2_TRGSTERR_SHIFT)) & ADC_SC2_TRGSTERR_MASK);
    obj->SC2 = tmp;
}

/*! \brief Gets the Trigger Status
 *
 * This function gets the current Trigger Status.
 * Each of these status bits indicate that a multiplexed hardware trigger request from a source
 * has been latched. Each bit in this field corresponds to an individual trigger request:
 * - Bit 16 corresponds to trigger request 0
 * - Bit 17 corresponds to trigger request 1
 * - Bit 18 corresponds to trigger request 2
 * - Bit 19 corresponds to trigger request 3
 * The read value of each bit in this field is interpreted individually as follows:
 *
 * \param[in] obj : pointer to ADC register instance
 * \return Trigger Status
 *         - 0b : No trigger request has been latched
 *         - 1b : A trigger request has been latched
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2TrgStLat(const AdcRegType *obj)
{
    return ((obj->SC2 & ADC_SC2_TRGSTLAT_MASK) >> ADC_SC2_TRGSTLAT_SHIFT);
}

/*! \brief Gets the Trigger Process Number
 *
 * This function gets the current Trigger Process Number.
 * Indicates the trigger number that is being serviced. This has to be qualified with the 1-bit
 * value for the corresponding trigger latch status.
 * - TRGPRNUM=00 is valid only if TRGSTLAT[16]=1
 * - TRGPRNUM=01 is valid only if TRGSTLAT[17]=1
 * - TRGPRNUM=10 is valid only if TRGSTLAT[18]=1
 * - TRGPRNUM=11 is valid only if TRGSTLAT[19]=1
 * NOTE: Occasionally there may be a mismatch between the TRGPRNUM and the ideal trigger to be
 * selected as per TRGSTLAT by Round Robin algorithm. This happens because of different operating
 * clocks of the TRGSTLAT and the hardware logic. The TRGSTLAT is updated first with arrival of
 * triggers, and then it is synchronized into the hardware clock. So, the hardware uses a delayed
 * version of TRGSTLAT. Any trigger that arrives during the synchronization time is not presented
 * to hardware immediately, but shows in TRGSTLAT
 *
 * \param[in] obj : pointer to ADC register instance
 * \return Trigger Process Number

 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2TrgPrNum(const AdcRegType *obj)
{
    return ((obj->SC2 & ADC_SC2_TRGPRNUM_MASK) >> ADC_SC2_TRGPRNUM_SHIFT);
}

/*! \brief Gets the Conversion Active
 *
 * This function gets the current Conversion Active.
 * Indicates that a conversion or hardware averaging is in progress. ADACT is set when a
 * conversion is initiated and cleared when a conversion is completed or aborted.
 *
 * \param[in] obj : pointer to ADC register instance
 * \return Conversion Active
 *         - 0b : Conversion not in progress.
 *         - 1b : Conversion in progress.
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2AdAct(const AdcRegType *obj)
{
    return ((obj->SC2 & ADC_SC2_ADACT_MASK) >> ADC_SC2_ADACT_SHIFT);
}

/*! \brief Gets the Conversion Trigger state
 *
 * This function gets the current Conversion Trigger state.
 *
 * \param[in] obj : pointer to ADC register instance
 * \return Conversion Trigger Select
 *         - 0b : trigger disable.
 *         - 1b : trigger enable.
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2AdTrg(const AdcRegType *obj)
{
    return ((obj->SC2 & ADC_SC2_ADTRG_MASK) >> ADC_SC2_ADTRG_SHIFT);
}

/*! \brief Sets the Conversion Trigger state
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of Conversion Trigger state select
 *                    - 0b : trigger disable.
 *                    - 1b : trigger enable.
 */
__attribute__((always_inline)) static inline void AdcReg_SetSc2AdTrg(AdcRegType *obj, uint8_t value)
{
    uint32_t tmp = obj->SC2;

    tmp &= ADC_SC2_WITHOUT_W1C_MASK;
    tmp &= ~ADC_SC2_ADTRG_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC2_ADTRG_SHIFT)) & ADC_SC2_ADTRG_MASK);
    obj->SC2 = tmp;
}

/*! \brief Gets the Compare Function Enable
 *
 * This function gets the current Compare Function Enable.
 * Enables the compare function.
 *
 * \param[in] obj : pointer to ADC register instance
 * \return Compare Function Enable
 *         - 0b : Compare function disabled.
 *         - 1b : Compare function enabled.
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2Acfe(const AdcRegType *obj)
{
    return ((obj->SC2 & ADC_SC2_ACFE_MASK) >> ADC_SC2_ACFE_SHIFT);
}

/*! \brief Sets the Compare Function Enable
 *
 * This function sets the Compare Function Enable.
 * Enables the compare function.
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of Compare Function Enable
 *                    - 0b : Compare function disabled.
 *                    - 1b : Compare function enabled.
 */
__attribute__((always_inline)) static inline void AdcReg_SetSc2Acfe(AdcRegType *obj, uint8_t value)
{
    uint32_t tmp = obj->SC2;

    tmp &= ADC_SC2_WITHOUT_W1C_MASK;
    tmp &= ~ADC_SC2_ACFE_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC2_ACFE_SHIFT)) & ADC_SC2_ACFE_MASK);
    obj->SC2 = tmp;
}

/*! \brief Gets the Compare Function Greater Than Enable
 *
 * This function gets the current Compare Function Greater Than Enable.
 * Configures the compare function to check the conversion result relative to CV1 and CV2 based
 * upon the value of ACREN. ACFE must be set for ACFGT to have any effect. See "Compare modes" for
 * further details in adcc_spec document
 *
 * \param[in] obj : pointer to ADC register instance
 * \return Compare Function Greater Than Enable

 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2AcFgt(const AdcRegType *obj)
{
    return ((obj->SC2 & ADC_SC2_ACFGT_MASK) >> ADC_SC2_ACFGT_SHIFT);
}

/*! \brief Sets the Compare Function Greater Than Enable
 *
 * This function sets the Compare Function Greater Than Enable.
 * Configures the compare function to check the conversion result relative to CV1 and CV2 based
 * upon the value of ACREN. ACFE must be set for ACFGT to have any effect. See "Compare modes" for
 * further details in adcc_spec document
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of Compare Function Greater Than Enable

 */
__attribute__((always_inline)) static inline void AdcReg_SetSc2AcFgt(AdcRegType *obj, uint8_t value)
{
    uint32_t tmp = obj->SC2;

    tmp &= ADC_SC2_WITHOUT_W1C_MASK;
    tmp &= ~ADC_SC2_ACFGT_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC2_ACFGT_SHIFT)) & ADC_SC2_ACFGT_MASK);
    obj->SC2 = tmp;
}

/*! \brief Gets the Compare Function Range Enable
 *
 * This function gets the current Compare Function Range Enable.
 * Configures the compare function to check if the conversion result of the input being
 * monitored is either between or outside the range formed by CV1 and CV2 determined by the value
 * of ACFGT. ACFE must be set for ACFGT to have any effect. See "Compare modes" for further
 * details in adcc_spec document
 *
 * \param[in] obj : pointer to ADC register instance
 * \return Compare Function Range Enable

 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2AcREn(const AdcRegType *obj)
{
    return ((obj->SC2 & ADC_SC2_ACREN_MASK) >> ADC_SC2_ACREN_SHIFT);
}

/*! \brief Sets the Compare Function Range Enable
 *
 * This function sets the Compare Function Range Enable.
 * Configures the compare function to check if the conversion result of the input being
 * monitored is either between or outside the range formed by CV1 and CV2 determined by the value
 * of ACFGT. ACFE must be set for ACFGT to have any effect. See "Compare modes" for further
 * details in adcc_spec document
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of Compare Function Range Enable

 */
__attribute__((always_inline)) static inline void AdcReg_SetSc2AcREn(AdcRegType *obj, uint8_t value)
{
    uint32_t tmp = obj->SC2;

    tmp &= ADC_SC2_WITHOUT_W1C_MASK;
    tmp &= ~ADC_SC2_ACREN_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC2_ACREN_SHIFT)) & ADC_SC2_ACREN_MASK);
    obj->SC2 = tmp;
}

/*! \brief Gets the DMA Enable
 *
 * This function gets the current DMA Enable.
 *
 * \param[in] obj : pointer to ADC register instance
 * \return DMA Enable
 *         - 0b : DMA is disabled.
 *         - 1b : DMA is enabled and will assert the ADC DMA request during an ADC conversion
 *                complete event , which is indicated when any SCn[COCO] flag is asserted.
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc2DmaEn(const AdcRegType *obj)
{
    return ((obj->SC2 & ADC_SC2_DMAEN_MASK) >> ADC_SC2_DMAEN_SHIFT);
}

/*! \brief Sets the DMA Enable
 *
 * This function sets the DMA Enable.
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of DMA Enable
 *                    - 0b : DMA is disabled.
 *                    - 1b : DMA is enabled and will assert the ADC DMA request during an ADC
 *                           conversion complete event , which is indicated when any SCn[COCO] flag is asserted.
 */
__attribute__((always_inline)) static inline void AdcReg_SetSc2DmaEn(AdcRegType *obj, uint8_t value)
{
    uint32_t tmp = obj->SC2;

    tmp &= ADC_SC2_WITHOUT_W1C_MASK;
    tmp &= ~ADC_SC2_DMAEN_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC2_DMAEN_SHIFT)) & ADC_SC2_DMAEN_MASK);
    obj->SC2 = tmp;
}

/*! \brief Gets the ADC Power Down
 *
 * This function gets the current ADC Power Down.
 *
 * \param[in] obj : pointer to ADC register instance
 * \return ADC Power Down
 *         - 0b : power on
 *         - 1b : power down
 * It is recommended that powers on ADC first, and then configs other registers.
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc3AdcPD(const AdcRegType *obj)
{
    return ((obj->SC3 & ADC_SC3_ADC_PD_MASK) >> ADC_SC3_ADC_PD_SHIFT);
}

/*! \brief Sets the ADC Power Down
 *
 * This function sets the ADC Power Down.
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of ADC Power Down
 *                    - 0b : power on
 *                    - 1b : power down
It is recommended that powers on ADC first, and then configs other registers.
 */
__attribute__((always_inline)) static inline void AdcReg_SetSc3AdcPD(AdcRegType *obj, uint8_t value)
{
    uint32_t tmp = obj->SC3;

    tmp &= ~ADC_SC3_ADC_PD_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC3_ADC_PD_SHIFT)) & ADC_SC3_ADC_PD_MASK);
    obj->SC3 = tmp;
}

/*! \brief Gets the Gain Error Calibration Start
 *
 * This function gets the current Gain Error Calibration Start.
 * Write 1 to this bit to start gain error calibration. This bit is cleared by hardware when
 * calibration finishes.
 *
 * \param[in] obj : pointer to ADC register instance
 * \return Gain Error Calibration Start
 *         - 0b : gain error calibration is no ongoing
 *         - 1b : gain error calibration is in progress
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc3CalGE(const AdcRegType *obj)
{
    return ((obj->SC3 & ADC_SC3_CAL_GE_MASK) >> ADC_SC3_CAL_GE_SHIFT);
}

/*! \brief Sets the Gain Error Calibration Start
 *
 * This function sets the Gain Error Calibration Start.
 * Write 1 to this bit to start gain error calibration. This bit is cleared by hardware when
 * calibration finishes.
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of Gain Error Calibration Start
 *                    - 0b : gain error calibration is no ongoing
 *                    - 1b : gain error calibration is in progress
 */
__attribute__((always_inline)) static inline void AdcReg_SetSc3CalGE(AdcRegType *obj, uint8_t value)
{
    uint32_t tmp = obj->SC3;

    tmp &= ~ADC_SC3_CAL_GE_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC3_CAL_GE_SHIFT)) & ADC_SC3_CAL_GE_MASK);
    obj->SC3 = tmp;
}

/*! \brief Gets the Offset Calibration Start
 *
 * This function gets the current Offset Calibration Start.
 * Write 1 to this bit to start offset calibration. This bit is cleared by hardware when
 * calibration finishes.
 *
 * \param[in] obj : pointer to ADC register instance
 * \return Offset Calibration Start
 *         - 0b : offset calibration is no ongoing
 *         - 1b : offset calibration is in progress
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc3CalOfs(const AdcRegType *obj)
{
    return ((obj->SC3 & ADC_SC3_CAL_OFS_MASK) >> ADC_SC3_CAL_OFS_SHIFT);
}

/*! \brief Sets the Offset Calibration Start
 *
 * This function sets the Offset Calibration Start.
 * Write 1 to this bit to start offset calibration. This bit is cleared by hardware when
 * calibration finishes.
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of Offset Calibration Start
 *                    - 0b : offset calibration is no ongoing
 *                    - 1b : offset calibration is in progress
 */
__attribute__((always_inline)) static inline void AdcReg_SetSc3CalOfs(AdcRegType *obj, uint8_t value)
{
    uint32_t tmp = obj->SC3;

    tmp &= ~ADC_SC3_CAL_OFS_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC3_CAL_OFS_SHIFT)) & ADC_SC3_CAL_OFS_MASK);
    obj->SC3 = tmp;
}

/*! \brief Gets the Continuous Conversion Enable
 *
 * This function gets the current Continuous Conversion Enable.
 * Enables continuous conversions.
 *
 * \param[in] obj : pointer to ADC register instance
 * \return Continuous Conversion Enable
 *         - 0b : One conversion will be performed (or one set of conversions, if AVGE is set)
 *                after a conversion is initiated.
 *         - 1b : Continuous conversions will be performed (or continuous sets of conversions,
 *                if AVGE is set) after a conversion is initiated.
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc3AdCo(const AdcRegType *obj)
{
    return ((obj->SC3 & ADC_SC3_ADCO_MASK) >> ADC_SC3_ADCO_SHIFT);
}

/*! \brief Sets the Continuous Conversion Enable
 *
 * This function sets the Continuous Conversion Enable.
 * Enables continuous conversions.
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of Continuous Conversion Enable
 *                    - 0b : One conversion will be performed (or one set of conversions, if
 *                           AVGE is set) after a conversion is initiated.
 *                    - 1b : Continuous conversions will be performed (or continuous sets of
 *                           conversions, if AVGE is set) after a conversion is initiated.
 */
__attribute__((always_inline)) static inline void AdcReg_SetSc3AdCo(AdcRegType *obj, uint8_t value)
{
    uint32_t tmp = obj->SC3;

    tmp &= ~ADC_SC3_ADCO_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC3_ADCO_SHIFT)) & ADC_SC3_ADCO_MASK);
    obj->SC3 = tmp;
}

/*! \brief Gets the Hardware Average Enable
 *
 * This function gets the current Hardware Average Enable.
 * Enables the hardware average function of the ADC.
 *
 * \param[in] obj : pointer to ADC register instance
 * \return Hardware Average Enable
 *         - 0b : Hardware average function disabled.
 *         - 1b : Hardware average function enabled.
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc3AvgE(const AdcRegType *obj)
{
    return ((obj->SC3 & ADC_SC3_AVGE_MASK) >> ADC_SC3_AVGE_SHIFT);
}

/*! \brief Sets the Hardware Average Enable
 *
 * This function sets the Hardware Average Enable.
 * Enables the hardware average function of the ADC.
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of Hardware Average Enable
 *                    - 0b : Hardware average function disabled.
 *                    - 1b : Hardware average function enabled.
 */
__attribute__((always_inline)) static inline void AdcReg_SetSc3AvgE(AdcRegType *obj, uint8_t value)
{
    uint32_t tmp = obj->SC3;

    tmp &= ~ADC_SC3_AVGE_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC3_AVGE_SHIFT)) & ADC_SC3_AVGE_MASK);
    obj->SC3 = tmp;
}

/*! \brief Gets the Hardware Average Select
 *
 * This function gets the current Hardware Average Select.
 * Determines how many ADC conversions will be averaged to create the ADC average result.
 *
 * \param[in] obj : pointer to ADC register instance
 * \return Hardware Average Select
 *         - 00b : 4 samples averaged.
 *         - 01b : 8 samples averaged.
 *         - 10b : 16 samples averaged.
 *         - 11b : 32 samples averaged.
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetSc3AvgS(const AdcRegType *obj)
{
    return ((obj->SC3 & ADC_SC3_AVGS_MASK) >> ADC_SC3_AVGS_SHIFT);
}

/*! \brief Sets the Hardware Average Select
 *
 * This function sets the Hardware Average Select.
 * Determines how many ADC conversions will be averaged to create the ADC average result.
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of Hardware Average Select
 *                    - 00b : 4 samples averaged.
 *                    - 01b : 8 samples averaged.
 *                    - 10b : 16 samples averaged.
 *                    - 11b : 32 samples averaged.
 */
__attribute__((always_inline)) static inline void AdcReg_SetSc3AvgS(AdcRegType *obj, uint8_t value)
{
    uint32_t tmp = obj->SC3;

    tmp &= ~ADC_SC3_AVGS_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC3_AVGS_SHIFT)) & ADC_SC3_AVGS_MASK);
    obj->SC3 = tmp;
}

/*! \brief Gets the ADC Gain Error Value
 *
 * This function gets the current ADC Gain Error Value.
 * Used in gain error adjusting. It can be set by hardware or software.
 * ADC output * 3072/VAL_GE is the gain erro
 *
 * \param[in] obj : pointer to ADC register instance
 * \return ADC Gain Error Value
 */
__attribute__((always_inline)) static inline uint16_t AdcReg_GetSingleGoValGE(const AdcRegType *obj)
{
    return ((obj->SINGLEGO & ADC_SINGLEGO_VAL_GE_MASK) >> ADC_SINGLEGO_VAL_GE_SHIFT);
}

/*! \brief Sets the ADC Gain Error Value
 *
 * This function sets the ADC Gain Error Value.
 * Used in gain error adjusting. It can be set by hardware or software.
 * ADC output * 3072/VAL_GE is the gain erro
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of ADC Gain Error Value
 */
__attribute__((always_inline)) static inline void AdcReg_SetSingleGoValGE(AdcRegType *obj,
                                                                          uint16_t value)
{
    uint32_t tmp = obj->SINGLEGO;

    tmp &= ~ADC_SINGLEGO_VAL_GE_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SINGLEGO_VAL_GE_SHIFT)) & ADC_SINGLEGO_VAL_GE_MASK);
    obj->SINGLEGO = tmp;
}

/*! \brief Gets the ADC Offset Addition Subtraction Flag
 *
 * This function gets the current ADC Offset Addition Subtraction Flag.
 * This bit configs how offset is used in calibration. It can be set by hardware or software.
 *
 * \param[in] obj : pointer to ADC register instance
 * \return ADC Offset Addition Subtraction Flag
 *         - 0b : ADC output will be added by VAL_OFS(ceiling to 4095)
 *         - 1b : ADC output will be subtracted by VAL_OFS(flooring to 4095)
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetSingleGoSubOfs(const AdcRegType *obj)
{
    return ((obj->SINGLEGO & ADC_SINGLEGO_SUB_OFS_MASK) >> ADC_SINGLEGO_SUB_OFS_SHIFT);
}

/*! \brief Sets the ADC Offset Addition Subtraction Flag
 *
 * This function sets the ADC Offset Addition Subtraction Flag.
 * This bit configs how offset is used in calibration. It can be set by hardware or software.
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of ADC Offset Addition Subtraction Flag
 *                    - 0b : ADC output will be added by VAL_OFS(ceiling to 4095)
 *                    - 1b : ADC output will be subtracted by VAL_OFS(flooring to 4095)
 */
__attribute__((always_inline)) static inline void AdcReg_SetSingleGoSubOfs(AdcRegType *obj,
                                                                           uint8_t value)
{
    uint32_t tmp = obj->SINGLEGO;

    tmp &= ~ADC_SINGLEGO_SUB_OFS_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SINGLEGO_SUB_OFS_SHIFT)) & ADC_SINGLEGO_SUB_OFS_MASK);
    obj->SINGLEGO = tmp;
}

/*! \brief Gets the ADC Offset Value
 *
 * This function gets the current ADC Offset Value.
 * Used in calibration to caculate the final result. It can be set by hardware or software
 *
 * \param[in] obj : pointer to ADC register instance
 * \return ADC Offset Value
 */
__attribute__((always_inline)) static inline uint16_t AdcReg_GetSingleGoValOfs(const AdcRegType *obj)
{
    return ((obj->SINGLEGO & ADC_SINGLEGO_VAL_OFS_MASK) >> ADC_SINGLEGO_VAL_OFS_SHIFT);
}

/*! \brief Sets the ADC Offset Value
 *
 * This function sets the ADC Offset Value.
 * Used in calibration to caculate the final result. It can be set by hardware or software
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of ADC Offset Value
 */
__attribute__((always_inline)) static inline void AdcReg_SetSingleGoValOfs(AdcRegType *obj,
                                                                           uint16_t value)
{
    uint32_t tmp = obj->SINGLEGO;

    tmp &= ~ADC_SINGLEGO_VAL_OFS_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SINGLEGO_VAL_OFS_SHIFT)) & ADC_SINGLEGO_VAL_OFS_MASK);
    obj->SINGLEGO = tmp;
}

/*! \brief Gets the ADC Gain Error Value
 *
 * This function gets the current ADC Gain Error Value.
 * Used in gain error adjusting. It can be set by hardware or software.
 * ADC output * 3072/VAL_GE is the gain erro
 *
 * \param[in] obj : pointer to ADC register instance
 * \return ADC Gain Error Value
 */
__attribute__((always_inline)) static inline uint16_t AdcReg_GetDiffGoValGE(const AdcRegType *obj)
{
    return ((obj->DIFFGO & ADC_DIFFGO_VAL_GE_MASK) >> ADC_DIFFGO_VAL_GE_SHIFT);
}

/*! \brief Sets the ADC Gain Error Value
 *
 * This function sets the ADC Gain Error Value.
 * Used in gain error adjusting. It can be set by hardware or software.
 * ADC output * 3072/VAL_GE is the gain erro
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of ADC Gain Error Value
 */
__attribute__((always_inline)) static inline void AdcReg_SetDiffGoValGE(AdcRegType *obj,
                                                                        uint16_t value)
{
    uint32_t tmp = obj->DIFFGO;

    tmp &= ~ADC_DIFFGO_VAL_GE_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_DIFFGO_VAL_GE_SHIFT)) & ADC_DIFFGO_VAL_GE_MASK);
    obj->DIFFGO = tmp;
}

/*! \brief Gets the ADC Offset Addition Subtraction Flag
 *
 * This function gets the current ADC Offset Addition Subtraction Flag.
 * This bit configs how offset is used in calibration. It can be set by hardware or software.
 *
 * \param[in] obj : pointer to ADC register instance
 * \return ADC Offset Addition Subtraction Flag
 *         - 0b : ADC output will be added by VAL_OFS(ceiling to 4095)
 *         - 1b : ADC output will be subtracted by VAL_OFS(flooring to 4095)
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetDiffGoSubOfs(const AdcRegType *obj)
{
    return ((obj->DIFFGO & ADC_DIFFGO_SUB_OFS_MASK) >> ADC_DIFFGO_SUB_OFS_SHIFT);
}

/*! \brief Sets the ADC Offset Addition Subtraction Flag
 *
 * This function sets the ADC Offset Addition Subtraction Flag.
 * This bit configs how offset is used in calibration. It can be set by hardware or software.
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of ADC Offset Addition Subtraction Flag
 *                    - 0b : ADC output will be added by VAL_OFS(ceiling to 4095)
 *                    - 1b : ADC output will be subtracted by VAL_OFS(flooring to 4095)
 */
__attribute__((always_inline)) static inline void AdcReg_SetDiffGoSubOfs(AdcRegType *obj,
                                                                         uint8_t value)
{
    uint32_t tmp = obj->DIFFGO;

    tmp &= ~ADC_DIFFGO_SUB_OFS_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_DIFFGO_SUB_OFS_SHIFT)) & ADC_DIFFGO_SUB_OFS_MASK);
    obj->DIFFGO = tmp;
}

/*! \brief Gets the ADC Offset Value
 *
 * This function gets the current ADC Offset Value.
 * Used in calibration to caculate the final result. It can be set by hardware or software
 *
 * \param[in] obj : pointer to ADC register instance
 * \return ADC Offset Value
 */
__attribute__((always_inline)) static inline uint16_t AdcReg_GetDiffGoValOfs(const AdcRegType *obj)
{
    return ((obj->DIFFGO & ADC_DIFFGO_VAL_OFS_MASK) >> ADC_DIFFGO_VAL_OFS_SHIFT);
}

/*! \brief Sets the ADC Offset Value
 *
 * This function sets the ADC Offset Value.
 * Used in calibration to caculate the final result. It can be set by hardware or software
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of ADC Offset Value
 */
__attribute__((always_inline)) static inline void AdcReg_SetDiffGoValOfs(AdcRegType *obj,
                                                                         uint16_t value)
{
    uint32_t tmp = obj->DIFFGO;

    tmp &= ~ADC_DIFFGO_VAL_OFS_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_DIFFGO_VAL_OFS_SHIFT)) & ADC_DIFFGO_VAL_OFS_MASK);
    obj->DIFFGO = tmp;
}

/*! \brief Gets the touch ADC data result
 *
 * This function gets the current touch ADC data result.
 *
 * \param[in] obj : pointer to ADC register instance
 * \return touch ADC data result
 */
__attribute__((always_inline)) static inline uint16_t AdcReg_GetTouData(const AdcRegType *obj)
{
    return ((obj->TOU & ADC_TOU_DATA_MASK) >> ADC_TOU_DATA_SHIFT);
}

__attribute__((always_inline)) static inline uint8_t AdcReg_GetTouAdAct(const AdcRegType *obj)
{
    return ((obj->TOU & ADC_TOU_ADACT_MASK) >> ADC_TOU_ADACT_SHIFT);
}

/*! \brief Gets the touch conversion complete flag
 *
 * This function gets the current touch conversion complete flag,
 * This is a read-only field that is set each time a conversion is completed
 * COCO is cleared when ADCC_TOU[DATA] is read
 *
 * \param[in] obj : pointer to ADC register instance
 * \return touch conversion complete flag
 *         - 0b : Conversion is not completed.
 *         - 1b : Conversion is completed.
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetTouCoco(const AdcRegType *obj)
{
    return ((obj->TOU & ADC_TOU_COCO_MASK) >> ADC_TOU_COCO_SHIFT);
}

/*! \brief Gets the ADC Self-test Channel Select
 *
 * This function gets the current ADC Self-test Channel Select.
 * in single-end mode
 *
 * \param[in] obj : pointer to ADC register instance
 * \return ADC Self-test Channel Select
 *         - 00b : PCH=AVSS
 *         - 01b : PCH=1/8*VREF
 *         - 10b : PCH=1/2*VREF
 *         - 11b : PCH=7/8*VREF
 *         in difference mode
 *         - 00b : PCH=AVSS, NCH=AVSS
 *         - 01b : PCH=1/8*VREF, NCH=7/8*VREF
 *         - 10b : PCH=1/2*VREF, NCH=1/2*VREF
 *         - 11b : PCH=7/8*VREF, NCH=1/8*VREF
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetGlo1Stsel(const AdcRegType *obj)
{
    return ((obj->GLO1 & ADC_GLO1_STSEL_MASK) >> ADC_GLO1_STSEL_SHIFT);
}

/*! \brief Sets the ADC Self-test Channel Select
 *
 * This function sets the ADC Self-test Channel Select.
 * in single-end mode
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of ADC Self-test Channel Select
 *                    - 00b : PCH=AVSS
 *                    - 01b : PCH=1/8*VREF
 *                    - 10b : PCH=1/2*VREF
 *                    - 11b : PCH=7/8*VREF
                      in difference mode
 *                    - 00b : PCH=AVSS, NCH=AVSS
 *                    - 01b : PCH=1/8*VREF, NCH=7/8*VREF
 *                    - 10b : PCH=1/2*VREF, NCH=1/2*VREF
 *                    - 11b : PCH=7/8*VREF, NCH=1/8*VREF
 */
__attribute__((always_inline)) static inline void AdcReg_SetGlo1Stsel(AdcRegType *obj,
                                                                      uint8_t value)
{
    uint32_t tmp = obj->GLO1;

    tmp &= ~ADC_GLO1_STSEL_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_GLO1_STSEL_SHIFT)) & ADC_GLO1_STSEL_MASK);

    obj->USRK = ADC_REG_UNLOCK_KEY;
    obj->GLO1 = tmp;
    obj->USRK = ADC_REG_LOCK_KEY;
}

/*! \brief Gets the ADC Self-test Common Mode Level Enable
 *
 * This function gets the current ADC Self-test Common Mode Level Enable.
 * This configs the common mode level enable, which is used in calibration and self-test
 *
 * \param[in] obj : pointer to ADC register instance
 * \return ADC Self-test Common Mode Level Enable
 *         - 0b : disable
 *         - 1b : enable
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetGlo1StvcmEn(const AdcRegType *obj)
{
    return ((obj->GLO1 & ADC_GLO1_STVCM_EN_MASK) >> ADC_GLO1_STVCM_EN_SHIFT);
}

/*! \brief Sets the ADC Self-test Common Mode Level Enable
 *
 * This function sets the ADC Self-test Common Mode Level Enable.
 * This configs the common mode level enable, which is used in calibration and self-test
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of ADC Self-test Common Mode Level Enable
 *                    - 0b : disable
 *                    - 1b : enable
 */
__attribute__((always_inline)) static inline void AdcReg_SetGlo1StvcmEn(AdcRegType *obj,
                                                                        uint8_t value)
{
    uint32_t tmp = obj->GLO1;

    tmp &= ~ADC_GLO1_STVCM_EN_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_GLO1_STVCM_EN_SHIFT)) & ADC_GLO1_STVCM_EN_MASK);

    obj->USRK = ADC_REG_UNLOCK_KEY;
    obj->GLO1 = tmp;
    obj->USRK = ADC_REG_LOCK_KEY;
}

/*! \brief Gets the ADC Low Noise Mode Enable
 *
 * This function gets the current ADC Low Noise Mode Enable.
 *
 * \param[in] obj : pointer to ADC register instance
 * \return ADC Low Noise Mode Enable
 *         - 0b : disable
 *         - 1b : enable
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetGlo1LowNoiseEn(const AdcRegType *obj)
{
    return ((obj->GLO1 & ADC_GLO1_LOWNOISE_EN_MASK) >> ADC_GLO1_LOWNOISE_EN_SHIFT);
}

/*! \brief Sets the ADC Low Noise Mode Enable
 *
 * This function sets the ADC Low Noise Mode Enable.
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of ADC Low Noise Mode Enable
 *                    - 0b : disable
 *                    - 1b : enable
 */
__attribute__((always_inline)) static inline void AdcReg_SetGlo1LowNoiseEn(AdcRegType *obj,
                                                                           uint8_t value)
{
    uint32_t tmp = obj->GLO1;

    tmp &= ~ADC_GLO1_LOWNOISE_EN_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_GLO1_LOWNOISE_EN_SHIFT)) & ADC_GLO1_LOWNOISE_EN_MASK);

    obj->USRK = ADC_REG_UNLOCK_KEY;
    obj->GLO1 = tmp;
    obj->USRK = ADC_REG_LOCK_KEY;
}

/*! \brief Gets the POWER On Sample Delay Config
 *
 * This function gets the current POWER On Sample Delay Config.
 * After ADC power on, this register configs delay time before sampling is started. The delay
 * time is (LEN_PWR_ON+1)*clk_ad
 *
 * \param[in] obj : pointer to ADC register instance
 * \return POWER On Sample Delay Config
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetGlo2LenPwrOn(const AdcRegType *obj)
{
    return ((obj->GLO2 & ADC_GLO2_LEN_PWR_ON_MASK) >> ADC_GLO2_LEN_PWR_ON_SHIFT);
}

/*! \brief Sets the POWER On Sample Delay Config
 *
 * This function sets the POWER On Sample Delay Config.
 * After ADC power on, this register configs delay time before sampling is started. The delay
 * time is (LEN_PWR_ON+1)*clk_ad
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of POWER On Sample Delay Config
 */
__attribute__((always_inline)) static inline void AdcReg_SetGlo2LenPwrOn(AdcRegType *obj,
                                                                         uint8_t value)
{
    uint32_t tmp = obj->GLO2;

    tmp &= ~ADC_GLO2_LEN_PWR_ON_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_GLO2_LEN_PWR_ON_SHIFT)) & ADC_GLO2_LEN_PWR_ON_MASK);
    obj->GLO2 = tmp;
}

/*! \brief Gets the arbitration change enable
 *
 * This function gets the current Arbitration change enable
 * \param[in] obj : pointer to ADC register instance
 * \return arbitration change enable
 *         - 0 : user can't write [ARB]
 *         - 1 : [ARB] sync successful, user can write [ARB] again.
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetGlo2ArbChange(const AdcRegType *obj)
{
    return ((obj->GLO2 & ADC_GLO2_ARB_CHANGE_MASK) >> ADC_GLO2_ARB_CHANGE_SHIFT);
}

/*! \brief Gets the Arbitration
 *
 * This function gets the current Arbitration.
 * decide the priority of norm-ADC and touch request
 *
 * \param[in] obj : pointer to ADC register instance
 * \return Arbitration
 *         - 0 : norm-ADC request has the priority to use ADC_CTRL
 *         - 1 : touch request has the priority to use ADC_CTRL
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetGlo2Arb(const AdcRegType *obj)
{
    return ((obj->GLO2 & ADC_GLO2_ARB_MASK) >> ADC_GLO2_ARB_SHIFT);
}

/*! \brief Sets the Arbitration
 *
 * This function sets the Arbitration.
 * decide the priority of norm-ADC and touch request
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of Arbitration
 *                    - 0 : norm-ADC request has the priority to use ADC_CTRL
 *                    - 1 : touch request has the priority to use ADC_CTRL
 */
__attribute__((always_inline)) static inline void AdcReg_SetGlo2Arb(AdcRegType *obj,
                                                                    uint8_t value)
{
    uint32_t tmp = obj->GLO2;

    tmp &= ~ADC_GLO2_ARB_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_GLO2_ARB_SHIFT)) & ADC_GLO2_ARB_MASK);
    obj->GLO2 = tmp;
}

/*! \brief Sets the User Key Register
 *
 * This function sets the User Key Register.
 * USRK needs to be 0xA5D2C3C3 in order to write SC2[0] or SC3[13:10]. If there are other ADC
 * conversion register access between USRK and SC2[0] or SC3[13:10], the write will also fail
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] value : the value of User Key Register
 */
__attribute__((always_inline)) static inline void AdcReg_SetUsrkUserKey(AdcRegType *obj,
                                                                        uint32_t value)
{
    uint32_t tmp = obj->USRK;

    tmp &= ~ADC_USRK_USER_KEY_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_USRK_USER_KEY_SHIFT)) & ADC_USRK_USER_KEY_MASK);
    obj->USRK = tmp;
}

/*! \brief Gets the Conversion Complete Flag
 *
 * This function gets the current Conversion Complete Flag.
 * This is a read-only field that is set each time a conversion is completed when one or more of
 * the following is true:
 * - The compare function is disabled SC2[ACFE]=0 and the hardware average function is disabled
 * SC3[AVGE]=0 If the compare result is true, then COCO is set upon completion of a conversion if
 * one or more of the following is true:
 * - The compare function is enabled  SC2[ACFE]=1
 * COCO is set upon completion of the selected number of conversions (determined by AVGS) if one or
 * more of the following is true:
 * - The hardware average function is enabled SC3[AVGE]=1
 * COCO is cleared when one of the following is true:
 * - The respective SCn register is written
 * - The respective Rn register is read
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] channel : ADC channel number
 * \return Conversion Complete Flag
 *         - 0b : Conversion is not completed.
 *         - 1b : Conversion is completed.
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetScCoCo(const AdcRegType *obj,
                                                                      uint8_t channel)
{
    return ((obj->SC[channel] & ADC_SC_COCO_MASK) >> ADC_SC_COCO_SHIFT);
}

/*! \brief Gets the Interrupt Enable
 *
 * This function gets the current Interrupt Enable.
 * Enables conversion complete interrupts. When COCO becomes set while the respective AIEN is
 * high, an interrupt is asserted.
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] channel : ADC channel number
 * \return Interrupt Enable
 *         - 0b : Conversion complete interrupt is disabled.
 *         - 1b : Conversion complete interrupt is enabled.
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetScAIEn(const AdcRegType *obj,
                                                                      uint8_t channel)
{
    return ((obj->SC[channel] & ADC_SC_AIEN_MASK) >> ADC_SC_AIEN_SHIFT);
}

/*! \brief Sets the Interrupt Enable
 *
 * This function sets the Interrupt Enable.
 * Enables conversion complete interrupts. When COCO becomes set while the respective AIEN is
 * high, an interrupt is asserted.
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] channel : ADC channel number
 * \param[in] value : the value of Interrupt Enable
 *                    - 0b : Conversion complete interrupt is disabled.
 *                    - 1b : Conversion complete interrupt is enabled.
 */
__attribute__((always_inline)) static inline void AdcReg_SetScAIEn(AdcRegType *obj,
                                                                   uint8_t channel,
                                                                   uint8_t value)
{
    uint32_t tmp = obj->SC[channel];

    tmp &= ~ADC_SC_AIEN_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC_AIEN_SHIFT)) & ADC_SC_AIEN_MASK);
    obj->SC[channel] = tmp;
}

/*! \brief Gets the ADC Pchannel selection
 *
 * This function gets the current ADC Pchannel selection.
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] channel : ADC channel number
 * \return ADC Pchannel selection
 *         -  000000：TK_ADC00
 *         -  000001：TK_ADC01
 *         -  000010：TK_ADC02
 *         -  000011：TK_ADC03
 *         -  000100：TK_ADC04
 *         -  000101：TK_ADC05
 *         -  000110：TK_ADC06
 *         -  000111：TK_ADC07
 *         -  001000：TK_ADC08
 *         -  001001：TK_ADC09
 *         -  001010：TK_ADC10
 *         -  001011：TK_ADC11
 *         -  001100：TK_ADC12
 *         -  001101：TK_ADC13
 *         -  001110：TK_ADC14
 *         -  001111: TK_ADC15
 *         -  010000：TK_ADC16
 *         -  010001：TK_ADC17
 *         -  010010：TK_ADC18
 *         -  010011：TK_ADC19
 *         -  010100：TK_ADC20
 *         -  010101：TK_ADC21
 *         -  010110：TK_ADC22
 *         -  010111：TK_ADC23
 *         -  011000：TK_ADC24
 *         -  011001：TK_ADC25
 *         -  011010：TK_ADC26
 *         -  011011：TK_ADC27
 *         -  011100：TK_ADC28
 *         -  011101：TK_ADC29
 *         -  011110：inner Bandgap voltage
 *         -  011111：Reserved
 *         -  100000：inner self test voltage
 *         -  100001~111110：Reserved
 *         -  111111：Module is disabled
 */
__attribute__((always_inline)) static inline uint8_t AdcReg_GetScPch(const AdcRegType *obj,
                                                                     uint8_t channel)
{
    return ((obj->SC[channel] & ADC_SC_PCH_MASK) >> ADC_SC_PCH_SHIFT);
}

/*! \brief Sets the ADC Pchannel selection
 *
 * This function sets the ADC Pchannel selection.
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] channel : ADC channel number
 * \param[in] value : the value of ADC Pchannel selection
 *         -  000000：TK_ADC00
 *         -  000001：TK_ADC01
 *         -  000010：TK_ADC02
 *         -  000011：TK_ADC03
 *         -  000100：TK_ADC04
 *         -  000101：TK_ADC05
 *         -  000110：TK_ADC06
 *         -  000111：TK_ADC07
 *         -  001000：TK_ADC08
 *         -  001001：TK_ADC09
 *         -  001010：TK_ADC10
 *         -  001011：TK_ADC11
 *         -  001100：TK_ADC12
 *         -  001101：TK_ADC13
 *         -  001110：TK_ADC14
 *         -  001111: TK_ADC15
 *         -  010000：TK_ADC16
 *         -  010001：TK_ADC17
 *         -  010010：TK_ADC18
 *         -  010011：TK_ADC19
 *         -  010100：TK_ADC20
 *         -  010101：TK_ADC21
 *         -  010110：TK_ADC22
 *         -  010111：TK_ADC23
 *         -  011000：TK_ADC24
 *         -  011001：TK_ADC25
 *         -  011010：TK_ADC26
 *         -  011011：TK_ADC27
 *         -  011100：TK_ADC28
 *         -  011101：TK_ADC29
 *         -  011110：inner Bandgap voltage
 *         -  011111：Reserved
 *         -  100000：inner self test voltage
 *         -  100001~111110：Reserved
 *         -  111111：Module is disabled
 */
__attribute__((always_inline)) static inline void AdcReg_SetScPch(AdcRegType *obj,
                                                                  uint8_t channel,
                                                                  uint8_t value)
{
    uint32_t tmp = obj->SC[channel];

    tmp &= ~ADC_SC_PCH_MASK;
    tmp |= (((uint32_t)(((uint32_t)(value)) << ADC_SC_PCH_SHIFT)) & ADC_SC_PCH_MASK);
    obj->SC[channel] = tmp;
}

/*! \brief Gets the ADC data result
 *
 * This function gets the current ADC data result.
 * Unsigned right justified
 * ORG_CODE = 1，b13-b0 valid
 * ORG_CODE=0 && MODE=00b，b7-b0 valid
 * ORG_CODE=0 && MODE=10b，b9-b0 valid
 * ORG_CODE=0 && MODE=x1b，b11-b0 vali
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] channel : ADC channel number
 * \return ADC data result
 */
__attribute__((always_inline)) static inline uint16_t AdcReg_GetRData(const AdcRegType *obj,
                                                                      uint8_t channel)
{
    return ((obj->R[channel] & ADC_R_DATA_MASK) >> ADC_R_DATA_SHIFT);
}

/*! \brief Abort ADC channel
 *
 * This function for software trigger ADC.
 *
 * \param[in] obj : pointer to ADC register instance
 * \param[in] channel : expect abort channel number
 */
__attribute__((always_inline)) static inline void AdcReg_AbortChn(AdcRegType *obj,
                                                                  uint8_t channel)
{
    uint32_t tmp = obj->SC[channel];

    obj->SC[channel] = tmp;
}

#if FEATURE_ADC_SWTRG_ON == 1
/*! \brief Software trigger ADC
 *
 * This function for software trigger ADC.
 *
 * \param[in] obj : pointer to ADC register instance
 */
__attribute__((always_inline)) static inline void AdcReg_SwTrig(AdcRegType *obj)
{
    uint32_t tmp = obj->SC[0];

    obj->SC[0] = tmp;
}
#endif
#ifdef __cplusplus
}
#endif /* extern "C" */

#endif /* _ADC_REG_H_ */
