#ifndef __HAL_AUDIO_ADC_H__
#define __HAL_AUDIO_ADC_H__
#include "hal_dma.h"
#include "hal_audio.h"

#define ADC_MIX_GAIN_1                  (0x00 << 30)
#define ADC_MIX_GAIN_1_2                (0x01 << 30)
#define ADC_MIXER_SOURCE_ADC_ENABLE     (0x01 << 28)
#define ADC_MIXER_SOURCE_ADC_DISABLE    (0x00 << 28)
#define ADC_MIXER_SOURCE_DAC_ENABLE     (0x01 << 29)
#define ADC_MIXER_SOURCE_DAC_DISABLE    (0x00 << 29)
#define DMIC_DATA_PIN_MIX               (0x00 << 27)
#define DMIC_DATA_PIN_INDIVIDUAL        (0x01 << 27)
#define DMIC_CLK_DIV_4                  (0x01 << 24)
#define DMIC_CLK_DIV_2                  (0x00 << 24)
#define DMIC_CLK_DIV_6                  (0x02 << 24)
#define DMIC_CLK_DIV_8                  (0x03 << 24)
#define DMIC_CLK_DIV_12                 (0x04 << 24)
#define DMIC_CLK_DIV_16                 (0x05 << 24)
#define DMIC_DELAY_SEL_0                (0x00 << 22)
#define DMIC_DELAY_SEL_1                (0x01 << 22)
#define DMIC_DELAY_SEL_2                (0x02 << 22)
#define DMIC_DELAY_SEL_3                (0x03 << 22)
#define CLOCK_PHASE_POSITIVE            (0x00 << 21)
#define CLOCK_PHASE_NEGATIVE            (0x01 << 21)
#define HPF_COEF_16                     (0x00 << 17)
#define HPF_COEF_32                     (0x01 << 17)
#define HPF_COEF_64                     (0x02 << 17)
#define HPF_COEF_128                    (0x03 << 17)
#define HPF_COEF_256                    (0x04 << 17)
#define HPF_COEF_512                    (0x05 << 17)
#define HPF_COEF_1024                   (0x06 << 17)
#define HPF_COEF_2048                   (0x07 << 17)
#define HPF_ENABLE                      (0x01 << 16)
#define HPF_DISABLE                     (0x00 << 16)
#define VOLUME_CONTROL_16               (0x00 << 12)
#define VOLUME_CONTROL_8                (0x01 << 12)
#define VOLUME_CONTROL_4                (0x02 << 12)
#define VOLUME_CONTROL_2                (0x03 << 12)
#define VOLUME_CONTROL_1                (0x04 << 12)
#define VOLUME_CONTROL_1_2              (0x05 << 12)
#define VOLUME_CONTROL_1_4              (0x06 << 12)
#define VOLUME_CONTROL_1_8              (0x07 << 12)
#define VOLUME_CONTROL_1_16             (0x08 << 12)
#define FIR_CLK_DIV_1                   (0x00 << 9)
#define FIR_CLK_DIV_2                   (0x01 << 9)
#define FIR_CLK_DIV_4                   (0x02 << 9)
#define FIR_CLK_DIV_6                   (0x03 << 9)
#define FIR_CLK_DIV_8                   (0x04 << 9)
#define FIR_CLK_DIV_12                  (0x05 << 9)
#define FIR_CLK_DIV_16                  (0x06 << 9)
#define FIR_CLK_DIV_24                  (0x07 << 9)
#define FIR_CLK_SEL_DEBUG               (0x00 << 8)
#define FIR_CLK_SEL_DAC                 (0x01 << 8)
#define CIC_CLK_DIV_2                   (0x00 << 6)
#define CIC_CLK_DIV_4                   (0x01 << 6)
#define CIC_CLK_DIV_8                   (0x02 << 6)
#define CIC_DATA_SEL_DEBUG              (0x00 << 5)
#define CIC_DATA_SEL_DACSDM             (0x01 << 5)
#define CIC_CLK_SEL_DEBUG               (0x00 << 4)
#define CIC_CLK_SEL_DAC                 (0x01 << 4)
#define CIC_SEL_32                      (0x00 << 2)
#define CIC_SEL_16                      (0x01 << 2)
#define CIC_SEL_8                       (0x02 << 2)
#define CIC_SEL_4                       (0x03 << 2)
#define MODE_SEL_ADC                    (0x00 << 1)
#define MODE_SEL_DMIC                   (0x01 << 1)
#define CHN_DISABLE                     (0x00 << 0)
#define CHN_ENABLE                      (0x01 << 0)

