/*********************************************************************************

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 NTSC_MODE
#define NEC_LCD

/*********************************************************************

Include files

*********************************************************************/
#include <drivers/adi_dev.h>			// Device manager includes
#include <drivers/decoder/adi_adv7183.h>		// AD7183 device driver includes
#if defined NEC_LCD	// NEC LCD
#include <drivers/lcd/nec/adi_nl6448bc33_54.h>
#else
#include <drivers/lcd/sharp/adi_lq10d368.h>
#endif
#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

// NTSC or PAL Video input
#define ACTIVE_FIELD_DATA_LEN		720	// Active field data length per line for PAL video format

#if defined NTSC_MODE	// NTSC mode
#define ACTIVE_FIELD_LINES	507		// Number of lines per active field frame for NTSC format   
#define CROP_VIDEO_LINES	13
#define OFFSET_TO_ODD_FRAME	((ACTIVE_FIELD_LINES+1)/2)
#else // PAL mode
#define ACTIVE_FIELD_LINES	576		// Number of lines per active field frame for PAL format   
#define CROP_VIDEO_LINES	24
#define OFFSET_TO_ODD_FRAME	288
#endif

#define ACTIVE_FIELD_FRAME_SIZE	(ACTIVE_FIELD_DATA_LEN * ACTIVE_FIELD_LINES)
#define VIDEOHORZLINES		ACTIVE_FIELD_DATA_LEN/2
#define CROP_HORIZONTAL_LINES	20

#define IPOFFSET_EVEN	(CROP_VIDEO_LINES*VIDEOHORZLINES)+CROP_HORIZONTAL_LINES// VIDEO buffer offset for even frame
#define IPOFFSET_ODD	IPOFFSET_EVEN + (OFFSET_TO_ODD_FRAME*VIDEOHORZLINES)// VIDEO buffer offset for odd frame



// VGA LCD output
#define VGA_WIDTH		640
#define VGA_PADLEFT		0
#define VGA_PADRIGHT		0

#define VGA_HEIGHT		480
#define VGA_PADTOP		33
#define VGA_PADBOTTOM		12

#define VGA_FRAME_WIDTH		(VGA_WIDTH+VGA_PADLEFT+VGA_PADRIGHT) // 640
#define VGA_FRAME_HEIGHT	(VGA_HEIGHT+VGA_PADTOP+VGA_PADBOTTOM) // 525
#define VGA_FRAME_SIZE		(VGA_FRAME_WIDTH*VGA_FRAME_HEIGHT) // 640*525

#define LCDHORZLINES	VGA_FRAME_WIDTH/2
#define OPOFFSET_EVEN	(VGA_PADTOP*LCDHORZLINES)// LCD buffer offset for even frame
#define OPOFFSET_ODD	((VGA_PADTOP+1)*LCDHORZLINES)//LCD buffer offset for odd frame


section("sdram0") volatile u16 sFrame0[ACTIVE_FIELD_FRAME_SIZE];

section("sdram0_bank1") volatile u16 sFrame1[VGA_FRAME_SIZE];

// Storage for YUV to RGB565 conversion
section("L1_data_a") static unsigned long InData[512],OutData[512];




ADI_DEV_2D_BUFFER In_Buffer2D, Out_Buffer2D; 

	
	

// 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 LcdDriverHandle;// handle to the LCD driver

/*********************************************************************

static function prototypes

*********************************************************************/
static void InitSystemServices(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 Read7183StatusReg(ADI_DEV_DEVICE_HANDLE AD7183DevHandler);
static void Set7183RangeReg(void);// Set AD7183 Extended Output Control register
static void DisplayFrame(
	ADI_DEV_MANAGER_HANDLE 	DeviceManagerHandle,
	ADI_DMA_MANAGER_HANDLE 	DMAManagerHandle );
static void CaptureFrame(
	ADI_DEV_MANAGER_HANDLE 	DeviceManagerHandle,
	ADI_DMA_MANAGER_HANDLE 	DMAManagerHandle );
void convertFrame(void);   
static void convertyuvrgb(unsigned short OutSize, unsigned long *Output, unsigned short InSize, unsigned long *Input);

volatile bool FrameCapture = FALSE;
volatile u32	FrameCounter;
bool KeepGoing = TRUE;


// 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_1,(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 LCD device drivers,this
	                program demonstrates a simple video display program.
					The video data is captured into SDRAM from the AD7183 decoder,
					convert active video data from YUV to RGB and stored into another
					SDRAM memory.
					LCD driver outputs RGB data into lcd panel. 
*********************************************************************/
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);
	}
	
	ezTurnOffAllLEDs();


	// keep going ..........
    while (KeepGoing){
    	
        // capture a new frame
		CaptureFrame( adi_dev_ManagerHandle, adi_dma_ManagerHandle);
		convertFrame();// convert YUV to RGB
		
		// display the frame of video
		DisplayFrame( 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);
	
	adi_pwr_SetFreq(400000000,100000000,ADI_PWR_DF_NONE);



	
	// return
}

