Clean up TX setup code and add compatibility options

This commit is contained in:
marqs 2017-05-29 20:43:24 +03:00
parent d98c23c8c1
commit 2577470abe
13 changed files with 1019 additions and 1003 deletions

View File

@ -29,11 +29,10 @@ set_input_delay -clock pclk_hdtv -max $TVP_dmax $critinputs
set_input_delay -clock pclk_sdtv -min $TVP_dmin $critinputs -add_delay
set_input_delay -clock pclk_sdtv -max $TVP_dmax $critinputs -add_delay
# output delay constraints (TODO: add vsync)
# output delay constraints (TODO: investigate why adding vsync upsets timing analyzer)
set IT_Tsu 1.0
set IT_Th -0.5
#todo VS
set critoutputs_hdmi {HDMI_TX_RD* HDMI_TX_GD* HDMI_TX_BD* HDMI_TX_DE HDMI_TX_HS}
set critoutputs_hdmi [get_ports {HDMI_TX_RD* HDMI_TX_GD* HDMI_TX_BD* HDMI_TX_DE HDMI_TX_HS}]
set_output_delay -reference_pin HDMI_TX_PCLK -clock pclk_hdtv -min $IT_Th $critoutputs_hdmi
set_output_delay -reference_pin HDMI_TX_PCLK -clock pclk_hdtv -max $IT_Tsu $critoutputs_hdmi
set_output_delay -reference_pin HDMI_TX_PCLK -clock pclk_2x -min $IT_Th $critoutputs_hdmi -add_delay

View File

@ -415,7 +415,13 @@ end
assign h_unstable = (warn_h_unstable != 0);
assign pll_lock_lost = {(warn_pll_lock_lost != 0), (warn_pll_lock_lost_3x != 0)};
//Check if TVP7002 is skipping VSYNCs (occurs with interlace on TTL sync).
//Detect if TVP7002 is skipping VSYNCs. This occurs for interlaced signals fed via digital sync inputs,
//causing TVP7002 not to regenerate VSYNC for field 1. Moreover, if leading edges of HSYNC and VSYNC are
//too far from each other for field 0, no VSYNC is regenerated at all. This can be avoided by disabling
//doubled sampling rates ("AV3 interlacefix") and/or minimizing VSYNC delay induced by RC filter on PCB.
//However, TVP7002 datasheet warns that HSYNC/VSYNC should not change simultaneously, so leaving out the
//filter may lead to stability issues and is not recommended. A combination of 220ohm resistor and 1nF
//capacitor seems to be optimal for 480i/576i, including doubled sampling rates.
always @(posedge clk27 or negedge reset_n)
begin
if (!reset_n) begin

View File

