#include "platform.h"
#include "hal_def.h"
#include "board.h"
#include "hal_audio.h"
#include "hal_pmu.h"
#include "hal_cmu.h"
#include "hal_audio_adc.h"
#include "iir_config.h"
#include "hal_audio_dac.h"
#include "hal_log.h"
#include "hal_efuse.h"
#include "hal_pmu.h"
#include "hal_gpio.h"
#include "debug.h"


void vmic_config(vmic_vol_type_def vmic_voltage);
HAL_StatusTypeDef audio_dac_drc_cmd(Options_EnableEnum cmd);


/**
* @brief        dac初始化函数
* @details      通过hadc中的配置信息对dac寄存器做初始化
* @param[in]    *hdac：audio_dac_handle_typedef 结构体中的成员
* @return       none
* @note         none
*/
HAL_StatusTypeDef  hal_audio_dac_init(audio_dac_handle_typedef *hdac)
{
    uint32_t dac_clk_div;
    uint32_t mono_en, bit_slot, bit_format, dac_r_mix, dac_l_mix;
    HAL_StatusTypeDef status;

    if (hdac == NULL)
    {
        return HAL_ERROR;
    }

    DEV_RMU->RSTEN0 |= DEV_RMU_RSTEN0_AON;
    DEV_CMU->CLKEN0 |= DEV_CMU_CLKEN0_AON;
    pmu_avcc_voltage_config(PMU_AVCC_VOL_3_0V);
    pmu_power_normal_on_config(PMU_POWER_NORMAL_ON_AVCC, ENABLE);
    pmu_power_normal_on_config(PMU_POWER_NORMAL_ON_CPP, ENABLE);//1.8v
    AON_OSC->XTAL_CTL |= AON_OSC_XTAL_CTL_EN;
    DEV_RMU->RSTEN0 &= ~DEV_RMU_RSTEN0_DAC;
    delay_us(360 * MHz, 10);
    DEV_RMU->RSTEN0 |= DEV_RMU_RSTEN0_DAC ;
    DEV_CMU->CLKEN0 |= DEV_CMU_CLKEN0_DAC ;/*一点点毛刺*/
#ifdef DAC_USE_AUDIO_PLL
    cmu_dac_set_clk(CMU_Clock_PLL_AUDIO, 2);
#else
    cmu_dac_set_clk(CMU_Clock_OSC_XTAL, 1);
#endif
    status = get_dac_clk_div(hdac->init.sample_rate, &dac_clk_div);
    audio_dac_mix_get(hdac, &dac_r_mix, &dac_l_mix); /*计算DAC mix信息*/

    if (status != HAL_OK)
    {
        return HAL_ERROR;
    }

    if (hdac->init.track == DAC_MONO)
    {
        mono_en = hdac->init.track;
    }
    else
    {
        mono_en = 0;
    }

    if (hdac->init.data_format == width_16bit_useful_16bit)
    {
        bit_slot = 1;
    }
    else
    {
        bit_slot = 0;
    }

    if ((hdac->init.data_format == width_32bit_useful_low_16bit) || (hdac->init.data_format == width_32bit_useful_low_24bit) || (hdac->init.data_format == width_16bit_useful_16bit))
    {
        bit_format = 0;
    }
    else
    {
        bit_format = 1;
    }
#ifdef DAC_USING_ECLK
    DEV_CMU->DACCLK = ((dac_clk_div - 1) << 4) | DEV_CMU_DACCLK_SEL_EXT_CLK | DEV_CMU_DACCLK_EN_ENABLE; //使用外部时钟作为时钟源
#endif
#ifdef DAC_USE_AUDIO_PLL
    DEV_CMU->DACCLK = ((dac_clk_div * 2 - 1) << 4) | DEV_CMU_DACCLK_SEL_PLL_AUDIO | DEV_CMU_DACCLK_EN_ENABLE; //使用AUDIO PLL时钟作为时钟源
#else
    DEV_CMU->DACCLK = ((dac_clk_div - 1) << 4) | DEV_CMU_DACCLK_SEL_OSC_XTAL | DEV_CMU_DACCLK_EN_ENABLE; //使用外部时钟作为时钟源
#endif
    DEV_DAC->CFG0 = (30 << 8) | /*这里的阈值需要大于等于SRC或者DMA的单次输出*/
                    (hdac->init.inverse << 15) |
                    (hdac->init.src_sel << 4);
    DEV_DAC->CFG1 = (dac_l_mix) |
                    (dac_r_mix << 4) |
                    (hdac->init.vol << 16) |//DAC_VOL_L
                    (hdac->init.vol << 24);//DAC_VOL_R

    if (hdac->init.mix_source == MIX_SOURCE_DAC_MERGED)
    {
        DEV_DAC->CFG1 |=  DEV_DAC_CFG1_DACL_MIX_GAIN_1_2 | DEV_DAC_CFG1_DACL_MIX_GAIN_1_2 ;
    }
    else
    {
        DEV_DAC->CFG1 |=  DEV_DAC_CFG1_DACL_MIX_GAIN_1 | DEV_DAC_CFG1_DACR_MIX_GAIN_1 ;
    }

    DEV_DAC->CTL = 0;
    DEV_DAC->CFG2 = (mono_en << 4) |
                    (bit_slot << 12) |
                    (bit_format << 13);

    if ((hdac->init.src_sel == AHB) && (hdac->dma_handle != NULL))
    {
        DEV_DAC->CTL = DEV_DAC_CTL_DMA_EN_ENABLE | DEV_DAC_CTL_TX_EN_ENABLE;
    }
    else if (hdac->init.src_sel == SRC)
    {
        DEV_DAC->CTL  = DEV_DAC_CTL_TX_EN_ENABLE;
    }
    else
    {
        return HAL_ERROR;
    }

    if (((DEV_ADC->VMIC0_CTRL & DEV_ADC_VMIC0_CTRL_VMIC0_EN_ENABLE) == 0) || ((DEV_ADC->VMIC1_CTRL & DEV_ADC_VMIC1_CTRL_VMIC1_EN_ENABLE) == 0))
    {
        vmic_config(VOLT_2o71);
    }
    /*****************eco trim***************************************************/
    audio_offsets();

    /*****************eco trim***************************************************/
    DEV_DAC->DA_CTL  |= (DEV_DAC_DA_CTL_DAC0_EN_ENABLE | DEV_DAC_DA_CTL_DAC1_EN_ENABLE);/**/
    DEV_DAC->DA_CTL  |= DEV_DAC_DA_CTL_DAC_CHOP_EN_ENABLE;
    audio_dac_ibgm_set();/*IBGM*/




    //if (hdac->init.outfrom & LINE_OUT)
    {
        line_out_ramp_up_config(ENABLE);/*耳机不需要该配置*/
    }/*接耳机息屏，亮屏后初始化line不响*/
    delay_ms(360 * MHz, 2);
    if (hdac->init.outfrom & HEADPHONE)
    {
        DEV_DAC->HP_CTL0 |= (DEV_DAC_HP_CTL0_HSPA0_DAC0_EN_ENABLE) | //HSPA0 DAC0 ENABLE
                            (DEV_DAC_HP_CTL0_HSPA1_DAC1_EN_USEDAC);  //HSPA1 DAC1 ENABLE
        DEV_DAC->HP_CTL0_f.GMIC0_EN = 1;
        DEV_DAC->HP_CTL0_f.GMIC1_EN = 0;
        DEV_DAC->HP_CTL0_f.HPFBSW0_EN = 1;
        DEV_DAC->HP_CTL0_f.HPFBSW1_EN = 0;
        DEV_DAC->HP_CTL0 |= (DEV_DAC_HP_CTL0_HSCAL0_EN_ENABLE) |(DEV_DAC_HP_CTL0_HSCAL1_EN_ENABLE);
    }

    DEV_DAC->HP_CTL1 = 0x7f;/*防止上翹，過充*/
    DEV_DAC->CP_CTL  |= DEV_DAC_CP_CTL_CP_EN_ENABLE;//CHARGE PUMP ENABLE  -1.8
    audio_dac_set_eq_type(hdac, hdac->init.eq_type);
    return HAL_OK;
}

