Files
kunlun/dtest/ate_test/ate_main.c
2024-09-28 14:24:04 +08:00

1571 lines
51 KiB
C
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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

/****************************************************************************
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__