/*********************************************************************************

Copyright(c) 2006 Analog Devices, Inc. All Rights Reserved.

This software is proprietary and confidential.  By using this software you agree
to the terms of the associated Analog Devices License Agreement.

*********************************************************************************/

			
/********** MACROS ************************************************************************/
#define USE_CIRCULAR_BUFFER
//#define PAL_FRAME
/*********************************************************************

Include files

*********************************************************************/
#include <drivers/adi_dev.h>			// Device manager includes
#include <drivers/decoder/adi_adv7183.h>		// AD7183 device driver includes
#include <drivers/encoder/adi_adv717x.h>		// ADV7171 device driver includes
#include <drivers/twi/adi_twi.h>			// TWI device driver includes
#include <SDK-ezkitutilities.h>
#include <adi_ssl_Init.h>
#include <stdio.h>

/*****************************************************************************

Static data

*****************************************************************************/
#define	PAL		1
#define NTSC	0

#if defined(PAL_FRAME)
#define FRAME_DATA_LEN	1728		// Data length per line for PAL video format
#define NUM_LINES		625			// Number of lines per frame    
#define ACTIVE_FIELD1   22			// Line number of first active field1
#define ACTIVE_FIELD2   335			// Line number of first active field2
#define HORIZONTAL_BLANKING 72		// Width (32bits) of horizontal blanking
#define NUM_LINES_ACTIVE	288		// Number of active lines per frame    

#else   // its NTSC Frame
#define FRAME_DATA_LEN	1716		// Data length per line for NTSC format
#define NUM_LINES		525			// Number of lines per frame    
#define ACTIVE_FIELD1   19			// Line number of first active field1
#define ACTIVE_FIELD2   282			// Line number of first active field2
#define HORIZONTAL_BLANKING 69		// Width (32bits) of horizontal blanking
#define NUM_LINES_ACTIVE 240			// Number of active lines per frame    
#endif 

#define FRAME_SIZE	FRAME_DATA_LEN*NUM_LINES
#define FRAME_DATA_LEN_32BIT FRAME_DATA_LEN/4

// Define the DMA buffer for one video frame.
section("sdram0") static char sFrame0[FRAME_SIZE];

#ifdef USE_CIRCULAR_BUFFER
// buffer for input/output.
static ADI_DEV_CIRCULAR_BUFFER CircBuffer;
#else
	ADI_DEV_2D_BUFFER Buffer2D; 
#endif
	

// storage for critical region
static ADI_INT_CRITICAL_REGION_DATA	CriticalRegionData;	
		
/*********************************************************************

handles to device drivers

*********************************************************************/
ADI_DEV_DEVICE_HANDLE AD7183DriverHandle;// handle to the ad7183 driver
ADI_DEV_DEVICE_HANDLE EncoderDriverHandle;// handle to the ad7171 driver

/*********************************************************************

static function prototypes

*********************************************************************/
static void InitSystemServices(void);

static void SetEncoderMode(ADI_DEV_DEVICE_HANDLE EncoderDevHandle, u32 mode);	
static void Read7183StatusReg(ADI_DEV_DEVICE_HANDLE AD7183DevHandler);	
static void ReadEncoderRegs(ADI_DEV_DEVICE_HANDLE EncoderDevHandler);	

static void DisplayVideoFrame(
	ADI_DEV_MANAGER_HANDLE 	DeviceManagerHandle,
	ADI_DMA_MANAGER_HANDLE 	DMAManagerHandle );
	
static void CaptureVideoFrame(
	ADI_DEV_MANAGER_HANDLE 	DeviceManagerHandle,
	ADI_DMA_MANAGER_HANDLE 	DMAManagerHandle );

static void PrepareBuffer(void);


static ADI_INT_HANDLER(ExceptionHandler);	// exception handler
static ADI_INT_HANDLER(HWErrorHandler);		// hardware error handler
static void ClientCallback(void *AppHandle,u32  Event,void *pArg);

