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