937 lines
26 KiB
C
937 lines
26 KiB
C
|
/****************************************************************************
|
||
|
|
||
|
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 "hw_reg_api.h"
|
||
|
#include "plc_utils.h"
|
||
|
#include "mac_reset.h"
|
||
|
#include "mac_hwq_reg.h"
|
||
|
#include "mac_sys_reg.h"
|
||
|
#include "mac_rx_reg.h"
|
||
|
#include "mac_tmr_reg.h"
|
||
|
#include "ada_reg.h"
|
||
|
#include "hw_phy_init.h"
|
||
|
#include "mac_desc_engine.h"
|
||
|
#include "iot_pkt_api.h"
|
||
|
#include "plc_const.h"
|
||
|
#include "rx_pb_reorder.h"
|
||
|
#include "phy_reg.h"
|
||
|
#include "iot_bitops.h"
|
||
|
#include "phy_bb.h"
|
||
|
#include "phy_chn.h"
|
||
|
#include "hw_tonemask.h"
|
||
|
#if HW_PLATFORM > HW_PLATFORM_SIMU
|
||
|
#include "dbg_io.h"
|
||
|
#endif
|
||
|
#include "iot_io.h"
|
||
|
#include "phy_ana.h"
|
||
|
#include "mac_rx_test.h"
|
||
|
#include "mac_rx_buf_ring.h"
|
||
|
#include "iot_config.h"
|
||
|
#include "hw_desc.h"
|
||
|
#include "phy_dfe_reg.h"
|
||
|
#include "gpio_mtx.h"
|
||
|
#include "iot_irq.h"
|
||
|
#include "tx_mpdu_start.h"
|
||
|
#include "mac_tx_main.h"
|
||
|
#include "phy_cal.h"
|
||
|
#include "iot_errno_api.h"
|
||
|
#if IOT_DTEST_ONLY_SUPPORT == 0
|
||
|
#include "iot_cal_data.h"
|
||
|
#endif
|
||
|
#include "hw_phy_api.h"
|
||
|
#include "phy_tools.h"
|
||
|
#include "rx_entry.h"
|
||
|
#include "tx_entry.h"
|
||
|
#include "math_log10.h"
|
||
|
#include "hw_tx.h"
|
||
|
#include "hw_rx.h"
|
||
|
#include "phy_mix.h"
|
||
|
#include "hal_rx.h"
|
||
|
#include "phy_perf.h"
|
||
|
#include "phy_dump.h"
|
||
|
#include "phy_dump_hw.h"
|
||
|
|
||
|
void mpdu_rx_cnt_callback(rx_pb_end *pb_ed, uint32_t *cnt)
|
||
|
{
|
||
|
if (pb_ed->rx_pb_crc_err == 0)
|
||
|
cnt += 1;
|
||
|
}
|
||
|
|
||
|
void handle_rx_buf(uint8_t *buf, uint32_t buf_byte_len)
|
||
|
{
|
||
|
(void)buf;
|
||
|
(void)buf_byte_len;
|
||
|
/* print the content out */
|
||
|
//iot_printf("packet received.\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* mac rx snr cal */
|
||
|
uint32_t mac_rx_snr_scan()
|
||
|
{
|
||
|
uint32_t ret = ERR_OK;
|
||
|
uint32_t tone_idx = 0;
|
||
|
int32_t snr_buf[TONE_MAX_NUM] = {0};
|
||
|
ret = phy_rx_snr_get( \
|
||
|
0, TONE_MAX_NUM, snr_buf, PHY_DUMP_DLY_CNT);
|
||
|
if(ret != ERR_OK) {
|
||
|
iot_printf("file=%s,func=%s,line=%d fail!\n", \
|
||
|
__FILE__, __FUNCTION__, __LINE__);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/* cal snr for every tone */
|
||
|
for(tone_idx = 0; tone_idx < TONE_MAX_NUM; tone_idx++)
|
||
|
{
|
||
|
iot_printf("tone%d snr:%d\r\n",tone_idx, snr_buf[tone_idx]);
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/* mac rx snr cal dump */
|
||
|
uint32_t mac_rx_softbit_dump()
|
||
|
{
|
||
|
uint32_t ret = ERR_OK;
|
||
|
uint32_t tone_idx = 0;
|
||
|
int32_t snr_buf[TONE_MAX_NUM] = {0};
|
||
|
|
||
|
ret = phy_rx_softbit_get( \
|
||
|
0, TONE_MAX_NUM, snr_buf, PHY_DUMP_DLY_CNT);
|
||
|
|
||
|
if (ret != ERR_OK) {
|
||
|
iot_printf("file=%s,func=%s,line=%d fail!\n", \
|
||
|
__FILE__, __FUNCTION__, __LINE__);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/* cal snr for every tone */
|
||
|
for (tone_idx = 0; tone_idx < TONE_MAX_NUM; tone_idx++)
|
||
|
{
|
||
|
iot_printf("tone%d softbit:%d\r\n",tone_idx, snr_buf[tone_idx]);
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* mac rx csi cal */
|
||
|
uint32_t mac_rx_csi_scan()
|
||
|
{
|
||
|
uint32_t ret = ERR_OK;
|
||
|
uint32_t tone_idx = 0;
|
||
|
uint32_t csi_buf[TONE_MAX_NUM] = {0};
|
||
|
ret = phy_rx_csi_get( \
|
||
|
0, TONE_MAX_NUM, csi_buf, PHY_DUMP_DLY_CNT);
|
||
|
if(ret != ERR_OK) {
|
||
|
iot_printf("file=%s,func=%s,line=%d fail!\n", \
|
||
|
__FILE__, __FUNCTION__, __LINE__);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/* cal snr for every tone */
|
||
|
for(tone_idx = 0; tone_idx < TONE_MAX_NUM; tone_idx++)
|
||
|
{
|
||
|
iot_printf("csi power=%d\r\n", csi_buf[tone_idx]);
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/* mac rx noise floor cal */
|
||
|
uint32_t mac_rx_noise_floor_scan()
|
||
|
{
|
||
|
uint32_t ret = ERR_OK;
|
||
|
int32_t gain = 0;
|
||
|
uint32_t rssi_nf = 0;
|
||
|
uint32_t tone_idx = 0;
|
||
|
uint32_t nf_buf[TONE_MAX_NUM] = {0};
|
||
|
|
||
|
ret = phy_rx_noise_floor_get( \
|
||
|
0, TONE_MAX_NUM, nf_buf, PHY_DUMP_DLY_CNT, PHY_SNR_DUMP_NF);
|
||
|
|
||
|
if(ret != ERR_OK) {
|
||
|
iot_printf("file=%s,func=%s,line=%d fail!\n", \
|
||
|
__FILE__, __FUNCTION__, __LINE__);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/* noise floor for every tone */
|
||
|
for(tone_idx = 0; tone_idx < TONE_MAX_NUM; tone_idx++)
|
||
|
{
|
||
|
iot_printf("tone%d noise floor:%d\n", \
|
||
|
tone_idx, nf_buf[tone_idx]);
|
||
|
}
|
||
|
|
||
|
phy_rx_snr_gain_get(&gain, &rssi_nf);
|
||
|
iot_printf("Gain-NF: %hd-%hd\r\n", gain, rssi_nf);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/* mac rx spur cal */
|
||
|
uint32_t mac_rx_spur_scan()
|
||
|
{
|
||
|
uint32_t ret = ERR_OK;
|
||
|
int32_t gain = 0;
|
||
|
uint32_t rssi_nf = 0;
|
||
|
uint32_t tone_idx = 0;
|
||
|
uint32_t nf_buf[TONE_MAX_NUM] = {0};
|
||
|
|
||
|
ret = phy_rx_spur_get( \
|
||
|
0, TONE_MAX_NUM, nf_buf, PHY_DUMP_DLY_CNT);
|
||
|
|
||
|
if (ret != ERR_OK) {
|
||
|
iot_printf("file=%s,func=%s,line=%d fail!\n", \
|
||
|
__FILE__, __FUNCTION__, __LINE__);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/* spur for every tone */
|
||
|
for (tone_idx = 0; tone_idx < TONE_MAX_NUM; tone_idx++)
|
||
|
iot_printf("tone%d spur:%d\n", \
|
||
|
tone_idx, nf_buf[tone_idx]);
|
||
|
|
||
|
phy_rx_snr_gain_get(&gain, &rssi_nf);
|
||
|
iot_printf("Gain-NF: %hd-%hd\r\n", gain, rssi_nf);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/* STA mac rx ppm cali */
|
||
|
uint32_t mac_rx_ppm_cali()
|
||
|
{
|
||
|
int16_t ppm_cali_rd = 0;
|
||
|
int16_t ppm_cali_wr = 0;
|
||
|
uint32_t start_time = 0, end_time = 0;
|
||
|
int64_t time_span = 0;
|
||
|
uint32_t tmp = 0;
|
||
|
|
||
|
#ifdef PHY_PPM_CAL_ON_SNR
|
||
|
int32_t snr_buf[TONE_MAX_NUM] = {0};
|
||
|
uint32_t tone_idx = 0;
|
||
|
uint32_t snr = 0;
|
||
|
|
||
|
do{
|
||
|
phy_rx_snr_get(0,TONE_MAX_NUM,snr_buf);
|
||
|
/* cal snr for every tone */
|
||
|
for(tone_idx = 0; tone_idx < TONE_MAX_NUM; tone_idx++)
|
||
|
{
|
||
|
iot_printf("tone%d snr:%d\r\n",tone_idx, snr_buf[tone_idx]);
|
||
|
if(snr_buf[tone_idx] > 20){
|
||
|
snr = snr_buf[tone_idx];
|
||
|
}
|
||
|
}
|
||
|
}while(!snr);
|
||
|
|
||
|
/* shutdown self comp */
|
||
|
phy_freq_shift_self_comp(false,false);
|
||
|
#endif
|
||
|
|
||
|
/* calibration start */
|
||
|
start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
|
do {
|
||
|
ppm_cali_rd = phy_ppm_info_get();
|
||
|
/* no need cal if |ppm| < 1 */
|
||
|
if (ppm_cali_rd > -1 && ppm_cali_rd < 1 )
|
||
|
break;
|
||
|
|
||
|
if (ppm_cali_rd > 50 || ppm_cali_rd < -50){
|
||
|
iot_printf("calibration failed: ppm error big than 50!\n");
|
||
|
}
|
||
|
|
||
|
/* set calibration to ppm setting reg */
|
||
|
#if IOT_RATE_MODE_RX == IOT_SUPPORT_RATE_XR
|
||
|
phy_ppm_cal_and_update_hw( \
|
||
|
PHY_CAL_UNIT_1_1,-ppm_cali_rd,IOT_SUPPORT_RATE_XR, BB_PPM_TXRX);
|
||
|
#elif IOT_RATE_MODE_RX == IOT_SUPPORT_RATE_QR
|
||
|
phy_ppm_cal_and_update_hw( \
|
||
|
PHY_CAL_UNIT_1_4,-ppm_cali_rd,IOT_SUPPORT_RATE_QR, BB_PPM_TXRX);
|
||
|
#else
|
||
|
phy_ppm_cal_and_update_hw( \
|
||
|
PHY_CAL_UNIT_1_16,-ppm_cali_rd,IOT_SUPPORT_RATE_SR, BB_PPM_TXRX);
|
||
|
#endif
|
||
|
|
||
|
do{
|
||
|
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;
|
||
|
}
|
||
|
}while((uint64_t)time_span < 25000*100);//25000*0.04us=1ms
|
||
|
start_time = end_time;
|
||
|
}while (1);
|
||
|
|
||
|
tmp = PHY_DFE_READ_REG(CFG_BB_PPM_SETTING_ADDR);
|
||
|
ppm_cali_wr = REG_FIELD_GET(SW_RX_PPM,tmp);
|
||
|
iot_printf("mac_rx_ppm_cali: calibration success! ");
|
||
|
iot_printf("ppm_cali_wr=0x%x\r\n",ppm_cali_wr);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/* dump fc */
|
||
|
uint32_t mac_rx_fc_from_phy()
|
||
|
{
|
||
|
uint32_t start_time = 0, end_time = 0;
|
||
|
uint64_t time_span = 0;
|
||
|
iot_phy_sts_info_t total_sts = {0};
|
||
|
uint32_t wd_idx = 0, rd_idx = 0;
|
||
|
uint32_t fc_raw[MAC_RX_PHY_FC_DUMP_NUM][4] = {{0}};
|
||
|
|
||
|
/* check if rx ring has content */
|
||
|
start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
|
/* clear cnt */
|
||
|
PHY_WRITE_REG(CFG_BB_FC_PLD_CNTR_CLR_ADDR,0xF);
|
||
|
do {
|
||
|
/* read phy fc cnt */
|
||
|
wd_idx = PHY_READ_REG(CFG_BB_FC_CRC_OK_CNTR_ADDR);
|
||
|
while (rd_idx < wd_idx)
|
||
|
{
|
||
|
fc_raw[rd_idx][0] = PHY_READ_REG(CFG_BB_RX_FC_RAW_0_ADDR);
|
||
|
fc_raw[rd_idx][1] = PHY_READ_REG(CFG_BB_RX_FC_RAW_1_ADDR);
|
||
|
fc_raw[rd_idx][2] = PHY_READ_REG(CFG_BB_RX_FC_RAW_2_ADDR);
|
||
|
fc_raw[rd_idx][3] = PHY_READ_REG(CFG_BB_RX_FC_RAW_3_ADDR);
|
||
|
rd_idx++;
|
||
|
}
|
||
|
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;
|
||
|
}
|
||
|
if((uint64_t)time_span > g_plc_dt_ctxt.indep.print_period_ms*TICKS_MS){
|
||
|
phy_sts_get(&total_sts);
|
||
|
iot_printf("mac tx ok:%d/4s, fc_ok:%d/4s, fc_err:%d/4s,", \
|
||
|
total_sts.mac_tx_ok_cnt,total_sts.fc_crc_ok_cnt, \
|
||
|
total_sts.fc_crc_fail_cnt);
|
||
|
iot_printf("pld_ok:%d/4s, pld fail:%d/4s, sync ok:%d/4s\r\n", \
|
||
|
total_sts.pld_crc_ok_cnt,total_sts.pld_crc_fail_cnt, \
|
||
|
total_sts.sync_ok_cnt);
|
||
|
|
||
|
/* mac rx cnt */
|
||
|
iot_printf("[MAC][rx-ring%d]:ring-%d, fc-%d, pkt-%d\r\n", 0, \
|
||
|
RGF_RX_READ_REG(CFG_RX_RING0_DBG_CNT_ADDR), \
|
||
|
RGF_RX_READ_REG(CFG_RX_FC_DBG_CNT_ADDR), \
|
||
|
RGF_RX_READ_REG(CFG_RX_PKT_DETECTED_CNT_ADDR));
|
||
|
RGF_RX_WRITE_REG(CFG_DBG_CNT_CLR_ADDR,0x1f);
|
||
|
RGF_RX_WRITE_REG(CFG_RX_DBG_CNT_CLR_ADDR,0xf);
|
||
|
|
||
|
/* 4s print all */
|
||
|
iot_printf("FC RAW DATA:%d\r\n", rd_idx);
|
||
|
do{
|
||
|
iot_printf("%02x %02x %02x %02x %02x %02x %02x %02x ", \
|
||
|
fc_raw[rd_idx][0]&0xFF, \
|
||
|
(fc_raw[rd_idx][0]&0xFF00)>>8, \
|
||
|
(fc_raw[rd_idx][0]&0xFF0000)>>16, \
|
||
|
(fc_raw[rd_idx][0]&0xFF000000)>>24, \
|
||
|
fc_raw[rd_idx][1]&0xFF, \
|
||
|
(fc_raw[rd_idx][1]&0xFF00)>>8, \
|
||
|
(fc_raw[rd_idx][1]&0xFF0000)>>16, \
|
||
|
(fc_raw[rd_idx][1]&0xFF000000)>>24);
|
||
|
iot_printf("%02x %02x %02x %02x %02x %02x %02x %02x\r\n",\
|
||
|
fc_raw[rd_idx][2]&0xFF, \
|
||
|
(fc_raw[rd_idx][2]&0xFF00)>>8, \
|
||
|
(fc_raw[rd_idx][2]&0xFF0000)>>16, \
|
||
|
(fc_raw[rd_idx][2]&0xFF000000)>>24, \
|
||
|
fc_raw[rd_idx][3]&0xFF, \
|
||
|
(fc_raw[rd_idx][3]&0xFF00)>>8, \
|
||
|
(fc_raw[rd_idx][3]&0xFF0000)>>16, \
|
||
|
(fc_raw[rd_idx][3]&0xFF000000)>>24);
|
||
|
fc_raw[rd_idx][0] = 0;
|
||
|
fc_raw[rd_idx][1] = 0;
|
||
|
fc_raw[rd_idx][2] = 0;
|
||
|
fc_raw[rd_idx][3] = 0;
|
||
|
}while(rd_idx--);
|
||
|
iot_printf("FC RAW DUMP DONE!\r\n");
|
||
|
|
||
|
/* clear cnt */
|
||
|
PHY_WRITE_REG(CFG_BB_FC_PLD_CNTR_CLR_ADDR,0xF);
|
||
|
rd_idx = 0;
|
||
|
start_time = end_time;
|
||
|
}
|
||
|
} while (true); /* keep check */
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/* zero cross */
|
||
|
void mac_rx_zero_cross_test()
|
||
|
{
|
||
|
#if TBD
|
||
|
uint32_t tmp = 0;
|
||
|
|
||
|
/* map AE21 to ZC0 */
|
||
|
gpio_mtx_enable();
|
||
|
gpio_sig_info_t info = {
|
||
|
1,
|
||
|
{
|
||
|
{IO_TYPE_IN, 0, 13, 48, 0xff}
|
||
|
}
|
||
|
};
|
||
|
gpio_module_pin_select(&info);
|
||
|
gpio_module_sig_select(&info, GPIO_MTX_MODE_MATRIX);
|
||
|
|
||
|
while(1)
|
||
|
{
|
||
|
/* trig en */
|
||
|
tmp = RGF_MAC_READ_REG(CFG_ZC_CAP_ADDR);
|
||
|
REG_FIELD_SET(CFG_ZC_TRIG, tmp , 1);
|
||
|
REG_FIELD_SET(CFG_ZC_CAP_INTERVAL, tmp , 0);
|
||
|
RGF_MAC_WRITE_REG(CFG_ZC_CAP_ADDR, tmp);
|
||
|
|
||
|
tmp = RGF_MAC_READ_REG(CFG_ZC_LCT_TRACK_CTRL_ADDR);
|
||
|
REG_FIELD_SET(CFG_ZC_VIBRATE_PROTECT, tmp, 375000);
|
||
|
RGF_MAC_WRITE_REG(CFG_ZC_LCT_TRACK_CTRL_ADDR, tmp);
|
||
|
|
||
|
do{
|
||
|
tmp = RGF_MAC_READ_REG(CFG_MAC_INT_STS_ADDR);
|
||
|
tmp = (tmp & 0x80000);
|
||
|
}while(!tmp);
|
||
|
|
||
|
/* clr intr */
|
||
|
RGF_MAC_WRITE_REG(CFG_MAC_INT_CLR_ADDR,0x80000);
|
||
|
|
||
|
/* print */
|
||
|
iot_printf("ZC TS:%u,%u,%u,%u,%u,%u,%u,%u\r\n", \
|
||
|
RGF_MAC_READ_REG(CFG_ZC0_TS0_ADDR), \
|
||
|
RGF_MAC_READ_REG(CFG_ZC0_TS1_ADDR), \
|
||
|
RGF_MAC_READ_REG(CFG_ZC0_TS2_ADDR), \
|
||
|
RGF_MAC_READ_REG(CFG_ZC0_TS3_ADDR), \
|
||
|
RGF_MAC_READ_REG(CFG_ZC0_TS4_ADDR), \
|
||
|
RGF_MAC_READ_REG(CFG_ZC0_TS5_ADDR), \
|
||
|
RGF_MAC_READ_REG(CFG_ZC0_TS6_ADDR), \
|
||
|
RGF_MAC_READ_REG(CFG_ZC0_TS7_ADDR));
|
||
|
|
||
|
/* period */
|
||
|
iot_printf("period:%u\r\n",RGF_MAC_READ_REG(CFG_ZC0_PERIOD_ADDR));
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void mac_rx_with_tx()
|
||
|
{
|
||
|
uint32_t cur_time = 0;
|
||
|
uint32_t start_time = 0, end_time = 0;
|
||
|
uint64_t time_span = 0;
|
||
|
iot_phy_sts_info_t total_sts = {0};
|
||
|
|
||
|
/* mac tx common init interface */
|
||
|
tx_common_init(IOT_PLC_PHY_BAND_DFT);
|
||
|
|
||
|
/* check if rx ring has content */
|
||
|
uint8_t *rx_buf_tmp;
|
||
|
start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
|
do {
|
||
|
while (!is_rx_ring0_empty())
|
||
|
{
|
||
|
rx_buf_tmp = pop_rx_buf_from_ring(0);
|
||
|
if (rx_buf_tmp) {
|
||
|
handle_rx_buf(rx_buf_tmp, RX_BUF_DW_SIZE << 2);
|
||
|
}
|
||
|
}
|
||
|
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;
|
||
|
}
|
||
|
if((uint64_t)time_span > g_plc_dt_ctxt.indep.print_period_ms*TICKS_MS){
|
||
|
phy_sts_get(&total_sts);
|
||
|
iot_printf("[CNT][mac]tx_ok:%d/4s\n"
|
||
|
"[CNT][phy]fc_ok:%d/4s, fc_err:%d/4s,", \
|
||
|
total_sts.mac_tx_ok_cnt,total_sts.fc_crc_ok_cnt, \
|
||
|
total_sts.fc_crc_fail_cnt);
|
||
|
iot_printf("pld_ok:%d/4s, pld_fail:%d/4s, sync_ok:%d/4s\r\n", \
|
||
|
total_sts.pld_crc_ok_cnt,total_sts.pld_crc_fail_cnt, \
|
||
|
total_sts.sync_ok_cnt);
|
||
|
start_time = end_time;
|
||
|
}
|
||
|
|
||
|
/* mac tx */
|
||
|
cur_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
|
if(cur_time%100000 > 90000){
|
||
|
mac_tx_mpdu_test(NULL, mpdu_start);
|
||
|
dt_mac_tx_hwq0_re_trig();
|
||
|
}
|
||
|
} while (true); /* keep check */
|
||
|
}
|
||
|
|
||
|
void mac_rx_three_phase()
|
||
|
{
|
||
|
uint32_t start_time = 0, end_time = 0;
|
||
|
uint64_t time_span = 0;
|
||
|
iot_phy_sts_info_t total_sts = {0};
|
||
|
uint32_t tmp = 0;
|
||
|
|
||
|
/* phase config */
|
||
|
*(uint32_t *)0x51c00420 = 0x2 | (0x8 << 6) | (0x20 << 12) | (0x2a << 18);
|
||
|
|
||
|
/* phase A */
|
||
|
tmp = RGF_MAC_READ_REG(CFG_PHY_FORCE_0_ADDR);
|
||
|
REG_FIELD_SET(CFG_PHY_RX_PHASE_SEL, tmp, 0);
|
||
|
REG_FIELD_SET(CFG_PHY_RX_PHASE_SEL_FORCE_EN, tmp, 1);
|
||
|
RGF_MAC_WRITE_REG(CFG_PHY_FORCE_0_ADDR, tmp);
|
||
|
|
||
|
/* attenuate */
|
||
|
*(uint32_t *)0x51800690 = 0x0AAA0000;
|
||
|
|
||
|
/* sw phase cfg en */
|
||
|
*(uint32_t *)0x51c0041c |= 0x80000000;
|
||
|
|
||
|
/* check if rx ring has content */
|
||
|
uint8_t *rx_buf_tmp;
|
||
|
start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
|
||
|
do {
|
||
|
while (!is_rx_ring0_empty())
|
||
|
{
|
||
|
rx_buf_tmp = pop_rx_buf_from_ring(0);
|
||
|
if (rx_buf_tmp) {
|
||
|
handle_rx_buf(rx_buf_tmp, RX_BUF_DW_SIZE << 2);
|
||
|
}
|
||
|
}
|
||
|
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;
|
||
|
}
|
||
|
if((uint64_t)time_span > g_plc_dt_ctxt.indep.print_period_ms*TICKS_MS){
|
||
|
phy_sts_get(&total_sts);
|
||
|
iot_printf("[CNT][mac]tx_ok:%d/4s\n"
|
||
|
"[CNT][phy]fc_ok:%d/4s, fc_err:%d/4s,", \
|
||
|
total_sts.mac_tx_ok_cnt,total_sts.fc_crc_ok_cnt, \
|
||
|
total_sts.fc_crc_fail_cnt);
|
||
|
iot_printf("pld_ok:%d/4s, pld_fail:%d/4s, sync_ok:%d/4s\r\n", \
|
||
|
total_sts.pld_crc_ok_cnt,total_sts.pld_crc_fail_cnt, \
|
||
|
total_sts.sync_ok_cnt);
|
||
|
start_time = end_time;
|
||
|
}
|
||
|
} while (true); /* keep check */
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* spur filter:
|
||
|
* 1.spur mask: tone mask table
|
||
|
* 2.notch filter: dfe module
|
||
|
*/
|
||
|
void mac_rx_spur_mask()
|
||
|
{
|
||
|
/* config spur mask*/
|
||
|
phy_spur_mask_set(123,6);
|
||
|
phy_spur_mask_set(246,6);
|
||
|
phy_spur_mask_set(328,6);
|
||
|
|
||
|
/* normal tx */
|
||
|
mac_rx_single_mode(false);
|
||
|
}
|
||
|
|
||
|
/* alpha config:
|
||
|
* freq 1M: 0x8073
|
||
|
* freq 3M: 0x8405
|
||
|
* freq 6M: 0x8fd5
|
||
|
* freq 8M: 0x9bb0
|
||
|
* freq 15M: 0xd872
|
||
|
*/
|
||
|
void mac_rx_notch_filter()
|
||
|
{
|
||
|
/* band0 1M/8M/15M */
|
||
|
if(all_mask_band_table_r0_full.start_tone == 80 && \
|
||
|
all_mask_band_table_r0_full.end_tone == 490)
|
||
|
{
|
||
|
phy_anf_option_set(PHY_ANF_MODE_FIX,1,1,0x8073);
|
||
|
phy_anf_option_set(PHY_ANF_MODE_FIX,1,1,0x9bb0);
|
||
|
|
||
|
/* config spur mask*/
|
||
|
//phy_spur_mask_set(123,30);
|
||
|
//phy_spur_mask_set(246,30);
|
||
|
phy_spur_mask_set(328,30);
|
||
|
}
|
||
|
/* band0 1M/3M/6M */
|
||
|
else if(all_mask_band_table_r0_full.start_tone == 100 && \
|
||
|
all_mask_band_table_r0_full.end_tone == 230)
|
||
|
{
|
||
|
phy_anf_option_set(PHY_ANF_MODE_FIX,1,1,0x8073);
|
||
|
phy_anf_option_set(PHY_ANF_MODE_FIX,1,2,0x8405);
|
||
|
|
||
|
/* config spur mask*/
|
||
|
phy_spur_mask_set(123,30);
|
||
|
//phy_spur_mask_set(246,30);
|
||
|
//phy_spur_mask_set(328,30);
|
||
|
}
|
||
|
|
||
|
/* normal tx */
|
||
|
mac_rx_single_mode(false);
|
||
|
}
|
||
|
|
||
|
void mac_rx_nf_td_self()
|
||
|
{
|
||
|
uint8_t nf = 0;
|
||
|
uint32_t i = 0;
|
||
|
|
||
|
while(1)
|
||
|
{
|
||
|
nf = phy_rx_nf_by_rxtd_get(12);
|
||
|
iot_printf("Gain-NF: %hd\r\n", nf);
|
||
|
for(i=0; i < 1000000; i++){};
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* WAR for GP tmi fix and SPG ext tmi fix */
|
||
|
void phy_rx_tmi_fix()
|
||
|
{
|
||
|
/* normal tx */
|
||
|
mac_rx_single_mode(false);
|
||
|
}
|
||
|
|
||
|
void phy_rx_snr_cal_scan()
|
||
|
{
|
||
|
iot_phy_info_t phy_info = {0};
|
||
|
|
||
|
/* fd snr range */
|
||
|
for(int8_t i = -10; i < 100; i++)
|
||
|
{
|
||
|
/* fd snr */
|
||
|
phy_info.avg_snr = i;
|
||
|
/* loop start */
|
||
|
iot_printf("[FD]:%d\n", i);
|
||
|
for(int8_t j = -50; j <= 50; )
|
||
|
{
|
||
|
/* gain = 0, nf = 0 */
|
||
|
phy_info.adc_power = i + j + 10;
|
||
|
phy_info.agc_tbl_entry = 24;
|
||
|
g_phy_ctxt.dep.nf = 0;
|
||
|
iot_printf("[SNR]:%d\n", phy_rx_snr_cal(&phy_info, 1));
|
||
|
j = j + 10;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void phy_rx_fft_dump_loop()
|
||
|
{
|
||
|
uint32_t i = 0;
|
||
|
uint32_t tone_idx = 0;
|
||
|
int8_t current_gain = 0;
|
||
|
int16_t csi_i = 0, csi_q = 0;
|
||
|
uint32_t csi_buf[IOT_PHY_CSI_BUF_LEN >> 2] = {0};
|
||
|
|
||
|
phy_reset(PHY_RST_REASON_WARM);
|
||
|
|
||
|
do {
|
||
|
/* get average gain */
|
||
|
current_gain = phy_gain_get_from_agc();
|
||
|
|
||
|
/* get valid fft dump */
|
||
|
for(i = 0; i < PHY_CHN_EST_AI_RTY_CNT; i++)
|
||
|
{
|
||
|
/* trig fft to dump */
|
||
|
phy_rx_fft_dump(csi_buf, current_gain, 0, 1);
|
||
|
|
||
|
/* cal csi for every tone for debug*/
|
||
|
for(tone_idx = 0; tone_idx < (IOT_PHY_CSI_BUF_LEN >> 2); tone_idx++)
|
||
|
{
|
||
|
csi_i = (int16_t)(*(csi_buf + tone_idx) & 0xFFFF);
|
||
|
csi_q = (int16_t)(*(csi_buf + tone_idx) >> 16);
|
||
|
iot_printf("tone:%u, csi_i:%d, csi_q:%d, dB:%u\n", \
|
||
|
tone_idx, \
|
||
|
csi_i, \
|
||
|
csi_q, \
|
||
|
(uint32_t)(10 * mlog10(csi_i * csi_i + csi_q * csi_q + 1)));
|
||
|
}
|
||
|
}
|
||
|
} while(1);
|
||
|
}
|
||
|
|
||
|
uint32_t phy_rx_sound_snr_dump()
|
||
|
{
|
||
|
uint32_t ret = ERR_OK;
|
||
|
uint32_t tone_idx = 0;
|
||
|
int32_t snr_buf[TONE_MAX_NUM] = {0};
|
||
|
|
||
|
/* config sump condition */
|
||
|
phy_sound_dump_cond_set(true, 0xb, true, 2);
|
||
|
|
||
|
/* enable and trig begin */
|
||
|
ret = phy_rx_sound_snr_get( \
|
||
|
0, TONE_MAX_NUM, snr_buf, PHY_DUMP_DLY_CNT);
|
||
|
|
||
|
if(ret != ERR_OK) {
|
||
|
iot_printf("file=%s,func=%s,line=%d fail!\n", \
|
||
|
__FILE__, __FUNCTION__, __LINE__);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/* cal snr for every tone */
|
||
|
for(tone_idx = 0; tone_idx < TONE_MAX_NUM; tone_idx++)
|
||
|
{
|
||
|
iot_printf("tone%d snr:%d\r\n",tone_idx, snr_buf[tone_idx]);
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
void phy_rx_gp_hybrid_mode_test()
|
||
|
{
|
||
|
#if SUPPORT_GREEN_PHY
|
||
|
/* check protocol */
|
||
|
IOT_ASSERT(glb_cfg.m_type == PLC_PROTO_TYPE_GP);
|
||
|
|
||
|
/* init gp hybrid mode */
|
||
|
phy_gp_hybrid_mode_init();
|
||
|
|
||
|
/* update ppdu mode */
|
||
|
glb_cfg.ppdu_mode = HW_DESC_PPDU_MODE_HYBRID_1FCSYM;
|
||
|
|
||
|
mac_rx_single_mode(false);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void phy_rx_tmap_test()
|
||
|
{
|
||
|
#if SUPPORT_GREEN_PHY
|
||
|
/* check protocol */
|
||
|
IOT_ASSERT(glb_cfg.m_type == PLC_PROTO_TYPE_GP);
|
||
|
|
||
|
/* some conf overwrite by tmap */
|
||
|
phy_gp_burst_init();
|
||
|
/* tmap common config must behind burst */
|
||
|
phy_tmap_common_init();
|
||
|
/* self tmi */
|
||
|
phy_tmap_self_tmi_set(2);
|
||
|
/* mac tmap init */
|
||
|
mac_tmap_init();
|
||
|
|
||
|
mac_rx_single_mode(false);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void phy_rx_av_burst_test()
|
||
|
{
|
||
|
#if SUPPORT_GREEN_PHY
|
||
|
/* check protocol */
|
||
|
IOT_ASSERT(glb_cfg.m_type == PLC_PROTO_TYPE_GP);
|
||
|
|
||
|
/* init burst mode */
|
||
|
phy_gp_burst_init();
|
||
|
|
||
|
mac_rx_single_mode(false);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
static void dump_mem(uint8_t *mem_buf, int32_t st_offset, uint32_t b_size)
|
||
|
{
|
||
|
#if 1
|
||
|
int16_t *p_addr = NULL;
|
||
|
|
||
|
p_addr = (int16_t *)(mem_buf + st_offset);
|
||
|
iot_printf("[dump]\n");
|
||
|
while(p_addr < (int16_t *)(mem_buf + b_size))
|
||
|
{
|
||
|
|
||
|
iot_printf("%x: %06d\n", p_addr,*p_addr);
|
||
|
iot_printf("%x: %06d\n", p_addr+1,*(p_addr+1));
|
||
|
p_addr += 2;
|
||
|
}
|
||
|
#else
|
||
|
uint32_t *p_addr = NULL;
|
||
|
|
||
|
p_addr = (uint32_t *)(mem_buf + st_offset);
|
||
|
iot_printf("[dump]\n");
|
||
|
while(p_addr < (uint32_t *)(mem_buf + b_size))
|
||
|
{
|
||
|
iot_printf("%x: %u\n", p_addr,*p_addr);
|
||
|
p_addr++;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void mac_rx_ada_dump_test(void)
|
||
|
{
|
||
|
uint16_t cur_tone_id = 0;
|
||
|
uint32_t b_size = 1024*4;
|
||
|
uint32_t s_size = 1024*4;
|
||
|
uint32_t trig_offset = 0;
|
||
|
uint8_t *adc_buf = (uint8_t *)AHB_RAM3_BASEADDR;
|
||
|
|
||
|
uint8_t glna = 4;
|
||
|
uint8_t gpga = 0;
|
||
|
uint8_t gbq = 3;
|
||
|
uint8_t gpgf = 3;
|
||
|
|
||
|
/* sw control tx rx */
|
||
|
phy_ana_hw_en_bitmap(0);
|
||
|
/* force adc/rx enable and disable tx */
|
||
|
phy_ana_rx_fe_set(1);
|
||
|
phy_ana_adc_set(1);
|
||
|
phy_ana_top_enlic_rx_set(1);
|
||
|
phy_ana_top_enlic_tx_set(0);
|
||
|
phy_ana_top_dac_en(0);
|
||
|
phy_ana_top_tx_en(0);
|
||
|
|
||
|
/* force rx gain */
|
||
|
phy_ana_rx_glna(glna);
|
||
|
phy_ana_rx_fe_gpga(gpga);
|
||
|
phy_ana_rx_fe_gbq(gbq);
|
||
|
phy_ana_rx_fe_gpgf(gpgf);
|
||
|
|
||
|
/* fix gain and disable agc */
|
||
|
phy_agc_gain_lvl_set(1, 60, -24, 0);
|
||
|
phy_dump_from_ada(b_size, \
|
||
|
s_size, \
|
||
|
cur_tone_id, \
|
||
|
ADC_DUMP_MODE_SUPPORT, \
|
||
|
PHY_PHASE_OVR_A, \
|
||
|
&trig_offset, \
|
||
|
adc_buf, \
|
||
|
ADC_DUMP_SPEED_SUPPORT, \
|
||
|
NULL);
|
||
|
dump_mem(adc_buf, 0, b_size);
|
||
|
}
|
||
|
|
||
|
void mac_rx_test()
|
||
|
{
|
||
|
platform_rx_pre_init();
|
||
|
|
||
|
#if HW_PLATFORM > HW_PLATFORM_SIMU
|
||
|
#if EDA_SIMU_SUPPORT != 1
|
||
|
iot_print_config(true);
|
||
|
|
||
|
/* serial init */
|
||
|
dbg_uart_init();
|
||
|
iot_printf("mac_rx_test begin...\n");
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
/* basic data struct init for bit ops */
|
||
|
iot_bitops_init();
|
||
|
|
||
|
#if SUPPORT_SMART_GRID
|
||
|
glb_cfg.m_type = PLC_PROTO_TYPE_SG;
|
||
|
#elif SUPPORT_SOUTHERN_POWER_GRID
|
||
|
glb_cfg.m_type = PLC_PROTO_TYPE_SPG;
|
||
|
#endif
|
||
|
|
||
|
/* mac rx initial */
|
||
|
mac_rx_init(IOT_PLC_PHY_BAND_DFT);
|
||
|
|
||
|
/* setup the rx ring */
|
||
|
rx_ring_setup_hw(0, NULL);
|
||
|
|
||
|
/* enable the rx ring */
|
||
|
rx_ring_enable(0, true);
|
||
|
|
||
|
#if 0
|
||
|
/* disable intr */
|
||
|
PHY_WRITE_REG(CFG_BB_INT_EN_0_ADDR, 0);
|
||
|
PHY_WRITE_REG(CFG_BB_INT_EN_1_ADDR, 0);
|
||
|
PHY_WRITE_REG(CFG_BB_INT_EN_2_ADDR, 0);
|
||
|
PHY_WRITE_REG(CFG_BB_INT_EN_3_ADDR, 0);
|
||
|
#endif
|
||
|
|
||
|
mac_csi_back_t info;
|
||
|
csi_est_dump_cond cond;
|
||
|
|
||
|
switch(MAC_RX_TEST_ID)
|
||
|
{
|
||
|
case MAC_RX_PKT:
|
||
|
mac_rx_single_mode(false);
|
||
|
break;
|
||
|
case MAC_RX_SNR_SCAN:
|
||
|
mac_rx_snr_scan();
|
||
|
break;
|
||
|
case MAC_RX_CSI_SCAN:
|
||
|
mac_rx_csi_scan();
|
||
|
break;
|
||
|
case MAC_RX_NOISE_FLOOR_SCAN:
|
||
|
mac_rx_noise_floor_scan();
|
||
|
break;
|
||
|
case MAC_RX_SOUND_SNR_DUMP:
|
||
|
phy_rx_sound_snr_dump();
|
||
|
break;
|
||
|
case MAC_PPM_CALIBRATION:
|
||
|
mac_rx_ppm_cali();
|
||
|
break;
|
||
|
case MAC_RX_FC_FROM_PHY:
|
||
|
mac_rx_fc_from_phy();
|
||
|
break;
|
||
|
case MAC_RX_ZC:
|
||
|
mac_rx_zero_cross_test();
|
||
|
break;
|
||
|
case MAC_RX_WITH_TX:
|
||
|
mac_rx_with_tx();
|
||
|
break;
|
||
|
case MAC_RX_THREE_PHASE:
|
||
|
mac_rx_three_phase();
|
||
|
break;
|
||
|
case MAC_RX_LOOPBACK:
|
||
|
phy_granite_loopback(IOT_PLC_PHY_BAND_DFT);
|
||
|
break;
|
||
|
case MAC_RX_SPUR_MASK:
|
||
|
mac_rx_spur_mask();
|
||
|
break;
|
||
|
case MAC_RX_NOTCH_FILTER:
|
||
|
mac_rx_notch_filter();
|
||
|
break;
|
||
|
case MAC_RX_PPM_CAL:
|
||
|
mac_rx_single_mode(false);
|
||
|
break;
|
||
|
case MAC_RX_NF_SELF:
|
||
|
mac_rx_nf_td_self();
|
||
|
break;
|
||
|
case MAC_RX_CSI_DUMP:
|
||
|
mac_rx_csi_dump(&info, &cond, 0);
|
||
|
break;
|
||
|
case MAC_RX_FFT_DUMP:
|
||
|
phy_rx_fft_dump_loop();
|
||
|
break;
|
||
|
case PHY_RX_TMI_FIX:
|
||
|
phy_rx_tmi_fix();
|
||
|
break;
|
||
|
case MAC_TX_PHY_SNR_CAL:
|
||
|
phy_rx_snr_cal_scan();
|
||
|
break;
|
||
|
case MAC_RX_GP_TMAP:
|
||
|
phy_rx_tmap_test();
|
||
|
break;
|
||
|
case MAC_RX_GP_HYBRID:
|
||
|
phy_rx_gp_hybrid_mode_test();
|
||
|
break;
|
||
|
case PHY_RX_BURST_MODE:
|
||
|
phy_rx_av_burst_test();
|
||
|
break;
|
||
|
case MAC_RX_SOFTBIT_DUMP:
|
||
|
mac_rx_softbit_dump();
|
||
|
break;
|
||
|
case MAC_RX_SPUR_SCAN:
|
||
|
mac_rx_spur_scan();
|
||
|
break;
|
||
|
case MAC_RX_ADA_DUMP:
|
||
|
mac_rx_ada_dump_test();
|
||
|
break;
|
||
|
default:
|
||
|
IOT_ASSERT(0);
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
#ifdef __GNUC__
|
||
|
#if !MODULE_EN
|
||
|
|
||
|
int main(void) {
|
||
|
mac_rx_test();
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
#endif // __GCC__
|
||
|
|