716 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			716 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /* os shim includes */
 | |
| #include "os_utils.h"
 | |
| 
 | |
| #include "chip_reg_base.h"
 | |
| #include "hw_reg_api.h"
 | |
| #include "mac_reset.h"
 | |
| #include "mac_sys_reg.h"
 | |
| #include "mac_rx_reg.h"
 | |
| #include "iot_pkt_api.h"
 | |
| #include "plc_const.h"
 | |
| #include "os_mem.h"
 | |
| #include "rx_pb_reorder.h"
 | |
| #include "phy_reg.h"
 | |
| #include "phy_bb.h"
 | |
| #include "phy_chn.h"
 | |
| #include "hw_tonemask.h"
 | |
| #include "iot_io.h"
 | |
| #include "phy_ana.h"
 | |
| #include "mac_rx_buf_ring.h"
 | |
| #include "iot_config.h"
 | |
| #include "plc_protocol.h"
 | |
| #include "phy_rxtd_reg.h"
 | |
| #include "phy_rx_fd_reg.h"
 | |
| #include "phy_txrx_pwr.h"
 | |
| #include "phy_dfe_reg.h"
 | |
| #include "tx_mpdu_start.h"
 | |
| #include "phy_cal.h"
 | |
| #include "iot_errno_api.h"
 | |
| #if IOT_DTEST_ONLY_SUPPORT == 0
 | |
| #include "iot_cal_data.h"
 | |
| #endif
 | |
| #include "hw_phy_api.h"
 | |
| #include "tx_entry.h"
 | |
| #include "iot_config_api.h"
 | |
| #include "iot_gpio_api.h"
 | |
| #include "phy_test_api.h"
 | |
| #include "mac_init_api.h"
 | |
| #include "phy_tools.h"
 | |
| #include "hw_tx.h"
 | |
| #include "hw_rx.h"
 | |
| #include "mac_channel.h"
 | |
| #include "mpdu_header.h"
 | |
| #include "iot_board_api.h"
 | |
| #include "iot_pt_func.h"
 | |
| #include "hal_rx.h"
 | |
| #include "iot_version_api.h"
 | |
| #include "mp_mode.h"
 | |
| #include "iot_oem.h"
 | |
| #include "iot_efuse.h"
 | |
| 
 | |
| iot_pt_ctxt_t iot_pt_ctxt = {{false}, {0}};
 | |
| 
 | |
| void mp_pt_golden_unit_rx()
 | |
