/**
 * *************************************************************************************************************
 * @file Adc24.h
 * @author BH_CodeGenerator
 * @version 0.1
 * @date 2022-04-01
 * @warning <!--auto generated by Tools, do not modify or add anything, otherwise, your change will be lost!!! -->
 * @brief all the functions prototypes for Adc24 firmware library
 * MCU / CFG Ver. :BH66F2455/1.7
 * Version = 1.0.0

 * *************************************************************************************************************
 *  @attention
 *
 *  Firmware Disclaimer Information
 *
 *  1. The customer hereby acknowledges and agrees that the program technical documentation, including the
 *     code, which is supplied by BEST HEALTH ELECTRONIC Inc., (hereinafter referred to as BestHealth) is the
 *     proprietary and confidential intellectual property of BestHealth, and is protected by copyright law and
 *     other intellectual property laws.
 *
 *  2. The customer hereby acknowledges and agrees that the program technical documentation, including the
 *     code, is confidential information belonging to BestHealth, and must not be disclosed to any third parties
 *     other than BestHealth and the customer.
 *
 *  3. The program technical documentation, including the code, is provided and for customer reference
 *     only. After delivery by BestHealth, the customer shall use the program technical documentation, including
 *     the code, at their own risk. BestHealth disclaims any expressed, implied or statutory warranties, including
 *     the warranties of merchantability, satisfactory quality and fitness for a particular purpose.
 *
 *  <h2><center>Copyright (C) BEST HEALTH ELECTRONIC Inc. All rights reserved</center></h2>
 */
/* Define to prevent recursive inclusion -------------------------------------------------------------------*/
#ifndef _ADC24_H_
#define _ADC24_H_

/* Includes ------------------------------------------------------------------------------------------------*/
#include <stdint.h>
#include "BH66F2455.h"
#include "..\board\BoardCfg.h"

#define ADC_USE_RATE3 (1)    // default use
#define ADC_USE_RATE2 (0)
#if (ADC_USE_RATE3 + ADC_USE_RATE2) != 1
    #error "Only one ADC use rate can be selected"
#endif

/* Exported types ----------------------------------------------------------------------------------------*/
/*! adc sample rate enum */
typedef enum {
#if ADC_USE_RATE3
    ADC24_RATE_4MHZ_4HZ,
    ADC24_RATE_4MHZ_8HZ,
    ADC24_RATE_4MHZ_10HZ,
    ADC24_RATE_4MHZ_16HZ,
    ADC24_RATE_4MHZ_20HZ,
    ADC24_RATE_4MHZ_33HZ,
    ADC24_RATE_4MHZ_41HZ,
    ADC24_RATE_4MHZ_65HZ,
    ADC24_RATE_4MHZ_81HZ,
    ADC24_RATE_4MHZ_130HZ,
    ADC24_RATE_4MHZ_163HZ,
    ADC24_RATE_4MHZ_260HZ,
    ADC24_RATE_4MHZ_326HZ,
    ADC24_RATE_4MHZ_521HZ,
    ADC24_RATE_4MHZ_651HZ,
    ADC24_RATE_4MHZ_1302HZ,
#endif

#if ADC_USE_RATE2
    ADC24_RATE_4MHZ_2HZ,
    ADC24_RATE_4MHZ_4HZ,
    ADC24_RATE_4MHZ_5HZ,
    ADC24_RATE_4MHZ_8HZ,
    ADC24_RATE_4MHZ_10HZ,
    ADC24_RATE_4MHZ_16HZ,
    ADC24_RATE_4MHZ_20HZ,
    ADC24_RATE_4MHZ_33HZ,
    ADC24_RATE_4MHZ_41HZ,
    ADC24_RATE_4MHZ_65HZ,
    ADC24_RATE_4MHZ_81HZ,
    ADC24_RATE_4MHZ_130HZ,
    ADC24_RATE_4MHZ_163HZ,
    ADC24_RATE_4MHZ_260HZ,
    ADC24_RATE_4MHZ_326HZ,
    ADC24_RATE_4MHZ_521HZ,
    ADC24_RATE_4MHZ_651HZ,
    ADC24_RATE_4MHZ_1302HZ,
#endif

    ADC24_RATE_400KHZ_6HZ,
    ADC24_RATE_400KHZ_12HZ,
    ADC24_RATE_400KHZ_24HZ,
    ADC24_RATE_400KHZ_49HZ,
    ADC24_RATE_400KHZ_98HZ,
    ADC24_RATE_400KHZ_195HZ,
    ADC24_RATE_400KHZ_391HZ,
    ADC24_RATE_400KHZ_781HZ,
    ADC24_RATE_400KHZ_1563HZ,
    ADC24_RATE_400KHZ_3125HZ,
    
    ADC24_SINC2_RATE_400KHZ_391HZ,
} Adc24_SampleRate_e;

