mirror of
https://github.com/marqs85/ossc
synced 2025-04-09 22:56:34 +03:00
tweak activity detection to fix auto input
This commit is contained in:
parent
e49106b635
commit
10f1afd79c
@ -35,7 +35,7 @@ typedef union {
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t pcnt_frame:20;
|
||||
uint32_t pcnt_field:20;
|
||||
uint8_t hsync_width:8;
|
||||
uint8_t fe_rsv:4;
|
||||
} __attribute__((packed, __may_alias__));
|
||||
|
@ -172,7 +172,7 @@ end
|
||||
wire [7:0] TVP_R_post, TVP_G_post, TVP_B_post;
|
||||
wire TVP_HSYNC_post, TVP_VSYNC_post, TVP_DE_post, TVP_FID_post, TVP_datavalid_post;
|
||||
wire TVP_fe_interlace, TVP_fe_frame_change, TVP_sof_scaler, TVP_sync_active;
|
||||
wire [19:0] TVP_fe_pcnt_frame;
|
||||
wire [19:0] TVP_fe_pcnt_field;
|
||||
wire [7:0] TVP_hsync_width;
|
||||
wire [10:0] TVP_fe_vtotal, TVP_fe_xpos, TVP_fe_ypos;
|
||||
tvp7002_frontend u_tvp_frontend (
|
||||
@ -208,7 +208,7 @@ tvp7002_frontend u_tvp_frontend (
|
||||
.vtotal(TVP_fe_vtotal),
|
||||
.frame_change(TVP_fe_frame_change),
|
||||
.sof_scaler(TVP_sof_scaler),
|
||||
.pcnt_frame(TVP_fe_pcnt_frame),
|
||||
.pcnt_field(TVP_fe_pcnt_field),
|
||||
.hsync_width(TVP_hsync_width),
|
||||
.sync_active(TVP_sync_active)
|
||||
);
|
||||
@ -379,7 +379,7 @@ sys sys_inst(
|
||||
.pio_0_sys_ctrl_out_export (sys_ctrl),
|
||||
.pio_1_controls_in_export (controls),
|
||||
.sc_config_0_sc_if_fe_status_i ({19'h0, TVP_sync_active, TVP_fe_interlace, TVP_fe_vtotal}),
|
||||
.sc_config_0_sc_if_fe_status2_i ({4'h0, TVP_hsync_width, TVP_fe_pcnt_frame}),
|
||||
.sc_config_0_sc_if_fe_status2_i ({4'h0, TVP_hsync_width, TVP_fe_pcnt_field}),
|
||||
.sc_config_0_sc_if_lt_status_i (32'h00000000),
|
||||
.sc_config_0_sc_if_hv_in_config_o (hv_in_config),
|
||||
.sc_config_0_sc_if_hv_in_config2_o (hv_in_config2),
|
||||
|
@ -50,7 +50,7 @@ module tvp7002_frontend (
|
||||
output reg [10:0] vtotal,
|
||||
output reg frame_change,
|
||||
output reg sof_scaler,
|
||||
output reg [19:0] pcnt_frame,
|
||||
output reg [19:0] pcnt_field,
|
||||
output reg [7:0] hsync_width,
|
||||
output reg sync_active
|
||||
);
|
||||
@ -102,7 +102,7 @@ wire [3:0] lumacode = {lumacode_msbs, lumacode_lsbs};
|
||||
// Measurement registers
|
||||
reg [20:0] pcnt_frame_ctr;
|
||||
reg [17:0] syncpol_det_ctr, hsync_hpol_ctr, vsync_hpol_ctr;
|
||||
reg [3:0] sync_inactive_ctr;
|
||||
reg [2:0] sync_inactive_ctr;
|
||||
reg [11:0] pcnt_line, pcnt_line_ctr, meas_h_cnt, meas_h_cnt_sogref;
|
||||
reg [7:0] hs_ctr;
|
||||
reg pcnt_line_stored;
|
||||
@ -130,8 +130,8 @@ wire [11:0] even_max_thold = (H_TOTAL / 12'd2) + (H_TOTAL / 12'd4);
|
||||
wire [11:0] meas_h_cnt_ref = (vsync_i_type == VSYNC_SEPARATED) ? meas_h_cnt_sogref : meas_h_cnt;
|
||||
wire [11:0] meas_even_min_thold = (pcnt_line / 12'd4);
|
||||
wire [11:0] meas_even_max_thold = (pcnt_line / 12'd2) + (pcnt_line / 12'd4);
|
||||
wire meas_vblank_region = (pcnt_frame_ctr < 8*pcnt_line) | (pcnt_frame_ctr > (({1'b0, pcnt_frame}<<interlace_flag) - 4*pcnt_line)) |
|
||||
(interlace_flag & (pcnt_frame_ctr < (pcnt_frame+8*pcnt_line)) & (pcnt_frame_ctr > (pcnt_frame - 4*pcnt_line)));
|
||||
wire meas_vblank_region = (pcnt_frame_ctr < 8*pcnt_line) | (pcnt_frame_ctr > (({1'b0, pcnt_field}<<interlace_flag) - 4*pcnt_line)) |
|
||||
(interlace_flag & (pcnt_frame_ctr < (pcnt_field+8*pcnt_line)) & (pcnt_frame_ctr > (pcnt_field - 4*pcnt_line)));
|
||||
wire [11:0] glitch_filt_thold = meas_vblank_region ? (pcnt_line/4) : (pcnt_line/8);
|
||||
|
||||
// TODO: calculate H/V polarity independently
|
||||
@ -145,7 +145,7 @@ wire [3:0] H_SAMPLE_SEL = hv_in_config3[31:28];
|
||||
wire [3:0] H_SAMPLE_SEL_ALT = (H_SAMPLE_SEL >= (H_SKIP+1)/2) ? (H_SAMPLE_SEL - ((H_SKIP+1)/2)) : (H_SAMPLE_SEL + ((H_SKIP+1)/2));
|
||||
|
||||
// Lumacode tables (C64, Spectrum, empty)
|
||||
wire [23:0] lumacode_data[0:2][0:15] = '{'{ 24'h000000,24'h483aaa,24'h924a40,24'h9351b6,24'h675200,24'h606060,24'h8a8a8a,24'h84c5cc,24'hc33d00,24'h867ade,24'hb3b3b3,24'hd5df7c,24'h72b14b,24'hc18178,24'hb3ec91,24'hffffff},
|
||||
wire [23:0] lumacode_data[0:2][0:15] = '{'{ 24'h000000,24'h2a1b9d,24'h7d202c,24'h84258c,24'h4c2e00,24'h3c3c3c,24'h646464,24'h4fb3a5,24'h7f410d,24'h6351db,24'h939393,24'hbfd04a,24'h339840,24'hb44f5c,24'h7ce587,24'hffffff},
|
||||
'{ 24'h000000,24'h000000,24'h0200FD,24'hCF01CE,24'h0100CE,24'hCF0100,24'hFF02FD,24'h01CFCF,24'hFF0201,24'h00CF15,24'h02FFFF,24'hFFFF1D,24'h00FF1C,24'hCFCF15,24'hCFCFCF,24'hFFFFFF},
|
||||
'{ 24'h000000,24'h000000,24'h000000,24'h000000,24'h000000,24'h000000,24'h000000,24'h000000,24'h000000,24'h000000,24'h000000,24'h000000,24'h000000,24'h000000,24'h000000,24'h000000}};
|
||||
|
||||
@ -330,9 +330,12 @@ always @(posedge CLK_MEAS_i) begin
|
||||
if ((VSYNC_i_np_prev & ~VSYNC_i_np) & (~interlace_flag | (meas_fid == FID_EVEN))) begin
|
||||
pcnt_frame_ctr <= 1;
|
||||
pcnt_line_stored <= 1'b0;
|
||||
pcnt_frame <= interlace_flag ? (pcnt_frame_ctr>>1) : pcnt_frame_ctr[19:0];
|
||||
end else if (pcnt_frame_ctr < 21'h1fffff) begin
|
||||
if (sync_active & (pcnt_frame_ctr != '1))
|
||||
pcnt_field <= interlace_flag ? (pcnt_frame_ctr>>1) : pcnt_frame_ctr[19:0];
|
||||
end else if (pcnt_frame_ctr < '1) begin
|
||||
pcnt_frame_ctr <= pcnt_frame_ctr + 1'b1;
|
||||
end else begin
|
||||
pcnt_field <= 0;
|
||||
end
|
||||
|
||||
if (HSYNC_i_np_prev & ~HSYNC_i_np) begin
|
||||
@ -355,7 +358,7 @@ always @(posedge CLK_MEAS_i) begin
|
||||
VSYNC_i_np_prev <= VSYNC_i_np;
|
||||
end
|
||||
|
||||
// Detect sync polarities and activity
|
||||
// Detect sync polarities and activity during ~10ms interval
|
||||
always @(posedge CLK_MEAS_i) begin
|
||||
if (syncpol_det_ctr == 0) begin
|
||||
hsync_i_pol <= (hsync_hpol_ctr > 18'h1ffff);
|
||||
@ -365,6 +368,7 @@ always @(posedge CLK_MEAS_i) begin
|
||||
vsync_hpol_ctr <= 0;
|
||||
|
||||
if ((vsync_hpol_ctr == '0) | (vsync_hpol_ctr == '1)) begin
|
||||
// If vsync has been stale for ~100ms, clear activity flag
|
||||
if (sync_inactive_ctr == '1)
|
||||
sync_active <= 1'b0;
|
||||
else
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -294,8 +294,8 @@ inline int check_linecnt(alt_u8 progressive, alt_u32 totlines) {
|
||||
// Check if input video status / target configuration has changed
|
||||
status_t get_status(tvp_sync_input_t syncinput)
|
||||
{
|
||||
alt_u32 totlines, clkcnt, pcnt_frame;
|
||||
alt_u8 progressive, sync_active, valid_linecnt, hsync_width;
|
||||
alt_u32 totlines, clkcnt, pcnt_field;
|
||||
alt_u8 progressive, sync_active, valid_mode, hsync_width;
|
||||
status_t status = NO_CHANGE;
|
||||
alt_timestamp_type start_ts = alt_timestamp();
|
||||
|
||||
@ -305,34 +305,32 @@ status_t get_status(tvp_sync_input_t syncinput)
|
||||
break;
|
||||
}
|
||||
|
||||
//sync_active = tvp_check_sync(syncinput);
|
||||
sync_active = sc->fe_status.sync_active;
|
||||
|
||||
// Read sync information from TVP7002 frontend
|
||||
sync_active = sc->fe_status.sync_active;
|
||||
totlines = sc->fe_status.vtotal;
|
||||
progressive = !sc->fe_status.interlace_flag;
|
||||
pcnt_frame = (unsigned long)sc->fe_status2.pcnt_frame;
|
||||
pcnt_field = (unsigned long)sc->fe_status2.pcnt_field;
|
||||
hsync_width = (unsigned long)sc->fe_status2.hsync_width;
|
||||
clkcnt = pcnt_frame/(totlines>>!progressive);
|
||||
|
||||
valid_linecnt = check_linecnt(progressive, totlines);
|
||||
clkcnt = pcnt_field/(totlines>>!progressive);
|
||||
valid_mode = (pcnt_field > 0) && check_linecnt(progressive, totlines);
|
||||
|
||||
// Check sync activity
|
||||
if (!cm.sync_active && sync_active && valid_linecnt) {
|
||||
if (!cm.sync_active && sync_active && valid_mode) {
|
||||
cm.sync_active = 1;
|
||||
status = ACTIVITY_CHANGE;
|
||||
} else if (cm.sync_active && (!sync_active || !valid_linecnt)) {
|
||||
} else if (cm.sync_active && (!sync_active || !valid_mode)) {
|
||||
cm.sync_active = 0;
|
||||
status = ACTIVITY_CHANGE;
|
||||
}
|
||||
|
||||
if (valid_linecnt) {
|
||||
if (sync_active && valid_mode) {
|
||||
if ((totlines != cm.totlines) ||
|
||||
(progressive != cm.progressive) ||
|
||||
(pcnt_frame < (cm.pcnt_frame - PCNT_TOLERANCE)) ||
|
||||
(pcnt_frame > (cm.pcnt_frame + PCNT_TOLERANCE)) ||
|
||||
(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)) {
|
||||
printf("totlines: %lu (cur) / %lu (prev), pcnt_frame: %lu (cur) / %lu (prev), hsync_width: %lu (cur) / %lu (prev)\n", totlines, cm.totlines, pcnt_frame, cm.pcnt_frame, hsync_width, cm.hsync_width);
|
||||
printf("totlines: %lu (cur) / %lu (prev), pcnt_field: %lu (cur) / %lu (prev), hsync_width: %lu (cur) / %lu (prev)\n", totlines, cm.totlines, pcnt_field, cm.pcnt_field, hsync_width, cm.hsync_width);
|
||||
|
||||
status = (status < MODE_CHANGE) ? MODE_CHANGE : status;
|
||||
}
|
||||
@ -345,7 +343,7 @@ status_t get_status(tvp_sync_input_t syncinput)
|
||||
|
||||
cm.totlines = totlines;
|
||||
cm.clkcnt = clkcnt;
|
||||
cm.pcnt_frame = pcnt_frame;
|
||||
cm.pcnt_field = pcnt_field;
|
||||
cm.hsync_width = hsync_width;
|
||||
cm.progressive = progressive;
|
||||
}
|
||||
@ -541,8 +539,8 @@ void program_mode()
|
||||
|
||||
memset(&vmode_in, 0, sizeof(mode_data_t));
|
||||
|
||||
vmode_in.timings.v_hz_x100 = (100*27000000UL)/cm.pcnt_frame;
|
||||
h_hz = (100*27000000UL)/((100*cm.pcnt_frame*(1+!cm.progressive))/cm.totlines);
|
||||
vmode_in.timings.v_hz_x100 = (100*27000000UL)/cm.pcnt_field;
|
||||
h_hz = (100*27000000UL)/((100*cm.pcnt_field*(1+!cm.progressive))/cm.totlines);
|
||||
|
||||
printf("\nLines: %u %c\n", (unsigned)cm.totlines, cm.progressive ? 'p' : 'i');
|
||||
printf("Clocks per line: %u\n", (unsigned)cm.clkcnt);
|
||||
@ -941,7 +939,7 @@ int main()
|
||||
printf("### DIY VIDEO DIGITIZER / SCANCONVERTER INIT OK ###\n\n");
|
||||
sniprintf(row1, LCD_ROW_LEN+1, "OSSC fw. %u.%.2u" FW_SUFFIX1 FW_SUFFIX2, FW_VER_MAJOR, FW_VER_MINOR);
|
||||
#ifndef DEBUG
|
||||
strncpy(row2, "2014-2023 marqs", LCD_ROW_LEN+1);
|
||||
strncpy(row2, "2014-2024 marqs", LCD_ROW_LEN+1);
|
||||
#else
|
||||
strncpy(row2, "** DEBUG BUILD *", LCD_ROW_LEN+1);
|
||||
#endif
|
||||
@ -1123,6 +1121,9 @@ int main()
|
||||
auto_input_ctr = 0;
|
||||
auto_input_timestamp = alt_timestamp();
|
||||
}
|
||||
// Avoid detection of initial vsync pulses after auto mode switch
|
||||
if (auto_input_changed)
|
||||
usleep(120000);
|
||||
}
|
||||
|
||||
// Check here to enable regardless of input
|
||||
|
@ -76,7 +76,7 @@ typedef struct {
|
||||
//TODO: transform binary values into flags
|
||||
typedef struct {
|
||||
alt_u32 totlines;
|
||||
alt_u32 pcnt_frame;
|
||||
alt_u32 pcnt_field;
|
||||
alt_u32 hsync_width;
|
||||
alt_u32 clkcnt;
|
||||
alt_u8 progressive;
|
||||
|
@ -185,8 +185,8 @@ int parse_control()
|
||||
case RC_SL_TYPE:
|
||||
tc.sl_type = (tc.sl_type < SL_TYPE_MAX) ? (tc.sl_type + 1) : 0;
|
||||
if (!menu_active) {
|
||||
strncpy((char*)osd->osd_array.data[0][0], menu_scanlines.items[5].name, OSD_CHAR_COLS);
|
||||
strncpy((char*)osd->osd_array.data[1][0], menu_scanlines.items[5].sel.setting_str[tc.sl_type], OSD_CHAR_COLS);
|
||||
strncpy((char*)osd->osd_array.data[0][0], menu_scanlines.items[6].name, OSD_CHAR_COLS);
|
||||
strncpy((char*)osd->osd_array.data[1][0], menu_scanlines.items[6].sel.setting_str[tc.sl_type], OSD_CHAR_COLS);
|
||||
osd->osd_config.status_refresh = 1;
|
||||
osd->osd_row_color.mask = 0;
|
||||
osd->osd_sec_enable[0].mask = 3;
|
||||
@ -265,7 +265,7 @@ int parse_control()
|
||||
set_sampler_phase(video_modes_plm[cm.id].sampler_phase, 1);
|
||||
|
||||
if (!menu_active) {
|
||||
strncpy((char*)osd->osd_array.data[0][0], menu_advtiming.items[8].name, OSD_CHAR_COLS);
|
||||
strncpy((char*)osd->osd_array.data[0][0], menu_advtiming.items[10].name, OSD_CHAR_COLS);
|
||||
sampler_phase_disp(video_modes_plm[cm.id].sampler_phase);
|
||||
strncpy((char*)osd->osd_array.data[1][0], menu_row2, OSD_CHAR_COLS);
|
||||
osd->osd_config.status_refresh = 1;
|
||||
|
@ -304,8 +304,8 @@ void tvp_setup_hpll(alt_u16 h_samplerate, alt_u16 pixs_per_line, alt_u16 refclks
|
||||
}
|
||||
|
||||
cp_current = (40*Kvco[vco_range]+pixs_per_line/2) / pixs_per_line; //"+pixs_per_line/2" for fast rounding
|
||||
if (cp_current > 7)
|
||||
cp_current = 7;
|
||||
if (cp_current > 6)
|
||||
cp_current = 6;
|
||||
|
||||
printf("VCO range: %s\nCPC: %u\n", Kvco_str[vco_range], cp_current);
|
||||
tvp_writereg(TVP_HPLLCTRL, ((vco_range << 6) | (cp_current << 3)));
|
||||
|
Loading…
Reference in New Issue
Block a user