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

1007 lines
33 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 "plc_fr.h"
#include "hw_tonemask.h"
#include "plc_utils.h"
#include "phy_bb.h"
#include "phy_chn.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_tone_tbl.h"
plc_band_table_t *g_plc_band_tbl_r0[MAX_HW_BAND] = { 0 };
plc_band_table_t *g_plc_band_tbl_r1[MAX_HW_BAND] = { 0 };
/* full band */
plc_band_table_t all_mask_band_table_r0_full = {
411, // valid_tone_number, 1536 max
4, // fc sym number
0, // rate type
58, // max rms
80, // start tone
0, // resv1
490, // end tone
0, // resv2
};
/* low band */
plc_band_table_t all_mask_band_table_r0_low = {
131, // valid_tone_number, 1536 max
12, // fc sym number
0, // rate type
63, // max rms
100, // start tone
0, // resv1
230, // end tone
0, // resv2
};
/* high band */
plc_band_table_t all_mask_band_table_r0_high = {
260, // valid_tone_number, 1536 max
12, // fc sym number
0, // rate type
60, // max rms
231, // start tone
0, // resv1
490, // end tone
0, // resv2
};
/* full band */
plc_band_table_t all_mask_band_table_r1_full = {
411, // valid_tone_number, 1536 max
4, // fc sym number
1, // rate type
58, // max rms
80, // start tone
0, // resv1
490, // end tone
0, // resv2
};
/* low band */
plc_band_table_t all_mask_band_table_r1_low = {
131, // valid_tone_number, 1536 max
12, // fc sym number
1, // rate type
63, // max rms
100, // start tone
0, // resv1
230, // end tone
0, // resv2
};
/* high band */
plc_band_table_t all_mask_band_table_r1_high = {
260, // valid_tone_number, 1536 max
12, // fc sym number
1, // rate type
60, // max rms
231, // start tone
0, // resv1
490, // end tone
0, // resv2
};
/*
* note:
* rms full pwr reduce 12dB by default, and add back by digital att.
*/
/* band support by NSG */
const plc_phy_band_table_t iot_plc_nsg_band_all[] = {
/* band_id valid fc rate rms start resv1 end resv2*/
#if SUPPORT_SOUTHERN_POWER_GRID
{IOT_SUPPORT_TONE_80_490, {411, 2, 0, 46, 80, 0, 490, 0}},
{IOT_SUPPORT_TONE_100_230, {131, 8, 0, 51, 100, 0, 230, 0}},
#else /* SUPPORT_SOUTHERN_POWER_GRID */
{IOT_SUPPORT_TONE_80_490, {411, 4, 0, 46, 80, 0, 490, 0}},
{IOT_SUPPORT_TONE_100_230, {131, 12, 0, 51, 100, 0, 230, 0}},
#endif /* SUPPORT_SOUTHERN_POWER_GRID */
{IOT_SUPPORT_TONE_32_120, {89, 12, 0, 56, 32, 0, 120, 0}},
{IOT_SUPPORT_TONE_72_120, {49, 12, 0, 56, 72, 0, 120, 0}},
{IOT_SUPPORT_TONE_231_490, {260, 12, 0, 48, 231, 0, 490, 0}},
#if SUPPORT_SMART_GRID
{IOT_SUPPORT_TONE_240_370, {131, 12, 0, 51, 240, 0, 370, 0}},
{IOT_SUPPORT_TONE_TIDE, {89, 12, 0, 56, 65, 0, 205, 0}},
{IOT_SUPPORT_TONE_100_230_CE, {49, 12, 0, 56, 100, 0, 230, 0}},
{IOT_SUPPORT_TONE_80_490_CE, {194, 4, 0, 46, 83, 0, 472, 0}},
{IOT_SUPPORT_TONE_231_490_CE, {132, 12, 0, 53, 255, 0, 472, 0}},
/* CUSTOM0:6~25M */
{IOT_SUPPORT_TONE_200_1000, {801, 4, 0, 43, 200, 0, 1000, 0}},
/* CUSTOM0:30~38M */
{IOT_SUPPORT_TONE_1160_1415,{256, 12, 0, 48, 1160, 0, 1415, 0}},
/* TODO: dvt 256 valid tone num for multiband */
{IOT_SUPPORT_TONE_200_500, {301, 12, 0, 48, 200, 0, 500, 0}},
#if IOT_HTBUS_EN
/* HT BUS band */
{IOT_SUPPORT_TONE_100_400, {301, 4, 0, 56, 100, 0, 400, 0}},
{IOT_SUPPORT_TONE_850_1150, {301, 4, 0, 56, 850, 0, 1150, 0}},
#endif /* IOT_HTBUS_EN */
#endif /* SUPPORT_SMART_GRID */
};
//TODO: maybe some customer need to use gp's config
#if 1 //SUPPORT_GREEN_PHY
/* band support by GP */
const plc_phy_band_table_t iot_plc_gp_band_all[] = {
/* band_id valid fc rate rms start resv1 end resv2*/
{IOT_SUPPORT_TONE_80_743, {664, 1, 0, 44, 80, 0, 743, 0}},
{IOT_SUPPORT_TONE_80_1228, {1149, 1, 0, 42, 80, 0, 1228, 0}},
{IOT_SUPPORT_TONE_80_600, {521, 1, 0, 40, 80, 0, 600, 0}},
};
#endif
/* tonemask rms table */
const plc_tonemask_rms_table iot_plc_tonemask_rms_all[TONEMASK_RMS_NUM] = {
/*band_id valid rms*/
{TONE_MASK_ID_SG0, 371, 47},
{TONE_MASK_ID_SG1, 126, 52},
{TONE_MASK_ID_SG2, 84, 53},
{TONE_MASK_ID_SG3, 45, 56},
{TONE_MASK_ID_GP, 917, 43},
{TONE_MASK_ID_TIDE, 89, 56},
{TONE_MASK_ID_CE, 49, 56},
{TONE_MASK_ID_CE, 132, 53},
{TONE_MASK_ID_CE, 194, 46},
};
uint8_t phy_get_plc_nsg_band_tab_info(const plc_phy_band_table_t **band_tab)
{
if (band_tab != NULL) {
*band_tab = iot_plc_nsg_band_all;
}
return (uint8_t)IOT_ARRAY_CNT(iot_plc_nsg_band_all);
}
uint8_t phy_get_plc_gp_band_tab_info(const plc_phy_band_table_t **band_tab)
{
if (band_tab != NULL) {
*band_tab = iot_plc_gp_band_all;
}
return (uint8_t)IOT_ARRAY_CNT(iot_plc_gp_band_all);
}
/* caluculate how many valid tones in the band from a tone mask table.
* based on the iot_bitops.h utils
*/
uint32_t get_valid_tone_number(const plc_tonemask_table *tmt, \
uint32_t start_tone, uint32_t end_tone) {
uint32_t total = 0;
uint8_t start = (uint8_t)(start_tone >> 5); // div 32, get start dword index
uint8_t end = (uint8_t)(end_tone >> 5); // div 32, get end dword index
uint8_t tmt_bit;
uint8_t i;
uint32_t start_dw, end_dw;
tmt_bit = 0x1f;
tmt_bit &= (uint8_t)start_tone; // mod start_tone, get start bit
start_dw = (tmt->tone_mask_bitmap[start]) & (0xffffffff << tmt_bit);
total += iot_bitops_cbs((uint8_t)(start_dw));
total += iot_bitops_cbs((uint8_t)(start_dw >> 8));
total += iot_bitops_cbs((uint8_t)(start_dw >> 16));
total += iot_bitops_cbs((uint8_t)(start_dw >> 24));
tmt_bit = 0x1f;
tmt_bit &= (uint8_t)end_tone; // mod start_tone, get end bit
tmt_bit = 31 - tmt_bit;
end_dw = (tmt->tone_mask_bitmap[end]) & (0xffffffff >> tmt_bit);
total += iot_bitops_cbs((uint8_t)(end_dw));
total += iot_bitops_cbs((uint8_t)(end_dw >> 8));
total += iot_bitops_cbs((uint8_t)(end_dw >> 16));
total += iot_bitops_cbs((uint8_t)(end_dw >> 24));
if (start == end) {
total -= iot_bitops_cbs((uint8_t)(tmt->tone_mask_bitmap[end]));
total -= iot_bitops_cbs((uint8_t)(tmt->tone_mask_bitmap[end] >> 8));
total -= iot_bitops_cbs((uint8_t)(tmt->tone_mask_bitmap[end] >> 16));
total -= iot_bitops_cbs((uint8_t)(tmt->tone_mask_bitmap[end] >> 24));
}
for (i = start + 1; i < end; i++) {
total += iot_bitops_cbs((uint8_t)(tmt->tone_mask_bitmap[i]));
total += iot_bitops_cbs((uint8_t)(tmt->tone_mask_bitmap[i] >> 8));
total += iot_bitops_cbs((uint8_t)(tmt->tone_mask_bitmap[i] >> 16));
total += iot_bitops_cbs((uint8_t)(tmt->tone_mask_bitmap[i] >> 24));
}
return total;
}
/* cal the start tone and last tone
* from the tonemask table
*/
uint32_t cal_start_end_tone(
const plc_tonemask_table *tmt, \
uint32_t band_start_tone, uint32_t band_end_tone, \
uint32_t *start_tone, uint32_t *end_tone)
{
uint32_t start_index;
uint32_t end_index;
uint32_t start_dw;
uint32_t end_dw;
uint8_t tmt_bit;
start_index = band_start_tone >> 5;
end_index = band_end_tone >> 5;
start_dw = tmt->tone_mask_bitmap[start_index];
end_dw = tmt->tone_mask_bitmap[end_index];
tmt_bit = 0x1f;
tmt_bit &= (uint8_t)band_start_tone; // mod band_start_tone, get start bit
start_dw = start_dw & (0xffffffff << tmt_bit);
while (start_dw == 0) {
start_index += 1;
start_dw = tmt->tone_mask_bitmap[start_index];
}
tmt_bit = 0x1f;
tmt_bit &= (uint8_t)band_end_tone; // mod band_start_tone, get end bit
tmt_bit = 31 - tmt_bit;
end_dw = end_dw & (0xffffffff >> tmt_bit);
while (end_dw == 0) {
end_index -= 1;
end_dw = tmt->tone_mask_bitmap[end_index];
}
IOT_ASSERT(start_index <= end_index);
*start_tone = (start_index << 5) - 1;
*end_tone = (end_index << 5) + 31;
while ((start_dw << 24) == 0) {
start_dw = start_dw >> 8;
*start_tone += 8;
}
while ((end_dw >> 24) == 0) {
end_dw = end_dw << 8;
*end_tone -= 8;
}
*start_tone += iot_bitops_ffs((uint8_t)start_dw);
*end_tone -= (8 - iot_bitops_fls((uint8_t)(end_dw >> 24)));
return 0;
}
/* init the band table
* @band_start_tone - start tone id, 0 - 1535
* retrun 0 for success
*/
uint32_t init_band_table(plc_band_table_t *table, \
uint32_t band_id, \
const plc_tonemask_table *tmt, uint32_t fc_sym, \
uint32_t band_start_tone, uint32_t band_end_tone)
{
uint32_t start_tone, end_tone;
IOT_ASSERT(table && band_start_tone <= band_end_tone);
table->valid_tone_number = \
get_valid_tone_number(tmt, band_start_tone, band_end_tone);
IOT_ASSERT(table->valid_tone_number);
cal_start_end_tone(tmt, band_start_tone, band_end_tone, \
&start_tone, &end_tone);
table->fc_sym_num = fc_sym;
table->start_tone = start_tone;
table->end_tone = end_tone;
if(table->rate_type == 0)
{
g_plc_band_tbl_r0[band_id] = table;
}
else{
g_plc_band_tbl_r1[band_id] = table;
}
return 0;
}
void print_band_table(plc_band_table_t *table)
{
#if HW_PLATFORM >= HW_PLATFORM_SIMU
iot_printf("valid_tone_number:%d, start:%d, end:%d, fc_num:%d\n",
table->valid_tone_number, table->start_tone, table->end_tone,
table->fc_sym_num);
#endif
}
bool_t phy_tone_mask_get( \
const plc_tonemask_table *tone_tbl_ptr, \
uint16_t tone_idx)
{
bool_t msk_en = false;
uint8_t tone_tbl_idx = (uint8_t)(tone_idx >> 5);
uint8_t tone_group_idx = (uint8_t)(tone_idx & 0x1F);
if((1 << tone_group_idx) & \
tone_tbl_ptr->tone_mask_bitmap[tone_tbl_idx])
{
msk_en = false;
}
else{
msk_en = true;
}
return msk_en;
}
/* tone mask info */
bool_t phy_tone_mask_en(plc_tone_mask_id msk_id, uint16_t tone_idx)
{
const plc_tonemask_table *table = phy_tone_mask_ptr_get(msk_id);
if (table) {
return phy_tone_mask_get(table, tone_idx);
}
return false;
}
static void phy_get_phase_tbl(uint32_t proto_band_id, \
const plc_tone_mask_amp_phase_table *tbl, \
plc_tone_mask_amp_phase_table *up_table)
{
/*
* nw phase modify have three case:
* 1. band0/1 use nw preamble/fc
* 2. band2 use gw preamble/fc
* 3. mutiband use nw multiband preamble/fc
*/
#if SUPPORT_SOUTHERN_POWER_GRID
if (proto_band_id == IOT_SUPPORT_TONE_MULTI_BAND021) {
os_mem_cpy(up_table->preamble_phase_tab, \
preamble_phase_tab_muti_band_spg, \
sizeof(preamble_phase_tab_muti_band_spg));
os_mem_cpy(up_table->fc_payload_phase_tab, \
fc_payload_phase_tab_muti_band_spg, \
sizeof(fc_payload_phase_tab_muti_band_spg));
} else if (proto_band_id == IOT_SUPPORT_TONE_32_120) {
os_mem_cpy(up_table, tbl, \
sizeof(plc_tone_mask_amp_phase_table));
} else {
os_mem_cpy(up_table->preamble_phase_tab, \
preamble_phase_tab_spg, \
sizeof(preamble_phase_tab_spg));
os_mem_cpy(up_table->fc_payload_phase_tab, \
fc_payload_phase_tab_spg, \
sizeof(fc_payload_phase_tab_spg));
}
#else
os_mem_cpy(up_table, tbl, \
sizeof(plc_tone_mask_amp_phase_table));
(void)proto_band_id;
#endif
}
static void phy_update_phase_tbl(uint32_t buf_addr, plc_tone_mask_amp_phase_table *table)
{
uint16_t i = 0;
/* preable phase table */
for (i = 0; i < TOTAL_TX_PHASE_DW_NUM; i++)
{
SOC_WRITE_REG(buf_addr, table->preamble_phase_tab[i]);
buf_addr += 4;
}
/* fc phase table */
for (i = 0; i < TOTAL_TX_PHASE_DW_NUM; i++)
{
SOC_WRITE_REG(buf_addr, table->fc_payload_phase_tab[i]);
buf_addr += 4;
}
(void)table;
}
void phy_tone_mask_amp_phase_tab_load( \
const plc_tone_mask_amp_phase_table *table, \
plc_tone_mask_id msk_id, \
uint32_t mac_proto)
{
#if HW_PLATFORM >= HW_PLATFORM_FPGA
uint32_t i = 0;
uint32_t tmp = 0;
uint32_t buf_addr = 0;
uint32_t *p_tone_addr = \
(uint32_t *)BB_TONE_MASK_PHASE_BASEADDR;
uint32_t proto_band_id = phy_band_id_get();
plc_tone_mask_amp_phase_table update_table;
enable_sw_access_tmi_buf(true);
/* tone mask table */
for(i=0; i < TOTAL_TONE_MASK_NUM; i+=4)
{
/* Must word write */
if(phy_tone_mask_en(msk_id,i) || \
phy_tone_mask_en(msk_id,i+1) || \
phy_tone_mask_en(msk_id,i+2) || \
phy_tone_mask_en(msk_id,i+3)){
tmp = (!phy_tone_mask_en(msk_id,i)) |\
(table->tone_amp_tab[0].spur_filter << 1) |\
(table->tone_amp_tab[0].tone_amp << 4) |\
((!phy_tone_mask_en(msk_id,i+1)) << 8) |\
(table->tone_amp_tab[0].spur_filter << 9) |\
(table->tone_amp_tab[0].tone_amp << 12) |\
((!phy_tone_mask_en(msk_id,i+2)) << 16) |\
(table->tone_amp_tab[0].spur_filter << 17) |\
(table->tone_amp_tab[0].tone_amp << 20) |\
((!phy_tone_mask_en(msk_id,i+3)) << 24) |\
(table->tone_amp_tab[0].spur_filter << 25) |\
(table->tone_amp_tab[0].tone_amp << 28);
}
else{
tmp = table->tone_amp_tab[0].tone_mask |\
(table->tone_amp_tab[0].spur_filter << 1) |\
(table->tone_amp_tab[0].tone_amp << 4) |\
(table->tone_amp_tab[0].tone_mask << 8) |\
(table->tone_amp_tab[0].spur_filter << 9) |\
(table->tone_amp_tab[0].tone_amp << 12) |\
(table->tone_amp_tab[0].tone_mask << 16) |\
(table->tone_amp_tab[0].spur_filter << 17) |\
(table->tone_amp_tab[0].tone_amp << 20) |\
(table->tone_amp_tab[0].tone_mask << 24) |\
(table->tone_amp_tab[0].spur_filter << 25) |\
(table->tone_amp_tab[0].tone_amp << 28);
}
*p_tone_addr++ = tmp;
}
phy_get_phase_tbl(proto_band_id, table, &update_table);
/* phase table update */
buf_addr = BB_TONE_MASK_PHASE_BASEADDR + TOTAL_TONE_MAX;
phy_update_phase_tbl(buf_addr, &update_table);
enable_sw_access_tmi_buf(false);
/* check for special tone mask */
phy_amp_mask_set_special_limit();
#else
(void)table;
(void)msk_id;
(void)mac_proto;
#endif
}
void phy_spur_mask_set(uint32_t center_idx, uint32_t width)
{
#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(center_idx > width/2);
enable_sw_access_tmi_buf(true);
/* get start tone */
mask_begin_col_idx = (center_idx - (width >> 1)) & 0x3;
mask_begin_group_idx = (center_idx - (width >> 1)) >> 2;
/* get end tone */
mask_end_col_idx = (center_idx + (width >> 1)) & 0x3;
mask_end_group_idx = (center_idx + (width >> 1)) >> 2;
if(mask_begin_group_idx == mask_end_group_idx)
{
tmp = *(p_tone_addr + mask_begin_group_idx);
tmp |= 0x0E0E0E0E & \
(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 |= (0x0E0E0E0E & \
(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 |= (0x0E0E0E0E & \
(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 |= 0x0E0E0E0E;
*(p_tone_addr + index) = tmp;
}
}
enable_sw_access_tmi_buf(false);
#else
(void)center_idx;
(void)width;
#endif
}
void phy_limit_amp_mask_set(uint32_t start_tone, uint32_t end_tone)
{
#if HW_PLATFORM >= HW_PLATFORM_FPGA
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 mask_offset_equ = 0;
uint32_t mask_start_offset_unequ = 0;
uint32_t mask_end_offset_unequ = 0;
uint32_t *p_tone_addr = \
(uint32_t *)BB_TONE_MASK_PHASE_BASEADDR;
int32_t delta_start_offset = 0;
int32_t delta_end_offset = 0;
uint32_t delta_offset = 0;
uint32_t delta_start_offset_uneq = 0;
uint32_t delta_end_offset_uneq = 0;
uint32_t delta_start_offset_next = 0;
uint32_t delta_end_offset_next = 0;
IOT_ASSERT(start_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;
mask_offset_equ = (0xF0F0F0F0 &
(0xFFFFFFFF << 8*mask_begin_col_idx) &
(0xFFFFFFFF >> 8*(3-mask_end_col_idx)));
mask_start_offset_unequ = (0xF0F0F0F0 &
(0xFFFFFFFF << 8*mask_begin_col_idx));
mask_end_offset_unequ = (0xF0F0F0F0 &
(0xFFFFFFFF >> 8*(3-mask_end_col_idx)));
uint32_t mask_amp_begin_remain = (MASK_AMP_MAX - \
MASK_AMP_STEP * mask_begin_col_idx);
uint32_t mask_amp_end_remain = (MASK_AMP_MAX - \
MASK_AMP_STEP * (sizeof(uint32_t) - mask_end_col_idx - 1));
for (uint8_t idx=0; idx < sizeof(uint32_t); idx++) {
delta_offset = (MASK_AMP_MAX - MASK_AMP_STEP * idx);
delta_start_offset_uneq |= (delta_offset \
<< ((sizeof(uint32_t) - idx - 1) * 8));
delta_end_offset_uneq |= (delta_offset << (idx * 8));
delta_start_offset = (mask_amp_begin_remain - MASK_AMP_STEP * idx);
if (0 >= delta_start_offset) {
delta_start_offset = 0;
} else {
delta_start_offset_next |= (delta_start_offset \
<< ((sizeof(uint32_t) - idx - 1) * 8));
}
delta_end_offset = (mask_amp_end_remain - MASK_AMP_STEP * idx);
if (0 >= delta_end_offset) {
delta_end_offset = 0;
} else {
delta_end_offset_next |= (delta_end_offset << (idx * 8));
}
}
if (mask_begin_group_idx == mask_end_group_idx) {
/* start&end group */
*(p_tone_addr + mask_begin_group_idx) |= mask_offset_equ;
*(p_tone_addr + mask_begin_group_idx) |= (delta_start_offset_uneq >> \
((sizeof(uint32_t) - mask_begin_col_idx) * 8));
*(p_tone_addr + mask_begin_group_idx) |= (delta_end_offset_uneq << \
((mask_end_col_idx + 1) * 8) & 0xFFFFFFFF);
*(p_tone_addr + mask_end_group_idx) = *(p_tone_addr + mask_begin_group_idx);
} else {
/* start group */
*(p_tone_addr + mask_begin_group_idx) |= mask_start_offset_unequ;
*(p_tone_addr + mask_begin_group_idx) |= (delta_start_offset_uneq >> \
((sizeof(uint32_t) - mask_begin_col_idx) * 8));
/* end group */
*(p_tone_addr + mask_end_group_idx) |= mask_end_offset_unequ;
*(p_tone_addr + mask_end_group_idx) |= (delta_end_offset_uneq << \
((mask_end_col_idx + 1) * 8) & 0xFFFFFFFF);
}
*(p_tone_addr + mask_begin_group_idx - 1) |= delta_start_offset_next;
*(p_tone_addr + mask_end_group_idx + 1) |= delta_end_offset_next;
if (0 == mask_begin_col_idx) {
*(p_tone_addr + mask_begin_group_idx - 2) |= (MASK_AMP_STEP << 24);
} else if (3 == mask_end_col_idx) {
*(p_tone_addr + mask_end_group_idx + 2) |= MASK_AMP_STEP;
}
iot_printf("mask amp begin/end next: %x, %x.\n", \
delta_start_offset_next, delta_end_offset_next);
enable_sw_access_tmi_buf(false);
#else
(void)start_tone;
(void)end_tone;
#endif
}
void phy_amp_mask_set(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);
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 & \
(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 & \
(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 & \
(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
}
void phy_spur_mask_clr(uint32_t center_idx, uint32_t width)
{
#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(center_idx > width/2);
enable_sw_access_tmi_buf(true);
/* get start tone */
mask_begin_col_idx = (center_idx - (width >> 1)) & 0x3;
mask_begin_group_idx = (center_idx - (width >> 1)) >> 2;
/* get end tone */
mask_end_col_idx = (center_idx + (width >> 1)) & 0x3;
mask_end_group_idx = (center_idx + (width >> 1)) >> 2;
if(mask_begin_group_idx == mask_end_group_idx)
{
tmp = *(p_tone_addr + mask_begin_group_idx);
tmp &= ~(0x0E0E0E0E & \
(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 &= ~(0x0E0E0E0E & \
(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 &= ~(0x0E0E0E0E & \
(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 &= ~0x0E0E0E0E;
*(p_tone_addr + index) = tmp;
}
}
enable_sw_access_tmi_buf(false);
#else
(void)center_idx;
(void)width;
#endif
}
/* get band info */
uint32_t phy_band_info_get_by_id(
uint32_t mac_proto,
uint32_t range_id,
uint32_t band_id,
volatile uint16_t *valid_tone_num,
volatile uint8_t *fc_num,
volatile uint16_t *start_tone,
volatile uint16_t *end_tone)
{
(void)range_id;
uint8_t band_idx = 0, band_cnt = 0;
uint32_t ret = ERR_FAIL;
const plc_phy_band_table_t *band_tbl = NULL;
if (mac_proto == PLC_PROTO_TYPE_SG) {
#if SUPPORT_SMART_GRID
band_tbl = iot_plc_nsg_band_all;
band_cnt = IOT_ARRAY_CNT(iot_plc_nsg_band_all);
#endif
}
#if SUPPORT_SOUTHERN_POWER_GRID
else if (mac_proto == PLC_PROTO_TYPE_SPG) {
band_tbl = iot_plc_nsg_band_all;
band_cnt = IOT_ARRAY_CNT(iot_plc_nsg_band_all);
}
#endif
#if SUPPORT_GREEN_PHY
else if (mac_proto == PLC_PROTO_TYPE_GP) {
band_tbl = iot_plc_gp_band_all;
band_cnt = IOT_ARRAY_CNT(iot_plc_gp_band_all);
}
#endif
IOT_ASSERT(band_tbl != NULL);
for (band_idx = 0; band_idx < band_cnt; band_idx++) {
if (band_tbl[band_idx].band_id != band_id) {
continue;
}
*valid_tone_num =
(uint16_t)(band_tbl[band_idx].band_info.valid_tone_number);
*fc_num = (uint8_t)(band_tbl[band_idx].band_info.fc_sym_num);
*start_tone = (uint16_t)(band_tbl[band_idx].band_info.start_tone);
*end_tone = (uint16_t)(band_tbl[band_idx].band_info.end_tone);
ret = ERR_OK;
break;
}
return ret;
}
const plc_tonemask_table *phy_tone_mask_ptr_get(plc_tone_mask_id mask_id)
{
const plc_tonemask_table *tone_msk_ptr = NULL;
switch(mask_id)
{
case TONE_MASK_ID_NULL:
tone_msk_ptr = &all_mask_tone_mask_table;
break;
#if SUPPORT_SMART_GRID
case TONE_MASK_ID_SG0:
tone_msk_ptr = &all_mask_tone_mask_table_sg_band0;
break;
case TONE_MASK_ID_SG1:
tone_msk_ptr = &all_mask_tone_mask_table_sg_band1;
break;
case TONE_MASK_ID_SG2:
tone_msk_ptr = &all_mask_tone_mask_table_sg_band2;
break;
case TONE_MASK_ID_SG3:
tone_msk_ptr = &all_mask_tone_mask_table_sg_band3;
break;
case TONE_MASK_ID_CUS:
tone_msk_ptr = &all_mask_tone_mask_table_custom;
break;
case TONE_MASK_ID_TIDE:
tone_msk_ptr = &all_mask_tone_mask_table_sg_tide;
break;
case TONE_MASK_ID_CE:
tone_msk_ptr = &all_mask_tone_mask_table_sg_ce;
break;
#endif /* SUPPORT_SMART_GRID */
#if SUPPORT_GREEN_PHY
case TONE_MASK_ID_GP:
tone_msk_ptr = &all_mask_tone_mask_table_gp;
break;
#endif
default:
iot_printf("%s: tome mask table not exit, use default!\n", __FUNCTION__);
tone_msk_ptr = &all_mask_tone_mask_table;
break;
}
return tone_msk_ptr;
}
void phy_update_tone_det_range()
{
uint32_t mac_proto = phy_proto_type_to_get();
uint32_t band_id = phy_band_id_get();
uint32_t start_tone_r0 = all_mask_band_table_r0_full.start_tone;
uint32_t end_tone_r0 = all_mask_band_table_r0_full.end_tone;
uint32_t start_tone_r1 = all_mask_band_table_r1_full.start_tone;
uint32_t end_tone_r1 = all_mask_band_table_r1_full.end_tone;
/* find min start_tone */
start_tone_r0 = min(start_tone_r0, all_mask_band_table_r0_low.start_tone);
start_tone_r0 = min(start_tone_r0, all_mask_band_table_r0_high.start_tone);
start_tone_r1 = min(start_tone_r1, all_mask_band_table_r1_low.start_tone);
start_tone_r1 = min(start_tone_r1, all_mask_band_table_r1_high.start_tone);
/* find max end_tone */
end_tone_r0 = max(end_tone_r0, all_mask_band_table_r0_low.end_tone);
end_tone_r0 = max(end_tone_r0, all_mask_band_table_r0_high.end_tone);
end_tone_r1 = max(end_tone_r1, all_mask_band_table_r1_low.end_tone);
end_tone_r1 = max(end_tone_r1, all_mask_band_table_r1_high.end_tone);
/* band3: if 500 > (end-start), END = START + 500 */
if (mac_proto == PLC_PROTO_TYPE_SG && \
band_id == IOT_SUPPORT_TONE_72_120) {
end_tone_r0 = start_tone_r0 + PHY_DET_TONE_EXT_ADD;
end_tone_r1 = start_tone_r1 + PHY_DET_TONE_EXT_ADD;
}
/* config det tone */
phy_rxfd_rate0_det(start_tone_r0, end_tone_r0);
phy_rxfd_rate1_det(start_tone_r1, end_tone_r1);
iot_printf("update tone detect range r0:%d~:%d, r1:%d~r1:%d\n",\
start_tone_r0, end_tone_r0, start_tone_r1, end_tone_r1);
}
static void phy_amp_mask_set_special_tide(void)
{
/* tide freq mask for 1.635-1.685M */
phy_limit_amp_mask_set(65, 67);
/* tide freq mask for 1.8-2M */
phy_limit_amp_mask_set(73, 82);
/* tide freq mask for 2.1735-2.1905M */
phy_limit_amp_mask_set(89, 90);
/* tide freq mask for 2.85-3.025M */
phy_limit_amp_mask_set(116, 124);
/* tide freq mask for 3.4-4M */
phy_limit_amp_mask_set(139, 164);
/* tide freq mask for 4.028-4.15M */
phy_limit_amp_mask_set(165, 170);
/* tide freq mask for 4.1765-4.1785M */
phy_limit_amp_mask_set(171, 172);
}
static void phy_amp_mask_set_special_ce(void)
{
switch (phy_band_id_get()) {
case IOT_SUPPORT_TONE_100_230_CE:
phy_limit_amp_mask_set(100, 102); /* 2.3 - 2.498M */
phy_limit_amp_mask_set(117, 123); /* 2.85 - 3.025M */
phy_limit_amp_mask_set(133, 165); /* 3.2 - 4.05M */
phy_limit_amp_mask_set(191, 208); /* 4.65 - 5.11M */
phy_limit_amp_mask_set(218, 230); /* 5.25 - 5.615M */
break;
case IOT_SUPPORT_TONE_80_490_CE:
phy_limit_amp_mask_set(74, 82); /* start tone 83, 2.002M */
phy_limit_amp_mask_set(96, 100); /* (+2/-2) 2.295 - 2.490 */
phy_limit_amp_mask_set(118, 122); /* (+1/-2) 2.856 - 3.027 */
phy_limit_amp_mask_set(133, 165); /* (+2/-1) 3.198 - 4.053 */
phy_limit_amp_mask_set(190, 208); /* (0/-1) 4.639 - 5.103 */
/* war for mask tone */
phy_amp_mask_set(74, 82); /* must mask tone 80~83 */
phy_amp_mask_set(134, 165);
phy_amp_mask_set(191, 207);
/* not break */
case IOT_SUPPORT_TONE_231_490_CE:
/* for band IOT_SUPPORT_TONE_231_490 */
phy_limit_amp_mask_set(253, 254); /* start tone 255 */
phy_limit_amp_mask_set(268, 273); /* 6.519 - 6.689 */
phy_limit_amp_mask_set(288, 316); /* 7.007 - 7.690 */
phy_limit_amp_mask_set(361, 367); /* 8.813 - 8.960 */
phy_limit_amp_mask_set(381, 416); /* 9.302 - 10.156 */
phy_limit_amp_mask_set(462, 465); /* 11.279 - 11.401 */
phy_limit_amp_mask_set(474, 490); /* end tone 472 */
/* war for mask tone */
phy_amp_mask_set(215, 254); /* must mask tone 252~254 */
break;
default:
break;
}
}
void phy_band_tone_range_get(uint32_t *start_tone, uint32_t *end_tone)
{
uint8_t hw_band_id = HW_FULL_BAND;
uint32_t start = 0xfffffff, end = 0;
for (hw_band_id = HW_FULL_BAND; hw_band_id < MAX_HW_BAND; hw_band_id++) {
if (start > g_plc_band_tbl_r0[hw_band_id]->start_tone) {
start = g_plc_band_tbl_r0[hw_band_id]->start_tone;
}
if (end < g_plc_band_tbl_r0[hw_band_id]->end_tone) {
end = g_plc_band_tbl_r0[hw_band_id]->end_tone;
}
}
if (start_tone) {
*start_tone = start;
}
if (end_tone) {
*end_tone = end;
}
}
void phy_amp_mask_set_special_limit()
{
switch (phy_mask_id_get()) {
case TONE_MASK_ID_TIDE:
phy_amp_mask_set_special_tide();
break;
case TONE_MASK_ID_CE:
phy_amp_mask_set_special_ce();
break;
default:
if (phy_band_id_get() == IOT_SUPPORT_TONE_1160_1415) {
/* set the amplitude for 30M to 37M */
phy_tone_amp_set(1160, 1311, 0x2);
phy_tone_amp_set(1312, 1389, 0x1);
phy_tone_amp_set(1390, 1415, 0x0);
}
break;
}
}