HAL_StatusTypeDef dac_deinit(audio_dac_handle_typedef *hdac)
{
    HAL_StatusTypeDef state;
    uint32_t volume_bak;
    state = HAL_OK;
    volume_bak = DEV_DAC->CFG1_f.DAC_VOL_L;
    DEV_RMU->RSTEN0 &= ~DEV_RMU_RSTEN0_DAC;
    delay_us(360 * MHz, 100);
    DEV_CMU->CLKEN0 &= ~DEV_CMU_CLKEN0_DAC;
    DEV_DAC->CFG1_f.DAC_VOL_L = volume_bak;
    DEV_DAC->CFG1_f.DAC_VOL_R = volume_bak;
    return state;
}

/**
* @brief        获取采样率对应的时钟分频值
* @details      通过audio采样率值，计算得出dac时钟合适的分频系数:Fout = dac_clk/clk_div/256
* @param[in]    sample：dac_sample_rate_typedef 枚举成员之一
* @return       HAL_StatusTypeDef 枚举成员之一
* @note         none
*/
HAL_StatusTypeDef get_dac_clk_div(dac_sample_rate_typedef sample, uint32_t *addr)
{
    HAL_StatusTypeDef state;
    state = HAL_OK;

    switch (sample)
    {
    case DAC_SAMPLE_RATE_8K:
        *addr = 12;
        break;

    case DAC_SAMPLE_RATE_16K:
        *addr = 6;
        break;

    case DAC_SAMPLE_RATE_24K:
        *addr = 4;
        break;

    case DAC_SAMPLE_RATE_32K:
        *addr = 3;
        break;

    case DAC_SAMPLE_RATE_48K:
        *addr = 2;
        break;

    case DAC_SAMPLE_RATE_96K:
        *addr = 1;
        break;

    default:
        state = HAL_ERROR;
        break;
    }

    return state;
}


/**
* @brief        根据drv层的配置，转化为HAL层的mix寄存器接口
* @details      none
* @param[in]    *hdac： dac_sample_rate_typedef 枚举成员之一
* @param[in]    dac_r_mix,dac_l_mix:dac mix临时变量
* @return       HAL_StatusTypeDef 枚举成员之一
* @note         none
*/
HAL_StatusTypeDef audio_dac_mix_get(audio_dac_handle_typedef *hdac, uint32_t *dac_r_mix, uint32_t *dac_l_mix)
{
    HAL_StatusTypeDef state = HAL_OK;

    if (hdac->init.mix_source == MIX_SOURCE_DAC_DETACHED) /*DAC数据,左右声道分开*/
    {
        *dac_r_mix = 0x02;
        *dac_l_mix = 0x01;
    }
    else if (hdac->init.mix_source == MIX_SOURCE_DAC_MERGED) /*DAC数据,左右声道合并到一起*/
    {
        *dac_r_mix = 0x03;
        *dac_l_mix = 0x03;
    }
    else
    {
#if 1
//模拟数据
        *dac_r_mix = 0x00;
        *dac_l_mix = 0x00;
        DEV_DAC->HP_CTL0 &= ~(0x000003fc);
        DEV_DAC->HP_CTL0 |= (0x00000120);
#endif

#if 0
        *dac_r_mix = (1<<2);
        *dac_l_mix = (1<<3);
#endif
    }

    return state;
}
/**
* @brief        audio功能使能或者失能
* @details      none
* @param[in]    *hdac： dac_sample_rate_typedef 枚举成员之一
* @param[in]    cmd：   Options_EnableEnum 枚举成员之一
* @return       HAL_StatusTypeDef 枚举成员之一
* @note         none
*/
HAL_StatusTypeDef audio_dac_cmd(audio_dac_handle_typedef *hdac, Options_EnableEnum cmd)
{
    if (hdac == NULL)
    {
        return HAL_ERROR;
    }

    if (cmd == ENABLE)
    {
        if (hdac->init.outfrom & LINE_OUT)
        {
            DEV_DAC->LO_CTL0 |= (DEV_DAC_LO_CTL0_LO0_EN_ENABLE | DEV_DAC_LO_CTL0_LO1_EN_ENABLE);
        }

        if (hdac->init.outfrom & HEADPHONE)
        {
            DEV_DAC->HP_CTL0 |= (DEV_DAC_HP_CTL0_HSPA0_EN_ENABLE | DEV_DAC_HP_CTL0_HSPA1_EN_ENABLE);
        }

        hdac->state = WORK;
    }
    else
    {
        if (hdac->init.outfrom & LINE_OUT)
        {
            DEV_DAC->LO_CTL0 &= ~(DEV_DAC_LO_CTL0_LO0_EN_ENABLE | DEV_DAC_LO_CTL0_LO1_EN_ENABLE);
        }

        if (hdac->init.outfrom & HEADPHONE)
        {
            DEV_DAC->HP_CTL0 &= ~(DEV_DAC_HP_CTL0_HSPA0_EN_ENABLE | DEV_DAC_HP_CTL0_HSPA1_EN_ENABLE);
        }

        if (hdac->init.outfrom == NONE_OUT)
        {
            DEV_DAC->LO_CTL0 &= ~(DEV_DAC_LO_CTL0_LO0_EN_ENABLE | DEV_DAC_LO_CTL0_LO1_EN_ENABLE);
            DEV_DAC->HP_CTL0 &= ~(DEV_DAC_HP_CTL0_HSPA0_EN_ENABLE | DEV_DAC_HP_CTL0_HSPA1_EN_ENABLE);
            DEV_DAC->DA_CTL  &= ~(DEV_DAC_DA_CTL_DAC0_EN_ENABLE | DEV_DAC_DA_CTL_DAC1_EN_ENABLE);
        }

        hdac->state = IDLE;
    }

    return HAL_OK;
}




