3254 lines
		
	
	
		
			112 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			3254 lines
		
	
	
		
			112 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_utils.h"
 | 
						|
#include "os_task.h"
 | 
						|
#include "hw_reg_api.h"
 | 
						|
#include "mac_sys_reg.h"
 | 
						|
#include "mac_reset.h"
 | 
						|
#include "mpdu_header.h"
 | 
						|
#include "ahb.h"
 | 
						|
#include "plc_protocol.h"
 | 
						|
#include "dbg_msg_pop.h"
 | 
						|
#include "iot_io_api.h"
 | 
						|
#include "iot_clock.h"
 | 
						|
#include "iot_errno.h"
 | 
						|
#include "iot_module.h"
 | 
						|
#include "iot_ftm_msg.h"
 | 
						|
#include "iot_board.h"
 | 
						|
 | 
						|
#if IOT_MP_SUPPORT == 1 && HPLC_RF_DEV_SUPPORT
 | 
						|
 | 
						|
#include "rf_mac_int.h"
 | 
						|
#include "rf_mac_reg.h"
 | 
						|
#include "rfplc_reg_base.h"
 | 
						|
#include "rf_hw_tonemap.h"
 | 
						|
#include "phy_rf_init.h"
 | 
						|
#include "phy_rf_chn.h"
 | 
						|
#include "rf_mac_tx.h"
 | 
						|
#include "mac_rf_isr.h"
 | 
						|
#include "mac_rf_tx_hw.h"
 | 
						|
#include "mac_rf_rx_buf_ring.h"
 | 
						|
#include "mac_rf_common_hw.h"
 | 
						|
#include "mac_rf_txq_hw.h"
 | 
						|
#include "iot_system.h"
 | 
						|
 | 
						|
/* hplc mac and phy Common header */
 | 
						|
#include "phy_txrx_pwr.h"
 | 
						|
#include "phy_chn.h"
 | 
						|
#include "phy_bb.h"
 | 
						|
#include "mac_sys_reg.h"
 | 
						|
#include "mac_rx_descriptor_reg.h"
 | 
						|
#include "rx_desc_reg_api.h"
 | 
						|
#include "mpdu_header.h"
 | 
						|
#include "mac_rx_buf_ring.h"
 | 
						|
#include "tx_entry.h"
 | 
						|
#include "hw_rx.h"
 | 
						|
 | 
						|
#include "bb_init.h"
 | 
						|
#include "bb_rf_cfg.h"
 | 
						|
#include "rf_phy_tx.h"
 | 
						|
#include "rf_phy_rx.h"
 | 
						|
#include "phy_ada_dump.h"
 | 
						|
#include "iot_pt_rf_func.h"
 | 
						|
#include "iot_gpio_api.h"
 | 
						|
#include "iot_led.h"
 | 
						|
#include "iot_board_api.h"
 | 
						|
#include "mp_mode.h"
 | 
						|
#include "math_log10.h"
 | 
						|
#include "iot_crc_api.h"
 | 
						|
#include "iot_bitmap_api.h"
 | 
						|
#include "hw_reg_api.h"
 | 
						|
#include "phy_reg.h"
 | 
						|
 | 
						|
/* define mp rf tx descriptors count */
 | 
						|
#define MP_RF_TX_DESC_CNT                           2
 | 
						|
 | 
						|
/* test massage magic number */
 | 
						|
#define MP_RF_TEST_MSG_MAGIC_NUMBER                 0x55AA55AA
 | 
						|
 | 
						|
/* define mp rf csr tx max count */
 | 
						|
#define MP_RF_CSR_TX_MAX_COUNT                      200
 | 
						|
 | 
						|
/* maximum number of TX EVM samples */
 | 
						|
#define MP_RF_TX_EVM_SMAP_MAX_CNT                   1000
 | 
						|
 | 
						|
/* default time limit of CSI test, unit: ms */
 | 
						|
#define MP_RF_TEST_CASE_CSI_TIMEOUT_DEF             1000
 | 
						|
 | 
						|
/* default time limit of CSR test, unit: ms */
 | 
						|
#define MP_RF_TEST_CASE_CSR_TIMEOUT_DEF             1000
 | 
						|
 | 
						|
/* max time limit of CSR test, unit: ms */
 | 
						|
#define MP_RF_TEST_CASE_CSR_TIMEOUT_MAX             5000
 | 
						|
 | 
						|
/* default time limit of TX EVM test, unit: ms */
 | 
						|
#define MP_RF_TEST_CASE_TX_EVM_TIMEOUT_DEF          1000
 | 
						|
 | 
						|
/* default time limit of change phy option test, unit: ms */
 | 
						|
#define MP_RF_TEST_CASE_CHG_PHY_TIMEOUT_DEF         900
 | 
						|
 | 
						|
/* default time delay of change phy option, unit: ms */
 | 
						|
#define MP_RF_TEST_CASE_CHG_PHY_EXEC_DELAY          600
 | 
						|
 | 
						|
/* define the number of times the command is sent repeatedly */
 | 
						|
#define MP_RF_CMD_RETRY_COUNT                       4
 | 
						|
 | 
						|
/* define the repeated sending interval of the command */
 | 
						|
#define MP_RF_CMD_RETRY_INTERVAL                    100
 | 
						|
 | 
						|
/* define invalid rssi of snr value */
 | 
						|
#define MP_RF_INVAL_RSSI_SNR                        (-127)
 | 
						|
 | 
						|
/* default snr threshold of CSI test */
 | 
						|
#define MP_RF_CSI_TEST_SNR_THR                      10
 | 
						|
 | 
						|
/* default snr threshold of CSI test */
 | 
						|
#define MP_RF_CSI_TEST_RSSI_THR                     (-110)
 | 
						|
 | 
						|
/* define mp rf golden common timer period, unit:ms*/
 | 
						|
#define MP_RF_GOLDEN_COMMON_TIMER_PERIOD            (100)
 | 
						|
 | 
						|
/* default time limit of TX CALI test, unit: ms */
 | 
						|
#define MP_RF_TEST_CASE_TX_CALI_TIMEOUT_DEF         1000
 | 
						|
 | 
						|
/* define rf phy iq phase compensation maximum code */
 | 
						|
#define RF_PHY_IQ_PHASE_COMPEN_CODE_MAX             32
 | 
						|
 | 
						|
/* define rf phy iq magnitude compensation maximum code */
 | 
						|
#define RF_PHY_IQ_MAG_COMPEN_CODE_MAX               16
 | 
						|
 | 
						|
/* define the size of tx cali data array */
 | 
						|
#define MP_RF_TEST_CASE_TX_CALI_SNR_SAMP_BUF_SIZE   \
 | 
						|
    (RF_PHY_IQ_PHASE_COMPEN_CODE_MAX * RF_PHY_IQ_PHASE_COMPEN_CODE_MAX)
 | 
						|
 | 
						|
/* judge whether the value of phase is within the range */
 | 
						|
#define rf_phy_iq_phase_compen_code_valid(v)    (v >= 0 && \
 | 
						|
    v < RF_PHY_IQ_PHASE_COMPEN_CODE_MAX)
 | 
						|
 | 
						|
/* judge whether the value of mag is within the range */
 | 
						|
#define rf_phy_iq_mag_compen_code_valid(v)      (v >= 0 && \
 | 
						|
    v < RF_PHY_IQ_MAG_COMPEN_CODE_MAX)
 | 
						|
 | 
						|
/* The maximum number of best compensation results calculated from snr samples.
 | 
						|
 */
 | 
						|
#define MP_RF_TX_CALI_SNR_BEST_RESULT_MAX           3
 | 
						|
 | 
						|
/* how many i/q combinations of snr data can be recorded */
 | 
						|
#define MP_RF_TX_CALI_SNR_REAL_DATA_GROUP_SIZE      81
 | 
						|
 | 
						|
/* how many sets of data can be recorded for each i/q combination */
 | 
						|
#define MP_RF_TX_CALI_SNR_REAL_DATA_GROUP_DEPTH     30
 | 
						|
 | 
						|
/* define the size of tx cali bitmap array */
 | 
						|
#define MP_RF_TX_CALI_SNR_BM_SIZE                   128
 | 
						|
 | 
						|
/* convert the i/q combination to a large number */
 | 
						|
#define MP_RF_IQ_CODE_TO_MAGIC(max_code, i, q)      ((i) * (max_code) + (q))
 | 
						|
 | 
						|
/* minimum number of points required for linear fitting */
 | 
						|
#define MP_RF_TX_CALI_SNR_LINER_FIT_VALID_SAMP_NUM  6
 | 
						|
 | 
						|
/* define MP rf test message id */
 | 
						|
#define MP_RF_MSG_ID_CSI                            0
 | 
						|
#define MP_RF_MSG_ID_CSR                            1
 | 
						|
#define MP_RF_MSG_ID_TX_EVM_SAMP                    2
 | 
						|
#define MP_RF_MSG_ID_TX_EVM_STAT_QUERY              3
 | 
						|
#define MP_RF_MSG_ID_CHG_PHY                        4
 | 
						|
#define MP_RF_MSG_ID_TX_CALI_STAT_QUERY             5
 | 
						|
 | 
						|
/* define event id */
 | 
						|
#define MP_RF_EVT_ID_RF_RX                          0
 | 
						|
#define MP_RF_EVT_ID_PLC_RX                         1
 | 
						|
#define MP_RF_EVT_ID_TIMEROUT                       2
 | 
						|
 | 
						|
/* enable/disable Calibration measurement data dump */
 | 
						|
#define MP_RF_CAL_MEAS_DUMP_EN                      0
 | 
						|
/* define the maximum average number of calibration measurements */
 | 
						|
#define MP_RF_CAL_MEAS_AVG_CNT_MAX                  128
 | 
						|
/* define the maximum average number of calibration measurements */
 | 
						|
#define MP_RF_CAL_MEAS_AVG_CNT_DEFAULT              32
 | 
						|
 | 
						|
#if SUPPORT_SOUTHERN_POWER_GRID
 | 
						|
 | 
						|
/* define the tmi used for PLC communication with less data */
 | 
						|
#define MP_RF_PLC_NORMAL_PACKET_TMI                 MAC_TMI_6
 | 
						|
/* define the tmi used for PLC communication with more data */
 | 
						|
#define MP_RF_PLC_LARGE_PACKET_TMI                  MAC_TMI_0
 | 
						|
/* define plc init band */
 | 
						|
#define MP_RF_PLC_INIT_BAND                         IOT_SUPPORT_TONE_100_230
 | 
						|
 | 
						|
#else /* SUPPORT_SOUTHERN_POWER_GRID */
 | 
						|
 | 
						|
/* define the tmi used for PLC communication with less data */
 | 
						|
#define MP_RF_PLC_NORMAL_PACKET_TMI                 MAC_TMI_13
 | 
						|
/* define the tmi used for PLC communication with more data */
 | 
						|
#define MP_RF_PLC_LARGE_PACKET_TMI                  MAC_TMI_12
 | 
						|
/* define plc init band */
 | 
						|
#define MP_RF_PLC_INIT_BAND                         IOT_SUPPORT_TONE_240_370
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
#pragma pack(push)  /* save the pack status */
 | 
						|
#pragma pack(1)     /* 1 byte align */
 | 
						|
 | 
						|
/* command message layout, from dut to golden */
 | 
						|
typedef struct {
 | 
						|
    /* magic number, fixed as MP_RF_TEST_MSG_MAGIC_NUMBER */
 | 
						|
    uint32_t magic;
 | 
						|
    /* message id, see MP_RF_MSG_ID_XXX */
 | 
						|
    uint8_t  msg_id;
 | 
						|
    /* golden tx phr mcs, see MCS_ID_X */
 | 
						|
    uint8_t  phr_mcs;
 | 
						|
    /* golden tx payload mcs, see MCS_ID_X  */
 | 
						|
    uint8_t  pld_mcs;
 | 
						|
    /* golden tx pb block size, see BLOCK_SIZE_XXX */
 | 
						|
    uint8_t  pld_blkz;
 | 
						|
    /* golden tx power, uint is dbm */
 | 
						|
    int8_t   power;
 | 
						|
    /* data payload label*/
 | 
						|
    uint8_t  data[0];
 | 
						|
} mp_rf_test_cmd_hdr_t;
 | 
						|
 | 
						|
/* CSR cmd payload layout */
 | 
						|
typedef struct {
 | 
						|
    /* packet count */
 | 
						|
    uint16_t packet_num;
 | 
						|
    /* mac address of dut */
 | 
						|
    uint8_t  mac_addr[IOT_MAC_ADDR_LEN];
 | 
						|
    /* generation timestamp of the command */
 | 
						|
    uint32_t ts;
 | 
						|
    /* if set, golden uses test mode power configuration. */
 | 
						|
    uint8_t  is_test_mode : 1,
 | 
						|
    /* reserved field 0 for further use */
 | 
						|
             rsvd0        : 7;
 | 
						|
    /* time interval when Golden sending packets, unit: us. */
 | 
						|
    uint16_t interval;
 | 
						|
    /* reserved field 1 for further use */
 | 
						|
    uint8_t  rsvd1[5];
 | 
						|
} mp_rf_test_cmd_csr_t;
 | 
						|
 | 
						|
/* TX EVM cmd payload layout */
 | 
						|
typedef struct {
 | 
						|
    /* mac address of dut */
 | 
						|
    uint8_t  mac_addr[IOT_MAC_ADDR_LEN];
 | 
						|
    /* generation timestamp of the command */
 | 
						|
    uint32_t ts;
 | 
						|
    /* reserved for further use */
 | 
						|
    uint8_t  rsvd[8];
 | 
						|
} mp_rf_test_cmd_tx_evm_t;
 | 
						|
 | 
						|
/* change phy cmd payload layout */
 | 
						|
typedef struct {
 | 
						|
    /* rf option, see RF_OPTION_XXX */
 | 
						|
    uint8_t option;
 | 
						|
    /* rf channel, RF_CHANNEL_ID_XXX */
 | 
						|
    uint8_t channel;
 | 
						|
} mp_rf_test_cmd_chg_phy_t;
 | 
						|
 | 
						|
/* TX CALI cmd payload layout */
 | 
						|
typedef struct {
 | 
						|
    /* magic number of dev_id */
 | 
						|
    uint16_t  dev_id_magic;
 | 
						|
    /* tx cali type, see RF_TEST_TX_CALI_REG_IQ_XXX */
 | 
						|
    uint8_t   type;
 | 
						|
    /* flag to mark whether to use original data */
 | 
						|
    uint8_t   liner_fit_en;
 | 
						|
    /* reserved for further use */
 | 
						|
    uint8_t   rsvd[8];
 | 
						|
} mp_rf_test_cmd_tx_cali_stat_qr_t;
 | 
						|
 | 
						|
/* response message layout, from golden to dut */
 | 
						|
typedef struct {
 | 
						|
    /* magic number, fixed as MP_RF_TEST_MSG_MAGIC_NUMBER */
 | 
						|
    uint32_t magic;
 | 
						|
    /* message id, see MP_RF_MSG_ID_XXX */
 | 
						|
    uint8_t  msg_id;
 | 
						|
    /* rssi for received from dut packets */
 | 
						|
    int8_t   tx_rssi;
 | 
						|
    /* snr for received from dut packets */
 | 
						|
    int8_t   tx_snr;
 | 
						|
    /* ppm for received from dut packets */
 | 
						|
    int8_t   tx_ppm;
 | 
						|
    /* adc gain for received from dut packets */
 | 
						|
    uint8_t  tx_gain;
 | 
						|
    /* data payload label */
 | 
						|
    uint8_t  data[0];
 | 
						|
} mp_rf_test_rsp_t;
 | 
						|
 | 
						|
/* TX EVM response payload layout, from golden to dut */
 | 
						|
typedef struct {
 | 
						|
    /* rx success count */
 | 
						|
    uint16_t rx_cnt;
 | 
						|
    /* 10 times the average RSSI of DUT tx evaluated by golden */
 | 
						|
    int16_t  avg_rssi;
 | 
						|
    /* 10 times the average snr of DUT tx evaluated by golden */
 | 
						|
    int16_t  avg_snr;
 | 
						|
} mp_rf_rsp_tx_evm_t;
 | 
						|
 | 
						|
/* TX CALI result structure */
 | 
						|
typedef struct {
 | 
						|
    /* rf phy i value of MAG/PHASE register */
 | 
						|
    int8_t   i;
 | 
						|
    /* rf phy q value of MAG/PHASE register */
 | 
						|
    int8_t   q;
 | 
						|
    /* snr */
 | 
						|
    float    snr;
 | 
						|
} tx_cali_comen_result_t;
 | 
						|
 | 
						|
/* TX CALI response payload layout, from golden to dut */
 | 
						|
typedef struct {
 | 
						|
    /* bitmap representing iq combination */
 | 
						|
    uint8_t                 bm[MP_RF_TX_CALI_SNR_BM_SIZE];
 | 
						|
    /* indicates how many sets of iq data are available next */
 | 
						|
    uint8_t                 cnt;
 | 
						|
    /* TX CALI result payload */
 | 
						|
    tx_cali_comen_result_t  result[0];
 | 
						|
} mp_rf_rsp_tx_cali_t;
 | 
						|
 | 
						|
/* csr response payload layout, from golden to dut */
 | 
						|
typedef struct {
 | 
						|
    /* packet serial number */
 | 
						|
    uint16_t sn;
 | 
						|
} mp_rf_rsp_csr_t;
 | 
						|
 | 
						|
/* define MP rf calibration message id */
 | 
						|
#define MP_RF_CAL_MSG_ID_MEAS_CFG                   0
 | 
						|
#define MP_RF_CAL_MSG_ID_MEAS_REQ                   1
 | 
						|
#define MP_RF_CAL_MSG_ID_GET_SNR                    2
 | 
						|
 | 
						|
/* rf calibration response message header layout */
 | 
						|
typedef struct {
 | 
						|
    /* magic number, fixed as MP_RF_TEST_MSG_MAGIC_NUMBER */
 | 
						|
    uint32_t magic;
 | 
						|
    /* message id, see MP_RF_CAL_MSG_ID_XXX */
 | 
						|
    uint8_t  msg_id;
 | 
						|
    /* dut address */
 | 
						|
    uint8_t  dut_addr[IOT_MAC_ADDR_LEN];
 | 
						|
    /* Measurement sequence number */
 | 
						|
    uint32_t sn;
 | 
						|
    /* 1. When the direction DUT-->golden, it is an invalid field.
 | 
						|
     * 2. When the direction gold -->DUT, it is an error code, see ERR_XX
 | 
						|
     */
 | 
						|
    uint8_t  option;
 | 
						|
    /* payload label */
 | 
						|
    uint8_t  data[0];
 | 
						|
} mp_rf_cal_msg_hdr_t;
 | 
						|
 | 
						|
/* rf calibration config message layout, DUT --> golden */
 | 
						|
typedef struct {
 | 
						|
    /* configure golden to measurement mode, 1 - enable / 0 - disable */
 | 
						|
    uint8_t  meas_en;
 | 
						|
    /* rf option */
 | 
						|
    uint8_t  option;
 | 
						|
    /* rf channel */
 | 
						|
    uint8_t  ch;
 | 
						|
    /* communication power between DUT and golden (HPLC), uint is dBuV */
 | 
						|
    uint8_t  comm_pwr;
 | 
						|
    /* communication power between DUT and golden (HPLC), see MAC_TMI_XX */
 | 
						|
    uint8_t  comm_tmi;
 | 
						|
    /* reserved for further use */
 | 
						|
    uint8_t  rsvd[8];
 | 
						|
} mp_rf_cal_meas_cfg_t;
 | 
						|
 | 
						|
/* rf calibration measurement req msg layout, including measurement,
 | 
						|
 * DUT --> golden.
 | 
						|
 */
 | 
						|
typedef struct {
 | 
						|
    /* receiving LO frequency used in measurement, uint is Hz */
 | 
						|
    uint32_t    lo_freq;
 | 
						|
    /* index of dc signal in fft result */
 | 
						|
    uint16_t    dc_idx;
 | 
						|
    /* index of img signal in fft result */
 | 
						|
    uint16_t    img_idx;
 | 
						|
    /* index of tone signal in fft result */
 | 
						|
    uint16_t    tone_idx;
 | 
						|
    /* measurements average number */
 | 
						|
    uint8_t     avg_cnt;
 | 
						|
    /* reserved for further use */
 | 
						|
    uint8_t     rsvd[7];
 | 
						|
} mp_rf_cal_meas_req_t;
 | 
						|
 | 
						|
/* rf calibration measurement response msg layout, including measurement result
 | 
						|
 * info, golden --> DUT.
 | 
						|
 */
 | 
						|
typedef struct {
 | 
						|
    /* dut address */
 | 
						|
    uint8_t     dut_addr[IOT_MAC_ADDR_LEN];
 | 
						|
    /* Measurement sequence number */
 | 
						|
    uint32_t    sn;
 | 
						|
    /* tone signal power, no gain compensation */
 | 
						|
    uint32_t    tone_pwr;
 | 
						|
    /* dc signal power, no gain compensation */
 | 
						|
    uint32_t    dc_pwr;
 | 
						|
    /* img signal power, no gain compensation */
 | 
						|
    uint32_t    img_pwr;
 | 
						|
    /* receive gain */
 | 
						|
    uint8_t     gain;
 | 
						|
    /* receive gain after 100x amplification */
 | 
						|
    uint16_t    gain_x100;
 | 
						|
    /* eserved for further use  */
 | 
						|
    uint8_t     rsvd[6];
 | 
						|
} mp_rf_cal_meas_rsp_t;
 | 
						|
 | 
						|
/* rf tx cali info. */
 | 
						|
typedef struct {
 | 
						|
    /* rf tx calibration register type, see RF_TEST_TX_CALI_REG_XXX */
 | 
						|
    uint8_t     reg_type;
 | 
						|
    /* rf phy i value of MAG/PHASE register */
 | 
						|
    int8_t      i;
 | 
						|
    /* rf phy q value of MAG/PHASE register */
 | 
						|
    int8_t      q;
 | 
						|
    /* dvice id magic number */
 | 
						|
    uint16_t    dev_id_magic;
 | 
						|
    /* raw snr */
 | 
						|
    uint16_t    raw_snr;
 | 
						|
} mp_rf_tx_cali_samp_desc_t;
 | 
						|
 | 
						|
#pragma pack(pop)   /* restore the pack status */
 | 
						|
 | 
						|
/* NTB timestamp span calculation */
 | 
						|
#define mp_rf_ntb_span_calc(ntb1, ntb2)  ((uint32_t)((int32_t)(ntb1) - \
 | 
						|
            (int32_t)(ntb2)))
 | 
						|
 | 
						|
/* rf tx cali real snr data */
 | 
						|
typedef struct {
 | 
						|
    /* i/q combination number */
 | 
						|
    uint16_t    magic;
 | 
						|
    /* how many groups of snr data have been stored */
 | 
						|
    uint8_t     cnt;
 | 
						|
    /* record real snr data */
 | 
						|
    uint16_t    snr[MP_RF_TX_CALI_SNR_REAL_DATA_GROUP_DEPTH];
 | 
						|
} snr_record_desc_t;
 | 
						|
 | 
						|
/* mp rf tx descriptor */
 | 
						|
typedef struct {
 | 
						|
    rf_tx_mpdu_start    mpdu_start;
 | 
						|
    rf_tx_mpdu_end      mpdu_end;
 | 
						|
    rf_tx_pb_start      pb_start;
 | 
						|
    rf_tx_dummy_node    tx_dummy;
 | 
						|
} mp_rf_tx_desc_t;
 | 
						|
 | 
						|
/* mp rf test context structure */
 | 
						|
