Files
99_7018_lmx/cpu/br28/smart_voice/vad_clock_trim.c
2025-10-29 13:10:02 +08:00

214 lines
6.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*****************************************************************
>file name : vco_clock_trim.c
>author : IC lishanliao
>create time : Mon 22 Nov 2021 02:44:34 PM CST
>Decription : 通过vco时钟的trim使vco clock接近29MHz
这样adc采样对应电压更准确
*****************************************************************/
#include "vad_mic.h"
#include "voice_mic_data.h"
static u8 vco_clock_calibrated = 0;
#define VAD_EN_10V_1_(x) SFR(P11_LPVAD->VAD_ACON0, 29, 1, x)
#define VAD_ACM_10V_4_(x) SFR(P11_LPVAD->VAD_ACON0, 0, 4, x)
#define VAD_LDO_IS_10V_2_(x) SFR(P11_LPVAD->VAD_ACON1, 0, 2, x)
#define VAD_LDO_VS_10V_3_(x) SFR(P11_LPVAD->VAD_ACON1, 2, 3, x)
#define VAD_BUF_EN_10V_1_(x) SFR(P11_LPVAD->VAD_ACON0, 17, 1, x)
#define VAD_BUF_IS_10V_2_(x) SFR(P11_LPVAD->VAD_ACON0, 18, 2, x)
#define VAD_PGA_EN_10V_1_(x) SFR(P11_LPVAD->VAD_ACON1, 22, 1, x)
#define VAD_PGA_IS_10V_2_(x) SFR(P11_LPVAD->VAD_ACON1, 27, 2, x)
#define VAD_PGA_GS_10V_4_(x) SFR(P11_LPVAD->VAD_ACON1, 23, 4, x)
#define VAD_BUF2INN_EN_10V_1_(x) SFR(P11_LPVAD->VAD_ACON0, 16, 1, x)
#define VAD_ADC_EN_10V_1_(x) SFR(P11_LPVAD->VAD_ACON0, 4, 1, x)
#define VAD_ADC_RIN_10V_3_(x) SFR(P11_LPVAD->VAD_ACON0, 9, 3, x)
#define VAD_ADC_RBS_10V_3_(x) SFR(P11_LPVAD->VAD_ACON0, 6, 3, x)
#define VAD_ADC_TEN_10V_1_(x) SFR(P11_LPVAD->VAD_ACON0, 12, 1, x)
#define VAD_VCON_TOE_10V_1_(x) SFR(P11_LPVAD->VAD_CON , 27, 1, x)
#define VAD_VCOP_TOE_10V_1_(x) SFR(P11_LPVAD->VAD_CON , 28, 1, x)
#define VAD_IREF1U_TOE_10V_1_(x) SFR(P11_LPVAD->VAD_ACON1, 30, 1, x)
void vco_clock_test_mode_setup(void)
{
P11_LPVAD->VAD_ACON0 = 0;
P11_LPVAD->VAD_ACON1 = 0;
P11_LPVAD->VAD_CON = 0;
SFR(JL_ADDA->ADDA_CON1, 1, 1, 1);//enable vad analog to ANA pad
VAD_EN_10V_1_(1) ;
VAD_ACM_10V_4_(7) ;
VAD_LDO_VS_10V_3_(3) ;
VAD_LDO_IS_10V_2_(2) ;
VAD_BUF_EN_10V_1_(1) ;
VAD_BUF_IS_10V_2_(2) ;
VAD_PGA_EN_10V_1_(1) ;
VAD_PGA_IS_10V_2_(2) ;
VAD_PGA_GS_10V_4_(4) ;
VAD_BUF2INN_EN_10V_1_(1);
VAD_ADC_EN_10V_1_(1) ;
VAD_ADC_RIN_10V_3_(5) ;
VAD_ADC_RBS_10V_3_(5) ;
VAD_VCON_TOE_10V_1_(1) ;
VAD_VCOP_TOE_10V_1_(1) ;
VAD_IREF1U_TOE_10V_1_(1);
}
/*
void vco_clk2io_test(void)
{
//vad_vcon0->PA6
//vad_vcop0->PA7
SFR(JL_CLOCK->CLK_CON0, 24, 4, 15); //clk_out2_sel sel vad_vcon0
SFR(JL_CLOCK->CLK_CON0, 28, 4, 15); //clk_out2_sel sel vad_vcop0
SFR(JL_IOMC->OCH_CON0, 0, 5, 16); //
SFR(JL_IOMC->OCH_CON0, 5, 9, 17);
JL_OMAP->PA6_OUT = (0 << 0) | //input enable
(1 << 1) | //output enable
(0 << 2); //output signal select
JL_OMAP->PA7_OUT = (0 << 0) | //input enable
(1 << 1) | //output enable
(1 << 2); //output signal select
JL_PORTA->DIR &= ~BIT(6);
JL_PORTA->DIR &= ~BIT(7);
printf("============== start VCO_CLK_IO test =================");
}
*/
void delay1us(u16 i)
{
int num = clk_get("sys") / 1000000 * i;
while (num--) {
asm("nop");
}
}
#define GPC_FD_MUX_3_(x) SFR(JL_CLOCK->CLK_CON2,28,4,x)
//osc clk mux 0:btosc24m 1:btosc48m 2:std24m
// 3:rtc_osc 4:lrc_clk 5:pat_clk
#define OSC_CLK_MUX_3_(x) SFR(JL_CLOCK->CLK_CON0,1,3,x)
//0:lsb_clk 1:osc_clk 2:cap_mux_clk 3:clk_mux
//4:gpc_fd(9:vad_vcon 10:vad_vcop) 5:ring_clk
//6:pll_d1p0_mo 7:irflt_in
#define GPCNT_CSS_3_(x) SFR(JL_GPCNT->CON,1,3,x)//count source select
#define GPCNT_GSS_3_(x) SFR(JL_GPCNT->CON,12,3,x)//gate source select
#define GPCNT_GTS_4_(x) SFR(JL_GPCNT->CON,8,4,x)//gate time select 32*2^n
#define GPCNT_EN_1_(x) SFR(JL_GPCNT->CON,0,1,x)
#define CLR_PND_1_(x) SFR(JL_GPCNT->CON,6,1,x)
u32 get_gpcnt(u8 sel_p_n, u8 gs_clk, u8 cs_clk, u8 prd)
{
u32 gpcnt_n = 0;
/*printf("start get cnt\r\n");*/
GPCNT_EN_1_(0);
if (sel_p_n == 0) {
GPC_FD_MUX_3_(9);//9:vad_vcon 10:vad_vcop
} else {
GPC_FD_MUX_3_(10);//9:vad_vcon 10:vad_vcop
}
OSC_CLK_MUX_3_(gs_clk);
GPCNT_CSS_3_(cs_clk);
GPCNT_GSS_3_(1);
GPCNT_GTS_4_(prd);//32*2^n
GPCNT_EN_1_(1);
CLR_PND_1_(1);
delay1us(1000);
asm("csync");
asm("csync");
asm("csync");
while (!(JL_GPCNT->CON >> 7 & 0x01));
asm("csync");
asm("csync");
asm("csync");
gpcnt_n = JL_GPCNT->NUM;
return gpcnt_n;
}
#define FCNT_N 10
u32 get_avr_gpcnt(void)
{
u32 f_cnt = 0, i = 0, fc_num = 0, f_max = 0, f_min = 1000000;
// delay_1000ms();
for (i = 0; i < FCNT_N; i++) {
//osc clk mux 0:btosc24m 1:btosc48m 2:std24m
// 3:rtc_osc 4:lrc_clk 5:pat_clk
// 32*2^(7)=4096
f_cnt = get_gpcnt(1, 2, 4, 7); //32*2^n
//f_cnt = get_gpcnt(1,0,4,7); //32*2^n
//printf("===========get vco clk cnt=%d \r\r\n\n",f_cnt);
fc_num = f_cnt + fc_num;
if (f_max < f_cnt) {
f_max = f_cnt;
}
if (f_min > f_cnt) {
f_min = f_cnt;
}
wdt_clear();
}
//printf("===========get vco f_min clk cnt=%d \r\r\n\n",f_min);
//printf("===========get vco f_max clk cnt=%d \r\r\n\n",f_max);
f_cnt = (fc_num - f_max - f_min) / (FCNT_N - 2);
return f_cnt;
}
#define VCO_TRIM_CNT 8
#define VCO_TRIM_TAR 4949 // 24/32.99= 32*2^7/VCO_TRIM_TAR
void vad_vco_clk_trim(void)
{
u32 gp_cnt[VCO_TRIM_CNT], gp_min, gp_ind;
u8 i;
os_time_dly(80); //500ms delay
for (i = 0; i < VCO_TRIM_CNT; i++) {
VAD_ADC_RIN_10V_3_(i) ;
VAD_ADC_RBS_10V_3_(i) ;
gp_cnt[i] = get_avr_gpcnt();
printf("get vco clk average cnt[%d]=%d\n", i, gp_cnt[i]);
}
for (i = 0; i < VCO_TRIM_CNT; i++) {
if (gp_cnt[i] > VCO_TRIM_TAR) {
gp_cnt[i] = gp_cnt[i] - VCO_TRIM_TAR;
} else {
gp_cnt[i] = VCO_TRIM_TAR - gp_cnt[i];
}
if (i == 0) {
gp_min = gp_cnt[i];
gp_ind = i;
} else if (gp_min > gp_cnt[i]) {
gp_min = gp_cnt[i];
gp_ind = i;
}
wdt_clear();
}
printf("set vco clk index=%d,res=%d\n", gp_ind, gp_min);
/*VAD_ADC_RIN_10V_3_(gp_ind) ;*/
/*VAD_ADC_RBS_10V_3_(gp_ind) ;*/
struct vad_mic_platform_data *data = (struct vad_mic_platform_data *)(VAD_AVAD_CONFIG_BEGIN + sizeof(struct avad_config));
data->mic_data.adc_rin = gp_ind;
data->mic_data.adc_rbs = gp_ind;
}
void audio_vad_clock_trim(void)
{
if (vco_clock_calibrated) {
return;
}
vco_clock_test_mode_setup();
/*vco_clk2io_test();*/
vad_vco_clk_trim();
vco_clock_calibrated = 1;
}