1571 lines
		
	
	
		
			51 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			1571 lines
		
	
	
		
			51 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /****************************************************************************
 | |||
|  | 
 | |||
|  | 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__
 |