1023 lines
		
	
	
		
			35 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1023 lines
		
	
	
		
			35 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 "iot_config.h"
 | 
						|
#include "phy_bbai_calu.h"
 | 
						|
#include "phy_dump.h"
 | 
						|
#include "phy_bb.h"
 | 
						|
#include "os_types.h"
 | 
						|
#include "hw_reg_api.h"
 | 
						|
#include "iot_io.h"
 | 
						|
#include "mac_sys_reg.h"
 | 
						|
#include "iot_errno_api.h"
 | 
						|
#include "hw_tonemask.h"
 | 
						|
#include "phy_ana.h"
 | 
						|
#include "phy_bb.h"
 | 
						|
#include "phy_dfe_reg.h"
 | 
						|
#include "phy_data.h"
 | 
						|
#include "hw_phy_api.h"
 | 
						|
#include "phy_phase.h"
 | 
						|
#include "math.h"
 | 
						|
#include "phy_ana.h"
 | 
						|
#include "math_log10.h"
 | 
						|
#include "hw_phy_api.h"
 | 
						|
#include "phy_dump_hw.h"
 | 
						|
#include "phy_tools.h"
 | 
						|
#include "phy_perf.h"
 | 
						|
#include "phy_math_tb.h"
 | 
						|
 | 
						|
#if PHY_BBAI_ALGORITHM == PHY_BBAI_FIX_WINDOWS
 | 
						|
 | 
						|
#define PHY_CHN_EST_AI_SPUR_LEN             500
 | 
						|
 | 
						|
/* spur array */
 | 
						|
typedef struct _iot_phy_spur{
 | 
						|
    /* notch filter enable */
 | 
						|
    uint8_t notch_filter_en_cnt;
 | 
						|
    /* PHY_BBAI_FIX_WINDOWS :color
 | 
						|
     * PHY_BBAI_SLIDE_WINDOWS: is max spur
 | 
						|
     */
 | 
						|
    uint8_t color;
 | 
						|
    /* tone number */
 | 
						|
    uint16_t tone_id;
 | 
						|
    /* center/sidelobe */
 | 
						|
    uint32_t spur_ratio;
 | 
						|
    /* spur occur cnt */
 | 
						|
    uint16_t spur_cnt;
 | 
						|
} iot_phy_spur_t;
 | 
						|
 | 
						|
