diff --git a/src/atsc_app/inc/config.h b/src/atsc_app/inc/config.h index 697aaf4..966bc40 100755 --- a/src/atsc_app/inc/config.h +++ b/src/atsc_app/inc/config.h @@ -45,6 +45,11 @@ #define USE_UART_DEV_LINK 1 +/* IQ spectrum/eye-analysis periodic diagnostics on the debug UART. + * Keep disabled in normal operation; set to 1 only when timing/packet + * continuity troubleshooting is required. */ +#define IQ_ANALYSIS_UART_DEBUG 0 + /* * Prefer the local key/LCD path when the single-core CPU is busy with IQ * analysis. Set to 0 to restore the original thread priorities. diff --git a/src/atsc_app/task/iq_rx.c b/src/atsc_app/task/iq_rx.c index ac27635..f7ae504 100755 --- a/src/atsc_app/task/iq_rx.c +++ b/src/atsc_app/task/iq_rx.c @@ -370,6 +370,7 @@ static void *iq_spec_thr(void *arg) } /* a full window is 26.21 ms = 1.08 ATSC fields; print only a short burst every 30s */ +#if IQ_ANALYSIS_UART_DEBUG { static time_t log_burst_start = 0; static int log_burst_count = 0; @@ -386,6 +387,7 @@ static void *iq_spec_thr(void *arg) log_burst_count++; } } +#endif if (npkt == IQ_NPKT && ++nraw >= IQ_RAW_EVERY) { FILE *r = fopen("/tmp/iq_raw.bin", "wb"); /* whole contiguous window, for PC-side analysis */ if (r) { fwrite(iq_win[buf], 1, IQ_WBYTES, r); fclose(r); } diff --git a/src/atsc_app/task/iq_vsb.c b/src/atsc_app/task/iq_vsb.c index 43470ec..07fd399 100755 --- a/src/atsc_app/task/iq_vsb.c +++ b/src/atsc_app/task/iq_vsb.c @@ -41,6 +41,7 @@ #include #include "iq_rx.h" +#include "../inc/config.h" #ifndef M_PI #define M_PI 3.14159265358979323846 @@ -1395,6 +1396,7 @@ void iq_vsb_analyse(const unsigned char *win, int wid) minh = eyeh[0]; for (j = 1; j < 7; j++) if (eyeh[j] < minh) minh = eyeh[j]; +#if IQ_ANALYSIS_UART_DEBUG printf("[iq_vsb] win %d: SNR %.2f dB (raw %.2f, ORx AGC jitter %.2f%%) tau %.4f theta %+.1f deg coff %+.3f Hz " "segsync %.1f@%d eye_w %.3f UI min_eye_h %.2f %s " "[ms: unpack %d tau %d demod %d stats %d eye %d total %d]\n", @@ -1412,4 +1414,5 @@ void iq_vsb_analyse(const unsigned char *win, int wid) else printf("[pr12] win %d: no field sync (ratio %.1f < %.1f), LEGACY fallback\n", wid, pr.ratio, PR12_RATIO_THR); +#endif } diff --git a/src/atsc_app/task/lcd_task.c b/src/atsc_app/task/lcd_task.c index 9151980..c2bee4c 100755 --- a/src/atsc_app/task/lcd_task.c +++ b/src/atsc_app/task/lcd_task.c @@ -944,7 +944,7 @@ void get_tsnr_limd_uimd(uint16 *ptsnr, uint8 *plmid, uint8 *pumid) // UIMD/LIMD and SNR now all come from the imx6's own 10 MSPS ORx window: // - LIMD/UIMD: iq_rx.c, same taps as the FPGA but band-averaged over 11 bins // and Welch-averaged. LIMD is the shoulder on the pilot's side. Half-dB units, - // no +11 dB display offset (the web adds that). + // displayed without the historical +11 dB offset. // - SNR: iq_vsb.c, the real 8VSB MER (I-path) of a demodulated window. // If a source has not produced a fresh value we keep the previous one rather than // report a fabricated number. @@ -4215,11 +4215,11 @@ static void refresh_ad4(void *parg,void *parv) //需添加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))。 + //ab_flag=TRUE -> 逻辑/丝印 B;FALSE -> 逻辑/丝印 A,硬件位由统一映射转换。 if(atsc_para.system_para.ab_mode==1) { if(check_delay_over(&tickbak,50)==TRUE) - { // 0x23 IQB_UPD: 1=B, 0=A (E_SELECT_A=0/E_SELECT_B=1) + { // 0x23 IQB_UPD: 逻辑A/B由 DPD_RF_SEL_VALUE() 映射到反向硬件位 if(++ppara->ab_sec>16) { ppara->ab_flag = ppara->ab_flag?FALSE:TRUE; @@ -14533,14 +14533,24 @@ static void sec_proc_func(void) static void update_fssi_state(void) { - // 0x23 IQB_UPD: 1=B, 0=A (E_SELECT_A=0/E_SELECT_B=1) + // 0x23 IQB_UPD: 逻辑A/B由 DPD_RF_SEL_VALUE() 映射到反向硬件位 uint8 a_fssi; uint8 b_fssi; uint8 data; static uint16 sec_cnt=0; static uint8 ab_flg =0; + static int last_ab_mode = -1; + int ab_mode = (atsc_para.system_para.ab_mode == 1); + /* FSSI Refresh alternates the ORx A/B path. IQ UDP windows can therefore + * contain both paths and must not be collected until Refresh is off. + * This edge check is intentionally before every early return below, so all + * configuration entry points take effect even while DPD is busy. */ + if (ab_mode != last_ab_mode) { + iq_spec_set_enable(!ab_mode); + last_ab_mode = ab_mode; + } /* 1. UPDATE and UPDLIN 返回 @@ -14800,7 +14810,7 @@ int sys_rf_agc_switch_proc(uint8 trigger) //1 射频开关切换到A u_dpdctl_r23.u8val = 0; u_dpdctl_r23.dpd_bt.iqb_upd = 0; - u_dpdctl_r23.dpd_bt.rf_sel = 0; //A + u_dpdctl_r23.dpd_bt.rf_sel = DPD_RF_SEL_VALUE(E_SELECT_A); u_dpdctl_r23.dpd_bt.sync_mode = 0; fpga_byte_write(0x05, FPGA_ADDR_DPD_IQB_UPD, u_dpdctl_r23.u8val);