Files
kunlun/dtest/mac_tx_test/mac_tx_main.c
2024-09-28 14:24:04 +08:00

1026 lines
33 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 "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<MAC_BB_MAX_RATE; rate_idx++)
{
for(band_idx=0; band_idx<MAX_HW_BAND; band_idx++)
{
if(band_cnt[rate_idx][band_idx] != 0){
iot_printf("[RATE-%d][BAND-%d]:%d\r\n", \
rate_idx, band_idx, band_cnt[rate_idx][band_idx]);
band_cnt[rate_idx][band_idx] = 0;
}
}
}
}
} while (true);
return 0;
}
extern tonemap_table_entry spg_tonemap_table[];
extern tonemap_table_entry spg_ext_tonemap_table[];
extern tonemap_table_entry sg_tonemap_table[];
extern tonemap_table_entry sg_ext_tonemap_table[];
extern tonemap_table_entry gp_tonemap_table[];
uint32_t mac_tx_tmi_scan()
{
uint32_t tx_done = 0;
uint32_t enq_time = 0, cur_time = 0;
int64_t time_span = 0;
iot_phy_sts_info_t total_sts = {0};
uint32_t tmi_retry_cnt = 0;
/* pb num for each tmi */
for(uint32_t j=1; j<5; j++)
{
for(uint32_t i=0; i<MAC_EXT_TMI_MAX; i++)
{
#if (SUPPORT_SMART_GRID)
if(PHY_PROTO_TYPE_GET() == PLC_PROTO_TYPE_SG) {
if(i < 15) {
/* mask unused TMI in standard table */
if(sg_tonemap_table[i].pb_size == 0 || \
j > 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<MAC_BB_MAX_RATE; rate_idx++)
{
for(band_idx=0; band_idx<MAX_HW_BAND; band_idx++)
{
if(band_cnt[rate_idx][band_idx] != 0){
iot_printf("[RATE-%d][BAND-%d]:%d\r\n", \
rate_idx, band_idx, band_cnt[rate_idx][band_idx]);
band_cnt[rate_idx][band_idx] = 0;
}
}
}
}
} while (true);
return 0;
}
uint32_t mac_tx_sched()
{
uint32_t tmp1 = 0;
uint32_t cur_time;
hw_sched_cmd_t cmd[HW_SCHED_CMD_MAX_CNT];
/* schedule: beacon ahead alert interrupt */
do {
/* send the beacon */
mac_tx_mpdu_test(NULL, mpdu_start);
dt_mac_tx_hwq0_re_trig();
/* q0 ptr */
RGF_HWQ_WRITE_REG(CFG_Q0_PTR_ADDR,(uint32_t)(mpdu_start));
/* q0 ena */
RGF_HWQ_WRITE_REG(CFG_Q_ENA_ADDR,0x1);
#if MAC_DTEST_PLATFORM == MAC_DTEST_EDA
/* beacon period */
RGF_MAC_WRITE_REG(CFG_BEACON_PERIOD_ADDR, 0x320000);//50ms
/* beacon alert ahead */
RGF_MAC_WRITE_REG(CFG_BEACON_ADDR,5);//5ms
#define END_TIME_UNIT 10
#elif MAC_DTEST_PLATFORM == MAC_DTEST_FPGA
/* beacon period */
RGF_MAC_WRITE_REG(CFG_BEACON_PERIOD_ADDR, 0x3E80000);//1s
/* beacon alert ahead */
RGF_MAC_WRITE_REG(CFG_BEACON_ADDR,100);//100ms
#define END_TIME_UNIT 10
#endif
cmd[0].t_info.se.end_t=END_TIME_UNIT;//1ms
cmd[0].t_info.se.start_t=0x0;
cmd[0].t_info.se.r_flag=0x0;
cmd[0].t_info.se.s_flag=0x0;
cmd[0].phase=0x1;
cmd[0].nb_flag=0x0;
cmd[0].idle_bit=0x0;
cmd[0].req_int=0x0;
cmd[0].rx_rate_mode=RX_MODE_SR;
cmd[0].tx_q_en_bm=0x1;
for(uint32_t i=1;i<HW_SCHED_CMD_MAX_CNT;i++)
{
cmd[i]=cmd[i-1];
cmd[i].t_info.se.end_t=(i+1)*END_TIME_UNIT;
}
/* sch ptr */
RGF_HWQ_WRITE_REG(CFG_SCH_PTR_ADDR,(uint32_t)cmd);
cur_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR); //25M 0.04us
RGF_MAC_WRITE_REG(CFG_BCN_START_NTB_ADDR,cur_time+0x500);
/* 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,100);
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;
}
void mac_tx_mix()
{
uint32_t tmp = 0;
/* mix en from mac in the future */
tmp = RGF_MAC_READ_REG(CFG_PHY_CTRL_ADDR);
REG_FIELD_SET(CFG_PHY_TX_LONG_PREAM_EN, tmp, 1);
RGF_MAC_WRITE_REG(CFG_PHY_CTRL_ADDR,tmp);
/* normal tx */
mac_tx_single_mode();
}
void mac_tx_gp_ext()
{
uint32_t tmp = 0;
uint32_t tx_done = 0;
uint32_t enq_time = 0, cur_time = 0;
int64_t time_span = 0;
iot_phy_sts_info_t total_sts = {0};
uint32_t tmi_retry_cnt = 0;
/* mix en */
phy_mix_flag_set(true);
/* mix en from mac in the future */
tmp = RGF_MAC_READ_REG(CFG_GP_CTRL_ADDR);
REG_FIELD_SET(CFG_GP_PB_SIZE_SEL, tmp, 1);
RGF_MAC_WRITE_REG(CFG_GP_CTRL_ADDR,tmp);
tmp = PHY_RX_FD_READ_REG(CFG_BB_SEND_MAC_CTRL_ADDR);
REG_FIELD_SET(SW_ALWAYS_SEND_FC, tmp, 0);
PHY_RX_FD_WRITE_REG(CFG_BB_SEND_MAC_CTRL_ADDR, tmp);
#if MAC_TMI_ID == MAC_TMI_4 || MAC_TMI_ID == 5
/* fix symbnum */
tmp = RGF_TMR_READ_REG(CFG_TX_FC_CTRL_ADDR);
REG_FIELD_SET(CFG_TX_FC_FL_BY_SW, tmp , 1);
RGF_TMR_WRITE_REG(CFG_TX_FC_CTRL_ADDR, tmp);
#endif
#if IOT_PLC_PHY_BAND_DFT == IOT_SUPPORT_TONE_80_1228
phy_rxfd_rate0_det(80,1228);
phy_rxfd_rate1_det(80,1228);
#endif
/* normal tx for single mode */
//mac_tx_single_mode();
/* pb num for each tmi */
for(uint32_t j=1; j<5; j++)
{
for(uint32_t i=4; i<MAC_EXT_TMI_2; i++)
{
if(i == 4 || i == 5)
{
/* fix symbnum */
tmp = RGF_TMR_READ_REG(CFG_TX_FC_CTRL_ADDR);
REG_FIELD_SET(CFG_TX_FC_FL_BY_SW, tmp , 1);
RGF_TMR_WRITE_REG(CFG_TX_FC_CTRL_ADDR, tmp);
}
else{
/* fix symbnum */
tmp = RGF_TMR_READ_REG(CFG_TX_FC_CTRL_ADDR);
REG_FIELD_SET(CFG_TX_FC_FL_BY_SW, tmp , 0);
RGF_TMR_WRITE_REG(CFG_TX_FC_CTRL_ADDR, tmp);
}
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\n"
"mac 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);
}
}
}
void mac_tx_gp_tone_mask()
{
/* check protocol */
IOT_ASSERT(glb_cfg.m_type == PLC_PROTO_TYPE_GP);
const plc_tonemask_table *tonemask_tbl_ptr = \
&all_mask_tone_mask_table_gp;
/* full band */
init_band_table(&all_mask_band_table_r0_full, \
HW_FULL_BAND, \
tonemask_tbl_ptr, \
all_mask_band_table_r0_full.fc_sym_num, \
all_mask_band_table_r0_full.start_tone, \
all_mask_band_table_r0_full.end_tone);
/* low band */
init_band_table(&all_mask_band_table_r0_low, \
HW_LOW_BAND, \
tonemask_tbl_ptr, \
all_mask_band_table_r0_low.fc_sym_num, \
all_mask_band_table_r0_low.start_tone, \
all_mask_band_table_r0_low.end_tone);
/* high band */
init_band_table(&all_mask_band_table_r0_high, \
HW_HIGH_BAND, \
tonemask_tbl_ptr, \
all_mask_band_table_r0_high.fc_sym_num, \
all_mask_band_table_r0_high.start_tone, \
all_mask_band_table_r0_high.end_tone);
/* full band */
init_band_table(&all_mask_band_table_r1_full, \
HW_FULL_BAND, \
tonemask_tbl_ptr, \
all_mask_band_table_r1_full.fc_sym_num, \
all_mask_band_table_r1_full.start_tone, \
all_mask_band_table_r1_full.end_tone);
/* low band */
init_band_table(&all_mask_band_table_r1_low, \
HW_LOW_BAND, \
tonemask_tbl_ptr, \
all_mask_band_table_r1_low.fc_sym_num, \
all_mask_band_table_r1_low.start_tone, \
all_mask_band_table_r1_low.end_tone);
/* high band */
init_band_table(&all_mask_band_table_r1_high, \
HW_HIGH_BAND, \
tonemask_tbl_ptr, \
all_mask_band_table_r1_high.fc_sym_num, \
all_mask_band_table_r1_high.start_tone, \
all_mask_band_table_r1_high.end_tone);
/* cal new tone para */
phy_band_init(PLC_PROTO_TYPE_GP, IOT_SUPPORT_TONE_80_1228);
/* load new mask */
phy_tone_mask_amp_phase_tab_load(&all_mask_amp_phase_table, \
TONE_MASK_ID_GP, \
PLC_PROTO_TYPE_GP);
/* add amplitude mask to optimze mask snr */
phy_amp_mask_set(214, 214);
phy_amp_mask_set(226, 226);
phy_amp_mask_set(749, 749);
phy_amp_mask_set(735, 736);
phy_amp_mask_set(420, 421);
/* normal tx */
mac_tx_single_mode();
}
void mac_tx_band_switch()
{
/* init */
phy_reinit( \
PLC_PROTO_TYPE_SG, \
IOT_SUPPORT_TONE_80_490, \
TONE_MASK_ID_NULL, \
true);
/* delay */
for(uint32_t i = 0; i < 300; i++)
{
mac_tx_mpdu_test(NULL, mpdu_start);
dt_mac_tx_hwq0_re_trig();
for(uint32_t j = 0; j < 50000; j++);
}
/* init */
phy_reinit( \
PLC_PROTO_TYPE_SG, \
IOT_SUPPORT_TONE_100_230, \
TONE_MASK_ID_NULL, \
true);
/* normal tx */
mac_tx_single_mode();
}
void phy_tx_td_start_test()
{
uint8_t tmi = 0;
uint32_t rate_idx = 0;
uint32_t band_idx = 0;
int64_t time_span = 0;
uint32_t enq_time = 0, cur_time = 0;
uint32_t start_time = 0, end_time = 0;
iot_phy_sts_info_t total_sts = {0};
volatile uint32_t tx_done = 0;
/* init phy interrupt */
#if TARGET_VERSION < 2
phy_interrupt_init();
#endif
/* tx start */
start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);/*for cnt*/
/* beacon or sof transmit */
do {
glb_cfg.tmi = tmi;
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));
/* update tmi */
tmi = (tmi > 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<MAC_BB_MAX_RATE; rate_idx++)
{
for(band_idx=0; band_idx<MAX_HW_BAND; band_idx++)
{
if(band_cnt[rate_idx][band_idx] != 0){
iot_printf("[RATE-%d][BAND-%d]:%d\r\n", \
rate_idx, band_idx, band_cnt[rate_idx][band_idx]);
band_cnt[rate_idx][band_idx] = 0;
}
}
}
}
} while (true);
}
/*
* 1 high power bcn and 9 -20dB low power bcn with tmi 3. pkt time span 4-10s.
* transmit tmi7 pb520 have the same tx power with the same bcn. gree low band.
*/
void phy_tx_emc_scan()
{
volatile uint32_t tx_done = 0;
/* bcn time start and end time */
uint32_t last_time = 0, cur_time = 0;
int64_t time_span = 0;
/* broadcast sof start and end time */
uint32_t start_time = 0, end_time = 0;
/* broadcast delay */
uint32_t dly_start_time = 0, dly_end_time = 0;
/* bcn time span: ms */
uint16_t bcn_time_period = 2000;
/* sof time span: ms */
uint16_t sof_time_period = 1000;
/* sts print */
iot_phy_sts_info_t total_sts = {0};
uint32_t rate_idx = 0;
uint32_t band_idx = 0;
/* bcn index */
uint8_t bcn_index = 0;
start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);/*for cnt*/
last_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);/*for tx*/
dly_start_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
/* beacon or sof transmit */
do {
cur_time = RGF_MAC_READ_REG(CFG_RD_NTB_ADDR);
time_span = cur_time - last_time;
if (time_span < 0) { // wrap around
time_span = (0x100000000LL) - last_time + cur_time;
}
if((uint64_t)time_span > 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<MAC_BB_MAX_RATE; rate_idx++)
{
for(band_idx=0; band_idx<MAX_HW_BAND; band_idx++)
{
if(band_cnt[rate_idx][band_idx] != 0){
iot_printf("[RATE-%d][BAND-%d]:%d\r\n", \
rate_idx, band_idx, band_cnt[rate_idx][band_idx]);
band_cnt[rate_idx][band_idx] = 0;
}
}
}
dly_start_time = dly_end_time;
}
} while (true);
}
void mac_phy_rst_flow()
{
int64_t time_span = 0;
uint32_t enq_time = 0, cur_time = 0;
uint32_t start_time = 0, end_time = 0;
uint32_t rate_idx = 0, band_idx = 0;
iot_phy_sts_info_t total_sts = {0};
volatile uint32_t tx_done = 0;
/* tx start */
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);
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) {
/* 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<MAC_BB_MAX_RATE; rate_idx++)
{
for(band_idx=0; band_idx<MAX_HW_BAND; band_idx++)
{
if(band_cnt[rate_idx][band_idx] != 0){
iot_printf("[RATE-%d][BAND-%d]:%d\r\n", \
rate_idx, band_idx, band_cnt[rate_idx][band_idx]);
band_cnt[rate_idx][band_idx] = 0;
}
}
}
}
} while (true);
}
void mac_tmap_test()
{
#if SUPPORT_GREEN_PHY
/* check protocol */
IOT_ASSERT(glb_cfg.m_type == PLC_PROTO_TYPE_GP);
/* update ext tmi */
glb_cfg.tmi = MAC_TMI_7;
/* tmap common config must behind burst */
phy_tmap_common_init();
/* self tmi */
phy_tmap_self_tmi_set(1);
/* mac tmap init */
mac_tmap_init();
mac_tx_single_mode();
#endif
}
void phy_gp_hybrid_mode_test()
{
#if SUPPORT_GREEN_PHY
/* check protocol */
IOT_ASSERT(glb_cfg.m_type == PLC_PROTO_TYPE_GP);
/* update standard tmi */
glb_cfg.tmi = MAC_TMI_2;
/* init gp hybrid mode */
phy_gp_hybrid_mode_init();
/* update ppdu mode */
glb_cfg.ppdu_mode = HW_DESC_PPDU_MODE_HYBRID_1FCSYM;
mac_tx_single_mode();
#endif
}
void phy_gp_burst_mode_test()
{
#if SUPPORT_GREEN_PHY
/* check protocol */
IOT_ASSERT(glb_cfg.m_type == PLC_PROTO_TYPE_GP);
/* update standard tmi */
glb_cfg.tmi = MAC_TMI_2;
/* init gp burst mode */
phy_gp_burst_init();
/* update mpdu number */
glb_cfg.mpdu_cnt = 2;
/* 20us +/- 0.5 us */
dtest_mac_bifs_set(5);
mac_tx_single_mode();
#endif
}
void mac_tx_start()
{
platform_tx_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_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