279 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			279 lines
		
	
	
		
			9.5 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 "hw_reg_api.h"
							 | 
						||
| 
								 | 
							
								#include "tx_mpdu_start.h"
							 | 
						||
| 
								 | 
							
								#include "rx_desc_reg_api.h"
							 | 
						||
| 
								 | 
							
								#include "phy_bb.h"
							 | 
						||
| 
								 | 
							
								#include "hw_rx.h"
							 | 
						||
| 
								 | 
							
								#include "rx_entry.h"
							 | 
						||
| 
								 | 
							
								#include "tx_entry.h"
							 | 
						||
| 
								 | 
							
								#include "hal_rx.h"
							 | 
						||
| 
								 | 
							
								#include "iot_bitops.h"
							 | 
						||
| 
								 | 
							
								#include "iot_io.h"
							 | 
						||
| 
								 | 
							
								#include "iot_led.h"
							 | 
						||
| 
								 | 
							
								#include "mpdu_header.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								plc_dt_ctxt_t g_plc_dt_ctxt = {{0, NULL, {{0}}, NULL, 4000}};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void dut_flag_set(bool_t flag_status)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    g_plc_dt_ctxt.indep.dut_flag = flag_status;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								mac_rx_phy_info_t *phy_info_ptr_get()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return g_plc_dt_ctxt.indep.phy_info;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* support mode : ftm, module, dtest scan */
							 | 
						||
| 
								 | 
							
								void rx_common_init(uint32_t band_idx)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    /* basic data struct init for bit ops */
							 | 
						||
| 
								 | 
							
								    iot_bitops_init();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if SUPPORT_SMART_GRID
							 | 
						||
| 
								 | 
							
								    glb_cfg.m_type = PLC_PROTO_TYPE_SG;
							 | 
						||
| 
								 | 
							
								#elif SUPPORT_SOUTHERN_POWER_GRID
							 | 
						||
| 
								 | 
							
								    glb_cfg.m_type = PLC_PROTO_TYPE_SPG;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								    mac_rx_init(band_idx);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* setup the rx ring */
							 | 
						||
| 
								 | 
							
								    rx_ring_setup_hw(0, NULL);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* enable the rx ring */
							 | 
						||
| 
								 | 
							
								    rx_ring_enable(0, true);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void mac_tmi_cnt_clr()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    for(uint32_t j = 0; j < MAX_TMI_NUM; j++)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        g_plc_dt_ctxt.indep.tmi_beacon_cnt[j][0] = 0;
							 | 
						||
| 
								 | 
							
								        g_plc_dt_ctxt.indep.tmi_beacon_cnt[j][1] = 0;
							 | 
						||
| 
								 | 
							
								        g_plc_dt_ctxt.indep.tmi_beacon_cnt[j][2] = 0;
							 | 
						||
| 
								 | 
							
								        g_plc_dt_ctxt.indep.tmi_beacon_cnt[j][3] = 0;
							 | 
						||
| 
								 | 
							
								        g_plc_dt_ctxt.indep.tmi_sof_cnt[j][0] = 0;
							 | 
						||
| 
								 | 
							
								        g_plc_dt_ctxt.indep.tmi_sof_cnt[j][1] = 0;
							 | 
						||
| 
								 | 
							
								        g_plc_dt_ctxt.indep.tmi_sof_cnt[j][2] = 0;
							 | 
						||
| 
								 | 
							
								        g_plc_dt_ctxt.indep.tmi_sof_cnt[j][3] = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for(uint32_t k = 0; k < MAX_PB_NUM; k++)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        g_plc_dt_ctxt.indep.tmi_sack_cnt[k] = 0;
							 | 
						||
| 
								 | 
							
								        g_plc_dt_ctxt.indep.tmi_nncco_cnt[k] = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* packets detail cnt printer */
							 | 
						||
| 
								 | 
							
								void mac_pkt_info_cnt_print()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t tmi = 0, tmp = 0, i = 0;
							 | 
						||
| 
								 | 
							
								    uint32_t rate_idx = 0;
							 | 
						||
| 
								 | 
							
								    iot_phy_sts_info_t total_sts = {0};
							 | 
						||
| 
								 | 
							
								    iot_mac_sts_info_t mac_sts = {0};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    phy_sts_get(&total_sts);
							 | 
						||
| 
								 | 
							
								    iot_printf("[CNT][mac]tx_ok:%d/4s\r\n", total_sts.mac_tx_ok_cnt);
							 | 
						||
| 
								 | 
							
								    iot_printf("[CNT][phy]fc_ok:%d/4s, fc_err:%d/4s,", \
							 | 
						||
| 
								 | 
							
								            total_sts.fc_crc_ok_cnt,total_sts.fc_crc_fail_cnt);
							 | 
						||