| {
 | |
|     uint8_t *pb_addr_ptr = 0;
 | |
|     uint8_t cur_nid = 0, pwr_dbuv = 0;
 | |
|     uint8_t gpio_val = 0, gpio_val_new = 0;
 | |
|     uint8_t gpio_tx_led = 0, gpio_rx_led = 0;
 | |
|     int16_t ppm_cal = 0;
 | |
|     uint32_t tmp = 0;
 | |
|     uint32_t start_time = 0, end_time = 0;
 | |
|     uint64_t time_span = 0;
 | |
|     uint64_t led_control_time = 1000 * TICKS_MS;
 | |
| 
 | |
|     dut_flag_set(false);
 | |
|     mac_rx_phy_info_t *phy_info = phy_info_ptr_get();
 | |
| 
 | |
|     /* mac tx common init interface */
 | |
|     tx_common_init(IOT_PLC_PHY_MP_BAND);
 | |
| 
 | |
|     /* setup the rx ring */
 | |
|     rx_ring_setup_hw(0, NULL);
 | |
| 
 | |
|     /* enable the rx ring */
 | |
|     rx_ring_enable(0, true);
 | |
| 
 | |
|     /* disable intr */
 | |
|     RGF_MAC_WRITE_REG(CFG_INT_ENA_MASK_ADDR,0);
 | |
| 
 | |
|     /* led init */
 | |
|     gpio_tx_led = iot_board_get_gpio(GPIO_TX_LED);
 | |
|     iot_gpio_open_as_output(gpio_tx_led);
 | |
|     gpio_rx_led = iot_board_get_gpio(GPIO_RX_LED);
 | |
|     iot_gpio_open_as_output(gpio_rx_led);
 | |
| 
 | |
|     /* set nid by gpio status */
 | |
|     glb_cfg.nid = mp_pt_golden_nid_config();
 | |
|     iot_printf("Global nid has been set to %d.\n", glb_cfg.nid);
 | |
| 
 | |
|     /* Initial force phase A */
 | |
| #if K48_STA_MULTI_CHANNEL_SELECT_ENABLE
 | |
|     iot_printf("Golden Rx Init K48 STA L/G Phase: %d...\n", MAC_CHANNEL_L_PE);
 | |
|     iot_mac_k48sta_setchannel_gpio(MAC_CHANNEL_L_PE);
 | |
| #else
 | |
|     iot_printf("Golden Rx Init A Phase: %d...\n", PLC_PHASE_A);
 | |
|     phy_rx_phase_force_set(true, PLC_PHASE_A);
 | |
| #endif
 | |
| 
 | |
|     /* expand pkt detect thd */
 | |
|     phy_rxfd_pkt_det_thd_set(PT_PHY_PKT_TH, PT_PHY_PKT_TH);
 | |
|     /* check if rx ring has content */
 | |
|     start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | |
|     do {
 | |
|         while (!is_rx_ring0_empty()) {
 | |
|             rx_buf_hdr_t *pb_buf_ptr = NULL;
 | |
|             uint8_t *rx_buf_tmp = pop_rx_buf_from_ring(0);
 | |
|             if (rx_buf_tmp) {
 | |
|                 pb_buf_ptr = (rx_buf_hdr_t *)rx_buf_tmp;
 | |
|                 phy_plt_case_info_t *case_info = ((phy_plt_case_info_t *)
 | |
|                     (rx_buf_tmp + PB_PAYLOAD_OFFSET));
 | |
|                 cur_nid = mac_get_nid_from_fc(phy_proto_type_get(),
 | |
|                     mac_rx_mpdu_st_get_fc_addr(&pb_buf_ptr->mpdu_st));
 | |
|                 iot_printf("Current nid is %d.\n", cur_nid);
 | |
| 
 | |
|                 if (0 == K48_STA_MULTI_CHANNEL_SELECT_ENABLE
 | |
|                     && 0 == K48_CCO_MULTI_CHANNEL_SELECT_ENABLE) {
 | |
|                     /* Reduce power for tx */
 | |
|                     pwr_dbuv = PHY_FULL_PWR_DBUV - PHY_MP_PWR_REDUCE;
 | |
|                     iot_printf("Reduce tx power to: %d (decrease: %d).\n",
 | |
|                         pwr_dbuv, PHY_MP_PWR_REDUCE);
 | |
|                     phy_pwr_adjust_set(pwr_dbuv);
 | |
|                 }
 | |
| 
 | |
|                 if (cur_nid == glb_cfg.nid &&
 | |
|                     case_info->magic_num0 == PHY_PDL_TX_MAGIC_NUM0 &&
 | |
|                     case_info->magic_num1 == PHY_PDL_TX_MAGIC_NUM1) {
 | |
|                     switch (case_info->case_id) {
 | |
|                         /* for communication success rate */
 | |
|                         case FTM_CMD_TX_CSR:
 | |
|                             /* Reduce power for csr */
 | |
|                             pwr_dbuv = PHY_FULL_PWR_DBUV - PHY_MP_PWR_REDUCE - case_info->pwr_set;
 | |
|                             iot_printf("Communication success test reduce power to: %d.\n", pwr_dbuv);
 | |
|                             phy_pwr_adjust_set(pwr_dbuv);
 | |
| 
 | |
|                             /* global attr */
 | |
|                             glb_cfg.tmi = case_info->tmi;
 | |
|                             glb_cfg.p_type = case_info->pkt_type;
 | |
|                             glb_cfg.ack_en = false;
 | |
| 
 | |
|                             /* clr cnt */
 | |
|                             tmp = RGF_MAC_READ_REG(CFG_TX_DBG_CTRL_ADDR);
 | |
|                             REG_FIELD_SET(CFG_TX_DBG_CNT_CLR,tmp,0x1);
 | |
|                             RGF_MAC_WRITE_REG(CFG_TX_DBG_CTRL_ADDR,tmp);
 | |
| 
 | |
|                             while (1) {
 | |
|                                 tx_send_packet_interval(10);
 | |
| 
 | |
|                                 tmp = RGF_MAC_READ_REG(CFG_TX_DBG_CNT_ADDR)>>16;
 | |
|                                 if (tmp >= case_info->pkt_cnt) {
 | |
|                                     start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | |
|                                     break;
 | |
|                                 }
 | |
|                             }
 | |
| 
 | |
|                             /* global tmi recovery */
 | |
|                             glb_cfg.tmi = MAC_TMI_4;
 | |
|                             /* fix start time for print */
 | |
|                             start_time -= g_plc_dt_ctxt.indep.print_period_ms*TICKS_MS;
 | |
|                             break;
 | |
|                         /* for golden phase switch */
 | |
|                         case FTM_CMD_TX_PHASE:
 | |
|                             /* change golden phase */
 | |
|                             glb_cfg.phase = case_info->phase_num;
 | |
|                             iot_mac_chan_select(case_info->phase_num);
 | |
|                             for (uint32_t i = 0; i < 3; i++) {
 | |
|                                 tx_send_packet_interval(TX_PKT_SEND_INTERVAL);
 | |
|                             }
 | |
|                             iot_printf("Golden respond tx phase id send pkts\n");
 | |
|                             break;
 | |
|                         /* for csi dump */
 | |
|                         case FTM_CMD_TX_CSI:
 | |
|                             for (uint32_t i = 0; i < 5; i++) {
 | |
|                                 tx_send_packet_interval(TX_PKT_SEND_INTERVAL);
 | |
|                             }
 | |
|                             iot_printf("Golden respond tx csi dump send pkts\n");
 | |
|                             break;
 | |
|                         /* for deviation calibration */
 | |
|                         case FTM_CMD_TX_CALI:
 | |
|                             /* tx back with phy info */
 | |
|                             pb_addr_ptr = (uint8_t *)phy_get_pb_buf_ptr_from_mpdu(mpdu_start);
 | |
|                             *pb_addr_ptr++ = phy_info->gain;
 | |
|                             *pb_addr_ptr++ = phy_info->rmi;
 | |
|                             *pb_addr_ptr++ = phy_info->est_dc;
 | |
|                             tmp = PHY_DFE_READ_REG(CFG_BB_PPM_SETTING_ADDR);
 | |
|                             ppm_cal = (int16_t)REG_FIELD_GET(SW_RX_PPM,tmp);
 | |
|                             *pb_addr_ptr++ = (ppm_cal >> 4) & 0xFF; //est_ppm low;
 | |
|                             *pb_addr_ptr++ = (ppm_cal >> 12) & 0xFF; //est_ppm high;
 | |
|                             *pb_addr_ptr++ = phy_info->avr_snr;
 | |
|                             iot_printf("return gain:%d, rmi:%d, est_dc:%d, ppm:%d, snr:%d.\n",
 | |
|                                 phy_info->gain,
 | |
|                                 phy_info->rmi,
 | |
|                                 phy_info->est_dc,
 | |
|                                 ppm_cal,
 | |
|                                 phy_info->avr_snr);
 | |
|                             tx_send_packet_interval(TX_PKT_SEND_INTERVAL);
 | |
|                             break;
 | |
|                         case FTM_CMD_TX_BAND:
 | |
|                             /* change golden band */
 | |
|                             iot_printf("Golden FTM_CMD_TX_BAND\n");
 | |
|                             for (uint32_t i = 0; i < 3; i++) {
 | |
|                                 tx_send_packet_interval(TX_PKT_SEND_INTERVAL);
 | |
|                             }
 | |
|                             iot_printf("Golden respond tx band id send pkts\n");
 | |
|                             os_delay(2000);
 | |
|                             glb_cfg.band_id= case_info->phase_num;
 | |
|                             iot_printf("golden will shift to new band: %d.\n",
 | |
|                                 case_info->phase_num);
 | |
|                             tx_common_init(case_info->phase_num);
 | |
|                             rx_common_init(case_info->phase_num);
 | |
|                             break;
 | |
|                         case FTM_CMD_TX_GET_GOLDEN_INFO:
 | |
|                             iot_printf("Golden FTM_CMD_TX_GET_GOLDEN_INFO\n");
 | |
|                             pb_addr_ptr = (uint8_t *)phy_get_pb_buf_ptr_from_mpdu(mpdu_start);
 | |
|                             iot_pt_golden_info info = { 0 };
 | |
|                             iot_efuse_get_mac_addr(info.mac);
 | |
|                             info.version = iot_version_hex();
 | |
|                             os_mem_cpy(pb_addr_ptr, &info, sizeof(info));
 | |
|                             iot_printf("golden mac:%x:%x:%x:%x:%x:%x,version:%d\n",
 | |
|                                 info.mac[0], info.mac[1], info.mac[2], info.mac[3],
 | |
|                                 info.mac[4], info.mac[5], info.version);
 | |
|                             /* tx back with golden info */
 | |
|                             tx_send_packet_interval(TX_PKT_SEND_INTERVAL);
 | |
|                             break;
 | |
|                         default:
 | |
|                             break;
 | |
|                     }
 | |
|                 }
 | |
|                 else {
 | |
|                     iot_printf("Golden received packets, case info not matched!");
 | |
|                     break;
 | |
|                 }
 | |
| 
 | |
|                 if (0 == K48_STA_MULTI_CHANNEL_SELECT_ENABLE
 | |
|                     && 0 == K48_CCO_MULTI_CHANNEL_SELECT_ENABLE) {
 | |
|                     /* pwr config default */
 | |
|                     phy_pwr_adjust_set(PHY_FULL_PWR_DBUV - PHY_MP_PWR_REDUCE);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         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 (time_span < led_control_time) {
 | |
|             gpio_val = 1;
 | |
|         } else if (time_span < led_control_time * 2) {
 | |
|             gpio_val = 0;
 | |
|         } else if (time_span < led_control_time * 3) {
 | |
|             gpio_val = 1;
 | |
|         } else if (time_span < led_control_time * 4) {
 | |
|             gpio_val = 0;
 | |
|         } else {
 | |
|             gpio_val = 1;
 | |
|         }
 | |
|         if (gpio_val != gpio_val_new) {
 | |
|             iot_gpio_value_set(gpio_tx_led, gpio_val);
 | |
|             iot_gpio_value_set(gpio_rx_led, gpio_val_new);
 | |
|             gpio_val_new = gpio_val;
 | |
|         }
 | |
| 
 | |
|         if ((uint64_t)time_span >
 | |
|             g_plc_dt_ctxt.indep.print_period_ms*TICKS_MS) {
 | |
|             start_time = end_time;
 | |
|             mac_pkt_info_cnt_print();
 | |
|         }
 | |
|     } while (true); /* keep check */
 | |
| }
 | |
| 
 | |
| void mp_pt_dut_tx(iot_ftm_tx_cmd_t *tx_cmd,
 | |
|     uint8_t anf_en,
 | |
|     uint8_t power,
 | |
|     int16_t g_ppm,
 | |
|     void *buf_ptr)
 | |
| {
 | |
|     uint8_t *rx_buf_tmp;
 | |
|     uint8_t snr_filter = 0, cur_nid = 0, m_tmi = 0;
 | |
|     int16_t real_ppm = 0;
 | |
|     uint32_t tmp = 0;
 | |
|     static volatile uint8_t first_flag = 0;
 | |
|     uint32_t start_time = 0, end_time = 0;
 | |
|     uint32_t phase = 0, mode_num = 0;
 | |
|     uint64_t time_span = 0;
 | |
|     rx_buf_hdr_t *pb_buf_ptr = NULL;
 | |
| 
 | |
|     phase = tx_cmd->phase;
 | |
|     mode_num = tx_cmd->total_num;
 | |
|     m_tmi = tx_cmd->mac_tmi;
 | |
| 
 | |
|     /* dut flag for pop */
 | |
|     dut_flag_set(true);
 | |
| 
 | |
|     if (!first_flag) {
 | |
|         /* mac rx common init interface */
 | |
|         rx_common_init(IOT_PLC_PHY_MP_BAND);
 | |
| 
 | |
|         /* mac tx common init interface */
 | |
|         tx_common_init(IOT_PLC_PHY_MP_BAND);
 | |
| 
 | |
|         /* setup the rx ring */
 | |
|         rx_ring_setup_hw(0, NULL);
 | |
| 
 | |
|         /* enable the rx ring */
 | |
|         rx_ring_enable(0, true);
 | |
| 
 | |
|         /* disable intr */
 | |
|         RGF_MAC_WRITE_REG(CFG_INT_ENA_MASK_ADDR,0);
 | |
| 
 | |
|         /* update flag */
 | |
|         first_flag = 1;
 | |
|     }
 | |
| 
 | |
|     if (phy_is_sta_role()) {
 | |
|         /* set tx rx phase */
 | |
|         glb_cfg.phase = PLC_PHASE_A;
 | |
|     } else {
 | |
|         glb_cfg.phase = phase;
 | |
|     }
 | |
|     iot_mac_chan_select(phase);
 | |
| 
 | |
|     /* Reduce power for tx */
 | |
|     if (0 == K48_STA_MULTI_CHANNEL_SELECT_ENABLE
 | |
|         && 0 == K48_CCO_MULTI_CHANNEL_SELECT_ENABLE) {
 | |
|         phy_pwr_adjust_set(PHY_FULL_PWR_DBUV - PHY_MP_PWR_REDUCE);
 | |
|     }
 | |
| 
 | |
|     start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | |
| 
 | |
|     /* set payload info */
 | |
|     phy_plt_case_info_t *case_info =
 | |
|         (phy_plt_case_info_t *)phy_get_pb_buf_ptr_from_mpdu(mpdu_start);
 | |
|     /* magic number */
 | |
|     case_info->magic_num0 = PHY_PDL_TX_MAGIC_NUM0;
 | |
|     case_info->magic_num1 = PHY_PDL_TX_MAGIC_NUM1;
 | |
| 
 | |
|     if (FTM_CMD_TX_PHASE == mode_num) {
 | |
|         /* adjust phase for golden */
 | |
|         mac_tx_back_t *info = (mac_tx_back_t *)buf_ptr;
 | |
|         /* case id */
 | |
|         case_info->case_id = FTM_CMD_TX_PHASE;
 | |
|         /* phase num */
 | |
|         case_info->phase_num = phase;
 | |
| 
 | |
|         for (uint8_t l_index = 1; l_index <= 3; l_index++) {
 | |
|             /* set tx rx phase */
 | |
|             glb_cfg.phase = l_index;
 | |
|             iot_mac_chan_select(l_index);
 | |
|             /* step1:tx packet */
 | |
|             tx_send_packet_interval(TX_PKT_SEND_INTERVAL);
 | |
| 
 | |
|             /* step2:wait to receive packt */
 | |
|             rx_buf_tmp = rx_recev_packet();
 | |
|             if (!rx_buf_tmp) {
 | |
|                 iot_printf("Cannot receive golden packets replay...\n");
 | |
|                 continue;
 | |
|             } else {
 | |
|                 pb_buf_ptr = (rx_buf_hdr_t *)rx_buf_tmp;
 | |
|                 cur_nid = mac_get_nid_from_fc(phy_proto_type_get(),
 | |
|                     mac_rx_mpdu_st_get_fc_addr(&pb_buf_ptr->mpdu_st));
 | |
|                 if ((pb_buf_ptr->att.is_fcserr == 0)
 | |
|                     && (pb_buf_ptr->pb_ed.rx_pb_crc_err == 0)
 | |
|                     && (cur_nid == glb_cfg.nid)) {
 | |
|                     iot_printf("Channel conmunication completes!\n");
 | |
|                     info->info_arry[0] = phase;
 | |
|                     info->len = 1;
 | |
|                     break;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         /* set back tx rx phase */
 | |
|         glb_cfg.phase = phase;
 | |
|         iot_mac_chan_select(phase);
 | |
|     } else if (FTM_CMD_TX_CALI == mode_num) {
 | |
|         /* ppm calibration */
 | |
|         glb_cfg.p_type = FC_DELIM_BEACON;
 | |
|         mac_tx_back_t *info = (mac_tx_back_t *)buf_ptr;
 | |
|         phy_ppm_cal_and_update_hw(PHY_CAL_UNIT_1_1, 0, IOT_SUPPORT_RATE_SR, BB_PPM_TXRX);
 | |
| 
 | |
|         /* case id */
 | |
|         case_info->case_id = FTM_CMD_TX_CALI;
 | |
| 
 | |
|         /* clear current pkt */
 | |
|         RX_RING_SET_RD_IDX(0, RX_RING_GET_WR_IDX(0));
 | |
| 
 | |
|         /* expand pkt detect threshold */
 | |
|         phy_rxfd_pkt_det_thd_set(PT_PHY_PKT_TH, PT_PHY_PKT_TH);
 | |
| 
 | |
|         do {
 | |
|             iot_printf("DUT TX phase %d\r\n", glb_cfg.phase);
 | |
|             /* step1:tx packet */
 | |
|             for (uint32_t i = 0; i < 3; i++) {
 | |
|                 tx_send_packet_interval(0);
 | |
|             }
 | |
| 
 | |
|             start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | |
| 
 | |
|             /* step2:wait to receive packt */
 | |
|             do{
 | |
|                 rx_buf_tmp = NULL;
 | |
|                 //is_rx_ring0_empty()
 | |
|                 while (!rx_buf_tmp) {
 | |
|                     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 > 2000*TICKS_MS) {
 | |
|                         info->info_arry[0] = 'W';
 | |
|                         info->info_arry[1] = 'Q';
 | |
|                         if (0 == snr_filter) {
 | |
|                             info->info_arry[2] = 0x01;
 | |
|                             info->len = 3;
 | |
|                             iot_printf("[fail]golden unit is not online\n");
 | |
|                         } else {
 | |
|                             info->info_arry[2] = 4;
 | |
|                             info->info_arry[15] = real_ppm & 0xFF;
 | |
|                             info->info_arry[16] = (real_ppm >> 8) & 0xFF;
 | |
|                             info->len = 17;
 | |
|                             iot_printf("[fail]snr too low, timeout.\n");
 | |
|                         }
 | |
|                         return;
 | |
|                     }
 | |
|                     if (((uint64_t)time_span)%(200*TICKS_MS) < 100) {
 | |
|                         tx_send_packet_interval(0);
 | |
|                     }
 | |
| 
 | |
|                     if (!is_rx_ring0_empty()) {
 | |
|                         rx_buf_tmp = pop_rx_buf_from_ring(0);
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 /* step3:cal ppm */
 | |
|                 pb_buf_ptr = (rx_buf_hdr_t *)rx_buf_tmp;
 | |
|                 cur_nid = mac_get_nid_from_fc(phy_proto_type_get(),
 | |
|                     mac_rx_mpdu_st_get_fc_addr(&pb_buf_ptr->mpdu_st));
 | |
|                 if ((mac_rx_att_get_is_fcserr((void *)&pb_buf_ptr->att)  == 0)
 | |
|                     && (mac_rx_pb_end_get_rx_pb_crc_err((void *)&pb_buf_ptr->pb_ed) == 0)
 | |
|                     && (cur_nid == glb_cfg.nid)) {
 | |
|                     iot_printf("[rx] pb crc:%d, nid:%x\n",
 | |
|                         mac_rx_pb_end_get_rx_pb_crc_err((void *)&pb_buf_ptr->pb_ed),
 | |
|                         cur_nid);
 | |
|                     info->info_arry[0] = 'W';
 | |
|                     info->info_arry[1] = 'Q';
 | |
|                     info->info_arry[2] = 0xFF;
 | |
|                     info->info_arry[3] = *(rx_buf_tmp + PB_PAYLOAD_OFFSET);/*tx gain*/
 | |
|                     info->info_arry[4] = *(rx_buf_tmp + PB_PAYLOAD_OFFSET + 1);/*tx rmi*/
 | |
|                     info->info_arry[5] = *(rx_buf_tmp + PB_PAYLOAD_OFFSET + 2);/*tx dc*/
 | |
|                     info->info_arry[6] = *(rx_buf_tmp + PB_PAYLOAD_OFFSET + 3);/*tx ppm*/
 | |
|                     info->info_arry[7] = *(rx_buf_tmp + PB_PAYLOAD_OFFSET + 4);/*tx ppm*/
 | |
|                     info->info_arry[8] = *(rx_buf_tmp + PB_PAYLOAD_OFFSET + 5);/*tx snr*/
 | |
|                     info->info_arry[9] = mac_rx_mpdu_st_get_rx_phase(
 | |
|                         (void *)&pb_buf_ptr->mpdu_st);/*rx phase*/
 | |
| 
 | |
|                     if (mac_rx_mpdu_st_get_agc_gain_entry((void *)&pb_buf_ptr->mpdu_st)
 | |
|                         >= PHY_AGC_NB_GAIN_ENTRY_START) {
 | |
|                         info->info_arry[10] = mac_rx_mpdu_st_get_agc_gain_entry(
 | |
|                             (void *)&pb_buf_ptr->mpdu_st) - PHY_AGC_NB_GAIN_ENTRY_START;/*rx gain*/
 | |
|                     } else {
 | |
|                         info->info_arry[10] = mac_rx_mpdu_st_get_agc_gain_entry(
 | |
|                             (void *)&pb_buf_ptr->mpdu_st);/*rx gain*/
 | |
|                     }
 | |
|                     info->info_arry[11] = mac_rx_mpdu_st_get_adc_power(
 | |
|                         (void *)&pb_buf_ptr->mpdu_st);/*rx rmi*/
 | |
|                     info->info_arry[12] = mac_rx_mpdu_st_get_estimated_dc(
 | |
|                         (void *)&pb_buf_ptr->mpdu_st);/*rx dc*/
 | |
|                     info->info_arry[13] = mac_rx_mpdu_st_get_estimated_ppm(
 | |
|                         (void *)&pb_buf_ptr->mpdu_st);/*rx ppm*/
 | |
|                     info->info_arry[14] = mac_rx_mpdu_st_get_avg_snr(
 | |
|                         (void *)&pb_buf_ptr->mpdu_st);/*rx snr*/
 | |
| 
 | |
|                     /* check snr */
 | |
|                     if ((int8_t)(info->info_arry[8]) > 10 && (int8_t)(info->info_arry[14]) > 0) {
 | |
|                         iot_printf("loopback nid:%x gain:%d, rmi:%d, dc:%d, snr:%d, ppm:%d\n",
 | |
|                             cur_nid, \
 | |
|                             (int8_t)(info->info_arry[3]),
 | |
|                             (int8_t)(info->info_arry[4]),
 | |
|                             (int8_t)(info->info_arry[5]),
 | |
|                             (int8_t)(info->info_arry[8]),
 | |
|                             (int16_t)(info->info_arry[6] | (info->info_arry[7] << 8)));
 | |
|                         iot_printf("loopback local rx phase:%x dc:%d, ppm:%d, snr:%d\n",
 | |
|                             info->info_arry[9], \
 | |
|                             (int8_t)(info->info_arry[12]),
 | |
|                             (int8_t)(info->info_arry[13]),
 | |
|                             (int8_t)(info->info_arry[14]));
 | |
|                         snr_filter = 0;
 | |
|                         break;
 | |
|                     } else {
 | |
|                         real_ppm = g_ppm - \
 | |
|                             (int16_t)(info->info_arry[6] | (info->info_arry[7] << 8));
 | |
|                         snr_filter = 1;
 | |
|                         iot_printf("loopback snr too small, tx snr: %d, rx snr: %d.\n",
 | |
|                             (int8_t)(info->info_arry[8]), (int8_t)(info->info_arry[14]));
 | |
|                     }
 | |
|                 }
 | |
|             } while (1);
 | |
| 
 | |
| #if IOT_DTEST_ONLY_SUPPORT == 0
 | |
|             /* write to oem */
 | |
|             iot_cal_data_cfg_t *oemcfg;
 | |
|             uint32_t ret = ERR_FAIL;
 | |
| 
 | |
|             ret = iot_cal_data_get_cfg(&oemcfg);
 | |
|             if (ERR_OK == ret) {
 | |
|                 iot_printf("cal block load complete, ppm: %d.\n", oemcfg->halphy_cfg.ppm);
 | |
|             } else {
 | |
|                 info->info_arry[0] = 'W';
 | |
|                 info->info_arry[1] = 'Q';
 | |
|                 info->info_arry[2] = 5;
 | |
|                 info->len = 3;
 | |
|                 iot_printf("cal data get cfg failed, ret:%d.\n", ret);
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             /* update ppm */
 | |
|             real_ppm = g_ppm -
 | |
|                 (int16_t)(info->info_arry[6] | (info->info_arry[7] << 8));
 | |
|             iot_printf("Golden ppm: %d, Dut real ppm: %d;\n", g_ppm, real_ppm);
 | |
|             info->info_arry[15] = real_ppm & 0xFF;
 | |
|             info->info_arry[16] = (real_ppm >> 8) & 0xFF;
 | |
|             info->len = 17;
 | |
|             if ((MIN_PPM_THD <= real_ppm) && (MAX_PPM_THD >= real_ppm)) {
 | |
|                 oemcfg->halphy_cfg.ppm = (int8_t)(-real_ppm);  //opposite number
 | |
|             } else {
 | |
|                 info->info_arry[0] = 'W';
 | |
|                 info->info_arry[1] = 'Q';
 | |
|                 info->info_arry[2] = 0;
 | |
|                 info->len = 3;
 | |
|                 iot_printf("ppm value: %d beyond data range, check fail!\n", real_ppm);
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             /* update mask */
 | |
|             iot_cal_data_set_mask(oemcfg, IOT_PHY_CFG_MASK_PPM);
 | |
| 
 | |
|             if (*(rx_buf_tmp+69) > RECEV_TX_SNR_THD_VALUE) {
 | |
|                 info->info_arry[0] = 'W';
 | |
|                 info->info_arry[1] = 'Q';
 | |
|                 info->info_arry[2] = 2;
 | |
|                 info->len = 3;
 | |
|                 iot_printf("[data check] nid:%x, snr:%d check fail!\n",
 | |
|                     cur_nid, *(rx_buf_tmp+69));
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             ret = iot_cal_data_set_cfg(oemcfg);
 | |
|             if (ret == ERR_OK) {
 | |
|                 iot_printf("[success]ppm calibration and burn finish!\n");
 | |
|             } else {
 | |
|                 info->info_arry[0] = 'W';
 | |
|                 info->info_arry[1] = 'Q';
 | |
|                 info->info_arry[2] = 3;
 | |
|                 info->len = 3;
 | |
|                 iot_printf("[success]ppm burn fail!\n");
 | |
|             }
 | |
| #endif
 | |
| 
 | |
|             /* step4:return with 1 pkt */
 | |
|             return;
 | |
|         } while (true); /* keep check */
 | |
|     } else if (FTM_CMD_TX_CSI == mode_num) {
 | |
|         iot_printf("FTM_CMD_TX_CSI\n");
 | |
|         if (anf_en) {
 | |
|             /* anf recovery */
 | |
|             phy_anf_top_option_set(PHY_ANF_OPT_RECOVERY);
 | |
|         } else {
 | |
|             /* bypass anf */
 | |
|             phy_anf_top_option_set(PHY_ANF_OPT_BYPASS);
 | |
|             /* case id */
 | |
|             case_info->case_id = FTM_CMD_TX_CSI;
 | |
|             /* tx packets */
 | |
|             for (uint32_t i = 0; i < 5; i++) {
 | |
|                 tx_send_packet_interval(100);
 | |
|             }
 | |
|             iot_printf("end send FTM_CMD_TX_CSI\n");
 | |
|         }
 | |
|     }
 | |
|     /* transmission success rate */
 | |
|     if (FTM_CMD_TX_CSR == mode_num) {
 | |
|         uint16_t timeout_value = 3500;
 | |
| 
 | |
|         /* get back struct ptr */
 | |
|         mac_tx_back_t *info = (mac_tx_back_t *)buf_ptr;
 | |
| 
 | |
|         /* clear cnt */
 | |
|         mac_tmi_cnt_clr();
 | |
| 
 | |
|         /* tmi select */
 | |
|         glb_cfg.p_type = FC_DELIM_SOF;
 | |
|         glb_cfg.tmi = MAC_TMI_4;
 | |
|         glb_cfg.ack_en = false;
 | |
| 
 | |
|         /* case id */
 | |
|         case_info->case_id = FTM_CMD_TX_CSR;
 | |
|         case_info->tmi = m_tmi;
 | |
|         case_info->pkt_type = FC_DELIM_SOF;
 | |
|         case_info->pkt_cnt = PHY_PDL_RATE_RTY_CNT;
 | |
|         case_info->pwr_set = power;
 | |
|         iot_printf("Communication success test tx power decrease %d.\n", power);
 | |
|         /* clr cnt */
 | |
|         tmp = RGF_MAC_READ_REG(CFG_TX_DBG_CTRL_ADDR);
 | |
|         REG_FIELD_SET(CFG_TX_DBG_CNT_CLR,tmp,0x1);
 | |
|         RGF_MAC_WRITE_REG(CFG_TX_DBG_CTRL_ADDR,tmp);
 | |
| 
 | |
|         if (MAC_EXT_TMI_1 == m_tmi) {
 | |
|             timeout_value = 1000;
 | |
|         } else if (MAC_TMI_4 == m_tmi) {
 | |
|             timeout_value = 2000;
 | |
|         } else if (MAC_EXT_TMI_3 == m_tmi) {
 | |
|             timeout_value = 1800;
 | |
|         }
 | |
| 
 | |
|         /* step1:tx packet */
 | |
|         tx_send_packet_interval(0);
 | |
| 
 | |
|         /* update start time */
 | |
|         start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | |
| 
 | |
|         /* step2:wait to receive packt */
 | |
|         rx_buf_tmp = NULL;
 | |
|         while (1) {
 | |
|             if (!is_rx_ring0_empty()) {
 | |
|                 rx_buf_tmp = pop_rx_buf_from_ring(0);
 | |
| 
 | |
|                 /* step3:add cnt */
 | |
|                 if (rx_buf_tmp) {
 | |
|                     pb_buf_ptr = (rx_buf_hdr_t *)rx_buf_tmp;
 | |
|                     cur_nid = mac_get_nid_from_fc(phy_proto_type_get(),
 | |
|                         mac_rx_mpdu_st_get_fc_addr(&pb_buf_ptr->mpdu_st));
 | |
|                     if ((pb_buf_ptr->att.is_fcserr == 0)
 | |
|                         && (pb_buf_ptr->pb_ed.rx_pb_crc_err == 0)
 | |
|                         && (cur_nid == glb_cfg.nid)) {
 | |
|                         info->info_arry[0] += 1;
 | |
|                         if (info->info_arry[0] >= 100) {
 | |
|                             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 > timeout_value*TICKS_MS) {
 | |
|                 break;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /* PHY_PDL_RATE_RTY_CNT < 256 */
 | |
|         info->len = 1;
 | |
|         mac_pkt_info_cnt_print();
 | |
|         /* magic number */
 | |
|         case_info->magic_num0 = 0x0;
 | |
|         case_info->magic_num1 = 0x0;
 | |
|     }
 | |
|     if (FTM_CMD_TX_BAND == mode_num) {
 | |
|         iot_printf("FTM_CMD_TX_BAND\n");
 | |
|         uint8_t new_band = tx_cmd->p_type;
 | |
|         /* adjust band for golden */
 | |
|         /* case id */
 | |
|         case_info->case_id = FTM_CMD_TX_BAND;
 | |
|         /* band id */
 | |
|         case_info->phase_num= new_band;
 | |
|         /* step1:tx packet */
 | |
|         for (uint32_t i = 0; i < 3; i++) {
 | |
|             tx_send_packet_interval(0);
 | |
|         }
 | |
| 
 | |
|         /* step2:wait to receive packt */
 | |
|         rx_buf_tmp = rx_recev_packet();
 | |
|         if (!rx_buf_tmp) {
 | |
|             iot_printf("Cannot receive golden packets replay...\n");
 | |
|         } else {
 | |
|             pb_buf_ptr = (rx_buf_hdr_t *)rx_buf_tmp;
 | |
|             if ((pb_buf_ptr->att.is_fcserr == 0)
 | |
|                 && (pb_buf_ptr->pb_ed.rx_pb_crc_err == 0)) {
 | |
|                 iot_printf("Channel conmunication completes!\n");
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     if (FTM_CMD_TX_GET_GOLDEN_INFO == mode_num) {
 | |
|         /* get back struct ptr */
 | |
|         mac_tx_back_t *info = (mac_tx_back_t *)buf_ptr;
 | |
|         iot_printf("FTM_CMD_TX_GET_GOLDEN_INFO\n");
 | |
|         glb_cfg.p_type = FC_DELIM_SOF;
 | |
|         case_info->case_id = FTM_CMD_TX_GET_GOLDEN_INFO;
 | |
|         /* clear current pkt */
 | |
|         RX_RING_SET_RD_IDX(0, RX_RING_GET_WR_IDX(0));
 | |
|         /* step1:tx packet */
 | |
|         for (uint32_t i = 0; i < 3; i++) {
 | |
|             tx_send_packet_interval(0);
 | |
|             /* step2:wait to receive packt */
 | |
|             rx_buf_tmp = rx_recev_packet();
 | |
|             if (!rx_buf_tmp) {
 | |
|                 iot_printf("Cannot receive golden packets replay...\n");
 | |
|             } else {
 | |
|                 pb_buf_ptr = (rx_buf_hdr_t *)rx_buf_tmp;
 | |
|                 cur_nid = mac_get_nid_from_fc(phy_proto_type_get(),
 | |
|                     mac_rx_mpdu_st_get_fc_addr(&pb_buf_ptr->mpdu_st));
 | |
|                 if ((pb_buf_ptr->att.is_fcserr == 0)
 | |
|                     && (pb_buf_ptr->pb_ed.rx_pb_crc_err == 0)
 | |
|                     && (cur_nid == glb_cfg.nid)) {
 | |
|                     os_mem_cpy((void*)&(info->info_arry[0]),
 | |
|                         rx_buf_tmp + PB_PAYLOAD_OFFSET, sizeof(iot_pt_golden_info));
 | |
|                 }
 | |
|                 break;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     (void)pb_buf_ptr;
 | |
| }
 |