1571 lines
51 KiB
C
Executable File
1571 lines
51 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 "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"
|
||
|
||
|
||
/* ate global structure */
|
||
ate_info_t *glb_ate_info = (ate_info_t *) 0xff8000;
|
||
|
||
/********************************************************************************
|
||
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);
|
||
|
||
/* alloc 1K size ram */
|
||
os_mem_init((uint8_t *)0xfff000, 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());
|
||
|
||
/* print software version */
|
||
iot_printf("[ATE]software version:%s\r\n", ATE_SW_VER);
|
||
|
||
/* read ver */
|
||
tmp = efuse_read(CFG_EFUSE_BITS32_7_ADDR);
|
||
glb_ate_info->version = (tmp & VERSION_PKG_MASK) >> VERSION_PKG_OFFSET;
|
||
iot_printf("[ATE]efuse read pkg version:%x\r\n", \
|
||
(tmp & VERSION_PKG_MASK) >> VERSION_PKG_OFFSET);
|
||
|
||
tmp = efuse_read(CFG_EFUSE_BITS32_0_ADDR);
|
||
glb_ate_info->version_wafer = ((tmp & VERSION_WAFER_MASK) >> VERSION_WAFER_OFFSET);
|
||
iot_printf("[ATE]efuse read wafer version:%x\r\n", \
|
||
(tmp & VERSION_WAFER_MASK) >> VERSION_WAFER_OFFSET);
|
||
|
||
tmp = efuse_read(CFG_EFUSE_BITS32_0_ADDR);
|
||
glb_ate_info->version_reserve = ((tmp & VERSION_RESERVE_MASK) >> VERSION_RESERVE_OFFSET);
|
||
iot_printf("[ATE]efuse read reserve version:%x\r\n", \
|
||
(tmp & VERSION_WAFER_MASK) >> VERSION_WAFER_OFFSET);
|
||
|
||
/* read ver */
|
||
tmp = efuse_read(CFG_EFUSE_BITS32_2_ADDR);
|
||
iot_printf("[ATE]efuse read MAC:%02X:", REG_FIELD_GET(MAC_ADDR_B0, tmp));
|
||
glb_ate_info->mac[0] = REG_FIELD_GET(MAC_ADDR_B0, tmp);
|
||
|
||
tmp = efuse_read(CFG_EFUSE_BITS32_3_ADDR);
|
||
iot_printf("%02X:%02X:%02X:%02X:", REG_FIELD_GET(MAC_ADDR_B1, tmp), \
|
||
REG_FIELD_GET(MAC_ADDR_B2, tmp), \
|
||
REG_FIELD_GET(MAC_ADDR_B3, tmp), \
|
||
REG_FIELD_GET(MAC_ADDR_B4, tmp));
|
||
glb_ate_info->mac[1] = REG_FIELD_GET(MAC_ADDR_B1, tmp);
|
||
glb_ate_info->mac[2] = REG_FIELD_GET(MAC_ADDR_B2, tmp);
|
||
glb_ate_info->mac[3] = REG_FIELD_GET(MAC_ADDR_B3, tmp);
|
||
glb_ate_info->mac[4] = REG_FIELD_GET(MAC_ADDR_B4, tmp);
|
||
|
||
tmp = efuse_read(CFG_EFUSE_BITS32_4_ADDR);
|
||
iot_printf("%02X\r\n", REG_FIELD_GET(MAC_ADDR_B5, tmp));
|
||
glb_ate_info->mac[5] = REG_FIELD_GET(MAC_ADDR_B5, tmp);
|
||
|
||
os_mem_cpy(glb_ate_info->sw_version, ATE_SW_VER, sizeof(ATE_SW_VER));
|
||
}
|
||
|
||
uint32_t mac_granite_loop_back()
|
||
{
|
||
uint32_t ret = ERR_OK;
|
||
uint32_t tmp = 0;
|
||
uint8_t reg_id = 0;
|
||
uint8_t rodata = 0;
|
||
uint32_t rdata = 0;
|
||
uint32_t wdata = 0;
|
||
uint32_t wmask = 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, 1535);
|
||
phy_rxfd_rate1_det(0, 1535);
|
||
|
||
#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
|
||
|
||
/* 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 */
|
||
reg_id = ANA_GRANITE_TX_REG;
|
||
phy_ana_i2c_read(reg_id, &rdata, &rodata);
|
||
REG_FIELD_SET(TX_GPGA, rdata, ate_granite_lpbk_gain_list[i].tx_pga_gain);
|
||
phy_ana_i2c_write(reg_id, rdata, ~0);
|
||
|
||
/* rx pgf bq pga*/
|
||
reg_id = ANA_GRANITE_RX_REG_0;
|
||
wdata = ate_granite_lpbk_gain_list[i].rx_pgf_gain << RX_GPGF_OFFSET;
|
||
wdata |= ate_granite_lpbk_gain_list[i].rx_bq_gain << RX_GBQ_OFFSET;
|
||
wdata |= ate_granite_lpbk_gain_list[i].rx_pga_gain << RX_GPGA_OFFSET;
|
||
wmask = RX_GPGF_MASK | RX_GBQ_MASK | RX_GPGA_MASK;
|
||
phy_ana_i2c_write(reg_id, wdata, wmask);
|
||
/* 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;
|
||
|
||
/* 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
|
||
}
|
||
|
||
/* 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;
|
||
}
|
||
|
||
/* enable sw csi buf access */
|
||
enable_sw_access_csi_buf(0);
|
||
}
|
||
|
||
/* recover to the state before ana loopback */
|
||
phy_txrx_loop_back_end();
|
||
|
||
return ret;
|
||
}
|
||
|
||
uint32_t mac_geode_loop_back()
|
||
{
|
||
uint32_t ret = ERR_OK;
|
||
uint32_t tmp = 0;
|
||
uint8_t reg_id = 0;
|
||
uint8_t rodata = 0;
|
||
uint32_t rdata = 0;
|
||
uint32_t wdata = 0;
|
||
uint32_t wmask = 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, 1535);
|
||
phy_rxfd_rate1_det(0, 1535);
|
||
|
||
/* tone 3M */
|
||
phy_dfe_tone_cfg(1, ATE_TONE_3M, 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);
|
||
|
||
/* en analog tx/rx */
|
||
reg_id = ANA_GRANITE_TOP_REG;
|
||
wdata = TOP_EN_TX_MASK | TOP_EN_DAC_MASK | \
|
||
TOP_EN_RX_MASK | TOP_EN_ADC_MASK | TOP_ENLIC_MASK;
|
||
wmask = TOP_EN_TX_MASK | TOP_EN_DAC_MASK | \
|
||
TOP_EN_RX_MASK | TOP_EN_ADC_MASK | TOP_ENLIC_MASK;
|
||
phy_ana_i2c_write(reg_id, wdata, wmask);
|
||
|
||
/* 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 */
|
||
reg_id = ANA_GRANITE_TX_REG;
|
||
phy_ana_i2c_read(reg_id, &rdata, &rodata);
|
||
REG_FIELD_SET(TX_GPGA, rdata, ate_geode_lpbk_gain_list[i].tx_pga_gain);
|
||
phy_ana_i2c_write(reg_id, rdata, ~0);
|
||
|
||
/* rx pgf bq pga*/
|
||
reg_id = ANA_GRANITE_RX_REG_0;
|
||
wdata = ate_geode_lpbk_gain_list[i].rx_pgf_gain << RX_GPGF_OFFSET;
|
||
wdata |= ate_geode_lpbk_gain_list[i].rx_bq_gain << RX_GBQ_OFFSET;
|
||
wdata |= ate_geode_lpbk_gain_list[i].rx_pga_gain << RX_GPGA_OFFSET;
|
||
wmask = RX_GPGF_MASK | RX_GBQ_MASK | RX_GPGA_MASK;
|
||
phy_ana_i2c_write(reg_id, wdata, wmask);
|
||
|
||
/* rx lna */
|
||
reg_id = ANA_GRANITE_TOP_REG;
|
||
wdata = ate_geode_lpbk_gain_list[i].rx_lna_gain << TOP_GLNA_OFFSET;
|
||
wmask = TOP_GLNA_MASK;
|
||
phy_ana_i2c_write(reg_id, wdata, wmask);
|
||
|
||
/* 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;
|
||
|
||
/* 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,%d\r\n", tone_idx, csi_i, csi_q);
|
||
#endif
|
||
} else {
|
||
csi_i = (int16_t)(*(csi_buf + tone_idx) & 0xFFFF);
|
||
csi_q = (int16_t)(*(csi_buf + tone_idx) >> 16);
|
||
#if ATE_DEBUG_LEVEL >= 0
|
||
iot_printf("%d,%d,%d\r\n", tone_idx, csi_i, csi_q);
|
||
#endif
|
||
}
|
||
}
|
||
|
||
/* 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;
|
||
}
|
||
|
||
/* enable sw csi buf access */
|
||
enable_sw_access_csi_buf(0);
|
||
}
|
||
|
||
/* revover to the state before ana loopback */
|
||
phy_txrx_loop_back_end();
|
||
|
||
return ret;
|
||
}
|
||
|
||
void ate_efuse_version_reserve(void)
|
||
{
|
||
volatile uint32_t *reg = (volatile uint32_t *)0x62040120;
|
||
REG32(0xFF8000) = 0xff;
|
||
|
||
/* set user space to 0 */
|
||
*reg = 0;
|
||
|
||
uint32_t tmp = efuse_read(0);
|
||
|
||
if (tmp & 0x1000) { /* VERSION_RESERVE BIT0 */
|
||
return;
|
||
} else {
|
||
tmp |= 0x1000;
|
||
}
|
||
|
||
efuse_write(CFG_EFUSE_BITS32_0_ADDR, tmp);
|
||
|
||
/* return result*/
|
||
REG32(0xFF8000) = 0x11;
|
||
iot_printf("[ATE]check successfully!\r\n");
|
||
}
|
||
|
||
bool_t ate_efuse_entry(void)
|
||
{
|
||
uint32_t tmp = 0;
|
||
bool_t check_fail = false;
|
||
bool_t check_empty = true;
|
||
uint8_t mac_addr[6] = {0};
|
||
uint8_t version[3] = {0};
|
||
|
||
/* check if 2048 bit empty or not */
|
||
/* efuse_read() read a 32-bit data */
|
||
for(uint32_t i = 0; i < 64; i++)
|
||
{
|
||
tmp = efuse_read(i*4);
|
||
if (tmp != 0) {
|
||
check_empty = false;
|
||
iot_printf("check efuse empty false\n");
|
||
}
|
||
}
|
||
|
||
/* empty branch */
|
||
if (check_empty == true) {
|
||
/* check info valid */
|
||
if ((REG8(0xFF0000) != 0x48) || \
|
||
(REG8(0xFF0001) != 0x55) || \
|
||
(REG8(0xFF0002) != 0x5c)) {
|
||
iot_printf("[ATE]efuse info is illegal!\r\n");
|
||
check_fail = true;
|
||
} else {
|
||
/* fuse mac byte0 */
|
||
tmp = 0;
|
||
REG_FIELD_SET(MAC_ADDR_B0, tmp, REG8(0xFF0000));
|
||
efuse_write(CFG_EFUSE_BITS32_2_ADDR,tmp);
|
||
/* fuse mac byte1/2/3/4 */
|
||
tmp = 0;
|
||
REG_FIELD_SET(MAC_ADDR_B1, tmp, REG8(0xFF0001));
|
||
REG_FIELD_SET(MAC_ADDR_B2, tmp, REG8(0xFF0002));
|
||
REG_FIELD_SET(MAC_ADDR_B3, tmp, REG8(0xFF0003));
|
||
REG_FIELD_SET(MAC_ADDR_B4, tmp, REG8(0xFF0004));
|
||
efuse_write(CFG_EFUSE_BITS32_3_ADDR,tmp);
|
||
/* fuse mac byte5 */
|
||
tmp = 0;
|
||
REG_FIELD_SET(MAC_ADDR_B5, tmp, REG8(0xFF0005));
|
||
efuse_write(CFG_EFUSE_BITS32_4_ADDR, tmp);
|
||
|
||
/* fuse: wafer, reserve version 8 bits */
|
||
tmp = 0;
|
||
REG_FIELD_SET(VERSION_WAFER, tmp, REG8(0xFF0008));
|
||
REG_FIELD_SET(VERSION_RESERVE, tmp, REG8(0xFF0009));
|
||
efuse_write(CFG_EFUSE_BITS32_0_ADDR, tmp);
|
||
|
||
/* fuse: pkg version 4 bits */
|
||
tmp = 0;
|
||
REG_FIELD_SET(VERSION_PKG, tmp, REG8(0xFF000A));
|
||
efuse_write(CFG_EFUSE_BITS32_7_ADDR, tmp);
|
||
|
||
check_fail = false;
|
||
|
||
mac_addr[0] = REG8(0xFF0000);
|
||
mac_addr[1] = REG8(0xFF0001);
|
||
mac_addr[2] = REG8(0xFF0002);
|
||
mac_addr[3] = REG8(0xFF0003);
|
||
mac_addr[4] = REG8(0xFF0004);
|
||
mac_addr[5] = REG8(0xFF0005);
|
||
version[0] = REG8(0xFF0008);
|
||
version[1] = REG8(0xFF0009);
|
||
version[2] = REG8(0xFF000A);
|
||
iot_printf("[ATE]efuse write mac [%02X:%02X:%02X:%02X:%02X:%02X] successfully!\r\n",\
|
||
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
|
||
iot_printf("[ATE]efuse write verisoin [%01X:%01X:%01X] successfully!\r\n",version[0], version[1], version[2]);
|
||
|
||
#if ATE_EFUSE_PROG_DONE
|
||
/* efuse: efuse prog done */
|
||
tmp = 0;
|
||
REG_FIELD_SET(VENDOR_EFUSE_PROG_DONE, tmp, 1);
|
||
efuse_write(CFG_EFUSE_BITS32_0_ADDR, tmp);
|
||
tmp = 0;
|
||
REG_FIELD_SET(VENDOR_EFUSE_PROG_DONE_BACKUP, tmp, 1);
|
||
efuse_write(CFG_EFUSE_BITS32_0_ADDR, tmp);
|
||
/* efuse: efuse */
|
||
tmp = 0;
|
||
tmp |= (1 << 16); //usr_efuse_prog_done
|
||
tmp |= (1 << 24); //usr_efuse_prog_done backup
|
||
efuse_write(0x20, tmp);
|
||
|
||
iot_printf("[ATE]efuse program bit done\n");
|
||
#endif
|
||
}
|
||
} else {
|
||
/* check sum for fused chip */
|
||
tmp = efuse_read(CFG_EFUSE_BITS32_2_ADDR);
|
||
if (0x48 != REG_FIELD_GET(MAC_ADDR_B0, tmp)) {
|
||
check_fail = true;
|
||
}
|
||
tmp = efuse_read(CFG_EFUSE_BITS32_3_ADDR);
|
||
if (0x55 != REG_FIELD_GET(MAC_ADDR_B1, tmp)) {
|
||
check_fail = true;
|
||
}
|
||
tmp = efuse_read(CFG_EFUSE_BITS32_3_ADDR);
|
||
if (0x5c != REG_FIELD_GET(MAC_ADDR_B2, tmp)) {
|
||
check_fail = true;
|
||
}
|
||
iot_printf("[ATE]mac or version have been efused!\r\n");
|
||
}
|
||
|
||
/* return result*/
|
||
if(check_empty == true)
|
||
{
|
||
if (check_fail == true) {
|
||
REG32(0xFF8000) = 0x00;
|
||
iot_printf("[ATE]check fail!\r\n");
|
||
} else {
|
||
REG32(0xFF8000) = 0x01;
|
||
iot_printf("[ATE]check successfully!\r\n");
|
||
}
|
||
} else {
|
||
if(check_fail == true) {
|
||
REG32(0xFF8000) = 0x10;
|
||
iot_printf("[ATE]check fail!\r\n");
|
||
} else {
|
||
REG32(0xFF8000) = 0x11;
|
||
iot_printf("[ATE]check successfully!\r\n");
|
||
}
|
||
}
|
||
|
||
while(1)
|
||
{
|
||
*((volatile uint32_t *)(0xff8008)) += 1;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
/* try flow by tx tone */
|
||
bool_t ate_analog_test_demo()
|
||
{
|
||
uint32_t tmp = 0;
|
||
uint8_t *dst_addr = (uint8_t *)0xFF8000;
|
||
uint32_t start_time = 0, end_time = 0;
|
||
uint64_t time_span = 0;
|
||
uint32_t tone_att = 1;
|
||
uint8_t reg_id = 0;
|
||
uint32_t wdata = 0;
|
||
uint32_t wmask = 0;
|
||
|
||
/* reset mac */
|
||
mac_reset(MAC_RST_REASON_COLD);
|
||
/* reset phy */
|
||
phy_reset(PHY_RST_REASON_COLD);
|
||
/* reset mac */
|
||
mac_reset(MAC_RST_REASON_COLD);
|
||
|
||
/* init gain table */
|
||
phy_init(PLC_PROTO_TYPE_SG, IOT_PLC_PHY_BAND_DFT, TONE_MASK_ID_NULL, true);
|
||
/* phy param init */
|
||
phy_param_init(PHY_PROTO_TYPE_GET());
|
||
|
||
/* tone */
|
||
phy_dfe_tone_cfg(1, 100, 0);
|
||
|
||
/* enable tx/rx and ad/da */
|
||
reg_id = ANA_GRANITE_TOP_REG;
|
||
wdata = TOP_EN_TX_MASK | TOP_EN_DAC_MASK | \
|
||
TOP_EN_RX_MASK | TOP_EN_ADC_MASK | TOP_ENLIC_MASK;
|
||
wmask = TOP_EN_TX_MASK | TOP_EN_DAC_MASK | \
|
||
TOP_EN_RX_MASK | TOP_EN_ADC_MASK | TOP_ENLIC_MASK;
|
||
phy_ana_i2c_write(reg_id, wdata, wmask);
|
||
|
||
/* enable geode */
|
||
phy_phase_ovr_set(PHY_PHASE_OVR_A, true, PHY_TXRX_OVR_TX);
|
||
phy_phase_ovr_set(PHY_PHASE_OVR_B, true, PHY_TXRX_OVR_TX);
|
||
phy_phase_ovr_set(PHY_PHASE_OVR_C, true, PHY_TXRX_OVR_TX);
|
||
|
||
/* copy phy info to iram */
|
||
*(dst_addr + 524) = 1;
|
||
|
||
/* get start time */
|
||
start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
while(1)
|
||
{
|
||
/* wait flag */
|
||
tmp = REG32(0xff0000 + 0x100);
|
||
if (tmp) {
|
||
for(uint16_t efuse_id = 0; efuse_id < 64; efuse_id++)
|
||
{
|
||
tmp = REG32(0xff0000 + efuse_id * 4);
|
||
//efuse_write(efuse_id*4, tmp);
|
||
}
|
||
break;
|
||
}
|
||
|
||
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;
|
||
}
|
||
if ((uint64_t)time_span > 200 * TICKS_MS) {
|
||
phy_dfe_tone_att_cfg(0, tone_att, tone_att);
|
||
if (tone_att++ > 5) {
|
||
tone_att = 1;
|
||
}
|
||
start_time = end_time;
|
||
}
|
||
}
|
||
|
||
while(1)
|
||
{
|
||
*((volatile uint32_t *)(0xff8214)) += 1;
|
||
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;
|
||
}
|
||
if ((uint64_t)time_span > 200 * TICKS_MS) {
|
||
phy_dfe_tone_att_cfg(0, tone_att, tone_att);
|
||
if (tone_att++ > 5) {
|
||
tone_att = 1;
|
||
}
|
||
start_time = end_time;
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
void ate_bringup_test(void)
|
||
{
|
||
uint8_t reg_id = 0;
|
||
uint8_t rodata = 0;
|
||
uint32_t rdata = 0;
|
||
uint32_t wdata = 0;
|
||
uint32_t wmask = 0;
|
||
|
||
while(1)
|
||
{
|
||
reg_id = ANA_GRANITE_TOP_REG;
|
||
phy_ana_i2c_read(reg_id, &rdata, &rodata);
|
||
iot_printf("TOP %x,%x\r\n", rdata, rodata);
|
||
|
||
reg_id = ANA_GRANITE_BIAS_REG_2;
|
||
phy_ana_i2c_read(reg_id, &rdata, &rodata);
|
||
iot_printf("BIAS2 %x,%x\r\n", rdata, rodata);
|
||
|
||
reg_id = ANA_GRANITE_BIAS_REG_1;
|
||
phy_ana_i2c_read(reg_id, &rdata, &rodata);
|
||
iot_printf("BIAS1 %x,%x\r\n", rdata, rodata);
|
||
|
||
reg_id = ANA_GRANITE_BIAS_REG_0;
|
||
phy_ana_i2c_read(reg_id, &rdata, &rodata);
|
||
iot_printf("BIAS0 %x,%x\r\n", rdata, rodata);
|
||
|
||
reg_id = ANA_GRANITE_TX_REG;
|
||
phy_ana_i2c_read(reg_id, &rdata, &rodata);
|
||
iot_printf("TX %x,%x\r\n", rdata, rodata);
|
||
|
||
reg_id = ANA_GRANITE_DAC_REG;
|
||
phy_ana_i2c_read(reg_id, &rdata, &rodata);
|
||
iot_printf("DAC %x,%x\r\n", rdata, rodata);
|
||
|
||
reg_id = ANA_GRANITE_PLL_REG;
|
||
phy_ana_i2c_read(reg_id, &rdata, &rodata);
|
||
iot_printf("PLL %x,%x\r\n", rdata, rodata);
|
||
|
||
reg_id = ANA_GRANITE_SADC_REG;
|
||
phy_ana_i2c_read(reg_id, &rdata, &rodata);
|
||
iot_printf("SADC %x,%x\r\n", rdata, rodata);
|
||
|
||
reg_id = ANA_GRANITE_ADC_REG;
|
||
phy_ana_i2c_read(reg_id, &rdata, &rodata);
|
||
iot_printf("ADC %x,%x\r\n", rdata, rodata);
|
||
|
||
reg_id = ANA_GRANITE_RX_REG_1;
|
||
phy_ana_i2c_read(reg_id, &rdata, &rodata);
|
||
iot_printf("RX1 %x,%x\r\n", rdata, rodata);
|
||
|
||
reg_id = ANA_GRANITE_RX_REG_0;
|
||
phy_ana_i2c_read(reg_id, &rdata, &rodata);
|
||
iot_printf("RX0 %x,%x\r\n", rdata, rodata);
|
||
|
||
wdata = TOP_EN_TX_OFFSET | TOP_EN_RX_OFFSET;
|
||
wmask = TOP_EN_TX_MASK | TOP_EN_RX_MASK;
|
||
phy_ana_i2c_write(reg_id, wdata, wmask);
|
||
}
|
||
}
|
||
|
||
void ate_chip_filter_test()
|
||
{
|
||
uint32_t tmp = 0;
|
||
uint8_t reg_id = 0;
|
||
uint8_t rodata = 0;
|
||
uint32_t rdata = 0;
|
||
uint32_t wdata = 0;
|
||
uint32_t wmask = 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, 1535);
|
||
phy_rxfd_rate1_det(0, 1535);
|
||
|
||
#if IOT_DTEST_ONLY_SUPPORT == 1
|
||
/* tone 3M */
|
||
phy_dfe_tone_cfg(1, 41, 0);
|
||
/* att */
|
||
phy_dfe_tone_att_cfg(0, 1, 1);
|
||
#endif
|
||
|
||
/* 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++)
|
||
{
|
||
#if 1
|
||
/* 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 */
|
||
reg_id = ANA_GRANITE_TX_REG;
|
||
phy_ana_i2c_read(reg_id, &rdata, &rodata);
|
||
REG_FIELD_SET(TX_GPGA, rdata, ate_granite_lpbk_gain_list[i].tx_pga_gain);
|
||
phy_ana_i2c_write(reg_id, rdata, ~0);
|
||
|
||
/* rx pgf bq pga*/
|
||
reg_id = ANA_GRANITE_RX_REG_0;
|
||
wdata = 3 << RX_GPGF_OFFSET;
|
||
wdata |= 3 << RX_GBQ_OFFSET;
|
||
wdata |= 4 << RX_GPGA_OFFSET;
|
||
wmask = RX_GPGF_MASK | RX_GBQ_MASK | RX_GPGA_MASK;
|
||
phy_ana_i2c_write(reg_id, wdata, wmask);
|
||
/* 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);
|
||
}
|
||
#endif
|
||
/* 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;
|
||
|
||
/* 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
|
||
}
|
||
}
|
||
|
||
/* get AMP(-30dB) and SNR */
|
||
glb_ate_info->csi_amp[0] = 10 * mlog10(golden_data/1000);
|
||
glb_ate_info->csi_snr[0] = 10 * mlog10(golden_data/noise_data);
|
||
if (glb_ate_info->csi_snr[0] >= 20) {
|
||
iot_printf("[ATE]Granite Loopback:amp %d, snr %d, ###success###\r\n", \
|
||
glb_ate_info->csi_amp[0], glb_ate_info->csi_snr[0]);
|
||
} else {
|
||
iot_printf("[ATE]Granite Loopback:amp %d, snr %d, ###fail###\r\n", \
|
||
glb_ate_info->csi_amp[0], glb_ate_info->csi_snr[0]);
|
||
}
|
||
|
||
/* enable sw csi buf access */
|
||
enable_sw_access_csi_buf(0);
|
||
}
|
||
|
||
/* revover to the state before ana loopback */
|
||
phy_txrx_loop_back_end();
|
||
|
||
}
|
||
uint8_t rdata[256] = {0};
|
||
uint8_t wdata[256] = {0};
|
||
uint32_t cost_time[11] = {0};
|
||
uint32_t wdg_cnt_start = 0;
|
||
uint32_t flash_cost_wdg_cnt_end = 0;
|
||
uint32_t ana_cost_wdg_cnt = 0;
|
||
#define FLASH_TEST_ADDRESS_OFFSET 0xfe000
|
||
|
||
uint8_t efuse_zero_check(uint32_t start)
|
||
{
|
||
uint32_t tmp;
|
||
uint32_t i;
|
||
uint32_t offset;
|
||
offset = start/(4 * 8);
|
||
iot_printf("efuse zero check test start\n");
|
||
for(i = offset; i < 64; i++) {
|
||
tmp = efuse_read(i * 4);
|
||
iot_printf("val[0x%02x]=0x%08x\n",i * 4, tmp);
|
||
if (i == 8) {
|
||
if (tmp != 0 && tmp != 0x1010000) {
|
||
iot_printf("[efuse check] val[0x%02x]=0x%08x\n", i * 4, tmp);
|
||
iot_printf("[ATE]efuse test ###fail###\n");
|
||
return 1;
|
||
}
|
||
} else {
|
||
if (tmp != 0) {
|
||
iot_printf("[efuse check] val[0x%02x]=0x%08x\n", i * 4, tmp);
|
||
iot_printf("[ATE]efuse test ###fail###\n");
|
||
return 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
uint8_t ate_flash_test()
|
||
{
|
||
uint8_t id[2] = {0};
|
||
volatile uint32_t i = 0;
|
||
int ret = 0;
|
||
uint32_t begin = 0;
|
||
uint32_t start_time = 0;
|
||
uint32_t end_time = 0;
|
||
|
||
/* init struct */
|
||
glb_ate_info->flash_read_id = 0xff;
|
||
glb_ate_info->flash_init_ret = 0xff;
|
||
glb_ate_info->flash_reg_sts = 0xff;
|
||
glb_ate_info->flash_erase_ret = 0xff;
|
||
glb_ate_info->flash_write_ret = 0xff;
|
||
glb_ate_info->flash_read_ret = 0xff;
|
||
|
||
/* id test */
|
||
uint32_t flash_test_offset = 0;
|
||
flash_init(0);
|
||
start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
glb_ate_info->flash_read_id = 0xaa;
|
||
if(flash_get_dev_id(&id) == HAL_ERROR) {
|
||
glb_ate_info->flash_read_id = 0xee;
|
||
return SFC_ATE_TEST_READ_ID_ERR;
|
||
}
|
||
glb_ate_info->flash_read_id = id[0];
|
||
end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
cost_time[1] = (end_time - start_time )/TICKS_US;
|
||
glb_ate_info->flash_id_cost = cost_time[1];
|
||
if (id[0] != 0xc8 && id[0] != 0x85) {
|
||
/* get id error */
|
||
iot_printf("[flash id]get id error, id value: %d\n", id[0]);
|
||
return SFC_ATE_TEST_READ_ID_ERR;
|
||
}
|
||
|
||
if (id[0] == 0x85) {
|
||
if (id[1] != 0x14 && id[1] != 0x13) {
|
||
/* flash device id not illegal */
|
||
glb_ate_info->flash_read_id = 0xdd;
|
||
iot_printf("[flash id]get device id error, id value: %d\n", id[1]);
|
||
return SFC_ATE_TEST_READ_ID_ERR;
|
||
}
|
||
if (id[1] == 0x13) {
|
||
flash_test_offset = 0;
|
||
iot_printf("8M flash\n");
|
||
} else {
|
||
flash_test_offset = 0x100000;
|
||
iot_printf("16M flash\n");
|
||
}
|
||
glb_ate_info->flash_device_id = id[1];
|
||
}
|
||
|
||
/* sfc set quad */
|
||
start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
begin = start_time;
|
||
glb_ate_info->flash_init_ret = 0xff;
|
||
uint8_t init_ret = 0;
|
||
init_ret = flash_init(1);
|
||
if ( init_ret == HAL_ERROR) {
|
||
/* set quad error */
|
||
iot_printf("[flash quad] set quad error\n");
|
||
glb_ate_info->flash_init_ret = 0xff;
|
||
return SFC_ATE_TEST_SET_QUAD_ERR;
|
||
} else if (init_ret == HAL_TIMEOUT) {
|
||
/* set quad error */
|
||
iot_printf("[flash quad] set quad timout\n");
|
||
glb_ate_info->flash_init_ret = 0xdd;
|
||
return SFC_ATE_TEST_SET_QUAD_ERR;
|
||
} else if (init_ret == HAL_BUSY) {
|
||
/* set quad timeout */
|
||
iot_printf("[flash quad] set quad timeout\n");
|
||
glb_ate_info->flash_init_ret = 0xee;
|
||
return SFC_ATE_TEST_SET_QUAD_ERR;
|
||
}
|
||
glb_ate_info->flash_init_ret = 0x0;
|
||
end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
cost_time[0] = (end_time - start_time )/TICKS_US;
|
||
glb_ate_info->flash_init_cost = cost_time[0];
|
||
|
||
iot_printf("[flash test] start.......\n");
|
||
|
||
/* quad sts query test */
|
||
#if 1
|
||
uint8_t sts = 0;
|
||
start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
glb_ate_info->flash_reg_sts = 0xff;
|
||
if (flash_get_sts_reg(&sts, 1) == HAL_ERROR) {
|
||
/* flash set quad error */
|
||
glb_ate_info->flash_reg_sts = 0xff;
|
||
iot_printf("[flash quad]quad mode error, status register:%02x\n", sts);
|
||
return SFC_ATE_TEST_SET_QUAD_ERR;
|
||
}
|
||
glb_ate_info->flash_reg_sts = sts;
|
||
end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
cost_time[2] = (end_time - start_time ) / TICKS_US;
|
||
glb_ate_info->flash_reg_cost = cost_time[2];
|
||
if ((sts & 0x2) != 0x2) {
|
||
/* flash set quad error */
|
||
iot_printf("[flash quad]quad mode error, status register:%02x\n", sts);
|
||
return SFC_ATE_TEST_SET_QUAD_ERR;
|
||
}
|
||
#endif
|
||
/* erase test */
|
||
start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
glb_ate_info->flash_erase_ret = 0xff;
|
||
ret = g_sfc_ctrl->erase_sector(FLASH_TEST_ADDRESS_OFFSET + flash_test_offset, \
|
||
MOD_SW_MODE_DIS);
|
||
end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
cost_time[3] = (end_time - start_time )/TICKS_US;
|
||
glb_ate_info->flash_erase_cost = cost_time[3];
|
||
if (ret) {
|
||
glb_ate_info->flash_erase_ret = ret;
|
||
iot_printf("[flash erase]erase command timeout(ret:%d)\n", ret);
|
||
return SFC_ATE_TEST_ERASE_SECTOR_ERR;
|
||
}
|
||
for(i = 0; i < 256; i++) {
|
||
rdata[i] = 0xdd;
|
||
}
|
||
/* flash single test , set div = 1 */
|
||
qspi_set_edge(0, 0, 1);
|
||
glb_ate_info->flash_erase_ret = 0xaa;
|
||
start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
ret = g_sfc_ctrl->read(rdata, FLASH_TEST_ADDRESS_OFFSET + flash_test_offset, \
|
||
sizeof(rdata), MOD_SFC_READ_SIG);
|
||
end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
qspi_set_edge(0, 0, 0);
|
||
cost_time[4] = (end_time - start_time ) / TICKS_US;
|
||
if (ret) {
|
||
glb_ate_info->flash_erase_ret = 0xef;
|
||
iot_printf("[flash erase]erase command timeout\n");
|
||
return SFC_ATE_TEST_ERASE_SECTOR_ERR;
|
||
}
|
||
for(i = 0; i < 256; i++) {
|
||
if (rdata[i] != 0xff) {
|
||
/* flash erase failed */
|
||
glb_ate_info->flash_erase_ret = 1;
|
||
iot_printf("[flash erase]read check error\n");
|
||
return SFC_ATE_TEST_ERASE_SECTOR_ERR;
|
||
}
|
||
}
|
||
glb_ate_info->flash_erase_ret = 0;
|
||
|
||
/* write test */
|
||
for(i = 0; i < 256; i++) {
|
||
wdata[i] = i;
|
||
rdata[i] = 0;
|
||
}
|
||
start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
glb_ate_info->flash_write_ret = 0xff;
|
||
ret = g_sfc_ctrl->write(wdata,FLASH_TEST_ADDRESS_OFFSET + flash_test_offset,
|
||
sizeof(wdata), MOD_SFC_PROG_QUAD, MOD_SW_MODE_DIS);
|
||
end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
cost_time[5] = (end_time - start_time )/TICKS_US;
|
||
glb_ate_info->flash_write_cost = cost_time[5];
|
||
if (ret) {
|
||
glb_ate_info->flash_write_ret = ret;
|
||
iot_printf("[flash write]write command error(ret:%d)\n", ret);
|
||
return SFC_ATE_TEST_WRITE_QUAD_ERR;
|
||
}
|
||
/* flash single test , set div = 1 */
|
||
qspi_set_edge(0, 0, 1);
|
||
glb_ate_info->flash_write_ret = 0xaa;
|
||
start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
ret = g_sfc_ctrl->read(rdata,FLASH_TEST_ADDRESS_OFFSET + flash_test_offset,
|
||
sizeof(wdata), MOD_SFC_READ_SIG);
|
||
end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
qspi_set_edge(0, 0, 0);
|
||
cost_time[6] = (end_time - start_time )/TICKS_US;
|
||
if (ret) {
|
||
glb_ate_info->flash_write_ret = 0xef;
|
||
iot_printf("[flash erase]erase command timeout\n");
|
||
return SFC_ATE_TEST_WRITE_QUAD_ERR;
|
||
}
|
||
for(i = 0; i < 256; i++) {
|
||
if (rdata[i] != wdata[i]) {
|
||
/* flash write quad failed */
|
||
glb_ate_info->flash_write_ret = 1;
|
||
iot_printf("[flash write]write check error, write: 0x%02x, read: 0x%02x\n",
|
||
wdata[i], rdata[i]);
|
||
return SFC_ATE_TEST_WRITE_QUAD_ERR;
|
||
}
|
||
}
|
||
glb_ate_info->flash_write_ret = 0;
|
||
|
||
/* read test */
|
||
for (i = 0; i < 256; i++) {
|
||
rdata[i] = 0;
|
||
}
|
||
start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
glb_ate_info->flash_read_ret = 0xff;
|
||
ret = g_sfc_ctrl->read(rdata,FLASH_TEST_ADDRESS_OFFSET + flash_test_offset,
|
||
sizeof(wdata), MOD_SFC_READ_QUAD_IO_FAST);
|
||
end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
cost_time[7] = (end_time - start_time )/TICKS_US;
|
||
glb_ate_info->flash_read_cost = cost_time[7];
|
||
if (ret) {
|
||
glb_ate_info->flash_read_ret = 0xee;
|
||
iot_printf("[flash read]read error, write: 0x%02x, read: 0x%02x\n",
|
||
wdata[i], rdata[i]);
|
||
return SFC_ATE_TEST_READ_QUAD_ERR;
|
||
}
|
||
for(i = 0; i < 256; i++) {
|
||
if (rdata[i] != wdata[i]) {
|
||
/* flash read serial failed */
|
||
glb_ate_info->flash_read_ret = 1;
|
||
iot_printf("[flash read]read error, write: 0x%02x, read: 0x%02x\n",
|
||
wdata[i], rdata[i]);
|
||
return SFC_ATE_TEST_READ_QUAD_ERR;
|
||
}
|
||
}
|
||
glb_ate_info->flash_read_ret = 0;
|
||
end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
cost_time[8] = (end_time - begin )/TICKS_US;
|
||
|
||
/* efuse zero check */
|
||
glb_ate_info->efuse_check_ret = 0xff;
|
||
start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
uint32_t efuse_offset = 256;
|
||
ret = efuse_zero_check(efuse_offset);
|
||
if (ret) {
|
||
glb_ate_info->efuse_check_ret = 1;
|
||
iot_printf("[efuse check] efuse zero (offset:%d) check failed\n",efuse_offset);
|
||
return SFC_ATE_TEST_EFUSE_ZERO_ERR;
|
||
}
|
||
end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
cost_time[9] = (end_time - start_time )/TICKS_US;
|
||
return SFC_ATE_TEST_OK;
|
||
}
|
||
|
||
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);
|
||
|
||
/* en adc and rx, disable dac and tx */
|
||
phy_ana_i2c_write(CFG_ANA_TOP_REG_ADDR, \
|
||
(1 << TOP_EN_ADC_OFFSET) | \
|
||
(1 << TOP_ENLIC_OFFSET) | \
|
||
(1 << TOP_EN_RX_OFFSET) | \
|
||
(0 << TOP_GLNA_OFFSET), \
|
||
TOP_EN_DAC_MASK | \
|
||
TOP_EN_ADC_MASK | \
|
||
TOP_ENLIC_MASK | \
|
||
TOP_EN_TX_MASK | \
|
||
TOP_EN_RX_MASK | \
|
||
TOP_GLNA_MASK);
|
||
|
||
/* 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_i2c_write(CFG_ANA_RX_REG_0_ADDR, \
|
||
0 << RX_PGFLOOPEN_OFFSET, \
|
||
RX_PGFLOOPEN_MASK);
|
||
/* rx pgf bq pga*/
|
||
phy_ana_i2c_write(ANA_GRANITE_RX_REG_0, \
|
||
1 << RX_GPGF_OFFSET | \
|
||
1 << RX_GBQ_OFFSET | \
|
||
0 << RX_GPGA_OFFSET | \
|
||
PHY_RX_PGF_OFFSET_DFT << RX_PGFOFFSET_OFFSET | \
|
||
PHY_RX_PGA_OFFSET_DFT << RX_PGAOFFSET_OFFSET | \
|
||
0 << RX_HPFENORD2_OFFSET | \
|
||
0 << RX_BYPHPF_OFFSET | \
|
||
0 << RX_PWDPGFOFFSET_OFFSET | \
|
||
0 << RX_PWDPGAOFFSET_OFFSET, \
|
||
RX_GPGF_MASK | \
|
||
RX_GBQ_MASK |
|
||
RX_GPGA_MASK | \
|
||
RX_PGFOFFSET_MASK | \
|
||
RX_PGAOFFSET_MASK | \
|
||
RX_HPFENORD2_MASK | \
|
||
RX_BYPHPF_MASK | \
|
||
RX_PWDPGAOFFSET_MASK | \
|
||
RX_PWDPGFOFFSET_MASK);
|
||
|
||
/* 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);
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
/* main entry */
|
||
void ate_entry(void)
|
||
{
|
||
uint32_t start_time = 0;
|
||
uint32_t end_time = 0;
|
||
uint64_t time_span = 0;
|
||
|
||
start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
|
||
#if ATE_TEST_CASE_ID == 6
|
||
uint32_t ret = ERR_OK;
|
||
uint16_t tx_dc[4] = {0};
|
||
uint16_t rx_dc[PHY_GAIN_STEP_MAX] = {0};
|
||
|
||
int32_t sadc_dc[4] = {0};
|
||
int32_t sadc_arvg[4] = {0};
|
||
int32_t sadc_input_voltg[2] = {1200, 148};
|
||
|
||
#if 1
|
||
uint8_t sadc_bias_ical = 0;
|
||
uint8_t sadc_trim_adcref = 3;
|
||
uint8_t sadc_trim_dcdc = 3;
|
||
int16_t vtemp = 0;
|
||
int8_t fail_cnt = 0;
|
||
#endif
|
||
#endif
|
||
|
||
#if HW_PLATFORM > HW_PLATFORM_SIMU
|
||
#if EDA_SIMU_SUPPORT != 1
|
||
for(volatile uint32_t i = 0; i < 5000; i++);
|
||
/* serial init */
|
||
iot_print_config(true);
|
||
dbg_uart_init();
|
||
iot_printf("ate_test begin...\n");
|
||
#endif
|
||
#endif
|
||
|
||
ate_init();
|
||
|
||
wdg_cnt_enable(1);
|
||
wdg_enable(1);
|
||
REG32(0x62010008) = 0x0;
|
||
REG32(0x4400e008) = 0x0;
|
||
wdg_cnt_start = WDG1_READ_REG(CFG_WDG_CNT_ADDR);
|
||
/* efuse chip-id nad version */
|
||
#if ATE_TEST_CASE_ID == 1
|
||
ate_efuse_entry();
|
||
//ate_efuse_version_reserve();
|
||
/* test all and report result */
|
||
#elif ATE_TEST_CASE_ID == 2
|
||
ate_analog_test_demo();
|
||
#elif ATE_TEST_CASE_ID == 3
|
||
ate_bringup_test();
|
||
#elif ATE_TEST_CASE_ID == 4
|
||
ate_chip_filter_test();
|
||
while(1);
|
||
#elif ATE_TEST_CASE_ID == 5
|
||
volatile uint32_t i;
|
||
while(1)
|
||
{
|
||
/* tx dc calibration */
|
||
tx_dc_calibration(tx_dc);
|
||
|
||
/* rx dc calibration */
|
||
rx_dc_calibration(rx_dc);
|
||
|
||
/* granite loopback */
|
||
mac_granite_loop_back();
|
||
|
||
/* geode loopback */
|
||
mac_geode_loop_back();
|
||
|
||
/* 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);
|
||
|
||
for(i = 0; i< 100000; i++);
|
||
}
|
||
#else
|
||
iot_phy_sts_info_t total_sts = {0};
|
||
glb_ate_info->result = 0;
|
||
glb_ate_info->ret_flag = 0;
|
||
|
||
/* 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);
|
||
|
||
#if 0
|
||
mac_tx_back_t tx_back;
|
||
/* tx to golden unit and receive phy info */
|
||
mac_dut_tx(PHY_PHASE_OVR_B,PLC_PROTO_TYPE_SG,FC_DELIM_SOF,1,&tx_back);
|
||
glb_ate_info->rssi = tx_back.info_arry[1];
|
||
glb_ate_info->gain = tx_back.info_arry[0];
|
||
glb_ate_info->est_dc = tx_back.info_arry[2];
|
||
glb_ate_info->est_ppm = tx_back.info_arry[3];
|
||
glb_ate_info->avg_snr = tx_back.info_arry[4];
|
||
#endif
|
||
|
||
/* tx/rx cnt */
|
||
phy_sts_get(&total_sts);
|
||
glb_ate_info->sync_ok_cnt = total_sts.sync_ok_cnt;
|
||
glb_ate_info->fc_crc_ok_cnt = total_sts.fc_crc_ok_cnt;
|
||
glb_ate_info->fc_crc_fail_cnt = total_sts.fc_crc_fail_cnt;
|
||
glb_ate_info->pld_crc_ok_cnt = total_sts.pld_crc_ok_cnt;
|
||
glb_ate_info->pld_crc_fail_cnt = total_sts.pld_crc_fail_cnt;
|
||
|
||
/* copy tx, rx, loopback results to FDMA mem */
|
||
//os_mem_cpy(dst_addr, glb_ate_info, sizeof(glb_ate_info));
|
||
|
||
#if ATE_SADC_SUPPORT == 1
|
||
/* sadc test */
|
||
int32_t sadc_ret = 0;
|
||
int32_t rx_adc_ret = 0;
|
||
phy_adc_mon_sel_set(true);
|
||
|
||
#if 1
|
||
uint8_t adc_cfg_dly = 3;
|
||
uint8_t adc_f_h = 3;
|
||
sadc_ret = rx_adc_eoc_meta_task(&adc_cfg_dly, &adc_f_h);
|
||
if (sadc_ret) {
|
||
iot_printf("[ATE]sadc eoc meta ###fail###\n");
|
||
glb_ate_info->ret_flag |= ERR_BIT(8);
|
||
} else {
|
||
iot_printf("[ATE]sadc eoc meta ###success###\n");
|
||
}
|
||
glb_ate_info->adc_cfg_dly = adc_cfg_dly;
|
||
glb_ate_info->adc_f_h = adc_f_h;
|
||
#endif
|
||
rx_adc_ret = sadc_dc_calibration_task(sadc_dc);
|
||
glb_ate_info->sadc_dc[0] = sadc_dc[0];
|
||
glb_ate_info->sadc_dc[1] = sadc_dc[1];
|
||
glb_ate_info->sadc_dc[2] = sadc_dc[2];
|
||
glb_ate_info->sadc_dc[3] = sadc_dc[3];
|
||
if (sadc_ret) {
|
||
iot_printf("[ATE]rx adc dc calibration ###fail###\n");
|
||
glb_ate_info->ret_flag |= ERR_BIT(9);
|
||
} else {
|
||
iot_printf("[ATE]rx adc dc calibration ###success###\n");
|
||
}
|
||
|
||
sadc_ret = sadc_ref_voltg_task(sadc_arvg, sadc_dc, sadc_input_voltg);
|
||
if (sadc_ret) {
|
||
iot_printf("[ATE]sadc ref voltage ###fail###\n");
|
||
glb_ate_info->ret_flag |= ERR_BIT(10);
|
||
} else {
|
||
iot_printf("[ATE]sadc ref voltage ###success###\n");
|
||
}
|
||
glb_ate_info->sadc_ref[0] = sadc_arvg[0];
|
||
glb_ate_info->sadc_ref[1] = sadc_arvg[1];
|
||
glb_ate_info->sadc_ref[2] = sadc_arvg[2];
|
||
glb_ate_info->sadc_ref[3] = sadc_arvg[3];
|
||
#if 1
|
||
sadc_ret = atb_for_ical(&sadc_bias_ical, sadc_dc[1], sadc_input_voltg[0], sadc_arvg[1]);
|
||
if (sadc_ret) {
|
||
iot_printf("[ATE]sadc bias ical ###fail###\n");
|
||
glb_ate_info->ret_flag |= ERR_BIT(11);
|
||
} else {
|
||
iot_printf("[ATE]sadc bias ical ###success###\n");
|
||
}
|
||
glb_ate_info->sadc_ical_code = sadc_bias_ical;
|
||
|
||
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]);
|
||
if (fail_cnt) {
|
||
iot_printf("[ATE]sadc inner signal ###fail###\n");
|
||
glb_ate_info->ret_flag |= ERR_BIT(12);
|
||
} else {
|
||
iot_printf("[ATE]sadc inner signal ###success###\n");
|
||
}
|
||
glb_ate_info->sadc_adcref_code = sadc_trim_adcref;
|
||
glb_ate_info->sadc_dcdc_code = sadc_trim_dcdc;
|
||
glb_ate_info->sadc_vtemp = vtemp;
|
||
|
||
/* copy data to FDMA mem */
|
||
//os_mem_cpy(dst_addr, glb_ate_info, sizeof(glb_ate_info));
|
||
#endif
|
||
|
||
#endif
|
||
|
||
/* nf test */
|
||
ret = ate_nf_test();
|
||
if (ret != ERR_OK) {
|
||
glb_ate_info->ret_flag |= ERR_BIT(4);
|
||
}
|
||
|
||
/* fuse the glb info */
|
||
#if ATE_FUSE_INFO_EN == 1
|
||
tmp = efuse_read(CFG_EFUSE_BITS32_6_ADDR);
|
||
REG_FIELD_SET(ANA_TRIM_PARA_F0,tmp,glb_ate_info->rssi);
|
||
tmp = tmp & ANA_TRIM_PARA_F0_MASK;
|
||
efuse_write(CFG_EFUSE_BITS32_6_ADDR,tmp);
|
||
#endif
|
||
|
||
#if (ATE_GEODE_ONLY != 1)
|
||
/* ate flash test */
|
||
end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
time_span = end_time - start_time;
|
||
ana_cost_wdg_cnt = WDG1_READ_REG(CFG_WDG_CNT_ADDR) - wdg_cnt_start;
|
||
glb_ate_info->ana_wdg_cost_cnt = ana_cost_wdg_cnt;
|
||
uint8_t flash_ret = ate_flash_test();
|
||
flash_cost_wdg_cnt_end = WDG1_READ_REG(CFG_WDG_CNT_ADDR);
|
||
glb_ate_info->flash_wdg_cost_cnt = flash_cost_wdg_cnt_end - ana_cost_wdg_cnt;
|
||
|
||
wdg_deinit(1);
|
||
if (flash_ret) {
|
||
iot_printf("flash test result: %02x\n", flash_ret);
|
||
iot_printf("[ATE]flash test ###fail###\n");
|
||
glb_ate_info->ret_flag |= flash_ret<<16;
|
||
} else {
|
||
iot_printf("[ATE]flash test ###success###\n");
|
||
}
|
||
//os_mem_cpy(dst_addr+1, glb_ate_info->ret_flag, sizeof(glb_ate_info->ret_flag));
|
||
#endif // ATE_GEODE_ONLY
|
||
|
||
/* ate test result, bypass geode */
|
||
|
||
#if (ATE_GEODE_ONLY == 1)
|
||
apb_enable(APB_GPIO);
|
||
iot_printf("glb_ate_info->ret_flag : 0x%d\n", glb_ate_info->ret_flag);
|
||
if((glb_ate_info->ret_flag & 0x8) == 0)
|
||
#else // ATE_GEODE_ONLY
|
||
if(glb_ate_info->ret_flag == 0x0)
|
||
#endif // ATE_GEODE_ONLY
|
||
{
|
||
glb_ate_info->result = ATE_TEST_OK;
|
||
#if (ATE_GEODE_ONLY == 1)
|
||
/* return gpio info */
|
||
/* set gpio 8 to high, gpio 9 to low, gpio 10 to low */
|
||
iot_printf("gpio return ok information\n");
|
||
gpio_mtx_enable();
|
||
apb_enable(APB_GPIO);
|
||
gpio_pin_select(8, 0);
|
||
gpio_pin_select(9, 0);
|
||
gpio_pin_select(10, 0);
|
||
|
||
gpio_pin_wpu(8, 1);
|
||
gpio_pin_wpd(8, 0);
|
||
|
||
gpio_pin_wpu(9, 0);
|
||
gpio_pin_wpd(9, 1);
|
||
|
||
gpio_pin_wpu(10, 0);
|
||
gpio_pin_wpd(10, 1);
|
||
#endif
|
||
} else {
|
||
glb_ate_info->result = ATE_TEST_FAIL;
|
||
#if (ATE_GEODE_ONLY == 1)
|
||
/* return gpio info */
|
||
/* set gpio 8 to high, gpio 9 to low, gpio 10 to low */
|
||
iot_printf("gpio return fail information\n");
|
||
gpio_mtx_enable();
|
||
apb_enable(APB_GPIO);
|
||
gpio_pin_select(8, 0);
|
||
gpio_pin_select(9, 0);
|
||
gpio_pin_select(10, 0);
|
||
gpio_pin_wpu(8, 1);
|
||
gpio_pin_wpu(9, 1);
|
||
gpio_pin_wpd(10, 1);
|
||
#endif
|
||
}
|
||
|
||
/* cpy data to FDMA mem */
|
||
//os_mem_cpy(dst_addr, glb_ate_info->result, sizeof(glb_ate_info->result));
|
||
|
||
#endif//TEST_ID
|
||
|
||
iot_printf("[ATE]end\n");
|
||
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);
|
||
|
||
}
|
||
|
||
#ifdef __GNUC__
|
||
int main(void) {
|
||
|
||
ate_entry();
|
||
|
||
return 0;
|
||
}
|
||
#endif // __GCC__
|