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__
 | |
| 
 |