static void CopyField2ToField1(void);

volatile bool FrameReady = FALSE;


// Pseudo TWI Configuration 
#if defined(__ADSP_TETON__)
// Pseudo TWI will be used to access ADV7183 and ADV7179 registers.
// BF561 Ports (PF0=SCL,PF1=SDA) & Timer(Timer 3) used for Pseudo TWI
adi_twi_pseudo_port TWIPseudo= {ADI_FLAG_PF0,ADI_FLAG_PF1,ADI_TMR_GP_TIMER_3,(ADI_INT_PERIPHERAL_ID)NULL};
#else
// Pseudo TWI will be used to access ADV7183 and ADV7171 registers.
// BF533 Ports (PF0=SCL,PF1=SDA) & Timer(Timer 1) used for Pseudo TWI
adi_twi_pseudo_port TWIPseudo= {ADI_FLAG_PF0,ADI_FLAG_PF1,ADI_TMR_GP_TIMER_0,(ADI_INT_PERIPHERAL_ID)NULL};
#endif
	ADI_DEV_CMD_VALUE_PAIR PseudoTWIConfig[]={
	{ADI_TWI_CMD_SET_PSEUDO,(void *)(&TWIPseudo)},
	{ADI_DEV_CMD_SET_DATAFLOW_METHOD,(void *)ADI_DEV_MODE_SEQ_CHAINED},
	{ADI_DEV_CMD_SET_DATAFLOW,(void *)TRUE},
	{ADI_DEV_CMD_END,NULL}
	};


/*********************************************************************
*
*	Function:	main
*	Description:	Using the AD7183 and AD7179 device drivers,this
	                program demonstrates a simple video display program.
			A single frame video data is captured into SDRAM from the AD7183 decoder,
			then output through AD7179 encoder continuosly.
			When first push button is pressed, a new video data is captured.
			In this example,no processing is done on the video data.
*********************************************************************/
void main(void)
{
    

	unsigned int i;	
	

	// initialize the system services
	InitSystemServices();

	
	// enable all LED's
	for(i=0;i<EZ_NUM_LEDS;i++){
		ezInitLED(i);
	}
	
	// enable the first push button(SW4)
	ezInitButton(EZ_FIRST_BUTTON);
	
	// enable the last push button(SW7)
	ezInitButton(EZ_LAST_BUTTON);
	
	
	ezTurnOffAllLEDs();

 	// prepare input/output buffers
 	PrepareBuffer();
	

	// capture the first video frame
	CaptureVideoFrame(adi_dev_ManagerHandle, adi_dma_ManagerHandle);
	
	// and display the first video frame continuosly
	DisplayVideoFrame( adi_dev_ManagerHandle, adi_dma_ManagerHandle);


	// keep going ..........
	// to exit this program push last button(SW7)
    while (ezIsButtonPushed(EZ_LAST_BUTTON) == FALSE){
    
        // capture a new frame of video if first button(SW4) is push
        if(ezIsButtonPushed(EZ_FIRST_BUTTON) == TRUE){
            
            // stop displaying video
			ezErrorCheck(adi_dev_Close(EncoderDriverHandle));
			ezTurnOffLED(0);

            // capture a new video frame
			CaptureVideoFrame( adi_dev_ManagerHandle, adi_dma_ManagerHandle);
		
			// display the video frame.
			DisplayVideoFrame( adi_dev_ManagerHandle, adi_dma_ManagerHandle);
        }
    }

   ezTurnOnAllLEDs();

	// close the Device Manager
	ezErrorCheck(adi_dev_Terminate(adi_dev_ManagerHandle));
	
	// close down the DMA Manager
	ezErrorCheck(adi_dma_Terminate(adi_dma_ManagerHandle));

	
			
}




/*********************************************************************

	Function:		InitSystemServices

	Description:	Initializes the necessary system services.  

*********************************************************************/

