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;
|
|
}
|
|
|