/******************************************************************************

Copyright (c) 2005 Analog Devices.  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.  

******************************************************************************/



/******************************************************************************

$File:		encoder.c $
$Revision: 1.3 $
$Date: 2008/03/24 20:03:52 $


Description:
	This file contains functions to control a video encoder devices like the 
	adv7179
	

Modification History:
====================
Revision 1.0 build 1 - BJ 2006/03/27
	Created file
Revision 1.0 build 2 - BJ 2006/05/08
	Updaed example to support revision to device access functions
	
******************************************************************************/



/******************************************************************************

Include files

******************************************************************************/

#include <SensorCommon/device.h>
#include <SensorCommon/encoder.h>
#include <drivers/twi/adi_twi.h>
#include <drivers/encoder/adi_adv717x.h>




/******************************************************************************

Definitions

******************************************************************************/




/******************************************************************************

	Function: encoder_open_adv7179
	
	Description: Open the adv7179 video encoder for outputting

******************************************************************************/

ADI_DEV_DEVICE_HANDLE encoder_open_adv7179(
	ADI_DEV_MANAGER_HANDLE	DevManager,
	ADI_DMA_MANAGER_HANDLE	DevDMA,
	ADI_DCB_HANDLE			DevDCB,
	u32 PPI,
	u16 *Data, u8 DataSize, 
	ADI_DCB_CALLBACK_FN Callback,
	ADI_DEV_CMD_VALUE_PAIR *Args)
{
	u32 Code,Height,Width;
	GFX_MODE Mode=GFX_MODE_NTSCI;
	ADI_DEV_DEVICE_HANDLE Handle=NULL;
	
	
	while (Args&&Args->CommandID!=ADI_DEV_CMD_END)
	{
		switch (Args->CommandID)
		{
			case ENCODER_CMD_SET_MODE: Mode=(GFX_MODE)Args->Value; break;
		}
		Args++;
	}
	
	
    // this value is setup in the pre-processor definitions in project options
#ifdef ADI_TWIPSEUDO
	static adi_twi_pseudo_port TWIPseudo=ADI_TWIPSEUDO;
	static ADI_DEV_CMD_VALUE_PAIR TWIConfig[]={
		{ADI_TWI_CMD_SET_PSEUDO,(void *)(&TWIPseudo)},
		{ADI_DEV_CMD_SET_DATAFLOW_METHOD,(void *)ADI_DEV_MODE_SEQ_CHAINED},
		{ADI_TWI_CMD_SET_ANAK,(void *)0},
		{ADI_TWI_CMD_SET_DNAK,(void *)0},
		{ADI_DEV_CMD_SET_DATAFLOW,(void *)TRUE},
		{ADI_DEV_CMD_END,NULL}
	};
#else
	static ADI_DEV_CMD_VALUE_PAIR TWIConfig[]={
		{ADI_DEV_CMD_SET_DATAFLOW_METHOD,(void *)ADI_DEV_MODE_SEQ_CHAINED},
		{ADI_TWI_CMD_SET_ANAK,(void *)0},
		{ADI_TWI_CMD_SET_DNAK,(void *)0},
		{ADI_DEV_CMD_SET_DATAFLOW,(void *)TRUE},
		{ADI_DEV_CMD_END,NULL}
	};
#endif
	
	
	ADI_DEV_ACCESS_REGISTER WriteNTSCI[]={
		// Configure adv7179 for NTSC interlaced video output
	    {ADV717x_MR0,0x00},
	    {ADV717x_MR1,0x58},
	    {ADV717x_MR2,0x00},
	    {ADV717x_MR3,0x00},
	    {ADV717x_MR4,0x10},
	    {ADV717x_TMR0,0x00},
	    {ADV717x_TMR1,0x00},
	    {ADI_DEV_REGEND,0}
	}, WritePALI[]={
	    // Configure adv7179 for PAL interlaced video output
	    {ADV717x_MR0,0x05},
	    {ADV717x_MR1,0x10},
	    {ADV717x_MR2,0x00},
	    {ADV717x_MR3,0x00},
	    {ADV717x_MR4,0x00},
	    {ADV717x_TMR0,0x08},
	    {ADV717x_TMR1,0x00},
	    {ADI_DEV_REGEND,0}
	};
	
	
	ADI_DEV_CMD_VALUE_PAIR ConfigNTSCI[]={
	    {ADI_ADV717x_CMD_SET_TWI_CONFIG_TABLE,(void*)TWIConfig},
		{ADI_ADV717x_CMD_SET_PPI_DEVICE_NUMBER,(void *)PPI},
		{ADI_ADV717x_CMD_SET_PPI_STATUS,ADI_ADV717x_PPI_OPEN},
		{ADI_DEV_CMD_SET_DATAFLOW_METHOD,(void *)ADI_DEV_MODE_CHAINED_LOOPBACK},
		{ADI_ADV717x_CMD_SET_SCF_REG,(void *)ADV717x_SCF_VALUE_NTSC},
		{ADI_DEV_CMD_REGISTER_TABLE_WRITE,(void *)&WriteNTSCI},
		{ADI_DEV_CMD_END,NULL}
	}, ConfigPALI[]={
	    {ADI_ADV717x_CMD_SET_TWI_CONFIG_TABLE,(void*)TWIConfig},
		{ADI_ADV717x_CMD_SET_PPI_DEVICE_NUMBER,(void *)PPI},
		{ADI_ADV717x_CMD_SET_PPI_STATUS,ADI_ADV717x_PPI_OPEN},
		{ADI_DEV_CMD_SET_DATAFLOW_METHOD,(void *)ADI_DEV_MODE_CHAINED_LOOPBACK},
		{ADI_ADV717x_CMD_SET_SCF_REG,(void *)ADV717x_SCF_VALUE_PAL_BI},
		{ADI_DEV_CMD_REGISTER_TABLE_WRITE,(void *)&WritePALI},
		{ADI_DEV_CMD_END,NULL}
	};
	
	
	if (Mode!=GFX_MODE_NTSCI&&Mode!=GFX_MODE_PALI) return NULL;
	
	
    // try and open the device, if it fails then return error code
	if ((Code=adi_dev_Open(
		DevManager,
		&ADIADV7179EntryPoint,
		0,
		&Handle,
		&Handle,
		ADI_DEV_DIRECTION_OUTBOUND,
		DevDMA,
		DevDCB,
		Callback?Callback:NULL))!=ADI_DEV_RESULT_SUCCESS)
		return NULL;


	// now configure the device
	Code=adi_dev_Control(Handle,ADI_DEV_CMD_TABLE,Mode==GFX_MODE_NTSCI?ConfigNTSCI:ConfigPALI);

	
	if (Code==ADI_DEV_RESULT_SUCCESS)
	{
		static ADI_DEV_BUFFER Buffer[1];
		GFX_CANVAS Canvas;
		u32 i,Height,Width;
		
		
		gfx_init(&Canvas,Mode,(u16 *)Data,0,0,0,0);
		Width=gfx_getframewidth(&Canvas);
		Height=gfx_getframeheight(&Canvas);
		
		
		for (i=0;i<sizeof(Buffer)/sizeof(Buffer[0]);i++)
		{
			Buffer[i].TwoD.Data=Data;
			Buffer[i].TwoD.ElementWidth=DataSize;
			Buffer[i].TwoD.XCount=(Width*sizeof(u16))/Buffer[i].TwoD.ElementWidth;
			Buffer[i].TwoD.XModify=Buffer[i].TwoD.ElementWidth;
			Buffer[i].TwoD.YCount=Height;
			Buffer[i].TwoD.YModify=Buffer[i].TwoD.ElementWidth;
			Buffer[i].TwoD.CallbackParameter=&Buffer[i];
			Buffer[i].TwoD.pNext=NULL;
			Buffer[i].TwoD.pAdditionalInfo=(void *)ADI_DEV_BUFFER_UNDEFINED;
			Code=adi_dev_Write(Handle,ADI_DEV_2D,&Buffer[i]);
		}
	}
	
	if (Code==ADI_DEV_RESULT_SUCCESS) Code=adi_dev_Control(Handle,ADI_DEV_CMD_SET_DATAFLOW,(void *)TRUE);
	
	// If configuration failed close the device
	if (Code!=ADI_DEV_RESULT_SUCCESS)
	{
		adi_dev_Close(Handle);
		Handle=NULL;
	}
	
	
	return Handle;
}

/*****************************************************************************/
