655 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			655 lines
		
	
	
		
			21 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 "chip_reg_base.h"
 | |
| #include "iot_config.h"
 | |
| #include "iot_errno_api.h"
 | |
| #include "hw_reg_api.h"
 | |
| #include "hw_phy_api.h"
 | |
| #include "phy_perf.h"
 | |
| 
 | |
| #include "math_log10.h"
 | |
| #include "phy_cal.h"
 | |
| #include "hw_tonemask.h"
 | |
| #include "phy_data.h"
 | |
| #include "phy_math_tb.h"
 | |
| #include "phy_nf.h"
 | |
| #include "phy_ana.h"
 | |
| #include "phy_chn.h"
 | |
| #include "phy_txrx_pwr.h"
 | |
| 
 | |
| #include "mac_sys_reg.h"
 | |
| #include "phy_dfe_reg.h"
 | |
| #include "phy_rxtd_reg.h"
 | |
| #include "phy_rx_fd_reg.h"
 | |
| #include "phy_tx_reg.h"
 | |
| #include "phy_reg.h"
 | |
| #include "ahb.h"
 | |
| #include "phy_rxtd_reg.h"
 | |
| #include "granite_reg.h"
 | |
| 
 | |
| #include "iot_io.h"
 | |
| #include "iot_utils_api.h"
 | |
| #include "iot_share_task.h"
 | |
| #include "iot_module_api.h"
 | |
| #include "iot_pkt_api.h"
 | |
| #include "iot_system.h"
 | |
| 
 | |
| #include "plc_mpdu_header.h"
 | |
| #include "plc_protocol.h"
 | |
| #include "plc_const.h"
 | |
| #include "phy_dfe_reg.h"
 | |
| #include "phy_nf.h"
 | |
| 
 | |
| void phy_anti_spur_set(int8_t bw_id)
 | |
