From ab6bd9fc8ad012a723825cd8dc5d77af40ce9499 Mon Sep 17 00:00:00 2001 From: marqs Date: Sun, 14 May 2023 12:10:20 +0300 Subject: [PATCH] calculate hsync width on FPGA instead of reading TVP7002 --- ip/sc_config/inc/sc_config_regs.h | 3 ++- rtl/ossc.v | 4 +++- rtl/tvp7002_frontend.v | 6 ++++++ software/sys_controller/ossc/av_controller.c | 16 ++++++++++++---- software/sys_controller/ossc/av_controller.h | 1 + software/sys_controller/ossc/firmware.h | 2 +- software/sys_controller/ossc/userdata.c | 8 ++++---- software/sys_controller/tvp7002/tvp7002.c | 2 ++ 8 files changed, 31 insertions(+), 11 deletions(-) diff --git a/ip/sc_config/inc/sc_config_regs.h b/ip/sc_config/inc/sc_config_regs.h index 3275beb..9521751 100644 --- a/ip/sc_config/inc/sc_config_regs.h +++ b/ip/sc_config/inc/sc_config_regs.h @@ -36,7 +36,8 @@ typedef union { typedef union { struct { uint32_t pcnt_frame:20; - uint16_t fe_rsv:12; + uint8_t hsync_width:8; + uint8_t fe_rsv:4; } __attribute__((packed, __may_alias__)); uint32_t data; } fe_status2_reg; diff --git a/rtl/ossc.v b/rtl/ossc.v index 0ad1e7d..4aee221 100644 --- a/rtl/ossc.v +++ b/rtl/ossc.v @@ -176,6 +176,7 @@ 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 [7:0] TVP_hsync_width; wire [10:0] TVP_fe_vtotal, TVP_fe_xpos, TVP_fe_ypos; tvp7002_frontend u_tvp_frontend ( .PCLK_i(TVP_PCLK_i), @@ -210,6 +211,7 @@ tvp7002_frontend u_tvp_frontend ( .frame_change(TVP_fe_frame_change), .sof_scaler(TVP_sof_scaler), .pcnt_frame(TVP_fe_pcnt_frame), + .hsync_width(TVP_hsync_width), .sync_active(TVP_sync_active) ); @@ -374,7 +376,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 ({12'h0, TVP_fe_pcnt_frame}), + .sc_config_0_sc_if_fe_status2_i ({4'h0, TVP_hsync_width, TVP_fe_pcnt_frame}), .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), diff --git a/rtl/tvp7002_frontend.v b/rtl/tvp7002_frontend.v index 4d89494..8385342 100644 --- a/rtl/tvp7002_frontend.v +++ b/rtl/tvp7002_frontend.v @@ -50,6 +50,7 @@ module tvp7002_frontend ( output reg frame_change, output reg sof_scaler, output reg [19:0] pcnt_frame, + output reg [7:0] hsync_width, output reg sync_active ); @@ -87,6 +88,7 @@ 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 [11:0] pcnt_line, pcnt_line_ctr, meas_h_cnt, meas_h_cnt_sogref; +reg [7:0] hs_ctr; reg pcnt_line_stored; reg [10:0] meas_v_cnt; reg meas_hl_det, meas_fid; @@ -252,14 +254,18 @@ always @(posedge CLK_MEAS_i) begin if (HSYNC_i_np_prev & ~HSYNC_i_np) begin pcnt_line_ctr <= 1; + hs_ctr <= 1; // store count 1ms after vsync if (~pcnt_line_stored & (pcnt_frame_ctr > 21'd27000)) begin pcnt_line <= pcnt_line_ctr; + hsync_width <= hs_ctr; pcnt_line_stored <= 1'b1; end end else begin pcnt_line_ctr <= pcnt_line_ctr + 1'b1; + if (~HSYNC_i_np) + hs_ctr <= hs_ctr + 1'b1; end HSYNC_i_np_prev <= HSYNC_i_np; diff --git a/software/sys_controller/ossc/av_controller.c b/software/sys_controller/ossc/av_controller.c index cc7bfd1..7ab436b 100644 --- a/software/sys_controller/ossc/av_controller.c +++ b/software/sys_controller/ossc/av_controller.c @@ -47,6 +47,7 @@ #define STATUS_TIMEOUT_US 25000 #define PCNT_TOLERANCE 50 +#define HSYNC_WIDTH_TOLERANCE 8 alt_u32 sys_ctrl; @@ -309,7 +310,7 @@ void set_sampler_phase(uint8_t sampler_phase) { status_t get_status(tvp_sync_input_t syncinput) { alt_u32 totlines, clkcnt, pcnt_frame; - alt_u8 progressive, sync_active, valid_linecnt; + alt_u8 progressive, sync_active, valid_linecnt, hsync_width; status_t status = NO_CHANGE; alt_timestamp_type start_ts = alt_timestamp(); @@ -326,6 +327,7 @@ status_t get_status(tvp_sync_input_t syncinput) totlines = sc->fe_status.vtotal; progressive = !sc->fe_status.interlace_flag; pcnt_frame = (unsigned long)sc->fe_status2.pcnt_frame; + hsync_width = (unsigned long)sc->fe_status2.hsync_width; clkcnt = pcnt_frame/(totlines>>!progressive); valid_linecnt = check_linecnt(progressive, totlines); @@ -343,8 +345,10 @@ status_t get_status(tvp_sync_input_t syncinput) if ((totlines != cm.totlines) || (progressive != cm.progressive) || (pcnt_frame < (cm.pcnt_frame - PCNT_TOLERANCE)) || - (pcnt_frame > (cm.pcnt_frame + PCNT_TOLERANCE))) { - printf("totlines: %lu (cur) / %lu (prev), pcnt_frame: %lu (cur) / %lu (prev)\n", totlines, cm.totlines, pcnt_frame, cm.pcnt_frame); + (pcnt_frame > (cm.pcnt_frame + PCNT_TOLERANCE)) || + (hsync_width < (cm.hsync_width - HSYNC_WIDTH_TOLERANCE)) || + (hsync_width > (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); status = (status < MODE_CHANGE) ? MODE_CHANGE : status; } @@ -358,6 +362,7 @@ status_t get_status(tvp_sync_input_t syncinput) cm.totlines = totlines; cm.clkcnt = clkcnt; cm.pcnt_frame = pcnt_frame; + cm.hsync_width = hsync_width; cm.progressive = progressive; } @@ -556,10 +561,13 @@ void program_mode() printf("\nLines: %u %c\n", (unsigned)cm.totlines, cm.progressive ? 'p' : 'i'); printf("Clocks per line: %u\n", (unsigned)cm.clkcnt); - h_syncinlen = tvp_readreg(TVP_HSINWIDTH); + //h_syncinlen = tvp_readreg(TVP_HSINWIDTH); + h_syncinlen = cm.hsync_width; +#ifdef DEBUG v_syncinlen = tvp_readreg(TVP_VSINWIDTH); macrovis = !!(tvp_readreg(TVP_LINECNT2) & (1<<6)); printf("Hswidth: %u Vswidth: %u Macrovision: %u\n", (unsigned)h_syncinlen, (unsigned)(v_syncinlen & 0x1F), (unsigned)macrovis); +#endif vmode_in.timings.h_synclen = h_syncinlen; vmode_in.timings.v_total = cm.totlines; diff --git a/software/sys_controller/ossc/av_controller.h b/software/sys_controller/ossc/av_controller.h index b986f8d..b39aaa9 100644 --- a/software/sys_controller/ossc/av_controller.h +++ b/software/sys_controller/ossc/av_controller.h @@ -77,6 +77,7 @@ typedef struct { typedef struct { alt_u32 totlines; alt_u32 pcnt_frame; + alt_u32 hsync_width; alt_u32 clkcnt; alt_u8 progressive; alt_8 id; diff --git a/software/sys_controller/ossc/firmware.h b/software/sys_controller/ossc/firmware.h index c40459e..f6d78e9 100644 --- a/software/sys_controller/ossc/firmware.h +++ b/software/sys_controller/ossc/firmware.h @@ -24,7 +24,7 @@ #include "sysconfig.h" #define FW_VER_MAJOR 1 -#define FW_VER_MINOR 02 +#define FW_VER_MINOR 03 #define PROFILE_VER_MAJOR 1 #define PROFILE_VER_MINOR 02 diff --git a/software/sys_controller/ossc/userdata.c b/software/sys_controller/ossc/userdata.c index 55d9c6e..be424fb 100644 --- a/software/sys_controller/ossc/userdata.c +++ b/software/sys_controller/ossc/userdata.c @@ -179,7 +179,7 @@ int read_userdata(alt_u8 entry, int dry_run) switch (((ude_hdr*)databuf)->type) { case UDE_INITCFG: if ((((ude_hdr*)databuf)->version_major != INITCFG_VER_MAJOR) || (((ude_hdr*)databuf)->version_minor != INITCFG_VER_MINOR)) { - printf("Initconfig version %u.%u does not match current one\n", ((ude_hdr*)databuf)->version_major, ((ude_hdr*)databuf)->version_minor); + printf("Initconfig version %u.%.2u does not match current one\n", ((ude_hdr*)databuf)->version_major, ((ude_hdr*)databuf)->version_minor); return 2; } if (((ude_initcfg*)databuf)->data_len == sizeof(ude_initcfg) - offsetof(ude_initcfg, last_profile)) { @@ -210,7 +210,7 @@ int read_userdata(alt_u8 entry, int dry_run) break; case UDE_PROFILE: if ((((ude_hdr*)databuf)->version_major != PROFILE_VER_MAJOR) || (((ude_hdr*)databuf)->version_minor != PROFILE_VER_MINOR)) { - printf("Profile version %u.%u does not match current one\n", ((ude_hdr*)databuf)->version_major, ((ude_hdr*)databuf)->version_minor); + printf("Profile version %u.%.2u does not match current one\n", ((ude_hdr*)databuf)->version_major, ((ude_hdr*)databuf)->version_minor); return 2; } if ((((ude_profile*)databuf)->avc_data_len == sizeof(avconfig_t)) && (((ude_profile*)databuf)->vm_data_len == sizeof(video_modes_plm_default))) { @@ -310,10 +310,10 @@ int import_userdata() } if ((header.type == UDE_PROFILE) && ((header.version_major != PROFILE_VER_MAJOR) || (header.version_minor != PROFILE_VER_MINOR))) { - printf("Profile version %u.%u does not match current one\n", header.version_major, header.version_minor); + printf("Profile version %u.%.2u does not match current one\n", header.version_major, header.version_minor); continue; } else if ((header.type == UDE_INITCFG) && ((header.version_major != INITCFG_VER_MAJOR) || (header.version_minor != INITCFG_VER_MINOR))) { - printf("Initconfig version %u.%u does not match current one\n", header.version_major, header.version_minor); + printf("Initconfig version %u.%.2u does not match current one\n", header.version_major, header.version_minor); continue; } else if (header.type > UDE_PROFILE) { printf("Unknown userdata entry type %u\n", header.type); diff --git a/software/sys_controller/tvp7002/tvp7002.c b/software/sys_controller/tvp7002/tvp7002.c index 48093ce..7f9c78b 100644 --- a/software/sys_controller/tvp7002/tvp7002.c +++ b/software/sys_controller/tvp7002/tvp7002.c @@ -91,6 +91,8 @@ static void tvp_set_clamp_alc(video_type type, alt_u8 clamp_ref_offset, alt_8 cl else if (clamp_pos + clamp_width + alc_offset > 255) clamp_pos = 255 - alc_offset - clamp_width; + printf("Clamp pos: %u, width: %u (ref_offset: %u, user_offset %d)\n", clamp_pos, clamp_width, clamp_ref_offset, clamp_user_offset); + tvp_writereg(TVP_CLAMPSTART, (alt_u8)clamp_pos); tvp_writereg(TVP_CLAMPWIDTH, clamp_width);