@ -3274,13 +3274,13 @@ DISABLE_MPG_INFOFRM_PKT()
HDMITX_WriteI2C_Byte(REG_TX_MPG_INFOFRM_CTRL,0);
}
void HDMITX_SetPixelRepetition(BYTE pixelrep, BYTE set_infoframe) {
void TX_SetPixelRepetition(BYTE pixelrep, BYTE via_infoframe) {
BYTE pllpr;
Switch_HDMITX_Bank(0);
pllpr = HDMITX_ReadI2C_Byte(REG_TX_CLK_CTRL1) & 0x2F;
if (!set_infoframe)
if (!via_infoframe)
pllpr |= (1<<4)|((pixelrep&0x3)<<6);
HDMITX_WriteI2C_Byte(REG_TX_CLK_CTRL1, pllpr);

View File

@ -834,7 +834,7 @@ BOOL EnableAudioInfoFrame(BYTE bEnable,BYTE *pAudioInfoFrame);
void SetAVMute(BYTE bEnable) ;
void SetOutputColorDepthPhase(BYTE ColorDepth,BYTE bPhase) ;
void Get6613Reg(BYTE *pReg) ;
void HDMITX_SetPixelRepetition(BYTE pixelrep, BYTE set_infoframe);
void TX_SetPixelRepetition(BYTE pixelrep, BYTE via_infoframe);
////////////////////////////////////////////////////////////////////
// Required Interfance

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
//
// Copyright (C) 2015-2016 Markus Hiienkari <mhiienka@niksula.hut.fi>
// Copyright (C) 2015-2017 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
@ -91,10 +91,10 @@ inline void SetupAudio(tx_mode_t mode)
DisableAudioOutput();
EnableAudioInfoFrame(FALSE, NULL);
if (tc.tx_mode == TX_HDMI) {
if (mode == TX_HDMI) {
alt_u32 pclk_out = (TVP_EXTCLK_HZ/cm.clkcnt)*video_modes[cm.id].h_total*cm.sample_mult*(cm.fpga_vmultmode+1);
pclk_out *= 1+cm.hdmitx_pixelrep;
pclk_out *= 1+cm.tx_pixelrep;
printf("PCLK_out: %luHz\n", pclk_out);
EnableAudioOutput4OSSC(pclk_out, tc.audio_dw_sampl, tc.audio_swap_lr);
@ -119,17 +119,19 @@ inline void TX_enable(tx_mode_t mode)
DisableVideoOutput();
EnableAVIInfoFrame(FALSE, NULL);
// re-setup
//Setup TX configuration
//TODO: set pclk target and VIC dynamically
EnableVideoOutput(PCLK_MEDIUM, COLOR_RGB444, COLOR_RGB444, !mode);
//TODO: set VIC based on mode
if (mode == TX_HDMI) {
HDMITX_SetAVIInfoFrame(HDMI_Unkown, 0, 0, tc.hdmi_itc, cm.hdmitx_pixelrep);
HDMITX_SetAVIInfoFrame(HDMI_Unkown, 0, 0, tc.hdmi_itc, cm.hdmitx_pixr_ifr ? cm.tx_pixelrep : 0);
cm.cc.hdmi_itc = tc.hdmi_itc;
#ifdef DIY_AUDIO
SetupAudio(mode);
#endif
}
#ifdef DIY_AUDIO
SetupAudio(mode);
#endif
// start TX
SetAVMute(FALSE);
}
@ -215,7 +217,7 @@ status_t get_status(tvp_input_t input, video_format format)
data2 = tvp_readreg(TVP_CLKCNT2);
clkcnt = ((data2 & 0x0f) << 8) | data1;
// Read how many lines TVP7002 outputs in reality
// Read how many lines TVP7002 outputs in reality (valid only if output enabled)
totlines_tvp = ((IORD_ALTERA_AVALON_PIO_DATA(PIO_2_BASE) >> 18) & 0x7ff)+1;
// NOTE: "progressive" may not have correct value if H-PLL is not locked (!cm.sync_active)
@ -253,7 +255,8 @@ status_t get_status(tvp_input_t input, video_format format)
}
if (valid_linecnt) {
if ((totlines != cm.totlines) || (clkcnt != cm.clkcnt) || (progressive != cm.progressive)) {
// Line count reported in TVP7002 status registers is sometimes +-1 line off and may alternate with correct value. Ignore these events
if ((totlines > cm.totlines+1) || (totlines+1 < cm.totlines) || (clkcnt != cm.clkcnt) || (progressive != cm.progressive)) {
printf("totlines: %lu (cur) / %lu (prev), clkcnt: %lu (cur) / %lu (prev). totlines_tvp: %u, VSM: %u\n", totlines, cm.totlines, clkcnt, cm.clkcnt, totlines_tvp, vsyncmode);
/*if (!cm.sync_active)
act_ctr = 0;*/
@ -274,7 +277,8 @@ status_t get_status(tvp_input_t input, video_format format)
(tc.l4_mode != cm.cc.l4_mode) ||
(tc.l5_mode != cm.cc.l5_mode) ||
(tc.l5_fmt != cm.cc.l5_fmt) ||
(tc.tvp_hpll2x != cm.cc.tvp_hpll2x))
(tc.tvp_hpll2x != cm.cc.tvp_hpll2x) ||
(tc.vga_ilace_fix != cm.cc.vga_ilace_fix))
status = (status < MODE_CHANGE) ? MODE_CHANGE : status;
if ((tc.s480p_mode != cm.cc.s480p_mode) && ((video_modes[cm.id].group == GROUP_DTV480P) || (video_modes[cm.id].group == GROUP_VGA480P)))
@ -507,20 +511,21 @@ void program_mode()
set_lpf(cm.cc.video_lpf);
cm.sample_sel = tvp_set_hpll_phase(cm.cc.sampler_phase, cm.sample_mult);
HDMITX_SetPixelRepetition(cm.hdmitx_pixelrep, (cm.cc.tx_mode==TX_HDMI) ? cm.hdmitx_pixr_ifr : 0);
if (cm.cc.tx_mode==TX_HDMI)
HDMITX_SetAVIInfoFrame(HDMI_Unkown, 0, 0, cm.cc.hdmi_itc, cm.hdmitx_pixr_ifr ? cm.hdmitx_pixelrep : 0);
set_videoinfo();
// TX re-init skipped to minimize mode switch delay
//TX_enable(cm.cc.tx_mode);
TX_SetPixelRepetition(cm.tx_pixelrep, (cm.cc.tx_mode==TX_HDMI) ? cm.hdmitx_pixr_ifr : 0);
// Full TX initialization increases mode switch delay, use only for compatibility
if (cm.cc.full_tx_setup) {
TX_enable(cm.cc.tx_mode);
} else if (cm.cc.tx_mode==TX_HDMI) {
HDMITX_SetAVIInfoFrame(HDMI_Unkown, 0, 0, cm.cc.hdmi_itc, cm.hdmitx_pixr_ifr ? cm.tx_pixelrep : 0);
#ifdef DIY_AUDIO
#ifdef MANUAL_CTS
SetupAudio(cm.cc.tx_mode);
SetupAudio(cm.cc.tx_mode);
#endif
#endif
}
}
void load_profile_disp(alt_u8 code) {
@ -703,8 +708,7 @@ void enable_outputs()
// enable TVP output
tvp_enable_output();
// enable and unmute HDMITX
// TODO: check pclk
// enable and unmute TX
TX_enable(tc.tx_mode);
}
@ -850,7 +854,7 @@ int main()
if ((tc.tx_mode == TX_HDMI) && (tc.hdmi_itc != cm.cc.hdmi_itc)) {
//EnableAVIInfoFrame(FALSE, NULL);
printf("setting ITC to %d\n", tc.hdmi_itc);
HDMITX_SetAVIInfoFrame(0, 0, 0, tc.hdmi_itc, cm.hdmitx_pixelrep);
HDMITX_SetAVIInfoFrame(HDMI_Unkown, 0, 0, tc.hdmi_itc, cm.hdmitx_pixr_ifr ? cm.tx_pixelrep : 0);
cm.cc.hdmi_itc = tc.hdmi_itc;
}

View File

@ -34,9 +34,9 @@
// HDMI_TX definitions
#define HDMITX_MODE_MASK 0x00040000
#define HDMITX_PIXELREP_DISABLE 0
#define HDMITX_PIXELREP_2X 1
#define HDMITX_PIXELREP_4X 2
#define TX_PIXELREP_DISABLE 0
#define TX_PIXELREP_2X 1
#define TX_PIXELREP_4X 3
// FPGA macros
#define FPGA_V_MULTMODE_1X 0
@ -94,7 +94,7 @@ typedef struct {
alt_u8 sync_active;
alt_u8 fpga_vmultmode;
alt_u8 fpga_hmultmode;
alt_u8 hdmitx_pixelrep;
alt_u8 tx_pixelrep;
alt_u8 hdmitx_pixr_ifr;
alt_u8 sample_mult;
alt_u8 sample_sel;

View File

@ -1,5 +1,5 @@
//
// Copyright (C) 2015-2016 Markus Hiienkari <mhiienka@niksula.hut.fi>
// Copyright (C) 2015-2017 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
@ -47,7 +47,6 @@ const avconfig_t tc_default = {
.pm_480i = 1,
.pm_1080i = 1,
.tvp_hpll2x = 1,
.hdmi_itc = 1,
.sampler_phase = DEFAULT_SAMPLER_PHASE,
.sync_vth = DEFAULT_SYNC_VTH,
.linelen_tol = DEFAULT_LINELEN_TOL,

View File

@ -1,5 +1,5 @@
//
// Copyright (C) 2015-2016 Markus Hiienkari <mhiienka@niksula.hut.fi>
// Copyright (C) 2015-2017 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
@ -74,6 +74,8 @@ typedef struct {
alt_u8 video_lpf;
alt_u8 pre_coast;
alt_u8 post_coast;
alt_u8 full_tx_setup;
alt_u8 vga_ilace_fix;
#ifdef DIY_AUDIO
alt_u8 audio_dw_sampl;
alt_u8 audio_swap_lr;

View File

@ -1,5 +1,5 @@
//
// Copyright (C) 2015-2016 Markus Hiienkari <mhiienka@niksula.hut.fi>
// Copyright (C) 2015-2017 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
@ -135,6 +135,11 @@ MENU(menu_postproc, P99_PROTECT({ \
{ LNG("Mask brightness","マスクアカルサ"), OPT_AVCONFIG_NUMVALUE, { .num = { &tc.mask_br, OPT_NOWRAP, 0, HV_MASK_MAX_BR, value_disp } } },
}))
MENU(menu_compatibility, P99_PROTECT({ \
{ "Full TX setup", OPT_AVCONFIG_SELECTION, { .sel = { &tc.full_tx_setup, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ "AV3 interlacefix", OPT_AVCONFIG_SELECTION, { .sel = { &tc.vga_ilace_fix, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
}))
#ifdef DIY_AUDIO
MENU(menu_audio, P99_PROTECT({ \
{ LNG("Down-sampling","ダウンサンプリング"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.audio_dw_sampl, OPT_WRAP, SETTING_ITEM(audio_dw_sampl_desc) } } },
@ -152,6 +157,7 @@ MENU(menu_main, P99_PROTECT({ \
{ LNG("Sync opt. >","ドウキオプション >"), OPT_SUBMENU, { .sub = { &menu_sync, NULL } } },
{ LNG("Output opt. >","シュツリョクオプション >"), OPT_SUBMENU, { .sub = { &menu_output, NULL } } },
{ LNG("Post-proc. >","アトショリ >"), OPT_SUBMENU, { .sub = { &menu_postproc, NULL } } },
{ "Compatibility >", OPT_SUBMENU, { .sub = { &menu_compatibility, NULL } } },
AUDIO_MENU
{ LNG("<Load profile >","<プロファイルロード >"), OPT_SUBMENU, { .sub = { NULL, load_profile_disp } } },
{ LNG("<Save profile >","<プロファイルセーブ >"), OPT_SUBMENU, { .sub = { NULL, save_profile_disp } } },

View File

@ -1,5 +1,5 @@
//
// Copyright (C) 2015-2016 Markus Hiienkari <mhiienka@niksula.hut.fi>
// Copyright (C) 2015-2017 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
@ -80,7 +80,7 @@ alt_8 get_mode_id(alt_u32 totlines, alt_u8 progressive, alt_u32 hz, video_type t
if ((typemask & mode_type) && (target_lm & video_modes[i].flags) && (progressive == !(video_modes[i].flags & MODE_INTERLACED)) && (totlines <= (video_modes[i].v_total+LINECNT_MAX_TOLERANCE))) {
// defaults
cm.hdmitx_pixelrep = HDMITX_PIXELREP_DISABLE;
cm.tx_pixelrep = TX_PIXELREP_DISABLE;
cm.hdmitx_pixr_ifr = 0;
cm.sample_mult = 1;
cm.hsync_cut = 0;
@ -90,21 +90,21 @@ alt_8 get_mode_id(alt_u32 totlines, alt_u8 progressive, alt_u32 hz, video_type t
case MODE_PT:
cm.fpga_vmultmode = FPGA_V_MULTMODE_1X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_FULLWIDTH;
cm.hdmitx_pixelrep = ((video_modes[i].group == GROUP_240P) || (video_modes[i].group == GROUP_480I)) ? HDMITX_PIXELREP_2X : HDMITX_PIXELREP_DISABLE;
cm.hdmitx_pixr_ifr = cm.hdmitx_pixelrep;
cm.tx_pixelrep = ((video_modes[i].group == GROUP_240P) || (video_modes[i].group == GROUP_480I)) ? TX_PIXELREP_2X : TX_PIXELREP_DISABLE;
cm.hdmitx_pixr_ifr = cm.tx_pixelrep;
break;
case MODE_L2:
cm.fpga_vmultmode = FPGA_V_MULTMODE_2X;
if ((video_modes[i].group == GROUP_240P) || (video_modes[i].group == GROUP_384P) || (video_modes[i].group == GROUP_480I)) {
if ((!cm.cc.vga_ilace_fix) && ((video_modes[i].group == GROUP_240P) || (video_modes[i].group == GROUP_384P) || (video_modes[i].group == GROUP_480I))) {
cm.fpga_hmultmode = FPGA_H_MULTMODE_OPTIMIZED;
cm.sample_mult = 2;
} else {
cm.fpga_hmultmode = FPGA_H_MULTMODE_FULLWIDTH;
}
cm.hdmitx_pixelrep = ((video_modes[i].group == GROUP_384P) ||
cm.tx_pixelrep = ((video_modes[i].group == GROUP_384P) ||
(video_modes[i].group == GROUP_DTV480P) ||
(video_modes[i].group == GROUP_VGA480P) ||
((video_modes[i].group == GROUP_1080I) && (video_modes[i].h_total < 1200))) ? HDMITX_PIXELREP_2X : HDMITX_PIXELREP_DISABLE;
((video_modes[i].group == GROUP_1080I) && (video_modes[i].h_total < 1200))) ? TX_PIXELREP_2X : TX_PIXELREP_DISABLE;
break;
case MODE_L2_256_COL:
cm.fpga_vmultmode = FPGA_V_MULTMODE_2X;
@ -120,7 +120,7 @@ alt_8 get_mode_id(alt_u32 totlines, alt_u8 progressive, alt_u32 hz, video_type t
cm.fpga_vmultmode = FPGA_V_MULTMODE_3X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_FULLWIDTH;
if (video_modes[i].group == GROUP_480I)
cm.hdmitx_pixelrep = HDMITX_PIXELREP_2X;
cm.tx_pixelrep = TX_PIXELREP_2X;
break;
case MODE_L3_GEN_4_3:
cm.fpga_vmultmode = FPGA_V_MULTMODE_3X;
@ -140,7 +140,7 @@ alt_8 get_mode_id(alt_u32 totlines, alt_u8 progressive, alt_u32 hz, video_type t
cm.fpga_vmultmode = FPGA_V_MULTMODE_4X;
cm.fpga_hmultmode = FPGA_H_MULTMODE_FULLWIDTH;
if (video_modes[i].group == GROUP_480I)
cm.hdmitx_pixelrep = HDMITX_PIXELREP_2X;
cm.tx_pixelrep = TX_PIXELREP_2X;
break;
case MODE_L4_320_COL:
cm.fpga_vmultmode = FPGA_V_MULTMODE_4X;

View File

@ -1,5 +1,5 @@
//
// Copyright (C) 2015-2016 Markus Hiienkari <mhiienka@niksula.hut.fi>
// Copyright (C) 2015-2017 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
@ -138,7 +138,7 @@ typedef struct {
/* PS2 GSM 960i mode */ \
{ "640x960i", 640, 480, 5994, 800, 1050, 48, 33, 96, 2, (VIDEO_EDTV | VIDEO_PC), GROUP_1080I, (MODE_PT | MODE_L2 | MODE_INTERLACED) }, \
/* 1080i/p HDTV modes */ \
{ "1080i", 1920, 540, 5994, 2200, 1125, 188, 16, 44, 5, VIDEO_HDTV, GROUP_1080I, (MODE_PT | MODE_L2 | MODE_INTERLACED) }, \
{ "1080i", 1920, 540, 5994, 2200, 1125, 188, 16, 44, 5, (VIDEO_HDTV | VIDEO_PC), GROUP_1080I, (MODE_PT | MODE_L2 | MODE_INTERLACED) }, \
{ "1080p", 1920, 1080, 5994, 2200, 1125, 188, 36, 44, 5, VIDEO_HDTV, GROUP_NONE, MODE_PT }, \
{ "1920x1080", 1920, 1080, 6000, 2200, 1125, 148, 36, 44, 5, VIDEO_PC, GROUP_NONE, MODE_PT }, \
/* VESA UXGA with reduced h.backporch */ \

View File

@ -2,8 +2,8 @@
<sch:Settings xmlns:sch="http://www.altera.com/embeddedsw/bsp/schema">
<BspType>hal</BspType>
<BspVersion>default</BspVersion>
<BspGeneratedTimeStamp>May 17, 2017 10:57:24 PM</BspGeneratedTimeStamp>
<BspGeneratedUnixTimeStamp>1495051044048</BspGeneratedUnixTimeStamp>
<BspGeneratedTimeStamp>May 27, 2017 1:39:56 AM</BspGeneratedTimeStamp>
<BspGeneratedUnixTimeStamp>1495838396594</BspGeneratedUnixTimeStamp>
<BspGeneratedLocation>./</BspGeneratedLocation>
<BspSettingsFile>settings.bsp</BspSettingsFile>
<SopcDesignFile>../../sys.sopcinfo</SopcDesignFile>