static uint32_t phy_spur_arry_append(iot_phy_spur_t *spur_buf, uint32_t buf_len,
 | 
						|
    uint16_t tone_id, uint32_t pwr_ratio, bool_t notch_en)
 | 
						|
{
 | 
						|
    uint32_t ret = ERR_OK;
 | 
						|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
 | 
						|
    uint32_t i = 0;
 | 
						|
    bool_t tone_find_en = false;
 | 
						|
    uint32_t spur_buf_size = buf_len/sizeof(iot_phy_spur_t);
 | 
						|
 | 
						|
    /* valid check */
 | 
						|
    IOT_ASSERT(spur_buf != NULL && buf_len > 0);
 | 
						|
 | 
						|
    /*
 | 
						|
     * spur mask valid for inband only, notch filter for all.
 | 
						|
    */
 | 
						|
    if (spur_buf[spur_buf_size - 1].tone_id != 0) {
 | 
						|
        /* check same tone_id */
 | 
						|
        for(i = 0; i < spur_buf_size; i++)
 | 
						|
        {
 | 
						|
            /* tone exist */
 | 
						|
            if (spur_buf[i].tone_id  == tone_id) {
 | 
						|
                spur_buf[i].spur_cnt++;
 | 
						|
                spur_buf[i].spur_ratio = (spur_buf[i].spur_ratio > pwr_ratio) ?
 | 
						|
                    spur_buf[i].spur_ratio :
 | 
						|
                    pwr_ratio;
 | 
						|
                spur_buf[i].notch_filter_en_cnt += notch_en;
 | 
						|
 | 
						|
                tone_find_en = true;
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        /* if not exist */
 | 
						|
        if (tone_find_en != true) {
 | 
						|
            /* find the minimal spur */
 | 
						|
            uint32_t min_spur_idx = 0;
 | 
						|
            uint32_t min_spur_ratio = spur_buf[0].spur_ratio;
 | 
						|
            for (i = 0; i < spur_buf_size; i++) {
 | 
						|
                if (min_spur_ratio > spur_buf[i].spur_ratio) {
 | 
						|
                    min_spur_ratio = spur_buf[i].spur_ratio;
 | 
						|
                    min_spur_idx = i;
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            /* fill */
 | 
						|
            spur_buf[min_spur_idx].tone_id = tone_id;
 | 
						|
            spur_buf[min_spur_idx].spur_cnt = 1;
 | 
						|
            spur_buf[min_spur_idx].spur_ratio = pwr_ratio;
 | 
						|
            spur_buf[min_spur_idx].notch_filter_en_cnt = notch_en;
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
        for(i = 0; i < spur_buf_size; i++)
 | 
						|
        {
 | 
						|
            /* tone exist */
 | 
						|
            if (spur_buf[i].tone_id  == tone_id) {
 | 
						|
                spur_buf[i].spur_cnt++;
 | 
						|
                spur_buf[i].spur_ratio = (spur_buf[i].spur_ratio > pwr_ratio) ?
 | 
						|
                    spur_buf[i].spur_ratio :
 | 
						|
                    pwr_ratio;
 | 
						|
                spur_buf[i].notch_filter_en_cnt += notch_en;
 | 
						|
                break;
 | 
						|
            } else if (spur_buf[i].tone_id == 0) {
 | 
						|
                /* add new */
 | 
						|
                spur_buf[i].tone_id = tone_id;
 | 
						|
                spur_buf[i].spur_cnt++;
 | 
						|
                spur_buf[i].spur_ratio = pwr_ratio;
 | 
						|
                spur_buf[i].notch_filter_en_cnt += notch_en;
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
#else
 | 
						|
    (void *)spur_buf;
 | 
						|
    (void)buf_len;
 | 
						|
    (void)tone_id;
 | 
						|
    (void)pwr_ratio;
 | 
						|
    (void)notch_en;
 | 
						|
#endif
 | 
						|
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
static void phy_chn_spur_arry_peak_extract(iot_phy_spur_t *spur_buf,
 | 
						|
    uint32_t buf_len, uint32_t est_rty_cnt)
 | 
						|
{
 | 
						|
    uint32_t i = 0;
 | 
						|
    uint16_t spur_idx = 2;
 | 
						|
    uint32_t spur_total_len = 0;
 | 
						|
 | 
						|
    /* valid check */
 | 
						|
    IOT_ASSERT(spur_buf != NULL && buf_len > 0);
 | 
						|
 | 
						|
    /* clr current cnt */
 | 
						|
    g_phy_ctxt.dep.phy_status.spur_array[1] = 0;
 | 
						|
    /* cal total spur len */
 | 
						|
    spur_total_len = buf_len/sizeof(iot_phy_spur_t);
 | 
						|
 | 
						|
    /* init first color */
 | 
						|
    if(spur_buf[0].tone_id == 0) {
 | 
						|
        return;
 | 
						|
    } else {
 | 
						|
        spur_buf[0].color = 1;
 | 
						|
    }
 | 
						|
 | 
						|
    /* color the neighbouring tone */
 | 
						|
    for(i = 1; i < spur_total_len; i++)
 | 
						|
    {
 | 
						|
        if(spur_buf[i].tone_id == 0) {
 | 
						|
            break;
 | 
						|
        }
 | 
						|
 | 
						|
        if(spur_buf[i].tone_id == (spur_buf[i-1].tone_id + 1)) {
 | 
						|
            spur_buf[i].color = spur_buf[i-1].color;
 | 
						|
        } else {
 | 
						|
            spur_buf[i].color = spur_buf[i-1].color + 1;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /* find peak by loop */
 | 
						|
    for(i = 0; i < spur_total_len -1; i++)
 | 
						|
    {
 | 
						|
        if(spur_buf[i].tone_id == 0) {
 | 
						|
            break;
 | 
						|
        }
 | 
						|
 | 
						|
        if(spur_buf[i].color == (spur_buf[i+1].color)){
 | 
						|
            if(spur_buf[i].spur_ratio <= spur_buf[i+1].spur_ratio) {
 | 
						|
                spur_buf[i].tone_id = 0;
 | 
						|
            } else {
 | 
						|
                spur_buf[i+1].tone_id = spur_buf[i].tone_id;
 | 
						|
                spur_buf[i+1].spur_cnt = spur_buf[i].spur_cnt;
 | 
						|
                spur_buf[i+1].spur_ratio = spur_buf[i].spur_ratio;
 | 
						|
                spur_buf[i+1].notch_filter_en_cnt = spur_buf[i].notch_filter_en_cnt;
 | 
						|
                spur_buf[i].tone_id = 0;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /* save peak */
 | 
						|
    for(i = 0; i < spur_total_len; i++)
 | 
						|
    {
 | 
						|
        if(spur_buf[i].spur_cnt > (est_rty_cnt >> 1) &&
 | 
						|
        spur_buf[i].tone_id != 0) {
 | 
						|
            /* spur total num */
 | 
						|
            g_phy_ctxt.dep.phy_status.spur_array[0] += 1;
 | 
						|
            /* spur current num */
 | 
						|
            g_phy_ctxt.dep.phy_status.spur_array[1] += 1;
 | 
						|
            /* spur id */
 | 
						|
            if(spur_idx < PHY_LOG_SPUR_MAX_CNT) {
 | 
						|
                g_phy_ctxt.dep.phy_status.spur_array[spur_idx++] =
 | 
						|
                    (uint16_t)(spur_buf[i].tone_id);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void phy_spur_high_pwr_handler(bool_t pulse_flag, uint16_t base_spur_id)
 | 
						|
{
 | 
						|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
 | 
						|
    uint16_t notch_alpha = 0;
 | 
						|
    uint32_t band_id = phy_band_id_get();
 | 
						|
 | 
						|
    /* find harmonic */
 | 
						|
    if ((pulse_flag == true) && (band_id == IOT_SUPPORT_TONE_100_230 ||
 | 
						|
        base_spur_id < PHY_SPUR_3M_DET_START)) {
 | 
						|
        /* dc block hp */
 | 
						|
        phy_dc_blk_alpha_step3_set(32);
 | 
						|
        iot_printf("dc blk alpha 32!\n");
 | 
						|
 | 
						|
        if (band_id == IOT_SUPPORT_TONE_100_230) {
 | 
						|
            notch_alpha = phy_alpha_cal(123);
 | 
						|
            phy_anf_option_set(PHY_ANF_MODE_FIX, 1, 1, notch_alpha);
 | 
						|
            notch_alpha = phy_alpha_cal(164);
 | 
						|
            phy_anf_option_set(PHY_ANF_MODE_FIX, 1, 2, notch_alpha);
 | 
						|
        } else if (band_id == IOT_SUPPORT_TONE_32_120 ||
 | 
						|
            band_id == IOT_SUPPORT_TONE_MULTI_BAND021) {
 | 
						|
            notch_alpha = phy_alpha_cal(82);
 | 
						|
            phy_anf_option_set(PHY_ANF_MODE_FIX, 1, 1, notch_alpha);
 | 
						|
            notch_alpha = phy_alpha_cal(123);
 | 
						|
            phy_anf_option_set(PHY_ANF_MODE_FIX, 1, 2, notch_alpha);
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
        /* if nf > 100 shutdown sw-agc */
 | 
						|
        if (g_phy_ctxt.dep.nf >= 100) {
 | 
						|
            /* 3M special */
 | 
						|
            if ((base_spur_id >= PHY_SPUR_3M_DET_START) &&
 | 
						|
                (base_spur_id <= PHY_SPUR_3M_DET_END)) {
 | 
						|
                /* shut dwon sw-agc */
 | 
						|
                phy_swagc_set(false);
 | 
						|
                g_phy_ctxt.indep.sw_agc_force_off = true;
 | 
						|
 | 
						|
                /* dc block hp */
 | 
						|
                phy_dc_blk_alpha_step3_set(253);
 | 
						|
            } else if ((band_id == IOT_SUPPORT_TONE_100_230) &&
 | 
						|
                (base_spur_id >= PHY_SPUR_6M_DET_START) &&
 | 
						|
                (base_spur_id <= PHY_SPUR_6M_DET_END)) {
 | 
						|
                /* 6M pulse tgt pwr to 110 */
 | 
						|
                g_phy_cpu_share_ctxt.spur_exist = 0;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        notch_alpha = phy_alpha_cal(base_spur_id);
 | 
						|
        phy_anf_option_set(PHY_ANF_MODE_FIX, 1, 2, notch_alpha);
 | 
						|
        phy_anf_option_set(PHY_ANF_MODE_FIX, 1, 1, notch_alpha);
 | 
						|
    }
 | 
						|
 | 
						|
    phy_anf_sel_set(2);
 | 
						|
    phy_anf2_sel_set(2);
 | 
						|
#else
 | 
						|
    (void)pulse_flag;
 | 
						|
    (void)base_spur_id;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
static bool_t phy_pulse_check(iot_phy_spur_t *spur_buf,
 | 
						|
    uint32_t spur_total_len, uint16_t base_spur_id)
 | 
						|
{
 | 
						|
    bool_t pulse_flag = false;
 | 
						|
    uint32_t harmonic_cnt = 0, harmonic1_cnt = 0, harmonic2_cnt = 0;
 | 
						|
 | 
						|
    if (base_spur_id != 0) {
 | 
						|
        for(uint32_t i = 0; i < spur_total_len; i++)
 | 
						|
        {
 | 
						|
            /* find harmonic */
 | 
						|
            if ((spur_buf[i].tone_id / base_spur_id >= 1) &&
 | 
						|
                (spur_buf[i].tone_id % base_spur_id == 0)) {
 | 
						|
                harmonic_cnt++;
 | 
						|
            }
 | 
						|
            /* find harmonic1 -1 */
 | 
						|
            if ((spur_buf[i].tone_id / (base_spur_id - 1) >= 1) &&
 | 
						|
                (spur_buf[i].tone_id % (base_spur_id - 1) == 0)) {
 | 
						|
                harmonic1_cnt++;
 | 
						|
            }
 | 
						|
            /* find harmonic2 +1 */
 | 
						|
            if ((spur_buf[i].tone_id / (base_spur_id + 1) >= 1) &&
 | 
						|
                (spur_buf[i].tone_id % (base_spur_id + 1) == 0)) {
 | 
						|
                harmonic2_cnt++;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        /* check pulse or spur */
 | 
						|
        if (harmonic_cnt >= PHY_PULSE_HARMONIC_THD ||
 | 
						|
            harmonic1_cnt >= PHY_PULSE_HARMONIC_THD ||
 | 
						|
            harmonic2_cnt >= PHY_PULSE_HARMONIC_THD) {
 | 
						|
            pulse_flag = true;
 | 
						|
        }
 | 
						|
 | 
						|
        iot_printf("tone %d harmonic cnt:%d-%d-%d!\n",
 | 
						|
            base_spur_id, harmonic_cnt, harmonic1_cnt, harmonic2_cnt);
 | 
						|
    }
 | 
						|
 | 
						|
    return pulse_flag;
 | 
						|
}
 | 
						|
 | 
						|
static uint16_t phy_spur_arry_base_id_find(iot_phy_spur_t *spur_buf,
 | 
						|
    uint16_t max_spur_id)
 | 
						|
{
 | 
						|
    uint32_t base_spur_id = 0;
 | 
						|
 | 
						|
    if (max_spur_id != 0) {
 | 
						|
        for(uint32_t i = 0; i < max_spur_id; i++)
 | 
						|
        {
 | 
						|
            /* check */
 | 
						|
            if (max_spur_id%spur_buf[i].tone_id == 0 ||
 | 
						|
                (max_spur_id + 1)%spur_buf[i].tone_id == 0 ||
 | 
						|
                (max_spur_id - 1)%spur_buf[i].tone_id == 0) {
 | 
						|
                base_spur_id = spur_buf[i].tone_id;
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        /* if not find */
 | 
						|
        if (base_spur_id == 0) {
 | 
						|
            base_spur_id = max_spur_id;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return (uint16_t)base_spur_id;
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t phy_spur_arry_peak_handler(iot_phy_spur_t *spur_buf,
 | 
						|
    uint32_t buf_len, uint32_t est_rty_cnt)
 | 
						|
{
 | 
						|
    uint32_t ret = ERR_OK;
 | 
						|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
 | 
						|
    uint32_t spur_total_len = 0;
 | 
						|
    uint32_t max_ratio = 0;
 | 
						|
    uint16_t max_spur_id = 0, base_spur_id = 0;
 | 
						|
    uint16_t notch_alpha = 0;
 | 
						|
    uint16_t inband_tone_mask_curr = 0;
 | 
						|
    uint16_t inband_tone_mask_total = 0;
 | 
						|
    uint32_t cmp_thd_cnt = est_rty_cnt >> 1;
 | 
						|
    bool_t pulse_flag = false, spur_flag = false, spur6m_flag = false;
 | 
						|
    uint32_t band_id = phy_band_id_get();
 | 
						|
    uint32_t end_tone;
 | 
						|
 | 
						|
    if (g_phy_cpu_share_ctxt.pt_mode_entry == 1) {
 | 
						|
        return ERR_NOSUPP;
 | 
						|
    }
 | 
						|
 | 
						|
    /* valid check */
 | 
						|
    IOT_ASSERT(spur_buf != NULL && buf_len > 0);
 | 
						|
 | 
						|
    /* first fft pwr full for band narrow */
 | 
						|
    if (band_id == IOT_SUPPORT_TONE_32_120 ||
 | 
						|
        band_id == IOT_SUPPORT_TONE_MULTI_BAND021) {
 | 
						|
        cmp_thd_cnt = (cmp_thd_cnt > 0) ? (cmp_thd_cnt - 1) : 0;
 | 
						|
    }
 | 
						|
 | 
						|
    /* cal total spur len */
 | 
						|
    spur_total_len = buf_len/sizeof(iot_phy_spur_t);
 | 
						|
    /* cal max mask tone number */
 | 
						|
    inband_tone_mask_total = all_mask_band_table_r0_full.valid_tone_number/3;
 | 
						|
    /* scan all spur */
 | 
						|
    for (uint32_t i = 0; i < spur_total_len; i++) {
 | 
						|
        if (spur_buf[i].tone_id != 0) {
 | 
						|
            iot_printf("[BB_AI] spur: %u, cnt: %u!\n",
 | 
						|
                spur_buf[i].tone_id, spur_buf[i].spur_cnt);
 | 
						|
 | 
						|
            /* check cnt */
 | 
						|
            if (spur_buf[i].spur_cnt > cmp_thd_cnt) {
 | 
						|
                /* check inband max masked number */
 | 
						|
                if (
 | 
						|
                (spur_buf[i].tone_id >= all_mask_band_table_r0_full.start_tone &&
 | 
						|
                spur_buf[i].tone_id <= all_mask_band_table_r0_full.end_tone) ||
 | 
						|
                (spur_buf[i].tone_id >= all_mask_band_table_r1_full.start_tone &&
 | 
						|
                spur_buf[i].tone_id <= all_mask_band_table_r1_full.end_tone)) {
 | 
						|
                    if (inband_tone_mask_curr < inband_tone_mask_total) {
 | 
						|
                        inband_tone_mask_curr++;
 | 
						|
                        /* mask spur */
 | 
						|
                        phy_spur_mask_set(spur_buf[i].tone_id,0);
 | 
						|
                        iot_printf("[BB_AI] spur tone: %u mask done!\n",
 | 
						|
                            spur_buf[i].tone_id);
 | 
						|
                    } else {
 | 
						|
                        /* do nothing for other inband tone */
 | 
						|
                        continue;
 | 
						|
                    }
 | 
						|
                } else {
 | 
						|
                    /* mask spur */
 | 
						|
                    phy_spur_mask_set(spur_buf[i].tone_id,0);
 | 
						|
                    iot_printf("[BB_AI] spur tone: %u mask done!\n",
 | 
						|
                        spur_buf[i].tone_id);
 | 
						|
                }
 | 
						|
 | 
						|
                /* notch filter set */
 | 
						|
                if (spur_buf[i].notch_filter_en_cnt > cmp_thd_cnt) {
 | 
						|
                    /* find max spur */
 | 
						|
                    if (!g_phy_ctxt.indep.notch_filter_en) {
 | 
						|
                        g_phy_ctxt.indep.notch_filter_en = true;
 | 
						|
                        max_ratio = spur_buf[i].spur_ratio;
 | 
						|
                        max_spur_id = spur_buf[i].tone_id;
 | 
						|
                    } else if(max_ratio < spur_buf[i].spur_ratio &&
 | 
						|
                        spur_buf[i].tone_id < 512) {
 | 
						|
                        /* compare max */
 | 
						|
                        max_ratio = spur_buf[i].spur_ratio;
 | 
						|
                        max_spur_id = spur_buf[i].tone_id;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
#if PHY_BB_AI_WITH_PULSE_CHECK_EN
 | 
						|
                if (spur_buf[i].tone_id == IOT_SPUR_8M_CENTER_TONE) {
 | 
						|
                    phy_anti_spur_set(IOT_SUPPORT_TONE_80_490);
 | 
						|
                } else if(spur_buf[i].tone_id == IOT_SPUR_3M_CENTER_TONE) {
 | 
						|
                    phy_anti_spur_set(IOT_SUPPORT_TONE_100_230);
 | 
						|
                } else if(spur_buf[i].tone_id == IOT_SPUR_2M_CENTER_TONE) {
 | 
						|
                    phy_anti_spur_set(IOT_SUPPORT_TONE_32_120);
 | 
						|
                }
 | 
						|
#endif
 | 
						|
 | 
						|
                /* maybe 6M not detect because of notch thd */
 | 
						|
                if ((band_id == IOT_SUPPORT_TONE_100_230 ||
 | 
						|
                    band_id == IOT_SUPPORT_TONE_MULTI_BAND021) &&
 | 
						|
                    spur_buf[i].tone_id >= PHY_SPUR_6M_DET_START &&
 | 
						|
                    spur_buf[i].tone_id <= PHY_SPUR_6M_DET_END) {
 | 
						|
                    spur6m_flag = true;
 | 
						|
                }
 | 
						|
 | 
						|
                spur_flag = true;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /* not work for cert and other low pwr scenario */
 | 
						|
    if (phy_get_nf_of_bbai() >= PHY_CHN_HIGH_NOISE_NF_THD) {
 | 
						|
        /* find spur base id */
 | 
						|
        base_spur_id = phy_spur_arry_base_id_find(spur_buf, max_spur_id);
 | 
						|
 | 
						|
        /* check pulse */
 | 
						|
        pulse_flag = phy_pulse_check(spur_buf, spur_total_len, base_spur_id);
 | 
						|
 | 
						|
        /* diff noise and spur/pulse */
 | 
						|
        if (spur_flag) {
 | 
						|
            /* reduce warning */
 | 
						|
            if (band_id == IOT_SUPPORT_TONE_MULTI_BAND021) {
 | 
						|
                phy_rxfd_pkt_det_thd_set(32, 32);
 | 
						|
            } else {
 | 
						|
                phy_rxfd_pkt_det_thd_set(16, 32);
 | 
						|
            }
 | 
						|
 | 
						|
            phy_band_tone_range_get(NULL, &end_tone);
 | 
						|
            if (end_tone <= 230) {
 | 
						|
                phy_ana_filter_set(63);
 | 
						|
            }
 | 
						|
        } else {
 | 
						|
            /* big nf, but not spur */
 | 
						|
            g_phy_ctxt.dep.big_nf_handle = 1;
 | 
						|
            if (band_id == IOT_SUPPORT_TONE_MULTI_BAND021) {
 | 
						|
                phy_rxfd_pkt_det_thd_set(32, 32);
 | 
						|
            } else {
 | 
						|
                /* more sensitive */
 | 
						|
                phy_rxfd_pkt_det_thd_set(8, 16);
 | 
						|
            }
 | 
						|
 | 
						|
            /* dc block hp */
 | 
						|
            phy_dc_blk_alpha_step3_set(253);
 | 
						|
 | 
						|
            /* clean notch filter */
 | 
						|
            phy_perf_common_init();
 | 
						|
 | 
						|
            /* Must recover 8M high pass filter for att and noise
 | 
						|
                if not will worsen performance index */
 | 
						|
            phy_ana_filter_set(
 | 
						|
                (g_phy_ctxt.dep.band_8m_cap_set > 0) ?
 | 
						|
                    g_phy_ctxt.dep.band_8m_cap_set : 36);
 | 
						|
 | 
						|
            iot_printf("[BB_AI]spur flag:%d, bf 8M\n", spur_flag);
 | 
						|
        }
 | 
						|
 | 
						|
        /* notch filter set */
 | 
						|
        if (max_ratio) {
 | 
						|
            g_phy_cpu_share_ctxt.spur_exist = 1;
 | 
						|
 | 
						|
            /* spur handler */
 | 
						|
            phy_spur_high_pwr_handler(pulse_flag, base_spur_id);
 | 
						|
        } else if (spur6m_flag) {
 | 
						|
            /* tgt pwr to 110 */
 | 
						|
            g_phy_cpu_share_ctxt.spur_exist = 0;
 | 
						|
 | 
						|
            /* 6M spur */
 | 
						|
            notch_alpha = phy_alpha_cal(246);
 | 
						|
            phy_anf_option_set(PHY_ANF_MODE_FIX, 1, 1, notch_alpha);
 | 
						|
        }
 | 
						|
        /* for kl1 */
 | 
						|
#if !PHY_HW_SPIKE_OPTIMIZATION
 | 
						|
        if (band_id == IOT_SUPPORT_TONE_100_230) {
 | 
						|
            /* dc block hp */
 | 
						|
            phy_dc_blk_alpha_step3_set(32);
 | 
						|
        }
 | 
						|
#endif
 | 
						|
 | 
						|
        iot_printf("[BB_AI]ratio:%d, 6m:%d, max=%u, base=%u!\n",
 | 
						|
            max_ratio, spur6m_flag, max_spur_id, base_spur_id);
 | 
						|
    } else {
 | 
						|
        /* if big_nf_handle is true,
 | 
						|
         * indicates that nf has been recover,
 | 
						|
         * and recover threshold
 | 
						|
         */
 | 
						|
        if (g_phy_ctxt.dep.big_nf_handle) {
 | 
						|
            g_phy_ctxt.dep.big_nf_handle = 0;
 | 
						|
            /* reduce warning */
 | 
						|
            if (band_id == IOT_SUPPORT_TONE_MULTI_BAND021) {
 | 
						|
                phy_rxfd_pkt_det_thd_set(32, 32);
 | 
						|
            } else {
 | 
						|
                phy_rxfd_pkt_det_thd_set(16, 32);
 | 
						|
            }
 | 
						|
 | 
						|
#if PHY_HW_SPIKE_OPTIMIZATION
 | 
						|
            if (IOT_SUPPORT_TONE_32_120 == band_id) {
 | 
						|
                phy_rxfd_pkt_det_thd_set(8, 16);
 | 
						|
            }
 | 
						|
#endif
 | 
						|
            /* filter reset */
 | 
						|
            phy_ana_set_filter_init(band_id);
 | 
						|
        }
 | 
						|
 | 
						|
        /* notch filter set */
 | 
						|
        if (max_ratio) {
 | 
						|
            g_phy_cpu_share_ctxt.spur_exist = 1;
 | 
						|
            notch_alpha = phy_alpha_cal(max_spur_id);
 | 
						|
            if (PHY_DFE_READ_REG(CFG_BB_ANF_1_ALPHA_BETA_ADDR) &
 | 
						|
                SW_ANF_OPTION1_MASK) {
 | 
						|
                phy_anf_option_set(PHY_ANF_MODE_FIX, 1, 2, notch_alpha);
 | 
						|
            } else {
 | 
						|
                phy_anf_option_set(PHY_ANF_MODE_FIX, 1, 1, notch_alpha);
 | 
						|
            }
 | 
						|
            phy_check_spur_cert_handle(notch_alpha);
 | 
						|
            iot_printf("[BB_AI] notch filter: %u enable!\n", max_spur_id);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /* find peak and output log */
 | 
						|
    phy_chn_spur_arry_peak_extract(spur_buf, buf_len, est_rty_cnt);
 | 
						|
#else
 | 
						|
    (void *)spur_buf;
 | 
						|
    (void)buf_len;
 | 
						|
    (void)est_rty_cnt;
 | 
						|
#endif
 | 
						|
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t phy_chn_est_data_process(uint32_t *csi_buf,
 | 
						|
    iot_phy_spur_t *spur_buf, int8_t *current_gain, uint8_t pkt_idx)
 | 
						|
{
 | 
						|
    uint32_t ret = ERR_OK;
 | 
						|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
 | 
						|
    uint32_t j = 0;
 | 
						|
    int16_t csi_i = 0, csi_q = 0;
 | 
						|
    uint32_t center_pwr = 0;
 | 
						|
    uint32_t sidelobe_pwr = 0;
 | 
						|
    uint32_t dump_valid_cnt = 0;
 | 
						|
    uint64_t inband_pwr = 0;
 | 
						|
    uint64_t outband_pwr = 0;
 | 
						|
    uint32_t tone_idx = 0;
 | 
						|
    bool_t full_flag = false;
 | 
						|
    uint8_t pwr_ratio = 0;
 | 
						|
    uint32_t bbai_nf = phy_get_nf_of_bbai();
 | 
						|
    bool_t is_w_size_6 = false;
 | 
						|
    uint32_t ext_pwr = 0;
 | 
						|
 | 
						|
#if PHY_DEBUG_EN
 | 
						|
    /* cal csi for every tone for debug*/
 | 
						|
    for (tone_idx = 0; tone_idx < (IOT_PHY_CSI_BUF_LEN >> 2); tone_idx++) {
 | 
						|
        csi_i = (int16_t)(*(csi_buf + tone_idx) & 0xFFFF);
 | 
						|
        csi_q = (int16_t)(*(csi_buf + tone_idx) >> 16);
 | 
						|
        iot_printf("tone:%u, csi_i:%d, csi_q:%d, dB:%u\n",
 | 
						|
            tone_idx + pkt_idx * 512,
 | 
						|
            csi_i,
 | 
						|
            csi_q,
 | 
						|
            (uint32_t)(10 * mlog10(csi_i * csi_i + csi_q * csi_q + 1)));
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
    /* cal outband total pwr */
 | 
						|
    outband_pwr = 0;
 | 
						|
    for (j = 1; j < PHY_CHN_VALID_TONE_NUM + 1; j++) {
 | 
						|
        csi_i = (int16_t)(*(csi_buf +
 | 
						|
            g_plc_band_tbl_r0[HW_FULL_BAND]->start_tone - j) & 0xFFFF);
 | 
						|
        csi_q = (int16_t)(*(csi_buf +
 | 
						|
            g_plc_band_tbl_r0[HW_FULL_BAND]->start_tone - j) >> 16);
 | 
						|
        outband_pwr += csi_i * csi_i + csi_q * csi_q;
 | 
						|
    }
 | 
						|
    /* cal outband average pwr */
 | 
						|
    outband_pwr = outband_pwr/PHY_CHN_VALID_TONE_NUM;
 | 
						|
 | 
						|
    /* check outband pwr */
 | 
						|
    if (!outband_pwr) {
 | 
						|
        return ERR_FAIL;
 | 
						|
    }
 | 
						|
 | 
						|
    /* cal inband pwr */
 | 
						|
    for (j = 0; j < PHY_CHN_VALID_TONE_NUM; j++) {
 | 
						|
        csi_i = (int16_t)(*(csi_buf +
 | 
						|
            g_plc_band_tbl_r0[HW_FULL_BAND]->start_tone + j) & 0xFFFF);
 | 
						|
        csi_q = (int16_t)(*(csi_buf +
 | 
						|
            g_plc_band_tbl_r0[HW_FULL_BAND]->start_tone + j) >> 16);
 | 
						|
        inband_pwr = csi_i * csi_i + csi_q * csi_q;
 | 
						|
        /* pkt feature: inband > outband 10dB */
 | 
						|
        if (10 * mlog10(inband_pwr/outband_pwr) < PHY_FD_PKT_CHECK_THD) {
 | 
						|
            dump_valid_cnt += 1;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /* check valid dump */
 | 
						|
    if (dump_valid_cnt < (PHY_CHN_VALID_TONE_NUM >> 1)) {
 | 
						|
#if PHY_DEBUG_EN
 | 
						|
        iot_printf("[BB_AI] find pkt, valid cnt:%u\n", dump_valid_cnt);
 | 
						|
#endif
 | 
						|
        return ERR_FAIL;
 | 
						|
    }
 | 
						|
 | 
						|
    /* spur check: scan band 0-511 with special point */
 | 
						|
    for (j = PHY_CHN_EST_AI_SIDELOBE_NUM + 1;
 | 
						|
        j < (IOT_PHY_CSI_BUF_LEN >> 2) - PHY_CHN_EST_AI_SIDELOBE_NUM; j++) {
 | 
						|
 | 
						|
        /* zero pwr */
 | 
						|
        center_pwr = 0;
 | 
						|
        sidelobe_pwr = 0;
 | 
						|
        ext_pwr = 0;
 | 
						|
 | 
						|
        /* spur find loop */
 | 
						|
        for (tone_idx = j - PHY_CHN_EST_AI_SIDELOBE_NUM;
 | 
						|
            tone_idx <= j + PHY_CHN_EST_AI_SIDELOBE_NUM; tone_idx++) {
 | 
						|
 | 
						|
            csi_i = (int16_t)(*(csi_buf + tone_idx) & 0xFFFF);
 | 
						|
            csi_q = (int16_t)(*(csi_buf + tone_idx) >> 16);
 | 
						|
 | 
						|
            /* check full */
 | 
						|
            if ((csi_i > PHY_CHN_EST_AI_FULL_PWR ||
 | 
						|
                csi_i < -PHY_CHN_EST_AI_FULL_PWR) &&
 | 
						|
                (csi_q > PHY_CHN_EST_AI_FULL_PWR ||
 | 
						|
                csi_q < -PHY_CHN_EST_AI_FULL_PWR)) {
 | 
						|
                /* if current gain is not least gain,
 | 
						|
                 * decrease gain and discard this data.
 | 
						|
                 * else use this data.
 | 
						|
                 */
 | 
						|
                if (*current_gain != -PHY_AGC_GAIN_ENTRY_OFFSET) {
 | 
						|
                    full_flag = true;
 | 
						|
                    break;
 | 
						|
                }
 | 
						|
            } else {
 | 
						|
                if (tone_idx >= (j - PHY_CHN_EST_AI_W_SIZE_4) &&
 | 
						|
                    tone_idx <= (j + PHY_CHN_EST_AI_W_SIZE_4)) {
 | 
						|
                    center_pwr += csi_i * csi_i + csi_q * csi_q;
 | 
						|
                } else {
 | 
						|
                    sidelobe_pwr += csi_i * csi_i + csi_q * csi_q;
 | 
						|
                }
 | 
						|
                if (tone_idx == j - PHY_CHN_EST_AI_W_SIZE_6 ||
 | 
						|
                    tone_idx == j + PHY_CHN_EST_AI_W_SIZE_6 ) {
 | 
						|
                    ext_pwr += csi_i * csi_i + csi_q * csi_q;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        if (full_flag) {
 | 
						|
            /* reint full flag */
 | 
						|
            full_flag = false;
 | 
						|
            uint8_t gain_step = ((bbai_nf > PHY_CHN_EST_AI_SPUR_NF_THD) ?
 | 
						|
                (PHY_CHN_EST_AI_GAIN_STEP << 1) : (PHY_CHN_EST_AI_GAIN_STEP));
 | 
						|
            /* decrease gain */
 | 
						|
            if ((*current_gain - gain_step + PHY_AGC_GAIN_ENTRY_OFFSET) > 0) {
 | 
						|
                *current_gain -= (int8_t)gain_step;
 | 
						|
            } else {
 | 
						|
                *current_gain = -PHY_AGC_GAIN_ENTRY_OFFSET;
 | 
						|
            }
 | 
						|
 | 
						|
            iot_printf("[BB_AI] pwr full, decrease gain to:%d\n", *current_gain);
 | 
						|
            return ERR_FAIL;
 | 
						|
        } else {
 | 
						|
 | 
						|
            is_w_size_6 = false;
 | 
						|
windows:
 | 
						|
            /* check sidelobe_pwr */
 | 
						|
            if (!sidelobe_pwr) {
 | 
						|
                continue;
 | 
						|
            }
 | 
						|
 | 
						|
            /* cal pwr ratio*/
 | 
						|
            pwr_ratio = center_pwr/sidelobe_pwr;
 | 
						|
            bool_t judge_spur_flag;
 | 
						|
            if ((center_pwr > PHY_CHN_EST_AI_SUPR_PWR_THD) &&
 | 
						|
                (bbai_nf > PHY_CHN_EST_AI_SPUR_NF_THD)) {
 | 
						|
                /* power > 24000000 and nf > 100 */
 | 
						|
                judge_spur_flag = true;
 | 
						|
            } else {
 | 
						|
                judge_spur_flag = (pwr_ratio > PHY_CHN_EST_AI_SPUR_THD);
 | 
						|
            }
 | 
						|
 | 
						|
            if (judge_spur_flag) {
 | 
						|
#if PHY_DEBUG_EN
 | 
						|
                iot_printf("[BB_AI] tone:%u, center_pwr:%u, ext_pwr:%u\n",
 | 
						|
                    j + pkt_idx * (IOT_PHY_CSI_BUF_LEN >> 2),
 | 
						|
                    center_pwr, sidelobe_pwr);
 | 
						|
#endif
 | 
						|
                /* notch filter thd check */
 | 
						|
                bool_t judge_notch_flag;
 | 
						|
                if ((center_pwr > PHY_CHN_EST_AI_SUPR_PWR_THD) &&
 | 
						|
                    (bbai_nf > PHY_CHN_EST_AI_SPUR_NF_THD)) {
 | 
						|
                    /* power > 24000000 and nf > 100 */
 | 
						|
                    judge_notch_flag = true;
 | 
						|
                } else {
 | 
						|
                    judge_notch_flag =
 | 
						|
                        (pwr_ratio > PHY_CHN_EST_AI_SPUR_NOTCH_THD);
 | 
						|
                }
 | 
						|
                if (judge_notch_flag) {
 | 
						|
                    /* append to spur array with notch filter */
 | 
						|
                    phy_spur_arry_append(spur_buf,
 | 
						|
                        PHY_CHN_EST_AI_SPUR_LEN,
 | 
						|
                        j + pkt_idx * (IOT_PHY_CSI_BUF_LEN >> 2),
 | 
						|
                        center_pwr >> 5, true);
 | 
						|
                } else {
 | 
						|
                    /* append to spur array without notch filter */
 | 
						|
                    phy_spur_arry_append(spur_buf,
 | 
						|
                        PHY_CHN_EST_AI_SPUR_LEN,
 | 
						|
                        j + pkt_idx * (IOT_PHY_CSI_BUF_LEN >> 2),
 | 
						|
                        center_pwr >> 5, false);
 | 
						|
                }
 | 
						|
            } else {
 | 
						|
                /* if find spur fail, adjust main windows form 4 to 6 */
 | 
						|
                if (is_w_size_6 == false) {
 | 
						|
                    is_w_size_6 = true;
 | 
						|
                    center_pwr += ext_pwr;
 | 
						|
                    sidelobe_pwr -= ext_pwr;
 | 
						|
                    goto windows;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
#else
 | 
						|
    (void)csi_buf;
 | 
						|
    (void)spur_buf;
 | 
						|
    (void)current_gain;
 | 
						|
    (void)pkt_idx;
 | 
						|
#endif
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
static void phy_chn_est_sidelobe_process(uint32_t *csi_buf,
 | 
						|
    iot_phy_spur_t *spur_buf, int8_t *current_gain, uint8_t pkt_idx)
 | 
						|
{
 | 
						|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
 | 
						|
    uint32_t j = 0;
 | 
						|
    int16_t csi_i = 0, csi_q = 0;
 | 
						|
    uint32_t center_pwr = 0;
 | 
						|
    uint32_t sidelobe_pwr = 0;
 | 
						|
    uint32_t tone_idx = 0;
 | 
						|
    bool_t full_flag = false;
 | 
						|
#if PHY_DEBUG_EN
 | 
						|
    for (tone_idx = 0; tone_idx <= (PHY_CHN_EST_AI_SIDELOBE_NUM << 2);
 | 
						|
        tone_idx++) {
 | 
						|
        csi_i = (int16_t)(*(csi_buf + tone_idx) & 0xFFFF);
 | 
						|
        csi_q = (int16_t)(*(csi_buf + tone_idx) >> 16);
 | 
						|
        iot_printf("tone:%u, csi_i:%d, csi_q:%d, dB:%u\n",
 | 
						|
            tone_idx + pkt_idx * 512 - (PHY_CHN_EST_AI_SIDELOBE_NUM << 1),
 | 
						|
            csi_i, csi_q,
 | 
						|
            (uint32_t)(10 * mlog10(csi_i * csi_i + csi_q * csi_q + 1)));
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
    /* spur check: scan band 0-24 with special point */
 | 
						|
    for (j = PHY_CHN_EST_AI_SIDELOBE_NUM;
 | 
						|
        j <= (PHY_CHN_EST_AI_SIDELOBE_NUM << 2) - PHY_CHN_EST_AI_SIDELOBE_NUM;
 | 
						|
        j++) {
 | 
						|
        /* zero pwr */
 | 
						|
        center_pwr = 0;
 | 
						|
        sidelobe_pwr = 0;
 | 
						|
 | 
						|
        /* spur find loop */
 | 
						|
        for (tone_idx = j - PHY_CHN_EST_AI_SIDELOBE_NUM;
 | 
						|
            tone_idx <= j + PHY_CHN_EST_AI_SIDELOBE_NUM; tone_idx++) {
 | 
						|
            csi_i = (int16_t)(*(csi_buf + tone_idx) & 0xFFFF);
 | 
						|
            csi_q = (int16_t)(*(csi_buf + tone_idx) >> 16);
 | 
						|
 | 
						|
            /* check full */
 | 
						|
            if((csi_i == PHY_CHN_EST_AI_FULL_PWR ||
 | 
						|
                csi_i == -PHY_CHN_EST_AI_FULL_PWR) &&
 | 
						|
                (csi_q == PHY_CHN_EST_AI_FULL_PWR ||
 | 
						|
                csi_q == -PHY_CHN_EST_AI_FULL_PWR)) {
 | 
						|
                full_flag = true;
 | 
						|
                break;
 | 
						|
            } else {
 | 
						|
                if(tone_idx >= (j - 2) && tone_idx <= (j + 2)) {
 | 
						|
                    center_pwr += csi_i * csi_i + csi_q * csi_q;
 | 
						|
                } else {
 | 
						|
                    sidelobe_pwr += csi_i * csi_i + csi_q * csi_q;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        if(full_flag) {
 | 
						|
            /* reint full flag */
 | 
						|
            full_flag = false;
 | 
						|
            /* decrease gain */
 | 
						|
            *current_gain -= (int8_t)PHY_CHN_EST_AI_GAIN_STEP;
 | 
						|
            iot_printf("[BB_AI] pwr full, decrease gain to:%d\n", *current_gain);
 | 
						|
            break;
 | 
						|
        } else {
 | 
						|
            /* check sidelobe_pwr */
 | 
						|
            if(!sidelobe_pwr) {
 | 
						|
                continue;
 | 
						|
            }
 | 
						|
 | 
						|
            if(center_pwr/sidelobe_pwr > PHY_CHN_EST_AI_SPUR_THD) {
 | 
						|
#if PHY_DEBUG_EN
 | 
						|
               iot_printf("[BB_AI] tone:%u, center_pwr:%u, ext_pwr:%u\n",
 | 
						|
                    j + pkt_idx * (IOT_PHY_CSI_BUF_LEN >> 2) -
 | 
						|
                        (PHY_CHN_EST_AI_SIDELOBE_NUM << 1),
 | 
						|
                    center_pwr, sidelobe_pwr);
 | 
						|
#endif
 | 
						|
                /* notch filter thd check */
 | 
						|
                if(center_pwr/sidelobe_pwr > PHY_CHN_EST_AI_SPUR_NOTCH_THD) {
 | 
						|
                    /* append to spur array with notch filter */
 | 
						|
                    phy_spur_arry_append(spur_buf,
 | 
						|
                        PHY_CHN_EST_AI_SPUR_LEN,
 | 
						|
                        j + pkt_idx * ((IOT_PHY_CSI_BUF_LEN >> 2) -
 | 
						|
                            (PHY_CHN_EST_AI_SIDELOBE_NUM << 1)),
 | 
						|
                        10 * mlog10(center_pwr/sidelobe_pwr), true);
 | 
						|
                } else {
 | 
						|
                    /* append to spur array without notch filter */
 | 
						|
                    phy_spur_arry_append(spur_buf,
 | 
						|
                        PHY_CHN_EST_AI_SPUR_LEN,
 | 
						|
                        j + pkt_idx * ((IOT_PHY_CSI_BUF_LEN >> 2) -
 | 
						|
                            (PHY_CHN_EST_AI_SIDELOBE_NUM << 1)),
 | 
						|
                        10 * mlog10(center_pwr/sidelobe_pwr), false);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
#else
 | 
						|
    (void)csi_buf;
 | 
						|
    (void)spur_buf;
 | 
						|
    (void)current_gain;
 | 
						|
    (void)pkt_idx;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
uint32_t phy_chn_est_ai(int8_t current_gain, uint32_t est_rty_cnt,
 | 
						|
    uint32_t timeout_ms)
 | 
						|
{
 | 
						|
    uint32_t success_cnt = 0;
 | 
						|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
 | 
						|
    uint32_t i = 0;
 | 
						|
    uint32_t ret = ERR_OK;
 | 
						|
    uint32_t start_time = 0, end_time = 0;
 | 
						|
    int64_t time_span = 0;
 | 
						|
    iot_pkt_t *pkt_buf = NULL;
 | 
						|
    iot_pkt_t *hash_buf = NULL;
 | 
						|
    uint32_t *csi_buf = NULL;
 | 
						|
    iot_phy_spur_t *spur_buf = NULL;
 | 
						|
    uint32_t *sidelobe_buf = NULL;
 | 
						|
    uint8_t pkt_idx = 0;
 | 
						|
 | 
						|
    /* check dump busy flag */
 | 
						|
    if (phy_busy_get(&g_phy_ctxt, PHY_BUSY_DUMP)) {
 | 
						|
        iot_printf("phy dump busy!\n");
 | 
						|
        return ERR_BUSY;
 | 
						|
    } else {
 | 
						|
        phy_dump_busy_set(true);
 | 
						|
    }
 | 
						|
 | 
						|
    /* get start time */
 | 
						|
    start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
 | 
						|
    /* get mem from iot_pkt to save csi data */
 | 
						|
    IOT_PKT_GET(pkt_buf, IOT_PHY_CSI_BUF_LEN, 0, PLC_PHY_COMMON_MID);
 | 
						|
    if(!pkt_buf){
 | 
						|
        iot_printf("phy chn est fatal error, iot_pkt_get fail\n");
 | 
						|
        phy_dump_busy_set(false);
 | 
						|
        return success_cnt;
 | 
						|
    }
 | 
						|
    csi_buf = (uint32_t *)iot_pkt_put(pkt_buf, IOT_PHY_CSI_BUF_LEN);
 | 
						|
 | 
						|
    /* get mem from iot_pkt to save spur data and sidelobe */
 | 
						|
    IOT_PKT_GET(hash_buf,
 | 
						|
        PHY_CHN_EST_AI_SPUR_LEN + (PHY_CHN_EST_AI_SIDELOBE_NUM << 4) + 4,
 | 
						|
        0,
 | 
						|
        PLC_PHY_COMMON_MID);
 | 
						|
    if(!hash_buf){
 | 
						|
        iot_printf("phy chn est spur fatal error, iot_pkt_get fail\n");
 | 
						|
        /* free iot pkt */
 | 
						|
        iot_pkt_free(pkt_buf);
 | 
						|
        phy_dump_busy_set(false);
 | 
						|
        return success_cnt;
 | 
						|
    }
 | 
						|
    spur_buf = (iot_phy_spur_t *)iot_pkt_put(hash_buf, PHY_CHN_EST_AI_SPUR_LEN);
 | 
						|
    sidelobe_buf = (uint32_t *)spur_buf + (PHY_CHN_EST_AI_SPUR_LEN >> 2);
 | 
						|
 | 
						|
#if PHY_HW_SPIKE_OPTIMIZATION
 | 
						|
    /* NOTE: KL2/3 can not use max gain, need get average gain */
 | 
						|
    current_gain = phy_gain_get_from_agc();
 | 
						|
    if (current_gain > PHY_BBAI_GAIN_MAX) {
 | 
						|
        current_gain = PHY_BBAI_GAIN_MAX;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
    /* check csi buf pointer valid and flag */
 | 
						|
    if(csi_buf != NULL)
 | 
						|
    {
 | 
						|
        /* rst to trig enable */
 | 
						|
        phy_reset(PHY_RST_REASON_WARM);
 | 
						|
 | 
						|
        /* get valid fft dump */
 | 
						|
        for(i = 0; i < est_rty_cnt; i++)
 | 
						|
        {
 | 
						|
            for(pkt_idx = 0; pkt_idx < FFT_DUMP_PKT_MAX; pkt_idx++) {
 | 
						|
                /* trig fft to dump */
 | 
						|
                ret = phy_rx_fft_dump(csi_buf, current_gain, pkt_idx, FFT_DUMP_PKT_MAX);
 | 
						|
                if (ret != ERR_OK) {
 | 
						|
                    /* clr dump and close current dump */
 | 
						|
                    phy_rx_fft_dump(csi_buf, current_gain,
 | 
						|
                        FFT_DUMP_PKT_MAX - 1, FFT_DUMP_PKT_MAX);
 | 
						|
                    break;
 | 
						|
                }
 | 
						|
 | 
						|
                /* data process */
 | 
						|
                ret = phy_chn_est_data_process(
 | 
						|
                    csi_buf, spur_buf, ¤t_gain, pkt_idx);
 | 
						|
                if(ret != ERR_OK) {
 | 
						|
                    /* clr dump and close current dump */
 | 
						|
                    phy_rx_fft_dump(csi_buf, current_gain,
 | 
						|
                        FFT_DUMP_PKT_MAX - 1, FFT_DUMP_PKT_MAX);
 | 
						|
                    break;
 | 
						|
                }
 | 
						|
 | 
						|
                /* sidelobe data like 512-6~512+6 */
 | 
						|
                if(pkt_idx > 0) {
 | 
						|
                    /* copy current pkt sidelobe */
 | 
						|
                    os_mem_cpy(sidelobe_buf + (PHY_CHN_EST_AI_SIDELOBE_NUM << 1),
 | 
						|
                        csi_buf,
 | 
						|
                        (PHY_CHN_EST_AI_SIDELOBE_NUM << 3) + 4);
 | 
						|
                    /* sidelobe data process */
 | 
						|
                    phy_chn_est_sidelobe_process(
 | 
						|
                        sidelobe_buf, spur_buf, ¤t_gain, pkt_idx);
 | 
						|
                }
 | 
						|
                /* save last pkt sidelobe */
 | 
						|
                os_mem_cpy(sidelobe_buf,
 | 
						|
                    csi_buf + (IOT_PHY_CSI_BUF_LEN >> 2)
 | 
						|
                        - (PHY_CHN_EST_AI_SIDELOBE_NUM << 1),
 | 
						|
                    PHY_CHN_EST_AI_SIDELOBE_NUM << 3);
 | 
						|
            }
 | 
						|
 | 
						|
            /* record successful dump cnt */
 | 
						|
            if (ret == ERR_OK) {
 | 
						|
                success_cnt++;
 | 
						|
            }
 | 
						|
 | 
						|
            /* check timeout */
 | 
						|
            end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
 | 
						|
            /* cal span time */
 | 
						|
            time_span = end_time - start_time;
 | 
						|
            if (time_span < 0) { // wrap around
 | 
						|
                time_span = (0x100000000LL) - start_time + end_time;
 | 
						|
            }
 | 
						|
 | 
						|
            /* break if timeout */
 | 
						|
            if (time_span >= timeout_ms * NTB_TICKS_PER_MS) {
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
#if PHY_DEBUG_EN
 | 
						|
        uint32_t spur_buf_size1 = PHY_CHN_EST_AI_SPUR_LEN/sizeof(iot_phy_spur_t);
 | 
						|
        for (i = 0; i < spur_buf_size1; i++) {
 | 
						|
            iot_printf("B tone:%d, spur_cnt:%d, ratio:%d, notch_cnt:%d\n",
 | 
						|
                spur_buf[i].tone_id, spur_buf[i].spur_cnt,
 | 
						|
                spur_buf[i].spur_ratio, spur_buf[i].notch_filter_en_cnt);
 | 
						|
        }
 | 
						|
#endif
 | 
						|
        /* get peak point */
 | 
						|
        phy_spur_arry_peak_handler(spur_buf, PHY_CHN_EST_AI_SPUR_LEN, est_rty_cnt);
 | 
						|
    }
 | 
						|
    else{
 | 
						|
        iot_printf("csi buf pointer get fail from iot_pkt!\n");
 | 
						|
    }
 | 
						|
    /* free iot pkt */
 | 
						|
    iot_pkt_free(pkt_buf);
 | 
						|
    iot_pkt_free(hash_buf);
 | 
						|
 | 
						|
    /* get end time */
 | 
						|
    end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | 
						|
 | 
						|
    /* cal span time */
 | 
						|
    time_span = end_time - start_time;
 | 
						|
    if (time_span < 0) { // wrap around
 | 
						|
        time_span = (0x100000000LL) - start_time + end_time;
 | 
						|
    }
 | 
						|
 | 
						|
    /* clear dump flag */
 | 
						|
    phy_dump_busy_set(false);
 | 
						|
 | 
						|
    /* for kl3 */
 | 
						|
    phy_increase_tgt_pwr(g_phy_cpu_share_ctxt.spur_exist);
 | 
						|
 | 
						|
    iot_printf("start_time:%u, end time:%u, bbai success cnt:%d\n",
 | 
						|
        start_time, end_time, success_cnt);
 | 
						|
#else
 | 
						|
    (void)est_rty_cnt;
 | 
						|
    (void)timeout_ms;
 | 
						|
#endif
 | 
						|
    return success_cnt;
 | 
						|
}
 | 
						|
 | 
						|
#endif /* PHY_BBAI_ALGORITHM == PHY_BBAI_FIX_WINDOWS */
 |