/*****************************************************************************
Copyright(c) 2005 Analog Devices, Inc.  All Rights Reserved. This software is
proprietary and confidential to Analog Devices, Inc. and its licensors.
******************************************************************************

$RCSfile: jpeg_mjpeg_system.c,v $
$Revision: 1.4 $
$Date: 2007/11/15 01:37:11 $

Project:	BlackfinSDK (JPEG-MJPEG)
Title:		system services
Author(s):	bmk
Revised by: 

Description:
			Functions to configure system services and start devices 
			for jpeg-mjpeg

References:
			None

******************************************************************************
Tab Setting:			4
Target Processor:		ADSP-BF5xx
Target Tools Revision:	ADSP VisualDSP++ v4.5
******************************************************************************

Modification History:
====================
$Log: jpeg_mjpeg_system.c,v $
Revision 1.4  2007/11/15 01:37:11  randreol
Support for ssl_init

Revision 1.4  2006/11/13 01:30:51  bmk
BF561-removed ezDelay call in encoding mode


Revision 1.2  2006/11/10 07:18:58  bmk
merged BF533 & BF561 apps
Fixed BF561 cache issue

Revision 1.1  2006/11/03 07:12:09  bmk
SDK 2.0  files - Initial Entry

******************************************************************************
Includes
********************************/

#include <jpeg_mjpeg_system.h>					// System includes
#include <jpeg_mjpeg_heap.h>					// Heap includes
#include <jpeg_mjpeg_cache.h>					// Cache includes
#include <jpeg_mjpeg_err.h>						// JPEG-MJPEG error code process includes
#include <jpeg_mjpeg_cplb_tables.h>				// CPLB table includes

// USB includes
#include <drivers\usb\usb_core\adi_usb_objects.h>
#include <drivers\usb\usb_core\adi_usb_core.h>
#include <adi_usbcmd.h>							// supported USB commands
#include <drivers\usb\class\peripheral\vendor_specific\adi\bulkadi\adi_usb_bulkadi.h>	// adi bulk driver header file
#include <drivers\usb\controller\peripheral\plx\net2272\adi_usb_net2272.h>				// net2272 driver header file
#include <adi_usbio_blackfin.h>					// USB I/O functions for Blackfin
// Device Driver Includes
#include <drivers\twi\adi_twi.h>				// TWI driver includes
#include <drivers\ppi\adi_ppi.h>				// PPI driver includes
#include <drivers\encoder\adi_adv717x.h>		// video encoder driver includes
#include <drivers\decoder\adi_adv7183.h>		// video decoder driver includes

/********************************
Local data and handles
********************************/

/*****************
Callback functions
******************/
// Exception handler
static		ADI_INT_HANDLER		(ExceptionHandler);
// Hardware error handler
static		ADI_INT_HANDLER		(HWErrorHandler);
// Video In callback function (for ADV7183)
static void VideoInCallback		(void *AppHandle, u32  Event, void *pArg);
// Video Out callback function (for ADV717x)
static void VideoOutCallback	(void *AppHandle, u32  Event, void *pArg);
// USB driver callback
static void NET2272_Callback	(void *AppHandle, u32  Event, void *pArg);

/************************
Local function prototype
************************/
// Installs USB driver
void 		InstallUSBdriver	(void);
// Enables USB driver
void 		EnableUSBdriver	(void);
// updates video parameters to selected video mode
void 		UpdateVideoMode 	(void);

/*****************
Globals
******************/
// Device Driver and System Services Handles
// handle to the callback service Manager
ADI_DCB_HANDLE			DCBManagerHandle;
// handle to the ADV717x device driver
ADI_DEV_DEVICE_HANDLE	ADV717xDeviceHandle;
// handle to the ADV7183 device driver
ADI_DEV_DEVICE_HANDLE	ADV7183DeviceHandle;
// handle to the USB bulk class device driver
ADI_DEV_DEVICE_HANDLE	USBDeviceHandle;
// handle to the USB controller device driver
ADI_DEV_PDD_HANDLE PeripheralDevHandle;	

// Video parameters
// Video data per line (bytes)
u32	DataPerLine;
// Number of lines per ITU656 video frame (bytes)
u32	FrameLines;
// Number of Active lines per ITU656 video frame (bytes)
u32	ActiveFrameLines;
// Number of bytes to skip to reach active video data in a single line
u32	ActiveVideoSkip;
// Number of bytes to skip to reach active video frame field1 (odd frame)
u32	Field1Skip;
// Number of bytes to skip to reach active video frame field2 (even frame)
u32	Field2Skip;
// Video Input/Output mode
u8	VideoMode;
// Selected Video Output mode
u8	OutputVideoMode;