| 
								 | 
							
								    iot_printf("pld_ok:%d/4s, pld_fail:%d/4s, sync_ok:%d/4s, "
							 | 
						||
| 
								 | 
							
								            "rx_abort:%d/4s\r\n", \
							 | 
						||
| 
								 | 
							
								            total_sts.pld_crc_ok_cnt, total_sts.pld_crc_fail_cnt, \
							 | 
						||
| 
								 | 
							
								            total_sts.sync_ok_cnt, total_sts.phy_rx_abort_cnt);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*control IOT_PLC_RX_LED on the basis of pld_crc_ok_cnt*/
							 | 
						||
| 
								 | 
							
								    if(total_sts.pld_crc_ok_cnt >= PHY_RX_CRC_RATE_LED_ON) {
							 | 
						||
| 
								 | 
							
								        iot_led_on(IOT_PLC_RX_LED);
							 | 
						||
| 
								 | 
							
								    } else if (total_sts.pld_crc_ok_cnt == PHY_RX_CRC_RATE_LED_OFF) {
							 | 
						||
| 
								 | 
							
								        iot_led_off(IOT_PLC_RX_LED);
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        iot_led_off(IOT_PLC_RX_LED);
							 | 
						||
| 
								 | 
							
								        iot_led_blink(IOT_PLC_RX_LED, 1);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* Multi PB cnt */
							 | 
						||
| 
								 | 
							
								    iot_printf("[MPB]pb_ok_1st:%d, 2nd:%d, 3rd:%d, 4th:%d\r\n", \
							 | 
						||
| 
								 | 
							
								            g_plc_dt_ctxt.indep.fisrt_pb_crc_ok_cnt, \
							 | 
						||
| 
								 | 
							
								            g_plc_dt_ctxt.indep.second_pb_crc_ok_cnt, \
							 | 
						||
| 
								 | 
							
								            g_plc_dt_ctxt.indep.third_pb_crc_ok_cnt, \
							 | 
						||
| 
								 | 
							
								            g_plc_dt_ctxt.indep.last_pb_crc_ok_cnt);
							 | 
						||
| 
								 | 
							
								    /* reset cnt */
							 | 
						||
| 
								 | 
							
								    g_plc_dt_ctxt.indep.fisrt_pb_crc_ok_cnt = 0;
							 | 
						||
| 
								 | 
							
								    g_plc_dt_ctxt.indep.second_pb_crc_ok_cnt = 0;
							 | 
						||
| 
								 | 
							
								    g_plc_dt_ctxt.indep.third_pb_crc_ok_cnt = 0;
							 | 
						||
| 
								 | 
							
								    g_plc_dt_ctxt.indep.last_pb_crc_ok_cnt = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* print tmi cnt */
							 | 
						||
| 
								 | 
							
								    tmi = MAX_TMI_NUM;
							 | 
						||
| 
								 | 
							
								    while(tmi--){
							 | 
						||
| 
								 | 
							
								        for(i = 0; i < 4; i++)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            /* beacon */
							 | 
						||
| 
								 | 
							
								            if (g_plc_dt_ctxt.indep.tmi_beacon_cnt[tmi][i] != 0) {
							 | 
						||
| 
								 | 
							
								                if (tmi < 15) {
							 | 
						||
| 
								 | 
							
								                    iot_printf("[BCN][tmi-%d][pb-%d]:%d\r\n", \
							 | 
						||
| 
								 | 
							
								                            tmi,i,g_plc_dt_ctxt.indep.tmi_beacon_cnt[tmi][i]);
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    tmp = tmi - 15;/* skip optimization for next  */
							 | 
						||
| 
								 | 
							
								                    iot_printf("[BCN][ext-tmi-%d][pb-%d]:%d\r\n", \
							 | 
						||
| 
								 | 
							
								                            tmp,i,g_plc_dt_ctxt.indep.tmi_beacon_cnt[tmi][i]);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                g_plc_dt_ctxt.indep.tmi_beacon_cnt[tmi][i] = 0;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            /* sof */
							 | 
						||
| 
								 | 
							
								            if (g_plc_dt_ctxt.indep.tmi_sof_cnt[tmi][i] != 0) {
							 | 
						||
| 
								 | 
							
								                if (tmi < 15) {
							 | 
						||
| 
								 | 
							
								                    iot_printf("[SOF][tmi-%d][pb-%d]:%d\r\n", \
							 | 
						||
| 
								 | 
							
								                            tmi,i,g_plc_dt_ctxt.indep.tmi_sof_cnt[tmi][i]);
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    tmp = tmi - 15;/* skip optimization for next  */
							 | 
						||
| 
								 | 
							
								                    iot_printf("[SOF][ext-tmi-%d][pb-%d]:%d\r\n", \
							 | 
						||
| 
								 | 
							
								                            tmp,i,g_plc_dt_ctxt.indep.tmi_sof_cnt[tmi][i]);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                g_plc_dt_ctxt.indep.tmi_sof_cnt[tmi][i] = 0;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* sack & nncco */
							 | 
						||
| 
								 | 
							
								    for(i=0; i<4; i++)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (g_plc_dt_ctxt.indep.tmi_sack_cnt[i] != 0) {
							 | 
						||
| 
								 | 
							
								            iot_printf("[SACK][pb-%d]:%d\r\n", i, \
							 | 
						||
| 
								 | 
							
								                g_plc_dt_ctxt.indep.tmi_sack_cnt[i]);
							 | 
						||
| 
								 | 
							
								            g_plc_dt_ctxt.indep.tmi_sack_cnt[i] = 0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (g_plc_dt_ctxt.indep.tmi_nncco_cnt[i] != 0) {
							 | 
						||
| 
								 | 
							
								            iot_printf("[NNCCO][pb-%d]:%d\r\n", i, \
							 | 
						||
| 
								 | 
							
								                g_plc_dt_ctxt.indep.tmi_nncco_cnt[i]);
							 | 
						||
| 
								 | 
							
								            g_plc_dt_ctxt.indep.tmi_nncco_cnt[i] = 0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* band info */
							 | 
						||
| 
								 | 
							
								    for(rate_idx=0; rate_idx<MAC_BB_MAX_RATE; rate_idx++)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        for(i=0; i<MAX_HW_BAND; i++)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if (g_plc_dt_ctxt.indep.band_cnt_rx[rate_idx][i] != 0) {
							 | 
						||
| 
								 | 
							
								                iot_printf("[RB][rate-%d][band-%d]:%d\r\n", \
							 | 
						||
| 
								 | 
							
								                        rate_idx, i, g_plc_dt_ctxt.indep.band_cnt_rx[rate_idx][i]);
							 | 
						||
| 
								 | 
							
								                g_plc_dt_ctxt.indep.band_cnt_rx[rate_idx][i] = 0;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /* mac rx cnt */
							 | 
						||
| 
								 | 
							
								    mac_sts_get(&mac_sts);
							 | 
						||
| 
								 | 
							
								    iot_printf("[MAC][rx-ring%d]:ring-%d, fc-%d, pkt-%d\n\n", 0, \
							 | 
						||
| 
								 | 
							
								            mac_sts.mac_rx_ring0_dbg_cnt, \
							 | 
						||
| 
								 | 
							
								            mac_sts.mac_rx_fc_dbg_cnt, \
							 | 
						||
| 
								 | 
							
								            mac_sts.mac_rx_pkt_det_cnt);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void phy_granite_loopback(uint32_t band_idx)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    /* reset phy */
							 | 
						||
| 
								 | 
							
								    phy_reset(PHY_RST_REASON_WARM);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* Must cfg start adn end tone */
							 | 
						||
| 
								 | 
							
								    mac_rx_init(band_idx);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    phy_rx_loopback();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* TODO: replace by mac_ppm_cal */
							 | 
						||
| 
								 | 
							
								uint32_t mac_ntb_ppm_cali_start(rx_buf_hdr_t *pb_buf, uint32_t ppm_cnt)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    /* ppm calibration */
							 | 
						||
| 
								 | 
							
								    volatile int64_t ppm = 0;
							 | 
						||
| 
								 | 
							
								    volatile int64_t rx_span = 0, tx_span = 0, rx_ntb_span = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* ppm cali */
							 | 
						||
| 
								 | 
							
								    g_plc_dt_ctxt.indep.rx_ts_last = g_plc_dt_ctxt.indep.rx_ts_cur;
							 | 
						||
| 
								 | 
							
								    g_plc_dt_ctxt.indep.rx_ts_cur = \
							 | 
						||
| 
								 | 
							
								        mac_rx_mpdu_end_get_local_timestamp(&pb_buf->mpdu_ed);
							 | 
						||
| 
								 | 
							
								    g_plc_dt_ctxt.indep.rx_ntb_ts_last = g_plc_dt_ctxt.indep.rx_ntb_ts_cur;
							 | 
						||
| 
								 | 
							
								    g_plc_dt_ctxt.indep.rx_ntb_ts_cur = \
							 | 
						||
| 
								 | 
							
								        mac_rx_mpdu_end_get_ntb_timestamp(&pb_buf->mpdu_ed);;
							 | 
						||
| 
								 | 
							
								    g_plc_dt_ctxt.indep.tx_ts_last = g_plc_dt_ctxt.indep.tx_ts_cur;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    g_plc_dt_ctxt.indep.tx_ts_cur = \
							 | 
						||
| 
								 | 
							
								        mac_get_bcn_st(PHY_PROTO_TYPE_GET(), \
							 | 
						||
| 
								 | 
							
								            mac_rx_mpdu_st_get_fc_addr(&pb_buf->mpdu_st));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    rx_span = g_plc_dt_ctxt.indep.rx_ts_cur - \
							 | 
						||
| 
								 | 
							
								        g_plc_dt_ctxt.indep.rx_ts_last;
							 | 
						||
| 
								 | 
							
								    if (rx_span < 0) { // wrap around
							 | 
						||
| 
								 | 
							
								        rx_span = (0x100000000LL) - \
							 | 
						||
| 
								 | 
							
								            g_plc_dt_ctxt.indep.rx_ts_last + \
							 | 
						||
| 
								 | 
							
								            g_plc_dt_ctxt.indep.rx_ts_cur;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    rx_ntb_span = g_plc_dt_ctxt.indep.rx_ntb_ts_cur - \
							 | 
						||
| 
								 | 
							
								        g_plc_dt_ctxt.indep.rx_ntb_ts_last;
							 | 
						||
| 
								 | 
							
								    if (rx_ntb_span < 0) { // wrap around
							 | 
						||
| 
								 | 
							
								        rx_ntb_span = (0x100000000LL) - \
							 | 
						||
| 
								 | 
							
								            g_plc_dt_ctxt.indep.rx_ntb_ts_last + \
							 | 
						||
| 
								 | 
							
								            g_plc_dt_ctxt.indep.rx_ntb_ts_cur;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    tx_span = g_plc_dt_ctxt.indep.tx_ts_cur - \
							 | 
						||
| 
								 | 
							
								        g_plc_dt_ctxt.indep.tx_ts_last;
							 | 
						||
| 
								 | 
							
								    if (tx_span < 0) { // wrap around
							 | 
						||
| 
								 | 
							
								        tx_span = (0x100000000LL) - \
							 | 
						||
| 
								 | 
							
								            g_plc_dt_ctxt.indep.tx_ts_last + \
							 | 
						||
| 
								 | 
							
								            g_plc_dt_ctxt.indep.tx_ts_cur;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if PHY_RX_DBG_EN
							 | 
						||
| 
								 | 
							
								    iot_printf("[Debug]ntb ts0:%u, ts1:%u, ts_span:%u\r\n",  \
							 | 
						||
| 
								 | 
							
								        g_plc_dt_ctxt.indep.rx_ntb_ts_last, \
							 | 
						||
| 
								 | 
							
								        g_plc_dt_ctxt.indep.rx_ntb_ts_cur, \
							 | 
						||
| 
								 | 
							
								        (uint32_t)rx_ntb_span);
							 | 
						||
| 
								 | 
							
								    iot_printf("[Debug]rx0:%u,rx1:%u,tx0:%u,tx1:%u,\r\n", \
							 | 
						||
| 
								 | 
							
								        g_plc_dt_ctxt.indep.rx_ts_last, \
							 | 
						||
| 
								 | 
							
								        g_plc_dt_ctxt.indep.rx_ts_cur, \
							 | 
						||
| 
								 | 
							
								        g_plc_dt_ctxt.indep.tx_ts_last, \
							 | 
						||
| 
								 | 
							
								        g_plc_dt_ctxt.indep.tx_ts_cur);
							 | 
						||
| 
								 | 
							
								    iot_printf("r1-r0:%u,t1-t0:%u, ppm_pkt:%d\r\n", \
							 | 
						||
| 
								 | 
							
								        (uint32_t)rx_span, \
							 | 
						||
| 
								 | 
							
								        (uint32_t)tx_span, pb_buf->mpdu_st.phy.est_ppm);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (rx_span > (ppm_cnt - (ppm_cnt >> 1)) && \
							 | 
						||
| 
								 | 
							
								        rx_span < (ppm_cnt + (ppm_cnt >> 1))) {
							 | 
						||
| 
								 | 
							
								        /* cal ppm */
							 | 
						||
| 
								 | 
							
								        ppm = (rx_ntb_span - tx_span) * (1 << 20);
							 | 
						||
| 
								 | 
							
								        ppm = ppm/tx_span;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /* check ppm valid */
							 | 
						||
| 
								 | 
							
								        if (ppm < 200 && ppm > -200) {
							 | 
						||
| 
								 | 
							
								            phy_ppm_cal_and_update_hw(PHY_CAL_UNIT_1_1, \
							 | 
						||
| 
								 | 
							
								                -ppm, IOT_SUPPORT_RATE_SR, BB_PPM_TXRX);
							 | 
						||
| 
								 | 
							
								            iot_printf("[ppm cali] write ppm:%d successfully!\r\n", \
							 | 
						||
| 
								 | 
							
								                (uint32_t)ppm);
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            iot_printf("[ppm cali] ppm:%d cal failed!\r\n",(uint32_t)ppm);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        iot_printf("[ppm cali] rx_span:%lld not valid!\r\n", rx_span);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ERR_OK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 |