250 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			250 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/****************************************************************************
 | 
						|
 | 
						|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
 | 
						|
 | 
						|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
 | 
						|
be copied by any method or incorporated into another program without
 | 
						|
the express written consent of Aerospace C.Power. This Information or any portion
 | 
						|
thereof remains the property of Aerospace C.Power. The Information contained herein
 | 
						|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
 | 
						|
liability for its use in any way and conveys no license or title under
 | 
						|
any patent or copyright and makes no representation or warranty that this
 | 
						|
Information is free from patent or copyright infringement.
 | 
						|
 | 
						|
****************************************************************************/
 | 
						|
 | 
						|
#include "os_types.h"
 | 
						|
#include "hw_reg_api.h"
 | 
						|
#include "phy_test_api.h"
 | 
						|
#include "phy_cal.h"
 | 
						|
#include "phy_bb.h"
 | 
						|
#include "phy_phase.h"
 | 
						|
#include "phy_ana_glb.h"
 | 
						|
#include "granite_reg.h"
 | 
						|
#include "phy_rxtd_reg.h"
 | 
						|
#include "phy_rx_fd_reg.h"
 | 
						|
#include "phy_dfe_reg.h"
 | 
						|
#include "mac_sys_reg.h"
 | 
						|
#include "iot_io.h"
 | 
						|
#include "iot_config.h"
 | 
						|
#include "iot_errno.h"
 | 
						|
#include "ahb.h"
 | 
						|
#include "phy_ana.h"
 | 
						|
#include "phy_tools.h"
 | 
						|
#include "hw_tonemask.h"
 | 
						|
 | 
						|