static void InitSystemServices(void) {
    

    // initialize the ezKit power,EBIU,DMA....
	adi_ssl_Init();	
	
	
	// enable and configure async memory
	ezInit(1);

    ezErrorCheck(adi_int_CECHook(3, ExceptionHandler, NULL, FALSE));
	ezErrorCheck(adi_int_CECHook(5, HWErrorHandler, NULL, FALSE));
                 
	
	// return
}


/*********************************************************************

    Function:       PrepareBuffer
    Description:    Prepares Video-In buffer for ADV7183 and 
    				Video-Out buffer for ADV7171(BF533) or ADV7179(BF561)

*********************************************************************/
static void PrepareBuffer(void){
  
#if defined(__ADSP_EDINBURGH__)         // the Edinburgh EZ-Kit uses a flash for ports
      
	// populate the buffers that we'll use for the PPI input and output
#ifdef	USE_CIRCULAR_BUFFER	
	CircBuffer.Data = (void*)sFrame0;
	CircBuffer.SubBufferCount = NUM_LINES;
    CircBuffer.SubBufferElementCount = (FRAME_DATA_LEN/2);
	CircBuffer.ElementWidth = 2;
	CircBuffer.CallbackType = ADI_DEV_CIRC_FULL_BUFFER;
	CircBuffer.pAdditionalInfo	= NULL;
#else
	Buffer2D.Data = (void*)sFrame0;
	Buffer2D.ElementWidth = 2;
	Buffer2D.XCount = (FRAME_DATA_LEN/2);
	Buffer2D.XModify = 2;
	Buffer2D.YCount = NUM_LINES;
	Buffer2D.YModify = 2;
	Buffer2D.CallbackParameter = &Buffer2D;
	Buffer2D.pNext = NULL;
#endif	

#endif

#if defined(__ADSP_TETON__)

#ifdef	USE_CIRCULAR_BUFFER	
	CircBuffer.Data = (void*)sFrame0;
	CircBuffer.SubBufferCount = NUM_LINES;
    CircBuffer.SubBufferElementCount = (FRAME_DATA_LEN/4);
	CircBuffer.ElementWidth = 4;
	CircBuffer.CallbackType = ADI_DEV_CIRC_FULL_BUFFER;
	CircBuffer.pAdditionalInfo	= NULL;
#else
	Buffer2D.Data = (void*)sFrame0;
	Buffer2D.ElementWidth = 4;
	Buffer2D.XCount = (FRAME_DATA_LEN/4);
	Buffer2D.XModify = 4;
	Buffer2D.YCount = NUM_LINES;
	Buffer2D.YModify = 4;
	Buffer2D.CallbackParameter = &Buffer2D;
	Buffer2D.pNext = NULL;
#endif	

#endif

}


/*********************************************************************

	Function:		ExceptionHandler
					HWErrorHandler

	Description:	We should never get an exception or hardware error,
					but just in case we'll catch them and simply turn
					on all the LEDS should one ever occur.

*********************************************************************/

static ADI_INT_HANDLER(ExceptionHandler)	// exception handler
{
	         // turn on all LEDs and wait for help
            ezTurnOnAllLEDs();

	return(ADI_INT_RESULT_PROCESSED);
}

static ADI_INT_HANDLER(HWErrorHandler)		// hardware error handler
{
	         // turn on all LEDs and wait for help
            ezTurnOnAllLEDs();

	return(ADI_INT_RESULT_PROCESSED);
}


/*********************************************************************

	Function:		ClientCallback

	Description:	Each type of callback event has it's own unique ID
					so we can use a single callback function for all
					callback events.  The switch statement tells us
					which event has occurred.

					Note that in the device driver model, in order to 
					generate a callback for buffer completion, the 
					CallbackParameter of the buffer must be set to a non-NULL 
					value.
   
*********************************************************************/

static void ClientCallback(
	void *AppHandle,
	u32  Event,
	void *pArg)
{

	switch (Event)
	{
		// CASE (DMA buffer processed)
        	case ADI_DEV_EVENT_BUFFER_PROCESSED:
        	      	
    	    if (AppHandle == (void *)0x7183) {
        		FrameReady = TRUE;
    	    }
            break;
		
		
	}

}