typedef struct {
 | 
						|
    /* mp rf tx descriptor */
 | 
						|
    mp_rf_tx_desc_t     tx_desc_buf[MP_RF_TX_DESC_CNT];
 | 
						|
    /* pointer to tx desc currently being sent */
 | 
						|
    mp_rf_tx_desc_t     *cur_tx_desc;
 | 
						|
    /* plc irq0 handle */
 | 
						|
    iot_irq_t           plc_isr_0_h;
 | 
						|
    /* plc irq1 handle */
 | 
						|
    iot_irq_t           plc_isr_1_h;
 | 
						|
    /* plc irq2 handle */
 | 
						|
    iot_irq_t           plc_isr_2_h;
 | 
						|
    /* rf irq handle */
 | 
						|
    iot_irq_t           rf_isr_h;
 | 
						|
    /* common timer */
 | 
						|
    timer_id_t          common_timer;
 | 
						|
    /* timer timeout times */
 | 
						|
    uint8_t             timeout_count;
 | 
						|
    /* option, see RF_OPTION_XXX */
 | 
						|
    uint8_t             option;
 | 
						|
    /* channel numbel */
 | 
						|
    uint8_t             channel;
 | 
						|
    /* target option, see RF_OPTION_XXX */
 | 
						|
    uint8_t             target_option;
 | 
						|
    /* target channel numbel */
 | 
						|
    uint8_t             target_channel;
 | 
						|
    /* phy header mcs, see MCS_ID_XXX */
 | 
						|
    uint8_t             phr_mcs;
 | 
						|
    /* payload mcs, see MCS_ID_XXX */
 | 
						|
    uint8_t             pld_mcs;
 | 
						|
    /* payload block size, see BLOCK_SIZE_XXX */
 | 
						|
    uint8_t             pld_blkz;
 | 
						|
    /* next allocable tx descriptor index */
 | 
						|
    uint8_t             tx_desc_idx;
 | 
						|
    /* flag to mark if rf phy has been initialized */
 | 
						|
    volatile uint32_t   rf_phy_inited   : 1,
 | 
						|
    /* flag to mark if rf phy changing */
 | 
						|
                        rf_phy_changing : 1,
 | 
						|
    /* flag to mark if golden is in calibration mode */
 | 
						|
                        is_cal_mode     : 1,
 | 
						|
    /* flag to mark if current device is golden */
 | 
						|
                        is_golden       : 1,
 | 
						|
    /* flag to mark if led status of goolden */
 | 
						|
                        led_status      : 1,
 | 
						|
    /* flag to mark if tx done */
 | 
						|
                        tx_done         : 1,
 | 
						|
    /* flag to mark if rx done */
 | 
						|
                        rx_done         : 1,
 | 
						|
    /* reserved for further use */
 | 
						|
                        rsvd            : 25;
 | 
						|
    /* timestamp of rf phy change */
 | 
						|
    uint32_t            rf_phy_chg_ts;
 | 
						|
    /* rf receive ring buf config structure */
 | 
						|
    rx_buf_ring_t       rx_ring;
 | 
						|
    /* the dut address of the last tx evm test */
 | 
						|
    uint8_t             dut_addr_in_tx_evm[IOT_MAC_ADDR_LEN];
 | 
						|
    /* generation timestamp of the last TX EVM command from DUT */
 | 
						|
    uint32_t            tx_evm_ts;
 | 
						|
    /* the dut address of the last CSR test */
 | 
						|
    uint8_t             dut_addr_in_csr[IOT_MAC_ADDR_LEN];
 | 
						|
    /* generation timestamp of the last CSR command from DUT */
 | 
						|
    uint32_t            csr_cmd_ts;
 | 
						|
    /* marks the amount of data received in the TX EVM test */
 | 
						|
    uint16_t            recv_data_cnt;
 | 
						|
    /* record the SNR of the signal received in the TX EVM or CSR test */
 | 
						|
    int8_t              snr_buf[max(MP_RF_CSR_TX_MAX_COUNT, \
 | 
						|
        MP_RF_TX_EVM_SMAP_MAX_CNT)];
 | 
						|
    /* record the RSSI of the signal received in the TX EVM or CSR test */
 | 
						|
    int8_t              rssi_buf[max(MP_RF_CSR_TX_MAX_COUNT, \
 | 
						|
        MP_RF_TX_EVM_SMAP_MAX_CNT)];
 | 
						|
    uint8_t             dut_addr_in_cal[IOT_MAC_ADDR_LEN];
 | 
						|
    /* measured buffer for tone power */
 | 
						|
    uint32_t            tone_pwr_buf[MP_RF_CAL_MEAS_AVG_CNT_MAX];
 | 
						|
    /* measured buffer for dc power */
 | 
						|
    uint32_t            dc_pwr_buf[MP_RF_CAL_MEAS_AVG_CNT_MAX];
 | 
						|
    /* measured buffer for inmage power */
 | 
						|
    uint32_t            img_pwr_buf[MP_RF_CAL_MEAS_AVG_CNT_MAX];
 | 
						|
    /* measured buffer for rx gain */
 | 
						|
    uint8_t             gain_buf[MP_RF_CAL_MEAS_AVG_CNT_MAX];
 | 
						|
    /* power information of the last golden measurement */
 | 
						|
    uint32_t            last_meas_sn;
 | 
						|
    uint32_t            last_tone_pwr;
 | 
						|
    uint32_t            last_dc_pwr;
 | 
						|
    uint32_t            last_img_pwr;
 | 
						|
    float               last_gain;
 | 
						|
    /* led gpio */
 | 
						|
    int                 led_gpio;
 | 
						|
    /* tx pb buffer */
 | 
						|
    uint8_t             rf_pb_buf[520];
 | 
						|
    /* rf tx packet count */
 | 
						|
    uint32_t            tx_done_cnt;
 | 
						|
    /* rf rx packet count */
 | 
						|
    uint32_t            rx_done_cnt;
 | 
						|
    /* store data generated after curve fitting */
 | 
						|
    float               snr_fit_buf[MP_RF_TEST_CASE_TX_CALI_SNR_SAMP_BUF_SIZE];
 | 
						|
    /* array y for curve fitting */
 | 
						|
    float               fit_y[RF_PHY_IQ_PHASE_COMPEN_CODE_MAX];
 | 
						|
    /* array x for curve fitting */
 | 
						|
    float               fit_x[RF_PHY_IQ_PHASE_COMPEN_CODE_MAX];
 | 
						|
    /* the bit mapping of the i/q combination indicates whether the
 | 
						|
     * corresponding i/q combination has received enough data packets
 | 
						|
     * in the tx snr calibration test.
 | 
						|
     */
 | 
						|
    uint8_t             snr_samp_bitmap[MP_RF_TX_CALI_SNR_BM_SIZE];
 | 
						|
    /* temporarily save the maximum value  */
 | 
						|
    tx_cali_comen_result_t max_snr_buf[MP_RF_TX_CALI_SNR_BEST_RESULT_MAX];
 | 
						|
    /* record up to 81 i/q combinations of snr data */
 | 
						|
    snr_record_desc_t   real_snr[MP_RF_TX_CALI_SNR_REAL_DATA_GROUP_SIZE];
 | 
						|
    /* magic number of current tx cali device */
 | 
						|
    uint16_t            cur_tx_cali_dev;
 | 
						|
    /* rf test tx calibration register type */
 | 
						|
    uint8_t             cur_tx_cali_reg_type;
 | 
						|
} mp_rf_ctxt_t;
 | 
						|
 | 
						|
/* global variable for mp rf ctxt */
 | 
						|
static mp_rf_ctxt_t* g_mp_rf_ctxt = NULL;
 | 
						|
 | 
						|
/* variable and function declarations */
 | 
						|
extern os_task_h _init_handle;
 | 
						|
 | 
						|
#if MP_RF_CAL_MEAS_DUMP_EN
 | 
						|
 | 
						|
static void mp_rf_cal_meas_dump(const char *label, void *buf, uint32_t len,
 | 
						|
    uint32_t elm_size)
 | 
						|
{
 | 
						|
    uint32_t i, *p_uint32 = buf;
 | 
						|
    uint16_t *p_uint16 = buf;
 | 
						|
    uint8_t *p_uint8 = buf;
 | 
						|
    uint32_t temp;
 | 
						|
    uint8_t start = 0;
 | 
						|
 | 
						|
    for (i = 0; i < len; i++) {
 | 
						|
        if (0 == (i % 64)) {
 | 
						|
            iot_printf("%s", label);
 | 
						|
            start = 1;
 | 
						|
        }
 | 
						|
        if (sizeof(uint32_t) == elm_size) {
 | 
						|
            temp = *p_uint32++;
 | 
						|
        } else if (sizeof(uint16_t) == elm_size) {
 | 
						|
            temp = (uint32_t)*p_uint16++;
 | 
						|
        } else {
 | 
						|
            temp = (uint32_t)*p_uint8++;
 | 
						|
        }
 | 
						|
        iot_printf("%lu,", temp);
 | 
						|
        if (0 == ((i + 1) % 64)) {
 | 
						|
            start = 0;
 | 
						|
            iot_printf("\n");
 | 
						|
        }
 | 
						|
    }
 | 
						|
    if (start) {
 | 
						|
        iot_printf("\n");
 | 
						|
    }
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
#else /* MP_RF_CAL_MEAS_DUMP_EN */
 | 
						|
 | 
						|
#define mp_rf_cal_meas_dump(label, buf, len, elm_size)
 | 
						|
 | 
						|
#endif /* MP_RF_CAL_MEAS_DUMP_EN */
 | 
						|
 | 
						|
static uint32_t IRAM_ATTR mp_rf_isr(uint32_t vector, iot_addrword_t data)
 | 
						|
{
 | 
						|
    (void)vector;
 | 
						|
    (void)data;
 | 
						|
    uint32_t hwq_id;
 | 
						|
    uint32_t irq_sts, txq_map = 0, ring_map = 0;
 | 
						|
    uint32_t sw_sts = RF_MAC_READ_REG(CFG_RF_MAC_COMMON_INT_REG_26_ADDR);
 | 
						|
    RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_24_ADDR, sw_sts);
 | 
						|
    if (sw_sts & (1 << RF_MAC_SW_ISR_TX_MPDU_COMPLETE)) {
 | 
						|
        irq_sts = RF_MAC_READ_REG(CFG_RF_MAC_COMMON_INT_REG_16_ADDR);
 | 
						|
        txq_map = irq_sts & RF_MAC_INT_HWQ_BIT_MASK;
 | 
						|
        RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_14_ADDR, txq_map);
 | 
						|
        for (hwq_id = 0; txq_map && hwq_id < 7; hwq_id++) {
 | 
						|
            if ((0x1 << hwq_id) & txq_map) {
 | 
						|
                if (hwq_id == 0) {
 | 
						|
                    g_mp_rf_ctxt->tx_done = 1;
 | 
						|
                    g_mp_rf_ctxt->tx_done_cnt++;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (sw_sts & (1 << RF_MAC_SW_ISR_RX_MPDU_COMPLETE)) {
 | 
						|
        irq_sts = RF_MAC_READ_REG(CFG_RF_MAC_COMMON_INT_REG_16_ADDR);
 | 
						|
        ring_map = irq_sts & RF_MAC_INT_RX_RING_BIT_MASK;
 | 
						|
        RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_14_ADDR, ring_map);
 | 
						|
        g_mp_rf_ctxt->rx_done_cnt++;
 | 
						|
        if (g_mp_rf_ctxt->is_golden) {
 | 
						|
            os_set_task_event_with_v_from_isr(_init_handle,
 | 
						|
                1 << MP_RF_EVT_ID_RF_RX);
 | 
						|
        } else {
 | 
						|
            g_mp_rf_ctxt->rx_done = 1;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static void mp_rf_isr_start()
 | 
						|
{
 | 
						|
    g_mp_rf_ctxt->rf_isr_h = iot_interrupt_create(HAL_VECTOR_RFMAC_INT0,
 | 
						|
        HAL_INTR_PRI_7, (iot_addrword_t)NULL, mp_rf_isr);
 | 
						|
    iot_interrupt_attach(g_mp_rf_ctxt->rf_isr_h);
 | 
						|
    iot_interrupt_unmask(g_mp_rf_ctxt->rf_isr_h);
 | 
						|
    RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_10_ADDR, 0xffffffff);
 | 
						|
    RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_14_ADDR, 0xffffffff);
 | 
						|
    RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_18_ADDR, 0xffffffff);
 | 
						|
 | 
						|
    RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_20_ADDR, 0xffffffff);
 | 
						|
    RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_24_ADDR, 0xffffffff);
 | 
						|
    RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_28_ADDR, 0xffffffff);
 | 
						|
}
 | 
						|
 | 
						|
static void mp_rf_txq_init(void)
 | 
						|
{
 | 
						|
    uint32_t tmp;
 | 
						|
    tmp = RF_MAC_READ_REG(CFG_RF_MAC_DEBUG_CFG_ADDR);
 | 
						|
    REG_FIELD_SET(RF_MAC_DEBUG_EN, tmp, 1);
 | 
						|
    REG_FIELD_SET(RF_MAC_DEBUG_START, tmp, 1);
 | 
						|
    REG_FIELD_SET(RF_MAC_DEBUG_TXQ_BITMAP, tmp, 1);
 | 
						|
    RF_MAC_WRITE_REG(CFG_RF_MAC_DEBUG_CFG_ADDR, tmp);
 | 
						|
}
 | 
						|
 | 
						|