/***********************************ADC_CFG***********************************/
#define FIFO_DATA_SEL_CHAN0_ENABLE      (0x01 << 24)
#define FIFO_DATA_SEL_CHAN1_ENABLE      (0x01 << 25)
#define FIFO_DATA_SEL_CHAN2_ENABLE      (0x01 << 26)
#define FIFO_DATA_SEL_CHAN3_ENABLE      (0x01 << 27)
#define ADC_RX_FIFO_CLK_CHAN0           (0x00 << 20)
#define ADC_RX_FIFO_CLK_CHAN1           (0x01 << 20)
#define ADC_RX_FIFO_CLK_CHAN2           (0x02 << 20)
#define ADC_RX_FIFO_CLK_CHAN3           (0x03 << 20)
#define DBG_CHN_SEL_CHAN0               (0x00 << 18)
#define DBG_CHN_SEL_CHAN1               (0x01 << 18)
#define DBG_CHN_SEL_CHAN2               (0x02 << 18)
#define DBG_CHN_SEL_CHAN3               (0x03 << 18)
#define DBG_OUT_DISABLE                 (0x00 << 17)
#define DBG_OUT_ENABLE                  (0x01 << 17)
#define DBG_IN_DISABLE                  (0x00 << 16)
#define DBG_IN_ENABLE                   (0x01 << 16)
#define HFUL_TH(n)                      (n << 8)
#define ADC_DATA_WIDTH_24               (0x00 << 6)
#define ADC_DATA_WIDTH_16               (0x01 << 6)

typedef enum
{
    AMIC_CH0                     = (1 << 0),
    AMIC_CH1                     = (1 << 1),
    DMIC0_GPIO0_GPIO1            = (1 << 2),
    DMIC0_GPIO18_GPIO19          = (1 << 3),
    DMIC0_GPIO30_GPIO31          = (1 << 4),
    DMIC1_GPIO4_GPIO5            = (1 << 5),
    DIMC1_GPIO20_GPIO21          = (1 << 6),
    DIMC2_GPIO14_GPIO15          = (1 << 7),
    DMIC2_GPIO22_GPIO23          = (1 << 8),
    DIMC3_GPIO16_GPIO17          = (1 << 9),
    MIC_FREE                     = (1 << 10),
} microphone_type_def;

typedef enum
{
    SAMPLE_RATE_8K,
    SAMPLE_RATE_16K,
    SAMPLE_RATE_24K,
    SAMPLE_RATE_32K,
    SAMPLE_RATE_48K,
    SAMPLE_RATE_96K,
    SAMPLE_RATE_192K
} sample_rate_type_def;

typedef enum
{
    VOLUME_16X     = 0X00,
    VOLUME_08X,
    VOLUME_04X,
    VOLUME_02X,
    VOLUME_01X,
    VOLUME_1_2X,
    VOLUME_1_4X,
    VOLUME_1_8X,
    VOLUME_1_6X,
    VOLUME_NUM,
} volume_type_def;

typedef enum
{
    WIDTH_24BIT     = 0UL,
    WIDTH_16BIT,
} adc_data_width_type_def;


typedef enum
{
    VOLT_2o77     =  0UL,
    VOLT_2o71,
    VOLT_2o59,
    VOLT_2o49,
    VOLT_2o40,
    VOLT_2o29,
    VOLT_2o21,
    VOLT_2o10,
    VOLT_2o00,
    VOLT_1o91,
    VOLT_1o81,
    VOLT_1o71,
    VOLT_1o60,
    VOLT_1o50,
} vmic_vol_type_def;


typedef enum
{
    stereo = 0x01,
    mono   = 0x02,
} channel_number_type_def;

typedef enum _mic_enum
{
    MIC0,
    MIC1,
} mic_enum;

typedef enum  _amic_mode_type_def
{
    mic_mix = 0UL,
    single_n,
    single_p,
    different,
} amic_mode_type_def;

typedef enum  _amic_mic_gain_type_def
{
    MADC_MIC_GAIN_N12DB = 0x00UL,
    MADC_MIC_GAIN_N6DB  = 0x01UL,
    MADC_MIC_GAIN_0DB   = 0x02UL,
    MADC_MIC_GAIN_6DB   = 0x03UL,
    MADC_MIC_GAIN_12DB  = 0x04UL,
    MADC_MIC_GAIN_18DB  = 0x05UL,
    MADC_MIC_GAIN_24DB  = 0x06UL,
    MADC_MIC_GAIN_30DB  = 0x07UL,
} amic_mic_gain_type_def;


