668 lines
21 KiB
C
Executable File
668 lines
21 KiB
C
Executable File
/****************************************************************************
|
||
*
|
||
* 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.
|
||
*
|
||
* ****************************************************************************/
|
||
|
||
#include "os_types.h"
|
||
#include "chip_reg_base.h"
|
||
#include "hw_reg_api.h"
|
||
#include "ate_main.h"
|
||
#include "iot_bitops.h"
|
||
#include "dbg_io.h"
|
||
#include "iot_io.h"
|
||
#include "iot_clock.h"
|
||
#include "gp_timer.h"
|
||
#include "phy_cal.h"
|
||
#include "mac_rx_test.h"
|
||
#include <string.h>
|
||
#include "phy_bb.h"
|
||
#include "plc_protocol.h"
|
||
#include "plc_mpdu_header.h"
|
||
#include "granite_reg.h"
|
||
#include "phy_dfe_reg.h"
|
||
#include "phy_ana_glb.h"
|
||
#include "phy_ana.h"
|
||
#include "clk.h"
|
||
#include "math_log10.h"
|
||
#include "efuse.h"
|
||
#include "efuse_mapping.h"
|
||
#include "hw_phy_init.h"
|
||
#include "mac_reset.h"
|
||
//#include "sadc_t.h"
|
||
#include "ahb_rf.h"
|
||
#include "apb_glb_reg.h"
|
||
#include "mac_sys_reg.h"
|
||
#include "os_mem.h"
|
||
#include "iot_errno.h"
|
||
#include "wdg_reg.h"
|
||
#include "watchdog.h"
|
||
#include "phy_rxtd_reg.h"
|
||
#include "phy_phase.h"
|
||
#include "phy_tools.h"
|
||
#include "hal_rx.h"
|
||
|
||
#include "sfc_rf.h"
|
||
#include "sfc.h"
|
||
#include "flash.h"
|
||
#include "gpio_mtx.h"
|
||
#include "apb.h"
|
||
#include "iot_gpio_api.h"
|
||
#include "sadc_hw.h"
|
||
#include "sadc_t.h"
|
||
#include "hal_sadc.h"
|
||
#include "ana_pmu_wrap_rf.h"
|
||
#include "hw_sadc.h"
|
||
#include "iot_wdg_api.h"
|
||
|
||
/* ate global structure */
|
||
ate_info_t *glb_ate_info = (ate_info_t *) 0xfff8000;//0x73FC2000
|
||
|
||
/********************************************************************************
|
||
Test item
|
||
TX gain setting
|
||
sw_tone_0_att sw_tx_pwr_scale TX_PGA_gain
|
||
RX gain setting
|
||
RX_PGF_gain RX_BQ_gain RX_PGA_gain sw_rx_gain_shift CSI_power(I^2+Q^2)(dBLSB)
|
||
TX gain
|
||
-24 0 -4.53 -6 0 0 0 70.269
|
||
-24 0 1.47 -6 0 0 1 70.269
|
||
-24 0 7.47 -6 0 0 2 70.269
|
||
-24 0 13.47 -6 0 0 3 70.269
|
||
RX gain
|
||
-24 0 1.47 -6 0 0 1 70.269
|
||
-24 0 1.47 -6 -6 12 2 70.269
|
||
-24 0 1.47 -6 12 0 3 70.269
|
||
-24 0 1.47 -6 0 6 2 70.269
|
||
TX PGA
|
||
0~3 -4.5, 1.5, 7.5, 13.5
|
||
********************************************************************************/
|
||
ate_loop_back_gain_list_t ate_granite_lpbk_gain_list[] =
|
||
{
|
||
{1, 0, 0, 0, 1, 0, 1, 0},
|
||
{2, 0, 1, 0, 1, 0, 1, 0},
|
||
{3, 0, 2, 0, 1, 0, 0, 0},
|
||
{4, 0, 3, 0, 1, 0, 0, 0},
|
||
{1, 0, 0, 0, 1, 0, 0, 0},
|
||
{2, 0, 0, 0, 0, 8, 0, 0},
|
||
{3, 0, 1, 0, 1, 4, 0, 0},
|
||
{4, 0, 1, 0, 3, 0, 0, 0},
|
||
};
|
||
/*tx_tone_att, tx_factor, tx_pga_gain, rx_pgf_gain, rx_bq_gain, rx_pga_gain, rx_shift, rx_lna_gain*/
|
||
ate_loop_back_gain_list_t ate_geode_lpbk_gain_list[] =
|
||
{
|
||
{1, 0, 1, 3, 0, 0, 0, 1},
|
||
{1, 0, 1, 2, 0, 0, 0, 2},
|
||
{1, 0, 1, 1, 0, 0, 0, 3},
|
||
{1, 0, 1, 0, 0, 0, 0, 4},
|
||
{1, 0, 0, 0, 0, 0, 0, 5},
|
||
{2, 0, 0, 0, 0, 0, 0, 6},
|
||
{3, 0, 0, 0, 0, 0, 0, 7},
|
||
};
|
||
|
||
/* initialize ate */
|
||
void ate_init(void)
|
||
{
|
||
uint32_t tmp = 0;
|
||
|
||
/* init global info */
|
||
memset(glb_ate_info, 0, sizeof(ate_info_t));
|
||
|
||
/* change clk to 150M */
|
||
clk_core_freq_set(CPU_FREQ_150M);
|
||
|
||
gp_timer_init();
|
||
gp_timer_enable(0,0,0);
|
||
|
||
/* alloc 1K size ram */
|
||
os_mem_init((uint8_t *)0xffffc00, 0x1000);
|
||
|
||
/* eb clk */
|
||
tmp = 0xFFFFFFFF;
|
||
AHB_RF_WRITE_REG(CFG_AHB_REG1_ADDR, tmp);
|
||
/* sadc eb */
|
||
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);
|
||
|
||
/* basic data struct init for bit ops */
|
||
iot_bitops_init();
|
||
|
||
/* reset mac */
|
||
mac_reset(MAC_RST_REASON_COLD);
|
||
/* reset phy */
|
||
phy_reset(PHY_RST_REASON_COLD);
|
||
/* reset mac */
|
||
mac_reset(MAC_RST_REASON_COLD);
|
||
|
||
/* phy param init */
|
||
phy_param_init(PHY_PROTO_TYPE_GET());
|
||
|
||
iot_wdg_enable();
|
||
|
||
/* print software version */
|
||
iot_printf("[ATE]software version:%s\r\n", ATE_SW_VER);
|
||
|
||
}
|
||
|
||
uint32_t mac_granite_loop_back()
|
||
{
|
||
uint32_t ret = ERR_OK;
|
||
uint32_t tmp = 0;
|
||
uint32_t tone_idx = 0;
|
||
uint32_t fft_loop = 1;
|
||
int16_t csi_i = 0, csi_q = 0;
|
||
uint32_t golden_data = 0, noise_data = 0;
|
||
uint32_t *csi_buf = (uint32_t *)BB_CSI_BASEADDR;
|
||
|
||
/* reset phy */
|
||
phy_reset(PHY_RST_REASON_WARM);
|
||
|
||
/* Must cfg start adn end tone */
|
||
mac_rx_init(IOT_PLC_PHY_BAND_DFT);
|
||
|
||
/* config det tone */
|
||
phy_rxfd_rate0_det(0, TOTAL_TONE_MASK_NUM - 4);
|
||
phy_rxfd_rate1_det(0, TOTAL_TONE_MASK_NUM - 4);
|
||
|
||
#if IOT_DTEST_ONLY_SUPPORT == 1
|
||
/* tone 3M */
|
||
phy_dfe_tone_cfg(1, 41, 0);
|
||
/* att */
|
||
phy_dfe_tone_att_cfg(0, 3, 3);
|
||
#endif
|
||
/* sw control tx rx */
|
||
phy_ana_hw_en_bitmap(0);
|
||
|
||
/* enable ana loopback */
|
||
phy_txrx_loop_back_begin(0, TXRX_LOOP_BACK_GRANITE);
|
||
|
||
for(uint32_t i = 0; \
|
||
i < sizeof(ate_granite_lpbk_gain_list)/sizeof(ate_loop_back_gain_list_t); i++)
|
||
{
|
||
/* tone atten and tx factor */
|
||
phy_dfe_tone_att_cfg(0, ate_granite_lpbk_gain_list[i].tx_tone_att, 0);
|
||
//*(uint32_t *)0x51c00404 = ate_granite_lpbk_gain_list[i].tx_tone_att;
|
||
phy_tx_gain_factor_set(ate_granite_lpbk_gain_list[i].tx_factor);
|
||
|
||
/* tx pga */
|
||
phy_ana_rx_fe_gpga(ate_granite_lpbk_gain_list[i].tx_pga_gain);
|
||
|
||
/* rx pgf bq pga*/
|
||
phy_ana_rx_fe_gpgf(ate_granite_lpbk_gain_list[i].rx_pgf_gain);
|
||
phy_ana_rx_fe_gbq(ate_granite_lpbk_gain_list[i].rx_bq_gain);
|
||
phy_ana_rx_fe_gpga(ate_granite_lpbk_gain_list[i].rx_pga_gain);
|
||
/* rx scale */
|
||
if (ate_granite_lpbk_gain_list[i].rx_gain_shift > 0) {
|
||
phy_gain_shift_set(0, 0, 0, ate_granite_lpbk_gain_list[i].rx_gain_shift);
|
||
} else {
|
||
ate_granite_lpbk_gain_list[i].rx_gain_shift = -ate_granite_lpbk_gain_list[i].rx_gain_shift;
|
||
phy_gain_shift_set(0, 0, 1, ate_granite_lpbk_gain_list[i].rx_gain_shift);
|
||
}
|
||
|
||
/* trig fft */
|
||
tmp = PHY_DFE_READ_REG(CFG_BB_LOOPBACK_TEST_CFG_ADDR);
|
||
REG_FIELD_SET(SW_LOOP_FFT_CYCLE, tmp, fft_loop);
|
||
REG_FIELD_SET(SW_LOOP_FFT_START, tmp, 1);
|
||
PHY_DFE_WRITE_REG(CFG_BB_LOOPBACK_TEST_CFG_ADDR, tmp);
|
||
|
||
/* wait fft done */
|
||
do{
|
||
tmp = PHY_DFE_READ_REG(CFG_BB_LOOPBACK_TEST_CFG_ADDR);
|
||
}while(!REG_FIELD_GET(LOOP_FFT_DONE, tmp));
|
||
|
||
/* enable sw csi buf access */
|
||
enable_sw_access_csi_buf(1);
|
||
|
||
/* get tone power */
|
||
tone_idx = ATE_TONE_3M;
|
||
csi_i = (int16_t)(*(csi_buf + tone_idx * 3) & 0xFFFF);
|
||
csi_q = (int16_t)(*(csi_buf + tone_idx * 3) >> 16);
|
||
golden_data = csi_i * csi_i + csi_q * csi_q;
|
||
noise_data = 0;
|
||
|
||
/* cal csi for every tone */
|
||
for(tone_idx = 6; tone_idx < TONE_MAX_NUM; tone_idx++)
|
||
{
|
||
if (tone_idx != ATE_TONE_3M * 3) {
|
||
csi_i = (int16_t)(*(csi_buf + tone_idx) & 0xFFFF);
|
||
csi_q = (int16_t)(*(csi_buf + tone_idx) >> 16);
|
||
noise_data += csi_i * csi_i + csi_q * csi_q;
|
||
} else {
|
||
csi_i = (int16_t)(*(csi_buf + tone_idx) & 0xFFFF);
|
||
csi_q = (int16_t)(*(csi_buf + tone_idx) >> 16);
|
||
}
|
||
#if ATE_DEBUG_LEVEL > 1
|
||
iot_printf("%d,%d,%d\r\n", tone_idx, csi_i, csi_q);
|
||
#endif
|
||
}
|
||
/* enable sw csi buf access */
|
||
enable_sw_access_csi_buf(0);
|
||
|
||
/* get AMP(-30dB) and SNR */
|
||
glb_ate_info->csi_amp[i] = 10 * mlog10(golden_data/1000);
|
||
glb_ate_info->csi_snr[i] = 10 * mlog10(golden_data/noise_data);
|
||
if (glb_ate_info->csi_snr[i] >= 15) {
|
||
iot_printf("[ATE]Granite AMP %d, snr %d, ###success###\r\n", \
|
||
glb_ate_info->csi_amp[i], glb_ate_info->csi_snr[i]);
|
||
} else {
|
||
iot_printf("[ATE]Granite AMP %d, snr %d, ###fail###\r\n", \
|
||
glb_ate_info->csi_amp[i], glb_ate_info->csi_snr[i]);
|
||
ret = ERR_FAIL;
|
||
}
|
||
}
|
||
|
||
/* recover to the state set in ana loopback */
|
||
phy_txrx_loop_back_end();
|
||
|
||
/* hw control tx rx */
|
||
phy_ana_hw_en_bitmap(~0);
|
||
|
||
return ret;
|
||
}
|
||
|
||
uint32_t mac_geode_loop_back()
|
||
{
|
||
uint32_t ret = ERR_OK;
|
||
uint32_t tmp = 0;
|
||
uint32_t tone_idx = 0;
|
||
uint32_t fft_loop = 1;
|
||
int16_t csi_i = 0, csi_q = 0;
|
||
uint32_t golden_data = 0, noise_data = 0;
|
||
uint32_t *csi_buf = (uint32_t *)BB_CSI_BASEADDR;
|
||
|
||
/* reset phy */
|
||
phy_reset(PHY_RST_REASON_WARM);
|
||
|
||
/* cfg det tone range */
|
||
phy_rxfd_rate0_det(0, TOTAL_TONE_MASK_NUM - 4);
|
||
phy_rxfd_rate1_det(0, TOTAL_TONE_MASK_NUM - 4);
|
||
|
||
/* tone 3M */
|
||
phy_dfe_tone_cfg(1, ATE_TONE_3M, 0);
|
||
/* sw control tx rx */
|
||
phy_ana_hw_en_bitmap(0);
|
||
|
||
/* ovr phase A/B/C */
|
||
tmp = PHY_DFE_READ_REG(CFG_BB_DFE_OPTION_0_ADDR);
|
||
REG_FIELD_SET(SW_ENLIC_A_OVR_EN, tmp, 1);
|
||
REG_FIELD_SET(SW_ENLIC_A_OVR, tmp, 3);
|
||
REG_FIELD_SET(SW_ENLIC_B_OVR_EN, tmp, 1);
|
||
REG_FIELD_SET(SW_ENLIC_B_OVR, tmp, 3);
|
||
REG_FIELD_SET(SW_ENLIC_C_OVR_EN, tmp, 1);
|
||
REG_FIELD_SET(SW_ENLIC_C_OVR, tmp, 3);
|
||
PHY_DFE_WRITE_REG(CFG_BB_DFE_OPTION_0_ADDR, tmp);
|
||
|
||
/* enable ana lic tx rx */
|
||
phy_ana_top_enlic_rx_set(1);
|
||
phy_ana_top_enlic_tx_set(1);
|
||
|
||
/* enable ana loopback */
|
||
phy_txrx_loop_back_begin(0, TXRX_LOOP_BACK_GEODE);
|
||
for(uint32_t i = 0; \
|
||
i < sizeof(ate_geode_lpbk_gain_list)/sizeof(ate_loop_back_gain_list_t); i++)
|
||
{
|
||
#if ATE_DEBUG_LEVEL >= 0
|
||
iot_printf("att:%d,factor:%d,tx_pga:%d,rx_pgf:%d,rx_bq:%d,rx_pga:%d,rx_shift:%d,lna:%d\r\n", \
|
||
ate_geode_lpbk_gain_list[i].tx_tone_att, \
|
||
ate_geode_lpbk_gain_list[i].tx_factor, \
|
||
ate_geode_lpbk_gain_list[i].tx_pga_gain, \
|
||
ate_geode_lpbk_gain_list[i].rx_pgf_gain, \
|
||
ate_geode_lpbk_gain_list[i].rx_bq_gain, \
|
||
ate_geode_lpbk_gain_list[i].rx_pga_gain, \
|
||
ate_geode_lpbk_gain_list[i].rx_gain_shift, \
|
||
ate_geode_lpbk_gain_list[i].rx_lna_gain);
|
||
#endif
|
||
/* tone atten and tx factor */
|
||
phy_dfe_tone_att_cfg(0, ate_geode_lpbk_gain_list[i].tx_tone_att, 0);
|
||
*(uint32_t *)0x51c00404=ate_geode_lpbk_gain_list[i].tx_tone_att;
|
||
phy_tx_gain_factor_set(ate_geode_lpbk_gain_list[i].tx_factor);
|
||
|
||
/* tx pga */
|
||
phy_ana_rx_fe_gpga(ate_granite_lpbk_gain_list[i].tx_pga_gain);
|
||
|
||
/* rx pgf bq pga*/
|
||
phy_ana_rx_fe_gpgf(ate_granite_lpbk_gain_list[i].rx_pgf_gain);
|
||
phy_ana_rx_fe_gbq(ate_granite_lpbk_gain_list[i].rx_bq_gain);
|
||
phy_ana_rx_fe_gpga(ate_granite_lpbk_gain_list[i].rx_pga_gain);
|
||
|
||
/* rx lna */
|
||
phy_ana_rx_glna(ate_geode_lpbk_gain_list[i].rx_lna_gain);
|
||
|
||
/* rx scale */
|
||
if (ate_geode_lpbk_gain_list[i].rx_gain_shift > 0) {
|
||
phy_gain_shift_set(0, 0, 0, ate_geode_lpbk_gain_list[i].rx_gain_shift);
|
||
} else {
|
||
ate_geode_lpbk_gain_list[i].rx_gain_shift = 0 - ate_geode_lpbk_gain_list[i].rx_gain_shift;
|
||
phy_gain_shift_set(0, 0, 1, ate_geode_lpbk_gain_list[i].rx_gain_shift);
|
||
}
|
||
|
||
/* trig fft */
|
||
tmp = PHY_DFE_READ_REG(CFG_BB_LOOPBACK_TEST_CFG_ADDR);
|
||
REG_FIELD_SET(SW_LOOP_FFT_CYCLE, tmp, fft_loop);
|
||
REG_FIELD_SET(SW_LOOP_FFT_START, tmp, 1);
|
||
PHY_DFE_WRITE_REG(CFG_BB_LOOPBACK_TEST_CFG_ADDR, tmp);
|
||
|
||
/* wait fft done */
|
||
do{
|
||
tmp = PHY_DFE_READ_REG(CFG_BB_LOOPBACK_TEST_CFG_ADDR);
|
||
}while(!REG_FIELD_GET(LOOP_FFT_DONE, tmp));
|
||
|
||
/* enable sw csi buf access */
|
||
enable_sw_access_csi_buf(1);
|
||
|
||
/* get tone power */
|
||
tone_idx = ATE_TONE_3M;
|
||
csi_i = (int16_t)(*(csi_buf + tone_idx * 3) & 0xFFFF);
|
||
csi_q = (int16_t)(*(csi_buf + tone_idx * 3) >> 16);
|
||
golden_data = csi_i * csi_i + csi_q * csi_q;
|
||
noise_data = 0;
|
||
|
||
/* cal csi for every tone */
|
||
for(tone_idx = 6; tone_idx < TONE_MAX_NUM; tone_idx++)
|
||
{
|
||
if(tone_idx != ATE_TONE_3M * 3){
|
||
csi_i = (int16_t)(*(csi_buf + tone_idx) & 0xFFFF);
|
||
csi_q = (int16_t)(*(csi_buf + tone_idx) >> 16);
|
||
noise_data += csi_i * csi_i + csi_q * csi_q;
|
||
#if 0
|
||
iot_printf("%d %d \n", tone_idx, csi_i * csi_i + csi_q * csi_q);
|
||
#endif
|
||
} else {
|
||
csi_i = (int16_t)(*(csi_buf + tone_idx) & 0xFFFF);
|
||
csi_q = (int16_t)(*(csi_buf + tone_idx) >> 16);
|
||
#if 0
|
||
iot_printf("%d %d \n", tone_idx, csi_i * csi_i + csi_q * csi_q);
|
||
#endif
|
||
}
|
||
}
|
||
/* disable sw csi buf access */
|
||
enable_sw_access_csi_buf(0);
|
||
|
||
//iot_printf("golden_data %d noise_data %d \n", golden_data, noise_data);
|
||
|
||
/* get AMP(-30dB) and SNR */
|
||
glb_ate_info->csi_amp[8+i] = 10 * mlog10(golden_data/1000);
|
||
glb_ate_info->csi_snr[8+i] = 10 * mlog10(golden_data/noise_data);
|
||
|
||
if (glb_ate_info->csi_snr[8+i] >= 10) {
|
||
iot_printf("[ATE]geode amp %d, snr %d, ###success###\r\n", \
|
||
glb_ate_info->csi_amp[8+i], glb_ate_info->csi_snr[8+i]);
|
||
} else {
|
||
iot_printf("[ATE]geode amp %d, snr %d, ###fail###\r\n", \
|
||
glb_ate_info->csi_amp[8+i], glb_ate_info->csi_snr[8+i]);
|
||
ret = ERR_FAIL;
|
||
}
|
||
|
||
}
|
||
|
||
/* recover to the state set in ana loopback */
|
||
phy_txrx_loop_back_end();
|
||
|
||
/* hw control tx rx */
|
||
phy_ana_hw_en_bitmap(~0);
|
||
|
||
return ret;
|
||
}
|
||
|
||
uint32_t ate_nf_test()
|
||
{
|
||
uint32_t tmp = 0;
|
||
uint32_t ret = ERR_OK;
|
||
uint32_t valid_nf_num = 0;
|
||
uint32_t nf_tmp = 0;
|
||
uint32_t idx = 0;
|
||
|
||
/* reset phy reg */
|
||
phy_reset(PHY_RST_REASON_COLD);
|
||
|
||
/* fix 60dB gain */
|
||
phy_agc_gain_lvl_set(1, 60, -24, 0);
|
||
|
||
/* 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, 0);
|
||
PHY_RXTD_WRITE_REG(CFG_BB_PKT_TIME_OUT_ADDR, tmp);
|
||
|
||
/* disable reset by full */
|
||
tmp = PHY_RXTD_READ_REG(CFG_BB_AGC_GAIN_LEVEL_ADDR);
|
||
REG_FIELD_SET(SW_ADJ_REQ_DIS, tmp, 0);
|
||
REG_FIELD_SET(SW_SAT_DIS, tmp, 0);
|
||
PHY_RXTD_WRITE_REG(CFG_BB_AGC_GAIN_LEVEL_ADDR, tmp);
|
||
|
||
/* ad/da bits shift */
|
||
phy_gain_shift_set(0, 0, 0, 0);
|
||
tmp = PHY_DFE_READ_REG(CFG_BB_AGC_SWCFG_EN_ADDR);
|
||
REG_FIELD_SET(SW_AR1540_EN, tmp, 0x0);
|
||
PHY_DFE_WRITE_REG(CFG_BB_AGC_SWCFG_EN_ADDR, tmp);
|
||
|
||
/* config default RX ON regsiter */
|
||
phy_agc_gain_adj_dis(0xE7FFC0FF);
|
||
|
||
/* sw control tx rx */
|
||
phy_ana_hw_en_bitmap(0);
|
||
|
||
/* en adc and rx, disable dac and tx */
|
||
phy_ana_top_tx_en(0);
|
||
phy_ana_top_rx_en(1);
|
||
phy_ana_top_adc_en(1);
|
||
phy_ana_top_dac_en(0);
|
||
phy_ana_top_enlic_rx_set(1);
|
||
phy_ana_top_enlic_tx_set(0);
|
||
|
||
/* force phy in rx state */
|
||
phy_txrx_ovr_set(true, 1);
|
||
/* enable geode */
|
||
phy_phase_ovr_set(PHY_PHASE_OVR_A, true, PHY_TXRX_OVR_RX);
|
||
phy_phase_ovr_set(PHY_PHASE_OVR_B, true, PHY_TXRX_OVR_RX);
|
||
phy_phase_ovr_set(PHY_PHASE_OVR_C, true, PHY_TXRX_OVR_RX);
|
||
|
||
/* disable tone */
|
||
phy_dfe_tone_cfg(0, 0, 0);
|
||
/* diable analog loopen */
|
||
phy_ana_rx_pgfloop_set(0);
|
||
|
||
/* rx pgf bq pga*/
|
||
phy_ana_rx_fe_gpgf(1);
|
||
phy_ana_rx_fe_gbq(1);
|
||
phy_ana_rx_fe_gpga(0);
|
||
phy_ana_rx_fe_gpga_offset(PHY_RX_PGA_OFFSET_DFT);
|
||
phy_ana_rx_fe_gpgf_offset(PHY_RX_PGF_OFFSET_DFT);
|
||
phy_ana_rx_fe_hpfenord2_set(0);
|
||
phy_ana_rx_fe_byphpf_set(0);
|
||
phy_ana_rx_fe_pwdpgf_offset_set(0);
|
||
phy_ana_rx_fe_pwdpga_offset_set(0);
|
||
|
||
glb_ate_info->nf = 0;
|
||
/* nf get */
|
||
for (idx = 0; idx < PHY_NF_RTY_CNT; idx++)
|
||
{
|
||
nf_tmp = phy_rx_nf_by_rxtd_get(14);
|
||
/*121 is reset value, not valid value*/
|
||
if (nf_tmp != PHY_NF_RST_VAL) {
|
||
glb_ate_info->nf += nf_tmp;
|
||
//iot_printf("[ATE]nf:%d\n", nf_tmp);
|
||
valid_nf_num++;
|
||
}
|
||
}
|
||
glb_ate_info->nf = glb_ate_info->nf/valid_nf_num;
|
||
if (glb_ate_info->nf >= 30) {
|
||
iot_printf("[ATE] current nf:%d ###fail###\n", glb_ate_info->nf);
|
||
ret = ERR_FAIL;
|
||
} else {
|
||
iot_printf("[ATE] current nf:%d ###success###\n", glb_ate_info->nf);
|
||
}
|
||
/* hw control tx rx */
|
||
phy_ana_hw_en_bitmap(~0);
|
||
|
||
return ret;
|
||
}
|
||
|
||
void meter_test(void)
|
||
{
|
||
int32_t doffset_avg = 0;
|
||
int32_t dx_avg = 0;
|
||
int32_t dy_avg = 0;
|
||
float vref = 0;
|
||
int32_t dc_offset = 0;
|
||
int32_t dv = 0;
|
||
int32_t ch1_adc3_v = 0;
|
||
|
||
iot_printf("doffset_avg************0x%x\n", &glb_ate_info->doffset_avg);
|
||
doffset_avg = sadc_ref_voltg_test(SADC_PHASE0, SADC_TSW_SEL_SCL_MUX_VCM_VCM, CP);
|
||
glb_ate_info->doffset_avg = doffset_avg;
|
||
|
||
/* cp test,single phase DIFF_CH10 */
|
||
iot_printf("dx_avg*****************0x%x\n",&glb_ate_info->dx_avg);
|
||
dx_avg = sadc_ref_voltg_test(SADC_PHASE0, SADC_TSW_SEL_SCL_MUX_DIFF_CH10, CP);
|
||
glb_ate_info->dx_avg = dx_avg;
|
||
|
||
/* cp test,single phase DIFF_CH32 */
|
||
iot_printf("dy_avg****************0x%x\n",&glb_ate_info->dy_avg);
|
||
dy_avg = sadc_ref_voltg_test(SADC_PHASE0, SADC_TSW_SEL_SCL_MUX_DIFF_CH32, CP);
|
||
glb_ate_info->dy_avg = dy_avg;
|
||
|
||
vref = (dx_avg - doffset_avg)/46786.0 + (dy_avg - doffset_avg)/23393.0;
|
||
glb_ate_info->vref = vref;
|
||
iot_printf("vref*****************0x%x\n", &glb_ate_info->vref);
|
||
|
||
iot_printf("doffset_avg:%d dx_avg:%d dy_avg:%d vref:%f\n",doffset_avg,dx_avg,dy_avg,vref);
|
||
|
||
/* ate test,VCM_VCM */
|
||
dc_offset = sadc_ref_voltg_test(SADC_PHASE0, SADC_TSW_SEL_SCL_MUX_VCM_VCM, ATE);
|
||
glb_ate_info->dc_offset = dc_offset;
|
||
|
||
/* ch0 chopper 0x28 */
|
||
uint32_t tmp = ANA_PMU_WRAP_RF_READ_REG(CFG_ANA_PMU_REG_CFG10_ADDR);
|
||
REG_FIELD_SET(ICCAL, tmp, 0x10);
|
||
ANA_PMU_WRAP_RF_WRITE_REG(CFG_ANA_PMU_REG_CFG10_ADDR, tmp);
|
||
|
||
/* ate test,single phase CH1_ADC3 */
|
||
iot_printf("CH1_ADC3\n");
|
||
|
||
dv = sadc_ref_voltg_test(SADC_PHASE0, SADC_TSW_SEL_SCL_MUX_SING_CH3, ATE);
|
||
iot_printf("%d\n",dv);
|
||
|
||
ch1_adc3_v = dv - dc_offset;
|
||
iot_printf("ch1_adc3_v:%d=%d - %d\n",ch1_adc3_v, dv, dc_offset);
|
||
iot_printf("dc_offset*****************0x%x\n", &glb_ate_info->dc_offset);
|
||
|
||
iot_printf("ch1_adc3_v*****************0x%x\n", glb_ate_info->ch1_adc3_v);
|
||
|
||
/* ch0 chopper 0x28 */
|
||
for(uint16_t j = 0; j < PMU_ICCAL_NUM; j++) {
|
||
tmp = ANA_PMU_WRAP_RF_READ_REG(CFG_ANA_PMU_REG_CFG10_ADDR);
|
||
REG_FIELD_SET(ICCAL, tmp, j);
|
||
ANA_PMU_WRAP_RF_WRITE_REG(CFG_ANA_PMU_REG_CFG10_ADDR, tmp);
|
||
dv = sadc_ref_voltg_test(SADC_PHASE0, SADC_TSW_SEL_SCL_MUX_SING_CH3, ATE);
|
||
ch1_adc3_v = dv - dc_offset;
|
||
glb_ate_info->ch1_adc3_v[j] = ch1_adc3_v;
|
||
iot_printf("ICCAL + 1:%d=%d - %d\n", ch1_adc3_v, dv, dc_offset);
|
||
}
|
||
}
|
||
/* main entry */
|
||
void ate_entry(void)
|
||
{
|
||
uint32_t start_time = 0;
|
||
uint32_t end_time = 0;
|
||
uint64_t time_span = 0;
|
||
|
||
uint32_t ret = ERR_OK;
|
||
uint16_t tx_dc[4] = {0};
|
||
uint16_t rx_dc[PHY_GAIN_STEP_MAX] = {0};
|
||
|
||
start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
|
||
#if HW_PLATFORM > HW_PLATFORM_SIMU
|
||
#if EDA_SIMU_SUPPORT != 1
|
||
for(volatile uint32_t i = 0; i < 5000; i++);
|
||
/* serial init */
|
||
dbg_uart_init();
|
||
iot_printf("ate_test begin...\n");
|
||
#endif
|
||
#endif
|
||
|
||
ate_init();
|
||
|
||
/* efuse chip-id nad version */
|
||
glb_ate_info->result = 0;
|
||
glb_ate_info->ret_flag = 0;
|
||
glb_ate_info->rsv[0] = 0x5a5a5a5a;
|
||
glb_ate_info->rsv[1] = 0x5a5a5a5a;
|
||
glb_ate_info->rsv[2] = 0x5a5a5a5a;
|
||
glb_ate_info->rsv[3] = 0x5a5a5a5a;
|
||
|
||
/* tx dc calibration */
|
||
ret = tx_dc_calibration(tx_dc);
|
||
if (ret == ERR_OK) {
|
||
os_mem_cpy(glb_ate_info->tx_dc, tx_dc, sizeof(tx_dc));
|
||
} else {
|
||
glb_ate_info->ret_flag |= ERR_BIT(0);
|
||
}
|
||
|
||
/* rx dc calibration */
|
||
ret = rx_dc_calibration(rx_dc);
|
||
if (ret == ERR_OK) {
|
||
os_mem_cpy(glb_ate_info->rx_dc, rx_dc, sizeof(rx_dc));
|
||
} else {
|
||
glb_ate_info->ret_flag |= ERR_BIT(1);
|
||
}
|
||
|
||
/* granite loopback */
|
||
ret = mac_granite_loop_back();
|
||
if (ret != ERR_OK) {
|
||
glb_ate_info->ret_flag |= ERR_BIT(2);
|
||
}
|
||
|
||
/* geode loopback */
|
||
ret = mac_geode_loop_back();
|
||
if (ret != ERR_OK) {
|
||
glb_ate_info->ret_flag |= ERR_BIT(3);
|
||
}
|
||
|
||
/* rx bandwidth filter calibration */
|
||
phy_rx_bw_filter(RX_BW_LIST_BAND0_12M);
|
||
/* reset phy */
|
||
phy_reset(PHY_RST_REASON_WARM);
|
||
phy_rx_bw_filter(RX_BW_LIST_BAND1_5P6M);
|
||
|
||
/* nf test */
|
||
ret = ate_nf_test();
|
||
if (ret != ERR_OK) {
|
||
glb_ate_info->ret_flag |= ERR_BIT(4);
|
||
}
|
||
|
||
meter_test();
|
||
|
||
end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
time_span = end_time - start_time;
|
||
if (time_span < 0) { // wrap around
|
||
time_span = (0x100000000LL) - start_time + end_time;
|
||
}
|
||
iot_printf("[ATE]total time: %llu us\n", time_span/TICKS_US);
|
||
if (!glb_ate_info->ret_flag) {
|
||
glb_ate_info->result = true;
|
||
iot_printf("ATE test pass!\n");
|
||
} else {
|
||
glb_ate_info->result = 0x55;
|
||
iot_printf("glb_ate_info->ret_flag: %d\n",glb_ate_info->ret_flag);
|
||
iot_printf("ATE test fail!\n");
|
||
}
|
||
}
|
||
|
||
int main(void) {
|
||
|
||
ate_entry();
|
||
|
||
return 0;
|
||
}
|