Files
kunlun/dtest/rawdata_test/mac_rx_test/mac_rx_test.c

815 lines
24 KiB
C
Raw Normal View History

2024-09-28 14:24:04 +08:00
/****************************************************************************
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 "os_mem.h"
#include "rx_pb_reorder.h"
#include "phy_reg.h"
#include "iot_bitops.h"
#include "phy_bb.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_rxtd_reg.h"
#include "phy_rx_fd_reg.h"
#include "phy_dfe_reg.h"
#define IPC_CONTROL
#ifdef IPC_CONTROL
#include "iot_errno.h"
#include "iot_mc_ipc.h"
#endif
#if IOT_FTM_SUPPORT == 1
uint8_t *rx_buf[RX_BUF_NUM];
#else
uint8_t rx_buf[RX_BUF_NUM][RX_BUF_BYTE_SIZE];
#endif
uint8_t *rx_buf_ptr_list[RX_BUF_NUM];
uint32_t tmi_beacon_cnt[MAX_TMI_NUM][4] = {0};
uint32_t tmi_sof_cnt[MAX_TMI_NUM][4] = {0};
uint32_t tmi_sack_cnt[4] = {0};
uint32_t tmi_nncco_cnt[4] = {0};
int16_t gain = 0,rmi = 0;
uint16_t band_cnt[MAX_HW_BAND] = {0};
uint32_t print_period_ms=4000; /*receive 25*4 packets in 4s*/
extern void phy_sts_get(iot_phy_sts_info_t *pkt_sts);
extern agc_gain_tbl_t gain_reg_tbl[];
#ifdef IPC_CONTROL
#define IPC_MSG_ID_RAWDATA_START_REQ 1
#define REQ_TYPE_NEW 1
typedef struct _ipc_msg_rawdata_start_req
{
uint8_t req_type;
}ipc_msg_rawdata_start_req_t;
#define IPC_MSG_ID_RAWDATA_START_CNF 2
#define CNF_STATUS_OK 1
#define CNF_STATUS_FAIL 2
typedef struct _ipc_msg_rawdata_start_cnf
{
uint8_t status;
}ipc_msg_rawdata_cnf_t;
ipc_msg_rawdata_start_req_t start_msg;
ipc_msg_rawdata_cnf_t cnf_msg;
volatile uint32_t rawdata_cnf_received = 0;
volatile uint32_t rawdata_start_received = 0;
void scpu_recv_ipc_msg(uint32_t msg_id, void* msg_arg);
void acpu_recv_ipc_msg(uint32_t msg_id, void* msg_arg);
uint32_t iot_rawdata_init_ipc(uint8_t cpuid)
{
if(cpuid == IOT_SECCPU_ID){
iot_mc_ipc_init(scpu_recv_ipc_msg, IOT_SECCPU_ID, INTC_MODE);
}else{
iot_mc_ipc_init(acpu_recv_ipc_msg, IOT_APPCPU_ID, INTC_MODE);
}
return ERR_OK;
}
volatile uint32_t rawdata_start_send = 0;
uint32_t acpu_start_rawdata(void)
{
uint32_t j = 0;
start_msg.req_type = REQ_TYPE_NEW;
while(!rawdata_cnf_received){
if(!rawdata_start_send){
if(iot_mc_ipc_query_mailbox_freecredit() >0){
iot_mc_ipc_send_msg(IPC_MSG_ID_RAWDATA_START_REQ, (void*)&start_msg);
rawdata_start_send = 1;
}
}
//iot_printf("rawdata_cnf_received=%d rawdata_start_send=%d\n", rawdata_cnf_received, rawdata_start_send);
for(j=0;j<APP_CPU_POLL_SPEED;j++);
for(j=0;j<APP_CPU_POLL_SPEED;j++);
for(j=0;j<APP_CPU_POLL_SPEED;j++);
}
return ERR_OK;
}
void acpu_recv_ipc_msg(uint32_t msg_id, void* msg_arg)
{
ipc_msg_rawdata_cnf_t* pmsg = NULL;
iot_printf("secpu[rec] msg_id:%x arg:%x status:%x\n", msg_id, msg_arg, iot_mc_ipc_get_hw_stauts());
switch(msg_id)
{
case IPC_MSG_ID_RAWDATA_START_CNF:
pmsg = (ipc_msg_rawdata_cnf_t*)msg_arg;
iot_printf("IPC_MSG_ID_RAWDATA_START_CNF : %d\n", pmsg->status);
if(pmsg->status == CNF_STATUS_OK){
rawdata_cnf_received = 1;
}
break;
default:
iot_printf("unhandled msgid:0x%x\n", msg_id);
break;
}
}
void scpu_recv_ipc_msg(uint32_t msg_id, void* msg_arg)
{
ipc_msg_rawdata_start_req_t* pmsg = NULL;
iot_printf("secpu[rec] msg_id:%x arg:%x status:%x\n", msg_id, msg_arg, iot_mc_ipc_get_hw_stauts());
switch(msg_id)
{
case IPC_MSG_ID_RAWDATA_START_REQ:
pmsg = (ipc_msg_rawdata_start_req_t*)msg_arg;
iot_printf("IPC_MSG_ID_RAWDATA_START_REQ : %d\n", pmsg->req_type);
cnf_msg.status = CNF_STATUS_OK;
if(iot_mc_ipc_query_mailbox_freecredit() >0){
iot_mc_ipc_send_msg(IPC_MSG_ID_RAWDATA_START_CNF, (void*)&cnf_msg);
rawdata_start_received = 1;
}
break;
default:
iot_printf("unhandled msgid:0x%x\n", msg_id);
break;
}
}
/* acpu will send ipc request to scpu to start rawmode */
#endif
void mpdu_rx_cnt_callback(rx_pb_end *pb_ed, uint32_t *cnt)
{
if (pb_ed->rx_pb_crc_err == 0)
cnt += 1;
}
static uint32_t mac_hw_init()
{
uint32_t tmp = 0;
uint32_t symbnum_ppb = 0;
uint32_t fl_ppb = 0;
#if IOT_FTM_SUPPORT == 1
tmp = RX_BUF_NUM;
while(tmp--)
rx_buf[tmp] = (uint8_t *)os_mem_malloc(IOT_FTM_MID, RX_BUF_BYTE_SIZE);
#endif
/* reset mac */
mac_reset(MAC_RST_REASON_COLD);
/* reset phy */
phy_reset(PHY_RST_REASON_COLD);
/* reset mac */
mac_reset(MAC_RST_REASON_COLD);
phy_init(PLC_PROTO_TYPE_SG, \
IOT_PLC_PHY_BAND_DFT, TONE_MASK_ID_NULL, true);
/* enable packets receive */
tmp = RGF_RX_READ_REG(CFG_RX_FILTER_0_ADDR);
REG_FIELD_SET(CFG_NID_FILTER_DIS, tmp, 1);
REG_FIELD_SET(CFG_MPDU_DTEI_FILTER_DIS, tmp, 1);
REG_FIELD_SET(CFG_BEACON_PHASE_FILTER_DIS, tmp, 1);
RGF_RX_WRITE_REG(CFG_RX_FILTER_0_ADDR, tmp);
/* config my nid */
tmp = RGF_MAC_READ_REG(CFG_MYNID_ADDR);
if(PHY_PROTO_TYPE_GET() == PLC_PROTO_TYPE_SG){
REG_FIELD_SET(CFG_MYNID, tmp, 0x123456);
}
else if(PHY_PROTO_TYPE_GET() == PLC_PROTO_TYPE_SPG){
REG_FIELD_SET(CFG_MYNID, tmp, 0xb);
}
else if(PHY_PROTO_TYPE_GET() == PLC_PROTO_TYPE_GP){
REG_FIELD_SET(CFG_MYNID, tmp, 0xb);/*11 for kunlun*/
}
RGF_MAC_WRITE_REG(CFG_MYNID_ADDR, tmp);
/* tei cfg */
RGF_MAC_WRITE_REG(CFG_MYTEI_ADDR, 2);
/* delete timeout for long pkt */
tmp = RGF_RX_READ_REG(CFG_RX_TIMEOUT_1_ADDR);
REG_FIELD_SET(CFG_RX_PB_TIMEOUT, tmp, 2000000);
RGF_RX_WRITE_REG(CFG_RX_TIMEOUT_1_ADDR, tmp);
/* pb framelength for gp */
if(PHY_PROTO_TYPE_GET() == PLC_PROTO_TYPE_GP){
/* tmi0 band0 */
symbnum_ppb = phy_get_sym_per_pb(PHY_PROTO_TYPE_GET(), 0, 0, 0, 0);
fl_ppb = (uint32_t)(FRAME_LENGTH_PER_PB_GP(symbnum_ppb, GI_STD_ROBO)/1.28);
tmp = RGF_RX_READ_REG(CFG_TMI0_BAND0_ADDR);
REG_FIELD_SET(CFG_TMI0_BAND0_PBFL,tmp,fl_ppb);
RGF_RX_WRITE_REG(CFG_TMI0_BAND0_ADDR,tmp);
/* tmi1 band0 */
symbnum_ppb = phy_get_sym_per_pb(PHY_PROTO_TYPE_GET(), 0, 1, 0, 0);
fl_ppb = (uint32_t)(FRAME_LENGTH_PER_PB_GP(symbnum_ppb, GI_HS_ROBO)/1.28);
tmp = RGF_RX_READ_REG(CFG_TMI1_BAND0_ADDR);
REG_FIELD_SET(CFG_TMI1_BAND0_PBFL,tmp,fl_ppb);
RGF_RX_WRITE_REG(CFG_TMI1_BAND0_ADDR,tmp);
/* tmi2 band0 */
symbnum_ppb = phy_get_sym_per_pb(PHY_PROTO_TYPE_GET(), 0, 2, 0, 0);
fl_ppb = (uint32_t)(FRAME_LENGTH_PER_PB_GP(symbnum_ppb, GI_MINI_ROBO)/1.28);
tmp = RGF_RX_READ_REG(CFG_TMI2_BAND0_ADDR);
REG_FIELD_SET(CFG_TMI2_BAND0_PBFL,tmp,fl_ppb);
RGF_RX_WRITE_REG(CFG_TMI2_BAND0_ADDR,tmp);
}
return 0;
}
void rx_ring_setup_hw(uint32_t ring_id, rx_ring_cfg_t *cfg)
{
(void)ring_id;
(void)cfg;
uint32_t tmp;
uint32_t i;
/* init the rx ring buf */
for (i = 0; i < RX_BUF_NUM; i++) {
rx_buf_ptr_list[i] = rx_buf[i];
}
RGF_RX_WRITE_REG(CFG_BUFFER_RING0_0_ADDR, (uint32_t)rx_buf_ptr_list);
/* set ring sz and buf len */
tmp = RGF_RX_READ_REG(CFG_BUFFER_RING0_1_ADDR);
REG_FIELD_SET(CFG_RING0_BUF_SIZE, tmp, RX_BUF_DW_SIZE);
REG_FIELD_SET(CFG_RING0_BUF_NUM, tmp, RX_BUF_NUM);
RGF_RX_WRITE_REG(CFG_BUFFER_RING0_1_ADDR, tmp);
/* set rd idx = 0 as default */
tmp = RGF_RX_READ_REG(CFG_BUFFER_RING0_2_ADDR);
REG_FIELD_SET(CFG_RING0_RD_IDX, tmp, 0);
RGF_RX_WRITE_REG(CFG_BUFFER_RING0_2_ADDR, tmp);
/* set desc and payload offset */
tmp = RGF_RX_READ_REG(CFG_BUFFER_RING0_3_ADDR);
REG_FIELD_SET(CFG_RING0_DESC_EN, tmp, 1);
REG_FIELD_SET(CFG_RING0_PAYLOAD_EN, tmp, 1);
REG_FIELD_SET(CFG_RING0_DESC_OFFSET, tmp, 0);
REG_FIELD_SET(CFG_RING0_PAYLOAD_OFFSET, tmp, \
iot_ceil(sizeof(rx_buf_hdr_t), 4));
RGF_RX_WRITE_REG(CFG_BUFFER_RING0_3_ADDR, tmp);
return;
}
void rx_ring_enable(uint32_t ring_id, uint32_t enable)
{
(void)ring_id;
uint32_t tmp;
tmp = RGF_RX_READ_REG(CFG_BUFFER_RING0_2_ADDR);
REG_FIELD_SET(CFG_RING0_EN, tmp, enable);
RGF_RX_WRITE_REG(CFG_BUFFER_RING0_2_ADDR, tmp);
return;
}
uint32_t is_rx_ring0_empty()
{
uint32_t rd_idx, wr_idx;
rd_idx = RX_RING_GET_RD_IDX(0);
wr_idx = RX_RING_GET_WR_IDX(0);
return (rd_idx == wr_idx);
}
uint32_t* dbg_fc = NULL;
uint8_t *pop_rx_buf_from_ring(uint32_t ring_id)
{
static uint32_t enq_time = 0, cur_time = 0;
static int64_t time_span = 0;
(void)ring_id;
uint32_t rd_idx = 0;
static uint32_t fisrt_pb_crc_ok_cnt = 0, second_pb_crc_ok_cnt = 0, \
third_pb_crc_ok_cnt = 0, last_pb_crc_ok_cnt = 0;
uint8_t *rx_buf_start;
rx_buf_hdr_t *pb_buf;
uint32_t gain_reg0 = 0, gain_reg1 = 0;
rd_idx = RX_RING_GET_RD_IDX(0);
rx_buf_start = rx_buf[rd_idx];
pb_buf = (rx_buf_hdr_t *)rx_buf_start;
if ((pb_buf->att.rx_mpdu_done == 1) && (pb_buf->att.is_fcserr == 0)){
if(!pb_buf->pb_ed.rx_pb_crc_err)
{
if(1 == pb_buf->mpdu_ed.rx_buf_num)
fisrt_pb_crc_ok_cnt++;
else if(2 == pb_buf->mpdu_ed.rx_buf_num)
second_pb_crc_ok_cnt++;
else if(3 == pb_buf->mpdu_ed.rx_buf_num)
third_pb_crc_ok_cnt++;
else if(4 == pb_buf->mpdu_ed.rx_buf_num)
last_pb_crc_ok_cnt++;
if(PHY_PROTO_TYPE_GET() == PLC_PROTO_TYPE_SG)
{
switch(pb_buf->mpdu_st.fc.sg_fc.delimiter_type)
{
case FC_DELIM_BEACON:
tmi_beacon_cnt[pb_buf->mpdu_st.fc.sg_fc.vf.bcn.tmi]\
[pb_buf->mpdu_ed.rx_buf_num-1] += 1;
break;
case FC_DELIM_SOF:
dbg_fc = (uint32_t*)&pb_buf->mpdu_st.fc.sg_fc;
tmi_sof_cnt[pb_buf->mpdu_st.fc.sg_fc.vf.sof.tmi_ext + \
pb_buf->mpdu_st.fc.sg_fc.vf.sof.tmi][pb_buf->mpdu_ed.rx_buf_num-1] += 1;
iot_printf("FC:0x%04x pb_num:%d rx_abort:%d\n", dbg_fc[0],pb_buf->att.pb_num, pb_buf->att.rx_abort);
iot_printf("FC:0x%04x 0x%04x 0x%04x\n", dbg_fc[1],dbg_fc[2],dbg_fc[3]);
break;
case FC_DELIM_SACK:
tmi_sack_cnt[pb_buf->mpdu_ed.rx_buf_num-1] += 1;
break;
case FC_DELIM_NNCCO:
tmi_nncco_cnt[pb_buf->mpdu_ed.rx_buf_num-1] += 1;
break;
default:
break;
}
}
else if(PHY_PROTO_TYPE_GET() == PLC_PROTO_TYPE_SPG)
{
switch(pb_buf->mpdu_st.fc.spg_fc.delimiter_type)
{
case FC_DELIM_BEACON:
tmi_beacon_cnt[pb_buf->mpdu_st.fc.spg_fc.vf.bcn.tmi]\
[pb_buf->mpdu_ed.rx_buf_num-1] += 1;
break;
case FC_DELIM_SOF:
tmi_sof_cnt[pb_buf->mpdu_st.fc.spg_fc.vf.sof.tmi_ext + \
pb_buf->mpdu_st.fc.spg_fc.vf.sof.tmi]\
[pb_buf->mpdu_ed.rx_buf_num-1] += 1;
break;
case FC_DELIM_SACK:
tmi_sack_cnt[pb_buf->mpdu_ed.rx_buf_num-1] += 1;
break;
case FC_DELIM_NNCCO:
tmi_nncco_cnt[pb_buf->mpdu_ed.rx_buf_num-1] += 1;
break;
default:
break;
}
}
else if(PHY_PROTO_TYPE_GET() == PLC_PROTO_TYPE_GP)
{
switch(pb_buf->mpdu_st.fc.hpav_fc.delimiter_type)
{
case FC_DELIM_BEACON:
tmi_beacon_cnt[0][pb_buf->mpdu_ed.rx_buf_num-1] += 1;
break;
case FC_DELIM_SOF:
tmi_sof_cnt[pb_buf->mpdu_st.fc.hpav_fc.vf_av.sof.tmi_av]\
[pb_buf->mpdu_ed.rx_buf_num-1] += 1;
break;
case FC_DELIM_SACK:
tmi_sack_cnt[pb_buf->mpdu_ed.rx_buf_num-1] += 1;
break;
case FC_DELIM_NNCCO:
tmi_nncco_cnt[pb_buf->mpdu_ed.rx_buf_num-1] += 1;
break;
default:
break;
}
}
/* fresh gain by cco */
if(pb_buf->mpdu_st.fc.spg_fc.vf.bcn.src_tei == 1 || \
pb_buf->mpdu_st.fc.spg_fc.vf.sof.src_tei == 1 || \
pb_buf->mpdu_st.fc.sg_fc.vf.bcn.src_tei == 1 || \
pb_buf->mpdu_st.fc.sg_fc.vf.sof.src_tei == 1 || \
pb_buf->mpdu_st.fc.hpav_fc.vf_av.sof.src_tei == 1 || \
pb_buf->mpdu_st.fc.hpav_fc.vf_av.rtscts.src_tei == 1 || \
pb_buf->mpdu_st.fc.hpav_fc.vf_av.sound.stei == 1)
{
#if 0
if(pb_buf->mpdu_st.peer & 0x8000)
gain = (int16_t)(((pb_buf->mpdu_st.peer & 0xFF00)>>8)|0xFF00);/*fix char print error*/
else
gain = (int16_t)((pb_buf->mpdu_st.peer & 0xFF00)>>8);
if(pb_buf->mpdu_st.peer & 0x80)
rmi = (int16_t)((pb_buf->mpdu_st.peer & 0xFF)|0xFF00);
else
rmi = (int16_t)(pb_buf->mpdu_st.peer & 0xFF);
gain_reg0 = all_mask_gain_table[gain] & 0xff;
gain_reg1 = (all_mask_gain_table[gain] >> 8) & 0xff;
gain = phy_gain_val_get(gain_reg0,gain_reg1);
#endif
(void)gain_reg0;
(void)gain_reg1;
}
/* rate and band info */
if(pb_buf->att.rx_band_sel < MAX_HW_BAND){
band_cnt[pb_buf->att.rx_band_sel] += 1;
}
else{
IOT_ASSERT(0);
}
}
if(++rd_idx >= RX_BUF_NUM)
rd_idx = 0;
RX_RING_SET_RD_IDX(0, rd_idx);
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;
}
/*agc gain info*/
if((uint64_t)time_span > print_period_ms*TICKS_MS)
{
enq_time = cur_time;
iot_printf("AGC gain info: %hd-%hd, pb crc ok:1st=%d,", \
gain, rmi, fisrt_pb_crc_ok_cnt);
iot_printf("2nd=%d, 3rd=%d, 4th=%d\r\n", \
second_pb_crc_ok_cnt, third_pb_crc_ok_cnt, last_pb_crc_ok_cnt);
gain = -1;
rmi = -1;
fisrt_pb_crc_ok_cnt = 0;
second_pb_crc_ok_cnt = 0;
third_pb_crc_ok_cnt = 0;
last_pb_crc_ok_cnt = 0;
}
return rx_buf_start;
}
else {
if (++rd_idx >= RX_BUF_NUM) {
rd_idx = 0;
}
RX_RING_SET_RD_IDX(0, rd_idx);
return NULL;
}
}
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;
}
/* support mode : ftm, module, dtest scan */
void rx_common_init()
{
/* basic data struct init for bit ops */
iot_bitops_init();
mac_hw_init();
}
/* mac rx pkt single */
uint32_t mac_rx_single_mode()
{
uint32_t start_time = 0, end_time = 0;
uint64_t time_span = 0;
iot_phy_sts_info_t total_sts = {0};
uint8_t tmi = 0;
uint8_t tmp = 0;
uint32_t i = 0;
/* 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 > 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);
start_time = end_time;
/* print tmi counter */
tmi = MAX_TMI_NUM;
while(tmi--){
for(i=0; i<4; i++)
{
/* beacon */
if(tmi_beacon_cnt[tmi][i] != 0)
{
if(tmi < 15)
iot_printf("[TMI-%d][BCN][PB-%d]:%d\r\n", \
tmi,i,tmi_beacon_cnt[tmi][i]);
else{
tmp = tmi - 15;/* skip optimization for next */
iot_printf("[EXT-TMI-%d][BCN][PB-%d]:%d\r\n", \
tmp,i,tmi_beacon_cnt[tmi][i]);
}
tmi_beacon_cnt[tmi][i] = 0;
}
/* sof */
if(tmi_sof_cnt[tmi][i] != 0)
{
if(tmi < 15)
iot_printf("[TMI-%d][SOF][PB-%d]:%d\r\n", \
tmi,i,tmi_sof_cnt[tmi][i]);
else{
tmp = tmi - 15;/* skip optimization for next */
iot_printf("[EXT-TMI-%d][SOF][PB-%d]:%d\r\n", \
tmp,i,tmi_sof_cnt[tmi][i]);
}
tmi_sof_cnt[tmi][i] = 0;
}
}
}
/* sack & nncco */
for(i=0; i<4; i++)
{
if(tmi_sack_cnt[i] != 0){
iot_printf("[SACK][PB-%d]:%d\r\n",i,tmi_sack_cnt[i]);
tmi_sack_cnt[i] = 0;
}
if(tmi_nncco_cnt[i] != 0){
iot_printf("[NNCCO][PB-%d]:%d\r\n",i,tmi_nncco_cnt[i]);
tmi_nncco_cnt[i] = 0;
}
}
/* band info */
for(i=0; i<MAX_HW_BAND; i++)
{
if(band_cnt[i] != 0){
iot_printf("[BAND-%d]:%d\r\n", i, band_cnt[i]);
band_cnt[i] = 0;
}
}
}
} while (true); /* keep check */
return 0;
}
/* mac rx snr cal */
uint32_t mac_rx_snr_scan()
{
uint32_t tone_idx = 0;
int32_t snr_buf[TONE_MAX_NUM] = {0};
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]);
}
return 0;
}
/* mac rx csi cal */
uint32_t mac_rx_csi_scan()
{
uint32_t tone_idx = 0;
uint32_t csi_buf[TONE_MAX_NUM] = {0};
phy_rx_csi_get(0,TONE_MAX_NUM,csi_buf);
/* 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()
{
int32_t gain = 0;
uint32_t rssi_nf = 0;
uint32_t tone_idx = 0;
uint32_t nf_buf[TONE_MAX_NUM] = {0};
phy_rx_noise_floor_get(0,TONE_MAX_NUM,nf_buf);
/* noise floor for every tone */
for(tone_idx = 0; tone_idx < TONE_MAX_NUM; tone_idx++)
{
iot_printf("tone%d noise floor:%d\r\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!\r\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;
}
void mac_rx_test()
{
#if HW_PLATFORM > HW_PLATFORM_SIMU
#if EDA_SIMU_SUPPORT != 1
/* 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_hw_init();
/* ppm calibration */
#ifdef MAC_RX_PPM_SUPPORT
#if MAC_RX_TEST_ID != MAC_RX_NOISE_FLOOR_SCAN
mac_rx_ppm_cali();
#endif
#endif
/* setup the rx ring */
rx_ring_setup_hw(0, NULL);
/* enable the rx ring */
rx_ring_enable(0, true);
#ifdef IPC_CONTROL
iot_rawdata_init_ipc(IOT_APPCPU_ID);
acpu_start_rawdata();
#endif
switch(MAC_RX_TEST_ID)
{
case MAC_RX_PKT:
mac_rx_single_mode();
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_PPM_CALIBRATION:
mac_rx_ppm_cali();
break;
default:
IOT_ASSERT(0);
}
return;
}
#ifdef __GNUC__
#if !MODULE_EN
int main(void) {
mac_rx_test();
return 0;
}
#endif
#endif // __GCC__