#include "include.h"
#include "bsp_dac.h"

#if DAC_EN
const u8  *dac_avol_table;
const u16 *dac_dvol_table;

AT(.rodata.bsp.dac.table)
const u8 dac_vol_tbl_16[16 + 1] = {
    //取值范围：(54-54) ~ (54+5),共60个值;
    //说明：值(54-54)对应音量-54dB; 54对应音量0dB;
    54-54, 54-43, 54-32, 54-26, 54-22, 54-18, 54-15, 54-12,
    54-10, 54-8,  54-6,  54-4,  54-3,  54-2,  54-1,  54,  54+1
};

AT(.com_rodata.vol)
const u8 dac_vol_tbl_16_diff[16 + 1] = {
    //取值范围：(54-54) ~ (54+5),共60个值;
    //说明：值(54-54)对应音量-54dB; 54对应音量0dB;
    54-54, 54-34, 54-30, 54-26, 54-22, 54-18, 54-15, 54-12,
    54-10, 54-8,  54-6,  54-5,  54-4,  54-3,  54-2,  54-1,  54
};

AT(.text.bsp.dac.table)
const u16 dac_dvol_tbl_16[16 + 1] = {
    DIG_N60DB,  DIG_N43DB,  DIG_N32DB,  DIG_N26DB,  DIG_N24DB,  DIG_N22DB,  DIG_N20DB,  DIG_N18DB, DIG_N16DB,
    DIG_N14DB,  DIG_N12DB,  DIG_N10DB,  DIG_N8DB,   DIG_N6DB,   DIG_N4DB,   DIG_N2DB,   DIG_N0DB,
};

AT(.com_text.dac_volume)
void bsp_change_volume(u8 vol)
{
#if !SYS_ADJ_DIGVOL_EN
    ///sys adjust dac analog volume
    u8 anl_vol = 0;
    if (vol <= VOL_MAX) {
        if (vol > 0) {
            anl_vol = dac_avol_table[vol] + sys_cb.anl_gain_offset;
        }
        dac_set_volume(anl_vol);
    }
#else
    ///sys adjust dac digital volume
    u16 dig_vol = 0;
    if (vol <= VOL_MAX) {
        dig_vol = dac_dvol_table[vol];
        dac_set_dvol(dig_vol);
    }
#endif
}

AT(.text.bsp.dac)
bool bsp_set_volume(u8 vol)
{
    bsp_change_volume(vol);
    if (vol <= VOL_MAX) {
        sys_cb.vol = vol;
        param_sys_vol_write();
        sys_cb.cm_times = 0;
        sys_cb.cm_vol_change = 1;
    }
    printf("vol: %d\n", sys_cb.vol);
    return true;
}

void loudspeaker_mute_init(void)
{
    //io初始化例子，实际把X替换具体的B或E或其他，NUM替换为具体的端口号
//    GPIOXFEN &= ~BIT(NUM);
//    GPIOXDE  |=  BIT(NUM);
//    GPIOXDIR &= ~BIT(NUM);
}

void loudspeaker_mute(void)
{
//    GPIOXSET |= BIT(NUM);    //拉高io
}

void loudspeaker_unmute(void)
{
//    GPIOXCLR |= BIT(NUM);    //拉低io
}

//开机控制DAC电容放电等待时间
AT(.text.dac)
void dac_pull_down_delay(void)
{
    delay_5ms(DAC_PULL_DOWN_DELAY);
}

AT(.text.bsp.dac)
u8 bsp_volume_inc(u8 vol)
{
    vol++;
    if(vol > VOL_MAX)
        vol = VOL_MAX;
    return vol;
}

AT(.text.bsp.dac)
u8 bsp_volume_dec(u8 vol)
{
    if(vol > 0)
        vol--;
    return vol;
}

AT(.text.bsp.dac)
void dac_set_anl_offset(u8 bt_call_flag)
{
    sys_cb.anl_gain_offset = 54 - 9 + DAC_MAX_GAIN - dac_avol_table[VOL_MAX];
}

AT(.text.bsp.dac)
void dac_set_vol_table(u8 vol_max)
{
    if (vol_max == 16) {
        dac_avol_table = dac_vol_tbl_16;
        dac_dvol_table = dac_dvol_tbl_16;
    }
    dac_set_anl_offset(0);
}

u8 dac_get_max_anl_vol(void)
{
    return sys_cb.anl_gain_offset + dac_avol_table[VOL_MAX];
}

u8 dacr_is_output(void)
{
    return DACR_OUTPUT_EN;
}

AT(.text.bsp.dac)
void dac_init(void)
{
    CLKGAT1 |= (BIT(23)|BIT(12));
    CLKGAT0 |= (BIT(16)| BIT(12));
    dac_set_vol_table(VOL_MAX);
    dac_anl_fade_sta_set(SYS_ADJ_DIGVOL_EN);
    printf("[%s] vol_max:%d, offset: %d\n", __func__, VOL_MAX, sys_cb.anl_gain_offset);
    dac_obuf_init();
    dac_power_on();
#if (DAC_OUT_SPR == DAC_OUT_48K)
    DACDIGCON0 |= BIT(1);           //dac out sample 48K
#endif
    dac_digital_enable();

#if SYS_ADJ_DIGVOL_EN
    dac_set_volume(sys_cb.anl_gain_offset + dac_avol_table[VOL_MAX]);
#endif
}
#endif