void disable_dac(void)
{
    DEV_DAC->LO_CTL0 &= ~(DEV_DAC_LO_CTL0_LO0_EN_ENABLE | DEV_DAC_LO_CTL0_LO1_EN_ENABLE);
    DEV_DAC->HP_CTL0 &= ~(DEV_DAC_HP_CTL0_HSPA0_EN_ENABLE | DEV_DAC_HP_CTL0_HSPA1_EN_ENABLE);
    DEV_DAC->DA_CTL  &= ~(DEV_DAC_DA_CTL_DAC0_EN_ENABLE | DEV_DAC_DA_CTL_DAC1_EN_ENABLE);
}


void audio_dac_option_cmd(dac_channels_typedef channel,uint32_t option)//目前只支持耳机
{
  if(option)//开
  {
	if(channel == DAC_HPL)
	{
		DEV_DAC->DA_CTL  |= DEV_DAC_DA_CTL_DAC0_EN_ENABLE;
		//DEV_DAC->HP_CTL0 |= DEV_DAC_HP_CTL0_HSPA0_EN_ENABLE;
	}
	else if(channel == DAC_HPR)
	{
		DEV_DAC->DA_CTL  |= DEV_DAC_DA_CTL_DAC1_EN_ENABLE;
		//DEV_DAC->HP_CTL0 |= DEV_DAC_HP_CTL0_HSPA1_EN_ENABLE;
	}
	else if(channel == DAC_ALL)
	{
		DEV_DAC->DA_CTL  |= DEV_DAC_DA_CTL_DAC0_EN_ENABLE|DEV_DAC_DA_CTL_DAC1_EN_ENABLE;
		//DEV_DAC->HP_CTL0 |= (DEV_DAC_HP_CTL0_HSPA0_EN_ENABLE | DEV_DAC_HP_CTL0_HSPA1_EN_ENABLE);
	}
  }
  else//关
  {
	if(channel == DAC_HPL)
	{
		//DEV_DAC->HP_CTL0 &= ~DEV_DAC_HP_CTL0_HSPA0_EN_ENABLE;
		DEV_DAC->DA_CTL  &= ~DEV_DAC_DA_CTL_DAC0_EN_ENABLE;
	}
	else if(channel == DAC_HPR)
	{
		//DEV_DAC->HP_CTL0 &= ~DEV_DAC_HP_CTL0_HSPA1_EN_ENABLE;
		DEV_DAC->DA_CTL  &= ~DEV_DAC_DA_CTL_DAC1_EN_ENABLE;
	}
	else if(channel == DAC_ALL)
	{
		//DEV_DAC->HP_CTL0 &= ~(DEV_DAC_HP_CTL0_HSPA0_EN_ENABLE | DEV_DAC_HP_CTL0_HSPA1_EN_ENABLE);
		DEV_DAC->DA_CTL  &= ~(DEV_DAC_DA_CTL_DAC0_EN_ENABLE|DEV_DAC_DA_CTL_DAC1_EN_ENABLE);
	}
  }
}

/**
* @brief        audio dac设置音量大小
* @details      将芯片寄存器描述音量转化为0-VOL_NUM音量
* @param[in]    *hdac： dac_sample_rate_typedef 枚举成员之一
* @param[in]    uint32_t volume：   0-VOL_NUM
* @return       HAL_StatusTypeDef 枚举成员之一
* @note         none
*/
HAL_StatusTypeDef audio_dac_set_volume(audio_dac_handle_typedef *hdac, uint32_t volume)
{
    if (hdac == NULL)
    {
        return HAL_ERROR;
    }

    if (volume > VOL_NUM)
    {
        volume = VOL_NUM;
    }

    DEV_DAC->CFG1_f.DAC_VOL_L = volume;
    DEV_DAC->CFG1_f.DAC_VOL_R = volume;
    hdac->init.vol = volume;
    return HAL_OK;
}

void dac_set_volume(uint32_t volume)
{
    DEV_DAC->CFG1_f.DAC_VOL_L = volume;
    DEV_DAC->CFG1_f.DAC_VOL_R = volume;
}

void dac_set_hpl_volume(uint32_t volume)
{
	DEV_DAC->CFG1_f.DAC_VOL_L = volume;
}

void dac_set_hpr_volume(uint32_t volume)
{
	DEV_DAC->CFG1_f.DAC_VOL_R = volume;
}
/**
* @brief        audio dac读取音量大小
* @details      none
* @param[in]    *hdac： dac_sample_rate_typedef 枚举成员之一
* @param[in]    uint32_t* addr   存储返回音量值的地址
* @return       HAL_StatusTypeDef 枚举成员之一
* @note         none
*/
HAL_StatusTypeDef audio_dac_get_volume(audio_dac_handle_typedef *hdac, uint32_t *addr)
{
    if (hdac == NULL)
    {
        return HAL_ERROR;
    }

    *addr = DEV_DAC->CFG1_f.DAC_VOL_L;
    //*addr = DEV_DAC->CFG1_f.DAC_VOL_R;
    return HAL_OK;
}

