V131R-260725:修正FSSI/FWD显示并优化8VSB频谱分析

修正FSSI/FWD标定、存储和LCD显示;增强8VSB场同步、MER分析及网页频谱展示;更新版本号与修改记录。
This commit is contained in:
2026-07-28 14:05:40 +08:00
parent 296c330197
commit 92b155499d
14 changed files with 1084 additions and 269 deletions
+72 -100
View File
@@ -814,26 +814,19 @@ void lcd_write_prompt(const PROMPT_POS *ppos,PMENU_S pmenu)
lcd_write_string(ppos->line,ppos->pos[pmenu->item_index],PROMPT_CHAR);
}
/* 取一次 ORx 输入功率(dB)。
/* 取一次 ORx gain index(=255-cw_hi), 5 点中位数原子读。
*
* ORx RF-AGC 是闭环: dpd_rx_rfagc_1x.vhd:129 把 mean(I^2+Q^2) 伺服到
* fagcpwrlevel*64 = 16384, 且 dz=232 的死区(同文件 :29,:176)把偏离夹在 2.00dB 内。
* 因此 ob_fb_rms_pwr 恒被钉在 fagcpwrlevel*4 ≈ 1024, 单独用它不可能跟随输入功率 ——
* 输入功率的信息全部转移到了增益字上。
*
* 粗档取 FAGC 增益字(0x36/0x37, 0.5dB/step), 细档取死区内残差(0x03/0x04), 两者相加。
* 各取 5 次中位数: 加锁挡不住板上 i2cget 或其它 master 插入,
* 中位数对孤立野值免疫, 均值不免疫(这正是原 FWD 炸掉的机理)。 */
static float orx_input_power_db(void)
* ORx RF-AGC 闭环下(dpd_rx_rfagc_1x.vhd:179-187): 输入升高 -> 实测高于设定点
* -> agcctrlword(cw_hi) 递增 -> gain_index = 255-cw_hi 递减 -> 增益降低。
* 5 点中位数对孤立野值(板上 i2cget 或其它 master 插入造成)免疫, 均值不免疫。 */
static uint8 orx_gain_index_now(void)
{
uint16 cw[5], rms[5];
uint16 cw[5];
int i;
for (i = 0; i < 5; i++) {
rms[i] = fpga_word_read_lh(0x01, 0x03, 0x04); /* ob_fb_rms_pwr */
cw[i] = fpga_word_read_hl(0x01, 0x36, 0x37); /* agcctrlword */
}
return orx_power_combine_db(orx_median5(cw), orx_median5(rms));
for (i = 0; i < 5; i++)
cw[i] = fpga_word_read_hl(0x01, 0x36, 0x37);
return (uint8)(255 - ((orx_median5(cw) >> 8) & 0xff));
}
static void calc_fwd(void)
@@ -899,32 +892,26 @@ static void calc_fwd(void)
}
}
#else
float p_db;
int16 delta_hdb;
uint16 cw[5], rms[5];
int i;
uint8 cw_hi;
if( !atsc_para.ad3_para.power_ref ) {
/* 未标定(S4 缺省标记, cal_fagc_cw==0xFF, 见 task-s4-report.md)时 FWD 显示 0 */
if (atsc_para.ad3_para.cal_fagc_cw == 0xff) {
atsc_para.log_para.fwd = 0;
return;
}
p_db = orx_input_power_db();
/* power_ref 存的是额定功率处的 p_db, 0.1 dB/LSB 定点 */
atsc_para.log_para.fwd =
orx_fwd_percent(p_db, (float)atsc_para.ad3_para.power_ref / 10.0f);
/* 标定用日志, 标定完成后删除 */
{
static uint8 dbg_cnt = 0;
if(++dbg_cnt >= 5){ dbg_cnt = 0;
uint16 cw = fpga_word_read_hl(0x01, 0x36, 0x37);
uint16 rms = fpga_word_read_lh(0x01, 0x03, 0x04);
printf("[FSSI] cw_hi=%u rms=%u p_db=%.2f FWD=%d%% A_FSSI=%d B_FSSI=%d (ref=%d rf=%d)\n",
(cw >> 8) & 0xff, rms, p_db, atsc_para.log_para.fwd,
st_extend_state.a_fssi, st_extend_state.b_fssi,
atsc_para.ad3_para.power_ref, atsc_para.rf_para.rf);
}
for (i = 0; i < 5; i++) {
rms[i] = fpga_word_read_lh(0x01, 0x03, 0x04);
cw[i] = fpga_word_read_hl(0x01, 0x36, 0x37);
}
cw_hi = (uint8)((orx_median5(cw) >> 8) & 0xff);
delta_hdb = (int16)((int16)cw_hi + orx_pwr_halfdb(orx_median5(rms)))
- (int16)((int16)atsc_para.ad3_para.cal_fagc_cw
+ (int16)atsc_para.ad3_para.cal_orx_pwr_hdb);
atsc_para.log_para.fwd = orx_fwd_percent_hdb(delta_hdb);
#endif
}
void get_tsnr_limd_uimd(uint16 *ptsnr, uint8 *plmid, uint8 *pumid)
@@ -4178,20 +4165,12 @@ static void refresh_ad3(void *parg,void *parv)
#endif
}
static uint8 ad_fssi_calc(float p_db)
{
int is_vhf = (atsc_para.rf_para.txfreq <= FREQ_MAX_V) ? 1 : 0;
/* -20 / VHF -18 两段 EMV7 遗留显示微调在 orx_fssi_percent() 内保留 */
return orx_fssi_percent(p_db, FSSI_REF_DB, is_vhf);
}
//" PDT CFR ADPC FSSI "
static void refresh_ad4(void *parg,void *parv)
{
PMENU_S pmenu = (PMENU_S)parg;
const PROMPT_POS prompt_pos = {LINE_1,{1,7,13,22}};
PS_ADVANCE4_PARA ppara = (PS_ADVANCE4_PARA)para_middle;
float p_db;
uint8 data;
static uint32 tickbak=0;
@@ -4234,68 +4213,62 @@ static void refresh_ad4(void *parg,void *parv)
break;*/
}
#if 1
//需添加A:FSSI和B:FSSI
if(check_delay_over(&tickbak,50)==TRUE)
{ //05 3a 发1 为A 发0 为B
if(++ppara->ab_sec>16)
{
ppara->ab_flag = ppara->ab_flag?FALSE:TRUE;
ppara->ab_sec = 0;
}
set_ab_switch(ppara->ab_flag);
p_db = orx_input_power_db();
ppara->fssi = ad_fssi_calc(p_db);
}
if(ppara->ab_flag)
//需添加A:FSSI和B:FSSI ; FSSI 单源: update_fssi_state() 是唯一计算点,
//本函数只读 st_extend_state.a_fssi/b_fssi 显示, 不再自己取数/换算。
//ab_flag=TRUE -> 当前选中 B 路(set_ab_switch(1)); FALSE -> A 路(set_ab_switch(0))。
if(atsc_para.system_para.ab_mode==1)
{
st_extend_state.a_fssi=ppara->fssi;
if((ppara->fssi > 75) || (ppara->fssi < 20))
if(check_delay_over(&tickbak,50)==TRUE)
{ // 0x23 IQB_UPD: 1=B, 0=A (E_SELECT_A=0/E_SELECT_B=1)
if(++ppara->ab_sec>16)
{
ppara->ab_flag = ppara->ab_flag?FALSE:TRUE;
ppara->ab_sec = 0;
}
set_ab_switch(ppara->ab_flag);
}
if(ppara->ab_flag)
{
if(ppara->ab_sec&1)
sprintf(out_str,"B:%d%%!",ppara->fssi); //250307 feedback, need to change A->B
ppara->fssi = st_extend_state.b_fssi;
if((ppara->fssi > 75) || (ppara->fssi < 20))
{
if(ppara->ab_sec&1)
sprintf(out_str,"B:%d%%!",ppara->fssi);
else
return;
}
else
return;
{
sprintf(out_str,"B:%d%%",ppara->fssi);
}
}
else
{
sprintf(out_str,"B:%d%%",ppara->fssi);
ppara->fssi = st_extend_state.a_fssi;
if((ppara->fssi > 75) || (ppara->fssi < 20))
{
if(ppara->ab_sec&1)
sprintf(out_str,"A:%d%%!",ppara->fssi);
else
return;
}
else
{
sprintf(out_str,"A:%d%%",ppara->fssi);
}
}
}
else
{
st_extend_state.b_fssi=ppara->fssi;
//ab_mode!=1(出厂默认 0): update_fssi_state() 只更新 a_fssi, b_fssi 恒 0,
//不做 A/B 轮换、也不再周期性 set_ab_switch() 打扰 DPD 反馈通路,
//固定显示 A 路(S5 fix1, 对应评审 C2/I1)。
ppara->fssi = st_extend_state.a_fssi;
if((ppara->fssi > 75) || (ppara->fssi < 20))
{
if(ppara->ab_sec&1)
sprintf(out_str,"A:%d%%!",ppara->fssi); //250307 feedback, need to change B->A
else
return;
}
sprintf(out_str,"A:%d%%!",ppara->fssi);
else
{
sprintf(out_str,"A:%d%%",ppara->fssi);
}
}
#else
set_ab_switch(0); // 0 : A
//printf("ad4 AB - A\n");
p_db = orx_input_power_db();
ppara->fssi = ad_fssi_calc(p_db);
st_extend_state.a_fssi = ppara->fssi;
if((ppara->fssi > 75) || (ppara->fssi < 20))
{
sprintf(out_str,"%d%%!",ppara->fssi);
}
else
{
sprintf(out_str,"%d%%",ppara->fssi);
}
#endif
lcd_write_string(LINE_2,prompt_pos.pos[3]+1,out_str);
}
@@ -14560,11 +14533,10 @@ static void sec_proc_func(void)
static void update_fssi_state(void)
{
//05 3a 发1 为A ; 发0 为B
// 0x23 IQB_UPD: 1=B, 0=A (E_SELECT_A=0/E_SELECT_B=1)
uint8 a_fssi;
uint8 b_fssi;
uint8 data;
float p_db;
static uint16 sec_cnt=0;
static uint8 ab_flg =0;
@@ -14608,10 +14580,10 @@ static void update_fssi_state(void)
if(ab_flg){
//B
set_ab_switch(E_SELECT_B);
p_db = orx_input_power_db();
{ /* 显示滞回: FAGC 一步 0.5dB = FSSI 2.5%, 无滞回会来回闪 */
static uint8 b_prev = 0;
b_prev = orx_fssi_hysteresis(b_prev, ad_fssi_calc(p_db));
b_prev = orx_fssi_hysteresis(b_prev,
orx_fssi_from_gain_index(orx_gain_index_now(), FSSI_GI_MIN, FSSI_GI_MAX));
st_extend_state.b_fssi = b_prev;
}
}
@@ -14619,10 +14591,10 @@ static void update_fssi_state(void)
//delay_ms(9);
//A
set_ab_switch(E_SELECT_A);
p_db = orx_input_power_db();
{
static uint8 a_prev = 0;
a_prev = orx_fssi_hysteresis(a_prev, ad_fssi_calc(p_db));
a_prev = orx_fssi_hysteresis(a_prev,
orx_fssi_from_gain_index(orx_gain_index_now(), FSSI_GI_MIN, FSSI_GI_MAX));
st_extend_state.a_fssi = a_prev;
}
}
@@ -14631,10 +14603,10 @@ static void update_fssi_state(void)
else{
set_ab_switch(0);
//printf("AB switch A\n");
p_db = orx_input_power_db();
{
static uint8 a_prev2 = 0;
a_prev2 = orx_fssi_hysteresis(a_prev2, ad_fssi_calc(p_db));
a_prev2 = orx_fssi_hysteresis(a_prev2,
orx_fssi_from_gain_index(orx_gain_index_now(), FSSI_GI_MIN, FSSI_GI_MAX));
st_extend_state.a_fssi = a_prev2;
}
//printf("[%s,%d] only A_FSSI=%d\n",__FUNCTION__,__LINE__,st_extend_state.a_fssi);