fix(atsc_app): 暂停FSSI刷新期间的IQ采集

FSSI Refresh开启后,网页提前改写全局状态,使频谱隐藏函数误判状态
未变化而直接返回;同时i.MX仍持续组装IQ窗口并执行FFT和眼图分析。

由频谱页状态函数统一完成前端切换。后端在A/B轮询期间丢弃IQ包,
清除待处理窗口和旧测量结果;关闭FSSI Refresh后,从pkt_idx=0的
新窗口恢复采集,避免混入A/B切换期间或内核积压的旧数据。

验证:node --check src/web/www/js/dashboard.js,通过。
验证:加载Yocto环境后执行make -C src/atsc_app -j2,编译通过。
未部署到192.168.1.143,未执行板端FSSI开关和恢复验证。
This commit is contained in:
efox
2026-08-28 20:06:02 +08:00
parent 61c85f1fdc
commit f6e4f84c27
4 changed files with 50 additions and 11 deletions
+6 -1
View File
@@ -41,6 +41,7 @@
#include "../inc/fpga.h"
#include "../inc/http_get.h"
#include "../inc/adrv9009_ext.h"
#include "../inc/iq_rx.h"
extern uint32 adpc_source_udp;
extern uint32 adpc_source_web;
@@ -890,7 +891,12 @@ void http_write_sys(S_CGI_SET *ppara)
if(atsc_para.system_para.adpc<=ADPC_HOLD&&g_trigger_up_tsnr_flg == 0)// 无大小均衡
{
atsc_para.system_para.ab_mode = ppara->ab_mode;
/* FSSI Refresh alternates A/B feedback paths. Pause IQ collection until
* the unit returns to the stable single-A path. */
iq_spec_set_enable(ppara->ab_mode == 0);
}
//-----------------------------------------
uint8 adpc_bak;
@@ -1650,4 +1656,3 @@ void http_save_change_para(void *p)
/*****************************END**************************************/
+36 -6
View File
@@ -161,11 +161,22 @@ void iq_spec_set_enable(int enable)
iq_spec_enable = enable;
if (!enable) {
/* This switch controls spectrum-page files only. Status-page SNR and
* shoulders must continue to be measured in the background. */
/* FSSI A/B switching mixes two feedback paths, so no IQ window collected
* in this mode is valid as a stable single-path spectrum or eye. */
pthread_mutex_lock(&iq_mtx);
iq_ready = -1;
pthread_mutex_unlock(&iq_mtx);
pthread_mutex_lock(&vsb_mtx);
vsb_pending = 0;
pthread_mutex_unlock(&vsb_mtx);
pthread_mutex_lock(&imd_mtx);
imd_stamp = 0;
pthread_mutex_unlock(&imd_mtx);
iq_vsb_clear_results();
unlink(IQ_JSON);
unlink(IQ_JSON_TMP);
unlink("/tmp/iq_eye.json");
unlink("/tmp/iq_raw.bin");
}
printf("[iq_rx] spectrum %s\n", enable ? "enabled" : "disabled");
}
@@ -184,9 +195,10 @@ static void *iq_vsb_thr(void *arg)
while (!vsb_pending) pthread_cond_wait(&vsb_cond, &vsb_mtx);
pthread_mutex_unlock(&vsb_mtx);
iq_vsb_analyse(vsb_win, vsb_wid);
if (!iq_spec_get_enable()) {
if (iq_spec_get_enable()) {
iq_vsb_analyse(vsb_win, vsb_wid);
} else {
iq_vsb_clear_results();
unlink("/tmp/iq_eye.json");
}
@@ -245,6 +257,13 @@ static void *iq_spec_thr(void *arg)
buf = iq_ready; npkt = iq_ready_pkts; run = iq_ready_run; wid = iq_ready_wid;
pthread_mutex_unlock(&iq_mtx);
if (!iq_spec_get_enable()) {
pthread_mutex_lock(&iq_mtx);
iq_ready = -1;
pthread_mutex_unlock(&iq_mtx);
continue;
}
for (i = 0; i < IQ_FFT; i++) psd[i] = 0.0f;
nseg = 0;
for (s = 0; s < IQ_NSEG; s++) {
@@ -437,13 +456,24 @@ void *iq_rx_thr(void *arg)
for (;;) {
int wid, idx;
n = recvfrom(fd, pkt, sizeof(pkt), 0, NULL, NULL);
if (!iq_spec_get_enable()) {
cur = -1;
npkt = 0;
continue;
}
if (n < 8 + IQ_PAY) continue;
if (pkt[0] != 0x49 || pkt[1] != 0x51 || pkt[6] != 0x02) continue; /* 'IQ', fmt=2 */
wid = pkt[2];
idx = ((pkt[4] & 0x03) << 8) | pkt[5];
if (idx >= IQ_NPKT) continue;
if (cur < 0) cur = wid;
/* After FSSI Refresh is turned off, wait for packet zero so the first
* analysed window cannot contain a stale or partial A/B interval. */
if (cur < 0) {
if (idx != 0) continue;
memset(iq_seen[buf], 0, IQ_NPKT);
cur = wid;
}
if (wid != cur) { /* window boundary: hand this one off */
int other = buf ^ 1;
pthread_mutex_lock(&iq_mtx);
+3 -2
View File
@@ -1315,8 +1315,9 @@ int set_spec_cfg(char *pbuf,short bufMaxLen)
if (!pbuf || bufMaxLen == 0) return -1;
atsc_para.system_para.spec_enable = 1;
c256_bytewrite(EEPROM_SPEC_ENABLE, atsc_para.system_para.spec_enable);
iq_spec_set_enable(1);
log_printf(LOG_INFO, I_USER_CFG, "spectrum enable fixed on\n");
iq_spec_set_enable(atsc_para.system_para.ab_mode == 0);
log_printf(LOG_INFO, I_USER_CFG, "spectrum page enabled, IQ collection %s\n",
atsc_para.system_para.ab_mode == 0 ? "running" : "paused by FSSI Refresh");
return 0;
}
+5 -2
View File
@@ -242,9 +242,12 @@
// The status interface already carries the shared A/B FSSI values.
// Spectrum consumes the same values instead of issuing another request.
updateSpectrumFssi(Number(form[16]), Number(form[17]), ab_modenum);
window.fssiRefreshActive = (ab_modenum === 1);
var refreshActive = (ab_modenum === 1);
if (typeof window.setSpectrumRefreshActive === 'function') {
window.setSpectrumRefreshActive(window.fssiRefreshActive);
// Let the spectrum page compare with and update its previous state.
window.setSpectrumRefreshActive(refreshActive);
} else {
window.fssiRefreshActive = refreshActive;
}
// Input source — C1: via the single accessor; the old >5 clamp is gone