/**
* @brief        audio dac设置采样率
* @details      none
* @param[in]    *hdac： dac_sample_rate_typedef 枚举成员之一
* @param[in]    dac_sample_rate_typedef   枚举成员之一
* @return       HAL_StatusTypeDef 枚举成员之一
* @note         none
*/
HAL_StatusTypeDef audio_dac_set_samplerate(audio_dac_handle_typedef *hdac, dac_sample_rate_typedef samplerate)
{
    uint32_t dac_clk_div, status = HAL_OK;

    if (hdac == NULL)
    {
        return HAL_ERROR;
    }

    status = get_dac_clk_div(samplerate, &dac_clk_div);

    if (status != HAL_OK)
    {
        return HAL_ERROR;
    }

#ifdef DAC_USE_AUDIO_PLL
    DEV_CMU->DACCLK = ((dac_clk_div * 2 - 1) << 4) | DEV_CMU_DACCLK_SEL_PLL_AUDIO | DEV_CMU_DACCLK_EN_ENABLE; //使用AUDIO PLL时钟作为时钟源
#else
    DEV_CMU->DACCLK = ((dac_clk_div - 1) << 4) | DEV_CMU_DACCLK_SEL_OSC_XTAL | DEV_CMU_DACCLK_EN_ENABLE; //使用外部时钟作为时钟源
#endif
    hdac->init.sample_rate = samplerate;
    return status;
}

/**
* @brief        audio dac获取采样率
* @details      none
* @param[in]    *hdac： dac_sample_rate_typedef 枚举成员之一
* @param[in]    uint32_t* addr   存储采样率的地址
* @return       HAL_StatusTypeDef 枚举成员之一
* @note         none
*/
HAL_StatusTypeDef audio_dac_get_samplerate(audio_dac_handle_typedef *hdac, uint32_t *addr)
{
    uint32_t status = HAL_OK;

    if (hdac == NULL)
    {
        return HAL_ERROR;
    }

    *addr = hdac->init.sample_rate;
    return status;
}

/**
* @brief        audio dac设置通道数
* @details      none
* @param[in]    *hdac： dac_sample_rate_typedef 枚举成员之一
* @param[in]    uint32_t channels     1:单通道  2：立体声
* @return       HAL_StatusTypeDef 枚举成员之一
* @note         none
*/
HAL_StatusTypeDef audio_dac_set_channels(audio_dac_handle_typedef *hdac, uint32_t channels)
{
    uint32_t status = HAL_OK;

    if (hdac == NULL)
    {
        return HAL_ERROR;
    }

    if (channels == DAC_MONO)
    {
        DEV_DAC->CFG2_f.MONO_EN = 1;
    }
    else if (channels == DAC_STEREO)
    {
        DEV_DAC->CFG2_f.MONO_EN = 0;
    }

    hdac->init.track = channels;
    return status;
}

/**
* @brief        audio dac获取通道数
* @details      none
* @param[in]    *hdac： dac_sample_rate_typedef 枚举成员之一
* @param[in]    uint32_t* addr   存储通道数的地址
* @return       HAL_StatusTypeDef 枚举成员之一
* @note         none
*/
HAL_StatusTypeDef audio_dac_get_channels(audio_dac_handle_typedef *hdac, uint32_t *addr)
{
    uint32_t status = HAL_OK;

    if (hdac == NULL)
    {
        return HAL_ERROR;
    }

    *addr = hdac->init.track;
    return status;
}

/**
* @brief        audio dac设置bit数和有效数据在bit数的高低位
* @details      none
* @param[in]    *hdac： dac_sample_rate_typedef 枚举成员之一
* @param[in]    samplebits:  dac_data_format_typedef 枚举成员之一
* @return       HAL_StatusTypeDef 枚举成员之一
* @note         none
*/
HAL_StatusTypeDef audio_dac_set_samplebits(audio_dac_handle_typedef *hdac, dac_data_format_typedef samplebits)
{
    uint32_t bit_slot, bit_format, status = HAL_OK;

    if (hdac == NULL)
    {
        return HAL_ERROR;
    }

    if (samplebits == width_16bit_useful_16bit)
    {
        bit_slot = 1;
    }
    else
    {
        bit_slot = 0;
    }

    if ((samplebits == width_32bit_useful_low_16bit) || (samplebits == width_32bit_useful_low_24bit) || (samplebits == width_16bit_useful_16bit))
    {
        bit_format = 0;
    }
    else
    {
        bit_format = 1;
    }

    DEV_DAC->CFG2_f.DAC_FMT_USEHI = bit_format;
    DEV_DAC->CFG2_f.DAC_FMT_16BIT = bit_slot;
    hdac->init.data_format = samplebits;
    return status;
}

/**
* @brief        audio dac读取bit数和有效数据在bit数的高低位
* @details      none
* @param[in]    *hdac： dac_sample_rate_typedef 枚举成员之一
* @param[in]    uint32_t* addr   存储通道数的地址
* @return       HAL_StatusTypeDef 枚举成员之一
* @note         none
*/
HAL_StatusTypeDef audio_dac_get_samplebits(audio_dac_handle_typedef *hdac, dac_data_format_typedef *addr)
{
    uint32_t status = HAL_OK;

    if (hdac == NULL)
    {
        return HAL_ERROR;
    }

    *addr = hdac->init.data_format;
    return status;
}

/**
* @brief        audio dac设置输出方式，line_out,head_phone
* @details      none
* @param[in]    *hdac： dac_sample_rate_typedef 枚举成员之一
* @param[in]    outfrom:  dac_outfrom_typedef 枚举成员之一
* @return       HAL_StatusTypeDef 枚举成员之一
* @note         none
*/
HAL_StatusTypeDef audio_dac_set_outform(audio_dac_handle_typedef *hdac, dac_outfrom_typedef outfrom)
{
    uint32_t status = HAL_OK;

    if (hdac == NULL)
    {
        return HAL_ERROR;
    }

    if ((outfrom & LINE_OUT_HEADPHONE) == 0)
    {
        return HAL_ERROR;
    }

    if (outfrom == LINE_OUT)
    {
        dac_headphone_cmd(DISABLE);
        dac_line_out_cmd(ENABLE);
    }
    else if (outfrom == HEADPHONE)
    {
        dac_line_out_cmd(DISABLE);
        dac_headphone_cmd(ENABLE);
    }
    else if (outfrom == LINE_OUT_HEADPHONE)
    {
        dac_line_out_cmd(ENABLE);
        dac_headphone_cmd(ENABLE);
    }

    hdac->init.outfrom = outfrom;
    return status;
}