/*********************************************************************

	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) {

        	FrameCapture = TRUE;
    	    }
    	    else
    	    FrameCounter++;
    	    
            break;
		
		
	}

}





/*********************************************************************

	Function:		CaptureFrame

	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 CaptureFrame(
	ADI_DEV_MANAGER_HANDLE 	DeviceManagerHandle,
	ADI_DMA_MANAGER_HANDLE 	DMAManagerHandle
){
	int Result;

	FrameCapture = FALSE;	

// turn on LED
//	ezTurnOnLED(1);
	
#if defined(__ADSP_EDINBURGH__)			// ADSP-BF533 EZ-Kit specific info
	// enable the video decoder (7183)
	ezEnableVideoDecoder();

	ezDelay(500); // wait for 7183 to come out of reset
	
#else
   	//disable the EZ-Kit561 video decoder, use the AV-Extender card decoder 
	ezDisableVideoDecoder();
//	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

					
/********* open AD7183-PPI ****************************************/		
	// 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(NTSC_MODE)
		ezErrorCheck( adi_dev_Control(AD7183DriverHandle, ADI_AD7183_CMD_SET_VIDEO_FORMAT, (void *)NTSC));
#else
		ezErrorCheck( adi_dev_Control(AD7183DriverHandle, ADI_AD7183_CMD_SET_VIDEO_FORMAT, (void *)PAL));
#endif		
	/******************* AD7183 Inbound Buffers  ***********************************************/	
	// populate the buffers that we'll use for the PPI input
	In_Buffer2D.Data = (void*)sFrame0;
#if defined(__ADSP_EDINBURGH__)			// ADSP-BF533 EZ-Kit specific info
	In_Buffer2D.ElementWidth = sizeof(u16);
	In_Buffer2D.XCount = ACTIVE_FIELD_DATA_LEN;
	In_Buffer2D.XModify = sizeof(u16);
	In_Buffer2D.YModify = sizeof(u16);
#else	// ADSP-BF561 EZ-Kit specific
	In_Buffer2D.ElementWidth = sizeof(u32);
	In_Buffer2D.XCount = ACTIVE_FIELD_DATA_LEN/2;
	In_Buffer2D.XModify = sizeof(u32);
	In_Buffer2D.YModify = sizeof(u32);

#endif
	
	In_Buffer2D.YCount = ACTIVE_FIELD_LINES;
	In_Buffer2D.CallbackParameter = &In_Buffer2D;
	In_Buffer2D.pNext = NULL;

	
	// configure the ad7183 dataflow method to chained
	Result = adi_dev_Control(AD7183DriverHandle, ADI_DEV_CMD_SET_DATAFLOW_METHOD, (void *)ADI_DEV_MODE_CHAINED);
	 if (Result != ADI_DEV_RESULT_SUCCESS) 
	 {
	 	printf("%x\n", Result);
	 }
	 	FrameCapture = FALSE;	

	 

	
	
		// give the PPI driver the buffer to process
	ezErrorCheck( adi_dev_Read(AD7183DriverHandle, ADI_DEV_2D, (ADI_DEV_BUFFER *)&In_Buffer2D));
	
	/********* AD7183 registers access ****************************************/		
	// 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)); 

	//set Extended Output Control register to ITU656 for 16<Y<235 and 16<C<240
	//Set7183RangeReg();
	
	 // configure the PPI driver for receiving active field only
	ezErrorCheck( adi_dev_Control(AD7183DriverHandle, ADI_AD7183_CMD_SET_ACTIVE_VIDEO, (void*)TRUE));
	
	
	/***********************************************************************************/
	// 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 (FrameCapture == FALSE) ;
	
	//Read7183StatusReg(AD7183DriverHandle);			

	ezErrorCheck( adi_dev_Control(AD7183DriverHandle, ADI_DEV_CMD_SET_DATAFLOW, (void*)FALSE));
		
	// close the PPI driver
	ezErrorCheck(adi_dev_Close(AD7183DriverHandle));
 
	// turn off LED