/*********************************************************************

	Function:		CaptureVideoFrame

	Description:	This function is called to capture a frame of video
			data using ADV7183 device driver.  
			This function first enables the AD7183 video
			decoder and gives it time to sync. 
			After the buffer has been processed, meaning the 
			frame of video data has been captured in SDRAM, the 
			ADV7183 driver is closed and the function returns to the
			caller.

*********************************************************************/

static void CaptureVideoFrame(
	ADI_DEV_MANAGER_HANDLE 	DeviceManagerHandle,
	ADI_DMA_MANAGER_HANDLE 	DMAManagerHandle

){
	int Result;

	FrameReady = FALSE;	

// turn on last LED 
	ezTurnOnLED(EZ_LAST_LED);

	ezEnableVideoDecoder();// enable the video decoder (7183)
#if defined(__ADSP_EDINBURGH__)         // the Edinburgh EZ-Kit uses a flash for ports
	ezDelay(500); // wait for 7183 to come out of reset
#endif	

/********************** AD7183 driver *************************************************************/
	// open the ad7183 driver
	ezErrorCheck( adi_dev_Open(	adi_dev_ManagerHandle,		// DevMgr handle
				&ADIADV7183EntryPoint,		// pdd entry point
				0,				// device instance
				(void*)0x7183,				// client handle callback identifier
				&AD7183DriverHandle,			// DevMgr handle for this device
				ADI_DEV_DIRECTION_INBOUND,// data direction for this device
				adi_dma_ManagerHandle,			// handle to DmaMgr for this device
				NULL,				// handle to deferred callback service
				ClientCallback));		// client's callback function
	
	
	// Send Pseudo TWI Configuration table to AD7183 if register configuratian is needed
	ezErrorCheck(adi_dev_Control(AD7183DriverHandle,ADI_AD7183_CMD_SET_TWI_CONFIG_TABLE,(void*)PseudoTWIConfig)); 

	// do the register read/write here if needed.

	//Read7183StatusReg(AD7183DriverHandle);			
					
	// open the AD7183-PPI device 0 (see Schematic)
	ezErrorCheck( adi_dev_Control(AD7183DriverHandle, ADI_AD7183_CMD_OPEN_PPI, (void *)0));
			
	// command PPI to work in NTSC or PAL mode
#if defined(PAL_FRAME)
		ezErrorCheck( adi_dev_Control(AD7183DriverHandle, ADI_AD7183_CMD_SET_VIDEO_FORMAT, (void *)PAL));
#else
		ezErrorCheck( adi_dev_Control(AD7183DriverHandle, ADI_AD7183_CMD_SET_VIDEO_FORMAT, (void *)NTSC));
#endif		

#ifdef	USE_CIRCULAR_BUFFER	
	// configure the ad7183 dataflow method to circular
	Result =  adi_dev_Control(AD7183DriverHandle, ADI_DEV_CMD_SET_DATAFLOW_METHOD, (void*)ADI_DEV_MODE_CIRCULAR);
	
	 if (Result != ADI_DEV_RESULT_SUCCESS) 
	 {
	 	printf("%x\n", Result);
	 }

	
	
		// give the PPI driver the buffer to process
	ezErrorCheck( adi_dev_Read(AD7183DriverHandle, ADI_DEV_CIRC, (ADI_DEV_BUFFER *)&CircBuffer));
#else	
	// configure the ad7183 dataflow method to chained
	ezErrorCheck( adi_dev_Control(AD7183DriverHandle, ADI_DEV_CMD_SET_DATAFLOW_METHOD, (void *)ADI_DEV_MODE_CHAINED));
	
		// give the PPI driver the buffer to process
	ezErrorCheck( adi_dev_Read(AD7183DriverHandle, ADI_DEV_2D, (ADI_DEV_BUFFER *)&Buffer2D));
#endif	
	
	
	/***********************************************************************************/
	// start capturing the input data
	ezErrorCheck( adi_dev_Control(AD7183DriverHandle, ADI_DEV_CMD_SET_DATAFLOW, (void*)TRUE));

	// wait till the buffer has been processed
	while (FrameReady == FALSE) ;
	
	// close the PPI driver
	ezErrorCheck(adi_dev_Close(AD7183DriverHandle));
 
	// turn off LED 
	ezTurnOffLED(5);
	
	CopyField2ToField1();

}




