642 lines
19 KiB
C
Executable File
642 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 "plc_fr.h"
|
|
#include "hw_tonemask.h"
|
|
#include "plc_utils.h"
|
|
#include "phy_bb.h"
|
|
#include "phy_ana.h"
|
|
#include "hw_phy_api.h"
|
|
#include "iot_io.h"
|
|
#include "hw_desc.h"
|
|
#include "hw_reg_api.h"
|
|
#include "plc_protocol.h"
|
|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
|
|
#include "granite_reg.h"
|
|
#endif
|
|
#include "iot_errno_api.h"
|
|
#include "phy_txrx_pwr.h"
|
|
#include "phy_cfg.h"
|
|
#include "phy_dfe_reg.h"
|
|
#include "phy_rxtd_reg.h"
|
|
#include "iot_config.h"
|
|
#include "phy_chn.h"
|
|
#include "iot_system.h"
|
|
#include "iot_io_api.h"
|
|
|
|
void phy_tone_amp_reduce_set(uint32_t start_tone, uint32_t end_tone,
|
|
uint8_t reduce_db)
|
|
{
|
|
uint32_t tmp = 0;
|
|
uint32_t mask_begin_col_idx = 0;
|
|
uint32_t mask_begin_group_idx = 0;
|
|
uint32_t ampdata, tone_id;
|
|
uint32_t *p_tone_addr = (uint32_t *)BB_TONE_MASK_PHASE_BASEADDR;
|
|
|
|
IOT_ASSERT(start_tone <= end_tone);
|
|
|
|
if (reduce_db <= 28) {
|
|
ampdata = reduce_db >> 1;
|
|
} else {
|
|
ampdata = 0x0F;
|
|
}
|
|
ampdata <<= 4;
|
|
|
|
enable_sw_access_tmi_buf(true);
|
|
|
|
for (tone_id = start_tone; tone_id <= end_tone; tone_id++) {
|
|
mask_begin_col_idx = tone_id & 0x3;
|
|
mask_begin_group_idx = tone_id >> 2;
|
|
|
|
tmp = *(p_tone_addr + mask_begin_group_idx);
|
|
tmp &= ~(0xF0 << (8 * mask_begin_col_idx));
|
|
tmp |= ampdata << (8 * mask_begin_col_idx);
|
|
*(p_tone_addr + mask_begin_group_idx) = tmp;
|
|
}
|
|
|
|
enable_sw_access_tmi_buf(false);
|
|
}
|
|
|
|
void phy_tone_amp_set(uint32_t start_tone, uint32_t end_tone, uint8_t amp_value)
|
|
{
|
|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
|
|
uint32_t tmp = 0;
|
|
uint32_t index = 0;
|
|
uint32_t mask_begin_col_idx = 0;
|
|
uint32_t mask_begin_group_idx = 0;
|
|
uint32_t mask_end_col_idx = 0;
|
|
uint32_t mask_end_group_idx = 0;
|
|
uint32_t *p_tone_addr = \
|
|
(uint32_t *)BB_TONE_MASK_PHASE_BASEADDR;
|
|
|
|
IOT_ASSERT(start_tone <= end_tone);
|
|
|
|
enable_sw_access_tmi_buf(true);
|
|
|
|
/* get start tone */
|
|
mask_begin_col_idx = (start_tone) & 0x3;
|
|
mask_begin_group_idx = (start_tone) >> 2;
|
|
|
|
/* get end tone */
|
|
mask_end_col_idx = (end_tone) & 0x3;
|
|
mask_end_group_idx = (end_tone) >> 2;
|
|
|
|
if (mask_begin_group_idx == mask_end_group_idx) {
|
|
tmp = *(p_tone_addr + mask_begin_group_idx);
|
|
tmp |= ((0xF0F0F0F0 & (amp_value<<24 | amp_value<<16 | \
|
|
amp_value<<8 | amp_value)) & \
|
|
(0xFFFFFFFF << 8*mask_begin_col_idx) & \
|
|
(0xFFFFFFFF >> 8*(3-mask_end_col_idx)));
|
|
*(p_tone_addr + mask_begin_group_idx) = tmp;
|
|
}else {
|
|
/* start group */
|
|
tmp = *(p_tone_addr + mask_begin_group_idx);
|
|
tmp |= ((0xF0F0F0F0 & (amp_value<<24 | amp_value<<16 | \
|
|
amp_value<<8 | amp_value)) & \
|
|
(0xFFFFFFFF << 8*mask_begin_col_idx));
|
|
*(p_tone_addr + mask_begin_group_idx) = tmp;
|
|
|
|
/* end group */
|
|
tmp = *(p_tone_addr + mask_end_group_idx);
|
|
tmp |= ((0xF0F0F0F0 & (amp_value<<24 | amp_value<<16 | \
|
|
amp_value<<8 | amp_value)) & \
|
|
(0xFFFFFFFF >> 8*(3-mask_end_col_idx)));
|
|
*(p_tone_addr + mask_end_group_idx) = tmp;
|
|
|
|
/* cover */
|
|
index = mask_begin_group_idx + 1;
|
|
for(; index < mask_end_group_idx; index++)
|
|
{
|
|
tmp = *(p_tone_addr + index);
|
|
tmp |= (0xF0F0F0F0 & (amp_value<<24 | amp_value<<16 | \
|
|
amp_value<<8 | amp_value));
|
|
*(p_tone_addr + index) = tmp;
|
|
}
|
|
}
|
|
|
|
enable_sw_access_tmi_buf(false);
|
|
#else
|
|
(void)start_tone;
|
|
(void)end_tone;
|
|
(void)amp_value;
|
|
#endif
|
|
}
|
|
|
|
void phy_tone_amp_clr(uint32_t start_tone, uint32_t end_tone)
|
|
{
|
|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
|
|
uint32_t tmp = 0;
|
|
uint32_t index = 0;
|
|
uint32_t mask_begin_col_idx = 0;
|
|
uint32_t mask_begin_group_idx = 0;
|
|
uint32_t mask_end_col_idx = 0;
|
|
uint32_t mask_end_group_idx = 0;
|
|
uint32_t *p_tone_addr = \
|
|
(uint32_t *)BB_TONE_MASK_PHASE_BASEADDR;
|
|
|
|
IOT_ASSERT(start_tone <= end_tone);
|
|
|
|
enable_sw_access_tmi_buf(true);
|
|
|
|
/* get start tone */
|
|
mask_begin_col_idx = (start_tone) & 0x3;
|
|
mask_begin_group_idx = (start_tone) >> 2;
|
|
|
|
/* get end tone */
|
|
mask_end_col_idx = (end_tone) & 0x3;
|
|
mask_end_group_idx = (end_tone) >> 2;
|
|
|
|
if (mask_begin_group_idx == mask_end_group_idx) {
|
|
tmp = *(p_tone_addr + mask_begin_group_idx);
|
|
tmp &= (0x0F0F0F0F &\
|
|
(0xFFFFFFFF << 8*mask_begin_col_idx) & \
|
|
(0xFFFFFFFF >> 8*(3-mask_end_col_idx)));
|
|
*(p_tone_addr + mask_begin_group_idx) = tmp;
|
|
} else {
|
|
/* start group */
|
|
tmp = *(p_tone_addr + mask_begin_group_idx);
|
|
tmp &= (0x0F0F0F0F &\
|
|
(0xFFFFFFFF << 8*mask_begin_col_idx));
|
|
*(p_tone_addr + mask_begin_group_idx) = tmp;
|
|
|
|
/* end group */
|
|
tmp = *(p_tone_addr + mask_end_group_idx);
|
|
tmp &= (0x0F0F0F0F0 &\
|
|
(0xFFFFFFFF >> 8*(3-mask_end_col_idx)));
|
|
*(p_tone_addr + mask_end_group_idx) = tmp;
|
|
|
|
/* cover */
|
|
index = mask_begin_group_idx + 1;
|
|
for(; index < mask_end_group_idx; index++)
|
|
{
|
|
tmp = *(p_tone_addr + index);
|
|
tmp &= 0xF0F0F0F0;
|
|
*(p_tone_addr + index) = tmp;
|
|
}
|
|
}
|
|
|
|
enable_sw_access_tmi_buf(false);
|
|
#else
|
|
(void)start_tone;
|
|
(void)end_tone;
|
|
#endif
|
|
}
|
|
|
|
static uint32_t phy_rms_get_in_band_tbl(const plc_phy_band_table_t *band_tbl,
|
|
uint8_t tbl_len, uint16_t valid_tone_num, uint8_t *fd_rms)
|
|
{
|
|
uint32_t ret = ERR_FAIL;
|
|
uint8_t band_idx = 0;
|
|
|
|
#if IOT_DTEST_ONLY_SUPPORT == 0
|
|
if (g_phy_ctxt.indep.tx_pwr_psd_fix_db > 0) {
|
|
if (g_phy_cpu_share_ctxt.tx_pwr_ctl_ena) {
|
|
*fd_rms = (uint8_t)(g_phy_ctxt.indep.tx_pwr_psd_fix_db -
|
|
PHY_PWR_DIG_ATT_MAX);
|
|
} else {
|
|
*fd_rms = (uint8_t)(g_phy_ctxt.indep.tx_pwr_psd_fix_db);
|
|
}
|
|
return ERR_OK;
|
|
}
|
|
#endif
|
|
|
|
if (band_tbl == NULL) {
|
|
IOT_ASSERT(0);
|
|
return ret;
|
|
}
|
|
for (band_idx = 0; band_idx < tbl_len; band_idx++) {
|
|
if (band_tbl[band_idx].band_info.valid_tone_number == valid_tone_num) {
|
|
*fd_rms = (uint8_t)(band_tbl[band_idx].band_info.fd_rms_max);
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
}
|
|
|
|
#if IOT_DTEST_ONLY_SUPPORT == 0
|
|
if (!g_phy_cpu_share_ctxt.tx_pwr_ctl_ena) {
|
|
if (ret == ERR_OK) {
|
|
*fd_rms -= (uint8_t)g_phy_ctxt.indep.tx_pwr_reduce_db;
|
|
}
|
|
*fd_rms += PHY_PWR_DIG_ATT_MAX;
|
|
}
|
|
#else
|
|
if (ret == ERR_OK) {
|
|
*fd_rms -= (uint8_t)g_phy_ctxt.indep.tx_pwr_reduce_db;
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
uint32_t phy_rms_get_by_valid_tone(uint16_t valid_tone_num, uint8_t *fd_rms)
|
|
{
|
|
uint32_t ret = ERR_FAIL;
|
|
uint32_t mac_proto = PHY_PROTO_TYPE_GET();
|
|
const plc_phy_band_table_t *band_tbl = NULL;
|
|
uint8_t tbl_len = 0;
|
|
tbl_len = (uint8_t)phy_support_band_table_get(mac_proto, (void **)&band_tbl);
|
|
ret = phy_rms_get_in_band_tbl(band_tbl, tbl_len, valid_tone_num, fd_rms);
|
|
return ret;
|
|
}
|
|
|
|
/* get fd rms info depend on proto and band id */
|
|
uint32_t phy_gp_band_rms_get_by_valid_tone(uint16_t valid_tone_num,
|
|
uint8_t *fd_rms)
|
|
{
|
|
uint32_t ret = ERR_FAIL;
|
|
|
|
// TODO: maybe some customer need to use gp's config
|
|
#if 1 // SUPPORT_GREEN_PHY
|
|
const plc_phy_band_table_t *band_tbl = NULL;
|
|
uint8_t tbl_len = 0;
|
|
tbl_len = phy_get_plc_gp_band_tab_info(&band_tbl);
|
|
ret = phy_rms_get_in_band_tbl(band_tbl, tbl_len, valid_tone_num, fd_rms);
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* TARGET_TD_RMS valid_tone_num FD_RMS
|
|
* 128 131 58.86
|
|
* 128 260 55.88
|
|
* 128 411 53.89
|
|
* 128 664 51.81
|
|
*/
|
|
uint32_t phy_fd_rms_get(uint32_t valid_tone_num, uint8_t *para_int, uint8_t *para_frac)
|
|
{
|
|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
|
|
uint32_t ret = ERR_FAIL;
|
|
uint32_t mask_id = phy_mask_id_get();
|
|
|
|
/* check tonemask or not */
|
|
if (mask_id == TONE_MASK_ID_NULL) {
|
|
ret = phy_rms_get_by_valid_tone(valid_tone_num, para_int);
|
|
} else {
|
|
ret = phy_tone_msk_rms_get_by_valid_tone(valid_tone_num, para_int);
|
|
}
|
|
|
|
if (ret != ERR_OK) {
|
|
/* make sure work firstly */
|
|
*para_int = PHY_DEF_RMS;
|
|
}
|
|
|
|
/* frac */
|
|
*para_frac = 3;
|
|
return ret;
|
|
#else
|
|
(void)valid_tone_num;
|
|
(void)para_int;
|
|
(void)para_frac;
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
void phy_fd_rms_band_set(uint32_t rate_id, uint32_t hw_band_id, uint8_t rms_cal)
|
|
{
|
|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
|
|
uint32_t valid_tone_num = 0;
|
|
uint8_t para_int = 0, para_frac = 0;
|
|
|
|
valid_tone_num = phy_vld_tone_num_get(rate_id, hw_band_id);
|
|
phy_fd_rms_get(valid_tone_num, ¶_int, ¶_frac);
|
|
para_int = para_int + rms_cal;
|
|
phy_tx_rms_set(rate_id, hw_band_id, para_int, para_frac);
|
|
#else
|
|
(void)rate_id;
|
|
(void)hw_band_id;
|
|
(void)rms_cal;
|
|
#endif
|
|
}
|
|
|
|
void phy_fd_rms_batch_set(uint8_t rms_cal)
|
|
{
|
|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
|
|
/* rate0/1 band0/1/2 */
|
|
phy_fd_rms_band_set(0, HW_FULL_BAND, rms_cal);
|
|
phy_fd_rms_band_set(0, HW_LOW_BAND, rms_cal);
|
|
phy_fd_rms_band_set(0, HW_HIGH_BAND, rms_cal);
|
|
|
|
phy_fd_rms_band_set(1, HW_FULL_BAND, rms_cal);
|
|
phy_fd_rms_band_set(1, HW_LOW_BAND, rms_cal);
|
|
phy_fd_rms_band_set(1, HW_HIGH_BAND, rms_cal);
|
|
#else
|
|
(void)rms_cal;
|
|
#endif
|
|
}
|
|
|
|
void phy_fd_short_band_rms_get(uint32_t valid_tone_num, \
|
|
uint8_t *para_int, \
|
|
uint8_t *para_frac)
|
|
{
|
|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
|
|
uint32_t ret = ERR_FAIL;
|
|
|
|
ret = phy_gp_band_rms_get_by_valid_tone(valid_tone_num, para_int);
|
|
if (ret == ERR_OK) {
|
|
/* fractional part */
|
|
*para_frac = 3;
|
|
} else {
|
|
iot_printf("phy short band rms get failed by valid tone num %d\n", \
|
|
valid_tone_num);
|
|
IOT_ASSERT(0);
|
|
}
|
|
#else
|
|
(void)valid_tone_num;
|
|
(void)para_int;
|
|
(void)para_frac;
|
|
#endif
|
|
}
|
|
|
|
void phy_fd_rms_update(void)
|
|
{
|
|
uint32_t valid_tone_num = 0;
|
|
uint8_t para_int = 0, para_frac = 0;
|
|
|
|
/* rate0 band0/1/2 */
|
|
valid_tone_num = phy_vld_tone_num_get(0, HW_FULL_BAND);
|
|
phy_fd_rms_get(valid_tone_num, ¶_int, ¶_frac);
|
|
phy_tx_rms_set(0, HW_FULL_BAND, para_int, para_frac);
|
|
|
|
valid_tone_num = phy_vld_tone_num_get(0, HW_LOW_BAND);
|
|
phy_fd_rms_get(valid_tone_num, ¶_int, ¶_frac);
|
|
phy_tx_rms_set(0, HW_LOW_BAND, para_int, para_frac);
|
|
|
|
valid_tone_num = phy_vld_tone_num_get(0, HW_HIGH_BAND);
|
|
phy_fd_rms_get(valid_tone_num, ¶_int, ¶_frac);
|
|
phy_tx_rms_set(0, HW_HIGH_BAND, para_int, para_frac);
|
|
|
|
/* rate1 band0/1/2 */
|
|
valid_tone_num = phy_vld_tone_num_get(1, HW_FULL_BAND);
|
|
phy_fd_rms_get(valid_tone_num, ¶_int, ¶_frac);
|
|
phy_tx_rms_set(1, HW_FULL_BAND, para_int, para_frac);
|
|
|
|
valid_tone_num = phy_vld_tone_num_get(1, HW_LOW_BAND);
|
|
phy_fd_rms_get(valid_tone_num, ¶_int, ¶_frac);
|
|
phy_tx_rms_set(1, HW_LOW_BAND, para_int, para_frac);
|
|
|
|
valid_tone_num = phy_vld_tone_num_get(1, HW_HIGH_BAND);
|
|
phy_fd_rms_get(valid_tone_num, ¶_int, ¶_frac);
|
|
phy_tx_rms_set(1, HW_HIGH_BAND, para_int, para_frac);
|
|
}
|
|
|
|
void phy_time_rms_set(void)
|
|
{
|
|
uint32_t valid_tone_num = 0;
|
|
uint8_t para_int = 0, para_frac = 0;
|
|
uint16_t b0_full = 0, b0_low = 0, b0_high = 0;
|
|
uint16_t b1_full = 0, b1_low = 0, b1_high = 0;
|
|
|
|
/* update rms value */
|
|
phy_fd_rms_update();
|
|
|
|
/* short band init */
|
|
if (PHY_PROTO_TYPE_GET() == PLC_PROTO_TYPE_SG){
|
|
/* short band rms for mix mode */
|
|
valid_tone_num = phy_short_vld_tone_num_get();
|
|
phy_fd_short_band_rms_get(valid_tone_num, ¶_int, ¶_frac);
|
|
phy_tx_rms_set(2, 0, para_int, para_frac);
|
|
}
|
|
|
|
/* fd -12dB, td att +12dB */
|
|
#if PHY_LOAD_CFG_FROM_PIB_EN == 1 && \
|
|
IOT_DTEST_ONLY_SUPPORT == 0
|
|
if (g_phy_cpu_share_ctxt.tx_pwr_ctl_ena) {
|
|
if (!g_phy_ctxt.indep.tx_pwr_psd_fix_db) {
|
|
/* load global tx pwr reduce */
|
|
if (g_phy_ctxt.indep.tx_pwr_reduce_db <= PHY_PWR_DIG_ATT_MAX) {
|
|
phy_tx_gain_factor_set( \
|
|
(uint8_t)(PHY_PWR_DIG_ATT_MAX - \
|
|
g_phy_ctxt.indep.tx_pwr_reduce_db));
|
|
} else if (g_phy_ctxt.indep.tx_pwr_reduce_db <= \
|
|
(PHY_PWR_DIG_ATT_MAX << 1)) {
|
|
phy_tx_gain_factor_set( \
|
|
(uint8_t)(( \
|
|
SW_TX_PWR_SCALE_FACTOR_MASK >> SW_TX_PWR_SCALE_FACTOR_OFFSET) \
|
|
+ 1 - (g_phy_ctxt.indep.tx_pwr_reduce_db - PHY_PWR_DIG_ATT_MAX)));
|
|
} else {
|
|
IOT_ASSERT(0);
|
|
}
|
|
} else {
|
|
/* for dynamic adjust pwr */
|
|
phy_tx_gain_factor_set(PHY_PWR_DIG_ATT_MAX);
|
|
}
|
|
} else {
|
|
/* more snr by reduce analog */
|
|
if (!g_phy_ctxt.indep.tx_pwr_psd_fix_db) {
|
|
/* att config */
|
|
phy_tx_gain_factor_set(0);
|
|
|
|
if (g_phy_ctxt.indep.tx_pwr_reduce_db <= 5) {
|
|
/* tx pga config */
|
|
g_phy_ctxt.indep.tx_pga = 3;
|
|
} else if (g_phy_ctxt.indep.tx_pwr_reduce_db <= 23) {
|
|
/* reduce number */
|
|
uint8_t reduce_int = (uint8_t)( \
|
|
(g_phy_ctxt.indep.tx_pwr_reduce_db - 6) / 6);
|
|
uint8_t reduce_frac = (uint8_t)( \
|
|
(g_phy_ctxt.indep.tx_pwr_reduce_db - 6) % 6);
|
|
|
|
/* tx pga config */
|
|
g_phy_ctxt.indep.tx_pga = 3 - reduce_int;
|
|
|
|
uint8_t rms_cal_val = (uint8_t)( \
|
|
g_phy_ctxt.indep.tx_pwr_reduce_db - 6 - reduce_frac);
|
|
phy_fd_rms_batch_set(rms_cal_val);
|
|
} else if (g_phy_ctxt.indep.tx_pwr_reduce_db <= 41) {
|
|
phy_fd_rms_batch_set(18);
|
|
|
|
/* tx pga config */
|
|
g_phy_ctxt.indep.tx_pga = 0;
|
|
} else {
|
|
/* pwr too small */
|
|
IOT_ASSERT(0);
|
|
}
|
|
}
|
|
}
|
|
#else
|
|
#if IOT_PLC_PHY_TX_PWR_REDUCE <= PHY_PWR_DIG_ATT_MAX
|
|
phy_tx_gain_factor_set( \
|
|
PHY_PWR_DIG_ATT_MAX - IOT_PLC_PHY_TX_PWR_REDUCE);
|
|
#elif IOT_PLC_PHY_TX_PWR_REDUCE <= (PHY_PWR_DIG_ATT_MAX << 1)
|
|
phy_tx_gain_factor_set( \
|
|
(SW_TX_PWR_SCALE_FACTOR_MASK >> SW_TX_PWR_SCALE_FACTOR_OFFSET) \
|
|
+ 1 - (IOT_PLC_PHY_TX_PWR_REDUCE - PHY_PWR_DIG_ATT_MAX));
|
|
#else
|
|
IOT_ASSERT(0);
|
|
#endif
|
|
#endif
|
|
|
|
/* print all the rms setting */
|
|
phy_tx_rms_get(0, HW_FULL_BAND, &b0_full, ¶_frac);
|
|
phy_tx_rms_get(0, HW_LOW_BAND, &b0_low, ¶_frac);
|
|
phy_tx_rms_get(0, HW_HIGH_BAND, &b0_high, ¶_frac);
|
|
phy_tx_rms_get(1, HW_FULL_BAND, &b1_full, ¶_frac);
|
|
phy_tx_rms_get(1, HW_LOW_BAND, &b1_low, ¶_frac);
|
|
phy_tx_rms_get(1, HW_HIGH_BAND, &b1_high, ¶_frac);
|
|
|
|
iot_printf( \
|
|
"b0_full_rms = %d, b0_low_rms = %d, b0_high_rms = %d\n" \
|
|
"b1_full_rms = %d, b1_low_rms = %d, b1_high_rms = %d " \
|
|
"td_att = %d, reduce: %d\n", \
|
|
b0_full, b0_low, b0_high, b1_full, b1_low, b1_high, \
|
|
phy_tx_gain_factor_get(), IOT_PLC_PHY_TX_PWR_REDUCE);
|
|
}
|
|
|
|
uint32_t phy_get_def_tx_power( \
|
|
uint32_t hw_rate_id, \
|
|
uint32_t hw_band_id, \
|
|
uint8_t *para_int, \
|
|
uint8_t *para_frac)
|
|
{
|
|
uint32_t ret = ERR_OK;
|
|
uint32_t vld_tone_num = 0;
|
|
|
|
/* get valid tone number from current protocol, rate id and band id */
|
|
vld_tone_num = phy_vld_tone_num_get(hw_rate_id, hw_band_id);
|
|
/* get tx power from global array */
|
|
phy_fd_rms_get(vld_tone_num, para_int, para_frac);
|
|
|
|
return ret;
|
|
}
|
|
|
|
uint32_t phy_get_proto_band_fc_num_from_band_table(uint32_t proto_band_id)
|
|
{
|
|
uint32_t proto = PHY_PROTO_TYPE_GET();
|
|
uint32_t proto_band_idx;
|
|
const plc_phy_band_table_t *band_tab;
|
|
#if SUPPORT_SMART_GRID || SUPPORT_SOUTHERN_POWER_GRID
|
|
if (proto == PLC_PROTO_TYPE_SG || proto == PLC_PROTO_TYPE_SPG) {
|
|
uint32_t support_band_max = phy_get_plc_nsg_band_tab_info(&band_tab);
|
|
for(proto_band_idx = 0; proto_band_idx < support_band_max;
|
|
proto_band_idx++) {
|
|
if (band_tab[proto_band_idx].band_id == proto_band_id) {
|
|
return band_tab[proto_band_idx].band_info.fc_sym_num;
|
|
}
|
|
}
|
|
iot_printf("phy not support this proto band:%d\n", proto_band_id);
|
|
IOT_ASSERT(0);
|
|
}
|
|
#endif
|
|
#if SUPPORT_GREEN_PHY
|
|
if (proto == PLC_PROTO_TYPE_GP) {
|
|
/* TODO: need add */
|
|
}
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
uint32_t phy_get_pwr_psd_fix_db()
|
|
{
|
|
return g_phy_ctxt.indep.tx_pwr_psd_fix_db;
|
|
}
|
|
|
|
uint32_t phy_get_pwr_ctl_en()
|
|
{
|
|
return !!g_phy_cpu_share_ctxt.tx_pwr_ctl_ena;
|
|
}
|
|
|
|
uint32_t phy_get_pwr_reduce_db()
|
|
{
|
|
return g_phy_ctxt.indep.tx_pwr_reduce_db;
|
|
}
|
|
|
|
uint32_t phy_set_tx_pwr_limit(uint32_t pwr_db)
|
|
{
|
|
g_phy_ctxt.dep.is_valid_power = 1;
|
|
g_phy_ctxt.dep.power_limit_db = pwr_db;
|
|
|
|
/* set mpdu pwr reg */
|
|
phy_set_common_pwr_reg(pwr_db);
|
|
|
|
/* set sack pwr reg */
|
|
phy_set_sack_tx_power(pwr_db);
|
|
return 0;
|
|
}
|
|
|
|
static uint32_t phy_get_init_tx_pwr(uint32_t single_proto_band)
|
|
{
|
|
uint8_t tx_power = 0;
|
|
uint8_t dlt_max = 0;
|
|
int8_t reduce = 0;
|
|
|
|
if (phy_get_default_tx_pwr(single_proto_band, &tx_power, &dlt_max)) {
|
|
iot_printf("%s band %d get power fail!\n", __FUNCTION__,
|
|
single_proto_band);
|
|
IOT_ASSERT(0);
|
|
}
|
|
|
|
/* NOTE: if psd != 0, recuce is invaild on lp */
|
|
if (phy_get_pwr_ctl_en() || !phy_get_pwr_psd_fix_db()) {
|
|
if (phy_get_pwr_reduce_db() & 0x80) {
|
|
reduce = phy_get_pwr_reduce_db() & 0x7f;
|
|
|
|
if (reduce > dlt_max) {
|
|
reduce = dlt_max;
|
|
}
|
|
tx_power = tx_power + reduce;
|
|
} else {
|
|
reduce = (uint8_t)phy_get_pwr_reduce_db();
|
|
|
|
if (tx_power < (uint8_t)reduce) {
|
|
tx_power = reduce;
|
|
}
|
|
tx_power = tx_power - reduce;
|
|
}
|
|
}
|
|
|
|
return (uint32_t)tx_power;
|
|
}
|
|
|
|
uint32_t phy_get_tx_pwr_limit(uint32_t single_proto_band)
|
|
{
|
|
uint32_t tx_power;
|
|
|
|
/* uplayer set tx power */
|
|
if (g_phy_ctxt.dep.is_valid_power == 1) {
|
|
tx_power = g_phy_ctxt.dep.power_limit_db;
|
|
} else {
|
|
tx_power = phy_get_init_tx_pwr(single_proto_band);
|
|
}
|
|
return tx_power;
|
|
}
|
|
|
|
uint32_t phy_pwr_adjust_set(uint8_t uint_dbuv)
|
|
{
|
|
uint32_t ret = ERR_OK;
|
|
#if (HW_PLATFORM > HW_PLATFORM_SIMU)
|
|
uint32_t power = uint_dbuv;
|
|
|
|
if (power == 0) {
|
|
power = phy_get_init_tx_pwr(phy_proto_single_band_id_get());
|
|
}
|
|
/* set power by sw */
|
|
g_phy_ctxt.dep.sw_set_pwr = power;
|
|
|
|
phy_overstress_ctxt_t *ovs_ctxt = &g_phy_ctxt.indep.ovs_ctxt;
|
|
if (ovs_ctxt->ovr_stress) {
|
|
/* set power */
|
|
phy_set_tx_pwr_limit(min(power, ovs_ctxt->ovr_pwr));
|
|
} else {
|
|
/* set power */
|
|
phy_set_tx_pwr_limit(power);
|
|
}
|
|
#else
|
|
(void)uint_dbuv;
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|