//	ezTurnOffLED(1);

}




/*********************************************************************

	Function:		DisplayFrame

	Description:	This function is called to display a frame of video
			data using LCD driver. The function is called
			after AD7183 driver has captured a frame of data.
			 
			We display the video for a about 2-3 seconds, allowing the data to be 
			seen on LCD monitor, then we close the LCD device driver.  

*********************************************************************/

static void DisplayFrame(
	ADI_DEV_MANAGER_HANDLE 	DeviceManagerHandle,
	ADI_DMA_MANAGER_HANDLE 	DMAManagerHandle
){

	// turn on LED
//	ezTurnOnLED(5);

		// open the LCD driver
	ezErrorCheck(adi_dev_Open(adi_dev_ManagerHandle,		// DevMgr handle
#if defined NEC_LCD	// NEC LCD
				&ADI_NL6448BC3354_EntryPoint,		// pdd entry point
#else
				&ADI_LQ10D368_EntryPoint,		// pdd entry point
#endif				
				0,				// device instance
				NULL,				// client handle callback identifier
				&LcdDriverHandle,			// DevMgr handle for this device
				ADI_DEV_DIRECTION_OUTBOUND,// 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
				
				
#if defined(__ADSP_EDINBURGH__)			// ADSP-BF533 EZ-Kit specific info
	// Select PPI device number and open it for LCD driver.
#if defined NEC_LCD	// NEC LCD
	ezErrorCheck(adi_dev_Control(LcdDriverHandle, ADI_NL6448BC3354_CMD_OPEN_PPI, (void*)0));
#else	
	ezErrorCheck(adi_dev_Control(LcdDriverHandle, ADI_LQ10D368_CMD_OPEN_PPI, (void*)0));
#endif	
	// populate LCD outbound buffers
	Out_Buffer2D.Data = (void*)sFrame1;// address of the data storage
	Out_Buffer2D.ElementWidth = sizeof(u16); //2 bytes wide
	Out_Buffer2D.XCount = VGA_FRAME_WIDTH;
	Out_Buffer2D.XModify = sizeof(u16);
	Out_Buffer2D.YCount = VGA_FRAME_HEIGHT;
	Out_Buffer2D.YModify = sizeof(u16);
	Out_Buffer2D.CallbackParameter = &Out_Buffer2D;// callback
	Out_Buffer2D.pNext = NULL; // terminate the chain of buffers
#else	// ADSP-BF561 EZ-Kit specific
	// Select PPI device number and open it for LCD driver.
#if defined NEC_LCD	// NEC LCD
	ezErrorCheck(adi_dev_Control(LcdDriverHandle, ADI_NL6448BC3354_CMD_OPEN_PPI, (void*)1));
#else	
	ezErrorCheck(adi_dev_Control(LcdDriverHandle, ADI_LQ10D368_CMD_OPEN_PPI, (void*)1));
#endif	
	
	// populate LCD outbound buffers
	Out_Buffer2D.Data = (void*)sFrame1;// address of the data storage
	Out_Buffer2D.ElementWidth = sizeof(u32);
	Out_Buffer2D.XCount = VGA_FRAME_WIDTH/2;
	Out_Buffer2D.XModify = sizeof(u32);
	Out_Buffer2D.YCount = VGA_FRAME_HEIGHT;
	Out_Buffer2D.YModify = sizeof(u32);
	Out_Buffer2D.CallbackParameter = &Out_Buffer2D;// callback
	Out_Buffer2D.pNext = NULL; // terminate the chain of buffers
#endif




	// configure the LCD dataflow method to "chained with loopback"
	ezErrorCheck( adi_dev_Control(LcdDriverHandle, ADI_DEV_CMD_SET_DATAFLOW_METHOD, (void *)ADI_DEV_MODE_CHAINED_LOOPBACK));
		// give the PPI driver the buffer to process
	ezErrorCheck( adi_dev_Write(LcdDriverHandle, ADI_DEV_2D, (ADI_DEV_BUFFER *)&Out_Buffer2D));
	
	FrameCounter = 0;
	// start outputting the output data
	ezErrorCheck( adi_dev_Control(LcdDriverHandle, ADI_DEV_CMD_SET_DATAFLOW, (void*)TRUE));

	// delay for a while so we can see the image
	while (FrameCounter < 120) ;
	ezErrorCheck( adi_dev_Control(LcdDriverHandle, ADI_DEV_CMD_SET_DATAFLOW, (void*)FALSE));
		
	// close the PPI driver
	ezErrorCheck(adi_dev_Close(LcdDriverHandle));
	
	// turn off LED 
//	ezTurnOffLED(5);




}

/******************************************************************************

	Function: convertFrame
	
	Description: When a input buffer is filled by the ADV7183 driver,
		     a function is called to convert each line of the buffer
		     into RGB format.	
******************************************************************************/
void convertFrame(void){
	u32 m;	
	u32 *ipF, *opF, *ipF1, *opF1;

	// process video frame 0
	    
	ipF =((u32 *)sFrame0)+ IPOFFSET_EVEN; // input point to even section of sFrame0
	ipF1 =((u32 *)sFrame0)+ IPOFFSET_ODD; // input point to odd section of sFrame0
	opF =(u32 *)sFrame1+OPOFFSET_EVEN;// output point to even section of sFrame1
	opF1 =(u32 *)sFrame1+OPOFFSET_ODD;// output point to odd section of sFrame1
	
	for(m=0;m<VGA_HEIGHT/2;m++,opF+=LCDHORZLINES*2,ipF+=VIDEOHORZLINES,opF1+=LCDHORZLINES*2,ipF1+=VIDEOHORZLINES){ //output to every second line.

		convertyuvrgb(LCDHORZLINES,opF,VIDEOHORZLINES,ipF);	
		convertyuvrgb(LCDHORZLINES,opF1,VIDEOHORZLINES,ipF);	
	
	}

}

/******************************************************************************

	Function: convertyuvrgb
	
		Description: This function takes an input buffer, output buffer 
		and writes back to the output.

		Cb=*(pYUV+n+j);
		Y0=*(pYUV+n+j+1);
		Cr=*(pYUV+n+j+2);
		Y1=*(pYUV+n+j+3); 
				
 		Red = Y0 + 1.397 * (Cr-RGBOFF);
 		Green = Y0 - 0.711 * (Cr-RGBOFF) - 0.343 * (Cb-RGBOFF);
	 	Blue = Y0 + 1.765 * (Cb-RGBOFF);
 	
******************************************************************************/
static void convertyuvrgb(
	unsigned short OutSize, unsigned long *Output,
 	unsigned short InSize, unsigned long *Input)
{
 	unsigned short i,j;
 
 	long r,g,b,r1,g1,b1,cb,cr,y0,y1; 
	u8 *yuv;
	
 	for (i=0;i<OutSize;i++) 
  		InData[i]=*Input++;
 
	for (i=0,j=0;i<OutSize;i++,j++)
  	{   

    	
 	    yuv = (u8*)(&InData[j]);
  	    y1 = (*(yuv+3)*298)-16;
  	    cr = *(yuv+2)-128;
   	    y0 = (*(yuv+1)*298)-16;
  	    cb = *yuv-128;
  	    
		r = (409*cr);
  	    g = (100*cb + 208*cr);
  	    b = (516*cb);

		r1=y0+r;
		g1=y0-g;
		b1=y0+b;
		
  	    if(r1>0xFFFF)  r1 = 255; 
  	    else if(r1<0)  r1 = 0;   	    
    	else r1>>=8;
    
    	if(g1>0xFFFF)  g1 = 255; 
    	else if(g1<0)  g1 = 0; 
    	else g1>>=8;
    
    	if(b1>0xFFFF)  b1 = 255; 
    	else if(b1<0)  b1 = 0; 
    	else b1>>=8;
        
    	r=y1+r;
		g=y1-g;
		b=y1+b;
    	
    	if(r>0xFFFF)  r = 255; 
    	else if(r<0)  r = 0; 
    	else r>>=8; 
    
    	if(g>0xFFFF)  g = 255; 
    	else if(g<0)  g = 0; 
    	else g>>=8;
    
    	if(b>0xFFFF)  b = 255; 
    	else if(b<0)  b = 0; 
    	else b>>=8;    		    
  	      	    
    	OutData[j]=
    		((b<<24) & 0xF8000000)|
    		((g<<19) & 0x07E00000)|
    		((r<<13) & 0x001F0000)|
    		((b1<<8) & 0x0000F800)|
    		((g1<<3) & 0x000007E0)|
    		((r1>>3) & 0x0000001F);
	}


 	for (i=0;i<OutSize;i++) *Output++=OutData[i];
}




/**********************************************************************
* 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_SELECTIVE_REGISTER_READ failed(error:%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");

    }

}