/*********************************************************************

	Function:		DisplayVideoFrame

	Description: This function called an encoder driver to output the
			buffered video data.
			The encoder driver for ADSP_BF533 is ADV7171 or for ADSP_BF561 is
			ADV7179 driver.
					
			First the encoder driver is opened ,then the encoder register is set
			using TWI register access service to the NTSC or PAL format,
			depending on the macro PAL_FRAME. 
			When dataflow is enabled,the Encoder driver sends continuously the 
			buffered data to the video monitor. 


*********************************************************************/

static void DisplayVideoFrame(
	ADI_DEV_MANAGER_HANDLE 	DeviceManagerHandle,
	ADI_DMA_MANAGER_HANDLE 	DMAManagerHandle

){

	
	// turn on first LED 
	ezTurnOnLED(0);

	ezEnableVideoEncoder();// enable the video encoder (7171)
	//ezDelay(500);
	
	// open the ad7171 driver
	ezErrorCheck( adi_dev_Open(  adi_dev_ManagerHandle,            // Dev manager Handle
#if defined(__ADSP_TETON__)
                 		   		&ADIADV7179EntryPoint,          // Device Entry point
#else
                 		   		&ADIADV7171EntryPoint,          // Device Entry point
#endif                 		   		
                            	0,                              // Device number 
	                            NULL,                           // No client handle
    	                        &EncoderDriverHandle,                  // Device manager handle address
        	                    ADI_DEV_DIRECTION_OUTBOUND,     // Data Direction
        	                    
            	                adi_dma_ManagerHandle,               // Handle to DMA Manager
                	            NULL,               			// Handle to callback manager
                    	        ClientCallback));
	/**************** PPI Configuration Settings ****************/	
	// Set PPI Device number.
#if defined(__ADSP_TETON__)
	ezErrorCheck(adi_dev_Control( EncoderDriverHandle, ADI_ADV717x_CMD_SET_PPI_DEVICE_NUMBER, (void*)1 ));
#else	
	ezErrorCheck(adi_dev_Control( EncoderDriverHandle, ADI_ADV717x_CMD_SET_PPI_DEVICE_NUMBER, (void*)0 ));
#endif	

	// Open PPI Device
	ezErrorCheck(adi_dev_Control( EncoderDriverHandle, ADI_ADV717x_CMD_SET_PPI_STATUS, (void*)ADI_ADV717x_PPI_OPEN ));

	// Send Pseudo TWI Configuration table to AD7171 driver
	ezErrorCheck(adi_dev_Control(EncoderDriverHandle,ADI_ADV717x_CMD_SET_TWI_CONFIG_TABLE,(void*)PseudoTWIConfig));
							
	/*************** Read AD7171 registers before configuration **********************/  
	//ReadEncoderRegs(EncoderDriverHandle);							
   								
    /*********************************************************************************/								
    								
#ifdef PAL_FRAME

	SetEncoderMode(EncoderDriverHandle,PAL);

#else
// NTSC video out configuration

    SetEncoderMode(EncoderDriverHandle,NTSC);
    
#endif 
	
// Read AD7171 register value after configuration
	//ReadEncoderRegs(EncoderDriverHandle);
		

#ifdef	USE_CIRCULAR_BUFFER
	// configure the ad7171 dataflow method
	ezErrorCheck( adi_dev_Control(EncoderDriverHandle, ADI_DEV_CMD_SET_DATAFLOW_METHOD, (void*)ADI_DEV_MODE_CIRCULAR));

		// give the PPI driver the buffer to process
	ezErrorCheck( adi_dev_Write(EncoderDriverHandle, ADI_DEV_CIRC, (ADI_DEV_BUFFER *)&CircBuffer));

#else
	// configure the ad7171 dataflow method to "chained with loopback"
	ezErrorCheck( adi_dev_Control(EncoderDriverHandle, ADI_DEV_CMD_SET_DATAFLOW_METHOD, (void *)ADI_DEV_MODE_CHAINED_LOOPBACK));
		// give the PPI driver the buffer to process
	ezErrorCheck( adi_dev_Write(EncoderDriverHandle, ADI_DEV_2D, (ADI_DEV_BUFFER *)&Buffer2D));
	
#endif	
	
	
	// start outputting the output data
	ezErrorCheck( adi_dev_Control(EncoderDriverHandle, ADI_DEV_CMD_SET_DATAFLOW, (void*)TRUE));


}


