744 lines
23 KiB
C
Executable File
744 lines
23 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 "hw_reg_api.h"
|
|
#include "chip_reg_base.h"
|
|
#include "ada_reg.h"
|
|
#include "iot_config.h"
|
|
#include "phy_dfe_reg.h"
|
|
#include "phy_rx_fd_reg.h"
|
|
#include "phy_rxtd_reg.h"
|
|
#include "phy_cal.h"
|
|
#include "phy_ana.h"
|
|
#include "ahb.h"
|
|
#include "ahb_hw.h"
|
|
#include "phy_reg.h"
|
|
#include "clk.h"
|
|
#include "mac_sys_reg.h"
|
|
#include "math_log10.h"
|
|
#include "hw_tonemask.h"
|
|
#include "phy_isr.h"
|
|
#include "os_types.h"
|
|
#include "iot_errno_api.h"
|
|
#include "plc_protocol.h"
|
|
#include "granite_reg.h"
|
|
#include "phy_cfg.h"
|
|
#include "phy_perf.h"
|
|
#include "hw_phy_init.h"
|
|
#include "phy_dump.h"
|
|
#if HW_PLATFORM > HW_PLATFORM_SIMU
|
|
#include "dbg_io.h"
|
|
#endif
|
|
#include "iot_io.h"
|
|
#include "phy_data.h"
|
|
#include "os_mem.h"
|
|
#include "hw_phy_api.h"
|
|
#include "phy_tools.h"
|
|
#include "mpdu_header.h"
|
|
|
|
/* ada common init */
|
|
void ada_common_init(uint16_t tone_id, uint32_t b_size, uint32_t s_size)
|
|
{
|
|
/* dac init */
|
|
phy_ada_dump_dac_init(tone_id);
|
|
|
|
phy_dac_en_cfg(false);
|
|
|
|
/* delay */
|
|
phy_busy_wait(ADA_DUMP_INIT_DLY_CNT);
|
|
|
|
/* adc init */
|
|
phy_ada_dump_adc_init(tone_id, b_size, s_size);
|
|
|
|
/* gen tone if tone id > 0 for ada loopback */
|
|
if (tone_id > 0) {
|
|
/* att */
|
|
phy_dfe_tone_att_cfg(0, ADA_DUMP_R_SHIFT_NUM, 0);
|
|
/* config tone id */
|
|
phy_dfe_tone_cfg(1, tone_id, 0);
|
|
}
|
|
}
|
|
|
|
void adc_trigger()
|
|
{
|
|
/* trigger ADC */
|
|
phy_adc_trig_en_cfg(false);
|
|
phy_adc_trig_en_cfg(true);
|
|
}
|
|
|
|
void dumpMem(uint8_t *mem_buf, int32_t st_offset, uint32_t b_size)
|
|
{
|
|
int16_t *p_addr = NULL;
|
|
int16_t check_bits = 0;
|
|
#if ADC_DUMP_DATA_SEL == ADC_DUMP_SEL_GAIN_RAW
|
|
uint8_t gain_entry = 0;
|
|
int16_t gain = 0;
|
|
#endif
|
|
|
|
p_addr = (int16_t *)(mem_buf + st_offset*4);
|
|
/* print the pre-trig buf to the end */
|
|
iot_printf("[dump]\n");
|
|
while(p_addr <= (int16_t *)(mem_buf + b_size*4))
|
|
{
|
|
#if ADC_DUMP_DATA_SEL == ADC_DUMP_SEL_GAIN_RAW
|
|
/* gain entry */
|
|
if((*p_addr)&0x4000){
|
|
gain_entry = ((*p_addr)&0x3c00)>>6;
|
|
gain_entry |= (*(p_addr+1)&0x3c00)>>10;
|
|
}
|
|
else{
|
|
gain_entry = ((*p_addr)&0x3c00)>>10;
|
|
gain_entry |= (*(p_addr+1)&0x3c00)>>6;
|
|
}
|
|
gain = phy_gain_val_get(all_mask_gain_table[gain_entry] & 0xff, \
|
|
(all_mask_gain_table[gain_entry] >> 8) & 0xff);
|
|
|
|
if((*p_addr)&0x200)
|
|
iot_printf("%hd,%02d,%6d\n",((*p_addr)&0x8000)>>15, \
|
|
gain,((*p_addr)&0x3ff)-1024);
|
|
else
|
|
iot_printf("%hd,%02d,%6d\n",((*p_addr)&0x8000)>>15, \
|
|
gain,(*p_addr)&0x3ff);
|
|
if(*(p_addr+1)&0x200)
|
|
iot_printf("%hd,%02d,%6d\n",(*(p_addr+1)&0x8000)>>15, \
|
|
gain,(*(p_addr+1)&0x3ff)-1024);
|
|
else
|
|
iot_printf("%hd,%02d,%6d\n",(*(p_addr+1)&0x8000)>>15, \
|
|
gain,*(p_addr+1)&0x3ff);
|
|
#else
|
|
#if DATA_INV_EN
|
|
iot_printf("%06d\n",*(p_addr+1));
|
|
iot_printf("%06d\n",*p_addr);
|
|
#else
|
|
iot_printf("%06d\n",*p_addr);
|
|
iot_printf("%06d\n",*(p_addr+1));
|
|
#endif
|
|
#endif
|
|
check_bits = *p_addr ^ check_bits;
|
|
check_bits = *(p_addr+1) ^ check_bits;
|
|
p_addr += 2;
|
|
}
|
|
|
|
/* print the begin to start offset */
|
|
p_addr = (int16_t *)(mem_buf);
|
|
while(p_addr < (int16_t *)(mem_buf + st_offset*4))
|
|
{
|
|
#if ADC_DUMP_DATA_SEL == ADC_DUMP_SEL_GAIN_RAW
|
|
/* gain entry */
|
|
if((*p_addr)&0x4000){
|
|
gain_entry = ((*p_addr)&0x3c00)>>6;
|
|
gain_entry |= (*(p_addr+1)&0x3c00)>>10;
|
|
}
|
|
else{
|
|
gain_entry = ((*p_addr)&0x3c00)>>10;
|
|
gain_entry |= (*(p_addr+1)&0x3c00)>>6;
|
|
}
|
|
gain = phy_gain_val_get(all_mask_gain_table[gain_entry] & 0xff, \
|
|
(all_mask_gain_table[gain_entry] >> 8) & 0xff);
|
|
|
|
if((*p_addr)&0x200)
|
|
iot_printf("%hd,%02d,%6d\n",((*p_addr)&0x8000)>>15, \
|
|
gain,((*p_addr)&0x3ff)-1024);
|
|
else
|
|
iot_printf("%hd,%02d,%6d\n",((*p_addr)&0x8000)>>15, \
|
|
gain,(*p_addr)&0x3ff);
|
|
if(*(p_addr+1)&0x200)
|
|
iot_printf("%hd,%02d,%6d\n",(*(p_addr+1)&0x8000)>>15, \
|
|
gain,(*(p_addr+1)&0x3ff)-1024);
|
|
else
|
|
iot_printf("%hd,%02d,%6d\n",(*(p_addr+1)&0x8000)>>15, \
|
|
gain,*(p_addr+1)&0x3ff);
|
|
#else
|
|
#if DATA_INV_EN
|
|
iot_printf("%06d\n",*(p_addr+1));
|
|
iot_printf("%06d\n",*p_addr);
|
|
#else
|
|
iot_printf("%06d\n",*p_addr);
|
|
iot_printf("%06d\n",*(p_addr+1));
|
|
#endif
|
|
#endif
|
|
check_bits = *p_addr ^ check_bits;
|
|
check_bits = *(p_addr+1) ^ check_bits;
|
|
p_addr += 2;
|
|
}
|
|
iot_printf("[end]\r\ncheck:%x\r\n the last:%x\r\n", \
|
|
check_bits,*(int16_t *)(mem_buf + b_size*4));
|
|
}
|
|
|
|
uint32_t ada_dump_with_csi()
|
|
{
|
|
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);
|
|
|
|
/* tx att -6dB */
|
|
phy_tx_gain_factor_set(26);
|
|
/* enable ana loopback */
|
|
phy_txrx_loop_back_begin(0,TXRX_LOOP_BACK_GRANITE);
|
|
|
|
#if ADA_DUMP_NF_WITH_CSI_BUF_DUMP == 1
|
|
/* gain max and disable loopback */
|
|
phy_ana_i2c_write(CFG_ANA_RX_REG_0_ADDR, \
|
|
24 << RX_SELC_OFFSET, \
|
|
RX_SELC_MASK);/* 12M */
|
|
/* en adc and rx, disable dac and tx */
|
|
phy_ana_i2c_write(CFG_ANA_TOP_REG_ADDR, \
|
|
(1 << TOP_EN_ADC_OFFSET) | \
|
|
(1 << TOP_ENLIC_OFFSET) | \
|
|
(1 << TOP_EN_RX_OFFSET), \
|
|
TOP_EN_DAC_MASK | \
|
|
TOP_EN_ADC_MASK | \
|
|
TOP_ENLIC_MASK | \
|
|
TOP_EN_TX_MASK | \
|
|
TOP_EN_RX_MASK);
|
|
/* fix geode rx */
|
|
phy_txrx_ovr_set(1,1);
|
|
phy_phase_ovr_set(PHY_PHASE_OVR_B,true,PHY_TXRX_OVR_RX);
|
|
#endif
|
|
|
|
/* 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);
|
|
|
|
/* recover to the state set in ana loopback */
|
|
phy_txrx_loop_back_end();
|
|
|
|
iot_printf("[dump]\r\n");
|
|
/* cal csi for every tone */
|
|
for(tone_idx = 0; tone_idx < 1536; tone_idx++)
|
|
{
|
|
csi_i = (int16_t)(*csi_buf & 0xFFFF);
|
|
csi_q = (int16_t)(*csi_buf >> 16);
|
|
iot_printf("%d,%d,%d\r\n", tone_idx, csi_i, csi_q);
|
|
csi_buf++;
|
|
}
|
|
|
|
iot_printf("[end]\r\n");
|
|
/* enable sw csi buf access */
|
|
enable_sw_access_csi_buf(0);
|
|
|
|
/* 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);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* ADA adc data dump */
|
|
int phy_dump_from_ada( \
|
|
uint32_t b_size, \
|
|
uint32_t s_size, \
|
|
uint16_t tone_id, \
|
|
ADC_DUMP_MODE mode, \
|
|
PHY_PHASE_OVR_ID phase, \
|
|
uint32_t *trig_offset, \
|
|
uint8_t *adc_buf, \
|
|
uint32_t speed, \
|
|
phy_trig_dump_cond *trig_cond)
|
|
|
|
{
|
|
uint32_t ret = ERR_OK;
|
|
uint32_t *ram_ptr = NULL;
|
|
|
|
/* ada soft reset */
|
|
warm_rst_ada();
|
|
|
|
/* adc and dac init */
|
|
ada_common_init(tone_id, b_size, s_size);
|
|
|
|
/* TODO: dtei stei and nid for kl2 */
|
|
if (trig_cond != NULL) {
|
|
if (trig_cond->thd != 0) {
|
|
/* ADC threshhold conf */
|
|
phy_adc_thrd_cfg(trig_cond->thd);
|
|
} else {
|
|
/* stei, dtei and nid */
|
|
}
|
|
}
|
|
|
|
/* force inte rx state */
|
|
phy_txrx_ovr_set(1,1);
|
|
|
|
/* force rx phase */
|
|
phy_rx_phase_force_set(true, phase);
|
|
|
|
#if ADA_DUMP_WITH_CSI_BUF_DUMP == 1
|
|
ada_dump_with_csi();
|
|
#endif
|
|
|
|
/* not reset when drop */
|
|
phy_agc_drop_restart_dis_set(true);
|
|
|
|
/* not reset when up */
|
|
phy_agc_ramup_restart_dis_set(true);
|
|
|
|
/* full */
|
|
phy_agc_sat_rst_dis_set(1);
|
|
|
|
/* jusge counter */
|
|
phy_agc_sat_jug_cnt_set(32);
|
|
|
|
#if EDA_SIMU_SUPPORT == 1
|
|
phy_busy_wait(ADC_DUMP_EDA_DLY_CYCLE);
|
|
(void)ram_ptr;
|
|
#else
|
|
ram_ptr = (uint32_t *)adc_buf;
|
|
/* init default val */
|
|
uint32_t cnt = b_size;
|
|
do {
|
|
*ram_ptr++ = 0xffffffff;
|
|
} while(cnt--);
|
|
#endif
|
|
|
|
/* must flush ddr before dump */
|
|
if ((uint32_t)adc_buf == \
|
|
(ADC_DUMP_DDR_OFFSET + ADC_DUMP_DST_ADDR)) {
|
|
ahb_dmc_cache_rst_clear();
|
|
ahb_dmc_cache_clear();
|
|
}
|
|
|
|
/* ada dump with max dly */
|
|
if (trig_cond != NULL) {
|
|
ret = phy_ada_dump_start(b_size, s_size, \
|
|
mode, ~0, trig_offset, trig_cond->trig_id, speed);
|
|
} else {
|
|
ret = phy_ada_dump_start(b_size, s_size, \
|
|
mode, ~0, trig_offset, 0, speed);
|
|
}
|
|
/* disable force phase */
|
|
phy_rx_phase_force_set(false, PLC_PHASE_ALL);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* csi dump to cal SNR/NF
|
|
*/
|
|
float mac_rx_csi_dump(mac_csi_back_t *info, \
|
|
csi_est_dump_cond *cond, \
|
|
uint16_t p_num)
|
|
{
|
|
uint8_t cur_nid = 0;
|
|
int16_t csi_i = 0, csi_q = 0;
|
|
uint16_t total_packets_num = 0, first_flag = 0;
|
|
uint16_t array_index = 0, cur_gain_entry = 0;
|
|
uint16_t array_index_i = 0, array_index_q = 0;
|
|
volatile bool_t trig_flag = false;
|
|
uint32_t tmp = 0, tmp_i = 0, data_interval = 10;
|
|
uint32_t start_time = 0, end_time = 0;
|
|
uint32_t start_pos = 0, end_pos = 0;
|
|
uint32_t pkt_rssi = 0, pkt_adc_pwr = 0, pkt_gain = 0;
|
|
uint32_t *csi_buf = (uint32_t *)BB_CSI_BASEADDR;
|
|
float amp_value = 0, amp_avg = 0, amp_vari = 0;
|
|
float pre_amp_avg = 0, post_amp_avg = 0;
|
|
uint64_t time_span = 0;
|
|
|
|
/* clear shift */
|
|
phy_gain_shift_set(0,0,0,0);
|
|
|
|
/* notch filter clear */
|
|
phy_anf_option_set(PHY_ANF_MODE_BYPASS,0,0,0);
|
|
|
|
/* clear to avoid mask over for time-varying spur */
|
|
phy_tone_mask_amp_phase_tab_load(&all_mask_amp_phase_table,
|
|
phy_mask_id_get(), PHY_PROTO_TYPE_GET());
|
|
|
|
/* disable intr */
|
|
PHY_WRITE_REG(CFG_BB_INT_CLR_0_ADDR, (PHY_RECV_FD_FC_OK | PHY_RECV_FD_FC_FAIL));
|
|
|
|
total_packets_num = ((all_mask_band_table_r0_full.end_tone - \
|
|
all_mask_band_table_r0_full.start_tone + 1) << 2) \
|
|
/ MAC_CSI_BACK_MAX_LEN;
|
|
if(total_packets_num) {
|
|
first_flag = 1;
|
|
}
|
|
|
|
/* step1: polling rx_fd_fc_ok/fail
|
|
todo: add to interrupt handler */
|
|
if(p_num == first_flag) {
|
|
if((cond->trig_id & PHY_CSI_DUMP_TRIG_FC_OK) || \
|
|
(cond->trig_id & PHY_CSI_DUMP_TRIG_FC_FAIL))
|
|
{
|
|
/*polling rx_fd_fc_ok*/
|
|
start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
|
while(!trig_flag)
|
|
{
|
|
/* read reg */
|
|
tmp = PHY_READ_REG(CFG_BB_INT_RAW_0_ADDR);
|
|
if(cond->trig_id & PHY_CSI_DUMP_TRIG_FC_OK) {
|
|
if(0 != (tmp & PHY_RECV_FD_FC_OK)) {
|
|
uint32_t bb_fc[4];
|
|
bb_fc[0] = PHY_READ_REG(CFG_BB_RX_FC_RAW_0_ADDR);
|
|
bb_fc[1] = PHY_READ_REG(CFG_BB_RX_FC_RAW_1_ADDR);
|
|
bb_fc[2] = PHY_READ_REG(CFG_BB_RX_FC_RAW_2_ADDR);
|
|
bb_fc[3] = PHY_READ_REG(CFG_BB_RX_FC_RAW_3_ADDR);
|
|
cur_nid = mac_get_nid_from_fc(PHY_PROTO_TYPE_GET(), bb_fc);
|
|
iot_printf("Trigger done. glb_nid: %d, cur_nid: %d.\n", \
|
|
cond->nid, cur_nid);
|
|
|
|
tmp_i = PHY_RXTD_READ_REG(CFG_BB_PACKET_INF_0_ADDR);
|
|
pkt_adc_pwr = REG_FIELD_GET(FREE_RSSI, tmp_i);
|
|
pkt_gain = REG_FIELD_GET(GAIN_TABLE_ENTRY, tmp_i);
|
|
pkt_rssi = PHY_RSSI_FROM_RMI_GAIN(pkt_adc_pwr, pkt_gain);
|
|
iot_printf("Trigger done. adc_pwr: %d, gain: %d, rssi: %d.\n", \
|
|
pkt_adc_pwr, pkt_gain, pkt_rssi);
|
|
if((cond->nid == cur_nid) \
|
|
&& (PHY_DUMP_PKT_RSSI_THD < pkt_rssi)) {
|
|
trig_flag = 1;
|
|
} else {
|
|
trig_flag = 0;
|
|
}
|
|
}
|
|
} else if(cond->trig_id & PHY_CSI_DUMP_TRIG_FC_FAIL) {
|
|
trig_flag |= ((tmp & PHY_RECV_FD_FC_FAIL) != 0)?1:0;
|
|
}
|
|
|
|
end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
|
time_span = end_time - start_time;
|
|
if (time_span < 0) { // wrap around
|
|
time_span = (0x100000000LL) - start_time + end_time;
|
|
}
|
|
|
|
/* wait 1s */
|
|
if((uint64_t)time_span > 1000 * TICKS_UNIT_MS){
|
|
iot_printf("trig fail: wait more than 1s, check rx line!\n");
|
|
return ERR_FAIL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
tmp = PHY_RXTD_READ_REG(CFG_BB_PACKET_INF_0_ADDR);
|
|
cur_gain_entry = REG_FIELD_GET(GAIN_TABLE_ENTRY, tmp);
|
|
iot_printf("Current Gain Entry: %d\n", cur_gain_entry);
|
|
|
|
/* enable csi buf dump */
|
|
enable_sw_access_csi_buf(true);
|
|
enable_sw_access_loopback(true);
|
|
|
|
/* read data, to do with tone mask */
|
|
if(0 == p_num && 0 == total_packets_num) {
|
|
start_pos = all_mask_band_table_r0_full.start_tone;
|
|
end_pos = all_mask_band_table_r0_full.end_tone;
|
|
} else if(0 == p_num && 0 < total_packets_num) {
|
|
start_pos = all_mask_band_table_r0_full.start_tone + \
|
|
total_packets_num * (MAC_CSI_BACK_MAX_LEN >> 2);
|
|
end_pos = all_mask_band_table_r0_full.end_tone;
|
|
} else {
|
|
start_pos = all_mask_band_table_r0_full.start_tone + \
|
|
(p_num - 1) * (MAC_CSI_BACK_MAX_LEN >> 2);
|
|
end_pos = start_pos + (MAC_CSI_BACK_MAX_LEN >> 2) - 1;
|
|
}
|
|
|
|
for(uint32_t i = start_pos; i <= end_pos; i++)
|
|
{
|
|
csi_i = (int16_t)(*(csi_buf + i) & 0xFFFF);
|
|
csi_q = (int16_t)(*(csi_buf + i) >> 16);
|
|
//iot_printf("%u,%d,%d\r\n", i, csi_i, csi_q);
|
|
|
|
array_index_i = array_index << 1;
|
|
array_index_q = array_index_i + 1;
|
|
info->info_arry[array_index_i] = csi_i;
|
|
info->info_arry[array_index_q] = csi_q;
|
|
array_index += 1;
|
|
}
|
|
|
|
if(end_pos == all_mask_band_table_r0_full.end_tone) {
|
|
/* get average */
|
|
for(uint32_t i = all_mask_band_table_r0_full.start_tone; \
|
|
i <= all_mask_band_table_r0_full.end_tone; i++)
|
|
{
|
|
csi_i = (int16_t)(*(csi_buf + i) & 0xFFFF);
|
|
csi_q = (int16_t)(*(csi_buf + i) >> 16);
|
|
amp_value = 10*mlog10(csi_i * csi_i + csi_q * csi_q + 1);
|
|
amp_avg += amp_value;
|
|
|
|
if(0 == (i - all_mask_band_table_r0_full.start_tone) % data_interval) {
|
|
iot_printf("data interval: %d, %u\r\n", i, (uint32_t)amp_value);
|
|
}
|
|
|
|
if(i < all_mask_band_table_r0_full.start_tone + data_interval) {
|
|
pre_amp_avg += amp_value;
|
|
}
|
|
|
|
if(i > all_mask_band_table_r0_full.end_tone - data_interval) {
|
|
post_amp_avg += amp_value;
|
|
}
|
|
}
|
|
amp_avg = amp_avg/all_mask_band_table_r0_full.valid_tone_number;
|
|
pre_amp_avg = pre_amp_avg/data_interval;
|
|
post_amp_avg = post_amp_avg/data_interval;
|
|
iot_printf("data interval %d, pre amp avg: %u, post amp avg: %u\r\n", \
|
|
data_interval, (uint32_t)pre_amp_avg, (uint32_t)post_amp_avg);
|
|
|
|
info->info_arry[array_index_q + 1] = \
|
|
(int16_t)(all_mask_band_table_r0_full.start_tone);
|
|
info->info_arry[array_index_q + 2] = \
|
|
(int16_t)(all_mask_band_table_r0_full.end_tone);
|
|
info->info_arry[array_index_q + 3] = (uint16_t)cur_gain_entry;
|
|
|
|
/* differentiate 700K and 2M spectrogram for band 32-120 */
|
|
info->info_arry[array_index_q + 4] = (int16_t)(post_amp_avg - pre_amp_avg);
|
|
|
|
/* cal variance */
|
|
for(uint32_t i = all_mask_band_table_r0_full.start_tone; \
|
|
i <= all_mask_band_table_r0_full.end_tone; i++)
|
|
{
|
|
csi_i = (int16_t)(*(csi_buf + i) & 0xFFFF);
|
|
csi_q = (int16_t)(*(csi_buf + i) >> 16);
|
|
amp_vari += (10*mlog10(csi_i * csi_i + csi_q * csi_q + 1)-amp_avg) * \
|
|
(10*mlog10(csi_i * csi_i + csi_q * csi_q + 1)-amp_avg);
|
|
}
|
|
|
|
/* get average */
|
|
amp_vari = amp_vari/all_mask_band_table_r0_full.valid_tone_number;
|
|
iot_printf("average:%u,variance^2:%u\r\n", (uint32_t)amp_avg, (uint32_t)amp_vari);
|
|
|
|
} else {
|
|
info->info_arry[array_index_q + 1] = 0;
|
|
info->info_arry[array_index_q + 2] = 0;
|
|
info->info_arry[array_index_q + 3] = (uint16_t)cur_gain_entry;
|
|
info->info_arry[array_index_q + 4] = p_num;
|
|
}
|
|
|
|
info->len = (array_index << 2) + 8;
|
|
|
|
/* default last packet number and single one packet number is 0 */
|
|
if(0 == p_num) {
|
|
/* disable csi buf dump */
|
|
enable_sw_access_csi_buf(false);
|
|
enable_sw_access_loopback(false);
|
|
}
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
uint32_t phy_fft_flash_dump(uint32_t *buf_ptr)
|
|
{
|
|
uint32_t ret = ERR_OK;
|
|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
|
|
uint32_t tmp = 0;
|
|
int8_t gain = 0;
|
|
uint32_t *csi_buf = (uint32_t *)BB_CSI_BASEADDR;
|
|
|
|
/* get current gain */
|
|
gain = phy_gain_get_from_agc();
|
|
iot_printf("current gain: %u\n", gain);
|
|
*(buf_ptr + 1) = gain;
|
|
|
|
/* fix gain and disable agc */
|
|
phy_agc_gain_lvl_set(1,gain,-24,0);
|
|
|
|
/* enable phase A rx */
|
|
phy_rx_phase_force_set(true, PLC_PHASE_A);
|
|
|
|
/* rst to trig enable after tone change */
|
|
phy_reset(PHY_RST_REASON_WARM);
|
|
|
|
/* fft prepare */
|
|
phy_fft_dump_prepare();
|
|
|
|
/* 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);
|
|
|
|
/* memcpy data from csi buf to buf */
|
|
for(uint32_t tone_idx = 2; tone_idx < TOTAL_TONE_MASK_NUM; tone_idx++)
|
|
{
|
|
*(buf_ptr + tone_idx) = *(csi_buf + tone_idx);
|
|
}
|
|
|
|
/* enable sw csi buf access */
|
|
enable_sw_access_csi_buf(0);
|
|
|
|
/* fft revert */
|
|
phy_fft_dump_recover();
|
|
|
|
/* disable force phase */
|
|
phy_rx_phase_force_set(false, PLC_PHASE_ALL);
|
|
#else
|
|
(void)buf_ptr;
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
uint32_t phy_rx_scan_fft_dump(uint32_t *buf_ptr, int8_t rx_gain,\
|
|
uint16_t cur_pnum, uint16_t total_pnum)
|
|
{
|
|
uint32_t ret = ERR_OK;
|
|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
|
|
uint32_t tmp = 0;
|
|
uint32_t *csi_buf = (uint32_t *)BB_CSI_BASEADDR;
|
|
|
|
/* enable phase A rx */
|
|
phy_rx_phase_force_set(true, PLC_PHASE_A);
|
|
|
|
/* rst to trig enable after tone change */
|
|
phy_reset(PHY_RST_REASON_WARM);
|
|
|
|
/* enable first packet */
|
|
if(cur_pnum < 2) {
|
|
/* fix gain and disable agc */
|
|
if(rx_gain >= -24 && rx_gain <= 60) {
|
|
phy_agc_gain_lvl_set(1,rx_gain,-24,0);
|
|
} else {
|
|
iot_printf("rx_gain out of range, it should be at [-24, +60]!\n");
|
|
return 0;
|
|
}
|
|
|
|
/* fft dump prepare */
|
|
phy_fft_dump_prepare();
|
|
|
|
/* 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);
|
|
}
|
|
|
|
csi_buf += (cur_pnum - 1) * IOT_PHY_FFT_BUF_LEN / 4;
|
|
/* memcpy data from csi buf to buf */
|
|
os_mem_cpy(buf_ptr, csi_buf, IOT_PHY_FFT_BUF_LEN);
|
|
|
|
if(cur_pnum == total_pnum) {
|
|
/* enable sw csi buf access */
|
|
enable_sw_access_csi_buf(0);
|
|
|
|
/* fft dump revert */
|
|
phy_fft_dump_recover();
|
|
}
|
|
|
|
/* disable force */
|
|
phy_rx_phase_force_set(false, PLC_PHASE_ALL);
|
|
#else
|
|
(void)buf_ptr;
|
|
(void)rx_gain;
|
|
(void)cur_pnum;
|
|
(void)total_pnum;
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
void phy_auto_tone_tx(timer_id_t timer_id, void *arg)
|
|
{
|
|
(void)timer_id;
|
|
phy_ctxt_t *phy_ctxt_ptr = arg;
|
|
|
|
if (phy_ctxt_ptr->indep.tx_tone.curent_tone < \
|
|
phy_ctxt_ptr->indep.tx_tone.end_tone) {
|
|
/* config tone */
|
|
phy_dfe_tone_cfg(1, \
|
|
phy_ctxt_ptr->indep.tx_tone.curent_tone, 0);
|
|
phy_ctxt_ptr->indep.tx_tone.curent_tone++;
|
|
iot_printf("%s tone_id %d\r\n",__FUNCTION__,\
|
|
phy_ctxt_ptr->indep.tx_tone.curent_tone);
|
|
} else {
|
|
phy_ctxt_ptr->indep.tx_tone.curent_tone = \
|
|
phy_ctxt_ptr->indep.tx_tone.start_tone;
|
|
/* disable tone tx */
|
|
phy_dfe_tone_cfg(0, 0, 0);
|
|
|
|
os_stop_timer(phy_ctxt_ptr->indep.tx_tone.auto_tone_timer);
|
|
/*after finish tone tx,rest 10000ms */
|
|
os_start_timer(phy_ctxt_ptr->indep.tx_tone.rest_tone_timer,PHY_TX_TONE_REST_TIME);
|
|
}
|
|
}
|
|
|
|
void phy_star_tone_tx_timer(timer_id_t timer_id, void *arg)
|
|
{
|
|
(void)timer_id;
|
|
phy_ctxt_t *phy_ctxt_ptr = arg;
|
|
|
|
os_stop_timer(phy_ctxt_ptr->indep.tx_tone.rest_tone_timer);
|
|
/* start timer */
|
|
os_start_timer(phy_ctxt_ptr->indep.tx_tone.auto_tone_timer, \
|
|
phy_ctxt_ptr->indep.tx_tone.tx_intval_time_ms);
|
|
}
|
|
|
|
void phy_auto_tone_tx_start(iot_phy_tone_param_ctxt_t *tx_tone_ptr)
|
|
{
|
|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
|
|
uint16_t start_tone = 0,end_tone = 0,tx_inval_time = 0;
|
|
|
|
phy_load_ada_scan_cfg(&start_tone, &end_tone, &tx_inval_time);
|
|
if((0 == start_tone) || (0 == end_tone) || (0 == tx_inval_time)){
|
|
start_tone = 32;
|
|
end_tone = 120;
|
|
tx_inval_time = 400;
|
|
}
|
|
iot_printf("%s,start %d,end %d ,inter %d\r\n",__FUNCTION__,\
|
|
start_tone,end_tone,tx_inval_time);
|
|
|
|
/* update tone id */
|
|
tx_tone_ptr->start_tone = start_tone / 3;
|
|
tx_tone_ptr->end_tone = end_tone / 3;
|
|
tx_tone_ptr->curent_tone = start_tone / 3;
|
|
tx_tone_ptr->rty_cnt = 1;
|
|
tx_tone_ptr->tx_intval_time_ms = tx_inval_time;
|
|
tx_tone_ptr->auto_tone_timer = \
|
|
os_create_timer( \
|
|
PLC_PHY_COMMON_MID, true, phy_auto_tone_tx, &g_phy_ctxt);
|
|
if(tx_tone_ptr->auto_tone_timer == 0){
|
|
return;
|
|
}
|
|
|
|
tx_tone_ptr->rest_tone_timer = \
|
|
os_create_timer( \
|
|
PLC_PHY_COMMON_MID, true, phy_star_tone_tx_timer, &g_phy_ctxt);
|
|
if(tx_tone_ptr->rest_tone_timer == 0){
|
|
return;
|
|
}
|
|
|
|
/* force phy in tx state */
|
|
phy_txrx_ovr_set(true, 2);
|
|
|
|
/* en analog tx */
|
|
phy_ana_tx_en(true);
|
|
phy_ana_rx_en(false);
|
|
phy_ana_enlic_en(PHY_ENLIC_TXRX_TX);
|
|
|
|
/* att */
|
|
phy_dfe_tone_att_cfg(0, 3, 0);
|
|
|
|
os_start_timer(tx_tone_ptr->auto_tone_timer, \
|
|
tx_tone_ptr->tx_intval_time_ms);
|
|
#endif
|
|
}
|