static void mp_rf_recv_ring_clear()
 | 
						|
{
 | 
						|
    iot_pkt_t *iot_pkt_array[1] = { 0 };
 | 
						|
 | 
						|
    /* clear invalid data */
 | 
						|
    while(rf_pop_buf_from_ring(&g_mp_rf_ctxt->rx_ring, 1, iot_pkt_array)) {
 | 
						|
        iot_pkt_free(iot_pkt_array[0]);
 | 
						|
    }
 | 
						|
    g_mp_rf_ctxt->rx_done = 0;
 | 
						|
    g_mp_rf_ctxt->rx_done_cnt = 0;
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t mp_rf_check_rf_rx_done()
 | 
						|
{
 | 
						|
    uint8_t temp;
 | 
						|
    /* disable irq */
 | 
						|
    if (!g_mp_rf_ctxt->rx_done) {
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
    os_disable_irq();
 | 
						|
    temp = g_mp_rf_ctxt->rx_done;
 | 
						|
    g_mp_rf_ctxt->rx_done = 0;
 | 
						|
    os_enable_irq();
 | 
						|
    return temp;
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t mp_rf_recv_ring_init()
 | 
						|
{
 | 
						|
    uint8_t ret = 0;
 | 
						|
 | 
						|
    if (!g_mp_rf_ctxt->rx_ring.cfg_enabled) {
 | 
						|
        ring_config config_sof[] =
 | 
						|
        {
 | 
						|
            { CONFIG_RX_ATTENTION, RF_RX_ATTENTION_OFFSET, 0},
 | 
						|
            { CONFIG_RX_MPDU_START, 0, 0 },
 | 
						|
            { CONFIG_RX_MPDU_END, 0, 0 },
 | 
						|
            { CONFIG_RX_PB_START, 0, 0 },
 | 
						|
            { CONFIG_RX_PB_END, 0, 0 },
 | 
						|
            { CONFIG_FC, 0, 0 },
 | 
						|
            { CONFIG_PAYLOAD, RF_RX_PB_PAYLOAD_OFFSET, 0},
 | 
						|
        };
 | 
						|
        ret = rf_rx_buf_ring_init(&g_mp_rf_ctxt->rx_ring,
 | 
						|
            RF_RING_0, PLC_SHORT_RX_BUF_COUNT, PLC_SHORT_BUF_SIZE, NULL, config_sof,
 | 
						|
            0, 0);
 | 
						|
        if (ERR_OK == ret) {
 | 
						|
            mac_rf_rx_ring_enable(&g_mp_rf_ctxt->rx_ring, true);
 | 
						|
            iot_printf("enable rf ring id %d\n", RF_RING_0);
 | 
						|
            return ERR_OK;
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
        iot_printf("rf ring id %d re enable\n", RF_RING_0);
 | 
						|
        rf_rx_ring_fill_hw_cfg(&g_mp_rf_ctxt->rx_ring);
 | 
						|
        mac_rf_rx_ring_enable(&g_mp_rf_ctxt->rx_ring, true);
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
void mp_rf_clear_rf_common()
 | 
						|
{
 | 
						|
    uint32_t tmp;
 | 
						|
 | 
						|
    if (!g_mp_rf_ctxt)
 | 
						|
        return;
 | 
						|
 | 
						|
    mac_rf_txq_force_disable(0);
 | 
						|
    mac_rf_rx_ring_enable(&g_mp_rf_ctxt->rx_ring, 0);
 | 
						|
    tmp = RF_MAC_READ_REG(CFG_RF_MAC_DEBUG_CFG_ADDR);
 | 
						|
    REG_FIELD_SET(RF_MAC_DEBUG_EN, tmp, 0);
 | 
						|
    REG_FIELD_SET(RF_MAC_DEBUG_START, tmp, 0);
 | 
						|
    REG_FIELD_SET(RF_MAC_DEBUG_TXQ_BITMAP, tmp, 0);
 | 
						|
    RF_MAC_WRITE_REG(CFG_RF_MAC_DEBUG_CFG_ADDR, tmp);
 | 
						|
 | 
						|
    /* if receiving a packet, wait for the last packet to be received */
 | 
						|
    os_delay(100);
 | 
						|
    mp_rf_recv_ring_clear();
 | 
						|
    g_mp_rf_ctxt->rf_phy_inited = 0;
 | 
						|
}
 | 
						|
 | 
						|
static void mp_rf_common_init(uint8_t option, uint8_t channel)
 | 
						|
{
 | 
						|
    if (!PLC_RF_OPTION_IS_VALID(option)) {
 | 
						|
        iot_printf("%s fail, invalid option %lu\n", __FUNCTION__, option);
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    /* check channel */
 | 
						|
    if (channel >= phy_rf_get_channel_id_max(option) ||
 | 
						|
        channel < RF_CHANNEL_ID_1) {
 | 
						|
        iot_printf("%s fail, invalid channel %lu\n", __FUNCTION__, channel);
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    if (g_mp_rf_ctxt->rf_phy_inited) {
 | 
						|
        if (option == g_mp_rf_ctxt->option &&
 | 
						|
            channel == g_mp_rf_ctxt->channel) {
 | 
						|
            mac_rf_rx_ring_enable(&g_mp_rf_ctxt->rx_ring, 1);
 | 
						|
            goto out;
 | 
						|
        } else {
 | 
						|
            mp_rf_clear_rf_common();
 | 
						|
        }
 | 
						|
    }
 | 
						|
    uint32_t proto = phy_proto_type_get();
 | 
						|
    /* plc cpu and bbcpu sync init, rf rxdc disable */
 | 
						|
    phy_rf_init(proto, option, channel, 1, 0, 0);
 | 
						|
    mp_rf_recv_ring_init();
 | 
						|
    mp_rf_isr_start();
 | 
						|
    mp_rf_txq_init();
 | 
						|
    g_mp_rf_ctxt->option = option;
 | 
						|
    g_mp_rf_ctxt->channel = channel;
 | 
						|
    g_mp_rf_ctxt->phr_mcs = MCS_ID_0;
 | 
						|
    g_mp_rf_ctxt->pld_mcs = MCS_ID_2;
 | 
						|
    g_mp_rf_ctxt->pld_blkz = BLOCK_SIZE_3;
 | 
						|
    g_mp_rf_ctxt->cur_tx_desc = NULL;
 | 
						|
    g_mp_rf_ctxt->tx_desc_idx = 0;
 | 
						|
    g_mp_rf_ctxt->rf_phy_inited = 1;
 | 
						|
    iot_printf("%s ok, option %lu, channel %lu\n", __FUNCTION__, option,
 | 
						|
        channel);
 | 
						|
out:
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
static mp_rf_tx_desc_t *mp_rf_alloc_tx_desc()
 | 
						|
{
 | 
						|
    mp_rf_tx_desc_t *tx_desc = NULL;
 | 
						|
    tx_desc = &g_mp_rf_ctxt->tx_desc_buf[g_mp_rf_ctxt->tx_desc_idx];
 | 
						|
    g_mp_rf_ctxt->tx_desc_idx++;
 | 
						|
    if (g_mp_rf_ctxt->tx_desc_idx >= MP_RF_TX_DESC_CNT) {
 | 
						|
        g_mp_rf_ctxt->tx_desc_idx = 0;
 | 
						|
    }
 | 
						|
    mac_rf_tx_mpdu_fill_dummy(&tx_desc->tx_dummy);
 | 
						|
    os_mem_set(&tx_desc->mpdu_end, 0x0, sizeof(tx_desc->mpdu_end));
 | 
						|
    mac_rf_tx_mpdu_fill_pb_start(&tx_desc->pb_start, g_mp_rf_ctxt->rf_pb_buf,
 | 
						|
         0, 1, 1, PHY_PROTO_TYPE_GET());
 | 
						|
    return tx_desc;
 | 
						|
}
 | 
						|
 | 
						|
static void mp_rf_tx_mpdu_with_tx_cali_samp(RF_TEST_TX_CALI_REG_T type,
 | 
						|
    uint16_t i_reg, uint16_t q_reg, uint16_t dev_id_magic)
 | 
						|
{
 | 
						|
    iot_ftm_mp_rf_tx_cal_update_t cal_update = { 0 };
 | 
						|
 | 
						|
    uint32_t tmp;
 | 
						|
    mp_rf_tx_desc_t *tx_desc;
 | 
						|
    tx_desc = mp_rf_alloc_tx_desc();
 | 
						|
    /* reinit tx dummy node */
 | 
						|
    mac_rf_tx_mpdu_fill_macinfo(
 | 
						|
        &tx_desc->mpdu_start,
 | 
						|
        (rf_tx_mpdu_start*)&tx_desc->tx_dummy,
 | 
						|
        NULL,
 | 
						|
        &tx_desc->mpdu_end,
 | 
						|
        PHY_PROTO_TYPE_GET(),       /* protocol type */
 | 
						|
        0,                          /* need ack */
 | 
						|
        0,                          /* retry cnt */
 | 
						|
        0,                          /* tx power */
 | 
						|
        0,                          /* retry bit en */
 | 
						|
        0,                          /* is msdu */
 | 
						|
        0,                          /* pb buf reuse */
 | 
						|
        0,                          /* tx desc reuse */
 | 
						|
        0,                          /* sw buf offset */
 | 
						|
        0,                          /* is list start */
 | 
						|
        0,                          /* is list end */
 | 
						|
        g_mp_rf_ctxt->phr_mcs,      /* payload hdr mcs */
 | 
						|
        0,                          /* pts */
 | 
						|
        0,                          /* pts off */
 | 
						|
        0,                          /* payload mcs */
 | 
						|
        0,                          /* payload block size */
 | 
						|
        0,                          /* crc32 en */
 | 
						|
        0,                          /* crc32 ofs */
 | 
						|
        0,                          /* hwq id */
 | 
						|
        g_mp_rf_ctxt->option,       /* option */
 | 
						|
        0,                          /* pb num */
 | 
						|
        0);                         /* tx frame len */
 | 
						|
    /* fill phyinfo */
 | 
						|
    mac_rf_tx_mpdu_fill_phyinfo(&tx_desc->mpdu_start, 0);
 | 
						|
 | 
						|
    /* fill tx cal update info */
 | 
						|
    if (type == RF_TEST_TX_CALI_REG_IQ_MAG) {
 | 
						|
        cal_update.tx_iq_mag_update = 1;
 | 
						|
        cal_update.tx_i_mag = i_reg;
 | 
						|
        cal_update.tx_q_mag = q_reg;
 | 
						|
    } else if (type  == RF_TEST_TX_CALI_REG_IQ_PHASE) {
 | 
						|
        cal_update.tx_iq_phase_update = 1;
 | 
						|
        cal_update.tx_i_phase = i_reg;
 | 
						|
        cal_update.tx_q_phase = q_reg;
 | 
						|
    } else if (type  == RF_TEST_TX_CALI_REG_IQ_DC) {
 | 
						|
        cal_update.tx_iq_dc_update = 1;
 | 
						|
        cal_update.tx_i_dc = i_reg;
 | 
						|
        cal_update.tx_q_dc = q_reg;
 | 
						|
    } else {
 | 
						|
        IOT_ASSERT(0);
 | 
						|
    }
 | 
						|
    mp_rf_dut_cal_reg_update(&cal_update);
 | 
						|
 | 
						|
    mac_rf_fill_rftest_txcali_phrinfo(&tx_desc->mpdu_start,
 | 
						|
        PHY_PROTO_TYPE_GET(), glb_cfg.nid, type, dev_id_magic,
 | 
						|
        i_reg | q_reg << 16);
 | 
						|
    if (g_mp_rf_ctxt->cur_tx_desc == NULL) {
 | 
						|
        RF_MAC_WRITE_REG(CFG_RF_MAC_TXQ0_PTR_ADDR,
 | 
						|
            (uint32_t)&tx_desc->mpdu_start);
 | 
						|
        tmp = RF_MAC_READ_REG(CFG_RF_MAC_TXQ_ENABLE_LOAD_REG_ADDR);
 | 
						|
        REG_FIELD_SET(RF_MAC_TXQ_LOAD, tmp, 1);
 | 
						|
        REG_FIELD_SET(RF_MAC_TXQ_ENABLE, tmp, 1);
 | 
						|
        RF_MAC_WRITE_REG(CFG_RF_MAC_TXQ_ENABLE_LOAD_REG_ADDR, tmp);
 | 
						|
    } else {
 | 
						|
        g_mp_rf_ctxt->cur_tx_desc->tx_dummy.next = &tx_desc->mpdu_start;
 | 
						|
    }
 | 
						|
    g_mp_rf_ctxt->cur_tx_desc = tx_desc;
 | 
						|
    iot_printf("--tx cali phr,mcs:%lu,reg_type:%lu,tx_cali_reg:[%d %d]"
 | 
						|
        ",tx_done_cnt:%lu\n", g_mp_rf_ctxt->phr_mcs, type,
 | 
						|
        (int16_t)i_reg, (int16_t)q_reg, g_mp_rf_ctxt->tx_done_cnt);
 | 
						|
    while (g_mp_rf_ctxt->tx_done == 0);
 | 
						|
    g_mp_rf_ctxt->tx_done = 0;
 | 
						|
}
 | 
						|
 | 
						|
static void mp_rf_tx_mpdu(void)
 | 
						|
{
 | 
						|
    uint32_t tmp;
 | 
						|
    mp_rf_tx_desc_t *tx_desc;
 | 
						|
    tx_desc = mp_rf_alloc_tx_desc();
 | 
						|
    /* reinit tx dummy node */
 | 
						|
    mac_rf_tx_mpdu_fill_macinfo(
 | 
						|
        &tx_desc->mpdu_start,
 | 
						|
        (rf_tx_mpdu_start*)&tx_desc->tx_dummy,
 | 
						|
        &tx_desc->pb_start,
 | 
						|
        &tx_desc->mpdu_end,
 | 
						|
        PHY_PROTO_TYPE_GET(),       /* protocol type */
 | 
						|
        0,                          /* need ack */
 | 
						|
        0,                          /* retry cnt */
 | 
						|
        0,                          /* tx power */
 | 
						|
        0,                          /* retry bit en */
 | 
						|
        0,                          /* is msdu */
 | 
						|
        0,                          /* pb buf reuse */
 | 
						|
        0,                          /* tx desc reuse */
 | 
						|
        0,                          /* sw buf offset */
 | 
						|
        1,                          /* is list start */
 | 
						|
        1,                          /* is list end */
 | 
						|
        g_mp_rf_ctxt->phr_mcs,      /* payload hdr mcs */
 | 
						|
        0,                          /* pts */
 | 
						|
        0,                          /* pts off */
 | 
						|
        g_mp_rf_ctxt->pld_mcs,      /* payload mcs */
 | 
						|
        g_mp_rf_ctxt->pld_blkz,     /* payload block size */
 | 
						|
        1,                          /* crc32 en */
 | 
						|
        0,                          /* crc32 ofs */
 | 
						|
        0,                          /* hwq id */
 | 
						|
        g_mp_rf_ctxt->option,       /* option */
 | 
						|
        1,                          /* pb num */
 | 
						|
        0);                         /* tx frame len */
 | 
						|
    /* fill phyinfo */
 | 
						|
    mac_rf_tx_mpdu_fill_phyinfo(&tx_desc->mpdu_start, 0);
 | 
						|
    /* fill fc */
 | 
						|
    mac_rf_tx_mpdu_fill_phrinfo(&tx_desc->mpdu_start,
 | 
						|
        PHY_PROTO_TYPE_GET(),       /* protocol type */
 | 
						|
        FC_DELIM_SOF,               /* delimiter type */
 | 
						|
        0,                          /* network */
 | 
						|
        glb_cfg.nid,                /* nid */
 | 
						|
        0,                          /* bcn_period_cnt */
 | 
						|
        0,                          /* src tei */
 | 
						|
        PLC_TEI_BCAST,              /* dst tei */
 | 
						|
        g_mp_rf_ctxt->pld_mcs,      /* payload mcs */
 | 
						|
        0,                          /* link id */
 | 
						|
        g_mp_rf_ctxt->pld_blkz,     /* payload pb size */
 | 
						|
        0,                          /* is retry */
 | 
						|
        0,                          /* is enrcy */
 | 
						|
        1);                         /* is bcast */
 | 
						|
    if (g_mp_rf_ctxt->cur_tx_desc == NULL) {
 | 
						|
        RF_MAC_WRITE_REG(CFG_RF_MAC_TXQ0_PTR_ADDR,
 | 
						|
            (uint32_t)&tx_desc->mpdu_start);
 | 
						|
        tmp = RF_MAC_READ_REG(CFG_RF_MAC_TXQ_ENABLE_LOAD_REG_ADDR);
 | 
						|
        REG_FIELD_SET(RF_MAC_TXQ_LOAD, tmp, 1);
 | 
						|
        REG_FIELD_SET(RF_MAC_TXQ_ENABLE, tmp, 1);
 | 
						|
        RF_MAC_WRITE_REG(CFG_RF_MAC_TXQ_ENABLE_LOAD_REG_ADDR, tmp);
 | 
						|
    } else {
 | 
						|
        g_mp_rf_ctxt->cur_tx_desc->tx_dummy.next = &tx_desc->mpdu_start;
 | 
						|
    }
 | 
						|
    g_mp_rf_ctxt->cur_tx_desc = tx_desc;
 | 
						|
    iot_printf("--tx sof,mcs:%lu-%lu,pbsz:%lu,ts:%lu,tx_done_cnt:%lu\n",
 | 
						|
        g_mp_rf_ctxt->phr_mcs, g_mp_rf_ctxt->pld_mcs, g_mp_rf_ctxt->pld_blkz,
 | 
						|
        RGF_MAC_READ_REG(CFG_RD_NTB_ADDR), g_mp_rf_ctxt->tx_done_cnt);
 | 
						|
    while (g_mp_rf_ctxt->tx_done == 0);
 | 
						|
    g_mp_rf_ctxt->tx_done = 0;
 | 
						|
}
 | 
						|
 | 
						|
static void mp_rf_tx_packet(uint32_t interval)
 | 
						|
{
 | 
						|
    mp_rf_tx_mpdu();
 | 
						|
    if (interval) {
 | 
						|
        iot_delay_us(interval);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t mp_rf_check_rx_packet(iot_pkt_t *pkt_buf)
 | 
						|
{
 | 
						|
    IOT_ASSERT(pkt_buf);
 | 
						|
    rf_rx_buf_hdr_t *rx_buf;
 | 
						|
    rf_rx_attention *att;
 | 
						|
    rf_rx_pb_end *pb_ed;
 | 
						|
 | 
						|
    rx_buf = (rf_rx_buf_hdr_t *)iot_pkt_data(pkt_buf);
 | 
						|
    att = &(rx_buf->att);
 | 
						|
    pb_ed = &(rx_buf->pb_ed);
 | 
						|
 | 
						|
    if (!mac_rf_rx_pb_end_get_rx_pb_done(pb_ed)) {
 | 
						|
        iot_printf("%s not done PB\n", __FUNCTION__);
 | 
						|
        return 1;
 | 
						|
    }
 | 
						|
    if (!mac_rf_rx_att_get_rx_mpdu_done(att)) {
 | 
						|
        iot_printf("%s not done RX MPDU\n", __FUNCTION__);
 | 
						|
        return 1;
 | 
						|
    }
 | 
						|
    if (mac_rf_rx_att_get_rx_status(att)) {
 | 
						|
        iot_printf("%s RX STATUS err=%d\n", __FUNCTION__,
 | 
						|
            mac_rf_rx_att_get_rx_status(att));
 | 
						|
        return 1;
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t mp_rf_test_tx_cali_info_parse(rf_rx_mpdu_start *rx_mpdu,
 | 
						|
    uint32_t proto, mp_rf_tx_cali_samp_desc_t *cali_info)
 | 
						|
{
 | 
						|
    int8_t i = 0, q = 0;
 | 
						|
    uint8_t reg_type = 0, test_type, ret = ERR_OK;
 | 
						|
    uint16_t dev_id_magic = 0;
 | 
						|
 | 
						|
    switch (proto) {
 | 
						|
#if SUPPORT_SMART_GRID
 | 
						|
    case PLC_PROTO_TYPE_SG:
 | 
						|
    {
 | 
						|
        frame_control_t *sg_fc;
 | 
						|
        sg_fc = (frame_control_t *)mac_rf_rx_mpdu_st_get_phr_addr(rx_mpdu);
 | 
						|
        test_type = sg_fc->vf.rf_test_tx_cali.test_type;
 | 
						|
        if (test_type != RF_TEST_TYPE_TX_CALI) {
 | 
						|
            ret = ERR_FAIL;
 | 
						|
            goto out;
 | 
						|
        }
 | 
						|
 | 
						|
        dev_id_magic = sg_fc->vf.rf_test_tx_cali.dev_id_magic;
 | 
						|
        reg_type = sg_fc->vf.rf_test_tx_cali.reg_type;
 | 
						|
        i = (int8_t)(sg_fc->vf.rf_test_tx_cali.reg_magic & 0xFF);
 | 
						|
        q = (int8_t)((sg_fc->vf.rf_test_tx_cali.reg_magic >> 16) & 0xFF);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
#if SUPPORT_SOUTHERN_POWER_GRID
 | 
						|
    case PLC_PROTO_TYPE_SPG:
 | 
						|
    {
 | 
						|
        spg_frame_control_t *spg_fc;
 | 
						|
        spg_fc = (spg_frame_control_t *)mac_rf_rx_mpdu_st_get_phr_addr(rx_mpdu);
 | 
						|
        test_type = spg_fc->vf.rf_test_tx_cali.test_type;
 | 
						|
        if (test_type != RF_TEST_TYPE_TX_CALI) {
 | 
						|
            ret = ERR_FAIL;
 | 
						|
            goto out;
 | 
						|
        }
 | 
						|
 | 
						|
        dev_id_magic = spg_fc->vf.rf_test_tx_cali.dev_id_magic;
 | 
						|
        reg_type = spg_fc->vf.rf_test_tx_cali.reg_type;
 | 
						|
        i = (int8_t)(spg_fc->vf.rf_test_tx_cali.reg_magic & 0xFF);
 | 
						|
        q = (int8_t)((spg_fc->vf.rf_test_tx_cali.reg_magic >> 16) & 0xFF);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
    default:
 | 
						|
    {
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    }
 | 
						|
 | 
						|
    switch (reg_type) {
 | 
						|
    case RF_TEST_TX_CALI_REG_IQ_MAG:
 | 
						|
    {
 | 
						|
        if (!rf_phy_iq_mag_compen_code_valid(i) ||
 | 
						|
            !rf_phy_iq_mag_compen_code_valid(q)) {
 | 
						|
            ret = ERR_FAIL;
 | 
						|
            goto out;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case RF_TEST_TX_CALI_REG_IQ_PHASE:
 | 
						|
    {
 | 
						|
        if (!rf_phy_iq_phase_compen_code_valid(i) ||
 | 
						|
            !rf_phy_iq_phase_compen_code_valid(q)) {
 | 
						|
            ret = ERR_FAIL;
 | 
						|
            goto out;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    cali_info->reg_type = reg_type;
 | 
						|
    cali_info->i = i;
 | 
						|
    cali_info->q = q;
 | 
						|
    cali_info->dev_id_magic = dev_id_magic;
 | 
						|
    cali_info->raw_snr = mac_rf_rx_mpdu_st_get_raw_snr(rx_mpdu);
 | 
						|
out:
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
static void mp_rf_rx_show_message_info(iot_pkt_t *pkt_buf)
 | 
						|
{
 | 
						|
    IOT_ASSERT(pkt_buf);
 | 
						|
    int8_t rssi, snr, i;
 | 
						|
    uint8_t rx_gain;
 | 
						|
    uint8_t *data;
 | 
						|
    int16_t dlt;
 | 
						|
    int32_t ppm;
 | 
						|
    /* mac proto */
 | 
						|
    uint32_t proto = PHY_PROTO_TYPE_GET();
 | 
						|
    rf_rx_buf_hdr_t *rx_buf =
 | 
						|
        (rf_rx_buf_hdr_t *)iot_pkt_data(pkt_buf);
 | 
						|
    rf_rx_attention *rx_att = &(rx_buf->att);
 | 
						|
    rf_rx_mpdu_start *rx_mpdu = &(rx_buf->mpdu_st);
 | 
						|
    rf_rx_pb_start *pb_st = &(rx_buf->pb_st);
 | 
						|
    rf_rx_pb_end *pb_end = &(rx_buf->pb_ed);
 | 
						|
    /* get rx fc message */
 | 
						|
    rx_fc_msg_t rx_fc_msg = {0};
 | 
						|
    mac_rf_get_rx_frm_msg_from_fc(proto,
 | 
						|
        mac_rf_rx_mpdu_st_get_phr_addr(rx_mpdu),
 | 
						|
        &rx_fc_msg);
 | 
						|
 | 
						|
    rssi = mac_rf_rx_mpdu_st_get_rssi(rx_mpdu);
 | 
						|
    snr = mac_rf_rx_mpdu_st_get_avg_snr(rx_mpdu);
 | 
						|
    rx_gain = mac_rf_rx_mpdu_st_get_rx_gain(rx_mpdu);
 | 
						|
    dlt = mac_rf_rx_pb_end_get_mismatch_dlt(pb_end);
 | 
						|
    ppm = mac_rf_rx_mpdu_st_get_rx_ppmhz(rx_mpdu);
 | 
						|
 | 
						|
    switch(rx_fc_msg.delimiter) {
 | 
						|
    case FC_DELIM_BEACON:
 | 
						|
    {
 | 
						|
        iot_printf("rx_bcn nid:0x%x, stei:%d, dtei:%d, phr_mcs:%d, "
 | 
						|
            "pld_mcs:%d, gain:%d, rssi:%d, snr:%d, dlt:%d, ppm:%d, "
 | 
						|
            "pb_crc_err:%lu\n", rx_fc_msg.nid, rx_fc_msg.src_tei,
 | 
						|
            rx_fc_msg.dst_tei, rx_att->phr_mcs, rx_fc_msg.rf_mcs,
 | 
						|
            rx_gain, rssi, snr, dlt, ppm, pb_end->rx_beacon_pld_crc_err);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case FC_DELIM_SOF:
 | 
						|
    {
 | 
						|
        iot_printf("rx_sof nid:0x%x, stei:%d, dtei:%d, phr_mcs:%d"
 | 
						|
            ", pld_mcs:%d, ssn:%d, gain:%d, rssi:%d, "
 | 
						|
            "snr:%d, dlt:%d, ppm:%d, pb_crc_err:%lu\n", rx_fc_msg.nid,
 | 
						|
            rx_fc_msg.src_tei, rx_fc_msg.dst_tei,
 | 
						|
            rx_att->phr_mcs, rx_fc_msg.rf_mcs, pb_st->ssn, rx_gain, rssi,
 | 
						|
            snr, dlt, ppm, pb_end->rx_pb_crc_err);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case FC_DELIM_RF_TEST:
 | 
						|
    {
 | 
						|
        iot_printf("rx_rf_test nid:0x%x, phr_mcs:%d, gain:%d, rssi:%d,"
 | 
						|
            " snr:%d, ppm:%d, phr_info:", rx_fc_msg.nid, rx_att->phr_mcs,
 | 
						|
            rx_gain, rssi, snr, ppm);
 | 
						|
        data = (uint8_t *)mac_rf_rx_mpdu_st_get_phr_addr(rx_mpdu);
 | 
						|
        for (i = 0; i < 16; i++)
 | 
						|
            iot_printf("%x ", data[i]);
 | 
						|
        iot_printf("\n");
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void mp_rf_recover_def_rate()
 | 
						|
{
 | 
						|
    if (g_mp_rf_ctxt->option == RF_OPTION_3) {
 | 
						|
        g_mp_rf_ctxt->phr_mcs = MCS_ID_2;
 | 
						|
        g_mp_rf_ctxt->pld_mcs = MCS_ID_2;
 | 
						|
        g_mp_rf_ctxt->pld_blkz = BLOCK_SIZE_1;
 | 
						|
    } else {
 | 
						|
        g_mp_rf_ctxt->phr_mcs = MCS_ID_0;
 | 
						|
        g_mp_rf_ctxt->pld_mcs = MCS_ID_1;
 | 
						|
        g_mp_rf_ctxt->pld_blkz = BLOCK_SIZE_1;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static int16_t mp_rf_calc_avg_value(int8_t *data, uint16_t cnt)
 | 
						|
{
 | 
						|
    uint16_t i;
 | 
						|
    int32_t sum = 0, avg;
 | 
						|
 | 
						|
    if (!cnt) {
 | 
						|
        avg = 0;
 | 
						|
        goto ret;
 | 
						|
    }
 | 
						|
 | 
						|
    if (cnt <= 6) {
 | 
						|
        for (i = 0; i < cnt; i++) {
 | 
						|
            sum += data[i];
 | 
						|
        }
 | 
						|
        avg = 10 * sum / cnt;
 | 
						|
        goto ret;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_bubble_sort_int8(data, cnt, 1);
 | 
						|
    for (i = 2; i < cnt - 2; i++) {
 | 
						|
        sum += data[i];
 | 
						|
    }
 | 
						|
    avg = 10 * sum / (cnt - 4);
 | 
						|
 | 
						|
ret:
 | 
						|
    return (int16_t)avg;
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t mp_rf_calc_avg_u32(uint32_t *data, uint8_t cnt)
 | 
						|
{
 | 
						|
    uint8_t i;
 | 
						|
    uint64_t sum = 0;
 | 
						|
    for (i = 0; i < cnt; i++) {
 | 
						|
        sum += (uint64_t)data[i];
 | 
						|
    }
 | 
						|
    return (uint32_t)((float)sum / cnt + 0.5);
 | 
						|
}
 | 
						|
 | 
						|
static float mp_rf_calc_avg_u8(uint8_t *data, uint8_t cnt)
 | 
						|
{
 | 
						|
    uint8_t i;
 | 
						|
    uint32_t sum = 0;
 | 
						|
    for (i = 0; i < cnt; i++) {
 | 
						|
        sum += (uint32_t)data[i];
 | 
						|
    }
 | 
						|
    return (float)sum / cnt;
 | 
						|
}
 | 
						|
 | 
						|
static void mp_rf_add_tx_evm_samp(mp_rf_test_cmd_tx_evm_t *dut,
 | 
						|
    int8_t snr, int8_t rssi)
 | 
						|
{
 | 
						|
    if (g_mp_rf_ctxt->tx_evm_ts != dut->ts ||
 | 
						|
        !iot_mac_addr_cmp(g_mp_rf_ctxt->dut_addr_in_tx_evm, dut->mac_addr)) {
 | 
						|
        g_mp_rf_ctxt->tx_evm_ts = dut->ts;
 | 
						|
        iot_mac_addr_cpy(g_mp_rf_ctxt->dut_addr_in_tx_evm, dut->mac_addr);
 | 
						|
        g_mp_rf_ctxt->recv_data_cnt = 0;
 | 
						|
    }
 | 
						|
 | 
						|
    g_mp_rf_ctxt->snr_buf[g_mp_rf_ctxt->recv_data_cnt] = snr;
 | 
						|
    g_mp_rf_ctxt->rssi_buf[g_mp_rf_ctxt->recv_data_cnt] = rssi;
 | 
						|
    g_mp_rf_ctxt->recv_data_cnt++;
 | 
						|
}
 | 
						|
 | 
						|
static void mp_rf_get_tx_evm_res(mp_rf_test_cmd_tx_evm_t *dut,
 | 
						|
    mp_rf_rsp_tx_evm_t *resp)
 | 
						|
{
 | 
						|
    if (g_mp_rf_ctxt->tx_evm_ts != dut->ts ||
 | 
						|
        !iot_mac_addr_cmp(g_mp_rf_ctxt->dut_addr_in_tx_evm, dut->mac_addr)) {
 | 
						|
        g_mp_rf_ctxt->tx_evm_ts = dut->ts;
 | 
						|
        iot_mac_addr_cpy(g_mp_rf_ctxt->dut_addr_in_tx_evm, dut->mac_addr);
 | 
						|
        g_mp_rf_ctxt->recv_data_cnt = 0;
 | 
						|
        resp->rx_cnt = 0;
 | 
						|
        resp->avg_snr = 0;
 | 
						|
        resp->avg_rssi = 0;
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    resp->rx_cnt = g_mp_rf_ctxt->recv_data_cnt;
 | 
						|
    resp->avg_snr = mp_rf_calc_avg_value(g_mp_rf_ctxt->snr_buf,
 | 
						|
        g_mp_rf_ctxt->recv_data_cnt);
 | 
						|
    resp->avg_rssi = mp_rf_calc_avg_value(g_mp_rf_ctxt->rssi_buf,
 | 
						|
        g_mp_rf_ctxt->recv_data_cnt);
 | 
						|
}
 | 
						|
 | 
						|
static void mp_rf_add_tx_cali_samp(mp_rf_tx_cali_samp_desc_t *cali_info)
 | 
						|
{
 | 
						|
    uint16_t i, q, pos, max_code;
 | 
						|
    snr_record_desc_t *record;
 | 
						|
 | 
						|
    i = cali_info->i;
 | 
						|
    q = cali_info->q;
 | 
						|
 | 
						|
    if (g_mp_rf_ctxt->cur_tx_cali_dev != cali_info->dev_id_magic ||
 | 
						|
        g_mp_rf_ctxt->cur_tx_cali_reg_type != cali_info->reg_type) {
 | 
						|
        os_mem_set(g_mp_rf_ctxt->real_snr, 0,
 | 
						|
            sizeof(g_mp_rf_ctxt->real_snr));
 | 
						|
        iot_printf("%s data buf clear\n", __FUNCTION__);
 | 
						|
        g_mp_rf_ctxt->cur_tx_cali_dev = cali_info->dev_id_magic;
 | 
						|
        g_mp_rf_ctxt->cur_tx_cali_reg_type = cali_info->reg_type;
 | 
						|
    }
 | 
						|
    iot_printf("%s reg_type=%d, i=%d, q=%d, snr=%d\n", __FUNCTION__,
 | 
						|
        cali_info->reg_type, i, q, cali_info->raw_snr);
 | 
						|
 | 
						|
    max_code = (cali_info->reg_type == RF_TEST_TX_CALI_REG_IQ_MAG) ?
 | 
						|
        RF_PHY_IQ_MAG_COMPEN_CODE_MAX : RF_PHY_IQ_PHASE_COMPEN_CODE_MAX;
 | 
						|
    pos = MP_RF_IQ_CODE_TO_MAGIC(max_code, i, q);
 | 
						|
    record = g_mp_rf_ctxt->real_snr;
 | 
						|
    for (i = 0; i < MP_RF_TX_CALI_SNR_REAL_DATA_GROUP_SIZE; i++) {
 | 
						|
        if (record[i].magic == pos || record[i].cnt == 0) {
 | 
						|
            record[i].magic = pos;
 | 
						|
            if (record[i].cnt < MP_RF_TX_CALI_SNR_REAL_DATA_GROUP_DEPTH) {
 | 
						|
                record[i].snr[record[i].cnt] = cali_info->raw_snr;
 | 
						|
                record[i].cnt++;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
/* polynomial fitting, y=a0 + a1*x + a2*x*x */
 | 
						|
void mp_rf_least_squarel_liner_fit(float *x, float *y, uint8_t n,
 | 
						|
    float *a0, float *a1, float *a2)
 | 
						|
{
 | 
						|
    float temp = 0;
 | 
						|
    float x0 = n, x1 = 0, x2 = 0, x3 = 0, x4 = 0, x0y1 = 0, x1y1 = 0, x2y1 = 0;
 | 
						|
    float x0x2, x0x3, x0x4, x1x1, x1x2, x1x3, x1x4, x2x2, x2x3, x2x4, x3x3;
 | 
						|
    float a_banshui[3][3], a_ni[3][3];
 | 
						|
    float a_abs;
 | 
						|
    uint8_t i, j;
 | 
						|
 | 
						|
    for (i = 0; i < n; i++) {
 | 
						|
        x0y1 += *(y + i);
 | 
						|
        temp = *(x + i);
 | 
						|
        x1 += temp;
 | 
						|
        x1y1 += temp*(*(y + i));
 | 
						|
        temp *= *(x + i);
 | 
						|
        x2 += temp;
 | 
						|
        x2y1 += temp*(*(y + i));
 | 
						|
        temp *= *(x + i);
 | 
						|
        x3 += temp;
 | 
						|
        temp *= *(x + i);
 | 
						|
        x4 += temp;
 | 
						|
    }
 | 
						|
    x0x2 = x0 * x2;
 | 
						|
    x0x3 = x0 * x3;
 | 
						|
    x0x4 = x0 * x4;
 | 
						|
    x1x1 = x1 * x1;
 | 
						|
    x1x2 = x1 * x2;
 | 
						|
    x1x3 = x1 * x3;
 | 
						|
    x1x4 = x1 * x4;
 | 
						|
    x2x2 = x2 * x2;
 | 
						|
    x2x3 = x2 * x3;
 | 
						|
    x2x4 = x2 * x4;
 | 
						|
    x3x3 = x3 * x3;
 | 
						|
    a_banshui[0][0] = (x2x4 - x3x3);
 | 
						|
    a_banshui[0][1] = -(x1x4 - x2x3);
 | 
						|
    a_banshui[0][2] = (x1x3 - x2x2);
 | 
						|
    a_banshui[1][0] = -(x1x4 - x2x3);
 | 
						|
    a_banshui[1][1] = (x0x4 - x2x2);
 | 
						|
    a_banshui[1][2] = -(x0x3 - x1x2);
 | 
						|
    a_banshui[2][0] = (x1x3 - x2x2);
 | 
						|
    a_banshui[2][1] = -(x0x3 - x1x2);
 | 
						|
    a_banshui[2][2] = (x0x2 - x1x1);
 | 
						|
    a_abs = (x0 * a_banshui[0][0] + x1 * a_banshui[0][1] + x2 * a_banshui[0][2]);
 | 
						|
    for (i = 0; i < 3; i++) {
 | 
						|
        for (j = 0; j < 3; j++) {
 | 
						|
            a_ni[i][j] = a_banshui[i][j] / a_abs;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    *a0 = a_ni[0][0] * x0y1 + a_ni[0][1] * x1y1 + a_ni[0][2] * x2y1;
 | 
						|
    *a1 = a_ni[1][0] * x0y1 + a_ni[1][1] * x1y1 + a_ni[1][2] * x2y1;
 | 
						|
    *a2 = a_ni[2][0] * x0y1 + a_ni[2][1] * x1y1 + a_ni[2][2] * x2y1;
 | 
						|
    iot_printf("%s a0:%f a1:%f a2:%f\n", __FUNCTION__, *a0, *a1, *a2);
 | 
						|
}
 | 
						|
 | 
						|
static int32_t mp_rf_calculate_expection(int32_t *data, uint8_t cnt)
 | 
						|
{
 | 
						|
    uint8_t i;
 | 
						|
    int32_t sum = 0, avg;
 | 
						|
 | 
						|
    if (!cnt) {
 | 
						|
        avg = 0;
 | 
						|
        goto ret;
 | 
						|
    }
 | 
						|
 | 
						|
    if (cnt <= 10) {
 | 
						|
        for (i = 0; i < cnt; i++) {
 | 
						|
            sum += data[i];
 | 
						|
        }
 | 
						|
        avg = sum / cnt;
 | 
						|
        goto ret;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_bubble_sort_int32(data, cnt, 1);
 | 
						|
    for (i = 3; i < cnt - 3; i++) {
 | 
						|
        sum += data[i];
 | 
						|
    }
 | 
						|
    avg = sum / (cnt - 6);
 | 
						|
ret:
 | 
						|
    return (int16_t)avg;
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t mp_rf_tx_cali_update_best_iq(int8_t max_code)
 | 
						|
{
 | 
						|
    int8_t i, q;
 | 
						|
    uint16_t pos, count = 0, k, j, max_pos;
 | 
						|
    float max_snr;
 | 
						|
 | 
						|
    for(i = 0; i < MP_RF_TX_CALI_SNR_BEST_RESULT_MAX; i++) {
 | 
						|
        g_mp_rf_ctxt->max_snr_buf[i].snr = MP_RF_INVAL_RSSI_SNR;
 | 
						|
        g_mp_rf_ctxt->max_snr_buf[i].i = RF_PHY_IQ_PHASE_COMPEN_CODE_MAX;
 | 
						|
        g_mp_rf_ctxt->max_snr_buf[i].q = RF_PHY_IQ_PHASE_COMPEN_CODE_MAX;
 | 
						|
    }
 | 
						|
 | 
						|
    for(i = 0; i < max_code; i++) {
 | 
						|
        pos = i * max_code;
 | 
						|
        max_snr = MP_RF_INVAL_RSSI_SNR;
 | 
						|
        for (q = 0, max_pos = 0; q < max_code; q++) {
 | 
						|
            if (iot_bitmap_is_set(g_mp_rf_ctxt->snr_samp_bitmap,
 | 
						|
                MP_RF_TX_CALI_SNR_BM_SIZE, pos + q + 1) && max_snr <
 | 
						|
                g_mp_rf_ctxt->snr_fit_buf[pos + q]) {
 | 
						|
                max_pos = q;
 | 
						|
                max_snr = g_mp_rf_ctxt->snr_fit_buf[pos + q];
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        if (max_snr == MP_RF_INVAL_RSSI_SNR) {
 | 
						|
            continue;
 | 
						|
        }
 | 
						|
 | 
						|
        for (k = 0; k < MP_RF_TX_CALI_SNR_BEST_RESULT_MAX; k++) {
 | 
						|
            if (max_snr > g_mp_rf_ctxt->max_snr_buf[k].snr) {
 | 
						|
                count++;
 | 
						|
                for (j = MP_RF_TX_CALI_SNR_BEST_RESULT_MAX - 1; j > k; j--) {
 | 
						|
                    g_mp_rf_ctxt->max_snr_buf[j].snr =
 | 
						|
                        g_mp_rf_ctxt->max_snr_buf[j - 1].snr;
 | 
						|
                    g_mp_rf_ctxt->max_snr_buf[j].i =
 | 
						|
                        g_mp_rf_ctxt->max_snr_buf[j - 1].i;
 | 
						|
                    g_mp_rf_ctxt->max_snr_buf[j].q =
 | 
						|
                        g_mp_rf_ctxt->max_snr_buf[j - 1].q;
 | 
						|
                }
 | 
						|
                g_mp_rf_ctxt->max_snr_buf[k].snr = max_snr;
 | 
						|
                g_mp_rf_ctxt->max_snr_buf[k].i = i;
 | 
						|
                g_mp_rf_ctxt->max_snr_buf[k].q = max_pos;
 | 
						|
                iot_printf("%s pos=%d, i=%d, q=%d, snr=%f, count=%d\n",
 | 
						|
                    __FUNCTION__, k, i, max_pos, max_snr, count);
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    count = min(count, MP_RF_TX_CALI_SNR_BEST_RESULT_MAX);
 | 
						|
 | 
						|
    return count;
 | 
						|
}
 | 
						|
 | 
						|
static void mp_rf_get_tx_cali_res(mp_rf_test_cmd_tx_cali_stat_qr_t *rf_cmd,
 | 
						|
    mp_rf_rsp_tx_cali_t *rsp)
 | 
						|
{
 | 
						|
    int8_t i = 0, q = 0, max_code, loop;
 | 
						|
    uint8_t m, n, cnt;
 | 
						|
    uint8_t *bm;
 | 
						|
    uint16_t pos, bm_size = MP_RF_TX_CALI_SNR_BM_SIZE;
 | 
						|
    float a0, a1, a2, *fit_x, *fit_y, *fit_buf;
 | 
						|
    uint32_t timer_start, time_span;
 | 
						|
    int32_t snr[MP_RF_TX_CALI_SNR_REAL_DATA_GROUP_DEPTH];
 | 
						|
 | 
						|
    iot_printf("%s tx cali type:%d liner_fit_en:%d\n", __FUNCTION__,
 | 
						|
        rf_cmd->type, rf_cmd->liner_fit_en);
 | 
						|
 | 
						|
    switch (rf_cmd->type) {
 | 
						|
    case RF_TEST_TX_CALI_REG_IQ_MAG:
 | 
						|
    {
 | 
						|
        max_code = RF_PHY_IQ_MAG_COMPEN_CODE_MAX;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case RF_TEST_TX_CALI_REG_IQ_PHASE:
 | 
						|
    {
 | 
						|
        max_code = RF_PHY_IQ_PHASE_COMPEN_CODE_MAX;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    /* at least half of the packets received can be considered valid */
 | 
						|
    n = rf_cmd->liner_fit_en ? 2 : 10;
 | 
						|
 | 
						|
    fit_x = g_mp_rf_ctxt->fit_x;
 | 
						|
    fit_y = g_mp_rf_ctxt->fit_y;
 | 
						|
    fit_buf = g_mp_rf_ctxt->snr_fit_buf;
 | 
						|
    os_mem_set(fit_buf, 0, sizeof(g_mp_rf_ctxt->snr_fit_buf));
 | 
						|
 | 
						|
    bm = g_mp_rf_ctxt->snr_samp_bitmap;
 | 
						|
    os_mem_set(bm, 0, bm_size);
 | 
						|
    timer_start = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
    for (i = 0; i < MP_RF_TX_CALI_SNR_REAL_DATA_GROUP_SIZE; i++) {
 | 
						|
        if (g_mp_rf_ctxt->real_snr[i].cnt <= n)
 | 
						|
            continue;
 | 
						|
        /* calculate the mathematical expectation of snr */
 | 
						|
        for (m = 0; m < g_mp_rf_ctxt->real_snr[i].cnt; m++) {
 | 
						|
            snr[m] = g_mp_rf_ctxt->real_snr[i].snr[m];
 | 
						|
        }
 | 
						|
        pos = g_mp_rf_ctxt->real_snr[i].magic;
 | 
						|
        iot_bitmap_set(bm, bm_size, pos + 1);
 | 
						|
        fit_buf[pos] = mp_rf_calculate_expection(snr,
 | 
						|
            g_mp_rf_ctxt->real_snr[i].cnt);
 | 
						|
    }
 | 
						|
 | 
						|
    if (!rf_cmd->liner_fit_en) {
 | 
						|
        goto get_res;
 | 
						|
    }
 | 
						|
 | 
						|
    /* smooth curve, at least twice */
 | 
						|
    for(loop = 0; loop < 2; loop++) {
 | 
						|
        /* keep i unchanged, fit the q curve, and record the fitted data */
 | 
						|
        for (i = 0; i < max_code; i++) {
 | 
						|
            for (q = 0, cnt = 0; q < max_code; q++) {
 | 
						|
                pos = MP_RF_IQ_CODE_TO_MAGIC(max_code, i, q);
 | 
						|
                if (iot_bitmap_is_set(bm, bm_size, pos + 1)) {
 | 
						|
                    fit_y[cnt] = fit_buf[pos];
 | 
						|
                    fit_x[cnt] = q;
 | 
						|
                    cnt++;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            if (cnt) {
 | 
						|
                iot_printf("%s i:%d, cnt:%d, fit_x[%d, %d]\n", __FUNCTION__, i,
 | 
						|
                    cnt, (uint8_t)fit_x[0], (uint8_t)fit_x[cnt - 1]);
 | 
						|
            }
 | 
						|
            /* curve fitting, required data points cannot be too few */
 | 
						|
            if (cnt >= MP_RF_TX_CALI_SNR_LINER_FIT_VALID_SAMP_NUM) {
 | 
						|
                mp_rf_least_squarel_liner_fit(fit_x, fit_y, cnt, &a0, &a1, &a2);
 | 
						|
                /* Generate new data according to fitting parameters */
 | 
						|
                for (q = fit_x[0]; q <= fit_x[cnt - 1]; q++) {
 | 
						|
                    pos = MP_RF_IQ_CODE_TO_MAGIC(max_code, i, q);
 | 
						|
                    if (iot_bitmap_is_set(bm, bm_size, pos + 1)) {
 | 
						|
                        fit_buf[pos] = a0 + a1 * q + a2 * q * q;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        /* keep q unchanged, fit the i curve, and record the fitted data */
 | 
						|
        for (q = 0; q < max_code; q++) {
 | 
						|
            for (i = 0, cnt = 0; i < max_code; i++) {
 | 
						|
                pos = MP_RF_IQ_CODE_TO_MAGIC(max_code, i, q);
 | 
						|
                if (iot_bitmap_is_set(bm, bm_size, pos + 1)) {
 | 
						|
                    fit_y[cnt] = fit_buf[pos];
 | 
						|
                    fit_x[cnt] = i;
 | 
						|
                    cnt++;
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            if (cnt) {
 | 
						|
                iot_printf("%s q:%d, cnt:%d, fit_x[%d, %d]\n", __FUNCTION__, q,
 | 
						|
                    cnt, (uint8_t)fit_x[0], (uint8_t)fit_x[cnt - 1]);
 | 
						|
            }
 | 
						|
            if (cnt >= MP_RF_TX_CALI_SNR_LINER_FIT_VALID_SAMP_NUM) {
 | 
						|
                mp_rf_least_squarel_liner_fit(fit_x, fit_y, cnt, &a0, &a1, &a2);
 | 
						|
                for (i = fit_x[0]; i < fit_x[cnt - 1]; i++) {
 | 
						|
                    pos = MP_RF_IQ_CODE_TO_MAGIC(max_code, i, q);
 | 
						|
                    if (iot_bitmap_is_set(bm, bm_size, pos + 1)) {
 | 
						|
                        fit_buf[pos] = a0 + a1 * i + a2 * i * i;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
get_res:
 | 
						|
    cnt = rf_cmd->liner_fit_en ? MP_RF_TX_CALI_SNR_BEST_RESULT_MAX : 1;
 | 
						|
    rsp->cnt = mp_rf_tx_cali_update_best_iq(max_code);
 | 
						|
    rsp->cnt = min(cnt, rsp->cnt);
 | 
						|
    os_mem_cpy(rsp->bm, bm, bm_size);
 | 
						|
 | 
						|
    time_span = mp_rf_ntb_span_calc(RGF_MAC_READ_REG(CFG_RD_NTB_ADDR),
 | 
						|
        timer_start);
 | 
						|
    time_span = MAC_NTB_TO_MS(time_span);
 | 
						|
    iot_printf("%s time consuming is %d, best_result:", __FUNCTION__,
 | 
						|
        time_span);
 | 
						|
 | 
						|
    for (i = 0; i < rsp->cnt; i++) {
 | 
						|
        rsp->result[i].i = g_mp_rf_ctxt->max_snr_buf[i].i;
 | 
						|
        rsp->result[i].q = g_mp_rf_ctxt->max_snr_buf[i].q;
 | 
						|
        rsp->result[i].snr = g_mp_rf_ctxt->max_snr_buf[i].snr / 10.0;
 | 
						|
        iot_printf("[%f, %d, %d], ", rsp->result[i].snr, rsp->result[i].i,
 | 
						|
            rsp->result[i].q);
 | 
						|
    }
 | 
						|
    iot_printf("\n");
 | 
						|
}
 | 
						|
 | 
						|
static void mp_rf_golden_rf_rx()
 | 
						|
{
 | 
						|
    int8_t rssi, snr;
 | 
						|
    uint16_t num, i;
 | 
						|
    iot_pkt_t *iot_pkt_array[1] = { 0 };
 | 
						|
    mp_rf_test_cmd_hdr_t *test_cmd;
 | 
						|
    mp_rf_test_cmd_chg_phy_t *phy_para;
 | 
						|
    rf_rx_pb_end *pb_end;
 | 
						|
    rf_rx_buf_hdr_t *rx_buf;
 | 
						|
    mp_rf_test_rsp_t* golden_rsp;
 | 
						|
    rf_rx_mpdu_start *rx_mpdu;
 | 
						|
    /* rx fc message */
 | 
						|
    rx_fc_msg_t rx_fc_msg = {0};
 | 
						|
    mp_rf_test_cmd_csr_t* csr_cmd;
 | 
						|
    mp_rf_rsp_csr_t* csr_rsp;
 | 
						|
    mp_rf_tx_cali_samp_desc_t cali_info = { 0 };
 | 
						|
 | 
						|
    golden_rsp = (mp_rf_test_rsp_t *)g_mp_rf_ctxt->rf_pb_buf;
 | 
						|
    golden_rsp->magic = MP_RF_TEST_MSG_MAGIC_NUMBER;
 | 
						|
    golden_rsp->tx_ppm = 0;
 | 
						|
    for (; ;) {
 | 
						|
        if (0 == rf_pop_buf_from_ring(&g_mp_rf_ctxt->rx_ring, 1,
 | 
						|
            iot_pkt_array)) {
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        if (mp_rf_check_rx_packet(iot_pkt_array[0]))
 | 
						|
            goto free_packet;
 | 
						|
        mp_rf_rx_show_message_info(iot_pkt_array[0]);
 | 
						|
        rx_buf = (rf_rx_buf_hdr_t *)iot_pkt_data(iot_pkt_array[0]);
 | 
						|
        test_cmd = (mp_rf_test_cmd_hdr_t *)((uint8_t *)rx_buf +
 | 
						|
            PB_PAYLOAD_OFFSET);
 | 
						|
        rx_mpdu = &rx_buf->mpdu_st;
 | 
						|
        mac_rf_get_rx_frm_msg_from_fc(PHY_PROTO_TYPE_GET(),
 | 
						|
             mac_rf_rx_mpdu_st_get_phr_addr(rx_mpdu), &rx_fc_msg);
 | 
						|
        pb_end = &rx_buf->pb_ed;
 | 
						|
        snr = mac_rf_rx_mpdu_st_get_avg_snr(rx_mpdu);
 | 
						|
        rssi = mac_rf_rx_mpdu_st_get_rssi(rx_mpdu);
 | 
						|
 | 
						|
        if (rx_fc_msg.delimiter == FC_DELIM_RF_TEST &&
 | 
						|
            rx_fc_msg.nid == glb_cfg.nid) {
 | 
						|
            if (mp_rf_test_tx_cali_info_parse(rx_mpdu, PHY_PROTO_TYPE_GET(),
 | 
						|
                &cali_info) == ERR_OK) {
 | 
						|
                mp_rf_add_tx_cali_samp(&cali_info);
 | 
						|
            }
 | 
						|
            goto free_packet;
 | 
						|
        }
 | 
						|
 | 
						|
        if (rx_fc_msg.delimiter != FC_DELIM_SOF
 | 
						|
            || pb_end->rx_pb_crc_err
 | 
						|
            || test_cmd->magic != MP_RF_TEST_MSG_MAGIC_NUMBER
 | 
						|
            || rx_fc_msg.nid != glb_cfg.nid) {
 | 
						|
            goto free_packet;
 | 
						|
        }
 | 
						|
        if (g_mp_rf_ctxt->rf_phy_changing &&
 | 
						|
            test_cmd->msg_id != MP_RF_MSG_ID_CHG_PHY) {
 | 
						|
            goto free_packet;
 | 
						|
        }
 | 
						|
        switch (test_cmd->msg_id) {
 | 
						|
        case MP_RF_MSG_ID_CSR:
 | 
						|
        {
 | 
						|
            csr_cmd = (mp_rf_test_cmd_csr_t*)test_cmd->data;
 | 
						|
            /* do not execute duplicate csr commands */
 | 
						|
            if (iot_mac_addr_cmp(g_mp_rf_ctxt->dut_addr_in_csr,
 | 
						|
                csr_cmd->mac_addr) && g_mp_rf_ctxt->csr_cmd_ts ==
 | 
						|
                csr_cmd->ts) {
 | 
						|
                iot_printf("%s discard the same csr command received\n",
 | 
						|
                    __FUNCTION__);
 | 
						|
                break;
 | 
						|
            }
 | 
						|
            iot_mac_addr_cpy(g_mp_rf_ctxt->dut_addr_in_csr, csr_cmd->mac_addr);
 | 
						|
            g_mp_rf_ctxt->csr_cmd_ts = csr_cmd->ts;
 | 
						|
            golden_rsp->msg_id = MP_RF_MSG_ID_CSR;
 | 
						|
            golden_rsp->tx_snr = snr;
 | 
						|
            golden_rsp->tx_rssi = rssi;
 | 
						|
            golden_rsp->tx_gain = 0;
 | 
						|
 | 
						|
            g_mp_rf_ctxt->phr_mcs = test_cmd->phr_mcs;
 | 
						|
            g_mp_rf_ctxt->pld_mcs = test_cmd->pld_mcs;
 | 
						|
            g_mp_rf_ctxt->pld_blkz = test_cmd->pld_blkz;
 | 
						|
            if (csr_cmd->is_test_mode) {
 | 
						|
                /* use the cert test mode power configuration */
 | 
						|
                mac_rf_set_cert_mode(CERT_TEST_CMD_ENTER_PHY_HPLC2RF_LP);
 | 
						|
                if (g_mp_rf_ctxt->phr_mcs == MCS_ID_5 ||
 | 
						|
                    g_mp_rf_ctxt->phr_mcs == MCS_ID_6 ||
 | 
						|
                    g_mp_rf_ctxt->pld_mcs == MCS_ID_5 ||
 | 
						|
                    g_mp_rf_ctxt->pld_mcs == MCS_ID_6) {
 | 
						|
                    /* mcs 5/6 need special config */
 | 
						|
                    mac_rf_set_cert_16qam_flag(1);
 | 
						|
                } else {
 | 
						|
                    mac_rf_set_cert_16qam_flag(0);
 | 
						|
                }
 | 
						|
            } else {
 | 
						|
                /* cfg tx power */
 | 
						|
                mac_rf_set_target_tx_power(test_cmd->power);
 | 
						|
            }
 | 
						|
            csr_rsp = (mp_rf_rsp_csr_t*)golden_rsp->data;
 | 
						|
            num =  min(MP_RF_CSR_TX_MAX_COUNT, csr_cmd->packet_num);
 | 
						|
            for (i = 0; i < num; i++) {
 | 
						|
                csr_rsp->sn = i;
 | 
						|
                mp_rf_tx_packet(csr_cmd->interval);
 | 
						|
            }
 | 
						|
            if (csr_cmd->is_test_mode) {
 | 
						|
                /* after sending samples, restore the power config. */
 | 
						|
                mac_rf_set_cert_mode(0);
 | 
						|
                mac_rf_set_cert_16qam_flag(0);
 | 
						|
                mac_rf_set_target_tx_power(test_cmd->power);
 | 
						|
            }
 | 
						|
            break;
 | 
						|
         }
 | 
						|
         case MP_RF_MSG_ID_CSI:
 | 
						|
         {
 | 
						|
             g_mp_rf_ctxt->phr_mcs = test_cmd->phr_mcs;
 | 
						|
             g_mp_rf_ctxt->pld_mcs = test_cmd->pld_mcs;
 | 
						|
             g_mp_rf_ctxt->pld_blkz = test_cmd->pld_blkz;
 | 
						|
             /* cfg tx power */
 | 
						|
             mac_rf_set_target_tx_power(test_cmd->power);
 | 
						|
 | 
						|
             golden_rsp->msg_id = MP_RF_MSG_ID_CSI;
 | 
						|
             golden_rsp->tx_snr = snr;
 | 
						|
             golden_rsp->tx_rssi = rssi;
 | 
						|
             golden_rsp->tx_gain = mac_rf_rx_mpdu_st_get_rx_gain(rx_mpdu);
 | 
						|
             mp_rf_tx_packet(0);
 | 
						|
             break;
 | 
						|
         }
 | 
						|
         case MP_RF_MSG_ID_TX_EVM_SAMP:
 | 
						|
         {
 | 
						|
             mp_rf_add_tx_evm_samp((mp_rf_test_cmd_tx_evm_t *)test_cmd->data,
 | 
						|
                 snr, rssi);
 | 
						|
             break;
 | 
						|
         }
 | 
						|
         case MP_RF_MSG_ID_TX_EVM_STAT_QUERY:
 | 
						|
         {
 | 
						|
             golden_rsp->msg_id = MP_RF_MSG_ID_TX_EVM_STAT_QUERY;
 | 
						|
             mp_rf_get_tx_evm_res((mp_rf_test_cmd_tx_evm_t *)test_cmd->data,
 | 
						|
                 (mp_rf_rsp_tx_evm_t *)golden_rsp->data);
 | 
						|
 | 
						|
             /* cfg tx power */
 | 
						|
             mac_rf_set_target_tx_power(test_cmd->power);
 | 
						|
             mp_rf_recover_def_rate();
 | 
						|
             for (i = 0; i < 3; i++)
 | 
						|
                 mp_rf_tx_packet(0);
 | 
						|
             break;
 | 
						|
         }
 | 
						|
        case MP_RF_MSG_ID_CHG_PHY:
 | 
						|
        {
 | 
						|
            phy_para = (mp_rf_test_cmd_chg_phy_t *)test_cmd->data;
 | 
						|
            golden_rsp->msg_id = MP_RF_MSG_ID_CHG_PHY;
 | 
						|
            golden_rsp->tx_snr = 0;
 | 
						|
            golden_rsp->tx_rssi = 0;
 | 
						|
            golden_rsp->tx_gain = 0;
 | 
						|
            /* cfg tx power */
 | 
						|
            mac_rf_set_target_tx_power(test_cmd->power);
 | 
						|
            mp_rf_recover_def_rate();
 | 
						|
            mp_rf_tx_packet(0);
 | 
						|
            g_mp_rf_ctxt->rf_phy_changing = 1;
 | 
						|
            g_mp_rf_ctxt->rf_phy_chg_ts = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
            g_mp_rf_ctxt->target_option = phy_para->option;
 | 
						|
            g_mp_rf_ctxt->target_channel = phy_para->channel;
 | 
						|
            iot_printf("%s -- current phy para[option:%d channel:%d],"
 | 
						|
                " target phy para[option:%d channel:%d]\n",
 | 
						|
                __FUNCTION__, g_mp_rf_ctxt->option, g_mp_rf_ctxt->channel,
 | 
						|
                phy_para->option, phy_para->channel);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        default:
 | 
						|
        {
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        }
 | 
						|
free_packet:
 | 
						|
        iot_pkt_free(iot_pkt_array[0]);
 | 
						|
    }
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
void mp_rf_plc_massage_show(uint8_t *rx_buf)
 | 
						|
{
 | 
						|
    /* mac proto */
 | 
						|
    uint32_t proto = PHY_PROTO_TYPE_GET();
 | 
						|
    /* rx fc message */
 | 
						|
    rx_fc_msg_t rx_fc_msg = {0};
 | 
						|
    rx_buf_hdr_t *rx_buf_t = (rx_buf_hdr_t *)rx_buf;
 | 
						|
    rx_mpdu_start *rx_mpdu = &(rx_buf_t->mpdu_st);
 | 
						|
    rx_pb_start *pb_st = &(rx_buf_t->pb_st);
 | 
						|
    rx_pb_end *pb_end = &(rx_buf_t->pb_ed);
 | 
						|
    if (mac_rx_att_get_is_fcserr(&rx_buf_t->att) == 1) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
    mac_get_rx_frm_msg_from_fc(proto, mac_rx_mpdu_st_get_fc_addr(rx_mpdu),
 | 
						|
        &rx_fc_msg);
 | 
						|
    switch(rx_fc_msg.delimiter){
 | 
						|
    case FC_DELIM_BEACON:
 | 
						|
    {
 | 
						|
        iot_printf("rx bcn nid:0x%x,stei:%d,tmi:%d-%d,fc_phase:%d,"
 | 
						|
            "rx_phase:%d,rssi:%d,gain:%d,snr:%d,pb_crc:%lu\n",
 | 
						|
            rx_fc_msg.nid, rx_fc_msg.src_tei, rx_fc_msg.tmi,rx_fc_msg.tmi_ext,
 | 
						|
            rx_fc_msg.phase, mac_rx_mpdu_st_get_rx_phase(rx_mpdu),
 | 
						|
            PHY_RSSI_FROM_RMI_GAIN(mac_rx_mpdu_st_get_adc_power(rx_mpdu),
 | 
						|
                mac_rx_mpdu_st_get_agc_gain_entry(rx_mpdu)),
 | 
						|
            PHY_GET_AGC_POWER(mac_rx_mpdu_st_get_agc_gain_entry(rx_mpdu)),
 | 
						|
                mac_rx_mpdu_st_get_avg_snr(rx_mpdu),
 | 
						|
            pb_end->rx_pb_crc_err);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case FC_DELIM_SOF:
 | 
						|
    {
 | 
						|
       iot_printf("rx sof nid:0x%x,stei:%lu,dtei:%lu,tmi:%d-%d,"
 | 
						|
            "rx_phase:%d,pb_num:%lu,ssn:%lu,rssi:%d,gain:%d,snr:%d,pb_crc:%lu\n",
 | 
						|
            rx_fc_msg.nid, rx_fc_msg.src_tei, rx_fc_msg.dst_tei, rx_fc_msg.tmi,
 | 
						|
            rx_fc_msg.tmi_ext, mac_rx_mpdu_st_get_rx_phase(rx_mpdu),
 | 
						|
            mac_rx_mpdu_st_get_rx_pb_num(rx_mpdu),
 | 
						|
            mac_rx_pb_st_get_ssn(pb_st),
 | 
						|
            PHY_RSSI_FROM_RMI_GAIN(mac_rx_mpdu_st_get_adc_power(rx_mpdu),
 | 
						|
                mac_rx_mpdu_st_get_agc_gain_entry(rx_mpdu)),
 | 
						|
            PHY_GET_AGC_POWER(mac_rx_mpdu_st_get_agc_gain_entry(rx_mpdu)),
 | 
						|
            mac_rx_mpdu_st_get_avg_snr(rx_mpdu),
 | 
						|
            pb_end->rx_pb_crc_err);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case FC_DELIM_SACK:
 | 
						|
    {
 | 
						|
        iot_printf("rx a ack,stei:%d,dtei:%d,nid:0x%x,result:%d,status:%x\n",
 | 
						|
           rx_fc_msg.src_tei, rx_fc_msg.dst_tei, rx_fc_msg.nid,
 | 
						|
           rx_fc_msg.result_in_sack, rx_fc_msg.bitmap_in_sack);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
    {
 | 
						|
        iot_printf("rx other frame type: %d\n", rx_fc_msg.delimiter);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void mp_rf_comm_test_info_clear()
 | 
						|
{
 | 
						|
    g_mp_rf_ctxt->csr_cmd_ts = 0;
 | 
						|
    g_mp_rf_ctxt->tx_evm_ts = 0;
 | 
						|
    g_mp_rf_ctxt->rf_phy_changing = 0;
 | 
						|
    g_mp_rf_ctxt->rf_phy_chg_ts = 0;
 | 
						|
    g_mp_rf_ctxt->recv_data_cnt = 0;
 | 
						|
    os_mem_set(g_mp_rf_ctxt->dut_addr_in_tx_evm, 0x0, IOT_MAC_ADDR_LEN);
 | 
						|
    os_mem_set(g_mp_rf_ctxt->dut_addr_in_csr, 0x0, IOT_MAC_ADDR_LEN);
 | 
						|
    os_mem_set(g_mp_rf_ctxt->dut_addr_in_cal, 0x0, IOT_MAC_ADDR_LEN);
 | 
						|
    g_mp_rf_ctxt->last_meas_sn = 0;
 | 
						|
    g_mp_rf_ctxt->option = RF_OPTION_INVALID;
 | 
						|
    g_mp_rf_ctxt->channel = RF_CHANNEL_ID_INVALID;
 | 
						|
    g_mp_rf_ctxt->target_option = MP_RF_GOLDEN_DEF_OPTION;
 | 
						|
    g_mp_rf_ctxt->target_channel = MP_RF_GOLDEN_DEF_CHANNEL;
 | 
						|
}
 | 
						|
 | 
						|
static void mp_rf_cal_mode_enter(uint8_t option, uint8_t ch,
 | 
						|
    uint8_t comm_pwr, uint8_t comm_tmi)
 | 
						|
{
 | 
						|
    uint32_t freq;
 | 
						|
    if (!g_mp_rf_ctxt->is_cal_mode) {
 | 
						|
        /* phy tx common init interface */
 | 
						|
        rf_phy_tx_init(phy_rf_get_band_sel(), option);
 | 
						|
        freq = phy_rf_get_channel_freq_by_id(option, ch);
 | 
						|
        /* phy channel setting */
 | 
						|
        bb_rf_reset();
 | 
						|
        bb_rf_set_tx_dc(0, 0);
 | 
						|
        bb_rf_set_tx_iq_mag(0, 0);
 | 
						|
        bb_rf_set_tx_iq_phase(0, 0);
 | 
						|
 | 
						|
        bb_rf_rx_cfg(option, freq);
 | 
						|
        /* Note: here is to increase the rx filter bandwidth, which can improve
 | 
						|
         * the accuracy of golden measurement power.
 | 
						|
         */
 | 
						|
        bb_rf_set_filter(0x10);
 | 
						|
        bb_rf_debug_rx_immd();
 | 
						|
        g_mp_rf_ctxt->is_cal_mode = 1;
 | 
						|
        mp_rf_comm_test_info_clear();
 | 
						|
    }
 | 
						|
    phy_pwr_adjust_set(comm_pwr);
 | 
						|
    glb_cfg.tmi = comm_tmi;
 | 
						|
    iot_printf("%s - option:%lu, ch:%lu, pwr:%lu, tmi:%lu\n", __FUNCTION__,
 | 
						|
        option, ch, comm_pwr, comm_tmi);
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t mp_rf_cal_mode_exit()
 | 
						|
{
 | 
						|
    if (g_mp_rf_ctxt->is_cal_mode) {
 | 
						|
        iot_printf("%s\n", __FUNCTION__);
 | 
						|
        g_mp_rf_ctxt->is_cal_mode = 0;
 | 
						|
        return ERR_OK;
 | 
						|
    }
 | 
						|
    return ERR_EXIST;
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t mp_rf_cal_pwr_meas(uint8_t *dut_addr, uint32_t sn,
 | 
						|
    uint32_t lo_freq, uint16_t tone_idx,
 | 
						|
    uint16_t dc_idx, uint16_t img_idx, uint32_t *tone_pwr,
 | 
						|
    uint32_t *dc_pwr, uint32_t *img_pwr, float *gain, uint8_t try_cnt)
 | 
						|
{
 | 
						|
    uint32_t dump_addr;
 | 
						|
    uint32_t dump_len;
 | 
						|
    uint32_t sample_cnt = 1024 * 8;
 | 
						|
    uint32_t *fft_raw;
 | 
						|
    uint32_t start_ntb, end_ntb;
 | 
						|
    uint8_t i, fix_gain;
 | 
						|
    if (!g_mp_rf_ctxt->is_cal_mode) {
 | 
						|
        /* golden is not in calibration mode, not ready, and returns
 | 
						|
         * error code to DUT.
 | 
						|
         */
 | 
						|
        iot_printf("%s error golden not ready!!!\n", __FUNCTION__);
 | 
						|
        return ERR_NOT_READY;
 | 
						|
    }
 | 
						|
    start_ntb = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
    if (iot_mac_addr_cmp(dut_addr, g_mp_rf_ctxt->dut_addr_in_cal) == 1
 | 
						|
        && g_mp_rf_ctxt->last_meas_sn == sn) {
 | 
						|
        /* repeated measurement request from DUT, directly returning the
 | 
						|
         * latest test results.
 | 
						|
         */
 | 
						|
        iot_printf("%s repeat req-dut[%02x:%02x:%02x:%02x:%02x:%02x], sn:%lu\n",
 | 
						|
            __FUNCTION__, dut_addr[0], dut_addr[1], dut_addr[2], dut_addr[3],
 | 
						|
            dut_addr[4], dut_addr[5], sn);
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    bb_rf_rx_reset();
 | 
						|
    bb_rf_set_fchz(lo_freq);
 | 
						|
    fix_gain = rf_phy_rx_gain_lock(-1);
 | 
						|
    bb_rf_debug_rx_immd();
 | 
						|
    try_cnt = min(try_cnt, MP_RF_CAL_MEAS_AVG_CNT_MAX);
 | 
						|
    if (try_cnt == 0) {
 | 
						|
        try_cnt = MP_RF_CAL_MEAS_AVG_CNT_DEFAULT;
 | 
						|
    }
 | 
						|
    dump_len = phy_ada_dump_addr_get(&dump_addr);
 | 
						|
    IOT_ASSERT((sample_cnt << 2) <= dump_len);
 | 
						|
 | 
						|
    for (i = 0; i < try_cnt; i++) {
 | 
						|
        g_mp_rf_ctxt->gain_buf[i] = fix_gain;
 | 
						|
        rf_phy_ada_dump_entry(dump_addr, sample_cnt << 2);
 | 
						|
        fft_raw = rf_phy_ada_dump_fft_cal((uint32_t *)dump_addr, sample_cnt,
 | 
						|
            512, tone_idx, dc_idx, img_idx);
 | 
						|
        g_mp_rf_ctxt->tone_pwr_buf[i] = fft_raw[tone_idx];
 | 
						|
        g_mp_rf_ctxt->dc_pwr_buf[i] = fft_raw[dc_idx];
 | 
						|
        g_mp_rf_ctxt->img_pwr_buf[i] = fft_raw[img_idx];
 | 
						|
    }
 | 
						|
 | 
						|
    mp_rf_cal_meas_dump("golden_meas gain:", g_mp_rf_ctxt->gain_buf,
 | 
						|
        (uint32_t)try_cnt, sizeof(g_mp_rf_ctxt->gain_buf[0]));
 | 
						|
    mp_rf_cal_meas_dump("golden_meas pwr1:", g_mp_rf_ctxt->tone_pwr_buf,
 | 
						|
        (uint32_t)try_cnt, sizeof(g_mp_rf_ctxt->tone_pwr_buf[0]));
 | 
						|
    mp_rf_cal_meas_dump("golden_meas pwr2:", g_mp_rf_ctxt->dc_pwr_buf,
 | 
						|
        (uint32_t)try_cnt, sizeof(g_mp_rf_ctxt->dc_pwr_buf[0]));
 | 
						|
    mp_rf_cal_meas_dump("golden_meas pwr3:", g_mp_rf_ctxt->img_pwr_buf,
 | 
						|
        (uint32_t)try_cnt, sizeof(g_mp_rf_ctxt->img_pwr_buf[0]));
 | 
						|
    iot_mac_addr_cpy(g_mp_rf_ctxt->dut_addr_in_cal, dut_addr);
 | 
						|
 | 
						|
    g_mp_rf_ctxt->last_meas_sn = sn;
 | 
						|
    g_mp_rf_ctxt->last_tone_pwr = mp_rf_calc_avg_u32(g_mp_rf_ctxt->tone_pwr_buf,
 | 
						|
        try_cnt);
 | 
						|
    g_mp_rf_ctxt->last_dc_pwr = mp_rf_calc_avg_u32(g_mp_rf_ctxt->dc_pwr_buf,
 | 
						|
        try_cnt);
 | 
						|
    g_mp_rf_ctxt->last_img_pwr = mp_rf_calc_avg_u32(g_mp_rf_ctxt->img_pwr_buf,
 | 
						|
        try_cnt);
 | 
						|
    g_mp_rf_ctxt->last_gain = mp_rf_calc_avg_u8(g_mp_rf_ctxt->gain_buf,
 | 
						|
        try_cnt);
 | 
						|
 out:
 | 
						|
    *tone_pwr = g_mp_rf_ctxt->last_tone_pwr;
 | 
						|
    *dc_pwr = g_mp_rf_ctxt->last_dc_pwr;
 | 
						|
    *img_pwr = g_mp_rf_ctxt->last_img_pwr;
 | 
						|
    *gain = g_mp_rf_ctxt->last_gain;
 | 
						|
    end_ntb = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
    iot_printf("%s - lo_freq:%luHz, idx:[%d,%d,%d], power[%d,%d,%d],"
 | 
						|
        "gain %f, cons:%lums\n", __FUNCTION__, lo_freq, tone_idx, dc_idx,
 | 
						|
        img_idx, *tone_pwr, *dc_pwr, *img_pwr, *gain,
 | 
						|
        MAC_NTB_TO_MS(mp_rf_ntb_span_calc(end_ntb, start_ntb)));
 | 
						|
    rf_phy_rx_gain_unlock();
 | 
						|
    return ERR_OK;
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t IRAM_ATTR mp_plc_isr_handler(uint32_t vector, iot_addrword_t data)
 | 
						|
{
 | 
						|
 | 
						|
    uint32_t int_status, tmp;
 | 
						|
    (void)vector;
 | 
						|
    (void)data;
 | 
						|
 | 
						|
    /* read pending interrupt status */
 | 
						|
    int_status = RGF_MAC_READ_REG(CFG_MAC_INT_STS_ADDR);
 | 
						|
    int_status >>= MAC_INT_STATUS_OFFSET;
 | 
						|
    /* clear pending interrupt status */
 | 
						|
    RGF_MAC_WRITE_REG(CFG_MAC_INT_CLR_ADDR,
 | 
						|
        (int_status << MAC_INT_CLR_0_OFFSET));
 | 
						|
    tmp = RGF_MAC_READ_REG(CFG_RX_INT_CLR_ADDR);
 | 
						|
    REG_FIELD_SET(CFG_RX_MPDU_INT_CLR_0, tmp, 1);
 | 
						|
    RGF_MAC_WRITE_REG(CFG_RX_INT_CLR_ADDR, tmp);
 | 
						|
    if (int_status & (1 << MAC_ISR_MPDU_RX_ID)) {
 | 
						|
        os_set_task_event_with_v_from_isr(_init_handle,
 | 
						|
            1 << MP_RF_EVT_ID_PLC_RX);
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static void mp_plc_isr_reset()
 | 
						|
{
 | 
						|
    uint32_t prio_mask;
 | 
						|
 | 
						|
    /* disable all mac interrupt and clean up any pending interrupt */
 | 
						|
    RGF_MAC_WRITE_REG(CFG_INT_ENA_MASK_ADDR, 0);
 | 
						|
 | 
						|
     /* clean up all pending interrupt */
 | 
						|
    RGF_MAC_WRITE_REG(CFG_MAC_INT_CLR_ADDR, CFG_INT_ENABLE_MASK_MASK);
 | 
						|
    /* assign priority 0 interrupts, CPU0 & CPU1 use the interrupt */
 | 
						|
    prio_mask = 1 << (MAC_ISR_MPDU_RX_ID + CFG_INT_PRI0_MASK_OFFSET);
 | 
						|
    RGF_MAC_WRITE_REG(CFG_INT_PRI0_MASK_ADDR, prio_mask);
 | 
						|
}
 | 
						|
 | 
						|
void mp_plc_isr_init(void)
 | 
						|
{
 | 
						|
    /* allocate soc irq resource */
 | 
						|
    g_mp_rf_ctxt->plc_isr_0_h = iot_interrupt_create(HAL_VECTOR_MAC_0,
 | 
						|
        HAL_INTR_PRI_7, (iot_addrword_t)NULL, mp_plc_isr_handler);
 | 
						|
    g_mp_rf_ctxt->plc_isr_1_h = iot_interrupt_create(HAL_VECTOR_MAC_1,
 | 
						|
        HAL_INTR_PRI_7, (iot_addrword_t)NULL, mp_plc_isr_handler);
 | 
						|
    g_mp_rf_ctxt->plc_isr_2_h = iot_interrupt_create(HAL_VECTOR_MAC_2,
 | 
						|
        HAL_INTR_PRI_7, (iot_addrword_t)NULL, mp_plc_isr_handler);
 | 
						|
 | 
						|
    /* attach soc irq resource */
 | 
						|
    iot_interrupt_attach(g_mp_rf_ctxt->plc_isr_0_h);
 | 
						|
    iot_interrupt_attach(g_mp_rf_ctxt->plc_isr_1_h);
 | 
						|
    iot_interrupt_attach(g_mp_rf_ctxt->plc_isr_2_h);
 | 
						|
    /* enable soc irq */
 | 
						|
    iot_interrupt_unmask(g_mp_rf_ctxt->plc_isr_0_h);
 | 
						|
    iot_interrupt_unmask(g_mp_rf_ctxt->plc_isr_1_h);
 | 
						|
    iot_interrupt_unmask(g_mp_rf_ctxt->plc_isr_2_h);
 | 
						|
 | 
						|
    /* enable interrupt: MAC_ISR_MPDU_RX_ID */
 | 
						|
    RGF_MAC_WRITE_REG(CFG_INT_ENA_MASK_ADDR, 1 << MAC_ISR_MPDU_RX_ID);
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t mp_rf_golden_plc_rx(void)
 | 
						|
{
 | 
						|
    uint8_t *rx_buf = NULL, *rx_pb_buf, *tx_pb_buf, *data;
 | 
						|
    uint8_t ret = ERR_OK;
 | 
						|
    uint8_t reinit = 0;
 | 
						|
    float gain = 0.0;
 | 
						|
    mp_rf_cal_msg_hdr_t *cmd_hdr, *rsp_hdr;
 | 
						|
    mp_rf_cal_meas_cfg_t *meas_cfg;
 | 
						|
    mp_rf_cal_meas_req_t *meas_req;
 | 
						|
    mp_rf_cal_meas_rsp_t *meas_rsp;
 | 
						|
    uint32_t tone_pwr, dc_pwr, img_pwr;
 | 
						|
    rx_buf_hdr_t *hdr = NULL;
 | 
						|
    rx_fc_msg_t rx_fc_msg = {0};
 | 
						|
    mp_rf_rsp_tx_cali_t* tx_cali_res;
 | 
						|
    while (!is_rx_ring0_empty()) {
 | 
						|
        rx_buf = pop_rx_buf_from_ring(0);
 | 
						|
        if (!rx_buf) {
 | 
						|
            continue;
 | 
						|
        }
 | 
						|
 | 
						|
        mp_rf_plc_massage_show(rx_buf);
 | 
						|
        hdr = (rx_buf_hdr_t *)rx_buf;
 | 
						|
        rx_pb_buf = (uint8_t *)(rx_buf + PB_PAYLOAD_OFFSET);
 | 
						|
 | 
						|
        data = rx_pb_buf;
 | 
						|
        cmd_hdr = (mp_rf_cal_msg_hdr_t *)data;
 | 
						|
        data += sizeof(*cmd_hdr);
 | 
						|
        mac_get_rx_frm_msg_from_fc(PHY_PROTO_TYPE_GET(),
 | 
						|
            mac_rx_mpdu_st_get_fc_addr(&hdr->mpdu_st), &rx_fc_msg);
 | 
						|
        if (rx_fc_msg.delimiter != FC_DELIM_SOF ||
 | 
						|
            rx_fc_msg.nid != glb_cfg.nid
 | 
						|
            || cmd_hdr->magic != MP_RF_TEST_MSG_MAGIC_NUMBER) {
 | 
						|
            continue;
 | 
						|
        }
 | 
						|
        tx_pb_buf = (uint8_t *)phy_get_pb_buf_ptr_from_mpdu(mpdu_start);
 | 
						|
        rsp_hdr = (mp_rf_cal_msg_hdr_t *)tx_pb_buf;
 | 
						|
        rsp_hdr->msg_id = cmd_hdr->msg_id;
 | 
						|
        rsp_hdr->magic = cmd_hdr->magic;
 | 
						|
        iot_mac_addr_cpy(rsp_hdr->dut_addr, cmd_hdr->dut_addr);
 | 
						|
        rsp_hdr->sn = cmd_hdr->sn;
 | 
						|
 | 
						|
        switch (cmd_hdr->msg_id) {
 | 
						|
        case MP_RF_CAL_MSG_ID_MEAS_CFG:
 | 
						|
        {
 | 
						|
            meas_cfg = (mp_rf_cal_meas_cfg_t *)data;
 | 
						|
            if (meas_cfg->meas_en) {
 | 
						|
                mp_rf_cal_mode_enter(meas_cfg->option, meas_cfg->ch,
 | 
						|
                    meas_cfg->comm_pwr, meas_cfg->comm_tmi);
 | 
						|
            } else {
 | 
						|
                ret = mp_rf_cal_mode_exit();
 | 
						|
                if (ret == ERR_OK) {
 | 
						|
                    /* golden exit calibration mode */
 | 
						|
                    reinit = 1;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            rsp_hdr->option = ERR_OK;
 | 
						|
            tx_send_packet_interval(10);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case MP_RF_CAL_MSG_ID_MEAS_REQ:
 | 
						|
        {
 | 
						|
            meas_req = (mp_rf_cal_meas_req_t *)data;
 | 
						|
            meas_rsp = (mp_rf_cal_meas_rsp_t *)rsp_hdr->data;
 | 
						|
            ret = mp_rf_cal_pwr_meas(cmd_hdr->dut_addr, cmd_hdr->sn,
 | 
						|
                meas_req->lo_freq, meas_req->tone_idx,
 | 
						|
                meas_req->dc_idx, meas_req->img_idx,
 | 
						|
                &tone_pwr, &dc_pwr, &img_pwr, &gain, meas_req->avg_cnt);
 | 
						|
            rsp_hdr->option = ret;
 | 
						|
            if (ret == ERR_OK) {
 | 
						|
                meas_rsp->tone_pwr = tone_pwr;
 | 
						|
                meas_rsp->dc_pwr = dc_pwr;
 | 
						|
                meas_rsp->img_pwr = img_pwr;
 | 
						|
                meas_rsp->gain = (uint8_t)(gain + 0.5);
 | 
						|
                meas_rsp->gain_x100 = (uint16_t)(gain * 100.0 + 0.5);
 | 
						|
                os_mem_set(meas_rsp->rsvd, 0, sizeof(meas_rsp->rsvd));
 | 
						|
            } else {
 | 
						|
                os_mem_set(meas_rsp, 0x0, sizeof(*meas_rsp));
 | 
						|
            }
 | 
						|
            tx_send_packet_interval(10);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case MP_RF_MSG_ID_TX_CALI_STAT_QUERY:
 | 
						|
        {
 | 
						|
            tx_cali_res = (mp_rf_rsp_tx_cali_t*)rsp_hdr->data;
 | 
						|
            mp_rf_get_tx_cali_res((mp_rf_test_cmd_tx_cali_stat_qr_t *)data,
 | 
						|
                tx_cali_res);
 | 
						|
            glb_cfg.tmi = MP_RF_PLC_LARGE_PACKET_TMI;
 | 
						|
            tx_send_packet_interval(10);
 | 
						|
            glb_cfg.tmi = MP_RF_PLC_NORMAL_PACKET_TMI;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        default:
 | 
						|
            break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return reinit;
 | 
						|
}
 | 
						|
 | 
						|
static void mp_rf_cal_plc_comm_init(uint8_t band)
 | 
						|
{
 | 
						|
    uint32_t tmp;
 | 
						|
    static uint8_t first_flag = 0;
 | 
						|
    if (!first_flag) {
 | 
						|
        g_phy_cpu_share_ctxt.pt_mode_entry = 1;
 | 
						|
        dut_flag_set(!g_mp_rf_ctxt->is_golden);
 | 
						|
         /* mac rx common init interface */
 | 
						|
        rx_common_init(band);
 | 
						|
        /* mac tx common init interface */
 | 
						|
        tx_common_init(band);
 | 
						|
        /* setup the rx ring */
 | 
						|
        rx_ring_setup_hw(0, NULL);
 | 
						|
        /* enable the rx ring */
 | 
						|
        rx_ring_enable(0, true);
 | 
						|
        mp_plc_isr_reset();
 | 
						|
        if (g_mp_rf_ctxt->is_golden) {
 | 
						|
            mp_plc_isr_init();
 | 
						|
            phy_rxfd_pkt_det_thd_set(32, 32);
 | 
						|
        }
 | 
						|
        /* update flag */
 | 
						|
        first_flag = 1;
 | 
						|
        glb_cfg.p_type = FC_DELIM_SOF;
 | 
						|
        glb_cfg.tmi = MP_RF_PLC_NORMAL_PACKET_TMI;
 | 
						|
        glb_cfg.ack_en = false;
 | 
						|
 | 
						|
        tmp = PHY_READ_REG(CFG_BB_DBG_BUS_SEL_ADDR);
 | 
						|
        REG_FIELD_SET(SW_TX_PILOT_PSS_OVR_EN, tmp, 1);
 | 
						|
        REG_FIELD_SET(SW_RX_PILOT_PSS_OVR_EN, tmp, 1);
 | 
						|
        REG_FIELD_SET(SW_TX_PILOT_PSS, tmp, 6);
 | 
						|
        REG_FIELD_SET(SW_RX_PILOT_PSS, tmp, 6);
 | 
						|
        PHY_WRITE_REG(CFG_BB_DBG_BUS_SEL_ADDR, tmp);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t mp_rf_dut_test_case_csr(iot_ftm_mp_rf_cmd_hdr_t *cmd,
 | 
						|
    void *rsp)
 | 
						|
{
 | 
						|
    rf_rx_pb_end *pb_end;
 | 
						|
    rf_rx_buf_hdr_t *rx_buf;
 | 
						|
    mp_rf_test_cmd_hdr_t *hdr;
 | 
						|
    mp_rf_test_rsp_t* golden_rsp;
 | 
						|
    mp_rf_test_cmd_csr_t* cmd_csr;
 | 
						|
    iot_ftm_mp_rf_cmd_csr_t* test_csr_cmd;
 | 
						|
    rf_rx_mpdu_start *rx_mpdu = NULL;
 | 
						|
    iot_pkt_t *iot_pkt_array[1] = { 0 };
 | 
						|
    uint32_t time_span, timeout, timer_start, count = 0;
 | 
						|
    iot_ftm_mp_rf_rsp_csr_t *csr_rsp = (iot_ftm_mp_rf_rsp_csr_t *)rsp;
 | 
						|
    uint32_t proto = PHY_PROTO_TYPE_GET();
 | 
						|
    /* get rx fc message */
 | 
						|
    rx_fc_msg_t rx_fc_msg = {0};
 | 
						|
    uint8_t ret = ERR_TIMEOVER, done = 0, rx_done_tmp = 0;
 | 
						|
    mp_rf_rsp_csr_t* csr_info;
 | 
						|
    uint32_t time0, package_dur;
 | 
						|
 | 
						|
    /* cfg DUT tx power */
 | 
						|
    mac_rf_set_target_tx_power(cmd->dut_power);
 | 
						|
 | 
						|
    os_mem_set(csr_rsp, 0, sizeof(*csr_rsp));
 | 
						|
    mp_rf_recover_def_rate();
 | 
						|
 | 
						|
    hdr = (mp_rf_test_cmd_hdr_t *)g_mp_rf_ctxt->rf_pb_buf;
 | 
						|
    hdr->msg_id = MP_RF_MSG_ID_CSR;
 | 
						|
    hdr->power = cmd->golden_power;
 | 
						|
    hdr->pld_blkz = cmd->pld_blkz;
 | 
						|
    hdr->phr_mcs = cmd->phr_mcs;
 | 
						|
    hdr->pld_mcs = cmd->pld_mcs;
 | 
						|
    hdr->magic = MP_RF_TEST_MSG_MAGIC_NUMBER;
 | 
						|
    cmd_csr = (mp_rf_test_cmd_csr_t*)hdr->data;
 | 
						|
    test_csr_cmd = (iot_ftm_mp_rf_cmd_csr_t*)cmd->data;
 | 
						|
    cmd_csr->packet_num = min(test_csr_cmd->packet_num, MP_RF_CSR_TX_MAX_COUNT);
 | 
						|
    cmd_csr->is_test_mode = test_csr_cmd->is_test_mode;
 | 
						|
    cmd_csr->interval = test_csr_cmd->interval;
 | 
						|
    iot_chip_get_mac_addr(cmd_csr->mac_addr);
 | 
						|
    cmd_csr->ts = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
    cmd_csr->rsvd0 = 0;
 | 
						|
    os_mem_set(cmd_csr->rsvd1, 0, sizeof(cmd_csr->rsvd1));
 | 
						|
 | 
						|
    package_dur = phy_rf_get_g_stf_ltf_fl() + phy_rf_get_g_sig_fl() +
 | 
						|
        phy_rf_get_g_phr_fl(hdr->phr_mcs) + phy_rf_get_g_psdu_fl(hdr->pld_mcs,
 | 
						|
        hdr->pld_blkz);
 | 
						|
    iot_printf("%s start -- phr_mcs:%lu, pld_mcs:%lu, pld_blkz:%lu, pwr:%d,"
 | 
						|
        " is_tets_mode:%lu, packet_num:%lu, package_dur:%luus, interval:%lu\n",
 | 
						|
        __FUNCTION__, hdr->phr_mcs, hdr->pld_mcs, hdr->pld_blkz, hdr->power,
 | 
						|
        cmd_csr->is_test_mode, cmd_csr->packet_num, package_dur,
 | 
						|
        cmd_csr->interval);
 | 
						|
 | 
						|
    timeout = min(max(test_csr_cmd->timeout, MP_RF_TEST_CASE_CSR_TIMEOUT_DEF),
 | 
						|
        MP_RF_TEST_CASE_CSR_TIMEOUT_MAX);
 | 
						|
    mp_rf_tx_packet(0);
 | 
						|
    timer_start = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
    time0 = timer_start;
 | 
						|
    do {
 | 
						|
        time_span = mp_rf_ntb_span_calc(RGF_MAC_READ_REG(CFG_RD_NTB_ADDR),
 | 
						|
            timer_start);
 | 
						|
        time_span = MAC_NTB_TO_MS(time_span);
 | 
						|
        if (!csr_rsp->rx_cnt && time_span >= MP_RF_CMD_RETRY_INTERVAL &&
 | 
						|
            count < MP_RF_CMD_RETRY_COUNT) {
 | 
						|
            count++;
 | 
						|
            mp_rf_tx_packet(0);
 | 
						|
            timer_start = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
            timeout -= MP_RF_CMD_RETRY_INTERVAL;
 | 
						|
        }
 | 
						|
        if (!rx_done_tmp) {
 | 
						|
            rx_done_tmp = mp_rf_check_rf_rx_done();
 | 
						|
            if (!rx_done_tmp) {
 | 
						|
                continue;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        if (0 == rf_pop_buf_from_ring(&g_mp_rf_ctxt->rx_ring, 1,
 | 
						|
            iot_pkt_array)) {
 | 
						|
            rx_done_tmp = 0;
 | 
						|
            continue;
 | 
						|
        }
 | 
						|
        if (mp_rf_check_rx_packet(iot_pkt_array[0]))
 | 
						|
            goto free_packet;
 | 
						|
        mp_rf_rx_show_message_info(iot_pkt_array[0]);
 | 
						|
        rx_buf = (rf_rx_buf_hdr_t *)iot_pkt_data(iot_pkt_array[0]);
 | 
						|
        golden_rsp = (mp_rf_test_rsp_t *)((uint8_t *)rx_buf +
 | 
						|
            PB_PAYLOAD_OFFSET);
 | 
						|
        pb_end = &rx_buf->pb_ed;
 | 
						|
        rx_mpdu = &rx_buf->mpdu_st;
 | 
						|
        mac_rf_get_rx_frm_msg_from_fc(proto,
 | 
						|
            mac_rf_rx_mpdu_st_get_phr_addr(rx_mpdu), &rx_fc_msg);
 | 
						|
 | 
						|
        csr_info = (mp_rf_rsp_csr_t*)golden_rsp->data;
 | 
						|
        if ((rx_fc_msg.delimiter == FC_DELIM_SOF) && (!pb_end->rx_pb_crc_err) &&
 | 
						|
            (rx_fc_msg.nid == glb_cfg.nid) &&
 | 
						|
            (golden_rsp->magic == MP_RF_TEST_MSG_MAGIC_NUMBER) &&
 | 
						|
            (golden_rsp->msg_id == MP_RF_MSG_ID_CSR)) {
 | 
						|
            g_mp_rf_ctxt->snr_buf[csr_rsp->rx_cnt] =
 | 
						|
                mac_rf_rx_mpdu_st_get_avg_snr(rx_mpdu);
 | 
						|
            g_mp_rf_ctxt->rssi_buf[csr_rsp->rx_cnt] =
 | 
						|
                mac_rf_rx_mpdu_st_get_rssi(rx_mpdu);
 | 
						|
            /* estimate the remaining time for golden to send data. */
 | 
						|
            if (!csr_rsp->rx_cnt && csr_info->sn < cmd_csr->packet_num) {
 | 
						|
                timer_start = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
                time_span = 0;
 | 
						|
                /* each package plus 3ms fixed consumption */
 | 
						|
                timeout = (package_dur + 3000 + cmd_csr->interval) *
 | 
						|
                (cmd_csr->packet_num - csr_info->sn) / 1000;
 | 
						|
            }
 | 
						|
            csr_rsp->rx_cnt++;
 | 
						|
            if (csr_rsp->rx_cnt >= cmd_csr->packet_num ||
 | 
						|
                csr_info->sn >= cmd_csr->packet_num - 1) {
 | 
						|
                done = 1;
 | 
						|
            }
 | 
						|
        }
 | 
						|
free_packet:
 | 
						|
        iot_pkt_free(iot_pkt_array[0]);
 | 
						|
    } while (time_span < timeout && !done);
 | 
						|
 | 
						|
    if (csr_rsp->rx_cnt) {
 | 
						|
        ret = ERR_OK;
 | 
						|
        csr_rsp->avg_snr = mp_rf_calc_avg_value(g_mp_rf_ctxt->snr_buf,
 | 
						|
            csr_rsp->rx_cnt) / 10;
 | 
						|
        csr_rsp->avg_rssi = mp_rf_calc_avg_value(g_mp_rf_ctxt->rssi_buf,
 | 
						|
            csr_rsp->rx_cnt) / 10;
 | 
						|
    }
 | 
						|
    time_span = mp_rf_ntb_span_calc(RGF_MAC_READ_REG(CFG_RD_NTB_ADDR), time0);
 | 
						|
    time_span = MAC_NTB_TO_MS(time_span);
 | 
						|
    iot_printf("%s csr_rsp: rx_cnt=%lu avg_rssi=%d avg_snr=%d consumed=%lums\n",
 | 
						|
        __FUNCTION__, csr_rsp->rx_cnt, csr_rsp->avg_rssi, csr_rsp->avg_snr,
 | 
						|
        time_span);
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t mp_rf_dut_test_case_csi(iot_ftm_mp_rf_cmd_hdr_t *cmd,
 | 
						|
    void *rsp)
 | 
						|
{
 | 
						|
    rf_rx_pb_end *pb_end;
 | 
						|
    rf_rx_buf_hdr_t *rx_buf;
 | 
						|
    rf_rx_mpdu_start *rx_mpdu;
 | 
						|
    mp_rf_test_cmd_hdr_t *hdr;
 | 
						|
    mp_rf_test_rsp_t* golden_rsp;
 | 
						|
    iot_pkt_t *iot_pkt_array[1] = { 0 };
 | 
						|
    uint32_t timer_start, time_span, timeout, count = 0, done = 0;
 | 
						|
    iot_ftm_mp_rf_rsp_csi_t *csi_rsp = (iot_ftm_mp_rf_rsp_csi_t *)rsp;
 | 
						|
    uint32_t package_dur, proto = PHY_PROTO_TYPE_GET();
 | 
						|
    iot_ftm_mp_rf_cmd_csi_t *csi_cmd;
 | 
						|
    /* get rx fc message */
 | 
						|
    rx_fc_msg_t rx_fc_msg = {0};
 | 
						|
    uint8_t ret = ERR_TIMEOVER, rx_count = 0, rx_done_tmp = 0;;
 | 
						|
    int8_t tx_rssi_thr, rx_rssi_thr, tx_snr_thr, rx_snr_thr;
 | 
						|
    /* cfg DUT tx power */
 | 
						|
    mac_rf_set_target_tx_power(cmd->dut_power);
 | 
						|
 | 
						|
    g_mp_rf_ctxt->phr_mcs = cmd->phr_mcs;
 | 
						|
    g_mp_rf_ctxt->pld_mcs = cmd->pld_mcs;
 | 
						|
    g_mp_rf_ctxt->pld_blkz = cmd->pld_blkz;
 | 
						|
    hdr = (mp_rf_test_cmd_hdr_t *)g_mp_rf_ctxt->rf_pb_buf;
 | 
						|
    hdr->msg_id = MP_RF_MSG_ID_CSI;
 | 
						|
    hdr->power = cmd->golden_power;
 | 
						|
    hdr->pld_blkz = g_mp_rf_ctxt->pld_blkz;
 | 
						|
    hdr->phr_mcs = g_mp_rf_ctxt->phr_mcs;
 | 
						|
    hdr->pld_mcs = g_mp_rf_ctxt->pld_mcs;
 | 
						|
    hdr->magic = MP_RF_TEST_MSG_MAGIC_NUMBER;
 | 
						|
    csi_cmd = (iot_ftm_mp_rf_cmd_csi_t *)cmd->data;
 | 
						|
    package_dur = phy_rf_get_g_stf_ltf_fl() + phy_rf_get_g_sig_fl() +
 | 
						|
        phy_rf_get_g_phr_fl(hdr->phr_mcs) + phy_rf_get_g_psdu_fl(hdr->pld_mcs,
 | 
						|
        hdr->pld_blkz);
 | 
						|
    iot_printf("%s start -- phr_mcs:%lu, pld_mcs:%lu, pld_blkz:%lu, pwr:%d, "
 | 
						|
        "package_dur:%luus, tx_rssi_thr=%d, rx_rssi_thr=%d, tx_snr_thr=%d, "
 | 
						|
        "rx_snr_thr=%d\n", __FUNCTION__, hdr->phr_mcs, hdr->pld_mcs,
 | 
						|
        hdr->pld_blkz, hdr->power, package_dur, csi_cmd->tx_rssi_thr,
 | 
						|
        csi_cmd->rx_rssi_thr, csi_cmd->tx_snr_thr, csi_cmd->rx_snr_thr);
 | 
						|
 | 
						|
    timeout = MP_RF_TEST_CASE_CSI_TIMEOUT_DEF;
 | 
						|
    mp_rf_tx_packet(0);
 | 
						|
    os_mem_set(csi_rsp, 0, sizeof(*csi_rsp));
 | 
						|
    csi_rsp->tx_rssi = MP_RF_INVAL_RSSI_SNR;
 | 
						|
    csi_rsp->rx_rssi = MP_RF_INVAL_RSSI_SNR;
 | 
						|
    csi_rsp->tx_snr = MP_RF_INVAL_RSSI_SNR;
 | 
						|
    csi_rsp->rx_snr = MP_RF_INVAL_RSSI_SNR;
 | 
						|
    tx_rssi_thr = csi_cmd->tx_rssi_thr == MP_RF_INVAL_RSSI_SNR ?
 | 
						|
        MP_RF_CSI_TEST_RSSI_THR : csi_cmd->tx_rssi_thr;
 | 
						|
    rx_rssi_thr = csi_cmd->rx_rssi_thr == MP_RF_INVAL_RSSI_SNR ?
 | 
						|
        MP_RF_CSI_TEST_RSSI_THR : csi_cmd->rx_rssi_thr;
 | 
						|
    tx_snr_thr = csi_cmd->tx_snr_thr == MP_RF_INVAL_RSSI_SNR ?
 | 
						|
        MP_RF_CSI_TEST_SNR_THR : csi_cmd->tx_snr_thr;
 | 
						|
    rx_snr_thr = csi_cmd->rx_snr_thr == MP_RF_INVAL_RSSI_SNR ?
 | 
						|
        MP_RF_CSI_TEST_SNR_THR : csi_cmd->rx_snr_thr;
 | 
						|
    timer_start = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
    do {
 | 
						|
        time_span = mp_rf_ntb_span_calc(RGF_MAC_READ_REG(CFG_RD_NTB_ADDR),
 | 
						|
            timer_start);
 | 
						|
        time_span = MAC_NTB_TO_MS(time_span);
 | 
						|
        if (time_span >= MP_RF_CMD_RETRY_INTERVAL &&
 | 
						|
            count < MP_RF_CMD_RETRY_COUNT) {
 | 
						|
            count++;
 | 
						|
            mp_rf_tx_packet(0);
 | 
						|
            timer_start = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
            timeout -= MP_RF_CMD_RETRY_INTERVAL;
 | 
						|
        }
 | 
						|
 | 
						|
        if (!rx_done_tmp) {
 | 
						|
            rx_done_tmp = mp_rf_check_rf_rx_done();
 | 
						|
            if (!rx_done_tmp) {
 | 
						|
                continue;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        if (0 == rf_pop_buf_from_ring(&g_mp_rf_ctxt->rx_ring, 1,
 | 
						|
            iot_pkt_array)) {
 | 
						|
            rx_done_tmp = 0;
 | 
						|
            continue;
 | 
						|
        }
 | 
						|
        if (mp_rf_check_rx_packet(iot_pkt_array[0]))
 | 
						|
            goto free_packet;
 | 
						|
        mp_rf_rx_show_message_info(iot_pkt_array[0]);
 | 
						|
        rx_buf = (rf_rx_buf_hdr_t *)iot_pkt_data(iot_pkt_array[0]);
 | 
						|
        golden_rsp = (mp_rf_test_rsp_t *)((uint8_t *)rx_buf +
 | 
						|
            PB_PAYLOAD_OFFSET);
 | 
						|
        pb_end = &rx_buf->pb_ed;
 | 
						|
        rx_mpdu = &rx_buf->mpdu_st;
 | 
						|
        mac_rf_get_rx_frm_msg_from_fc(proto,
 | 
						|
            mac_rf_rx_mpdu_st_get_phr_addr(rx_mpdu), &rx_fc_msg);
 | 
						|
 | 
						|
        if ((rx_fc_msg.delimiter == FC_DELIM_SOF) && (!pb_end->rx_pb_crc_err) &&
 | 
						|
            (rx_fc_msg.nid == glb_cfg.nid) &&
 | 
						|
            (golden_rsp->magic == MP_RF_TEST_MSG_MAGIC_NUMBER) &&
 | 
						|
            (golden_rsp->msg_id == MP_RF_MSG_ID_CSI)) {
 | 
						|
            csi_rsp->tx_rssi = max(csi_rsp->tx_rssi, golden_rsp->tx_rssi);
 | 
						|
            csi_rsp->tx_snr = max(csi_rsp->tx_snr, golden_rsp->tx_snr);
 | 
						|
            csi_rsp->tx_gain = max(golden_rsp->tx_gain, csi_rsp->tx_gain);
 | 
						|
            csi_rsp->rx_snr = max(csi_rsp->rx_snr,
 | 
						|
                mac_rf_rx_mpdu_st_get_avg_snr(rx_mpdu));
 | 
						|
            csi_rsp->rx_rssi = max(csi_rsp->rx_rssi,
 | 
						|
                mac_rf_rx_mpdu_st_get_rssi(rx_mpdu));
 | 
						|
            csi_rsp->rx_gain = max(csi_rsp->rx_gain,
 | 
						|
                mac_rf_rx_mpdu_st_get_rx_gain(rx_mpdu));
 | 
						|
            rx_count++;
 | 
						|
            if (rx_count >= 3 || (csi_rsp->tx_rssi >= tx_rssi_thr &&
 | 
						|
                csi_rsp->rx_rssi >= rx_rssi_thr &&
 | 
						|
                csi_rsp->tx_snr >= tx_snr_thr &&
 | 
						|
                csi_rsp->rx_snr >= rx_snr_thr)) {
 | 
						|
                done = 1;
 | 
						|
            }
 | 
						|
            ret = ERR_OK;
 | 
						|
            iot_printf("csi_recv: tx_rssi=%d, rx_rssi=%d, tx_snr=%d,"
 | 
						|
                " rx_snr=%d, tx_gain=%d, rx_gain=%d\n", csi_rsp->tx_rssi,
 | 
						|
                csi_rsp->rx_rssi, csi_rsp->tx_snr, csi_rsp->rx_snr,
 | 
						|
                csi_rsp->tx_gain, csi_rsp->rx_gain);
 | 
						|
        }
 | 
						|
free_packet:
 | 
						|
        iot_pkt_free(iot_pkt_array[0]);
 | 
						|
    } while (time_span < timeout && !done);
 | 
						|
    if (!done) {
 | 
						|
        iot_printf("%s fail....\n", __FUNCTION__);
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t mp_rf_dut_test_case_tx_evm(iot_ftm_mp_rf_cmd_hdr_t *cmd,
 | 
						|
    void *rsp)
 | 
						|
{
 | 
						|
    rf_rx_pb_end *pb_end;
 | 
						|
    rf_rx_buf_hdr_t *rx_buf;
 | 
						|
    rf_rx_mpdu_start *rx_mpdu;
 | 
						|
    mp_rf_test_cmd_hdr_t *hdr;
 | 
						|
    iot_ftm_mp_rf_rsp_tx_evm_t *dut_rsp = (iot_ftm_mp_rf_rsp_tx_evm_t *)rsp;
 | 
						|
    mp_rf_test_cmd_tx_evm_t *tx_evm_cmd;
 | 
						|
    iot_ftm_mp_rf_cmd_tx_evm_t *test_cmd;
 | 
						|
    mp_rf_rsp_tx_evm_t *tx_evm_rsp;
 | 
						|
    mp_rf_test_rsp_t* golden_rsp;
 | 
						|
    iot_pkt_t *iot_pkt_array[1] = { 0 };
 | 
						|
    uint32_t timer_start, time_span, timeout, count = 0, done = 0;
 | 
						|
    uint32_t proto = PHY_PROTO_TYPE_GET();
 | 
						|
    /* get rx fc message */
 | 
						|
    rx_fc_msg_t rx_fc_msg = {0};
 | 
						|
    uint8_t ret = ERR_TIMEOVER, rx_done_tmp = 0;
 | 
						|
    uint16_t packet_num, i;
 | 
						|
 | 
						|
    hdr = (mp_rf_test_cmd_hdr_t *)g_mp_rf_ctxt->rf_pb_buf;
 | 
						|
    hdr->pld_blkz = 0;
 | 
						|
    hdr->phr_mcs = 0;
 | 
						|
    hdr->pld_mcs = 0;
 | 
						|
    hdr->power = cmd->golden_power;
 | 
						|
    hdr->magic = MP_RF_TEST_MSG_MAGIC_NUMBER;
 | 
						|
    hdr->msg_id = MP_RF_MSG_ID_TX_EVM_SAMP;
 | 
						|
    tx_evm_cmd = (mp_rf_test_cmd_tx_evm_t *)hdr->data;
 | 
						|
    iot_chip_get_mac_addr(tx_evm_cmd->mac_addr);
 | 
						|
    tx_evm_cmd->ts = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
 | 
						|
    test_cmd = (iot_ftm_mp_rf_cmd_tx_evm_t *)cmd->data;
 | 
						|
    packet_num = test_cmd->packet_num;
 | 
						|
    packet_num = min(MP_RF_TX_EVM_SMAP_MAX_CNT, packet_num);
 | 
						|
    iot_printf("%s start -- phr_mcs:%lu, pld_mcs:%lu, pld_blkz:%lu, "
 | 
						|
        "is_nor_pwr:%lu, dut_pwr:%d, golden_pwr:%d, packet_num:%lu, "
 | 
						|
        "no_req_flag:%d, interval:%lu\n", __FUNCTION__, cmd->phr_mcs,
 | 
						|
        cmd->pld_mcs, cmd->pld_blkz, test_cmd->is_nor_pwr, cmd->dut_power,
 | 
						|
        cmd->golden_power, packet_num, test_cmd->no_req_flag,
 | 
						|
        test_cmd->interval);
 | 
						|
 | 
						|
    /* step1: send tx evm sample data to golden */
 | 
						|
    if (!test_cmd->is_nor_pwr) {
 | 
						|
        /* use the cert test mode power configuration */
 | 
						|
        mac_rf_set_cert_mode(CERT_TEST_CMD_ENTER_PHY_HPLC2RF_LP);
 | 
						|
        if (cmd->phr_mcs == MCS_ID_5 || cmd->phr_mcs == MCS_ID_6 ||
 | 
						|
            cmd->pld_mcs == MCS_ID_5 || cmd->pld_mcs == MCS_ID_6) {
 | 
						|
            /* mcs 5/6 need special config */
 | 
						|
            mac_rf_set_cert_16qam_flag(1);
 | 
						|
        } else {
 | 
						|
            mac_rf_set_cert_16qam_flag(0);
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
        /* use the power configuration specified by the test script. */
 | 
						|
        mac_rf_set_target_tx_power(cmd->dut_power);
 | 
						|
    }
 | 
						|
    g_mp_rf_ctxt->phr_mcs = cmd->phr_mcs;
 | 
						|
    g_mp_rf_ctxt->pld_mcs = cmd->pld_mcs;
 | 
						|
    g_mp_rf_ctxt->pld_blkz = cmd->pld_blkz;
 | 
						|
    for (i = 0; i < packet_num; i++) {
 | 
						|
        mp_rf_tx_packet(test_cmd->interval);
 | 
						|
    }
 | 
						|
 | 
						|
    /* step2: send command MP_RF_MSG_ID_TX_EVM_STAT_QUERY to get results from
 | 
						|
     * golden and wait for a response.
 | 
						|
     */
 | 
						|
    timeout = MP_RF_TEST_CASE_TX_EVM_TIMEOUT_DEF;
 | 
						|
    timer_start = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
    mp_rf_recover_def_rate();
 | 
						|
    if (!test_cmd->is_nor_pwr) {
 | 
						|
        /* after sending the evm samples, restore the power configuration.
 | 
						|
         * for some DUT, the success rate of query results can be improved.
 | 
						|
         */
 | 
						|
        mac_rf_set_cert_mode(0);
 | 
						|
        mac_rf_set_cert_16qam_flag(0);
 | 
						|
        mac_rf_set_target_tx_power(cmd->dut_power);
 | 
						|
    }
 | 
						|
 | 
						|
    if (test_cmd->no_req_flag) {
 | 
						|
        return ERR_OK;
 | 
						|
    }
 | 
						|
 | 
						|
    hdr->msg_id = MP_RF_MSG_ID_TX_EVM_STAT_QUERY;
 | 
						|
    mp_rf_tx_packet(0);
 | 
						|
 | 
						|
    do {
 | 
						|
        time_span = mp_rf_ntb_span_calc(RGF_MAC_READ_REG(CFG_RD_NTB_ADDR),
 | 
						|
            timer_start);
 | 
						|
        time_span = MAC_NTB_TO_MS(time_span);
 | 
						|
        if (time_span >= MP_RF_CMD_RETRY_INTERVAL &&
 | 
						|
            count < MP_RF_CMD_RETRY_COUNT) {
 | 
						|
            count++;
 | 
						|
            timer_start = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
            timeout -= MP_RF_CMD_RETRY_INTERVAL;
 | 
						|
            mp_rf_tx_packet(0);
 | 
						|
        }
 | 
						|
 | 
						|
        if (!rx_done_tmp) {
 | 
						|
            rx_done_tmp = mp_rf_check_rf_rx_done();
 | 
						|
            if (!rx_done_tmp) {
 | 
						|
                continue;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        if (0 == rf_pop_buf_from_ring(&g_mp_rf_ctxt->rx_ring, 1,
 | 
						|
            iot_pkt_array)) {
 | 
						|
            rx_done_tmp = 0;
 | 
						|
            continue;
 | 
						|
        }
 | 
						|
        if (mp_rf_check_rx_packet(iot_pkt_array[0]))
 | 
						|
            goto free_packet;
 | 
						|
        mp_rf_rx_show_message_info(iot_pkt_array[0]);
 | 
						|
        rx_buf = (rf_rx_buf_hdr_t *)iot_pkt_data(iot_pkt_array[0]);
 | 
						|
        golden_rsp = (mp_rf_test_rsp_t *)((uint8_t *)rx_buf +
 | 
						|
            PB_PAYLOAD_OFFSET);
 | 
						|
        pb_end = &rx_buf->pb_ed;
 | 
						|
        rx_mpdu = &rx_buf->mpdu_st;
 | 
						|
        mac_rf_get_rx_frm_msg_from_fc(proto,
 | 
						|
            mac_rf_rx_mpdu_st_get_phr_addr(rx_mpdu), &rx_fc_msg);
 | 
						|
 | 
						|
        if ((rx_fc_msg.delimiter == FC_DELIM_SOF) && (!pb_end->rx_pb_crc_err) &&
 | 
						|
            (rx_fc_msg.nid == glb_cfg.nid) &&
 | 
						|
            (golden_rsp->msg_id == MP_RF_MSG_ID_TX_EVM_STAT_QUERY) &&
 | 
						|
            (golden_rsp->magic == MP_RF_TEST_MSG_MAGIC_NUMBER)) {
 | 
						|
 | 
						|
            tx_evm_rsp = (mp_rf_rsp_tx_evm_t *)golden_rsp->data;
 | 
						|
            dut_rsp->avg_rssi = tx_evm_rsp->avg_rssi;
 | 
						|
            dut_rsp->avg_snr = tx_evm_rsp->avg_snr;
 | 
						|
            dut_rsp->rx_cnt = tx_evm_rsp->rx_cnt;
 | 
						|
            os_mem_set(dut_rsp->rsvd, 0, sizeof(dut_rsp->rsvd));
 | 
						|
            iot_printf("%s rx_count=%lu, rssi=%f, snr=%f\n", __FUNCTION__,
 | 
						|
                tx_evm_rsp->rx_cnt, (float)tx_evm_rsp->avg_rssi / 10,
 | 
						|
                (float)tx_evm_rsp->avg_snr / 10);
 | 
						|
            ret = ERR_OK;
 | 
						|
            done = 1;
 | 
						|
        }
 | 
						|
free_packet:
 | 
						|
        iot_pkt_free(iot_pkt_array[0]);
 | 
						|
    } while (time_span < timeout && !done);
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t mp_rf_cal_rsp_poll(uint8_t msg_id, uint8_t **buf,
 | 
						|
    uint32_t timeout, mp_rf_cal_msg_hdr_t *req_hdr)
 | 
						|
{
 | 
						|
    uint8_t *rx_buf, *rx_pb_buf, *data;
 | 
						|
    rx_buf_hdr_t *hdr = NULL;
 | 
						|
    mp_rf_cal_msg_hdr_t *rsp_hdr;
 | 
						|
    rx_fc_msg_t rx_fc_msg = {0};
 | 
						|
    uint32_t start_ntb, time_sapn;
 | 
						|
    rx_pb_end *pb_end;
 | 
						|
    start_ntb = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
    for (; ;) {
 | 
						|
        if (is_rx_ring0_empty()) {
 | 
						|
            goto next;
 | 
						|
        }
 | 
						|
        rx_buf = pop_rx_buf_from_ring(0);
 | 
						|
        if (!rx_buf) {
 | 
						|
            goto next;
 | 
						|
        }
 | 
						|
        mp_rf_plc_massage_show(rx_buf);
 | 
						|
        hdr = (rx_buf_hdr_t *)rx_buf;
 | 
						|
        rx_pb_buf = (uint8_t *)(rx_buf + PB_PAYLOAD_OFFSET);
 | 
						|
        pb_end = &(hdr->pb_ed);
 | 
						|
        data = rx_pb_buf;
 | 
						|
        rsp_hdr = (mp_rf_cal_msg_hdr_t *)data;
 | 
						|
        data += sizeof(*rsp_hdr);
 | 
						|
        mac_get_rx_frm_msg_from_fc(PHY_PROTO_TYPE_GET(),
 | 
						|
            mac_rx_mpdu_st_get_fc_addr(&hdr->mpdu_st), &rx_fc_msg);
 | 
						|
 | 
						|
        if (rx_fc_msg.delimiter == FC_DELIM_SOF && !pb_end->rx_pb_crc_err
 | 
						|
            && rx_fc_msg.nid == glb_cfg.nid
 | 
						|
            && rsp_hdr->magic == MP_RF_TEST_MSG_MAGIC_NUMBER
 | 
						|
            && rsp_hdr->msg_id == msg_id) {
 | 
						|
            if (iot_mac_addr_cmp(req_hdr->dut_addr, rsp_hdr->dut_addr) == 1
 | 
						|
                && req_hdr->sn == rsp_hdr->sn) {
 | 
						|
                *buf = rx_pb_buf;
 | 
						|
                return ERR_OK;
 | 
						|
            }
 | 
						|
        }
 | 
						|
next:
 | 
						|
        time_sapn = mp_rf_ntb_span_calc(RGF_MAC_READ_REG(CFG_RD_NTB_ADDR),
 | 
						|
            start_ntb);
 | 
						|
        if (MAC_NTB_TO_MS(time_sapn) > timeout) {
 | 
						|
            break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return ERR_TIMEOVER;
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t mp_rf_dut_test_case_tx_cali_exec(
 | 
						|
    iot_ftm_mp_rf_cmd_tx_cali_t* test_cmd, uint8_t** buf, uint16_t dev_id_magic)
 | 
						|
{
 | 
						|
    uint32_t pos;
 | 
						|
    mp_rf_test_cmd_tx_cali_stat_qr_t *rf_cmd;
 | 
						|
    /* get rx fc message */
 | 
						|
    int8_t i, q, ret = ERR_TIMEOVER;
 | 
						|
    uint8_t *tx_pb_buf;
 | 
						|
    uint8_t repeat_cnt, max_code;
 | 
						|
    mp_rf_cal_msg_hdr_t *rsp_hdr;
 | 
						|
    mp_rf_cal_msg_hdr_t *req_hdr;
 | 
						|
    uint8_t *bm = g_mp_rf_ctxt->snr_samp_bitmap;
 | 
						|
    uint8_t bm_size = MP_RF_TX_CALI_SNR_BM_SIZE;
 | 
						|
 | 
						|
    max_code = (test_cmd->type == RF_TEST_TX_CALI_REG_IQ_MAG) ?
 | 
						|
        RF_PHY_IQ_MAG_COMPEN_CODE_MAX : RF_PHY_IQ_PHASE_COMPEN_CODE_MAX;
 | 
						|
    repeat_cnt = test_cmd->repeat_cnt;
 | 
						|
    while (repeat_cnt-- > 0) {
 | 
						|
        for (i = 0; i < max_code; i++) {
 | 
						|
            for (q = 0; q < max_code; q++) {
 | 
						|
                pos = MP_RF_IQ_CODE_TO_MAGIC(max_code, i, q);
 | 
						|
                if (iot_bitmap_is_set(bm, bm_size, pos + 1)) {
 | 
						|
                    mp_rf_tx_mpdu_with_tx_cali_samp(test_cmd->type, i, q,
 | 
						|
                        dev_id_magic);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /* step 2: query result */
 | 
						|
    tx_pb_buf = (uint8_t *)phy_get_pb_buf_ptr_from_mpdu(mpdu_start);
 | 
						|
    req_hdr = (mp_rf_cal_msg_hdr_t *)tx_pb_buf;
 | 
						|
    req_hdr->magic = MP_RF_TEST_MSG_MAGIC_NUMBER;
 | 
						|
    req_hdr->msg_id = MP_RF_MSG_ID_TX_CALI_STAT_QUERY;
 | 
						|
    req_hdr->sn = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
    iot_chip_get_mac_addr(req_hdr->dut_addr);
 | 
						|
    rf_cmd = (mp_rf_test_cmd_tx_cali_stat_qr_t*)req_hdr->data;
 | 
						|
    rf_cmd->dev_id_magic = dev_id_magic;
 | 
						|
    rf_cmd->type = test_cmd->type;
 | 
						|
    rf_cmd->liner_fit_en = test_cmd->liner_fit_en;
 | 
						|
 | 
						|
    for (i = 0; i < 5; i++) {
 | 
						|
        tx_send_packet_interval(10);
 | 
						|
        ret = mp_rf_cal_rsp_poll(MP_RF_MSG_ID_TX_CALI_STAT_QUERY, buf, 50,
 | 
						|
            req_hdr);
 | 
						|
        if (ret == ERR_OK) {
 | 
						|
            rsp_hdr = (mp_rf_cal_msg_hdr_t *)(*buf);
 | 
						|
            *buf = rsp_hdr->data;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t mp_rf_dut_test_case_tx_cali(iot_ftm_mp_rf_cmd_hdr_t *cmd,
 | 
						|
    void *rsp, uint8_t *len)
 | 
						|
{
 | 
						|
    iot_ftm_mp_rf_cmd_tx_cali_t *test_cmd;
 | 
						|
    uint8_t ret = ERR_TIMEOVER, step;
 | 
						|
    int8_t i, q, min_i, max_i, min_q, max_q, min_code, max_code, code;
 | 
						|
    uint16_t dev_id_magic, j;
 | 
						|
    uint8_t buf[IOT_MAC_ADDR_LEN + 4];
 | 
						|
    uint8_t i_sweep_list[RF_PHY_IQ_PHASE_COMPEN_CODE_MAX];
 | 
						|
    uint8_t q_sweep_list[RF_PHY_IQ_PHASE_COMPEN_CODE_MAX], i_cnt = 0, q_cnt = 0;
 | 
						|
    uint8_t *data_buf;
 | 
						|
    mp_rf_rsp_tx_cali_t *rsp_hdr;
 | 
						|
    iot_ftm_mp_rf_rsp_tx_cali_t* dut_rsp;
 | 
						|
    uint32_t timer_start;
 | 
						|
 | 
						|
    g_mp_rf_ctxt->phr_mcs = cmd->phr_mcs;
 | 
						|
    test_cmd = (iot_ftm_mp_rf_cmd_tx_cali_t*)cmd->data;
 | 
						|
    iot_chip_get_mac_addr(buf);
 | 
						|
    timer_start = (uint16_t)RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
    os_mem_cpy(buf + IOT_MAC_ADDR_LEN, &timer_start, 4);
 | 
						|
    dev_id_magic = iot_getcrc16(buf, sizeof(buf), 0);
 | 
						|
 | 
						|
    switch (test_cmd->type) {
 | 
						|
    case RF_TEST_TX_CALI_REG_IQ_MAG:
 | 
						|
    {
 | 
						|
        min_code = 0;
 | 
						|
        max_code = RF_PHY_IQ_MAG_COMPEN_CODE_MAX;
 | 
						|
        step = min(2, test_cmd->step);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case RF_TEST_TX_CALI_REG_IQ_PHASE:
 | 
						|
    {
 | 
						|
        min_code = 0;
 | 
						|
        max_code = RF_PHY_IQ_PHASE_COMPEN_CODE_MAX;
 | 
						|
        step = min(4, test_cmd->step);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        iot_printf("%s parameters error\n", __FUNCTION__);
 | 
						|
        ret = ERR_INVAL;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    min_i = min(max_code, max(min_code, test_cmd->i_min));
 | 
						|
    max_i = min(max_code, max(min_code, test_cmd->i_max));
 | 
						|
    min_q = min(max_code, max(min_code, test_cmd->q_min));
 | 
						|
    max_q = min(max_code, max(min_code, test_cmd->q_max));
 | 
						|
 | 
						|
    if (!step)
 | 
						|
        step = 1;
 | 
						|
    iot_printf("%s tx cali type:%d, i:[%d, %d], q:[%d, %d], step:%d, "
 | 
						|
        "liner_fit_en:%d, is_nor_pwr:%d, power:%d, phr_mcs:%d, rounds:%d\n",
 | 
						|
        __FUNCTION__, test_cmd->type, min_i, max_i, min_q, max_q, step,
 | 
						|
        test_cmd->liner_fit_en, test_cmd->is_nor_pwr, cmd->dut_power,
 | 
						|
        cmd->phr_mcs, test_cmd->rounds);
 | 
						|
    if (max_i < min_i || max_q < min_q || !test_cmd->rounds) {
 | 
						|
        ret = ERR_INVAL;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!test_cmd->is_nor_pwr) {
 | 
						|
        /* use the cert test mode power configuration */
 | 
						|
        mac_rf_set_cert_mode(CERT_TEST_CMD_ENTER_PHY_HPLC2RF_LP);
 | 
						|
        if (cmd->phr_mcs == MCS_ID_5 || cmd->phr_mcs == MCS_ID_6 ||
 | 
						|
            cmd->pld_mcs == MCS_ID_5 || cmd->pld_mcs == MCS_ID_6) {
 | 
						|
            /* mcs 5/6 need special config */
 | 
						|
            mac_rf_set_cert_16qam_flag(1);
 | 
						|
        } else {
 | 
						|
            mac_rf_set_cert_16qam_flag(0);
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
        /* use the power configuration specified by the test script. */
 | 
						|
        mac_rf_set_target_tx_power(cmd->dut_power);
 | 
						|
    }
 | 
						|
 | 
						|
    os_mem_set(g_mp_rf_ctxt->snr_samp_bitmap, 0, MP_RF_TX_CALI_SNR_BM_SIZE);
 | 
						|
    if (test_cmd->iq_delta_en) {
 | 
						|
        for (code = max_i - 1; code > -max_q; code -= step) {
 | 
						|
            if (code > 0) {
 | 
						|
                j = MP_RF_IQ_CODE_TO_MAGIC(max_code, code, 0);
 | 
						|
            } else {
 | 
						|
                j = MP_RF_IQ_CODE_TO_MAGIC(max_code, 0, -code);
 | 
						|
            }
 | 
						|
            iot_bitmap_set(g_mp_rf_ctxt->snr_samp_bitmap,
 | 
						|
                MP_RF_TX_CALI_SNR_BM_SIZE, j + 1);
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
        iot_printf("%s i_sweep_list[", __FUNCTION__);
 | 
						|
        for (i = min_i; i < max_i; i += step) {
 | 
						|
            i_sweep_list[i_cnt] = i;
 | 
						|
            iot_printf("%d, ", i_sweep_list[i_cnt]);
 | 
						|
            i_cnt++;
 | 
						|
        }
 | 
						|
        if (i_sweep_list[i_cnt - 1] < max_i - 1) {
 | 
						|
            i_sweep_list[i_cnt] = max_i - 1;
 | 
						|
            iot_printf("%d", i_sweep_list[i_cnt]);
 | 
						|
            i_cnt++;
 | 
						|
        }
 | 
						|
        iot_printf("], q_sweep_list[");
 | 
						|
        for (q = min_q; q < max_q; q += step) {
 | 
						|
            q_sweep_list[q_cnt] = q;
 | 
						|
            iot_printf("%d, ", q_sweep_list[q_cnt]);
 | 
						|
            q_cnt++;
 | 
						|
        }
 | 
						|
        if (q_sweep_list[q_cnt - 1] < max_q - 1) {
 | 
						|
            q_sweep_list[q_cnt] = max_q - 1;
 | 
						|
            iot_printf("%d", q_sweep_list[q_cnt]);
 | 
						|
            q_cnt++;
 | 
						|
        }
 | 
						|
        iot_printf("]\n");
 | 
						|
 | 
						|
        if (q_cnt * i_cnt > MP_RF_TX_CALI_SNR_REAL_DATA_GROUP_SIZE) {
 | 
						|
            ret = ERR_NOMEM;
 | 
						|
            goto out;
 | 
						|
        }
 | 
						|
        for (i = 0; i < i_cnt; i++) {
 | 
						|
            for (q = 0; q < q_cnt; q++) {
 | 
						|
                j = MP_RF_IQ_CODE_TO_MAGIC(max_code, i_sweep_list[i],
 | 
						|
                    q_sweep_list[q]);
 | 
						|
                iot_bitmap_set(g_mp_rf_ctxt->snr_samp_bitmap,
 | 
						|
                    MP_RF_TX_CALI_SNR_BM_SIZE, j + 1);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    for (i = 0; i < test_cmd->rounds; i++) {
 | 
						|
        ret = mp_rf_dut_test_case_tx_cali_exec(test_cmd, &data_buf,
 | 
						|
            dev_id_magic);
 | 
						|
        if (ret == ERR_OK) {
 | 
						|
            rsp_hdr = (mp_rf_rsp_tx_cali_t *)data_buf;
 | 
						|
            for (j = 0; j < MP_RF_TX_CALI_SNR_BM_SIZE; j++) {
 | 
						|
                g_mp_rf_ctxt->snr_samp_bitmap[j] &= ~rsp_hdr->bm[j];
 | 
						|
            }
 | 
						|
            if (iot_bitmap_cbs(g_mp_rf_ctxt->snr_samp_bitmap,
 | 
						|
                MP_RF_TX_CALI_SNR_BM_SIZE) == 0) {
 | 
						|
                iot_printf("%s bitmap all clear, retry=%d\n", __FUNCTION__, i);
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (ret == ERR_OK) {
 | 
						|
        *len = sizeof(iot_ftm_mp_rf_rsp_tx_cali_t);
 | 
						|
        dut_rsp = (iot_ftm_mp_rf_rsp_tx_cali_t *)rsp;
 | 
						|
        dut_rsp->cnt = min(rsp_hdr->cnt, MP_RF_TX_CALI_SNR_BEST_RESULT_MAX);
 | 
						|
        *len += sizeof(iot_ftm_mp_rf_tx_cali_comen_result_t) * dut_rsp->cnt;
 | 
						|
        iot_printf("%s best_result:", __FUNCTION__);
 | 
						|
        for (i = 0; i < dut_rsp->cnt; i++) {
 | 
						|
            dut_rsp->result[i].i = rsp_hdr->result[i].i;
 | 
						|
            dut_rsp->result[i].q = rsp_hdr->result[i].q;
 | 
						|
            dut_rsp->result[i].snr = rsp_hdr->result[i].snr;
 | 
						|
            iot_printf("[%f, %d, %d], ", __FUNCTION__, dut_rsp->result[i].snr,
 | 
						|
                dut_rsp->result[i].i, dut_rsp->result[i].q);
 | 
						|
        }
 | 
						|
        iot_printf("\n");
 | 
						|
    }
 | 
						|
 | 
						|
    if (!test_cmd->is_nor_pwr) {
 | 
						|
        /* after sending the evm samples, restore the power configuration.
 | 
						|
         * for some DUT, the success rate of query results can be improved.
 | 
						|
         */
 | 
						|
        mac_rf_set_cert_mode(0);
 | 
						|
        mac_rf_set_cert_16qam_flag(0);
 | 
						|
        mac_rf_set_target_tx_power(cmd->dut_power);
 | 
						|
    }
 | 
						|
 | 
						|
out:
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t mp_rf_dut_test_case_chg_phy(iot_ftm_mp_rf_cmd_hdr_t *cmd,
 | 
						|
    void *rsp)
 | 
						|
{
 | 
						|
    rf_rx_pb_end *pb_end;
 | 
						|
    rf_rx_buf_hdr_t *rx_buf;
 | 
						|
    rf_rx_mpdu_start *rx_mpdu;
 | 
						|
    mp_rf_test_cmd_hdr_t *hdr;
 | 
						|
    mp_rf_test_rsp_t* golden_rsp;
 | 
						|
    iot_pkt_t *iot_pkt_array[1] = { 0 };
 | 
						|
    iot_ftm_mp_rf_cmd_chg_phy_t *target_para;
 | 
						|
    mp_rf_test_cmd_chg_phy_t *phy_para;
 | 
						|
    uint32_t timer_start, time_span, timeout, count = 0, done = 0;
 | 
						|
    uint32_t proto = PHY_PROTO_TYPE_GET();
 | 
						|
    /* get rx fc message */
 | 
						|
    rx_fc_msg_t rx_fc_msg = {0};
 | 
						|
    uint8_t ret = ERR_TIMEOVER, rx_done_tmp = 0;
 | 
						|
 | 
						|
    /* cfg DUT tx power */
 | 
						|
    mac_rf_set_target_tx_power(cmd->dut_power);
 | 
						|
 | 
						|
    hdr = (mp_rf_test_cmd_hdr_t *)g_mp_rf_ctxt->rf_pb_buf;
 | 
						|
    hdr->pld_blkz = 0;
 | 
						|
    hdr->phr_mcs = 0;
 | 
						|
    hdr->pld_mcs = 0;
 | 
						|
    hdr->power = cmd->golden_power;
 | 
						|
    hdr->magic = MP_RF_TEST_MSG_MAGIC_NUMBER;
 | 
						|
    hdr->msg_id = MP_RF_MSG_ID_CHG_PHY;
 | 
						|
    target_para = (iot_ftm_mp_rf_cmd_chg_phy_t *)cmd->data;
 | 
						|
    phy_para = (mp_rf_test_cmd_chg_phy_t *)hdr->data;
 | 
						|
    phy_para->option = target_para->option;
 | 
						|
    phy_para->channel = target_para->channel;
 | 
						|
 | 
						|
    iot_printf("%s start -- current phy para[option:%d channel:%d], "
 | 
						|
        "target phy para[option:%d channel:%d]\n",
 | 
						|
        __FUNCTION__, cmd->option, cmd->channel, target_para->option,
 | 
						|
        target_para->channel);
 | 
						|
 | 
						|
    if (target_para->option == g_mp_rf_ctxt->option &&
 | 
						|
        target_para->channel == g_mp_rf_ctxt->channel) {
 | 
						|
        iot_printf("%s no need change phy parameters\n", __FUNCTION__);
 | 
						|
        ret = ERR_OK;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    /* step1: notify golden to switch option and channel */
 | 
						|
    mp_rf_recover_def_rate();
 | 
						|
    mp_rf_tx_packet(0);
 | 
						|
 | 
						|
    timeout = MP_RF_TEST_CASE_CHG_PHY_TIMEOUT_DEF;
 | 
						|
    timer_start = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
    do {
 | 
						|
        time_span = mp_rf_ntb_span_calc(RGF_MAC_READ_REG(CFG_RD_NTB_ADDR),
 | 
						|
            timer_start);
 | 
						|
        time_span = MAC_NTB_TO_MS(time_span);
 | 
						|
        if (!done && time_span >= MP_RF_CMD_RETRY_INTERVAL &&
 | 
						|
            count < MP_RF_CMD_RETRY_COUNT) {
 | 
						|
            count++;
 | 
						|
            timer_start = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
            timeout -= MP_RF_CMD_RETRY_INTERVAL;
 | 
						|
            mp_rf_tx_packet(0);
 | 
						|
        }
 | 
						|
        if (!rx_done_tmp) {
 | 
						|
            rx_done_tmp = mp_rf_check_rf_rx_done();
 | 
						|
            if (!rx_done_tmp) {
 | 
						|
                continue;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        if (0 == rf_pop_buf_from_ring(&g_mp_rf_ctxt->rx_ring, 1,
 | 
						|
            iot_pkt_array)) {
 | 
						|
            rx_done_tmp = 0;
 | 
						|
            continue;
 | 
						|
        }
 | 
						|
        /* after receiving the correct reply, discard all packets received
 | 
						|
         * during the waiting period. If the correct response is not received,
 | 
						|
         * discard the received exception packet.
 | 
						|
         */
 | 
						|
        if (mp_rf_check_rx_packet(iot_pkt_array[0]))
 | 
						|
            goto free_packet;
 | 
						|
        mp_rf_rx_show_message_info(iot_pkt_array[0]);
 | 
						|
        if (done)
 | 
						|
            goto free_packet;
 | 
						|
 | 
						|
        rx_buf = (rf_rx_buf_hdr_t *)iot_pkt_data(iot_pkt_array[0]);
 | 
						|
        golden_rsp = (mp_rf_test_rsp_t *)((uint8_t *)rx_buf +
 | 
						|
            PB_PAYLOAD_OFFSET);
 | 
						|
        pb_end = &rx_buf->pb_ed;
 | 
						|
        rx_mpdu = &rx_buf->mpdu_st;
 | 
						|
        mac_rf_get_rx_frm_msg_from_fc(proto,
 | 
						|
            mac_rf_rx_mpdu_st_get_phr_addr(rx_mpdu), &rx_fc_msg);
 | 
						|
 | 
						|
        if ((rx_fc_msg.delimiter == FC_DELIM_SOF) && (!pb_end->rx_pb_crc_err) &&
 | 
						|
            (rx_fc_msg.nid == glb_cfg.nid) &&
 | 
						|
            (golden_rsp->magic == MP_RF_TEST_MSG_MAGIC_NUMBER) &&
 | 
						|
            (golden_rsp->msg_id == MP_RF_MSG_ID_CHG_PHY)) {
 | 
						|
            iot_printf("%s golden response successfully\n", __FUNCTION__);
 | 
						|
            ret = ERR_OK;
 | 
						|
            done = 1;
 | 
						|
            timeout = MP_RF_TEST_CASE_CHG_PHY_TIMEOUT_DEF;
 | 
						|
            timer_start = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
        }
 | 
						|
free_packet:
 | 
						|
        iot_pkt_free(iot_pkt_array[0]);
 | 
						|
    } while (time_span < timeout);
 | 
						|
out:
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
uint8_t mp_rf_dut_cal_cfg(iot_ftm_mp_rf_cal_meas_cfg_t *cfg)
 | 
						|
{
 | 
						|
    uint8_t *tx_pb_buf, *rx_pb_buf, i;
 | 
						|
    uint8_t *data, result;
 | 
						|
    mp_rf_cal_msg_hdr_t *req_hdr, *rsp_hdr;
 | 
						|
    mp_rf_cal_meas_cfg_t *meas_cfg;
 | 
						|
    mp_rf_cal_plc_comm_init(MP_RF_PLC_INIT_BAND);
 | 
						|
    tx_pb_buf = (uint8_t *)phy_get_pb_buf_ptr_from_mpdu(mpdu_start);
 | 
						|
    data = tx_pb_buf;
 | 
						|
 | 
						|
    req_hdr = (mp_rf_cal_msg_hdr_t *)data;
 | 
						|
    req_hdr->magic = MP_RF_TEST_MSG_MAGIC_NUMBER;
 | 
						|
    req_hdr->msg_id = MP_RF_CAL_MSG_ID_MEAS_CFG;
 | 
						|
    req_hdr->sn = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
    iot_chip_get_mac_addr(req_hdr->dut_addr);
 | 
						|
 | 
						|
    /* update DUT communication power and tmi */
 | 
						|
    phy_pwr_adjust_set(cfg->comm_pwr);
 | 
						|
    glb_cfg.tmi = MP_RF_PLC_NORMAL_PACKET_TMI;
 | 
						|
    data += sizeof(*req_hdr);
 | 
						|
    meas_cfg = (mp_rf_cal_meas_cfg_t *)data;
 | 
						|
    meas_cfg->meas_en = cfg->meas_en;
 | 
						|
    meas_cfg->option = cfg->option;
 | 
						|
    meas_cfg->ch = cfg->ch;
 | 
						|
 | 
						|
    meas_cfg->comm_pwr = cfg->comm_pwr;
 | 
						|
    meas_cfg->comm_tmi = MP_RF_PLC_NORMAL_PACKET_TMI;
 | 
						|
 | 
						|
    iot_printf("%s en:%lu,option:%lu,ch:%lu,comm_pwr:%lu,comm_tmi:%lu\n",
 | 
						|
        __FUNCTION__, cfg->meas_en, cfg->option, cfg->ch, cfg->comm_pwr,
 | 
						|
        cfg->comm_tmi);
 | 
						|
 | 
						|
    for (i = 0; i < 5; i++) {
 | 
						|
        tx_send_packet_interval(10);
 | 
						|
        result = mp_rf_cal_rsp_poll(req_hdr->msg_id, &rx_pb_buf, 50, req_hdr);
 | 
						|
        if (result == ERR_OK) {
 | 
						|
            rsp_hdr = (mp_rf_cal_msg_hdr_t *)rx_pb_buf;
 | 
						|
            result = rsp_hdr->option;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (i >= 5) {
 | 
						|
        result = ERR_TIMEOVER;
 | 
						|
    }
 | 
						|
    iot_printf("%s result:%lu\n", __FUNCTION__, result);
 | 
						|
    return result;
 | 
						|
}
 | 
						|
 | 
						|
void mp_rf_dut_cal_reg_update(iot_ftm_mp_rf_tx_cal_update_t *cal_update)
 | 
						|
{
 | 
						|
#define TX_CAL_UPDATE_TIMEOUT 5000000
 | 
						|
    uint32_t start_ntb, time_span;
 | 
						|
 | 
						|
    if (cal_update->tx_iq_mag_update) {
 | 
						|
        mac_rf_set_tx_iqm_cali(cal_update->tx_i_mag, cal_update->tx_q_mag);
 | 
						|
        iot_printf("%s, iq_mag[%d %d]\n", __FUNCTION__,
 | 
						|
            cal_update->tx_i_mag, cal_update->tx_q_mag);
 | 
						|
    }
 | 
						|
    if (cal_update->tx_iq_phase_update) {
 | 
						|
        mac_rf_set_tx_iqp_cali(cal_update->tx_i_phase, cal_update->tx_q_phase);
 | 
						|
        iot_printf("%s, iq_phase[%d %d]\n", __FUNCTION__,
 | 
						|
            cal_update->tx_i_phase, cal_update->tx_q_phase);
 | 
						|
    }
 | 
						|
    if (cal_update->tx_iq_dc_update) {
 | 
						|
        mac_rf_set_tx_dc_cali(cal_update->tx_i_dc, cal_update->tx_q_dc);
 | 
						|
        iot_printf("%s, iq_dc[%d %d]\n ", __FUNCTION__,
 | 
						|
            cal_update->tx_i_dc, cal_update->tx_q_dc);
 | 
						|
    }
 | 
						|
    if (cal_update->filter_update) {
 | 
						|
        mac_rf_set_tx_filter_cali(cal_update->filter_option, 1,
 | 
						|
            cal_update->filter_bw_sel);
 | 
						|
        iot_printf("%s, option:%lu, filter:%lu\n", __FUNCTION__,
 | 
						|
            cal_update->filter_option, cal_update->filter_bw_sel);
 | 
						|
    }
 | 
						|
 | 
						|
    mac_rf_set_tx_cal_update_status(0);
 | 
						|
    mac_rf_set_sw_irq_to_bbcpu(RF_MAC_SW_ISR_TX_CAL_UPDATE);
 | 
						|
    /* wait bbcpu update RF calibration register */
 | 
						|
    start_ntb = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
    while (!mac_rf_get_tx_cal_update_status()) {
 | 
						|
        time_span = mp_rf_ntb_span_calc(RGF_MAC_READ_REG(CFG_RD_NTB_ADDR),
 | 
						|
            start_ntb);
 | 
						|
        if (time_span > TX_CAL_UPDATE_TIMEOUT) {
 | 
						|
            IOT_ASSERT(0);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
void mp_rf_dut_cal_meas_pwr(iot_ftm_mp_rf_cal_meas_req_t *req,
 | 
						|
    iot_ftm_mp_rf_cal_meas_rsp_t *rsp)
 | 
						|
{
 | 
						|
    uint8_t *tx_pb_buf, *rx_pb_buf, i;
 | 
						|
    uint8_t *data, ret = ERR_OK;
 | 
						|
    mp_rf_cal_msg_hdr_t *req_hdr, *rsp_hdr;
 | 
						|
    mp_rf_cal_meas_req_t *meas_req;
 | 
						|
    mp_rf_cal_meas_rsp_t *meas_rsp;
 | 
						|
    uint32_t start_ntb, time_span;
 | 
						|
    uint32_t timeout;
 | 
						|
    /* initialize HPLC phy */
 | 
						|
    mp_rf_cal_plc_comm_init(MP_RF_PLC_INIT_BAND);
 | 
						|
    start_ntb = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
    tx_pb_buf = (uint8_t *)phy_get_pb_buf_ptr_from_mpdu(mpdu_start);
 | 
						|
    data = tx_pb_buf;
 | 
						|
    req_hdr = (mp_rf_cal_msg_hdr_t *)data;
 | 
						|
    req_hdr->magic = MP_RF_TEST_MSG_MAGIC_NUMBER;
 | 
						|
    req_hdr->msg_id = MP_RF_CAL_MSG_ID_MEAS_REQ;
 | 
						|
    req_hdr->sn = start_ntb;
 | 
						|
    iot_chip_get_mac_addr(req_hdr->dut_addr);
 | 
						|
 | 
						|
    /* step1: update the specified tx calibration register before measuring
 | 
						|
     * power.
 | 
						|
     */
 | 
						|
    mp_rf_dut_cal_reg_update(&req->tx_cal);
 | 
						|
 | 
						|
    data += sizeof(*req_hdr);
 | 
						|
    meas_req = (mp_rf_cal_meas_req_t *)data;
 | 
						|
    meas_req->lo_freq = req->lo_freq;
 | 
						|
    meas_req->tone_idx = req->tone_idx;
 | 
						|
    meas_req->dc_idx = req->dc_idx;
 | 
						|
    meas_req->img_idx = req->img_idx;
 | 
						|
    meas_req->avg_cnt = req->avg_cnt;
 | 
						|
    os_mem_set(meas_req->rsvd, 0, sizeof(meas_req->rsvd));
 | 
						|
    /* TODO: it is necessary to adjust the optimal retry policy to balance the
 | 
						|
     * communication reliability and efficiency.
 | 
						|
     */
 | 
						|
    timeout = req->timeout;
 | 
						|
    for (i = 0; i < req->try_cnt; i++) {
 | 
						|
        tx_send_packet_interval(10);
 | 
						|
        ret = mp_rf_cal_rsp_poll(req_hdr->msg_id, &rx_pb_buf, timeout, req_hdr);
 | 
						|
        if (ret) {
 | 
						|
            continue;
 | 
						|
        }
 | 
						|
        rsp_hdr = (mp_rf_cal_msg_hdr_t *)rx_pb_buf;
 | 
						|
        ret = rsp_hdr->option;
 | 
						|
        if (ret) {
 | 
						|
            rsp->err_no = ret;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        ret = ERR_OK;
 | 
						|
        meas_rsp = (mp_rf_cal_meas_rsp_t *)rsp_hdr->data;
 | 
						|
        rsp->gain = meas_rsp->gain_x100;
 | 
						|
        rsp->tone_pwr = meas_rsp->tone_pwr;
 | 
						|
        rsp->dc_pwr = meas_rsp->dc_pwr;
 | 
						|
        rsp->img_pwr = meas_rsp->img_pwr;
 | 
						|
        os_mem_set(rsp->rsvd, 0x0, sizeof(rsp->rsvd));
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    rsp->err_no = ret;
 | 
						|
    time_span = mp_rf_ntb_span_calc(RGF_MAC_READ_REG(CFG_RD_NTB_ADDR),
 | 
						|
        start_ntb);
 | 
						|
    iot_printf("%s result:%lu, cons:%lums, lo_freq:%luHz, idx:[%d, %d, %d], "
 | 
						|
        "power[%d, %d, %d], gain %lu\n", __FUNCTION__, ret,
 | 
						|
        MAC_NTB_TO_MS(time_span), req->lo_freq, req->tone_idx, req->dc_idx,
 | 
						|
        req->img_idx, rsp->tone_pwr, rsp->dc_pwr, rsp->img_pwr,
 | 
						|
        rsp->gain);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
static void mp_rf_common_timer_func(uint32_t id, void *arg)
 | 
						|
{
 | 
						|
    (void)id;
 | 
						|
    (void)arg;
 | 
						|
    os_set_task_event_with_v(_init_handle, 1 << MP_RF_EVT_ID_TIMEROUT);
 | 
						|
}
 | 
						|
 | 
						|
void mp_rf_ctxt_init(uint8_t is_golden, uint8_t option, uint8_t channel)
 | 
						|
{
 | 
						|
    if (!g_mp_rf_ctxt) {
 | 
						|
        g_mp_rf_ctxt = (mp_rf_ctxt_t*)os_mem_malloc(IOT_FTM_MID,
 | 
						|
            sizeof(mp_rf_ctxt_t));
 | 
						|
        if (!g_mp_rf_ctxt)
 | 
						|
            IOT_ASSERT(0);
 | 
						|
    }
 | 
						|
    if (is_golden) {
 | 
						|
        rf_phy_power_meas_init();
 | 
						|
        g_mp_rf_ctxt->is_golden = 1;
 | 
						|
        g_mp_rf_ctxt->target_option = option;
 | 
						|
        g_mp_rf_ctxt->target_channel = channel;
 | 
						|
        g_mp_rf_ctxt->common_timer = os_create_timer(IOT_FTM_MID, true,
 | 
						|
            mp_rf_common_timer_func, NULL);
 | 
						|
        mp_rf_cal_plc_comm_init(MP_RF_PLC_INIT_BAND);
 | 
						|
        g_mp_rf_ctxt->led_gpio = iot_board_get_led(IOT_PLC_RX_LED);
 | 
						|
        iot_gpio_open_as_output(g_mp_rf_ctxt->led_gpio);
 | 
						|
        os_start_timer(g_mp_rf_ctxt->common_timer,
 | 
						|
            MP_RF_GOLDEN_COMMON_TIMER_PERIOD);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
uint32_t mp_rf_dut_test_phy_cfg(uint8_t option, uint8_t channel)
 | 
						|
{
 | 
						|
    if (!g_mp_rf_ctxt) {
 | 
						|
        mp_rf_ctxt_init(0, 0, 0);
 | 
						|
    }
 | 
						|
    mp_rf_common_init(option, channel);
 | 
						|
    return ERR_OK;
 | 
						|
}
 | 
						|
 | 
						|
void mp_rf_dut_test_case_handle(iot_ftm_mp_rf_cmd_hdr_t *cmd,
 | 
						|
    iot_ftm_mp_rf_rsp_hdr_t *rsp_hdr, uint8_t *len)
 | 
						|
{
 | 
						|
    uint8_t ret, tmp = 0;
 | 
						|
    *len = sizeof(*rsp_hdr);
 | 
						|
 | 
						|
    mp_rf_dut_test_phy_cfg(cmd->option, cmd->channel);
 | 
						|
    mp_rf_cal_plc_comm_init(MP_RF_PLC_INIT_BAND);
 | 
						|
 | 
						|
    switch (cmd->id) {
 | 
						|
    case IOT_FTM_MP_RF_CASE_ID_CSR:
 | 
						|
    {
 | 
						|
        ret = mp_rf_dut_test_case_csr(cmd, rsp_hdr->data);
 | 
						|
        tmp = sizeof(iot_ftm_mp_rf_rsp_csr_t);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_FTM_MP_RF_CASE_ID_CSI:
 | 
						|
    {
 | 
						|
        ret = mp_rf_dut_test_case_csi(cmd, rsp_hdr->data);
 | 
						|
        tmp = sizeof(iot_ftm_mp_rf_rsp_csi_t);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_FTM_MP_RF_CASE_ID_TX_EVM:
 | 
						|
    {
 | 
						|
        ret = mp_rf_dut_test_case_tx_evm(cmd, rsp_hdr->data);
 | 
						|
        tmp = sizeof(iot_ftm_mp_rf_rsp_tx_evm_t);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_FTM_MP_RF_CASE_ID_CHG_PHY:
 | 
						|
    {
 | 
						|
        ret = mp_rf_dut_test_case_chg_phy(cmd, rsp_hdr->data);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_FTM_MP_RF_CASE_ID_TX_CALI_BY_SNR:
 | 
						|
    {
 | 
						|
        ret = mp_rf_dut_test_case_tx_cali(cmd, rsp_hdr->data, &tmp);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
    {
 | 
						|
        ret = ERR_NOSUPP;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    }
 | 
						|
    rsp_hdr->id = cmd->id;
 | 
						|
    rsp_hdr->result = ret;
 | 
						|
    if (ret == ERR_OK) {
 | 
						|
        *len += tmp;
 | 
						|
    }
 | 
						|
    if (g_mp_rf_ctxt->rf_phy_inited) {
 | 
						|
        mac_rf_rx_ring_enable(&g_mp_rf_ctxt->rx_ring, 0);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t mp_rf_common_timer_handle()
 | 
						|
{
 | 
						|
    uint8_t toggle_flag = 0;
 | 
						|
    uint32_t time_span;
 | 
						|
 | 
						|
    if (g_mp_rf_ctxt->rf_phy_changing) {
 | 
						|
        time_span = mp_rf_ntb_span_calc(RGF_MAC_READ_REG(CFG_RD_NTB_ADDR),
 | 
						|
            g_mp_rf_ctxt->rf_phy_chg_ts);
 | 
						|
        time_span = MAC_NTB_TO_MS(time_span);
 | 
						|
        if (time_span >= MP_RF_TEST_CASE_CHG_PHY_EXEC_DELAY) {
 | 
						|
            g_mp_rf_ctxt->rf_phy_changing = 0;
 | 
						|
            return 1;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    g_mp_rf_ctxt->timeout_count++;
 | 
						|
    /* blinking cycle 100ms */
 | 
						|
    if (g_mp_rf_ctxt->is_cal_mode) {
 | 
						|
        toggle_flag = 1;
 | 
						|
    } else {
 | 
						|
        /* blinking cycle 500ms */
 | 
						|
        if (g_mp_rf_ctxt->timeout_count % 5 == 1) {
 | 
						|
            toggle_flag = 1;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (toggle_flag) {
 | 
						|
        iot_gpio_value_set(g_mp_rf_ctxt->led_gpio, (int)g_mp_rf_ctxt->led_status);
 | 
						|
        g_mp_rf_ctxt->led_status = !g_mp_rf_ctxt->led_status;
 | 
						|
    }
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
void mp_rf_golden_unit_main(uint32_t option, uint32_t channel)
 | 
						|
{
 | 
						|
    uint8_t reinit_req;
 | 
						|
    uint32_t events;
 | 
						|
 | 
						|
    mp_rf_ctxt_init(1, option, channel);
 | 
						|
    /* set nid by gpio status */
 | 
						|
    glb_cfg.nid = mp_pt_golden_nid_config();
 | 
						|
#if SUPPORT_SOUTHERN_POWER_GRID
 | 
						|
    if (glb_cfg.nid > PLC_NID_MAX_SPG)
 | 
						|
        glb_cfg.nid = PLC_NID_MAX_SPG;
 | 
						|
#endif
 | 
						|
    if (iot_board_is_overseas_rf_band()) {
 | 
						|
        phy_rf_band_info_init(PHY_RF_BAND_OVERSEAS);
 | 
						|
    } else {
 | 
						|
        phy_rf_band_info_init(PHY_RF_BAND_NSG);
 | 
						|
    }
 | 
						|
    iot_printf("Global nid has been set to %d.\n", glb_cfg.nid);
 | 
						|
 | 
						|
reinit:
 | 
						|
    mp_rf_common_init(g_mp_rf_ctxt->target_option,
 | 
						|
        g_mp_rf_ctxt->target_channel);
 | 
						|
    for (; ;) {
 | 
						|
        events = os_wait_task_event_with_v(MAX_TIME);
 | 
						|
        if (events & (1 << MP_RF_EVT_ID_PLC_RX)) {
 | 
						|
            reinit_req = mp_rf_golden_plc_rx();
 | 
						|
            if (reinit_req) {
 | 
						|
                goto reinit;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        if (events & (1 << MP_RF_EVT_ID_RF_RX)) {
 | 
						|
            mp_rf_golden_rf_rx();
 | 
						|
        }
 | 
						|
        if (events & (1 << MP_RF_EVT_ID_TIMEROUT)) {
 | 
						|
            reinit_req = mp_rf_common_timer_handle();
 | 
						|
            if (reinit_req) {
 | 
						|
                goto reinit;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#else /* IOT_MP_SUPPORT == 1 && HPLC_RF_DEV_SUPPORT */
 | 
						|
 | 
						|
uint32_t mp_rf_dut_test_phy_cfg(uint8_t option, uint8_t channel)
 | 
						|
{
 | 
						|
    (void)option;
 | 
						|
    (void)channel;
 | 
						|
    return ERR_FAIL;
 | 
						|
}
 | 
						|
 | 
						|
void mp_rf_dut_test_case_handle(iot_ftm_mp_rf_cmd_hdr_t *cmd,
 | 
						|
    iot_ftm_mp_rf_rsp_hdr_t *rsp_hdr, uint8_t *len)
 | 
						|
{
 | 
						|
    (void)cmd;
 | 
						|
    *len = sizeof(*rsp_hdr);
 | 
						|
    rsp_hdr->result = ERR_NOSUPP;
 | 
						|
    rsp_hdr->id = cmd->id;
 | 
						|
}
 | 
						|
 | 
						|
void mp_rf_golden_unit_main(uint32_t option, uint32_t channel)
 | 
						|
{
 | 
						|
    (void)option;
 | 
						|
    (void)channel;
 | 
						|
}
 | 
						|
 | 
						|
uint8_t mp_rf_dut_cal_cfg(iot_ftm_mp_rf_cal_meas_cfg_t *cfg)
 | 
						|
{
 | 
						|
    (void)cfg;
 | 
						|
    return ERR_NOSUPP;
 | 
						|
}
 | 
						|
 | 
						|
void mp_rf_dut_cal_reg_update(iot_ftm_mp_rf_tx_cal_update_t *cal_update)
 | 
						|
{
 | 
						|
    (void)cal_update;
 | 
						|
}
 | 
						|
 | 
						|
void mp_rf_dut_cal_meas_pwr(iot_ftm_mp_rf_cal_meas_req_t *req,
 | 
						|
    iot_ftm_mp_rf_cal_meas_rsp_t *rsp)
 | 
						|
{
 | 
						|
    (void)req;
 | 
						|
    (void)rsp;
 | 
						|
}
 | 
						|
 | 
						|
void mp_rf_clear_rf_common()
 | 
						|
{
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
#endif
 |