/**
* @brief        使能或者失能dac的line_out输出功能
* @details      none
* @param[in]    使能：ENABLE  失能：DISABLE
* @return       none
* @note         none
*/
void dac_line_out_cmd(uint32_t enable)
{
    if (enable == ENABLE)
    {
        DEV_DAC->LO_CTL0 |= DEV_DAC_LO_CTL0_LO0_DIFF_EN_ENABLE |
                            DEV_DAC_LO_CTL0_LO1_DIFF_EN_ENABLE |
                            DEV_DAC_LO_CTL0_LO0_DAC0_EN_USEDAC |
                            DEV_DAC_LO_CTL0_LO1_DAC1_EN_USEDAC |
                            DEV_DAC_LO_CTL0_LO_CHOP_EN_ENABLE;
    }
    else
    {
        DEV_DAC->LO_CTL0 &= ~(DEV_DAC_LO_CTL0_LO0_DIFF_EN_ENABLE |
                              DEV_DAC_LO_CTL0_LO1_DIFF_EN_ENABLE |
                              DEV_DAC_LO_CTL0_LO0_DAC0_EN_USEDAC |
                              DEV_DAC_LO_CTL0_LO1_DAC1_EN_USEDAC |
                              DEV_DAC_LO_CTL0_LO_CHOP_EN_ENABLE);
    }
}

/**
* @brief        使能或者失能dac的headphone输出功能
* @details      none
* @param[in]    使能：ENABLE  失能：DISABLE
* @return       none
* @note         none
*/
void dac_headphone_cmd(uint32_t enable)
{
    if (enable == ENABLE)
    {
        DEV_DAC->HP_CTL0 |= (DEV_DAC_HP_CTL0_HSPA0_DAC0_EN_ENABLE) | //HSPA0 DAC0 ENABLE
                            (DEV_DAC_HP_CTL0_HSPA1_DAC1_EN_USEDAC);  //HSPA1 DAC1 ENABLE
        DEV_DAC->HP_CTL0 |= (DEV_DAC_HP_CTL0_HSCAL0_EN_ENABLE) |
                            (DEV_DAC_HP_CTL0_HSCAL1_EN_ENABLE);
        DEV_DAC->HP_CTL0 |= (DEV_DAC_HP_CTL0_HSPA0_EN_ENABLE | DEV_DAC_HP_CTL0_HSPA1_EN_ENABLE);
    }
    else
    {
        DEV_DAC->HP_CTL0 &= ~(DEV_DAC_HP_CTL0_HSPA0_DAC0_EN_ENABLE |
                              DEV_DAC_HP_CTL0_HSPA1_DAC1_EN_USEDAC |
                              DEV_DAC_HP_CTL0_HSCAL0_EN_ENABLE |
                              DEV_DAC_HP_CTL0_HSCAL1_EN_ENABLE |
                              DEV_DAC_HP_CTL0_HSPA0_EN_ENABLE |
                              DEV_DAC_HP_CTL0_HSPA1_EN_ENABLE);
    }
}

/**
* @brief        audio dac读取输出方式，line_out,head_phone
* @details      none
* @param[in]    *hdac： dac_sample_rate_typedef 枚举成员之一
* @param[in]    *addr: 存储dac_outfrom_typedef 枚举成员之一
* @return       HAL_StatusTypeDef 枚举成员之一
* @note         none
*/
HAL_StatusTypeDef audio_dac_get_outform(audio_dac_handle_typedef *hdac, dac_outfrom_typedef *addr)
{
    uint32_t status = HAL_OK;

    if (hdac == NULL)
    {
        return HAL_ERROR;
    }

    *addr = hdac->init.outfrom;
    return status;
}

/**
* @brief        HSPA_IBGM 设置
* @details      none
* @param[in]    none
* @return       none
* @note         none
*/
void audio_dac_ibgm_set(void)
{
    //uint32_t reg = DEV_DAC->HP_CTL0;/*20231221*/
    uint32_t reg = 0;
    reg &= ~(DEV_DAC_HP_CTL0_HSPA_IBIAS_CTL_MASK | DEV_DAC_HP_CTL0_HSPA_IBGM1_CTL_MASK);
    reg |= DEV_DAC_HP_CTL0_HSPA_IBIAS_CTL_15U | DEV_DAC_HP_CTL0_HSPA_IBGM1_CTL_5U;
    DEV_DAC->HP_CTL0 = reg;
}
/**
* @brief        设置DAC MIX源
* @details      设置DAC mix源，从而决定DAC输出DAC数据或者MIC数据
* @param[in]    MIX的数据源，在枚举变量#dac_mix_sorce_def中选择
* @return       none
* @note         none
*/
HAL_StatusTypeDef audio_dac_set_mix_source(audio_dac_handle_typedef *hdac, dac_mix_sorce_def mix_source)
{
    uint32_t temp_reg;
    temp_reg = DEV_DAC->CFG1;

    if (mix_source == MIX_SOURCE_DAC_DETACHED) /*DAC数据多个声道分开*/
    {
        temp_reg &= ~0xFFF;
        temp_reg |= 0x00000021;/*MIX DAC*/
        DEV_DAC->CFG1 = temp_reg;
        DEV_DAC->HP_CTL0 &= ~(0x000003fc);
        DEV_DAC->HP_CTL0 |= (0x0000084);
    }
    else if (mix_source == MIX_SOURCE_DAC_MERGED) /*DAC数据多个声道合并*/
    {
        temp_reg &= ~0xFFF;
        temp_reg |= 0x00000533;/*MIX DAC*/
        DEV_DAC->CFG1 = temp_reg;
        DEV_DAC->HP_CTL0 &= ~(0x000003fc);
        DEV_DAC->HP_CTL0 |= (0x0000084);
    }
    else if(mix_source == MIX_SOURCE_ADC_emulated)
    {
        temp_reg &= ~0xFFF;
        temp_reg |= 0x00000000;/*MIX ADC*/
        DEV_DAC->HP_CTL0 &= ~(0x000003fc);
        DEV_DAC->HP_CTL0 |= (0x00000120);
        DEV_DAC->CFG1 = temp_reg;
    }
    else if(mix_source == MIX_SOURCE_ADC_digital)
    {
        temp_reg &= ~0xFFF;
        temp_reg |= ((0x04<<4)+(0x04<<0));/*MIX ADC*/
        DEV_DAC->HP_CTL0 &= ~(0x000003fc);
        DEV_DAC->HP_CTL0 |= (0x0000084);
        DEV_DAC->CFG1 = temp_reg;
    }
    return HAL_OK;
}

