1007 lines
33 KiB
C
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;
|
|
}
|
|
}
|