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

669 lines
19 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 "tx_mpdu_start.h"
#include "tx_mpdu_end.h"
#include "tx_pb_start.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 "phy_bb.h"
#include "mpdu_frame.h"
#include "ahb_rf.h"
#include "iot_irq.h"
//#include "iot_mem.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 "plc_protocol.h"
#define IPC_CONTROL
#ifdef IPC_CONTROL
#include "iot_errno.h"
#include "iot_mc_ipc.h"
#endif
extern void tx_common_init();
extern uint32_t mac_tx_mpdu_test(void *pdev, tx_mpdu_start *mpdu);
extern void mac_glb_map(uint32_t mac_type, uint32_t pkt_type, uint32_t test_type);
extern tx_mpdu_start mpdu_start;
extern iot_tx_cfg_info_t glb_cfg;
extern iot_mac_intr_info_t mac_info;
extern volatile bool_t mac_beacon_alert_flag;
extern volatile bool_t mac_tx_complete_flag;
extern uint32_t bcn_period_ms;
extern uint32_t print_tx_period_ms;
extern void phy_sts_get(iot_phy_sts_info_t *pkt_sts);
#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
#if 0
#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;
uint32_t rawdata_cnf_received = 0;
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;
}
uint32_t acpu_start_rawdata(void)
{
uint32_t j = 0;
start_msg.req_type = REQ_TYPE_NEW;
while(!rawdata_cnf_received){
if(iot_mc_ipc_query_mailbox_freecredit() >0){
iot_mc_ipc_send_msg(IPC_MSG_ID_RAWDATA_START_REQ, (void*)&start_msg);
}
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
uint32_t mac_tx_single_mode()
{
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};
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);
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 = mpdu_start.tx_status->tx_done;
} 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;
}
} while (true);
return 0;
}
extern tonemap_table_entry spg_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(PHY_PROTO_TYPE_GET() == PLC_PROTO_TYPE_SG)
{
/* mask unused TMI in standard table */
if(sg_tonemap_table[i].pb_size == 0 || j > sg_tonemap_table[i].max_pb_num){
continue;
}
/* mask unused TMI in ext table */
if(i >= 15){
if(sg_ext_tonemap_table[i].pb_size == 0 || \
j > sg_ext_tonemap_table[i].max_pb_num){
continue;
}
}
/* not support,delete in the future */
if(i == 16 || i == 17)
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
}
#if SUPPORT_SOUTHERN_POWER_GRID
else if(PHY_PROTO_TYPE_GET() == PLC_PROTO_TYPE_SPG)
{
/* mask some unused TMI */
if(spg_tonemap_table[i].pb_size == 0 || j > spg_tonemap_table[i].max_pb_num)
continue;
/* TMIExt not done now */
if(i > 10)
continue;
}
#endif
else 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;
}
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);
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 = mpdu_start.tx_status->tx_done;
} 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;
/* 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);
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 (0&& (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;
}
} 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);
/* 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_start()
{
#if HW_PLATFORM > HW_PLATFORM_SIMU
#if EDA_SIMU_SUPPORT != 1
/* serial init */
dbg_uart_init();
iot_printf("mac_tx_test begin...\n");
#endif
#endif
/* glb cfg mapping */
glb_cfg.m_type = PHY_PROTO_TYPE_GET();
/* mac tx common init interface */
tx_common_init();
#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);
while(!mac_tx_complete_flag);
mac_tx_complete_flag = false;
return;
#endif
#ifdef IPC_CONTROL
iot_rawdata_init_ipc(IOT_APPCPU_ID);
acpu_start_rawdata();
#endif
switch(MAC_TX_TEST_ID)
{
case MAC_TX_BEACON:
case MAC_TX_SOF:
mac_tx_single_mode();
break;
case MAC_TX_TMI:
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;
default:
while(true);
}
return;
}
#if !MODULE_EN
int main(void) {
mac_tx_start();
return 0;
}
#endif