660 lines
20 KiB
C
660 lines
20 KiB
C
|
/****************************************************************************
|
||
|
|
||
|
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 "iot_config.h"
|
||
|
#include "os_types.h"
|
||
|
#include "hw_reg_api.h"
|
||
|
#include "phy_tmap.h"
|
||
|
#include "phy_bb.h"
|
||
|
#include "iot_errno_api.h"
|
||
|
#include "phy_reg.h"
|
||
|
#include "phy_tx_reg.h"
|
||
|
#include "phy_rx_fd_reg.h"
|
||
|
#include "phy_rxtd_reg.h"
|
||
|
#include "hw_tonemask.h"
|
||
|
#include "hw_tonemap.h"
|
||
|
#include "iot_io.h"
|
||
|
#include "phy_mix.h"
|
||
|
#include "hw_phy_api.h"
|
||
|
|
||
|
void phy_fft_4096p_init(bool_t en)
|
||
|
{
|
||
|
/* init */
|
||
|
uint32_t tmp = 0;
|
||
|
|
||
|
if(en == true) {
|
||
|
/* 4096 point */
|
||
|
tmp = PHY_READ_REG(CFG_BB_SAMPLING_RATE_ADDR);
|
||
|
REG_FIELD_SET(SW_SAMPLING_RATE_SEL, tmp, 1);
|
||
|
PHY_WRITE_REG(CFG_BB_SAMPLING_RATE_ADDR, tmp);
|
||
|
|
||
|
tmp = PHY_READ_REG(CFG_BB_FCPLD_FFT_NUM_CTRT_ADDR);
|
||
|
REG_FIELD_SET(SW_PLD_FFT_HALF_NUM, tmp, 2048);
|
||
|
REG_FIELD_SET(SW_FC_FFT_HALF_NUM, tmp, 2048);
|
||
|
PHY_WRITE_REG(CFG_BB_FCPLD_FFT_NUM_CTRT_ADDR, tmp);
|
||
|
|
||
|
tmp = PHY_TX_READ_REG(CFG_BB_TX_CONST_CTRL_3_ADDR);
|
||
|
REG_FIELD_SET(SW_IS_191_INSERT_PREAM, tmp, 255);
|
||
|
PHY_TX_WRITE_REG(CFG_BB_TX_CONST_CTRL_3_ADDR, tmp);
|
||
|
|
||
|
tmp = PHY_TX_READ_REG(CFG_BB_TX_CONST_CTRL_1_ADDR);
|
||
|
REG_FIELD_SET(SW_IS_1535_INSERT_PREAM, tmp, 2047);
|
||
|
PHY_TX_WRITE_REG(CFG_BB_TX_CONST_CTRL_1_ADDR, tmp);
|
||
|
|
||
|
tmp = PHY_TX_READ_REG(CFG_BB_TX_CONST_CTRL_D_ADDR);
|
||
|
REG_FIELD_SET(SW_SG_IFFT_POINT_NUM_HALF, tmp, 2048);
|
||
|
REG_FIELD_SET(SW_SG_IFFT_POINT_NUM, tmp, 4096);
|
||
|
PHY_TX_WRITE_REG(CFG_BB_TX_CONST_CTRL_D_ADDR, tmp);
|
||
|
|
||
|
tmp = PHY_TX_READ_REG(CFG_BB_TX_CONST_CTRL_E_ADDR);
|
||
|
REG_FIELD_SET(SW_GP_PREAM_IFFT_POINT_NUM_HALF, tmp, 256);
|
||
|
REG_FIELD_SET(SW_GP_PREAM_IFFT_POINT_NUM, tmp, 512);
|
||
|
PHY_TX_WRITE_REG(CFG_BB_TX_CONST_CTRL_E_ADDR, tmp);
|
||
|
|
||
|
tmp = PHY_TX_READ_REG(CFG_BB_TX_CONST_CTRL_C_ADDR);
|
||
|
REG_FIELD_SET(SW_RI_POINT_NUM, tmp, 496);
|
||
|
PHY_TX_WRITE_REG(CFG_BB_TX_CONST_CTRL_C_ADDR, tmp);
|
||
|
|
||
|
tmp = PHY_READ_REG(CFG_BB_TONE_MAP_GIX_POINT_ADDR);
|
||
|
REG_FIELD_SET(SW_AV_HIGH_SPEED_GI_567, tmp, 756);
|
||
|
REG_FIELD_SET(SW_AV_HIGH_SPEED_GI_417, tmp, 556);
|
||
|
PHY_WRITE_REG(CFG_BB_TONE_MAP_GIX_POINT_ADDR, tmp);
|
||
|
|
||
|
tmp = PHY_READ_REG(CFG_BB_TONE_MAP_GIX_LONG_ADDR);
|
||
|
REG_FIELD_SET(SW_AV_HIGH_SPEED_GI_3534, tmp, 4712);
|
||
|
PHY_WRITE_REG(CFG_BB_TONE_MAP_GIX_LONG_ADDR, tmp);
|
||
|
|
||
|
tmp = PHY_READ_REG(CFG_BB_TR_GP_FC_PLD_GI_ADDR);
|
||
|
REG_FIELD_SET(SW_GP_PLD_GI_STD, tmp, 556);
|
||
|
PHY_WRITE_REG(CFG_BB_TR_GP_FC_PLD_GI_ADDR, tmp);
|
||
|
|
||
|
tmp = PHY_READ_REG(CFG_BB_TR_GP_PLD_GI_ADDR);
|
||
|
REG_FIELD_SET(SW_GP_PLD_GI_HS, tmp, 556);
|
||
|
REG_FIELD_SET(SW_GP_PLD_GI_MIN, tmp, 756);
|
||
|
PHY_WRITE_REG(CFG_BB_TR_GP_PLD_GI_ADDR, tmp);
|
||
|
|
||
|
phy_rxfd_rate0_det(0, 2047);
|
||
|
phy_rxfd_rate1_det(0, 2047);
|
||
|
} else {
|
||
|
/* 4096 point */
|
||
|
tmp = PHY_READ_REG(CFG_BB_SAMPLING_RATE_ADDR);
|
||
|
REG_FIELD_SET(SW_SAMPLING_RATE_SEL, tmp, 0);
|
||
|
PHY_WRITE_REG(CFG_BB_SAMPLING_RATE_ADDR, tmp);
|
||
|
|
||
|
tmp = PHY_READ_REG(CFG_BB_FCPLD_FFT_NUM_CTRT_ADDR);
|
||
|
REG_FIELD_SET(SW_PLD_FFT_HALF_NUM, tmp, 1536);
|
||
|
REG_FIELD_SET(SW_FC_FFT_HALF_NUM, tmp, 1536);
|
||
|
PHY_WRITE_REG(CFG_BB_FCPLD_FFT_NUM_CTRT_ADDR, tmp);
|
||
|
|
||
|
tmp = PHY_TX_READ_REG(CFG_BB_TX_CONST_CTRL_3_ADDR);
|
||
|
REG_FIELD_SET(SW_IS_191_INSERT_PREAM, tmp, 191);
|
||
|
PHY_TX_WRITE_REG(CFG_BB_TX_CONST_CTRL_3_ADDR, tmp);
|
||
|
|
||
|
tmp = PHY_TX_READ_REG(CFG_BB_TX_CONST_CTRL_1_ADDR);
|
||
|
REG_FIELD_SET(SW_IS_1535_INSERT_PREAM, tmp, 1535);
|
||
|
PHY_TX_WRITE_REG(CFG_BB_TX_CONST_CTRL_1_ADDR, tmp);
|
||
|
|
||
|
tmp = PHY_TX_READ_REG(CFG_BB_TX_CONST_CTRL_D_ADDR);
|
||
|
REG_FIELD_SET(SW_SG_IFFT_POINT_NUM_HALF, tmp, 1536);
|
||
|
REG_FIELD_SET(SW_SG_IFFT_POINT_NUM, tmp, 3072);
|
||
|
PHY_TX_WRITE_REG(CFG_BB_TX_CONST_CTRL_D_ADDR, tmp);
|
||
|
|
||
|
tmp = PHY_TX_READ_REG(CFG_BB_TX_CONST_CTRL_E_ADDR);
|
||
|
REG_FIELD_SET(SW_GP_PREAM_IFFT_POINT_NUM_HALF, tmp, 192);
|
||
|
REG_FIELD_SET(SW_GP_PREAM_IFFT_POINT_NUM, tmp, 384);
|
||
|
PHY_TX_WRITE_REG(CFG_BB_TX_CONST_CTRL_E_ADDR, tmp);
|
||
|
|
||
|
tmp = PHY_TX_READ_REG(CFG_BB_TX_CONST_CTRL_C_ADDR);
|
||
|
REG_FIELD_SET(SW_RI_POINT_NUM, tmp, 372);
|
||
|
PHY_TX_WRITE_REG(CFG_BB_TX_CONST_CTRL_C_ADDR, tmp);
|
||
|
|
||
|
tmp = PHY_READ_REG(CFG_BB_TONE_MAP_GIX_POINT_ADDR);
|
||
|
REG_FIELD_SET(SW_AV_HIGH_SPEED_GI_567, tmp, 567);
|
||
|
REG_FIELD_SET(SW_AV_HIGH_SPEED_GI_417, tmp, 417);
|
||
|
PHY_WRITE_REG(CFG_BB_TONE_MAP_GIX_POINT_ADDR, tmp);
|
||
|
|
||
|
tmp = PHY_READ_REG(CFG_BB_TONE_MAP_GIX_LONG_ADDR);
|
||
|
REG_FIELD_SET(SW_AV_HIGH_SPEED_GI_3534, tmp, 3534);
|
||
|
PHY_WRITE_REG(CFG_BB_TONE_MAP_GIX_LONG_ADDR, tmp);
|
||
|
|
||
|
tmp = PHY_READ_REG(CFG_BB_TR_GP_FC_PLD_GI_ADDR);
|
||
|
REG_FIELD_SET(SW_GP_PLD_GI_STD, tmp, 417);
|
||
|
PHY_WRITE_REG(CFG_BB_TR_GP_FC_PLD_GI_ADDR, tmp);
|
||
|
|
||
|
tmp = PHY_READ_REG(CFG_BB_TR_GP_PLD_GI_ADDR);
|
||
|
REG_FIELD_SET(SW_GP_PLD_GI_HS, tmp, 417);
|
||
|
REG_FIELD_SET(SW_GP_PLD_GI_MIN, tmp, 567);
|
||
|
PHY_WRITE_REG(CFG_BB_TR_GP_PLD_GI_ADDR, tmp);
|
||
|
|
||
|
/* config det tone */
|
||
|
phy_update_tone_det_range();
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if SUPPORT_GREEN_PHY
|
||
|
|
||
|
uint32_t phy_tmap_cal( \
|
||
|
uint32_t *sound_data_ptr, \
|
||
|
uint32_t *tone_map_ptr, \
|
||
|
uint32_t start_tone, \
|
||
|
uint32_t end_tone, \
|
||
|
uint8_t cal_lvl)
|
||
|
{
|
||
|
uint32_t ret = ERR_OK;
|
||
|
#if HW_PLATFORM >= HW_PLATFORM_FPGA && \
|
||
|
SUPPORT_GREEN_PHY == 1
|
||
|
uint32_t i = 0;
|
||
|
uint32_t tmp = 0;
|
||
|
volatile uint32_t map_begin_col_idx = 0;
|
||
|
volatile uint32_t map_begin_group_idx = 0;
|
||
|
volatile uint32_t map_end_col_idx = 0;
|
||
|
volatile uint32_t map_end_group_idx = 0;
|
||
|
|
||
|
/* check valid */
|
||
|
IOT_ASSERT((start_tone < end_tone) && \
|
||
|
(end_tone < TOTAL_TONE_MASK_NUM) && \
|
||
|
(sound_data_ptr != NULL) && \
|
||
|
(tone_map_ptr != NULL));
|
||
|
|
||
|
/* get start tone */
|
||
|
map_begin_col_idx = start_tone & 0x7;
|
||
|
map_begin_group_idx = start_tone >> 3;
|
||
|
|
||
|
/* get end tone */
|
||
|
map_end_col_idx = end_tone & 0x7;
|
||
|
map_end_group_idx = end_tone >> 3;
|
||
|
|
||
|
enable_sw_access_tmi_buf(true);
|
||
|
/* tone mask table */
|
||
|
for(i = map_begin_group_idx; i <= map_end_group_idx; i++)
|
||
|
{
|
||
|
tmp = 0;
|
||
|
/* Must word write */
|
||
|
if((map_begin_col_idx != 0) && \
|
||
|
(i == map_begin_group_idx)) {
|
||
|
while(map_begin_col_idx < 8)
|
||
|
{
|
||
|
tmp |= ((1 << PHY_TMAP_MODU_EN_OFFSET) | PHY_MODU_QPSK) << \
|
||
|
(map_begin_col_idx << 2);
|
||
|
map_begin_col_idx++;
|
||
|
}
|
||
|
} else if((map_end_col_idx != 7) && \
|
||
|
(i == map_end_group_idx)){
|
||
|
map_end_col_idx = map_end_col_idx + 1;
|
||
|
while(map_end_col_idx > 0)
|
||
|
{
|
||
|
tmp |= ((1 << PHY_TMAP_MODU_EN_OFFSET) | PHY_MODU_QPSK) << \
|
||
|
((map_end_col_idx - 1) << 2);
|
||
|
map_end_col_idx--;
|
||
|
}
|
||
|
} else {
|
||
|
/* TODO: get data from sound data */
|
||
|
(void)sound_data_ptr;
|
||
|
tmp = (((1 << PHY_TMAP_MODU_EN_OFFSET) | PHY_MODU_QPSK) << 0) | \
|
||
|
(((1 << PHY_TMAP_MODU_EN_OFFSET) | PHY_MODU_QPSK) << 4) | \
|
||
|
(((1 << PHY_TMAP_MODU_EN_OFFSET) | PHY_MODU_QPSK) << 8) | \
|
||
|
(((1 << PHY_TMAP_MODU_EN_OFFSET) | PHY_MODU_QPSK) << 12) |\
|
||
|
(((1 << PHY_TMAP_MODU_EN_OFFSET) | PHY_MODU_QPSK) << 16) | \
|
||
|
(((1 << PHY_TMAP_MODU_EN_OFFSET) | PHY_MODU_QPSK) << 20) | \
|
||
|
(((1 << PHY_TMAP_MODU_EN_OFFSET) | PHY_MODU_QPSK) << 24) | \
|
||
|
(((1 << PHY_TMAP_MODU_EN_OFFSET) | PHY_MODU_QPSK) << 28);
|
||
|
}
|
||
|
*(tone_map_ptr + map_begin_group_idx) = tmp;
|
||
|
tone_map_ptr++;
|
||
|
}
|
||
|
enable_sw_access_tmi_buf(false);
|
||
|
|
||
|
(void)cal_lvl;
|
||
|
#else
|
||
|
(void)sound_data_ptr;
|
||
|
(void)tone_map_ptr;
|
||
|
(void)start_tone;
|
||
|
(void)end_tone;
|
||
|
(void)cal_lvl;
|
||
|
#endif
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
void phy_tmap_tx_rule_set(plc_tmap_rule_t *rule)
|
||
|
{
|
||
|
#if HW_PLATFORM >= HW_PLATFORM_FPGA && \
|
||
|
SUPPORT_GREEN_PHY == 1
|
||
|
uint32_t tmp = 0;
|
||
|
uint32_t reg_base = 0;
|
||
|
uint32_t tmap_base = 0;
|
||
|
uint32_t tmap_idx = 0;
|
||
|
|
||
|
/* valid en */
|
||
|
tmap_base = rule->rule_id >> 5;
|
||
|
tmap_idx = 31 - (rule->rule_id & 0x1F);
|
||
|
reg_base = CFG_BB_TMAP_TX_VLD_CTRL_0_ADDR + (tmap_base << 2);
|
||
|
tmp = PHY_READ_REG(reg_base);
|
||
|
if(rule->en) {
|
||
|
tmp |= 1 << tmap_idx;
|
||
|
PHY_WRITE_REG(reg_base, tmp);
|
||
|
} else {
|
||
|
tmp &= ~(1 << tmap_idx);
|
||
|
PHY_WRITE_REG(reg_base, tmp);
|
||
|
}
|
||
|
|
||
|
/* tx dtei */
|
||
|
tmap_base = rule->rule_id >> 2;
|
||
|
tmap_idx = (3 - (rule->rule_id & 0x3)) << 3;
|
||
|
reg_base = CFG_BB_TMAP_TX_DTEI_CTRL_0_ADDR + (tmap_base << 2);
|
||
|
tmp = PHY_READ_REG(reg_base);
|
||
|
tmp |= rule->dtei << tmap_idx;
|
||
|
PHY_WRITE_REG(reg_base, tmp);
|
||
|
|
||
|
/* tmi */
|
||
|
tmap_base = rule->rule_id >> 2;
|
||
|
tmap_idx = (3 - (rule->rule_id & 0x3)) << 3;
|
||
|
reg_base = CFG_BB_TMAP_TX_TMI_CTRL_0_ADDR + (tmap_base << 2);
|
||
|
tmp = PHY_READ_REG(reg_base);
|
||
|
tmp |= rule->tmi << tmap_idx;
|
||
|
PHY_WRITE_REG(reg_base, tmp);
|
||
|
#else
|
||
|
(void)rule;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void phy_tmap_rx_rule_set(plc_tmap_rule_t *rule)
|
||
|
{
|
||
|
#if HW_PLATFORM >= HW_PLATFORM_FPGA && \
|
||
|
SUPPORT_GREEN_PHY == 1
|
||
|
uint32_t tmp = 0;
|
||
|
uint32_t reg_base = 0;
|
||
|
uint32_t tmap_base = 0;
|
||
|
uint32_t tmap_idx = 0;
|
||
|
|
||
|
/* valid en */
|
||
|
tmap_base = rule->rule_id >> 5;
|
||
|
tmap_idx = 31 - (rule->rule_id & 0x1F);
|
||
|
reg_base = CFG_BB_TMAP_RX_VLD_CTRL_0_ADDR + (tmap_base << 2);
|
||
|
tmp = PHY_READ_REG(reg_base);
|
||
|
if(rule->en) {
|
||
|
tmp |= 1 << tmap_idx;
|
||
|
PHY_WRITE_REG(reg_base, tmp);
|
||
|
} else {
|
||
|
tmp &= ~(1 << tmap_idx);
|
||
|
PHY_WRITE_REG(reg_base, tmp);
|
||
|
}
|
||
|
|
||
|
/* rx stei */
|
||
|
tmap_base = rule->rule_id >> 2;
|
||
|
tmap_idx = (3 - (rule->rule_id & 0x3)) << 3;
|
||
|
reg_base = CFG_BB_TMAP_RX_STEI_CTRL_0_ADDR + (tmap_base << 2);
|
||
|
tmp = PHY_READ_REG(reg_base);
|
||
|
tmp |= rule->dtei << tmap_idx;
|
||
|
PHY_WRITE_REG(reg_base, tmp);
|
||
|
|
||
|
/* tmi */
|
||
|
tmap_base = rule->rule_id >> 2;
|
||
|
tmap_idx = (3 - (rule->rule_id & 0x3)) << 3;
|
||
|
reg_base = CFG_BB_TMAP_RX_TMI_CTRL_0_ADDR + (tmap_base << 2);
|
||
|
tmp = PHY_READ_REG(reg_base);
|
||
|
tmp |= rule->tmi << tmap_idx;
|
||
|
PHY_WRITE_REG(reg_base, tmp);
|
||
|
#else
|
||
|
(void)rule;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void phy_tmap_self_tmi_set(uint8_t tmi)
|
||
|
{
|
||
|
#if HW_PLATFORM >= HW_PLATFORM_FPGA && \
|
||
|
SUPPORT_GREEN_PHY == 1
|
||
|
uint32_t tmp = 0;
|
||
|
|
||
|
/* tx/rx stei */
|
||
|
tmp = PHY_READ_REG(CFG_BB_TMAP_SELF_TEI_CTRL_ADDR);
|
||
|
REG_FIELD_SET(SW_TMAP_TX_STEI, tmp, tmi);
|
||
|
REG_FIELD_SET( SW_TMAP_RX_DTEI, tmp, tmi);
|
||
|
PHY_WRITE_REG(CFG_BB_TMAP_SELF_TEI_CTRL_ADDR, tmp);
|
||
|
#else
|
||
|
(void)tmi;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void phy_tmap_init()
|
||
|
{
|
||
|
#if HW_PLATFORM >= HW_PLATFORM_FPGA && \
|
||
|
SUPPORT_GREEN_PHY == 1
|
||
|
uint32_t tmp = 0;
|
||
|
|
||
|
tmp = PHY_RX_FD_READ_REG(CFG_BB_DECISION_FEEDBACK_ADDR);
|
||
|
REG_FIELD_SET(SW_DCFB_ALPHA, tmp, 4);
|
||
|
REG_FIELD_SET(SW_DCFB_EN, tmp, 0);
|
||
|
PHY_RX_FD_WRITE_REG(CFG_BB_DECISION_FEEDBACK_ADDR, tmp);
|
||
|
|
||
|
phy_mix_flag_set(false);
|
||
|
|
||
|
tmp = PHY_RX_FD_READ_REG(CFG_BB_RATE_OFFET_ADDR);
|
||
|
REG_FIELD_SET(SW_CSI_RATE1_OFFSET, tmp, 0);
|
||
|
PHY_RX_FD_WRITE_REG(CFG_BB_RATE_OFFET_ADDR, tmp);
|
||
|
|
||
|
phy_rxfd_mc_en(true);
|
||
|
|
||
|
tmp = PHY_RX_FD_READ_REG(CFG_BB_PKT_DET_ADDR);
|
||
|
REG_FIELD_SET(SW_SYMB_SYNC_OFFSET, tmp, 1);
|
||
|
PHY_RX_FD_WRITE_REG(CFG_BB_PKT_DET_ADDR, tmp);
|
||
|
|
||
|
/* disable acc first negative preamble */
|
||
|
tmp = PHY_RX_FD_READ_REG(CFG_BB_FRAME_SYNC_ADDR);
|
||
|
REG_FIELD_SET(SW_SYNC_SYMB_ACC_EN, tmp, 0);
|
||
|
PHY_RX_FD_WRITE_REG(CFG_BB_FRAME_SYNC_ADDR,tmp);
|
||
|
|
||
|
/* GI */
|
||
|
tmp = PHY_RXTD_READ_REG(CFG_BB_TUNE_FOR_GI_ADDR);
|
||
|
REG_FIELD_SET(SW_TUNE_FOR_PLD_GI2, tmp, 2);
|
||
|
REG_FIELD_SET(SW_TUNE_FOR_PLD_GI1, tmp, 2);
|
||
|
REG_FIELD_SET(SW_TUNE_FOR_PLD_GI0, tmp, 2);
|
||
|
REG_FIELD_SET(SW_TUNE_FOR_FC_GI1, tmp, 0);
|
||
|
PHY_RXTD_WRITE_REG(CFG_BB_TUNE_FOR_GI_ADDR, tmp);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
/* tmap bits array
|
||
|
PHY_MODU_BPSK ~ PHY_MODU_4096QAM */
|
||
|
uint8_t tmap_bits_arry[] = {1,2,4,3,6,8,10,12};
|
||
|
|
||
|
uint32_t phy_cal_tmap_symb_bits( \
|
||
|
uint32_t start_tone, \
|
||
|
uint32_t end_tone, \
|
||
|
uint32_t *tone_map_ptr, \
|
||
|
const plc_tonemask_table *tmt)
|
||
|
{
|
||
|
uint32_t i = 0;
|
||
|
uint32_t modu = 0;
|
||
|
uint32_t bits_in_a_symb = 0;
|
||
|
uint32_t tmap_col_idx = 0, tmsk_col_idx = 0;
|
||
|
uint32_t tmap_group_idx = 0, tmsk_group_idx = 0;
|
||
|
|
||
|
/* check valid */
|
||
|
IOT_ASSERT((start_tone < end_tone) && \
|
||
|
(end_tone < TOTAL_TONE_MASK_NUM) && \
|
||
|
(tone_map_ptr != NULL) && \
|
||
|
(tmt != NULL));
|
||
|
|
||
|
for(i = start_tone; i <= end_tone; i++)
|
||
|
{
|
||
|
/* get tmap index */
|
||
|
tmap_col_idx = i & 0x7;
|
||
|
tmap_group_idx = i >> 3;
|
||
|
/* get tone mask index */
|
||
|
tmsk_col_idx = i & 0x1F;
|
||
|
tmsk_group_idx = i >> 5;
|
||
|
|
||
|
/* (*(tone_map_ptr + group_idx) & (0x8 << (col_idx << 2))) */
|
||
|
if (tmt->tone_mask_bitmap[tmsk_group_idx] & \
|
||
|
(1 << tmsk_col_idx)) {
|
||
|
/* cal modulation */
|
||
|
modu = (*(tone_map_ptr + tmap_group_idx) >> \
|
||
|
(tmap_col_idx << 2)) & 0x7;
|
||
|
/* cal bits */
|
||
|
bits_in_a_symb += tmap_bits_arry[modu];
|
||
|
}
|
||
|
//iot_printf("i=%d, bits:%d\n", i, bits_in_a_symb);
|
||
|
}
|
||
|
return bits_in_a_symb;
|
||
|
}
|
||
|
|
||
|
static const uint8_t sv_turbo_rate_x16[3] =
|
||
|
{
|
||
|
32, 21, 18
|
||
|
};
|
||
|
|
||
|
int hpav_cal_fl_tmap
|
||
|
(
|
||
|
uint8_t mpdu_cnt,
|
||
|
uint8_t pb_num,
|
||
|
uint8_t turbo_rate,
|
||
|
uint8_t tmap_gi,
|
||
|
uint32_t bits_per_symb
|
||
|
)
|
||
|
{
|
||
|
int cur_ifs;
|
||
|
uint16_t pb_size;
|
||
|
int pb_gi0;
|
||
|
int pb_gi0_range;
|
||
|
int align_para;
|
||
|
int bits_num_total;
|
||
|
int bits_rest;
|
||
|
int bits_per_pb;
|
||
|
int turbo_rate_x16;
|
||
|
int max_symb_num;
|
||
|
int max_pb_num;
|
||
|
int symb_num_total;
|
||
|
float fl_total;
|
||
|
int fl_total_new;
|
||
|
int tmap_gi_val;
|
||
|
|
||
|
tmap_gi_val = (tmap_gi == PHY_GI_417) ? 417 :
|
||
|
(tmap_gi == PHY_GI_567) ? 567 : 3534;
|
||
|
|
||
|
cur_ifs = (mpdu_cnt == 0) ? HPAV_RIFS : HPAV_BIFS ;
|
||
|
pb_size = PB_SIZE_520;
|
||
|
|
||
|
if (turbo_rate > 2) {
|
||
|
turbo_rate = 2;
|
||
|
}
|
||
|
turbo_rate_x16 = sv_turbo_rate_x16[turbo_rate];
|
||
|
|
||
|
pb_gi0 = PB_GI0;
|
||
|
pb_gi0_range = 2;
|
||
|
align_para = ALIGN_PARA;
|
||
|
|
||
|
bits_per_pb = (pb_size * 8 * turbo_rate_x16)/16 ;
|
||
|
|
||
|
/* (4095-140/1.28) = 3985.625 */
|
||
|
max_symb_num = (int)(((3985.625) * (float)(align_para) - \
|
||
|
(FFT_POINT + pb_gi0) * pb_gi0_range) / \
|
||
|
(FFT_POINT + tmap_gi_val) + pb_gi0_range - 1) ;
|
||
|
max_pb_num = (int)(max_symb_num * bits_per_symb / bits_per_pb);
|
||
|
if (pb_num > max_pb_num) {
|
||
|
pb_num = max_pb_num;
|
||
|
}
|
||
|
|
||
|
bits_num_total = pb_num * bits_per_pb ;
|
||
|
symb_num_total = bits_num_total / bits_per_symb ;
|
||
|
bits_rest = bits_num_total % bits_per_symb;
|
||
|
|
||
|
if (bits_rest == 0) {
|
||
|
symb_num_total = symb_num_total - 1;
|
||
|
bits_rest = bits_per_symb;
|
||
|
}
|
||
|
|
||
|
while (bits_rest > bits_per_pb)
|
||
|
{
|
||
|
pb_num = pb_num + 1;
|
||
|
|
||
|
bits_num_total = bits_num_total + bits_per_pb ;
|
||
|
symb_num_total = bits_num_total / bits_per_symb ;
|
||
|
bits_rest = bits_num_total % bits_per_symb;
|
||
|
|
||
|
if (bits_rest == 0) {
|
||
|
symb_num_total = symb_num_total - 1;
|
||
|
bits_rest = bits_per_symb;
|
||
|
}
|
||
|
}
|
||
|
symb_num_total = symb_num_total + 1;
|
||
|
|
||
|
fl_total = (float)( (FFT_POINT + pb_gi0) * pb_gi0_range + \
|
||
|
(symb_num_total - pb_gi0_range) * (FFT_POINT + tmap_gi_val) \
|
||
|
) / ((float)align_para) + (float)(cur_ifs) / 1.28;
|
||
|
|
||
|
if (fl_total > 4095) {
|
||
|
/* error, it should not happen! */
|
||
|
IOT_ASSERT("Based on spec, GP fl_total cannot be over 4095!");
|
||
|
}
|
||
|
|
||
|
if (fl_total - (int)fl_total > 0) {
|
||
|
fl_total_new = (int)fl_total + 1;
|
||
|
} else {
|
||
|
fl_total_new = (int)fl_total;
|
||
|
}
|
||
|
|
||
|
return fl_total_new;
|
||
|
}
|
||
|
|
||
|
extern tonemap_table_entry gp_tonemap_table[];
|
||
|
|
||
|
int hpav_cal_fl_robo(uint8_t tmi, uint8_t mpdu_cnt, uint8_t pb_num)
|
||
|
{
|
||
|
int cur_ifs;
|
||
|
uint16_t pb_size;
|
||
|
uint8_t copy_num;
|
||
|
uint8_t modulation;
|
||
|
uint8_t turbo_rate;
|
||
|
int pb_gi0;
|
||
|
int pb_gi1;
|
||
|
int pb_gi0_range;
|
||
|
int align_para;
|
||
|
int bpc;
|
||
|
int inter_num;
|
||
|
int car_robo_cnt;
|
||
|
int car_in_seg;
|
||
|
int inter_bits_num;
|
||
|
int bits_per_symb;
|
||
|
int bits_in_seg;
|
||
|
int bits_in_last_sym;
|
||
|
int pad_bit_num;
|
||
|
int bits_in_last_seg;
|
||
|
int last_bits_seg;
|
||
|
int bits_per_pb;
|
||
|
int turbo_rate_x16;
|
||
|
int symb_per_pb;
|
||
|
int symb_num_total;
|
||
|
float fl_total;
|
||
|
int fl_total_new;
|
||
|
int tx_vld_tone_num = phy_vld_tone_num_get(0, phy_band_id_get());
|
||
|
|
||
|
if (tmi > 2) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
cur_ifs = (mpdu_cnt == 0) ? HPAV_RIFS : HPAV_BIFS ;
|
||
|
pb_size = gp_tonemap_table[tmi].pb_size;
|
||
|
copy_num = gp_tonemap_table[tmi].robo_cnt;
|
||
|
modulation = gp_tonemap_table[tmi].modulation;
|
||
|
turbo_rate = gp_tonemap_table[tmi].coding_rate_idx;
|
||
|
|
||
|
if (turbo_rate > 2) {
|
||
|
turbo_rate = 2;
|
||
|
}
|
||
|
turbo_rate_x16 = sv_turbo_rate_x16[turbo_rate];
|
||
|
|
||
|
pb_gi0 = PB_GI0;
|
||
|
pb_gi0_range = 2;
|
||
|
pb_gi1 = ((tmi == 1) || (tmi == 0)) ? GI_STD_ROBO : GI_MINI_ROBO;
|
||
|
align_para = ALIGN_PARA;
|
||
|
|
||
|
bpc = modulation;
|
||
|
inter_num = copy_num;
|
||
|
car_robo_cnt = (tx_vld_tone_num / inter_num) * inter_num;
|
||
|
car_in_seg = car_robo_cnt / copy_num;
|
||
|
|
||
|
inter_bits_num = (pb_size * 8 * turbo_rate_x16) / 16;
|
||
|
bits_per_symb = bpc * car_robo_cnt;
|
||
|
bits_in_seg = bpc * car_in_seg;
|
||
|
bits_in_last_sym = inter_bits_num % bits_per_symb;
|
||
|
|
||
|
if (bits_in_last_sym == 0) {
|
||
|
bits_in_last_sym = bits_per_symb;
|
||
|
bits_in_last_seg = bits_in_seg;
|
||
|
} else {
|
||
|
int tmp;
|
||
|
|
||
|
tmp = (bits_in_last_sym - 1) / bits_in_seg;
|
||
|
bits_in_last_seg = bits_in_last_sym - bits_in_seg * tmp;
|
||
|
}
|
||
|
|
||
|
pad_bit_num = bits_in_seg - bits_in_last_seg;
|
||
|
last_bits_seg = (bits_in_last_sym / bits_in_seg);
|
||
|
|
||
|
if (bits_in_last_sym % bits_in_seg == 0) {
|
||
|
if (last_bits_seg) {
|
||
|
last_bits_seg--;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bits_per_pb = \
|
||
|
((pb_size * 8 * turbo_rate_x16) / 16 + pad_bit_num) * copy_num;
|
||
|
symb_per_pb = (bits_per_pb + bits_per_symb -1)/bits_per_symb;
|
||
|
symb_num_total = symb_per_pb * pb_num;
|
||
|
|
||
|
fl_total = (float)( (FFT_POINT + pb_gi0) * pb_gi0_range +
|
||
|
(symb_num_total - pb_gi0_range) * (FFT_POINT + pb_gi1)
|
||
|
) / ((float)align_para) + (float)(cur_ifs) / 1.28;
|
||
|
|
||
|
if (fl_total > 4095) {
|
||
|
/* error, it should not happen! */
|
||
|
IOT_ASSERT("Based on spec, GP fl_total cannot be over 4095!");
|
||
|
}
|
||
|
|
||
|
if (fl_total - (int)fl_total > 0) {
|
||
|
fl_total_new = (int)fl_total + 1;
|
||
|
} else {
|
||
|
fl_total_new = (int)fl_total;
|
||
|
}
|
||
|
|
||
|
#if PHY_DBG_EN
|
||
|
hpav_printf(ePRINT_LEVEL_INFO, \
|
||
|
"hpav_cal_fl_robo::tmi = %d\n", tmi);
|
||
|
hpav_printf(ePRINT_LEVEL_INFO, \
|
||
|
"hpav_cal_fl_robo::tx_vld_tone_num = %d\n", tx_vld_tone_num);
|
||
|
hpav_printf(ePRINT_LEVEL_INFO, \
|
||
|
"hpav_cal_fl_robo::fl_total_new = %d\n", fl_total_new);
|
||
|
#endif
|
||
|
|
||
|
return fl_total_new;
|
||
|
}
|
||
|
|
||
|
uint32_t phy_symb_bits_get(uint32_t *tmap_addr)
|
||
|
{
|
||
|
/* get symbol number bits */
|
||
|
uint16_t band_start_tone = 0;
|
||
|
uint16_t band_end_tone = 0;
|
||
|
uint16_t valid_tone_num = 0;
|
||
|
uint8_t fc_sym = 0;
|
||
|
const plc_tonemask_table *tone_msk_ptr = NULL;
|
||
|
uint32_t symb_bits = 0;
|
||
|
|
||
|
/* get tone */
|
||
|
phy_band_info_get_by_id( \
|
||
|
PHY_PROTO_TYPE_GET(), \
|
||
|
IOT_PLC_PHY_BAND_RANGE_DFT, \
|
||
|
phy_band_id_get(), \
|
||
|
&valid_tone_num, \
|
||
|
&fc_sym, \
|
||
|
&band_start_tone, \
|
||
|
&band_end_tone);
|
||
|
|
||
|
/* mask id */
|
||
|
tone_msk_ptr = phy_tone_mask_ptr_get(phy_mask_id_get());
|
||
|
|
||
|
/* get symb bits */
|
||
|
symb_bits = phy_cal_tmap_symb_bits( \
|
||
|
band_start_tone, \
|
||
|
band_end_tone, \
|
||
|
tmap_addr, \
|
||
|
tone_msk_ptr);
|
||
|
//iot_printf("symb_bits :%d\n", symb_bits);
|
||
|
|
||
|
return symb_bits;
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|