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