/**
* @brief        audio dac设置数据源
* @details      AHB:需要通过DMA给RAM中的数据给dac播报，SRC:芯片内部通过硬件连接到dac，只需要给SRC给数据，并配置正确的采样率倍率
* @param[in]    *hdac： dac_sample_rate_typedef 枚举成员之一
* @param[in]    source:  src_sel_type_def 枚举成员之一
* @return       HAL_StatusTypeDef 枚举成员之一
* @note         none
*/
HAL_StatusTypeDef audio_dac_set_data_source(audio_dac_handle_typedef *hdac, src_sel_type_def source)
{
    uint32_t status = HAL_OK;

    if (hdac == NULL)
    {
        return HAL_ERROR;
    }

    DEV_DAC->CFG0_f.SRC_SEL = source;

    if ((source == AHB) && (hdac->dma_handle != NULL))
    {
        DEV_DAC->CTL |= (DEV_DAC_CTL_DMA_EN_ENABLE | DEV_DAC_CTL_TX_EN_ENABLE);
    }
    else if (source == SRC)
    {
        DEV_DAC->CTL &= ~DEV_DAC_CTL_DMA_EN_ENABLE;
        DEV_DAC->CTL  = DEV_DAC_CTL_TX_EN_ENABLE;
    }
    else
    {
        return HAL_ERROR;
    }

    hdac->init.src_sel = source;
    return status;
}

// HAL_StatusTypeDef audio_dac_set_data_source(audio_dac_handle_typedef *hdac, src_sel_type_def source)
// {
//     uint32_t status = HAL_OK;

//     if (hdac == NULL)
//     {
//         return HAL_ERROR;
//     }

//     DEV_DAC->CFG0_f.SRC_SEL = source;

//     if ((source == AHB) && (hdac->dma_handle != NULL))
//     {
//         DEV_DAC->CTL  &= ~DEV_DAC_CTL_TX_EN_ENABLE;
//         DEV_DAC->CTL  |= (DEV_DAC_CTL_DMA_EN_ENABLE | DEV_DAC_CTL_TX_EN_ENABLE);
//     }
//     else if (source == SRC)
//     {
//         DEV_DAC->CTL  &= ~(DEV_DAC_CTL_DMA_EN_ENABLE | DEV_DAC_CTL_TX_EN_ENABLE);
//         DEV_DAC->CTL  |= DEV_DAC_CTL_TX_EN_ENABLE;
//     }
//     else
//     {
//         return HAL_ERROR;
//     }

//     hdac->init.src_sel = source;
//     return status;
// }
/**
* @brief        audio dac获取数据源
* @details      AHB:需要通过DMA给RAM中的数据给dac播报，SRC:芯片内部通过硬件连接到dac，只需要给SRC给数据，并配置正确的采样率倍率
* @param[in]    *hdac： dac_sample_rate_typedef 枚举成员之一
* @param[in]    addr:  src_sel_type_def 枚举成员之一
* @return       HAL_StatusTypeDef 枚举成员之一
* @note         none
*/
HAL_StatusTypeDef audio_dac_get_data_source(audio_dac_handle_typedef *hdac, src_sel_type_def *addr)
{
    uint32_t status = HAL_OK;

    if (hdac == NULL)
    {
        return HAL_ERROR;
    }

    *addr = hdac->init.src_sel;
    return status;
}

/**
* @brief        设置GMIC0通路
* @details      GMIC接GND或者浮空
* @param[in]    0:浮空   1：接GND
* @param[in]    none
* @return       none
* @note         none
*/
void gmic0_ctrl(uint32_t option)
{
    if (option == DISABLE)
    {
        DEV_DAC->HP_CTL0_f.GMIC0_EN = 0;
    }
    else
    {
        DEV_DAC->HP_CTL0_f.GMIC0_EN = 1;
    }
}

/**
* @brief        设置GMIC1通路
* @details      GMIC接GND或者浮空
* @param[in]    0:浮空   1：接GND
* @param[in]    none
* @return       none
* @note         none
*/
void gmic1_ctrl(uint32_t option)
{
    if (option == DISABLE)
    {
        DEV_DAC->HP_CTL0_f.GMIC1_EN = 0;
    }
    else
    {
        DEV_DAC->HP_CTL0_f.GMIC1_EN = 1;
    }
}

/**
* @brief        设置HPFB通路
* @details      HPFB接GMIC0
* @param[in]    0:浮空   1：接GMIC
* @param[in]    none
* @return       none
* @note         none
*/
void hpfbsw0_ctrl(uint32_t option)
{
    if (option == DISABLE)
    {
        DEV_DAC->HP_CTL0_f.HPFBSW0_EN = 0;
    }
    else
    {
        DEV_DAC->HP_CTL0_f.HPFBSW0_EN = 1;
    }
}

/**
* @brief        设置HPFB通路
* @details      HPFB接GMIC1
* @param[in]    0:浮空   1：接GMIC
* @param[in]    none
* @return       none
* @note         none
*/
void hpfbsw1_ctrl(uint32_t option)
{
    if (option == DISABLE)
    {
        DEV_DAC->HP_CTL0_f.HPFBSW1_EN = 0;
    }
    else
    {
        DEV_DAC->HP_CTL0_f.HPFBSW1_EN = 1;
    }
}
/**
* @brief        设置HPR接GND
* @details      设置HPR接GND
* @param[in]    0:不接GND   1：接GND
* @param[in]    none
* @return       none
* @note         none
*/
void hpr_to_gnd(uint32_t option)
{
    if (option == DISABLE)
    {
        DEV_DAC->HP_CTL0_f.GMIC1_S78_EN = 0;
    }
    else
    {
        DEV_DAC->HP_CTL0_f.GMIC1_S78_EN = 1;
    }
}
/**
* @brief        设置HPL接GND
* @details      设置HPL接GND
* @param[in]    0:不接GND   1：接GND
* @param[in]    none
* @return       none
* @note         none
*/
void hpl_to_gnd(uint32_t option)
{
    if (option == DISABLE)
    {
        DEV_DAC->HP_CTL0_f.GMIC0_S78_EN = 0;
    }
    else
    {
        DEV_DAC->HP_CTL0_f.GMIC0_S78_EN = 1;
    }
}

void line_out_ramp_up_config(Options_EnableEnum  option)
{
    DEV_DAC->LO_CTL0 &= ~DEV_DAC_LO_CTL0_LO_VCMSTUP_CTL_MASK | DEV_DAC_LO_CTL0_LO_FASTSTUP_MASK;
    DEV_DAC->LO_CTL0 |= (2 & 0x3) << 14;
    DEV_DAC->LO_CTL1 &= ~DEV_DAC_LO_CTL1_RAMP_TIME_MASK;
    DEV_DAC->LO_CTL1 |= (4999 << 16);//ramp_up_down_time_interval
    DEV_DAC->LO_CTL2 = 1 | (400 << 16); //ramp_up_high_num,ramp_up_total_num
    delay_us(360 * MHz, 10);

    if (option == ENABLE)
    {
        DEV_DAC->LO_CTL1 |= (DEV_DAC_LO_CTL1_LO0_RAMP_UP_EN_ENABLE + DEV_DAC_LO_CTL1_LO1_RAMP_UP_EN_ENABLE);
    }
    else
    {
        DEV_DAC->LO_CTL1 &= ~(DEV_DAC_LO_CTL1_LO0_RAMP_UP_EN_ENABLE + DEV_DAC_LO_CTL1_LO1_RAMP_UP_EN_ENABLE);
    }
}

