Files
kunlun/plc/halphy/hw2/phy_tmap.c
2024-09-28 14:24:04 +08:00

660 lines
20 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 "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