/**************************************************************************** Copyright(c) 2024 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 "iot_errno_api.h" #include "iot_io.h" #include "iot_pkt_api.h" #include "iot_share_task.h" #include "os_mem_api.h" #include "os_timer_api.h" #include "os_utils_api.h" #include "phy_ana.h" #include "phy_bb.h" #include "phy_data_ckb.h" #include "phy_phase.h" #if (IOT_STA_CONTROL_MODE == IOT_STA_CONTROL_TYPE_STA) #if HW_PLATFORM >= HW_PLATFORM_FPGA #include "phy_ada_dump.h" #include "phy_perf.h" #include "phy_tools.h" #include "phy_ana.h" #if HPLC_RF_DEV_SUPPORT #include "bb_rf_cfg.h" #include "mac_rf.h" #include "phy_rf_init.h" #include "rf_phy_rx.h" #include "rf_phy_tx.h" #endif #endif #define PHY_GAIN_CFG_AUTO (0x7F) static iot_phy_chn_dump_cb g_phy_chn_rx_dump_cb; #if HW_PLATFORM >= HW_PLATFORM_FPGA static uint32_t iot_phy_dump_handle(uint32_t size, int8_t gain, ADC_DUMP_MODE mode, iot_phy_chn_dump_rt_speed_t speed, phy_trig_dump_cond *trig_dump) { uint32_t ret = ERR_FAIL; uint32_t trig_offset = 0; int8_t curr_gain = 0; uint32_t adc_buf_addr, buf_len; iot_phy_chn_dump_report_t dump_report = { 0 }; /* check dump busy flag */ if (phy_busy_get(&g_phy_ctxt, PHY_BUSY_DUMP)) { dump_report.params.dump_rst = ERR_BUSY; g_phy_chn_rx_dump_cb(0, 0, 0, &dump_report); return ERR_BUSY; } else { phy_dump_busy_set(true); } /* check not empty */ IOT_ASSERT(g_phy_chn_rx_dump_cb != NULL); /* force enter rx state */ phy_txrx_ovr_set(1, 1); /* phy reset*/ phy_reset(PHY_RST_REASON_WARM); /* ada soft reset */ warm_rst_ada(); /* notch filter bypass */ phy_anf_option_set(PHY_ANF_MODE_BYPASS, 0, 0, 0); phy_fnf_option_set(PHY_FNF_MODE_BYPASS, 0, 0); /* reset spike cancel and filter */ phy_spike_check_set(0xFF, 0, 3); phy_impuse_cancel_set(0, 6, 14); phy_hpf_set(1, 230); phy_ana_rx_fe_selc_hpf(3); phy_ana_rx_fe_selc_pgf_bq(115); /* fix gain or auto gain */ if (gain == PHY_GAIN_CFG_AUTO) { /* enable power satuation and hw adjust gain req */ phy_agc_sat_adj_set(0, 0); phy_agc_seg_num_set(1); phy_agc_sat_jug_cnt_set(32); /* not fix gain*/ phy_agc_gain_lvl_set(0, 60, -24, 0); /* get current gain */ os_delay(5); /* get current gain */ curr_gain = phy_gain_get_from_agc() - 3; } else { curr_gain = gain; } /* fix gain and disable agc */ phy_agc_gain_lvl_set(1, curr_gain, -24, 0); buf_len = phy_ada_dump_addr_get(&adc_buf_addr); if (size > (buf_len >> 1)) { size = (buf_len >> 1); } /* start force dump, word for register, 2 byte each point */ ret = phy_dump_from_ada(size >> 1, size >> 1, 0, ADC_DUMP_MODE_FORCE, PHY_PHASE_OVR_A, &trig_offset, (uint8_t *)adc_buf_addr, speed, trig_dump); /* call cb api if dump success */ if (ret == ERR_OK) { dump_report.params.trig_offset = trig_offset; g_phy_chn_rx_dump_cb((uint8_t *)adc_buf_addr, size << 1, curr_gain, &dump_report); } else { dump_report.params.dump_rst = ERR_FAIL; g_phy_chn_rx_dump_cb(0, 0, 0, &dump_report); } /* clr dump flag */ phy_dump_busy_set(false); return ret; } uint32_t iot_phy_dump_force_cb(iot_phy_chn_dump_rt_param_t *force_dump) { uint32_t ret = ERR_FAIL; ret = iot_phy_dump_handle(force_dump->size, force_dump->gain, ADC_DUMP_MODE_FORCE, ADC_DUMP_SPEED_SUPPORT, NULL); return ret; } uint32_t iot_phy_dump_auto_cb(iot_phy_chn_dump_trig_thd_param_t *trig_thd) { uint32_t ret = ERR_FAIL; phy_trig_dump_cond trig_dump = { 0 }; /* ADC threshhold conf */ trig_dump.thd = trig_thd->thd; ret = iot_phy_dump_handle(trig_thd->trig_common.buf_size, trig_thd->trig_common.gain, ADC_DUMP_MODE_AUTO, trig_thd->trig_common.speed, &trig_dump); return ret; } uint32_t iot_phy_dump_trig_phy_cb(iot_phy_chn_dump_trig_phy_param_t *trig_phy) { uint32_t ret = ERR_FAIL; phy_trig_dump_cond trig_dump = { 0 }; /* trig param */ trig_dump.trig_id = trig_phy->trig_id; ret = iot_phy_dump_handle(trig_phy->trig_common.buf_size, trig_phy->trig_common.gain, ADC_DUMP_MODE_PHY, trig_phy->trig_common.speed, &trig_dump); return ret; } static uint32_t iot_phy_rf_rx_dump_cb(iot_phy_chn_dump_rf_param_t *rf_dump) { uint32_t ret = ERR_FAIL; #if HPLC_RF_DEV_SUPPORT int8_t curr_gain = 0; uint32_t adc_buf_addr, buf_len; uint8_t option = mac_rf_get_self_option(); iot_phy_chn_dump_report_t dump_report = { 0 }; /* check dump busy flag */ if (phy_busy_get(&g_phy_ctxt, PHY_BUSY_DUMP)) { dump_report.params.dump_rst = ERR_BUSY; g_phy_chn_rx_dump_cb(0, 0, 0, &dump_report); return ERR_BUSY; } else { phy_dump_busy_set(true); } /* check not empty */ IOT_ASSERT(g_phy_chn_rx_dump_cb != NULL); /* phy tx common init interface */ rf_phy_tx_init(phy_rf_get_band_sel() , option); bb_rf_rx_cfg(option, rf_dump->lo_freq); if (rf_dump->rx_filter != 0) { bb_rf_set_filter(rf_dump->rx_filter); } /* fix gain or auto gain */ if (rf_dump->gain == 0) { /* get current gain */ curr_gain = bb_rf_get_cur_gain(); } else { /* fix gain and disable agc */ curr_gain = (int8_t)(rf_dump->gain); } curr_gain = rf_phy_rx_gain_lock(curr_gain - 13); bb_rf_debug_rx_immd(); buf_len = phy_ada_dump_addr_get(&adc_buf_addr); if (rf_dump->size > (buf_len >> 2)) { rf_dump->size = (buf_len >> 2); } buf_len = rf_dump->size << 2; rf_phy_ada_dump_entry(adc_buf_addr, buf_len); /* call cb api */ dump_report.params.trig_offset = 0; g_phy_chn_rx_dump_cb((uint8_t *)adc_buf_addr, rf_dump->size << 1, curr_gain, &dump_report); #else /* HPLC_RF_DEV_SUPPORT */ (void)rf_dump; #endif /* HPLC_RF_DEV_SUPPORT */ return ret; } #endif /* HW_PLATFORM >= HW_PLATFORM_FPGA */ uint32_t iot_phy_chn_dump_start(iot_phy_chn_dump_rt_cfg_t *dump_cfg) { uint32_t ret = ERR_FAIL; #if HW_PLATFORM >= HW_PLATFORM_FPGA switch (dump_cfg->dump_typ) { case IOT_PHY_CHN_DUMP_NOISE: iot_phy_dump_force_cb(&dump_cfg->param.force_dump); break; case IOT_PHY_CHN_DUMP_TRIG_THD: iot_phy_dump_auto_cb(&dump_cfg->param.trig_thd); break; case IOT_PHY_CHN_DUMP_TRIG_FC: iot_phy_dump_trig_phy_cb(&dump_cfg->param.trig_phy); break; case IOT_PHY_CHN_DUMP_RF: iot_phy_rf_rx_dump_cb(&dump_cfg->param.rf_dump); break; default: break; } #else (void)dump_cfg; #endif return ret; } void iot_phy_chn_dump_cb_register(iot_phy_chn_dump_cb cb) { g_phy_chn_rx_dump_cb = cb; } #endif /* (IOT_STA_CONTROL_MODE == IOT_STA_CONTROL_TYPE_STA) */