882 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			882 lines
		
	
	
		
			24 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 "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"
 | 
						|
#if (TARGET_VERSION == TARGET_KUNLUN2)
 | 
						|
#include "phy_dump.h"
 | 
						|
#include "phy_tmap.h"
 | 
						|
#endif
 | 
						|
#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};
 | 
						|
 | 
						|
#if TARGET_VERSION == TARGET_KUNLUN
 | 
						|
    ret = phy_rx_snr_get(0, TONE_MAX_NUM, snr_buf);
 | 
						|
#else
 | 
						|
    ret = phy_rx_snr_get( \
 | 
						|
        0, TONE_MAX_NUM, snr_buf, PHY_DUMP_DLY_CNT);
 | 
						|
#endif
 | 
						|
 | 
						|
    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};
 | 
						|
 | 
						|
#if TARGET_VERSION == TARGET_KUNLUN
 | 
						|
    ret = phy_rx_csi_get(0, TONE_MAX_NUM, csi_buf);
 | 
						|
#else
 | 
						|
    ret = phy_rx_csi_get( \
 | 
						|
        0, TONE_MAX_NUM, csi_buf, PHY_DUMP_DLY_CNT);
 | 
						|
#endif
 | 
						|
 | 
						|
    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};
 | 
						|
 | 
						|
#if TARGET_VERSION == TARGET_KUNLUN
 | 
						|
    ret = phy_rx_noise_floor_get(0, TONE_MAX_NUM, nf_buf);
 | 
						|
#else
 | 
						|
    ret = phy_rx_noise_floor_get( \
 | 
						|
        0, TONE_MAX_NUM, nf_buf, PHY_DUMP_DLY_CNT, PHY_SNR_DUMP_NF);
 | 
						|
#endif
 | 
						|
 | 
						|
    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()
 | 
						|
{
 | 
						|
    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));
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
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()
 | 
						|
{
 | 
						|
#if TARGET_VERSION < 2
 | 
						|
    phy_interrupt_init();
 | 
						|
#endif
 | 
						|
 | 
						|
    /* 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;
 | 
						|
#if TARGET_VERSION > 1
 | 
						|
    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]);
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
    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
 | 
						|
}
 | 
						|
 | 
						|
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();
 | 
						|
 | 
						|
    /* 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;
 | 
						|
        default:
 | 
						|
            IOT_ASSERT(0);
 | 
						|
    }
 | 
						|
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
#ifdef __GNUC__
 | 
						|
#if !MODULE_EN
 | 
						|
 | 
						|
int main(void) {
 | 
						|
    mac_rx_test();
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
#endif
 | 
						|
#endif // __GCC__
 | 
						|
 |