void line_out_ramp_down_config(Options_EnableEnum  option)
{
    if (option == ENABLE)
    {
        DEV_DAC->LO_CTL1 |= DEV_DAC_LO_CTL1_LO0_RAMP_DN_EN_ENABLE;
        DEV_DAC->LO_CTL1 |= DEV_DAC_LO_CTL1_LO1_RAMP_DN_EN_ENABLE;
    }
}

/**
* @brief        HP开启后会有一个直流台阶，导致开启的瞬间有一个啪啪声，通过ft校准校准消除这个偏置
* @details
* @param[in]    none  x(v)/1.8*2^23
* @return       none
* @note         none
*/
void audio_offsets(void)
{
	#define CPID_SPV6040B_A 		0x49004180
	#define CPID_SPV6040B_B 		0x49014180
	int32_t value;
	if(*(volatile uint32_t *)(DEV_CHIP_BASE) == CPID_SPV6040B_B)//B版本SPV6040B
	{
		cmu_efuse_set_clk();
		cmu_aon_set_clk();
		pmu_power_normal_on_config(PMU_POWER_NORMAL_ON_VDDQ, 1);


		value = hal_efuse_read(SECTOR1, EFUSE2);
		if((value & 0xff) != 0x01)
		{
			value = hal_efuse_read(SECTOR1, EFUSE4);
		}
		value = value >> 8;
		*(uint32_t *)(0x20130000 + 0xf80) = value; /*left offset reg addr*/


		value = hal_efuse_read(SECTOR1, EFUSE3);
		if((value & 0xff) != 0x01)
		{
			value = hal_efuse_read(SECTOR1, EFUSE5);
		}
		value = value >> 8;
		*(uint32_t *)(0x20130000 + 0x1020) = value; /*right offset reg addr*/

		value = hal_efuse_read(SECTOR0, EFUSE0);
	}
	else
	{
		;
	}



}

void vmic_config(vmic_vol_type_def vmic_voltage)//dac ramp up function should enable vmic.
{
    vmic_config_struct vmic_config;
    vmic_config.bypass_enable = DISABLE;
    vmic_config.ramp_down_enbale = DISABLE;
    vmic_config.ramp_up_enbale = ENABLE;
    vmic_config.ramp_up_down_time_interval = 4999;
    vmic_config.ramp_up_high_num = 20;
    vmic_config.ramp_up_total_num = 244;
    vmic_config.vmic_ref_sel = VCM;
    vmic_config.mic_fast_charge_cap_enable = ENABLE;
    vmic_config.voltage = VOLT_2o59;
    pmu_control_vmic(VMIC0, ENABLE, vmic_config);
    pmu_control_vmic(VMIC1, ENABLE, vmic_config);
}

//斜率0   阈值-20dB
//DRC_LMTH = (uint32_t)(pow(10,(-20./20.0))*pow(2,30));
//DRC_SLOP = (uint32_t)(0.*pow(2,30));
//斜率0.2 阈值-10DB

// DRC LMTH = (uint32 t)(pow(10,(-10.0/20.0))*pow(2,30));
// DRC SLOP = (uint32 t)(0.0*pow(2,30))
// DRC PEAK AT = (uint32 t)((1-exp(-2.2*(1/48000.0)/0.001))*pow(2,30));
// DRC PEAK RT = (uint32 t)((1-exp(-2.2*(1/48000.8)/0.3))*pow(2,30));
// DRC GAIN AT = (uint32 t)((1-exp(-2.2*(1/48000.0)/0.001))*pow(2,30));
// DRC GAIN RT = (uint32 t)((1-exp(-2.2*(1/48000.)/0.3))*pow(2,30));
// DAC CTL = DRC ENABLE;
// DEV_DAC->DRC_LMTH = (uint32_t)(pow(10,(-5.0/20.0))*pow(2,30));//
// DEV_DAC->DRC_SLOP = (uint32_t)(0.1*pow(2,30));//斜率0.1
// DEV_DAC->DRC_PEAK_AT = (uint32_t)((1-exp(-2.2*(1/48000.0)/0.0001))*pow(2,30));
// DEV_DAC->DRC_PEAK_RT = (uint32_t)((1-exp(-2.2*(1/48000.0)/0.3))*pow(2,30));
// DEV_DAC->DRC_GAIN_AT = (uint32_t)((1-exp(-2.2*(1/48000.0)/0.0001))*pow(2,30));
// DEV_DAC->DRC_GAIN_RT = (uint32_t)((1-exp(-2.2*(1/48000.0)/0.3))*pow(2,30));
//dac_drc_config_typedef_def
//uint32_t drc_enable;
//uint32_t drc_lmth;
//uint32_t drc_slop;
//uint32_t drc_peak_at;
//uint32_t drc_peak_rt;
//uint32_t drc_gain_at;
//uint32_t drc_gain_rt;

HAL_StatusTypeDef audio_dac_drc_config(audio_dac_handle_typedef *hdac, dac_drc_config_typedef_def *ptr)
{
    if (ptr->drc_enable)
    {
        DEV_DAC->DRC_LMTH = ptr->drc_lmth;
        DEV_DAC->DRC_SLOP = ptr->drc_slop;
        DEV_DAC->DRC_PEAK_AT = ptr->drc_peak_at;
        DEV_DAC->DRC_PEAK_RT = ptr->drc_peak_rt;
        DEV_DAC->DRC_GAIN_AT = ptr->drc_gain_at;
        DEV_DAC->DRC_GAIN_RT = ptr->drc_gain_rt;
        DEV_DAC->CTL  |= DEV_DAC_CTL_DRC_EN_ENABLE;
    }
    else
    {
        DEV_DAC->CTL  &= ~DEV_DAC_CTL_DRC_EN_ENABLE;
    }

    return HAL_OK;
}


HAL_StatusTypeDef audio_dac_EQ_channel_cmd(dac_ch_typedef chn, Options_EnableEnum cmd)
{
    uint32_t status = HAL_OK;

    if (cmd)
    {
        DEV_DAC->CFG0 |= ((1 << (24 + chn)) | (1 << (16 + chn)));
    }
    else
    {
        DEV_DAC->CFG0 &= ~((1 << (24 + chn)) | (1 << (16 + chn)));
    }

    return status;
}