void phy_rx_loopback()
 | 
						|
{
 | 
						|
    uint32_t tmp = 0;
 | 
						|
    uint32_t tone_idx = 0;
 | 
						|
    uint32_t fft_loop = 1;
 | 
						|
    int16_t csi_i = 0, csi_q = 0;
 | 
						|
    uint32_t *csi_buf = (uint32_t *)BB_CSI_BASEADDR;
 | 
						|
 | 
						|
    /* config det tone */
 | 
						|
    phy_rxfd_rate0_det(0, 1535);
 | 
						|
    phy_rxfd_rate1_det(0, 1535);
 | 
						|
 | 
						|
#if IOT_DTEST_ONLY_SUPPORT == 1
 | 
						|
    /* tone 3M  */
 | 
						|
    phy_dfe_tone_cfg(1,41,0);
 | 
						|
    /* att */
 | 
						|
    phy_dfe_tone_att_cfg(0,3,3);
 | 
						|
#endif
 | 
						|
 | 
						|
    /* enable ana loopback */
 | 
						|
    phy_txrx_loop_back_begin(0,TXRX_LOOP_BACK_GRANITE);
 | 
						|
 | 
						|
    /* trig fft */
 | 
						|
    tmp = PHY_DFE_READ_REG(CFG_BB_LOOPBACK_TEST_CFG_ADDR);
 | 
						|
    REG_FIELD_SET(SW_LOOP_FFT_CYCLE, tmp, fft_loop);
 | 
						|
    REG_FIELD_SET(SW_LOOP_FFT_START, tmp, 1);
 | 
						|
    PHY_DFE_WRITE_REG(CFG_BB_LOOPBACK_TEST_CFG_ADDR, tmp);
 | 
						|
 | 
						|
    /* wait fft done */
 | 
						|
    do{
 | 
						|
        tmp = PHY_DFE_READ_REG(CFG_BB_LOOPBACK_TEST_CFG_ADDR);
 | 
						|
    }while(!REG_FIELD_GET(LOOP_FFT_DONE, tmp));
 | 
						|
 | 
						|
    /* enable sw csi buf access */
 | 
						|
    enable_sw_access_csi_buf(1);
 | 
						|
 | 
						|
    iot_printf("[dump]\r\n");
 | 
						|
    /* cal csi for every tone */
 | 
						|
    for(tone_idx = 0; tone_idx < TONE_MAX_NUM; tone_idx++)
 | 
						|
    {
 | 
						|
        csi_i = (int16_t)(*csi_buf & 0xFFFF);
 | 
						|
        csi_q = (int16_t)(*csi_buf >> 16);
 | 
						|
#if IOT_DTEST_ONLY_SUPPORT == 0
 | 
						|
        iot_printf("%d,%d,%d\r\n", tone_idx, csi_i, csi_q);
 | 
						|
#else
 | 
						|
        iot_printf("csi power tone,i,q=%d,%d,%d\r\n", \
 | 
						|
                    tone_idx,csi_i, csi_q);
 | 
						|
#endif
 | 
						|
        csi_buf++;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_printf("[end]\r\n");
 | 
						|
    /* enable sw csi buf access */
 | 
						|
    enable_sw_access_csi_buf(0);
 | 
						|
 | 
						|
    /* recover to the state set in ana loopback */
 | 
						|
    phy_txrx_loop_back_end();
 | 
						|
 | 
						|
    /* update the precise det range */
 | 
						|
    phy_rxfd_rate0_det(all_mask_band_table_r0_full.start_tone, \
 | 
						|
        all_mask_band_table_r0_full.end_tone);
 | 
						|
    phy_rxfd_rate1_det(all_mask_band_table_r1_full.start_tone, \
 | 
						|
        all_mask_band_table_r1_full.end_tone);
 | 
						|
}
 | 
						|
 | 
						|
uint32_t phy_info_cnt_cal(mac_rx_phy_info_t *phy_info_ptr)
 | 
						|
{
 | 
						|
    uint32_t ret = ERR_OK;
 | 
						|
 | 
						|
    if( phy_info_ptr->retry_num == 0)
 | 
						|
    {
 | 
						|
        if(phy_info_ptr->gain >= PHY_AGC_NB_GAIN_ENTRY_START) {
 | 
						|
            phy_info_ptr->rssi = phy_info_ptr->rmi - \
 | 
						|
                (phy_info_ptr->gain - \
 | 
						|
                    PHY_AGC_NB_GAIN_ENTRY_START - PHY_AGC_GAIN_ENTRY_OFFSET);
 | 
						|
            phy_info_ptr->gain -= PHY_AGC_NB_GAIN_ENTRY_START;
 | 
						|
        } else {
 | 
						|
            phy_info_ptr->rssi = phy_info_ptr->rmi - \
 | 
						|
                (phy_info_ptr->gain - PHY_AGC_GAIN_ENTRY_OFFSET);
 | 
						|
        }
 | 
						|
        phy_info_ptr->gain_max = phy_info_ptr->gain;
 | 
						|
        phy_info_ptr->rssi_max = phy_info_ptr->rssi;
 | 
						|
        phy_info_ptr->rmi_max = phy_info_ptr->rmi;
 | 
						|
        phy_info_ptr->dc_max = phy_info_ptr->est_dc;
 | 
						|
        phy_info_ptr->ppm_max = phy_info_ptr->est_ppm;
 | 
						|
        phy_info_ptr->snr_max = phy_info_ptr->avr_snr;
 | 
						|
        phy_info_ptr->gain_min = phy_info_ptr->gain;
 | 
						|
        phy_info_ptr->rssi_min = phy_info_ptr->rssi;
 | 
						|
        phy_info_ptr->rmi_min = phy_info_ptr->rmi;
 | 
						|
        phy_info_ptr->dc_min = phy_info_ptr->est_dc;
 | 
						|
        phy_info_ptr->ppm_min = phy_info_ptr->est_ppm;
 | 
						|
        phy_info_ptr->snr_min = phy_info_ptr->avr_snr;
 | 
						|
        phy_info_ptr->gain_avg = phy_info_ptr->gain;
 | 
						|
        phy_info_ptr->rssi_avg = phy_info_ptr->rssi;
 | 
						|
        phy_info_ptr->rmi_avg = phy_info_ptr->rmi;
 | 
						|
        phy_info_ptr->dc_avg = phy_info_ptr->est_dc;
 | 
						|
        phy_info_ptr->ppm_avg = phy_info_ptr->est_ppm;
 | 
						|
        phy_info_ptr->snr_avg = phy_info_ptr->avr_snr;
 | 
						|
    }
 | 
						|
    else{
 | 
						|
        if(phy_info_ptr->gain >= PHY_AGC_NB_GAIN_ENTRY_START) {
 | 
						|
            phy_info_ptr->rssi = phy_info_ptr->rmi - \
 | 
						|
                (phy_info_ptr->gain - \
 | 
						|
                    PHY_AGC_NB_GAIN_ENTRY_START - PHY_AGC_GAIN_ENTRY_OFFSET);
 | 
						|
            phy_info_ptr->gain -= PHY_AGC_NB_GAIN_ENTRY_START;
 | 
						|
        } else {
 | 
						|
            phy_info_ptr->rssi = phy_info_ptr->rmi - \
 | 
						|
                (phy_info_ptr->gain - PHY_AGC_GAIN_ENTRY_OFFSET);
 | 
						|
        }
 | 
						|
        phy_info_ptr->gain_avg += phy_info_ptr->gain;
 | 
						|
        phy_info_ptr->rmi_avg += phy_info_ptr->rmi;
 | 
						|
        phy_info_ptr->rssi_avg += phy_info_ptr->rssi;
 | 
						|
        phy_info_ptr->dc_avg += phy_info_ptr->est_dc;
 | 
						|
        phy_info_ptr->ppm_avg += phy_info_ptr->est_ppm;
 | 
						|
        phy_info_ptr->snr_avg += phy_info_ptr->avr_snr;
 | 
						|
 | 
						|
        /* update max value */
 | 
						|
        phy_info_ptr->gain_max = \
 | 
						|
            MATH_MAX(phy_info_ptr->gain_max,phy_info_ptr->gain);
 | 
						|
        phy_info_ptr->rssi_max = \
 | 
						|
            MATH_MAX(phy_info_ptr->rssi_max,phy_info_ptr->rssi);
 | 
						|
        phy_info_ptr->rmi_max = \
 | 
						|
            MATH_MAX(phy_info_ptr->rmi_max,phy_info_ptr->rmi);
 | 
						|
        phy_info_ptr->dc_max = \
 | 
						|
            MATH_MAX(phy_info_ptr->dc_max,phy_info_ptr->est_dc);
 | 
						|
        phy_info_ptr->ppm_max = \
 | 
						|
            MATH_MAX(phy_info_ptr->ppm_max,phy_info_ptr->est_ppm);
 | 
						|
        phy_info_ptr->snr_max = \
 | 
						|
            MATH_MAX(phy_info_ptr->snr_max,phy_info_ptr->avr_snr);
 | 
						|
        /* update min value */
 | 
						|
        phy_info_ptr->gain_min = \
 | 
						|
            MATH_MIN(phy_info_ptr->gain_min,phy_info_ptr->gain);
 | 
						|
        phy_info_ptr->rssi_min = \
 | 
						|
            MATH_MIN(phy_info_ptr->rssi_min,phy_info_ptr->rssi);
 | 
						|
        phy_info_ptr->rmi_min = \
 | 
						|
            MATH_MIN(phy_info_ptr->rmi_min,phy_info_ptr->rmi);
 | 
						|
        phy_info_ptr->dc_min = \
 | 
						|
            MATH_MIN(phy_info_ptr->dc_min,phy_info_ptr->est_dc);
 | 
						|
        phy_info_ptr->ppm_min = \
 | 
						|
            MATH_MIN(phy_info_ptr->ppm_min,phy_info_ptr->est_ppm);
 | 
						|
        phy_info_ptr->snr_min = \
 | 
						|
            MATH_MIN(phy_info_ptr->snr_min,phy_info_ptr->avr_snr);
 | 
						|
    }
 | 
						|
    phy_info_ptr->retry_num++;
 | 
						|
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
uint32_t phy_info_cnt_print(mac_rx_phy_info_t *phy_info_ptr)
 | 
						|
{
 | 
						|
    uint32_t ret = ERR_OK;
 | 
						|
 | 
						|
    phy_info_ptr->gain_avg = \
 | 
						|
        phy_info_ptr->gain_avg/phy_info_ptr->retry_num;
 | 
						|
    phy_info_ptr->rmi_avg = \
 | 
						|
        phy_info_ptr->rmi_avg/phy_info_ptr->retry_num;
 | 
						|
    phy_info_ptr->rssi_avg = \
 | 
						|
        phy_info_ptr->rssi_avg/phy_info_ptr->retry_num;
 | 
						|
    phy_info_ptr->dc_avg = \
 | 
						|
        phy_info_ptr->dc_avg/phy_info_ptr->retry_num;
 | 
						|
    phy_info_ptr->ppm_avg = \
 | 
						|
        phy_info_ptr->ppm_avg/phy_info_ptr->retry_num;
 | 
						|
    phy_info_ptr->snr_avg = \
 | 
						|
        phy_info_ptr->snr_avg/phy_info_ptr->retry_num;
 | 
						|
 | 
						|
    phy_info_ptr->est_dc = phy_info_ptr->est_dc & 0x1F;
 | 
						|
    if(phy_info_ptr->est_dc & 0x10){
 | 
						|
        phy_info_ptr->est_dc = (phy_info_ptr->est_dc & 0xF) - 16;
 | 
						|
    }
 | 
						|
    if(phy_info_ptr->gain >= PHY_AGC_NB_GAIN_ENTRY_START) {
 | 
						|
        iot_printf("[PHY]gain_avg:%hd, gain_max:%hd, gain_min:%hd (=dB)\r\n", \
 | 
						|
                    phy_info_ptr->gain_avg - \
 | 
						|
                    PHY_AGC_GAIN_ENTRY_OFFSET - PHY_AGC_NB_GAIN_ENTRY_START, \
 | 
						|
                    phy_info_ptr->gain_max - \
 | 
						|
                    PHY_AGC_GAIN_ENTRY_OFFSET - PHY_AGC_NB_GAIN_ENTRY_START, \
 | 
						|
                    phy_info_ptr->gain_min - \
 | 
						|
                    PHY_AGC_GAIN_ENTRY_OFFSET - PHY_AGC_NB_GAIN_ENTRY_START);
 | 
						|
    } else {
 | 
						|
        iot_printf("[PHY]gain_avg:%hd, gain_max:%hd, gain_min:%hd (=dB)\r\n", \
 | 
						|
                    phy_info_ptr->gain_avg-PHY_AGC_GAIN_ENTRY_OFFSET, \
 | 
						|
                    phy_info_ptr->gain_max-PHY_AGC_GAIN_ENTRY_OFFSET, \
 | 
						|
                    phy_info_ptr->gain_min-PHY_AGC_GAIN_ENTRY_OFFSET);
 | 
						|
    }
 | 
						|
    iot_printf("adc_pwr:%hd, adc_pwr_max:%hd, adc_pwr_min:%hd (-120=dBFS)\r\n", \
 | 
						|
                phy_info_ptr->rmi_avg, \
 | 
						|
                phy_info_ptr->rmi_max, \
 | 
						|
                phy_info_ptr->rmi_min);
 | 
						|
    iot_printf("rssi_avg:%hd, rssi_max:%hd, rssi_min:%hd (-3=dBuV)\r\n", \
 | 
						|
                phy_info_ptr->rssi_avg, \
 | 
						|
                phy_info_ptr->rssi_max, \
 | 
						|
                phy_info_ptr->rssi_min);
 | 
						|
    iot_printf("dc_avg:%hd, dc_max:%hd, dc_min:%hd (*1.4=mV)\r\n", \
 | 
						|
                phy_info_ptr->dc_avg, \
 | 
						|
                phy_info_ptr->dc_max, \
 | 
						|
                phy_info_ptr->dc_min);
 | 
						|
    iot_printf("ppm_avg:%hd, ppm_max:%hd, ppm_min:%hd\r\n",\
 | 
						|
                phy_info_ptr->ppm_avg, \
 | 
						|
                phy_info_ptr->ppm_max, \
 | 
						|
                phy_info_ptr->ppm_min);
 | 
						|
    iot_printf("snr_avg:%hd, snr_max:%hd, snr_min:%hd (=dB)\r\n", \
 | 
						|
                phy_info_ptr->snr_avg*3/4, \
 | 
						|
                phy_info_ptr->snr_max*3/4, \
 | 
						|
                phy_info_ptr->snr_min*3/4);
 | 
						|
 | 
						|
    /* clear phy info */
 | 
						|
    uint8_t *tp = (uint8_t *)phy_info_ptr;
 | 
						|
    for(uint8_t in = 0; in < sizeof(mac_rx_phy_info_t); in++)
 | 
						|
    {
 | 
						|
        *tp++ = 0x0;
 | 
						|
    }
 | 
						|
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 |