/**********************************************************************
* Configure EZ-Kit Encoder mode to PAL or NTSC
**********************************************************************/
static void SetEncoderMode(ADI_DEV_DEVICE_HANDLE EncoderDevHandle, u32 mode)	
{	
	int Result;
    // ADV7171 register configuration array for NTSC mode
    ADI_DEV_ACCESS_REGISTER NTSCCfg[]=
    						{{ADV717x_MR0, 	0x00},	// register address, configuration data
    					   {ADV717x_MR1, 	0x58},
    					   {ADV717x_MR2, 	0x00},
    					   {ADV717x_MR3, 	0x00},
    					   {ADV717x_MR4, 	0x10},
    					   {ADV717x_TMR0, 	0x00}, 
    					   {ADV717x_TMR1, 	0x00},
    					   {ADI_DEV_REGEND,0	}};	// End of register access
  
	// ADV7171 register configuration array for PAL mode
    ADI_DEV_ACCESS_REGISTER PALCfg[]=
    						{{ADV717x_MR0,	0x05},		// register address, configuration data
    					   {ADV717x_MR1,	0x10},
    					   {ADV717x_MR2,	0x00},
    					   {ADV717x_MR3,	0x00},
    					   {ADV717x_MR4,	0x00},
    					   {ADV717x_TMR0, 	0x08}, 
    					   {ADV717x_TMR1, 	0x00},
    					   {ADI_DEV_REGEND,0	}};	// End of register access

	
	if (mode == NTSC){						
    	ezErrorCheck(adi_dev_Control(EncoderDevHandle, ADI_ADV717x_CMD_SET_SCF_REG, (void *) ADV717x_SCF_VALUE_NTSC));
    
   		// configure encoder(ADV7171 or ADV7179) in selected mode
    	ezErrorCheck(adi_dev_Control(EncoderDevHandle, ADI_DEV_CMD_REGISTER_TABLE_WRITE, (void *)NTSCCfg));
	}
	else {
	    Result = adi_dev_Control(EncoderDevHandle, ADI_ADV717x_CMD_SET_SCF_REG, (void *) ADV717x_SCF_VALUE_PAL_BI);
    	if (Result != 0)
    	printf("SCF failed %x\n",Result);
    	
   		// configure encoder(ADV7171 or ADV7179) in selected mode
    	Result = adi_dev_Control(EncoderDevHandle, ADI_DEV_CMD_REGISTER_TABLE_WRITE, (void *)PALCfg);
    	if (Result != 0)
    	printf("Reg-table-write failed %x\n",Result);

	}

}