/*! Adc gain config */
typedef enum {
    ADC24_REFx1_GAINx1       = 0x00,    //!< Limited PGA input range adc_gain=1 Pga_gain=1
    ADC24_REFx1_GAINx2       = 0x01,    //!< Limited PGA input range adc_gain=1 Pga_gain=2
    ADC24_REFx1_GAINx4       = 0x02,    //!< Limited PGA input range adc_gain=1 Pga_gain=4
    ADC24_REFx1_GAINx8       = 0x03,    //!< Limited PGA input range adc_gain=1 Pga_gain=8
    ADC24_REFx1_GAINx16      = 0x04,    //!< Limited PGA input range adc_gain=1 Pga_gain=16
    ADC24_REFx1_GAINx32      = 0x05,    //!< Limited PGA input range adc_gain=1 Pga_gain=32
    ADC24_REFx1_GAINx64      = 0x0D,    //!< Limited PGA input range adc_gain=2 Pga_gain=32
    ADC24_REFx1_GAINx128     = 0x0E,    //!< Limited PGA input range adc_gain=2 Pga_gain=64
    ADC24_REFx1_GAINx256     = 0x0F,    //!< Limited PGA input range adc_gain=2 Pga_gain=128
    ADC24_REFx1_GAINx1BYPASS = 0x80,    //!< Minimal noise, but also minimal input impedance
} Adc24_Gain_e;

/*! Adc channel negative config */
typedef enum {
    ADC24_CHP_OP1O_N_DAC1O  = 0x88,
    ADC24_CHP_OP2O_N_DAC2O  = 0x99,
    ADC24_CHP_OP3O_N_DAC3O  = 0xAA,
    ADC24_CHP_AVDD5_N_AVDD6 = 0xBC,
    ADC24_CHP_AN0_N_AVSS    = 0xCD,
    ADC24_CHP_AN0_N_AN1     = 0xDD,
    ADC24_CHP_OP1O_N_AVSS   = 0xC8,
    ADC24_CHP_OP2O_N_AVSS   = 0xC9,
    ADC24_CHP_OP3O_N_AVSS   = 0xCA,
    ADC24_CHP_AVSS_N_AN1    = 0xDB,
    ADC24_CHP_AN0_N_DAC1O   = 0x8D,
} Adc24_Channel_e;

/*! Adc data skip config */
typedef enum {
    ADC24_DATA_SKIP_DISABLE = 0x00,               //!< Disable data skip
    ADC24_DATA_SKIP_1       = 0x80 + (0 << 5),    //!< Skip 1 data conversion
    ADC24_DATA_SKIP_2       = 0x80 + (1 << 5),    //!< Skip 2 data conversions
    ADC24_DATA_SKIP_3       = 0x80 + (2 << 5),    //!< Skip 3 data conversions
    ADC24_DATA_SKIP_4       = 0x80 + (3 << 5),    //!< Skip 4 data conversions
} Adc24_DataSkip_e;

/*! Adc data averaging count config */
typedef enum {
    ADC24_ADACC_DISABLE = 0x00,    //!< Averaging disabled
    ADC24_ADACC_4       = 0x80,    //!< 4 times averaging
    ADC24_ADACC_8       = 0x81,    //!< 8 times averaging
    ADC24_ADACC_16      = 0x82,    //!< 16 times averaging
    ADC24_ADACC_32      = 0x83,    //!< 32 times averaging
    ADC24_ADACC_64      = 0x84     //!< 64 times averaging for other values
} Adc24_DataAvg_Cnt_e;

