From 88577e146758ea140bf59319fcdbb6b46c091bf5 Mon Sep 17 00:00:00 2001 From: Peter Yoo Date: Sat, 12 Sep 2026 20:19:41 +0900 Subject: [PATCH] Add "Sync glitch filt" compatibility option While an input is locked, single-shot deviations of the frontend measurements (line count, field period beyond PCNT_TOLERANCE, hsync width beyond HSYNC_WIDTH_TOLERANCE, activity flag or the validity check) make get_status() re-program the mode or drop sync. A NeXT SoG source produced such glitches (868 -> 814 -> 868 lines) every few minutes, each one a visible blink. With this option on, a deviation is acted upon only once it has been seen on three consecutive status reads; the first two deviating reads are replaced by the previous stable values. That is 30 ms in the normal case and up to about 105 ms if the vsync wait in get_status() times out on every read. Counting deviating reads (rather than requiring identical readings) guarantees that a real mode change or sync loss is always accepted on the third read. The counter is cleared whenever the input is not locked or the option is off. Default Off (stock behaviour). Stored as profile item id 69. Co-Authored-By: Claude Fable 5.1 Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01WiXHy7Jhh5yTdsBaenucgw --- software/sys_controller/av_controller.c | 31 ++++++++++++++++++++++++- software/sys_controller/inc/avconfig.h | 1 + software/sys_controller/src/menu.c | 1 + software/sys_controller/src/userdata.c | 1 + 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/software/sys_controller/av_controller.c b/software/sys_controller/av_controller.c index ee3320d..b7c15fd 100644 --- a/software/sys_controller/av_controller.c +++ b/software/sys_controller/av_controller.c @@ -70,6 +70,7 @@ tvp_input_t target_tvp; tvp_sync_input_t target_tvp_sync; alt_u8 target_type; alt_u8 update_cur_vm; +static alt_u8 glitch_dev_ctr; // "Sync glitch filt": consecutive deviating status reads while locked // Default settings const settings_t ts_default = { @@ -369,9 +370,37 @@ status_t get_status(tvp_sync_input_t syncinput) pcnt_field = (unsigned long)sc->fe_status2.pcnt_field; hsync_width = (unsigned long)sc->fe_status2.hsync_width; - clkcnt = (totlines>>!progressive) ? pcnt_field/(totlines>>!progressive) : 0; valid_mode = (pcnt_field > 0) && check_linecnt(progressive, totlines); + // Optional glitch filter: while locked, act on a changed measurement (line count, field period, hsync width, + // activity flag or validity) only once it has deviated on 3 consecutive status reads (30 ms, up to ~105 ms if + // the vsync wait above times out on every read); until then keep the previous values. Single-shot glitches + // (e.g. 868 -> 814 -> 868 lines seen on a NeXT SoG source) otherwise trigger a mode re-program or a + // sync-loss/re-lock cycle. Counting reads rather than requiring identical candidate values guarantees that a + // real change or loss is always accepted on the third read. + if (!tc.sync_glitch_filt || !cm.sync_active) { + glitch_dev_ctr = 0; + } else { + alt_u8 deviates = !sync_active || !valid_mode || + (totlines != cm.totlines) || (progressive != cm.progressive) || + (pcnt_field < (cm.pcnt_field - PCNT_TOLERANCE)) || (pcnt_field > (cm.pcnt_field + PCNT_TOLERANCE)) || + (abs(((int)hsync_width - (int)cm.hsync_width)) > HSYNC_WIDTH_TOLERANCE); + + if (!deviates) { + glitch_dev_ctr = 0; + } else if (glitch_dev_ctr < 2) { + glitch_dev_ctr++; + sync_active = 1; + valid_mode = 1; + totlines = cm.totlines; + progressive = cm.progressive; + pcnt_field = cm.pcnt_field; + hsync_width = cm.hsync_width; + } + } + + clkcnt = (totlines>>!progressive) ? pcnt_field/(totlines>>!progressive) : 0; + // Check sync activity if (!cm.sync_active && sync_active && valid_mode) { cm.sync_active = 1; diff --git a/software/sys_controller/inc/avconfig.h b/software/sys_controller/inc/avconfig.h index 11d54dd..6798d11 100644 --- a/software/sys_controller/inc/avconfig.h +++ b/software/sys_controller/inc/avconfig.h @@ -160,6 +160,7 @@ typedef struct { alt_u8 av3_alt_rgb; avinput_t link_av; alt_u8 pc_sog_coast; + alt_u8 sync_glitch_filt; } __attribute__((packed)) avconfig_t; int set_default_profile(int update_cc); diff --git a/software/sys_controller/src/menu.c b/software/sys_controller/src/menu.c index a7dbe83..4096d44 100644 --- a/software/sys_controller/src/menu.c +++ b/software/sys_controller/src/menu.c @@ -249,6 +249,7 @@ MENU(menu_compatibility, P99_PROTECT({ \ { "Panasonic hack", OPT_AVCONFIG_SELECTION, { .sel = { &tc.panasonic_hack, OPT_WRAP, SETTING_ITEM(off_on_desc) } } }, { "Disable PR2x", OPT_AVCONFIG_SELECTION, { .sel = { &tc.hdmi_pr2x_disable, OPT_WRAP, SETTING_ITEM(off_on_desc) } } }, { "PC SoG/CS coast", OPT_AVCONFIG_SELECTION, { .sel = { &tc.pc_sog_coast, OPT_WRAP, SETTING_ITEM(off_on_desc) } } }, + { "Sync glitch filt", OPT_AVCONFIG_SELECTION, { .sel = { &tc.sync_glitch_filt, OPT_WRAP, SETTING_ITEM(off_on_desc) } } }, })) MENU(menu_audio, P99_PROTECT({ \ diff --git a/software/sys_controller/src/userdata.c b/software/sys_controller/src/userdata.c index ad43c2c..8ed6449 100644 --- a/software/sys_controller/src/userdata.c +++ b/software/sys_controller/src/userdata.c @@ -145,6 +145,7 @@ const ude_item_map ude_profile_items[] = { UDE_ITEM(61, 122, tc.hdmi_ar), UDE_ITEM(61, 122, tc.hdmi_pr2x_disable), UDE_ITEM(68, 122, tc.pc_sog_coast), + UDE_ITEM(69, 122, tc.sync_glitch_filt), }; int write_userdata(uint8_t entry) {