// Device parameters
u8 Coding_Algorithm	= CODING_ALGORITHM_JPEG;
u8 Coding_Action   	= CODING_ACTION_DECODE;
u8 File_Settings	= GET_FILE_SETTINGS_FROM_TXT_FILE;

// Buffer to Hold YUV data from decoded JPEG image 
// size to support only ITU656 resolution & YUV400/YUV420/YUV422 image formats
#pragma section("YUV_Buffer", NO_INIT)
u8 	YUVBufs			[YUV_BUF_SIZE];
// define two ITU656 video frame buffers (JPEG uses only one & MJPEG uses both)
// place them in separate SDRAM banks
#pragma section("ITU656_Buffer1", NO_INIT)
u8	ITU656_Frame0	[ITU656_BUF_SIZE];
#pragma section("ITU656_Buffer2", NO_INIT)
u8	ITU656_Frame1	[ITU656_BUF_SIZE];

// Buffer pointers
// Pointer to buffers containing YUV data of decoded JPEG image or to be encoded JPEG file
section("L1_data_b") u8 *pYUVBufs[NUM_YUV_BUFS] = {NULL} ;
// Pointer to buffers containing JPEG/MJPEG image in ITU656 frame format
section("L1_data_b") u8 *pITU656Frames[2] 		= { &ITU656_Frame0[0], &ITU656_Frame1[0] };

// YUV <-> ITU656 conversion parameters
u32	JPEGImageWidth;		// Actual width of JPEG image to be encoded/decoded
u32	JPEGImageHeight;	// Actual height of JPEG image to be encoded/decoded
unsigned int 	JPEGFrameFormat;	// Frame format of decoded JPEG/MJPEG file
// Pointer to Video frame /YUV buffer ready for YUV <-> Video frame (ITU656) conversion (to update MDMA source descriptor)
section("L1_data_b") volatile u8	*pSrcDescStartAddr;
// Pointer to YUV/Video frame buffer ready for YUV <-> Video frame (ITU656) conversion (to update MDMA destination descriptor)
section("L1_data_b") volatile u8	*pDestDescStartAddr;

// Semaphores used for handshaking btwn ISR and foreground code.
section("L1_data_a") volatile bool	StartMDMA;
section("L1_data_a") volatile bool	FrameReady;
section("L1_data_a") volatile u8	BufferLevel;
section("L1_data_a") volatile u8	YUV_MDMA_BufID;
section("L1_data_a") volatile u8	MJPEG_YUV_BufID;
section("L1_data_a") volatile u32   VideoFrameCounter;
section("L1_data_a") volatile u32 	FrameDroppedCounter;
section("L1_data_a") volatile bool	VideoFrameCompletedFlag;
section("L1_data_a") volatile bool 	isMJEInputDataAvailable;
section("L1_data_a") volatile bool 	isMJDInputDataAvailable;

// JPEG/MJPEG frame background colour - black (UYVY)
section("L1_data_b") char JPEGImageBackground[]	= {0x80,0x10,0x80,0x10};
/*********************************************************************

Device Configuration tables

*********************************************************************/

#if defined(__ADSPBF533__)

	// BF533 Ports (PF0=SCL,PF1=SDA) & Timer(Timer 0) used for Pseudo TWI
	adi_twi_pseudo_port port={ADI_FLAG_PF0,ADI_FLAG_PF1,ADI_TMR_GP_TIMER_0,(ADI_INT_PERIPHERAL_ID)NULL};

#elif defined(__ADSPBF561__)	

	// BF561 Ports (PF0=SCL,PF1=SDA) & Timer(Timer 2) used for Pseudo TWI
	adi_twi_pseudo_port port={ADI_FLAG_PF0,ADI_FLAG_PF1,ADI_TMR_GP_TIMER_2,(ADI_INT_PERIPHERAL_ID)NULL};

#endif