/*! Adc auto write number config */
typedef enum {
    ADC24_WRNUM_DISABLE = 0x00,    //!< Write 0 A/D conversion data
    ADC24_WRNUM_1       = 0x01,    //!< Write 1 A/D conversion data
    ADC24_WRNUM_2       = 0x02,    //!< Write 2 A/D conversion data
    ADC24_WRNUM_3       = 0x03,    //!< Write 3 A/D conversion data
    ADC24_WRNUM_4       = 0x04,    //!< Write 4 A/D conversion data
    ADC24_WRNUM_5       = 0x05,    //!< Write 5 A/D conversion data
    ADC24_WRNUM_6       = 0x06,    //!< Write 6 A/D conversion data
    ADC24_WRNUM_7       = 0x07,    //!< Write 7 A/D conversion data
    ADC24_WRNUM_8       = 0x08,    //!< Write 8 A/D conversion data
    ADC24_WRNUM_9       = 0x09,    //!< Write 9 A/D conversion data
    ADC24_WRNUM_10      = 0x0A,    //!< Write 10 A/D conversion data
    ADC24_WRNUM_11      = 0x0B,    //!< Write 11 A/D conversion data
    ADC24_WRNUM_12      = 0x0C,    //!< Write 12 A/D conversion data
    ADC24_WRNUM_13      = 0x0D,    //!< Write 13 A/D conversion data
    ADC24_WRNUM_14      = 0x0E,    //!< Write 14 A/D conversion data
    ADC24_WRNUM_15      = 0x0F,    //!< Write 15 A/D conversion data
    ADC24_WRNUM_16      = 0x10,    //!< Write 16 A/D conversion data
    ADC24_WRNUM_17      = 0x11,    //!< Write 17 A/D conversion data
    ADC24_WRNUM_18      = 0x12,    //!< Write 18 A/D conversion data
    ADC24_WRNUM_19      = 0x13,    //!< Write 19 A/D conversion data
    ADC24_WRNUM_20      = 0x14,    //!< Write 20 A/D conversion data
    ADC24_WRNUM_21      = 0x15,    //!< Write 21 A/D conversion data
} Adc24_AutoWriteNum_e;

/*! ADC error check configuration */
typedef enum {
    ADC24_ERRCHECK_DISABLE = 0x00,    //!< Err check disabled
    ADC24_ERRCHECK_ENABLE  = 0xC0,    //!< Err check enabled
} Adc24_ErrCheck_e;

/**
 * @brief adc config
 */
typedef struct
{
    uint8_t sampleRate;      //!< R/W @see Adc24_SampleRate_e
    uint8_t gain;            //!< R/W @see Adc24_Gain_e
    uint8_t channel;         //!< R/W @see Adc24_Chanel_e
    uint8_t dataSkip;        //!< R/W @see Adc24_DataSkip_e
    uint8_t dataAvgCnt;      //!< R/W @see Adc24_DataAvg_Cnt_e
    uint8_t autoWriteNum;    //!< R/W @see Adc24_AutoWriteNum_e
    uint8_t errCheck;        //!< R/W @see Adc24_ErrCheck_e
} Adc24_Cfg_t;

typedef struct
{
    union {
        struct {
            uint8_t byteLow;     //!< R adc data low byte
            uint8_t byteMid;     //!< R adc data mid byte
            uint8_t byteHigh;    //!< R adc data high byte
            uint8_t byteRes;     //!< R reserved
        } byte;

        int32_t adcData;    //!< R adc raw data
    } data;

    uint16_t samplingCnt;    //!< R adc sample count

    union {
        struct {
            uint8_t isReady         : 1;    //!< R/W adc data is ready
            uint8_t isAutoModeReady : 1;    //!< R/W adc data is ready
        } b;

        uint8_t byte;
    } flag;
} Adc24_Source_t;

/* Exported functions --------------------------------------------------------------------------------------*/
// clang-format off
extern volatile int8_t *adcAutoModeBufP;
extern volatile Adc24_Source_t adc24SourceData;
void Adc24_Cfg(Adc24_Cfg_t cfg);
void Adc24_Enable(Adc24_Cfg_t cfg);
void Adc24_Disable();
void Adc24_Poling();
#define Adc24_Auto_Modo_Isr_Enable()        { _adf = 1; _autoadf = 0; _autoade = 1;}
#define Adc24_Auto_Modo_Isr_Disable()       { _adf = 1; _autoadf = 0; _autoade = 0;}
#define Adc24_Isr_Enable()                  { _adf = 0; _ade = 1;}
#define Adc24_Isr_Disable()                 { _adf = 0; _ade = 0;}
#define Adc24_Average_Isr_Enable()          { _adf = 1; _adavgf = 0; _adavge = 1;}
#define Adc24_Average_Isr_Disable()         { _adf = 1; _adavgf = 0; _adavge = 0;}
#define Adc24_Short_Enable()                { _inis = true;}
#define Adc24_Short_Disable()               { _inis = false;}
// clang-format on

#endif