| {
 | |
| #if HW_PLATFORM >= HW_PLATFORM_FPGA
 | |
|     uint8_t tgt_pwr = 0;
 | |
|     uint8_t low = 0, hi = 0;
 | |
| 
 | |
|     /* tgt power = 110 */
 | |
|     phy_agc_rcv_tgt_get(&tgt_pwr, &low, &hi);
 | |
| #if PHY_BB_AI_WITH_PULSE_CHECK_EN
 | |
|     /* Disable AGC satuation */
 | |
|     phy_agc_sat_adj_set(1, 0);
 | |
|     phy_agc_rcv_tgt_set(113, low, hi);
 | |
| #else
 | |
|     phy_agc_rcv_tgt_set(110, low, hi);
 | |
| #endif
 | |
| 
 | |
|     if(bw_id == IOT_SUPPORT_TONE_80_490) { /* band0  80-490,  1M/8M/15M spurs exist */
 | |
|         /* mask 1M spur by notch filter */
 | |
|         phy_anf_option_set(PHY_ANF_MODE_FIX,1,1,0x8073);
 | |
|         /* mask 8M spur by notch filter */
 | |
|         phy_anf_option_set(PHY_ANF_MODE_FIX,1,2,0x9bb0);
 | |
|         /* mask 8M spur by spur mask, [-15,15] */
 | |
|         phy_spur_mask_set(328,30);
 | |
|     } else if (bw_id == IOT_SUPPORT_TONE_100_230) { /* band1 100-230, 1M/3M/6M spurs exist */
 | |
|         /* mask 3M spur by notch filter */
 | |
|         phy_anf_option_set(PHY_ANF_MODE_FIX,1,1,0x8405);
 | |
|         /* mask 6M spur by notch filter */
 | |
|         phy_anf_option_set(PHY_ANF_MODE_FIX,1,2,0x8fd5);
 | |
|         /* mask 3M spur by spur mask, [-7,7] */
 | |
|         phy_spur_mask_set(123,15);
 | |
|     } else if (bw_id == IOT_SUPPORT_TONE_32_120 || \
 | |
|         bw_id == IOT_SUPPORT_TONE_72_120) {
 | |
|         /* mask 500K spur by notch filter */
 | |
|         phy_anf_option_set(PHY_ANF_MODE_FIX,1,1,0x801c);
 | |
|         /* mask 2M spur by notch filter */
 | |
|         phy_anf_option_set(PHY_ANF_MODE_FIX,1,2,0x81ca);
 | |
|         /* mask 2M spur by spur mask, [-7,7] */
 | |
|         phy_spur_mask_set(82,15);
 | |
|     }
 | |
| #else
 | |
|     (void)bw_id;
 | |
| #endif
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| void phy_anti_spur_set_clr()
 | |
| {
 | |
| #if HW_PLATFORM >= HW_PLATFORM_FPGA
 | |
|     uint8_t tgt_pwr = 0;
 | |
|     uint8_t low = 0, hi = 0;
 | |
| 
 | |
|     /* tgt power = 100 */
 | |
|     phy_agc_rcv_tgt_get(&tgt_pwr, &low, &hi);
 | |
|     phy_agc_rcv_tgt_set(phy_rx_tgt_pwr_get(), low, hi);
 | |
| 
 | |
|     /* clr 1M spur by notch filter */
 | |
|     phy_anf_option_set(PHY_ANF_MODE_BYPASS,0,0,0);
 | |
|     /* clr 8M spur by spur mask, [-15,15] */
 | |
|     phy_spur_mask_clr(328,30);
 | |
|     /* clr 3M spur by spur mask, [-7,7] */
 | |
|     phy_spur_mask_clr(123,15);
 | |
|     /* clr 2M spur by spur mask, [-7,7] */
 | |
|     phy_spur_mask_clr(82,15);
 | |
| #endif
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| void phy_anti_pulse_set()
 | |
| {
 | |
| #if HW_PLATFORM >= HW_PLATFORM_FPGA
 | |
|     uint32_t tmp;
 | |
|     uint32_t bw_id = phy_band_id_get();
 | |
| 
 | |
|     /* Loweer Packet detection threshold */
 | |
|     if(bw_id != IOT_SUPPORT_TONE_72_120 && \
 | |
|         bw_id != IOT_SUPPORT_TONE_32_120) {
 | |
|         phy_rxfd_pkt_det_thd_set(8,16);
 | |
|     }
 | |
| 
 | |
|     /* Fix gain to MAXA gain */
 | |
|     phy_agc_gain_lvl_set(1,60,-24,0);
 | |
| 
 | |
|     /* Bypass DC blocker */
 | |
|     tmp = PHY_DFE_READ_REG(CFG_BB_DC_BLK_STAGE_DLY_ADDR);
 | |
|     REG_FIELD_SET(SW_DC_BLK_BYPASS, tmp, 1);
 | |
|     PHY_DFE_WRITE_REG(CFG_BB_DC_BLK_STAGE_DLY_ADDR, tmp);
 | |
| 
 | |
|     /* Disable AGC satuation */
 | |
|     phy_agc_sat_adj_set(1, 0);
 | |
| 
 | |
| #if PHY_BB_AI_WITH_PULSE_CHECK_EN
 | |
|     /* clear shift en */
 | |
|     PHY_RXTD_WRITE_REG(CFG_BB_RXTD_SPARE2_ADDR, 0);
 | |
|     /* dly a cycle */
 | |
|     phy_rx_nf_by_rxtd_get(14);
 | |
|     /* clear shift */
 | |
|     phy_gain_shift_set(0,0,0,0);
 | |
| #endif
 | |
| #endif
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| void phy_anti_pulse_set_clr()
 | |
| {
 | |
| #if HW_PLATFORM >= HW_PLATFORM_FPGA
 | |
|     uint32_t tmp;
 | |
|     uint32_t bw_id = phy_band_id_get();
 | |
| 
 | |
|     /* Loweer Packet detection threshold */
 | |
|     if(bw_id != IOT_SUPPORT_TONE_72_120 && \
 | |
|         bw_id != IOT_SUPPORT_TONE_32_120) {
 | |
|         phy_rxfd_pkt_det_thd_set(16,32);
 | |
|     }
 | |
| 
 | |
|     /* free gain to MAXA gain */
 | |
|     phy_agc_gain_lvl_set(0,60,-24,0);
 | |
| 
 | |
|     /* enable DC blocker */
 | |
|     tmp = PHY_DFE_READ_REG(CFG_BB_DC_BLK_STAGE_DLY_ADDR);
 | |
|     REG_FIELD_SET(SW_DC_BLK_BYPASS, tmp, 0);
 | |
|     PHY_DFE_WRITE_REG(CFG_BB_DC_BLK_STAGE_DLY_ADDR, tmp);
 | |
| 
 | |
|     /* enable AGC satuation */
 | |
|     phy_agc_sat_adj_set(0, 0);
 | |
| #endif
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| void phy_perf_common_init(void)
 | |
| {
 | |
|     uint32_t range_id = IOT_PLC_PHY_BAND_RANGE_DFT;
 | |
|     uint32_t band_id = phy_band_id_get();
 | |
| 
 | |
|     /* bypass anf 1 */
 | |
|     phy_anf_option_set(PHY_ANF_MODE_BYPASS, 0, 2, 0);
 | |
| 
 | |
|     /* notch filter 1.8M */
 | |
|     if(range_id == IOT_SUPPORT_PROTO_SG_NSG_BAND && \
 | |
|         band_id == IOT_SUPPORT_TONE_32_120) {
 | |
|         /* use external gain table */
 | |
|         phy_gain_table_ovr_set(1,1);
 | |
|         phy_anf_option_set(PHY_ANF_MODE_BYPASS,0,0,0);
 | |
|     } else if(range_id == IOT_SUPPORT_PROTO_SG_NSG_BAND && \
 | |
|         band_id == IOT_SUPPORT_TONE_72_120) {
 | |
|         phy_gain_table_ovr_set(0,0);
 | |
|         phy_anf_sel_set(0);
 | |
|         phy_anf_option_set(PHY_ANF_MODE_BYPASS,0,0,0);
 | |
|     } else {
 | |
|         phy_gain_table_ovr_set(0,0);
 | |
|         phy_anf_sel_set(0);
 | |
|         phy_anf_option_set(PHY_ANF_MODE_FIX,1,1,0x8174);
 | |
|     }
 | |
| 
 | |
|     /* bypass fnf */
 | |
|     phy_fnf_option_set(PHY_FNF_MODE_BYPASS, 0, 0);
 | |
|     phy_fnf_sel_set(1, 2);
 | |
|     phy_fnf_sel_set(2, 2);
 | |
| }
 | |
| 
 | |
| uint32_t phy_chn_est_cb(uint32_t band_id, void *chn_ptr)
 | |
| {
 | |
|     uint32_t ret = ERR_OK;
 | |
| #if HW_PLATFORM >= HW_PLATFORM_FPGA
 | |
|     uint32_t tone_idx = 0;
 | |
|     uint32_t start_time = 0, end_time = 0;
 | |
|     uint64_t time_span = 0;
 | |
|     int16_t csi_i = 0, csi_q = 0;
 | |
| #if PHY_BB_AI_WITH_PULSE_CHECK_EN == 0
 | |
|     uint32_t center_pwr_8m = 0, ext_pwr_8m = 0;
 | |
|     uint32_t center_pwr_3m = 0, ext_pwr_3m = 0;
 | |
|     uint32_t center_pwr_2m = 0, ext_pwr_2m = 0;
 | |
| #endif
 | |
| #if PHY_BB_AI_WITH_PULSE_CHECK_EN == 0
 | |
|     static uint8_t spur_8m_cnt = 0, spur_3m_cnt =0, \
 | |
|         spur_2m_cnt =0;
 | |
| #endif
 | |
|     iot_pkt_t *pkt_buf = NULL;
 | |
|     uint32_t *csi_buf = NULL;
 | |
|     phy_chn_est_t *chn_est = (phy_chn_est_t *)chn_ptr;
 | |
| 
 | |
|     /* get start time */
 | |
|     start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
 | |
| 
 | |
|     /* return if one scenario flag set */
 | |
|     if(chn_est->spur_8m_done_flag | \
 | |
|         chn_est->spur_3m_done_flag | \
 | |
|         chn_est->spur_2m_done_flag | \
 | |
|         chn_est->pulse_done_flag) {
 | |
|         iot_printf("phy cert flag:%x checked!\n", \
 | |
|             chn_est->spur_8m_done_flag | \
 | |
|             (chn_est->spur_3m_done_flag << 1) | \
 | |
|             (chn_est->spur_2m_done_flag << 2) | \
 | |
|             (chn_est->pulse_done_flag << 3));
 | |
|         return ret;
 | |
|     }
 | |
| 
 | |
|     /* 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");
 | |
|         return ret;
 | |
|     }
 | |
|     csi_buf = (uint32_t *)iot_pkt_put(pkt_buf, IOT_PHY_CSI_BUF_LEN);
 | |
| 
 | |
|     /* check csi buf pointer valid and flag */
 | |
|     if(csi_buf != NULL) {
 | |
|         /* rst to trig enable */
 | |
|         phy_reset(PHY_RST_REASON_WARM);
 | |
| 
 | |
|         /* trig fft to dump */
 | |
|         phy_rx_fft_dump(csi_buf, 0, 0, 1);
 | |
| 
 | |
| #if PHY_DEBUG_EN
 | |
|         /* cal csi for every tone for debug*/
 | |
|         for(tone_idx = 0; tone_idx < IOT_PHY_CSI_BUF_LEN/4; tone_idx++)
 | |
|         {
 | |
|             csi_i = (int16_t)(*(csi_buf + tone_idx) & 0xFFFF);
 | |
|             csi_q = (int16_t)(*(csi_buf + tone_idx) >> 16);
 | |
|             iot_printf("csi_i:%d, csi_q:%d, dB:%u\n", \
 | |
|                 csi_i, \
 | |
|                 csi_q, \
 | |
|                 (uint32_t)(10 * mlog10(csi_i * csi_i + csi_q * csi_q + 1)));
 | |
|         }
 | |
| #endif
 | |
| 
 | |
| #if PHY_BB_AI_WITH_PULSE_CHECK_EN == 0
 | |
|         /* spur check */
 | |
|         if(!chn_est->spur_8m_done_flag && \
 | |
|             !chn_est->spur_3m_done_flag && \
 | |
|             !chn_est->spur_2m_done_flag) {
 | |
|             if(band_id == IOT_SUPPORT_TONE_80_490) {
 | |
|                 /* spur: scan 8M with 32 point */
 | |
|                 for(tone_idx = IOT_SPUR_8M_CENTER_TONE - 16; \
 | |
|                     tone_idx <= IOT_SPUR_8M_CENTER_TONE + 16; tone_idx++)
 | |
|                 {
 | |
|                     csi_i = (int16_t)(*(csi_buf + tone_idx) & 0xFFFF);
 | |
|                     csi_q = (int16_t)(*(csi_buf + tone_idx) >> 16);
 | |
| 
 | |
|                     if(tone_idx > (IOT_SPUR_8M_CENTER_TONE - 8) && \
 | |
|                         tone_idx <= (IOT_SPUR_8M_CENTER_TONE + 8)) {
 | |
|                         center_pwr_8m += csi_i * csi_i + csi_q * csi_q;
 | |
|                     } else {
 | |
|                         ext_pwr_8m += csi_i * csi_i + csi_q * csi_q;
 | |
|                     }
 | |
|                 }
 | |
|                 iot_printf("center_pwr_8m:%u, ext_pwr_8m:%u\n", \
 | |
|                     center_pwr_8m, ext_pwr_8m);
 | |
| 
 | |
|                 /* compare 8M thd */
 | |
|                 if(center_pwr_8m/ext_pwr_8m > IOT_SPUR_8M_CMP_THD) {
 | |
|                     spur_8m_cnt++;
 | |
| 
 | |
|                     if(spur_8m_cnt >= 2) {
 | |
|                         phy_anti_spur_set(band_id);
 | |
|                         iot_printf("band %u phy_anti_spur_set done!\n", \
 | |
|                             band_id);
 | |
|                         spur_8m_cnt = 0;
 | |
|                         chn_est->spur_8m_done_flag = 1;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 /* spur: scan 3M with 32 point */
 | |
|                 for(tone_idx = IOT_SPUR_3M_CENTER_TONE - 16; \
 | |
|                     tone_idx <= IOT_SPUR_3M_CENTER_TONE + 16; tone_idx++)
 | |
|                 {
 | |
|                     csi_i = (int16_t)(*(csi_buf + tone_idx) & 0xFFFF);
 | |
|                     csi_q = (int16_t)(*(csi_buf + tone_idx) >> 16);
 | |
| 
 | |
|                     if(tone_idx > (IOT_SPUR_3M_CENTER_TONE - 8) && \
 | |
|                         tone_idx <= (IOT_SPUR_3M_CENTER_TONE + 8)) {
 | |
|                         center_pwr_3m += csi_i * csi_i + csi_q * csi_q;
 | |
|                     } else {
 | |
|                         ext_pwr_3m += csi_i * csi_i + csi_q * csi_q;
 | |
|                     }
 | |
|                 }
 | |
|                 iot_printf("center_pwr_3m:%u, ext_pwr_3m:%u\n", \
 | |
|                     center_pwr_3m, ext_pwr_3m);
 | |
| 
 | |
|                 /* compare 3M thd */
 | |
|                 if(center_pwr_3m/ext_pwr_3m > IOT_SPUR_3M_CMP_THD) {
 | |
|                     //mask 3M spur by notch filter
 | |
|                     phy_anf_option_set(PHY_ANF_MODE_FIX,1,1,0x8405);
 | |
|                     //mask 3M spur by spur mask, [-7,7]
 | |
|                     phy_spur_mask_set(123,15);
 | |
|                     iot_printf("band %u phy 3M att done!\n", band_id);
 | |
|                 }
 | |
|             } else if(band_id == IOT_SUPPORT_TONE_100_230) {
 | |
|                 /* spur: scan 3M with 32 point */
 | |
|                 for(tone_idx = IOT_SPUR_3M_CENTER_TONE - 16; \
 | |
|                     tone_idx <= IOT_SPUR_3M_CENTER_TONE + 16; tone_idx++)
 | |
|                 {
 | |
|                     csi_i = (int16_t)(*(csi_buf + tone_idx) & 0xFFFF);
 | |
|                     csi_q = (int16_t)(*(csi_buf + tone_idx) >> 16);
 | |
| 
 | |
|                     if(tone_idx > (IOT_SPUR_3M_CENTER_TONE - 8) && \
 | |
|                         tone_idx <= (IOT_SPUR_3M_CENTER_TONE + 8)) {
 | |
|                         center_pwr_3m += csi_i * csi_i + csi_q * csi_q;
 | |
|                     } else {
 | |
|                         ext_pwr_3m += csi_i * csi_i + csi_q * csi_q;
 | |
|                     }
 | |
|                 }
 | |
|                 iot_printf("center_pwr_3m:%u, ext_pwr_3m:%u\n", \
 | |
|                     center_pwr_3m, ext_pwr_3m);
 | |
| 
 | |
|                 /* compare 3M thd */
 | |
|                 if(center_pwr_3m/ext_pwr_3m > IOT_SPUR_3M_CMP_THD) {
 | |
|                     spur_3m_cnt++;
 | |
| 
 | |
|                     if(spur_3m_cnt >= 2) {
 | |
|                         phy_anti_spur_set(band_id);
 | |
|                         iot_printf("band %u phy_anti_spur_set done!\n", \
 | |
|                             band_id);
 | |
|                         spur_3m_cnt = 0;
 | |
|                         chn_est->spur_3m_done_flag = 1;
 | |
|                     }
 | |
|                 }
 | |
|             } else if(band_id == IOT_SUPPORT_TONE_32_120 || \
 | |
|                 band_id == IOT_SUPPORT_TONE_72_120) {
 | |
|                 /* spur: scan 2M with 32 point */
 | |
|                 for(tone_idx = IOT_SPUR_2M_CENTER_TONE - 16; \
 | |
|                     tone_idx <= IOT_SPUR_2M_CENTER_TONE + 16; tone_idx++)
 | |
|                 {
 | |
|                     csi_i = (int16_t)(*(csi_buf + tone_idx) & 0xFFFF);
 | |
|                     csi_q = (int16_t)(*(csi_buf + tone_idx) >> 16);
 | |
| 
 | |
|                     if(tone_idx > (IOT_SPUR_2M_CENTER_TONE - 8) && \
 | |
|                         tone_idx <= (IOT_SPUR_2M_CENTER_TONE + 8)) {
 | |
|                         center_pwr_2m += csi_i * csi_i + csi_q * csi_q;
 | |
|                     } else {
 | |
|                         ext_pwr_2m += csi_i * csi_i + csi_q * csi_q;
 | |
|                     }
 | |
|                 }
 | |
|                 iot_printf("center_pwr_2m:%u, ext_pwr_2m:%u\n", \
 | |
|                     center_pwr_2m, ext_pwr_2m);
 | |
| 
 | |
|                 /* compare 2M thd */
 | |
|                 if(center_pwr_2m/ext_pwr_2m > IOT_SPUR_2M_CMP_THD) {
 | |
|                     spur_2m_cnt++;
 | |
| 
 | |
|                     if(spur_2m_cnt >= 2) {
 | |
|                         phy_anti_spur_set(band_id);
 | |
|                         iot_printf("band %u phy_anti_spur_set done!\n", \
 | |
|                             band_id);
 | |
|                         spur_2m_cnt = 0;
 | |
|                         chn_est->spur_2m_done_flag = 1;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| #endif
 | |
|     } else {
 | |
|         iot_printf("csi buf pointer get fail from iot_pkt!\n");
 | |
|     }
 | |
| 
 | |
|     /* free iot pkt */
 | |
|     iot_pkt_free(pkt_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;
 | |
|     }
 | |
| 
 | |
|     iot_printf("start_time:%u, end time:%u, span:%llu=%llu us\n", \
 | |
|         start_time, end_time, time_span, (uint64_t)(time_span / 25));
 | |
| #else
 | |
|     (void)band_id;
 | |
|     (void)chn_ptr;
 | |
| #endif
 | |
| 
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| /* todo: pack ref info */
 | |
| void phy_chan_est_flag_clear(void)
 | |
| {
 | |
|     /* clear all channel est flag */
 | |
|     g_phy_ctxt.indep.chn_est.spur_8m_done_flag = 0;
 | |
|     g_phy_ctxt.indep.chn_est.spur_3m_done_flag = 0;
 | |
|     g_phy_ctxt.indep.chn_est.spur_2m_done_flag = 0;
 | |
|     g_phy_ctxt.indep.chn_est.pulse_done_flag = 0;
 | |
|     g_phy_ctxt.indep.chn_est.bcn_check_cnt = 0;
 | |
| }
 | |
| 
 | |
| uint32_t phy_chn_est_ai_period_ms_get(void)
 | |
| {
 | |
|     /* TODO: support more different clock sources */
 | |
|     return PHY_CHN_EST_AI_PERIOD_MS;
 | |
| }
 | |
| 
 | |
| void phy_chn_nf_update(uint8_t need_fix_gain)
 | |
| {
 | |
| #if HW_PLATFORM >= HW_PLATFORM_FPGA
 | |
|     uint32_t tmp = 0;
 | |
|     uint8_t origin_hs = 0;
 | |
|     uint8_t dly_exp = 0;
 | |
|     uint8_t tmp_nf_192p, tmp_nf_384p, tmp_nf_768p;
 | |
|     uint8_t tmp_nf_1536p, tmp_nf_3072p;
 | |
|     int8_t max_gain, min_gain, ini_gain;
 | |
|     uint8_t fix_gain_en;
 | |
| 
 | |
| #if PHY_HW_SPIKE_OPTIMIZATION
 | |
|     /* NOTE: KL2 before check nf, need trun off spike detection */
 | |
|     phy_spike_check_set(0xFF, 0, 3);
 | |
|     phy_impuse_cancel_set(0, 6, 14);
 | |
|     phy_hpf_set(1, 230);
 | |
|     phy_ana_set_filter_init(phy_band_id_get());
 | |
| #endif
 | |
| 
 | |
|     /* stop systick nf cal */
 | |
|     phy_cal_nf_systick_stop();
 | |
| 
 | |
|     if (need_fix_gain) {
 | |
|         tmp = PHY_RXTD_READ_REG(CFG_BB_AGC_GAIN_LEVEL_ADDR);
 | |
|         max_gain = (int8_t)REG_FIELD_GET(SW_MAX_GAIN, tmp);
 | |
|         min_gain = (int8_t)REG_FIELD_GET(SW_MIN_GAIN, tmp);
 | |
|         ini_gain = (int8_t)REG_FIELD_GET(SW_INI_GAIN, tmp);
 | |
|         fix_gain_en = REG_FIELD_GET(SW_FIX_GAIN_EN, tmp);
 | |
|         /* nf dump fix gain 0 */
 | |
|         phy_agc_gain_lvl_set(1, 0, -24,0);
 | |
|     }
 | |
|     /* 192 point */
 | |
|     tmp = PHY_RXTD_READ_REG(CFG_BB_AGC_ACC_STEP_ADDR);
 | |
|     /* backup hs */
 | |
|     origin_hs = (uint8_t)REG_FIELD_GET(SW_AGC_ACC_STEP_HS, tmp);
 | |
|     REG_FIELD_SET(SW_AGC_ACC_STEP_HS, tmp, PHY_AGC_ACC_STEP_192P);
 | |
|     PHY_RXTD_WRITE_REG(CFG_BB_AGC_ACC_STEP_ADDR, tmp);
 | |
|     dly_exp = phy_agc_acc_dly_get();
 | |
|     tmp_nf_192p = phy_rx_nf_by_rxtd_get(dly_exp);
 | |
|     if (tmp_nf_192p != PHY_NF_RST_VAL) {
 | |
|         g_phy_cpu_share_ctxt.nf_192p = tmp_nf_192p;
 | |
|     }
 | |
| 
 | |
|     /* 384 point */
 | |
|     REG_FIELD_SET(SW_AGC_ACC_STEP_HS, tmp, PHY_AGC_ACC_STEP_384P);
 | |
|     PHY_RXTD_WRITE_REG(CFG_BB_AGC_ACC_STEP_ADDR, tmp);
 | |
|     dly_exp = phy_agc_acc_dly_get();
 | |
|     tmp_nf_384p = phy_rx_nf_by_rxtd_get(dly_exp);
 | |
|     if (tmp_nf_384p != PHY_NF_RST_VAL) {
 | |
|         g_phy_cpu_share_ctxt.nf_384p = tmp_nf_384p;
 | |
|     }
 | |
| 
 | |
|     /* 768 point */
 | |
|     REG_FIELD_SET(SW_AGC_ACC_STEP_HS, tmp, PHY_AGC_ACC_STEP_768P);
 | |
|     PHY_RXTD_WRITE_REG(CFG_BB_AGC_ACC_STEP_ADDR, tmp);
 | |
|     dly_exp = phy_agc_acc_dly_get();
 | |
|     tmp_nf_768p = phy_rx_nf_by_rxtd_get(dly_exp);
 | |
|     if (tmp_nf_768p != PHY_NF_RST_VAL) {
 | |
|         g_phy_cpu_share_ctxt.nf_768p = tmp_nf_768p;
 | |
|     }
 | |
| 
 | |
|     /* 1536 point */
 | |
|     REG_FIELD_SET(SW_AGC_ACC_STEP_HS, tmp, PHY_AGC_ACC_STEP_1536P);
 | |
|     PHY_RXTD_WRITE_REG(CFG_BB_AGC_ACC_STEP_ADDR, tmp);
 | |
|     dly_exp = phy_agc_acc_dly_get();
 | |
|     tmp_nf_1536p = phy_rx_nf_by_rxtd_get(dly_exp);
 | |
|     if (tmp_nf_1536p != PHY_NF_RST_VAL) {
 | |
|         g_phy_cpu_share_ctxt.nf_1536p = tmp_nf_1536p;
 | |
|     }
 | |
| 
 | |
|     /* 3072 point */
 | |
|     REG_FIELD_SET(SW_AGC_ACC_STEP_HS, tmp, PHY_AGC_ACC_STEP_3072P);
 | |
|     PHY_RXTD_WRITE_REG(CFG_BB_AGC_ACC_STEP_ADDR, tmp);
 | |
|     dly_exp = phy_agc_acc_dly_get();
 | |
|     tmp_nf_3072p = phy_rx_nf_by_rxtd_get(dly_exp);
 | |
|     if (tmp_nf_3072p != PHY_NF_RST_VAL) {
 | |
|         g_phy_cpu_share_ctxt.nf_3072p = tmp_nf_3072p;
 | |
|     }
 | |
| 
 | |
|     /* revert hs */
 | |
|     REG_FIELD_SET(SW_AGC_ACC_STEP_HS, tmp, origin_hs);
 | |
|     PHY_RXTD_WRITE_REG(CFG_BB_AGC_ACC_STEP_ADDR, tmp);
 | |
| 
 | |
|     /* check rssi - nf thd: contiguous or max-min */
 | |
|     if((tmp_nf_192p != PHY_NF_RST_VAL && tmp_nf_384p != PHY_NF_RST_VAL &&
 | |
|         tmp_nf_192p <= (tmp_nf_384p - PHY_SPIKE_FIND_THD)) ||
 | |
| 
 | |
|         (tmp_nf_384p != PHY_NF_RST_VAL && tmp_nf_768p != PHY_NF_RST_VAL &&
 | |
|         tmp_nf_384p <= (tmp_nf_768p - PHY_SPIKE_FIND_THD)) ||
 | |
| 
 | |
|         (tmp_nf_768p != PHY_NF_RST_VAL && tmp_nf_1536p != PHY_NF_RST_VAL &&
 | |
|         tmp_nf_768p <= (tmp_nf_1536p - PHY_SPIKE_FIND_THD)) ||
 | |
| 
 | |
|         (tmp_nf_1536p != PHY_NF_RST_VAL && tmp_nf_3072p != PHY_NF_RST_VAL &&
 | |
|         tmp_nf_1536p <= (tmp_nf_3072p - PHY_SPIKE_FIND_THD)) ||
 | |
| 
 | |
|         (tmp_nf_192p != PHY_NF_RST_VAL && tmp_nf_3072p != PHY_NF_RST_VAL &&
 | |
|         tmp_nf_192p <= (tmp_nf_3072p - PHY_SPIKE_FIND_THD))) {
 | |
|         phy_spike_shift_en_set(1);
 | |
|     } else {
 | |
|         phy_spike_shift_en_set(0);
 | |
|     }
 | |
| 
 | |
|     /* updata current nf */
 | |
|     phy_updata_nf_of_bbai();
 | |
| 
 | |
|     if (!g_phy_ctxt.dep.nf) {
 | |
|         g_phy_ctxt.dep.nf = g_phy_cpu_share_ctxt.nf_for_bbai;
 | |
|     }
 | |
| 
 | |
|     /* recover gain */
 | |
|     if (need_fix_gain)
 | |
|         phy_agc_gain_lvl_set(fix_gain_en, max_gain, min_gain, ini_gain);
 | |
| 
 | |
|     iot_printf("[PHY]nf_192p: %d, nf_384p: %d, nf_768p: %d "\
 | |
|         "nf_1536p: %d, nf_3072p: %d, spike_shift_en: %d!\n", \
 | |
|         g_phy_cpu_share_ctxt.nf_192p, \
 | |
|         g_phy_cpu_share_ctxt.nf_384p, \
 | |
|         g_phy_cpu_share_ctxt.nf_768p, \
 | |
|         g_phy_cpu_share_ctxt.nf_1536p, \
 | |
|         g_phy_cpu_share_ctxt.nf_3072p, \
 | |
|         phy_spike_shift_en_get());
 | |
| #else
 | |
|     (void)need_fix_gain;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| void phy_rx_tgt_pwr_set(uint8_t pwr)
 | |
| {
 | |
|     g_phy_ctxt.indep.tgt_pwr = pwr;
 | |
| }
 | |
| 
 | |
| uint8_t phy_rx_tgt_pwr_get()
 | |
| {
 | |
|     return (uint8_t)(g_phy_ctxt.indep.tgt_pwr);
 | |
| }
 | |
| 
 | |
| void phy_spike_shift_en_set(bool_t en)
 | |
| {
 | |
|     g_phy_ctxt.indep.spike_shift_en= en;
 | |
| }
 | |
| 
 | |
| bool_t phy_spike_shift_en_get()
 | |
| {
 | |
|     return  (bool_t)(g_phy_ctxt.indep.spike_shift_en);
 | |
| }
 | |
| 
 | |
| bool_t phy_high_noise_sts_get()
 | |
| {
 | |
|     /* diff between big spur/pulse and packet */
 | |
|     if (g_phy_ctxt.dep.nf >= PHY_CHN_HIGH_NOISE_NF_THD) {
 | |
|         /* TODO: detect more in the future */
 | |
|         return true;
 | |
|     } else {
 | |
|         return false;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void phy_csma_ignore_cca(bool_t en)
 | |
| {
 | |
|     uint32_t tmp = PHY_DFE_READ_REG(CFG_BB_DFE_OPTION_0_ADDR);
 | |
|     if (true == en) {
 | |
|         REG_FIELD_SET(SW_CCA_OVR, tmp, 0);
 | |
|         REG_FIELD_SET(SW_CCA_OVR_EN, tmp, 1);
 | |
|         PHY_DFE_WRITE_REG(CFG_BB_DFE_OPTION_0_ADDR, tmp);
 | |
|     } else {
 | |
|         if (REG_FIELD_GET(SW_CCA_OVR_EN, tmp)) {
 | |
|             REG_FIELD_SET(SW_CCA_OVR_EN, tmp, 0);
 | |
|             PHY_DFE_WRITE_REG(CFG_BB_DFE_OPTION_0_ADDR, tmp);
 | |
|         }
 | |
|     }
 | |
|     iot_printf("ignore CCA:%d, dfe_option:0x%x\n", en, tmp);
 | |
| }
 | |
| 
 | |
| uint32_t phy_pkt_thd_set(uint8_t percent)
 | |
| {
 | |
|     /* check valid */
 | |
|     IOT_ASSERT(percent <= 100);
 | |
|     uint32_t ret = ERR_FAIL;
 | |
|     uint8_t thd0_dft, thd1_dft;
 | |
|     /* thd0 from 8 to 32 */
 | |
|     uint8_t thd0 = \
 | |
|         PHY_CHN_PKT_DET_THD1_DFT + (percent * 24) / 100;
 | |
|     /* thd1 from 16 to 48 */
 | |
|     uint8_t thd1 = \
 | |
|         PHY_CHN_PKT_DET_THD2_DFT + (percent * 32) / 100;
 | |
| 
 | |
|     /* get current config */
 | |
|     phy_rxfd_pkt_det_thd_get(&thd0_dft, &thd1_dft);
 | |
| 
 | |
|     /* get max */
 | |
|     thd0 = (thd0 > thd0_dft) ? thd0 : thd0_dft;
 | |
|     thd1 = (thd1 > thd1_dft) ? thd1 : thd1_dft;
 | |
| 
 | |
|     /* increase pkt detect threshold for decrease warnning */
 | |
|     if (g_phy_ctxt.indep.work_mode == PHY_MODE_NORMAL) {
 | |
|         phy_rxfd_pkt_det_thd_set(thd0, thd1);
 | |
|         ret = ERR_OK;
 | |
|         iot_printf("phy pkt_det_thd %d-%d\n", thd0, thd1);
 | |
|     }
 | |
| 
 | |
|     return ret;
 | |
| }
 |