#if defined(__ADSPBF533__) || defined (__ADSPBF561__)

	// Pseudo TWI Configuration	to access video encoder/decoder registers
	// Run TWI clock at 100MHz & 50% Duty Cycle
	adi_twi_bit_rate rate={100,50};
	
	ADI_DEV_CMD_VALUE_PAIR TWIConfig[]={	// configuration table for the TWI driver
		{ ADI_TWI_CMD_SET_PSEUDO,			(void *)(&port)					},
		{ ADI_DEV_CMD_SET_DATAFLOW_METHOD,	(void *)ADI_DEV_MODE_SEQ_CHAINED},
		{ ADI_TWI_CMD_SET_FIFO,				(void *)0x0000					},
		{ ADI_TWI_CMD_SET_RATE,				(void *)(&rate)					},
		{ ADI_TWI_CMD_SET_LOSTARB,			(void *)1						},
		{ 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
#error "*** ERROR: Application doesnot support this processor yet ***"
#endif

/*********************************************************************

    Function:       InitSystem

    Description:    Initialises EZ kit & Video Parameters

*********************************************************************/	
section("sdram0_bank1_nocache")
void InitSystem(void)
{
    u8 i;
       
	ezInit (1);				// Initialise Ez kit (This app uses only one core)	
	ezTurnOffAllLEDs ();	// Turn off all LEDs

	OutputVideoMode			= ITU656_NTSC;		// Default output mode 
	VideoMode				= OutputVideoMode;	// Default video mode 
	VideoFrameCompletedFlag = FALSE;
	isMJEInputDataAvailable = FALSE;
	isMJDInputDataAvailable = FALSE;
	VideoFrameCounter 		= 0;
	FrameDroppedCounter 	= 0;
	
	// generate YUV buffer addresses
	for (i=0; i<NUM_YUV_BUFS;i++)
	{	
		pYUVBufs[i] = &YUVBufs[(i*SINGLE_YUV_BUF_SIZE)];
	}
		
	// update video parameters
	UpdateVideoMode();

	// initialise the ezkit record button
	ezInitButton(JPEG_MJPEG_RECORD_BUTTON);
   
	return;
}

/*********************************************************************

    Function:       InstallMemory

    Description:    Initialises & installs Cache & Heap for JPEG-MJPEG

*********************************************************************/
section("sdram0_bank1_nocache")
void InstallMemory()
{
	// Configure cache
	disable_data_cache();
	configure_data_cache_cplbs(codec_dcplbs_table);
	enable_data_cache();

	disable_instruction_cache();
	configure_instruction_cache_cplbs(codec_icplbs_table);
	enable_instruction_cache();

		
	// Install heaps
	InstallCodecHeaps();

	return;
}	
		
/*********************************************************************

    Function:       InstallSystemServices

    Description:    Installs system services

*********************************************************************/
// function implementations
section("sdram0_bank1_nocache")
void InstallSystemServices(void)
{
	u32 ResponseCount;			// response counter

	// initialize the ezKit power,EBIU,DMA....
	adi_ssl_Init();	

	// enable and configure async memory
	ezInit (1);
	
	ezTurnOffAllLEDs ();	// Turn off all LEDs	
	
	// Install the USB driver	
	InstallUSBdriver();

	return;
}

/*********************************************************************

    Function:       InstallUSBdriver

    Description:    Installs USB device

*********************************************************************/
section("sdram0_bank1_nocache")
void InstallUSBdriver(void)	
{
	void *pConfig = NULL;
									
	// initialize USB Core
    adi_usb_CoreInit(pConfig);

    // open the USB controller driver
    ezErrorCheck( adi_dev_Open(	adi_dev_ManagerHandle, 			// DevMgr handle 
								&ADI_USB_NET2272_Entrypoint,	// pdd entry point 
								0,                          	// device instance 
								(void*)1,						// client handle callback identifier 
								&PeripheralDevHandle,	        // device handle 
								ADI_DEV_DIRECTION_BIDIRECTIONAL,// data direction for this device 
								adi_dma_ManagerHandle,				// handle to DmaMgr for this device 
								NULL,							// handle to deferred callback service 
								NET2272_Callback));		  	    // client's callback function 
			
	// open the vendor specific bulk USB class driver
	ezErrorCheck( adi_dev_Open(	adi_dev_ManagerHandle,			// DevMgr handle
								&ADI_USB_VSBulk_Entrypoint,		// pdd entry point
								0,								// device instance
								(void*)0x1,						// client handle callback identifier
								&USBDeviceHandle,				// DevMgr handle for this device
								ADI_DEV_DIRECTION_BIDIRECTIONAL,// data direction for this device
								adi_dma_ManagerHandle,				// handle to DmaMgr for this device
								NULL,							// handle to deferred callback service
								NET2272_Callback));				// client's callback function
	
		
		
	// give USB controller driver handle to the class drivers.
	ezErrorCheck( adi_dev_Control(USBDeviceHandle, ADI_USB_CMD_CLASS_SET_CONTROLLER_HANDLE, (void*)PeripheralDevHandle) );
	// configure the class driver
	ezErrorCheck( adi_dev_Control(USBDeviceHandle, ADI_USB_CMD_CLASS_CONFIGURE, (void*)0) );
	// configure the mode
	ezErrorCheck( adi_dev_Control(USBDeviceHandle, ADI_DEV_CMD_SET_DATAFLOW_METHOD, (void*)ADI_DEV_MODE_CHAINED) );
	// enable data flow
	ezErrorCheck( adi_dev_Control(USBDeviceHandle, ADI_DEV_CMD_SET_DATAFLOW, (void*)TRUE) );

	return;
}

/*********************************************************************

    Function:       EnableUSBdriver

    Description:    Enables USB device

*********************************************************************/
section("sdram0_bank1_nocache")
void EnableUSBdriver(void)	
{
	// enable USB
	ezErrorCheck( adi_dev_Control(PeripheralDevHandle, ADI_USB_CMD_ENABLE_USB, (void*)0 ));

	return;
}

/*********************************************************************

    Function:       InstallVideoEncoder
    Description:    Installs Video Encoder (ADV717x)

*********************************************************************/
section("sdram0_bank1_cache")
void InstallVideoEncoder()
{
   
	// ADV717x register to switch btwn NTSC and PAL
    ADI_DEV_ACCESS_REGISTER ADV717x_Cfg;
	// ADV717x register address to switch btwn NTSC & PAL    
    ADV717x_Cfg.Address = ADV717x_MR0;
        					
#if defined(__ADSPBF561__)
	
    // open the ADV7179 driver for video output
   	ezErrorCheck(adi_dev_Open(  adi_dev_ManagerHandle,     		// Dev manager Handle
                		   		&ADIADV7179EntryPoint,          // Device Entry point
                            	0,                              // Device number
	                            NULL,                           // No client handle
    	                        &ADV717xDeviceHandle,           // Device manager handle address
        	                    ADI_DEV_DIRECTION_OUTBOUND,     // Data Direction (video out)
            	                adi_dma_ManagerHandle,               // Handle to DMA Manager
                	            DCBManagerHandle,				// Callback Manager
                    	        VideoOutCallback));				// callback function
                    	        
#elif defined(__ADSPBF533__)

    // open the AD7171 driver for video output
    ezErrorCheck(adi_dev_Open(  adi_dev_ManagerHandle,            // Dev manager Handle
                 		   		&ADIADV7171EntryPoint,          // Device Entry point
                            	0,                              // Device number
	                            NULL,                           // No client handle
    	                        &ADV717xDeviceHandle,           // Device manager handle address
        	                    ADI_DEV_DIRECTION_OUTBOUND,     // Data Direction (video out)
            	                adi_dma_ManagerHandle,               // Handle to DMA Manager
                	            DCBManagerHandle,      			// Callback Manager
                    	        VideoOutCallback));				// callback function

#else
#error "*** ERROR: Processor not yet supported ***"
#endif
	
	// TWI Configuration table
	ezErrorCheck(adi_dev_Control(ADV717xDeviceHandle, ADI_ADV717x_CMD_SET_TWI_CONFIG_TABLE, (void *) TWIConfig));

	// update the output video mode
	VideoMode = OutputVideoMode;
	UpdateVideoMode ();
	
	// ADV717x register Configuration    
	// Check Output video mode
	if (VideoMode == ITU656_PAL)
	{
    	// Config ADV717x in PAL mode (SCFR with PAL config values)
		ezErrorCheck(adi_dev_Control(ADV717xDeviceHandle, ADI_ADV717x_CMD_SET_SCF_REG, (void *)ADV717x_SCF_VALUE_PAL_BI));
		// MR0 value to set ADV717x in PAL mode
		ADV717x_Cfg.Data = 0x05;
		// Config other internal regs of ADV717x to PAL video mode
		ezErrorCheck(adi_dev_Control(ADV717xDeviceHandle, ADI_DEV_CMD_REGISTER_WRITE, (void *)&ADV717x_Cfg));
	}
	else // VideoMode must be ITU656_NTSC
	{
    	// Config ADV717x in PAL mode (SCFR with NTSC config values)
		ezErrorCheck(adi_dev_Control(ADV717xDeviceHandle, ADI_ADV717x_CMD_SET_SCF_REG, (void *)ADV717x_SCF_VALUE_NTSC));
		// MR0 value to set ADV717x in NTSC mode
		ADV717x_Cfg.Data = 0x00;				
		// Config other internal regs of ADV717x to NTSC video mode
		ezErrorCheck(adi_dev_Control(ADV717xDeviceHandle, ADI_DEV_CMD_REGISTER_WRITE, (void *)&ADV717x_Cfg));		
	}

// Set PPI port for video out
#if defined(__ADSPBF561__)
	// BF561 - PPI 1 used for Video out
	ezErrorCheck(adi_dev_Control(ADV717xDeviceHandle, ADI_ADV717x_CMD_SET_PPI_DEVICE_NUMBER, (void *) 1));
#elif defined (__ADSPBF533__)
	// BF533 - PPI 0 used for Video out
	ezErrorCheck(adi_dev_Control(ADV717xDeviceHandle, ADI_ADV717x_CMD_SET_PPI_DEVICE_NUMBER, (void *) 0));
#endif

	// Open PPI device for video out
	ezErrorCheck(adi_dev_Control(ADV717xDeviceHandle, ADI_ADV717x_CMD_SET_PPI_STATUS, (void *)ADI_ADV717x_PPI_OPEN));	
	// Set Dataflow method
	ezErrorCheck(adi_dev_Control(ADV717xDeviceHandle, ADI_DEV_CMD_SET_DATAFLOW_METHOD, (void *) ADI_DEV_MODE_CHAINED_LOOPBACK));

	// Enable streaming
	ezErrorCheck(adi_dev_Control(ADV717xDeviceHandle, ADI_DEV_CMD_SET_STREAMING, (void *) TRUE));
				
	return;
}

/*********************************************************************

    Function:       InstallVideoDecoder
    Description:    Installs Video Decoder (ADV7183)

*********************************************************************/
section("sdram0_bank1_cache")
void InstallVideoDecoder()	
{
    // open the ADV7183 driver for video input
   	ezErrorCheck(adi_dev_Open(  adi_dev_ManagerHandle,     		// Dev manager Handle
               		   			&ADIADV7183EntryPoint,          // Device Entry point
                          		0,                              // Device number
	                            NULL,                           // No client handle
   		                        &ADV7183DeviceHandle,           // Device manager handle address
       		                    ADI_DEV_DIRECTION_INBOUND,      // Data Direction (video in)
           		                adi_dma_ManagerHandle,               // Handle to DMA Manager
               		            DCBManagerHandle,				// Callback Manager
                   		        VideoInCallback));				// callback function

	// Open PPI device for video in
	ezErrorCheck(adi_dev_Control(ADV7183DeviceHandle, ADI_AD7183_CMD_OPEN_PPI, (void *) 0));
	
	// TWI Configuration for video decoder
	ezErrorCheck(adi_dev_Control(ADV7183DeviceHandle, ADI_AD7183_CMD_SET_TWI_CONFIG_TABLE, (void *) TWIConfig));

	// Update Input Video Mode
	UpdateInputVideoMode();

	// for JPEG, only one should be captured
	if (Coding_Algorithm == CODING_ALGORITHM_JPEG)
	{
		// Set Dataflow method
		ezErrorCheck(adi_dev_Control(ADV7183DeviceHandle, ADI_DEV_CMD_SET_DATAFLOW_METHOD, (void *) ADI_DEV_MODE_CHAINED));
		// Disable streaming
		ezErrorCheck(adi_dev_Control(ADV7183DeviceHandle, ADI_DEV_CMD_SET_STREAMING, (void *) FALSE));
	}
	else	// for MJPEG, continue capturing video
	{	    
		// Set Dataflow method		
		ezErrorCheck(adi_dev_Control(ADV7183DeviceHandle, ADI_DEV_CMD_SET_DATAFLOW_METHOD, (void *) ADI_DEV_MODE_CHAINED_LOOPBACK));	
		// Enable streaming
		ezErrorCheck(adi_dev_Control(ADV7183DeviceHandle, ADI_DEV_CMD_SET_STREAMING, (void *) TRUE));		
	}
		
	return;
}

/*********************************************************************

    Function:       UpdateInputVideoMode
    Description:    Reads ADV7183 Status1 Reg to auto-detect
    				Input Video Mode

	Status1 Reg:
	bit 0 => ADV7183 is in Lock (1) with video / lost(0)
	bit 1 => ADV7183 have lost sync (1) since previous read
	bits 6,5,4 => Autodetection Result (value 0,1=NTSC / 2,3,4,6=PAL)	

*********************************************************************/
section("sdram0_bank1_cache")
void	UpdateInputVideoMode(void)
{
  
    ADI_DEV_ACCESS_REGISTER		Status1;		// read ADV7183 Status1 reg
        
    Status1.Address		= ADV7183_STATUS1_RO;	// Status1 reg address
   	Status1.Data	= 0;					// clear the location where the data will be read to    
   	
	// call Device Access to read Status1 reg
	ezErrorCheck(adi_dev_Control(ADV7183DeviceHandle, ADI_DEV_CMD_REGISTER_READ, (void *) &Status1));
   
    // retrive ITU656 Input video mode
	switch ((Status1.Data >> 4) & 0x07)	
	{
		// case (NTSC video)
    	case 0:
    	case 1:	        
			// update VideoMode flag to ITU656 NTSC
			VideoMode = ITU656_NTSC;
    		break;
	    	
    	// case (PAL video)
    	case 2:
    	case 3:
    	case 4:
    	case 6:
			// update VideoMode flag to ITU656 PAL
			VideoMode = ITU656_PAL;
			break;
			
		// other video modes not supported. NTSC mode is set as default
    	default:
    		printf("\nNo valid Video Input was found!. System will return to default settings"); 
    		VideoMode = ITU656_NTSC;
    		break;
	}
		
	// check if ADV7183 have lost sync since previous reg read
	if (Status1.Data & 2)
	{
	    // yes. This must be a new video input mode. Update video parameters
		// Check video mode
		if (VideoMode == ITU656_PAL)
		{
		    printf ("\nConfiguring system for ITU656 PAL Video Input (720 x 576)...\n");
	    	// Config ADV7183 PPI in PAL mode
			ezErrorCheck(adi_dev_Control(ADV7183DeviceHandle, ADI_AD7183_CMD_SET_VIDEO_FORMAT, (void *)1));
		}
		else // video mode must be ITU656_NTSC
		{
		    printf ("\nConfiguring system for ITU656 NTSC Video Input  (720 x 486)...\n");
	    	// Config ADV7183 PPI in NTSC mode
			ezErrorCheck(adi_dev_Control(ADV7183DeviceHandle, ADI_AD7183_CMD_SET_VIDEO_FORMAT, (void *)0));
		}
		// update video parameters
		UpdateVideoMode();		
	}
	
	return;
}

/*********************************************************************

    Function:       UpdateVideoMode
    Description:    Updates video parameters to selected video mode
    				Selects Video In/Out between ITU656 NTSC and PAL
    				In/Out Video will be set to NTSC when VideoMode = 0
    				In/Out Video will be set to PAL when VideoMode = 1

*********************************************************************/
section("sdram0_bank1_cache")
void UpdateVideoMode (void)
{
	// update video parameters
	// Check video mode
	if (VideoMode == ITU656_PAL)
	{
		// video mode is ITU656 PAL
	  	// Video data per line (bytes)
		DataPerLine		= PAL_DATA_PER_LINE;
		// Number of lines per ITU656 video frame (bytes)
		FrameLines		= PAL_FRAME_LINES;
		// Number of Active lines per ITU656 video frame (bytes)
		ActiveFrameLines= PAL_ACTIVE_LINES;
		// Number of bytes to skip to reach active video data in a single line
		ActiveVideoSkip	= PAL_ACTIVE_VIDEO_SKIP;
		// Number of bytes to skip to reach active video frame field1 (odd frame)
		Field1Skip		= PAL_F1_SKIP;
		// Number of bytes to skip to reach active video frame field2 (even frame)
		Field2Skip		= PAL_F2_SKIP;
	}	
	else if (VideoMode == ITU656_NTSC)
	{
   		// Video mode must be ITU656 NTSC
   		// Video data per line (bytes)
		DataPerLine		= NTSC_DATA_PER_LINE;
		// Number of lines per ITU656 video frame (bytes)
		FrameLines		= NTSC_FRAME_LINES;
		// Number of Active lines per ITU656 video frame (bytes)
		ActiveFrameLines= NTSC_ACTIVE_LINES;
		// Number of bytes to skip to reach active video data in a single line
		ActiveVideoSkip	= NTSC_ACTIVE_VIDEO_SKIP;
		// Number of bytes to skip to reach active video frame field1 (odd frame)
		Field1Skip		= NTSC_F1_SKIP;
		// Number of bytes to skip to reach active video frame field2 (even frame)
		Field2Skip		= NTSC_F2_SKIP;
	}
	
	return;
}

/*********************************************************************

	Function:		ResetVideoCodecs

	Description:	Resets video codec hardware

*********************************************************************/
section("sdram0_bank1_cache")
void ResetVideoCodecs (void)
{ 
	       
    // for Decode mode, Disable video decoder and Enable video encoder
    if (Coding_Action == CODING_ACTION_DECODE)
    {
// For BF533 & BF561, pull the video encoder from reset mode
#if defined (__ADSPBF533__) || defined (__ADSPBF561__)
		
    	// Disable video decoder (ADV7183)
		printf ("Disabling Video Decoder (ADV7183)...\n");
    	ezDisableVideoDecoder();
		// Enable video encoder (ADV717x)
		printf ("Enabling Video Encoder (ADV717x)...\n\n");		
		ezEnableVideoEncoder();
		// Delay to allow codecs to sync
		printf ("Waiting for codecs to synchronize...\n\n");
   		ezDelay (VIDEO_CODEC_SYNC_DELAY);	     
   		
#else
#error "*** ERROR: Application doesnot support this processor ***"
#endif
    }
    // for Encode mode, Disable video encoder and Enable video decoder
    else if (Coding_Action == CODING_ACTION_ENCODE)
    {
// For BF533 & BF561, pull the video decoder from reset mode
#if defined (__ADSPBF533__) || defined (__ADSPBF561__)
    	// Disable video encoder (ADV717x)
    	printf ("Disabling Video Encoder (ADV717x)...\n");
    	ezDisableVideoEncoder();	
		// Enable video decoder (ADV7183)
		// Delay to allow codecs to sync (for BF561 - ezEnableVideoDecoder function has a delay loop to sync codecs)
		printf ("Enabling Video Decoder (ADV7183)...\n\n");
		printf ("Waiting for codecs to synchronize...\n\n");		
		ezEnableVideoDecoder();
		
#if defined (__ADSPBF533__)
// BF533 - Application should provide delay to sync video codecs.
   		ezDelay (VIDEO_CODEC_SYNC_DELAY);		
#endif
   		
#else
#error "*** ERROR: Application doesnot support this processor ***"
#endif
    }

	return;
}
/*********************************************************************

	Function:		PerformIO

	Description:	Performs USB I/O

*********************************************************************/
section("sdram0_bank1_cache")
u32	PerformUSBIO()
{
    u32	Result = ADI_DEV_RESULT_SUCCESS;
	int	Codec_return_value = CODEC_SUCCESS;

	// Set USB as default I/O device
	Result = ConfigUSB_IO(USBDeviceHandle);
		
	// continue only if USB IO config is a success
	if (Result == ADI_DEV_RESULT_SUCCESS)
	{
		// Switch to selected coding algorithm
		switch (Coding_Algorithm)
		{
			// Case (select algorithm is JPEG)	
			case CODING_ALGORITHM_JPEG:
				// check the coding action
				if (Coding_Action == CODING_ACTION_DECODE)
					Codec_return_value = do_JPEG_Decode();	// start JPEG decoding
				else
					Codec_return_value = do_JPEG_Encode();	// start JPEG encoding
				break;
				    
	    	// Case (select algorithm is MJPEG)
			case CODING_ALGORITHM_MJPEG:
				// check the coding action
				if (Coding_Action == CODING_ACTION_DECODE)
					Codec_return_value = do_MJPEG_Decode();	// start MJPEG decoding
				else
					Codec_return_value = do_MJPEG_Encode();	// start MJPEG encoding
				break;
			
			default:
				fprintf( fperr, "Error: Invalid coding parameters\n" );
				break;
		}

		// Check if JPEG-MJPEG Encode/Decode operation is result
		if (Codec_return_value) 
			fprintf(fperr, "Codec aborted abnormally\n");

		// Done with JPEG-MJPEG Encoding/Decoding. Stop USB I/O
    	StopUSB_IO (USBDeviceHandle);
	}
	
	return (Result);
}

/*********************************************************************

	Function:		SetCodecParameters

	Description:	Set Device (Codec) parameters in relevance to
					selected user option

*********************************************************************/
section("sdram0_bank1_cache")
u32	SetCodecParameters (u32 *UserOptions)
{
    
	u32	Result = ADI_DEV_RESULT_SUCCESS;	// default return code

    // switch user option
    switch ((char)UserOptions[0])
    {
        // Case (JPEG Decoding)
        case '1':
        // Case (MJPEG Decoding)
        case '2':
        
        	// Decode JPEG/MJPEG file(s)
			Coding_Action = CODING_ACTION_DECODE;
			
			// JPEG or MJPEG ?
			if ((char)UserOptions[0] == '1')
				// Decode JPEG file(s)
				Coding_Algorithm = CODING_ALGORITHM_JPEG;
			else
				// Decode MJPEG file(s)
				Coding_Algorithm = CODING_ALGORITHM_MJPEG;
				
			// Video output mode?
			if ((char)UserOptions[2] == '1')
				// NTSC video out
				OutputVideoMode = ITU656_NTSC;
			else if ((char)UserOptions[2] == '2')
				// PAL video out
				OutputVideoMode = ITU656_PAL;
			else
				// default as NTSC video out
				OutputVideoMode = ITU656_NTSC;

			// JPEG/MJPEG Decoder file settings?
			if ((char)UserOptions[4] == '1')
				// Prompt for file location & settings
				File_Settings = PROMPT_FOR_FILE_SETTINGS;
			else if ((char)UserOptions[4] == '2')
				// Retrieve settings from '.txt' files under project directory
				File_Settings = GET_FILE_SETTINGS_FROM_TXT_FILE;
			else
				// Retrieve settings from '.txt' files under project directory
				File_Settings = GET_FILE_SETTINGS_FROM_TXT_FILE;
				
			break;
			
		// Case (JPEG Encoding)
        case '3':
        // Case (MJPEG Encoding)
        case '4':

        	// Encode to JPEG/MJPEG file
			Coding_Action = CODING_ACTION_ENCODE;
			
			// JPEG or MJPEG ?
			if ((char)UserOptions[0] == '3')
				// Encode to JPEG file
				Coding_Algorithm = CODING_ALGORITHM_JPEG;
			else
				// Encode to MJPEG file
				Coding_Algorithm = CODING_ALGORITHM_MJPEG;
				
			// Video source?
			if ((char)UserOptions[1] == '1')
				// ITU656 video input (this app only supports ITU656 input)
				{}
			
			// JPEG Encoder settings?
			if ((char)UserOptions[3] == '2')
				// Encode video/image to YUV 420 format
				JPEGFrameFormat = 1;	// YUV 420 format - will be sent to JPEG Encoder library
			else
				// default to encode video/image to YUV 420 format
				JPEGFrameFormat = 1;	// YUV 420 format - will be sent to JPEG Encoder library

			// JPEG/MJPEG Encoder file settings?
			if ((char)UserOptions[4] == '1')
				// Prompt for file location & settings
				File_Settings = PROMPT_FOR_FILE_SETTINGS;
			else if ((char)UserOptions[4] == '2')
				// Retrieve settings from '.txt' files under project directory
				File_Settings = GET_FILE_SETTINGS_FROM_TXT_FILE;
			else
				// Retrieve settings from '.txt' files under project directory
				File_Settings = GET_FILE_SETTINGS_FROM_TXT_FILE;
						
			break;
		
		default:
			Result = ADI_DEV_RESULT_FAILED;
			break;
    }
   
    return (Result);
}				
        
/*********************************************************************

	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.

*********************************************************************/
section("sdram0_bank1_nocache")
static ADI_INT_HANDLER(ExceptionHandler)	// exception handler
{
	printf("\nException Error occured!\n");
	ezTurnOnAllLEDs();
	while (1) ;
}

section("sdram0_bank1_nocache")
static ADI_INT_HANDLER(HWErrorHandler)		// hardware error handler
{
	printf("\nHardware Error occured!\n");
	ezTurnOnAllLEDs();
	while (1) ;
}

/*********************************************************************

    Function:       VideoInCallback

    Description:    Video In callback function (ADV7183)

*********************************************************************/
section ("Callback_Code")
static void VideoInCallback(
	void *AppHandle,
	u32  Event,
	void *pArg
){         
	// Call corresponding service routine   
	VideoIn(AppHandle,Event,pArg);
	return;
}

/*********************************************************************

    Function:       VideoOutCallback

    Description:    Video Out callback function (ADV717x)

*********************************************************************/
section ("Callback_Code")
static void VideoOutCallback(
	void *AppHandle,
	u32  Event,
	void *pArg
){         
	// Call corresponding service routine   
	VideoOut(AppHandle,Event,pArg);
	return;
}

/*********************************************************************

	Function:		NET2272_Callback

	Description:	USB I/O callback function for Net2272 device

*********************************************************************/
section ("Callback_Code")
static void NET2272_Callback(
	void 	*AppHandle,
	u32  	Event,
	void 	*pArg
){
    // Call corresponding service routine   
	USB_Callback(AppHandle,Event,pArg);
	return;
}	

/*****/

