/* Copyright Statement:
 *
 * This software/firmware and related documentation ("AutoChips Software") are
 * protected under relevant copyright laws. The information contained herein is
 * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
 * the prior written permission of AutoChips inc. and/or its licensors, any
 * reproduction, modification, use or disclosure of AutoChips Software, and
 * information contained herein, in whole or in part, shall be strictly
 * prohibited.
 *
 * AutoChips Inc. (C) 2022. All rights reserved.
 *
 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
 * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
 * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
 * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
 * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
 * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
 * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
 * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
 * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
 * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
 * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
 * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
 * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
 * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
 * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
 */

#ifndef _AC780X_ADC_H
#define _AC780X_ADC_H
/*!
 * @file ac780x_adc.h
 *
 * @brief This file provides analog to digital converter module integration functions interfaces.
 *
 */
#ifdef __cplusplus
extern "C" {
#endif

/* ===========================================  Includes  =========================================== */
#include "ac7802x.h"

/* ============================================  Define  ============================================ */
/*!
* @brief ADC instance index macro.
*/
#define ADC_INDEX(ADCx)    ((uint8_t)(((uint32_t)(ADCx) - ADC0_BASE)))

/*!
* @brief ADC regular group sequence length.
*/
#define ADC_REGULAR_SEQUENCE_LEGNTH         (21U)

/*!
* @brief ADC injected group sequence length.
*/
#define ADC_INJECT_SEQUENCE_LEGNTH          (4U)

#define ADC_IRQ_REOC_Msk                    (0x10000UL)
#define ADC_IRQ_IEOC_Msk                    (0x20000UL)

/* ===========================================  Typedef  ============================================ */
/*!
* @brief ADC channel type enumeration.
*/
typedef enum
{
    ADC_CH_0 = 0,       /*!< ADC channel 0 */
    ADC_CH_1,           /*!< ADC channel 1 */
    ADC_CH_2,           /*!< ADC channel 2 */
    ADC_CH_3,           /*!< ADC channel 3 */
    ADC_CH_4,           /*!< ADC channel 4 */
    ADC_CH_5,           /*!< ADC channel 5 */
    ADC_CH_6,           /*!< ADC channel 6 */
    ADC_CH_7,           /*!< ADC channel 7 */
    ADC_CH_8,           /*!< ADC channel 8 */
    ADC_CH_9,           /*!< ADC channel 9 */
    ADC_CH_10,          /*!< ADC channel 10 */
    ADC_CH_11,          /*!< ADC channel 11 */
    ADC_CH_12,          /*!< ADC channel 12 */
    ADC_CH_13,          /*!< ADC channel 13 */
    ADC_CH_14,          /*!< ADC channel 14 */
    ADC_CH_15,          /*!< ADC channel 15 */
    ADC_CH_16,          /*!< ADC channel 16 */
    ADC_CH_18 = 18,     /*!< ADC channel 18 */
    ADC_CH_VIN,
    ADC_CH_MAX,         /*!< Invalid channel */
} ADC_ChannelType;

/*!
* @brief ADC sample time enumeration.
*/
typedef enum
{
    ADC_SPT_CLK_9 = 0,          /*!< ADC Sample time 9 Clock Cycle */
    ADC_SPT_CLK_7,              /*!< ADC Sample time 7 Clock Cycle */
    ADC_SPT_CLK_17,             /*!< ADC Sample time 17 Clock Cycle */
    ADC_SPT_CLK_33,             /*!< ADC Sample time 33 Clock Cycle */
    ADC_SPT_CLK_64,             /*!< ADC Sample time 64 Clock Cycle */
    ADC_SPT_CLK_140,            /*!< ADC Sample time 140 Clock Cycle */
    ADC_SPT_CLK_215,            /*!< ADC Sample time 215 Clock Cycle */
    ADC_SPT_CLK_5,              /*!< ADC Sample time 5 Clock Cycle */
    ADC_SPT_CLK_MAX,            /*!< Invalid ADC Sample time */
} ADC_SampleTimeType;

/*!
* @brief ADC clock prescaler enumeration.
*/
typedef enum
{
    ADC_CLK_PRESCALER_1 = 0,    /*!< Clock presalcer divide 1 */
    ADC_CLK_PRESCALER_2,        /*!< Clock presalcer divide 2 */
    ADC_CLK_PRESCALER_3,        /*!< Clock presalcer divide 3 */
    ADC_CLK_PRESCALER_4,        /*!< Clock presalcer divide 4 */
    ADC_CLK_PRESCALER_5,        /*!< Clock presalcer divide 5 */
    ADC_CLK_PRESCALER_6,        /*!< Clock presalcer divide 6 */
    ADC_CLK_PRESCALER_7,        /*!< Clock presalcer divide 7 */
    ADC_CLK_PRESCALER_8,        /*!< Clock presalcer divide 8 */
    ADC_CLK_PRESCALER_9,        /*!< Clock presalcer divide 9 */
    ADC_CLK_PRESCALER_10,       /*!< Clock presalcer divide 10 */
    ADC_CLK_PRESCALER_11,       /*!< Clock presalcer divide 11 */
    ADC_CLK_PRESCALER_12,       /*!< Clock presalcer divide 12 */
    ADC_CLK_PRESCALER_13,       /*!< Clock presalcer divide 13 */
    ADC_CLK_PRESCALER_14,       /*!< Clock presalcer divide 14 */
    ADC_CLK_PRESCALER_15,       /*!< Clock presalcer divide 15 */
    ADC_CLK_PRESCALER_16,       /*!< Clock presalcer divide 16 */
    ADC_CLK_PRESCALER_MAX,      /*!< Invalid Clock presalcer */
} ADC_ClkPrescalerType;

/*!
* @brief ADC data alignment enumeration.
*/
typedef enum
{
    ADC_DATA_ALIGN_RIGHT = 0,   /*!< Data right alignment */
    ADC_DATA_ALIGN_LEFT,        /*!< Data left alignment */
} ADC_DataAlignType;

/*!
* @brief ADC analog monitor trigger mode enumeration.
*/
typedef enum
{
    ADC_AMO_TRIGGER_LEVEL = 0,  /*!< AMO Level trigger */
    ADC_AMO_TRIGGER_EDGE,       /*!< AMO Edge trigger */
} ADC_AMOTriggerModeType;

/*!
* @brief ADC trigger convert mode enumeration.
*/
typedef enum
{
    ADC_TRIGGER_INTERNAL = 0,   /*!< Internal software trigger */
    ADC_TRIGGER_EXTERNAL,       /*!< External signal trigger */
} ADC_TriggerConvertType;

/*!
* @brief ADC conversion mode enumeration.
*/
typedef enum
{
    ADC_SINGLE_REGULAR_ONESHOT_MODE = 0,                /*!< ADC conversion regular group single channel one shot mode */
    ADC_SINGLE_REGULAR_CONTINUOUS_MODE,                 /*!< ADC conversion regular group single channel continuous mode */
    ADC_MULTI_REGULAR_INJECT_ONESHOT_MODE,              /*!< ADC conversion multiple regular group and injected group one shot mode  */
    ADC_MULTI_REGULAR_INJECT_INTERVAL_ONESHOT_MODE,     /*!< ADC conversion multiple regular group and injected group interval one shot mode */
    ADC_MULTI_REGULAR_INJECT_AUTO_ONESHOT_MODE,         /*!< ADC conversion multiple regular group and auto inject group one shot mode */
    ADC_MULTI_REGULAR_INJECT_CONTINUOUS_MODE,           /*!< ADC conversion multiple regular group and injected group continuous mode */
    ADC_MULTI_REGULAR_INJECT_INTERVAL_CONTINUOUS_MODE,  /*!< ADC conversion multiple regular group and injected group interval continuous mode */
    ADC_MULTI_REGULAR_INJECT_AUTO_CONTINUOUS_MODE,      /*!< ADC conversion multiple regular group and auto inject group continuous mode */
    ADC_MULTI_REGULAR_DISCONTINUOUS_MODE,               /*!< ADC conversion multiple regular group discontinuous mode */
    ADC_MULTI_INJECT_DISCONTINUOUS_MODE,                /*!< ADC conversion multiple injected group discontinuous mode */
} ADC_ConversionModeType;

/*!
* @brief ADC power mode enumeration.
*/
typedef enum
{
    ADC_POWER_DOWN = 0,     /*!< Power down mode */
    ADC_POWER_ON,           /*!< Power on mode */
} ADC_PowerModeType;

/*!
 * @brief Voltage reference selection
 *
 * Implements : adc_voltage_reference_t_Class
 */
typedef enum adc_voltage_reference_t_Class
{
    ADC_VOLTAGEREF_VREF = 0U,       /*!< VrefH and VrefL as Voltage reference. */
    ADC_VOLTAGEREF_VDDA             /*!< VDDA as Voltage reference. */
} adc_voltage_reference_t;

/*!
 * @brief ADC internal monitor channel selection enumeration.
 *
 * Implements : adc_internal_channel_t_Class
 */
typedef enum adc_internal_channel_t_Class
{
    ADC_INTERNAL_BG = 0U,
    ADC_INTERNAL_TSENSOR,
} adc_internal_channel_t;

/*!
* @brief ADC configuration structure.
*/
typedef struct
{
    /* General parameters */
    ADC_ClkPrescalerType clkPsc;                /*!< Clock prescaler ratio */

    ACTION_Type scanModeEn;                     /*!< Enable/disable scan mode for regular and injected group */
    ACTION_Type continuousModeEn;               /*!< Enable/disable continuous mode */
    ACTION_Type regularDiscontinuousModeEn;     /*!< Enable/disable disconutinous mode for regular group */
    ACTION_Type injectDiscontinuousModeEn;      /*!< Enable/disable disconutinous mode for injected group */
    ACTION_Type injectAutoModeEn;               /*!< Enable/disable interval mode for mode3/5 */
    ACTION_Type intervalModeEn;                 /*!< Enable/disable antomatic mode for injected group */
    uint8_t regularDiscontinuousNum;            /*!< Regular disconutinous mode number */

    ACTION_Type interruptEn;                    /*!< Enable/disable adc interrupt  */

    adc_voltage_reference_t voltageRef;         /*!< ADC reference source selection */

    ADC_TriggerConvertType regularTriggerMode;  /*!< Select internal or external trigger for regular group */
    ADC_TriggerConvertType injectTriggerMode;   /*!< Select internal or external trigger for injected group */
    uint8_t regularSequenceLength;              /*!< Regular sequence length */
    uint8_t injectSequenceLength;               /*!< Injected sequence length */
    ADC_DataAlignType dataAlign;                /*!< 0:Right alignment; 1:left alignment */
    DeviceCallback_Type callBack;               /*!< Callback pointer */
    ADC_PowerModeType powerMode;                /*!< Power mode */
} ADC_ConfigType;

/*!
* @brief ADC analog monitor configuration structure.
*/
typedef struct
{
    ADC_AMOTriggerModeType AMOTriggerMode;      /*!< 0:level trigger; 1:edge trigger */
    ACTION_Type AMOInterruptEn;                 /*!< Enable/disable AMO interrupt */
    ACTION_Type AMORegularEn;                   /*!< Enable/disable analog monitor regular group mode */
    ACTION_Type AMOInjectEn;                    /*!< Enable/disable analog monitor injected group mode */
    ACTION_Type AMOSingleModeEn;                /*!< Enable/disable analog monitor single channel mode */
    ADC_ChannelType AMOSingleChannel;           /*!< Select analog monitor single channel */
    uint16_t AMOHighThreshold;                  /*!< Set analog monitor high Threshold */
    uint16_t AMOLowThreshold;                   /*!< Set analog monitor low Threshold */
    uint16_t AMOHighOffset;                     /*!< Set analog monitor high Offset */
    uint16_t AMOLowOffset;                      /*!< Set analog monitor low Offset */
} ADC_AMOConfigType;


/* ==========================================  Variables  =========================================== */

/* ====================================  Functions declaration  ===================================== */
/*!
* @brief ADC initialize.
*
* @param[in] ADCx: adc module
                - ADC0
* @param[in] config: pointer to configuration structure
* @return none
*/
void ADC_Init(ADC_Type *ADCx, const ADC_ConfigType *config);

/*!
* @brief ADC De-initialize.
*
* @param[in] ADCx: adc module
                - ADC0
* @return none
*/
void ADC_DeInit(ADC_Type *ADCx);

/*!
 * @brief Get ADC converter config.
 *
 * @param[in] ADCx: adc module
                - ADC0
 * @param[out] config: pointer to configuration structure that need to fill with.
 */
void ADC_GetConfig(const ADC_Type *ADCx, ADC_ConfigType * const config);

/*!
 * @brief Get adc regular group channel & sample time setting for specific sequence.
 *
 * @param[in] ADCx: adc module
                - ADC0
 * @param[in] channel: adc convert channel
                - ADC_CH_0
                - ADC_CH_1
                - ADC_CH_2
                - ADC_CH_3
                - ADC_CH_4
                - ADC_CH_5
                - ADC_CH_6
                - ADC_CH_7
                - ADC_CH_8
                - ADC_CH_9
                - ADC_CH_10
                - ADC_CH_11
                - ADC_CH_12
                - ADC_CH_13
                - ADC_CH_14
                - ADC_CH_15
                - ADC_CH_16
                - ADC_CH_18
                - ADC_CH_VIN
 * @param[in] spt: sampel time setting
                - ADC_SPT_CLK_9
                - ADC_SPT_CLK_7
                - ADC_SPT_CLK_17
                - ADC_SPT_CLK_33
                - ADC_SPT_CLK_64
                - ADC_SPT_CLK_140
                - ADC_SPT_CLK_215
                - ADC_SPT_CLK_5
 * @param[in] seq: regular group sequence
 */
void ADC_GetRegularGroupChannel(const ADC_Type *ADCx, ADC_ChannelType *channel, ADC_SampleTimeType *spt, uint8_t seq);

/*!
* @brief Set adc regular group channel
*
* @param[in] ADCx: adc module
                - ADC0
* @param[in] channel: adc channel
                - ADC_CH_0
                - ADC_CH_1
                - ADC_CH_2
                - ADC_CH_3
                - ADC_CH_4
                - ADC_CH_5
                - ADC_CH_6
                - ADC_CH_7
                - ADC_CH_8
                - ADC_CH_9
                - ADC_CH_10
                - ADC_CH_11
                - ADC_CH_12,
                - ADC_CH_13,
                - ADC_CH_14,
                - ADC_CH_15,
                - ADC_CH_16,
                - ADC_CH_18,
                - ADC_CH_VIN,
* @param[in] spt: sample time
                - ADC_SPT_CLK_9 = 0,
                - ADC_SPT_CLK_7,
                - ADC_SPT_CLK_17,
                - ADC_SPT_CLK_33,
                - ADC_SPT_CLK_64,
                - ADC_SPT_CLK_140,
                - ADC_SPT_CLK_215,
                - ADC_SPT_CLK_5,
* @param[in] seq: regular group convert sequence
                - 0 ~ 20
* @return none
*/
void ADC_SetRegularGroupChannel(ADC_Type *ADCx, ADC_ChannelType channel, ADC_SampleTimeType spt, uint8_t seq);

/*!
* @brief Set adc regular group channel
*
* @param[in] ADCx: adc module
                - ADC0
* @param[in] channel: adc channel
                - ADC_CH_0
                - ADC_CH_1
                - ADC_CH_2
                - ADC_CH_3
                - ADC_CH_4
                - ADC_CH_5
                - ADC_CH_6
                - ADC_CH_7
                - ADC_CH_8
                - ADC_CH_9
                - ADC_CH_10
                - ADC_CH_11
                - ADC_CH_12
                - ADC_CH_13
                - ADC_CH_14
                - ADC_CH_15
                - ADC_CH_16
                - ADC_CH_18
                - ADC_CH_VIN
* @param[in] spt: sample time
                - ADC_SPT_CLK_9
                - ADC_SPT_CLK_7
                - ADC_SPT_CLK_17
                - ADC_SPT_CLK_33
                - ADC_SPT_CLK_64
                - ADC_SPT_CLK_140
                - ADC_SPT_CLK_215
                - ADC_SPT_CLK_5
* @param[in] seq: regular group convert sequence
                - 0 ~ 20
* @return none
*/
void ADC_GetInjectGroupChannel(const ADC_Type *ADCx, ADC_ChannelType *channel, ADC_SampleTimeType *spt, uint8_t seq);

/*!
* @brief Set adc injected group channel.
*
* @param[in] ADCx: adc module
                - ADC0
* @param[in] channel: adc channel
                - ADC_CH_0
                - ADC_CH_1
                - ADC_CH_2
                - ADC_CH_3
                - ADC_CH_4
                - ADC_CH_5
                - ADC_CH_6
                - ADC_CH_7
                - ADC_CH_8
                - ADC_CH_9
                - ADC_CH_10
                - ADC_CH_11
                - ADC_CH_12
                - ADC_CH_13
                - ADC_CH_14
                - ADC_CH_15
                - ADC_CH_16
                - ADC_CH_18
                - ADC_CH_VIN
* @param[in] spt: sample time
                - ADC_SPT_CLK_9
                - ADC_SPT_CLK_7
                - ADC_SPT_CLK_17
                - ADC_SPT_CLK_33
                - ADC_SPT_CLK_64
                - ADC_SPT_CLK_140
                - ADC_SPT_CLK_215
                - ADC_SPT_CLK_5
* @param[in] seq: injected group convert sequence
                - 0 ~ 3
* @return none
*/
void ADC_SetInjectGroupChannel(ADC_Type *ADCx, ADC_ChannelType channel, ADC_SampleTimeType spt, uint8_t seq);

/*!
 * @brief Set adc analog monitor.
 *
 * @param[in] ADCx: adc module
                 - ADC0
 * @param[in] config: pointer to configuration structure
 * @return none
 */
void ADC_SetAnalogMonitor(ADC_Type *ADCx, const ADC_AMOConfigType *config);

/*!
* @brief Set adc callback function.
*
* @param[in] ADCx: adc module
                - ADC0
* @param[in] func: callback function
* @return none
*/
void ADC_SetCallback(ADC_Type *ADCx, const DeviceCallback_Type func);

#ifdef __cplusplus
}
#endif

#endif /* _AC780X_ADC_H */

/* =============================================  EOF  ============================================== */