HAL_StatusTypeDef audio_dac_EQ_cmd(Options_EnableEnum cmd)
{
    if (cmd)
    {
        DEV_DAC->CTL  |= DEV_DAC_CTL_EQ_EN_ENABLE;
    }
    else
    {
        DEV_DAC->CTL  &= ~DEV_DAC_CTL_EQ_EN_ENABLE;
    }

    return HAL_OK;
}


HAL_StatusTypeDef audio_dac_EQ_config(dac_ch_typedef chn, audio_adc_EQ_typedef param)
{
    uint32_t status = HAL_OK;
    DEV_DAC->CHNL_IIR[chn].B0 = param.b0;
    DEV_DAC->CHNL_IIR[chn].B1 = param.b1;
    DEV_DAC->CHNL_IIR[chn].B2 = param.b2;
    DEV_DAC->CHNL_IIR[chn].A1 = param.a1;
    DEV_DAC->CHNL_IIR[chn].A2 = param.a2;

    DEV_DAC->CHNR_IIR[chn].B0 = param.b0;
    DEV_DAC->CHNR_IIR[chn].B1 = param.b1;
    DEV_DAC->CHNR_IIR[chn].B2 = param.b2;
    DEV_DAC->CHNR_IIR[chn].A1 = param.a1;
    DEV_DAC->CHNR_IIR[chn].A2 = param.a2;
    audio_dac_EQ_channel_cmd(chn, ENABLE);
    return status;
}


void audio_EQ_init(void)
{
    /*默认使用*/
    audio_adc_EQ_typedef param;

    for (uint32_t i = 0; i < 8; i++)
    {
        param.b0 = EQ_param_normal[i][0];
        param.b1 = EQ_param_normal[i][1];
        param.b2 = EQ_param_normal[i][2];
        param.a1 = EQ_param_normal[i][3];
        param.a2 = EQ_param_normal[i][4];
        audio_dac_EQ_config(i, param);
    }

    audio_dac_EQ_cmd(ENABLE);
}

HAL_StatusTypeDef audio_dac_set_eq_param(audio_dac_handle_typedef *hdac, uint32_t *ptr)
{
    audio_adc_EQ_typedef param;

    for (uint32_t i = 0; i < 8; i++)
    {
        param.b0 = (uint32_t)ptr[i * 5 + 0];
        param.b1 = (uint32_t)ptr[i * 5 + 1];
        param.b2 = (uint32_t)ptr[i * 5 + 2];
        param.a1 = (uint32_t)ptr[i * 5 + 3];
        param.a2 = (uint32_t)ptr[i * 5 + 4];
        audio_dac_EQ_config(i, param);
    }

    audio_dac_EQ_cmd(ENABLE);
}

HAL_StatusTypeDef audio_dac_set_eq_type(audio_dac_handle_typedef *hdac, eq_param_class_type eqtype)
{
    uint32_t status = HAL_OK;
    audio_adc_EQ_typedef param;

    if (hdac == NULL)
    {
        return HAL_ERROR;
    }

    if (eqtype < 0 || eqtype >= EQ_TYPE_MAX)
    {
        hal_log_err("eq type invaild!");
        return HAL_ERROR;
    }

    audio_dac_EQ_cmd(DISABLE);

    switch (eqtype)
    {
    case EQ_NORMAL_TYPE:
        for (uint32_t i = 0; i < 8; i++)
        {
            audio_dac_EQ_channel_cmd(i, DISABLE);
        }

        audio_dac_EQ_cmd(DISABLE);
        break;

    case EQ_POP_TYPE:
        for (uint32_t i = 0; i < 8; i++)
        {
            param.b0 = EQ_param_pop[i][0];
            param.b1 = EQ_param_pop[i][1];
            param.b2 = EQ_param_pop[i][2];
            param.a1 = EQ_param_pop[i][3];
            param.a2 = EQ_param_pop[i][4];
            audio_dac_EQ_config(i, param);
        }

        audio_dac_EQ_cmd(ENABLE);
        break;

    case EQ_ROCK_TYPE:
        for (uint32_t i = 0; i < 8; i++)
        {
            param.b0 = EQ_param_rock[i][0];
            param.b1 = EQ_param_rock[i][1];
            param.b2 = EQ_param_rock[i][2];
            param.a1 = EQ_param_rock[i][3];
            param.a2 = EQ_param_rock[i][4];
            audio_dac_EQ_config(i, param);
        }

        audio_dac_EQ_cmd(ENABLE);
        break;

    case EQ_JAZZ_TYPE:
        for (uint32_t i = 0; i < 8; i++)
        {
            param.b0 = EQ_param_jazz[i][0];
            param.b1 = EQ_param_jazz[i][1];
            param.b2 = EQ_param_jazz[i][2];
            param.a1 = EQ_param_jazz[i][3];
            param.a2 = EQ_param_jazz[i][4];
            audio_dac_EQ_config(i, param);
        }

        audio_dac_EQ_cmd(ENABLE);
        break;

    case EQ_CLASSICAL_TYPE:
        for (uint32_t i = 0; i < 8; i++)
        {
            param.b0 = EQ_param_classical[i][0];
            param.b1 = EQ_param_classical[i][1];
            param.b2 = EQ_param_classical[i][2];
            param.a1 = EQ_param_classical[i][3];
            param.a2 = EQ_param_classical[i][4];
            audio_dac_EQ_config(i, param);
        }

        audio_dac_EQ_cmd(ENABLE);
        break;

    case EQ_COUNTRY_TYPE:
        for (uint32_t i = 0; i < 8; i++)
        {
            param.b0 = EQ_param_country[i][0];
            param.b1 = EQ_param_country[i][1];
            param.b2 = EQ_param_country[i][2];
            param.a1 = EQ_param_country[i][3];
            param.a2 = EQ_param_country[i][4];
            audio_dac_EQ_config(i, param);
        }

        audio_dac_EQ_cmd(ENABLE);
        break;

    case EQ_SELT_TPYE:
        for (uint32_t i = 0; i < 8; i++)
        {
            param.b0 = EQ_param_country[i][0];
            param.b1 = EQ_param_country[i][1];
            param.b2 = EQ_param_country[i][2];
            param.a1 = EQ_param_country[i][3];
            param.a2 = EQ_param_country[i][4];
            audio_dac_EQ_config(i, param);
        }

        audio_dac_EQ_cmd(ENABLE);
        break;

    default:
        break;
    }

    return status;
}
