/**************************************************************************** * * Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED. * * This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT * be copied by any method or incorporated into another program without * the express written consent of Aerospace C.Power. This Information or any portion * thereof remains the property of Aerospace C.Power. The Information contained herein * is believed to be accurate and Aerospace C.Power assumes no responsibility or * liability for its use in any way and conveys no license or title under * any patent or copyright and makes no representation or warranty that this * Information is free from patent or copyright infringement. * * ****************************************************************************/ /* os shim includes */ #include "os_types.h" #include "os_task.h" #include "os_utils.h" #include "os_task_api.h" /* common includes */ #include "iot_io.h" #include "iot_module.h" #include "apb_glb_reg.h" #include "ahb_rf.h" #include "phy_ana_glb.h" #include "phy_dfe_reg.h" #include "phy_rxtd_reg.h" #include "phy_reg.h" #include "phy_bb.h" #include "hw_reg_api.h" #include "granite_reg.h" #include "sadc_reg.h" #include "sadc.h" #include "mac_sys_reg.h" #include "sadc_t.h" #include "phy_ana.h" void granite_reg_init() { uint8_t reg_id = 0; uint8_t rodata = 0; uint32_t rdata = 0; uint32_t wdata = 0; uint32_t wmask = 0; /*init granite top reg */ reg_id = ANA_GRANITE_TOP_REG; wdata = TOP_EN_SADC_MASK; wmask = TOP_EN_SADC_MASK | TOP_ATB2PAD_EN_MASK | TOP_EN_ADC_MASK | TOP_EN_RX_MASK; phy_ana_i2c_write(reg_id, wdata, wmask); /* init granite sadc reg */ reg_id = ANA_GRANITE_SADC_REG; phy_ana_i2c_read(reg_id, &rdata, &rodata); REG_FIELD_SET(SADC_EN_CAL, rdata, 0); REG_FIELD_SET(SADC_EN, rdata, 1); //sadc_en = 1 REG_FIELD_SET(SADC_SEL_SCL_MUX, rdata, 0); //SADC_SEL_SCL_MUX = 0 REG_FIELD_SET(SADC_METER2PAD_EN_OVR, rdata, 0); //set 0000 REG_FIELD_SET(SADC_F_H, rdata, 4); //set 100 REG_FIELD_SET(SADC_CFG_DLY, rdata, 4); //set 100 REG_FIELD_SET(SADC_SAMPLE_SEL, rdata, 0); //set 0 REG_FIELD_SET(SADC_TIMER_DLY, rdata, 14); //sadc_timer_dly[3:0] = 1110 phy_ana_i2c_write(reg_id, rdata, ~0); /* init granite bias reg 2*/ reg_id = ANA_GRANITE_BIAS_REG_2; phy_ana_i2c_read(reg_id, &rdata, &rodata); REG_FIELD_SET(BIAS_EN_ICAL, rdata, 0); //en_ical=1 REG_FIELD_SET(BIAS_SEL_IC_TEST, rdata, 0); //sel_ic_test[7:0] = 0000_0000 // REG_FIELD_SET(BIAS_CAL, rdata, 16); //cal[4:0] = 1_0000 REG_FIELD_SET(BIAS_TRIM_ADCREF, rdata, 3); REG_FIELD_SET(BIAS_TRIM_DCDC, rdata, 3); REG_FIELD_SET(BIAS_TEST_VBG, rdata, 0); //BIAS_TEST_VBG phy_ana_i2c_write(reg_id, rdata, ~0); /* init granite ADC reg */ reg_id = ANA_GRANITE_ADC_REG; phy_ana_i2c_read(reg_id, &rdata, &rodata); REG_FIELD_SET(ADC_ATB_SEL, rdata, 0); phy_ana_i2c_write(reg_id, rdata, ~0); } void sadc_reg_init(uint8_t gain, uint8_t sel_pad) { sadc_start_en(ANA_SADC0, 0); sadc_sum_data_clr(1); sadc_data_num_set(ANA_SADC0, 0, 64); sadc_phase_mode_set(ANA_SADC0, 0); //1 phase mode sadc_phase_sel(ANA_SADC0, 0); sadc_phase_sel_scl_mux(0, sel_pad); //set sel_com_inp_cmd[3:0] = 011x for dc test, 1xxx for ref_voltg test sadc_adc_gain_set(sel_pad & 0x07, gain); //(channel, gain) } int32_t sadc_arvg_get(void) { uint8_t cnt = 0; int32_t dc_sum = 0; int32_t dc_acc = 0; #ifdef SADC_TIME_CAL uint32_t start_time = 0; uint32_t end_time = 0; uint32_t time_span = 0; start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); //0.04us #endif sadc_start_en(ANA_SADC0, 1); cnt = 0; /* bypass the first 64 point data*/ while (!sadc_check_sum_vld()) ; cnt++; sadc_sum_data_clr(1); while (cnt < 17) { while (!sadc_check_sum_vld()) ; cnt++; dc_sum = sadc_sum_data_get(); // iot_printf("the sum of 64 sadc point is %d\n", dc_sum); if (dc_sum > 32767) //dc_sum is negative { dc_acc += (dc_sum - 65536); } else { dc_acc += dc_sum; } sadc_sum_data_clr(1); } #ifdef SADC_TIME_CAL end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); if(end_time < start_time) { time_span = 0xFFFFFFFF - (start_time - end_time) +1; } else { time_span = end_time - start_time; } iot_printf("\nthe delay of 1024 sadc point is %d us\n", time_span/25); #endif sadc_start_en(ANA_SADC0, 0); #ifdef SADC_DEBUG iot_printf("the sum of 1024 sadc point is %d\n", dc_acc); #endif return dc_acc; //(dc_acc >> 10); } int32_t sadc_dc_calibration_task(int32_t *dc_calib) { uint8_t reg_id = 0; uint8_t rodata = 0; uint32_t rdata = 0; int32_t dc_threhold = 50*1024; //25*1024; int32_t dc_calib_tmp = 0; //gain4:011001/0x19 gain2:001001/0x9 gain1/2:001011/0xB gain1/5:001111/0xF uint8_t gain[4] = {11, 15, 25, 9}; //gain1/2 1/5 4 2 int32_t fail_cnt = 0; granite_reg_init(); /* set granite sadc reg */ reg_id = ANA_GRANITE_SADC_REG; phy_ana_i2c_read(reg_id, &rdata, &rodata); REG_FIELD_SET(SADC_METER2PAD_EN_OVR, rdata, 8); //set 1000 REG_FIELD_SET(SADC_EN_CAL, rdata, 1); phy_ana_i2c_write(reg_id, rdata, ~0); for (uint8_t i = 0; i < 4; i++) { sadc_reg_init(gain[i], 10); dc_calib[i] = sadc_arvg_get(); if ((dc_calib_tmp > dc_threhold) || (dc_calib_tmp < -dc_threhold)) { fail_cnt++; } } #ifdef SADC_DEBUG iot_printf("The dc code of gain 1/2 is %d, gain 1/5 is %d, gain 4 is %d, , gain 2 is %d\n", dc_calib[0], dc_calib[1], dc_calib[2], dc_calib[3]); return 0; #endif #ifdef SADC_TEMPERATURE iot_printf("%d, %d, %d, %d, ", dc_calib[0], dc_calib[1], dc_calib[2], dc_calib[3]); return 0; #else if(fail_cnt) { iot_printf("DC threhold is %d, %d calibrations don't meet the dc_threhold!\n", dc_threhold, fail_cnt); return -1; } else { return 0; } #endif } int32_t sadc_ref_voltg_task(int32_t* sadc_arvg, int32_t* input_dc, int32_t* input_voltg) { /*gain4:011001 gain1/2:001011 gain1/4:001111*/ uint8_t gain[4] = {11, 15, 25, 9}; int32_t sadc_max = 511*1024; int32_t ref_voltg[4] = {0, 0, 0, 0}; int32_t dc_calib[4] = {0, 0, 0, 0}; int32_t sadc_code_check = 0; int32_t ref_voltg_error = 0; granite_reg_init(); for(uint8_t i=0; i < 4; i++) { dc_calib[i] = input_dc[i]; } for (uint8_t i = 0; i < 4; i++) { if (i < 2) { sadc_reg_init(gain[i], 8); //SADC5, which is 1.2V } else { sadc_reg_init(gain[i], 12); //SADC4, which is 0.15V } sadc_arvg[i] = sadc_arvg_get(); } ref_voltg[0] = (sadc_max * input_voltg[0]) / (sadc_arvg[0] - dc_calib[0]) *5; //1.2v gain1/2 *10/2 ref_voltg[1] = (sadc_max * input_voltg[0]) / (sadc_arvg[1] - dc_calib[1]) *2; //1.2v gain1/5 *10/5 ref_voltg[2] = (sadc_max * input_voltg[1])*10 / (sadc_arvg[2] - dc_calib[2]) *4; //0.15v gain4 *10*4 ref_voltg[3] = (sadc_max * input_voltg[1])*10 / (sadc_arvg[3] - dc_calib[3]) *2; //0.15v gain2 *10*2 //check the ref voltage at gain 1/2 sadc_reg_init(11, 12); //for SADC4, input voltage is 148 mv sadc_code_check = sadc_arvg_get(); ref_voltg_error = sadc_max * input_voltg[1] / (sadc_code_check - dc_calib[0]) *5 - ref_voltg[0]; #ifdef SADC_DEBUG iot_printf("DC code at gain_1/2 is %d gain_1/5 is %d gain_4 is %d gain_2 is %d, vref0 is %dmv vref1 is %dmv \n", dc_calib[0], dc_calib[1], dc_calib[2], dc_calib[3], input_voltg[0], input_voltg[1]); iot_printf("Ref_code at gain 1/2 is %d , gain 1/5 is %d , gain 4 is %d, gain 2 is %d\n", sadc_arvg[0], sadc_arvg[1], sadc_arvg[2], sadc_arvg[3]); iot_printf("Ref_voltg at gain 1/2 is %d mv, gain 1/5 is %d mv, gain 4 is %d mv, gain 2 is %d mv\n", ref_voltg[0], ref_voltg[1], ref_voltg[2], ref_voltg[3]); int32_t code_error = 0; code_error = sadc_code_check - sadc_max * input_voltg[1] / 2 / ref_voltg[0]; iot_printf("For gain 1/2, Ref code is %d, ref voltage error is %d mv, sadc error is %d\n", sadc_code_check, ref_voltg_error, code_error/1024); return 0; #endif #ifdef SADC_TEMPERATURE iot_printf("%d, %d, %d, %d, %d, ", ref_voltg[0], ref_voltg[1], ref_voltg[2], ref_voltg[3], ref_voltg_error); return 0; #else int32_t ref_voltg_thr = 200; //the reference voltage is limited to 20:2mv, 200:20mv iot_printf("Ref_voltg at gain 1/2 is %d mv, gain 1/5 is %d mv, gain 4 is %d mv, gain 2 is %d mv\n", ref_voltg[0], ref_voltg[1], ref_voltg[2], ref_voltg[3]); if(ref_voltg_error - ref_voltg_thr >0 || ref_voltg_error + ref_voltg_thr <0) { iot_printf("At gain 1/2, sadc code is %d, ref voltage error is %d mv, error voltage thr is %d mv\n", sadc_code_check, ref_voltg_error, ref_voltg_thr); return -1; } else { return 0; } #endif } int8_t atb_for_ical(uint8_t *bias_cal, int32_t dc_calib, int32_t ref_voltg, int32_t ref_sadc) { uint8_t reg_id = 0; uint8_t rodata = 0; uint32_t rdata = 0; uint32_t wdata = 0; uint32_t wmask = 0; int32_t sadc_arvg = 0; int32_t target_voltg = 1500; //1500mv(15kohm * 100uA) int32_t diff_voltg = 20; //target_voltg*0.015 int32_t cal_voltg = 0; uint8_t step = 8; uint8_t bias_tmp = 16; granite_reg_init(); /* initialize the soc sadc reg */ sadc_reg_init(15, 10); /* en granite sadc top reg */ reg_id = ANA_GRANITE_TOP_REG; //atb2pad_en=1 en atb2pad wdata = TOP_ATB2PAD_EN_MASK; wmask = TOP_ATB2PAD_EN_MASK; phy_ana_i2c_write(reg_id, wdata, wmask); /* en granite sadc bias reg 2*/ reg_id = ANA_GRANITE_BIAS_REG_2; phy_ana_i2c_read(reg_id, &rdata, &rodata); REG_FIELD_SET(BIAS_EN_ICAL, rdata, 1); //en_ical=1 REG_FIELD_SET(BIAS_SEL_IC_TEST, rdata, 64); //sel_ic_test[7:0] = 0100_0000 REG_FIELD_SET(BIAS_CAL, rdata, bias_tmp); //cal[4:0] = 1_0000 phy_ana_i2c_write(reg_id, rdata, ~0); while (step) { sadc_arvg = sadc_arvg_get(); cal_voltg = (sadc_arvg - dc_calib) * ref_voltg / (ref_sadc - dc_calib); if (cal_voltg > target_voltg + diff_voltg) { bias_tmp -= step; } else if (cal_voltg < target_voltg - diff_voltg) { bias_tmp += step; } else { break; } step = step >> 1; reg_id = ANA_GRANITE_BIAS_REG_2; phy_ana_i2c_read(reg_id, &rdata, &rodata); REG_FIELD_SET(BIAS_CAL, rdata, bias_tmp); phy_ana_i2c_write(reg_id, rdata, ~0); } *bias_cal = bias_tmp; #ifdef SADC_DEBUG iot_printf("For ical_100u test, the ref code is %d, dc code is %d, ical_100u code is %d, target voltage is %d mv, cal_voltage is %d mv\n", ref_sadc, dc_calib, bias_tmp, target_voltg, cal_voltg); return 0; #endif #ifdef SADC_TEMPERATURE iot_printf("%d, %d\n", bias_tmp, cal_voltg); return 0; #else iot_printf("For ical_100u test, the ical code is %d, ical voltg is %d mv\n", bias_tmp, cal_voltg); if (step == 0 && ((cal_voltg > target_voltg + diff_voltg) || (cal_voltg < target_voltg - diff_voltg))) { iot_printf("The ical_100u test failed, ref code is %d, dc code is %d, target voltage is %d mv, diff voltg thr is %d mv\n", ref_sadc, dc_calib, target_voltg, diff_voltg); return -1; } else { return 0; } #endif } int32_t atb_for_adcref(uint8_t *trim_adcref, int32_t dc_calib, int32_t ref_voltg, int32_t ref_sadc) { uint8_t reg_id = 0; uint8_t rodata = 0; uint32_t rdata = 0; uint32_t wdata = 0; uint32_t wmask = 0; int32_t sadc_arvg = 0; int32_t target_voltg[3] = {196, 534, 873}; //mv int32_t diff_voltg[3] = {9, 17, 14}; //0.015*target_voltg int32_t cal_voltg = 0; uint8_t trim_adcref_tmp = 7; uint8_t fail_cnt = 0; uint8_t atb_sel_set_value[3] = {1, 2, 3}; granite_reg_init(); /* en granite top reg */ reg_id = ANA_GRANITE_TOP_REG; //ANA_GRANITE_TOP=1 en atb2pad wdata = TOP_EN_ADC_MASK | TOP_ATB2PAD_EN_MASK; wmask = TOP_EN_ADC_MASK | TOP_ATB2PAD_EN_MASK; phy_ana_i2c_write(reg_id, wdata, wmask); /* en granite sadc reg */ reg_id = ANA_GRANITE_SADC_REG; phy_ana_i2c_read(reg_id, &rdata, &rodata); REG_FIELD_SET(SADC_SEL_SCL_MUX, rdata, 4); //sadc_sel_scl_mux[2:0] = 100 phy_ana_i2c_write(reg_id, rdata, ~0); /* initialize the soc sadc reg */ // sadc_reg_init(11, 10); // gain1/2 pad2 sadc_reg_init(11, 11); // gain1/2 pad3 is better /* set granite adc reg*/ reg_id = ANA_GRANITE_ADC_REG; phy_ana_i2c_read(reg_id, &rdata, &rodata); REG_FIELD_SET(ADC_ATB_SEL, rdata, atb_sel_set_value[2]); phy_ana_i2c_write(reg_id, rdata, ~0); while (trim_adcref_tmp) { /* set granite sadc bias reg 2*/ reg_id = ANA_GRANITE_BIAS_REG_2; phy_ana_i2c_read(reg_id, &rdata, &rodata); REG_FIELD_SET(BIAS_TRIM_ADCREF, rdata, trim_adcref_tmp); phy_ana_i2c_write(reg_id, rdata, ~0); sadc_arvg = sadc_arvg_get(); cal_voltg = (sadc_arvg - dc_calib) * ref_voltg / (ref_sadc - dc_calib); if ((cal_voltg < target_voltg[2] + diff_voltg[2]) && (cal_voltg > target_voltg[2] - diff_voltg[2])) //2% for 1 bit change of trim_dcdc { *trim_adcref = trim_adcref_tmp; break; //trim_adcref_tmp = 0; //jump out of while loop } else { trim_adcref_tmp--; } } #ifdef SADC_DEBUG iot_printf("For rx adc ref voltg test, the ref code is %d, dc code is %d, trim_adcref code is %d, target voltage is %d mv, cal_voltage is %d mv\n", ref_sadc, dc_calib, trim_adcref_tmp, target_voltg[2], cal_voltg); #else #ifdef SADC_TEMPERATURE iot_printf("%d, %d, ", trim_adcref_tmp, cal_voltg); #else iot_printf("For rx adc ref voltg test, the trim_adcref code is %d, vref_p voltage is %d mv\n", trim_adcref_tmp, cal_voltg); if (trim_adcref_tmp == 0 && ((cal_voltg > target_voltg[2] + diff_voltg[2]) || (cal_voltg < target_voltg[2] - diff_voltg[2]))) { iot_printf("Rx ADC ref-voltg test failed, vref_p target voltg is %d mv, diff threhold is %d mv\n", target_voltg[2], diff_voltg); return -1; } #endif #endif *trim_adcref = trim_adcref_tmp; for (uint8_t i = 0; i < 2; i++) { /* set granite adc reg*/ reg_id = ANA_GRANITE_ADC_REG; phy_ana_i2c_read(reg_id, &rdata, &rodata); REG_FIELD_SET(ADC_ATB_SEL, rdata, atb_sel_set_value[i]); phy_ana_i2c_write(reg_id, rdata, ~0); /* set granite sadc bias reg 2*/ reg_id = ANA_GRANITE_BIAS_REG_2; phy_ana_i2c_read(reg_id, &rdata, &rodata); REG_FIELD_SET(BIAS_TRIM_ADCREF, rdata, trim_adcref_tmp); phy_ana_i2c_write(reg_id, rdata, ~0); sadc_arvg = sadc_arvg_get(); cal_voltg = (sadc_arvg - dc_calib) * ref_voltg / (ref_sadc - dc_calib); #ifdef SADC_DEBUG iot_printf("For adcref[%d], target voltage is %d mv and cal_voltage is %d mv\n", i, target_voltg[i], cal_voltg); #else #ifdef SADC_TEMPERATURE iot_printf("%d, ", cal_voltg); #else iot_printf("For adcref[%d], target voltage is %d mv and cal_voltage is %d mv\n", i, target_voltg[i], cal_voltg); #endif #endif if ((cal_voltg > target_voltg[i] + diff_voltg[i]) || (cal_voltg < target_voltg[i] - diff_voltg[i])) { fail_cnt++; } } #ifndef SADC_TEMPERATURE if (fail_cnt) { iot_printf("ADC ref-voltg failed, %d failures in the adcref code of Vref-P matching V-CM or Vref-N\n", fail_cnt); return -1; } else { return 0; } #else return 0; #endif } int8_t dcdc_1p2v_test(uint8_t *trim_dcdc, int32_t dc_calib, int32_t ref_voltg, int32_t ref_sadc) { uint8_t reg_id = 0; uint8_t rodata = 0; uint32_t rdata = 0; int32_t sadc_arvg = 0; int32_t target_voltg = 1220; //1.22v int32_t diff_voltg = 18; //0.015 * target_voltg; int32_t cal_voltg = 0; uint8_t trim_dcdc_tmp = 7; granite_reg_init(); /* en granite sadc reg */ reg_id = ANA_GRANITE_SADC_REG; phy_ana_i2c_read(reg_id, &rdata, &rodata); REG_FIELD_SET(SADC_SEL_SCL_MUX, rdata, 5); //sadc_sel_scl_mux[2:0] = 101 phy_ana_i2c_write(reg_id, rdata, ~0); /* initialize the soc sadc reg */ sadc_reg_init(11, 11); //sadc_gain[5:0] = 00_1011 gain1/2 while (trim_dcdc_tmp) { /* en granite sadc bias reg 2*/ reg_id = ANA_GRANITE_BIAS_REG_2; phy_ana_i2c_read(reg_id, &rdata, &rodata); REG_FIELD_SET(BIAS_TRIM_DCDC, rdata, trim_dcdc_tmp); phy_ana_i2c_write(reg_id, rdata, ~0); sadc_arvg = sadc_arvg_get(); cal_voltg = (sadc_arvg - dc_calib) * ref_voltg / (ref_sadc - dc_calib); if ((cal_voltg < target_voltg + diff_voltg) && (cal_voltg > target_voltg - diff_voltg)) { break; } else { trim_dcdc_tmp--; } } *trim_dcdc = trim_dcdc_tmp; #ifdef SADC_DEBUG iot_printf("For DCDC test, ref code is %d, dc code is %d, trim_dcdc is %d, target_voltage is %d mv, cal_voltage is %d mv\n", ref_sadc, dc_calib, trim_dcdc_tmp, target_voltg, cal_voltg); return 0; #endif #ifdef SADC_TEMPERATURE iot_printf("%d, %d, ", trim_dcdc_tmp, cal_voltg); return 0; #else iot_printf("For DCDC test, trim_dcdc code is %d, cal_voltage is %d mv\n", trim_dcdc_tmp, cal_voltg); if (trim_dcdc_tmp == 0 && ((cal_voltg > target_voltg + diff_voltg) || (cal_voltg < target_voltg - diff_voltg))) { iot_printf("DCDC test failed, ref code is %d, dc code is %d, target voltage is %d mv, diff voltg thr is %d mv\n", ref_sadc, dc_calib, target_voltg, diff_voltg); return -1; } else { return 0; } #endif } int32_t at_vbg_test(int32_t dc_calib, int32_t ref_voltg, int32_t ref_sadc) { uint8_t reg_id = 0; uint8_t rodata = 0; uint32_t rdata = 0; int32_t sadc_arvg = 0; int32_t cal_voltg = 0; granite_reg_init(); /* en granite sadc reg */ reg_id = ANA_GRANITE_SADC_REG; phy_ana_i2c_read(reg_id, &rdata, &rodata); REG_FIELD_SET(SADC_SEL_SCL_MUX, rdata, 7); //sadc_sel_scl_mux[2:0] = 111 phy_ana_i2c_write(reg_id, rdata, ~0); /* initialize the soc sadc reg */ sadc_reg_init(11, 11); //sadc_gain[5:0] = 00_1011 gain1/2 /* en granite sadc bias reg 2*/ reg_id = ANA_GRANITE_BIAS_REG_2; phy_ana_i2c_read(reg_id, &rdata, &rodata); REG_FIELD_SET(BIAS_TEST_VBG, rdata, 1); phy_ana_i2c_write(reg_id, rdata, ~0); sadc_arvg = sadc_arvg_get(); cal_voltg = (sadc_arvg - dc_calib) * ref_voltg / (ref_sadc - dc_calib); #ifdef SADC_DEBUG int32_t target_voltg = 970; //1110; //1.11v iot_printf("For vbg test, ref code is %d, dc code is %d, target_voltg is %d, cal_voltg is %d mv\n", ref_sadc, dc_calib, target_voltg, cal_voltg); return 0; #else #ifdef SADC_TEMPERATURE iot_printf("%d, ", cal_voltg); return 0; #else int32_t target_voltg = 970; //1110; //1.11v int32_t diff_voltg = 15; //0.015 * target_voltg; iot_printf("For vbg test, cal_voltg is %d mv\n", cal_voltg); if ((cal_voltg > target_voltg + diff_voltg) || (cal_voltg < target_voltg - diff_voltg)) { iot_printf("vbg test failed, ref code is %d, dc code is %d, target voltg is %dmv, diff voltg thr is %dmv\n", ref_sadc, dc_calib, target_voltg, diff_voltg); return -1; } else { return 0; } #endif #endif } int32_t vtemp_test(int16_t *vtemp, int32_t dc_calib, int32_t ref_voltg, int32_t ref_sadc) { uint8_t reg_id = 0; uint8_t rodata = 0; uint32_t rdata = 0; int32_t sadc_arvg = 0; int32_t cal_voltg = 0; granite_reg_init(); /* en granite sadc reg */ reg_id = ANA_GRANITE_SADC_REG; phy_ana_i2c_read(reg_id, &rdata, &rodata); REG_FIELD_SET(SADC_SEL_SCL_MUX, rdata, 6); //sadc_sel_scl_mux[2:0] = 110 phy_ana_i2c_write(reg_id, rdata, ~0); /* initialize the soc sadc reg, select hanging-up pad SADC3 */ sadc_reg_init(11, 11); //gain1/2 sadc_gain[5:0] = 00_1011 sadc_arvg = sadc_arvg_get(); cal_voltg = (sadc_arvg - dc_calib) * ref_voltg / (ref_sadc - dc_calib); *vtemp = cal_voltg; #ifdef SADC_DEBUG int32_t target_voltg = 874; //0.874v iot_printf("For vtemp test, ref code is %d, dc code is %d, target_voltg is %d, cal_voltg is %d mv\n", ref_sadc, dc_calib, target_voltg, cal_voltg); return 0; #else #ifdef SADC_TEMPERATURE iot_printf("%d\n", cal_voltg); return 0; #else int32_t target_voltg = 874; //0.874v int32_t diff_voltg = 20; //0.015 * target_voltg; iot_printf("For vtemp test, cal_voltg is %d mv\n", cal_voltg); if ((cal_voltg > target_voltg + diff_voltg) || (cal_voltg < target_voltg - diff_voltg)) { iot_printf("vtemp test failed, ref code is %d, dc code is %d, target voltg is %d mv, diff voltg thr is %d mv\n", ref_sadc, dc_calib, target_voltg, diff_voltg); return -1; } else { return 0; } #endif #endif } void tone_loopback(uint32_t TONE_NUM) { uint32_t tmp = 0; /* force inte rx state */ tmp = PHY_DFE_READ_REG(CFG_BB_DFE_OPTION_0_ADDR); REG_FIELD_SET(SW_MAC_TXRX_OVR_EN, tmp, 1); REG_FIELD_SET(SW_MAC_TXRX_OVR, tmp, 1); //force rx PHY_DFE_WRITE_REG(CFG_BB_DFE_OPTION_0_ADDR, tmp); /* disable packet detect timeout */ tmp = PHY_RXTD_READ_REG(CFG_BB_PKT_TIME_OUT_ADDR); REG_FIELD_SET(SW_PKT_DET_TIME_OUT_DISABLE, tmp, 1); PHY_RXTD_WRITE_REG(CFG_BB_PKT_TIME_OUT_ADDR, tmp); /* bypass dc blocker */ tmp = PHY_DFE_READ_REG(CFG_BB_DC_BLK_STAGE_DLY_ADDR); REG_FIELD_SET(SW_DC_BLK_BYPASS, tmp, 1); PHY_DFE_WRITE_REG(CFG_BB_DC_BLK_STAGE_DLY_ADDR, tmp); /* fix gain and disable agc */ tmp = PHY_RXTD_READ_REG(CFG_BB_AGC_GAIN_LEVEL_ADDR); REG_FIELD_SET(SW_MAX_GAIN, tmp, 0); REG_FIELD_SET(SW_MIN_GAIN, tmp, -24); REG_FIELD_SET(SW_INI_GAIN, tmp, 0); REG_FIELD_SET(SW_FIX_GAIN_EN, tmp, 1); PHY_RXTD_WRITE_REG(CFG_BB_AGC_GAIN_LEVEL_ADDR, tmp); tmp = PHY_RXTD_READ_REG(CFG_BB_AGC_GAIN_LEVEL_ADDR); REG_FIELD_SET(SW_ADJ_REQ_DIS, tmp, 1); REG_FIELD_SET(SW_SAT_DIS, tmp, 1); PHY_RXTD_WRITE_REG(CFG_BB_AGC_GAIN_LEVEL_ADDR, tmp); /* disable auto-adjust gain */ tmp = PHY_DFE_READ_REG(CFG_BB_ANA_RX_ON_CFG_MASK_ADDR); REG_FIELD_SET(SW_RX_ON_CFG_DATA_MASK, tmp, 0); PHY_DFE_WRITE_REG(CFG_BB_ANA_RX_ON_CFG_MASK_ADDR, tmp); /* fix tx gain to 7.5db */ phy_ana_i2c_write(6, 0x20, ~0); /* set the bw filter to 12M*/ phy_ana_i2c_write(0, 0x1800, 0x3f00); /* enable analog tx and rx */ phy_ana_i2c_write(10, 0x28003, 0x28003); /* enable analog loopen and fix rx gain to -6db */ phy_ana_i2c_write(0, 0x9080004, 0x9ffc0ff); tmp = PHY_DFE_READ_REG(CFG_BB_LOOPBACK_TEST_CFG_ADDR); REG_FIELD_SET(SW_LOOPBACK_EN, tmp, 1); PHY_DFE_WRITE_REG(CFG_BB_LOOPBACK_TEST_CFG_ADDR, tmp); /* tone */ tmp = PHY_DFE_READ_REG(CFG_BB_TX_TONE_0_CFG_ADDR); REG_FIELD_SET(SW_TONE_CFG_EN, tmp, 1); REG_FIELD_SET(SW_TONE_0_CFG_NUM, tmp, TONE_NUM); REG_FIELD_SET(SW_TONE_1_CFG_NUM, tmp, 0); PHY_DFE_WRITE_REG(CFG_BB_TX_TONE_0_CFG_ADDR, tmp); } void usleep(uint32_t cnt) { uint32_t start_time = 0; uint32_t end_time = 0; uint32_t time_span = 0; uint32_t delay = 0; if (cnt > 0x0A3D70A3) { delay = 0xFFFFFFFF; } else { delay = cnt*25; //(cnt <<4) + (cnt <<3) + (cnt << 1); //16+8+1 } start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); //0.04us while(time_span < delay) { end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); if(end_time < start_time) { time_span = 0xFFFFFFFF - (start_time - end_time) +1; } else { time_span = end_time - start_time; } } } int32_t rx_adc_eoc_meta_task(uint8_t *cfg_dly, uint8_t *f_h) { uint8_t reg_id = 0; uint8_t rodata = 0; uint32_t rdata = 0; uint32_t wdata = 0; uint32_t wmask = 0; uint32_t rdfe_reg = 0; uint8_t eoc_counter = 0; uint8_t timeout_counter = 0; uint8_t max = 0; uint8_t min = 7; uint8_t time_max = 0; granite_reg_init(); /* set granite top reg, enable adc */ reg_id = ANA_GRANITE_TOP_REG; wdata = TOP_EN_ADC_MASK; // | TOP_EN_RX_MASK; wmask = TOP_EN_ADC_MASK | TOP_EN_SADC_MASK; // | TOP_EN_RX_MASK; phy_ana_i2c_write(reg_id, wdata, wmask); tone_loopback(131); //contain enable TOP_EN_RX and TOP_EN_TX // tone_loopback(43); /* set granite adc reg */ reg_id = ANA_GRANITE_ADC_REG; phy_ana_i2c_read(reg_id, &rdata, &rodata); REG_FIELD_SET(ADC_TIMER_DLY, rdata, 15); //adc_timer_dly[3:0] = 1111 REG_FIELD_SET(ADC_EN_TIMER, rdata, 1); //adc_en_time = 1 REG_FIELD_SET(ADC_EN_CAL_COUNTER, rdata, 0); phy_ana_i2c_write(reg_id, rdata, ~0); for (uint8_t i = 0; i < 8; i++) { for (uint8_t j = 0; j < 8; j++) { /* set granite adc reg */ reg_id = ANA_GRANITE_ADC_REG; phy_ana_i2c_read(reg_id, &rdata, &rodata); REG_FIELD_SET(ADC_CFG_DLY, rdata, i); //adc_cfg_dly[2:0] = 0-->7 REG_FIELD_SET(ADC_F_H, rdata, j); //adc_F_h[2:0] = 0-->7 REG_FIELD_SET(ADC_EN_CAL_COUNTER, rdata, 1); phy_ana_i2c_write(reg_id, rdata, ~0); usleep(1); rdfe_reg = PHY_DFE_READ_REG(CFG_BB_ADC_CNT_DBG_ADDR); eoc_counter = (uint8_t)((rdfe_reg & EOC_ADC_MASK) >> EOC_ADC_OFFSET); timeout_counter = (uint8_t)((rdfe_reg & TIMEOUT_ADC_MASK) >> TIMEOUT_ADC_OFFSET); if (max < eoc_counter) { max = eoc_counter; } if (min > eoc_counter) { min = eoc_counter; } if (time_max < timeout_counter) { time_max = timeout_counter; } /* set granite adc reg */ reg_id = ANA_GRANITE_ADC_REG; phy_ana_i2c_read(reg_id, &rdata, &rodata); REG_FIELD_SET(ADC_EN_CAL_COUNTER, rdata, 0); phy_ana_i2c_write(reg_id, rdata, ~0); usleep(1); } } /* reset granite adc reg */ reg_id = ANA_GRANITE_ADC_REG; phy_ana_i2c_read(reg_id, &rdata, &rodata); REG_FIELD_SET(ADC_TIMER_DLY, rdata, 14); //default is 1000 REG_FIELD_SET(ADC_EN_CAL_COUNTER, rdata, 0);//default is 0 REG_FIELD_SET(ADC_CFG_DLY, rdata, 4); //default is 4 REG_FIELD_SET(ADC_F_H, rdata, 4); //default is 4 REG_FIELD_SET(ADC_EN_TIMER, rdata, 0);//default is 0 phy_ana_i2c_write(reg_id, rdata, ~0); #ifdef SADC_DEBUG iot_printf("For rx adc eoc counter test, the max counter is %d\n", max); iot_printf("For rx adc meta stability test, the timeout counter is %d\n", timeout_counter); #else iot_printf("For rx adc eoc meta test, eoc_max: %d, eoc_min: %d, timeout: %d\n", max, min, time_max); #endif if (max <= 1 || timeout_counter != 0) { return -1; } else if (max == 2) { *cfg_dly = 1; *f_h = 1; return 0; } else if(max == 3) { *cfg_dly = 4; *f_h = 4; return 0; } else { *cfg_dly = 7; *f_h = 7; return 0; } } void sadc_ftm(void) { int32_t sadc_dc[4] = {0, 0, 0}; int32_t sadc_arvg[4] = {0, 0, 0, 0}; //int32_t sadc_input_voltg[2] = {1200, 148}; int32_t sadc_input_voltg[2] = {1205, 151}; uint8_t sadc_bias_cal = 0; uint8_t sadc_trim_adcref = 3; uint8_t sadc_trim_dcdc = 3; int16_t vtemp = 0; //uint8_t cfg_dly = 3; //uint8_t f_h = 3; int8_t fail_cnt = 0; uint32_t tmp = 0; tmp = 0xFFFFFFFF; AHB_RF_WRITE_REG(CFG_AHB_REG1_ADDR, tmp); tmp = APB_GLB_READ_REG(CFG_APB_GLB_GEN0_ADDR); REG_FIELD_SET(SADC_EB, tmp, 1); APB_GLB_WRITE_REG(CFG_APB_GLB_GEN0_ADDR, tmp); tmp = PHY_DFE_READ_REG(CFG_BB_ADA_FORMAT_CFG_ADDR); REG_FIELD_SET(SW_MON_ADC_SEL, tmp, 1); PHY_DFE_WRITE_REG(CFG_BB_ADA_FORMAT_CFG_ADDR, tmp); iot_printf("\n**********************SADC and RX ADC test**************************\n"); #ifndef SADC_DEBUG iot_printf("DC_diff, ref_thr, ical_100uA_thr, adc_ref_thr, dcdc_thr, vbg_thr vtmp_thr:\n"); iot_printf("%d, %d %d %d %dmv, %dmv, %d %d %dmv, %dmv, %dmv, %dmv\n", 25, 6300, 6300, 6450, 6400, 1500, 873, 196, 534, 1220, 970, 874); #endif //fail_cnt -= rx_adc_eoc_meta_task(&cfg_dly, &f_h); #ifndef SADC_TEMPERATURE if(fail_cnt) { iot_printf("rx_adc_eoc_meta test failed\n"); } #endif #ifndef SADC_DEBUG iot_printf("\ndc[0], dc[1], dc[2], dc[3], ref_vol[0], ref_vol[1], "); iot_printf("ref_vol[2], ref_vol[3], ical_code, ical_100uA:\n"); #endif sadc_dc_calibration_task(sadc_dc); sadc_ref_voltg_task(sadc_arvg, sadc_dc, sadc_input_voltg); fail_cnt -= atb_for_ical(&sadc_bias_cal, sadc_dc[1], sadc_input_voltg[0], sadc_arvg[1]); #ifndef SADC_TEMPERATURE if(fail_cnt) { iot_printf("sadc ical_100uA test failed\n"); } #endif #ifndef SADC_DEBUG iot_printf("\ndc[0], dc[1], dc[2], dc[3], ref_vol[0], ref_vol[1], ref_vol[2], "); iot_printf("ref_vol[3], ref_error, vref_code, vrefp, vrefm, vrefm, dcdc_code, dcdc, vbg, vtemp\n"); #endif fail_cnt -= sadc_dc_calibration_task(sadc_dc); fail_cnt -= sadc_ref_voltg_task(sadc_arvg, sadc_dc, sadc_input_voltg); fail_cnt -= atb_for_adcref(&sadc_trim_adcref, sadc_dc[0], sadc_input_voltg[0], sadc_arvg[0]); fail_cnt -= dcdc_1p2v_test(&sadc_trim_dcdc, sadc_dc[0], sadc_input_voltg[0], sadc_arvg[0]); fail_cnt -= at_vbg_test(sadc_dc[0], sadc_input_voltg[0], sadc_arvg[0]); fail_cnt -= vtemp_test(&vtemp, sadc_dc[0], sadc_input_voltg[0], sadc_arvg[0]); #ifndef SADC_TEMPERATURE if(fail_cnt) { iot_printf("\nsadc test failed, fail %d items\n", fail_cnt); } #else iot_printf("\n**********************SADC and RX ADC test end**************************\n"); #endif }