/**************************************************************************** * * 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 "hw_reg_api.h" #include "tx_mpdu_start.h" #include "rx_desc_reg_api.h" #include "phy_bb.h" #include "hw_rx.h" #include "rx_entry.h" #include "tx_entry.h" #include "hal_rx.h" #include "iot_bitops.h" #include "iot_io.h" #include "iot_led.h" #include "mpdu_header.h" plc_dt_ctxt_t g_plc_dt_ctxt = {{0, NULL, {{0}}, NULL, 4000}}; void dut_flag_set(bool_t flag_status) { g_plc_dt_ctxt.indep.dut_flag = flag_status; } mac_rx_phy_info_t *phy_info_ptr_get() { return g_plc_dt_ctxt.indep.phy_info; } /* support mode : ftm, module, dtest scan */ void rx_common_init(uint32_t band_idx) { /* basic data struct init for bit ops */ iot_bitops_init(); #if SUPPORT_SMART_GRID glb_cfg.m_type = PLC_PROTO_TYPE_SG; #elif SUPPORT_SOUTHERN_POWER_GRID glb_cfg.m_type = PLC_PROTO_TYPE_SPG; #endif mac_rx_init(band_idx); /* setup the rx ring */ rx_ring_setup_hw(0, NULL); /* enable the rx ring */ rx_ring_enable(0, true); } void mac_tmi_cnt_clr() { for(uint32_t j = 0; j < MAX_TMI_NUM; j++) { g_plc_dt_ctxt.indep.tmi_beacon_cnt[j][0] = 0; g_plc_dt_ctxt.indep.tmi_beacon_cnt[j][1] = 0; g_plc_dt_ctxt.indep.tmi_beacon_cnt[j][2] = 0; g_plc_dt_ctxt.indep.tmi_beacon_cnt[j][3] = 0; g_plc_dt_ctxt.indep.tmi_sof_cnt[j][0] = 0; g_plc_dt_ctxt.indep.tmi_sof_cnt[j][1] = 0; g_plc_dt_ctxt.indep.tmi_sof_cnt[j][2] = 0; g_plc_dt_ctxt.indep.tmi_sof_cnt[j][3] = 0; } for(uint32_t k = 0; k < MAX_PB_NUM; k++) { g_plc_dt_ctxt.indep.tmi_sack_cnt[k] = 0; g_plc_dt_ctxt.indep.tmi_nncco_cnt[k] = 0; } } /* packets detail cnt printer */ void mac_pkt_info_cnt_print() { uint8_t tmi = 0, tmp = 0, i = 0; uint32_t rate_idx = 0; iot_phy_sts_info_t total_sts = {0}; iot_mac_sts_info_t mac_sts = {0}; phy_sts_get(&total_sts); iot_printf("[CNT][mac]tx_ok:%d/4s\r\n", total_sts.mac_tx_ok_cnt); iot_printf("[CNT][phy]fc_ok:%d/4s, fc_err:%d/4s,", \ 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, " "rx_abort:%d/4s\r\n", \ total_sts.pld_crc_ok_cnt, total_sts.pld_crc_fail_cnt, \ total_sts.sync_ok_cnt, total_sts.phy_rx_abort_cnt); /*control IOT_PLC_RX_LED on the basis of pld_crc_ok_cnt*/ if(total_sts.pld_crc_ok_cnt >= PHY_RX_CRC_RATE_LED_ON) { iot_led_on(IOT_PLC_RX_LED); } else if (total_sts.pld_crc_ok_cnt == PHY_RX_CRC_RATE_LED_OFF) { iot_led_off(IOT_PLC_RX_LED); } else { iot_led_off(IOT_PLC_RX_LED); iot_led_blink(IOT_PLC_RX_LED, 1); } /* Multi PB cnt */ iot_printf("[MPB]pb_ok_1st:%d, 2nd:%d, 3rd:%d, 4th:%d\r\n", \ g_plc_dt_ctxt.indep.fisrt_pb_crc_ok_cnt, \ g_plc_dt_ctxt.indep.second_pb_crc_ok_cnt, \ g_plc_dt_ctxt.indep.third_pb_crc_ok_cnt, \ g_plc_dt_ctxt.indep.last_pb_crc_ok_cnt); /* reset cnt */ g_plc_dt_ctxt.indep.fisrt_pb_crc_ok_cnt = 0; g_plc_dt_ctxt.indep.second_pb_crc_ok_cnt = 0; g_plc_dt_ctxt.indep.third_pb_crc_ok_cnt = 0; g_plc_dt_ctxt.indep.last_pb_crc_ok_cnt = 0; /* print tmi cnt */ tmi = MAX_TMI_NUM; while(tmi--){ for(i = 0; i < 4; i++) { /* beacon */ if (g_plc_dt_ctxt.indep.tmi_beacon_cnt[tmi][i] != 0) { if (tmi < 15) { iot_printf("[BCN][tmi-%d][pb-%d]:%d\r\n", \ tmi,i,g_plc_dt_ctxt.indep.tmi_beacon_cnt[tmi][i]); } else { tmp = tmi - 15;/* skip optimization for next */ iot_printf("[BCN][ext-tmi-%d][pb-%d]:%d\r\n", \ tmp,i,g_plc_dt_ctxt.indep.tmi_beacon_cnt[tmi][i]); } g_plc_dt_ctxt.indep.tmi_beacon_cnt[tmi][i] = 0; } /* sof */ if (g_plc_dt_ctxt.indep.tmi_sof_cnt[tmi][i] != 0) { if (tmi < 15) { iot_printf("[SOF][tmi-%d][pb-%d]:%d\r\n", \ tmi,i,g_plc_dt_ctxt.indep.tmi_sof_cnt[tmi][i]); } else { tmp = tmi - 15;/* skip optimization for next */ iot_printf("[SOF][ext-tmi-%d][pb-%d]:%d\r\n", \ tmp,i,g_plc_dt_ctxt.indep.tmi_sof_cnt[tmi][i]); } g_plc_dt_ctxt.indep.tmi_sof_cnt[tmi][i] = 0; } } } /* sack & nncco */ for(i=0; i<4; i++) { if (g_plc_dt_ctxt.indep.tmi_sack_cnt[i] != 0) { iot_printf("[SACK][pb-%d]:%d\r\n", i, \ g_plc_dt_ctxt.indep.tmi_sack_cnt[i]); g_plc_dt_ctxt.indep.tmi_sack_cnt[i] = 0; } if (g_plc_dt_ctxt.indep.tmi_nncco_cnt[i] != 0) { iot_printf("[NNCCO][pb-%d]:%d\r\n", i, \ g_plc_dt_ctxt.indep.tmi_nncco_cnt[i]); g_plc_dt_ctxt.indep.tmi_nncco_cnt[i] = 0; } } /* band info */ for(rate_idx=0; rate_idxmpdu_ed); g_plc_dt_ctxt.indep.rx_ntb_ts_last = g_plc_dt_ctxt.indep.rx_ntb_ts_cur; g_plc_dt_ctxt.indep.rx_ntb_ts_cur = \ mac_rx_mpdu_end_get_ntb_timestamp(&pb_buf->mpdu_ed);; g_plc_dt_ctxt.indep.tx_ts_last = g_plc_dt_ctxt.indep.tx_ts_cur; g_plc_dt_ctxt.indep.tx_ts_cur = \ mac_get_bcn_st(PHY_PROTO_TYPE_GET(), \ mac_rx_mpdu_st_get_fc_addr(&pb_buf->mpdu_st)); rx_span = g_plc_dt_ctxt.indep.rx_ts_cur - \ g_plc_dt_ctxt.indep.rx_ts_last; if (rx_span < 0) { // wrap around rx_span = (0x100000000LL) - \ g_plc_dt_ctxt.indep.rx_ts_last + \ g_plc_dt_ctxt.indep.rx_ts_cur; } rx_ntb_span = g_plc_dt_ctxt.indep.rx_ntb_ts_cur - \ g_plc_dt_ctxt.indep.rx_ntb_ts_last; if (rx_ntb_span < 0) { // wrap around rx_ntb_span = (0x100000000LL) - \ g_plc_dt_ctxt.indep.rx_ntb_ts_last + \ g_plc_dt_ctxt.indep.rx_ntb_ts_cur; } tx_span = g_plc_dt_ctxt.indep.tx_ts_cur - \ g_plc_dt_ctxt.indep.tx_ts_last; if (tx_span < 0) { // wrap around tx_span = (0x100000000LL) - \ g_plc_dt_ctxt.indep.tx_ts_last + \ g_plc_dt_ctxt.indep.tx_ts_cur; } #if PHY_RX_DBG_EN iot_printf("[Debug]ntb ts0:%u, ts1:%u, ts_span:%u\r\n", \ g_plc_dt_ctxt.indep.rx_ntb_ts_last, \ g_plc_dt_ctxt.indep.rx_ntb_ts_cur, \ (uint32_t)rx_ntb_span); iot_printf("[Debug]rx0:%u,rx1:%u,tx0:%u,tx1:%u,\r\n", \ g_plc_dt_ctxt.indep.rx_ts_last, \ g_plc_dt_ctxt.indep.rx_ts_cur, \ g_plc_dt_ctxt.indep.tx_ts_last, \ g_plc_dt_ctxt.indep.tx_ts_cur); iot_printf("r1-r0:%u,t1-t0:%u, ppm_pkt:%d\r\n", \ (uint32_t)rx_span, \ (uint32_t)tx_span, pb_buf->mpdu_st.phy.est_ppm); #endif if (rx_span > (ppm_cnt - (ppm_cnt >> 1)) && \ rx_span < (ppm_cnt + (ppm_cnt >> 1))) { /* cal ppm */ ppm = (rx_ntb_span - tx_span) * (1 << 20); ppm = ppm/tx_span; /* check ppm valid */ if (ppm < 200 && ppm > -200) { phy_ppm_cal_and_update_hw(PHY_CAL_UNIT_1_1, \ -ppm, IOT_SUPPORT_RATE_SR, BB_PPM_TXRX); iot_printf("[ppm cali] write ppm:%d successfully!\r\n", \ (uint32_t)ppm); } else { iot_printf("[ppm cali] ppm:%d cal failed!\r\n",(uint32_t)ppm); } } else { iot_printf("[ppm cali] rx_span:%lld not valid!\r\n", rx_span); } return ERR_OK; }