typedef enum  _amic_mix_gain_type_def
{
    MADC_MIX_GAIN_N4D5B = 0x00,
    MADC_MIX_GAIN_N3D0B = 0X01,
    MADC_MIX_GAIN_N1D5B = 0X02,
    MADC_MIX_GAIN_N0D0B = 0X03,
    MADC_MIX_GAIN_P1D5B = 0X04,
    MADC_MIX_GAIN_P3D0B = 0X05,
    MADC_MIX_GAIN_P4D5B = 0X06,
    MADC_MIX_GAIN_P6D0B = 0X07,
    MADC_MIX_GAIN_P7D5B = 0X08,
    MADC_MIX_GAIN_P9D0B = 0X09,
    MADC_MIX_GAIN_P10D5B = 0X0A,
    MADC_MIX_GAIN_P12D0B = 0X0B,
    MADC_MIX_GAIN_P13D5B = 0X0C,
    MADC_MIX_GAIN_P16D5B = 0X0D,
    MADC_MIX_GAIN_P18D0B = 0X0E,
} amic_mix_gain_type_def;

typedef enum  _amic_channel_type_def
{
    AMIC0 = 0x00UL,
    AMIC1,
} amic_channel_type_def;

typedef enum  _mic_type_def
{
    AMIC = 0x00UL,
    DMIC,
} mic_type_def;

typedef enum
{
    MIC_0,                  /*选择MIC0作为该功能输入*/
    MIC_1,                  /*选择MIC1作为该功能输入*/
}input_option_e;
typedef enum  _adc_channel_type_def
{
    CHN0 = (1 << 0),
    CHN1 = (1 << 1),
    CHN2 = (1 << 2),
    CHN3 = (1 << 3),
} adc_channel_type_def;

typedef enum  _dmic_mode_typedef
{
    SINGLE = 0x00UL,
    DUAL   = 0x01UL,
}
dmic_mode_typedef;


typedef enum _vmic_ref_enum
{
    VREF_VMIC,
    VCM,
} vmic_ref_enum;

typedef enum _vmic_enum
{
    VMIC0,
    VMIC1,
} vmic_enum;

typedef struct _audio_adc_init_typedef
{
    src_sel_type_def         src_sel;
    adc_data_width_type_def  data_width;/*数据宽度*/
    uint32_t                 channel_id;
} audio_adc_init_typedef;

typedef struct _audio_adc_amic_typedef
{
    amic_mode_type_def       mode;             /*输入方式*/
    amic_mic_gain_type_def   mic_gain;         /*mic增益*/
    amic_mix_gain_type_def   mix_gain;         /*mix增益*/
    vmic_vol_type_def        vmic;             /*VMIC电压*/
} audio_adc_amic_typedef;

typedef struct _audio_adc_dmic_typedef
{
    dmic_mode_typedef       mode;        /*输入方式,单通道还是左右通道*/
} audio_adc_dmic_typedef;

typedef struct _audio_adc_ch_cfg_typedef
{
    sample_rate_type_def     sample_rate;  /*采样率*/
    volume_type_def          digit_volume; /*数字音量*/
    microphone_type_def      hw_pin;
    audio_adc_dmic_typedef   dmic;
    audio_adc_amic_typedef   amic;
} audio_adc_ch_cfg_typedef;

typedef struct  _audio_adc_handle_typedef
{
    audio_adc_init_typedef        init;
    audio_adc_ch_cfg_typedef      ch_cfg[4];
    DMA_HandleTypeDef             *dma_handle; /*!< Pointer DMA Handler */
    audio_state_type_def          state;
    __IO uint32_t                 err_code;
} audio_adc_handle_typedef;

typedef struct  _clk_div_typedef
{
    uint32_t adc_osc_div;
    uint32_t fir_clk_div;
    uint32_t dmic_clk_div;
    uint32_t cic_sel;
    uint32_t adc_clkdiv_sel;
} clk_div_typedef;


typedef struct  adc_AGC_config_typedef_
{
    uint32_t AGC_enable;
    uint32_t noise_gain_enable;
    uint32_t Hysteresis;
    uint32_t Min_gain;
    uint32_t Max_gain;
    uint32_t noise_level;
    uint32_t Target_level;
    uint32_t Peak_Attack_time;
    uint32_t Peak_Release_time;
    uint32_t Gain_Attack_time;
    uint32_t Gain_Release_time;
} adc_AGC_config_typedef_def;