/**********************************************************************
* read ADV7183 status registers 
**********************************************************************/
static void Read7183StatusReg(ADI_DEV_DEVICE_HANDLE AD7183DevHandler)	
{
    	u32 Result = 0, i;

    // array to hold the read AD7183 subaddress register value
    u16 Read_data[4] ={0};        

    
    ADI_DEV_ACCESS_REGISTER Regs[] = 
	{{ ADV7183_STATUS1_RO, 	0 },		// Register address to access, corresponding register data
         { ADV7183_IDENT_RO, 	0 },
         { ADV7183_STATUS2_RO, 	0 },
         { ADV7183_STATUS3_RO, 	0 },
         { ADI_DEV_REGEND,	0 }};	// Register access delimiter (indicates end of register access)

//To read list of registers in DevRegs
    Result =  adi_dev_Control(AD7183DevHandler, ADI_DEV_CMD_REGISTER_TABLE_READ, (void *)&Regs);    
    if (Result != 0) printf("CMD_REGISTER_TABLE_READ failed%x)\n",Result);
    else {
    	// print the values	
		printf("AD7183: STATUS1 IDENT STATUS2 STATUS3\n ");
		for (i=0; i<4; i++){
		printf("0x%02X ",Regs[i].Data);
		}
		printf("\n");

    }

}


/**********************************************************************
* Read EZ-Kit encoder(ADV7171 or ADV7179) mode(PAL or NTSC) 
**********************************************************************/
static void ReadEncoderRegs(ADI_DEV_DEVICE_HANDLE EncoderDevHandler)	
{							
	u32 i,EncoderSCFValue,Result;
	
   // ADV7171 register configuration array for NTSC mode
    ADI_DEV_ACCESS_REGISTER read[]={{ADV717x_MR0, 	0},		// register address, configuration data
    										{ADV717x_MR1, 	0},
    										{ADV717x_MR2, 	0},
    										{ADV717x_MR3, 	0},
    										{ADV717x_MR4, 	0},
    										{ADV717x_TMR0, 	0}, 
    										{ADV717x_TMR1, 	0},
    										{ADI_DEV_REGEND,0	}	};	// End of register access

 	Result = adi_dev_Control(EncoderDevHandler, ADI_ADV717x_CMD_GET_SCF_REG, (void *)&EncoderSCFValue);
	if ( Result != ADI_DEV_RESULT_SUCCESS) printf("Get SCF-Reg failed\n");
	else 
	printf("\nEncoder SCF=0x%x\n",EncoderSCFValue);
	
	
	    // Read ADV7171 in selected mode
    Result = adi_dev_Control(EncoderDevHandler, ADI_DEV_CMD_REGISTER_TABLE_READ, (void *)read);       
	if ( Result != ADI_DEV_RESULT_SUCCESS) printf("Selective Read failed %x\n", Result);
	else {
		printf("Encoder Regs: ");
	
		for(i=0;i<7;i++){
		printf("0x%x ",read[i].Data);
		}
		printf("\n");
	}

}


/*********************************************************************

	Function:		Copy Odd to Even Frame

	Description:	This functions copies video field 2 over 
					the video field 1 in the 7183 input buffer

					This is necessary to reduce the video output 
					flicker caused when the odd and even video field
					contain different video frames
   
*********************************************************************/

static void CopyField2ToField1(void)

{

	u32 i,j;	
	u32 *ipF, *opF;

	// Field1, 1st active line number * line length(in 32 bit) + horizontal blanking length	
	ipF =((u32 *)sFrame0)+ ACTIVE_FIELD2*FRAME_DATA_LEN_32BIT + HORIZONTAL_BLANKING; // pointer to field1
	
	// Field2, 1st active line number * line length(in 32 bit) + horizontal blanking length
	opF= ((u32 *)sFrame0)+ ACTIVE_FIELD1*FRAME_DATA_LEN_32BIT + HORIZONTAL_BLANKING; // pointer to field2
	
	for(j=0;j<NUM_LINES_ACTIVE;ipF+=HORIZONTAL_BLANKING,opF+=HORIZONTAL_BLANKING,j++) 	
		for(i=0;i<360;ipF+=1,opF+=1,i++)
			*opF=*ipF;	//copy field1 to field 2
}


