2016-02-22 23:03:50 +00:00
//
2018-04-12 22:24:34 +00:00
// Copyright (C) 2015-2018 Markus Hiienkari <mhiienka@niksula.hut.fi>
2016-02-22 23:03:50 +00:00
//
// This file is part of Open Source Scan Converter project.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
# include <stdio.h>
# include <unistd.h>
# include "system.h"
# include "altera_avalon_pio_regs.h"
# include "i2c_opencores.h"
# include "tvp7002.h"
2016-03-27 19:40:44 +00:00
//#define SYNCBYPASS // Bypass VGA syncs (for debug - needed for interlace?)
//#define EXTADCCLK // Use external ADC clock (external osc)
//#define ADCPOWERDOWN // Power-down ADCs
//#define PLLPOSTDIV // Double-rate PLL with div-by-2 (decrease jitter?)
2016-02-22 23:03:50 +00:00
/* Y'Pb'Pr' to R'G'B' CSC coefficients.
*
* Coefficients from " Colour Space Conversions " ( http : //www.poynton.com/PDFs/coloureq.pdf).
*/
const ypbpr_to_rgb_csc_t csc_coeffs [ ] = {
2016-03-27 19:40:44 +00:00
{ " Rec. 601 " , 0x2000 , 0x0000 , 0x2CE5 , 0x2000 , 0xF4FD , 0xE926 , 0x2000 , 0x38BC , 0x0000 } , // eq. 101
{ " Rec. 709 " , 0x2000 , 0x0000 , 0x323E , 0x2000 , 0xFA04 , 0xF113 , 0x2000 , 0x3B61 , 0x0000 } , // eq. 105
2016-02-22 23:03:50 +00:00
} ;
2016-10-20 22:19:53 +00:00
static const alt_u8 Kvco [ ] = { 75 , 85 , 150 , 200 } ;
static const char * Kvco_str [ ] = { " Ultra low " , " Low " , " Medium " , " High " } ;
2016-03-27 19:40:44 +00:00
static void tvp_set_clamp ( video_format fmt )
{
2018-04-12 22:24:34 +00:00
alt_u8 status = tvp_readreg ( TVP_SOGTHOLD ) & 0xF8 ;
2016-03-27 19:40:44 +00:00
switch ( fmt ) {
case FORMAT_YPbPr :
//select mid clamp for Pb & Pr
2018-04-12 22:24:34 +00:00
status | = 0x5 ;
2016-03-27 19:40:44 +00:00
break ;
2016-08-20 12:54:28 +00:00
case FORMAT_RGBS :
case FORMAT_RGBHV :
case FORMAT_RGsB :
2016-03-27 19:40:44 +00:00
default :
2016-08-20 12:54:28 +00:00
//select bottom clamp (RGB)
2016-03-27 19:40:44 +00:00
break ;
}
2018-04-12 22:24:34 +00:00
tvp_writereg ( TVP_SOGTHOLD , status ) ;
2016-02-22 23:03:50 +00:00
}
2016-08-22 21:52:46 +00:00
static void tvp_set_clamp_position ( video_type type , alt_u8 h_syncinlen )
2016-03-27 19:40:44 +00:00
{
switch ( type ) {
case VIDEO_LDTV :
2016-08-22 21:52:46 +00:00
tvp_writereg ( TVP_CLAMPSTART , h_syncinlen + 0x2 ) ;
2016-03-27 19:40:44 +00:00
tvp_writereg ( TVP_CLAMPWIDTH , 0x6 ) ;
break ;
case VIDEO_HDTV :
2016-08-22 21:52:46 +00:00
tvp_writereg ( TVP_CLAMPSTART , h_syncinlen + 0x32 ) ;
2016-03-27 19:40:44 +00:00
tvp_writereg ( TVP_CLAMPWIDTH , 0x20 ) ;
break ;
2016-08-20 12:54:28 +00:00
case VIDEO_SDTV :
case VIDEO_EDTV :
case VIDEO_PC :
2016-03-27 19:40:44 +00:00
default :
2016-08-22 21:52:46 +00:00
tvp_writereg ( TVP_CLAMPSTART , h_syncinlen + 0x6 ) ;
2016-08-20 12:54:28 +00:00
tvp_writereg ( TVP_CLAMPWIDTH , 0x10 ) ;
2016-03-27 19:40:44 +00:00
break ;
}
2016-02-22 23:03:50 +00:00
}
2016-03-27 19:40:44 +00:00
inline alt_u32 tvp_readreg ( alt_u32 regaddr )
{
I2C_start ( I2CA_BASE , TVP_BASE , 0 ) ;
I2C_write ( I2CA_BASE , regaddr , 1 ) ; //don't use repeated start as it seems unreliable at 400kHz
I2C_start ( I2CA_BASE , TVP_BASE , 1 ) ;
return I2C_read ( I2CA_BASE , 1 ) ;
2016-02-22 23:03:50 +00:00
}
2016-03-27 19:40:44 +00:00
inline void tvp_writereg ( alt_u32 regaddr , alt_u8 data )
{
I2C_start ( I2CA_BASE , TVP_BASE , 0 ) ;
I2C_write ( I2CA_BASE , regaddr , 0 ) ;
I2C_write ( I2CA_BASE , data , 1 ) ;
2016-02-22 23:03:50 +00:00
}
2016-03-27 19:40:44 +00:00
inline void tvp_reset ( )
{
2016-10-20 22:19:53 +00:00
/*usleep(10000);
2016-03-27 19:40:44 +00:00
IOWR_ALTERA_AVALON_PIO_DATA ( PIO_0_BASE , 0x00 ) ;
usleep ( 10000 ) ;
IOWR_ALTERA_AVALON_PIO_DATA ( PIO_0_BASE , 0x01 ) ;
2016-10-20 22:19:53 +00:00
usleep ( 10000 ) ; */
2016-02-22 23:03:50 +00:00
}
2016-03-27 19:40:44 +00:00
inline void tvp_disable_output ( )
{
2016-05-24 22:06:48 +00:00
alt_u8 syncproc_rst = tvp_readreg ( TVP_MISCCTRL4 ) | ( 1 < < 7 ) ;
2016-03-27 19:40:44 +00:00
tvp_writereg ( TVP_MISCCTRL1 , 0x13 ) ;
usleep ( 10000 ) ;
tvp_writereg ( TVP_MISCCTRL2 , 0x03 ) ;
usleep ( 10000 ) ;
2016-05-24 22:06:48 +00:00
tvp_writereg ( TVP_MISCCTRL4 , syncproc_rst ) ;
usleep ( 1000 ) ;
tvp_writereg ( TVP_MISCCTRL4 , syncproc_rst & 0x7F ) ;
2016-02-22 23:03:50 +00:00
}
2016-03-27 19:40:44 +00:00
inline void tvp_enable_output ( )
{
usleep ( 10000 ) ;
tvp_writereg ( TVP_MISCCTRL1 , 0x11 ) ;
usleep ( 10000 ) ;
tvp_writereg ( TVP_MISCCTRL2 , 0x02 ) ;
usleep ( 10000 ) ;
2016-02-22 23:03:50 +00:00
}
2016-04-15 19:05:53 +00:00
inline void tvp_set_hpllcoast ( alt_u8 pre , alt_u8 post )
{
tvp_writereg ( TVP_HPLLPRECOAST , pre ) ;
tvp_writereg ( TVP_HPLLPOSTCOAST , post ) ;
}
2016-09-05 17:49:41 +00:00
inline void tvp_set_linelen_tol ( alt_u8 val ) {
tvp_writereg ( TVP_LINELENTOL , val ) ;
}
2016-05-23 21:27:50 +00:00
inline void tvp_set_ssthold ( alt_u8 vsdetect_thold )
{
tvp_writereg ( TVP_SSTHOLD , vsdetect_thold ) ;
}
2016-03-27 19:40:44 +00:00
void tvp_init ( )
{
2018-04-12 22:24:34 +00:00
color_setup_t def_gain_offs = {
. r_f_gain = DEFAULT_FINE_GAIN ,
. g_f_gain = DEFAULT_FINE_GAIN ,
. b_f_gain = DEFAULT_FINE_GAIN ,
. r_f_off = DEFAULT_FINE_OFFSET ,
. g_f_off = DEFAULT_FINE_OFFSET ,
. b_f_off = DEFAULT_FINE_OFFSET ,
2018-04-14 09:52:38 +00:00
. c_gain = DEFAULT_COARSE_GAIN ,
2018-04-12 22:24:34 +00:00
} ;
2016-03-27 19:40:44 +00:00
// disable output
tvp_disable_output ( ) ;
2016-02-22 23:03:50 +00:00
2018-04-12 22:24:34 +00:00
// Set default configuration (skip those which match register reset values)
2016-02-22 23:03:50 +00:00
2016-05-23 21:27:50 +00:00
// Configure external refclk
tvp_sel_clk ( REFCLK_EXT27 ) ;
2016-03-27 19:40:44 +00:00
// Hsync input->output delay (horizontal shift)
// Default is 13, which maintains alignment of RGB and hsync at output
//tvp_writereg(TVP_HSOUTSTART, 0);
2016-02-22 23:03:50 +00:00
2016-03-27 19:40:44 +00:00
// Hsync edge->Vsync edge delay
2017-05-09 15:55:24 +00:00
// NOTE: Value 1 syncs the edges!
tvp_writereg ( TVP_VSOUTALIGN , 1 ) ;
2016-02-22 23:03:50 +00:00
2016-03-27 19:40:44 +00:00
// Set default CSC coeffs.
tvp_sel_csc ( & csc_coeffs [ 0 ] ) ;
2016-02-22 23:03:50 +00:00
2016-03-27 19:40:44 +00:00
// Set default phase
2018-04-12 22:24:34 +00:00
//tvp_set_hpll_phase(DEFAULT_SAMPLER_PHASE, 1);
2016-02-22 23:03:50 +00:00
2018-04-12 22:24:34 +00:00
// Set min video LPF, max sync LPF
//tvp_set_lpf(0);
tvp_set_sync_lpf ( DEFAULT_SYNC_LPF ) ;
2016-02-22 23:03:50 +00:00
2016-03-27 19:40:44 +00:00
// Increase line length tolerance
2016-09-05 17:49:41 +00:00
tvp_set_linelen_tol ( DEFAULT_LINELEN_TOL ) ;
2016-02-22 23:03:50 +00:00
2016-08-22 21:52:46 +00:00
// Use HSYNC leading edge as fine clamp reference
// Allows minimizing HSYNC window
2016-08-23 16:24:22 +00:00
// Does not work properly for some reason, but is not critical as reference is at most LEADEDGE+MVSWIDTH
2016-08-22 21:52:46 +00:00
//tvp_writereg(TVP_OUTFORMAT, 0x0C);
2016-08-20 12:54:28 +00:00
// Minimize HSYNC window for best sync stability
2018-04-12 22:24:34 +00:00
//tvp_writereg(TVP_MVSWIDTH, 0x03);
2016-08-20 12:54:28 +00:00
2016-03-27 19:40:44 +00:00
// Common sync separator threshold
2016-02-22 23:03:50 +00:00
// Some arcade games need more that the default 0x40
2016-05-23 21:27:50 +00:00
tvp_set_ssthold ( DEFAULT_VSYNC_THOLD ) ;
2016-04-10 18:39:46 +00:00
2018-04-12 22:24:34 +00:00
// Analog sync/SoG thresholf
//tvp_set_sog_thold(DEFAULT_SYNC_VTH);
// Default (3,3) coast may lead to PLL jitter and sync loss (e.g. SNES)
tvp_set_hpllcoast ( DEFAULT_PRE_COAST , DEFAULT_POST_COAST ) ;
2016-04-10 18:39:46 +00:00
//set analog (coarse) gain to max recommended value (-> 91% of the ADC range with 0.7Vpp input)
//set rest of the gain digitally (fine) to utilize 100% of the range at the output (0.91*(1+(26/256)) = 1)
2018-04-14 09:52:38 +00:00
tvp_set_gain_offset ( & def_gain_offs ) ;
2016-08-20 12:54:28 +00:00
}
2018-04-14 09:52:38 +00:00
void tvp_set_gain_offset ( color_setup_t * col ) {
tvp_writereg ( TVP_BG_CGAIN , ( ( col - > c_gain < < 4 ) | ( col - > c_gain & 0xF ) ) ) ;
tvp_writereg ( TVP_R_CGAIN , col - > c_gain ) ;
2016-08-20 12:54:28 +00:00
tvp_writereg ( TVP_R_FGAIN , col - > r_f_gain ) ;
tvp_writereg ( TVP_G_FGAIN , col - > g_f_gain ) ;
tvp_writereg ( TVP_B_FGAIN , col - > b_f_gain ) ;
tvp_writereg ( TVP_R_FOFFSET_MSB , col - > r_f_off ) ;
tvp_writereg ( TVP_G_FOFFSET_MSB , col - > g_f_off ) ;
tvp_writereg ( TVP_B_FOFFSET_MSB , col - > b_f_off ) ;
2018-04-14 09:52:38 +00:00
2016-02-22 23:03:50 +00:00
}
// Configure H-PLL (sampling rate, VCO gain and charge pump current)
2017-02-07 21:04:30 +00:00
void tvp_setup_hpll ( alt_u16 h_samplerate , alt_u16 refclks_per_line , alt_u8 plldivby2 )
2016-03-27 19:40:44 +00:00
{
alt_u32 pclk_est ;
alt_u8 vco_range ;
alt_u8 cp_current ;
alt_u8 status = tvp_readreg ( TVP_HPLLPHASE ) & 0xF8 ;
// Enable PLL post-div-by-2 with double samplerate
2017-02-07 21:04:30 +00:00
if ( plldivby2 & & ( h_samplerate < 2048 ) ) {
2016-03-27 19:40:44 +00:00
tvp_writereg ( TVP_HPLLPHASE , status | 1 ) ;
h_samplerate = 2 * h_samplerate ;
} else {
tvp_writereg ( TVP_HPLLPHASE , status ) ;
}
tvp_writereg ( TVP_HPLLDIV_MSB , ( h_samplerate > > 4 ) ) ;
tvp_writereg ( TVP_HPLLDIV_LSB , ( ( h_samplerate & 0xf ) < < 4 ) ) ;
printf ( " Horizontal samplerate set to %u \n " , h_samplerate ) ;
2017-02-07 21:04:30 +00:00
pclk_est = ( ( alt_u32 ) h_samplerate * ( TVP_EXTCLK_HZ / ( alt_u32 ) refclks_per_line ) ) / 1000 ; //in kHz
2016-03-27 19:40:44 +00:00
2016-11-06 13:24:26 +00:00
printf ( " Estimated PCLK_HPLL: %lu.%.3lu MHz \n " , pclk_est / 1000 , pclk_est % 1000 ) ;
2016-03-27 19:40:44 +00:00
if ( pclk_est < 36000 ) {
vco_range = 0 ;
} else if ( pclk_est < 70000 ) {
vco_range = 1 ;
} else if ( pclk_est < 135000 ) {
vco_range = 2 ;
} else {
vco_range = 3 ;
}
cp_current = ( 40 * Kvco [ vco_range ] + h_samplerate / 2 ) / h_samplerate ; //"+h_samplerate/2" for fast rounding
if ( cp_current > 7 )
cp_current = 7 ;
printf ( " VCO range: %s \n CPC: %u \n " , Kvco_str [ vco_range ] , cp_current ) ;
tvp_writereg ( TVP_HPLLCTRL , ( ( vco_range < < 6 ) | ( cp_current < < 3 ) ) ) ;
2016-02-22 23:03:50 +00:00
}
2016-10-20 22:19:53 +00:00
void tvp_sel_clk ( tvp_refclk_t refclk )
2016-03-27 19:40:44 +00:00
{
alt_u8 status = tvp_readreg ( TVP_INPMUX2 ) & 0xFA ;
2016-02-22 23:03:50 +00:00
2016-03-27 19:40:44 +00:00
//TODO: set SOG and CLP LPF based on mode
if ( refclk = = REFCLK_INTCLK ) {
tvp_writereg ( TVP_INPMUX2 , status | 0x2 ) ;
} else {
2016-02-22 23:03:50 +00:00
# ifdef EXTADCCLK
2016-03-27 19:40:44 +00:00
tvp_writereg ( TVP_INPMUX2 , status | 0x8 ) ;
2016-02-22 23:03:50 +00:00
# else
2016-03-27 19:40:44 +00:00
tvp_writereg ( TVP_INPMUX2 , status | 0xA ) ;
2016-02-22 23:03:50 +00:00
# endif
2016-03-27 19:40:44 +00:00
}
}
2016-06-12 20:43:24 +00:00
void tvp_sel_csc ( const ypbpr_to_rgb_csc_t * csc )
2016-03-27 19:40:44 +00:00
{
tvp_writereg ( TVP_CSC1HI , ( csc - > G_Y > > 8 ) ) ;
tvp_writereg ( TVP_CSC1LO , ( csc - > G_Y & 0xff ) ) ;
tvp_writereg ( TVP_CSC2HI , ( csc - > G_Pb > > 8 ) ) ;
tvp_writereg ( TVP_CSC2LO , ( csc - > G_Pb & 0xff ) ) ;
tvp_writereg ( TVP_CSC3HI , ( csc - > G_Pr > > 8 ) ) ;
tvp_writereg ( TVP_CSC3LO , ( csc - > G_Pr & 0xff ) ) ;
tvp_writereg ( TVP_CSC4HI , ( csc - > R_Y > > 8 ) ) ;
tvp_writereg ( TVP_CSC4LO , ( csc - > R_Y & 0xff ) ) ;
tvp_writereg ( TVP_CSC5HI , ( csc - > R_Pb > > 8 ) ) ;
tvp_writereg ( TVP_CSC5LO , ( csc - > R_Pb & 0xff ) ) ;
tvp_writereg ( TVP_CSC6HI , ( csc - > R_Pr > > 8 ) ) ;
tvp_writereg ( TVP_CSC6LO , ( csc - > R_Pr & 0xff ) ) ;
tvp_writereg ( TVP_CSC7HI , ( csc - > B_Y > > 8 ) ) ;
tvp_writereg ( TVP_CSC7LO , ( csc - > B_Y & 0xff ) ) ;
tvp_writereg ( TVP_CSC8HI , ( csc - > B_Pb > > 8 ) ) ;
tvp_writereg ( TVP_CSC8LO , ( csc - > B_Pb & 0xff ) ) ;
tvp_writereg ( TVP_CSC9HI , ( csc - > B_Pr > > 8 ) ) ;
tvp_writereg ( TVP_CSC9LO , ( csc - > B_Pr & 0xff ) ) ;
2016-02-22 23:03:50 +00:00
}
2016-03-27 19:40:44 +00:00
void tvp_set_lpf ( alt_u8 val )
{
alt_u8 status = tvp_readreg ( TVP_VIDEOBWLIM ) & 0xF0 ;
tvp_writereg ( TVP_VIDEOBWLIM , status | val ) ;
printf ( " TVP LPF value set to 0x%x \n " , val ) ;
2016-02-22 23:03:50 +00:00
}
2016-03-27 19:40:44 +00:00
void tvp_set_sync_lpf ( alt_u8 val )
{
alt_u8 status = tvp_readreg ( TVP_INPMUX2 ) & 0x3F ;
2018-04-12 22:24:34 +00:00
tvp_writereg ( TVP_INPMUX2 , status | ( val < < 6 ) ) ;
printf ( " Sync LPF value set to 0x%x \n " , val ) ;
2016-02-22 23:03:50 +00:00
}
2017-01-22 22:56:17 +00:00
alt_u8 tvp_set_hpll_phase ( alt_u8 val , alt_u8 sample_mult )
2016-03-27 19:40:44 +00:00
{
2017-01-22 22:56:17 +00:00
alt_u8 sample_sel ;
2016-03-27 19:40:44 +00:00
alt_u8 status = tvp_readreg ( TVP_HPLLPHASE ) & 0x07 ;
2017-01-22 22:56:17 +00:00
sample_sel = ( val * sample_mult ) / 32 ;
val = val * sample_mult % 32 ;
2016-03-27 19:40:44 +00:00
tvp_writereg ( TVP_HPLLPHASE , ( val < < 3 ) | status ) ;
2017-01-22 22:56:17 +00:00
printf ( " Phase selection: %u/%u (FPGA), %u/32 (TVP) \n " , sample_sel + 1 , sample_mult , val + 1 ) ;
return sample_sel ;
2016-02-22 23:03:50 +00:00
}
2016-03-27 19:40:44 +00:00
void tvp_set_sog_thold ( alt_u8 val )
{
alt_u8 status = tvp_readreg ( TVP_SOGTHOLD ) & 0x07 ;
tvp_writereg ( TVP_SOGTHOLD , ( val < < 3 ) | status ) ;
printf ( " SOG thold set to 0x%x \n " , val ) ;
2016-02-22 23:03:50 +00:00
}
2016-08-22 21:52:46 +00:00
void tvp_set_alc ( alt_u8 en_alc , video_type type , alt_u8 h_syncinlen )
2016-04-14 10:39:49 +00:00
{
if ( en_alc ) {
tvp_writereg ( TVP_ALCEN , 0x80 ) ; //enable ALC
//select ALC placement
switch ( type ) {
case VIDEO_LDTV :
2016-08-22 21:52:46 +00:00
tvp_writereg ( TVP_ALCPLACE , h_syncinlen + 0x9 ) ;
2016-04-14 10:39:49 +00:00
break ;
case VIDEO_HDTV :
2016-08-22 21:52:46 +00:00
tvp_writereg ( TVP_ALCPLACE , h_syncinlen + 0x5A ) ;
2016-04-14 10:39:49 +00:00
break ;
2016-08-20 12:54:28 +00:00
case VIDEO_SDTV :
case VIDEO_EDTV :
case VIDEO_PC :
2016-04-14 10:39:49 +00:00
default :
2016-08-22 21:52:46 +00:00
tvp_writereg ( TVP_ALCPLACE , h_syncinlen + 0x18 ) ;
2016-04-14 10:39:49 +00:00
break ;
}
} else {
tvp_writereg ( TVP_ALCEN , 0x00 ) ; //disable ALC
}
}
2018-04-12 22:24:34 +00:00
void tvp_source_setup ( video_type type , alt_u16 h_samplerate , alt_u16 refclks_per_line , alt_u8 plldivby2 , alt_u8 h_syncinlen )
2016-03-27 19:40:44 +00:00
{
2016-08-20 12:54:28 +00:00
// Clamp position and ALC
2016-08-22 21:52:46 +00:00
tvp_set_clamp_position ( type , h_syncinlen ) ;
tvp_set_alc ( 1 , type , h_syncinlen ) ;
2016-08-20 12:54:28 +00:00
2016-09-05 17:49:41 +00:00
// Setup Macrovision stripper and H-PLL coast signal.
// Coast needs to be enabled when HSYNC is missing during VSYNC. RGBHV mode cannot use it, so turn off the internal signal for this mode.
2016-08-14 15:57:50 +00:00
// Macrovision stripper filters out glitches and serration pulses that may occur outside of sync window (HSYNC_lead +- TVP_MVSWIDTH*37ns). Enabled for all inputs.
2016-03-27 19:40:44 +00:00
switch ( type ) {
case VIDEO_PC :
tvp_writereg ( TVP_MISCCTRL4 , 0x0C ) ;
2016-08-14 15:57:50 +00:00
break ;
2016-03-27 19:40:44 +00:00
case VIDEO_LDTV :
case VIDEO_SDTV :
2016-08-20 12:54:28 +00:00
case VIDEO_EDTV :
case VIDEO_HDTV :
2016-03-27 19:40:44 +00:00
default :
2016-08-20 12:54:28 +00:00
tvp_writereg ( TVP_MISCCTRL4 , 0x08 ) ;
2016-03-27 19:40:44 +00:00
break ;
}
2017-02-07 21:04:30 +00:00
tvp_setup_hpll ( h_samplerate , refclks_per_line , plldivby2 ) ;
2016-02-22 23:03:50 +00:00
}
2016-05-23 21:27:50 +00:00
void tvp_source_sel ( tvp_input_t input , video_format fmt )
2016-03-27 19:40:44 +00:00
{
alt_u8 sync_status ;
alt_u8 sog_ch ;
2016-02-22 23:03:50 +00:00
2016-03-27 19:40:44 +00:00
if ( ( fmt = = FORMAT_RGsB ) | | ( fmt = = FORMAT_YPbPr ) )
2016-02-22 23:03:50 +00:00
sog_ch = ( input = = TVP_INPUT3 ) ? 2 : 0 ;
2016-03-27 19:40:44 +00:00
else if ( ( input = = TVP_INPUT1 ) & & ( fmt = = FORMAT_RGBS ) )
sog_ch = 1 ;
else
sog_ch = 2 ;
// RGB+SOG input select
tvp_writereg ( TVP_INPMUX1 , ( sog_ch < < 6 ) | ( input < < 4 ) | ( input < < 2 ) | input ) ;
// Clamp setup
tvp_set_clamp ( fmt ) ;
// HV/SOG sync select
2016-05-23 21:27:50 +00:00
if ( ( input = = TVP_INPUT3 ) & & ( ( fmt = = FORMAT_RGBHV ) | | ( fmt = = FORMAT_RGBS ) ) ) {
2016-03-27 19:40:44 +00:00
if ( fmt = = FORMAT_RGBHV )
tvp_writereg ( TVP_SYNCCTRL1 , 0x52 ) ;
else // RGBS
tvp_writereg ( TVP_SYNCCTRL1 , 0x53 ) ;
2016-06-22 20:22:59 +00:00
usleep ( 1000 ) ;
2016-03-27 19:40:44 +00:00
sync_status = tvp_readreg ( TVP_SYNCSTAT ) ;
if ( sync_status & ( 1 < < 7 ) )
printf ( " %s detected, %s polarity \n " , ( sync_status & ( 1 < < 3 ) ) ? " Csync " : " Hsync " , ( sync_status & ( 1 < < 5 ) ) ? " pos " : " neg " ) ;
if ( sync_status & ( 1 < < 4 ) )
printf ( " Vsync detected, %s polarity \n " , ( sync_status & ( 1 < < 2 ) ) ? " pos " : " neg " ) ;
} else {
tvp_writereg ( TVP_SYNCCTRL1 , 0x5B ) ;
2016-06-22 20:22:59 +00:00
usleep ( 1000 ) ;
2016-03-27 19:40:44 +00:00
sync_status = tvp_readreg ( TVP_SYNCSTAT ) ;
if ( sync_status & ( 1 < < 1 ) )
printf ( " SOG detected \n " ) ;
else
printf ( " SOG not detected \n " ) ;
}
// Enable CSC for YPbPr
if ( fmt = = FORMAT_YPbPr )
tvp_writereg ( TVP_MISCCTRL3 , 0x10 ) ;
else
tvp_writereg ( TVP_MISCCTRL3 , 0x00 ) ;
# ifdef SYNCBYPASS
tvp_writereg ( TVP_SYNCBYPASS , 0x03 ) ;
# else
tvp_writereg ( TVP_SYNCBYPASS , 0x00 ) ;
# endif
//TODO:
//TVP_ADCSETUP
printf ( " \n " ) ;
2016-02-22 23:03:50 +00:00
}
2016-05-23 21:27:50 +00:00
alt_u8 tvp_check_sync ( tvp_input_t input , video_format fmt )
2016-03-27 19:40:44 +00:00
{
alt_u8 sync_status ;
2016-02-22 23:03:50 +00:00
2016-03-27 19:40:44 +00:00
sync_status = tvp_readreg ( TVP_SYNCSTAT ) ;
2016-02-22 23:03:50 +00:00
2016-05-23 21:27:50 +00:00
if ( ( input = = TVP_INPUT3 ) & & ( fmt = = FORMAT_RGBHV ) )
return ( ( sync_status & 0x90 ) = = 0x90 ) ;
else if ( ( input = = TVP_INPUT3 ) & & ( fmt = = FORMAT_RGBS ) )
return ( ( sync_status & 0x88 ) = = 0x88 ) ;
2016-03-27 19:40:44 +00:00
else
return ! ! ( sync_status & ( 1 < < 1 ) ) ;
2016-02-22 23:03:50 +00:00
}