calculate hsync width on FPGA instead of reading TVP7002

This commit is contained in:
marqs 2023-05-14 12:10:20 +03:00
parent de1b441167
commit ab6bd9fc8a
8 changed files with 31 additions and 11 deletions

View File

@ -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;

View File

@ -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),

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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);