typedef struct
{
    vmic_vol_type_def   voltage;
    vmic_ref_enum       vmic_ref_sel;
    Options_EnableEnum  bypass_enable;
    Options_EnableEnum  ramp_up_enbale;
    Options_EnableEnum  ramp_down_enbale;
    Options_EnableEnum  mic_fast_charge_cap_enable;
    uint32_t            ramp_up_down_time_interval;
    uint32_t            ramp_up_high_num;
    uint32_t            ramp_up_total_num;
} vmic_config_struct;

int find_first_1bit(uint32_t data);
HAL_StatusTypeDef  hal_audio_adc_deinit(audio_adc_handle_typedef *hadc);
HAL_StatusTypeDef get_amic_clk_div(uint32_t sample, clk_div_typedef *addr);
HAL_StatusTypeDef get_dmic_clk_div(uint32_t sample, clk_div_typedef *addr);
HAL_StatusTypeDef  hal_audio_init(audio_adc_handle_typedef *hadc);

HAL_StatusTypeDef audio_adc_cmd(audio_adc_handle_typedef *hadc, Options_EnableEnum cmd);
HAL_StatusTypeDef hal_audio_adc_ch_cfg(audio_adc_handle_typedef *hadc, audio_adc_ch_cfg_typedef ch);
HAL_StatusTypeDef hal_audio_adc_vol_set(audio_adc_handle_typedef *hadc, adc_channel_type_def ch, volume_type_def vol);
HAL_StatusTypeDef hal_audio_adc_fifo_sel(audio_adc_handle_typedef *hadc, adc_channel_type_def ch);
HAL_StatusTypeDef hal_audio_adc_src_sel(audio_adc_handle_typedef *hadc, src_sel_type_def sel);
HAL_StatusTypeDef hal_audio_adc_set_samplerate(audio_adc_handle_typedef *hadc, sample_rate_type_def samplerate);
HAL_StatusTypeDef hal_audio_adc_set_samplebits(audio_adc_handle_typedef *hadc, adc_data_width_type_def samplebits);
HAL_StatusTypeDef hal_audio_adc_mic_gain_set(audio_adc_handle_typedef *hadc, amic_channel_type_def ch, amic_mic_gain_type_def gain);
HAL_StatusTypeDef hal_audio_adc_mic_gain_get(audio_adc_handle_typedef *hadc, amic_channel_type_def ch, amic_mic_gain_type_def* gain);
HAL_StatusTypeDef hal_audio_adc_mix_gain_set(audio_adc_handle_typedef *hadc, amic_channel_type_def ch, amic_mix_gain_type_def gain);
HAL_StatusTypeDef hal_audio_adc_set_agc_cmd(audio_adc_handle_typedef *hadc, Options_EnableEnum cmd);
HAL_StatusTypeDef hal_audio_adc_set_agc(audio_adc_handle_typedef *hadc, adc_AGC_config_typedef_def *agc_config);
void audio_adc_mic_set(mic_enum mic,amic_mode_type_def option,amic_mic_gain_type_def gain);
void set_mic_gain(input_option_e ch, amic_mic_gain_type_def gain);
void get_mic_gain(input_option_e ch, uint32_t *addr);
void get_mic_mix_gain(input_option_e ch, uint32_t *addr);
void set_mic_mix_gain(input_option_e ch, amic_mix_gain_type_def gain);
HAL_StatusTypeDef set_mic_pin_fun(uint32_t temp);
void pmu_vmic_set_voltage(vmic_enum vmic, vmic_config_struct vmic_cfg);
void pmu_vmic_ramp_up_control(vmic_enum vmic, vmic_config_struct vmic_cfg);
void pmu_vmic_bypass_control(vmic_enum vmic, Options_EnableEnum option);
void pmu_vmic_ref_sel(vmic_enum vmic, vmic_ref_enum ref);
void pmu_control_charge_pump(Options_EnableEnum option);
void pmu_control_vmic(vmic_enum vmic, Options_EnableEnum option, vmic_config_struct vmic_cfg);
void mic_fast_charge_cap_disable(void);
void vmic_init(vmic_enum vmic_sel, uint32_t vmic_voltage);
void hal_audio_adc_option(input_option_e ch,Options_EnableEnum cmd);
#endif
