/**************************************************************************** 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 "hw_tonemask.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 "phy_ana.h" #include "phy_reg.h" #include "mpdu_frame.h" #include "ahb_rf.h" #include "mac_tx_main.h" #include "intc_reg.h" #include "apb_glb_reg.h" #include "command_list.h" #include "dbg_io.h" #include "iot_config.h" #include "iot_io.h" #include "phy_rx_fd_reg.h" #include "phy_txrx_pwr.h" #include "plc_protocol.h" #include "clk.h" #include "iot_wdg.h" #include "hal_rx.h" #include "tx_entry.h" #include "hw_phy_api.h" #include "hw_tx.h" #include "phy_mix.h" #include "phy_chn.h" #if TARGET_VERSION == 2 #include "phy_tmap.h" #endif uint32_t mac_tx_single_mode() { volatile uint32_t tx_done = 0; uint32_t enq_time = 0, cur_time = 0; int64_t time_span = 0; uint32_t start_time = 0, end_time = 0; iot_phy_sts_info_t total_sts = {0}; uint32_t rate_idx = 0; uint32_t band_idx = 0; #if PHY_TX_ALWAYS_EN == 1 phy_ctrl_tx_always_en(true); #endif start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);/*for cnt*/ /* beacon or sof transmit */ do { enq_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);/*for tx*/ /* send the beacon */ mac_tx_mpdu_test(NULL, mpdu_start); /* hwq config */ dt_mac_hwq0_ptr_set((uint32_t)mpdu_start); /* multi hwq */ if (glb_cfg.hwq_num > 1) { dt_mac_hwq1_ptr_set((uint32_t)mpdu_start); } dt_mac_tx_hwq0_re_trig(); do { // wait for tx done and hwq disable cur_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); time_span = cur_time - enq_time; if (time_span < 0) { // wrap around time_span = (0x100000000LL) - enq_time + cur_time; } tx_done = phy_get_tx_done_from_mpdu(mpdu_start); } while (!tx_done \ || ((uint64_t)time_span < bcn_period_ms * TICKS_MS)); /* tx cnt print */ 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 > print_tx_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); start_time = end_time; #if MAC_TX_TEST_ID == MAC_TX_BURN mpdu_start->resv++; wdg_feed_dog(1); iot_printf("4s cnt %u, feed dog!\r\n",mpdu_start->resv); #endif /* band info */ for(rate_idx=0; rate_idx sg_tonemap_table[i].max_pb_num) { continue; } } else { /* mask unused TMI in ext table */ if(sg_ext_tonemap_table[i-15].pb_size == 0 || \ j > sg_ext_tonemap_table[i-15].max_pb_num) { continue; } } #if IOT_PLC_PHY_BAND_DFT == IOT_SUPPORT_TONE_100_230 /* total symb num >= 512*/ if((i == 7 && j >= 2) || (i == 8 && j >= 2) || \ (i == 3 && j >= 3) || (i == 9 && j >= 3) || \ (i == 12 && j >= 3) || (i == 0 && j == 4) || \ (i == 10 && j == 4)) continue; #endif } else #endif #if (SUPPORT_SOUTHERN_POWER_GRID) if (PHY_PROTO_TYPE_GET() == PLC_PROTO_TYPE_SPG) { if (i < 15) { /* mask some unused TMI */ if (spg_tonemap_table[i].pb_size == 0 || \ j > spg_tonemap_table[i].max_pb_num) { continue; } } else { /* mask unused TMI in ext table */ if (spg_ext_tonemap_table[i-15].pb_size == 0 || \ j > spg_ext_tonemap_table[i-15].max_pb_num) { continue; } } } #endif #if (SUPPORT_GREEN_PHY) if(PHY_PROTO_TYPE_GET() == PLC_PROTO_TYPE_GP) { /* mask some unused TMI */ if(gp_tonemap_table[i].pb_size == 0 || \ j > gp_tonemap_table[i].max_pb_num) continue; /* max tmi */ if(i >= GP_TMI_MAX) continue; } #endif {/* MACRO format */} glb_cfg.tmi = i; glb_cfg.pb_num = j; tmi_retry_cnt = MAC_TMI_SCAN_CNT; while(tmi_retry_cnt--) { enq_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);/*for tx*/ /* send the beacon */ mac_tx_mpdu_test(NULL, mpdu_start); dt_mac_tx_hwq0_re_trig(); do { // wait for tx done and hwq disable cur_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); time_span = cur_time - enq_time; if (time_span < 0) { // wrap around time_span = (0x100000000LL) - enq_time + cur_time; } tx_done = phy_get_tx_done_from_mpdu(mpdu_start); } while (!tx_done \ || ((uint64_t)time_span < bcn_period_ms * TICKS_MS)); } phy_sts_get(&total_sts); iot_printf("[TMI-%d][PB-%d]:\r\nmac tx ok:%d/4s," " fc_ok:%d/4s, fc_err:%d/4s,", \ glb_cfg.tmi, glb_cfg.pb_num, 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); } } return 0; } uint32_t mac_tx_bcn_alert() { uint32_t tmp1 = 0; /* beacon alert */ do { /* beacon period */ RGF_MAC_WRITE_REG(CFG_BEACON_PERIOD_ADDR, 0xffff0000);//1000ms /* beacon alert ahead */ RGF_MAC_WRITE_REG(CFG_BEACON_ADDR,1); /* scedule */ tmp1 = RGF_HWQ_READ_REG(CFG_SCHEDULE_ADDR); REG_FIELD_SET(CFG_SCH_EN,tmp1,1); REG_FIELD_SET(CFG_SCH_CMD_NUM,tmp1,0); REG_FIELD_SET(CFG_SCH_WR_TRIG,tmp1,1); REG_FIELD_SET(CFG_SCH_SELF_RECUR_EN,tmp1,1); REG_FIELD_SET(SCH_WR_TRIG_ENABLE,tmp1,0); REG_FIELD_SET(SCH_CUR_NUM,tmp1,0); RGF_HWQ_WRITE_REG(CFG_SCHEDULE_ADDR,tmp1); while(!mac_beacon_alert_flag); mac_beacon_alert_flag = false; } while (true); return 0; } uint32_t mac_tx_complete() { int64_t time_span = 0; uint32_t start_time = 0, end_time = 0; iot_phy_sts_info_t total_sts = {0}; uint32_t start1_time = 0, end1_time = 0; uint32_t rate_idx = 0; uint32_t band_idx = 0; /* tx complete */ start1_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);/*for print*/ do { /* send the beacon/sof */ mac_tx_mpdu_test(NULL, mpdu_start); dt_mac_tx_hwq0_re_trig(); while(!mac_tx_complete_flag); mac_tx_complete_flag = false; start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);/*for tx*/ do { // wait for tx done and hwq disable 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 < (bcn_period_ms-5) * TICKS_MS); /* tx cnt print */ end1_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); time_span = end1_time - start1_time; if (time_span < 0) { // wrap around time_span = (0x100000000LL) - start1_time + end1_time; } if((uint64_t)time_span > print_tx_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); start1_time = end1_time; /* band info */ for(rate_idx=0; rate_idx 1) ? 0 : (tmi + 1); /* tx cnt print */ 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 > print_tx_period_ms*TICKS_MS){ /* print sts */ phy_sts_get(&total_sts); iot_printf("[TMI-%d]:\n", glb_cfg.tmi); 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); start_time = end_time; /* band info */ for(rate_idx=0; rate_idx bcn_time_period*TICKS_MS){ if(bcn_index < 9) { /* -20dB power */ if(!bcn_index) { phy_pwr_adjust_set(127); } bcn_index++; } else { bcn_index = 0; /* full power */ phy_pwr_adjust_set(137); } glb_cfg.tmi = 3; glb_cfg.p_type = FC_DELIM_BEACON; /* send the beacon */ mac_tx_mpdu_test(NULL, mpdu_start); dt_mac_tx_hwq0_re_trig(); do { // wait for tx done and hwq disable tx_done = phy_get_tx_done_from_mpdu(mpdu_start); } while (!tx_done); last_time = cur_time; } /* sof time span */ 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 > sof_time_period*TICKS_MS){ /* update config */ glb_cfg.tmi = 7; glb_cfg.p_type = FC_DELIM_SOF; glb_cfg.ack_en = 0; /* send the sof */ mac_tx_mpdu_test(NULL, mpdu_start); dt_mac_tx_hwq0_re_trig(); do { // wait for tx done and hwq disable tx_done = phy_get_tx_done_from_mpdu(mpdu_start); } while (!tx_done); start_time = end_time; } dly_end_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); time_span = dly_end_time - dly_start_time; if (time_span < 0) { // wrap around time_span = (0x100000000LL) - dly_start_time + dly_end_time; } if((uint64_t)time_span > 4000*TICKS_MS){ /* print tx cnt */ 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); /* band info */ for(rate_idx=0; rate_idx print_tx_period_ms*TICKS_MS) { /* update band id */ glb_cfg.band_id = !glb_cfg.band_id; /* pre reinit */ mac_set_sw_idle_mode(1, 1); mac_wait_phy_txrx_idle(); mac_force_phy_tx_ready(1, 1); /* wait hwq to be idle */ mac_tx_wait_all_queue_idle(true, 30); /* mac rst hold */ //warm_rst_mac_hold(); /* phy reinit */ phy_reinit(PLC_PROTO_TYPE_SG, glb_cfg.band_id, TONE_MASK_ID_NULL, true); /* mac rst release */ //warm_rst_mac_release(); /* release idle mode */ mac_force_phy_tx_ready(0, 0); /* must del ena after del force */ mac_set_sw_idle_mode(1,0); mac_set_sw_idle_mode(0,0); /* print sts */ phy_sts_get(&total_sts); iot_printf("[TMI-%d]:\n", glb_cfg.tmi); 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); start_time = end_time; /* band info */ for(rate_idx=0; rate_idx HW_PLATFORM_SIMU #if EDA_SIMU_SUPPORT != 1 iot_print_config(true); /* serial init */ dbg_uart_init(); iot_printf("mac_tx_test begin...\n"); #endif #endif /* mac tx common init interface */ tx_common_init(IOT_PLC_PHY_BAND_DFT); /* mac rx common init interface */ rx_common_init(IOT_PLC_PHY_BAND_DFT); #if defined(MODULE_EN) if(glb_cfg.t_type == MAC_TX_SCHED_BCN_AHEAD_ALERT) iot_printf("[Error]: Must debug mode...\n"); /* send the beacon/sof */ mac_tx_mpdu_test(NULL, mpdu_start); dt_mac_tx_hwq0_re_trig(); while(!mac_tx_complete_flag); mac_tx_complete_flag = false; return; #endif #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 switch(MAC_TX_TEST_ID) { case MAC_TX_BEACON: case MAC_TX_SOF: mac_tx_single_mode(); break; case MAC_TX_TMI: phy_interrupt_init(); mac_tx_tmi_scan(); break; case MAC_TX_INTR_BCN_ALT: mac_tx_bcn_alert(); break; case MAC_TX_INTR_MPDU_COMPLETE: mac_tx_complete(); break; case MAC_TX_SCHED_BCN_AHEAD_ALERT: mac_tx_sched(); break; case MAC_TX_MIX_MODE: mac_tx_mix(); break; case MAC_TX_GP_EXT: mac_tx_gp_ext(); break; case MAC_TX_GP_TONE_MASK: mac_tx_gp_tone_mask(); break; case MAC_TX_BURN: mac_tx_single_mode(); break; case MAC_TX_BAND_SWITCH: mac_tx_band_switch(); break; case MAC_TX_PHY_TD_START: phy_tx_td_start_test(); break; case MAC_TX_EMC_SCAN: phy_tx_emc_scan(); break; case MAC_PHY_RST_FLOW: mac_phy_rst_flow(); break; case MAC_SOUND_TMAP: mac_tmap_test(); break; case MAC_TX_GP_HYBRID: phy_gp_hybrid_mode_test(); break; case PHY_BURST_MODE: phy_gp_burst_mode_test(); break; default: while(true); } return; } #if !MODULE_EN int main(void) { mac_tx_start(); return 0; } #endif